From the original SynthMaker forum (2004–2014), with its members’ names and dates.
rl ·
The following filter code is a translation of the CSound opcode posted at http://www.kunstmusik.com/udo/cache/moogladder.udo
which is based on the paper "Non-Linear Digital Implementation of the Moog Ladder Filter" by Antti Houvilainen (author of Asynth and Augur)
Copy and paste the code below into the code component.
You can do some adjusments for cutoff and resonance range by changing the values of cfScale and resScale. The settings below have been used to replace the filter in the example.osm synth.
Pls. note that the code is a bit messy, since it workarounds a couple of restrictions and minor bugs of the code component
polyin input;
polyin cutoff;
polyin resonance;
polyout sigout;
// filter based on the text "Non linear digital implementation of the moog ladder filter" by Antti Houvilainen
// resonance [0..1]
// cutoff from 0 (0Hz) to 1 (nyquist)
// constants
float pi; pi = 3.1415926535;
float v2; v2 = 40000; // twice the 'thermal voltage of a transistor'
float sr; sr = 22100;
float cfScale; cfScale = 10;
float resScale; resScale = 1.3;
// helper vars
float x; // temp var: input for taylor approximations
float denum; // temp vars to split complex expressions into simpler ones
float exprPos; // bug in code parser?
float exprNeg;
float expOut; // output of approximations
float tanh1Out;
float tanh2Out;
rl wrote: Pls. note that the code is a bit messy, since it workarounds a couple of restrictions and minor bugs of the code component
Do we know about these? Feel free to remind us.
EDIT: just saw your other post on these, thanks.
Shifrin ·
Thanks for this, going to have a look (listen 😉 ) now 😀
Shif.
Tom7777 ·
As im a beginner in coding could you if possible please give some examples on how you converted certain parts as the SM version is very very different to the Csound code. Or did you use a convertion tool to help you? Seems like you know alot more about the coding modules than i currently do hehe 🙂 Thanks
jorge ·
wow rl, thanks a lot. I replaced the old moog code in the example schematic with your code, it sound really great:
zip:[old link]
rar:[old link]
rl wrote: Pls. note that the code is a bit messy, since it workarounds a couple of restrictions and minor bugs of the code component
Didnt sound messy at all and that's what matters the most.
lalo ·
well...simply...AMAZING!!!
great rl...
if i stay away from SM for a week is like a light-year 😉
congrats
lalo
rl ·
Tom7777 wrote: As im a beginner in coding could you if possible please give some examples on how you converted certain parts as the SM version is very very different to the Csound code. Or did you use a convertion tool to help you? Seems like you know alot more about the coding modules than i currently do hehe 🙂 Thanks
basically it's the same code, manually converted into C-style syntax. The little magic is the approximation code for exp and tanh.
exp(x) uses the usual taylor series - for the range used more coefficients are needed for the desired accuracy.
the usual taylor approximation for tanh(x) turned out to be totally inaccurate, so I used the fact that tanh(x) can be expressed as (exp(x) - exp(-x))/(exp(x) + exp(-x)), which can be written as 1 - 2 / (exp (2*x) + 1) again using taylor for exp(2x), giving reasonable good results for x >=0 and using the fact that tanh is an odd function, thus tanh(-x) = -tanh(x) for x <0
The code can be further optimized, e.g. instead of dividing numbers you can multiply the inverse of the number, or by forming some terms into multiply-add operations, e.g.
expOut = 1 + x + x*x/2 + x*x*x/6 + x*x*x*x/24 + x*x*x*x*x/120 + x*x*x*x*x*x/720;
->
= 1 + x ( 1 + x ( 1/2 + x ( 1/6 + x (1/24 + x ( 1/120 + x/720 ) ) ) ) )
the latter expression uses only 5 multiplications and 6 adds (not counting the divides) , the former uses 15 MUL and 6 ADD;
Tom7777 ·
Thanks 🙂
dharma one ·
cool, i really like how the moog filter sounds like in antti's asynth. i tried to use this for audio processing, but it sounds really grainy...
i just wire up an audio input to this filter module and connect that to audio output and exported that as vst.
for controlling resonance and cutoff i connected two knobs (float output) to the cutoff and reso inputs of the filter module. it says in the comments
this takes values from 0-1 as input and the knob seems to give out 0 to 1 floats
any ideas what i'm doing wrong?
rl ·
dharma one wrote:
any ideas what i'm doing wrong?
The filter was tuned to be an replacement for the filter of the famous example.osm. I suggest you experiment with the cfScale and resScale variables. The grainyness has also to do with the quality of the approximations. It's a tradeoff between accuracy and speed. You could try to add more terms to the approximations for exp and tanh
Josh ·
Ha! Just when you think you've seen it all
What would be nice is if the filter actually worked lol. Example moog doesn't make any sound and the filter code is mostly black...
AngularMomentum ·
Electrogravtiy wrote: Ha! Just when you think you've seen it all
What would be nice is if the filter actually worked lol. Example moog doesn't make any sound and the filter code is mostly black...
Same here, next to that the example.osm posted here does not contain any graphics when I load it up.
Tom7777 ·
Well what do you expect guys this is quite an old topic now started - Sun Mar 20, 2005 😉 The program has changed alot over time. Im guessing this isn't the only old example which doesn't work now 😀
Josh ·
Perhaps one of you code geniuses can fix it. Ladder filters seem to be pretty much the buisiness. Even the virus uses them.
A high pass version would be cool too.
oddson ·
A very small change to the constants section is all that's needed to get rid of the compile errors:
// constants
float pi = 3.1415926535;
float v2 = 40000; // twice the 'thermal voltage of a transistor'
float sr = 22100;
float cfScale = 10;
float resScale = 1.3;
Josh ·
Woo Hoo. Cool
Cheers oddson
😀
AngularMomentum ·
Thanks Oddson, filter sounds nice indeed!
oddson ·
Don't thank me... I only spent 2 minutes on this... (all Kudos to Rudolph!)
The Code component will not allow any variable declarations after an assignment has occurred unless the assignment is part of the declaration.
If you see any more old code that won't compile look for this as a potential culprit.
Tom7777 ·
Yeah basically you just need to put all the floats to the top after the ins and outs and the old examples should work ok then 😀
rl ·
Here's more Moog. This time a port of the famous Stilson/Smith algorithm from music-dsp:
I replaced the lengthy gaintable by a simple polynomial approximation. The code is written for clarity and works. There is always room for some optimization though.
----------------
there should also be noted that there there is a much better implementation of the algorithm of my original post developed by sambean in this forum.
Tom7777 ·
Nice, thanks rl, im guessing this is a lowpass? as the output says lowpass hehe 😀 I thought i should ask though, can you have moog HP BP BR ect also? i don't think i have seen any yet 🙂
Josh ·
Has anyone got the new filter to work? I just get an audible click.
Btw what should the sample rate look like? I used 44100....
oddson ·
Works for me rlfilter.osm
rl ·
Thanks for the example. I was just too lazy to upload one 😊
Some tweaking tips:
- between Cutoff knob and "0-1 to Hz" multiply the cutoff with itself, so there is more control in the lower frequency range
- replace
float satLimit=0.95;
with
streamin satLimit;
to have control over the saturation.
- crank up resonance and sat Limit to higher values [0..2] for nasty bass sounds
- try tanh or sqrt limiting instead of clamping
- use
loop (3) {
for 3 pole 18 dB "computer controlled transistor bass" sounds
cheers, Rudolf
________________________
"all your base is belong to us"
Josh ·
Cheers oddson...again lol
Whoa the filter sounds good 😍
Thanks RL ....303 here we come he he he
stefan ·
rl wrote: Thanks for the example. I was just too lazy to upload one 😊
Some tweaking tips:
- between Cutoff knob and "0-1 to Hz" multiply the cutoff with itself, so there is more control in the lower frequency range
Or multiply cutoff with 140 or so and feed it into a pitch2freq converter!
Josh ·
How would I go about oversampling it?
Kingston ·
I had a look at the code module and thought of a simple optimisation,
I didn't count how many MULTs, DIVs and ADDs that saves but quite a lot! 😀 (like hundreds!!)
Both functions are equal by the way, except for maybe that 2.666666667 bit (cuz it's 4/1.5). I don't know what the resolution allowed is, before denormals start to happen.
Josh ·
RE the ladder filter. I'm getting a wierd wisteling noise when the cutoff is in a low postion and I play a low pitched note even when the resonance is set to 0. I whsh I could post a sample of it but I dont have webspace yet.
Has anyone else experienced the same?
Tom7777 ·
Hmm, haven't had the chance to check the latest version out yet but that sounds like something to do with the resonance, maybe theres a small bug in the code or something, are you giving it Hz values or normal 0-1's?
Josh ·
Kingston wrote: I had a look at the code module and thought of a simple optimisation,
I didn't count how many MULTs, DIVs and ADDs that saves but quite a lot! 😀 (like hundreds!!)
Both functions are equal by the way, except for maybe that 2.666666667 bit (cuz it's 4/1.5). I don't know what the resolution allowed is, before denormals start to happen.
// filter based on the text "Non linear digital implementation of the moog ladder filter" by Antti Houvilainen
// resonance [0..1]
// cutoff from 0 (0Hz) to 1 (nyquist)
// constants
float pi = 3.1415926535;
float v2 = 40000; // twice the 'thermal voltage of a transistor'
// helper vars
float x; // temp var: input for taylor approximations
float denum; // temp vars to split complex expressions into simpler ones
float exprPos; // bug in code parser?
float exprNeg;
float expOut; // output of approximations
float tanh1Out;
float tanh2Out;
is x*x*x the same as x^3 and are there any differances in cpu consumption between the two?
Shifrin ·
Electrogravtiy wrote: is x*x*x the same as x^3 and are there any differances in cpu consumption between the two?
x*x*x is indeed the same as x^3 - however you can't compare CPU consumption between those operations as the '^' operator is not supported in the code component! Indeed, in C++ the '^' operator is a bitwise exclusive OR operator 😉
Shif.
Josh ·
Cheers Shifrin 🙂
Josh ·
Kingston wrote: I had a look at the code module and thought of a simple optimisation,
// filter based on the text "Non linear digital implementation of the moog ladder filter" by Antti Houvilainen
// resonance [0..1]
// cutoff from 0 (0Hz) to 1 (nyquist)
// constants
float pi = 3.1415926535;
float v2 = 40000; // twice the 'thermal voltage of a transistor'
float sr ;
float cfScale = 3;
float resScale = 1.5;
// helper vars
float x; // temp var: input for taylor approximations
float denum; // temp vars to split complex expressions into simpler ones
float exprPos; // bug in code parser?
float exprNeg;
float expOut; // output of approximations
float tanh1Out;
float tanh2Out;
Electrogravtiy wrote: Or just delete a whole shedload of them. Seems to work but I have no idea exactly why or if its still oversampled or not?
The sections you're removing implement what I'd guess is saturation/nonlinearities in the feedback of the filter. Shouldn't affect any oversampling - just the sound of the filter.
[edit]On closer inspection of your code it seems there are still some tanh calculations going on! Nonetheless it's cool to fiddle with these things![/edit]
Shif.
sambean ·
Hola peeps..
Here's a primitive version of the moog filter... Easier to see what's going on and stuff.. Based on a paper from tinternet....
http://magalov.myweb.hinet.net/filters/Moog.osm
Sam
Shifrin ·
Cheers Sam 😉
Shif.
TheAudiophileDutchman ·
Doesn't look very 'primitive' to me 😀 😉
Josh ·
Nice one Sam 😀
Tom7777 ·
Nice one, many thanks 🙂
Josh ·
sambean wrote: Hola peeps..
Here's a primitive version of the moog filter... Easier to see what's going on and stuff.. Based on a paper from tinternet....
http://magalov.myweb.hinet.net/filters/Moog.osm
Sam
Does it come in a poly version? A dumb question perhaps: Does filtering a mono stream use less cpu than filtering a poly stream?
sambean ·
Electrogravtiy wrote:
sambean wrote: Hola peeps..
Here's a primitive version of the moog filter... Easier to see what's going on and stuff.. Based on a paper from tinternet....
http://magalov.myweb.hinet.net/filters/Moog.osm
Sam
Does it come in a poly version? A dumb question perhaps: Does filtering a mono stream use less cpu than filtering a poly stream?
It should be compatible with poly streams too, I may have 'Right-clicked' some of the connector types to mono, but those can be clicked back.. Just plug it into a poly stream, if the connectors don't change white, right click on them..
If there are less than 4 voices playing the the cpu should be the same, more than then the mono one will take less cpu...
Sam
TheAudiophileDutchman ·
@Sam: what would be the most efficient way to get a Moog HP/BP out of your example?
electrogear ·
Does it come in a poly version? A dumb question perhaps: Does filtering a mono stream use less cpu than filtering a poly stream?
I don't know the reason why, as I'm still trying to get to grips with what connectors I should be using at what times, but I've found that using the EQ with Poly gives me very high CPU (around 12% per EQ module), and with Mono quite a bit less. I'm still trying to work out where to use poly signals for effects, and what benefits there are over processing poly signals rather than Mono - It'a all a bit confusing... think I need to read up a bit more....
Cheers,
Mike
matti ·
electrogear wrote:
Does it come in a poly version? A dumb question perhaps: Does filtering a mono stream use less cpu than filtering a poly stream?
I don't know the reason why, as I'm still trying to get to grips with what connectors I should be using at what times, but I've found that using the EQ with Poly gives me very high CPU (around 12% per EQ module), and with Mono quite a bit less. I'm still trying to work out where to use poly signals for effects, and what benefits there are over processing poly signals rather than Mono - It'a all a bit confusing... think I need to read up a bit more....
Cheers,
Mike
The difference between poly and mono signals is really quite simple. If you think of a 16 voice synth that has an eq connected as poly, it processes every 16 voices separately with that eq. That means it takes 16x more power to process than the mono one(SSE might affect this, but basicly you can think this way). If the effect is in mono it only uses one instance of the eq. The "poly to mono" element mixes all the polyphonic voices together and makes it into one mono channel. So you can think of the mono example just like a mixer channel with an eq. Eq isn't really needed as a poly effect.
Wrote something here? To have a post removed or your name hidden, write to [email protected].