2013-11-21 63 views
2

我目前使用的GDX庫com.badlogic.gdx.audio.analysis.FFT和方法:使用GDX圖書館和FFT計算出頻率(JAVA)

private float[] fft(int N, int fs, float[] array) { 
    float[] fft_cpx, tmpr, tmpi; 
    float[] res = new float[N/2]; 
    // float[] mod_spec =new float[array.length/2]; 
    float[] real_mod = new float[N]; 
    float[] imag_mod = new float[N]; 
    double[] real = new double[N]; 
    double[] imag = new double[N]; 
    double[] mag = new double[N]; 
    double[] phase = new double[N]; 
    float[] new_array = new float[N]; 
    // Zero Pad signal 
    for (int i = 0; i < N; i++) { 
     if (i < array.length) { 
      new_array[i] = array[i]; 
     } 
     else { 
      new_array[i] = 0; 
     } 
    } 

    FFT fft = new FFT(N, 8000); 

    fft.forward(new_array); 
    fft_cpx = fft.getSpectrum(); 
    tmpi = fft.getImaginaryPart(); 
    tmpr = fft.getRealPart(); 
    for (int i = 0; i < new_array.length; i++) { 
     real[i] = (double) tmpr[i]; 
     imag[i] = (double) tmpi[i]; 

     mag[i] = Math.sqrt((real[i] * real[i]) + (imag[i] * imag[i])); 
     phase[i] = Math.atan2(imag[i], real[i]); 

     /**** Reconstruction ****/ 
     real_mod[i] = (float) (mag[i] * Math.cos(phase[i])); 
     imag_mod[i] = (float) (mag[i] * Math.sin(phase[i])); 

    } 
    fft.inverse(real_mod, imag_mod, res); 
    return res; 

} 

如何做,然後我用這個方法找出從麥克風錄製的聲音的頻率(然後記錄)?

回答

1

你的目標是在mag [i]中取所有個別頻率的大小,並找到最大的一個。首先,你可以繞過它們並找到最大的mag [i]。那麼你必須重新計算它的相應頻率i索引。

頻率由該公式確定:

freq = i * Fs/N; 

哪裏Fs是你的時域數據的採樣頻率(輸入波數據),N - 你從沒有計算FFT樣本數。 i是您的頻域數據(計算幅度和相位)

在你的情況,你可以添加一行指數等進入你的循環調試它:

double freq = (double)i*(double)fs/(double)N; 
System.out.println("Frequency: "+ Double.toString(freq) + "Magnitude: "+ Double.toString(mag[i])); 

檢查此鏈接瞭解更多信息: How to get frequency from fft result?

Nyquist theorem

...指出,可以完美的重建頻率如果你有兩倍的樣本......重建1000Hz,你必須每秒至少有2000個樣本。 (這一波仍然會非常扭曲)。

如果你有22000Hz的採樣率,你將能夠以某種方式測量高達11000Hz的頻率。您在magphase數據將是有意義的陣列0..N/2上半年的話,你會看到前一次的數據的鏡像(見鏈接wikipedia page的圖片。)

如果你想確定您的N check this answer或谷歌更多。嘗試從任意數字開始,如採樣率fs的十分之一。 N越大,越慢的算法就是你的算法。

Table of note frequencies

簡單的方法是讓你將檢測所有頻率的表,然後只需用最大震級比較你的頻率都frequencie值表。有一個小公差,例如表中的值的+ -2%。確保兩個連續音符的容差不重疊。

麥克風輸入

谷歌將關鍵字像Java麥克風輸入庫的使用,或檢查this answer

+0

對於麥克風輸入,我有點麻煩。我以爲我發現如何用javax.sound來做到這一點,但我使用的是沒有該包的Android SDK。我想我需要使用android.media.audiorecord,但我不知道如何以及沒有太多可以找到的信息。有沒有可以給我的建議/信息?其他一切看起來不錯。 – JoshSchellenberger

+0

你應該重申你的問題爲Android,如果你與麥克風輸入鬥爭,你可以開始通過生成sin函數的測試輸入,搜索帶有麥克風輸入的Android示例項目 – nio