-
Notifications
You must be signed in to change notification settings - Fork 9
/
Envelopes.scd
139 lines (85 loc) · 3.57 KB
/
Envelopes.scd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// ----------- //
// Envelopes
// ----------- //
/* Use Env.new to define an envelope from scratch using breakpoints. The first three arguments to Env.new are: levels, times, and curve (there are two more args, see help file).
levels - an array of levels. The first level is the initial value of the envelope.
times - an array of durations of segments in seconds. There should be one fewer duration than there are levels.
curve - choose from 'step', 'linear', 'exponential', 'sine', 'welch' (see help file for details). */
Env.new([0, 1, 0.3, 0.8, 0], [2, 3, 1, 4],'linear').test.plot; // this will play a test tone with envelope
// Here's how to "read" the two arrays above:
// "Go from 0 to 1 in two seconds;
// then go from 1 to 0.3 in 3 seconds;
// then go from 0.3 to 0.8 in 1 second;
// finally go from 0.8 to 0 in 4 seconds."
// If you choose 'exponential', you can't use zero in the first array, but something like 0.001 will do:
Env.new([0.001, 1, 0.3, 0.8, 0.001], [2, 3, 1, 4],'exponential').test.plot;
// You can also create some standard frequently-used envelope shapes by supplying durations to the following methods:
// LINE ENVELOPE
// *linen(attackTime, sustainTime, releaseTime, level, curve)
Env.linen(attackTime: 1, sustainTime: 2, releaseTime: 3, level: 0.6).test.plot;
Env.linen(0.1, 0.2, 0.1, 0.6).test.plot;
Env.linen(1, 2, 3, 0.6, 'sine').test.plot;
Env.linen(1, 2, 3, 0.6, 'welch').test.plot;
// TRIANGLE ENVELOPE
// *triangle(duration, level)
Env.triangle(1, 1).test.plot;
// HANNING ENVELOPE (BELL SHAPE)
// *sine(duration, level)
Env.sine(1,1).test.plot;
// PERCUSSIVE ENVELOPE
// *perc(attackTime, releaseTime, peakLevel, curve)
Env.perc(0.05, 1, 1, 0).test.plot; // linear
Env.perc(0.05, 1, 1, -4).test.plot; // exponential
Env.perc(0.001, 1, 1, -4).test.plot; // sharper attack
Env.perc(0.001, 1, 1, -8).test.plot; // change curvature
Env.perc(1, 0.01, 1, 4).test.plot; // reverse envelope
// --------------------------------------- //
// USING ENVELOPES IN SYNTH DEFINITIONS
// --------------------------------------- //
// In order to "perform" an Env inside a Synth, you need EnvGen, the Envelope Generator:
{SinOsc.ar(800, 0, 0.5) * EnvGen.kr(Env.perc(0.001, 1))}.play;
// In a SynthDef:
(
SynthDef("env-example", { arg freq = 440, amp = 0.2;
var snd, env;
snd = SinOsc.ar(freq: freq, mul: amp);
env = EnvGen.kr(Env.perc(attackTime: 0.001, releaseTime: 1), doneAction: 2);
Out.ar(0, snd * env);
}).add;
)
Synth("env-example");
// There is a shortcut to EnvGen. Here are the examples above rewritten using the shortcut:
{ SinOsc.ar(800, 0, 0.5) * Env.perc(0.001, 1).kr }.play;
// In a SynthDef:
(
SynthDef("env-example-2", { arg freq = 440, amp = 0.2;
var snd, env;
snd = SinOsc.ar(freq: freq, mul: amp);
env = Env.perc(attackTime: 0.001, releaseTime: 1).kr(doneAction: 2);
Out.ar(0, snd * env);
}).add;
)
Synth("env-example-2");
s.plotTree
// Example using a trigger.
// The "gate" argument of EnvGen triggers the envelope and holds it open while value is > 0.
// See EnvGen Help file for more info.
(
{
var freq, trigger, env;
freq = 800;
trigger = Impulse.kr(1/2); // trigger a note every 2 seconds
env = EnvGen.kr(Env.perc(0.001, 1), gate: trigger);
SinOsc.ar(freq, mul: env);
}.play;
)
// Similar, now using an envelope to control frequency as well.
(
{
var trigger, freqEnv, ampEnv;
trigger = Impulse.kr(1/2); // trigger a note every 2 seconds
freqEnv = EnvGen.kr(Env.linen(0.1, 0.5, 0.4), gate: trigger).range(440, 880);
ampEnv = EnvGen.kr(Env.perc(0.001, 1), gate: trigger);
SinOsc.ar(freq: freqEnv, mul: ampEnv);
}.play;
)