2

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.

Community
  • 1
  • 1
Paul T.
  • 4,938
  • 7
  • 45
  • 93
  • About my update 2: mFFTLength - is the lenght of complex data, but we need only half of it, so the max value of frequency relates to )(mFFTLength / 2 - 1) element. And that's why mBufferLen in Apple code = 1024 = mFFTLength / 2 – Paul T. Jul 16 '12 at 09:33

1 Answers1

1

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.

Community
  • 1
  • 1
Paul R
  • 208,748
  • 37
  • 389
  • 560
  • I updated my the question, please, look at it. – Paul T. Jul 16 '12 at 08:22
  • 1
    The edit hasn't shown up yet - it looks like you are using multiple StackOverflow logins and you edited under a different pseudonym than you originally posted under. You should probably just stick to one login to avoid confusion. – Paul R Jul 16 '12 at 08:29
  • We are a team of developers, that's why the question was updated by the other guy from our team. But I fixed the issue with update, so now you should see it – Paul T. Jul 16 '12 at 08:42
  • Anyway, if you don't see, here it is: 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? – Paul T. Jul 16 '12 at 08:43
  • I've looked at your link. It's the answer! – Paul T. Jul 16 '12 at 08:53
  • One more question, I updated my topic to "Update 2", please, comment this. Thank you very much! – Paul T. Jul 16 '12 at 09:22
  • It's a real-to-complex FFT with mFFTLength real inputs and mFFTLength/2 complex outputs (the other mFFTLength/2 complex outputs are symmetrical and are ignored). Note that a complex output point is twice the size of a real input point. The calculation of output bin frequency remains the same though, i.e. complex output bin n corresponds to frequency Fs * n / mFFTLength. – Paul R Jul 16 '12 at 09:55
  • I have the other little issue "Why do we use only the first buffer in aurioTouch project". I insert link to the issue in "Update 3". Please, look at it. Thank you so much!!! – Paul T. Jul 16 '12 at 11:21