now this makes sense to me, gonna try it
(finaly this thing explained in a simple way without all the hardcore math symbols and terms)
You can use the technique from the KeepTopology paper for computing an initial value. This will give you perfect prediction for a linear system (no iterations necessary) and will probably still yield a good approximation for the practical nonlinear case.neotec wrote: It uses less CPU resources than I expected, and the only optimization I can think of at the moment is a nice prediction function for calculation of the initial iteration value.
Yep, I'm currently going through all the KeepTopology stuff again ... and discovered some neat thing. You can build a simple one-liner delayless integrator from this KeepTopology stuff (using a simple integrator, not the bilinear one and transforming the feedbacksolver a bit):karrikuh wrote:You can use the technique from the KeepTopology paper for computing an initial value. This will give you perfect prediction for a linear system (no iterations necessary) and will probably still yield a good approximation for the practical nonlinear case.
Code: Select all
buffer = (f * input + buffer) / (1.0 + f);Code: Select all
Starting with:
out += f * (in - out)
Rearrange:
out = out + f * (in - out)
The last out is the feedback, second out is our previous state (buffer):
out = buf + f * (in - out)
Now:
out = buf + f * in - f * out
Solving for out:
out + f * out = buf + f * in
(1 + f) * out = buf + f * in
out = (buf + f * in) / (1 + f)
No, what neotec is doing is called fixed point iteration to predict the current value of out. A fixed point of a (generally nonlinear) function f is a solution ofrola wrote:Is this the same as Newton-Raphson?
Code: Select all
b0 = (b0 + f * input) / (1 + f)
b1 = (b1 + f * b0) / (1 + f)
b2 = (b2 + f * b1) / (1 + f)
b3 = (b3 + f * b2) / (1 + f)Code: Select all
out = integrator3( integrator2( integrator1( integrator0( input - out * r ) ) ) )Code: Select all
out = (b3 + f * ((b2 + f * ((b1 + f * ((b0 + f * (in - out * r)) / t)) / t)) / t)) / tCode: Select all
out = (b3 * g0 + b2 * g1 + b1 * g2 + b0 * g3 + in * g4) / g5Code: Select all
g0 = t^3
g1 = f * t^2
g2 = f^2 * t
g3 = f^3
g4 = f^4
g5 = t^4 + f^4 * rIf you want you can replace all the integrators with the bilinear variant. The feedback is solvable for any linear system and since bilinear transform maps an analog filter exactly (except warping the frequency axis) to a digital filter you can have not just perfect tuning (using tan(w/2) prewarp as usual) but also exact feedback gain.neotec wrote:So, as the integrator is now delayless I started to make the feedback path delayless.
[...]
... and now we're back at having an awful lot of variables... but reduced iteration count (1-2 using hard clipper), better stability on lower oversampling ratios and perfectly tuned when 'f = 1-exp(-2PI*fc/fs)' and 'r' still needs the gain correction factor: r = q * (1 + f * PI), where q is in [0.0, 4.0].
Another things: For full self oscillation (using only a Dirac function as input) we still need high oversampling (fs > 10*44100) ... have to check what causes this behaviour.
Thanks, I will try the bilinear integrators.mystran wrote:If you want you can replace all the integrators with the bilinear variant. The feedback is solvable for any linear system and since bilinear transform maps an analog filter exactly (except warping the frequency axis) to a digital filter you can have not just perfect tuning (using tan(w/2) prewarp as usual) but also exact feedback gain.
Code: Select all
out = buf + f * in
buf = f * in + outCode: Select all
pin = in - (f * in + buf) / (1 + f)
out = buf + f * pin
buf = f * pin + out
Code: Select all
f = tan(PI * fc / fs)Code: Select all
buf = saturate(f * pin + out)Wait a minute. This would work if you have a nice analytic formula for the non-linearity, and just throw it in with the rest of the stuff before you solve the feedback, but doesn't it fall apart if you need stuff like absolute values or hard-clip guards with the non-linearity?neotec wrote: The interresting thing is that you can put all kinds of non-linearities on the buffers and still have a totally predictable filter (using e.g. the formula I provided)
The feedback solver only works with buffer values, input and resonance factor. As long as you don't mess around with the filter input (input - r * feedback) or with the integrator input you can do everything you want with the buffers.mystran wrote:Wait a minute. This would work if you have a nice analytic formula for the non-linearity, and just throw it in with the rest of the stuff before you solve the feedback, but doesn't it fall apart if you need stuff like absolute values or hard-clip guards with the non-linearity?
Code: Select all
double out = b3 * g0 + b2 * g1 + b1 * g2 + b0 * g3 + input * g4;
final double tin = (input - out * r);
final double in0 = tin - (f * tin + b0) * f2;
final double c0 = b0 + f * in0;
b0 = hardClip(f * in0 + c0);
final double in1 = c0 - (f * c0 + b1) * f2;
final double c1 = b1 + f * in1;
b1 = f * in1 + c1;
final double in2 = c1 - (f * c1 + b2) * f2;
final double c2 = b2 + f * in2;
b2 = f * in2 + c2;
final double in3 = c2 - (f * c2 + b3) * f2;
final double c3 = b3 + f * in3;
b3 = softClip(f * in3 + c3);
// f2 = 1.0 / (1.0 + f)
// g0..4 were pre-divided by g5Submit: News, Plugins, Hosts & Apps | Advertise @ KVR | Developer Account | About KVR / Contact Us | Privacy Statement
© KVR Audio, Inc. 2000-2026