2

重複の可能性:
FFT結果から周波数を取得する方法

aurioTouch2サンプル コードを調査しています。また、描画ビュー関数では、fft データを計算するために常に 1 つの関数が呼び出されるため、さまざまな周波数の電力を計算できます。

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コードを見ました。それは本当にほとんどすべてを示しています。しかし、私が間違っている場合は、訂正してください。

このコードでは:

//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 あると思いindex = mFFTLength / 2 - 1ます。

アップデート 3

私は非常に似たような問題を抱えています。なぜ aurioTouch プロジェクトで最初のバッファのみを使用するのですか。答えは誰でも知っているかもしれません。

4

1 に答える 1

3

すべてのFFT出力ビンにはある程度のエネルギーがあります。しきい値を決定してから、このしきい値を超える大きさのビンを見つける必要があります。

各出力ビンに対応する周波数の解釈については、この優れた回答を参照してください。

于 2012-07-16T07:47:31.477 に答える