Poles and Zeros
In both control theory and DSP, poles and zeros act as the fundamental DNA of a system's transfer function. They dictate exactly how a system will respond to dynamic inputs, whether that's an actuator in an industrial control loop or a guitar signal hitting a digital filter. At a mathematical level, if we look at a linear time-invariant (LTI) system's transfer function, \(H(s)\) in the continuous analog domain or \(H(z)\) in the discrete digital domain, it is represented as a ratio of two polynomials. In DSP, this is typically expressed using the Z-transform:
Zeros are the roots of the numerator polynomial, where \(N(z)=0\). When the input signal contains a frequency matching a zero, the system's output drops to zero (or is heavily attenuated). They carve out notches and dips in the frequency response.
Poles are the roots of the denominator polynomial, where \(D(z)=0\). When the input frequency approaches a pole, the system's response shoots toward infinity. Poles create resonances, peaks, and fundamentally define the stability of the system.
The Analog vs. Digital Mapping
In analog control systems or physical circuits, analysis happens in the s-plane (Laplace transform). For stability, all poles must sit strictly in the left-half plane. If a pole drifts into the right half-plane, the system becomes unstable. Zeros can exist anywhere, but non-minimum phase zeros (in the right-half plane) cause reverse-action behaviors—like a system briefly dipping in the wrong direction before correcting itself.
When executing DSP—such as writing C++ audio algorithms for an ARM Cortex-M7 microcontroller—everything maps to the discrete z-plane. The stability boundary is no longer the vertical y-axis; it wraps into the unit circle (\(\mid z \mid =1\)).
- Stable: All poles must be located strictly inside the unit circle.
- Marginally Stable / Oscillating: Poles sitting exactly on the unit circle create sustained oscillation (effectively creating a pure sine wave oscillator).
- Unstable: A pole pushed outside the unit circle results in exponential runaway. In an audio buffer, this usually means infinite gain, resulting in a horrific digital clipping noise or a hard system crash.
Practical Impact on Tone and Filtering
If you are shaping an EQ curve, building a high-pass filter, or managing specific frequency bands in a wavelet decomposition, manipulating these roots is how you craft the character of the signal:
- Proximity to the Unit Circle: The closer a pole gets to the unit circle boundary, the sharper and more aggressive the resonance (a higher Q-factor). Conversely, the closer a zero gets to the unit circle, the deeper and more absolute the frequency notch.
- Angles: The angle of the pole or zero relative to the positive real axis determines the specific center frequency of that boost or cut.
- Real-time Modulation: When building dynamic effects like a sweeping phaser or an envelope filter, you are essentially recalculating the a and b coefficients on the fly to drag those poles and zeros around the z-plane in real-time.
Let’s dig into the “Angles”. Explain
To understand how the angles of poles and zeros dictate frequency, we have to look at the z-plane through the lens of polar coordinates.
Instead of looking at a complex number on a grid with an x-axis (real) and y-axis (imaginary), we define a pole or zero by its distance from the center point (r, the magnitude) and its angle from the positive horizontal axis (θ, the phase).
In the discrete-time domain, evaluating the frequency response of a system means "walking" around the perimeter of the unit circle (\(r=1\)).
Mapping Angle to Physical Frequency
As you walk counter-clockwise around the top half of the unit circle, you are sweeping through the frequency spectrum of your digital system, from 0 Hz up to the absolute maximum frequency the system can represent.
The angle \(\theta\) (in radians) corresponds directly to a physical frequency \(f\) (in Hertz), but it is entirely dependent on your system's sampling rate \(f_s\). The mathematical relationship is:
To flip that around and find the physical frequency an angle represents, the formula is:
Key Landmarks on the Unit Circle
Imagine a sampling rate of \(48\ \text{kHz}\). Here is how specific angles map to real-world frequencies:
Angle = 0 Radians (The far right edge):
- This represents 0 Hz, or Direct Current (DC).
- Placing a zero at \(z=1\) (angle 0) creates a notch at 0 Hz, effectively acting as a DC-blocker.
- Placing a pole here creates a massive boost at the lowest possible frequencies, acting as an integrator or a low-pass filter.
Angle = π Radians (The far left edge):
- This represents the Nyquist frequency, which is exactly half of your sampling rate \(f_s / 2\). At \(48\ \text{kHz}\), this angle represents exactly 24,000 Hz. This is the highest frequency your digital system can theoretically reproduce.
Angle = π/2 Radians (The top dead center):
- This represents a quarter of your sampling rate \(f_s / 4\). At \(48\ \text{kHz}\), this points directly to \(12\ \text{kHz}\).
If you want to design a bandpass filter that isolates a snare drum fundamental at exactly 200 Hz, you use that formula to calculate the exact angle θ that corresponds to 200 Hz at your current sample rate, and you drop a pole right on that angle (just inside the unit circle for stability).
Why They Travel in Pairs (Complex Conjugates)
Because the audio algorithms you write ultimately rely on real-world numbers for their filter coefficients (the a and b multipliers in the code), you cannot have a single pole or zero floating at a random angle in the top half of the unit circle.
Any complex math that leaves an imaginary remainder will break a real-world system. Therefore, any pole or zero placed at an angle \(\theta\) must be accompanied by an identical mirror image in the bottom half of the circle at \(-\theta\). These are called complex conjugates.
This pairing cancels out the imaginary math perfectly, leaving you with purely real coefficients that your processor can actually multiply and add, while maintaining the resonant peak or notch at your target frequency.
Envelope Filter
Let’s use this to deep dive into envelope filter design:
An envelope filter (often called an auto-wah) is a fantastic bridge between control theory and audio processing. It is essentially a system that listens to the dynamics of the incoming audio—like the nuanced attack of a finger-picked Stratocaster—and uses that amplitude data to sweep the center frequency of a filter in real-time.
To design one, we have to split the architecture into two distinct DSP pathways: the Sidechain (Envelope Follower) and the Audio Path (Modulated Filter).
1. The Sidechain: Extracting the Envelope
Before we can move any poles around, we need a control signal that accurately represents the volume envelope of the guitar.
Rectification: The raw AC audio signal swings above and below zero. We take the absolute value (\(|x[n]|\)) so all the energy is positive.
Smoothing (Low-Pass Filtering):
A rectified audio signal is just a jagged, high-frequency mess. To turn it into a smooth control curve, we run it through a very aggressive low-pass filter.
- In the z-plane, this smoothing filter is usually a single real pole placed extremely close to \(z=1\) (the DC angle, 0 radians).
- If the pole is at \(z=0.999\), the filter reacts slowly, creating a sluggish, syrupy wah effect.
- If the pole is at \(z=0.990\), it reacts much faster, quickly snapping open and closed to capture rapid transients.
Often, designers use two separate poles here: one for the "Attack" (how fast the filter opens when you pluck a string) and one for the "Release" (how fast it closes as the note decays).
2. The Audio Path: Moving the Poles
This is where the magic happens. The smoothed control signal from our sidechain is now used to dynamically modulate the angle \(\theta\) of our filter's poles.
When pushing the poles to a wider angle \(\theta\), the input is silent, the poles sit at a predetermined minimum angle (the "base frequency" or "depth"). When you dig in and play hard, the control signal spikes, which pushes the poles to a wider angle \(\theta\), sweeping the resonant peak higher up the frequency spectrum.
If we use a standard resonant band-pass or low-pass filter, the poles are a complex conjugate pair. The math linking the envelope signal to the filter coefficients typically requires trigonometric functions (sine and cosine) to calculate the new angle \(\theta\) for every single sample.
The Hardware Reality: C++ and Microcontrollers
This brings up a massive bottleneck in real-world DSP. When writing C++ for an embedded system like an ARM Cortex-M7, calculating \(\sin(\theta)\) and \(\cos(\theta)\) at an audio rate of 48,000 times per second just to update filter coefficients will absolutely shred your CPU cycles.
To get around this in boutique hardware design, engineers rely on a few tricks:
Lookup Tables: Instead of calculating trig functions on the fly, you pre-calculate an array of sine/cosine values and let the envelope signal simply index into that array.
The Chamberlin State Variable Filter (SVF):
This is a brilliant, highly efficient filter topology originally designed for digital synthesizers. Instead of standard biquad coefficients (\(a_1, a_2, b_0, b_1, b_2\)), the Chamberlin SVF uses internal feedback loops where the frequency control parameter (\(F\)) is a simple linear multiplier roughly proportional to \(\sin(\theta)\). For low frequencies (which is where most guitar envelope filters operate), \(\sin(\theta) \approx \theta\). This means you can directly multiply your envelope control signal into the filter structure with almost zero expensive math overhead, allowing you to drag those poles around the z-plane effortlessly.