tone 15.2.0 → 15.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Tone/component/analysis/Follower.test.ts +38 -42
- package/Tone/component/channel/Channel.test.ts +3 -4
- package/Tone/component/channel/Merge.test.ts +5 -6
- package/Tone/component/channel/MidSideSplit.test.ts +21 -25
- package/Tone/component/channel/Mono.test.ts +18 -20
- package/Tone/component/channel/PanVol.test.ts +3 -4
- package/Tone/component/channel/Panner.test.ts +28 -32
- package/Tone/component/channel/Recorder.ts +1 -1
- package/Tone/component/channel/Volume.test.ts +9 -12
- package/Tone/component/dynamics/Gate.test.ts +10 -14
- package/Tone/component/envelope/AmplitudeEnvelope.test.ts +7 -9
- package/Tone/component/envelope/Envelope.test.ts +347 -384
- package/Tone/component/filter/BiquadFilter.test.ts +5 -6
- package/Tone/component/filter/Convolver.test.ts +6 -9
- package/Tone/component/filter/FeedbackCombFilter.test.ts +14 -16
- package/Tone/component/filter/Filter.test.ts +5 -6
- package/Tone/component/filter/LowpassCombFilter.test.ts +15 -17
- package/Tone/core/clock/Clock.test.ts +12 -15
- package/Tone/core/clock/TickSignal.test.ts +18 -21
- package/Tone/core/clock/Transport.test.ts +133 -162
- package/Tone/core/clock/TransportEvent.test.ts +3 -4
- package/Tone/core/clock/TransportRepeatEvent.test.ts +6 -6
- package/Tone/core/context/Context.test.ts +8 -10
- package/Tone/core/context/Context.ts +8 -4
- package/Tone/core/context/Destination.test.ts +3 -4
- package/Tone/core/context/Offline.test.ts +23 -41
- package/Tone/core/context/OfflineContext.test.ts +20 -22
- package/Tone/core/context/Param.test.ts +33 -40
- package/Tone/core/context/ToneAudioBuffer.test.ts +3 -10
- package/Tone/core/context/ToneAudioBuffers.test.ts +9 -13
- package/Tone/core/worklet/ToneAudioWorklet.ts +3 -1
- package/Tone/effect/AutoFilter.test.ts +10 -12
- package/Tone/effect/AutoPanner.test.ts +10 -12
- package/Tone/effect/Chorus.test.ts +10 -14
- package/Tone/effect/FrequencyShifter.test.ts +6 -7
- package/Tone/effect/Reverb.test.ts +12 -15
- package/Tone/effect/Tremolo.test.ts +10 -12
- package/Tone/event/Loop.test.ts +29 -36
- package/Tone/event/Part.test.ts +152 -180
- package/Tone/event/Pattern.test.ts +16 -20
- package/Tone/event/Sequence.test.ts +86 -101
- package/Tone/event/ToneEvent.test.ts +60 -70
- package/Tone/instrument/MonoSynth.test.ts +3 -4
- package/Tone/instrument/PolySynth.test.ts +62 -74
- package/Tone/instrument/Sampler.test.ts +39 -48
- package/Tone/instrument/Synth.test.ts +40 -47
- package/Tone/signal/AudioToGain.test.ts +4 -5
- package/Tone/signal/Signal.test.ts +120 -143
- package/Tone/signal/SyncedSignal.test.ts +108 -122
- package/Tone/signal/ToneConstantSource.test.ts +21 -25
- package/Tone/signal/WaveShaper.test.ts +5 -6
- package/Tone/source/Source.test.ts +42 -48
- package/Tone/source/buffer/GrainPlayer.test.ts +29 -35
- package/Tone/source/buffer/Player.test.ts +162 -191
- package/Tone/source/buffer/Players.test.ts +44 -50
- package/Tone/source/buffer/ToneBufferSource.test.ts +176 -211
- package/Tone/source/oscillator/LFO.test.ts +49 -61
- package/Tone/source/oscillator/Oscillator.test.ts +24 -28
- package/Tone/source/oscillator/PulseOscillator.test.ts +36 -40
- package/Tone/source/oscillator/ToneOscillatorNode.test.ts +25 -29
- package/Tone/version.ts +1 -1
- package/build/Tone.js +1 -1
- package/build/Tone.js.map +1 -1
- package/build/esm/component/channel/Recorder.js.map +1 -1
- package/build/esm/core/context/Context.js +6 -3
- package/build/esm/core/context/Context.js.map +1 -1
- package/build/esm/core/worklet/ToneAudioWorklet.js.map +1 -1
- package/build/esm/version.js +1 -1
- package/package.json +1 -1
|
@@ -62,9 +62,9 @@ describe("Player", () => {
|
|
|
62
62
|
});
|
|
63
63
|
|
|
64
64
|
context("onstop", () => {
|
|
65
|
-
it("invokes the onstop method when the player is explicitly stopped", () => {
|
|
65
|
+
it("invokes the onstop method when the player is explicitly stopped", async () => {
|
|
66
66
|
let wasInvoked = false;
|
|
67
|
-
|
|
67
|
+
await Offline(() => {
|
|
68
68
|
const player = new Player({
|
|
69
69
|
onstop: () => {
|
|
70
70
|
wasInvoked = true;
|
|
@@ -72,36 +72,33 @@ describe("Player", () => {
|
|
|
72
72
|
url: buffer,
|
|
73
73
|
});
|
|
74
74
|
player.start(0).stop(0.1);
|
|
75
|
-
}, 0.2)
|
|
76
|
-
|
|
77
|
-
});
|
|
75
|
+
}, 0.2);
|
|
76
|
+
expect(wasInvoked).to.equal(true);
|
|
78
77
|
});
|
|
79
78
|
|
|
80
|
-
it("invokes the onstop method when the file is naturally over", () => {
|
|
79
|
+
it("invokes the onstop method when the file is naturally over", async () => {
|
|
81
80
|
let wasInvoked = false;
|
|
82
|
-
|
|
81
|
+
await Offline(() => {
|
|
83
82
|
const player = new Player(buffer);
|
|
84
83
|
player.start(0);
|
|
85
84
|
player.onstop = () => {
|
|
86
85
|
wasInvoked = true;
|
|
87
86
|
expect(player.state).to.equal("stopped");
|
|
88
87
|
};
|
|
89
|
-
}, buffer.duration * 1.1)
|
|
90
|
-
|
|
91
|
-
});
|
|
88
|
+
}, buffer.duration * 1.1);
|
|
89
|
+
expect(wasInvoked).to.equal(true);
|
|
92
90
|
});
|
|
93
91
|
|
|
94
|
-
it("invokes the onstop method on restart", () => {
|
|
92
|
+
it("invokes the onstop method on restart", async () => {
|
|
95
93
|
let wasInvoked = 0;
|
|
96
|
-
|
|
94
|
+
await Offline(() => {
|
|
97
95
|
const player = new Player(buffer);
|
|
98
96
|
player.start(0).restart(0.1).stop(0.2);
|
|
99
97
|
player.onstop = () => {
|
|
100
98
|
wasInvoked++;
|
|
101
99
|
};
|
|
102
|
-
}, 0.3)
|
|
103
|
-
|
|
104
|
-
});
|
|
100
|
+
}, 0.3);
|
|
101
|
+
expect(wasInvoked).to.equal(2);
|
|
105
102
|
});
|
|
106
103
|
});
|
|
107
104
|
|
|
@@ -114,11 +111,10 @@ describe("Player", () => {
|
|
|
114
111
|
});
|
|
115
112
|
});
|
|
116
113
|
|
|
117
|
-
it("loads a url using the load method", () => {
|
|
114
|
+
it("loads a url using the load method", async () => {
|
|
118
115
|
const player = new Player();
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
});
|
|
116
|
+
await player.load("./test/audio/sine.wav");
|
|
117
|
+
expect(player.buffer).to.be.instanceof(ToneAudioBuffer);
|
|
122
118
|
});
|
|
123
119
|
|
|
124
120
|
it("can be created with an options object", () => {
|
|
@@ -162,23 +158,22 @@ describe("Player", () => {
|
|
|
162
158
|
player.dispose();
|
|
163
159
|
});
|
|
164
160
|
|
|
165
|
-
it("can be played in reverse", () => {
|
|
161
|
+
it("can be played in reverse", async () => {
|
|
166
162
|
const shorterBuffer = buffer.slice(0, buffer.duration / 2);
|
|
167
163
|
const audioBuffer = (
|
|
168
164
|
shorterBuffer.get() as AudioBuffer
|
|
169
165
|
).getChannelData(0);
|
|
170
166
|
const lastSample = audioBuffer[audioBuffer.length - 1];
|
|
171
167
|
expect(lastSample).to.not.equal(0);
|
|
172
|
-
|
|
168
|
+
const buff = await Offline(() => {
|
|
173
169
|
const player = new Player({
|
|
174
170
|
reverse: true,
|
|
175
171
|
url: shorterBuffer.get(),
|
|
176
172
|
}).toDestination();
|
|
177
173
|
player.start(0);
|
|
178
|
-
}).then((buff) => {
|
|
179
|
-
const firstSample = buff.toArray()[0][0];
|
|
180
|
-
expect(firstSample).to.equal(lastSample);
|
|
181
174
|
});
|
|
175
|
+
const firstSample = buff.toArray()[0][0];
|
|
176
|
+
expect(firstSample).to.equal(lastSample);
|
|
182
177
|
});
|
|
183
178
|
});
|
|
184
179
|
|
|
@@ -206,84 +201,79 @@ describe("Player", () => {
|
|
|
206
201
|
player.dispose();
|
|
207
202
|
});
|
|
208
203
|
|
|
209
|
-
it("loops the audio", () => {
|
|
210
|
-
|
|
204
|
+
it("loops the audio", async () => {
|
|
205
|
+
const buff = await Offline(() => {
|
|
211
206
|
const player = new Player(buffer);
|
|
212
207
|
player.loop = true;
|
|
213
208
|
player.toDestination();
|
|
214
209
|
player.start(0);
|
|
215
|
-
}, buffer.duration * 1.5)
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
});
|
|
210
|
+
}, buffer.duration * 1.5);
|
|
211
|
+
expect(buff.getRmsAtTime(0)).to.be.above(0);
|
|
212
|
+
expect(buff.getRmsAtTime(buffer.duration * 0.5)).to.be.above(0);
|
|
213
|
+
expect(buff.getRmsAtTime(buffer.duration)).to.be.above(0);
|
|
214
|
+
expect(buff.getRmsAtTime(buffer.duration * 1.2)).to.be.above(0);
|
|
221
215
|
});
|
|
222
216
|
|
|
223
|
-
it("setting the loop multiple times has no affect", () => {
|
|
224
|
-
|
|
217
|
+
it("setting the loop multiple times has no affect", async () => {
|
|
218
|
+
const buff = await Offline(() => {
|
|
225
219
|
const player = new Player(buffer);
|
|
226
220
|
player.loop = true;
|
|
227
221
|
player.loop = true;
|
|
228
222
|
player.toDestination();
|
|
229
223
|
player.start(0);
|
|
230
|
-
}, buffer.duration * 1.5)
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
});
|
|
224
|
+
}, buffer.duration * 1.5);
|
|
225
|
+
expect(buff.getRmsAtTime(0)).to.be.above(0);
|
|
226
|
+
expect(buff.getRmsAtTime(buffer.duration * 0.5)).to.be.above(0);
|
|
227
|
+
expect(buff.getRmsAtTime(buffer.duration)).to.be.above(0);
|
|
228
|
+
expect(buff.getRmsAtTime(buffer.duration * 1.2)).to.be.above(0);
|
|
236
229
|
});
|
|
237
230
|
|
|
238
|
-
it("loops the audio when loop is set after start", () => {
|
|
239
|
-
|
|
231
|
+
it("loops the audio when loop is set after start", async () => {
|
|
232
|
+
const buff = await Offline(() => {
|
|
240
233
|
const player = new Player(buffer);
|
|
241
234
|
player.toDestination();
|
|
242
235
|
player.start(0);
|
|
243
236
|
player.loop = true;
|
|
244
|
-
}, buffer.duration * 1.5)
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
});
|
|
237
|
+
}, buffer.duration * 1.5);
|
|
238
|
+
expect(buff.getRmsAtTime(0)).to.be.above(0);
|
|
239
|
+
expect(buff.getRmsAtTime(buffer.duration * 0.5)).to.be.above(0);
|
|
240
|
+
expect(buff.getRmsAtTime(buffer.duration)).to.be.above(0);
|
|
241
|
+
expect(buff.getRmsAtTime(buffer.duration * 1.2)).to.be.above(0);
|
|
250
242
|
});
|
|
251
243
|
|
|
252
|
-
it("offset is the loopStart when set to loop", () => {
|
|
244
|
+
it("offset is the loopStart when set to loop", async () => {
|
|
253
245
|
const testSample =
|
|
254
246
|
buffer.toArray(0)[Math.floor(0.1 * getContext().sampleRate)];
|
|
255
|
-
|
|
247
|
+
const buff = await Offline(() => {
|
|
256
248
|
const player = new Player(buffer);
|
|
257
249
|
player.loopStart = 0.1;
|
|
258
250
|
player.loop = true;
|
|
259
251
|
player.toDestination();
|
|
260
252
|
player.start(0);
|
|
261
|
-
}, 0.05)
|
|
262
|
-
|
|
263
|
-
});
|
|
253
|
+
}, 0.05);
|
|
254
|
+
expect(buff.toArray()[0][0]).to.equal(testSample);
|
|
264
255
|
});
|
|
265
256
|
|
|
266
|
-
it("loops the audio for the specific duration", () => {
|
|
257
|
+
it("loops the audio for the specific duration", async () => {
|
|
267
258
|
const playDur = buffer.duration * 1.5;
|
|
268
|
-
|
|
259
|
+
const buff = await Offline(() => {
|
|
269
260
|
const player = new Player(buffer);
|
|
270
261
|
player.loop = true;
|
|
271
262
|
player.toDestination();
|
|
272
263
|
player.start(0, 0, playDur);
|
|
273
|
-
}, buffer.duration * 2)
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
}
|
|
264
|
+
}, buffer.duration * 2);
|
|
265
|
+
for (let time = 0; time < buffer.duration * 2; time += 0.1) {
|
|
266
|
+
const val = buff.getRmsAtTime(time);
|
|
267
|
+
if (time < playDur - 0.01) {
|
|
268
|
+
expect(val).to.be.greaterThan(0);
|
|
269
|
+
} else if (time > playDur) {
|
|
270
|
+
expect(val).to.equal(0);
|
|
281
271
|
}
|
|
282
|
-
}
|
|
272
|
+
}
|
|
283
273
|
});
|
|
284
274
|
|
|
285
|
-
it("correctly compensates if the offset is greater than the loopEnd", () => {
|
|
286
|
-
|
|
275
|
+
it("correctly compensates if the offset is greater than the loopEnd", async () => {
|
|
276
|
+
const buff = await Offline(() => {
|
|
287
277
|
// make a ramp between 0-1
|
|
288
278
|
const ramp = new Float32Array(
|
|
289
279
|
Math.floor(getContext().sampleRate * 0.3)
|
|
@@ -291,20 +281,19 @@ describe("Player", () => {
|
|
|
291
281
|
for (let i = 0; i < ramp.length; i++) {
|
|
292
282
|
ramp[i] = (i / ramp.length) * 0.3;
|
|
293
283
|
}
|
|
294
|
-
const
|
|
295
|
-
const player = new Player(
|
|
284
|
+
const playerBuff = ToneAudioBuffer.fromArray(ramp);
|
|
285
|
+
const player = new Player(playerBuff).toDestination();
|
|
296
286
|
player.loopStart = 0.1;
|
|
297
287
|
player.loopEnd = 0.2;
|
|
298
288
|
player.loop = true;
|
|
299
289
|
player.start(0, 0.35);
|
|
300
|
-
}, 0.05)
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
});
|
|
290
|
+
}, 0.05);
|
|
291
|
+
buff.forEach((sample, time) => {
|
|
292
|
+
if (time < 0.04) {
|
|
293
|
+
expect(sample).to.be.within(0.15, 0.2);
|
|
294
|
+
} else if (time > 0.05 && time < 0.09) {
|
|
295
|
+
expect(sample).to.be.within(0.1, 0.15);
|
|
296
|
+
}
|
|
308
297
|
});
|
|
309
298
|
});
|
|
310
299
|
});
|
|
@@ -401,20 +390,19 @@ describe("Player", () => {
|
|
|
401
390
|
});
|
|
402
391
|
|
|
403
392
|
context("Start Scheduling", () => {
|
|
404
|
-
it("can be start with an offset", () => {
|
|
393
|
+
it("can be start with an offset", async () => {
|
|
405
394
|
const testSample =
|
|
406
395
|
buffer.toArray(0)[Math.floor(0.1 * getContext().sampleRate)];
|
|
407
|
-
|
|
396
|
+
const buff = await Offline(() => {
|
|
408
397
|
const player = new Player(buffer.get());
|
|
409
398
|
player.toDestination();
|
|
410
399
|
player.start(0, 0.1);
|
|
411
|
-
}).then((buff) => {
|
|
412
|
-
expect(buff.toArray()[0][0]).to.equal(testSample);
|
|
413
400
|
});
|
|
401
|
+
expect(buff.toArray()[0][0]).to.equal(testSample);
|
|
414
402
|
});
|
|
415
403
|
|
|
416
|
-
it("is stopped and restarted when start is called twice", () => {
|
|
417
|
-
|
|
404
|
+
it("is stopped and restarted when start is called twice", async () => {
|
|
405
|
+
const buff = await Offline(() => {
|
|
418
406
|
// make a ramp between 0-1
|
|
419
407
|
const ramp = new Float32Array(
|
|
420
408
|
Math.floor(getContext().sampleRate * 0.3)
|
|
@@ -422,83 +410,78 @@ describe("Player", () => {
|
|
|
422
410
|
for (let i = 0; i < ramp.length; i++) {
|
|
423
411
|
ramp[i] = i / (ramp.length - 1);
|
|
424
412
|
}
|
|
425
|
-
const
|
|
426
|
-
const player = new Player(
|
|
413
|
+
const playerBuff = new ToneAudioBuffer().fromArray(ramp);
|
|
414
|
+
const player = new Player(playerBuff).toDestination();
|
|
427
415
|
player.start(0);
|
|
428
416
|
player.start(0.1);
|
|
429
|
-
}, 0.31)
|
|
430
|
-
|
|
431
|
-
});
|
|
417
|
+
}, 0.31);
|
|
418
|
+
expect(buff.max()).to.be.lessThan(1);
|
|
432
419
|
});
|
|
433
420
|
|
|
434
|
-
it("only seeks if player is started", () => {
|
|
435
|
-
|
|
421
|
+
it("only seeks if player is started", async () => {
|
|
422
|
+
const buff = await Offline(() => {
|
|
436
423
|
const player = new Player(buffer).toDestination();
|
|
437
424
|
player.seek(0.2, 0.01);
|
|
438
|
-
}, 0.05)
|
|
439
|
-
|
|
440
|
-
});
|
|
425
|
+
}, 0.05);
|
|
426
|
+
expect(buff.isSilent()).to.be.true;
|
|
441
427
|
});
|
|
442
428
|
|
|
443
|
-
it("can seek to a position at the given time", () => {
|
|
444
|
-
|
|
429
|
+
it("can seek to a position at the given time", async () => {
|
|
430
|
+
const buff = await Offline(() => {
|
|
445
431
|
const ramp = new Float32Array(
|
|
446
432
|
Math.floor(getContext().sampleRate * 0.3)
|
|
447
433
|
);
|
|
448
434
|
for (let i = 0; i < ramp.length; i++) {
|
|
449
435
|
ramp[i] = (i / ramp.length) * 0.3;
|
|
450
436
|
}
|
|
451
|
-
const
|
|
452
|
-
const player = new Player(
|
|
437
|
+
const playerBuff = new ToneAudioBuffer().fromArray(ramp);
|
|
438
|
+
const player = new Player(playerBuff).toDestination();
|
|
453
439
|
player.start(0);
|
|
454
440
|
player.seek(0.2, 0.1);
|
|
455
|
-
}, 0.3)
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
});
|
|
441
|
+
}, 0.3);
|
|
442
|
+
buff.forEach((sample, time) => {
|
|
443
|
+
if (time < 0.09) {
|
|
444
|
+
expect(sample).to.be.within(0, 0.1);
|
|
445
|
+
} else if (time > 0.1 && time < 0.19) {
|
|
446
|
+
expect(sample).to.be.within(0.2, 0.3);
|
|
447
|
+
}
|
|
463
448
|
});
|
|
464
449
|
});
|
|
465
450
|
|
|
466
|
-
it("can be play for a specific duration", () => {
|
|
467
|
-
|
|
451
|
+
it("can be play for a specific duration", async () => {
|
|
452
|
+
const buff = await Offline(() => {
|
|
468
453
|
const player = new Player(buffer);
|
|
469
454
|
player.toDestination();
|
|
470
455
|
player.start(0).stop(0.1);
|
|
471
|
-
return (
|
|
472
|
-
whenBetween(
|
|
456
|
+
return (time_2) => {
|
|
457
|
+
whenBetween(time_2, 0.1, Infinity, () => {
|
|
473
458
|
expect(player.state).to.equal("stopped");
|
|
474
459
|
});
|
|
475
|
-
whenBetween(
|
|
460
|
+
whenBetween(time_2, 0, 0.1, () => {
|
|
476
461
|
expect(player.state).to.equal("started");
|
|
477
462
|
});
|
|
478
463
|
};
|
|
479
|
-
}, 0.3)
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
});
|
|
464
|
+
}, 0.3);
|
|
465
|
+
buff.forEachBetween(
|
|
466
|
+
(sample) => {
|
|
467
|
+
expect(sample).to.equal(0);
|
|
468
|
+
},
|
|
469
|
+
0.11,
|
|
470
|
+
0.15
|
|
471
|
+
);
|
|
488
472
|
});
|
|
489
473
|
|
|
490
|
-
it("stops playing if invoked with 'stop' at a sooner time", () => {
|
|
491
|
-
|
|
474
|
+
it("stops playing if invoked with 'stop' at a sooner time", async () => {
|
|
475
|
+
const buff = await Offline(() => {
|
|
492
476
|
const player = new Player(buffer);
|
|
493
477
|
player.toDestination();
|
|
494
478
|
player.start(0).stop(0.1).stop(0.05);
|
|
495
|
-
}, 0.3)
|
|
496
|
-
|
|
497
|
-
});
|
|
479
|
+
}, 0.3);
|
|
480
|
+
expect(buff.getTimeOfLastSound()).to.be.closeTo(0.05, 0.02);
|
|
498
481
|
});
|
|
499
482
|
|
|
500
|
-
it("stops playing if at the last scheduled 'stop' time", () => {
|
|
501
|
-
|
|
483
|
+
it("stops playing if at the last scheduled 'stop' time", async () => {
|
|
484
|
+
const buff = await Offline(() => {
|
|
502
485
|
const player = new Player(buffer);
|
|
503
486
|
player.toDestination();
|
|
504
487
|
player
|
|
@@ -506,24 +489,22 @@ describe("Player", () => {
|
|
|
506
489
|
.start(0.1, 0, 0.05)
|
|
507
490
|
.start(0.2, 0, 0.05);
|
|
508
491
|
player.stop(0.1);
|
|
509
|
-
}, 0.3)
|
|
510
|
-
|
|
511
|
-
});
|
|
492
|
+
}, 0.3);
|
|
493
|
+
expect(buff.getTimeOfLastSound()).to.be.closeTo(0.1, 0.02);
|
|
512
494
|
});
|
|
513
495
|
|
|
514
|
-
it("can retrigger multiple sources which all stop at the stop time", () => {
|
|
515
|
-
|
|
496
|
+
it("can retrigger multiple sources which all stop at the stop time", async () => {
|
|
497
|
+
const buff = await Offline(() => {
|
|
516
498
|
const player = new Player(buffer);
|
|
517
499
|
player.toDestination();
|
|
518
500
|
player.loop = true;
|
|
519
501
|
player.start(0).start(0.1).start(0.2).stop(0.25);
|
|
520
|
-
}, 0.4)
|
|
521
|
-
|
|
522
|
-
});
|
|
502
|
+
}, 0.4);
|
|
503
|
+
expect(buff.getTimeOfLastSound()).to.be.closeTo(0.25, 0.02);
|
|
523
504
|
});
|
|
524
505
|
|
|
525
|
-
it("can be play for a specific duration passed in the 'start' method", () => {
|
|
526
|
-
|
|
506
|
+
it("can be play for a specific duration passed in the 'start' method", async () => {
|
|
507
|
+
const buff = await Offline(() => {
|
|
527
508
|
const player = new Player(buffer);
|
|
528
509
|
player.toDestination();
|
|
529
510
|
player.start(0, 0, 0.1);
|
|
@@ -535,9 +516,8 @@ describe("Player", () => {
|
|
|
535
516
|
expect(player.state).to.equal("started");
|
|
536
517
|
});
|
|
537
518
|
};
|
|
538
|
-
}, 0.3)
|
|
539
|
-
|
|
540
|
-
});
|
|
519
|
+
}, 0.3);
|
|
520
|
+
expect(buff.getTimeOfLastSound()).to.be.closeTo(0.1, 0.02);
|
|
541
521
|
});
|
|
542
522
|
|
|
543
523
|
it("reports itself as stopped after a single iterations of the buffer", () => {
|
|
@@ -556,16 +536,15 @@ describe("Player", () => {
|
|
|
556
536
|
}, buffer.duration * 1.1);
|
|
557
537
|
});
|
|
558
538
|
|
|
559
|
-
it("plays synced to the Transport", () => {
|
|
560
|
-
|
|
539
|
+
it("plays synced to the Transport", async () => {
|
|
540
|
+
const buff = await Offline(({ transport }) => {
|
|
561
541
|
const player = new Player(buffer)
|
|
562
542
|
.sync()
|
|
563
543
|
.start(0)
|
|
564
544
|
.toDestination();
|
|
565
545
|
transport.start(0);
|
|
566
|
-
}, 0.05)
|
|
567
|
-
|
|
568
|
-
});
|
|
546
|
+
}, 0.05);
|
|
547
|
+
expect(buff.isSilent()).to.be.false;
|
|
569
548
|
});
|
|
570
549
|
|
|
571
550
|
it("does not play twice when the offset is very small", () => {
|
|
@@ -584,24 +563,23 @@ describe("Player", () => {
|
|
|
584
563
|
);
|
|
585
564
|
});
|
|
586
565
|
|
|
587
|
-
it("offsets correctly when started by the Transport", () => {
|
|
566
|
+
it("offsets correctly when started by the Transport", async () => {
|
|
588
567
|
const testSample =
|
|
589
568
|
buffer.toArray(0)[
|
|
590
569
|
Math.floor(0.13125 * getContext().sampleRate)
|
|
591
570
|
];
|
|
592
|
-
|
|
571
|
+
const buff = await Offline(({ transport }) => {
|
|
593
572
|
const player = new Player(buffer)
|
|
594
573
|
.sync()
|
|
595
574
|
.start(0, 0.1)
|
|
596
575
|
.toDestination();
|
|
597
576
|
transport.start(0, 0.03125);
|
|
598
|
-
}, 0.05)
|
|
599
|
-
|
|
600
|
-
});
|
|
577
|
+
}, 0.05);
|
|
578
|
+
expect(buff.toArray()[0][0]).to.equal(testSample);
|
|
601
579
|
});
|
|
602
580
|
|
|
603
|
-
it("starts at the correct position when Transport is offset and playbackRate is not 1", () => {
|
|
604
|
-
|
|
581
|
+
it("starts at the correct position when Transport is offset and playbackRate is not 1", async () => {
|
|
582
|
+
const buff = await Offline(({ transport }) => {
|
|
605
583
|
// make a ramp between 0-1
|
|
606
584
|
const ramp = new Float32Array(
|
|
607
585
|
Math.floor(getContext().sampleRate * 0.3)
|
|
@@ -609,67 +587,64 @@ describe("Player", () => {
|
|
|
609
587
|
for (let i = 0; i < ramp.length; i++) {
|
|
610
588
|
ramp[i] = i / ramp.length;
|
|
611
589
|
}
|
|
612
|
-
const
|
|
613
|
-
const player = new Player(
|
|
590
|
+
const playerBuff = ToneAudioBuffer.fromArray(ramp);
|
|
591
|
+
const player = new Player(playerBuff).toDestination();
|
|
614
592
|
player.playbackRate = 0.5;
|
|
615
593
|
player.sync().start(0);
|
|
616
594
|
// start halfway through
|
|
617
595
|
transport.start(0, 0.15);
|
|
618
|
-
}, 0.05)
|
|
619
|
-
|
|
620
|
-
});
|
|
596
|
+
}, 0.05);
|
|
597
|
+
expect(buff.getValueAtTime(0)).to.be.closeTo(0.5, 0.05);
|
|
621
598
|
});
|
|
622
599
|
|
|
623
|
-
it("starts with an offset when synced and started after Transport is running", () => {
|
|
624
|
-
|
|
600
|
+
it("starts with an offset when synced and started after Transport is running", async () => {
|
|
601
|
+
const buff = await Offline(({ transport }) => {
|
|
625
602
|
const ramp = new Float32Array(
|
|
626
603
|
Math.floor(getContext().sampleRate * 0.3)
|
|
627
604
|
);
|
|
628
605
|
for (let i = 0; i < ramp.length; i++) {
|
|
629
606
|
ramp[i] = (i / ramp.length) * 0.3;
|
|
630
607
|
}
|
|
631
|
-
const
|
|
632
|
-
const player = new Player(
|
|
608
|
+
const playerBuff = new ToneAudioBuffer().fromArray(ramp);
|
|
609
|
+
const player = new Player(playerBuff).toDestination();
|
|
633
610
|
transport.start(0);
|
|
634
611
|
return atTime(0.1, () => {
|
|
635
612
|
player.sync().start(0);
|
|
636
613
|
});
|
|
637
|
-
}, 0.3)
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
});
|
|
614
|
+
}, 0.3);
|
|
615
|
+
expect(buff.getValueAtTime(0)).to.equal(0);
|
|
616
|
+
expect(buff.getValueAtTime(0.05)).to.equal(0);
|
|
617
|
+
expect(buff.getValueAtTime(0.11)).to.be.closeTo(0.11, 0.01);
|
|
618
|
+
expect(buff.getValueAtTime(0.2)).to.be.closeTo(0.2, 0.01);
|
|
643
619
|
});
|
|
644
620
|
|
|
645
|
-
it("can pass in an offset when synced and started after Transport is running", () => {
|
|
646
|
-
|
|
621
|
+
it("can pass in an offset when synced and started after Transport is running", async () => {
|
|
622
|
+
const buff = await Offline(({ transport }) => {
|
|
647
623
|
const ramp = new Float32Array(
|
|
648
624
|
Math.floor(getContext().sampleRate * 0.3)
|
|
649
625
|
);
|
|
650
626
|
for (let i = 0; i < ramp.length; i++) {
|
|
651
627
|
ramp[i] = (i / ramp.length) * 0.3;
|
|
652
628
|
}
|
|
653
|
-
const
|
|
654
|
-
const player = new Player(
|
|
629
|
+
const playerBuff = new ToneAudioBuffer().fromArray(ramp);
|
|
630
|
+
const player = new Player(playerBuff).toDestination();
|
|
655
631
|
player.loop = true;
|
|
656
632
|
transport.start(0);
|
|
657
633
|
return atTime(0.1, () => {
|
|
658
634
|
player.sync().start(0, 0.1);
|
|
659
635
|
});
|
|
660
|
-
}, 0.3)
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
});
|
|
636
|
+
}, 0.3);
|
|
637
|
+
expect(buff.getValueAtTime(0)).to.equal(0);
|
|
638
|
+
expect(buff.getValueAtTime(0.05)).to.equal(0);
|
|
639
|
+
expect(buff.getValueAtTime(0.11)).to.be.closeTo(0.21, 0.01);
|
|
640
|
+
expect(buff.getValueAtTime(0.15)).to.be.closeTo(0.25, 0.01);
|
|
641
|
+
expect(buff.getValueAtTime(0.2)).to.be.closeTo(0.0, 0.01);
|
|
642
|
+
expect(buff.getValueAtTime(0.25)).to.be.closeTo(0.05, 0.01);
|
|
668
643
|
});
|
|
669
644
|
|
|
670
|
-
it("fades in and out correctly", () => {
|
|
645
|
+
it("fades in and out correctly", async () => {
|
|
671
646
|
let duration = 0.5;
|
|
672
|
-
|
|
647
|
+
const buff = await Offline(() => {
|
|
673
648
|
const onesArray = new Float32Array(
|
|
674
649
|
getContext().sampleRate * duration
|
|
675
650
|
);
|
|
@@ -683,18 +658,14 @@ describe("Player", () => {
|
|
|
683
658
|
fadeIn: 0.1,
|
|
684
659
|
}).toDestination();
|
|
685
660
|
player.start(0);
|
|
686
|
-
}, 0.6)
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
0.1
|
|
695
|
-
);
|
|
696
|
-
expect(buff.getRmsAtTime(duration + 0.1)).to.be.closeTo(0, 0.1);
|
|
697
|
-
});
|
|
661
|
+
}, 0.6);
|
|
662
|
+
expect(buff.getRmsAtTime(0)).to.be.closeTo(0, 0.1);
|
|
663
|
+
expect(buff.getRmsAtTime(0.05)).to.be.closeTo(0.5, 0.1);
|
|
664
|
+
expect(buff.getRmsAtTime(0.1)).to.be.closeTo(1, 0.1);
|
|
665
|
+
duration -= 0.1;
|
|
666
|
+
expect(buff.getRmsAtTime(duration)).to.be.closeTo(1, 0.1);
|
|
667
|
+
expect(buff.getRmsAtTime(duration + 0.05)).to.be.closeTo(0.5, 0.1);
|
|
668
|
+
expect(buff.getRmsAtTime(duration + 0.1)).to.be.closeTo(0, 0.1);
|
|
698
669
|
});
|
|
699
670
|
|
|
700
671
|
it("stops only last activeSource when restarting at intervals < latencyHint", (done) => {
|