Deprecating singleton variables, use singleton getter instead (#1233)

* Deprecating singleton variables, use singleton getter instead

* updating references

* moving over to getters instead of global vars
This commit is contained in:
Yotam Mann 2024-04-28 13:05:26 -04:00 committed by GitHub
parent d0b874bfca
commit 3d42017f50
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 190 additions and 179 deletions

View file

@ -140,8 +140,10 @@ jobs:
- name: Increment version - name: Increment version
run: npm run increment run: npm run increment
- name: Publish @next - name: Publish @next
# dev branch gets published with @next tag
run: npm publish --tag next run: npm publish --tag next
if: ${{ github.ref == 'refs/heads/dev' }} if: ${{ github.ref == 'refs/heads/dev' }}
- name: Publish @latest - name: Publish @latest
# main branch gets published with @latest tag
run: npm publish run: npm publish
if: ${{ github.ref == 'refs/heads/main' }} if: ${{ github.ref == 'refs/heads/main' }}

View file

@ -8,7 +8,6 @@ Tone.js is a Web Audio framework for creating interactive music in the browser.
* [API](https://tonejs.github.io/docs/) * [API](https://tonejs.github.io/docs/)
* [Examples](https://tonejs.github.io/examples/) * [Examples](https://tonejs.github.io/examples/)
* [Demos](https://tonejs.github.io/demos)
# Installation # Installation
@ -29,7 +28,6 @@ Tone.js is also hosted at unpkg.com. It can be added directly within an HTML doc
```html ```html
<script src="http://unpkg.com/tone"></script> <script src="http://unpkg.com/tone"></script>
<script src="myScript.js"></script>
``` ```
# Hello Tone # Hello Tone
@ -44,7 +42,7 @@ synth.triggerAttackRelease("C4", "8n");
#### Tone.Synth #### Tone.Synth
[Tone.Synth](https://tonejs.github.io/docs/Synth) is a basic synthesizer with a single [oscillator](https://tonejs.github.io/docs/OmniOscillator) and an [ADSR envelope](https://tonejs.github.io/docs/Envelope). `Tone.Synth` is a basic synthesizer with a single oscillator and an ADSR envelope.
#### triggerAttack / triggerRelease #### triggerAttack / triggerRelease
@ -109,9 +107,9 @@ document.querySelector('button')?.addEventListener('click', async () => {
### Transport ### Transport
[Tone.Transport](https://tonejs.github.io/docs/Transport) is the main timekeeper. Unlike the AudioContext clock, it can be started, stopped, looped and adjusted on the fly. You can think of it like the arrangement view in a Digital Audio Workstation or channels in a Tracker. `Tone.getTransport()` returns the main timekeeper. Unlike the AudioContext clock, it can be started, stopped, looped and adjusted on the fly. You can think of it like the arrangement view in a Digital Audio Workstation.
Multiple events and parts can be arranged and synchronized along the Transport. [Tone.Loop](https://tonejs.github.io/docs/Loop) is a simple way to create a looped callback that can be scheduled to start and stop. Multiple events and parts can be arranged and synchronized along the Transport. `Tone.Loop` is a simple way to create a looped callback that can be scheduled to start and stop.
```javascript ```javascript
// create two monophonic synths // create two monophonic synths
@ -125,19 +123,19 @@ const loopA = new Tone.Loop(time => {
const loopB = new Tone.Loop(time => { const loopB = new Tone.Loop(time => {
synthB.triggerAttackRelease("C4", "8n", time); synthB.triggerAttackRelease("C4", "8n", time);
}, "4n").start("8n"); }, "4n").start("8n");
// all loops start until the Transport is started // all loops start when the Transport is started
Tone.Transport.start() Tone.getTransport().start()
``` ```
Since Javascript callbacks are **not precisely timed**, the sample-accurate time of the event is passed into the callback function. **Use this time value to schedule the events**. Since Javascript callbacks are **not precisely timed**, the sample-accurate time of the event is passed into the callback function. **Use this time value to schedule the events**.
# Instruments # Instruments
There are numerous synths to choose from including [Tone.FMSynth](https://tonejs.github.io/docs/FMSynth), [Tone.AMSynth](https://tonejs.github.io/docs/AMSynth) and [Tone.NoiseSynth](https://tonejs.github.io/docs/NoiseSynth). There are numerous synths to choose from including `Tone.FMSynth`, `Tone.AMSynth` and `Tone.NoiseSynth`.
All of these instruments are **monophonic** (single voice) which means that they can only play one note at a time. All of these instruments are **monophonic** (single voice) which means that they can only play one note at a time.
To create a **polyphonic** synthesizer, use [Tone.PolySynth](https://tonejs.github.io/docs/PolySynth), which accepts a monophonic synth as its first parameter and automatically handles the note allocation so you can pass in multiple notes. The API is similar to the monophonic synths, except `triggerRelease` must be given a note or array of notes. To create a **polyphonic** synthesizer, use `Tone.PolySynth`, which accepts a monophonic synth as its first parameter and automatically handles the note allocation so you can pass in multiple notes. The API is similar to the monophonic synths, except `triggerRelease` must be given a note or array of notes.
```javascript ```javascript
//pass in some initial values for the filter and filter envelope //pass in some initial values for the filter and filter envelope
@ -153,7 +151,7 @@ synth.triggerRelease(["D4", "F4", "A4", "C4", "E4"], now + 4);
# Samples # Samples
Sound generation is not limited to synthesized sounds. You can also load a sample and play that back in a number of ways. [Tone.Player](https://tonejs.github.io/docs/Player) is one way to load and play back an audio file. Sound generation is not limited to synthesized sounds. You can also load a sample and play that back in a number of ways. `Tone.Player` is one way to load and play back an audio file.
```javascript ```javascript
const player = new Tone.Player("https://tonejs.github.io/audio/berklee/gong_1.mp3").toDestination(); const player = new Tone.Player("https://tonejs.github.io/audio/berklee/gong_1.mp3").toDestination();
@ -166,7 +164,7 @@ Tone.loaded().then(() => {
## Sampler ## Sampler
Multiple samples can also be combined into an instrument. If you have audio files organized by note, [Tone.Sampler](https://tonejs.github.io/docs/Sampler) will pitch shift the samples to fill in gaps between notes. So for example, if you only have every 3rd note on a piano sampled, you could turn that into a full piano sample. Multiple samples can also be combined into an instrument. If you have audio files organized by note, `Tone.Sampler` will pitch shift the samples to fill in gaps between notes. So for example, if you only have every 3rd note on a piano sampled, you could turn that into a full piano sample.
Unlike the other synths, Tone.Sampler is polyphonic so doesn't need to be passed into Tone.PolySynth Unlike the other synths, Tone.Sampler is polyphonic so doesn't need to be passed into Tone.PolySynth
@ -188,7 +186,7 @@ Tone.loaded().then(() => {
# Effects # Effects
In the above examples, the sources were always connected directly to the [Destination](https://tonejs.github.io/docs/Destination), but the output of the synth could also be routed through one (or more) effects before going to the speakers. In the above examples, the sources were always connected directly to the `Destination`, but the output of the synth could also be routed through one (or more) effects before going to the speakers.
```javascript ```javascript
const player = new Tone.Player({ const player = new Tone.Player({
@ -204,15 +202,15 @@ player.connect(distortion);
The connection routing is very flexible. For example, you can connect multiple sources to the same effect and then route the effect through a network of other effects either serially or in parallel. The connection routing is very flexible. For example, you can connect multiple sources to the same effect and then route the effect through a network of other effects either serially or in parallel.
[Tone.Gain](https://tonejs.github.io/docs/Gain) is very useful in creating complex routing. `Tone.Gain` is very useful in creating complex routing.
# Signals # Signals
Like the underlying Web Audio API, Tone.js is built with audio-rate signal control over nearly everything. This is a powerful feature which allows for sample-accurate synchronization and scheduling of parameters. Like the underlying Web Audio API, Tone.js is built with audio-rate signal control over nearly everything. This is a powerful feature which allows for sample-accurate synchronization and scheduling of parameters.
[Signal](https://tonejs.github.io/docs/Signal) properties have a few built in methods for creating automation curves. `Signal` properties have a few built in methods for creating automation curves.
For example, the `frequency` parameter on [Oscillator](https://tonejs.github.io/docs/Signal) is a Signal so you can create a smooth ramp from one frequency to another. For example, the `frequency` parameter on `Oscillator` is a Signal so you can create a smooth ramp from one frequency to another.
```javascript ```javascript
const osc = new Tone.Oscillator().toDestination(); const osc = new Tone.Oscillator().toDestination();
@ -224,7 +222,7 @@ osc.frequency.rampTo("C5", 2)
# AudioContext # AudioContext
Tone.js creates an AudioContext when it loads and shims it for maximum browser compatibility using [standardized-audio-context](https://github.com/chrisguttandin/standardized-audio-context). The AudioContext can be accessed at `Tone.context`. Or set your own AudioContext using `Tone.setContext(audioContext)`. Tone.js creates an AudioContext when it loads and shims it for maximum browser compatibility using [standardized-audio-context](https://github.com/chrisguttandin/standardized-audio-context). The AudioContext can be accessed at `Tone.getContext`. Or set your own AudioContext using `Tone.setContext(audioContext)`.
# MIDI # MIDI
@ -238,7 +236,7 @@ Tone.js makes extensive use of the native Web Audio Nodes such as the GainNode a
# Testing # Testing
Tone.js runs an extensive test suite using [mocha](https://mochajs.org/) and [chai](http://chaijs.com/) with nearly 100% coverage. Each commit and pull request is run on [Travis-CI](https://app.travis-ci.com/github/Tonejs/Tone.js) across browsers and versions. Passing builds on the 'dev' branch are published on npm as `tone@next`. Tone.js runs an extensive test suite using [mocha](https://mochajs.org/) and [chai](http://chaijs.com/) with nearly 100% coverage. Passing builds on the 'dev' branch are published on npm as `tone@next`.
# Contributing # Contributing
@ -248,7 +246,6 @@ If you have questions (or answers) that are not necessarily bugs/issues, please
# References and Inspiration # References and Inspiration
* [Tuna.js](https://github.com/Dinahmoe/tuna)
* [Many of Chris Wilson's Repositories](https://github.com/cwilso) * [Many of Chris Wilson's Repositories](https://github.com/cwilso)
* [Many of Mohayonao's Repositories](https://github.com/mohayonao) * [Many of Mohayonao's Repositories](https://github.com/mohayonao)
* [The Spec](http://webaudio.github.io/web-audio-api/) * [The Spec](http://webaudio.github.io/web-audio-api/)

View file

@ -4,7 +4,7 @@ import { Time } from "Tone/core/type/Time";
import { noOp } from "Tone/core/util/Interface"; import { noOp } from "Tone/core/util/Interface";
import { Signal } from "../../signal/Signal"; import { Signal } from "../../signal/Signal";
import { TransportTime } from "../type/TransportTime"; import { TransportTime } from "../type/TransportTime";
import { Transport } from "./Transport"; import { TransportClass } from "./Transport";
// importing for side affects // importing for side affects
import "../context/Destination"; import "../context/Destination";
import { warns } from "test/helper/Basic"; import { warns } from "test/helper/Basic";
@ -16,7 +16,7 @@ describe("Transport", () => {
it("can get and set bpm", () => { it("can get and set bpm", () => {
return Offline((context) => { return Offline((context) => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.bpm.value = 125; transport.bpm.value = 125;
expect(transport.bpm.value).to.be.closeTo(125, 0.001); expect(transport.bpm.value).to.be.closeTo(125, 0.001);
transport.bpm.value = 120; transport.bpm.value = 120;
@ -26,7 +26,7 @@ describe("Transport", () => {
it("can get and set timeSignature as both an array or number", () => { it("can get and set timeSignature as both an array or number", () => {
return Offline((context) => { return Offline((context) => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.timeSignature = [6, 8]; transport.timeSignature = [6, 8];
expect(transport.timeSignature).to.equal(3); expect(transport.timeSignature).to.equal(3);
transport.timeSignature = 5; transport.timeSignature = 5;
@ -36,7 +36,7 @@ describe("Transport", () => {
it("can get and set timeSignature as both an array or number", () => { it("can get and set timeSignature as both an array or number", () => {
return Offline((context) => { return Offline((context) => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.timeSignature = [6, 8]; transport.timeSignature = [6, 8];
expect(transport.timeSignature).to.equal(3); expect(transport.timeSignature).to.equal(3);
transport.timeSignature = 5; transport.timeSignature = 5;
@ -50,7 +50,7 @@ describe("Transport", () => {
it("can get and set loop points", () => { it("can get and set loop points", () => {
return Offline((context) => { return Offline((context) => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.loopStart = 0.2; transport.loopStart = 0.2;
transport.loopEnd = 0.4; transport.loopEnd = 0.4;
expect(transport.loopStart).to.be.closeTo(0.2, 0.01); expect(transport.loopStart).to.be.closeTo(0.2, 0.01);
@ -64,7 +64,7 @@ describe("Transport", () => {
it("can loop events scheduled on the transport", () => { it("can loop events scheduled on the transport", () => {
let invocations = 0; let invocations = 0;
return Offline((context) => { return Offline((context) => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.schedule((time) => { transport.schedule((time) => {
invocations++; invocations++;
}, 0); }, 0);
@ -78,7 +78,7 @@ describe("Transport", () => {
it("jumps to the loopStart after the loopEnd point", () => { it("jumps to the loopStart after the loopEnd point", () => {
let looped = false; let looped = false;
return Offline((context) => { return Offline((context) => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.on("loop", () => { transport.on("loop", () => {
looped = true; looped = true;
}); });
@ -97,14 +97,14 @@ describe("Transport", () => {
it("returns 0 if the transports not started", () => { it("returns 0 if the transports not started", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
expect(transport.nextSubdivision()).to.equal(0); expect(transport.nextSubdivision()).to.equal(0);
}); });
}); });
it("can get the next subdivision of the transport", () => { it("can get the next subdivision of the transport", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.start(0); transport.start(0);
return time => { return time => {
whenBetween(time, 0.05, 0.07, () => { whenBetween(time, 0.05, 0.07, () => {
@ -126,7 +126,7 @@ describe("Transport", () => {
it("can get and set pulses per quarter", () => { it("can get and set pulses per quarter", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.PPQ = 96; transport.PPQ = 96;
expect(transport.PPQ).to.equal(96); expect(transport.PPQ).to.equal(96);
}); });
@ -134,7 +134,7 @@ describe("Transport", () => {
it("schedules a quarter note at the same time with a different PPQ", () => { it("schedules a quarter note at the same time with a different PPQ", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.PPQ = 1; transport.PPQ = 1;
const id = transport.schedule(time => { const id = transport.schedule(time => {
expect(time).to.be.closeTo(transport.toSeconds("4n"), 0.1); expect(time).to.be.closeTo(transport.toSeconds("4n"), 0.1);
@ -146,7 +146,7 @@ describe("Transport", () => {
it("invokes the right number of ticks with a different PPQ", () => { it("invokes the right number of ticks with a different PPQ", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.bpm.value = 120; transport.bpm.value = 120;
const ppq = 20; const ppq = 20;
transport.PPQ = ppq; transport.PPQ = ppq;
@ -166,7 +166,7 @@ describe("Transport", () => {
it("can jump to a specific tick number", () => { it("can jump to a specific tick number", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.ticks = 200; transport.ticks = 200;
expect(transport.ticks).to.equal(200); expect(transport.ticks).to.equal(200);
transport.start(0); transport.start(0);
@ -182,7 +182,7 @@ describe("Transport", () => {
it("can get the current position in BarsBeatsSixteenths", () => { it("can get the current position in BarsBeatsSixteenths", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
expect(transport.position).to.equal("0:0:0"); expect(transport.position).to.equal("0:0:0");
transport.start(0); transport.start(0);
return atTime(0.05, () => { return atTime(0.05, () => {
@ -193,7 +193,7 @@ describe("Transport", () => {
it("can get the current position in seconds", () => { it("can get the current position in seconds", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
expect(transport.seconds).to.equal(0); expect(transport.seconds).to.equal(0);
transport.start(0.05); transport.start(0.05);
return time => { return time => {
@ -206,7 +206,7 @@ describe("Transport", () => {
it("can get the current position in seconds during a bpm ramp", () => { it("can get the current position in seconds during a bpm ramp", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
expect(transport.seconds).to.equal(0); expect(transport.seconds).to.equal(0);
transport.start(0.05); transport.start(0.05);
transport.bpm.linearRampTo(60, 0.5, 0.5); transport.bpm.linearRampTo(60, 0.5, 0.5);
@ -220,7 +220,7 @@ describe("Transport", () => {
it("can set the current position in seconds", () => { it("can set the current position in seconds", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
expect(transport.seconds).to.equal(0); expect(transport.seconds).to.equal(0);
transport.seconds = 3; transport.seconds = 3;
expect(transport.seconds).to.be.closeTo(3, 0.01); expect(transport.seconds).to.be.closeTo(3, 0.01);
@ -229,7 +229,7 @@ describe("Transport", () => {
it("can set the current position in BarsBeatsSixteenths", () => { it("can set the current position in BarsBeatsSixteenths", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
expect(transport.position).to.equal("0:0:0"); expect(transport.position).to.equal("0:0:0");
transport.position = "3:0"; transport.position = "3:0";
expect(transport.position).to.equal("3:0:0"); expect(transport.position).to.equal("3:0:0");
@ -240,7 +240,7 @@ describe("Transport", () => {
it("can get the progress of the loop", () => { it("can get the progress of the loop", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.setLoopPoints(0, "1m").start(); transport.setLoopPoints(0, "1m").start();
transport.loop = true; transport.loop = true;
expect(transport.progress).to.be.equal(0); expect(transport.progress).to.be.equal(0);
@ -316,7 +316,7 @@ describe("Transport", () => {
it("resets ticks on stop but not on pause", () => { it("resets ticks on stop but not on pause", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.start(0).pause(0.1).stop(0.2); transport.start(0).pause(0.1).stop(0.2);
expect(transport.getTicksAtTime(0)).to.be.equal(Math.floor(transport.PPQ * 0)); expect(transport.getTicksAtTime(0)).to.be.equal(Math.floor(transport.PPQ * 0));
expect(transport.getTicksAtTime(0.05)).to.be.equal(Math.floor(transport.PPQ * 0.1)); expect(transport.getTicksAtTime(0.05)).to.be.equal(Math.floor(transport.PPQ * 0.1));
@ -329,7 +329,7 @@ describe("Transport", () => {
it("tracks ticks after start", () => { it("tracks ticks after start", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.bpm.value = 120; transport.bpm.value = 120;
const ppq = transport.PPQ; const ppq = transport.PPQ;
transport.start(); transport.start();
@ -344,7 +344,7 @@ describe("Transport", () => {
it("can start with a tick offset", () => { it("can start with a tick offset", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.start(0, "200i"); transport.start(0, "200i");
return time => { return time => {
@ -357,7 +357,7 @@ describe("Transport", () => {
it("can toggle the state of the transport", () => { it("can toggle the state of the transport", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.toggle(0); transport.toggle(0);
transport.toggle(0.2); transport.toggle(0.2);
@ -376,7 +376,7 @@ describe("Transport", () => {
it("tracks ticks correctly with a different PPQ and BPM", () => { it("tracks ticks correctly with a different PPQ and BPM", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.PPQ = 96; transport.PPQ = 96;
transport.bpm.value = 90; transport.bpm.value = 90;
transport.start(); transport.start();
@ -413,7 +413,7 @@ describe("Transport", () => {
it("can schedule an event on the timeline", () => { it("can schedule an event on the timeline", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const eventID = transport.schedule(() => { }, 0); const eventID = transport.schedule(() => { }, 0);
expect(eventID).to.be.a("number"); expect(eventID).to.be.a("number");
}); });
@ -422,7 +422,7 @@ describe("Transport", () => {
it("scheduled event gets invoked with the time of the event", () => { it("scheduled event gets invoked with the time of the event", () => {
let wasCalled = false; let wasCalled = false;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const startTime = 0.1; const startTime = 0.1;
transport.schedule(time => { transport.schedule(time => {
expect(time).to.be.closeTo(startTime, 0.01); expect(time).to.be.closeTo(startTime, 0.01);
@ -437,7 +437,7 @@ describe("Transport", () => {
it("can schedule events with TransportTime", () => { it("can schedule events with TransportTime", () => {
let wasCalled = false; let wasCalled = false;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const startTime = 0.1; const startTime = 0.1;
const eighth = transport.toSeconds("8n"); const eighth = transport.toSeconds("8n");
transport.schedule(time => { transport.schedule(time => {
@ -452,7 +452,7 @@ describe("Transport", () => {
it("can clear a scheduled event", () => { it("can clear a scheduled event", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const eventID = transport.schedule(() => { const eventID = transport.schedule(() => {
throw new Error("should not call this function"); throw new Error("should not call this function");
}, 0); }, 0);
@ -463,7 +463,7 @@ describe("Transport", () => {
it("can cancel the timeline of scheduled object", () => { it("can cancel the timeline of scheduled object", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.schedule(() => { transport.schedule(() => {
throw new Error("should not call this"); throw new Error("should not call this");
}, 0); }, 0);
@ -474,7 +474,7 @@ describe("Transport", () => {
it("can cancel the timeline of scheduleOnce object", () => { it("can cancel the timeline of scheduleOnce object", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.scheduleOnce(() => { transport.scheduleOnce(() => {
throw new Error("should not call this"); throw new Error("should not call this");
}, 0); }, 0);
@ -486,7 +486,7 @@ describe("Transport", () => {
it("scheduled event anywhere along the timeline", () => { it("scheduled event anywhere along the timeline", () => {
let wasCalled = false; let wasCalled = false;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const startTime = transport.now(); const startTime = transport.now();
transport.schedule(time => { transport.schedule(time => {
expect(time).to.be.closeTo(startTime + 0.5, 0.001); expect(time).to.be.closeTo(startTime + 0.5, 0.001);
@ -501,7 +501,7 @@ describe("Transport", () => {
it("can schedule multiple events and invoke them in the right order", () => { it("can schedule multiple events and invoke them in the right order", () => {
let wasCalled = false; let wasCalled = false;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
let first = false; let first = false;
transport.schedule(() => { transport.schedule(() => {
first = true; first = true;
@ -519,7 +519,7 @@ describe("Transport", () => {
it("invokes the event again if the timeline is restarted", () => { it("invokes the event again if the timeline is restarted", () => {
let iterations = 0; let iterations = 0;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.schedule(() => { transport.schedule(() => {
iterations++; iterations++;
}, 0.05); }, 0.05);
@ -532,7 +532,7 @@ describe("Transport", () => {
it("can add an event after the Transport is started", () => { it("can add an event after the Transport is started", () => {
let wasCalled = false; let wasCalled = false;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.start(0); transport.start(0);
let wasScheduled = false; let wasScheduled = false;
return time => { return time => {
@ -567,7 +567,7 @@ describe("Transport", () => {
it("can schedule a repeated event", () => { it("can schedule a repeated event", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const eventID = transport.scheduleRepeat(noOp, 1); const eventID = transport.scheduleRepeat(noOp, 1);
expect(eventID).to.be.a("number"); expect(eventID).to.be.a("number");
}); });
@ -576,7 +576,7 @@ describe("Transport", () => {
it("scheduled event gets invoked with the time of the event", () => { it("scheduled event gets invoked with the time of the event", () => {
let invoked = false; let invoked = false;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const startTime = 0.1; const startTime = 0.1;
const eventID = transport.scheduleRepeat(time => { const eventID = transport.scheduleRepeat(time => {
expect(time).to.be.closeTo(startTime, 0.01); expect(time).to.be.closeTo(startTime, 0.01);
@ -591,7 +591,7 @@ describe("Transport", () => {
it("can cancel the timeline of scheduleRepeat", () => { it("can cancel the timeline of scheduleRepeat", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.scheduleRepeat(() => { transport.scheduleRepeat(() => {
throw new Error("should not call this"); throw new Error("should not call this");
}, 0.01, 0); }, 0.01, 0);
@ -603,7 +603,7 @@ describe("Transport", () => {
it("can schedule events with TransportTime", () => { it("can schedule events with TransportTime", () => {
let invoked = false; let invoked = false;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const startTime = 0.1; const startTime = 0.1;
const eighth = transport.toSeconds("8n"); const eighth = transport.toSeconds("8n");
transport.scheduleRepeat(time => { transport.scheduleRepeat(time => {
@ -618,7 +618,7 @@ describe("Transport", () => {
it("can clear a scheduled event", () => { it("can clear a scheduled event", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const eventID = transport.scheduleRepeat(() => { const eventID = transport.scheduleRepeat(() => {
throw new Error("should not call this function"); throw new Error("should not call this function");
}, 1, 0); }, 1, 0);
@ -630,7 +630,7 @@ describe("Transport", () => {
it("can be scheduled in the future", () => { it("can be scheduled in the future", () => {
let invoked = false; let invoked = false;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const startTime = 0.1; const startTime = 0.1;
const eventID = transport.scheduleRepeat(time => { const eventID = transport.scheduleRepeat(time => {
transport.clear(eventID); transport.clear(eventID);
@ -646,7 +646,7 @@ describe("Transport", () => {
it("repeats a repeat event", () => { it("repeats a repeat event", () => {
let invocations = 0; let invocations = 0;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.scheduleRepeat(() => { transport.scheduleRepeat(() => {
invocations++; invocations++;
}, 0.1, 0); }, 0.1, 0);
@ -659,7 +659,7 @@ describe("Transport", () => {
it("repeats at the repeat interval", () => { it("repeats at the repeat interval", () => {
let wasCalled = false; let wasCalled = false;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
let repeatTime = -1; let repeatTime = -1;
transport.scheduleRepeat(time => { transport.scheduleRepeat(time => {
if (repeatTime !== -1) { if (repeatTime !== -1) {
@ -678,7 +678,7 @@ describe("Transport", () => {
let first = false; let first = false;
let second = false; let second = false;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const firstID = transport.scheduleRepeat(() => { const firstID = transport.scheduleRepeat(() => {
first = true; first = true;
transport.clear(firstID); transport.clear(firstID);
@ -698,7 +698,7 @@ describe("Transport", () => {
it("repeats for the given interval", () => { it("repeats for the given interval", () => {
let repeatCount = 0; let repeatCount = 0;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.scheduleRepeat(time => { transport.scheduleRepeat(time => {
repeatCount++; repeatCount++;
}, 0.1, 0, 0.5); }, 0.1, 0, 0.5);
@ -711,7 +711,7 @@ describe("Transport", () => {
it("can add an event after the Transport is started", () => { it("can add an event after the Transport is started", () => {
let invocations = 0; let invocations = 0;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.start(0); transport.start(0);
let wasScheduled = false; let wasScheduled = false;
const times = [0.15, 0.3]; const times = [0.15, 0.3];
@ -732,7 +732,7 @@ describe("Transport", () => {
it("can add an event to the past after the Transport is started", () => { it("can add an event to the past after the Transport is started", () => {
let invocations = 0; let invocations = 0;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.start(0); transport.start(0);
let wasScheduled = false; let wasScheduled = false;
const times = [0.15, 0.25]; const times = [0.15, 0.25];
@ -756,7 +756,7 @@ describe("Transport", () => {
it("can schedule a single event on the timeline", () => { it("can schedule a single event on the timeline", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const eventID = transport.scheduleOnce(() => {}, 0); const eventID = transport.scheduleOnce(() => {}, 0);
expect(eventID).to.be.a("number"); expect(eventID).to.be.a("number");
}); });
@ -765,7 +765,7 @@ describe("Transport", () => {
it("scheduled event gets invoked with the time of the event", () => { it("scheduled event gets invoked with the time of the event", () => {
let invoked = false; let invoked = false;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const startTime = 0.1; const startTime = 0.1;
const eventID = transport.scheduleOnce(time => { const eventID = transport.scheduleOnce(time => {
invoked = true; invoked = true;
@ -781,7 +781,7 @@ describe("Transport", () => {
it("can schedule events with TransportTime", () => { it("can schedule events with TransportTime", () => {
let invoked = false; let invoked = false;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const startTime = 0.1; const startTime = 0.1;
const eighth = transport.toSeconds("8n"); const eighth = transport.toSeconds("8n");
transport.scheduleOnce(time => { transport.scheduleOnce(time => {
@ -796,7 +796,7 @@ describe("Transport", () => {
it("can clear a scheduled event", () => { it("can clear a scheduled event", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const eventID = transport.scheduleOnce(() => { const eventID = transport.scheduleOnce(() => {
throw new Error("should not call this function"); throw new Error("should not call this function");
}, 0); }, 0);
@ -808,7 +808,7 @@ describe("Transport", () => {
it("can be scheduled in the future", () => { it("can be scheduled in the future", () => {
let invoked = false; let invoked = false;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const startTime = transport.now() + 0.1; const startTime = transport.now() + 0.1;
const eventID = transport.scheduleOnce(time => { const eventID = transport.scheduleOnce(time => {
transport.clear(eventID); transport.clear(eventID);
@ -824,7 +824,7 @@ describe("Transport", () => {
it("the event is removed after is is invoked", () => { it("the event is removed after is is invoked", () => {
let iterations = 0; let iterations = 0;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.scheduleOnce(() => { transport.scheduleOnce(() => {
iterations++; iterations++;
}, 0); }, 0);
@ -841,7 +841,7 @@ describe("Transport", () => {
it("invokes start/stop/pause events", () => { it("invokes start/stop/pause events", () => {
let invocations = 0; let invocations = 0;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.on("start", () => { transport.on("start", () => {
invocations++; invocations++;
}); });
@ -860,7 +860,7 @@ describe("Transport", () => {
it("invokes start event with correct offset", () => { it("invokes start event with correct offset", () => {
let wasCalled = false; let wasCalled = false;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.on("start", (time, offset) => { transport.on("start", (time, offset) => {
expect(time).to.be.closeTo(0.2, 0.01); expect(time).to.be.closeTo(0.2, 0.01);
expect(offset).to.be.closeTo(0.5, 0.001); expect(offset).to.be.closeTo(0.5, 0.001);
@ -875,7 +875,7 @@ describe("Transport", () => {
it("invokes the event just before the scheduled time", () => { it("invokes the event just before the scheduled time", () => {
let invoked = false; let invoked = false;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.on("start", (time, offset) => { transport.on("start", (time, offset) => {
expect(time - transport.context.currentTime).to.be.closeTo(0, 0.01); expect(time - transport.context.currentTime).to.be.closeTo(0, 0.01);
expect(offset).to.equal(0); expect(offset).to.equal(0);
@ -890,7 +890,7 @@ describe("Transport", () => {
it("passes in the time argument to the events", () => { it("passes in the time argument to the events", () => {
let invocations = 0; let invocations = 0;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const now = transport.now(); const now = transport.now();
transport.on("start", time => { transport.on("start", time => {
invocations++; invocations++;
@ -909,7 +909,7 @@ describe("Transport", () => {
it("invokes the 'loop' method on loop", () => { it("invokes the 'loop' method on loop", () => {
let loops = 0; let loops = 0;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const sixteenth = transport.toSeconds("16n"); const sixteenth = transport.toSeconds("16n");
transport.setLoopPoints(0, sixteenth); transport.setLoopPoints(0, sixteenth);
transport.loop = true; transport.loop = true;
@ -932,7 +932,7 @@ describe("Transport", () => {
it("can get/set the swing subdivision", () => { it("can get/set the swing subdivision", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.swingSubdivision = "8n"; transport.swingSubdivision = "8n";
expect(transport.swingSubdivision).to.equal("8n"); expect(transport.swingSubdivision).to.equal("8n");
transport.swingSubdivision = "4n"; transport.swingSubdivision = "4n";
@ -942,7 +942,7 @@ describe("Transport", () => {
it("can get/set the swing amount", () => { it("can get/set the swing amount", () => {
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.swing = 0.5; transport.swing = 0.5;
expect(transport.swing).to.equal(0.5); expect(transport.swing).to.equal(0.5);
transport.swing = 0; transport.swing = 0;
@ -953,7 +953,7 @@ describe("Transport", () => {
it("can swing", () => { it("can swing", () => {
let invocations = 0; let invocations = 0;
return Offline(context => { return Offline(context => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.swing = 1; transport.swing = 1;
transport.swingSubdivision = "8n"; transport.swingSubdivision = "8n";
const eightNote = transport.toSeconds("8n"); const eightNote = transport.toSeconds("8n");

View file

@ -79,15 +79,15 @@ type TransportCallback = (time: Seconds) => void;
* @example * @example
* const osc = new Tone.Oscillator().toDestination(); * const osc = new Tone.Oscillator().toDestination();
* // repeated event every 8th note * // repeated event every 8th note
* Tone.Transport.scheduleRepeat((time) => { * Tone.getTransport().scheduleRepeat((time) => {
* // use the callback time to schedule events * // use the callback time to schedule events
* osc.start(time).stop(time + 0.1); * osc.start(time).stop(time + 0.1);
* }, "8n"); * }, "8n");
* // transport must be started before it starts invoking events * // transport must be started before it starts invoking events
* Tone.Transport.start(); * Tone.getTransport().start();
* @category Core * @category Core
*/ */
export class Transport export class TransportClass
extends ToneWithContext<TransportOptions> extends ToneWithContext<TransportOptions>
implements Emitter<TransportEventNames> { implements Emitter<TransportEventNames> {
readonly name: string = "Transport"; readonly name: string = "Transport";
@ -130,14 +130,14 @@ export class Transport
* The Beats Per Minute of the Transport. * The Beats Per Minute of the Transport.
* @example * @example
* const osc = new Tone.Oscillator().toDestination(); * const osc = new Tone.Oscillator().toDestination();
* Tone.Transport.bpm.value = 80; * Tone.getTransport().bpm.value = 80;
* // start/stop the oscillator every quarter note * // start/stop the oscillator every quarter note
* Tone.Transport.scheduleRepeat(time => { * Tone.getTransport().scheduleRepeat(time => {
* osc.start(time).stop(time + 0.1); * osc.start(time).stop(time + 0.1);
* }, "4n"); * }, "4n");
* Tone.Transport.start(); * Tone.getTransport().start();
* // ramp the bpm to 120 over 10 seconds * // ramp the bpm to 120 over 10 seconds
* Tone.Transport.bpm.rampTo(120, 10); * Tone.getTransport().bpm.rampTo(120, 10);
*/ */
bpm: TickParam<"bpm">; bpm: TickParam<"bpm">;
@ -187,9 +187,9 @@ export class Transport
constructor(options?: Partial<TransportOptions>); constructor(options?: Partial<TransportOptions>);
constructor() { constructor() {
super(optionsFromArguments(Transport.getDefaults(), arguments)); super(optionsFromArguments(TransportClass.getDefaults(), arguments));
const options = optionsFromArguments( const options = optionsFromArguments(
Transport.getDefaults(), TransportClass.getDefaults(),
arguments arguments
); );
@ -280,7 +280,7 @@ export class Transport
* @return The id of the event which can be used for canceling the event. * @return The id of the event which can be used for canceling the event.
* @example * @example
* // schedule an event on the 16th measure * // schedule an event on the 16th measure
* Tone.Transport.schedule((time) => { * Tone.getTransport().schedule((time) => {
* // invoked on measure 16 * // invoked on measure 16
* console.log("measure 16!"); * console.log("measure 16!");
* }, "16:0:0"); * }, "16:0:0");
@ -308,7 +308,7 @@ export class Transport
* @example * @example
* const osc = new Tone.Oscillator().toDestination().start(); * const osc = new Tone.Oscillator().toDestination().start();
* // a callback invoked every eighth note after the first measure * // a callback invoked every eighth note after the first measure
* Tone.Transport.scheduleRepeat((time) => { * Tone.getTransport().scheduleRepeat((time) => {
* osc.start(time).stop(time + 0.1); * osc.start(time).stop(time + 0.1);
* }, "8n", "1m"); * }, "8n", "1m");
*/ */
@ -427,7 +427,7 @@ export class Transport
* @param offset The timeline offset to start the transport. * @param offset The timeline offset to start the transport.
* @example * @example
* // start the transport in one second starting at beginning of the 5th measure. * // start the transport in one second starting at beginning of the 5th measure.
* Tone.Transport.start("+1", "4:0:0"); * Tone.getTransport().start("+1", "4:0:0");
*/ */
start(time?: Time, offset?: TransportTime): this { start(time?: Time, offset?: TransportTime): this {
// start the context // start the context
@ -445,7 +445,7 @@ export class Transport
* Stop the transport and all sources synced to the transport. * Stop the transport and all sources synced to the transport.
* @param time The time when the transport should stop. * @param time The time when the transport should stop.
* @example * @example
* Tone.Transport.stop(); * Tone.getTransport().stop();
*/ */
stop(time?: Time): this { stop(time?: Time): this {
this._clock.stop(time); this._clock.stop(time);
@ -484,11 +484,11 @@ export class Transport
* For example 4/4 would be just 4 and 6/8 would be 3. * For example 4/4 would be just 4 and 6/8 would be 3.
* @example * @example
* // common time * // common time
* Tone.Transport.timeSignature = 4; * Tone.getTransport().timeSignature = 4;
* // 7/8 * // 7/8
* Tone.Transport.timeSignature = [7, 8]; * Tone.getTransport().timeSignature = [7, 8];
* // this will be reduced to a single number * // this will be reduced to a single number
* Tone.Transport.timeSignature; // returns 3.5 * Tone.getTransport().timeSignature; // returns 3.5
*/ */
get timeSignature(): TimeSignature { get timeSignature(): TimeSignature {
return this._timeSignature; return this._timeSignature;
@ -534,8 +534,8 @@ export class Transport
* Set the loop start and stop at the same time. * Set the loop start and stop at the same time.
* @example * @example
* // loop over the first measure * // loop over the first measure
* Tone.Transport.setLoopPoints(0, "1m"); * Tone.getTransport().setLoopPoints(0, "1m");
* Tone.Transport.loop = true; * Tone.getTransport().loop = true;
*/ */
setLoopPoints( setLoopPoints(
startPosition: TransportTime, startPosition: TransportTime,
@ -682,8 +682,8 @@ export class Transport
* @return The context time of the next subdivision. * @return The context time of the next subdivision.
* @example * @example
* // the transport must be started, otherwise returns 0 * // the transport must be started, otherwise returns 0
* Tone.Transport.start(); * Tone.getTransport().start();
* Tone.Transport.nextSubdivision("4n"); * Tone.getTransport().nextSubdivision("4n");
*/ */
nextSubdivision(subdivision?: Time): Seconds { nextSubdivision(subdivision?: Time): Seconds {
subdivision = this.toTicks(subdivision); subdivision = this.toTicks(subdivision);
@ -801,14 +801,14 @@ export class Transport
emit!: (event: any, ...args: any[]) => this; emit!: (event: any, ...args: any[]) => this;
} }
Emitter.mixin(Transport); Emitter.mixin(TransportClass);
//------------------------------------- //-------------------------------------
// INITIALIZATION // INITIALIZATION
//------------------------------------- //-------------------------------------
onContextInit((context) => { onContextInit((context) => {
context.transport = new Transport({ context }); context.transport = new TransportClass({ context });
}); });
onContextClose((context) => { onContextClose((context) => {

View file

@ -1,13 +1,13 @@
import { expect } from "chai"; import { expect } from "chai";
import { Offline } from "test/helper/Offline"; import { Offline } from "test/helper/Offline";
import { Transport } from "./Transport"; import { TransportClass } from "./Transport";
import { TransportEvent } from "./TransportEvent"; import { TransportEvent } from "./TransportEvent";
describe("TransportEvent", () => { describe("TransportEvent", () => {
it("can be created and disposed", () => { it("can be created and disposed", () => {
return Offline((context) => { return Offline((context) => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const event = new TransportEvent(transport, { const event = new TransportEvent(transport, {
time: 0, time: 0,
}); });
@ -17,7 +17,7 @@ describe("TransportEvent", () => {
it("has a unique id", () => { it("has a unique id", () => {
return Offline((context) => { return Offline((context) => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const event = new TransportEvent(transport, { const event = new TransportEvent(transport, {
time: 0, time: 0,
}); });
@ -29,7 +29,7 @@ describe("TransportEvent", () => {
it("can invoke the callback", () => { it("can invoke the callback", () => {
let wasInvoked = false; let wasInvoked = false;
return Offline((context) => { return Offline((context) => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const event = new TransportEvent(transport, { const event = new TransportEvent(transport, {
callback: (time) => { callback: (time) => {
expect(time).to.equal(100); expect(time).to.equal(100);

View file

@ -1,7 +1,7 @@
import { Seconds, Ticks } from "../type/Units"; import { Seconds, Ticks } from "../type/Units";
import { noOp } from "../util/Interface"; import { noOp } from "../util/Interface";
type Transport = import("../clock/Transport").Transport; type Transport = import("../clock/Transport").TransportClass;
export interface TransportEventOptions { export interface TransportEventOptions {
callback: (time: number) => void; callback: (time: number) => void;
@ -10,7 +10,7 @@ export interface TransportEventOptions {
} }
/** /**
* TransportEvent is an internal class used by [[Transport]] * TransportEvent is an internal class used by [[TransportClass]]
* to schedule events. Do no invoke this class directly, it is * to schedule events. Do no invoke this class directly, it is
* handled from within Tone.Transport. * handled from within Tone.Transport.
*/ */

View file

@ -1,13 +1,13 @@
import { expect } from "chai"; import { expect } from "chai";
import { Offline } from "test/helper/Offline"; import { Offline } from "test/helper/Offline";
import { Transport } from "./Transport"; import { TransportClass } from "./Transport";
import { TransportRepeatEvent } from "./TransportRepeatEvent"; import { TransportRepeatEvent } from "./TransportRepeatEvent";
describe("TransportRepeatEvent", () => { describe("TransportRepeatEvent", () => {
it("can be created and disposed", () => { it("can be created and disposed", () => {
return Offline((context) => { return Offline((context) => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const event = new TransportRepeatEvent(transport, { const event = new TransportRepeatEvent(transport, {
duration: 100, duration: 100,
interval: 4, interval: 4,
@ -19,7 +19,7 @@ describe("TransportRepeatEvent", () => {
it("generates a unique event ID", () => { it("generates a unique event ID", () => {
return Offline((context) => { return Offline((context) => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const event = new TransportRepeatEvent(transport, { const event = new TransportRepeatEvent(transport, {
time: 0, time: 0,
}); });
@ -30,7 +30,7 @@ describe("TransportRepeatEvent", () => {
it("is removed from the Transport when disposed", () => { it("is removed from the Transport when disposed", () => {
return Offline((context) => { return Offline((context) => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
const event = new TransportRepeatEvent(transport, { const event = new TransportRepeatEvent(transport, {
time: 0, time: 0,
}); });

View file

@ -4,7 +4,7 @@ import { Seconds, Ticks, Time } from "../type/Units";
import { TransportEvent, TransportEventOptions } from "./TransportEvent"; import { TransportEvent, TransportEventOptions } from "./TransportEvent";
import { GT, LT } from "../util/Math"; import { GT, LT } from "../util/Math";
type Transport = import("../clock/Transport").Transport; type Transport = import("../clock/Transport").TransportClass;
interface TransportRepeatEventOptions extends TransportEventOptions { interface TransportRepeatEventOptions extends TransportEventOptions {
interval: Ticks; interval: Ticks;

View file

@ -2,10 +2,10 @@ import { Seconds } from "../type/Units";
import { Emitter } from "../util/Emitter"; import { Emitter } from "../util/Emitter";
import { AnyAudioContext } from "./AudioContext"; import { AnyAudioContext } from "./AudioContext";
type Draw = import("../util/Draw").Draw; type Draw = import("../util/Draw").DrawClass;
type Destination = import("./Destination").Destination; type Destination = import("./Destination").DestinationClass;
type Transport = import("../clock/Transport").Transport; type Transport = import("../clock/Transport").TransportClass;
type Listener = import("./Listener").Listener; type Listener = import("./Listener").ListenerClass;
// these are either not used in Tone.js or deprecated and not implemented. // these are either not used in Tone.js or deprecated and not implemented.
export type ExcludedFromBaseAudioContext = export type ExcludedFromBaseAudioContext =

View file

@ -2,13 +2,13 @@ import { expect } from "chai";
import { ConstantOutput } from "test/helper/ConstantOutput"; import { ConstantOutput } from "test/helper/ConstantOutput";
import { Offline } from "test/helper/Offline"; import { Offline } from "test/helper/Offline";
import { ONLINE_TESTING } from "test/helper/Supports"; import { ONLINE_TESTING } from "test/helper/Supports";
import { Transport } from "../clock/Transport"; import { TransportClass } from "../clock/Transport";
import { getContext } from "../Global"; import { getContext } from "../Global";
import { createAudioContext } from "./AudioContext"; import { createAudioContext } from "./AudioContext";
import { Context } from "./Context"; import { Context } from "./Context";
import { Destination } from "./Destination"; import { DestinationClass } from "./Destination";
import { Listener } from "./Listener"; import { ListenerClass } from "./Listener";
import { Draw } from "../util/Draw"; import { DrawClass } from "../util/Draw";
import { connect } from "./ToneAudioNode"; import { connect } from "./ToneAudioNode";
describe("Context", () => { describe("Context", () => {
@ -19,9 +19,9 @@ describe("Context", () => {
const ctxDraw = context.draw; const ctxDraw = context.draw;
const ctxTransport = context.transport; const ctxTransport = context.transport;
const ctxListener = context.listener; const ctxListener = context.listener;
expect(context.destination).is.instanceOf(Destination); expect(context.destination).is.instanceOf(DestinationClass);
expect(context.draw).is.instanceOf(Draw); expect(context.draw).is.instanceOf(DrawClass);
expect(context.listener).is.instanceOf(Listener); expect(context.listener).is.instanceOf(ListenerClass);
await context.close(); await context.close();
expect(ctxDest.disposed).to.be.true; expect(ctxDest.disposed).to.be.true;
expect(ctxDraw.disposed).to.be.true; expect(ctxDraw.disposed).to.be.true;
@ -218,7 +218,7 @@ describe("Context", () => {
it("is invoked in the offline context", () => { it("is invoked in the offline context", () => {
return Offline((context) => { return Offline((context) => {
const transport = new Transport({ context }); const transport = new TransportClass({ context });
transport.context.setTimeout(() => { transport.context.setTimeout(() => {
expect(transport.now()).to.be.closeTo(0.01, 0.005); expect(transport.now()).to.be.closeTo(0.01, 0.005);
}, 0.01); }, 0.01);

View file

@ -13,10 +13,10 @@ import { closeContext, initializeContext } from "./ContextInitialization";
import { BaseContext, ContextLatencyHint } from "./BaseContext"; import { BaseContext, ContextLatencyHint } from "./BaseContext";
import { assert } from "../util/Debug"; import { assert } from "../util/Debug";
type Transport = import("../clock/Transport").Transport; type Transport = import("../clock/Transport").TransportClass;
type Destination = import("./Destination").Destination; type Destination = import("./Destination").DestinationClass;
type Listener = import("./Listener").Listener; type Listener = import("./Listener").ListenerClass;
type Draw = import("../util/Draw").Draw; type Draw = import("../util/Draw").DrawClass;
export interface ContextOptions { export interface ContextOptions {
clockSource: TickerClockSource; clockSource: TickerClockSource;

View file

@ -4,12 +4,12 @@ import { Offline } from "test/helper/Offline";
import { PassAudio } from "test/helper/PassAudio"; import { PassAudio } from "test/helper/PassAudio";
import { Oscillator } from "Tone/source/oscillator/Oscillator"; import { Oscillator } from "Tone/source/oscillator/Oscillator";
import { getContext } from "../Global"; import { getContext } from "../Global";
import { Destination } from "./Destination"; import { DestinationClass } from "./Destination";
describe("Destination", () => { describe("Destination", () => {
it("creates itself on the context", () => { it("creates itself on the context", () => {
expect(getContext().destination).instanceOf(Destination); expect(getContext().destination).instanceOf(DestinationClass);
}); });
it("can be muted and unmuted", () => { it("can be muted and unmuted", () => {

View file

@ -26,7 +26,7 @@ interface DestinationOptions extends ToneAudioNodeOptions {
* oscillator.toDestination(); * oscillator.toDestination();
* @category Core * @category Core
*/ */
export class Destination extends ToneAudioNode<DestinationOptions> { export class DestinationClass extends ToneAudioNode<DestinationOptions> {
readonly name: string = "Destination"; readonly name: string = "Destination";
@ -46,8 +46,8 @@ export class Destination extends ToneAudioNode<DestinationOptions> {
constructor(options: Partial<DestinationOptions>); constructor(options: Partial<DestinationOptions>);
constructor() { constructor() {
super(optionsFromArguments(Destination.getDefaults(), arguments)); super(optionsFromArguments(DestinationClass.getDefaults(), arguments));
const options = optionsFromArguments(Destination.getDefaults(), arguments); const options = optionsFromArguments(DestinationClass.getDefaults(), arguments);
connectSeries(this.input, this.output, this.context.rawContext.destination); connectSeries(this.input, this.output, this.context.rawContext.destination);
@ -120,7 +120,7 @@ export class Destination extends ToneAudioNode<DestinationOptions> {
//------------------------------------- //-------------------------------------
onContextInit(context => { onContextInit(context => {
context.destination = new Destination({ context }); context.destination = new DestinationClass({ context });
}); });
onContextClose(context => { onContextClose(context => {

View file

@ -2,10 +2,10 @@ import { BaseContext } from "./BaseContext";
import { Seconds } from "../type/Units"; import { Seconds } from "../type/Units";
import { AnyAudioContext } from "./AudioContext"; import { AnyAudioContext } from "./AudioContext";
type Draw = import("../util/Draw").Draw; type Draw = import("../util/Draw").DrawClass;
type Destination = import("./Destination").Destination; type Destination = import("./Destination").DestinationClass;
type Transport = import("../clock/Transport").Transport; type Transport = import("../clock/Transport").TransportClass;
type Listener = import("./Listener").Listener; type Listener = import("./Listener").ListenerClass;
export class DummyContext extends BaseContext { export class DummyContext extends BaseContext {
//--------------------------- //---------------------------

View file

@ -1,12 +1,12 @@
import { expect } from "chai"; import { expect } from "chai";
import { Offline } from "test/helper/Offline"; import { Offline } from "test/helper/Offline";
import { getContext } from "../Global"; import { getContext } from "../Global";
import { Listener } from "./Listener"; import { ListenerClass } from "./Listener";
describe("Listener", () => { describe("Listener", () => {
it("creates itself on the context", () => { it("creates itself on the context", () => {
expect(getContext().listener).instanceOf(Listener); expect(getContext().listener).instanceOf(ListenerClass);
}); });
it("can get and set values as an object", () => { it("can get and set values as an object", () => {

View file

@ -20,7 +20,7 @@ export interface ListenerOptions extends ToneAudioNodeOptions{
* to place sounds in 3D and Listener allows you to navigate the 3D sound environment from * to place sounds in 3D and Listener allows you to navigate the 3D sound environment from
* a first-person perspective. There is only one listener per audio context. * a first-person perspective. There is only one listener per audio context.
*/ */
export class Listener extends ToneAudioNode<ListenerOptions> { export class ListenerClass extends ToneAudioNode<ListenerOptions> {
readonly name: string = "Listener"; readonly name: string = "Listener";
@ -109,7 +109,7 @@ export class Listener extends ToneAudioNode<ListenerOptions> {
//------------------------------------- //-------------------------------------
onContextInit(context => { onContextInit(context => {
context.listener = new Listener({ context }); context.listener = new ListenerClass({ context });
}); });
onContextClose(context => { onContextClose(context => {

View file

@ -79,8 +79,6 @@ export abstract class ToneWithContext<Options extends ToneWithContextOptions> ex
/** /**
* The duration in seconds of one sample. * The duration in seconds of one sample.
* @example
* console.log(Tone.Transport.sampleTime);
*/ */
get sampleTime(): Seconds { get sampleTime(): Seconds {
return 1 / this.context.sampleRate; return 1 / this.context.sampleRate;
@ -97,7 +95,7 @@ export abstract class ToneWithContext<Options extends ToneWithContextOptions> ex
/** /**
* Convert the incoming time to seconds. * Convert the incoming time to seconds.
* This is calculated against the current [[Transport]] bpm * This is calculated against the current [[TransportClass]] bpm
* @example * @example
* const gain = new Tone.Gain(); * const gain = new Tone.Gain();
* setInterval(() => console.log(gain.toSeconds("4n")), 100); * setInterval(() => console.log(gain.toSeconds("4n")), 100);

View file

@ -1,12 +1,12 @@
import { expect } from "chai"; import { expect } from "chai";
import { ONLINE_TESTING } from "test/helper/Supports"; import { ONLINE_TESTING } from "test/helper/Supports";
import { Draw } from "./Draw"; import { DrawClass } from "./Draw";
describe("Draw", () => { describe("Draw", () => {
if (ONLINE_TESTING) { if (ONLINE_TESTING) {
const draw = new Draw(); const draw = new DrawClass();
after(() => { after(() => {
draw.dispose(); draw.dispose();

View file

@ -25,7 +25,7 @@ interface DrawEvent extends TimelineEvent {
* Tone.Transport.start(); * Tone.Transport.start();
* @category Core * @category Core
*/ */
export class Draw extends ToneWithContext<ToneWithContextOptions> { export class DrawClass extends ToneWithContext<ToneWithContextOptions> {
readonly name: string = "Draw"; readonly name: string = "Draw";
@ -117,7 +117,7 @@ export class Draw extends ToneWithContext<ToneWithContextOptions> {
//------------------------------------- //-------------------------------------
onContextInit(context => { onContextInit(context => {
context.draw = new Draw({ context }); context.draw = new DrawClass({ context });
}); });
onContextClose(context => { onContextClose(context => {

View file

@ -20,6 +20,7 @@ type IteratorCallback = (event: IntervalTimelineEvent) => void;
* for querying an intersection point with the timeline * for querying an intersection point with the timeline
* events. Internally uses an [Interval Tree](https://en.wikipedia.org/wiki/Interval_tree) * events. Internally uses an [Interval Tree](https://en.wikipedia.org/wiki/Interval_tree)
* to represent the data. * to represent the data.
* @internal
*/ */
export class IntervalTimeline extends Tone { export class IntervalTimeline extends Tone {

View file

@ -12,6 +12,7 @@ export interface StateTimelineEvent extends TimelineEvent {
/** /**
* A Timeline State. Provides the methods: `setStateAtTime("state", time)` and `getValueAtTime(time)` * A Timeline State. Provides the methods: `setStateAtTime("state", time)` and `getValueAtTime(time)`
* @param initial The initial state of the StateTimeline. Defaults to `undefined` * @param initial The initial state of the StateTimeline. Defaults to `undefined`
* @internal
*/ */
export class StateTimeline<AdditionalOptions extends Record<string, any> = Record<string, any>> extends Timeline<StateTimelineEvent & AdditionalOptions> { export class StateTimeline<AdditionalOptions extends Record<string, any> = Record<string, any>> extends Timeline<StateTimelineEvent & AdditionalOptions> {

View file

@ -26,6 +26,7 @@ export interface TimelineEvent {
* along a timeline. All events must have a "time" property. * along a timeline. All events must have a "time" property.
* Internally, events are stored in time order for fast * Internally, events are stored in time order for fast
* retrieval. * retrieval.
* @internal
*/ */
export class Timeline<GenericEvent extends TimelineEvent> extends Tone { export class Timeline<GenericEvent extends TimelineEvent> extends Tone {

View file

@ -1,8 +1,8 @@
import * as Classes from "./classes"; import * as Classes from "./classes";
import { Transport } from "./core/clock/Transport"; import { TransportClass } from "./core/clock/Transport";
import { Context } from "./core/context/Context"; import { Context } from "./core/context/Context";
import { Listener } from "./core/context/Listener"; import { ListenerClass } from "./core/context/Listener";
import { Destination } from "./core/context/Destination"; import { DestinationClass } from "./core/context/Destination";
import { FrequencyClass } from "./core/type/Frequency"; import { FrequencyClass } from "./core/type/Frequency";
import { MidiClass } from "./core/type/Midi"; import { MidiClass } from "./core/type/Midi";
import { TicksClass } from "./core/type/Ticks"; import { TicksClass } from "./core/type/Ticks";
@ -10,7 +10,7 @@ import { TimeClass } from "./core/type/Time";
import { TransportTimeClass } from "./core/type/TransportTime"; import { TransportTimeClass } from "./core/type/TransportTime";
import { isDefined, isFunction } from "./core/util/TypeCheck"; import { isDefined, isFunction } from "./core/util/TypeCheck";
import { omitFromObject } from "./core/util/Defaults"; import { omitFromObject } from "./core/util/Defaults";
import { Draw } from "./core/util/Draw"; import { DrawClass } from "./core/util/Draw";
type ClassesWithoutSingletons = Omit<typeof Classes, "Transport" | "Destination" | "Draw">; type ClassesWithoutSingletons = Omit<typeof Classes, "Transport" | "Destination" | "Draw">;
@ -19,10 +19,10 @@ type ClassesWithoutSingletons = Omit<typeof Classes, "Transport" | "Destination"
* to the same context and contains a singleton Transport and Destination node. * to the same context and contains a singleton Transport and Destination node.
*/ */
type ToneObject = { type ToneObject = {
Transport: Transport; Transport: TransportClass;
Destination: Destination; Destination: DestinationClass;
Listener: Listener; Listener: ListenerClass;
Draw: Draw; Draw: DrawClass;
context: Context; context: Context;
now: () => number; now: () => number;
immediate: () => number; immediate: () => number;

View file

@ -1,9 +1,9 @@
import * as Tone from "./index"; import * as Tone from "./index";
import { expect } from "chai"; import { expect } from "chai";
import { Destination } from "./core/context/Destination"; import { DestinationClass } from "./core/context/Destination";
import { Context } from "./core/context/Context"; import { Context } from "./core/context/Context";
import { Transport } from "./core/clock/Transport"; import { TransportClass } from "./core/clock/Transport";
import { Draw } from "./core/util/Draw"; import { DrawClass } from "./core/util/Draw";
describe("Tone", () => { describe("Tone", () => {
@ -15,16 +15,16 @@ describe("Tone", () => {
}); });
it("exports the global singletons", () => { it("exports the global singletons", () => {
expect(Tone.Destination).to.be.an.instanceOf(Destination); expect(Tone.Destination).to.be.an.instanceOf(DestinationClass);
expect(Tone.Draw).to.be.an.instanceOf(Draw); expect(Tone.Draw).to.be.an.instanceOf(DrawClass);
expect(Tone.Transport).to.be.an.instanceOf(Transport); expect(Tone.Transport).to.be.an.instanceOf(TransportClass);
expect(Tone.context).to.be.an.instanceOf(Context); expect(Tone.context).to.be.an.instanceOf(Context);
}); });
it("exports the global singleton getters", () => { it("exports the global singleton getters", () => {
expect(Tone.getDestination()).to.be.an.instanceOf(Destination); expect(Tone.getDestination()).to.be.an.instanceOf(DestinationClass);
expect(Tone.getDraw()).to.be.an.instanceOf(Draw); expect(Tone.getDraw()).to.be.an.instanceOf(DrawClass);
expect(Tone.getTransport()).to.be.an.instanceOf(Transport); expect(Tone.getTransport()).to.be.an.instanceOf(TransportClass);
}); });
it("can start the global context", () => { it("can start the global context", () => {

View file

@ -27,75 +27,80 @@ export function immediate(): Seconds {
/** /**
* The Transport object belonging to the global Tone.js Context. * The Transport object belonging to the global Tone.js Context.
* See [[Transport]] * See [[TransportClass]]
* @category Core * @category Core
* @deprecated Use {@link getTransport} instead
*/ */
export const Transport = getContext().transport; export const Transport = getContext().transport;
/** /**
* The Transport object belonging to the global Tone.js Context. * The Transport object belonging to the global Tone.js Context.
* See [[Transport]] * See [[TransportClass]]
* @category Core * @category Core
*/ */
export function getTransport(): import("./core/clock/Transport").Transport { export function getTransport(): import("./core/clock/Transport").TransportClass {
return getContext().transport; return getContext().transport;
} }
/** /**
* The Destination (output) belonging to the global Tone.js Context. * The Destination (output) belonging to the global Tone.js Context.
* See [[Destination]] * See [[DestinationClass]]
* @category Core * @category Core
* @deprecated Use {@link getDestination} instead
*/ */
export const Destination = getContext().destination; export const Destination = getContext().destination;
/** /**
* @deprecated Use [[Destination]] * @deprecated Use {@link getDestination} instead
*/ */
export const Master = getContext().destination; export const Master = getContext().destination;
/** /**
* The Destination (output) belonging to the global Tone.js Context. * The Destination (output) belonging to the global Tone.js Context.
* See [[Destination]] * See [[DestinationClass]]
* @category Core * @category Core
*/ */
export function getDestination(): import("./core/context/Destination").Destination { export function getDestination(): import("./core/context/Destination").DestinationClass {
return getContext().destination; return getContext().destination;
} }
/** /**
* The [[Listener]] belonging to the global Tone.js Context. * The [[ListenerClass]] belonging to the global Tone.js Context.
* @category Core * @category Core
* @deprecated Use {@link getListener} instead
*/ */
export const Listener = getContext().listener; export const Listener = getContext().listener;
/** /**
* The [[Listener]] belonging to the global Tone.js Context. * The [[ListenerClass]] belonging to the global Tone.js Context.
* @category Core * @category Core
*/ */
export function getListener(): import("./core/context/Listener").Listener { export function getListener(): import("./core/context/Listener").ListenerClass {
return getContext().listener; return getContext().listener;
} }
/** /**
* Draw is used to synchronize the draw frame with the Transport's callbacks. * Draw is used to synchronize the draw frame with the Transport's callbacks.
* See [[Draw]] * See [[DrawClass]]
* @category Core * @category Core
* @deprecated Use {@link getDraw} instead
*/ */
export const Draw = getContext().draw; export const Draw = getContext().draw;
/** /**
* Get the singleton attached to the global context. * Get the singleton attached to the global context.
* Draw is used to synchronize the draw frame with the Transport's callbacks. * Draw is used to synchronize the draw frame with the Transport's callbacks.
* See [[Draw]] * See [[DrawClass]]
* @category Core * @category Core
*/ */
export function getDraw(): import("./core/util/Draw").Draw { export function getDraw(): import("./core/util/Draw").DrawClass {
return getContext().draw; return getContext().draw;
} }
/** /**
* A reference to the global context * A reference to the global context
* See [[Context]] * See [[Context]]
* @deprecated Use {@link getContext} instead
*/ */
export const context = getContext(); export const context = getContext();
@ -111,6 +116,9 @@ export function loaded() {
// this fills in name changes from 13.x to 14.x // this fills in name changes from 13.x to 14.x
import { ToneAudioBuffers } from "./core/context/ToneAudioBuffers"; import { ToneAudioBuffers } from "./core/context/ToneAudioBuffers";
import { ToneBufferSource } from "./source/buffer/ToneBufferSource"; import { ToneBufferSource } from "./source/buffer/ToneBufferSource";
/** @deprecated Use {@link ToneAudioBuffer} */
export const Buffer: typeof ToneAudioBuffer = ToneAudioBuffer; export const Buffer: typeof ToneAudioBuffer = ToneAudioBuffer;
/** @deprecated Use {@link ToneAudioBuffers} */
export const Buffers: typeof ToneAudioBuffers = ToneAudioBuffers; export const Buffers: typeof ToneAudioBuffers = ToneAudioBuffers;
/** @deprecated Use {@link ToneBufferSource} */
export const BufferSource: typeof ToneBufferSource = ToneBufferSource; export const BufferSource: typeof ToneBufferSource = ToneBufferSource;

View file

@ -6,7 +6,8 @@ import { ToneConstantSource } from "./ToneConstantSource";
import { OutputNode } from "../core/context/ToneAudioNode"; import { OutputNode } from "../core/context/ToneAudioNode";
/** /**
* Adds the ability to synchronize the signal to the [[Transport]] * Adds the ability to synchronize the signal to the [[TransportClass]]
* @category Signal
*/ */
export class SyncedSignal<TypeName extends UnitName = "number"> extends Signal<TypeName> { export class SyncedSignal<TypeName extends UnitName = "number"> extends Signal<TypeName> {

View file

@ -9,4 +9,6 @@
"excludeProtected" : true, "excludeProtected" : true,
"excludePrivate" : true, "excludePrivate" : true,
"hideGenerator": true, "hideGenerator": true,
"includeVersion": true,
"excludeInternal": true
} }