Use 1D fast Fourier transform to compute the frequency components of a signal.
Accelerate’s vDSP module provides functions to perform 1D fast Fourier transforms (FFTs) on vectors of data, such as audio signals. The following shows an input signal (at left), and its frequency domain equivalent (at right) after transforming the signal with a forward FFT.
You can inspect the frequency-domain data of a forward FFT to compute the individual sine wave components of a composite wave. The technique described here is applicable in many digital signal processing applications; for example, finding the dominant frequencies in a dual-tone multi-frequency (DTMF) signal or removing noise from a signal.
You'll learn how to create a composite sine wave, perform a forward FFT, inspect the result to find its components, and perfom an inverse FFT to recreate the original signal.
Create the Composite Signal
Start by creating an array to generate a signal. You’ll need to populate an array of single-precision values using the sums of a series of sine waves. You define the frequencies as the number of cycles per
n. The highest measureable frequency, known as the Nyquist frequency, is the element with index
n/2, which is
1023 in a zero-based array that contains
The following creates the array, called
signal, that contains 10 component sine waves:
The following image is a visualization of composite sine waves in
Create the FFT Setup
Create a setup object that contains a precalculated weights array of complex exponentials required to perform the FFT operations. The vaues in the weights array simplify the FFT calculation. Creating this setup object can be expensive, so do it only once; for example, when starting your app. After creating the setup object, you can reuse it later, as needed.
The following code creates a setup object suitable for performing forward and inverse 1D FFTs on a signal containing
You can use this setup object for similarly sized smaller FFTs. However, using a weights array built for an FFT that processes a large number of elements can degrade performance for an FFT that processes a significantly smaller number of elements.
Create the Source and Destination Arrays for the Forward FFT
The FFT operates on complex numbers, that is numbers that contain a real part and an imaginary part. Create two arrays—one for the real parts and one for the imaginary parts—for the input and output to the FFT operation:
Because each complex value stores two real values, the length of teach array is half that of
Perform the Forward FFT
DSPSplit structures to pass pointers to the real and imaginary parts arrays to the FFT transform function. Use withUnsafeMutableBufferPointer(_:) to pass the output arrays to
To perform the forward FFT:
DSPSplitstructure to store
signalrepresented as complex numbers.
convert(interleavedto convert the real values in
Complex Vector: to Split Complex Vector:)
signalto complex numbers. The conversion stores the even values in
signalas the real components in
forward, and the odd values in
signalas the imaginary components in
DSPSplitstructure with pointers to
forwardto receive the FFT result.
Perform the forward FFT.
The following code shows how to perform the forward FFT using the steps described above.
forward contains the DC components of the forward FFT, and
forward contains the Nyquist components of the forward FFT.
Compute Component Frequencies in Frequency Domain
The Nyquist components of the forward FFT contain a series of high-magnitude items, rendered as vertical lines in the graph below:
These high-magnitude items correspond exactly to the frequencies you specified in the
Recreate the Original Signal
Use an inverse FFT to recreate a signal in the time domain, using the frequency-domain data returned by the forward FFT.
To perform the forward FFT:
Create the source of the inverse FFT, with pointers to
DSPSplitstructure to receive the FFT result.
Perform the inverse FFT.
Return an array of real values from the FFT result. Because the forward transform has a scaling factor of
2and the inverse transform has a scaling factor of the number of items, divide each result by
2 * n:
recreated is approximately equal to