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;

)