Dynamic Triggers

Hello. Im searching for a way to send a trigger but be able to emphasize how strong the trigger is. So a trigger with a 2.0 value would be louder than a trigger of 0.5. However the trigger of 0.5 shouldn’t overwrite the previous amplitude, but rather catapult the amplitude by a certain amount upwards and slowly decaying with a certain release time towards zero. Maybe also with a loudness cap.
Im not exactly sure how implement this. I guess maybe something similiar to a Compander.ar that takes Impulses (like Triggers) as control or some steadily decreasing function that can be added values.
I’ve written an example as a further explanation, however this example is obviously flawed and i explain it within the comment.

(

SynthDef(\test_sin,{
var sig, e, tr;
tr = \t_gate.kr(1);
e = EnvGen.kr(Env.perc(\atk.kr(0.01),\rel.kr(1)),gate:tr);
sig = SinOsc.ar(\freq.kr(440))!2;
/*
the next line would set the amp
of the envelope, however when a
trigger of a higher amplitude
wouldve been set at the same time
the lower amp trigger would overwrite
the Latch. this behavior is not wanted
*/
sig = sig * Latch.kr(tr,tr);

Out.ar(\out.kr(0),sig*e*\amp.kr(1));

Pmono(\test_sin,
\gate, Pseq([1,0.35],inf),
\amp, 0.8,
\dur, 1,
).play;
)

Does anybody know if there is a solution to this problem or has an idea?
Thank you very much!!

You’d want a Decay ugen: Decay | SuperCollider 3.12.2 Help

Decay has zero attack. Decay2 is one way of getting a slower attack, but the parameters behave sort of unintuitively/unmusically in my book, so I prefer the combination of Decay and then a .lag or .lagud.

1 Like

Oh I see, Decay is as an integrator. Yes that makes sense and works very well. Thank you very much.
I’ve created an example solution where i send 2 triggers with an amplitude of 0.5 immediately after each other which behave the same as a single trigger of amplitude 1. So for completion reasons i just add the example:

(
SynthDef(\test_sin,{
var sig, e, tr;
tr = \t_gate.kr(1);
e = Decay.kr(tr,1);
sig = SinOsc.ar(\freq.kr(440))!2;

Out.ar(\out.kr(0),sig*e*\amp.kr(1));

Pmono(\test_sin,
\gate, Pseq([1,0.5,0.5,0.5],inf),
\amp, 0.8,
\dur, Pseq([1,0.001,0.999,1],inf),
).play;
)

Unrelated… But (I’m pretty sure, away from pc so can’t test) when you have a trigger rate control you don’t need the \t_ bit (unless doing args as controls), you can instead use \gate.tr.

That’s correct – checked this morning – there are 3 ways to make a trigger control:

• t_gate in a SynthDef function arg list.
• \t_gate.kr in the SynthDef body. (I was surprised that “symbol.kr” uses the rate prefix.)
• \gate.tr in the SynthDef body.

When setting the value in a Synth() or set() arg array, the t_gate versions should be written t_gate but in patterns, it should be just gate (though “gate” is not normally sent, see msgFuncKeepGate). Dropping the prefix in patterns/events is a bit weird, making it one of the reasons why some have recommended against SynthDef function arg lists completely. (For triggers, I tend to agree with that, though for normal controls, I still use the arg list.)

The gate.tr version would be addressed as gate everywhere, which sidesteps the t_ weirdness.

hjh

1 Like

Actually when reconsidering the problem:
I think it would be interesting to have the option to cap the integration part of being only able to integrate up to a certain value. So that the Maximum input of the Decay (or maximum value from which to decay from) could be fixed and for example only reach a value of 1. Sure one can clip the decay but it would delay the decay.

I mean its not super important but if anyone has an Idea, I’m glad to hear.

Once again to clarify I show the problem in Code, 3 triggers are sent at (approximately) the same time, but im looking for a fix to make the sound be the same in the following example:

(
SynthDef(\test_sin,{
var sig, e, tr;
tr = \t_gate.kr(1);
e = Decay.kr(tr,1).poll.clip(0,1);
sig = SinOsc.ar(\freq.kr(440))!2;

Out.ar(\out.kr(0),sig*e*\amp.kr(1));