Arbitrary range select by inversion of control on an address bus

Related to a thread here that touched several topics, one trick that occurred to me is how to replicate what Pause.kr does but with actual control signals, meaning something nicer than an instant pause, while still not spamming separate busses for each gate or trigger. Basically make an “address bus” that gets decoded by the receiver Synth. Worth nothing that the “selecting controller” synth c here doesn’t have a fixed-sized Select array as the usual idiom, in fact it has no Select at all. That’s a plus on some level as it can control an arbitrary number of synths without being reinstantiated itself, but you can also mess things up if the controlled synhts don’t decode their address properly etc. Inversion of control is also a loss of control on some level. The receiver synths decode both transitions on the address bus to trigger and then later release themselves nicely .

(
b = Bus.control(s, 1); // "address" bus

d = SynthDef(\sina, {
	arg i_id = 0, freq = 333, sel = -1;
	var gate = (sel >= i_id) * (sel <= (i_id + 0.999));
	var env = Linen.kr(gate, doneAction:2);
	//Poll.kr(Impulse.kr(0.33), [i_id, sel, gate, env]);
	Out.ar(0, 0.1 * env * SinOsc.ar(freq ! 2))
}).add;

a = (0..5);
)

(
b.set(-1).get; // c-bus, so set before if play more than once :)

x = a.collect { |i| Synth(d.name, [\i_id, i, \freq, (i+1) * 300, \sel, b.asMap]) };

c = {
	var sel = Line.kr(-1, a.size, 3, doneAction:2);
	Out.kr(b, sel);
}.play)

To actually pass other params from c to those x synths is slightly more tricky if you want them to hold them, use a Latch etc. If performance of the running synth in the pre-gate-in state is a worry, this can be combined with Pause.kr trick to get them running as they receive their gate. I’ll post perhaps something more elaborate later that does a combo.