1
\$\begingroup\$

I wrote a simple playback audio application (you speak on the mic, it plays on the speakers, just to test), it works. However when I added an FFT + inverse FFT, it doesn't, I only hear noise whitout reaction to when I speak on the mic.

Please, do anyone see an error ?

#include<ADCChannelDrv.h>
#include<OCPWMDrv.h>
#include<sask.h>
#include<ex_sask_led.h>
#include<ex_sask_generic.h>
#include<dsp.h>


int AdcBuffer[ ADC_CHANNEL_DMA_BUFSIZE ] __attribute__((space(dma)));
int DacBuffer[ OCPWM_DMA_BUFSIZE ] __attribute__((space(dma)));

int main(void) {
ex_sask_init();

fractcomplex Frame[ 128 ];
fractional Output[ 128 ];
fractcomplex twiddleFactors[128/2];


/* FFT config */
int i = 0;
fractional *p_real;
fractcomplex *p_cmpx;

TwidFactorInit (7, &twiddleFactors[0], 0);  /* We need to do this only once at start-up */






/* Instantiate the drivers  */
ADCChannelHandle adcChannelHandle;
OCPWMHandle     ocPWMHandle;

/* Create the driver handles    */
ADCChannelHandle *MyADCHandle   = &adcChannelHandle;
OCPWMHandle     *MyDACHandle        = &ocPWMHandle;

ADCChannelInit (MyADCHandle, AdcBuffer);
OCPWMInit (MyDACHandle, DacBuffer);
ADCChannelStart(MyADCHandle);
OCPWMStart(MyDACHandle);

while (1) {
while (ADCChannelIsBusy(MyADCHandle));
ADCChannelRead  (MyADCHandle, (fractional*)Frame, ADC_BUFFER_SIZE);

p_real = &Frame[0].real ;
p_cmpx = &Frame[0] ;


for ( i = 0; i < 128; i++ )/* The FFT function requires input data */
{                   /* to be in the fractional fixed-point range [-0.5, +0.5]*/
        *p_real = *p_real >>1 ;     /* So, we shift all data samples by 1 bit to the right. */
        *p_real++;          /* Should you desire to optimize this process, perform */
}                   /* data scaling when first obtaining the time samples */
                        /* Or within the BitReverseComplex function source code */

p_real = &Frame[(128/2)-1].real ;   /* Set up pointers to convert real array */
p_cmpx = &Frame[128-1] ; /* to a complex array. The input array initially has all */
                        /* the real input samples followed by a series of zeros */


for ( i = 128; i > 0; i-- ) /* Convert the Real input sample array */
{                   /* to a Complex input sample array  */
        (*p_cmpx).real = (*p_real--);   /* We will simpy zero out the imaginary  */
        (*p_cmpx--).imag = 0x0000;  /* part of each data sample */
}





FFTComplexIP (7, &Frame[0], &twiddleFactors[0], COEFFS_IN_DATA);
IFFTComplexIP (7, &Frame[0], &twiddleFactors[0], COEFFS_IN_DATA);


for ( i = 0; i < 128; i++ )  /*Convert back */
{
        Output[i]=Frame[i].real;
}


OCPWMWrite  (MyDACHandle,Output, OCPWM_FRAME_SIZE);

}
return 0;
}
\$\endgroup\$
5
  • \$\begingroup\$ Important : When I delete the two lines : FFTComplexIP (7, &Frame[0], &twiddleFactors[0], COEFFS_IN_DATA); IFFTComplexIP (7, &Frame[0], &twiddleFactors[0], COEFFS_IN_DATA); It works perfectly, so please where is the error in these two lines ? \$\endgroup\$
    – user40200
    Commented Apr 11, 2014 at 7:20
  • \$\begingroup\$ Those two lines call your FFT and IFFT, do they not? \$\endgroup\$ Commented Apr 11, 2014 at 7:49
  • \$\begingroup\$ Also: (1) you should be continually calling those in a loop, (2) a 128-point FFT will probably not give you very good fidelity, and (3) are you applying a window function? You might want to spend a couple hours reading up on some DSP review, it might help. \$\endgroup\$ Commented Apr 11, 2014 at 7:54
  • \$\begingroup\$ This is what they should do, but there's no audio. \$\endgroup\$
    – user40200
    Commented Apr 11, 2014 at 7:55
  • \$\begingroup\$ for (1) They are already in the infinite loop (2) I will try with a higher size, but I thought I will receive the same aray as it was before passing it to the FFT so size don't matter (3) No window, I just want to get my signal before passing it to the FFT \$\endgroup\$
    – user40200
    Commented Apr 11, 2014 at 7:57

1 Answer 1

1
\$\begingroup\$

Perhaps it's an outdated answer. Anyway, the issue with your code is that FFTComplexIP store the result in the bitreversed order. You must add the

BitReverseComplex(7, &Frame[0]);

between the FFT and the iFFT function calls.

The following is written in the dsPIC Language Tools Library:

Remarks: N must be an integer power of 2. The elements in source complex vector are expected in natural order. The resulting transform is stored in bit reverse order.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.