Introduction
At the heart of most filers is a resonator characterized by its resonant frequency, Q factor and gain. In digital sound processing it is often desirable to change these parameters over time to give a dynamic character to the synthesized sound. For example the defining wobble bass of modern dubstep can be achieved by quickly varying a low-pass filter over a bass note making it sound dark or bright in the rhythm of the song.
The problem
There is unfortunately a limit on how quickly you can vary the filter parameters of a resonator based on a traditional two pole design. A straightforward implementation preserves the slope of the impulse response when the filter parameters change. While this may look nice and smooth when plotted it causes an undesirable audible change in loudness that often sound like clicks or pops.
Impulse response of a time variable two pole resonator. |
The solution
The reason two pole filters are used in the first place is that it's not possible to create a resonator using only real coefficients. However there is no magic involved in using complex numbers and creating a complex one pole resonator is in fact fairly straightforward.
Complex multiplication
You may recall that complex numbers are defined by their real and imaginary parts or alternatively by their magnitude (distance from zero) and phase (angle measured from the real line). You may also recall that complex multiplication of two numbers is achieved by multiplying the magnitudes together and adding up the phases. This means that starting from one and repeatedly multiplying it by a complex number with magnitude less than one and non-zero phase creates a spiral towards zero. Taking the real part of this gives us an exponentially decaying sine wave.
The number one successively multiplied by a complex number. |
Filter design
Now we can simply take the above observation and note that complex multiplication is a linear operation to get a filter out of it. We just need to pick our multiplying complex number so that it takes frequency / (sampling rate) steps to go around one full circle and thus make the real part oscillate at the desired frequency.
Effectively this creates a complex one pole filter that preserves the magnitude of the signal when we change our resonance parameters. The audible effect is much more pleasant than with the two pole design. Only one issue remains and that is the fact that impulse response of this filter starts at one and decays from that. A simple fix is to multiply the signal by the imaginary unit to get a filter where the impulse response starts at zero. Another feature is that it's impossible to achieve Q-factors bellow one half.
Impulse response of a time variable one pole resonator. |
Code
The filter design sketched above is realized by the following python generator:
Here I have divided the multiplying complex number a1 into the rotating phase part and the decaying magnitude part. (The gain constant is indeed called b1 and not b0 because the impulse response is delayed by one sample compared to a traditional two pole design.)
The design outlined above is unnormalized and only valid near DC. To arrive at the final form we need to take the bilinear transform of the two-pole version and factor that into it's one-pole form. The resulting designs for low-pass, high-pass, band-pass, band-reject (notch) and all-pass filters are available at: https://gist.github.com/frostburn/318e278dcdb050d71872
The design outlined above is unnormalized and only valid near DC. To arrive at the final form we need to take the bilinear transform of the two-pole version and factor that into it's one-pole form. The resulting designs for low-pass, high-pass, band-pass, band-reject (notch) and all-pass filters are available at: https://gist.github.com/frostburn/318e278dcdb050d71872
No comments:
Post a Comment