Cheap non-linear zero-delay filters

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

more in line with the main subject of the thread;

http://soundcloud.com/aciddose/ota-four-pole

this is the filter the code mystran posted i would assume is meant to emulate. this is a series of four lm13700 stages with nfet buffers. the circuit is configured the same as the standard roland filters ala sh-101, mc-202, juno-60, etc.

the inputs are not biased - all distortion is present. the feedback is clipped with a diode pair as usual. feedback clipping is at +12db from the input signal. (so not 2, but 4, again as in most roland filters.)

the diode saturation does not match tanh - neither does the saturation applied by the current mirrors and differential pair in the OTA stages. tanh isn't even a very reasonable approximation.

the error in the code posted is so high that even with the proper functions and oversampling it still doesn't produce very accurate results. i'm not sure why.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

aciddose wrote: the error in the code posted is so high that even with the proper functions and oversampling it still doesn't produce very accurate results. i'm not sure why.
Hey aciddose, I don't think that mystran intended for it to be an accurate model, he mentions a couple of times that he is neglecting and oversimplifying things. This thread, IMHO, is about trying to bridge the gap, between people like you -> who intrisically understand Euler, EE, and Trapezoidal intergration, and the people like me who stuggle with the concepts and the math parts. I like the fact that it's simplified, written from a c++ actual code perspective, and never once does he use complex numbers, it makes it much easier to digest the information.

Probably, given some time - mystran could probably make that filter sound awesome, but I don't think that's his intention behind this thread.

On a random note, I do love that pad-ey sound from your sound examples btw, and the filters obviously sound good too.

Regards

Post

aciddose wrote: the diode saturation does not match tanh - neither does the saturation applied by the current mirrors and differential pair in the OTA stages. tanh isn't even a very reasonable approximation.

the error in the code posted is so high that even with the proper functions and oversampling it still doesn't produce very accurate results. i'm not sure why.
What are the correct saturation functions for this filter?

Post

there are a few differences. the most significant is that you need to bias the input by about -0.05 to introduce some even harmonic if you want to match the lm136/7 or ca3080 or ba662 and ir3109, which all use nearly identical cores.

the difference increases however because of the buffers used on each stage. in the ba662 and ir3109 the buffers aren't just transistors and the effect on the total function is a little more complex.

the full function could in theory be quite accurately matched using several combined tanh curves at various depths and offsets. using a single one doesn't cut it, however.

when i said i can't eliminate the error enough to accurately reproduce the basic ota circuit's response, that was actually an honest question. it wasn't rhetorical. "i don't know why." i hope somebody can find out why and document the error in the feedback computation (or other sources of error) so we can make it possible to adjust it. perhaps the function needs additional history added to it? would doubling the computational expense double the accuracy?
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

aciddose wrote: the difference increases however because of the buffers used on each stage. in the ba662 and ir3109 the buffers aren't just transistors and the effect on the total function is a little more complex.

the full function could in theory be quite accurately matched using several combined tanh curves at various depths and offsets. using a single one doesn't cut it, however.
So tanh going into tanh with offset, scale etc. + a DC offset on the input?
aciddose wrote: when i said i can't eliminate the error enough to accurately reproduce the basic ota circuit's response, that was actually an honest question. it wasn't rhetorical. "i don't know why." i hope somebody can find out why and document the error in the feedback computation (or other sources of error) so we can make it possible to adjust it. perhaps the function needs additional history added to it? would doubling the computational expense double the accuracy?
Have you tried using a correction step as described in Mystrans first post? That might help with accuracy.

Post

rola wrote:Have you tried using a correction step as described in Mystrans first post? That might help with accuracy.
no. i don't think adding the additional step would make much of a difference compared to extra oversampling, which doesn't correct the response.

the oversampling works great in the linear case.

i think the real issue is there is some element missing from this model.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

rola wrote:Have you tried using a correction step as described in Mystrans first post? That might help with accuracy.
If I'm not mistaken, the sound of the correction step can be evaluated without actually coding it, simply by choosing a high enough sample rate. Put differently, if the sound doesn't change substantially using a much higher sample rate, there's no need for the correction step.
aciddose wrote:the diode saturation does not match tanh - neither does the saturation applied by the current mirrors and differential pair in the OTA stages. tanh isn't even a very reasonable approximation.
This is what I suspected earlier in the thread. Meanwhile I did some more measurements on a SH-2, this time using its internal oscillators and I still don't see any nonlinearities at least in the feedforward path (using maximum gain). But realism aside, what I'm mostly looking for is a way to reduce the aliasing to avoid 4x-8x oversampling.

Richard
Synapse Audio Software - www.synapse-audio.com

Post

almost all the aliasing is due to the extreme application of the tanh function. back it off a ton. you can either as mystran mentioned just scale down the input, or you can use another function.

i prefer to use another function because you can actually replace it with 1 - x * abs(input), which is a whole lot cheaper, and oddly the harmonics generated are really very similar.

i don't think there is any way to eliminate the aliasing. unless there is some type of integration which applies band-limiting via some kind of awesome magic.

the sh-2 filter is identical to the one i used in the "ota-four-pole" clip. same everything. absolutely identical.

you should be able to measure significant harmonics.

do this:

1khz sine input
- set feedback to zero
- adjust frequency to maximum

measurement should be near-zero thd.

- adjust frequency to half-way on the cutoff control, which is about 1khz

you should get:

1: -50db
2: -30db
3: -90db
4: -70db

from then on they'll fall below the noise floor.

lower cutoff will move the harmonics around but the level will be low, so it'll become difficult to identify them against the noise floor.

oh, i assume you have the tools to do that. otherwise it's a bit difficult.

because the thd is so low - it's practically non-existent - you can't measure it with any harmonics from the pulse/ramp waveforms because those harmonics will already be far above those levels. you might be able to measure the difference on the ramp waveform, but i doubt it.

i own the sh-09 which is almost identical to the sh-02.

so we're only concerned about harmonics added per-stage in terms of their subtle effects on high feedback levels and self-oscillation. the effect will tend to be the addition of 2nd and 4th harmonics on top of the mostly odd harmonics already generated by the diode clipping. the diode clipping isn't perfectly odd either though, because the output isn't perfectly centered. the same -0.05 offset might be a little too much, i haven't worked on that section yet.

so this is why i initially wanted to remove all the per-stage non-linearity. without it, the filter becomes equally as efficient as my existing 24db filter - except that in order to become as stable it requires at least 2x oversample. at 4x it out-performs my implementation unsurprisingly as it's using 4x as much processing power to compute.

even all this considered however i can't get the same response even when tweaking the saturation functions to be as close as possible to the circuit. the computation of the 4th integrator state seems to fail in some way related to the non-linearity which isn't corrected by mere oversampling.

i'm interested to try the correction step but the expense becomes ludicrous.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

Richard_Synapse wrote:
rola wrote:Have you tried using a correction step as described in Mystrans first post? That might help with accuracy.
If I'm not mistaken, the sound of the correction step can be evaluated without actually coding it, simply by choosing a high enough sample rate. Put differently, if the sound doesn't change substantially using a much higher sample rate, there's no need for the correction step.
Not quite. The trick is that for typical non-linearities, the evaluated conductance will be either too high or too low. The error goes down as a linear function of step-size. The correction strategy I proposed relies on the predicted value to give an opposite error, which (if I'm not mistaken) should cancel the error in second derivative, which means error goes down as a square of step-size.

So basically it's a question of whether the O(1/samplerate) term is the dominant error term: if the error from aliasing is more significant than the error integration error, then you should oversample. If the integration error dominates aliasing related issues, then you should probably do a corrective step.

I don't know if that's the best possible way to correct it, nor have I bothered with formal analysis, but intuitively that's how it should work.

Post

aciddose wrote: the difference increases however because of the buffers used on each stage. in the ba662 and ir3109 the buffers aren't just transistors and the effect on the total function is a little more complex.
I think I mentioned earlier that I assumed "ideal opamp" buffers. I'm certainly aware that this isn't a reasonable approximation for individual transistors or other simple constructs. The reason I did that, is because it allows us to side-step two important issues:

1. We're assuming transconductance is a function of input voltage only (ie there is a designated "input pin" and the conductance doesn't depend on the "output pin" in any way). That's why it's cheap.

2. If we have non-linearities that depend on other non-linearities directly (instead of just capacitor voltages), then we'd have to do dependency analysis to figure out what order to calculate then and solve conductance on the way. In the worst-case of circular dependencies (which is what happens in every real circuit) we either need an N-dimensional non-linearity or we're back to iterative solutions.

Post

it does work fine, it's just that it's far too much and unrealistic in terms of real world circuits.

you could in theory construct a circuit to produce the perfectly odd harmonic result at that strength, but you'd need a lot of extra biasing and you'd need to increase signal levels by about ten times to each input.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

aciddose wrote:so this is why i initially wanted to remove all the per-stage non-linearity. without it, the filter becomes equally as efficient as my existing 24db filter - except that in order to become as stable it requires at least 2x oversample. at 4x it out-performs my implementation unsurprisingly as it's using 4x as much processing power to compute.
Indeed the sound gets a lot closer to the real OTA ladder by removing the stage nonlinearities, thanks for the tip!

I wonder about the transistor ladder though, this might be a topology which distorts the input more in line with tanh.

Richard
Synapse Audio Software - www.synapse-audio.com

Post

most of the distortion in the ladder should come from the differential pair's inputs. the signal flowing through the transistors in each stage should be mostly linear although yes it does have some effect.

then you'll have the distortion from the output buffer as well, it's another differential amplifier. the whole circuit is actually comparable to a single ca3080 ota in terms of distortion. the vcf-vca in the minimoog then are more about applying a scaled tanh at the input and output than per-stage as well. i've always found the idea of applying it at such a high level per-stage a little ridiculous and wondered where anyone came up with the idea to do so.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

I think there was a mistake in Karrikuhs version of the OTA ladder. This one here is stable up to at least 0.49*Samplerate and doesn't have any strange artifacts.

Mystrans OTA ladder:

Code: Select all

r' = r / (1.458 * 1.96) ~ r / ( 2.86 ) 

 dV0/dt = f * tanh( 1.1 * in - r' * tanh(1.96 * V3) - v0) 
 dV1/dt = f * tanh( 1.1 * v0 - v1 ) 
 dV2/dt = f * tanh( 1.1 * v1 - v2 ) 
 dV3/dt = f * tanh( 1.1 * v2 - v3 ) 
Unoptimized implementation:

Code: Select all

   
    m1 := 1.1;
    m2 := 1.96;

    f := Tan(Frequency*Pi);
    r := Resonance * 1.7;

 
    ih := 0.5 * (inp + zi);
    zi := inp;

    // evaluate the non-linear gains 
    tfb := tanhxdx(m2*s3);
    t0 := tanhxdx(m1*ih - s0 - r*m2*tfb*s3);
    t1 := tanhxdx(m1*s0 - s1);
    t2 := tanhxdx(m1*s1 - s2);
    t3 := tanhxdx(m1*s2 - s3);

    // g# the denominators for solutions of individual stages 
    a0 := f*t0;
    a1 := f*t1;
    a2 := f*t2;
    a3 := f*t3;

    g0 := 1 / (1 + a0);
    g1 := 1 / (1 + a1);
    g2 := 1 / (1 + a2);
    g3 := 1 / (1 + a3);

 y3 :=
(g3*s3+a2*a3*g1*g2*g3*m1*m1*s1+a1*a2*a3*g0*g1*g2*g3*m1*m1*m1*s0+a0*a1*a2*a3*g0*g1*g2*g3*m1*m1*m1*m1*inp+a3*g2*g3*m1*s2)/
      (a0*a1*a2*a3*g0*g1*g2*g3*m1*m1*m1*m2*r*tfb+1);

   xx := m1*inp - r*tfb*m2*y3;
   y0 := (s0 + a0 * xx) * g0;
   y1 := (s1 + a1 * m1*y0) * g1;
   y2 := (s2 + a2 * m1*y1) * g2;

    // update state        
    s0 := s0 + 2*a0*(xx - y0);
    s1 := s1 + 2*a1*(1.1*y0 - y1);
    s2 := s2 + 2*a2*(1.1*y1 - y2);
    s3 := s3 + 2*a3*(1.1*y2 - y3);

Post

Richard_Synapse wrote:In the ladder filters the output gets fed back to the input, but this doesn't seem to work well for a two-stage 12dB filter (maybe there's a way but I haven't seen it yet)
When you apply negative feedback around second order LPF you get this (after normalisation of transfer function):

H(s) = (1/(1+a))*(1/(1 + 2*s/(1+a) + s^2/(1+a) ))
where a is feedback gain.

Compared it to canonical representation of second order lowpass:
1) you need a lot of feedback to get resonance levels expected fro synth filters (at least 20dB of gain, 40dB more likely to get usual range)
2) it will start to selfoscilate at infinite loopgain
3) it will start to detune when you increase feedback; resonant frequency shifts up ( Wp = Wop*sqrt(1+a))
4) passband gain is decreased when you increase feedback (by 1/(1+a)); in 4p filter you get self oscilation at loopgain of 4, here you get mild squelch at loopgain of 10

in digital domain it is feasible to make such resonant filter because you can compensate for both pass band gain and filter detune, but it is a bit costly (because you need 1/sqrt() for cutoff compensation)
Richard_Synapse wrote:When a signal is driven through the Korg35 chip, it seems to affect both the cutoff and resonance, which is truly weird.
That's perfectly normal. Salen-Key topology has highest sensitivity to component variation of all "classical" filter topologies (that's why you will not see many high-Q SK filters around). In K35 filter overdrive will cause high modulation of dynamic resistance of junctions (which combined with caps determines tuninig) and loopgain of resonance path (and resonance is already highly dependant on core RC sections) .

Post Reply

Return to “DSP and Plugin Development”