+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