Skip to content

Commit 9ed68eb

Browse files
(Gsoc'21)➕Added tests for envelope.js
1 parent f8f58f0 commit 9ed68eb

File tree

3 files changed

+273
-2
lines changed

3 files changed

+273
-2
lines changed

src/envelope.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ p5.Envelope.prototype._init = function () {
141141
* let l1 = 0.7; // attack level 0.0 to 1.0
142142
* let t2 = 0.3; // decay time in seconds
143143
* let l2 = 0.1; // decay level 0.0 to 1.0
144-
* let l3 = 0.2; // release time in seconds
144+
* let t3 = 0.2; // release time in seconds
145145
*
146146
* let env, triOsc;
147147
*
@@ -163,7 +163,7 @@ p5.Envelope.prototype._init = function () {
163163
*
164164
* // mouseClick triggers envelope if over canvas
165165
* function playSound() {
166-
* env.set(attackTime, l1, t2, l2, l3);
166+
* env.set(attackTime, l1, t2, l2, t3);
167167
*
168168
* triOsc.start();
169169
* env.play(triOsc);

test/tests.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import('./tests/p5.SoundRecorder.js');
2121
import('./tests/p5.SoundFile.js');
2222
import('./tests/p5.Amplitude.js');
2323
import('./tests/p5.Oscillator.js');
24+
import('./tests/p5.Envelope.js');
2425
import('./tests/p5.Pulse.js');
2526
import('./tests/p5.Noise.js');
2627
import('./tests/p5.Panner.js');

test/tests/p5.Envelope.js

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
const expect = chai.expect;
2+
3+
describe('p5.Envelope', function () {
4+
it('can be created and disposed without any arguments', function () {
5+
let envelope = new p5.Envelope();
6+
expect(envelope.aTime).to.equal(0.1);
7+
expect(envelope.aLevel).to.equal(1);
8+
expect(envelope.dTime).to.equal(0.5);
9+
expect(envelope.dLevel).to.be.zero;
10+
expect(envelope.rTime).to.be.zero;
11+
expect(envelope.rLevel).to.be.zero;
12+
expect(envelope._rampHighPercentage).to.equal(0.98);
13+
expect(envelope._rampLowPercentage).to.equal(0.02);
14+
expect(envelope.isExponential).to.be.false;
15+
expect(envelope.wasTriggered).to.be.false;
16+
expect(envelope).to.have.property('control').to.not.be.null;
17+
18+
envelope.dispose();
19+
expect(envelope.control).to.be.null;
20+
});
21+
describe('methods', function () {
22+
it('can be initialized', function () {
23+
let envelope = new p5.Envelope();
24+
envelope._init();
25+
expect(envelope.control.value).to.equal(0.00001);
26+
27+
// to ensure that _setRampAD is being called
28+
expect(envelope).to.have.property('_rampAttackTC').to.not.be.zero;
29+
expect(envelope).to.have.property('_rampDecayTC').to.not.be.zero;
30+
});
31+
it('can reset envelope using set function', function () {
32+
let envelope = new p5.Envelope();
33+
envelope.set(0.2, 0.15);
34+
expect(envelope.aTime).to.equal(0.2);
35+
expect(envelope.aLevel).to.equal(0.15);
36+
envelope.set(0.9, 0.8, 0.7, 0.6, 0.5, 0.4);
37+
expect(envelope.aTime).to.equal(0.9);
38+
expect(envelope.aLevel).to.equal(0.8);
39+
expect(envelope.dTime).to.equal(0.7);
40+
expect(envelope.dLevel).to.equal(0.6);
41+
expect(envelope.rTime).to.equal(0.5);
42+
expect(envelope.rLevel).to.equal(0.4);
43+
44+
// to ensure that _setRampAD is being called
45+
expect(envelope).to.have.property('_rampAttackTC').to.not.be.zero;
46+
expect(envelope).to.have.property('_rampDecayTC').to.not.be.zero;
47+
});
48+
it('can use setADSR to set like a traditional ADSR envelope', function () {
49+
let envelope = new p5.Envelope();
50+
//only one argument
51+
envelope.setADSR(0.75);
52+
expect(envelope.aTime).to.equal(0.75);
53+
expect(envelope.dTime).to.equal(0);
54+
expect(envelope.sPercent).to.equal(0);
55+
expect(envelope.dLevel).to.equal(0);
56+
57+
envelope.set(1, 0.8, 0.75, 0.3, 0.25, 0.45);
58+
//using all arguments
59+
envelope.setADSR(0.5, 0.2, 0.45, 0.7);
60+
expect(envelope.aTime).to.equal(0.5);
61+
expect(envelope.dTime).to.equal(0.2);
62+
expect(envelope.sPercent).to.equal(0.45);
63+
expect(envelope.dLevel).to.equal(0.6075);
64+
65+
// to ensure that _setRampAD is being called
66+
expect(envelope).to.have.property('_rampAttackTC').to.not.be.zero;
67+
expect(envelope).to.have.property('_rampDecayTC').to.not.be.zero;
68+
});
69+
it('can set the range of an envelope using setRange', function () {
70+
let envelope = new p5.Envelope();
71+
//no arguments
72+
envelope.setRange();
73+
expect(envelope.aLevel).to.equal(1);
74+
expect(envelope.rLevel).to.equal(0);
75+
//two arguments
76+
envelope.setRange(0.75, 0.25);
77+
expect(envelope.aLevel).to.equal(0.75);
78+
expect(envelope.rLevel).to.equal(0.25);
79+
});
80+
it('can set time constants for ramp using _setRampAD', function () {
81+
let envelope = new p5.Envelope();
82+
envelope._setRampAD(0.85, 0.65);
83+
expect(envelope._rampAttackTime).to.equal(0.85);
84+
expect(envelope._rampDecayTime).to.equal(0.65);
85+
expect(envelope._rampAttackTC).to.be.approximately(0.21727, 0.00001);
86+
expect(envelope._rampDecayTC).to.be.approximately(0.16615, 0.00001);
87+
});
88+
it('can set time constants for ramp using setRampPercentages', function () {
89+
let envelope = new p5.Envelope();
90+
envelope._setRampAD(0.85, 0.65);
91+
expect(envelope._rampAttackTime).to.equal(0.85);
92+
expect(envelope._rampDecayTime).to.equal(0.65);
93+
94+
envelope.setRampPercentages(0.8, 0.2);
95+
expect(envelope._rampAttackTC).to.be.approximately(0.52813, 0.00001);
96+
expect(envelope._rampDecayTC).to.be.approximately(0.40386, 0.00001);
97+
98+
envelope.setRampPercentages(0.99, 0.01);
99+
expect(envelope._rampAttackTC).to.be.approximately(0.18457, 0.00001);
100+
expect(envelope._rampDecayTC).to.be.approximately(0.14114, 0.00001);
101+
});
102+
it('can set a single or multiple inputs', function () {
103+
let envelope = new p5.Envelope();
104+
let osc1 = new p5.Oscillator();
105+
let osc2 = new p5.Oscillator();
106+
envelope.setInput(osc1);
107+
108+
envelope = new p5.Envelope();
109+
envelope.setInput(osc1, osc2);
110+
});
111+
it('can set ramp to be linear or exponential', function () {
112+
let envelope = new p5.Envelope();
113+
expect(envelope.isExponential).to.be.false;
114+
envelope.setExp(true);
115+
expect(envelope.isExponential).to.be.true;
116+
envelope.setExp(false);
117+
expect(envelope.isExponential).to.be.false;
118+
});
119+
it('checkExpInput can be used to protect against zero values', function () {
120+
let envelope = new p5.Envelope();
121+
expect(envelope.checkExpInput(0)).to.be.zero;
122+
expect(envelope.checkExpInput(-1.234)).to.be.zero;
123+
expect(envelope.checkExpInput(-100)).to.be.zero;
124+
expect(envelope.checkExpInput(10)).to.equal(10);
125+
});
126+
it('can trigger an attack at the present moment', function () {
127+
let envelope = new p5.Envelope(0.65, 0.75, 0.85, 0.55, 0.95, 0.9);
128+
let osc = new p5.SinOsc();
129+
let now = p5.prototype.getAudioContext().currentTime;
130+
envelope.triggerAttack(osc);
131+
expect(envelope.lastAttack).to.not.be.zero;
132+
expect(envelope.wasTriggered).to.be.true;
133+
134+
expect(envelope.control.getValueAtTime(now + 0.65)).to.equal(0.75);
135+
136+
expect(envelope.control.getValueAtTime(now + 1.5)).to.equal(0.55);
137+
138+
expect(envelope.control.getValueAtTime(now + 0.5)).to.not.be.zero;
139+
expect(envelope.control.getValueAtTime(now + 0.5)).to.be.below(0.75);
140+
expect(envelope.control.getValueAtTime(now + 1)).to.be.above(0.55);
141+
expect(envelope.control.getValueAtTime(now + 1)).to.be.below(0.75);
142+
expect(envelope.control.getValueAtTime(now + 2)).to.equal(0.55);
143+
});
144+
it('can trigger an attack few seconds from the present moment', function () {
145+
let envelope = new p5.Envelope(0.65, 0.75, 0.85, 0.55, 0.95, 0.9);
146+
let osc = new p5.SinOsc();
147+
let now = p5.prototype.getAudioContext().currentTime;
148+
envelope.setExp(true);
149+
envelope.triggerAttack(osc, 0.3);
150+
151+
expect(envelope.control.getValueAtTime(now + 0.1)).to.equal(0.00001); // from checkExpInput
152+
153+
expect(envelope.control.getValueAtTime(now + 0.95)).to.be.approximately(
154+
0.75,
155+
0.001
156+
);
157+
158+
expect(envelope.control.getValueAtTime(now + 1.8)).to.be.approximately(
159+
0.55,
160+
0.001
161+
);
162+
163+
expect(envelope.control.getValueAtTime(now + 0.5)).to.be.above(0.00001);
164+
expect(envelope.control.getValueAtTime(now + 0.5)).to.be.below(0.75);
165+
expect(envelope.control.getValueAtTime(now + 1.3)).to.be.above(0.55);
166+
expect(envelope.control.getValueAtTime(now + 1.3)).to.be.below(0.75);
167+
expect(envelope.control.getValueAtTime(now + 2)).to.equal(0.55);
168+
});
169+
it('can return if trigger is released before the attack', function () {
170+
let envelope = new p5.Envelope(0.85, 0.75, 0.65, 0.55, 0.45, 0.8);
171+
let osc = new p5.SinOsc();
172+
let now = p5.prototype.getAudioContext().currentTime;
173+
envelope.triggerRelease(osc, 0);
174+
175+
expect(envelope.control.getValueAtTime(now + 0.45)).to.equal(0.00001);
176+
});
177+
it('can trigger a release at the present moment', function () {
178+
let envelope = new p5.Envelope(0.65, 0.75, 0.85, 0.55, 0.95, 0.9);
179+
let osc = new p5.SinOsc();
180+
let now = p5.prototype.getAudioContext().currentTime;
181+
envelope.triggerAttack(osc);
182+
envelope.triggerRelease(osc);
183+
expect(envelope.wasTriggered).to.be.false;
184+
185+
expect(envelope.control.getValueAtTime(now + 0.95)).to.equal(0.9);
186+
187+
expect(envelope.control.getValueAtTime(now + 0.5)).to.not.be.zero;
188+
expect(envelope.control.getValueAtTime(now + 1)).to.equal(0.9);
189+
});
190+
it('can trigger a release few seconds from the present moment', function () {
191+
let envelope = new p5.Envelope(0.65, 0.75, 0.85, 0.55, 0.95, 0.9);
192+
let osc = new p5.SinOsc();
193+
let now = p5.prototype.getAudioContext().currentTime;
194+
envelope.setExp(true);
195+
envelope.triggerAttack(osc);
196+
envelope.triggerRelease(osc, 0.4);
197+
198+
expect(envelope.control.getValueAtTime(now + 1.35)).to.be.approximately(
199+
0.9,
200+
0.001
201+
);
202+
203+
expect(envelope.control.getValueAtTime(now + 1)).to.be.above(0);
204+
expect(envelope.control.getValueAtTime(now + 1)).to.be.below(0.9);
205+
expect(envelope.control.getValueAtTime(now + 1.5)).to.equal(0.9);
206+
});
207+
it('can be played on an input without any delay', function () {
208+
let envelope = new p5.Envelope(0.1, 0.65, 0.5, 0.5, 0.35, 0.4);
209+
let osc = new p5.SinOsc();
210+
let now = p5.prototype.getAudioContext().currentTime;
211+
envelope.play(osc);
212+
213+
expect(envelope.control.getValueAtTime(now + 0.1)).to.equal(0.65);
214+
215+
expect(envelope.control.getValueAtTime(now + 0.6)).to.equal(0.5);
216+
217+
expect(envelope.control.getValueAtTime(now + 0.95)).to.equal(0.4);
218+
219+
expect(envelope.control.getValueAtTime(now + 0.05)).to.not.be.zero;
220+
expect(envelope.control.getValueAtTime(now + 0.05)).to.be.below(0.65);
221+
expect(envelope.control.getValueAtTime(now + 0.4)).to.be.above(0.5);
222+
expect(envelope.control.getValueAtTime(now + 0.4)).to.be.below(0.65);
223+
expect(envelope.control.getValueAtTime(now + 0.8)).to.above(0.4);
224+
expect(envelope.control.getValueAtTime(now + 0.8)).to.below(0.5);
225+
expect(envelope.control.getValueAtTime(now + 1)).to.equal(0.4);
226+
});
227+
it('can be played on an input with delay', function () {
228+
let envelope = new p5.Envelope(0.1, 0.65, 0.5, 0.5, 0.35, 0.4);
229+
let osc = new p5.SinOsc();
230+
let now = p5.prototype.getAudioContext().currentTime;
231+
envelope.play(osc, 0.6);
232+
233+
expect(envelope.control.getValueAtTime(now + 0.7)).to.be.approximately(
234+
0.65,
235+
0.001
236+
);
237+
238+
expect(envelope.control.getValueAtTime(now + 1.2)).to.be.approximately(
239+
0.5,
240+
0.001
241+
);
242+
243+
expect(envelope.control.getValueAtTime(now + 1.55)).to.be.approximately(
244+
0.4,
245+
0.001
246+
);
247+
248+
expect(envelope.control.getValueAtTime(now + 0.5)).to.not.be.zero;
249+
expect(envelope.control.getValueAtTime(now + 0.5)).to.be.below(0.65);
250+
expect(envelope.control.getValueAtTime(now + 1)).to.be.above(0.5);
251+
expect(envelope.control.getValueAtTime(now + 1)).to.be.below(0.65);
252+
expect(envelope.control.getValueAtTime(now + 1.4)).to.above(0.4);
253+
expect(envelope.control.getValueAtTime(now + 1.4)).to.below(0.5);
254+
expect(envelope.control.getValueAtTime(now + 1.75)).to.equal(0.4);
255+
});
256+
it('can ramp to one/two value', function () {
257+
//todo
258+
});
259+
it('can be connected and disconnected', function () {
260+
let envelope = new p5.Envelope(0.1, 0.65, 0.5, 0.5, 0.35, 0.4);
261+
let reverb = new p5.Reverb();
262+
envelope.connect(reverb);
263+
envelope.disconnect();
264+
envelope.connect(reverb.output.gain);
265+
envelope.disconnect();
266+
});
267+
268+
//todo: signal math
269+
});
270+
});

0 commit comments

Comments
 (0)