Digital Filters & DSP
Digital filters process sampled signals in software or hardware. Learn FIR vs IIR, moving-average filters, windowed-sinc FIR design, linear phase and group delay, IIR biquads, filter order estimation, fixed-point implementation, DSP processors and MAC operations — with a Python FIR design.
Noise-cancelling headphones, ECG monitors, 5G modems and car radars all run digital filters millions of times per second. Unlike analog filters, digital filters are perfectly repeatable, easily changed and can have exactly linear phase.
An analogy
An FIR filter is like a weighted average of the last N samples — a recipe telling how much of each recent sample to mix into the output.
FIR vs IIR
FIR: no feedback, always stable, can have exactly linear phase, needs more taps. IIR: feedback, much lower order for sharp responses, non-linear phase, must be checked for stability and quantisation effects.
Design methods
FIR: windowed sinc, Parks–McClellan (equiripple), frequency sampling. IIR: bilinear transform of Butterworth/Chebyshev/elliptic prototypes, implemented as cascaded biquads for numerical robustness.
Implementation
Each tap is a multiply-accumulate (MAC). DSP processors, MCU DSP extensions (Cortex-M4/M7, CMSIS-DSP), FPGAs and GPUs execute MACs efficiently. Fixed-point (Q15/Q31) needs scaling to avoid overflow.
Multirate and adaptive
Decimation and interpolation with polyphase filters change sample rates efficiently. Adaptive filters (LMS, RLS) update coefficients in real time for echo and noise cancellation and channel equalisation.
Formulas
- FIR:
y[n] = Σ_{k=0}^{N−1} h[k] x[n − k] - IIR biquad:
y[n] = b₀x[n] + b₁x[n−1] + b₂x[n−2] − a₁y[n−1] − a₂y[n−2] - FIR order estimate:
N ≈ A / (22 Δf/f_s) - Linear-phase delay:
delay = (N − 1)/2 samples - Compute load:
MACs/s = N × f_s
Worked example: Filter order
Given: 60 dB attenuation, transition 500 Hz, f_s 8 kHz
Find: Taps.
- N ≈ 60/(22 × 500/8000) = 43.6 → 45 taps (odd for linear phase)
Answer: ≈ 45 taps
Worked example: Delay and load
Given: 51-tap FIR at 8 kHz
Find: Group delay and MACs/s.
- Delay = 25 samples = 3.125 ms
- MACs = 51 × 8000 = 408 000/s
Answer: 3.1 ms; 0.41 MMAC/s — trivial for a Cortex-M4
Windowed-sinc FIR low-pass design
import numpy as np
# Windowed-sinc low-pass FIR: fs = 8 kHz, cutoff 1 kHz, 51 taps (Hamming)
fs, fc, taps = 8000, 1000, 51
n = np.arange(taps) - (taps - 1) / 2
h = 2 * fc / fs * np.sinc(2 * fc / fs * n) * np.hamming(taps)
h /= h.sum() # unity gain at DC
def gain_db(f):
w = 2 * np.pi * f / fs
H = np.sum(h * np.exp(-1j * w * np.arange(taps)))
return 20 * np.log10(abs(H))
for f in (0, 500, 1000, 1500, 2000, 3000):
print(f"{f:5d} Hz: {gain_db(f):7.1f} dB")
# 0 Hz: -0.0 dB
# 500 Hz: 0.0 dB
# 1000 Hz: -6.0 dB
# 1500 Hz: -58.2 dB
# 2000 Hz: -61.0 dB
# 3000 Hz: -66.2 dB
# Filter a signal: 300 Hz (keep) + 3 kHz (reject)
t = np.arange(800) / fs
x = np.sin(2*np.pi*300*t) + np.sin(2*np.pi*3000*t)
y = np.convolve(x, h, mode="same")An ideal low-pass impulse response (sinc) is truncated to 51 taps and tapered with a Hamming window to reduce ripple. Windowed-sinc filters are −6 dB at the design cut-off and give ≈ 50–60 dB stop-band attenuation with Hamming.
Common mistakes
- Wrong: Using IIR where linear phase matters. — Right: Use linear-phase FIR for waveform fidelity.
- Wrong: Implementing high-order IIR directly. — Right: Cascade second-order sections.
Applications
- Audio & hearing aids: EQ, noise reduction, crossovers.
- Biomedical: ECG/EEG filtering.
- Communications: Pulse shaping and channel filtering.
Key takeaways
- FIR: stable, linear phase; IIR: efficient.
- N ≈ A/(22Δf/f_s).
- Delay (N − 1)/2 samples.
- MACs = N × f_s.
Going further
- Parks–McClellan: Optimal equiripple FIR design.
- Polyphase filters: Efficient multirate DSP.
- Fixed-point scaling: Q-format overflow management.