Wrong values in calculating Frequency using FFT

余生颓废 提交于 2019-12-07 02:13:36

问题


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

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..


回答1:


Your source code is almost fine. The only problem is that you search for the peaks through the full spectrum, i.e. from 0 via Fs/2 to 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). 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.

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.

P.S.: Typically, it is better to apply a window function to the analysis buffer (e.g. a Hamming window) but for your application of peak picking it won't change results very much.



来源:https://stackoverflow.com/questions/21853063/wrong-values-in-calculating-frequency-using-fft

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!