FIR Filters & Convolution¶
Four complementary methods for filtering and convolution, from educational time-domain approaches to efficient FFT-based processing.
Time-domain convolution¶
For signals of length N and kernels of length M, computes the full
linear convolution. Output length is N + M - 1.
import pyminidsp as md
import numpy as np
signal = md.impulse(100, amplitude=1.0, position=0)
kernel = np.array([1.0, 2.0, 3.0])
out = md.convolution_time(signal, kernel)
# out[:3] == [1.0, 2.0, 3.0]
# len(out) == 102
Moving-average filter¶
A simple low-pass filter that computes the running mean over a window. Output matches input length with zero-padded startup.
signal = md.sine_wave(1024, freq=440.0, sample_rate=44100.0)
smoothed = md.moving_average(signal, window_len=5)
General FIR filter¶
Apply a causal FIR filter with arbitrary coefficients:
Output matches input length.
coeffs = np.array([0.25, 0.5, 0.25])
filtered = md.fir_filter(signal, coeffs)
FFT overlap-add¶
Same result as time-domain convolution but much faster for long kernels by processing blocks in the frequency domain.
kernel = md.hann_window(256)
out_time = md.convolution_time(signal, kernel)
out_fft = md.convolution_fft_ola(signal, kernel)
np.testing.assert_allclose(out_time, out_fft, atol=1e-10)
Comparison¶
Method |
Complexity |
Output length |
Best for |
|---|---|---|---|
|
O(NM) |
N + M − 1 |
Teaching, short kernels |
|
O(N) |
N |
Simple smoothing |
|
O(NM) |
N |
Standard FIR design |
|
O(N log N) |
N + M − 1 |
Long kernels, production |
md.shutdown()