Can the server send s_new messages to itself?

I didn’t, but hacked one up just now.

This works to trigger nodes that are already set up.

I didn’t find a way to re-trigger an envelope on a node that had run once, paused itself and then needed to be reawakened.

Also, I can’t find a way for one server node to address specific control inputs of a different server node. (You could conceivably map those control inputs to control buses, and the controller node could Out.kr or ReplaceOut.kr to set the value, but I didn’t try to do that today. I don’t expect I will try it later either, tbh.)

So, this example creates 10 paused nodes, and the c controller synth wakes them up one by one, following a trigger in the server. You could replace the Dust.kr by an Onsets.kr or other analytical process to have instant response to audio triggers.

(
SynthDef(\defaultP, { arg out=0, freq=440, amp=0.1, pan=0, time = 2;
	var z;
	z = LPF.ar(
		Mix.new(VarSaw.ar(freq + [0, Rand(-0.4,0.0), Rand(0.0,0.4)], 0, 0.3, 0.3)),
		XLine.kr(Rand(4000,5000), Rand(2500,3200), 1)
	) * Linen.kr(Trig1.kr(Impulse.kr(0), time), 0.01, 0.7, 0.3, doneAction: Done.freeSelf);
	OffsetOut.ar(out, Pan2.ar(z, pan, amp));
}, [\ir]).add;
)

(
a = [-7, -1, 0, 2, 1, 5, 4, 8, 5, 6].collect { |degree|
	Synth.newPaused(\defaultP, [freq: (degree.degreeToKey(Scale.major) + 60).midicps]);
};

b = Buffer.sendCollection(s, a.collect(_.nodeID), 1);

~dummy = { Silent.ar(1) }.play;
)

(
c = { |bufnum, neutralID|
	var trig = Dust.kr(1.5);  // here's the server-side trigger
	var num = BufFrames.kr(bufnum);
	var idSource = Demand.kr(trig, 0, Dbufrd(bufnum, Dseries(0, 1, num), loop: 0));
	var stop = FreeSelfWhenDone.kr(idSource);

	var id = Select.kr((trig > 0), [neutralID, idSource]);
	[trig, id].poll(trig);  // can remove, just for display
	Pause.kr(trig, id);
}.play(outbus: 1000, args: [bufnum: b, neutralID: ~dummy.nodeID]);
)

~dummy.free; b.free;

// in case something broke, stop the others here
a.do(_.free); c.free;

The ~dummy node is necessary because Pause will pause that node ID when trig becomes 0. In early tests, I found it was easy to pause node 0, in which case, everything dies. So we give it something else to pause without doing any damage.

If you want the process to run indefinitely, you could have c do a SendReply to have the client generate more paused nodes and update part of the buffer that isn’t being used at that moment. (Also delete var stop.) I’m afraid I won’t have time to work that out for you, though. This is as far as I can take this for now.

hjh

2 Likes