tone 14.8.29 → 14.8.33
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/dynamics/Limiter.ts +1 -1
- package/Tone/component/envelope/Envelope.ts +2 -2
- package/Tone/component/filter/FeedbackCombFilter.ts +2 -2
- package/Tone/core/clock/TickSource.ts +1 -1
- package/Tone/core/clock/Transport.test.ts +15 -0
- package/Tone/core/clock/Transport.ts +93 -30
- package/Tone/core/context/ToneWithContext.ts +2 -0
- package/Tone/core/type/Frequency.ts +8 -8
- package/Tone/core/util/Debug.ts +37 -4
- package/Tone/core/util/StateTimeline.ts +1 -1
- package/Tone/effect/AutoFilter.ts +1 -1
- package/Tone/effect/Chebyshev.ts +1 -1
- package/Tone/effect/Chorus.test.ts +11 -8
- package/Tone/effect/Chorus.ts +1 -1
- package/Tone/effect/MidSideEffect.ts +2 -2
- package/Tone/effect/StereoEffect.ts +2 -2
- package/Tone/effect/Tremolo.ts +1 -1
- package/Tone/effect/Vibrato.ts +1 -1
- package/Tone/event/Pattern.ts +1 -1
- package/Tone/instrument/Instrument.ts +13 -0
- package/Tone/instrument/NoiseSynth.ts +56 -17
- package/Tone/instrument/PolySynth.test.ts +81 -18
- package/Tone/instrument/PolySynth.ts +11 -1
- package/Tone/instrument/Sampler.test.ts +0 -1
- package/Tone/instrument/Sampler.ts +1 -1
- package/Tone/instrument/Synth.test.ts +63 -0
- package/Tone/source/oscillator/PWMOscillator.ts +1 -1
- package/Tone/source/oscillator/PulseOscillator.ts +1 -1
- package/Tone/version.ts +1 -1
- package/build/Tone.js +1 -1
- package/build/Tone.js.map +1 -1
- package/build/esm/component/dynamics/Limiter.js +0 -1
- package/build/esm/component/dynamics/Limiter.js.map +1 -1
- package/build/esm/component/envelope/Envelope.js.map +1 -1
- package/build/esm/component/filter/FeedbackCombFilter.js +0 -2
- package/build/esm/component/filter/FeedbackCombFilter.js.map +1 -1
- package/build/esm/core/clock/TickSource.js.map +1 -1
- package/build/esm/core/clock/Transport.js +17 -11
- package/build/esm/core/clock/Transport.js.map +1 -1
- package/build/esm/core/context/ToneWithContext.js +2 -0
- package/build/esm/core/context/ToneWithContext.js.map +1 -1
- package/build/esm/core/type/Frequency.js +8 -8
- package/build/esm/core/type/Frequency.js.map +1 -1
- package/build/esm/core/util/Debug.d.ts +9 -1
- package/build/esm/core/util/Debug.js +22 -1
- package/build/esm/core/util/Debug.js.map +1 -1
- package/build/esm/core/util/StateTimeline.d.ts +1 -1
- package/build/esm/core/util/StateTimeline.js.map +1 -1
- package/build/esm/effect/AutoFilter.js.map +1 -1
- package/build/esm/effect/Chebyshev.js.map +1 -1
- package/build/esm/effect/Chorus.js.map +1 -1
- package/build/esm/effect/Tremolo.js.map +1 -1
- package/build/esm/effect/Vibrato.js.map +1 -1
- package/build/esm/event/Pattern.js.map +1 -1
- package/build/esm/instrument/Instrument.d.ts +4 -0
- package/build/esm/instrument/Instrument.js +10 -0
- package/build/esm/instrument/Instrument.js.map +1 -1
- package/build/esm/instrument/NoiseSynth.d.ts +10 -0
- package/build/esm/instrument/NoiseSynth.js +14 -2
- package/build/esm/instrument/NoiseSynth.js.map +1 -1
- package/build/esm/instrument/PolySynth.d.ts +4 -0
- package/build/esm/instrument/PolySynth.js +8 -0
- package/build/esm/instrument/PolySynth.js.map +1 -1
- package/build/esm/instrument/Sampler.js.map +1 -1
- package/build/esm/source/oscillator/PulseOscillator.js.map +1 -1
- package/build/esm/version.js +1 -1
- package/docs/tone.json +1 -1
- package/package.json +32 -30
|
@@ -4,7 +4,10 @@ import { omitFromObject, optionsFromArguments } from "../core/util/Defaults";
|
|
|
4
4
|
import { RecursivePartial } from "../core/util/Interface";
|
|
5
5
|
import { Noise, NoiseOptions } from "../source/Noise";
|
|
6
6
|
import { Instrument, InstrumentOptions } from "./Instrument";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
ToneAudioNode,
|
|
9
|
+
ToneAudioNodeOptions,
|
|
10
|
+
} from "../core/context/ToneAudioNode";
|
|
8
11
|
import { Envelope, EnvelopeOptions } from "../component/envelope/Envelope";
|
|
9
12
|
import { Source } from "../source/Source";
|
|
10
13
|
|
|
@@ -14,7 +17,7 @@ export interface NoiseSynthOptions extends InstrumentOptions {
|
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
/**
|
|
17
|
-
* Tone.NoiseSynth is composed of [[Noise]] through an [[AmplitudeEnvelope]].
|
|
20
|
+
* Tone.NoiseSynth is composed of [[Noise]] through an [[AmplitudeEnvelope]].
|
|
18
21
|
* ```
|
|
19
22
|
* +-------+ +-------------------+
|
|
20
23
|
* | Noise +>--> AmplitudeEnvelope +>--> Output
|
|
@@ -26,7 +29,6 @@ export interface NoiseSynthOptions extends InstrumentOptions {
|
|
|
26
29
|
* @category Instrument
|
|
27
30
|
*/
|
|
28
31
|
export class NoiseSynth extends Instrument<NoiseSynthOptions> {
|
|
29
|
-
|
|
30
32
|
readonly name = "NoiseSynth";
|
|
31
33
|
|
|
32
34
|
/**
|
|
@@ -39,17 +41,30 @@ export class NoiseSynth extends Instrument<NoiseSynthOptions> {
|
|
|
39
41
|
*/
|
|
40
42
|
readonly envelope: AmplitudeEnvelope;
|
|
41
43
|
|
|
42
|
-
constructor(options?: RecursivePartial<NoiseSynthOptions>)
|
|
44
|
+
constructor(options?: RecursivePartial<NoiseSynthOptions>);
|
|
43
45
|
constructor() {
|
|
44
46
|
super(optionsFromArguments(NoiseSynth.getDefaults(), arguments));
|
|
45
|
-
const options = optionsFromArguments(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
const options = optionsFromArguments(
|
|
48
|
+
NoiseSynth.getDefaults(),
|
|
49
|
+
arguments
|
|
50
|
+
);
|
|
51
|
+
this.noise = new Noise(
|
|
52
|
+
Object.assign(
|
|
53
|
+
{
|
|
54
|
+
context: this.context,
|
|
55
|
+
},
|
|
56
|
+
options.noise
|
|
57
|
+
)
|
|
58
|
+
);
|
|
49
59
|
|
|
50
|
-
this.envelope = new AmplitudeEnvelope(
|
|
51
|
-
|
|
52
|
-
|
|
60
|
+
this.envelope = new AmplitudeEnvelope(
|
|
61
|
+
Object.assign(
|
|
62
|
+
{
|
|
63
|
+
context: this.context,
|
|
64
|
+
},
|
|
65
|
+
options.envelope
|
|
66
|
+
)
|
|
67
|
+
);
|
|
53
68
|
|
|
54
69
|
// connect the noise to the output
|
|
55
70
|
this.noise.chain(this.envelope, this.output);
|
|
@@ -58,17 +73,23 @@ export class NoiseSynth extends Instrument<NoiseSynthOptions> {
|
|
|
58
73
|
static getDefaults(): NoiseSynthOptions {
|
|
59
74
|
return Object.assign(Instrument.getDefaults(), {
|
|
60
75
|
envelope: Object.assign(
|
|
61
|
-
omitFromObject(
|
|
76
|
+
omitFromObject(
|
|
77
|
+
Envelope.getDefaults(),
|
|
78
|
+
Object.keys(ToneAudioNode.getDefaults())
|
|
79
|
+
),
|
|
62
80
|
{
|
|
63
81
|
decay: 0.1,
|
|
64
82
|
sustain: 0.0,
|
|
65
|
-
}
|
|
83
|
+
}
|
|
66
84
|
),
|
|
67
85
|
noise: Object.assign(
|
|
68
|
-
omitFromObject(
|
|
86
|
+
omitFromObject(
|
|
87
|
+
Noise.getDefaults(),
|
|
88
|
+
Object.keys(Source.getDefaults())
|
|
89
|
+
),
|
|
69
90
|
{
|
|
70
91
|
type: "white",
|
|
71
|
-
}
|
|
92
|
+
}
|
|
72
93
|
),
|
|
73
94
|
});
|
|
74
95
|
}
|
|
@@ -87,7 +108,11 @@ export class NoiseSynth extends Instrument<NoiseSynthOptions> {
|
|
|
87
108
|
// start the noise
|
|
88
109
|
this.noise.start(time);
|
|
89
110
|
if (this.envelope.sustain === 0) {
|
|
90
|
-
this.noise.stop(
|
|
111
|
+
this.noise.stop(
|
|
112
|
+
time +
|
|
113
|
+
this.toSeconds(this.envelope.attack) +
|
|
114
|
+
this.toSeconds(this.envelope.decay)
|
|
115
|
+
);
|
|
91
116
|
}
|
|
92
117
|
return this;
|
|
93
118
|
}
|
|
@@ -110,7 +135,21 @@ export class NoiseSynth extends Instrument<NoiseSynthOptions> {
|
|
|
110
135
|
return this;
|
|
111
136
|
}
|
|
112
137
|
|
|
113
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Trigger the attack and then the release after the duration.
|
|
140
|
+
* @param duration The amount of time to hold the note for
|
|
141
|
+
* @param time The time the note should start
|
|
142
|
+
* @param velocity The volume of the note (0-1)
|
|
143
|
+
* @example
|
|
144
|
+
* const noiseSynth = new Tone.NoiseSynth().toDestination();
|
|
145
|
+
* // hold the note for 0.5 seconds
|
|
146
|
+
* noiseSynth.triggerAttackRelease(0.5);
|
|
147
|
+
*/
|
|
148
|
+
triggerAttackRelease(
|
|
149
|
+
duration: Time,
|
|
150
|
+
time?: Time,
|
|
151
|
+
velocity: NormalRange = 1
|
|
152
|
+
): this {
|
|
114
153
|
time = this.toSeconds(time);
|
|
115
154
|
duration = this.toSeconds(duration);
|
|
116
155
|
this.triggerAttack(time, velocity);
|
|
@@ -135,23 +135,6 @@ describe("PolySynth", () => {
|
|
|
135
135
|
});
|
|
136
136
|
});
|
|
137
137
|
|
|
138
|
-
it("can be synced to the transport", () => {
|
|
139
|
-
return Offline(({ transport }) => {
|
|
140
|
-
const polySynth = new PolySynth(Synth, {
|
|
141
|
-
envelope: {
|
|
142
|
-
release: 0.1,
|
|
143
|
-
},
|
|
144
|
-
}).sync();
|
|
145
|
-
polySynth.toDestination();
|
|
146
|
-
polySynth.triggerAttackRelease("C4", 0.1, 0.1);
|
|
147
|
-
polySynth.triggerAttackRelease("E4", 0.1, 0.3);
|
|
148
|
-
transport.start(0.1);
|
|
149
|
-
}, 0.8).then((buffer) => {
|
|
150
|
-
expect(buffer.getTimeOfFirstSound()).to.be.closeTo(0.2, 0.01);
|
|
151
|
-
expect(buffer.getTimeOfLastSound()).to.be.closeTo(0.6, 0.01);
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
|
|
155
138
|
it("disposes voices when they are no longer used", () => {
|
|
156
139
|
return Offline(() => {
|
|
157
140
|
const polySynth = new PolySynth(Synth, {
|
|
@@ -266,6 +249,86 @@ describe("PolySynth", () => {
|
|
|
266
249
|
|
|
267
250
|
});
|
|
268
251
|
|
|
252
|
+
context("Transport sync", () => {
|
|
253
|
+
it("can be synced to the transport", () => {
|
|
254
|
+
return Offline(({ transport }) => {
|
|
255
|
+
const polySynth = new PolySynth(Synth, {
|
|
256
|
+
envelope: {
|
|
257
|
+
release: 0.1,
|
|
258
|
+
},
|
|
259
|
+
}).sync();
|
|
260
|
+
polySynth.toDestination();
|
|
261
|
+
polySynth.triggerAttackRelease("C4", 0.1, 0.1);
|
|
262
|
+
polySynth.triggerAttackRelease("E4", 0.1, 0.3);
|
|
263
|
+
transport.start(0.1);
|
|
264
|
+
}, 0.8).then((buffer) => {
|
|
265
|
+
expect(buffer.getTimeOfFirstSound()).to.be.closeTo(0.2, 0.01);
|
|
266
|
+
expect(buffer.getTimeOfLastSound()).to.be.closeTo(0.6, 0.01);
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it("is silent until the transport is started", () => {
|
|
271
|
+
return Offline(({ transport }) => {
|
|
272
|
+
const synth = new PolySynth(Synth).sync().toDestination();
|
|
273
|
+
synth.triggerAttackRelease("C4", 0.5);
|
|
274
|
+
transport.start(0.5);
|
|
275
|
+
}, 1).then((buffer) => {
|
|
276
|
+
expect(buffer.getTimeOfFirstSound()).is.closeTo(0.5, 0.1);
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
it("stops when the transport is stopped", () => {
|
|
281
|
+
return Offline(({ transport }) => {
|
|
282
|
+
const synth = new PolySynth(Synth, {
|
|
283
|
+
envelope: {
|
|
284
|
+
release: 0
|
|
285
|
+
}
|
|
286
|
+
}).sync().toDestination();
|
|
287
|
+
synth.triggerAttackRelease("C4", 0.5);
|
|
288
|
+
transport.start(0.5).stop(1);
|
|
289
|
+
}, 1.5).then((buffer) => {
|
|
290
|
+
expect(buffer.getTimeOfLastSound()).is.closeTo(1, 0.1);
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
it("goes silent at the loop boundary", () => {
|
|
295
|
+
return Offline(({ transport }) => {
|
|
296
|
+
const synth = new PolySynth(Synth, {
|
|
297
|
+
envelope: {
|
|
298
|
+
release: 0
|
|
299
|
+
}
|
|
300
|
+
}).sync().toDestination();
|
|
301
|
+
synth.triggerAttackRelease("C4", 0.8, 0.5);
|
|
302
|
+
transport.loopEnd = 1;
|
|
303
|
+
transport.loop = true;
|
|
304
|
+
transport.start();
|
|
305
|
+
}, 2).then((buffer) => {
|
|
306
|
+
expect(buffer.getRmsAtTime(0)).to.be.closeTo(0, 0.05);
|
|
307
|
+
expect(buffer.getRmsAtTime(0.6)).to.be.closeTo(0.2, 0.05);
|
|
308
|
+
expect(buffer.getRmsAtTime(1.1)).to.be.closeTo(0, 0.05);
|
|
309
|
+
expect(buffer.getRmsAtTime(1.6)).to.be.closeTo(0.2, 0.05);
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it("can unsync", () => {
|
|
314
|
+
return Offline(({ transport }) => {
|
|
315
|
+
const synth = new PolySynth(Synth, {
|
|
316
|
+
envelope: {
|
|
317
|
+
sustain: 1,
|
|
318
|
+
release: 0
|
|
319
|
+
}
|
|
320
|
+
}).sync().toDestination().unsync();
|
|
321
|
+
synth.triggerAttackRelease("C4", 1, 0.5);
|
|
322
|
+
transport.start().stop(1);
|
|
323
|
+
}, 2).then((buffer) => {
|
|
324
|
+
expect(buffer.getRmsAtTime(0)).to.be.closeTo(0, 0.05);
|
|
325
|
+
expect(buffer.getRmsAtTime(0.6)).to.be.closeTo(0.6, 0.05);
|
|
326
|
+
expect(buffer.getRmsAtTime(1.4)).to.be.closeTo(0.6, 0.05);
|
|
327
|
+
expect(buffer.getRmsAtTime(1.6)).to.be.closeTo(0, 0.05);
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
|
|
269
332
|
context("API", () => {
|
|
270
333
|
|
|
271
334
|
it("can be constructed with an options object", () => {
|
|
@@ -282,7 +345,7 @@ describe("PolySynth", () => {
|
|
|
282
345
|
expect(() => {
|
|
283
346
|
// @ts-ignore
|
|
284
347
|
new PolySynth(PluckSynth);
|
|
285
|
-
}).throws(Error)
|
|
348
|
+
}).throws(Error);
|
|
286
349
|
});
|
|
287
350
|
|
|
288
351
|
it("can pass in the volume", () => {
|
|
@@ -341,10 +341,20 @@ export class PolySynth<Voice extends Monophonic<any> = Synth> extends Instrument
|
|
|
341
341
|
if (this._syncState()) {
|
|
342
342
|
this._syncMethod("triggerAttack", 1);
|
|
343
343
|
this._syncMethod("triggerRelease", 1);
|
|
344
|
+
|
|
345
|
+
// make sure that the sound doesn't play after its been stopped
|
|
346
|
+
this.context.transport.on("stop", this._syncedRelease);
|
|
347
|
+
this.context.transport.on("pause", this._syncedRelease);
|
|
348
|
+
this.context.transport.on("loopEnd", this._syncedRelease);
|
|
344
349
|
}
|
|
345
350
|
return this;
|
|
346
351
|
}
|
|
347
352
|
|
|
353
|
+
/**
|
|
354
|
+
* The release which is scheduled to the timeline.
|
|
355
|
+
*/
|
|
356
|
+
protected _syncedRelease = (time: number) => this.releaseAll(time);
|
|
357
|
+
|
|
348
358
|
/**
|
|
349
359
|
* Set a member/attribute of the voices
|
|
350
360
|
* @example
|
|
@@ -382,7 +392,7 @@ export class PolySynth<Voice extends Monophonic<any> = Synth> extends Instrument
|
|
|
382
392
|
});
|
|
383
393
|
return this;
|
|
384
394
|
}
|
|
385
|
-
|
|
395
|
+
|
|
386
396
|
dispose(): this {
|
|
387
397
|
super.dispose();
|
|
388
398
|
this._dummyVoice.dispose();
|
|
@@ -138,7 +138,7 @@ export class Sampler extends Instrument<SamplerOptions> {
|
|
|
138
138
|
return Object.assign(Instrument.getDefaults(), {
|
|
139
139
|
attack: 0,
|
|
140
140
|
baseUrl: "",
|
|
141
|
-
curve: "exponential" as
|
|
141
|
+
curve: "exponential" as const,
|
|
142
142
|
onload: noOp,
|
|
143
143
|
onerror: noOp,
|
|
144
144
|
release: 0.1,
|
|
@@ -106,6 +106,69 @@ describe("Synth", () => {
|
|
|
106
106
|
});
|
|
107
107
|
});
|
|
108
108
|
|
|
109
|
+
context("Transport sync", () => {
|
|
110
|
+
it("is silent until the transport is started", () => {
|
|
111
|
+
return Offline(({ transport }) => {
|
|
112
|
+
const synth = new Synth().sync().toDestination();
|
|
113
|
+
synth.triggerAttackRelease("C4", 0.5);
|
|
114
|
+
transport.start(0.5);
|
|
115
|
+
}, 1).then((buffer) => {
|
|
116
|
+
expect(buffer.getTimeOfFirstSound()).is.closeTo(0.5, 0.1);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("stops when the transport is stopped", () => {
|
|
121
|
+
return Offline(({ transport }) => {
|
|
122
|
+
const synth = new Synth({
|
|
123
|
+
envelope: {
|
|
124
|
+
release: 0
|
|
125
|
+
}
|
|
126
|
+
}).sync().toDestination();
|
|
127
|
+
synth.triggerAttackRelease("C4", 0.5);
|
|
128
|
+
transport.start(0.5).stop(1);
|
|
129
|
+
}, 1.5).then((buffer) => {
|
|
130
|
+
expect(buffer.getTimeOfLastSound()).is.closeTo(1, 0.1);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("goes silent at the loop boundary", () => {
|
|
135
|
+
return Offline(({ transport }) => {
|
|
136
|
+
const synth = new Synth({
|
|
137
|
+
envelope: {
|
|
138
|
+
release: 0
|
|
139
|
+
}
|
|
140
|
+
}).sync().toDestination();
|
|
141
|
+
synth.triggerAttackRelease("C4", 0.8, 0.5);
|
|
142
|
+
transport.loopEnd = 1;
|
|
143
|
+
transport.loop = true;
|
|
144
|
+
transport.start();
|
|
145
|
+
}, 2).then((buffer) => {
|
|
146
|
+
expect(buffer.getRmsAtTime(0)).to.be.closeTo(0, 0.05);
|
|
147
|
+
expect(buffer.getRmsAtTime(0.6)).to.be.closeTo(0.2, 0.05);
|
|
148
|
+
expect(buffer.getRmsAtTime(1.1)).to.be.closeTo(0, 0.05);
|
|
149
|
+
expect(buffer.getRmsAtTime(1.6)).to.be.closeTo(0.2, 0.05);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it("can unsync", () => {
|
|
154
|
+
return Offline(({ transport }) => {
|
|
155
|
+
const synth = new Synth({
|
|
156
|
+
envelope: {
|
|
157
|
+
sustain: 1,
|
|
158
|
+
release: 0
|
|
159
|
+
}
|
|
160
|
+
}).sync().toDestination().unsync();
|
|
161
|
+
synth.triggerAttackRelease("C4", 1, 0.5);
|
|
162
|
+
transport.start().stop(1);
|
|
163
|
+
}, 2).then((buffer) => {
|
|
164
|
+
expect(buffer.getRmsAtTime(0)).to.be.closeTo(0, 0.05);
|
|
165
|
+
expect(buffer.getRmsAtTime(0.6)).to.be.closeTo(0.6, 0.05);
|
|
166
|
+
expect(buffer.getRmsAtTime(1.4)).to.be.closeTo(0.6, 0.05);
|
|
167
|
+
expect(buffer.getRmsAtTime(1.6)).to.be.closeTo(0, 0.05);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
109
172
|
context("Portamento", () => {
|
|
110
173
|
it("can play notes with a portamento", () => {
|
|
111
174
|
return Offline(() => {
|
package/Tone/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version: string = "14.8.
|
|
1
|
+
export const version: string = "14.8.33";
|