Search guides and the APICtrl K
  1. API reference
  2. DSP

va_filters.h

The two other synth filters people ask for by name.

#include <sonore/va_filters.h>
On this page

Design notes

dsp.h has the Moog ladder. The next two requests are always "a 303 filter" and "an MS-20 filter", and they are not the Moog with different numbers:

DiodeLadder
the TB-303's four-pole. The stages are coupled through diodes rather than buffered, so each pole sees the one after it -- which is why its resonance is thinner and its cutoff slides as the resonance rises. Zavalishin's zero-delay-feedback solution of that coupled ladder ("The Art of VA Filter Design"), in the form Pirkle sets out ("Designing Software Synthesizer Plug-Ins in C++"): each one-pole carries its neighbour's feedback and the whole thing is solved as one implicit equation.
SallenKeyFilter
the Korg35 that the MS-20 is built on: a two-pole Sallen-Key with the resonance taken from a HIGH-pass in the feedback loop, and the diode clipper in that loop that makes its scream. Zero-delay-feedback again, derived below from the one-pole's split into "what depends on this input" and "what was already there".

Both keep the LINEAR core exact (TPT / ZDF -- the cutoff is where it is set, at any resonance, at any rate) and apply the nonlinearity to the solved loop signal, which is the standard trade every shipping VA filter makes; the alternative is a Newton loop per sample.

Included by dsp.h.

Types 2

The cutoff control sets the one-pole sections' corner, as in the circuit; the FILTER's corner is somewhere else, because the sections are coupled. Measured with the control at 1 kHz: -4.5 dB at 100 Hz and -31 dB at 1 kHz with no resonance (the -3 dB point is about three octaves below the setting), and an 18 dB peak at 653 Hz with the resonance at 0.8 -- the corner slides up toward the setting as the resonance rises, which is the 303's behaviour and the reason its sweeps sound the way they do. A plugin that wants a Moog-like corner at the number on the knob should scale the control up, and say so.

The linear response is 1 / (s² + (2 − K) s + 1) at the cutoff: K is the resonance, and at K = 2 the damping is gone and it oscillates. Lowpass and highpass are two different circuits on the MS-20 and two modes here.

The derivation the code follows, for the lowpass: with G = g/(1+g), a TPT one-pole's output is G·x + (1−G)·s, so its "already there" part is (1−G)·s, and a one-pole highpass's is −(1−G)·s. The loop is u = y1 + K·HP(LP2(u)); expanding LP2 and HP into their input-dependent and state parts and solving for u gives u = (y1 + S) / (1 − K·G·(1−G)), with S = K·(1−G)·((1−G)·s2 − sH). Zero delay: the current input is inside.

↑↓ to move↵ to openEvery public name in the headers, and every guide