Benjolin inspired instrument


Following the conversations on analog circuits, I thought I would like to share a supercollider instrument inspired on Rob Hordijk’s Benjolin

You’ll need from sc3-plugins: PulseDPW, SVF and DFM1

code here:

A bit of background on the Benjolin:


Alejandro Olarte


Hey Alejandro,

thanks so much for sharing, this is super-interesting and sounds marvellous!
Will also need some time to look through -


Great that you like it Daniel. I am turning my head around about the PLL question.


1 Like

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 =; at the end.

and a limiter!
output = output.tanh;

Here’s my version of it, the safety version, haha.

1 Like

You get a gui also via ‘ed’ from NdefMixer(s), which is a bit hidden (I’m a rare Ndef user)

This is great. Really fun, thanks!

Nice that you like it guys. Thank you for the feedback, I added the DC filter Mads. The limiter change the color a bit.

That’s distortion, btw, not limiting. See for the other.


a supercollider PLL would be a cool

wow! I always thought it was a hard clip limiter of sorts. Thanks for the clarification

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).

Sounds really good, this Benjolin clone!

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. )

My version in full here:

bests, Hannes


Hi Alejandro, just checking back in here to say that this synth is still FANTASTIC. Thanks!!!

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

filters = [,(rungler*runglerFilt)+filtFreq,q* -1 +1,gain),
			//,(rungler*runglerFilt)+filtFreq,q,0,gain),,(rungler*runglerFilt)+filtFreq,q* -1 +1,gain),,(rungler*runglerFilt)+filtFreq,q,1,0,0,0,0,gain),,(rungler*runglerFilt)+filtFreq,q,gain,1)
		filt = % (filters.size-1), filters);

		outs = [tri1, osc1, tri2, osc2, pwm, sh0, filt];
		sig = % (outs.size-1)).poll, outs);

this way you ensure that you don’t get crazyness on that account

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.

1 Like

You’re absolutely right. Thanks for pointing out!

I would kill for that.