2014-02-18 61 views
6

我收到錯誤的頻率,我不明白爲什麼我出現錯誤的值。因爲我按照指令進行了計算,接着是計算器。 我已經使用FFT從 http://introcs.cs.princeton.edu/java/97data/FFT.java.html 和複雜的 http://introcs.cs.princeton.edu/java/97data/Complex.java.html使用FFT計算頻率中的錯誤值

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 ...... 請幫我..... 謝謝你..

+2

您應該嘗試使用已知合成正弦曲線運行乾淨的數據。你似乎沒有看到數量,所以你的結果可能只是噪音。如果你使用窗口函數,這並不明顯。 –

+0

什麼是您的採樣率和緩衝區大小?你的輸入信號是什麼樣的? – hotpaw2

+0

@克里斯,因爲我是新來的DSP,請在編程詳解... – Pandian

回答

2

你的源代碼幾乎沒有問題。唯一的問題是您要搜索整個頻譜的峯值,即從0到Fs/2到Fs。對於任何實數輸入信號(您有),Fs/2和Fs(=採樣頻率)之間的頻譜是0到Fs/2(我找到this nice background explanation)之間的頻譜的精確反射鏡。因此,對於每個頻率存在兩個峯值,其幅度幾乎相同。我正在寫'幾乎',因爲由於機器精度有限,他們不一定是正好相同。因此,您可以在頻譜的前半部分隨機找到峯值,該峯值包含低於奈奎斯特頻率(= Fs/2)的頻率,或者在頻譜高於奈奎斯特頻率的頻譜的後半部分。

如果您想自己糾正錯誤,請停止閱讀此處。否則繼續:

只是

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

在你提供的源代碼替換

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

P.S:通常情況下,最好是到窗口函數適用於分析緩衝液(例如漢明窗),但你的顛峯應用採摘它不會改變結果感到非常。

+0

抱歉的延遲.... 我已經放棄了FFT零棒和零交叉。請參閱此[鏈接](https://github.com/gast-lib/gast-lib/blob/master/library/src/root/gast/audio/processing/ZeroCrossing.java)。 它在頻率檢測方面似乎沒有太大的區別。如果您有任何建議,請與我分享。謝謝 – Pandian

+0

我會看看鏈接。同時,你可以接受我的答案,因爲很可能你的alg的錯誤值也是通過鏡像譜搜索得到的。其他讀者可能會感興趣。 –

+0

實際上,這種粗略的零交叉分析只適用於諧波相對於基波非常低的情況,並且只有在良好的S/N無線電以及僅分析單聲道信號的情況下。在所有其他情況下,估計會變得或多或少。 –