有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java实现音频信号的高通滤波器

我能够编写一个程序来捕获音频信号,消除背景噪音,应用窗口功能并可视化该信号。我的程序一直工作到这一点,没有出现错误。现在我正试图在代码中实现高通滤波器。我已经找到了这个部分的API。但我无法根据我的代码应用它。这是我的代码:

private class RecordAudio extends AsyncTask<Void, double[], Void> {
    @Override
    protected Void doInBackground(Void... params) {
        started = true;
        try {
            DataOutputStream dos = new DataOutputStream(
                    new BufferedOutputStream(new FileOutputStream(
                            recordingFile)));
            int bufferSize = AudioRecord.getMinBufferSize(frequency,
                    channelConfiguration, audioEncoding);
            audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
                    frequency, channelConfiguration, audioEncoding,
                    bufferSize);

            NoiseSuppressor.create(audioRecord.getAudioSessionId());
            short[] buffer = new short[blockSize];
            double[] toTransform = new double[blockSize];
            long t = System.currentTimeMillis();
            long end = t + 15000;
            audioRecord.startRecording();

            while (started && System.currentTimeMillis() < end) {
                int bufferReadResult = audioRecord.read(buffer, 0,
                        blockSize);
                for (int i = 0; i < blockSize && i < bufferReadResult; i++) {
                    toTransform[i] = (double) buffer[i] / 32768.0;
                    dos.writeShort(buffer[i]);
                }
                toTransform = hann(toTransform);
                transformer.ft(toTransform);
                publishProgress(toTransform);
            } 
            audioRecord.stop();
            dos.close();
        } catch (Throwable t) {
            Log.e("AudioRecord", "Recording Failed");
        }
        return null;
    }

This是API链接

有人能帮我做这个功能吗?我真的很感激!:)

提前谢谢


共 (1) 个答案

  1. # 1 楼答案

    下面是我从c#中找到的库中转换为java的类。我使用它,效果很好。您也可以将该类用于低通滤波器

    public class Filter {
    
    
    /// <summary>
    /// rez amount, from sqrt(2) to ~ 0.1
    /// </summary>
    private float resonance;
    
    private float frequency;
    private int sampleRate;
    private PassType passType;
    
    
    public float value;
    
    private float c, a1, a2, a3, b1, b2;
    
    /// <summary>
    /// Array of input values, latest are in front
    /// </summary>
    private float[] inputHistory = new float[2];
    
    /// <summary>
    /// Array of output values, latest are in front
    /// </summary>
    private float[] outputHistory = new float[3];
    
    public Filter(float frequency, int sampleRate, PassType passType, float resonance)
    {
        this.resonance = resonance;
        this.frequency = frequency;
        this.sampleRate = sampleRate;
        this.passType = passType;
    
        switch (passType)
        {
            case Lowpass:
                c = 1.0f / (float)Math.tan(Math.PI * frequency / sampleRate);
                a1 = 1.0f / (1.0f + resonance * c + c * c);
                a2 = 2f * a1;
                a3 = a1;
                b1 = 2.0f * (1.0f - c * c) * a1;
                b2 = (1.0f - resonance * c + c * c) * a1;
                break;
            case Highpass:
                c = (float)Math.tan(Math.PI * frequency / sampleRate);
                a1 = 1.0f / (1.0f + resonance * c + c * c);
                a2 = -2f * a1;
                a3 = a1;
                b1 = 2.0f * (c * c - 1.0f) * a1;
                b2 = (1.0f - resonance * c + c * c) * a1;
                break;
        }
    }
    
    public enum PassType
    {
        Highpass,
        Lowpass,
    }
    
    public void Update(float newInput)
    {
        float newOutput = a1 * newInput + a2 * this.inputHistory[0] + a3 * this.inputHistory[1] - b1 * this.outputHistory[0] - b2 * this.outputHistory[1];
    
        this.inputHistory[1] = this.inputHistory[0];
        this.inputHistory[0] = newInput;
    
        this.outputHistory[2] = this.outputHistory[1];
        this.outputHistory[1] = this.outputHistory[0];
        this.outputHistory[0] = newOutput;
    }
    
    
    public float getValue()
    {
        return this.outputHistory[0];
    }
    
    
    }
    

    我就是这么用的

        Filter filter = new Filter(15000,44100, Filter.PassType.Highpass,1);
        for (int i = 0; i < numSamples; i++)
        {
            filter.Update(floatArray[i]);
            floatArray[i] = filter.getValue();
        }
    

    在得到阵列的fft后,你会看到它被过滤了。 希望有帮助