2012-07-16 58 views
2

可能重複:
How to get Frequency from FFT result如何檢測的最低和最高頻率值aurioTouch項目

我調查aurioTouch2示例代碼。 而在繪製視圖函數中,總是調用一個函數來計算fft數據,所以我們可以計算不同頻率的功率。

Boolean FFTBufferManager::ComputeFFT(int32_t *outFFTData) 
{ 
    if (HasNewAudioData()) 
    { 


     //Generate a split complex vector from the real data 
     // real1 = -0.005138, real2 = -0.005010;  r = -0.005138, im = -0.005010 
     vDSP_ctoz((COMPLEX *)mAudioBuffer, 2, &mDspSplitComplex, 1, mFFTLength); 

     //Take the fft and scale appropriately 
     // FFTSetup mSpectrumAnalysis - koefficients 
     vDSP_fft_zrip(mSpectrumAnalysis, &mDspSplitComplex, 1, mLog2N, kFFTDirection_Forward); 
     vDSP_vsmul(mDspSplitComplex.realp, 1, &mFFTNormFactor, mDspSplitComplex.realp, 1, mFFTLength); 
     vDSP_vsmul(mDspSplitComplex.imagp, 1, &mFFTNormFactor, mDspSplitComplex.imagp, 1, mFFTLength); 

     //Zero out the nyquist value 
     mDspSplitComplex.imagp[0] = 0.0; 

     //Convert the fft data to dB 
     // calculate complex number abs, write to tmpData 
     Float32 tmpData[mFFTLength]; 
     vDSP_zvmags(&mDspSplitComplex, 1, tmpData, 1, mFFTLength); 

     //In order to avoid taking log10 of zero, an adjusting factor is added in to make the minimum value equal -128dB 
     vDSP_vsadd(tmpData, 1, &mAdjust0DB, tmpData, 1, mFFTLength); 
     Float32 one = 1; 
     vDSP_vdbcon(tmpData, 1, &one, tmpData, 1, mFFTLength, 0); 

     //Convert floating point data to integer (Q7.24) 
     vDSP_vsmul(tmpData, 1, &m24BitFracScale, tmpData, 1, mFFTLength); 
     for(UInt32 i=0; i<mFFTLength; ++i) 
      outFFTData[i] = (SInt32) tmpData[i]; 

     OSAtomicDecrement32Barrier(&mHasAudioData); 
     OSAtomicIncrement32Barrier(&mNeedsAudioData); 
     mAudioBufferCurrentIndex = 0; 
     return true; 
    } 
    else if (mNeedsAudioData == 0) 
     OSAtomicIncrement32Barrier(&mNeedsAudioData); 

    return false; 
} 

問題是如何獲得我在屏幕上顯示的頻率的多樣性? 我的意思是,我有不同音頻的功率陣列。我怎麼能理解,例如,最低頻率的價值是什麼?

更新,以顯示我的觀點:

我知道,最低閾值(最低頻率)outFFTData [0],最高的是outFFTData [最後]。但我不知道,例如,數字中的頻率與outFFTData [0]有關。 outFFTData [0]與16Hz有關;並且outFFTData [last]與22 kHz有關?

現在我想,outFFTData [0]與音頻的最低頻率有關,一個人可以聽到; outFFTData [last]涉及音頻的最高頻率,即一個人可以聽到的頻率。

我錯了嗎?

更新2

我看着Paul R代碼here。它真的顯示幾乎所有的東西 但是,請糾正我,如果我錯了:

在此代碼:

//Generate a split complex vector from the real data 
     // real1 = -0.005138, real2 = -0.005010;  r = -0.005138, im = -0.005010 
     vDSP_ctoz((COMPLEX *)mAudioBuffer, 2, &mDspSplitComplex, 1, mFFTLength); 
//Take the fft and scale appropriately 
     // FFTSetup mSpectrumAnalysis - koefficients 
     vDSP_fft_zrip(mSpectrumAnalysis, &mDspSplitComplex, 1, mLog2N, kFFTDirection_Forward); 
     vDSP_vsmul(mDspSplitComplex.realp, 1, &mFFTNormFactor, mDspSplitComplex.realp, 1, mFFTLength); 
     vDSP_vsmul(mDspSplitComplex.imagp, 1, &mFFTNormFactor, mDspSplitComplex.imagp, 1, mFFTLength); 

在這段代碼mFFTLength = mAudioBufferLen/2;,所以我覺得,頻率的那最大值將在mDspSplitComplex爲index = mFFTLength - 1 或者可能是我錯了,頻率的最大值將在mDspSplitComplex處爲index = mFFTLength/2 - 1

更新3

我已經很simular問題Why do we use only the first buffer in aurioTouch project。 可能有人知道答案。

+0

關於我的更新2:mFFTLength - 是複雜數據的長度,但我們只需要它的一半,所以頻率的最大值與(mFFTLength/2 - 1)元素相關。這就是爲什麼在蘋果代碼mBufferLen = 1024 = mFFTLength/2 – 2012-07-16 09:33:36

回答

3

在FFT輸出箱中將會有一些能量在全部 - 您需要決定一個閾值,然後找到其大小超過此閾值的箱。

至於解釋每個出紙槽的相應頻率,請參見this excellent answer

+0

我更新了我的問題,請看看它。 – 2012-07-16 08:22:14

+1

編輯尚未顯示 - 它看起來像您正在使用多個StackOverflow登錄名,並且您使用不同於您最初發布的假名編輯。您應該堅持一次登錄以避免混淆。 – 2012-07-16 08:29:00

+0

我們是一個開發團隊,這就是爲什麼問題由我們團隊的其他人更新。但我更新了這個問題,所以現在你應該看到它 – 2012-07-16 08:42:48