orchestre-js 2.1.1 → 3.1.0
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 +127 -65
- package/dist/Orchestre.js +1 -1
- package/dist/esm/metronome.d.ts +14 -1
- package/dist/esm/metronome.js +23 -2
- package/dist/esm/orchestre.d.ts +10 -6
- package/dist/esm/orchestre.js +20 -14
- package/dist/esm/player.d.ts +4 -2
- package/dist/esm/sound-loop.d.ts +1 -1
- package/dist/esm/sound-loop.js +1 -2
- package/doc/absolute-diagram.png +0 -0
- package/doc/api.md +82 -18
- package/package.json +1 -1
- package/src/metronome.ts +25 -1
- package/src/orchestre.ts +56 -21
- package/src/player.ts +6 -3
- package/src/sound-loop.ts +36 -9
package/README.md
CHANGED
|
@@ -2,15 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|

|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
_Orchestre-JS_ is a web audio tool to create adaptive and interactive music.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- 🎶 **Vertical Layering:** Manage songs with several instruments and toggle them on and off
|
|
8
|
+
- 🎼 **Seamless Loops:** Play tracks in loop while keeping them in rhythm and preserving their decay
|
|
9
|
+
- 🥁 **Sync to the Beat:** Subscribe to events and trigger actions on the rhythm
|
|
10
|
+
- 🌊 **Syncopation:** Layer loops of different duration to create rich patterns
|
|
11
|
+
- ⏳️ **Scheduling:** Prepare the start and stop of instruments to make change just when you need to
|
|
12
|
+
- 💻️ **Developer Friendly:** Everything is done through code, no extra tool to learn
|
|
13
|
+
- ☁️ **Zero Dependency:** Works with all modern browsers
|
|
14
|
+
- 🌐 **Web Audio API Compatible:** Plug your music to any effects
|
|
8
15
|
|
|
9
|
-
Orchestre-JS is
|
|
16
|
+
Orchestre-JS is the perfect solution for **managing music in your web game or application**. Its modularity gives you the basic tools to play your music and design all kind of dynamic system around it. Its goal is to be easy to use, while powerful enough to support complex compositions.
|
|
10
17
|
|
|
11
|
-
|
|
18
|
+
[See the demo](https://clementrivaille.github.io/orchestre-js/) to learn all of its features.
|
|
19
|
+
|
|
20
|
+
You can also see it in action here:
|
|
21
|
+
|
|
22
|
+
- [Starseed Harmonies](https://starseed-harmonies.clementrivaille.fr): A musical garden made with Svelte
|
|
23
|
+
- [Echoes Traveler](https://itooh.itch.io/echoes-traveler): Music exploration game made with Phaser
|
|
24
|
+
- [Blood Not Allowed](https://itooh.itch.io/blood-not-allowed): A musical story created with Twine
|
|
12
25
|
|
|
13
|
-
If you want to see the library in action, you can check out those games: [Echoes Traveler](https://itooh.itch.io/echoes-traveler), [Blood Not Allowed](https://itooh.itch.io/blood-not-allowed) (made with Twine), and [Step Out](https://itooh.itch.io/step-out).
|
|
14
26
|
If you use Orchestre-JS in your creations, I would be really glad to see them! Feel free to show them to me.
|
|
15
27
|
|
|
16
28
|
## Install
|
|
@@ -29,15 +41,13 @@ Download the [latest release](https://github.com/ClementRivaille/orchestre-js/re
|
|
|
29
41
|
|
|
30
42
|
```javascript
|
|
31
43
|
import { Orchestre } from 'orchestre-js';
|
|
32
|
-
// or
|
|
33
|
-
const { Orchestre } = require('orchestre-js');
|
|
34
44
|
```
|
|
35
45
|
|
|
36
|
-
##
|
|
46
|
+
## Basic Usage
|
|
37
47
|
|
|
38
48
|
### Create an orchestra
|
|
39
49
|
|
|
40
|
-
The first thing you need is to create an _“
|
|
50
|
+
The first thing you need is to create an _“Orchestre”_ (French for orchestra, as you've probably already figured). The only thing it needs is the song's BPM (beats per minute).
|
|
41
51
|
|
|
42
52
|
```javascript
|
|
43
53
|
const orchestra = new Orchestre(120);
|
|
@@ -45,29 +55,23 @@ const orchestra = new Orchestre(120);
|
|
|
45
55
|
|
|
46
56
|
### Add players
|
|
47
57
|
|
|
48
|
-
Then, you will need to
|
|
58
|
+
Then, you will need to register your song's separate tracks. In Orchestre-JS, those are called _Players_. Each player needs:
|
|
49
59
|
|
|
50
60
|
- A unique **name** that will identify it
|
|
51
61
|
- The **URL** of the sound file it will play
|
|
52
62
|
- The **length** in beats of the track
|
|
53
|
-
- An optional **absolute** boolean if you want the track to be played on bars
|
|
54
63
|
|
|
55
64
|
_Be aware that you need a local server to request files_.
|
|
56
65
|
|
|
57
|
-
For example, in a 4/4 signature, a track of one bar would have a length of 4, two bars would
|
|
58
|
-
|
|
59
|
-
What does the **absolute** option means? By default, a player is relative, which means that it will play from its track beginning when it starts, no matter where we are in the song. Absolute players, on the other hand, will calculate their offset relatively from the start of the song. Which mean that every absolute players will always play together. This is useful for players that set the chords or main melodies, generally playing several bars.
|
|
60
|
-
|
|
61
|
-
Here is a diagram to better understand what absolute means. Each player here has a length of 4 beats, and are activated at the same time. See how the relative one starts right on the first beat, while the absolute one starts from the second beat.
|
|
62
|
-

|
|
66
|
+
The _length_ is the number of fourth notes in the track. For example, in a 4/4 signature, a track of one bar would have a length of 4, one of two bars would have 8, etc… You can also use a track of one bar and three beats (which gives a total of 7) and make it phases as it loops!
|
|
63
67
|
|
|
64
68
|
To add a single player, use:
|
|
65
69
|
|
|
66
70
|
```javascript
|
|
67
|
-
await orchestra.addPlayer('bass', './assets/music/bass.ogg', 16
|
|
71
|
+
await orchestra.addPlayer('bass', './assets/music/bass.ogg', 16);
|
|
68
72
|
```
|
|
69
73
|
|
|
70
|
-
`addPlayer` returns a promise that resolves once the sound file has been fetched. A player can't be used until
|
|
74
|
+
`addPlayer` returns a promise that resolves once the sound file has been fetched. A player can't be used until it is fully loaded.
|
|
71
75
|
|
|
72
76
|
However, you might want to use more than a single player! Therefore, you should use the `addPlayers` function, which takes an array of player configurations, and load them all:
|
|
73
77
|
|
|
@@ -77,13 +81,11 @@ const players = [
|
|
|
77
81
|
name: 'chords',
|
|
78
82
|
url: './assets/music/chords.ogg',
|
|
79
83
|
length: 16,
|
|
80
|
-
absolute: true,
|
|
81
84
|
},
|
|
82
85
|
{
|
|
83
86
|
name: 'bass',
|
|
84
87
|
url: './assets/music/bass.ogg',
|
|
85
88
|
length: 16,
|
|
86
|
-
absolute: true,
|
|
87
89
|
},
|
|
88
90
|
{
|
|
89
91
|
name: 'guitar',
|
|
@@ -105,9 +107,9 @@ Speaking of which, here is how it's done:
|
|
|
105
107
|
orchestra.start();
|
|
106
108
|
```
|
|
107
109
|
|
|
108
|
-
This won't play any sound yet. But it will initiate a
|
|
110
|
+
This won't play any sound yet. But it will initiate a _metronome_, that will set the beginning of the music, and count each beat based on the BPM.
|
|
109
111
|
|
|
110
|
-
|
|
112
|
+
If you want to start with some tracks immediately, you can call `start` with an array of player names as parameter.
|
|
111
113
|
|
|
112
114
|
```javascript
|
|
113
115
|
orchestra.start(['bass', 'chords']);
|
|
@@ -121,30 +123,69 @@ Once the orchestra has been loaded, you can activate your players:
|
|
|
121
123
|
orchestra.play('guitar');
|
|
122
124
|
```
|
|
123
125
|
|
|
124
|
-
|
|
126
|
+
To stop them, use:
|
|
125
127
|
|
|
126
128
|
```javascript
|
|
127
129
|
orchestra.stop('guitar');
|
|
128
130
|
```
|
|
129
131
|
|
|
130
|
-
Players will start and stop on the next beat
|
|
132
|
+
Players will start and stop **on the next beat**. They will then stay in rhythm according to their type (relative or absolute). It's as simple as that!
|
|
131
133
|
|
|
132
134
|
You don't have to worry if your player is already playing or not. If you call `play` when a player is already active, or stop when it isn't, nothing will happen. Thus you can use `play` and `stop` to make sure the player is in the right state.
|
|
133
135
|
|
|
134
|
-
You can also call the function `toggle`, that just changes the player
|
|
136
|
+
You can also call the function `toggle`, that just changes the player's state between play and stop.
|
|
135
137
|
|
|
136
138
|
```javascript
|
|
137
139
|
orchestra.toggle('guitar');
|
|
138
140
|
```
|
|
139
141
|
|
|
142
|
+
See below for more [playing options](#playing-options)
|
|
143
|
+
|
|
144
|
+
You now know the basics of Orchestre-JS. But it provides more tools to design a dynamic music system! Let's explore them.
|
|
145
|
+
|
|
146
|
+
## Features
|
|
147
|
+
|
|
148
|
+
### Absolute & relative player position
|
|
149
|
+
|
|
150
|
+
When adding a player, you can configure its **position** as either _"absolute"_ or _"relative"_. By default, it's _absolute_.
|
|
151
|
+
|
|
152
|
+
```javascript
|
|
153
|
+
await orchestra.addPlayer('melody', './assets/music/melody.ogg', 8, 'relative');
|
|
154
|
+
// or
|
|
155
|
+
await orchestra.addPlayers([
|
|
156
|
+
{
|
|
157
|
+
name: 'melody',
|
|
158
|
+
url: './assets/music/melody.ogg',
|
|
159
|
+
length: 8,
|
|
160
|
+
position: 'relative',
|
|
161
|
+
},
|
|
162
|
+
]);
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
What does this position mean? When you call the `play` method, **an absolute players will start with an offset so that it is always aligned in the song**. It's as if they were already playing silently and they volume has just been turned up. It's probably what you expect for an adaptive song.
|
|
166
|
+
|
|
167
|
+
**A relative player however will always start from its beginning**, no matter when you're calling `play`. It will still be on beat and in rhythm. But they won't be aligned on global a global sheet: they can play at any beat of any bar (with any length even).
|
|
168
|
+
|
|
169
|
+
Here is a diagram to better understand how it works. Each player here has a length of 4 beats, and are activated at the same time. See how the absolute player starts already in sync with the bar, while the relative one starts on its first beat.
|
|
170
|
+
|
|
171
|
+

|
|
172
|
+
|
|
173
|
+
Most of the time, you will want **absolute** players. They are guaranteed to stay aligned with each other, as they are playing on the bars of your song.
|
|
174
|
+
|
|
175
|
+
**Relative** players are useful for _stingers_: small melodic phrases played only once on an event (with the `once` option). They can also be used for complex generative compositions.
|
|
176
|
+
|
|
177
|
+
### <a id="playing-options"></a>Playing options
|
|
178
|
+
|
|
140
179
|
`play`, `stop` and `toggle` can take a second parameter _options_, which is an object that allows you to define some of those properties:
|
|
141
180
|
|
|
142
181
|
- **fade** _(float)_: time constant in seconds for a fade in or fade out. The length of fading is approximately equal to 1.6 times your constant. See [setTargetAtTime](https://developer.mozilla.org/en-US/docs/Web/API/AudioParam/setTargetAtTime) for more details.
|
|
143
|
-
- **now** _(bool)_: if true, sound will start / stop
|
|
144
|
-
- **once** _(bool)_: for _play_ only. Play
|
|
145
|
-
- **keep** _(bool)_: for _stop_ only. Keep playing the
|
|
182
|
+
- **now** _(bool)_: if true, sound will start / stop _immediately_ instead of waiting for next beat. This is better used with a fading.
|
|
183
|
+
- **once** _(bool)_: for _play_ only. Play the track only once (instead of a loop).
|
|
184
|
+
- **keep** _(bool)_: for _stop_ only. Keep playing the track until its completion, then stop looping.
|
|
146
185
|
|
|
147
|
-
|
|
186
|
+
### Scheduling
|
|
187
|
+
|
|
188
|
+
You can schedule a play/stop action on a player several beats in advance with the following method:
|
|
148
189
|
|
|
149
190
|
```javascript
|
|
150
191
|
orchestra.schedule('bass', 4, 'toggle'); // bass will be toggled after the next 4 beats
|
|
@@ -153,51 +194,53 @@ orchestra.schedule('guitar', 8, 'play', { absolute: true }); // guitar will play
|
|
|
153
194
|
|
|
154
195
|
_Warning:_ Once an action has been scheduled, it can't be cancelled.
|
|
155
196
|
|
|
156
|
-
###
|
|
197
|
+
### Events
|
|
198
|
+
|
|
199
|
+
Orchestre-JS provide several methods for subscribing to the beat of the music.
|
|
157
200
|
|
|
158
|
-
To
|
|
201
|
+
To **subscribe to a beat interval**, use `addListener`. It takes a _callback_ and the _length_ of the interval in beats.
|
|
159
202
|
|
|
160
203
|
```javascript
|
|
161
|
-
|
|
204
|
+
// Called every beat
|
|
205
|
+
const listenerId = orchestra.addListener(() => {
|
|
206
|
+
/* Do something */
|
|
207
|
+
}, 1);
|
|
208
|
+
// Called every 4 beats (starting from now)
|
|
209
|
+
const listenerId2 = orchestra.addListener(() => {
|
|
210
|
+
/* Do something */
|
|
211
|
+
}, 4);
|
|
162
212
|
```
|
|
163
213
|
|
|
164
|
-
`
|
|
214
|
+
`addListener` takes also a second _options_ parameter:
|
|
165
215
|
|
|
166
|
-
- **absolute** _(bool)_:
|
|
216
|
+
- **absolute** _(bool)_: listen to absolute bars of n beats
|
|
167
217
|
- **offset** _(number)_: use with absolute to set a position in the bar
|
|
168
218
|
|
|
169
|
-
|
|
219
|
+
For example, `addListener(cb, 4, { absolute: true })`, will trigger on every bar of 4 beat, while `addListener(cb, 4, { absolute: true, offset: 1 })` will trigger on the second beat of the bars (index "1").
|
|
220
|
+
|
|
221
|
+
To remove a listener, use `removeListener` with its id:
|
|
170
222
|
|
|
171
223
|
```javascript
|
|
172
|
-
|
|
173
|
-
() => {
|
|
174
|
-
/* Do something */
|
|
175
|
-
},
|
|
176
|
-
4,
|
|
177
|
-
{
|
|
178
|
-
absolute: true,
|
|
179
|
-
offset: 2,
|
|
180
|
-
}
|
|
181
|
-
);
|
|
224
|
+
orchestra.removeListener(listenerId);
|
|
182
225
|
```
|
|
183
226
|
|
|
184
|
-
|
|
227
|
+
If you want to **trigger an event just once**, you can use the `wait` method. It takes the number of beats to wait, and the same options as `addListener`. It then returns a Promise that resolves once the beat is reached.
|
|
185
228
|
|
|
186
229
|
```javascript
|
|
187
|
-
orchestra.
|
|
230
|
+
await orchestra.wait(2); // Waits 2 beats
|
|
231
|
+
await orchestra.wait(4, { absolute: true }); // Waits for next bar of 4
|
|
232
|
+
await orchestra.wait(4, { absolute: true, offset: 2 }); // Waits for next 3rd beat in a bar
|
|
188
233
|
```
|
|
189
234
|
|
|
190
235
|
### Stop
|
|
191
236
|
|
|
192
|
-
Once you are done with your song, you can call `fullStop` on the orchestra to immediately stop all the instruments
|
|
237
|
+
Once you are done with your song, you can call `fullStop` on the orchestra to immediately stop all the instruments as well as its metronome.
|
|
193
238
|
|
|
194
239
|
```javascript
|
|
195
240
|
orchestra.fullStop();
|
|
196
241
|
```
|
|
197
242
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
That's it! You know all the basics of Orchestre-JS.
|
|
243
|
+
The orchestra will need to be started to be used again.
|
|
201
244
|
|
|
202
245
|
## Accessibility
|
|
203
246
|
|
|
@@ -208,18 +251,17 @@ In order for your application to be accessible to anyone (including users with s
|
|
|
208
251
|
|
|
209
252
|
Orchestre-JS provides some functions that you can use in that order.
|
|
210
253
|
|
|
211
|
-
You can pause
|
|
254
|
+
You can **pause the orchestra** by calling `orchestre.suspend()`, and start it again with `orchestre.resume()`. This will immediately interrupt all players and the metronome. Calling `resume` will make it start just where it was.
|
|
212
255
|
|
|
213
|
-
You can change the volume of the whole orchestre with `orchestre.setVolume(value)`, where
|
|
256
|
+
You can **change the volume** of the whole orchestre with `orchestre.setVolume(value)`, where _value_ is a float between 0 and 1 (or higher, but this is at your own risk). _Do not use this method for a fade out_ or any other effect. It has been intended for giving users a way to change volume, and therefore is applied immediately.
|
|
214
257
|
|
|
215
258
|
## Advanced
|
|
216
259
|
|
|
217
260
|
### Using the Web Audio API
|
|
218
261
|
|
|
219
|
-
Orchestre-JS uses the _Web Audio API_. You don't need to
|
|
220
|
-
If you're more advanced with the Web Audio API, you might want to have some more complex usage of Orchestre-JS. Here are some options at your disposition.
|
|
262
|
+
Orchestre-JS uses the _Web Audio API_. You don't need to have experience with it to use Orchestre-JS. But knowing some if its basics can allow you to extend the possibilities that the lib offers. Here are some connecting options at your disposition.
|
|
221
263
|
|
|
222
|
-
By default, every new
|
|
264
|
+
By default, every new Orchestre creates its own audio context. But you can pass your own as a second argument.
|
|
223
265
|
|
|
224
266
|
```javascript
|
|
225
267
|
const context = new (window.AudioContext || window.webkitAudioContext)();
|
|
@@ -228,15 +270,15 @@ const orchestra = new Orchestre(120, context);
|
|
|
228
270
|
|
|
229
271
|
You can also access the audio context from the `context` property of the orchestra.
|
|
230
272
|
|
|
231
|
-
Players are by default connected to the orchestra's master gain (`orchestre.master`), which is connected to the context's destination. But if you want to connect
|
|
273
|
+
Players are by default connected to the orchestra's master gain (`orchestre.master`), which is connected to the context's destination. But if you want to **connect players to your own nodes**, you can change that with the `destination` parameter.
|
|
232
274
|
|
|
233
275
|
```javascript
|
|
234
276
|
await orchestra.addPlayer(
|
|
235
277
|
'bass',
|
|
236
278
|
'./assets/music/bass.ogg',
|
|
237
279
|
16,
|
|
238
|
-
|
|
239
|
-
myAudioNode
|
|
280
|
+
'absolute',
|
|
281
|
+
myAudioNode,
|
|
240
282
|
);
|
|
241
283
|
// Or
|
|
242
284
|
await orchestra.addPlayers([
|
|
@@ -249,7 +291,9 @@ await orchestra.addPlayers([
|
|
|
249
291
|
]);
|
|
250
292
|
```
|
|
251
293
|
|
|
252
|
-
|
|
294
|
+
This allows you to **add effects on individual players** (like panning or reverb) or analyse their output.
|
|
295
|
+
|
|
296
|
+
Alternatively, you can also connect or disconnect players after they have been added:
|
|
253
297
|
|
|
254
298
|
```javascript
|
|
255
299
|
orchestra.connect('bass', myAudioNode);
|
|
@@ -257,7 +301,7 @@ orchestra.disconnect('bass', myAudioNode);
|
|
|
257
301
|
orchestra.disconnect('bass'); // Will disconnect from every nodes
|
|
258
302
|
```
|
|
259
303
|
|
|
260
|
-
_Warning_: If a player is not connected to master
|
|
304
|
+
_Warning_: If a player is not connected to `orchestre.master`, it is no longer affected by the `setVolume` method. The best practice is to connect your final node to `orchestre.master` so that it can be affected by the orchestra's volume.
|
|
261
305
|
|
|
262
306
|
```javascript
|
|
263
307
|
orchestra.connect('bass', myAudioNode);
|
|
@@ -266,24 +310,42 @@ myAudioNode.connect(orchestra.master);
|
|
|
266
310
|
|
|
267
311
|
### Metronome
|
|
268
312
|
|
|
269
|
-
Orchestre-JS orchestra uses a metronome to sync all tracks. In most use cases, you don't need to interact with it.
|
|
313
|
+
Orchestre-JS orchestra uses a metronome to sync all tracks. In most use cases, you don't need to interact with it. But you can still access it from the `metronome` property of a created Orchestre.
|
|
270
314
|
|
|
271
|
-
The metronome gives you access to the property `beatsLength`, which is the length of a beat in seconds. _Beats_ are the tiniest unit of time calculated. If you want to be more precise, the better is to
|
|
315
|
+
The metronome gives you access to the property `beatsLength`, which is the length of a beat in seconds. _Beats_ are the tiniest unit of time calculated. By default, they correspond to fourth notes. If you want to be more precise, **the better is to multiply your BPM** (doubling the BPM for example will align beats to eighth notes).
|
|
272
316
|
|
|
273
317
|
Here are some metronome's methods you can use :
|
|
274
318
|
|
|
275
319
|
- `getNextBeatTime(): float` gives you the time, in second, of the next beat
|
|
276
320
|
- `getNextNthBeatTime(beats: number): float` gives you the time, in second, of the next nth beat
|
|
277
321
|
- `getOffset(time: float): float` gives in seconds the offset of the given time relatively to the closest beat before it
|
|
322
|
+
- `getTimeBeforeBeat(beat: number = 1): float` gives in seconds the time remaining before the next nth beat
|
|
278
323
|
- `getBeatPosition(time: float, barSize: number): number` for absolute bars of _barSize_ beats, gives the position of the given time. For example, for a bar of 4 beat, results may go from 0 (first beat) to 3 (last beat).
|
|
324
|
+
- `getBeatsToBar(barSize: number, bars: number = 1): number` gives the beats remaining before the next nth bar of the given size
|
|
279
325
|
|
|
280
326
|
For the simple tasks though (such as counting the position in a bar), I would advise not to use these functions and instead use the `addListener` method on the orchestra to manage your own counters.
|
|
281
327
|
|
|
328
|
+
### Duplicating an Orchestre
|
|
329
|
+
|
|
330
|
+
Sometime you might need another instance of an Orchestre, with the same players. This can be useful for horizontal layering. For example: starting the second Orchestre when the first one reaches its 8th bar, or maybe even inserting a transition track between them. But in this case, recreating a new Orchestre and loading all the players _again_ isn't ideal. This would duplicates the queries for the sound files.
|
|
331
|
+
|
|
332
|
+
For that purpose, you can create a **copy** of an Orchestre from an existing instance, with the static method `from`:
|
|
333
|
+
|
|
334
|
+
```javascript
|
|
335
|
+
const copy = Orchestre.from(orchestre);
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
The copy will have the **same players as the originals** and share the **same audio context**. You can still add new players afterward. On creation, it will be stopped, even if the original is playing. You can start it when you want with `.start`. It is a truly independent new Orchestre, with its own metronome and volume.
|
|
339
|
+
|
|
340
|
+
Players' destinations are also preserved _if_ you specified it in their configuration (in `addPlayer` or `addPlayers`). But otherwise, if you used `.connect` after their creation, the copy's players won't be linked to these new targets. Likewise, the Orchestre copy is directly connected to `context.destination`, regardless of the original's master target.
|
|
341
|
+
|
|
342
|
+
Subscriptions made with `addListeners` are also not included in the copy. They will still be triggered by the first Orchestre. To keep the alignment with the copy (if the first Orchestre is silent or stopped), the best is to recreate the listeners once the copy is started.
|
|
343
|
+
|
|
282
344
|
## API
|
|
283
345
|
|
|
284
346
|
[API Documentation](doc/api.md)
|
|
285
347
|
|
|
286
348
|
## Troubleshooting
|
|
287
349
|
|
|
288
|
-
- **My players loop too early / too late**: Make sure that the BPM you provided to your Orchestre matches your song's one, and that you wrote the correct number of beats in your loop in the player's _length_. For example, 4 bars in 4/4 will have a length of 16. Orchestre will use these values to loop your tracks,
|
|
350
|
+
- **My players loop too early / too late**: Make sure that the BPM you provided to your Orchestre matches your song's one, and that you wrote the correct number of beats in your loop in the player's _length_. For example, 4 bars in 4/4 will have a length of 16. Orchestre will use these values to loop your tracks, regardless of the audio file's actual length. This allows not only to keep them synchronized to the rhythm, but also to make them overlap if they have reverb or delay at the end.
|
|
289
351
|
- **My audio files don't play:** Make sure that you wrote the correct folder and name in the _url_ property of the player, and that this file is accessible. You can check its download in your browser's devtools. If you see another error in the console, refer to the Web Audio API documentation. Some browser might not accept all formats! You should be safe with .ogg, .wav or .mp3 though.
|