self-oscillating state variable filter


Recommended Posts



in a way this a public backup, but maybe someone sees this and comes up with something cool:

The attached code implements a 24-bit state variable filter.

It's a fairly basic building block for synthesizers etc. Details can be found here, also how to modify it to bandpass, highpass or bandstop variants.


The typical SNR at 96 kHz audio rate is around 110 dB, good enough for rock-n-roll...

On the Papilio Pro, I can synthesize at 96 MHz => 1000 clock cycles per audio sample. One filtering round needs 8 cycles. More than one channel, no problem, we can handle that at no extra cost (say, up to 100 channels with a modifed interface)

Turn up Q high enough and it will oscillate at a frequency controlled by f.


It comes with a zpu-compatible bus interface. Addresses 3 and 4 control Q factor and cutoff frequency, respectively (16 fractional bits, "1" is 65536).


For the time being, there is no implementation - the one that I use needs lots of analog control buttons on the Retrocade ADC, a specific SPI ADC and a MIDI keyboard so I doubt anybody would use it.

With the cutoff frequency on a poti, it gives an almost believable imitation of a Wah pedal.


There is also a floating-point reference implementation in C, a data-streaming RTL simulation and an Octave script to analyze the difference.


99 % of the code is "infrastructure" to connect it to a CPU bus, implement multiple channels, etc. The filter code itself is maybe a dozen lines, search for "mulOut".



Link to comment
Share on other sites

Actually it is, internally. There are three overlapping multiplications mapped to the same multiplier. Doing everything sequentially would need 3x3 = 9 cycles for multiplications, plus 2*2+2 for store and recall.

This implementation uses only 8 cycles, almost a factor-of-two speedup. Not that I expect this one to be the performance bottleneck...

But a more interesting observation is that the ZPU can handle real-time "wah" control :)

I'm sure this could be clocked at higher speed, but why bother as the rest of the design couldn't keep up. I had to redo it already once, add one pipeline register to the multiplication and rearrange operations around it.

Link to comment
Share on other sites


This topic is now archived and is closed to further replies.