SDKs

- iOS 13.0+
- Xcode 11.0+

Framework

- Accelerate

## Overview

Accelerate’s vDSP module provides functions to perform discrete and fast Fourier transforms (FFTs) on 1D vectors and 2D matrices containing complex numbers. If you want to perform a similar transform on a vector of real numbers, vDSP includes discrete cosine transforms (DCTs).

FFTs and DCTs decompose a signal into its frequency components (known as the *frequency domain* representation of the signal), and the inverse transform rebuilds a signal from the frequency components.

By zeroing low-amplitude data, such as noise, from the frequency domain data, you can reconstruct a signal, leaving only its dominant frequencies. Meaningful signals that you’re trying to isolate tend to have their energy packed at a few frequencies. Noise, however, has its energy more uniformly spread across the frequency spectrum (that’s what makes it noise). If you zero out low-amplitude frequency components, you can eliminate much of the noise from the spectrum.

This sample walks you through the steps for extracting a signal from noise:

Creating a signal from composite cosine waves and adding random noise to it

Performing a forward DCT on the signal

Zeroing the frequency domain data where the value is less than a specified threshold

Rebuilding the signal from the frequency domain data using an inverse DCT

### Generate the Test Signal

Build the test signal from a series of cosine waves, stored as 1024 samples in an array of single-precision values:

The signal function generates a sample at each data point:

The values generated by this code return a signal like the one in the image below:

Adding noise to the signal makes it unrecognizable, and it’s impossible to hear the original tones:

### Prepare the DCT Setups

Create setup objects that contain all the information required to perform the forward and inverse DCT operations. Creating these setup objects can be expensive, so do it only once—for example, when your app is starting—and reuse them.

The forward transform is a type II DCT:

The inverse transform is a type III DCT:

### Perform the DCT

Use the `transform(_:)`

function to perform the DCT. This function requires the array containing the source signal and returns the frequency domain data:

The following visualization of the frequency domain data shows the component cosine parts. The `cos(phase * 1) * 1`

component is on the left, and `cos(phase * 16) * 1`

is on the right:

The frequency domain visualization of the noisy signal shows the dominant frequencies with the noise spread evenly throughout the frequency range. The sample zeroes the low-amplitude data to generate the noise-free signal.

### Apply a Threshold to the Amplitude Data

Remove the noise from the signal by zeroing all values in the frequency domain data that are below a specified threshold.

The `threshold(_:`

function sets all values in the `forward`

array that fall below the threshold to 0:

### Recreate the Signal

Use an inverse DCT to generate a new signal using the cleaned-up frequency domain data:

Now scale the inverse DCT. The scaling factor for the forward transform is 2, and the scaling factor for the inverse transform is the number of samples (in this case, 1024). Use `divide(_:`

to divide the inverse DCT result by `count / 2`

to return a signal with the correct amplitude.