简体   繁体   English

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

[英]Wrong values in calculating Frequency using FFT

I'm getting wrong frequency, I don't understand why i'm getting wrong values.since i have calculating as per instructions followed by stackoverflow. 我的频率不正确,我不明白为什么我的值不正确,因为我已经按照指令进行了计算,然后进行了计算器溢出。 I've used FFT from http://introcs.cs.princeton.edu/java/97data/FFT.java.html and complex from http://introcs.cs.princeton.edu/java/97data/Complex.java.html 我已经使用了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+"---");
            }
        });

i'm getting values like 21000,18976,40222,30283 etc... Please help me..... Thank you.. 我正在获取21000,18976,40222,30283等值...请帮助我.....谢谢。

Your source code is almost fine. 您的源代码几乎没问题。 The only problem is that you search for the peaks through the full spectrum, ie from 0 via Fs/2 to Fs. 唯一的问题是您要在整个光谱中搜索峰,即从0到Fs / 2到Fs。

For any real-valued input signal (which you have) the spectrum between Fs/2 and Fs (=sample frequency) is an exact mirror of the spectrum between 0 and Fs/2 (I found this nice background explanation ). 对于任何实值输入信号(您拥有),Fs / 2和Fs之间的频谱(=采样频率)是0和Fs / 2之间的频谱的精确镜像(我发现了这种很好的背景说明 )。 Thus, for each frequency there exist two peaks with almost identical amplitude. 因此,对于每个频率,存在两个振幅几乎相同的峰。 I'm writing 'almost' because due to limited machine precision they are not necessarily exactly identical. 我之所以写“几乎”是因为由于机器精度的限制,它们不一定完全相同 So, you randomly find the peak in the first half of the spectrum which contains the frequencies below the Nyquist frequency (=Fs/2) or in the second half of the spectrum with the frequencies above the Nyquist frequency. 因此,您可以在频谱的上半部分随机找到峰值,该峰值包含低于奈奎斯特频率(= Fs / 2)的频率,或者在频谱的下半部分找到频率高于奈奎斯特频率的峰值。

If you want to correct the mistake yourself, stop reading here. 如果您想自己纠正错误,请在此处停止阅读。 Otherwise continue: 否则继续:

Just replace 只需更换

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

with

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

in the source code you presented. 在您提供的源代码中。

PS: Typically, it is better to apply a window function to the analysis buffer (eg a Hamming window) but for your application of peak picking it won't change results very much. PS:通常,最好将窗口函数应用于分析缓冲区(例如,汉明窗口),但对于峰选择的应用,其结果变化不会太大。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM