smplr 0.3.0 → 0.4.1
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 +73 -29
- package/dist/index.d.ts +23 -22
- package/dist/index.js +468 -287
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +466 -286
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -4,26 +4,44 @@
|
|
|
4
4
|
|
|
5
5
|
> `smplr` is a collection of sampled instruments for Web Audio API ready to be used with no setup required.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Examples:
|
|
8
8
|
|
|
9
9
|
```js
|
|
10
|
-
import {
|
|
10
|
+
import { Soundfont } from "smplr";
|
|
11
11
|
|
|
12
12
|
const context = new AudioContext();
|
|
13
|
-
const piano = new SplendidGrandPiano(context);
|
|
14
|
-
piano.start({ note: "C4" });
|
|
15
|
-
|
|
16
13
|
const marimba = new Soundfont(context, { instrument: "marimba" });
|
|
17
14
|
marimba.start({ note: 60, velocity: 80 });
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import { DrumMachine } from "smplr";
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
const context = new AudioContext();
|
|
21
|
+
const dm = new DrumMachine(context);
|
|
22
|
+
dm.start({ note: "kick" });
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```js
|
|
26
|
+
import { SplendidGrandPiano, Reverb } from "smplr";
|
|
27
|
+
|
|
28
|
+
const context = new AudioContext();
|
|
29
|
+
const piano = new SplendidGrandPiano(context);
|
|
30
|
+
piano.output.addEffect("reverb", new Reverb(context), 0.2);
|
|
31
|
+
|
|
32
|
+
piano.start({ note: "C4" });
|
|
23
33
|
```
|
|
24
34
|
|
|
25
35
|
See demo: https://danigb.github.io/smplr/
|
|
26
36
|
|
|
37
|
+
#### Library goals
|
|
38
|
+
|
|
39
|
+
- No setup: specifically, all samples are online, so no need for a server.
|
|
40
|
+
- Easy to use: everything should be intuitive for non-experienced developers
|
|
41
|
+
- Decent sounding: use high quality open source samples. For good or worst, is sample based 🤷
|
|
42
|
+
|
|
43
|
+
#### Installation
|
|
44
|
+
|
|
27
45
|
Install with npm or your favourite package manager:
|
|
28
46
|
|
|
29
47
|
```
|
|
@@ -70,7 +88,7 @@ The `start` function accepts a bunch of options:
|
|
|
70
88
|
piano.start({ note: "C4", velocity: 80, time: 5, duration: 1 });
|
|
71
89
|
```
|
|
72
90
|
|
|
73
|
-
The `velocity` is a number between 0 and
|
|
91
|
+
The `velocity` is a number between 0 and 127 the represents at which velocity the key is pressed. The bigger the number, louder the sound. But `velocity` not only controls the loudness. In some instruments, it also affects the timbre.
|
|
74
92
|
|
|
75
93
|
The `start` function returns a `stop` function for the given note:
|
|
76
94
|
|
|
@@ -81,34 +99,36 @@ stopNote({ time: 10 });
|
|
|
81
99
|
|
|
82
100
|
Bear in mind that you may need to call [`context.resume()` before playing a note](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Best_practices#autoplay_policy)
|
|
83
101
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
You can schedule notes using `time` and `duration` properties:
|
|
102
|
+
Instruments have a global `stop` function that can be used to stop all notes:
|
|
87
103
|
|
|
88
104
|
```js
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
piano.start({ note, time: now + i, duration: 0.5 });
|
|
92
|
-
});
|
|
105
|
+
// This will stop all notes
|
|
106
|
+
piano.stop();
|
|
93
107
|
```
|
|
94
108
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
Instruments have a global `stop` function that stops all notes:
|
|
109
|
+
Or stop the specified one:
|
|
98
110
|
|
|
99
111
|
```js
|
|
100
|
-
|
|
112
|
+
// This will stop C4 note
|
|
113
|
+
piano.stop(60);
|
|
101
114
|
```
|
|
102
115
|
|
|
103
|
-
|
|
116
|
+
### Schedule notes
|
|
117
|
+
|
|
118
|
+
You can schedule notes using `time` and `duration` properties. Both are measured in seconds, and time is the number of seconds since the AudioContext was created.
|
|
119
|
+
|
|
120
|
+
For example, next example plays a C major arpeggio, one note per second:
|
|
104
121
|
|
|
105
122
|
```js
|
|
106
|
-
|
|
123
|
+
const now = context.currentTime;
|
|
124
|
+
["C4", "E4", "G4", "C5"].forEach((note, i) => {
|
|
125
|
+
piano.start({ note, time: now + i, duration: 0.5 });
|
|
126
|
+
});
|
|
107
127
|
```
|
|
108
128
|
|
|
109
129
|
### Change volume
|
|
110
130
|
|
|
111
|
-
`setVolume` uses a scale where 0 means no volume, and
|
|
131
|
+
`setVolume` uses a scale where 0 means no volume, and 127 is max volume without amplification:
|
|
112
132
|
|
|
113
133
|
```js
|
|
114
134
|
piano.setVolume(80);
|
|
@@ -120,7 +140,7 @@ Bear in mind that `volume` is global to the instrument, but `velocity` is specif
|
|
|
120
140
|
|
|
121
141
|
An packed version of [DattorroReverbNode](https://github.com/khoin/DattorroReverbNode) algorithmic reverb is included.
|
|
122
142
|
|
|
123
|
-
Use `output.addEffect(name, effect, mix)` to
|
|
143
|
+
Use `output.addEffect(name, effect, mix)` to connect an effect using a send bus:
|
|
124
144
|
|
|
125
145
|
```js
|
|
126
146
|
import { Reverb, SplendidGrandPiano } from "smplr";
|
|
@@ -129,7 +149,7 @@ const piano = new SplendidGrandPiano(context, { volume });
|
|
|
129
149
|
piano.output.addEffect("reverb", reverb, 0.2);
|
|
130
150
|
```
|
|
131
151
|
|
|
132
|
-
|
|
152
|
+
To change the mix level, use `output.sendEffect(name, mix)`:
|
|
133
153
|
|
|
134
154
|
```js
|
|
135
155
|
piano.output.sendEffect("reverb", 0.5);
|
|
@@ -160,7 +180,7 @@ A Soundfont player. By default it loads audio from Benjamin Gleitzman's package
|
|
|
160
180
|
```js
|
|
161
181
|
import { Soundfont } from "smplr";
|
|
162
182
|
|
|
163
|
-
const marimba = new Soundfont(new AudioContext(), "marimba");
|
|
183
|
+
const marimba = new Soundfont(new AudioContext(), { instrument: "marimba" });
|
|
164
184
|
marimba.start({ note: "C4" });
|
|
165
185
|
```
|
|
166
186
|
|
|
@@ -184,7 +204,9 @@ piano.start({ note: "C4" });
|
|
|
184
204
|
A sampled electric pianos. Samples from https://github.com/sfzinstruments/GregSullivan.E-Pianos
|
|
185
205
|
|
|
186
206
|
```js
|
|
187
|
-
import { ElectricPiano } from "smplr";
|
|
207
|
+
import { ElectricPiano, getElectricPianoNames } from "smplr";
|
|
208
|
+
|
|
209
|
+
const instruments = getElectricPianoNames(); // => ["CP80", "PianetT", "WurlitzerEP200"]
|
|
188
210
|
|
|
189
211
|
const epiano = new ElectricPiano(new AudioContext(), {
|
|
190
212
|
instrument: "PianetT",
|
|
@@ -209,8 +231,30 @@ Samples from [The Versilian Community Sample Library](https://github.com/sgossne
|
|
|
209
231
|
```js
|
|
210
232
|
import { Mallet, getMalletNames } from "smplr";
|
|
211
233
|
|
|
234
|
+
const instruments = getMalletNames();
|
|
235
|
+
|
|
212
236
|
const mallet = new Mallet(new AudioContext(), {
|
|
213
|
-
instrument:
|
|
237
|
+
instrument: instruments[0],
|
|
238
|
+
});
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Drum Machines
|
|
242
|
+
|
|
243
|
+
Sampled drum machines. Samples from different sources:
|
|
244
|
+
|
|
245
|
+
```js
|
|
246
|
+
import { DrumMachine, getDrumMachineNames } from "smplr";
|
|
247
|
+
|
|
248
|
+
const instruments = getDrumMachineNames();
|
|
249
|
+
|
|
250
|
+
const context = new AudioContext();
|
|
251
|
+
const drums = new DrumMachine(context, { instrument: "TR-808" });
|
|
252
|
+
drums.start({ note: "kick" });
|
|
253
|
+
|
|
254
|
+
// Drum samples could have variations:
|
|
255
|
+
const now = context.currentTime;
|
|
256
|
+
drums.getVariations("kick").forEach((variation, index) => {
|
|
257
|
+
drums.start({ note: variation, time: now + index });
|
|
214
258
|
});
|
|
215
259
|
```
|
|
216
260
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
type AudioBuffers = Record<string | number, AudioBuffer>;
|
|
2
|
-
|
|
3
1
|
type AudioInsert = {
|
|
4
2
|
input: AudioNode;
|
|
5
3
|
output: AudioNode;
|
|
@@ -27,6 +25,8 @@ declare class Channel {
|
|
|
27
25
|
disconnect(): void;
|
|
28
26
|
}
|
|
29
27
|
|
|
28
|
+
type AudioBuffers = Record<string | number, AudioBuffer | undefined>;
|
|
29
|
+
|
|
30
30
|
type StopSample = {
|
|
31
31
|
stopId?: string | number;
|
|
32
32
|
time?: number;
|
|
@@ -69,10 +69,27 @@ declare class Sampler {
|
|
|
69
69
|
readonly buffers: AudioBuffers;
|
|
70
70
|
constructor(context: AudioContext, options: Partial<SamplerConfig>);
|
|
71
71
|
loaded(): Promise<this>;
|
|
72
|
-
start(note: SamplerNote | string | number): (time?: number) => void;
|
|
72
|
+
start(note: SamplerNote | string | number): (time?: number | undefined) => void;
|
|
73
73
|
stop(note?: StopSample | string | number): void;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
declare function getDrumMachineNames(): string[];
|
|
77
|
+
type DrumMachineConfig = {
|
|
78
|
+
instrument: string;
|
|
79
|
+
destination: AudioNode;
|
|
80
|
+
detune: number;
|
|
81
|
+
volume: number;
|
|
82
|
+
velocity: number;
|
|
83
|
+
decayTime?: number;
|
|
84
|
+
lpfCutoffHz?: number;
|
|
85
|
+
};
|
|
86
|
+
declare class DrumMachine extends Sampler {
|
|
87
|
+
#private;
|
|
88
|
+
constructor(context: AudioContext, options: Partial<DrumMachineConfig>);
|
|
89
|
+
get sampleNames(): string[];
|
|
90
|
+
getVariations(name: string): string[];
|
|
91
|
+
}
|
|
92
|
+
|
|
76
93
|
type SfzInstrument = {
|
|
77
94
|
name: string;
|
|
78
95
|
formats?: string[];
|
|
@@ -166,7 +183,7 @@ declare class SfzSampler {
|
|
|
166
183
|
disconnect(): void;
|
|
167
184
|
}
|
|
168
185
|
|
|
169
|
-
declare
|
|
186
|
+
declare function getElectricPianoNames(): string[];
|
|
170
187
|
declare class ElectricPiano extends SfzSampler {
|
|
171
188
|
readonly tremolo: Readonly<{
|
|
172
189
|
level: (value: number) => void;
|
|
@@ -182,21 +199,7 @@ declare class Mallet extends SfzSampler {
|
|
|
182
199
|
instrument: string;
|
|
183
200
|
});
|
|
184
201
|
}
|
|
185
|
-
declare const DATA:
|
|
186
|
-
readonly "Balafon - Hard Mallet": "Struck Idiophones/balafon-hard-mallet";
|
|
187
|
-
readonly "Balafon - Keyswitch": "Struck Idiophones/balafon-keyswitch";
|
|
188
|
-
readonly "Balafon - Soft Mallet": "Struck Idiophones/balafon-soft-mallet";
|
|
189
|
-
readonly "Balafon - Traditional Mallet": "Struck Idiophones/balafon-traditional-mallet";
|
|
190
|
-
readonly "Tubular Bells 1": "Struck Idiophones/tubular-bells-1";
|
|
191
|
-
readonly "Tubular Bells 2": "Struck Idiophones/tubular-bells-2";
|
|
192
|
-
readonly "Vibraphone - Hard Mallets": "Struck Idiophones/vibraphone-hard-mallets";
|
|
193
|
-
readonly "Vibraphone - Keyswitch": "Struck Idiophones/vibraphone-keyswitch";
|
|
194
|
-
readonly "Vibraphone - Soft Mallets": "Struck Idiophones/vibraphone-soft-mallets";
|
|
195
|
-
readonly "Xylophone - Hard Mallets": "Struck Idiophones/xylophone-hard-mallets";
|
|
196
|
-
readonly "Xylophone - Keyswitch": "Struck Idiophones/xylophone-keyswitch";
|
|
197
|
-
readonly "Xylophone - Medium Mallets": "Struck Idiophones/xylophone-medium-mallets";
|
|
198
|
-
readonly "Xylophone - Soft Mallets": "Struck Idiophones/xylophone-soft-mallets";
|
|
199
|
-
};
|
|
202
|
+
declare const DATA: Record<string, string | undefined>;
|
|
200
203
|
|
|
201
204
|
declare const PARAMS: readonly ["preDelay", "bandwidth", "inputDiffusion1", "inputDiffusion2", "decay", "decayDiffusion1", "decayDiffusion2", "damping", "excursionRate", "excursionDepth", "wet", "dry"];
|
|
202
205
|
declare class Reverb {
|
|
@@ -213,7 +216,6 @@ declare class Reverb {
|
|
|
213
216
|
type SoundfontConfig = {
|
|
214
217
|
library: SoundfontLibrary | LibraryUrlBuilder;
|
|
215
218
|
instrument: string;
|
|
216
|
-
format: string;
|
|
217
219
|
destination: AudioNode;
|
|
218
220
|
detune: number;
|
|
219
221
|
volume: number;
|
|
@@ -243,7 +245,6 @@ declare const SoundfontLibraries: Record<string, SoundfontLibrary>;
|
|
|
243
245
|
*/
|
|
244
246
|
type SplendidGrandPianoConfig = {
|
|
245
247
|
baseUrl: string;
|
|
246
|
-
format: "ogg" | "m4a";
|
|
247
248
|
destination: AudioNode;
|
|
248
249
|
detune: number;
|
|
249
250
|
volume: number;
|
|
@@ -266,4 +267,4 @@ declare const LAYERS: ({
|
|
|
266
267
|
cutoff?: undefined;
|
|
267
268
|
})[];
|
|
268
269
|
|
|
269
|
-
export { DATA,
|
|
270
|
+
export { DATA, DrumMachine, DrumMachineConfig, ElectricPiano, FluidR3, LAYERS, LibraryUrlBuilder, Mallet, MusyngKite, Reverb, Sampler, SamplerAudioLoader, SamplerConfig, SamplerNote, Soundfont, SoundfontConfig, SoundfontLibraries, SoundfontLibrary, SplendidGrandPiano, SplendidGrandPianoConfig, getDrumMachineNames, getElectricPianoNames, getMalletNames, gleitzKitUrl };
|