In using the cfftf_fr32 function call I notice the output is not symmetrical about the Nyquist frequency. Am I using the function correctly or is this a limitation of the fixed point math at low input. I have attached example code an a figure for an example case.

#define FFT_SIZE 2048

// fft variables

complex_fract32 input[FFT_SIZE];

complex_fract32 output[FFT_SIZE];

complex_fract32 twid[(3*FFT_SIZE)/4];

double spect[FFT_SIZE];

int main( void )

{

float pi;

int i, fft_length = FFT_SIZE;

double tempd;

complex_double tempcd;

pi = acosf(-1);

twidfftf_fr32(twid, fft_length);

for(i = 0; i < fft_length; i++){

input[i].re = (fract32) 0x400*sin(2*pi*0.065*i);

input[i].im = (fract32) 0x400*sin(2*pi*0.065*i);

}

cfftf_fr32(input, output, twid,1, fft_length);

for(i = 0; i < fft_length; i++){

tempcd.re = (double) output[i].re;

tempcd.im = (double) output[i].im;

tempd = cabs(tempcd);

tempd = tempd*tempd;

if(tempd > 0)

tempd = 10*log10(tempd);

else

tempd = 0;

spect[i] = (double) tempd;

}

return 0;

}

If you add the following code before the return statement:

printf("\nFirst maximum of %.6e at location %d.\n",

vecmax(spect, 1024), vecmaxloc(spect, 1024));

printf("Second maximum of %.6e at location %d.\n",

vecmax(&spect[1024], 1024), 1024+vecmaxloc(&spect[1024], 1024));

the function will print something like:

First maximum of 5.697983e+01 at location 133.

Second maximum of 5.699111e+01 at location 1915.

Starting to count at spect[1], since spect[0] relates the DC component, you thusly get a maximum 132 places from the beginning and end as expected.

The reason that the overall shape of the spectrum generated is not symmetrical is due to the combination of a very small input magnitude and the effects of static scaling when applied to a large fft. For a 2048-point FFT, intermediate results will be divided by 2 eleven times (log2(2048)), reducing your signal-to-noise ratio considerably. When computing the spectrum, the resultant noise will have a significant impact.

If you change your example, using the cfft_fr32 function instead and set the scaling mode to 2 (dynamic scaling) or 3 (no scaling), you will find that the resultant spectrum is symmetrical as expected.

In general, if using static or dynamic scaling one should ensure that the maximum input value for a Fourier transform is close to +/-0.25 in order to have the maximum dynamic range of the fixed point type at one's disposal (without the risk of overflow).