Unlocking the Power of Fast Fourier Transform (FFT) (with Python code)

Binayak Bhandari, PhD
5 min readDec 13, 2023

--

In this article, we will explore the Fast Fourier Transform (FFT) and its practical application in engineering using real sound data from CNC Machining (20-second clip). But before diving into the FFT, let us grasp the fundamental concepts of signals and waves.

Understanding Signals and Waves

Waves are essentially a discrete version of signals. Time and frequency domains are two different ways of looking at a signal. Once you have a wave, you can process it in either time-domain or frequency-domain or go back and forth between the two. The time domain looks at the signal with respect to information that varies over time, while the frequency domain dissects the signal’s frequency components. Visualize these domains in action through the GIF below.

Simple GIF illustrating signals in time and frequency domains

The Magic of Fourier Transform

The Fourier Transform is a mathematical procedure that transforms a function from the time domain to the frequency domain. It essentially decomposes any function into a sum of sinusoidal basis functions. This transformation works seamlessly with continuous and periodic functions.

The formula for the continuous Fourier Transform is:

Where x(t) is continuous and integrable function.

In the animation shows above, figure (a) is an original signal, which can be decomposed into sum of two sinusoidal waves as shown in (b) and (c ).

When we apply FFT to a waveform, it reveals its spectrum by decomposing the waveform into its constituent frequency components. When the function and its Fourier transform are replaced with discrete counterparts, it is called the discrete Fourier transform (DFT). DFT is the mathematical foundation of FFT that works with discrete data and provides insights into the frequency domain of a signal. Many practicing engineers use Fast Fourier Transform in their analysis, but it is the algorithm which performs DFT very fast hence the name Fast Fourier Transform or FFT in short.

Additionally, to create a spectrogram, we break the waveform into smaller segments by utilizing the Short-Time Fourier Transform (STFT). FFT is applied to each segment to observe how the frequency contents evolve over time. This process allows us to visualize changes in the signal’s frequency components over its duration.

Exploring Time Domain

To illustrate the concept further, let us consider an example from my CNC machining experiment. You can find the original audio file here. The plot below depicts normalized sound pressure values over time, with amplitude on the y-axis and time on the x-axis.

Time-domain plot of CNC machining experiment

Shifting to Frequency Domain

Now, let us perform the Fast Fourier Transform (FFT) of the audio signal and observe how it transforms into the frequency domain.

Plot of sound waves in frequency domain

In the frequency domain plot, obtained through FFT, we observe a spectrum of frequencies. These frequencies correspond to different components present in the audio signal. What’s interesting is the presence of multiple spikes, each representing a distinct frequency component.

Notably, the highest peak in the spectrum is at approximately 106.7 Hz. In the context os the CNC machining experiment, this corresponds to a rotation speed of about 6400 rpm (revolution per minute). Understanding these frequency components can be crucial for diagnosing machine conditions or analyzing the performance of the equipment.

The code for the plots is given below:

#Author: Binayak Bhandari, PhD

from scipy.io import wavfile # import the libraries for reading sound files
import numpy as np # import numpy to do the fft
import matplotlib.pyplot as plt
import os
from scipy.fft import fft, fftfreq

figure_width = 7 # inches
figure_height = 3.5 # inches

# 20 sec machining audio data
AUDIO_FILE = "machining_sound.wav"
PATH = os.getcwd() # Save the plots in current working directory
# Load the file -get sampling_frequency and the data array
sampling_freq, sound_data = wavfile.read(AUDIO_FILE)
print("Sampling frequency = ", sampling_freq, "\nShape of data array = ", sound_data.shape)

# Determine the maximum values
max_value = np.max(np.abs(sound_data))
print(f'Max Value is {max_value}')
# Use max_value and normalize sound data to get values between -1 & +1
sound_data = sound_data/max_value
# Lets just take a single audio channel (mono) even if it is stereo
if len(sound_data.shape) == 1:
s1 = sound_data
else:
s1 = sound_data[:, 0]

# Get time domain representation of the sound pressure waves
timeArray = np.arange(0, s1.shape[0], 1.0)
timeArray = timeArray / sampling_freq # Second
timeArray = timeArray * 1000 # Scale to milliseconds

# Plot the sound signal in time domain
plt.figure(figsize=(figure_width, figure_height))
plt.plot(timeArray, sound_data, color='b')

plt.xlabel('Time [ms]')
plt.ylabel('Amplitude', fontsize=12)
plt.grid()
plt.tight_layout()
plt.savefig(os.path.join(PATH, 'signal.png'), dpi=300)

# ================ Fast Fourier Transform ==============================
# Calculate length of the signal
N = len(s1)
Time_period = 1/sampling_freq

yf = fft(s1) # Perform the Fourier transform
xf = fftfreq(N, Time_period)[:N//2] # calculate the frequencies in the center of each bin

# Calculate the magnitude of the FFT result
magnitude = np.abs(yf)
# Find the index of the maximum magnitude
max_magnitude_index = np.argmax(magnitude)

# Calculate the corresponding frequency with respect to index and sampling rate
max_frequency = max_magnitude_index * sampling_freq / len(s1)
print("Frequency with highest FFT magnitude:", max_frequency, "Hz")

# ===========================Frequency domain plot ======================
plt.figure(figsize=(figure_width, figure_height))
# Typically only the FFT corresponding to positive frequencies is plotted
plt.plot(xf, 2.0/N * np.abs(yf[0:N//2]), color='r')
plt.xlabel('Frequency (Hz)')
plt.ylabel('Magnitude')
plt.xlim(0, 10000)
plt.grid()
plt.tight_layout()
plt.savefig(os.path.join(PATH, 'FFT.png'), dpi=300)
plt.show()

Application of FFT in Engineering

FFT has a myriad of applications in mechanical engineering, including machine fault analysis, quality control, and machine condition monitoring. It also plays an important role in solving partial differential equations and initial boundary value problems. Furthermore, it’s instrumental in signal and image processing.

While FFT is not directly employed within deep learning algorithms, it plays a pivotal role in data preprocessing, especially when extracting spectral features. These features include the Mel-Spectrogram and Mel-Frequency Cepstral Coefficients (MFCCs), which are paramount in the realms of deep learning.

These spectral features act as a bridge between the world of signal processing and deep learning. They serve as valuable input features for various deep learning models such as recurrent neural networks (RNNs), Convolution Neural Networks(CNNs) and Transformers. I plan to write a separate post dedicated to delving deeper into the intricate details of Mel-Spectrogram and MFCCs and look at their significance and how they enhance the capabilities of deep learning models.

Your feedback and insights are invaluable. Please share your thoughts, questions, and suggestions for further improvements in the comments below.

#Engineering #Innovation #ContinuousLearning #FFT #DeepLearning #DataVisualization

--

--