Skip to content

Commit 3f9e82d

Browse files
committed
env.play tFromNow fix and fix up examples
1 parent f45e497 commit 3f9e82d

File tree

4 files changed

+101
-102
lines changed

4 files changed

+101
-102
lines changed

examples/envelope/sketch.js

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
/*
44
This sketch shows how to use envelopes and oscillators. Envelopes are pre-defined amplitude
5-
distribution over time. The sound library provides an ASR envelope which stands for attach,
6-
sustain, release. The amplitude rises then sustains at the maximum level and decays slowly
7-
depending on pre defined time segments.
5+
distribution over time. The sound library provides an ADSR envelope which stands for attack,
6+
decay, sustain, release. The amplitude rises then decays to a sustain level, then decays slowly
7+
toward the release value.
88
9-
.________
10-
. ---
11-
. ---
12-
. ---
13-
A S R
9+
.
10+
. . _______
11+
. ---
12+
. ---
13+
A D S R
1414
1515
*/
1616

@@ -22,10 +22,10 @@ var a;
2222
var attackTime = 0.001;
2323
var attackLevel = 0.9;
2424
var decayTime = 0.3;
25-
var decayLevel = 0.2;
25+
var susPercent = 0.2;
2626
var sustainTime = 0.1;
27-
var sustainLevel = decayLevel;
2827
var releaseTime = 0.5;
28+
var releaseLevel = 0;
2929

3030
var midiSequence = [ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72 ];
3131
var duration = 1000;
@@ -36,24 +36,25 @@ var trigger;
3636
var note = 0;
3737

3838
function setup(){
39-
createCanvas(600, 600);
40-
background(255);
39+
createCanvas(600, 400);
40+
fill(0, 255, 0);
4141

4242
trigger = millis();
4343

4444
triOsc = new p5.TriOsc();
4545
triOsc.amp(0);
4646
triOsc.start();
4747

48-
env = new p5.Env(attackTime, attackLevel, decayTime, decayLevel, sustainTime, sustainLevel, releaseTime);
49-
fill(0);
48+
env = new p5.Env();
49+
env.setADSR(attackTime, decayTime, susPercent, releaseTime);
50+
env.setRange(attackLevel, releaseLevel);
5051

5152
a = new p5.Amplitude();
5253
}
5354

5455
function draw(){
5556
var size = 10;
56-
background(255, 255,255,20);
57+
background(20, 20, 20, 70);
5758
ellipse(map ( (trigger - millis()) % duration, 1000, 0, 0, width), map ( a.getLevel(), 0, .5, height-size, 0), size, size);
5859

5960
// If the determined trigger moment in time matches up with the computer clock and we if the
@@ -63,7 +64,8 @@ function draw(){
6364
triOsc.freq(midiToFreq(midiSequence[note]));
6465

6566
// The envelope gets triggered with the oscillator as input and the times and levels we defined earlier
66-
env.play(triOsc);
67+
// play accepts an object to play, time from now, and a sustain time—how long to hold before the release.
68+
env.play(triOsc, 0, sustainTime);
6769

6870
// Create the new trigger according to predefined durations and speed it up by deviding by 1.5
6971
trigger = millis() + duration;

examples/envelopeMultipleSources/sketch.js

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
// Adapting Wilm Thoben's Envelope example from the Processing Handbook ex2
22

33
/*
4-
This sketch shows how to use envelopes and oscillators. Envelopes are pre-defined amplitude
5-
distribution over time. The sound library provides an ASR envelope which stands for attach,
6-
sustain, release. The amplitude rises then sustains at the maximum level and decays slowly
7-
depending on pre defined time segments.
8-
9-
.________
10-
. ---
11-
. ---
12-
. ---
13-
A S R
14-
15-
In this example, the envelope controls two sources: a Pink Noise and a Triangle Oscillator
4+
This sketch shows how to use envelopes to trigger multiple sources (in this case,noise and oscillator).
5+
6+
Envelopes are pre-defined amplitude distribution over time.
7+
The sound library provides an ADSR envelope which stands for attack, decay, sustain, release.
8+
The amplitude rises then decays to a sustain level, then decays slowly toward the release value.
9+
10+
.
11+
. . _______
12+
. ---
13+
. ---
14+
A D S R
15+
1616
*/
1717

1818
var triOsc;
@@ -38,8 +38,8 @@ var trigger;
3838
var note = 0;
3939

4040
function setup(){
41-
createCanvas(600, 600);
42-
background(255);
41+
createCanvas(600, 400);
42+
fill(0, 255, 0);
4343

4444
trigger = millis();
4545

@@ -59,14 +59,13 @@ function setup(){
5959
// triOsc.amp(env);
6060

6161
env.setInput(noise, triOsc);
62-
fill(0);
6362

6463
a = new p5.Amplitude();
6564
}
6665

6766
function draw(){
6867
var size = 10;
69-
background(255, 255,255,20);
68+
background(20, 20, 20, 70);
7069
ellipse(map ( (trigger - millis()) % duration, 1000, 0, 0, width), map ( a.getLevel(), 0, .3, height-size, 0), size, size);
7170

7271
// If the determined trigger moment in time matches up with the computer clock and we if the

examples/envelopeOnOff/sketch.js

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@
44
* Trigger the Release when the mouse is released.
55
*/
66

7-
var triOsc;
7+
var osc;
88
var env;
99
var a;
1010

1111
// Times and levels for the ADSR envelope
1212
var attackTime = 0.001;
13-
var attackLevel = 0.9;
14-
var decayTime = 0.25;
15-
var decayLevel = 0.2;
16-
var sustainTime = 0.1;
17-
var sustainLevel = decayLevel;
18-
var releaseTime = .8;
13+
var attackLevel = 0.6;
14+
var decayTime = 0.1;
15+
var susPercent = 0.2;
16+
var releaseTime = 0.5;
17+
var releaseLevel = 0;
18+
1919
var duration = 1000;
2020
// Set the note trigger
2121
var trigger;
@@ -25,32 +25,35 @@ var note = 0;
2525

2626

2727
function setup(){
28-
createCanvas(600, 600);
29-
background(255);
28+
createCanvas(600, 300);
29+
background(20);
30+
fill(0,255,0);
3031

3132
trigger = millis();
3233

33-
triOsc = new p5.TriOsc();
34-
triOsc.freq(220);
35-
triOsc.start();
36-
env = new p5.Env(attackTime, attackLevel, decayTime, decayLevel, sustainTime, sustainLevel, releaseTime);
37-
triOsc.amp(env);
38-
fill(0);
34+
osc = new p5.SinOsc();
35+
osc.freq(220);
36+
osc.start();
37+
38+
env = new p5.Env();
39+
env.setADSR(attackTime, decayTime, susPercent, releaseTime);
40+
env.setRange(attackLevel, releaseLevel);
41+
42+
osc.amp(env);
3943
createP('click mouse to triggerAttack, release mouse to triggerRelease');
4044

4145
a = new p5.Amplitude();
4246
}
4347

4448
function draw(){
4549
var size = 10;
46-
background(255, 255,255,20);
50+
background(20, 20, 20, 70);
4751
ellipse( map ( (trigger - millis()) % duration, 1000, 0, 0, width) % width, map ( a.getLevel(), 0, .5, height-size, 0), size, size);
4852
}
4953

5054
function mousePressed(){
51-
// The envelope gets triggered with the oscillator as input and the times and levels we defined earlier
52-
env.triggerAttack();
53-
trigger = millis() + duration;
55+
env.triggerAttack();
56+
trigger = millis() + duration;
5457
}
5558

5659
function mouseReleased(){

src/env.js

Lines changed: 46 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ define(function (require) {
2929
* @param {Number} dTime Time
3030
* @param {Number} [dLevel] Amplitude (In a standard ADSR envelope,
3131
* decayLevel = sustainLevel)
32-
* @param {Number} [sTime] Time (in seconds)
33-
* @param {Number} [sLevel] Amplitude 0.0 to 1.0
3432
* @param {Number} [rTime] Time (in seconds)
3533
* @param {Number} [rLevel] Amplitude 0.0 to 1.0
3634
* @example
@@ -39,8 +37,6 @@ define(function (require) {
3937
* var aL = 0.7; // attack level 0.0 to 1.0
4038
* var dT = 0.3; // decay time in seconds
4139
* var dL = 0.1; // decay level 0.0 to 1.0
42-
* var sT = 0.2; // sustain time in seconds
43-
* var sL = dL; // sustain level 0.0 to 1.0
4440
* var rT = 0.5; // release time in seconds
4541
* // release level defaults to zero
4642
*
@@ -88,14 +84,6 @@ define(function (require) {
8884
* @property decayLevel
8985
*/
9086
this.dLevel = l2 || 0;
91-
/**
92-
* @property sustainTime
93-
*/
94-
this.sTime = t3 || 0;
95-
/**
96-
* @property sustainLevel
97-
*/
98-
this.sLevel = l3 || 0;
9987
/**
10088
* @property releaseTime
10189
*/
@@ -152,23 +140,21 @@ define(function (require) {
152140
* Reset the envelope with a series of time/value pairs.
153141
*
154142
* @method set
155-
* @param {Number} aTime Time (in seconds) before level
143+
* @param {Number} attackTime Time (in seconds) before level
156144
* reaches attackLevel
157-
* @param {Number} aLevel Typically an amplitude between
145+
* @param {Number} attackLevel Typically an amplitude between
158146
* 0.0 and 1.0
159-
* @param {Number} dTime Time
160-
* @param {Number} [sLevel] Amplitude (In a standard ADSR envelope,
147+
* @param {Number} decayTime Time
148+
* @param {Number} decayLevel Amplitude (In a standard ADSR envelope,
161149
* decayLevel = sustainLevel)
162-
* @param {Number} [rTime] Release Time (in seconds)
163-
* @param {Number} [rLevel] Amplitude 0.0 to 1.0
150+
* @param {Number} releaseTime Release Time (in seconds)
151+
* @param {Number} releaseLevel Amplitude
164152
*/
165-
p5.Env.prototype.set = function(t1, l1, t2, l2, t3, l3, t4, l4){
153+
p5.Env.prototype.set = function(t1, l1, t2, l2, t3, l3){
166154
this.aTime = t1;
167155
this.aLevel = l1;
168156
this.dTime = t2 || 0;
169157
this.dLevel = l2 || 0;
170-
this.sTime = t3 || 0;
171-
this.sLevel = l3 || 0;
172158
this.rTime = t4 || 0;
173159
this.rLevel = l4 || 0;
174160

@@ -183,23 +169,47 @@ define(function (require) {
183169
* </a>.
184170
*
185171
* @method setADSR
186-
* @param {Number} attackTime in seconds from now
187-
* @param {Number} attackVal value
188-
* @param {Number} [decayTime] in seconds from now (defaults to 0)
189-
* @param {Number} [sustainVal] value (defaults to 0)
190-
* @param {Number} [releaseTime] in seconds from now (defaults to 0)
191-
* @param {Number} [releaseVal] value (defaults to 0)
172+
* @param {Number} attackTime Time (in seconds before envelope
173+
* reaches Attack Level
174+
* @param {Number} [decayTime] Time (in seconds) before envelope
175+
* reaches Decay/Sustain Level
176+
* @param {Number} [sustainPercent] percent between attackLevel and releaseLevel
177+
* @param {Number} [releaseTime] Time in seconds from now (defaults to 0)
192178
*/
193179
p5.Env.prototype.setADSR = function(aTime, dTime, sPercent, rTime){
194180
this.aTime = aTime;
195181
this.dTime = dTime || 0;
182+
183+
// lerp
196184
this.sPercent = sPercent;
197-
this.rTime = rTime;
185+
this.dLevel = typeof(sPercent) !== 'undefined' ? sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;
186+
187+
this.rTime = rTime || 0;
198188

199189
// also set time constants for ramp
200190
this._setRampAD(aTime, dTime);
201191
};
202192

193+
/**
194+
* Set max and min of envelope
195+
*
196+
* @method setRange
197+
* @param {Number} aLevel attack level (defaults to 1)
198+
* @param {Number} rLevel release level (defaults to 0)
199+
*/
200+
p5.Env.prototype.setRange = function(aLevel, rLevel) {
201+
this.aLevel = aLevel || 1;
202+
this.rLevel = 0;
203+
204+
// not sure if this belongs here:
205+
206+
// {Number} [dLevel] decay/sustain level (optional)
207+
// if (typeof(dLevel) !== 'undefined') {
208+
// this.dLevel = dLevel
209+
// } else if (this.sPercent) {
210+
// this.dLevel = this.sPercent ? this.sPercent * (this.aLevel - this.rLevel) + this.rLevel : 0;
211+
// }
212+
}
203213

204214
// private (undocumented) method called when ADSR is set to set time constants for ramp
205215
//
@@ -287,27 +297,29 @@ define(function (require) {
287297
* @method play
288298
* @param {Object} unit A p5.sound object or
289299
* Web Audio Param.
290-
* @param {Number} secondsFromNow time from now (in seconds)
300+
* @param {Number} [startTime] time from now (in seconds) at which to play
301+
* @param {Number} [sustainTime] time to sustain before releasing the envelope
302+
291303
*/
292-
p5.Env.prototype.play = function(unit, secondsFromNow){
304+
p5.Env.prototype.play = function(unit, secondsFromNow, susTime){
293305
var now = p5sound.audiocontext.currentTime;
294306
var tFromNow = secondsFromNow || 0;
295-
var t = now + tFromNow;
307+
var susTime = susTime || 0;
296308

297309
if (unit) {
298310
if (this.connection !== unit) {
299311
this.connect(unit);
300312
}
301313
}
302314

303-
this.triggerAttack(unit, secondsFromNow);
315+
this.triggerAttack(unit, tFromNow);
304316

305-
this.triggerRelease(unit, secondsFromNow + this.aTime + this.dTime + this.sTime);
317+
this.triggerRelease(unit, tFromNow + this.aTime + this.dTime + susTime);
306318

307319
};
308320

309321
/**
310-
* Trigger the Attack, Decay, and Sustain of the Envelope.
322+
* Trigger the Attack, and Decay portion of the Envelope.
311323
* Similar to holding down a key on a piano, but it will
312324
* hold the sustain level until you let go. Input can be
313325
* any p5.sound object, or a <a href="
@@ -381,23 +393,6 @@ define(function (require) {
381393
this.control.cancelScheduledValues(t);
382394
this.control.linearRampToValueAtTime(valToSet, t);
383395
}
384-
385-
// move to sustain level and hold for sustain time (if using ADSR, sustain time is set to 0 and sustain level is set to decay level)
386-
t += this.sTime;
387-
if (this.isExponential == true)
388-
{
389-
this.control.exponentialRampToValueAtTime(this.checkExpInput(this.sLevel), t);
390-
valToSet = this.checkExpInput(this.control.getValueAtTime(t));
391-
this.control.cancelScheduledValues(t);
392-
this.control.exponentialRampToValueAtTime(valToSet, t);
393-
}
394-
else
395-
{
396-
this.control.linearRampToValueAtTime(this.sLevel, t);
397-
valToSet = this.control.getValueAtTime(t);
398-
this.control.cancelScheduledValues(t);
399-
this.control.linearRampToValueAtTime(valToSet, t);
400-
}
401396
};
402397

403398
/**

0 commit comments

Comments
 (0)