[sdiy] SVF LP trapezoidal
Andrew Simper
andy at cytomic.com
Sun Aug 21 05:50:24 CEST 2011
Hi Guys,
Since there is so much "dsp" stuff going on here I thought I would
post something as well. I'm doing some analog modelling plugins, and
have been investigating all possible variations on digitising
different non-linear circuit topologies with some promising results.
For starters I would like to share with you the linear trapezoidal
integrated SVF, which has excellent stability properties even when
being modulated very fast, and it has a very wide range of frequency,
and you can also have arbitrary values of damping, so you can use it
for eq as well. I haven't really had a chance to study the numerical
properties, but I am guessing it should fare better than direct form
one ugliness. I will eventually write some papers on all this going
through the forward euler, backward euler, and trapezoidal integration
of the SVF, Sallen-Key, and 4 one pole cascade structures and possibly
more if anyone can suggest other musical filters.
Here is the basic analysis from the SEM 1A SVF
http://dl.dropbox.com/u/14219031/Dsp/sem-1a-linear-svf.jpg --
vota1 = v0 - k*v1 - v2;
vota2 = v1;
vc1 = v1 - 0;
vc2 = v2 - 0;
iota1 = gr * vota1;
iota2 = gr * vota2;
gc = s*c;
gr = g = 1/r;
ic1 = gc * vc1;
ic2 = gc * vc2;
then solve the two equations which is just kirchoff's current law at each node:
0 = -iota1 + ic1
0 = -iota2 + ic2
and then the output responses are just the output divided by the input
(setting c = 1 since it doesn't matter in this case as we just want
the shape of the plot):
low = v2/v0 = (g^2)/(g^2 + g*k*s + s^2)
band = v1/v0 = (g*s)/(g^2 + g*k*s + s^2)
high = (v0 - k*v1 - v2)/v0 = (s^2)/(g^2 + g*k*s + s^2)
notch = (v0 - k*v1)/v0 = 1 - (g*k*s)/(g^2 + g*k*s + s^2)
peak = (v0 - k*v1 - 2*v2) = (-g^2 + s^2)/(g^2 + g*k*s + s^2)
And now for the digital implementation --
init:
v0 = v1 = v2 = 0;
v0z = v1z = v2z = 0;
process:
g = tan (pi * cutoff / samplerate);
k = damping factor (typically in the range 2 to 0, but damping can be > 2);
v0 = input;
v1 = v1z + g * (v0 + v0z - 2*(g + k)*v1z - 2*v2z) / (1 + g*(g + k));
v2 = v2z + g * (v1 + v1z);
v0z = v0;
v1z = v1;
v2z = v2;
outputs (the same as the analog circuit):
band = v1;
low = v2;
high = v0 - k*v1 - v2;
notch = high + low;
peak = high - low;
If the dampling and cutoff remain fixed then you can pre-compute the following:
gpk = 2*(g + k);
gv1 = g/(1 + g*(g+k));
and then process becomes:
v1z = v1;
v2z = v2;
v0 = input;
v1 = v1z + gv1 * (v0 + v0z - gpk*v1z - v2z - v2z);
v2 = v2z + g * (v1 + v1z);
v0z = v0;
which is is 7 adds and 3 mult
Andrew Simper
--
cytomic - sound music software
More information about the Synth-diy
mailing list