Audio & DSP
Filters and delay lines: two useful DSP building blocks
Filters and delay lines explain many familiar effects. Nonlinear processors such as waveshaping distortion are another important building block.
Many classic effects are built from filters, delay lines, or both. Reverb, chorus, flanger and echo are delay-based; EQ, wah and phaser are filter-based. Distortion often adds a nonlinear processor, sometimes combined with filtering.
The delay line is the simplest object in DSP: a buffer you write into and read from at an offset.
class DelayLine:
def __init__(self, max_len):
self.buf = np.zeros(max_len)
self.i = 0
def process(self, x, delay, feedback=0.0):
# read the past
r = int(self.i - delay) % len(self.buf)
y = self.buf[r]
# write the present, optionally mixed with what came back
self.buf[self.i] = x + y * feedback
self.i = (self.i + 1) % len(self.buf)
return y
# delay = time + feedback = 0 -> echo
# delay modulated + feedback = 0 -> chorus / flanger building blocks
# many delays + feedback > 0 -> reverb (a first approximation)
# This toy truncates delay to integer samples; practical modulation interpolates
# fractional-sample reads and carefully handles the feedback path.Both chorus and flanging can use a modulated delay, so modulation alone does not distinguish them. In common designs, a flanger uses a very short delay (often about 1–10 ms) mixed with the dry signal to create a moving comb-filter sweep; chorus usually uses longer delays (often about 10–50 ms) and may mix several slightly detuned voices. Implementations overlap, so these are typical patterns rather than strict definitions.
The filter is the other half. Many classic recursive filters can be introduced with one line of arithmetic on previous input and output samples:
# One-pole low-pass — the smallest useful filter there is
class OnePole:
def __init__(self, sr, cutoff_hz):
self.z = 0.0
self.a = np.exp(-2 * np.pi * cutoff_hz / sr) # matched-pole coefficient from cutoff and sample rate
def process(self, x):
# y[n] = (1-a)*x[n] + a*y[n-1] -- a weighted mix of new and old
self.z = (1 - self.a) * x + self.a * self.z
return self.z
# a close to 1 -> heavy smoothing -> low cutoff
# a close to 0 -> almost transparent -> high cutoffWire a handful of these together and you have an EQ (filters in parallel bands), a synth voice (oscillator → filter → envelope-controlled gain), or a reverb (a network of delays with feedback). The building blocks are genuinely this small; the craft is in the wiring and the parameter ranges.
What commonly distinguishes chorus from flanging?
For the one-pole recurrence shown, when is it unstable?
Delay line
A buffer read at an offset; echo/chorus/reverb all start here.
One-pole filter
y[n] = (1−a)x[n] + a·y[n−1]; the smallest useful filter.
Stability
A one-pole recurrence needs |a| < 1; a general causal IIR filter needs every pole inside the unit circle.
Review cards
Delay line
A buffer read at an offset; echo/chorus/reverb all start here.
One-pole filter
y[n] = (1−a)x[n] + a·y[n−1]; the smallest useful filter.
Stability
A one-pole recurrence needs |a| < 1; a general causal IIR filter needs every pole inside the unit circle.
Sources for this lesson
Below are the references, editions and original links for further reading and checking.
BookJulius O. Smith III — four online books (DFT / Filters / Physical Audio / Spectral Audio)free
Julius O. Smith III, CCRMA, Stanford
持续更新
音频 DSP 里最超值的一批资源,全免费,含 Matlab / Octave / Faust 代码。
BookDesigning Audio Effect Plugins in C++
Will Pirkle
2nd edition, Routledge
从数学到能落地的插件实现,给实现而不只给推导。
BookThe Art of VA Filter Designfree
Vadim Zavalishin (Native Instruments)
2.1(免费 PDF)
虚拟模拟滤波器的现代做法。合成器音色的关键,数学味重但绕不过去。
CourseMusic 206: Introduction to Delay and Filters II — Chorus Implementationfree
Tamara Smyth, Simon Fraser University
Course notes, online edition
说明合唱常见的多抽头延迟结构,以及合唱与镶边常用延迟时长的差异;这些时长是常见设计范围,不是严格边界。
CourseTime-Varying Delay Effectsfree
Julius O. Smith III, CCRMA, Stanford
Physical Audio Signal Processing, online chapter
Background on time-varying delay effects and interpolated delay lines.
Lights up these nodes in the hub:a-02 · a-03 · a-04