For today’s article, we’ll be talking about filters. So far in this series I haven’t spoken too much about filters, which might seem odd considering how much of signal processing in general is all about filters. The reason I’ve avoided filters is that most filters in audio signal processing are implemented as linear processors, and I’ve been focusing on nonlinear processing concepts.
However, this does not have to be the case. For instance, Vadim Zavalishin at Native Instruments has written extensively about including nonlinear elements in ladder filters and state variable filters, in ways that accurately reflect how these filters often behave in the analog world. Actually, Vadim’s entire book, The Art of Virtual Analog Filter Design, is a fantastic resource that I highly recommend for anyone with an interest in filter design for audio. That said, Vadim focuses mostly on the virtual analog world, and in this series of articles I’ve been striving to construct signal processing ideas that can be conceived and implemented entirely in the digital realm.
That said, one of the coolest things about analog filters is the way that they resonate. A “resonance” occurs in a filter when the filter is tuned to amplify a certain frequency, much like a guitar string is designed to resonate at the frequency to which it is tuned. In the analog world, whenever something is amplified, we run the risk of moving into nonlinear territory, where saturation and distortion can occur. One of the reasons that analog filters often sound “warm” to musicians and engineers is due to the fact that as the filters resonate, they begin to saturate as well. Thinking about this got me thinking: could there be a way to alter some existing digital filter forms so that any resonance in the filter automatically undergoes some saturation? This idea is what I’ll be developing below…
As always, any programmers reading this are encouraged to check out this article as a Jupyter Notebook.
To begin, I’d like to introduce the idea of a “biquad” filter, which is a short way for DSP engineers to refer to a 2nd-order filter. “2nd-order” means that the filter has “memory” that extends back to the two previous timesteps that it has computed. In other words, the current output of the filter depends not just on the current input, but also on the previous two inputs and outputs. DSP engineers like biquad filters a lot, because any filter can be broken down into a “cascade” of biquad filters.
Transposed Direct Form II
There are several way to implement a biquad filter, but one of my favorites is the so-called “Transposed Direct Form-II”. This a rather complicated name for a relatively simple thing, but more information on why this name exists, as well as other filter forms, can be found in Julius Smith’s wonderful Introduction to Digital Filters.
Above we see a signal flow diagram for Transposed Direct Form-II (TDF-II). TDF-II is a favorite of mine for several reasons. For one thing, it is pretty efficient in that it only uses a handful of multiplies and two delay elements. It also has some nice numerical properties for implementing highly resonant filters. Another convenient thing about TDF-II which will be useful here, is that we can easily see what values are stored in the unit delay (z^-1) elements. We’ll refer to these values as the “state” of the filter.
There are several particular filter “shapes” that are often useful for processing audio, and all of them can be constructed using a TDF-II structure. In this article, I’m going to focus on 6 shapes: Highpass, Lowpass, High Shelf, Low Shelf, Bell, and Notch. Plots of the frequency response for each of these filters can be found below. For instructions on how to implement these filters using a biquad filter, please check out Robert Bristow-Johnson’s Audio EQ Cookbook, another indespensible resource for audio DSP engineers.
In order to make any TDF-II filter exhibit nonlinear resonance, we can simply saturate the states. In the following examples, I will demonstrate three saturating nonlinearities: a soft clipper, a hard clipper, and a tanh clipper. The mathematics that describe why this works and ensure that we don’t accidentally make an unstable filter are a litle bit complex, for the more mathematically inclined reader, I recommend a more technical paper I’ve written on the topic. The resulting signal flow diagram will look something like this (the “NL” blocks represent nonlinear elements):
To get a sense of what this modified structure does to our filter, it would be nice to look at the frequency response of the filter. Unfortunately, as I mentioned in my introductory article for this series, a nonlinear system does not have a frequency response the same way that a linear system does. However, what we can do is choose some level (often called an “operating point”), and see how our system reacts to various frequencies at that level. Below, we show the “frequency response” for a low shelf filter and a bell filter, each with tanh nonlinearities, at various operating points.
From the above plots, it may seem that all we’re doing with our nonlinear filter is creating a filter for which the resonance decreases as the input level increases, almost like a voltage controlled filter (VCF). To an extent this is true, but remember that the active ingredients for this process of decreasing resonance are the saturating nonlinearities, which add harmonics, thus making our filter sound harmonically richer as well.
Now if we can measure the harmonic response of this nonlinear filter, that will be useful for us in avoiding aliasing artifacts. Below, we show the harmonic response of a 100 Hz sine wave, for a nonlinear bell filter with a center frequency at the same frequency, and a gain of 12 dB. We show this response for three types of saturating nonlinearities: hard clipper, soft clipper, and tanh clipper.
As you can see the soft clipping and tanhtanh response generate harmonics up past 10x the fundamental, while the hard clipper generates significantly more. For my purposes, I’ve found that upsampling by a factor of 8 mitigates aliasing artifacts down below -80 dB for the soft clipper and tanh clipper.
As usual, there is an example implementation of this nonlinear biquad filter available on GitHub as an audio plugin (VST, AU). Feel free to download and try it for yourself! There is also a video demo below:
Thanks for taking the time to read about yet another interesting nonlinear signal processing method. As always, I hope you’ve been inspired to try some things for yourself. For instance, what about adding nonlinearities to some other filter forms? What about trying different nonlinear shapes, saturating and otherwise? Once you start asking these sorts of questions, the possibilities are truly beyondless.
For myself, I’m hoping dig a little bit more into generalized systems with nonlinear feedback, and write about that for next time. Stay tuned!