PM.Ladder~: Implementation of the Moog Ladder Filter
I’ve ported the ICST’s Moog ladder filter code to gen~. It self-oscillates and has built-in saturation, as well as extra modes such as bandpass, highpass, etc.
It’s also not the lightest thing in the world, CPU-wise, but it has a nice, warm sound to it.
I’ve also included a demo of a monosynth using it.
I am interested in Moog filters and thought about making one in Gen. Well, your version looks great, thank you very much. I will test it very soon.
Just one question about oversampling.
In the ICST paper they say that part of the algorithm should be oversampled by a factor of 2 (at least). See the details from page 28 here:
So should we use 2x oversampling? As far as I know gen~ does not support oversampling at the moment, so poly~ would be required for this. I did not study it in depth, but it should be possible to use a combination of gen~, poly~ and MSP for making an oversampled version of this filter. I will try it very soon!
Hi Julien, that particular filter algorithm uses internal oversampling. It’s not using a higher sampling-rate per se, but if you look at the calculation of the poles, you’ll see that that operation appears eight times instead of four, so it’s doing it twice as often. (8 poles @ 44.1 kHz vs 4 poles at 88.2 kHz) There’s a decimation filter that then down-samples the result. (check page 31)
My filter is adapted from their source code. I added some fixes for low-Q situations and added the additional filter modes.
Also, the ICST filter uses a fun trick for self-oscillation: it uses an envelope follower to control the volume of the self-oscillation, and you can use the self-noise from the anti-denormal table to generate output even without input. The paper describes how to add self-oscillation to other filters using this technique, IIRC. The other interesting side effect is that the volume of the self-oscillation is fairly constant regardless of the volume of the input, which allows for the peak control that I added.
@julien breval, Peter’s PM.Ladder~ is indeed what you want for great sounding, efficient and musical filtering. I am particularly in admiration of the ‘low-Q situations’ fix. and it is a great example of quasi in-code oversampling.
However, for learning sake, there is a more simple moog ladder implementation in the gen examples folder – start with the file called ‘gen~.moogladder.maxpat’. this example does exactly what you mention in your post – poly~ upsampling. the ‘moogLadderFilter.genexpr’ document demonstrates what has to be done to the samplerate maths inside the gen~. it is also an example of how simple it is to port Csound udo’s to GenExpr-land. i think you need 6.0.4 or later.
Thank you very much for your explanation about oversampling. From some quick tests, mostly as part of a classic envelope filter for instruments, it sounds great. I will try it for synthesis when I have some time.
Thanks for this other version of the Moog filter. It should help me a lot indeed because I still have no gen~ practice. It’s been a few weeks since I upgraded to Max 6, but no time at all at the moment!
Now that gen~ displays its bytecode (don’t know if that’s the actual term), it might be good for me to clean up the implementation at some point…