The Fourier transform and its reverse transform convert a signal from a time or space domain to a frequency domain and from the frequency domain to a time or space domain, respectively. These transforms are very important in electrical engineering, communication, geology, medicine and optics, and the list is endless. However, for speed, these transforms are optimised to run fast. This has led to many algorithms, amongst these being the fast Fourier transform (FFT) Cooley–Tukey algorithm (1965) [1], the prime‐factor FFT algorithm [2] and the split‐radix FFT algorithm [3].
This chapter will introduce a derivation of an FFT algorithm and show its implementation.
Any periodic signal represented by a function f(x) can be expressed by an infinite series of sines and cosines, as shown in Equation (18.1).
where:
The Fourier transform of the function f(x) can be expressed as shown in Equation (18.2), and the inverse Fourier transform is shown in Equation (18.3).
where:
The discrete Fourier transform (DFT) of a discrete‐time signal x(nT) is given by Equation (18.4).
where:
If we let , then Equation (18.4) can be rewritten as Equation (18.5).
where:
Therefore, for N samples of x, we have N frequencies (frequency bins) representing the signal, and each frequency bin can be calculated, as shown in Equation (18.5).
From Table 18.1, it is clear that the DFT requires N*N complex multiplications and (N − 1)*N complex additions.
Table 18.1 DFT calculation for every frequency bin
X(0) = x[0]WN0 + x[1]WN0*1 + … + x[N − 1]WN0*(N−1) |
X(1) = x[0]WN0 + x[1]WN1*1 + … + x[N − 1]WN1*(N−1) |
: |
X(k) = x[0]WN0 + x[1]WNk*1 + … + x[N − 1]WNk*(N−1) |
: |
X(N − 1) = x[0]WN0 + x[1]WN (N−1)*1 + … + x[N − 1]WN (N−1)(N−1) |
A large amount of work has been devoted to reducing the computation time of a DFT. This has led to efficient algorithms known as fast Fourier transforms. In this section, the algorithm known as Radix 2 FFT is developed.
By manipulating the twiddle factor W, as shown here and in Figure 18.1, Equation (18.5) can be rewritten as shown in Equation (18.6).
Replacing , x[2n] by x1[n] and , Equation (18.6) can be rewritten as shown in Equation (18.7).
This shows that an N‐point DFT can be divided into two ‐point DFTs, Y(k) and Z(k), operating on the even and odd samples, respectively.
By exploiting the symmetry and periodicity of the twiddle factors, as shown here and illustrated in Figure 18.1, pairs of DFTs can be grouped together, as they share the same twiddle factors and therefore will reduce the number of calculations; see Equations (18.7) and (18.8).
Using the periodicity, the pair of DFTs can be rewritten as shown in Equations (18.9) and (18.10):
Equations (18.9) and (18.10) can be rewritten as Equations (18.11) and (18.12).
where Y(k) and Z(k) can be considered as two DFTs. By using the same process as shown in this section, Y(k) and Z(k) can be expressed as shown in Equations (18.13) to (18.16).
The process continues until 2‐point DFTs are reached. This is known as the decimation in time (DIT) Radix 2 FFT, as illustrated in Figure 18.2.
Note that input data need to be out of order (e.g. 0, 4, 2, 6, 1, 5, 3, 7, for an 8‐point FFT), and therefore the original data have to be reordered. This can be done by using a bit reversal since, when the binary representation of an index is reversed, it will lead to the correct value; see Figure 18.3. Reordering the input data of Figure 18.2 will lead to the decimation in frequency (DIF). However, the reordering should be performed at the end of the FFT; see Figure 18.4.
To implement the FFT as illustrated in Figure 18.2, a few observations should be made:
To implement the inner loop (butterfly), let’s calculate the outputs A and B of the butterfly, as shown in Figure 18.6, and derive the C code.
Let’s simplify Equations A and B by assuming:
These will lead to:
This can be implemented in C language by the C code shown in Figure 18.7. The complete implementation will require the calculations of each butterfly in each block starting from Stage 1 to the last stage. These can be performed by three loops, as shown in Figure 18.8.
Files location:
In this laboratory experiment, a signal composed of two sinewaves is generated (this can be modified to add more sinewaves) and an FFT is performed on this signal, as shown in Figure 18.9.
Pause the program after running it for a few seconds. Explore the code for generating the sinewaves; see Figure 18.12. Watch the variable where the data are stored (buffer1[i] = sinegen() ) and open the graph window to display the data, as shown in Figure 18.13. Display the input data (as shown in Figure 18.15) by using buffer1 and the buffer property, as shown in Figures 18.13 and 18.14. Finally, display the FFT of the signal (as shown in Figure 18.18) by using the magg buffer and the buffer proprieties shown in Figures 18.16 and 18.17, respectively.
Files location:
In this laboratory session, the EDMA copies data from a buffer (SrcPing) to another buffer DstPing. When the copy is completed, a callback function (cbckFunc) is called to instruct the EDMA to start another transfer of data from SrcPing to a DstPong buffer, and do an FFT, calculate the magnitude and extract the highest frequency bins (see Figure 18.19).
In this chapter, the FFT Radix 2 has been studied, and a detailed implementation in C language has been provided. The implementation also includes using the EDMA to increase the performance.
3.17.77.144