i would not use signals for this. (the idea of “sending xyz real quick” as a signal, doesn’t hold up.)
InTrig is useful for producing triggers from sclang in a deterministic way.
(
SynthDef.new(\ping, {
arg atk = 0.6, rel = 2, pan = 0, hz = 300,
trig_in;
var k, amp = 1;
k = SinOsc.ar(hz) * EnvGen.kr(Env.perc(atk, rel), gate: InTrig.kr(trig_in), doneAction:2) * amp;
k = Pan2.ar(k,pan);
Out.ar(0,k);
}).add;
)
~trig_b = Bus.control(s, 1);
x = Synth(\ping, [\trig_in, ~trig_b]);
(
~bang = {
x.set(\hz, rrand(30, 3000));
~trig_b.set(1);
};
)
~bang.value;
though, i might be misunderstanding the intent. code above shows how to retrigger the envelope in an arbitrary instance of a ping synth (named x).
if the intent is to immediately release the envelope on an arbitrary trigger, then the special “negative gate” would be usable, but it might be clearer to just have an additional multiplier/envelope/line with an additional DoneAction.
there is an additional factor. because you have doneAction:2, the synth will self-free when the envelope finishes. so to avoid runtime errors you should register created synths with Nodewatcher and check for .isRunning.
here’s a more complete example, assuming i understand that correctly now.
(
SynthDef.new(\ping, {
arg atk = 0.6, amp=1, rel = 2, pan = 0, hz = 300,
trig_in, defeat=0;
var k, trig;
trig = InTrig.kr(trig_in) - (defeat*1.1);
k = SinOsc.ar(hz) * EnvGen.kr(Env.perc(atk, rel), gate: trig, doneAction:2) * amp;
k = Pan2.ar(k,pan);
Out.ar(0,k);
}).add;
~create = {
var bus, synth;
bus = Bus.control(s, 1);
synth = Synth(\ping, [\trig_in, bus, \atk, 4.0]);
NodeWatcher.register(synth, true);
// returns an object prototype.
// this could be made slicker,
// by adding the ~reset and ~release functions below as pseudo-methods.
(synth:synth, bus:bus)
};
~reset = {
arg x;
if (x[\synth].isRunning, {
x[\synth].set(\hz, rrand(40, 60).midicps);
x[\bus].set(1);
true
}, {
false
});
};
~release = { arg x;
if (x[\synth].isRunning, {
postln("releasing node: " ++ x[\synth]);
x[\synth].set(\defeat, 1);
true
}, {
postln("synth does not appear to be running.");
false
});
};
)
x = ~create.value;
~reset.value(x);
~release.value(x);
and here is an alternative version of the SynthDef that uses an additional envelope, instead of relying on weird magic numbers.
SynthDef.new(\ping, {
arg atk = 0.6, amp=1, rel = 2, pan = 0, hz = 300,
trig_in, defeat=0;
var k, trig, defeater;
trig = InTrig.kr(trig_in);
defeater = 1 - EnvGen.ar(Env.new([0, 1], [0.01]), gate:defeat, doneAction:2);
k = SinOsc.ar(hz) * EnvGen.kr(Env.perc(atk, rel), gate: trig, doneAction:2) * amp * defeater;
k = Pan2.ar(k,pan);
Out.ar(0,k);
}).add;