使用FFT计算频率时的值错误

我的错频率,我不明白为什么我得到错误的值。因为我按照指令计算后跟stackoverflow。 我使用了来自http://introcs.cs.princeton.edu/java/97data/FFT.java.html的 FFT和http://introcs.cs.princeton.edu/java/97data/Complex.java中的复合体。 HTML

audioRec.startRecording(); audioRec.read(bufferByte, 0,bufferSize); for(int i=0;i<bufferSize;i++){ bufferDouble[i]=(double)bufferByte[i]; } Complex[] fftArray = new Complex[bufferSize]; for(int i=0;i<bufferSize;i++){ fftArray[i]=new Complex(bufferDouble[i],0); } FFT.fft(fftArray); double[] magnitude=new double[bufferSize]; for(int i=0;i<bufferSize;i++){ magnitude[i] = Math.sqrt((fftArray[i].re()*fftArray[i].re()) + (fftArray[i].im()*fftArray[i].im())); } double max = 0.0; int index = -1; for(int j=0;j<bufferSize;j++){ if(max < magnitude[j]){ max = magnitude[j]; index = j; } } final int peak=index * sampleRate/bufferSize; Log.v(TAG2, "Peak Frequency = " + index * sampleRate/bufferSize); handler.post(new Runnable() { public void run() { textView.append("---"+peak+"---"); } }); 

我得到的价值如21000,18976,40222,30283等…请帮帮我…..谢谢..

你的源代码几乎没问题。 唯一的问题是你在整个光谱中搜索峰值,即从0到Fs / 2到Fs。

对于任何实值输入信号(你有),Fs / 2和Fs之间的频谱(=采样频率)是0和Fs / 2之间频谱的精确镜像(我发现这个很好的背景解释 )。 因此,对于每个频率,存在两个具有几乎相同幅度的峰值。 我正在写’差不多’,因为由于机器精度有限,它们不一定完全相同 。 因此,您可以随机找到频谱前半部分的峰值,其中包含低于奈奎斯特频率(= Fs / 2)的频率,或频谱高于奈奎斯特频率的频谱的后半部分。

如果你想自己纠正错误,请在这里停止阅读。 否则继续:

只需更换

 for(int j=0;j 

 for(int j=0;j<=bufferSize/2;j++){ 

在您提供的源代码中。

PS:通常情况下,最好将窗口函数应用于分析缓冲区(例如汉明窗口),但对于峰值拾取的应用,它不会对结果产生太大影响。