# Retriggering/Resetting a Sustained Envelope

I’m hoping to be able to retrigger a sustained envelope as its being sustained. I couldn’t find a method for it.

I was able to figure out how to do it using two envelopes, while fading between them:

(
SynthDef(\retrigEnv, { |out|
var sig, env1, env2, toggleEnv, hold1, hold2, env, hold, trig, flux;

//// parameter controls
///////////////////////
var att = \att.kr(0.01),
dec = \dec.kr(0.3),
sus = \sus.kr(0.5),
rel = \rel.kr(1),
crv = \crv.kr(-2),
del = \del.kr(0),
timeScale = \timeScale.kr(1),
offset = \offset.kr(0),
peak = \peak.kr(1);

//// inputs
///////////
hold = \hold.kr(1);
trig = \trig.tr;
toggleEnv = ToggleFF.kr(trig);
hold1 = hold.min(ToggleFF.kr(trig + Impulse.kr(0))); // start high
hold2 = hold.min(toggleEnv);

//// signal generation
//////////////////////
env = Env.adsr(att, dec, sus, rel, 1, crv);
env2 = env.kr(0, hold2, timeScale, peak, offset);
env1 = env.kr(0, hold1, timeScale, peak, offset);

sig = LinXFade2.kr(env1, env2, toggleEnv.lag2(0.015) * 2 - 1);

//// output
///////////
Out.kr(out, sig)
)

z = Bus.control;
a = { SinOsc.ar ! 2 * \amp.kr }.play(args: [amp: z.asMap])
b = Synth(\retrigEnv, [att: 0.5, dec: 0.5, sus: 0.7, peak: 0.1, out: z])
b.set(\trig, 1)
b.set(\trig, 1)
b.set(\trig, 1)
b.set(\trig, 1)
b.set(\hold, 0) // gate - release control
b.set(\hold, 1) // gate - release control
z.free


But I’m wondering if there’s a better way?

I think you can cook something up with an “upside-down” trigger argument…does this do what you’re envisioning?

s.boot;

(
x = {
var env, sig;
sig = PinkNoise.ar(0.2!2);
env = EnvGen.kr(
Env.adsr(0.01, 0.5, 0.1, 1, 1, -2),
(1 - \trig.tr(1)) * \end.kr(1),
doneAction: 2
);
sig = sig * env;
}.play;
)

x.set(\trig, 1); //retrigger

1 Like

I works the same as my example, so it’s great and much simpler. Thank you Eli!

What’s confusing for me is that I figured that (1-\trig.tr(1)) * \end.kr(1) would null out and wouldn’t trigger at all, so I didn’t even try something as streamlined…

Is there a reason that on code evaluation, 1-1 * 1 still sneaks in as a positive going signal?

Boris

The expression (1 - \trig.tr(1)) is only equal to 0 for one control cycle. Trigger-rate arguments snap back to zero on the next control cycle after they are set to a non-zero value.

Ahh of course! Didn’t consider it over time.

Since (1- \trig.tr(1)) * \end.kr(1) does null out, even for one control cycle, how does that not trigger the doneAction?
Obviously it works. Just wondering why – I was about to go and re-edit a couple of SynthDefs when I remembered the doneAction was set to 2 (I was thinking of adding a FreeSelf.kr(1 - \end.kr(1))) when I remembered that your example works completely fine with the DA 2 in the EnvGen itself.