2012-07-16 55 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