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