tone 15.3.2 → 15.3.4
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/core/clock/Transport.test.ts +66 -6
- package/Tone/core/clock/Transport.ts +22 -0
- package/Tone/core/context/BaseContext.ts +3 -0
- package/Tone/core/context/Destination.test.ts +1 -1
- package/Tone/core/context/Param.test.ts +25 -38
- package/Tone/core/type/Time.test.ts +5 -2
- package/Tone/core/util/Debug.ts +1 -1
- package/Tone/core/util/Emitter.ts +0 -1
- package/Tone/event/Sequence.test.ts +12 -5
- package/Tone/instrument/MetalSynth.test.ts +1 -1
- package/Tone/signal/Signal.test.ts +232 -26
- package/Tone/signal/Signal.ts +98 -0
- package/Tone/source/Source.ts +0 -1
- package/Tone/version.ts +1 -1
- package/build/Tone.js +1 -1
- package/build/Tone.js.map +1 -1
- package/build/esm/core/clock/Transport.d.ts +12 -0
- package/build/esm/core/clock/Transport.js +20 -0
- package/build/esm/core/clock/Transport.js.map +1 -1
- package/build/esm/core/context/BaseContext.d.ts +3 -0
- package/build/esm/core/context/BaseContext.js +3 -0
- package/build/esm/core/context/BaseContext.js.map +1 -1
- package/build/esm/core/util/Debug.js +1 -1
- package/build/esm/core/util/Emitter.d.ts +0 -1
- package/build/esm/core/util/Emitter.js +0 -1
- package/build/esm/core/util/Emitter.js.map +1 -1
- package/build/esm/signal/Signal.d.ts +10 -0
- package/build/esm/signal/Signal.js +63 -1
- package/build/esm/signal/Signal.js.map +1 -1
- package/build/esm/source/Source.js +0 -1
- package/build/esm/source/Source.js.map +1 -1
- package/build/esm/version.js +1 -1
- package/package.json +1 -1
|
@@ -241,6 +241,33 @@ describe("Transport", () => {
|
|
|
241
241
|
});
|
|
242
242
|
});
|
|
243
243
|
|
|
244
|
+
it("can schedule the current seconds position", () => {
|
|
245
|
+
return Offline((context) => {
|
|
246
|
+
const transport = new TransportInstance({ context });
|
|
247
|
+
transport.start();
|
|
248
|
+
|
|
249
|
+
let scheduled = false;
|
|
250
|
+
|
|
251
|
+
return (time) => {
|
|
252
|
+
if (time > 0.5 && !scheduled) {
|
|
253
|
+
scheduled = true;
|
|
254
|
+
transport.setSecondsAtTime(3, 0.5);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
whenBetween(time, 0, 0.5, () => {
|
|
258
|
+
expect(transport.seconds).to.be.closeTo(time, 0.01);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
whenBetween(time, 0.5, 1, () => {
|
|
262
|
+
expect(transport.seconds).to.be.closeTo(
|
|
263
|
+
2.5 + time,
|
|
264
|
+
0.01
|
|
265
|
+
);
|
|
266
|
+
});
|
|
267
|
+
};
|
|
268
|
+
}, 1);
|
|
269
|
+
});
|
|
270
|
+
|
|
244
271
|
it("can set the current position in BarsBeatsSixteenths", () => {
|
|
245
272
|
return Offline((context) => {
|
|
246
273
|
const transport = new TransportInstance({ context });
|
|
@@ -330,14 +357,17 @@ describe("Transport", () => {
|
|
|
330
357
|
expect(transport.getTicksAtTime(0)).to.be.equal(
|
|
331
358
|
Math.floor(transport.PPQ * 0)
|
|
332
359
|
);
|
|
333
|
-
expect(transport.getTicksAtTime(0.05)).to.be.
|
|
334
|
-
Math.floor(transport.PPQ * 0.1)
|
|
360
|
+
expect(transport.getTicksAtTime(0.05)).to.be.closeTo(
|
|
361
|
+
Math.floor(transport.PPQ * 0.1),
|
|
362
|
+
0.5
|
|
335
363
|
);
|
|
336
|
-
expect(transport.getTicksAtTime(0.1)).to.be.
|
|
337
|
-
Math.floor(transport.PPQ * 0.2)
|
|
364
|
+
expect(transport.getTicksAtTime(0.1)).to.be.closeTo(
|
|
365
|
+
Math.floor(transport.PPQ * 0.2),
|
|
366
|
+
0.5
|
|
338
367
|
);
|
|
339
|
-
expect(transport.getTicksAtTime(0.15)).to.be.
|
|
340
|
-
Math.floor(transport.PPQ * 0.2)
|
|
368
|
+
expect(transport.getTicksAtTime(0.15)).to.be.closeTo(
|
|
369
|
+
Math.floor(transport.PPQ * 0.2),
|
|
370
|
+
0.5
|
|
341
371
|
);
|
|
342
372
|
expect(transport.getTicksAtTime(0.2)).to.be.equal(0);
|
|
343
373
|
}, 0.3);
|
|
@@ -420,6 +450,36 @@ describe("Transport", () => {
|
|
|
420
450
|
}, 2.5);
|
|
421
451
|
expect(invocations).to.equal(2);
|
|
422
452
|
});
|
|
453
|
+
|
|
454
|
+
it("can schedule the ticks", () => {
|
|
455
|
+
return Offline((context) => {
|
|
456
|
+
const transport = new TransportInstance({ context });
|
|
457
|
+
transport.start();
|
|
458
|
+
|
|
459
|
+
let scheduled = false;
|
|
460
|
+
|
|
461
|
+
return (time) => {
|
|
462
|
+
if (time > 0.5 && !scheduled) {
|
|
463
|
+
scheduled = true;
|
|
464
|
+
transport.setTicksAtTime(0, 0.5);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
whenBetween(time, 0, 0.5, () => {
|
|
468
|
+
expect(transport.ticks).to.be.closeTo(
|
|
469
|
+
transport.toTicks(time),
|
|
470
|
+
1
|
|
471
|
+
);
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
whenBetween(time, 0.5, 1, () => {
|
|
475
|
+
expect(transport.ticks).to.be.closeTo(
|
|
476
|
+
transport.toTicks(time - 0.5),
|
|
477
|
+
1
|
|
478
|
+
);
|
|
479
|
+
});
|
|
480
|
+
};
|
|
481
|
+
}, 1);
|
|
482
|
+
});
|
|
423
483
|
});
|
|
424
484
|
|
|
425
485
|
context("schedule", () => {
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
TransportTime,
|
|
28
28
|
} from "../type/Units.js";
|
|
29
29
|
import { enterScheduledCallback } from "../util/Debug.js";
|
|
30
|
+
import { assertUsedScheduleTime } from "../util/Debug.js";
|
|
30
31
|
import { optionsFromArguments } from "../util/Defaults.js";
|
|
31
32
|
import { Emitter } from "../util/Emitter.js";
|
|
32
33
|
import { readOnly, writable } from "../util/Interface.js";
|
|
@@ -623,6 +624,7 @@ export class TransportInstance
|
|
|
623
624
|
return this._clock.ticks;
|
|
624
625
|
}
|
|
625
626
|
set ticks(t: Ticks) {
|
|
627
|
+
assertUsedScheduleTime();
|
|
626
628
|
if (this._clock.ticks !== t) {
|
|
627
629
|
const now = this.now();
|
|
628
630
|
// stop everything synced to the transport
|
|
@@ -654,6 +656,16 @@ export class TransportInstance
|
|
|
654
656
|
return this._clock.getTicksAtTime(time);
|
|
655
657
|
}
|
|
656
658
|
|
|
659
|
+
/**
|
|
660
|
+
* Set the Transport's {@link ticks} value at the given time
|
|
661
|
+
* @param ticks The tick value to set
|
|
662
|
+
* @param time The Context time at which to set the seconds value
|
|
663
|
+
*/
|
|
664
|
+
setTicksAtTime(ticks: Ticks, time: Time): this {
|
|
665
|
+
this._clock.setTicksAtTime(ticks, time);
|
|
666
|
+
return this;
|
|
667
|
+
}
|
|
668
|
+
|
|
657
669
|
/**
|
|
658
670
|
* Return the elapsed seconds at the given time.
|
|
659
671
|
* @param time When to get the elapsed seconds
|
|
@@ -663,6 +675,16 @@ export class TransportInstance
|
|
|
663
675
|
return this._clock.getSecondsAtTime(time);
|
|
664
676
|
}
|
|
665
677
|
|
|
678
|
+
/**
|
|
679
|
+
* Set the Transport's {@link seconds} value at the given time.
|
|
680
|
+
* @param seconds The seconds value to set
|
|
681
|
+
* @param time The Context time at which to set the seconds value
|
|
682
|
+
*/
|
|
683
|
+
setSecondsAtTime(seconds: Seconds, time: Time): this {
|
|
684
|
+
this.setTicksAtTime(this.toTicks(seconds), time);
|
|
685
|
+
return this;
|
|
686
|
+
}
|
|
687
|
+
|
|
666
688
|
/**
|
|
667
689
|
* Pulses Per Quarter note. This is the smallest resolution
|
|
668
690
|
* the Transport timing supports. This should be set once
|
|
@@ -25,6 +25,9 @@ export type BaseAudioContextSubset = Omit<
|
|
|
25
25
|
|
|
26
26
|
export type ContextLatencyHint = AudioContextLatencyCategory;
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Shared class for both Offline and Online Audio Context's
|
|
30
|
+
*/
|
|
28
31
|
export abstract class BaseContext
|
|
29
32
|
extends Emitter<"statechange" | "tick">
|
|
30
33
|
implements BaseAudioContextSubset
|
|
@@ -59,7 +59,7 @@ describe("Destination", () => {
|
|
|
59
59
|
);
|
|
60
60
|
});
|
|
61
61
|
|
|
62
|
-
it("can set the audio channel configuration", () => {
|
|
62
|
+
it.skip("can set the audio channel configuration", () => {
|
|
63
63
|
return Offline(
|
|
64
64
|
(context) => {
|
|
65
65
|
expect(context.destination.channelCount).to.equal(4);
|
|
@@ -5,9 +5,8 @@ import { Plot } from "../../../test/helper/compare/index.js";
|
|
|
5
5
|
import { atTime, Offline } from "../../../test/helper/Offline.js";
|
|
6
6
|
import { Signal } from "../../signal/Signal.js";
|
|
7
7
|
import { getContext } from "../Global.js";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
} from "../type/Units.js";
|
|
8
|
+
import { UnitName } from "../type/Units.js";
|
|
9
|
+
import { Gain } from "./Gain.js";
|
|
11
10
|
import { Param } from "./Param.js";
|
|
12
11
|
import { connect } from "./ToneAudioNode.js";
|
|
13
12
|
|
|
@@ -120,7 +119,6 @@ describe("Param", () => {
|
|
|
120
119
|
1,
|
|
121
120
|
sampleRate
|
|
122
121
|
);
|
|
123
|
-
// document.body.appendChild(await Plot.signal(testBuffer));
|
|
124
122
|
matchesOutputCurve(param, testBuffer);
|
|
125
123
|
});
|
|
126
124
|
|
|
@@ -155,7 +153,6 @@ describe("Param", () => {
|
|
|
155
153
|
1,
|
|
156
154
|
sampleRate
|
|
157
155
|
);
|
|
158
|
-
// document.body.appendChild(await Plot.signal(testBuffer));
|
|
159
156
|
matchesOutputCurve(param, testBuffer);
|
|
160
157
|
});
|
|
161
158
|
|
|
@@ -199,30 +196,7 @@ describe("Param", () => {
|
|
|
199
196
|
sampleRate
|
|
200
197
|
);
|
|
201
198
|
matchesOutputCurve(param, testBuffer);
|
|
202
|
-
// document.body.appendChild(await Plot.signal(testBuffer));
|
|
203
199
|
});
|
|
204
|
-
|
|
205
|
-
// it ("matches known values", async () => {
|
|
206
|
-
// await Compare.toFile(context => {
|
|
207
|
-
// const source = context.createConstantSource();
|
|
208
|
-
// source.connect(context.rawContext.destination);
|
|
209
|
-
// source.start(0);
|
|
210
|
-
// const param = new Param({
|
|
211
|
-
// context,
|
|
212
|
-
// param: source.offset,
|
|
213
|
-
// value: 0.1,
|
|
214
|
-
// });
|
|
215
|
-
// param.setValueAtTime(0, 0);
|
|
216
|
-
// param.setValueAtTime(1, 0.2);
|
|
217
|
-
// param.cancelAndHoldAtTime(0.1);
|
|
218
|
-
// param.linearRampToValueAtTime(1, 0.3);
|
|
219
|
-
// param.cancelAndHoldAtTime(0.2);
|
|
220
|
-
// param.exponentialRampToValueAtTime(0, 0.4);
|
|
221
|
-
// param.cancelAndHoldAtTime(0.25);
|
|
222
|
-
// param.setTargetAtTime(1, 0.3, 0.1);
|
|
223
|
-
// param.cancelAndHoldAtTime(0.4);
|
|
224
|
-
// }, "/base/test/audio/param/curve_0.wav", 0.01, 0.5, 1, 11025);
|
|
225
|
-
// });
|
|
226
200
|
});
|
|
227
201
|
|
|
228
202
|
context("Units", () => {
|
|
@@ -453,7 +427,6 @@ describe("Param", () => {
|
|
|
453
427
|
testUnitConversion("frequency", 0.1, 0.1, 0.1);
|
|
454
428
|
testUnitConversion("normalRange", 0, 0, 0);
|
|
455
429
|
testUnitConversion("normalRange", 0.5, 0.5, 0.5);
|
|
456
|
-
testUnitConversion("normalRange", 1.5, 1, 1);
|
|
457
430
|
testUnitConversion("audioRange", -1, -1, -1);
|
|
458
431
|
testUnitConversion("audioRange", 0.5, 0.5, 0.5);
|
|
459
432
|
testUnitConversion("audioRange", 1, 1, 1);
|
|
@@ -533,9 +506,9 @@ describe("Param", () => {
|
|
|
533
506
|
context("setValueAtTime", () => {
|
|
534
507
|
function testSetValueAtTime(
|
|
535
508
|
units: UnitName,
|
|
536
|
-
value0,
|
|
537
|
-
value1,
|
|
538
|
-
value2
|
|
509
|
+
value0: number,
|
|
510
|
+
value1: number,
|
|
511
|
+
value2: number
|
|
539
512
|
): void {
|
|
540
513
|
it(`can schedule value with units ${units}`, async () => {
|
|
541
514
|
const testBuffer = await Offline(
|
|
@@ -601,6 +574,20 @@ describe("Param", () => {
|
|
|
601
574
|
testSetValueAtTime(unit, 0, 1, 0.5);
|
|
602
575
|
}
|
|
603
576
|
});
|
|
577
|
+
|
|
578
|
+
it("asserts a value range", async () => {
|
|
579
|
+
let errored = false;
|
|
580
|
+
try {
|
|
581
|
+
const source = new Gain();
|
|
582
|
+
const param = new Param({
|
|
583
|
+
param: source.gain,
|
|
584
|
+
units: "normalRange",
|
|
585
|
+
});
|
|
586
|
+
param.setValueAtTime(2, 0);
|
|
587
|
+
} catch (e) {
|
|
588
|
+
errored = true;
|
|
589
|
+
}
|
|
590
|
+
});
|
|
604
591
|
});
|
|
605
592
|
|
|
606
593
|
["linearRampToValueAtTime", "exponentialRampToValueAtTime"].forEach(
|
|
@@ -608,9 +595,9 @@ describe("Param", () => {
|
|
|
608
595
|
context(method, () => {
|
|
609
596
|
function testRampToValueAtTime(
|
|
610
597
|
units: UnitName,
|
|
611
|
-
value0,
|
|
612
|
-
value1,
|
|
613
|
-
value2
|
|
598
|
+
value0: number,
|
|
599
|
+
value1: number,
|
|
600
|
+
value2: number
|
|
614
601
|
): void {
|
|
615
602
|
it(`can schedule value with units ${units}`, async () => {
|
|
616
603
|
const testBuffer = await Offline(
|
|
@@ -689,9 +676,9 @@ describe("Param", () => {
|
|
|
689
676
|
context(method, () => {
|
|
690
677
|
function testRampToValueAtTime(
|
|
691
678
|
units: UnitName,
|
|
692
|
-
value0,
|
|
693
|
-
value1,
|
|
694
|
-
value2
|
|
679
|
+
value0: number,
|
|
680
|
+
value1: number,
|
|
681
|
+
value2: number
|
|
695
682
|
): void {
|
|
696
683
|
it(`can schedule value with units ${units}`, async () => {
|
|
697
684
|
const testBuffer = await Offline(
|
|
@@ -161,11 +161,14 @@ describe("TimeClass", () => {
|
|
|
161
161
|
|
|
162
162
|
it("converts time into ticks", () => {
|
|
163
163
|
return Offline(({ transport }) => {
|
|
164
|
-
expect(Time("2n").toTicks()).to.
|
|
164
|
+
expect(Time("2n").toTicks()).to.closeTo(2 * transport.PPQ, 0.1);
|
|
165
165
|
// floating point checks
|
|
166
166
|
const bpmOrig = transport.bpm.value;
|
|
167
167
|
transport.bpm.value = 100;
|
|
168
|
-
expect(Time("0:1:3").toTicks()).to.
|
|
168
|
+
expect(Time("0:1:3").toTicks()).to.closeTo(
|
|
169
|
+
1.75 * transport.PPQ,
|
|
170
|
+
0.1
|
|
171
|
+
);
|
|
169
172
|
transport.bpm.value = bpmOrig;
|
|
170
173
|
});
|
|
171
174
|
});
|
package/Tone/core/util/Debug.ts
CHANGED
|
@@ -60,7 +60,7 @@ export function assertUsedScheduleTime(time?: Time): void {
|
|
|
60
60
|
) {
|
|
61
61
|
printedScheduledWarning = true;
|
|
62
62
|
warn(
|
|
63
|
-
"
|
|
63
|
+
"Schedulable methods should include the provided time argument to ensure accurate timing. See https://github.com/Tonejs/Tone.js/wiki/Accurate-Timing"
|
|
64
64
|
);
|
|
65
65
|
}
|
|
66
66
|
}
|
|
@@ -10,7 +10,6 @@ export interface EmitterEventObject {
|
|
|
10
10
|
* the ability to listen for and emit events.
|
|
11
11
|
* Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js).
|
|
12
12
|
* MIT (c) 2011 Jerome Etienne.
|
|
13
|
-
* @category Core
|
|
14
13
|
*/
|
|
15
14
|
export class Emitter<EventType extends string = string> extends Tone {
|
|
16
15
|
readonly name: string = "Emitter";
|
|
@@ -61,13 +61,20 @@ describe("Sequence", () => {
|
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
it("loops by default with the loopEnd as the duration of the loop", async () => {
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
const values: number[] = [];
|
|
65
|
+
await Offline(({ transport }) => {
|
|
66
|
+
const seq = new Sequence(
|
|
67
|
+
(_, value) => {
|
|
68
|
+
values.push(value);
|
|
69
|
+
},
|
|
70
|
+
[0, 1, 2, 3],
|
|
71
|
+
"8n"
|
|
72
|
+
).start(0);
|
|
66
73
|
expect(seq.loop).to.be.true;
|
|
67
74
|
expect(seq.length).to.equal(4);
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
75
|
+
transport.start(0);
|
|
76
|
+
}, 2);
|
|
77
|
+
expect(values).to.deep.equal([0, 1, 2, 3, 0, 1, 2, 3]);
|
|
71
78
|
});
|
|
72
79
|
});
|
|
73
80
|
|
|
@@ -9,7 +9,7 @@ import { MetalSynth } from "./MetalSynth.js";
|
|
|
9
9
|
describe("MetalSynth", () => {
|
|
10
10
|
BasicTests(MetalSynth);
|
|
11
11
|
|
|
12
|
-
InstrumentTest(MetalSynth, "C2");
|
|
12
|
+
InstrumentTest(MetalSynth, "C2", undefined, undefined, true);
|
|
13
13
|
MonophonicTest(MetalSynth, "C4");
|
|
14
14
|
|
|
15
15
|
it("matches a file", () => {
|
|
@@ -4,7 +4,7 @@ import { BasicTests } from "../../test/helper/Basic.js";
|
|
|
4
4
|
import { ConstantOutput } from "../../test/helper/ConstantOutput.js";
|
|
5
5
|
import { Offline } from "../../test/helper/Offline.js";
|
|
6
6
|
import { Gain } from "../core/context/Gain.js";
|
|
7
|
-
import { Signal } from "./Signal.js";
|
|
7
|
+
import { connectSignal, disconnectSignal, Signal } from "./Signal.js";
|
|
8
8
|
|
|
9
9
|
describe("Signal", () => {
|
|
10
10
|
BasicTests(Signal);
|
|
@@ -142,32 +142,8 @@ describe("Signal", () => {
|
|
|
142
142
|
expect(buffer.getValueAtTime(1)).to.be.closeTo(0, 0.001);
|
|
143
143
|
});
|
|
144
144
|
|
|
145
|
-
it("can disconnect from all the connected notes", async () => {
|
|
146
|
-
await ConstantOutput(async (context) => {
|
|
147
|
-
const output0 = new Signal(1).toDestination();
|
|
148
|
-
const output1 = new Signal(1).toDestination();
|
|
149
|
-
const sig = new Signal(0).connect(output0);
|
|
150
|
-
sig.connect(output1);
|
|
151
|
-
sig.disconnect();
|
|
152
|
-
sig.setValueAtTime(0, 0);
|
|
153
|
-
sig.linearRampToValueAtTime(0.5, 0.5);
|
|
154
|
-
sig.linearRampToValueAtTime(0, 1);
|
|
155
|
-
}, 0);
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
it("can disconnect from a specific node", async () => {
|
|
159
|
-
await ConstantOutput(async (context) => {
|
|
160
|
-
const output = new Signal(1).toDestination();
|
|
161
|
-
const sig = new Signal(0).connect(output);
|
|
162
|
-
sig.disconnect(output);
|
|
163
|
-
sig.setValueAtTime(0, 0);
|
|
164
|
-
sig.linearRampToValueAtTime(0.5, 0.5);
|
|
165
|
-
sig.linearRampToValueAtTime(0, 1);
|
|
166
|
-
}, 0);
|
|
167
|
-
});
|
|
168
|
-
|
|
169
145
|
it("can schedule multiple automations from a connected signal through a multiple nodes", async () => {
|
|
170
|
-
const buffer = await Offline(
|
|
146
|
+
const buffer = await Offline(() => {
|
|
171
147
|
const output = new Signal(0).toDestination();
|
|
172
148
|
const proxy = new Signal(0).connect(output);
|
|
173
149
|
const gain = new Gain(1).connect(proxy);
|
|
@@ -427,6 +403,8 @@ describe("Signal", () => {
|
|
|
427
403
|
}).to.throw(RangeError);
|
|
428
404
|
const signal = new Signal(1, "normalRange");
|
|
429
405
|
expect(signal.value).to.be.closeTo(1, 0.01);
|
|
406
|
+
expect(signal.minValue).to.be.equal(0);
|
|
407
|
+
expect(signal.maxValue).to.be.equal(1);
|
|
430
408
|
signal.dispose();
|
|
431
409
|
});
|
|
432
410
|
|
|
@@ -436,6 +414,8 @@ describe("Signal", () => {
|
|
|
436
414
|
}).to.throw(RangeError);
|
|
437
415
|
const signal = new Signal(-1, "audioRange");
|
|
438
416
|
expect(signal.value).to.be.closeTo(-1, 0.01);
|
|
417
|
+
expect(signal.minValue).to.be.equal(-1);
|
|
418
|
+
expect(signal.maxValue).to.be.equal(1);
|
|
439
419
|
signal.dispose();
|
|
440
420
|
});
|
|
441
421
|
|
|
@@ -445,6 +425,7 @@ describe("Signal", () => {
|
|
|
445
425
|
}).to.throw(RangeError);
|
|
446
426
|
const signal = new Signal(100, "positive");
|
|
447
427
|
expect(signal.value).to.be.closeTo(100, 0.01);
|
|
428
|
+
expect(signal.minValue).to.be.equal(0);
|
|
448
429
|
signal.dispose();
|
|
449
430
|
});
|
|
450
431
|
});
|
|
@@ -510,4 +491,229 @@ describe("Signal", () => {
|
|
|
510
491
|
}, 5);
|
|
511
492
|
});
|
|
512
493
|
});
|
|
494
|
+
|
|
495
|
+
context("connectSignal/disconnectSignal", () => {
|
|
496
|
+
it("can connect a Signal to an AudioNode", () => {
|
|
497
|
+
return ConstantOutput((context) => {
|
|
498
|
+
const sig = new Signal({
|
|
499
|
+
value: 3,
|
|
500
|
+
context,
|
|
501
|
+
});
|
|
502
|
+
const gain = new Gain({
|
|
503
|
+
gain: 0.5,
|
|
504
|
+
context,
|
|
505
|
+
}).toDestination();
|
|
506
|
+
connectSignal(sig, gain);
|
|
507
|
+
}, 1.5);
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
it("can connect a Signal to a Param", () => {
|
|
511
|
+
return ConstantOutput((context) => {
|
|
512
|
+
const sig = new Signal({
|
|
513
|
+
value: 3,
|
|
514
|
+
context,
|
|
515
|
+
});
|
|
516
|
+
const scalar = new Signal({
|
|
517
|
+
value: 2,
|
|
518
|
+
context,
|
|
519
|
+
});
|
|
520
|
+
const gain = new Gain({
|
|
521
|
+
gain: 0.5,
|
|
522
|
+
context,
|
|
523
|
+
}).toDestination();
|
|
524
|
+
connectSignal(sig, gain);
|
|
525
|
+
connectSignal(scalar, gain.gain);
|
|
526
|
+
// gain of 0.5 is overridden
|
|
527
|
+
expect(gain.gain.value).to.equal(0);
|
|
528
|
+
}, 6);
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
it("can connect a Signal to a Signal", () => {
|
|
532
|
+
return ConstantOutput((context) => {
|
|
533
|
+
const sig = new Signal({
|
|
534
|
+
value: 3,
|
|
535
|
+
context,
|
|
536
|
+
});
|
|
537
|
+
const output = new Signal({
|
|
538
|
+
value: 0.5,
|
|
539
|
+
context,
|
|
540
|
+
}).toDestination();
|
|
541
|
+
|
|
542
|
+
connectSignal(sig, output);
|
|
543
|
+
expect(output.overridden).to.be.true;
|
|
544
|
+
}, 3);
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
it("can disconnect a Signal from an AudioNode", () => {
|
|
548
|
+
return ConstantOutput((context) => {
|
|
549
|
+
const sig = new Signal({
|
|
550
|
+
value: 3,
|
|
551
|
+
context,
|
|
552
|
+
});
|
|
553
|
+
const gain = new Gain({
|
|
554
|
+
gain: 0.5,
|
|
555
|
+
context,
|
|
556
|
+
}).toDestination();
|
|
557
|
+
connectSignal(sig, gain);
|
|
558
|
+
disconnectSignal(sig, gain);
|
|
559
|
+
}, 0);
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
it("can disconnect a Signal from a Param", () => {
|
|
563
|
+
return ConstantOutput((context) => {
|
|
564
|
+
const sig = new Signal({
|
|
565
|
+
value: 3,
|
|
566
|
+
context,
|
|
567
|
+
});
|
|
568
|
+
const scalar = new Signal({
|
|
569
|
+
value: 2,
|
|
570
|
+
context,
|
|
571
|
+
});
|
|
572
|
+
const gain = new Gain({
|
|
573
|
+
gain: 0.5,
|
|
574
|
+
context,
|
|
575
|
+
}).toDestination();
|
|
576
|
+
connectSignal(sig, gain);
|
|
577
|
+
connectSignal(scalar, gain.gain);
|
|
578
|
+
// gain of 0.5 is overridden
|
|
579
|
+
expect(gain.gain.value).to.equal(0);
|
|
580
|
+
|
|
581
|
+
disconnectSignal(scalar, gain.gain);
|
|
582
|
+
// the original value is restored
|
|
583
|
+
expect(gain.gain.value).to.equal(0.5);
|
|
584
|
+
}, 1.5);
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
it("can disconnect a Signal from a Signal", () => {
|
|
588
|
+
return ConstantOutput((context) => {
|
|
589
|
+
const sig = new Signal({
|
|
590
|
+
value: 3,
|
|
591
|
+
context,
|
|
592
|
+
});
|
|
593
|
+
const output = new Signal({
|
|
594
|
+
value: 2,
|
|
595
|
+
context,
|
|
596
|
+
}).toDestination();
|
|
597
|
+
|
|
598
|
+
connectSignal(sig, output);
|
|
599
|
+
expect(output.overridden).to.be.true;
|
|
600
|
+
expect(output.value).to.equal(0);
|
|
601
|
+
|
|
602
|
+
disconnectSignal(sig, output);
|
|
603
|
+
expect(output.value).to.equal(2);
|
|
604
|
+
expect(output.overridden).to.be.false;
|
|
605
|
+
}, 2);
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
it("can disconnect from all the connected notes", async () => {
|
|
609
|
+
await ConstantOutput(async (context) => {
|
|
610
|
+
// initially destination is 2
|
|
611
|
+
const output0 = new Signal(1).toDestination();
|
|
612
|
+
const output1 = new Signal(1).toDestination();
|
|
613
|
+
|
|
614
|
+
// both should now equal 0
|
|
615
|
+
const sig = new Signal(0).connect(output0).connect(output1);
|
|
616
|
+
|
|
617
|
+
// disconnect from both
|
|
618
|
+
sig.disconnect();
|
|
619
|
+
}, 2);
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
it("can disconnect from a specific node", async () => {
|
|
623
|
+
await ConstantOutput(() => {
|
|
624
|
+
// initially destination is 1
|
|
625
|
+
const output = new Signal(1).toDestination();
|
|
626
|
+
|
|
627
|
+
// overwrites it with 0
|
|
628
|
+
const sig = new Signal(0).connect(output);
|
|
629
|
+
|
|
630
|
+
// disconnects the signal and goes back to 1
|
|
631
|
+
sig.disconnect(output);
|
|
632
|
+
}, 1);
|
|
633
|
+
});
|
|
634
|
+
|
|
635
|
+
it("disconnects every input when no input is passed in", async () => {
|
|
636
|
+
await ConstantOutput(() => {
|
|
637
|
+
// initially destination is 1
|
|
638
|
+
const output = new Signal(1).toDestination();
|
|
639
|
+
|
|
640
|
+
// overwrites it with 0
|
|
641
|
+
const sig = new Signal(0).connect(output, 0);
|
|
642
|
+
|
|
643
|
+
// disconnects the signal and goes back to 1
|
|
644
|
+
sig.disconnect(output);
|
|
645
|
+
}, 1);
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
it("disconnects every output when no output is passed in", async () => {
|
|
649
|
+
await ConstantOutput(() => {
|
|
650
|
+
// initially destination is 1
|
|
651
|
+
const output = new Signal(1).toDestination();
|
|
652
|
+
|
|
653
|
+
// overwrites it with 0
|
|
654
|
+
const sig = new Signal(0).connect(output, undefined, 0);
|
|
655
|
+
|
|
656
|
+
// disconnects the signal and goes back to 1
|
|
657
|
+
sig.disconnect(output);
|
|
658
|
+
}, 1);
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
it("disconnects everything if no destination is passed in", () => {
|
|
662
|
+
return ConstantOutput((context) => {
|
|
663
|
+
const sig = new Signal({
|
|
664
|
+
value: 3,
|
|
665
|
+
context,
|
|
666
|
+
});
|
|
667
|
+
const output = new Signal({
|
|
668
|
+
value: 2,
|
|
669
|
+
context,
|
|
670
|
+
}).toDestination();
|
|
671
|
+
|
|
672
|
+
// overridden with value of 3
|
|
673
|
+
connectSignal(sig, output);
|
|
674
|
+
expect(output.overridden).to.be.true;
|
|
675
|
+
|
|
676
|
+
// disconnect goes back to 2
|
|
677
|
+
sig.disconnect();
|
|
678
|
+
expect(output.overridden).to.be.false;
|
|
679
|
+
}, 2);
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
it("can connect multiple times with no affect", () => {
|
|
683
|
+
return ConstantOutput((context) => {
|
|
684
|
+
const sig = new Signal({
|
|
685
|
+
value: 3,
|
|
686
|
+
context,
|
|
687
|
+
});
|
|
688
|
+
const output = new Signal({
|
|
689
|
+
value: 2,
|
|
690
|
+
context,
|
|
691
|
+
}).toDestination();
|
|
692
|
+
|
|
693
|
+
connectSignal(sig, output);
|
|
694
|
+
expect(output.overridden).to.be.true;
|
|
695
|
+
|
|
696
|
+
// no affect when called again
|
|
697
|
+
connectSignal(sig, output);
|
|
698
|
+
}, 3);
|
|
699
|
+
});
|
|
700
|
+
|
|
701
|
+
it("disconnecting multiple times throws an error", () => {
|
|
702
|
+
return ConstantOutput((context) => {
|
|
703
|
+
const sig = new Signal({
|
|
704
|
+
value: 3,
|
|
705
|
+
context,
|
|
706
|
+
});
|
|
707
|
+
const output = new Signal({
|
|
708
|
+
value: 2,
|
|
709
|
+
context,
|
|
710
|
+
}).toDestination();
|
|
711
|
+
|
|
712
|
+
connectSignal(sig, output);
|
|
713
|
+
|
|
714
|
+
disconnectSignal(sig, output);
|
|
715
|
+
expect(() => disconnectSignal(sig, output)).to.throw(Error);
|
|
716
|
+
}, 2);
|
|
717
|
+
});
|
|
718
|
+
});
|
|
513
719
|
});
|