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.

Trouble in Computing FFT Using DSP_APP.c Project

Expert 2370 points
Other Parts Discussed in Thread: CCSTUDIO

Hi Guys,

I have been trying to compute FFT of real time signal using dsk_app.c project given in C6713 example codes. As you know, in dsk_app.c project, input is taken from LINE IN jack and output is throughing using LINE OUT jack with out any change. I am trying to compute FFT before outputtiing the samples. I inputed a simple sine wave of 1 Khz with 1 Vp_p but I am not getting the peak at 1 Khz.. I'm basically converting both the ping and pong buffers into real and imaginary parts and then using fft on those buffers.

I processed the sampled data in void processBuffer(void) function in the following way.

float x1[BUFFSIZE];  // BUFFSIZE = 1024;
float y1[BUFFSIZE];

void processBuffer(void)
{
    Uint32 pingPong;
    Int16 i;

    /* Get contents of mailbox posted by edmaHwi */
    pingPong =  SWI_getmbox();

    /* Copy data from transmit to receive, could process audio here */
    if (pingPong == PING) {

    for (i = 0 ; i < BUFFSIZE ; i++)    // Converting values into real and imm part for FFT

    {
     samples[i].real= (float)gBufferRcvPing[i]; // changing RcvPing from int16 type to float type for FFT calculation
    }

       for (i = 0 ; i < BUFFSIZE ; i++)
     samples[i].imag = 0.0;        //imag components = 0

     FFT(samples,BUFFSIZE);              //call function FFT.c

   for (i = 0 ; i < BUFFSIZE ; i++)    //compute magnitude
    {
     x1[i] = sqrt(samples[i].real*samples[i].real  + samples[i].imag*samples[i].imag);
    gBufferXmtPing[i] = (Int16)x1[i]; // chaning back from float type to int16 type before transmitting
   
    }

       /* Copy receive PING buffer to transmit PING buffer */
        copyData(gBufferRcvPing, gBufferXmtPing, BUFFSIZE);
       
    } else {

    for (i = 0 ; i < BUFFSIZE ; i++)    // Converting values into real and imm part for FFT

    {
     samples[i].real= (float)gBufferRcvPong[i]; // chaning back from float type to int16 type before transmitting
    }

       for (i = 0 ; i < BUFFSIZE ; i++)
     samples[i].imag = 0.0;        //imag components = 0

     FFT(samples,BUFFSIZE);              //call function FFT.c

   for (i = 0 ; i < BUFFSIZE ; i++)    //compute magnitude
    {
     y1[i] = sqrt(samples[i].real*samples[i].real + samples[i].imag*samples[i].imag);
    gBufferXmtPong[i] = (Int16)y1[i]; // chaning back from float type to int16 type before transmitting
    }
        /* Copy receive PONG buffer to transmit PONG buffer */
       copyData(gBufferRcvPong, gBufferXmtPong, BUFFSIZE);
      
    }
}

Can any one please explain me where I am missing some thing or what is wrong ?

Looking forward for your kind help.

Thanks and Regards.

  • Start with the "sanity check" debug steps, and then move on from there.

    1. Set a breakpoint at the top of processBuffer(), for example at the "if" statement.
    2. Look at your input buffer in a memory window. Does it look like a 1KHz sine wave?
    3. Run up to the FFT call before it executes.
    4. Look at your samples buffer real part in a memory window. Does it look like a 1KHz sine wave?
    5. Step over the FFT call so it executes.
    6. Look at your samples buffer real and imaginary parts in a memory window. Do they look like a 1KHz FFT?
    7. Run up to the copyData call before it executes.
    8. Look at your y1 magnitude buffer in a memory window.Does it  look like what you expect?
    9. Look at your Xmt buffer in a memory window.Does it  look like what you expect, i.e. y1?
    10. Step over the copyData call so it executes.
    11. Look at your Xmt buffer in a memory window.Does it  look like what you expect?

    If you do these steps, you will see everything that the program is doing. You have to understand what the data is supposed to look like in each of these steps to figure out what you are doing wrong, if anything. My guess is you have at least one logic error and at least one C programming error.

  • Hi Randy,

    I did check all the steps and realized that program is computing FFT pretty fine. However, I changed two lines in the code in the following way.

    For PING Buffer:

    gBufferXmtPing[i] = (Int16)x1[i] has changed to gBufferRcvPing[i] = (Int16)x1[i];

    CopyData() function is transferring contents of gBufferRcvPing to gBufferXmtPing inorder to output them using AIC23, if I assign x1 value to gBufferXmtPing it replaces the FFT magnitude with new received samples in gBufferRcvPing which is wrong approach. Same thing has done for PONG Buffer. I did this according to my understanding, correct me if I am wrong.

    You can see the difference between the plots of x1 and gBufferRcvPing (after changing x1 from float to Int16). It dramatically changes the output just by converting floating point into fixed point.

    Plot of x1:

    http://tinypic.com/r/206htub/3

    Just click on the image get bigger image.

    Plot of gBufferRcvPing:

    http://tinypic.com/r/2nrmzad/3

    I am still unable to verify wheather that FFT is being computed correctly. Fs = 8000 and no. of FFT points are 1024 gives Frequency Resolution of 7.8125 Hz, FFT plot should contain a peak at 128th samples (7.8125*128 = 1 KHz) but there isn't any peak at such sample.

    I am using FFT function given in Ruplh Chassaing's book.

    FFT.C

    #define BUFFSIZE 1024                //# of points for FFT
    typedef struct {float real,imag;} COMPLEX;
    extern COMPLEX w[BUFFSIZE];               //twiddle constants stored in w

    void FFT(COMPLEX *Y, int N)      //input sample array, # of points    
    {
     COMPLEX temp1,temp2;             //temporary storage variables         
     int i,j,k;                       //loop counter variables              
     int upper_leg, lower_leg;           //index of upper/lower butterfly leg  
     int leg_diff;                    //difference between upper/lower leg  
     int num_stages = 0;              //number of FFT stages (iterations)
     int index, step;                 //index/step through twiddle constant
     i = 1;                           //log(base2) of N points= # of stages 
     do
      {
       num_stages +=1;
       i = i*2;
      }while (i!=N);
     leg_diff = N/2;                      //difference between upper&lower legs
     step = (BUFFSIZE*2)/N;       //step between values in twiddle.h             
     for (i = 0;i < num_stages; i++)  //for N-point FFT                
      {
       index = 0;
       for (j = 0; j < leg_diff; j++)
        {
         for (upper_leg = j; upper_leg < N; upper_leg += (2*leg_diff))
          {  
           lower_leg = upper_leg+leg_diff;
         temp1.real = (Y[upper_leg]).real + (Y[lower_leg]).real;
           temp1.imag = (Y[upper_leg]).imag + (Y[lower_leg]).imag;
           temp2.real = (Y[upper_leg]).real - (Y[lower_leg]).real;
           temp2.imag = (Y[upper_leg]).imag - (Y[lower_leg]).imag;
           (Y[lower_leg]).real = temp2.real*(w[index]).real
                        -temp2.imag*(w[index]).imag;
           (Y[lower_leg]).imag = temp2.real*(w[index]).imag
                        +temp2.imag*(w[index]).real;
           (Y[upper_leg]).real = temp1.real;
           (Y[upper_leg]).imag = temp1.imag;
          }
       index += step;
        }
         leg_diff = leg_diff/2;
         step *= 2;
          }
           j = 0;
           for (i = 1; i < (N-1); i++)     //bit reversal for resequencing data
          {
         k = N/2;
         while (k <= j)
          {
           j = j - k;
           k = k/2;
          }
         j = j + k;
         if (i<j)
          {
           temp1.real = (Y[j]).real;
           temp1.imag = (Y[j]).imag;
           (Y[j]).real = (Y[i]).real;
           (Y[j]).imag = (Y[i]).imag;
           (Y[i]).real = temp1.real;
           (Y[i]).imag = temp1.imag;
          }
        }
       return;
    }

    Can you please help me debugging this program OR help me verifying the result.

    Thanks for your valuable time.

     

     

  • If your input data to the FFT function looks correct and the output data from your FFT function does not look correct, where should your debug effort be focused next?

    Have you tried to use one of the FFT functions from another source, such as the DSPLIB functions that are available from TI?

    Are you sure your input data is stored correctly to meet the requirements stated by Chassaing? Are you interpreting the output data correctly as specified by Chassaing?

    I have seen other references to Chassaing on the forum. Have you searched for other posted threads that may have also used this same algorithm?

    Looking at the plot of x1 and comparing the values shown to what you have in the gBufferRcvPing plot, what would you expect the values in the gBufferRcvPing plot to look like? What should be the largest values shown in that plot? Why?

  • Hi Randy,

    I tried to modify dsk_app example using Radix-2 FFT example given by TI (DSPLIB) inorder to verify the FFT result but I am getting following errors of linking while compiling the project.

    undefined                        first referenced
     symbol                              in file
    ---------                        ----------------
    _DSPF_sp_bitrev_cplx             C:\CCStudio_v3.1\MyProjects\dsk_app\Debug\fft_r2.obj
    _DSPF_sp_cfftr2_dit              C:\CCStudio_v3.1\MyProjects\dsk_app\Debug\fft_r2.obj
    >>   error: symbol referencing errors - './Debug/dsk_app.out' not built

    >> Compilation failure

    Build Complete,
    2 Errors, 0 Warnings, 0 Remarks.

    Both DSPF_sp_bitrev_cplx and DSPF_sp_cfftr2_dit are placed in the directory defined in Preprocessor as .;$(Install_dir)\c6000\dsk6713\include.

    However, when I look at DSP_sp_bitrev_cplx.h and DSPF_sp_cfftr2_dit.h files, every thing is commented except these lines.

    #ifndef DSPF_SP_CFFTR2_DIT_ASM_H_
    #define DSPF_SP_CFFTR2_DIT_ASM_H_ 1

    void DSPF_sp_cfftr2_dit(float     * x, float * w, int n);

    #endif

    and

    #ifndef DSPF_SP_BITREV_CPLX_ASM_H_
    #define DSPF_SP_BITREV_CPLX_ASM_H_ 1

    void DSPF_sp_bitrev_cplx(double     * x, short * index, int n);

    #endif

    I don't know whats wrong and how to use them, please help me out.

    Looking forward for your quick response.

    Regards.


  • If you look a little earlier in your compiler output messages, you will see that the errors above come from the linker step and not from the compiler. These errors are because the actual functions are not being found by the linker steps.

    You can reference the C Compiler User's Guide and the Assembly Language Tools User's Guide for information on linking from libraries. What you need to do is to link in the DSPLIB library to get the actual object code for these functions.

  • Thanks Rand for your kind help. I managed to solve the problem.