This sounds amazing. I have an “authentic” analog Benjolin here and actually didn’t think it was possible to emulate digitally but this really does the trick but with an even larger potential. Great job!
By the way, you get a free gui if you type Ndef(\benjolis).gui (although not all params seem to scale correctly here)
I’d make one correction though and that is to add a DC filter to the output because this synth sometimes ends up in DC land which is a bit dangerous. So just add output = LeakDC.ar(output); at the end.
A proper limiter is a special case of a compressor, where the compression ratio is very high – set a threshold, and when signal’s volume goes over the threshold, reduce the volume by some ratio. If the ratio is inf:1 (in SC Compander terms, slopeAbove = 0), then the output signal can’t be louder than the threshold – that’s a limiter. (In practice, many audio engineering books say that a compression ratio > 10:1 is practically a limiter.)
All dynamics processors have attack (clamp) and release times. If you always instantaneously adjust the output level, the audio-rate amplitude modulation will distort the spectrum. I’d be skeptical of any compressor/limiter where the release time is shorter than 30 ms or so.
If there is no attack/release time, then it’s not a limiter.
Neither tanh nor hard clipping have an attack or release. (They are really transfer functions for waveshaping.)
Funnily while I was writing this, James posted, but no harm to post also anyway …
In a mathematical sense tanh of course is a limiting function as it monotonically maps (-inf, +inf) to (-1, 1) as many other so-called sigmoid functions. And also in DSP world tanh is occasionally called a limiter, though “classical” limiting is a form of compression with attack and release times and several possible refinements. Avoidance of distortion is a relevant point and this can be done better by the latter than by tanh and other operators that add a lot of partials with loud input (as they - more or less softly - clip).
These 3 lines turn it into a real beast with unlimited preset memory:
Quarks.install(“JITLibExtensions”); // required Quark for preset
NdefPreset(\benjolis); // make a preset instance
ProxyPresetGui(NdefPreset(\benjolis)); // and it’s GUI. stores preset as text file
Complex oscillator topologies like this do really profit from presetting! random positioning and morphing between the states yields another world of unexpected sounds.
(Although, I’d replace the Select for a SelectX uGen and adjust the Spec to
Ndef(\benjolis).addSpec(\outSignal, ControlSpec( 0.0, 6.0, \lin, 0, 6) );
for smoother transitions between the different wave forms. )
A thing that I have done in my version of this amazing script by Alejandro is to clamp the filterType and outsignal types to the maximum size of the outsignals
Hello madskjeldgaard,
are you sure about size-1 ?
I think you can’t access the last index that way, in my case, size without -1 is the good choice but maybe I misunderstanding something.
Thank you for your correction and advices.