This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DSPLIB : DSPF_sp_fftSPxSP issue

Hi

I think I'm having unexpectd result using DSPF_sp_fftSPxSP  (dsplib_c66x_3_4_0_0)

Pseudo code:

#define N_FFT 64

#pragma DATA_ALIGN(inputFFT, 8);
float inputFFT [2*N_FFT];

#pragma DATA_ALIGN(outputFFT, 8);
float outputFFT [2*N_FFT];


for (i = 0; i < N_FFT; i++)
{
inputFFT[2*i] = sinWaveMag * (float)cos(sinWaveIncFreq*i);
inputFFT[2*i + 1] = 0.0;

}

DSPF_sp_fftSPxSP(N_FFT,inputFFT,w_sp,outputFFT,brev,4,0,N_FFT);

This is ok, I get the result as in the following figure (OK)

Second test:


I use a 16 samples input function, zero padding in the time domain by adding 64-16 = 48 zeros

Pseudo code

/* Clear the input floating point array */
for (i = 0; i < N_FFT; i++)

{

inputFFT[2*i] = (float)0.0;
inputFFT[2*i + 1] = (float)0.0;
}

for (i = 0; i < 16; i++)
{
inputFFT[2*i] = sinWaveMag * (float)cos(sinWaveIncFreq*i);
inputFFT[2*i + 1] = 0.0;

}

I get unexpected result, see following figure

The expected result (using another DFT function) is the following:


am i doing something wrong?

Thank you
Fabio

  • Hi Fabio,

    The RTOS team have been notified. Their feedback will be posted here.

    Best Regards,
    Yordan
  • Hi

    no feedback... please help

    Fabio
  • HI,
    As far as I know the fft works well and your pseudocode looks ok. Maybe the problem is in the twiddle w_sp. How do you declare the array and generate it?
  • Hi

    w_sp is declared as

    #pragma DATA_ALIGN(w_sp, 8);
    float w_sp [2*64];

    I generate it using the function :

    gen_twiddle_fft_sp(w_sp, 64);

    see code below

    void gen_twiddle_fft_sp (float *w, int n)
    {
    int i, j, k;
    double x_t, y_t, theta1, theta2, theta3;

    for (j = 1, k = 0; j <= n >> 2; j = j << 2)
    {
    for (i = 0; i < n >> 2; i += j)
    {
    theta1 = 2 * PI * i / n;
    x_t = cos (theta1);
    y_t = sin (theta1);
    w[k] = (float) x_t;
    w[k + 1] = (float) y_t;

    theta2 = 4 * PI * i / n;
    x_t = cos (theta2);
    y_t = sin (theta2);
    w[k + 2] = (float) x_t;
    w[k + 3] = (float) y_t;

    theta3 = 6 * PI * i / n;
    x_t = cos (theta3);
    y_t = sin (theta3);
    w[k + 4] = (float) x_t;
    w[k + 5] = (float) y_t;
    k += 6;
    }
    }
    }



    brev array is as follows

    unsigned char brev[64] = {
    0x0, 0x20, 0x10, 0x30, 0x8, 0x28, 0x18, 0x38,
    0x4, 0x24, 0x14, 0x34, 0xc, 0x2c, 0x1c, 0x3c,
    0x2, 0x22, 0x12, 0x32, 0xa, 0x2a, 0x1a, 0x3a,
    0x6, 0x26, 0x16, 0x36, 0xe, 0x2e, 0x1e, 0x3e,
    0x1, 0x21, 0x11, 0x31, 0x9, 0x29, 0x19, 0x39,
    0x5, 0x25, 0x15, 0x35, 0xd, 0x2d, 0x1d, 0x3d,
    0x3, 0x23, 0x13, 0x33, 0xb, 0x2b, 0x1b, 0x3b,
    0x7, 0x27, 0x17, 0x37, 0xf, 0x2f, 0x1f, 0x3f
    };

    Thank you

    Fabio
  • Hi,
    Your gen function is different then mine. Try to swap x_t with y_t:
    w[k] = (float) y_t;
    w[k + 1] = (float) y_t;
    .... and so on in position +2,+3 and +4,+5.
    Since I see the difference I give a try and with this version the results seems to be ok.
  • Sorry a mistake:
    w[k] = (float) y_t;
    w[k + 1] = (float) x_t; //not again y_t
  • Hi

    thank you, your gen function works fine

    By the way, I copied my function from TI example
    [INSTALL DIR]\dsplib_c66x_3_4_0_0\examples\fft_sp_ex\fft_example_sp.c

    Thank you

    Fabio
  • Hi,

    it seems to me the example works for big endian only. In previous version 3.1.0.0, in the examples there is an explicit gen_twiddle_fft32x32.c that invert the sin/cos order in case of little/big endian.

    The version I suggest to you is for little endian only.

    If you look at the implementation of the FFT, you can see that the fft also invert some operands depending on the endianess.

    The origin of the problem is the order of the operand used by the CPU for the assembler instruction that multiply complex number (4 mul x one instruction). Since image/real part order change depending on the endianess, the twiddle order shall also also..

    By the way, the brev array is not required by the C6678 implementation (you can pass 0), since it has a dedicated assembler instruction.
  • Thank you for all

    Fabio