I am new to signal procession, so I found myself stuck. I have a script that performs an FFT with zero-padding and attenuation Hann window on a waveform. Then, I need to filter out frequencies above a certain threshold and perform an IFFT to get a reconstructed waveform. I think I was able to reverse all my steps and get a reconstructed waveform identical to the original waveform. The problem started when I input a filtered frequency spectrum into my IFFT function. Here are some problems I encountered: In this, there were three frequencies present, none of which were intented to be filtered out, and the reconstructed waveform looked like it had some frequencies removed In this image, I increased the sampling rate to what I will use later, and it resulted in a waveform that looked like this Here's my code: import pandas as pd import numpy as np import matplotlib.pyplot as plt # zero-padding function def nextpow2(x): return (x-1).bit_length() # Hann window and FFT function def preprocessing(waveform, duration): NS = len(waveform) # length of waveform in samples delF = 1/duration # stepsize in frequency domain Fmax = NS * delF / 2 # maximum frequency possible in f-domain NFFT = 2 ** (nextpow2(NS)+1) # Next power of 2 based on waveform length attHann = sum(np.hanning(NS)) # Attenuation Hann window y = (1/attHann) * np.fft.fft(np.hanning(NS) * waveform, NFFT) # spectrum of the input signal mag0 = abs(y[0]) # magnitude of DC component mag = abs(y[0:int(NFFT/2)])/mag0 # relative magnitude f = Fmax * np.linspace(0, 1, int(NFFT/2)) # frequency spectrum vector return f, mag, y, NFFT, Fmax def inverse_processing(y, waveform): NS = len(waveform) # length of waveform in samples NFFT = 2 ** (nextpow2(NS)+1) # Next power of 2 based on waveform length attHann = sum(np.hanning(NS)) # Attenuation Hanng window y = attHann * y # reverse attenuation Hann window waveform_windowed = np.fft.ifft(y, NFFT) # inverse FFT accounting for zero-padding waveform_windowed = waveform_windowed[:NS] # remove zero-padding reconstructed_waveform = waveform_windowed * (1 / np.hanning(NS)) # reverse Hann window reconstructed_waveform = reconstructed_waveform.real return reconstructed_waveform # A simulated sin wave # Parameters fs = 186567 # Sampling frequency (Hz) T = 1 # Duration in seconds timevector = np.linspace(0, T, int(fs*T), endpoint=False) # Frequencies to combine (Hz) freqs = [50, 120, 300] # Generate combined sine wave waveform = np.zeros_like(timevector) for f in freqs: waveform += np.sin(2 * np.pi * f * timevector) duration = timevector[-1] Srate = len(waveform)/duration # FFT, zero-padding, Hann window f, mag, y, NFFT, Fmax = preprocessing(waveform, duration) ############################################################################### # band-pass filter y_filtered = y.copy() y_filtered = y_filtered[:len(f)] mask = (f >= 0) & (f <= 400) y_filtered[~mask] = 0 ############################################################################### reconstructed_waveform = inverse_processing(y, waveform) filtered_waveform = inverse_processing(y_filtered,waveform) time_reconstructed = np.linspace(0, duration, len(reconstructed_waveform)) I tried doing my inverse process without the extra steps for zero-padding and Hann window. Continue reading...