FFT的基本频率

时间:2014-05-23 12:22:15

标签: android fft frequency voice recorder

我正在做一个从录音机返回基频的Android项目。 我用FFT类来计算频率:

http://introcs.cs.princeton.edu/java/97data/FFT.java

和Complex Array来自:

http://introcs.cs.princeton.edu/java/97data/Complex.java.html

这是我计算频率的代码:

public double calculateFFT(byte[] signal)
        {           
        final int mNumberOfFFTPoints =1024;
        double mMaxFFTSample;

        double temp;
        Complex[] y;
        Complex[] complexSignal = new Complex[mNumberOfFFTPoints];
        double[] absSignal = new double[mNumberOfFFTPoints/2];

        for(int i = 0; i < mNumberOfFFTPoints; i++){
            temp = (double)((signal[2*i] & 0xFF) | (signal[2*i+1] << 8)) / 32768.0F;
            complexSignal[i] = new Complex(temp,0.0);
        }

        y = FFT.fft(complexSignal); 

        mMaxFFTSample = 0.0;
        int mPeakPos = 0;
        for(int i = 0; i < (mNumberOfFFTPoints/2); i++)
        {
            absSignal[i] = Math.sqrt(Math.pow(y[i].re(), 2) + Math.pow(y[i].im(), 2));

            if(absSignal[i] > mMaxFFTSample)
            {
                mMaxFFTSample = absSignal[i];
                mPeakPos = i;
            } 
        }


        return ((1.0 * sampleRate) / (1.0 * mNumberOfFFTPoints)) * mPeakPos;

    }

其中sampleRate = 44100且mNumberOfFFTPoints = 1024。从这段代码中我读了很多值,但是我 想要得到唯一的基频,所以只有价值。你能帮我理解这个算法吗?

1 个答案:

答案 0 :(得分:1)

通常,音乐或语音的基频检测非常重要。话虽如此,根据您的来源,您可以简化问题。

例如,如果您的来源是一个人唱​​一个音符,录音中没有音乐或其他背景声音,修改后的峰值探测器可能会给出合理的结果。

下图显示了持有B-flat-3(Bb3)音符的女高音的频谱。 Bb3的基频是233赫兹,但女高音实际上是一个236赫兹的基音(最左边和最高峰)。

Frequency spectrum of female soprano singing B-flat-3 note. Sooeet.com FFT calculator

下图显示了持有F4音符的女高音的频谱。 F4的基频是349赫兹,但女高音实际上是在演唱一个360赫兹的基音(最左边的峰值)。

Frequency spectrum of female soprano singing F4 note. Sooeet.com FFT calculator

然而,上图还显示了基频检测的挑战之一。在这种情况下,最高峰不是基波,而是714 Hz的一次谐波。您修改后的峰值检测器必须与这些情况相抗衡。

其他可能性是倒谱分析和自相关 见这些参考文献: Fundamental frequency detection /// Speech Signal Analysis

来自Sooeet.com FFT calculator

的FFT,图表和音频数据