2 summary:: Envelope generator
3 related:: Classes/Linen, Classes/Env
4 categories:: UGens>Envelopes
9 Plays back break point envelopes. The envelopes are instances of the
10 link::Classes/Env:: class. The envelope and the arguments for code::levelScale:: ,
11 code::levelBias:: , and code::timeScale::
12 are polled when the EnvGen is triggered and remain constant for the
13 duration of the envelope.
16 { PinkNoise.ar(EnvGen.kr(Env.perc, doneAction: 2)) }.play
27 An link::Classes/Env:: instance, or an Array of Controls.
28 (See link::Classes/Control:: and the example below for how to use
31 The envelope is polled when the EnvGen is triggered. The Env inputs can be other UGens.
36 This triggers the envelope and holds it open while > 0. If the
37 Env is fixed-length (e.g. Env.linen, Env.perc), the gate argument
38 is used as a simple trigger. If it is an sustaining envelope
39 (e.g. Env.adsr, Env.asr), the envelope is held open until the
40 gate becomes 0, at which point is released.
42 If strong::gate:: < 0, force release with time code:: -1.0 - gate ::, see link::#forced_release:: below.
46 Scales the levels of the breakpoints.
51 Offsets the levels of the breakpoints.
56 Scales the durations of the segments.
61 An integer representing an action to be executed when the env is
62 finished playing. This can be used to free the enclosing synth,
63 etc. See link::Reference/UGen-doneActions:: for more detail.
67 The actual minimum duration of a segment is not zero, but one sample step for audio rate and one block for control rate. This may result in asynchronicity when in two envelopes of different number of levels, the envelope times add up to the same total duration. Similarly, when modulating times, the new time is only updated at the end of the current segment - this may lead to asynchronicity of two envelopes with modulated times.
72 // as amplitude envelope
75 var env = Env([0, 1, 0.5, 1, 0], [0.01, 0.5, 0.02, 0.5]);
76 SinOsc.ar(470) * EnvGen.kr(env, doneAction: 2)
80 // as amplitude and modulation envelope
83 var env = Env([0, 1, 0.5, 0.8, 0, 1.2, 0], [0.01, 0.5, 0.02, 0.5, 0.2, 0.5]);
84 var gate = Impulse.kr(MouseX.kr(0.2, 3), 0.5);
85 var gen = EnvGen.kr(env, gate);
86 SinOsc.ar(270, SinOsc.ar(gen * 473)) * gen * 0.2
89 // EnvGen multichannel expands when passed a multichannel envelope
94 Env.circle([0, 1, 0, (2..4), 0, LFNoise1.kr(0.1 ! 5) * 10, 0], [0.01, 0.6])
105 // retriggered envelope by Dust
108 var env = Env([0.0, 0.5, 0.0, 1.0, 0.9, 0.0], [0.05, 0.1, 0.01, 1.0, 1.5], -4);
109 var envgen = EnvGen.ar(env, Dust.ar(1));
119 var env = Env([0.0, [-0.2, 0.5], 0.0, 1.0, [-0.4, 0.9], 0.0], [0.05, 0.1, 0.01, 1.0, 1.5], -4);
120 var envgen = EnvGen.ar(env, Dust.ar([1, 1]));
127 // an envelope in a SynthDef can be used to limit the synth's lifetime (doneAction: 2)
130 SynthDef(\env_help, { | out, gate = 0, freq = 440 |
132 z = EnvGen.kr(Env.perc, doneAction: 2) * SinOsc.ar(freq, 0, 0.1);
153 // it does not matter to what value the gate is set, as long as it is > 0
158 // using a gated envelope to gate a sound:
160 SynthDef(\env_help, { | out, gate = 0, freq = 440, doneAction = 0 |
161 var z = EnvGen.kr(Env.adsr, gate, doneAction: doneAction) * SinOsc.ar(freq, 0, 0.1);
166 a = Synth(\env_help);
175 // it does not matter to what value the gate is set, as long as it is > 0
178 a.set(\doneAction, 2, \gate, 0); // set doneAction to two to let the synth free itself
180 a.free; // alternatively, free it directly.
183 subsection:: Specifying an envelope for each new synth
186 SynthDef(\help_Env_newClear, { |out = 0|
188 // make an empty 4 segment envelope
189 env = Env.newClear(4);
190 // create a control argument array
191 envctl = \env.kr(env.asArray);
193 SinOsc.ar(EnvGen.kr(envctl, \gate.tr), 0, 0.3) // the gate control is a trigger
198 Synth(\help_Env_newClear, [\gate, 1, \env, Env([700,900,900,800], [1,1,1], \exp)]); // 3 segments
200 // reset then play again:
201 Synth(\help_Env_newClear, [\gate, 1, \env, Env({ rrand(60, 70).midicps } ! 4, [1,1,1], \exp)]);
203 // the same written as an event:
204 (instrument: \help_Env_newClear, gate: 1, env: Env({ rrand(60, 70).midicps } ! 4, [1,1,1], \exp)).play;
208 subsection:: Forced release
209 If the gate of an EnvGen is set to -1 or below, then the envelope will cutoff immediately.
210 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.
211 The cutoff shape is linear.
214 SynthDef(\stealMe, { |out, gate = 1|
215 Out.ar(out, {BrownNoise.ar}.dup * EnvGen.kr(Env.asr, gate, doneAction:2))
220 a.release(3); // // cutoff in 3 seconds
222 // this is how the OSC data looks like:
223 s.sendMsg(\s_new, \stealMe, 1001, 1, 0);
224 s.sendMsg(\n_set, 1001, \gate, -1.1); // cutoff in 0.1 seconds
227 If the synthDef has an arg named "gate", the convenience method of Node can be used: code::node.release(releaseTime)::
229 d = { arg gate=1; {BrownNoise.ar}.dup * EnvGen.kr(Env.asr, gate, doneAction:2) }.play;
233 subsection:: Fast triggering tests
238 Env.new([ 0.001, 1, 0.5, 0 ], [ 0.01, 0.3, 1 ], -4, 2, nil),
240 ) * SinOsc.ar(440, 0, 0.1)
247 Env.perc( 0.1, 0.0, 0.5, 1, \welch ),
250 ) * SinOsc.ar(440, 0, 0.3)
255 subsection:: Modulating the levelScale
257 // no, it doesn't take a ugen in ...
261 Env.asr( 0.1, 1.0, 0.5, \welch ),
263 FSinOsc.ar(1.0).range(0.0, 1.0),
265 ) * SinOsc.ar(440, 0, 0.3)
269 // ...but an .ir rate input, a float or an ir rate ugen like Rand would work
273 Env.asr( 0.1, 1.0, 0.5, \welch ),
277 ) * SinOsc.ar(440, 0, 0.3)
282 subsection::More examples
284 For more information about the emphasis::control bus mapping:: used in the line code::a = Synth(\sine, [freq: f.asMap]);::, see link::Classes/Node#-map:: and link::Classes/Bus#-asMap::.
288 // Changing an Env while playing
290 SynthDef(\env, { arg i_outbus=0;
293 // make a dummy 8 segment envelope
294 env = Env.newClear(8);
296 // create a control argument array
297 envctl = \env.kr( env.asArray );
299 ReplaceOut.kr(i_outbus, EnvGen.kr(envctl, doneAction: 2));
304 SynthDef(\sine, { |freq = 0|
305 Out.ar(0, SinOsc.ar(freq, 0, 0.2));
309 f = Bus.control(s, 1);
312 // use f's control bus value for frequency
313 // i.e. *map* the control to read from the bus
314 a = Synth(\sine, [freq: f.asMap]);
316 Synth(\env, [i_outbus: f, env: Env([700, 900, 900, 800], [1, 1, 1]*0.4, \exp)]);
318 Synth(\env, [i_outbus: f, env: Env([1000, 1000, 800, 1000, 900, 1000], [1, 1, 1, 1, 1]*0.3, \step)]);