[Python] Problem with filtering frequencies and IFFT

Discussão em 'Python' iniciado por Stack, Junho 9, 2025.

  1. Stack

    Stack Membro Participativo

    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...

Compartilhe esta Página