|
miniDSP
A small C library for audio DSP
|
A brickwall lowpass filter removes all frequency content above a cutoff frequency with zero transition bandwidth. Unlike FIR or IIR filters that roll off gradually, a brickwall filter has a perfectly sharp boundary: everything at or below the cutoff passes through unchanged, and everything above is eliminated completely.
miniDSP implements this by transforming the signal into the frequency domain with an FFT, zeroing the bins above the cutoff, and inverse-FFTing back to the time domain.
Given a real signal \(x[n]\) of length \(N\) with DFT \(X(k)\), the brickwall lowpass at cutoff frequency \(f_c\) produces:
\[ X'(k) = \begin{cases} X(k) & \text{if } k \leq \lfloor f_c \cdot N / f_s \rfloor \\ 0 & \text{otherwise} \end{cases} \]
where \(f_s\) is the sample rate. The filtered signal is \(x'[n] = \mathrm{IFFT}(X'(k)) / N\) (the \(1/N\) factor normalizes FFTW's unnormalized inverse transform).
Reading the formula in C:
Quick example:
The full signature is:
The filter modifies the buffer in-place. It creates one-off FFTW plans (FFTW_ESTIMATE) internally, so there is no plan caching overhead — but it is best suited for offline/batch use rather than real-time sample-by-sample processing.
Because the brickwall filter has an infinitely sharp cutoff in the frequency domain, the time-domain impulse response has infinite length and exhibits Gibbs ringing — oscillatory overshoot and undershoot near the cutoff frequency. This is the fundamental tradeoff: zero transition bandwidth comes at the cost of time-domain ringing.
In practice, this matters only when the cutoff is close to a frequency band you care about. When the cutoff is far from the band of interest (e.g., filtering at 8 kHz when your signal content is below 4 kHz), the ringing is inaudible and invisible.
The plot below shows a 400 Hz + 12000 Hz signal before and after applying a brickwall lowpass at 4000 Hz. The 12000 Hz component is completely eliminated while the 400 Hz component passes through unchanged.