Question

Possible Duplicate:
How to get Frequency from FFT result

I'm investigating aurioTouch2 sample code. And in draw view function one function is always called to compute fft data, so we can compute power for different frequencies.

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;
}

The question is how to get the variety of frequencies I display in the screen? I mean, I have the array of power for different audio frequencies. And how can I understand, what the value for lowest frequency, for example?

Update to show my point of view:

I know, that lowest threshold value (the lowest frequency) is outFFTData[0] and highest is outFFTData[last]. But I don't know, what frequency in figures relates to outFFTData[0], for example. Is outFFTData[0] relates to 16Hz; and is outFFTData[last] relates to 22 kHz?

Now I think, that outFFTData[0] relates to lowest frequency of audio, that a man can hear; and outFFTData[last] relates to highest frequency of audio, that a man can hear.

Am I wrong?

Update 2

I looked at Paul R code here. It really shows almost everything. But, please, correct me, if I'm wrong:

In this code:

//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);

In this code mFFTLength = mAudioBufferLen / 2;, so I think , that max value of frequency will be in mDspSplitComplex at index = mFFTLength - 1 Or may be I'm wrong and max value of frequency will be in mDspSplitComplex at index = mFFTLength / 2 - 1?

Update 3

I have very simular issue Why do we use only the first buffer in aurioTouch project. May be anyone knows the answer.

Was it helpful?

Solution

There will be energy at some level in all of the FFT output bins - you need to decide upon a threshold value and then find the bins whose magnitude exceeds this threshold.

As for interpreting the corresponding frequency for each output bin, see this excellent answer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top