EnvGen envelope generator

superclass: UGen

Plays back break point envelopes. The envelopes are instances of the Env class. See the Env for more info. The arguments for levelScale, levelBias, and timeScale are polled when the EnvGen is triggered and remain constant for the duration of the envelope.

*ar(envelope, gate, levelScale, levelBias, timeScale, doneAction)

*kr(envelope, gate, levelScale, levelBias, timeScale, doneAction)

envelope - an instance of Env, or an Array of Controls. (See Control and the example below for how to use this.)

gate - this triggers the envelope and holds it open while > 0. If the Env is fixed-length (e.g. Env.linen, Env.perc), the gate argument is used as a simple trigger. If it is an sustaining envelope (e.g. Env.adsr, Env.asr), the envelope is held open until the gate becomes 0, at which point is released.

levelScale - scales the levels of the breakpoints.

levelBias - offsets the levels of the breakpoints.

timeScale - scales the durations of the segments.

doneAction - an integer representing an action to be executed when the env is finished playing. This can be used to free the enclosing synth, etc. See UGen-doneActions for more detail.

{ EnvGen.kr(Env.perc, 1.0, doneAction: 2) * SinOsc.ar(440,0,0.1) }.play;

// example

(

SynthDef("env-help", { arg out, gate;

var z;

z = EnvGen.kr(Env.adsr,gate) * SinOsc.ar(440,0,0.1);

Out.ar(out, z)

}).send(s);

)

s.sendMsg("/s_new", "env-help", 1980); // start a synth (silently, as gate defaults to 0)

// turn on

s.sendMsg("/n_set", 1980, \gate, 1);

// turn off

s.sendMsg("/n_set", 1980, \gate, 0);

// it does not matter to what value the gate is set, as long as it is > 0

s.sendMsg("/n_set", 1980, \gate, 2);

s.sendMsg("/n_free", 1980);

Changing an Env while playing

(

SynthDef("env", { arg i_outbus=0;

var env, envctl;

// make a dummy 8 segment envelope

env = Env.newClear(8);

// create a control argument array

envctl = Control.names([\env]).kr( env.asArray );

ReplaceOut.kr(i_outbus, EnvGen.kr(envctl, doneAction: 2));

}).send(s);

)

(

SynthDef("sine", {

Out.ar(0, SinOsc.ar(In.kr(0), 0, 0.2));

}).send(s);

)

s.sendMsg(\c_set, 0, 800);

s.sendMsg(\s_new, \sine, 1001, 1, 0);

e = Env([700,900,900,800], [1,1,1]*0.4, \exp).asArray;

s.sendBundle(nil,[\s_new, \env, 1002, 2, 1001],[\n_setn, 1002, \env, e.size] ++ e);

f = Env([1000,1000,800,1000,900,1000], [1,1,1,1,1]*0.3, \step).asArray;

s.sendBundle(nil,[\s_new, \env, 1003, 2, 1001],[\n_setn, 1003, \env, f.size] ++ f);

s.sendMsg(\n_free, 1001);

Forced release of the EnvGen

If the gate of an EnvGen is set to -1 or below, then the envelope will cutoff immediately. The time for it to cutoff is the amount less than -1, with -1 being as fast as possible, -1.5 being a cutoff in 0.5 seconds, etc. The cutoff shape is linear.

(

SynthDef("stealMe", { arg gate = 1;

Out.ar(0, {BrownNoise.ar}.dup * EnvGen.kr(Env.asr, gate, doneAction:2))

}).send(s);

)

s.sendMsg(\s_new, \stealMe, 1001, 1, 0);

s.sendMsg(\n_set, 1001, \gate, -1.1); // cutoff in 0.1 seconds

If the synthDef has an arg named "gate", the convienience method of Node can be used:

Node-release(releaseTime)

d = { arg gate=1; {BrownNoise.ar}.dup * EnvGen.kr(Env.asr, gate, doneAction:2) }.play;

d.release(3);

Fast triggering tests

(

{

EnvGen.kr(

Env.new([ 0.001, 1, 0.5, 0 ], [ 0.01, 0.3, 1 ], -4, 2, nil),

Impulse.kr(10)

) * SinOsc.ar(440,0,0.1)

}.play;

)

(

{

EnvGen.kr(

Env.perc( 0.1, 0.0, 0.5, 1, \welch ),

Impulse.kr(100),

timeScale: 0.1

) * SinOsc.ar(440,0,0.3)

}.play;

)

Modulating the levelScale

no,it doesn't take a ugen in

(

{

EnvGen.kr(

Env.asr( 0.1, 1.0, 0.5, \welch ),

1.0,

FSinOsc.ar(1.0).range(0.0,1.0),

timeScale: 0.1

) * SinOsc.ar(440,0,0.3)

}.play;

)

an .ir rate input, a float or an ir rate ugen like Rand would work

(

{

EnvGen.kr(

Env.asr( 0.1, 1.0, 0.5, \welch ),

1.0,

Rand(0.1,1.0),

timeScale: 0.1

) * SinOsc.ar(440,0,0.3)

}.play;

)