Complex Nonlinearities Episode 7: Adaptive EQ

In this article we’ll be examining some interesting uses of adaptive filtering for audio equalization, and how it can be extended with frequency warping and nonlinearities. The resulting effect can be used for setting an EQ filter that makes one instrument sound optimally similar to another, or to create an interesting effect that “copies” the frequencies from one sound onto another.

As always, this article can also be read as a Jupyter Notebook.

Adaptive Equalization

Below we show a simple example of using an adaptive EQ to approximate a pure sine wave from a white noise signal.

So that’s pretty cool! DSP engineers use this technique often for signal “prediction” where they can use white noise to approximate any desired signal. The reason why white noise works well for this is that it has frequency content at all frequencies, while your average audio signal may not. However, because adaptive filters are time varying, they can actually shift frequencies as well. As an example, we can use our adaptive filtering algorithm to filter a sine wave at one frequency to predict a sine wave at another.

So that works pretty well. But what if there was a way to make our signal a bit more broadband, a bit more like white noise, without losing it’s amplitude envelope, or overall melody and harmony.

Nonlinearities

Above we show another example of frequency shifting with our adaptive filter, but with a saturating nonlinearity at the input of the filter. A couple of interesting things to note here: First, the extra harmonics added by the nonlinearity allow for a smoother frequency shift, since there is more high frequency content to aid in the frequency shifting. Second, notice that the output signal has an interesting harmonic structure to it as well, with a number of both overtones and undertones. Adaptive filtering with a nonlinear input can give some pretty cool sounding and unique timbres (an audio example will be given later on).

Frequency Warping

As an example of the problem, below we show the spectrum of four sine waves, at 100, 300, 9000, and 10000 Hz. Audibly, we hear a big difference between 100 and 300 Hz, not so much between 9000 and 10000 Hz. Yet when we look at the spectrum linearly (much as our adaptive filter will see it), it’s pretty hard to distinguish between the two low-frequency signals, and pretty easy to distinguish between the high-frequency ones. We can fix this with allpass warping. Let’s try passing out signal through an allpass filter with a “warping factor” of -0.72, and see what happens.

So with allpass warping, we get a pretty drastic improvement in the frequency resolution of our filter at low frequencies where we care about it most. While the tradeoff is that our frequency resolution is is worse at high frequencies, I’ve found that by tuning the “warping factor”, it’s not too hard to find a happy medium, where the resolution across all frequencies is “just right”. For our adaptive filter, this means we can tune our filter to capture the frequency spectrum of the desired signal with an emphasis on the frequencies we care about most.

Implementation

Finally…

Jatin Chowdhury is a student.