Evaluate function when synth freed?

I have a synth running in a pattern and I would like to evaluate a function once it frees itself. I know how long this synth will run (minus latency to the server, of course), so I could work around it with a Pfunc, but I’d like to know whether there’s a more elegant solution. I’ve searched for relevant information for a while but come up short. I would assume there’s something in the neighborhood of Done to handle this but I can’t find anything.

http://doc.sccode.org/Classes/Node.html#-onFree

hjh

1 Like

Perfect, thank you. My next stupid question is, how do I call that from the Pbind (assuming it’s not possible from within the SynthDef)?

Another technique could be to use the Done ugen in your synth - http://doc.sccode.org/Classes/Done.html. It will produce a trigger when certain Ugens, like EnvGen finish. The trigger can be used to trigger a SendReply message - http://doc.sccode.org/Classes/SendReply.html - which can then notify a language side event.

Not a stupid question. Events don’t use Synth objects directly, generally, so there’s nothing to call onFree on.

There’s a poorly documented Event feature that will do it, though:

(
p = Pbind(
	\degree, Pwhite(0, 7, inf),
	\dur, 1,
	\callback, { |ev|
		// ev[\id] now has node IDs (array b/c may be several)
		ev[\id].do { |nodeID|
			OSCFunc({ |msg|
				"Synth(%) released\n".postf(msg[1]);
				// oneShot to remove it after firing
			}, '/n_end', s.addr, argTemplate: [nodeID]).oneShot;
		};
	}
).play;
)

p.stop;

// or, quick demo with strum
(
~releaseWatcher = { |ev|
	// ev[\id] now has node IDs (array b/c may be several)
	ev[\id].do { |nodeID|
		OSCFunc({ |msg|
			"Synth(%) released\n".postf(msg[1]);
			// oneShot to remove it after firing
		}, '/n_end', s.addr, argTemplate: [nodeID]).oneShot;
	};
};
)

(degree: (0, 2 .. 12), strum: 0.2, dur: 1.5, callback: ~releaseWatcher).play;

hjh

2 Likes

Thank you, that is exactly the mechanism I was looking for, I just didn’t the key to use.

I read through these, and they sure sounded interesting, but I couldn’t figure out where to begin wiring them up. That seems to be a frequent problem for me recently.

If you just want to find out when a node is finished (as opposed to sending a totally custom message from it), there’s no need to bother with adding anything to the SynthDef. What James’ code is doing in the latter half is setting up an OSC receiver for the /n_end messages that the server sends anyway when nodes end. These are explained in the rather lengthy Server Command Reference, more precisely in the “Node Notifications from Server” section. If that’s totally confusing, see Client vs Server for the big picture.

This doesn’t save much typing, but it might be conceptually simpler to understand if the “usual machinery” of Node is used to mask the OSC business:

(
var myfun = { |n| (n.nodeID + "says bye").postln };
(dur: 3, degree: [2, 3], callback: // chord two notes as test 
    { |ev| ev[\id] do: { |id| Node.basicNew(s, id).onFree(myfun); } }
).play
)