tone 14.8.35 → 14.8.38

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 (51) hide show
  1. package/Tone/component/analysis/Meter.test.ts +25 -0
  2. package/Tone/component/analysis/Meter.ts +7 -5
  3. package/Tone/core/clock/TickSource.test.ts +52 -0
  4. package/Tone/core/clock/TickSource.ts +70 -9
  5. package/Tone/core/clock/Ticker.ts +11 -5
  6. package/Tone/core/context/Context.test.ts +2 -0
  7. package/Tone/core/context/Context.ts +29 -38
  8. package/Tone/core/context/ToneAudioBuffer.ts +52 -27
  9. package/Tone/event/Pattern.test.ts +31 -5
  10. package/Tone/event/Pattern.ts +19 -6
  11. package/Tone/event/PatternGenerator.test.ts +18 -26
  12. package/Tone/event/PatternGenerator.ts +52 -59
  13. package/Tone/instrument/MetalSynth.ts +48 -21
  14. package/Tone/signal/ToneConstantSource.test.ts +1 -1
  15. package/Tone/source/OneShotSource.ts +1 -1
  16. package/Tone/source/buffer/Player.test.ts +25 -0
  17. package/Tone/source/buffer/Player.ts +1 -1
  18. package/Tone/source/oscillator/ToneOscillatorNode.test.ts +1 -1
  19. package/Tone/version.ts +1 -1
  20. package/build/Tone.js +1 -1
  21. package/build/Tone.js.map +1 -1
  22. package/build/esm/component/analysis/Meter.d.ts +1 -1
  23. package/build/esm/component/analysis/Meter.js +5 -7
  24. package/build/esm/component/analysis/Meter.js.map +1 -1
  25. package/build/esm/core/clock/TickSource.d.ts +8 -0
  26. package/build/esm/core/clock/TickSource.js +49 -7
  27. package/build/esm/core/clock/TickSource.js.map +1 -1
  28. package/build/esm/core/clock/Ticker.d.ts +5 -1
  29. package/build/esm/core/clock/Ticker.js +6 -4
  30. package/build/esm/core/clock/Ticker.js.map +1 -1
  31. package/build/esm/core/context/Context.d.ts +12 -12
  32. package/build/esm/core/context/Context.js +26 -29
  33. package/build/esm/core/context/Context.js.map +1 -1
  34. package/build/esm/core/context/ToneAudioBuffer.js +25 -15
  35. package/build/esm/core/context/ToneAudioBuffer.js.map +1 -1
  36. package/build/esm/event/Pattern.d.ts +8 -0
  37. package/build/esm/event/Pattern.js +11 -4
  38. package/build/esm/event/Pattern.js.map +1 -1
  39. package/build/esm/event/PatternGenerator.d.ts +4 -4
  40. package/build/esm/event/PatternGenerator.js +52 -58
  41. package/build/esm/event/PatternGenerator.js.map +1 -1
  42. package/build/esm/instrument/MetalSynth.d.ts +0 -1
  43. package/build/esm/instrument/MetalSynth.js +15 -13
  44. package/build/esm/instrument/MetalSynth.js.map +1 -1
  45. package/build/esm/source/OneShotSource.js +1 -1
  46. package/build/esm/source/OneShotSource.js.map +1 -1
  47. package/build/esm/source/buffer/Player.js +2 -1
  48. package/build/esm/source/buffer/Player.js.map +1 -1
  49. package/build/esm/version.js +1 -1
  50. package/docs/tone.json +1 -1
  51. package/package.json +2 -2
@@ -1,9 +1,22 @@
1
1
  import { Envelope, EnvelopeOptions } from "../component/envelope/Envelope";
2
2
  import { Filter } from "../component/filter/Filter";
3
3
  import { Gain } from "../core/context/Gain";
4
- import { ToneAudioNode, ToneAudioNodeOptions } from "../core/context/ToneAudioNode";
5
- import { Frequency, NormalRange, Positive, Seconds, Time } from "../core/type/Units";
6
- import { deepMerge, omitFromObject, optionsFromArguments } from "../core/util/Defaults";
4
+ import {
5
+ ToneAudioNode,
6
+ ToneAudioNodeOptions,
7
+ } from "../core/context/ToneAudioNode";
8
+ import {
9
+ Frequency,
10
+ NormalRange,
11
+ Positive,
12
+ Seconds,
13
+ Time,
14
+ } from "../core/type/Units";
15
+ import {
16
+ deepMerge,
17
+ omitFromObject,
18
+ optionsFromArguments,
19
+ } from "../core/util/Defaults";
7
20
  import { noOp, RecursivePartial } from "../core/util/Interface";
8
21
  import { Multiply } from "../signal/Multiply";
9
22
  import { Scale } from "../signal/Scale";
@@ -23,17 +36,15 @@ export interface MetalSynthOptions extends MonophonicOptions {
23
36
  * Inharmonic ratio of frequencies based on the Roland TR-808
24
37
  * Taken from https://ccrma.stanford.edu/papers/tr-808-cymbal-physically-informed-circuit-bendable-digital-model
25
38
  */
26
- const inharmRatios: number[] = [1.0, 1.483, 1.932, 2.546, 2.630, 3.897];
39
+ const inharmRatios: number[] = [1.0, 1.483, 1.932, 2.546, 2.63, 3.897];
27
40
 
28
41
  /**
29
42
  * A highly inharmonic and spectrally complex source with a highpass filter
30
43
  * and amplitude envelope which is good for making metallophone sounds.
31
44
  * Based on CymbalSynth by [@polyrhythmatic](https://github.com/polyrhythmatic).
32
- * Inspiration from [Sound on Sound](https://shorturl.at/rSZ12).
33
45
  * @category Instrument
34
46
  */
35
47
  export class MetalSynth extends Monophonic<MetalSynthOptions> {
36
-
37
48
  readonly name: string = "MetalSynth";
38
49
 
39
50
  /**
@@ -84,10 +95,13 @@ export class MetalSynth extends Monophonic<MetalSynthOptions> {
84
95
  */
85
96
  readonly envelope: Envelope;
86
97
 
87
- constructor(options?: RecursivePartial<MetalSynthOptions>)
98
+ constructor(options?: RecursivePartial<MetalSynthOptions>);
88
99
  constructor() {
89
100
  super(optionsFromArguments(MetalSynth.getDefaults(), arguments));
90
- const options = optionsFromArguments(MetalSynth.getDefaults(), arguments);
101
+ const options = optionsFromArguments(
102
+ MetalSynth.getDefaults(),
103
+ arguments
104
+ );
91
105
 
92
106
  this.detune = new Signal({
93
107
  context: this.context,
@@ -158,12 +172,15 @@ export class MetalSynth extends Monophonic<MetalSynthOptions> {
158
172
  static getDefaults(): MetalSynthOptions {
159
173
  return deepMerge(Monophonic.getDefaults(), {
160
174
  envelope: Object.assign(
161
- omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())),
175
+ omitFromObject(
176
+ Envelope.getDefaults(),
177
+ Object.keys(ToneAudioNode.getDefaults())
178
+ ),
162
179
  {
163
180
  attack: 0.001,
164
181
  decay: 1.4,
165
182
  release: 0.2,
166
- },
183
+ }
167
184
  ),
168
185
  harmonicity: 5.1,
169
186
  modulationIndex: 32,
@@ -177,24 +194,33 @@ export class MetalSynth extends Monophonic<MetalSynthOptions> {
177
194
  * @param time When the attack should be triggered.
178
195
  * @param velocity The velocity that the envelope should be triggered at.
179
196
  */
180
- protected _triggerEnvelopeAttack(time: Seconds, velocity: NormalRange = 1): this {
197
+ protected _triggerEnvelopeAttack(
198
+ time: Seconds,
199
+ velocity: NormalRange = 1
200
+ ): this {
181
201
  this.envelope.triggerAttack(time, velocity);
182
- this._oscillators.forEach(osc => osc.start(time));
202
+ this._oscillators.forEach((osc) => osc.start(time));
183
203
  if (this.envelope.sustain === 0) {
184
- this._oscillators.forEach(osc => {
185
- osc.stop(time + this.toSeconds(this.envelope.attack) + this.toSeconds(this.envelope.decay));
204
+ this._oscillators.forEach((osc) => {
205
+ osc.stop(
206
+ time +
207
+ this.toSeconds(this.envelope.attack) +
208
+ this.toSeconds(this.envelope.decay)
209
+ );
186
210
  });
187
211
  }
188
212
  return this;
189
213
  }
190
-
214
+
191
215
  /**
192
216
  * Trigger the release of the envelope.
193
217
  * @param time When the release should be triggered.
194
218
  */
195
219
  protected _triggerEnvelopeRelease(time: Seconds): this {
196
220
  this.envelope.triggerRelease(time);
197
- this._oscillators.forEach(osc => osc.stop(time + this.toSeconds(this.envelope.release)));
221
+ this._oscillators.forEach((osc) =>
222
+ osc.stop(time + this.toSeconds(this.envelope.release))
223
+ );
198
224
  return this;
199
225
  }
200
226
 
@@ -213,7 +239,7 @@ export class MetalSynth extends Monophonic<MetalSynthOptions> {
213
239
  return this._oscillators[0].modulationIndex.value;
214
240
  }
215
241
  set modulationIndex(val) {
216
- this._oscillators.forEach(osc => (osc.modulationIndex.value = val));
242
+ this._oscillators.forEach((osc) => (osc.modulationIndex.value = val));
217
243
  }
218
244
 
219
245
  /**
@@ -226,7 +252,7 @@ export class MetalSynth extends Monophonic<MetalSynthOptions> {
226
252
  return this._oscillators[0].harmonicity.value;
227
253
  }
228
254
  set harmonicity(val) {
229
- this._oscillators.forEach(osc => (osc.harmonicity.value = val));
255
+ this._oscillators.forEach((osc) => (osc.harmonicity.value = val));
230
256
  }
231
257
 
232
258
  /**
@@ -254,13 +280,14 @@ export class MetalSynth extends Monophonic<MetalSynthOptions> {
254
280
  }
255
281
  set octaves(val) {
256
282
  this._octaves = val;
257
- this._filterFreqScaler.max = this._filterFreqScaler.min * Math.pow(2, val);
283
+ this._filterFreqScaler.max =
284
+ this._filterFreqScaler.min * Math.pow(2, val);
258
285
  }
259
286
 
260
287
  dispose(): this {
261
288
  super.dispose();
262
- this._oscillators.forEach(osc => osc.dispose());
263
- this._freqMultipliers.forEach(freqMult => freqMult.dispose());
289
+ this._oscillators.forEach((osc) => osc.dispose());
290
+ this._freqMultipliers.forEach((freqMult) => freqMult.dispose());
264
291
  this.frequency.dispose();
265
292
  this.detune.dispose();
266
293
  this._filterFreqScaler.dispose();
@@ -152,7 +152,7 @@ describe("ToneConstantSource", () => {
152
152
  expect(source.getStateAtTime(0)).to.equal("stopped");
153
153
  expect(source.getStateAtTime(currentTime)).to.equal("started");
154
154
  setTimeout(() => {
155
- currentTime = source.context.currentTime;
155
+ currentTime = source.now();
156
156
  source.stop(0);
157
157
  expect(source.getStateAtTime(currentTime + 0.01)).to.equal("stopped");
158
158
  source.dispose();
@@ -168,7 +168,7 @@ export abstract class OneShotSource<
168
168
 
169
169
  // schedule the stop callback
170
170
  this._stopTime = this.toSeconds(time) + fadeOutTime;
171
- this._stopTime = Math.max(this._stopTime, this.context.currentTime);
171
+ this._stopTime = Math.max(this._stopTime, this.now());
172
172
  if (fadeOutTime > 0) {
173
173
  // start the fade out curve at the given time
174
174
  if (this._curve === "linear") {
@@ -696,5 +696,30 @@ describe("Player", () => {
696
696
  expect(buff.getRmsAtTime(duration + 0.1)).to.be.closeTo(0, 0.1);
697
697
  });
698
698
  });
699
+
700
+ it("stops only last activeSource when restarting at intervals < latencyHint", (done) => {
701
+ const originalLookAhead = getContext().lookAhead;
702
+ getContext().lookAhead = .3;
703
+ const player = new Player({
704
+ onload(): void {
705
+ player.start(undefined, undefined, 1);
706
+ setTimeout(() => player.restart(undefined, undefined, 1), 50);
707
+ setTimeout(() => player.restart(undefined, undefined, 1), 100);
708
+ setTimeout(() => player.restart(undefined, undefined, 1), 150);
709
+ setTimeout(() => {
710
+ player.restart(undefined, undefined, 1);
711
+ const checkStopTimes = new Set();
712
+ player["_activeSources"].forEach(source => {
713
+ checkStopTimes.add(source["_stopTime"]);
714
+ });
715
+ getContext().lookAhead = originalLookAhead;
716
+ // ensure each source has a different stopTime
717
+ expect(checkStopTimes.size).to.equal(player["_activeSources"].size);
718
+ done();
719
+ }, 250);
720
+ },
721
+ url: "./audio/sine.wav",
722
+ });
723
+ });
699
724
  });
700
725
  });
@@ -284,7 +284,7 @@ export class Player extends Source<PlayerOptions> {
284
284
  }
285
285
 
286
286
  protected _restart(time?: Seconds, offset?: Time, duration?: Time): void {
287
- this._stop(time);
287
+ [...this._activeSources].pop()?.stop(time); // explicitly stop only the most recently created source, to avoid edge case when > 1 source exists and _stop() erroneously sets all stop times past original end offset
288
288
  this._start(time, offset, duration);
289
289
  }
290
290
 
@@ -191,7 +191,7 @@ describe("ToneOscillatorNode", () => {
191
191
  expect(osc.getStateAtTime(0)).to.equal("stopped");
192
192
  expect(osc.getStateAtTime(currentTime)).to.equal("started");
193
193
  setTimeout(() => {
194
- currentTime = osc.context.currentTime;
194
+ currentTime = osc.now();
195
195
  osc.stop(0);
196
196
  expect(osc.getStateAtTime(currentTime + 0.01)).to.equal("stopped");
197
197
  osc.dispose();
package/Tone/version.ts CHANGED
@@ -1 +1 @@
1
- export const version: string = "14.8.35";
1
+ export const version: string = "14.8.38";