Search code examples
pythonnumpyaudiofft

Apply FFT to each chunk of 1024 samples


I have 1024 samples and I want to cut them into 32 chunks of 32 and run FFT on each one of them and plot it via a Frequency-Amplitude spectrum, I have most of the code working just the part of applying FFT to each chunk is not working, however I am able to apply FFT to the whole samples array.

I tried doing something like that:

realFFT = [for chunk in chunks(amplitude,32): np.fft.fft(chunk)]

but that is wrong syntax

I also tried going over the chunks array by casting it to a List and then saving it all to another list but that didn't work either.

Here is my code:

# Python example - Fourier transform using numpy.fft method
import numpy as np
import matplotlib.pyplot as plotter
from os import times
from PIL import Image
import numpy as np
from numpy.lib.type_check import real

def chunks(lst, n):
    """Yield successive n-sized chunks from lst."""
    for i in range(0, len(lst), n):
        yield lst[i:i + n]

# How many time points are needed i,e., Sampling Frequency
samplingFrequency = 100

# At what intervals time points are sampled
samplingInterval = 1 / samplingFrequency

# Begin time period of the signals
beginTime = 0

# End time period of the signals
endTime = 10.24

# Frequency of the signals
signal1Frequency = 4
signal2Frequency = 7

# Time points
time = np.arange(beginTime, endTime, samplingInterval)
# Create two sine waves
amplitude1 = 0.7* np.sin(2*np.pi*signal1Frequency*time)
amplitude2 = np.sin(2*np.pi*signal2Frequency*time)
# Create subplot

figure, axis = plotter.subplots(2, 1)
plotter.subplots_adjust(hspace=2)
# Time domain representation for sine wave 1

amplitude = amplitude1

axis[0].set_title('Sine wave with a frequency of 4 Hz')
axis[0].plot(time, amplitude)
axis[0].set_xlabel('Time')
axis[0].set_ylabel('Amplitude')
# Frequency domain representation

realFFT = [for chunk in chunks(amplitude,32): np.fft.fft(chunk)]
#fourierTransform = np.fft.fft(amplitude) # Normalize amplitude
fourierTransform = realFFT[range(int(len(amplitude)/2))] # Exclude sampling frequency
tpCount = len(amplitude)
values = np.arange(int(tpCount/2))
timePeriod = tpCount/samplingFrequency
frequencies = values/timePeriod

# Frequency domain representation

axis[1].set_title('Fourier transform depicting the frequency components')
#dBm = 30 + (20 * np.log10(abs(fourierTransform)))
axis[1].plot(frequencies, abs(fourierTransform))
axis[1].set_xlabel('Frequency')
axis[1].set_ylabel('Amplitude')

plotter.show()

Solution

  • You have the syntax slightly wrong

    realFFT = [np.fft.fft(chunk) for chunk in chunks(amplitude, 32)]
    

    The syntax of list comprehension is a little bit different that a for loop.