2013-10-30 647 views
2

我開始使用某些參數從AudioRecord錄製聲音。Android - 計算FFT後頻率不正確

private static final int RECORDER_SAMPLERATE = 44100; 
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO; 
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT; 
this.recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 
      RECORDER_SAMPLERATE, RECORDER_CHANNELS, 
      RECORDER_AUDIO_ENCODING, this.bufferSize); 

我將數據存儲到一個ArrayList中< byte []> soundRecord;

while (this.isRecording) { 
    read = this.recorder.read(data, 0, this.bufferSize); 
    if (AudioRecord.ERROR_INVALID_OPERATION != read) { 
     try { 
      soundRecord.add(data); 
      os.write(data); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

這是我將聲音計算爲複數陣列FFT的方法。在做之前,我將字節轉換爲double。

public ArrayList<double[]> computeFFT(byte[] audioSignal) { 
    final int fftPoint = 65536; 
    ArrayList<double[]> result; 

    double tmp; 
    Complex[] y; 
    Complex[] complexAudioSignal = new Complex[fftPoint]; 
    double[] magnitude = new double[fftPoint/2]; 

    for (int i = 0; i < fftPoint; i++) { 
     if (i >= 22050) tmp = 0; 
     else tmp = (double) ((audioSignal[2 * i] & 0xFF) | (audioSignal[2 * i + 1] << 8)/32768.0F; 
     complexAudioSignal[i] = new Complex(tmp, 0.0); 
    } 

    y = FFF.fft(complexAudioSignal); 

    // Calculate magnitude values from fft[] 
    for (int i = 0; (fftPoint/2); i++) { 
     magnitude[i] = y[i].abs(); 
    } 

    // get only values over mid value 
    result = showFrequencies(magnitude, fftPoint); 
    return result; 
} 

我的問題是,我測試440Hz(A4鋼琴)的恆定聲音。 我得到了我的陣列「大小」一個峯值,但這個峯值的頻率是220Hz。 每次我嘗試只有一個頻率(我使用n軌道)的示例聲音,頻率是實際頻率/ 2.

我知道頻率是f = index * SAMPLE_RATE/fftPoint。

有人可以幫助我。因爲我已經3日內問題...


編輯一:

修改我的轉換回路喜歡你的建議。它看起來像:

int bytePerSample =2; 
int j = 0; 
for (int i = 0; i < audioSignal.length/2; i++) { 
    if ((i % 8 == 0 || i % 8 == 2) && i < 22050) { 
     tmp = (double) ((audioSignal[bytesPerSample * i] & 0xFF) | audioSignal[bytePerSample * i + 1] << 8))/32768.0F; 
     complexAudioSignal[j] = new Complex(tmp, 0.0); 
     j++; 
    } 
} 

現在的問題是FrequencyIWant = FreqIObtain/2 我真的不知道現在該做什麼。「(

+0

你似乎被忽略了兩倍:你是否忽略了考慮你的錄音是帶有交錯通道的立體聲嗎?或者你可能把單個字節轉換成採樣,而不是字節對?要麼是錯誤,除了其他問題之外,有點像抽樣率是你認爲的兩倍。 –

+0

感謝您的評論,我是音頻的初學者,所以我不明白/知道你在說什麼。你能舉幾個例子嗎? – BlackRabbit

+0

如果您希望在音頻分析項目上取得進展,您需要花時間瞭解這些主題。但是,如果您無意處理立體聲聲道,請將您的信號源設置更改爲單聲道。 –

回答

2

您複製兩個立體聲聲道到您的FFT,而不僅僅是左邊或右邊的通道,嘗試在你的整數解包和轉換循環中每4個字節中使用2個連續的字節

+0

謝謝!我將我的記錄更改爲AudioFormat.CHANNEL_IN_MONO。而現在,我擁有正確的頻率。 – BlackRabbit

+0

隨着CHANNEL_IN_MONO,聲音正在加速,價值是荒謬的。我該怎麼做你建議的事情? – BlackRabbit