NXP has most kindly provided a free assembly coded DSP library for its users. I needed to extract the fundamental frequency of an audio signal and with this library, the job got over in 5 minutes.

Download the the latest code base and extract the DSP library to it. Radix-4 FFT functions for 64, 256, 1024, and 4096 points are available. Floating point arithmetic is not used. So, this library should be quite fast. Each real and imaginary number is a signed 16-bit number. And because of this, the accuracy suffers a bit. Even if you give a real-only input sequence, don't expect a perfectly mirrored DFT. Small discrepancies of +/- 5 might be there. And another caveat. The FFT functions, probably in order to prevent overflow, give 1/N times the DFT and not the unscaled DFT.

For example,

#include "LPC17xx.h"

#include "delay.h"

#include "cr_dsplib.h"

#include "usbserial.h"

int main()

{

usbSerialInit();

LPC_GPIO1->FIODIR |= 1 << 29; // P1.29 connected to LED

short int input[2048]; // 1024 real + 1024 imaginary. Input signal

short int dft[2048]; // DFT of the input sequence

int i;

for(i=0;i<1024;i++)

{

input[2*i] = 589; // constant DC signal ( real only ).

input[2*i + 1] = 0; // make imaginary values of input 0

}

vF_dspl_fftR4b16N1024(dft,input); // compute DFT

while(1)

{

VCOM_printf("DFT of the signal is : \n\r");

for(i=0;i<2048;i++)

{

VCOM_printf("%d , ",dft[i]);

}

VCOM_printf("\n\r\n\rDFT , X(0) = %d\n\r\n\r",dft[0]);

LPC_GPIO1->FIOPIN ^= 1 << 29; // Toggle P1.29

_delay_ms(1000); // wait for approx 1 sec

}

return 0;

}

Screen dump

DFT , X(0) = 588

If modest precision is acceptable, then this a very decent library. Here is the compiled code.

Download the the latest code base and extract the DSP library to it. Radix-4 FFT functions for 64, 256, 1024, and 4096 points are available. Floating point arithmetic is not used. So, this library should be quite fast. Each real and imaginary number is a signed 16-bit number. And because of this, the accuracy suffers a bit. Even if you give a real-only input sequence, don't expect a perfectly mirrored DFT. Small discrepancies of +/- 5 might be there. And another caveat. The FFT functions, probably in order to prevent overflow, give 1/N times the DFT and not the unscaled DFT.

For example,

#include "LPC17xx.h"

#include "delay.h"

#include "cr_dsplib.h"

#include "usbserial.h"

int main()

{

usbSerialInit();

LPC_GPIO1->FIODIR |= 1 << 29; // P1.29 connected to LED

short int input[2048]; // 1024 real + 1024 imaginary. Input signal

short int dft[2048]; // DFT of the input sequence

int i;

for(i=0;i<1024;i++)

{

input[2*i] = 589; // constant DC signal ( real only ).

input[2*i + 1] = 0; // make imaginary values of input 0

}

vF_dspl_fftR4b16N1024(dft,input); // compute DFT

while(1)

{

VCOM_printf("DFT of the signal is : \n\r");

for(i=0;i<2048;i++)

{

VCOM_printf("%d , ",dft[i]);

}

VCOM_printf("\n\r\n\rDFT , X(0) = %d\n\r\n\r",dft[0]);

LPC_GPIO1->FIOPIN ^= 1 << 29; // Toggle P1.29

_delay_ms(1000); // wait for approx 1 sec

}

return 0;

}

Screen dump

DFT of the signal is :

588 , 0 , 0 , 0 , -4 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -4 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -4 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -4 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -4 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -4 , -1 , 0 , 0 , 0 , 0 , 0 , 0

588 , 0 , 0 , 0 , -4 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -4 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -4 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -4 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -4 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -4 , -1 , 0 , 0 , 0 , 0 , 0 , 0

.....(many more points like this) and finally

DFT , X(0) = 588

If modest precision is acceptable, then this a very decent library. Here is the compiled code.

## No comments:

## Post a Comment