How to FFT with NXP’s DSP library

What a mouthful of acronyms in that title! This is going to be a very nerdy post.

Today I have been having fun processing audio with the NXP1758 Arm Cortex-M3 microprocessor. It’s really quite easy with the DSP library from NXP. Above is a screen shot of it showing the spectrum of a single note from a synthesizer.

The DSP Library

To get the library, download AN10913 from NXP’s website. There is no source code for the FFT, you need to link the static library NXP_M3_DSPLibFft.a into your project. The documentation doesn’t say much about the FFT function which is why I’m writing this blog post. Here’s some things they don’t mention:

  1. The FFT functions use complex numbers for both the input and output data
  2. It won’t do an in-place FFT – you need two separate data buffers
  3. The number of output data points is always equal to the number of input data points

Processing the data

I’m doing a 1024 point FFT so I’ll need a 4096 byte input buffer and a 4096 byte output buffer for a total RAM usage of 8k. The buffers are twice as large as you’d think because they need to store complex numbers. Each complex number consists of two 16-bit signed values, the first one being the real component and the second one the imaginary component which can be safely set to zero for audio data.

Interpreting the result

The result data contains a bunch of complex numbers which represent the amplitude and phase of each “frequency bin” in the spectrum. A frequency bin is a slice out of the total spectrum; being a digital process, FFT cannot deliver a continuous spectrum.

The bandwidth of each frequency bin is the sampling frequency divided by the number of FFT points. So for example if you are sampling at 22050Hz and using 1024 FFT points, each bin will cover a 21.53Hz slice of the total spectrum. Each bin has a centre frequency of (N*SAMPLERATE)/FFTSIZE where N is the bin number. So in my example above, bin 1 will be centred at 21.53Hz, bin 2 will be centred at 43.06Hz and so on. Bin 0 is centred at 0Hz and represents the DC component of the signal.

The results are complex numbers so you can work out not only the amplitude of each bin but also the phase. I am not interested in the phase so my example code below only computes the amplitude.

The Code

#include "dsp/cr_dsplib.h"

uint16_t fft_in[2048];
uint16_t fft_out[2048];
int16_t spectrum[512];

// Returns an array of 512 values containing the amplitude of each frequency
// bin from DC up to the sampling frequency / 2.
int16_t *processaudio(uint16_t audiobuffer)
int i;

// First copy the audio data to the real component of the FFT input buffer.
// Set the imaginary component to zero for all samples.
memset(fft_in, 0, sizeof(fft_in));
for(i = 0; i < 1024; i++)
fft_in[i*2] = audiobuffer[i];

// Now I can run the FFT.
vF_dspl_fftR4b16N1024(fft_out, fft_in);

// Convert the output data back into real numbers because I am not interested
// in the phase component.
// Also note that the second half of the FFT output mirrors the first half so it is
// only necessary to process 512 data points.
for(i = 0; i < 512; i++)
a = fft_out[i*2];
b = fft_out[i*2+1];
spectrum[i] = sqrt((a*a)+(b*b));

return spectrum;

6 thoughts on “How to FFT with NXP’s DSP library

  1. Adam Post author

    That totally depends on what development tools you are using. I use GNU tools and so I just add “-lNXP_M3_DSPLibFft” to my linker options. If you use a graphical IDE such as Keil or Eclipse, there will be something under the project options menu to add additional libraries to the project.

  2. sam

    in your opinion if i use external ADC and lpc1768 what is the max frequency that i can use fft function?

  3. Adam Post author

    Well I was using it on an LPC1768 with it’s own internal ADC. My project only needed to analyze frequencies up to 2.5kHz and it did that easily with plenty of CPU cycles left over for the application software.

    I don’t think it would make much difference whether you use an external ADC or not because the data still has to be copied into RAM.

    As for the maximum frequency, I haven’t tried it but I think you could probably go up to 15kHz, maybe more if you optimized the code a bit such as removing the square-root function or using the on-chip DMA to do some of the memory transfers.

    Let me know how you go with it.

  4. sam

    thank’s for your answer.
    i want to get fft from 2MHZ signal and it is not possible with internal ADC so i’m going to use AD9225 .
    is cortex m3 suitable for this work? is the speed of cpu enough?

  5. Adam Post author

    Isn’t this the same question you just asked?

    I haven’t pushed it to see how fast it will go but in my opinion 2MHz will be too much for this chip running this FFT library.

Comments are closed.