如何检测aurioTouch项目中最低和最高频率的值

时间:2012-07-16 06:35:19

标签: iphone ios audio frequency frequency-analysis

  

可能重复:
  How to get Frequency from FFT result

我正在调查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 [last]。但我不知道,例如,数字中的频率与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;中,我认为,频率的最大值将位于index = mFFTLength - 1处的mDspSplitComplex中 或者可能是我错了,频率的最大值将在index = mFFTLength / 2 - 1的mDspSplitComplex中?

更新3

我有非常类似的问题Why do we use only the first buffer in aurioTouch project。 可能有人都知道答案。

1 个答案:

答案 0 :(得分:3)

在FFT输出箱的所有中某个级别会有能量 - 您需要确定一个阈值,然后找到其幅度超过此阈值的箱。

至于解释每个出纸槽的相应频率,请参阅this excellent answer