SynthDefs that work with Pbind AND Pmono

What is the correct way to write a SynthDef that conditionally uses an env+done action if called from a Pbind, but is ignored if called from a Pmono? It would also need to respect .stop methods. Currently I just make two versions of a SynthDef to handle this but maybe there is a more graceful way…

You shouldn’t need two SynthDefs for this, at least, if the envelope is gated (like Env.adsr).

Or, do you mean that the Pbind version uses a timed envelope rather than a gated one?

The scenario isn’t quite clear to me.

hjh

If that’s what you meant (the difference between timed vs gated envelopes), here’s one SynthDef being played three different ways:

(
SynthDef(\x, { |out, freq, amp = 0.1, gate = 1|
	var env = NamedControl.kr(\env, Env.perc(0.01, 0.3).asArray.extend(5*4, 0));
	var eg = EnvGen.kr(env, gate, doneAction: 2);
	var sig = SinOsc.ar(freq) * amp;
	Out.ar(out, (sig * eg).dup)
}).add
)

// Pbind with non-gated envelope
(
p = Pbind(
	\instrument, \x,
	\sendGate, false,
	\freq, Pexprand(200, 800, inf),
	\dur, Pexprand(0.07, 0.4, inf),
	\env, [Env.perc(0.01, 0.6)]
).play;
)

p.stop;

// Pbind with gated envelope
(
p = Pbind(
	\instrument, \x,
	// \sendGate, false,  // make sure to remove this!!! adsr *must* send 'gate'
	\freq, Pexprand(200, 800, inf),
	\dur, Pexprand(0.07, 0.4, inf),
	\legato, Pexprand(0.5, 2.5, inf),
	\env, [Env.adsr(0.01, 1.0, 0.15, 0.1)]
).play;
)

p.stop;

// Pmono (must use gated envelope)
(
p = Pmono(\x,
	\freq, Pexprand(200, 800, inf),
	\dur, Pexprand(0.07, 0.4, inf),
	\legato, Pexprand(0.5, 2.5, inf),
	\env, [Env.adsr(0.01, 1.0, 0.5, 0.1)]
).play;
)

p.stop;

hjh