我正在研究吉他调音器应用程序,方法是录制音频,获取音频的FFT,然后找到峰值以找到基本频率。到目前为止,结果表明我的代码有效,并且在演奏纯音调时(特别是在500 + hz时)会返回准确的频率,但是由于吉他的低频和高音谐波,结果有点混乱。

我相信我需要引入一个窗函数以及一个低通滤波器来完善我的结果,并帮助我的应用检测正确的峰值,而不是谐波,但是我不太确定

尽管我不确定它是否会影响最终结果,但我已经实现了窗口功能,而且我完全不了解如何实现低通滤波器。

        byte data[] = new byte[bufferSize]; //the audio data read in
        ...

        double[] window = new double[bufferSize]; //window array

           //my window function, not sure if correct
           for(int i = 0; i< bufferSize-1; ++i){
               window[i] = ((1 - Math.cos(i*2*Math.PI/bufferSize-1))/2);
               data[i] = (byte) (data[i] * window[i]);
           }


            DoubleFFT_1D fft1d = new DoubleFFT_1D(bufferSize);
            double[] fftBuffer = new double[bufferSize*2];

            for(int i = 0; i < bufferSize-1; ++i){
                fftBuffer[2*i] = data[i];
                fftBuffer[2*i+1] = 0;
            }

            fft1d.complexForward(fftBuffer);


            //create/populate power spectrum
            double[] magnitude = new double[bufferSize/2];
            maxVal = 0;
            for(int i = 0; i < (bufferSize/2)-1; ++i) {

                double real =  fftBuffer[2*i];
                double imaginary =  fftBuffer[2*i + 1];

                magnitude[i] = Math.sqrt( real*real + imaginary*imaginary );
                                Log.i("mag",String.valueOf(magnitude[i]) + " " + i);

            //find peak magnitude
            for(int i = 0; i < (bufferSize/2)-1; ++i) {
            if(magnitude[i] > maxVal){
                maxVal = (int) magnitude[i];
                binNo = i;
                }
            }

            //results
            freq = 8000 * binNo/(bufferSize/2);
            Log.i("freq","Bin "+String.valueOf(binNo));
            Log.i("freq",String.valueOf(freq) + "Hz");

是的,不是完全确定窗口功能是否起作用,功率谱是否包含谐波峰值,而且我不确定从哪里开始使用低通滤波器。

最佳答案

窗口功能可以帮助您增加一些结果。

窗口的目的是减小窗口两端的幅度分量,以避免出现杂散高频,这是必要的,因为傅里叶变换假定信号是无限的,因此在窗口的情况下,双方无数次重复,导致边界不连续!

如果应用一个窗口,此问题将被最小化,但仍会在某种程度上发生。

如果您正在与吉他一起工作,则构建一个低通滤波器以过滤期望的最高调谐频率,那么在应用“窗函数”之前,您需要低通!

您需要考虑麦克风的频率响应,我相信这些移动麦克风要捕捉调谐吉他的低频并不容易,我们正在谈论82.4Hz

找到FFT的峰值不是一个好的调谐器!

10-04 10:21