FFT Library

Complex Fast Fourier Transform (CFFT) and Complex Inverse Fast Fourier Transform (CIFFT) is an efficient algorithm to compute Discrete Fourier Transform (DFT) and Inverse Discrete Fourier Transform (IDFT).
Computational complexity of CFFT reduces drastically when compared to DFT.

This library implements CFFT/CIFFT for Q15 data type. The functions operates on in-place buffer which uses same buffer for input and output. Complex input is stored in input buffer in an interleaved fashion.

The functions operate on blocks of input and output data and each call to the function processes 2*fftLen samples through the transform. pSrc points to In-place arrays containing 2*fftLen values.
The pSrc points to the array of in-place buffer of size 2*fftLen and inputs and outputs are stored in an interleaved fashion as shown below :

 {real[0], imag[0], real[1], imag[1],..}

Internally, the function utilize a radix-4 decimation in frequency algorithm and the size of the FFT supported are of the lengths [16, 64, 256, 1024, 4096].

Complex Fast Fourier Transform

Input real and imaginary data

x(n) = xa + j * ya
x(n+N/4 ) = xb + j * yb
x(n+N/2 ) = xc + j * yc
x(n+3N 4) = xd + j * yd

where N is length of FFT.

Output real and imaginary data

X(4r) = xa'+ j * ya'
X(4r+1) = xb'+ j * yb'
X(4r+2) = xc'+ j * yc'
X(4r+3) = xd'+ j * yd'

Twiddle factors for radix-4 FFT

Wn =  co1 + j * (- si1)   
W2n = co2 + j * (- si2)   
W3n = co3 + j * (- si3)

Output from Radix-4 CFFT results in digit reversal order. Interchange middle two branches of every butterfly results in bit reversed output./p>

Butterfly CFFT equations

xa' = xa + xb + xc + xd   
ya' = ya + yb + yc + yd   
xc' = (xa+yb-xc-yd)* co1 + (ya-xb-yc+xd)* (si1)   
yc' = (ya-xb-yc+xd)* co1 - (xa+yb-xc-yd)* (si1)   
xb' = (xa-xb+xc-xd)* co2 + (ya-yb+yc-yd)* (si2)   
yb' = (ya-yb+yc-yd)* co2 - (xa-xb+xc-xd)* (si2)   
xd' = (xa-yb-xc+yd)* co3 + (ya+xb-yc-xd)* (si3)   
yd' = (ya+xb-yc-xd)* co3 - (xa-yb-xc+yd)* (si3)

CIFFT uses same twiddle factor table as CFFT with modifications in the design equation as shown below.

Modified Butterfly CIFFT equations

xa' = xa + xb + xc + xd   
ya' = ya + yb + yc + yd   
xc' = (xa-yb-xc+yd)* co1 - (ya+xb-yc-xd)* (si1)   
yc' = (ya+xb-yc-xd)* co1 + (xa-yb-xc+yd)* (si1)   
xb' = (xa-xb+xc-xd)* co2 - (ya-yb+yc-yd)* (si2)   
yb' = (ya-yb+yc-yd)* co2 + (xa-xb+xc-xd)* (si2)   
xd' = (xa+yb-xc-yd)* co3 - (ya-xb-yc+xd)* (si3)   
yd' = (ya-xb-yc+xd)* co3 + (xa+yb-xc-yd)* (si3)   

Separate instance structure must be defined for each instance, but the twiddle factors and bit reversal tables can be reused.

Initialization Function

The initialization function performs the following operations :

Use of the initialization function is optional. However, if the initialization function is used, then the instance structure cannot be placed into a const data section.
To place an instance structure into a const data section, the instance structure must be manually initialized as follows :

TFFT_Radix4_Instance fftInstance = {fftLen, ifftFlag, bitReverseFlag, pTwiddle, pBitRevTable, twidCoefModifier, bitRevFactor}; 

where :

Pseudo code for generation of bit reversal table is :

for(l = 1; l <= N/4; l++) {
  for(i = 0; i < logN2; i++) {
    a[i] = l & (1 << i);   
  }   
  for(j = 0; j < logN2; j++){   
    if (a[j] != 0)   
      y[l] += (1 << ((logN2 - 1) - j));   
  }   
  y[l] = y[l] >> 1;   
}

where N = 1024, log2N = 10 and N is the maximum FFT size supported.

Pseudo code for generation of Q15 twiddle factors :

for(i = 0; i < N; i++) {   
  twiddleCoefQ15[2*i] = cos(i * 2*PI/(float)N);   
  twiddleCoefQ15[2*i+1] = sin(i * 2*PI/(float)N);   
}    

where cos and sin are in interleaved fashion.

Library Routines

FFT_Radix4_Init

Prototype

char FFT_Radix4_Init(TFFT_Radix4_Instance *fftInstance, uint16_t fftLen, uint8_t ifftFlag, uint8_t bitReverseFlag);

Description

Function initializes FFT transformation.

Parameters
  • fftInstance: points to an instance of the Q15 CFFT/CIFFT structure.
  • fftLen: length of the FFT.
  • ifftFlag: flag that selects forward (ifftFlag = 0) or inverse (ifftFlag = 1) transform.
  • bitReverseflag: flag that enables or disables bit reversal of output.
Returns
  • 0 - if initialization is successful.
  • 1 - if fftLen is not a supported value.
Requires

Nothing.

Example
char status;
TFFT_Radix4_Instance cfft_instance;

// Initialize the CFFT function to compute 64 point FFT
status = FFT_Radix4_Init(&cfft_instance, 64, 0, 1);
Notes

None.

FFT_Radix4

Prototype

void FFT_Radix4(const TFFT_Radix4_Instance *fftInstance, q15_t *pSrc);

Description

Function applies FFT transformation.

Parameters
  • fftInstance: points to an instance of the Q15 CFFT/CIFFT structure.
  • pSrc: points to the complex data buffer. Processing occurs in-place.
Returns

Nothing.

Requires

Nothing.

Example
#define FFT_BLOCKSIZE 128

q15_t Ak[FFT_BLOCKSIZE];             // q15 input A
TFFT_Radix4_Instance cfft_instance;
TFFT_Radix4_Instance *cfft_instance_ptr = (TFFT_Radix4_Instance*) &cfft_instance;

// Transform input a[n] from time domain to frequency domain A[k]
FFT_Radix4(cfft_instance_ptr, Ak);
Notes

None.

Input and output formats

Internally input is downscaled by 2 for every stage to avoid saturations inside CFFT/CIFFT process. Hence the output format is different for different FFT sizes.
The input and output formats for different FFT sizes and number of bits to upscale are mentioned in the tables below for CFFT and CIFFT :

Input and Output Formats for Q15 CFFT

CFFT Size Input format Output format Number of bits to upscale
16 1.15 5.11 4
64 1.15 7.9 6
256 1.15 9.7 8
1024 1.15 11.5 10
4096 1.15 13.3 12

Input and Output Formats for Q15 CIFFT

CIFFT Size Input format Output format Number of bits to upscale
16 1.15 5.11 0
64 1.15 7.9 0
256 1.15 9.7 0
1024 1.15 11.5 0
4096 1.15 13.3 0
Copyright (c) 2002-2019 mikroElektronika. All rights reserved.
What do you think about this topic ? Send us feedback!
Want more examples and libraries? 
Find them on LibStock - A place for the code