Another Benjolin/Rungler patch

It’s been done before, but whatever. The rungler’s shift register is hacked together using single-sample delays, so its behavior will not be very analog-like especially for clock signals approaching the sample rate. Single-sample feedback can also be used by setting the blockSize to 1 but the rungler’s shift register is already a kind of delay so I suspect the sound isn’t actually that different. In contrast to the original Benjolin, two different rungler outputs are used, one using bits 567 instead of 678 and reversed compared to the standard rungler output. This was inspired by the Rung Divisions Eurorack module which provides a lot of interesting alternatives to traditional rungling. The parameters are algorithmically modulated with a special kind of LFO I’ve been playing with lately that uses LFNoise2 for smooth modulation and TRand for static signals, and importantly there is random switching between them. I have found that this sounds more “human” than either pure LFNoise2 or pure TRand. Sometimes you leave knobs in place and sometimes you twist them, so I say why not both.

(
var rungler, lfo;

lfo = {
	var trigger;
	trigger = Dust.ar(0.4);
	Select.ar(ToggleFF.ar(trigger), [
		LFNoise2.ar(TExpRand.ar(0.5, 10, trigger)),
		TRand.ar(-1, 1, trigger),
	]);
};

rungler = { |dataSignal, clockSignal|
	var numBits, bits, bit, out, doDAC;
	doDAC = { |bits|
		var result;
		result = bits[0] + (bits[1] * 2) + (bits[2] * 4);
		result = result / 7;
		result = (result * 2) - 1;
		result;
	};
	bit = dataSignal > 0;
	numBits = 8;
	bits = [];
	numBits.do {
		bit = Latch.ar(bit, clockSignal);
		bits = bits.add(bit);
		bit = Delay1.ar(bit);
	};
	(
		out: doDAC.(bits[numBits - 3..numBits - 1]),
		outReverse: doDAC.(bits[numBits - 2..numBits - 4]),
	);
};

SynthDef(\rungler, {
	var snd, runglerOut;
	snd = LocalIn.ar(2);
	runglerOut = rungler.(snd[0], snd[1]);
	snd = [runglerOut[\out], runglerOut[\outReverse]];
	snd = LFTri.ar(({ lfo.() } ! 2).linexp(-1, 1, [10, 1], 8000) * (snd * 24).midiratio);
	LocalOut.ar(LeakDC.ar(Sanitize.ar(snd)));
	snd = (snd[0] > snd[1]) - 0.5;
	snd = MoogFF.ar(snd, ({ lfo.() } ! 2).linexp(-1, 1, 100, 8000) * (runglerOut[\out] * 24).midiratio, 3);
	snd = Splay.ar(snd, 0.3);
	snd = snd * -10.dbamp;
	Out.ar(\out.kr(0), snd);
}).add;
)

Synth(\rungler);
7 Likes

i found these experiments with the “Rung Divisions” Eurorack Module, which sound awesome IMO:

EDIT: really interesting point that you dont have to put the blocksize to 1. love that. Thats always bothering me when working with feedback in SC. Normally the feedback patch cant be a part of a larger composition made in SC, but only be played and recorded by itself. I dont like to record individual audio and chop that.
Maybe get some Eurorack modules controlled by SC.

1 Like

This is absolutely incredible work, Nathan. Thanks for sharing!

Thank you for sharing this code Nathan this is a great hommage to Rob Hordijk’s work.