tone 15.3.4 → 15.3.6

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.
Files changed (32) hide show
  1. package/Tone/component/envelope/Envelope.test.ts +2 -0
  2. package/Tone/component/envelope/Envelope.ts +15 -1
  3. package/Tone/core/clock/Transport.test.ts +30 -0
  4. package/Tone/core/clock/Transport.ts +24 -19
  5. package/Tone/core/context/ToneAudioNode.ts +1 -1
  6. package/Tone/signal/Signal.test.ts +12 -8
  7. package/Tone/signal/Signal.ts +28 -11
  8. package/Tone/signal/SignalOperator.test.ts +23 -0
  9. package/Tone/signal/SignalOperator.ts +8 -1
  10. package/Tone/source/oscillator/LFO.test.ts +2 -0
  11. package/Tone/source/oscillator/LFO.ts +13 -1
  12. package/Tone/version.ts +1 -1
  13. package/build/Tone.js +1 -1
  14. package/build/Tone.js.map +1 -1
  15. package/build/esm/component/envelope/Envelope.d.ts +2 -0
  16. package/build/esm/component/envelope/Envelope.js +6 -1
  17. package/build/esm/component/envelope/Envelope.js.map +1 -1
  18. package/build/esm/core/clock/Transport.js +20 -17
  19. package/build/esm/core/clock/Transport.js.map +1 -1
  20. package/build/esm/core/context/ToneAudioNode.js +1 -1
  21. package/build/esm/core/context/ToneAudioNode.js.map +1 -1
  22. package/build/esm/signal/Signal.d.ts +23 -0
  23. package/build/esm/signal/Signal.js +26 -2
  24. package/build/esm/signal/Signal.js.map +1 -1
  25. package/build/esm/signal/SignalOperator.d.ts +3 -0
  26. package/build/esm/signal/SignalOperator.js +7 -1
  27. package/build/esm/signal/SignalOperator.js.map +1 -1
  28. package/build/esm/source/oscillator/LFO.d.ts +4 -0
  29. package/build/esm/source/oscillator/LFO.js +8 -1
  30. package/build/esm/source/oscillator/LFO.js.map +1 -1
  31. package/build/esm/version.js +1 -1
  32. package/package.json +1 -1
@@ -3,10 +3,12 @@ import { expect } from "chai";
3
3
  import { BasicTests } from "../../../test/helper/Basic.js";
4
4
  import { connectTo } from "../../../test/helper/Connect.js";
5
5
  import { Offline } from "../../../test/helper/Offline.js";
6
+ import { SignalConnectAndDisconnect } from "../../../test/helper/SignalTests.js";
6
7
  import { Envelope, EnvelopeCurve } from "./Envelope.js";
7
8
 
8
9
  describe("Envelope", () => {
9
10
  BasicTests(Envelope);
11
+ SignalConnectAndDisconnect(Envelope);
10
12
 
11
13
  context("Envelope", () => {
12
14
  it("has an output connections", () => {
@@ -9,7 +9,11 @@ import { assert } from "../../core/util/Debug.js";
9
9
  import { range, timeRange } from "../../core/util/Decorator.js";
10
10
  import { optionsFromArguments } from "../../core/util/Defaults.js";
11
11
  import { isArray, isObject, isString } from "../../core/util/TypeCheck.js";
12
- import { connectSignal, Signal } from "../../signal/Signal.js";
12
+ import {
13
+ connectSignal,
14
+ disconnectSignal,
15
+ Signal,
16
+ } from "../../signal/Signal.js";
13
17
 
14
18
  type BasicEnvelopeCurve = "linear" | "exponential";
15
19
  type InternalEnvelopeCurve = BasicEnvelopeCurve | number[];
@@ -505,6 +509,16 @@ export class Envelope extends ToneAudioNode<EnvelopeOptions> {
505
509
  return this;
506
510
  }
507
511
 
512
+ /** @inheritdoc */
513
+ disconnect(
514
+ destination?: InputNode,
515
+ outputNumber = 0,
516
+ inputNumber = 0
517
+ ): this {
518
+ disconnectSignal(this, destination, outputNumber, inputNumber);
519
+ return this;
520
+ }
521
+
508
522
  /**
509
523
  * Render the envelope curve to an array of the given length.
510
524
  * Good for visualizing the envelope curve. Rescales the duration of the
@@ -302,6 +302,36 @@ describe("Transport", () => {
302
302
  });
303
303
  }, 0.2);
304
304
  });
305
+
306
+ it("invokes the first callback time when the scheduled time is a non-integer tick time", async () => {
307
+ let wasCalled = false;
308
+ await Offline(({ transport }) => {
309
+ // choose a value which is not cleanly representable as ticks
310
+ const problemValue = Time(100, "i").toSeconds() + 0.01;
311
+ transport.seconds = problemValue;
312
+ transport.schedule(() => {
313
+ wasCalled = true;
314
+ }, problemValue);
315
+ transport.start();
316
+ }, 0.2);
317
+ expect(wasCalled).to.be.true;
318
+ });
319
+
320
+ it("setting the same ticks value twice does not emit twice", async () => {
321
+ await Offline(({ transport }) => {
322
+ let callCount = 0;
323
+ transport.on("ticks", () => {
324
+ callCount++;
325
+ });
326
+ transport.ticks = 100;
327
+ expect(transport.ticks).to.equal(100);
328
+ expect(callCount).to.equal(1);
329
+
330
+ // set it to the same value again has no change
331
+ transport.ticks = 100;
332
+ expect(callCount).to.equal(1);
333
+ }, 0.1);
334
+ });
305
335
  });
306
336
 
307
337
  context("state", () => {
@@ -625,25 +625,30 @@ export class TransportInstance
625
625
  }
626
626
  set ticks(t: Ticks) {
627
627
  assertUsedScheduleTime();
628
- if (this._clock.ticks !== t) {
629
- const now = this.now();
630
- // stop everything synced to the transport
631
- if (this.state === "started") {
632
- const ticks = this._clock.getTicksAtTime(now);
633
- // schedule to start on the next tick, #573
634
- const remainingTick = this._clock.frequency.getDurationOfTicks(
635
- Math.ceil(ticks) - ticks,
636
- now
637
- );
638
- const time = now + remainingTick;
639
- this.emit("stop", time);
640
- this._clock.setTicksAtTime(t, time);
641
- // restart it with the new time
642
- this.emit("start", time, this._clock.getSecondsAtTime(time));
643
- } else {
644
- this.emit("ticks", now);
645
- this._clock.setTicksAtTime(t, now);
646
- }
628
+
629
+ // "floor" ensures that any events scheduled on this tick will be called.
630
+ t = Math.floor(t);
631
+
632
+ if (this._clock.ticks === t) {
633
+ return;
634
+ }
635
+ const now = this.now();
636
+ // stop everything synced to the transport
637
+ if (this.state === "started") {
638
+ const ticks = this._clock.getTicksAtTime(now);
639
+ // schedule to start on the next tick, #573
640
+ const remainingTick = this._clock.frequency.getDurationOfTicks(
641
+ Math.ceil(ticks) - ticks,
642
+ now
643
+ );
644
+ const time = now + remainingTick;
645
+ this.emit("stop", time);
646
+ this._clock.setTicksAtTime(t, time);
647
+ // restart it with the new time
648
+ this.emit("start", time, this._clock.getSecondsAtTime(time));
649
+ } else {
650
+ this.emit("ticks", now);
651
+ this._clock.setTicksAtTime(t, now);
647
652
  }
648
653
  }
649
654
 
@@ -374,7 +374,7 @@ export function disconnect(
374
374
  ): void {
375
375
  // resolve the destination node
376
376
  if (isDefined(dstNode)) {
377
- while (dstNode instanceof ToneAudioNode) {
377
+ while (dstNode instanceof ToneAudioNode || dstNode instanceof Param) {
378
378
  dstNode = dstNode.input;
379
379
  }
380
380
  }
@@ -3,11 +3,13 @@ import { expect } from "chai";
3
3
  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
+ import { SignalConnectAndDisconnect } from "../../test/helper/SignalTests.js";
6
7
  import { Gain } from "../core/context/Gain.js";
7
8
  import { connectSignal, disconnectSignal, Signal } from "./Signal.js";
8
9
 
9
10
  describe("Signal", () => {
10
11
  BasicTests(Signal);
12
+ SignalConnectAndDisconnect(Signal);
11
13
 
12
14
  context("Signal Rate Value", () => {
13
15
  it("has 1 input and 1 output", () => {
@@ -605,7 +607,7 @@ describe("Signal", () => {
605
607
  }, 2);
606
608
  });
607
609
 
608
- it("can disconnect from all the connected notes", async () => {
610
+ it("can disconnect from all the connected nodes", async () => {
609
611
  await ConstantOutput(async (context) => {
610
612
  // initially destination is 2
611
613
  const output0 = new Signal(1).toDestination();
@@ -621,15 +623,17 @@ describe("Signal", () => {
621
623
 
622
624
  it("can disconnect from a specific node", async () => {
623
625
  await ConstantOutput(() => {
624
- // initially destination is 1
625
- const output = new Signal(1).toDestination();
626
+ // initially destination is 3
627
+ const output0 = new Signal(1).toDestination();
628
+ const output1 = new Signal(2).toDestination();
626
629
 
627
- // overwrites it with 0
628
- const sig = new Signal(0).connect(output);
630
+ const sig = new Signal(3);
631
+ sig.connect(output0);
632
+ sig.connect(output1);
629
633
 
630
- // disconnects the signal and goes back to 1
631
- sig.disconnect(output);
632
- }, 1);
634
+ // output0 goes back to 1 after disconnecting
635
+ sig.disconnect(output0);
636
+ }, 4); // 1 + 3
633
637
  });
634
638
 
635
639
  it("disconnects every input when no input is passed in", async () => {
@@ -85,7 +85,7 @@ export class Signal<TypeName extends UnitName = "number">
85
85
  this._constantSource.start(0);
86
86
  this.input = this._param = this._constantSource.offset;
87
87
  }
88
-
88
+ /** @inheritdoc */
89
89
  static getDefaults(): SignalOptions<any> {
90
90
  return Object.assign(ToneAudioNode.getDefaults(), {
91
91
  convert: true,
@@ -93,13 +93,13 @@ export class Signal<TypeName extends UnitName = "number">
93
93
  value: 0,
94
94
  });
95
95
  }
96
-
96
+ /** @inheritdoc */
97
97
  connect(destination: InputNode, outputNum = 0, inputNum = 0): this {
98
98
  // start it only when connected to something
99
99
  connectSignal(this, destination, outputNum, inputNum);
100
100
  return this;
101
101
  }
102
-
102
+ /** @inheritdoc */
103
103
  disconnect(
104
104
  destination?: InputNode,
105
105
  outputNum?: number,
@@ -109,7 +109,7 @@ export class Signal<TypeName extends UnitName = "number">
109
109
  disconnectSignal(this, destination, outputNum, inputNum);
110
110
  return this;
111
111
  }
112
-
112
+ /** @inheritdoc */
113
113
  dispose(): this {
114
114
  super.dispose();
115
115
  this._param.dispose();
@@ -123,25 +123,31 @@ export class Signal<TypeName extends UnitName = "number">
123
123
  // all docs are generated from AbstractParam.ts
124
124
  //-------------------------------------
125
125
 
126
+ /** @inheritdoc */
126
127
  setValueAtTime(value: UnitMap[TypeName], time: Time): this {
127
128
  this._param.setValueAtTime(value, time);
128
129
  return this;
129
130
  }
131
+ /** @inheritdoc */
130
132
  getValueAtTime(time: Time): UnitMap[TypeName] {
131
133
  return this._param.getValueAtTime(time);
132
134
  }
135
+ /** @inheritdoc */
133
136
  setRampPoint(time: Time): this {
134
137
  this._param.setRampPoint(time);
135
138
  return this;
136
139
  }
140
+ /** @inheritdoc */
137
141
  linearRampToValueAtTime(value: UnitMap[TypeName], time: Time): this {
138
142
  this._param.linearRampToValueAtTime(value, time);
139
143
  return this;
140
144
  }
145
+ /** @inheritdoc */
141
146
  exponentialRampToValueAtTime(value: UnitMap[TypeName], time: Time): this {
142
147
  this._param.exponentialRampToValueAtTime(value, time);
143
148
  return this;
144
149
  }
150
+ /** @inheritdoc */
145
151
  exponentialRampTo(
146
152
  value: UnitMap[TypeName],
147
153
  rampTime: Time,
@@ -150,6 +156,7 @@ export class Signal<TypeName extends UnitName = "number">
150
156
  this._param.exponentialRampTo(value, rampTime, startTime);
151
157
  return this;
152
158
  }
159
+ /** @inheritdoc */
153
160
  linearRampTo(
154
161
  value: UnitMap[TypeName],
155
162
  rampTime: Time,
@@ -158,6 +165,7 @@ export class Signal<TypeName extends UnitName = "number">
158
165
  this._param.linearRampTo(value, rampTime, startTime);
159
166
  return this;
160
167
  }
168
+ /** @inheritdoc */
161
169
  targetRampTo(
162
170
  value: UnitMap[TypeName],
163
171
  rampTime: Time,
@@ -166,6 +174,7 @@ export class Signal<TypeName extends UnitName = "number">
166
174
  this._param.targetRampTo(value, rampTime, startTime);
167
175
  return this;
168
176
  }
177
+ /** @inheritdoc */
169
178
  exponentialApproachValueAtTime(
170
179
  value: UnitMap[TypeName],
171
180
  time: Time,
@@ -174,6 +183,7 @@ export class Signal<TypeName extends UnitName = "number">
174
183
  this._param.exponentialApproachValueAtTime(value, time, rampTime);
175
184
  return this;
176
185
  }
186
+ /** @inheritdoc */
177
187
  setTargetAtTime(
178
188
  value: UnitMap[TypeName],
179
189
  startTime: Time,
@@ -182,6 +192,7 @@ export class Signal<TypeName extends UnitName = "number">
182
192
  this._param.setTargetAtTime(value, startTime, timeConstant);
183
193
  return this;
184
194
  }
195
+ /** @inheritdoc */
185
196
  setValueCurveAtTime(
186
197
  values: UnitMap[TypeName][],
187
198
  startTime: Time,
@@ -191,44 +202,47 @@ export class Signal<TypeName extends UnitName = "number">
191
202
  this._param.setValueCurveAtTime(values, startTime, duration, scaling);
192
203
  return this;
193
204
  }
205
+ /** @inheritdoc */
194
206
  cancelScheduledValues(time: Time): this {
195
207
  this._param.cancelScheduledValues(time);
196
208
  return this;
197
209
  }
210
+ /** @inheritdoc */
198
211
  cancelAndHoldAtTime(time: Time): this {
199
212
  this._param.cancelAndHoldAtTime(time);
200
213
  return this;
201
214
  }
215
+ /** @inheritdoc */
202
216
  rampTo(value: UnitMap[TypeName], rampTime: Time, startTime?: Time): this {
203
217
  this._param.rampTo(value, rampTime, startTime);
204
218
  return this;
205
219
  }
206
-
220
+ /** @inheritdoc */
207
221
  get value(): UnitMap[TypeName] {
208
222
  return this._param.value;
209
223
  }
210
224
  set value(value: UnitMap[TypeName]) {
211
225
  this._param.value = value;
212
226
  }
213
-
227
+ /** @inheritdoc */
214
228
  get convert(): boolean {
215
229
  return this._param.convert;
216
230
  }
217
231
  set convert(convert: boolean) {
218
232
  this._param.convert = convert;
219
233
  }
220
-
234
+ /** @inheritdoc */
221
235
  get units(): UnitName {
222
236
  return this._param.units;
223
237
  }
224
-
238
+ /** @inheritdoc */
225
239
  get overridden(): boolean {
226
240
  return this._param.overridden;
227
241
  }
228
242
  set overridden(overridden: boolean) {
229
243
  this._param.overridden = overridden;
230
244
  }
231
-
245
+ /** @inheritdoc */
232
246
  get maxValue(): number {
233
247
  return this._param.maxValue;
234
248
  }
@@ -288,7 +302,7 @@ export function connectSignal(
288
302
  // reset the value
289
303
  destination.setValueAtTime(0, 0);
290
304
  // mark the value as overridden
291
- if (destination instanceof Signal) {
305
+ if (destination instanceof Signal || destination instanceof Param) {
292
306
  destination.overridden = true;
293
307
  }
294
308
  // store the connection
@@ -344,7 +358,10 @@ export function disconnectSignal(
344
358
 
345
359
  // restore the value
346
360
  connections.forEach((connection) => {
347
- if (connection.destination instanceof Signal) {
361
+ if (
362
+ connection.destination instanceof Signal ||
363
+ connection.destination instanceof Param
364
+ ) {
348
365
  connection.destination.overridden = false;
349
366
  }
350
367
  connection.destination.setValueAtTime(
@@ -0,0 +1,23 @@
1
+ import { BasicTests } from "../../test/helper/Basic.js";
2
+ import { SignalConnectAndDisconnect } from "../../test/helper/SignalTests.js";
3
+ import { Signal } from "./Signal.js";
4
+ import { SignalOperator, SignalOperatorOptions } from "./SignalOperator.js";
5
+
6
+ describe("SignalOperator", () => {
7
+ class TestSignalOperator extends SignalOperator<SignalOperatorOptions> {
8
+ name = "TestSignalOperator";
9
+
10
+ input: Signal;
11
+ output: Signal;
12
+
13
+ constructor(options: SignalOperatorOptions) {
14
+ super(options);
15
+ this.input = this.output = new Signal({
16
+ context: this.context,
17
+ });
18
+ }
19
+ }
20
+
21
+ BasicTests(TestSignalOperator);
22
+ SignalConnectAndDisconnect(TestSignalOperator);
23
+ });
@@ -4,7 +4,7 @@ import {
4
4
  ToneAudioNodeOptions,
5
5
  } from "../core/context/ToneAudioNode.js";
6
6
  import { optionsFromArguments } from "../core/util/Defaults.js";
7
- import { connectSignal } from "./Signal.js";
7
+ import { connectSignal, disconnectSignal } from "./Signal.js";
8
8
 
9
9
  export type SignalOperatorOptions = ToneAudioNodeOptions;
10
10
 
@@ -23,8 +23,15 @@ export abstract class SignalOperator<
23
23
  );
24
24
  }
25
25
 
26
+ /** @inheritdoc */
26
27
  connect(destination: InputNode, outputNum = 0, inputNum = 0): this {
27
28
  connectSignal(this, destination, outputNum, inputNum);
28
29
  return this;
29
30
  }
31
+
32
+ /** @inheritdoc */
33
+ disconnect(destination: InputNode, outputNum = 0, inputNum = 0): this {
34
+ disconnectSignal(this, destination, outputNum, inputNum);
35
+ return this;
36
+ }
30
37
  }
@@ -3,11 +3,13 @@ import { expect } from "chai";
3
3
  import { BasicTests } from "../../../test/helper/Basic.js";
4
4
  import { Offline } from "../../../test/helper/Offline.js";
5
5
  import { OutputAudio } from "../../../test/helper/OutputAudio.js";
6
+ import { SignalConnectAndDisconnect } from "../../../test/helper/SignalTests.js";
6
7
  import { Signal } from "../../signal/Signal.js";
7
8
  import { LFO, LFOOptions } from "./LFO.js";
8
9
 
9
10
  describe("LFO", () => {
10
11
  BasicTests(LFO);
12
+ SignalConnectAndDisconnect(LFO);
11
13
 
12
14
  context("API", () => {
13
15
  it("can get the current state", () => {
@@ -17,7 +17,11 @@ import { readOnly } from "../../core/util/Interface.js";
17
17
  import { BasicPlaybackState } from "../../core/util/StateTimeline.js";
18
18
  import { AudioToGain } from "../../signal/AudioToGain.js";
19
19
  import { Scale } from "../../signal/Scale.js";
20
- import { connectSignal, Signal } from "../../signal/Signal.js";
20
+ import {
21
+ connectSignal,
22
+ disconnectSignal,
23
+ Signal,
24
+ } from "../../signal/Signal.js";
21
25
  import { Zero } from "../../signal/Zero.js";
22
26
  import { Oscillator, ToneOscillatorType } from "./Oscillator.js";
23
27
  import {
@@ -325,6 +329,14 @@ export class LFO extends ToneAudioNode<LFOOptions> {
325
329
  return this;
326
330
  }
327
331
 
332
+ /**
333
+ * Disconnect the LFO.
334
+ */
335
+ disconnect(destination?: InputNode, outputNum = 0, inputNum = 0): this {
336
+ disconnectSignal(this, destination, outputNum, inputNum);
337
+ return this;
338
+ }
339
+
328
340
  /**
329
341
  * Private methods borrowed from Param
330
342
  */
package/Tone/version.ts CHANGED
@@ -1 +1 @@
1
- export const version: string = "15.3.4";
1
+ export const version: string = "15.3.6";