If I read Zavalishin correctly,I think you have the saturators (atan()) in the wrong place which is limiting the feedback too much. I’ll take a closer look when I get a chance.

I don’t think so. Either function will serve as a saturator. I think it’s a minor problem with gain in the feedback loop(s). The structure of the filter looks OK.

I had a chance to have a closer look at your filter this morning and noticed that your calculation for g wasn’t correct. g=wc*T/2 where wc is the circular frequency for the cutoff, and T is the sample period. In this case g does not represent gain. I modified the formula and the filter became very unstable. I realized that the structure you’ve used isn’t the TPT form of the overall ladder. Zavalishin has a habit of oversimplifying his block diagrams and leaving out the “messy” details. I found Will Pirkle’s paper: AN-4VirtualAnalogFilters.pdf (1.0 MB) to be a much better guide to constructing filters. He uses Zavalashin’s design but goes into much greater detail. Here’s his block diagram for the ladder:

You can see that the feedback loop is considerably more complex than it would appear from figure 4.12 in Zavalishin’s work, but instead is closer to figure 4.17.
I built a model using Pirkle’s work, but only used a single tanh() saturator in the main feedback loop. It should be possible to modify the design to put saturators inside each single pole unit and use atan() instead.
This is my model: uLad V1.1.audulus (145.1 KB)

I find Zavalashin’s work to be a bit hard to follow at times. I know he mentions needing to solve the non-linear equations, but from a computational load perspective I’m not sure that using a more sophisticated approach is worthwhile. I know our approach is only an approximation and I haven’t tried using saturator functions in the individual 1 pole sections in the ladder, but I got pretty good results with a single saturator in the primary feedback loop. It would be nice to have a z-2 (or z-n) node since there are additional filter types we could construct.

I did that to add some drive no matter what filter pole or resonance setting you had. I’m definitely lost by it, and I’m just trying to grasp the diagrams haha. This Pirkle paper seems just what I was looking for though! Thanks

I know what you mean. I tried building something from Zavalashin’s paper and got nowhere. Pirkle’s diagrams are much easier to understand, and his intro is a little easier to handle. Zavalishin assumes that the math is trivial, but it’s been a loooong time for me and it’s definitely a struggle. Even Pirkle’s design, which is just Zavalashin’s better explained, was a chore to put together. You should be able to pick off the outputs of the individual filters in the same way you are doing now and insert the saturators into the internal feedback loops per Zavalishin. Feel free to use the guts of the one I sent you if it makes life easier.

Really interesting paper, Urs Heckmann is such an awesome guy! I randomly talking with him in a youtube video comments section without realizing who he was and I gotta say, I like the way he thinks.

I’m curious how automatically solving the feedback loops would work. Would we still construct patches from the more familiar z-1 block diagrams? Would it affect non-audio rate feedback loops for things like counters or Markov chains?

Excuse my naïveté - I have a lot to learn I assumed that setting a1=0, a2=0, a3=1, b1=0, b2=0 would give me out[n] = in[n-2]. Oh well, back to playing and learning.

I saw @biminiroad’s post with the sample delay module. It should work in theory but rounding errors in the division could potentially cause problems. By including the z-1 node, you would force the circuit into single sample processing mode which would probably be necessary for a useable filter. I can’t think of an easy way to test it. I’m hoping that V4 will have a built-in z-2 node

Neat idea! The biquad node does use z-2 so you should be able to extract it by setting the co-efficients as you describe. You would probably still need to use a z-1 node to force single sample mode.