tone 14.9.9 → 14.9.10
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/README.md +15 -18
- package/Tone/core/clock/Transport.test.ts +60 -60
- package/Tone/core/clock/Transport.ts +22 -22
- package/Tone/core/clock/TransportEvent.test.ts +4 -4
- package/Tone/core/clock/TransportEvent.ts +2 -2
- package/Tone/core/clock/TransportRepeatEvent.test.ts +4 -4
- package/Tone/core/clock/TransportRepeatEvent.ts +1 -1
- package/Tone/core/context/BaseContext.ts +4 -4
- package/Tone/core/context/Context.test.ts +8 -8
- package/Tone/core/context/Context.ts +4 -4
- package/Tone/core/context/Destination.test.ts +2 -2
- package/Tone/core/context/Destination.ts +4 -4
- package/Tone/core/context/DummyContext.ts +4 -4
- package/Tone/core/context/Listener.test.ts +2 -2
- package/Tone/core/context/Listener.ts +2 -2
- package/Tone/core/context/ToneWithContext.ts +1 -3
- package/Tone/core/util/Draw.test.ts +2 -2
- package/Tone/core/util/Draw.ts +2 -2
- package/Tone/core/util/IntervalTimeline.ts +1 -0
- package/Tone/core/util/StateTimeline.ts +1 -0
- package/Tone/core/util/Timeline.ts +1 -0
- package/Tone/fromContext.ts +8 -8
- package/Tone/index.test.ts +9 -9
- package/Tone/index.ts +21 -13
- package/Tone/signal/SyncedSignal.ts +2 -1
- package/Tone/version.ts +1 -1
- package/build/Tone.js +1 -1
- package/build/Tone.js.map +1 -1
- package/build/esm/core/clock/Transport.d.ts +18 -18
- package/build/esm/core/clock/Transport.js +18 -18
- package/build/esm/core/clock/Transport.js.map +1 -1
- package/build/esm/core/clock/TransportEvent.d.ts +2 -2
- package/build/esm/core/clock/TransportEvent.js +1 -1
- package/build/esm/core/clock/TransportRepeatEvent.d.ts +1 -1
- package/build/esm/core/context/BaseContext.d.ts +4 -4
- package/build/esm/core/context/Context.d.ts +4 -4
- package/build/esm/core/context/Destination.d.ts +1 -1
- package/build/esm/core/context/Destination.js +4 -4
- package/build/esm/core/context/Destination.js.map +1 -1
- package/build/esm/core/context/DummyContext.d.ts +4 -4
- package/build/esm/core/context/Listener.d.ts +1 -1
- package/build/esm/core/context/Listener.js +2 -2
- package/build/esm/core/context/Listener.js.map +1 -1
- package/build/esm/core/context/ToneWithContext.d.ts +1 -3
- package/build/esm/core/context/ToneWithContext.js +1 -3
- package/build/esm/core/context/ToneWithContext.js.map +1 -1
- package/build/esm/core/util/Draw.d.ts +1 -1
- package/build/esm/core/util/Draw.js +2 -2
- package/build/esm/core/util/Draw.js.map +1 -1
- package/build/esm/core/util/IntervalTimeline.d.ts +1 -0
- package/build/esm/core/util/IntervalTimeline.js +1 -0
- package/build/esm/core/util/IntervalTimeline.js.map +1 -1
- package/build/esm/core/util/StateTimeline.d.ts +1 -0
- package/build/esm/core/util/StateTimeline.js +1 -0
- package/build/esm/core/util/StateTimeline.js.map +1 -1
- package/build/esm/core/util/Timeline.d.ts +1 -0
- package/build/esm/core/util/Timeline.js +1 -0
- package/build/esm/core/util/Timeline.js.map +1 -1
- package/build/esm/fromContext.d.ts +8 -8
- package/build/esm/index.d.ts +26 -18
- package/build/esm/index.js +17 -9
- package/build/esm/index.js.map +1 -1
- package/build/esm/signal/SyncedSignal.d.ts +2 -1
- package/build/esm/signal/SyncedSignal.js +2 -1
- package/build/esm/signal/SyncedSignal.js.map +1 -1
- package/build/esm/version.js +1 -1
- package/build/esm/version.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,6 @@ Tone.js is a Web Audio framework for creating interactive music in the browser.
|
|
|
8
8
|
|
|
9
9
|
* [API](https://tonejs.github.io/docs/)
|
|
10
10
|
* [Examples](https://tonejs.github.io/examples/)
|
|
11
|
-
* [Demos](https://tonejs.github.io/demos)
|
|
12
11
|
|
|
13
12
|
# Installation
|
|
14
13
|
|
|
@@ -29,7 +28,6 @@ Tone.js is also hosted at unpkg.com. It can be added directly within an HTML doc
|
|
|
29
28
|
|
|
30
29
|
```html
|
|
31
30
|
<script src="http://unpkg.com/tone"></script>
|
|
32
|
-
<script src="myScript.js"></script>
|
|
33
31
|
```
|
|
34
32
|
|
|
35
33
|
# Hello Tone
|
|
@@ -44,7 +42,7 @@ synth.triggerAttackRelease("C4", "8n");
|
|
|
44
42
|
|
|
45
43
|
#### Tone.Synth
|
|
46
44
|
|
|
47
|
-
|
|
45
|
+
`Tone.Synth` is a basic synthesizer with a single oscillator and an ADSR envelope.
|
|
48
46
|
|
|
49
47
|
#### triggerAttack / triggerRelease
|
|
50
48
|
|
|
@@ -109,9 +107,9 @@ document.querySelector('button')?.addEventListener('click', async () => {
|
|
|
109
107
|
|
|
110
108
|
### Transport
|
|
111
109
|
|
|
112
|
-
|
|
110
|
+
`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.
|
|
113
111
|
|
|
114
|
-
Multiple events and parts can be arranged and synchronized along the Transport.
|
|
112
|
+
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.
|
|
115
113
|
|
|
116
114
|
```javascript
|
|
117
115
|
// create two monophonic synths
|
|
@@ -125,19 +123,19 @@ const loopA = new Tone.Loop(time => {
|
|
|
125
123
|
const loopB = new Tone.Loop(time => {
|
|
126
124
|
synthB.triggerAttackRelease("C4", "8n", time);
|
|
127
125
|
}, "4n").start("8n");
|
|
128
|
-
// all loops start
|
|
129
|
-
Tone.
|
|
126
|
+
// all loops start when the Transport is started
|
|
127
|
+
Tone.getTransport().start()
|
|
130
128
|
```
|
|
131
129
|
|
|
132
130
|
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**.
|
|
133
131
|
|
|
134
132
|
# Instruments
|
|
135
133
|
|
|
136
|
-
There are numerous synths to choose from including
|
|
134
|
+
There are numerous synths to choose from including `Tone.FMSynth`, `Tone.AMSynth` and `Tone.NoiseSynth`.
|
|
137
135
|
|
|
138
136
|
All of these instruments are **monophonic** (single voice) which means that they can only play one note at a time.
|
|
139
137
|
|
|
140
|
-
To create a **polyphonic** synthesizer, use
|
|
138
|
+
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.
|
|
141
139
|
|
|
142
140
|
```javascript
|
|
143
141
|
//pass in some initial values for the filter and filter envelope
|
|
@@ -153,7 +151,7 @@ synth.triggerRelease(["D4", "F4", "A4", "C4", "E4"], now + 4);
|
|
|
153
151
|
|
|
154
152
|
# Samples
|
|
155
153
|
|
|
156
|
-
Sound generation is not limited to synthesized sounds. You can also load a sample and play that back in a number of ways.
|
|
154
|
+
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.
|
|
157
155
|
|
|
158
156
|
```javascript
|
|
159
157
|
const player = new Tone.Player("https://tonejs.github.io/audio/berklee/gong_1.mp3").toDestination();
|
|
@@ -166,7 +164,7 @@ Tone.loaded().then(() => {
|
|
|
166
164
|
|
|
167
165
|
## Sampler
|
|
168
166
|
|
|
169
|
-
Multiple samples can also be combined into an instrument. If you have audio files organized by note,
|
|
167
|
+
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.
|
|
170
168
|
|
|
171
169
|
Unlike the other synths, Tone.Sampler is polyphonic so doesn't need to be passed into Tone.PolySynth
|
|
172
170
|
|
|
@@ -188,7 +186,7 @@ Tone.loaded().then(() => {
|
|
|
188
186
|
|
|
189
187
|
# Effects
|
|
190
188
|
|
|
191
|
-
In the above examples, the sources were always connected directly to the
|
|
189
|
+
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.
|
|
192
190
|
|
|
193
191
|
```javascript
|
|
194
192
|
const player = new Tone.Player({
|
|
@@ -204,15 +202,15 @@ player.connect(distortion);
|
|
|
204
202
|
|
|
205
203
|
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.
|
|
206
204
|
|
|
207
|
-
|
|
205
|
+
`Tone.Gain` is very useful in creating complex routing.
|
|
208
206
|
|
|
209
207
|
# Signals
|
|
210
208
|
|
|
211
209
|
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.
|
|
212
210
|
|
|
213
|
-
|
|
211
|
+
`Signal` properties have a few built in methods for creating automation curves.
|
|
214
212
|
|
|
215
|
-
For example, the `frequency` parameter on
|
|
213
|
+
For example, the `frequency` parameter on `Oscillator` is a Signal so you can create a smooth ramp from one frequency to another.
|
|
216
214
|
|
|
217
215
|
```javascript
|
|
218
216
|
const osc = new Tone.Oscillator().toDestination();
|
|
@@ -224,7 +222,7 @@ osc.frequency.rampTo("C5", 2)
|
|
|
224
222
|
|
|
225
223
|
# AudioContext
|
|
226
224
|
|
|
227
|
-
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.
|
|
225
|
+
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)`.
|
|
228
226
|
|
|
229
227
|
# MIDI
|
|
230
228
|
|
|
@@ -238,7 +236,7 @@ Tone.js makes extensive use of the native Web Audio Nodes such as the GainNode a
|
|
|
238
236
|
|
|
239
237
|
# Testing
|
|
240
238
|
|
|
241
|
-
Tone.js runs an extensive test suite using [mocha](https://mochajs.org/) and [chai](http://chaijs.com/) with nearly 100% coverage.
|
|
239
|
+
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`.
|
|
242
240
|
|
|
243
241
|
# Contributing
|
|
244
242
|
|
|
@@ -248,7 +246,6 @@ If you have questions (or answers) that are not necessarily bugs/issues, please
|
|
|
248
246
|
|
|
249
247
|
# References and Inspiration
|
|
250
248
|
|
|
251
|
-
* [Tuna.js](https://github.com/Dinahmoe/tuna)
|
|
252
249
|
* [Many of Chris Wilson's Repositories](https://github.com/cwilso)
|
|
253
250
|
* [Many of Mohayonao's Repositories](https://github.com/mohayonao)
|
|
254
251
|
* [The Spec](http://webaudio.github.io/web-audio-api/)
|
|
@@ -4,7 +4,7 @@ import { Time } from "Tone/core/type/Time";
|
|
|
4
4
|
import { noOp } from "Tone/core/util/Interface";
|
|
5
5
|
import { Signal } from "../../signal/Signal";
|
|
6
6
|
import { TransportTime } from "../type/TransportTime";
|
|
7
|
-
import {
|
|
7
|
+
import { TransportClass } from "./Transport";
|
|
8
8
|
// importing for side affects
|
|
9
9
|
import "../context/Destination";
|
|
10
10
|
import { warns } from "test/helper/Basic";
|
|
@@ -16,7 +16,7 @@ describe("Transport", () => {
|
|
|
16
16
|
|
|
17
17
|
it("can get and set bpm", () => {
|
|
18
18
|
return Offline((context) => {
|
|
19
|
-
const transport = new
|
|
19
|
+
const transport = new TransportClass({ context });
|
|
20
20
|
transport.bpm.value = 125;
|
|
21
21
|
expect(transport.bpm.value).to.be.closeTo(125, 0.001);
|
|
22
22
|
transport.bpm.value = 120;
|
|
@@ -26,7 +26,7 @@ describe("Transport", () => {
|
|
|
26
26
|
|
|
27
27
|
it("can get and set timeSignature as both an array or number", () => {
|
|
28
28
|
return Offline((context) => {
|
|
29
|
-
const transport = new
|
|
29
|
+
const transport = new TransportClass({ context });
|
|
30
30
|
transport.timeSignature = [6, 8];
|
|
31
31
|
expect(transport.timeSignature).to.equal(3);
|
|
32
32
|
transport.timeSignature = 5;
|
|
@@ -36,7 +36,7 @@ describe("Transport", () => {
|
|
|
36
36
|
|
|
37
37
|
it("can get and set timeSignature as both an array or number", () => {
|
|
38
38
|
return Offline((context) => {
|
|
39
|
-
const transport = new
|
|
39
|
+
const transport = new TransportClass({ context });
|
|
40
40
|
transport.timeSignature = [6, 8];
|
|
41
41
|
expect(transport.timeSignature).to.equal(3);
|
|
42
42
|
transport.timeSignature = 5;
|
|
@@ -50,7 +50,7 @@ describe("Transport", () => {
|
|
|
50
50
|
|
|
51
51
|
it("can get and set loop points", () => {
|
|
52
52
|
return Offline((context) => {
|
|
53
|
-
const transport = new
|
|
53
|
+
const transport = new TransportClass({ context });
|
|
54
54
|
transport.loopStart = 0.2;
|
|
55
55
|
transport.loopEnd = 0.4;
|
|
56
56
|
expect(transport.loopStart).to.be.closeTo(0.2, 0.01);
|
|
@@ -64,7 +64,7 @@ describe("Transport", () => {
|
|
|
64
64
|
it("can loop events scheduled on the transport", () => {
|
|
65
65
|
let invocations = 0;
|
|
66
66
|
return Offline((context) => {
|
|
67
|
-
const transport = new
|
|
67
|
+
const transport = new TransportClass({ context });
|
|
68
68
|
transport.schedule((time) => {
|
|
69
69
|
invocations++;
|
|
70
70
|
}, 0);
|
|
@@ -78,7 +78,7 @@ describe("Transport", () => {
|
|
|
78
78
|
it("jumps to the loopStart after the loopEnd point", () => {
|
|
79
79
|
let looped = false;
|
|
80
80
|
return Offline((context) => {
|
|
81
|
-
const transport = new
|
|
81
|
+
const transport = new TransportClass({ context });
|
|
82
82
|
transport.on("loop", () => {
|
|
83
83
|
looped = true;
|
|
84
84
|
});
|
|
@@ -97,14 +97,14 @@ describe("Transport", () => {
|
|
|
97
97
|
|
|
98
98
|
it("returns 0 if the transports not started", () => {
|
|
99
99
|
return Offline(context => {
|
|
100
|
-
const transport = new
|
|
100
|
+
const transport = new TransportClass({ context });
|
|
101
101
|
expect(transport.nextSubdivision()).to.equal(0);
|
|
102
102
|
});
|
|
103
103
|
});
|
|
104
104
|
|
|
105
105
|
it("can get the next subdivision of the transport", () => {
|
|
106
106
|
return Offline(context => {
|
|
107
|
-
const transport = new
|
|
107
|
+
const transport = new TransportClass({ context });
|
|
108
108
|
transport.start(0);
|
|
109
109
|
return time => {
|
|
110
110
|
whenBetween(time, 0.05, 0.07, () => {
|
|
@@ -126,7 +126,7 @@ describe("Transport", () => {
|
|
|
126
126
|
|
|
127
127
|
it("can get and set pulses per quarter", () => {
|
|
128
128
|
return Offline(context => {
|
|
129
|
-
const transport = new
|
|
129
|
+
const transport = new TransportClass({ context });
|
|
130
130
|
transport.PPQ = 96;
|
|
131
131
|
expect(transport.PPQ).to.equal(96);
|
|
132
132
|
});
|
|
@@ -134,7 +134,7 @@ describe("Transport", () => {
|
|
|
134
134
|
|
|
135
135
|
it("schedules a quarter note at the same time with a different PPQ", () => {
|
|
136
136
|
return Offline(context => {
|
|
137
|
-
const transport = new
|
|
137
|
+
const transport = new TransportClass({ context });
|
|
138
138
|
transport.PPQ = 1;
|
|
139
139
|
const id = transport.schedule(time => {
|
|
140
140
|
expect(time).to.be.closeTo(transport.toSeconds("4n"), 0.1);
|
|
@@ -146,7 +146,7 @@ describe("Transport", () => {
|
|
|
146
146
|
|
|
147
147
|
it("invokes the right number of ticks with a different PPQ", () => {
|
|
148
148
|
return Offline(context => {
|
|
149
|
-
const transport = new
|
|
149
|
+
const transport = new TransportClass({ context });
|
|
150
150
|
transport.bpm.value = 120;
|
|
151
151
|
const ppq = 20;
|
|
152
152
|
transport.PPQ = ppq;
|
|
@@ -166,7 +166,7 @@ describe("Transport", () => {
|
|
|
166
166
|
|
|
167
167
|
it("can jump to a specific tick number", () => {
|
|
168
168
|
return Offline(context => {
|
|
169
|
-
const transport = new
|
|
169
|
+
const transport = new TransportClass({ context });
|
|
170
170
|
transport.ticks = 200;
|
|
171
171
|
expect(transport.ticks).to.equal(200);
|
|
172
172
|
transport.start(0);
|
|
@@ -182,7 +182,7 @@ describe("Transport", () => {
|
|
|
182
182
|
|
|
183
183
|
it("can get the current position in BarsBeatsSixteenths", () => {
|
|
184
184
|
return Offline(context => {
|
|
185
|
-
const transport = new
|
|
185
|
+
const transport = new TransportClass({ context });
|
|
186
186
|
expect(transport.position).to.equal("0:0:0");
|
|
187
187
|
transport.start(0);
|
|
188
188
|
return atTime(0.05, () => {
|
|
@@ -193,7 +193,7 @@ describe("Transport", () => {
|
|
|
193
193
|
|
|
194
194
|
it("can get the current position in seconds", () => {
|
|
195
195
|
return Offline(context => {
|
|
196
|
-
const transport = new
|
|
196
|
+
const transport = new TransportClass({ context });
|
|
197
197
|
expect(transport.seconds).to.equal(0);
|
|
198
198
|
transport.start(0.05);
|
|
199
199
|
return time => {
|
|
@@ -206,7 +206,7 @@ describe("Transport", () => {
|
|
|
206
206
|
|
|
207
207
|
it("can get the current position in seconds during a bpm ramp", () => {
|
|
208
208
|
return Offline(context => {
|
|
209
|
-
const transport = new
|
|
209
|
+
const transport = new TransportClass({ context });
|
|
210
210
|
expect(transport.seconds).to.equal(0);
|
|
211
211
|
transport.start(0.05);
|
|
212
212
|
transport.bpm.linearRampTo(60, 0.5, 0.5);
|
|
@@ -220,7 +220,7 @@ describe("Transport", () => {
|
|
|
220
220
|
|
|
221
221
|
it("can set the current position in seconds", () => {
|
|
222
222
|
return Offline(context => {
|
|
223
|
-
const transport = new
|
|
223
|
+
const transport = new TransportClass({ context });
|
|
224
224
|
expect(transport.seconds).to.equal(0);
|
|
225
225
|
transport.seconds = 3;
|
|
226
226
|
expect(transport.seconds).to.be.closeTo(3, 0.01);
|
|
@@ -229,7 +229,7 @@ describe("Transport", () => {
|
|
|
229
229
|
|
|
230
230
|
it("can set the current position in BarsBeatsSixteenths", () => {
|
|
231
231
|
return Offline(context => {
|
|
232
|
-
const transport = new
|
|
232
|
+
const transport = new TransportClass({ context });
|
|
233
233
|
expect(transport.position).to.equal("0:0:0");
|
|
234
234
|
transport.position = "3:0";
|
|
235
235
|
expect(transport.position).to.equal("3:0:0");
|
|
@@ -240,7 +240,7 @@ describe("Transport", () => {
|
|
|
240
240
|
|
|
241
241
|
it("can get the progress of the loop", () => {
|
|
242
242
|
return Offline(context => {
|
|
243
|
-
const transport = new
|
|
243
|
+
const transport = new TransportClass({ context });
|
|
244
244
|
transport.setLoopPoints(0, "1m").start();
|
|
245
245
|
transport.loop = true;
|
|
246
246
|
expect(transport.progress).to.be.equal(0);
|
|
@@ -316,7 +316,7 @@ describe("Transport", () => {
|
|
|
316
316
|
|
|
317
317
|
it("resets ticks on stop but not on pause", () => {
|
|
318
318
|
return Offline(context => {
|
|
319
|
-
const transport = new
|
|
319
|
+
const transport = new TransportClass({ context });
|
|
320
320
|
transport.start(0).pause(0.1).stop(0.2);
|
|
321
321
|
expect(transport.getTicksAtTime(0)).to.be.equal(Math.floor(transport.PPQ * 0));
|
|
322
322
|
expect(transport.getTicksAtTime(0.05)).to.be.equal(Math.floor(transport.PPQ * 0.1));
|
|
@@ -329,7 +329,7 @@ describe("Transport", () => {
|
|
|
329
329
|
it("tracks ticks after start", () => {
|
|
330
330
|
|
|
331
331
|
return Offline(context => {
|
|
332
|
-
const transport = new
|
|
332
|
+
const transport = new TransportClass({ context });
|
|
333
333
|
transport.bpm.value = 120;
|
|
334
334
|
const ppq = transport.PPQ;
|
|
335
335
|
transport.start();
|
|
@@ -344,7 +344,7 @@ describe("Transport", () => {
|
|
|
344
344
|
|
|
345
345
|
it("can start with a tick offset", () => {
|
|
346
346
|
return Offline(context => {
|
|
347
|
-
const transport = new
|
|
347
|
+
const transport = new TransportClass({ context });
|
|
348
348
|
transport.start(0, "200i");
|
|
349
349
|
|
|
350
350
|
return time => {
|
|
@@ -357,7 +357,7 @@ describe("Transport", () => {
|
|
|
357
357
|
|
|
358
358
|
it("can toggle the state of the transport", () => {
|
|
359
359
|
return Offline(context => {
|
|
360
|
-
const transport = new
|
|
360
|
+
const transport = new TransportClass({ context });
|
|
361
361
|
transport.toggle(0);
|
|
362
362
|
transport.toggle(0.2);
|
|
363
363
|
|
|
@@ -376,7 +376,7 @@ describe("Transport", () => {
|
|
|
376
376
|
it("tracks ticks correctly with a different PPQ and BPM", () => {
|
|
377
377
|
|
|
378
378
|
return Offline(context => {
|
|
379
|
-
const transport = new
|
|
379
|
+
const transport = new TransportClass({ context });
|
|
380
380
|
transport.PPQ = 96;
|
|
381
381
|
transport.bpm.value = 90;
|
|
382
382
|
transport.start();
|
|
@@ -413,7 +413,7 @@ describe("Transport", () => {
|
|
|
413
413
|
|
|
414
414
|
it("can schedule an event on the timeline", () => {
|
|
415
415
|
return Offline(context => {
|
|
416
|
-
const transport = new
|
|
416
|
+
const transport = new TransportClass({ context });
|
|
417
417
|
const eventID = transport.schedule(() => { }, 0);
|
|
418
418
|
expect(eventID).to.be.a("number");
|
|
419
419
|
});
|
|
@@ -422,7 +422,7 @@ describe("Transport", () => {
|
|
|
422
422
|
it("scheduled event gets invoked with the time of the event", () => {
|
|
423
423
|
let wasCalled = false;
|
|
424
424
|
return Offline(context => {
|
|
425
|
-
const transport = new
|
|
425
|
+
const transport = new TransportClass({ context });
|
|
426
426
|
const startTime = 0.1;
|
|
427
427
|
transport.schedule(time => {
|
|
428
428
|
expect(time).to.be.closeTo(startTime, 0.01);
|
|
@@ -437,7 +437,7 @@ describe("Transport", () => {
|
|
|
437
437
|
it("can schedule events with TransportTime", () => {
|
|
438
438
|
let wasCalled = false;
|
|
439
439
|
return Offline(context => {
|
|
440
|
-
const transport = new
|
|
440
|
+
const transport = new TransportClass({ context });
|
|
441
441
|
const startTime = 0.1;
|
|
442
442
|
const eighth = transport.toSeconds("8n");
|
|
443
443
|
transport.schedule(time => {
|
|
@@ -452,7 +452,7 @@ describe("Transport", () => {
|
|
|
452
452
|
|
|
453
453
|
it("can clear a scheduled event", () => {
|
|
454
454
|
return Offline(context => {
|
|
455
|
-
const transport = new
|
|
455
|
+
const transport = new TransportClass({ context });
|
|
456
456
|
const eventID = transport.schedule(() => {
|
|
457
457
|
throw new Error("should not call this function");
|
|
458
458
|
}, 0);
|
|
@@ -463,7 +463,7 @@ describe("Transport", () => {
|
|
|
463
463
|
|
|
464
464
|
it("can cancel the timeline of scheduled object", () => {
|
|
465
465
|
return Offline(context => {
|
|
466
|
-
const transport = new
|
|
466
|
+
const transport = new TransportClass({ context });
|
|
467
467
|
transport.schedule(() => {
|
|
468
468
|
throw new Error("should not call this");
|
|
469
469
|
}, 0);
|
|
@@ -474,7 +474,7 @@ describe("Transport", () => {
|
|
|
474
474
|
|
|
475
475
|
it("can cancel the timeline of scheduleOnce object", () => {
|
|
476
476
|
return Offline(context => {
|
|
477
|
-
const transport = new
|
|
477
|
+
const transport = new TransportClass({ context });
|
|
478
478
|
transport.scheduleOnce(() => {
|
|
479
479
|
throw new Error("should not call this");
|
|
480
480
|
}, 0);
|
|
@@ -486,7 +486,7 @@ describe("Transport", () => {
|
|
|
486
486
|
it("scheduled event anywhere along the timeline", () => {
|
|
487
487
|
let wasCalled = false;
|
|
488
488
|
return Offline(context => {
|
|
489
|
-
const transport = new
|
|
489
|
+
const transport = new TransportClass({ context });
|
|
490
490
|
const startTime = transport.now();
|
|
491
491
|
transport.schedule(time => {
|
|
492
492
|
expect(time).to.be.closeTo(startTime + 0.5, 0.001);
|
|
@@ -501,7 +501,7 @@ describe("Transport", () => {
|
|
|
501
501
|
it("can schedule multiple events and invoke them in the right order", () => {
|
|
502
502
|
let wasCalled = false;
|
|
503
503
|
return Offline(context => {
|
|
504
|
-
const transport = new
|
|
504
|
+
const transport = new TransportClass({ context });
|
|
505
505
|
let first = false;
|
|
506
506
|
transport.schedule(() => {
|
|
507
507
|
first = true;
|
|
@@ -519,7 +519,7 @@ describe("Transport", () => {
|
|
|
519
519
|
it("invokes the event again if the timeline is restarted", () => {
|
|
520
520
|
let iterations = 0;
|
|
521
521
|
return Offline(context => {
|
|
522
|
-
const transport = new
|
|
522
|
+
const transport = new TransportClass({ context });
|
|
523
523
|
transport.schedule(() => {
|
|
524
524
|
iterations++;
|
|
525
525
|
}, 0.05);
|
|
@@ -532,7 +532,7 @@ describe("Transport", () => {
|
|
|
532
532
|
it("can add an event after the Transport is started", () => {
|
|
533
533
|
let wasCalled = false;
|
|
534
534
|
return Offline(context => {
|
|
535
|
-
const transport = new
|
|
535
|
+
const transport = new TransportClass({ context });
|
|
536
536
|
transport.start(0);
|
|
537
537
|
let wasScheduled = false;
|
|
538
538
|
return time => {
|
|
@@ -567,7 +567,7 @@ describe("Transport", () => {
|
|
|
567
567
|
|
|
568
568
|
it("can schedule a repeated event", () => {
|
|
569
569
|
return Offline(context => {
|
|
570
|
-
const transport = new
|
|
570
|
+
const transport = new TransportClass({ context });
|
|
571
571
|
const eventID = transport.scheduleRepeat(noOp, 1);
|
|
572
572
|
expect(eventID).to.be.a("number");
|
|
573
573
|
});
|
|
@@ -576,7 +576,7 @@ describe("Transport", () => {
|
|
|
576
576
|
it("scheduled event gets invoked with the time of the event", () => {
|
|
577
577
|
let invoked = false;
|
|
578
578
|
return Offline(context => {
|
|
579
|
-
const transport = new
|
|
579
|
+
const transport = new TransportClass({ context });
|
|
580
580
|
const startTime = 0.1;
|
|
581
581
|
const eventID = transport.scheduleRepeat(time => {
|
|
582
582
|
expect(time).to.be.closeTo(startTime, 0.01);
|
|
@@ -591,7 +591,7 @@ describe("Transport", () => {
|
|
|
591
591
|
|
|
592
592
|
it("can cancel the timeline of scheduleRepeat", () => {
|
|
593
593
|
return Offline(context => {
|
|
594
|
-
const transport = new
|
|
594
|
+
const transport = new TransportClass({ context });
|
|
595
595
|
transport.scheduleRepeat(() => {
|
|
596
596
|
throw new Error("should not call this");
|
|
597
597
|
}, 0.01, 0);
|
|
@@ -603,7 +603,7 @@ describe("Transport", () => {
|
|
|
603
603
|
it("can schedule events with TransportTime", () => {
|
|
604
604
|
let invoked = false;
|
|
605
605
|
return Offline(context => {
|
|
606
|
-
const transport = new
|
|
606
|
+
const transport = new TransportClass({ context });
|
|
607
607
|
const startTime = 0.1;
|
|
608
608
|
const eighth = transport.toSeconds("8n");
|
|
609
609
|
transport.scheduleRepeat(time => {
|
|
@@ -618,7 +618,7 @@ describe("Transport", () => {
|
|
|
618
618
|
|
|
619
619
|
it("can clear a scheduled event", () => {
|
|
620
620
|
return Offline(context => {
|
|
621
|
-
const transport = new
|
|
621
|
+
const transport = new TransportClass({ context });
|
|
622
622
|
const eventID = transport.scheduleRepeat(() => {
|
|
623
623
|
throw new Error("should not call this function");
|
|
624
624
|
}, 1, 0);
|
|
@@ -630,7 +630,7 @@ describe("Transport", () => {
|
|
|
630
630
|
it("can be scheduled in the future", () => {
|
|
631
631
|
let invoked = false;
|
|
632
632
|
return Offline(context => {
|
|
633
|
-
const transport = new
|
|
633
|
+
const transport = new TransportClass({ context });
|
|
634
634
|
const startTime = 0.1;
|
|
635
635
|
const eventID = transport.scheduleRepeat(time => {
|
|
636
636
|
transport.clear(eventID);
|
|
@@ -646,7 +646,7 @@ describe("Transport", () => {
|
|
|
646
646
|
it("repeats a repeat event", () => {
|
|
647
647
|
let invocations = 0;
|
|
648
648
|
return Offline(context => {
|
|
649
|
-
const transport = new
|
|
649
|
+
const transport = new TransportClass({ context });
|
|
650
650
|
transport.scheduleRepeat(() => {
|
|
651
651
|
invocations++;
|
|
652
652
|
}, 0.1, 0);
|
|
@@ -659,7 +659,7 @@ describe("Transport", () => {
|
|
|
659
659
|
it("repeats at the repeat interval", () => {
|
|
660
660
|
let wasCalled = false;
|
|
661
661
|
return Offline(context => {
|
|
662
|
-
const transport = new
|
|
662
|
+
const transport = new TransportClass({ context });
|
|
663
663
|
let repeatTime = -1;
|
|
664
664
|
transport.scheduleRepeat(time => {
|
|
665
665
|
if (repeatTime !== -1) {
|
|
@@ -678,7 +678,7 @@ describe("Transport", () => {
|
|
|
678
678
|
let first = false;
|
|
679
679
|
let second = false;
|
|
680
680
|
return Offline(context => {
|
|
681
|
-
const transport = new
|
|
681
|
+
const transport = new TransportClass({ context });
|
|
682
682
|
const firstID = transport.scheduleRepeat(() => {
|
|
683
683
|
first = true;
|
|
684
684
|
transport.clear(firstID);
|
|
@@ -698,7 +698,7 @@ describe("Transport", () => {
|
|
|
698
698
|
it("repeats for the given interval", () => {
|
|
699
699
|
let repeatCount = 0;
|
|
700
700
|
return Offline(context => {
|
|
701
|
-
const transport = new
|
|
701
|
+
const transport = new TransportClass({ context });
|
|
702
702
|
transport.scheduleRepeat(time => {
|
|
703
703
|
repeatCount++;
|
|
704
704
|
}, 0.1, 0, 0.5);
|
|
@@ -711,7 +711,7 @@ describe("Transport", () => {
|
|
|
711
711
|
it("can add an event after the Transport is started", () => {
|
|
712
712
|
let invocations = 0;
|
|
713
713
|
return Offline(context => {
|
|
714
|
-
const transport = new
|
|
714
|
+
const transport = new TransportClass({ context });
|
|
715
715
|
transport.start(0);
|
|
716
716
|
let wasScheduled = false;
|
|
717
717
|
const times = [0.15, 0.3];
|
|
@@ -732,7 +732,7 @@ describe("Transport", () => {
|
|
|
732
732
|
it("can add an event to the past after the Transport is started", () => {
|
|
733
733
|
let invocations = 0;
|
|
734
734
|
return Offline(context => {
|
|
735
|
-
const transport = new
|
|
735
|
+
const transport = new TransportClass({ context });
|
|
736
736
|
transport.start(0);
|
|
737
737
|
let wasScheduled = false;
|
|
738
738
|
const times = [0.15, 0.25];
|
|
@@ -756,7 +756,7 @@ describe("Transport", () => {
|
|
|
756
756
|
|
|
757
757
|
it("can schedule a single event on the timeline", () => {
|
|
758
758
|
return Offline(context => {
|
|
759
|
-
const transport = new
|
|
759
|
+
const transport = new TransportClass({ context });
|
|
760
760
|
const eventID = transport.scheduleOnce(() => {}, 0);
|
|
761
761
|
expect(eventID).to.be.a("number");
|
|
762
762
|
});
|
|
@@ -765,7 +765,7 @@ describe("Transport", () => {
|
|
|
765
765
|
it("scheduled event gets invoked with the time of the event", () => {
|
|
766
766
|
let invoked = false;
|
|
767
767
|
return Offline(context => {
|
|
768
|
-
const transport = new
|
|
768
|
+
const transport = new TransportClass({ context });
|
|
769
769
|
const startTime = 0.1;
|
|
770
770
|
const eventID = transport.scheduleOnce(time => {
|
|
771
771
|
invoked = true;
|
|
@@ -781,7 +781,7 @@ describe("Transport", () => {
|
|
|
781
781
|
it("can schedule events with TransportTime", () => {
|
|
782
782
|
let invoked = false;
|
|
783
783
|
return Offline(context => {
|
|
784
|
-
const transport = new
|
|
784
|
+
const transport = new TransportClass({ context });
|
|
785
785
|
const startTime = 0.1;
|
|
786
786
|
const eighth = transport.toSeconds("8n");
|
|
787
787
|
transport.scheduleOnce(time => {
|
|
@@ -796,7 +796,7 @@ describe("Transport", () => {
|
|
|
796
796
|
|
|
797
797
|
it("can clear a scheduled event", () => {
|
|
798
798
|
return Offline(context => {
|
|
799
|
-
const transport = new
|
|
799
|
+
const transport = new TransportClass({ context });
|
|
800
800
|
const eventID = transport.scheduleOnce(() => {
|
|
801
801
|
throw new Error("should not call this function");
|
|
802
802
|
}, 0);
|
|
@@ -808,7 +808,7 @@ describe("Transport", () => {
|
|
|
808
808
|
it("can be scheduled in the future", () => {
|
|
809
809
|
let invoked = false;
|
|
810
810
|
return Offline(context => {
|
|
811
|
-
const transport = new
|
|
811
|
+
const transport = new TransportClass({ context });
|
|
812
812
|
const startTime = transport.now() + 0.1;
|
|
813
813
|
const eventID = transport.scheduleOnce(time => {
|
|
814
814
|
transport.clear(eventID);
|
|
@@ -824,7 +824,7 @@ describe("Transport", () => {
|
|
|
824
824
|
it("the event is removed after is is invoked", () => {
|
|
825
825
|
let iterations = 0;
|
|
826
826
|
return Offline(context => {
|
|
827
|
-
const transport = new
|
|
827
|
+
const transport = new TransportClass({ context });
|
|
828
828
|
transport.scheduleOnce(() => {
|
|
829
829
|
iterations++;
|
|
830
830
|
}, 0);
|
|
@@ -841,7 +841,7 @@ describe("Transport", () => {
|
|
|
841
841
|
it("invokes start/stop/pause events", () => {
|
|
842
842
|
let invocations = 0;
|
|
843
843
|
return Offline(context => {
|
|
844
|
-
const transport = new
|
|
844
|
+
const transport = new TransportClass({ context });
|
|
845
845
|
transport.on("start", () => {
|
|
846
846
|
invocations++;
|
|
847
847
|
});
|
|
@@ -860,7 +860,7 @@ describe("Transport", () => {
|
|
|
860
860
|
it("invokes start event with correct offset", () => {
|
|
861
861
|
let wasCalled = false;
|
|
862
862
|
return Offline(context => {
|
|
863
|
-
const transport = new
|
|
863
|
+
const transport = new TransportClass({ context });
|
|
864
864
|
transport.on("start", (time, offset) => {
|
|
865
865
|
expect(time).to.be.closeTo(0.2, 0.01);
|
|
866
866
|
expect(offset).to.be.closeTo(0.5, 0.001);
|
|
@@ -875,7 +875,7 @@ describe("Transport", () => {
|
|
|
875
875
|
it("invokes the event just before the scheduled time", () => {
|
|
876
876
|
let invoked = false;
|
|
877
877
|
return Offline(context => {
|
|
878
|
-
const transport = new
|
|
878
|
+
const transport = new TransportClass({ context });
|
|
879
879
|
transport.on("start", (time, offset) => {
|
|
880
880
|
expect(time - transport.context.currentTime).to.be.closeTo(0, 0.01);
|
|
881
881
|
expect(offset).to.equal(0);
|
|
@@ -890,7 +890,7 @@ describe("Transport", () => {
|
|
|
890
890
|
it("passes in the time argument to the events", () => {
|
|
891
891
|
let invocations = 0;
|
|
892
892
|
return Offline(context => {
|
|
893
|
-
const transport = new
|
|
893
|
+
const transport = new TransportClass({ context });
|
|
894
894
|
const now = transport.now();
|
|
895
895
|
transport.on("start", time => {
|
|
896
896
|
invocations++;
|
|
@@ -909,7 +909,7 @@ describe("Transport", () => {
|
|
|
909
909
|
it("invokes the 'loop' method on loop", () => {
|
|
910
910
|
let loops = 0;
|
|
911
911
|
return Offline(context => {
|
|
912
|
-
const transport = new
|
|
912
|
+
const transport = new TransportClass({ context });
|
|
913
913
|
const sixteenth = transport.toSeconds("16n");
|
|
914
914
|
transport.setLoopPoints(0, sixteenth);
|
|
915
915
|
transport.loop = true;
|
|
@@ -932,7 +932,7 @@ describe("Transport", () => {
|
|
|
932
932
|
|
|
933
933
|
it("can get/set the swing subdivision", () => {
|
|
934
934
|
return Offline(context => {
|
|
935
|
-
const transport = new
|
|
935
|
+
const transport = new TransportClass({ context });
|
|
936
936
|
transport.swingSubdivision = "8n";
|
|
937
937
|
expect(transport.swingSubdivision).to.equal("8n");
|
|
938
938
|
transport.swingSubdivision = "4n";
|
|
@@ -942,7 +942,7 @@ describe("Transport", () => {
|
|
|
942
942
|
|
|
943
943
|
it("can get/set the swing amount", () => {
|
|
944
944
|
return Offline(context => {
|
|
945
|
-
const transport = new
|
|
945
|
+
const transport = new TransportClass({ context });
|
|
946
946
|
transport.swing = 0.5;
|
|
947
947
|
expect(transport.swing).to.equal(0.5);
|
|
948
948
|
transport.swing = 0;
|
|
@@ -953,7 +953,7 @@ describe("Transport", () => {
|
|
|
953
953
|
it("can swing", () => {
|
|
954
954
|
let invocations = 0;
|
|
955
955
|
return Offline(context => {
|
|
956
|
-
const transport = new
|
|
956
|
+
const transport = new TransportClass({ context });
|
|
957
957
|
transport.swing = 1;
|
|
958
958
|
transport.swingSubdivision = "8n";
|
|
959
959
|
const eightNote = transport.toSeconds("8n");
|