Steiner Parker filter topology

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

camsr wrote:Small typo in Step 6, ic1eq and ic2eq were replaced with iceq1 and 2 respectively.
Ooopsie, also in Step 1. Fixed!

Post

Urs wrote: Note: I think this is only stable up to below Nyquist/2, possibly due to its unbuffered nature. You'll need 4x oversampling if you want to allow for screaming resonance.
Wondering were the instability comes from? Does this happen in the s-plane too? The 4x Oversampling that you'll need for the non-linearities in anyway makes this moot, but just wondering... :shrug:

Post

Ichad.c wrote:
Urs wrote: Note: I think this is only stable up to below Nyquist/2, possibly due to its unbuffered nature. You'll need 4x oversampling if you want to allow for screaming resonance.
Wondering were the instability comes from? Does this happen in the s-plane too? The 4x Oversampling that you'll need for the non-linearities in anyway makes this moot, but just wondering... :shrug:
Well, the non-linearities are kind of delayed by one sample with this method. The non-buffered nature makes it kind of a double-feedback system - more unpredictable than a buffered Sallen-Key filter. Sounds pretty funky though ;-)

You need an iterative solver to get *correct* (delayless) non-linear behaviour, and this gurantees stability. Alternatively, using a look-up table for stable maximum resonance has worked well for me - just gradually lower resonance above 8k until it's down below 2…

(We've got papers on iterative solvers that are almost ready to go… just need some linguistic tweaks to make them sound right…)

Post

As far as stability goes, actually just doing a single iteration is usually enough. :P

edit: that is, assuming some reasonably well-behaved sigmoid non-linearity or some such .. other things can be more problematic

edit2: also as a debugging tip, when observing stability issues one can set such cheap non-linearities to 1 (or whatever would be the value around zero) and then try running the filter (now fully implicit as a linear filter) and if it blows up with finite Q then there is some problem unrelated to the non-linearities

Post

Urs ... show us an alpha version and let it be debugged later ;)

I'm so curious..
For now I use quadratic sigmoids (instant solution) for internal nonlinearities and iterative approach for loops around them.
This works good @ sr 2x.

Haven't tried glorious Mystran's method yet, but intuitively it needs higher oversampling to "slow down" the signal enough. Can't wait to give it a try :)
giq

Post

mystran wrote:As far as stability goes, actually just doing a single iteration is usually enough. :P

edit: that is, assuming some reasonably well-behaved sigmoid non-linearity or some such .. other things can be more problematic

edit2: also as a debugging tip, when observing stability issues one can set such cheap non-linearities to 1 (or whatever would be the value around zero) and then try running the filter (now fully implicit as a linear filter) and if it blows up with finite Q then there is some problem unrelated to the non-linearities
I must admit, while we use the Cheap method a lot druing the design phase, I still haven't quite figured out what a correction step for the Cheap method looks like in practice. I assume it's like this:

get tmpF1-tmpFx from each state variable
create tmp state and run filter( x[n] ) on tmp state, using tmpF1-tmpFx
get F1-Fx from each tmp state variable
run filter( x[n] ) on actual state, using F1-Fx

Post

Urs wrote:
mystran wrote:As far as stability goes, actually just doing a single iteration is usually enough. :P

edit: that is, assuming some reasonably well-behaved sigmoid non-linearity or some such .. other things can be more problematic

edit2: also as a debugging tip, when observing stability issues one can set such cheap non-linearities to 1 (or whatever would be the value around zero) and then try running the filter (now fully implicit as a linear filter) and if it blows up with finite Q then there is some problem unrelated to the non-linearities
I must admit, while we use the Cheap method a lot druing the design phase, I still haven't quite figured out what a correction step for the Cheap method looks like in practice. I assume it's like this:

get tmpF1-tmpFx from each state variable
create tmp state and run filter( x[n] ) on tmp state, using tmpF1-tmpFx
get F1-Fx from each tmp state variable
run filter( x[n] ) on actual state, using F1-Fx
This confuses the crud out of me too. :scared: Maybe this would work?

http://en.wikipedia.org/wiki/Heun%27s_method
Wiki wrote:Heun's method is a predictor-corrector method with forward Euler's method as predictor and trapezoidal method as corrector
Basically you overestimate and underestimate and then use the middle of the two (?)

Post

mystran wrote: edit2: also as a debugging tip, when observing stability issues one can set such cheap non-linearities to 1 (or whatever would be the value around zero) and then try running the filter (now fully implicit as a linear filter) and if it blows up with finite Q then there is some problem unrelated to the non-linearities
Nice tip :tu:

Post

I think I got it.. the best lesson I've got this year :)

One question:
I assume you use tanh for educational purposes? There are diodes not ota so the saturation curve should be very different. Am I right?
giq

Post

itoa wrote:I think I got it.. the best lesson I've got this year :)

One question:
I assume you use tanh for educational purposes? There are diodes not ota so the saturation curve should be very different. Am I right?
Well, the "real" Steiner-Parker schematics have that differential path with two diodes on each side. If I remember correctly from Tom Stinchcombe's analysis of the Diode ladder, the differential pairs of diodes pretty much add up to a very tanh-ish shape. Such as, if you did the maths of the real Steiner-Parker, you'd end up with a non-linearity of the type of

(e^x - e^-x)/(e^x + e^-x)

which *is* tanh(x)

Of course, the world is never ideal. Feel free to use any shape you like, as long as it clamps the signal somewhere. The true challenge of analogue modeling isn't translating the schematics into workable equations, but to tweak the strength and shape of the non-linear elements to sound good.

Post

Thanks,

As for sigmoids, I've been playing with Desmos and came to this simple idea of variable steepness wave shaper:
https://www.desmos.com/calculator/yg2fhyye4j

It's like variable depth box filtering of clamped line.. and its 1st order, we can go deeper and perform this process recursively
giq

Post

itoa wrote:Thanks,

As for sigmoids, I've been playing with Desmos and came to this simple idea of variable steepness wave shaper:
https://www.desmos.com/calculator/yg2fhyye4j

It's like variable depth box filtering of clamped line.. and its 1st order, we can go deeper and perform this process recursively
very cool!

Post

Z1202 wrote:
itoa wrote:btw. Did I get it right? VA model of unbuffered RC pair is 2 one pole filters with different cutoff frequencies?
Not sure, but intuitively I would expect some feedback from the 2nd stage into the 1st or something like that (unless you ignore the topology of the filter and simply try to simulate the transfer function).
Edit: I probably misunderstood you. I thought you're talking about two RC pairs. If it's one pair, then it should be one 1-pole filter. Not sure about the coupling, but I guess it will be represented as extra feedbacks to/from the neighboring parts of the structure. A general rule is: one integrator/pole per one capacitor or inductor.
itoa: With unbuffered RC pairs you get a two pole filter with more damped response, so the cutoff remains the same, but the damping (1/Q) changes:

single RC (R and C set to 1): h(s) = 1/(1 + s)
unbuffered twin RC (R and C set to 1): h(s) = 1/(1 + 3 s + s^2)
buffered twin RC (R and C set to 1): h(s) = 1/(1 + 2 s + s^2)

nodal equations for single RC:
0 == 1/R (v2 - v1) + s C (v2 - 0)
hs == v2/v1

nodal equations for unbuffered twin RC:
0 == 1/R (v2 - v1) - 1/R (v3 - v2) + s C (v2 - 0)
0 == 1/R (v3 - v2) + s C (v3 - 0)
hs == v3/v1

nodal equations for buffered twin RC:
0 == 1/R (v2 - v1) + s C (v2 - 0)
0 == 1/R (v3 - v2) + s C (v3 - 0)
hs == v3/v1
The Glue, The Drop, The Scream - www.cytomic.com

Post

Urs wrote:...
Then for each sample replace gR1 by tanh(ic1eq)/ic1eq, gR2 by tanh(ic2eq)/ic2eq and res by tanh(V2)/V2, each using the previous sample.

Unfortunately, maybe due to the unbuffered nature, you'll need 4x oversampling to make it stable enough for high resonance.
Hey Urs, you may want to check your math, the only place I can see a Tanh come up in the Steiner Parker filter is in the control current from the differential pair of transistors, but that only affects tuning, but not by much since it is kept in the linear region.

ps: but don't let that stop you adding arbitrary non-linearities if they sound good, even if they aren't accurate to anything in the original circuit!
The Glue, The Drop, The Scream - www.cytomic.com

Post

andy-cytomic wrote:
Urs wrote:...
Then for each sample replace gR1 by tanh(ic1eq)/ic1eq, gR2 by tanh(ic2eq)/ic2eq and res by tanh(V2)/V2, each using the previous sample.

Unfortunately, maybe due to the unbuffered nature, you'll need 4x oversampling to make it stable enough for high resonance.
Hey Urs, you may want to check your math, the only place I can see a Tanh come up in the Steiner Parker filter is in the control current from the differential pair of transistors, but that only affects tuning, but not by much since it is kept in the linear region.

ps: but don't let that stop you adding arbitrary non-linearities if they sound good, even if they aren't accurate to anything in the original circuit!
Well, the whole topology of a "real" Steiner-Parker filter is differential, much like a diode ladder, but without shared capacitors between the stages. I guess this is called "diode ring". I'm not sure if tanh() is correct at all for pairs of diodes, but I'd intuitively say that each stage - when simplified into a non-differential form - adds a nonlinearity.

As always, finding the right non-linearity and balancing them (gain staging) of each is what makes the filter sound.

Post Reply

Return to “DSP and Plugin Development”