DSP - Problems using the inverse Fast Fourier Transform

Posted by Trap on Stack Overflow See other posts from Stack Overflow or by Trap
Published on 2010-05-28T13:34:33Z Indexed on 2010/05/30 9:42 UTC
Read the original article Hit count: 364

Filed under:
|
|
|
|

I've been playing around a little with the Exocortex implementation of the FFT, but I'm having some problems.

First, after calculating the inverse FFT of an unchanged frequency spectrum obtained by a previous forward FFT, one would expect to get the original signal back, but this is not the case. I had to figure out that I needed to scale the FFT output to about 1 / fftLength to get the amplitudes ok. Why is this?

Second, whenever I modify the amplitudes of the frequency bins before calling the iFFT the signal gets distorted at low frequencies. However, this does not happen if I attenuate all the bins by the same factor.

Let me put a very simplified example of the output buffer of a 4-sample FFT:

// Bin 0 (DC)
FFTOut[0] = 0.0000610351563
FFTOut[1] = 0.0

// Bin 1
FFTOut[2] = 0.000331878662
FFTOut[3] = 0.000629425049

// Central bin
FFTOut[4] = -0.0000381469727
FFTOut[5] =  0.0

// Bin 3, this is a negative frequency bin.
FFTOut[6] =  0.000331878662
FFTOut[7] = -0.000629425049

The output is composed of pairs of floats, each representing the real and imaginay parts of a single bin. So, bin 0 (array indexes 0, 1) would represent the real and imaginary parts of the DC frequency. As you can see, bins 1 and 3 both have the same values, (except for the sign of the Im part), so I guess these are the negative frequency values, and finally indexes (4, 5) would be the central frequency bin.

To attenuate the frequency bin 1 this is what I do:

// Attenuate the 'positive' bin
FFTOut[2] *= 0.5;
FFTOut[3] *= 0.5;

// Attenuate its corresponding negative bin.
FFTOut[6] *= 0.5;
FFTOut[7] *= 0.5;

For the actual tests I'm using a 1024-length FFT and I always provide all the samples so no 0-padding is needed.

// Attenuate
var halfSize = fftWindowLength / 2;
float leftFreq = 0f;
float rightFreq = 22050f; 
for( var c = 1; c < halfSize; c++ )
{
    var freq = c * (44100d / halfSize);

    // Calc. positive and negative frequency locations.
    var k = c * 2;
    var nk = (fftWindowLength - c) * 2;

    // This kind of attenuation corresponds to a high-pass filter.
    // The attenuation at the transition band is linearly applied, could
    // this be the cause of the distortion of low frequencies?
    var attn = (freq < leftFreq) ? 
                    0 : 
                    (freq < rightFreq) ? 
                        ((freq - leftFreq) / (rightFreq - leftFreq)) :
                        1;

    mFFTOut[ k ] *= (float)attn;
    mFFTOut[ k + 1 ] *= (float)attn;
    mFFTOut[ nk ] *= (float)attn;
    mFFTOut[ nk + 1 ] *= (float)attn;
}

Obviously I'm doing something wrong but can't figure out what or where.

© Stack Overflow or respective owner

Related posts about filtering

Related posts about dsp