Using gate in type \set pattern

Hi,

How to I get these envelopes to trigger using a \set pattern?

SynthDef(\tish, { |out, freq=440, gate=0|
	var sin = SinOsc.ar( freq+(freq*EnvGen.ar(Env.adsr( 0.1, 0.3, 0.5, 0.3), gate, doneAction:0)) )
	* EnvGen.ar(Env.adsr( 0.1, 0.3, 0.5, 0.3), gate, doneAction:0) * 0.1;
	Out.ar(out, sin!2);
}).add;

~sin = Synth(\tish);

~p = Pbind(
	\type, \set,
	\id, ~sin,
	\instrument, \tish,
	\args, #[],
	\freq, Pseq([220,440,880,330],inf),
	\gate, 1,
	\dur, 0.5,
	\legato, 0.5
);

~pp = ~p.play;
~pp.stop;
~sin.free;

Thanks,
L.

you need to use a trigger-rate control -

try changing gate to t_gate in your SynthDef [Edit this only works for non-sustaining envelopes sadly - see @jamshark70 answer below for a more complete solution]

also please use code fences when you post code: triple backticks before and after!

trigger rate controls send an impulse when they are set - the control-rate control in your original once set to 1 just stays at 1 - controls only trigger when they transition from non-positive to positive.

1 Like

+1 for code formatting:

```
code
block
```

Code should appear in a monospace font. If it doesn’t, then check the tags again.

Now to the question –

First, I advise against using \args, #[] and an instrument name with “set” events, because default values in the event prototype can overwrite the synth’s inputs. (I added this feature, but in hindsight, it was a bad idea.)

So then, you can specify \args, #[freq, gate].

If you’re really determined to use the instrument name, do this:

SynthDef(\name,
	/* blah blah */
).add;
SynthDescLib.at[\name].msgFuncKeepGate = true;

Second – semiquaver is correct that the gate needs to be closed before you can reopen it. But, t_gate is not appropriate for ADSR envelopes, because it will move to the release segment after just one control cycle (1.45 ms with default settings).

You’ll have to add a function to schedule the gate-close message.

SynthDef(\tish, { |out, freq=440, gate=0|
	var sin = SinOsc.ar( freq+(freq*EnvGen.ar(Env.adsr( 0.1, 0.3, 0.5, 0.3), gate, doneAction:0)) )
	* EnvGen.ar(Env.adsr( 0.1, 0.3, 0.5, 0.3), gate, doneAction:0) * 0.1;
	Out.ar(out, sin!2);
}).add;

~sin = Synth(\tish);

(
~p = Pbind(
	\type, \set,
	\id, ~sin.asNodeID,
	// \instrument, \tish,
	\args, #[freq, gate],
	\freq, Pseq([220,440,880,330],inf),
	\gate, 1,
	\dur, 0.5,
	\legato, 0.5,
	// could use \finish too
	\callback, {
		var sus = ~sustain.value;
		var id = ~id;
		var server = ~server;
		var latency = ~latency ?? { server.latency };
		// here written in a general way, to handle multiple node IDs
		// (even though you have just one)
		thisThread.clock.sched(sus, {
			server.listSendBundle(latency,
				[\n_set, id, \gate, 0].flop
			);
		});
	}
);
)

~pp = ~p.play;
~pp.stop;
~sin.free;

hjh

2 Likes

Thanks that’s great as always!
Should be able to imitate PmonArtic with thisThread logic and a Prout - which is what I’m after.
My browser is too old for forum now, had to email question & re-format code text on phone.
Many thanks,
L.