smplr 0.8.1 → 0.10.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 +90 -30
- package/dist/index.d.mts +492 -0
- package/dist/index.d.ts +135 -13
- package/dist/index.js +517 -110
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +511 -109
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -44,21 +44,49 @@ Read [CHANGELOG](https://github.com/danigb/smplr/blob/main/CHANGELOG.md) for cha
|
|
|
44
44
|
- Easy to use: everything should be intuitive for non-experienced developers
|
|
45
45
|
- Decent sounding: uses high quality open source samples. For better or worse, it is sample based 🤷
|
|
46
46
|
|
|
47
|
-
##
|
|
47
|
+
## Setup
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
You can install the library with a package manager or use it directly by importing from the browser.
|
|
50
|
+
|
|
51
|
+
Samples are stored at https://github.com/smpldsnds and there is no need to download them. Kudos to all _samplerist_ 🙌
|
|
52
|
+
|
|
53
|
+
#### Using a package manger
|
|
54
|
+
|
|
55
|
+
Use npm or your favourite package manager to install the library to use it in your project:
|
|
50
56
|
|
|
51
57
|
```
|
|
52
58
|
npm i smplr
|
|
53
59
|
```
|
|
54
60
|
|
|
55
|
-
|
|
61
|
+
#### Usage from the browser
|
|
62
|
+
|
|
63
|
+
You can import directly from the browser. For example:
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
<html>
|
|
67
|
+
<body>
|
|
68
|
+
<button id="btn">play</button>
|
|
69
|
+
</body>
|
|
70
|
+
<script type="module">
|
|
71
|
+
import { SplendidGrandPiano } from "https://unpkg.com/smplr@0.10.0/dist/index.mjs"; // needs to be a url
|
|
72
|
+
const context = new AudioContext(); // create the audio context
|
|
73
|
+
const marimba = new SplendidGrandPiano(context); // create and load the instrument
|
|
74
|
+
|
|
75
|
+
document.getElementById("btn").onclick = () => {
|
|
76
|
+
context.resume(); // enable audio context after a user interaction
|
|
77
|
+
marimba.start({ note: 60, velocity: 80 }); // play the note
|
|
78
|
+
};
|
|
79
|
+
</script>
|
|
80
|
+
</html>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The package needs to be serve as a url from a service like [unpkg](unpkg.com) or similar.
|
|
56
84
|
|
|
57
85
|
## Documentation
|
|
58
86
|
|
|
59
87
|
### Create and load an instrument
|
|
60
88
|
|
|
61
|
-
All instruments follows the same pattern: `new Instrument(context, options
|
|
89
|
+
All instruments follows the same pattern: `new Instrument(context, options)`. For example:
|
|
62
90
|
|
|
63
91
|
```js
|
|
64
92
|
import { SplendidGrandPiano, Soundfont } from "smplr";
|
|
@@ -84,6 +112,8 @@ Since the promise returns the instrument instance, you can create and wait in a
|
|
|
84
112
|
const piano = await new SplendidGrandPiano(context).load;
|
|
85
113
|
```
|
|
86
114
|
|
|
115
|
+
⚠️ In versions lower than 0.8.0 a `loaded()` function was exposed instead.
|
|
116
|
+
|
|
87
117
|
### Play
|
|
88
118
|
|
|
89
119
|
#### Start and stop notes
|
|
@@ -121,7 +151,7 @@ piano.stop(60);
|
|
|
121
151
|
|
|
122
152
|
#### Schedule notes
|
|
123
153
|
|
|
124
|
-
You can schedule notes using `time` and `duration` properties. Both are measured in seconds
|
|
154
|
+
You can schedule notes using `time` and `duration` properties. Both are measured in seconds. Time is the number of seconds since the AudioContext was created, like in `audioContext.currentTime`
|
|
125
155
|
|
|
126
156
|
For example, next example plays a C major arpeggio, one note per second:
|
|
127
157
|
|
|
@@ -137,16 +167,16 @@ const now = context.currentTime;
|
|
|
137
167
|
You can loop a note by using `loop`, `loopStart` and `loopEnd`:
|
|
138
168
|
|
|
139
169
|
```js
|
|
140
|
-
const sampler = new Sampler(audioContext, {
|
|
170
|
+
const sampler = new Sampler(audioContext, { duh: "duh-duh-ah.mp3" });
|
|
141
171
|
sampler.start({
|
|
142
|
-
note: "
|
|
143
|
-
loop:
|
|
172
|
+
note: "duh"
|
|
173
|
+
loop: true
|
|
144
174
|
loopStart: 1.0,
|
|
145
175
|
loopEnd: 9.0,
|
|
146
176
|
});
|
|
147
177
|
```
|
|
148
178
|
|
|
149
|
-
If `loopStart` or `loopEnd`
|
|
179
|
+
If `loop` is true but `loopStart` or `loopEnd` are not specified, 0 and total duration will be used by default, respectively.
|
|
150
180
|
|
|
151
181
|
#### Change volume
|
|
152
182
|
|
|
@@ -156,10 +186,28 @@ Instrument `output` attribute represents the main output of the instrument. `out
|
|
|
156
186
|
piano.output.setVolume(80);
|
|
157
187
|
```
|
|
158
188
|
|
|
159
|
-
|
|
189
|
+
⚠️ `volume` is global to the instrument, but `velocity` is specific for each note.
|
|
190
|
+
|
|
191
|
+
#### Events
|
|
192
|
+
|
|
193
|
+
You can add a `onEnded` callback that will be invoked when the note ends:
|
|
194
|
+
|
|
195
|
+
```js
|
|
196
|
+
piano.start({
|
|
197
|
+
note: "C4",
|
|
198
|
+
duration: 1,
|
|
199
|
+
onEnded: () => {
|
|
200
|
+
// will be called after 1 second
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
The callback will receive as parameter the same object you pass to the `start` function;
|
|
160
206
|
|
|
161
207
|
### Effects
|
|
162
208
|
|
|
209
|
+
#### Reverb
|
|
210
|
+
|
|
163
211
|
An packed version of [DattorroReverbNode](https://github.com/khoin/DattorroReverbNode) algorithmic reverb is included.
|
|
164
212
|
|
|
165
213
|
Use `output.addEffect(name, effect, mix)` to connect an effect using a send bus:
|
|
@@ -177,22 +225,6 @@ To change the mix level, use `output.sendEffect(name, mix)`:
|
|
|
177
225
|
piano.output.sendEffect("reverb", 0.5);
|
|
178
226
|
```
|
|
179
227
|
|
|
180
|
-
#### Events
|
|
181
|
-
|
|
182
|
-
You can add a `onEnded` callback that will be invoked when the note ends:
|
|
183
|
-
|
|
184
|
-
```js
|
|
185
|
-
piano.start({
|
|
186
|
-
note: "C4",
|
|
187
|
-
duration: 1,
|
|
188
|
-
onEnded: () => {
|
|
189
|
-
// will be called after 1 second
|
|
190
|
-
},
|
|
191
|
-
});
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
The callback will receive as parameter the same object you pass to the `start` function;
|
|
195
|
-
|
|
196
228
|
### Experimental features
|
|
197
229
|
|
|
198
230
|
#### Cache requests
|
|
@@ -265,7 +297,7 @@ const marimba = new Soundfont(context, {
|
|
|
265
297
|
});
|
|
266
298
|
```
|
|
267
299
|
|
|
268
|
-
####
|
|
300
|
+
#### Soundfont sustained notes
|
|
269
301
|
|
|
270
302
|
You can enable note looping to make note names indefinitely long by loading loop data:
|
|
271
303
|
|
|
@@ -276,11 +308,11 @@ const marimba = new Soundfont(context, {
|
|
|
276
308
|
});
|
|
277
309
|
```
|
|
278
310
|
|
|
279
|
-
|
|
311
|
+
⚠️ This feature is still experimental and can produces clicks on lot of instruments.
|
|
280
312
|
|
|
281
|
-
###
|
|
313
|
+
### SplendidGrandPiano
|
|
282
314
|
|
|
283
|
-
A sampled acoustic piano. It uses Steinway samples with 4 velocity
|
|
315
|
+
A sampled acoustic piano. It uses Steinway samples with 4 velocity groups from
|
|
284
316
|
[SplendidGrandPiano](https://github.com/sfzinstruments/SplendidGrandPiano)
|
|
285
317
|
|
|
286
318
|
```js
|
|
@@ -364,6 +396,34 @@ drums.getVariations("kick").forEach((variation, index) => {
|
|
|
364
396
|
});
|
|
365
397
|
```
|
|
366
398
|
|
|
399
|
+
### Smolken double bass
|
|
400
|
+
|
|
401
|
+
```js
|
|
402
|
+
import { Smolken, getSmolkenNames } from "smplr";
|
|
403
|
+
|
|
404
|
+
const instruments = getSmolkenNames(); // => Arco, Pizzicato & Switched
|
|
405
|
+
|
|
406
|
+
// Create an instrument
|
|
407
|
+
const context = new AudioContext();
|
|
408
|
+
const doubleBass = await new Smolken(context, { instrument: "Arco" }).load;
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### Versilian
|
|
412
|
+
|
|
413
|
+
Versilian is a sample capable of using the [Versilian Community Sample Library](https://github.com/sgossner/VCSL).
|
|
414
|
+
|
|
415
|
+
⚠️ Not all features are implemented. Some instruments may sound incorrect ⚠️
|
|
416
|
+
|
|
417
|
+
```js
|
|
418
|
+
import { Versilian, getVersilianInstruments } from "smplr";
|
|
419
|
+
|
|
420
|
+
// getVersilianInstruments returns a Promise
|
|
421
|
+
const instrumentNames = await getVersilianInstruments();
|
|
422
|
+
|
|
423
|
+
const context = new AudioContext();
|
|
424
|
+
const sampler = new Versilian(context, { instrument: instrumentNAmes[0] });
|
|
425
|
+
```
|
|
426
|
+
|
|
367
427
|
## License
|
|
368
428
|
|
|
369
429
|
MIT License
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
type AudioInsert = {
|
|
2
|
+
input: AudioNode;
|
|
3
|
+
output: AudioNode;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
type ChannelOptions = {
|
|
7
|
+
destination: AudioNode;
|
|
8
|
+
volume: number;
|
|
9
|
+
volumeToGain: (volume: number) => number;
|
|
10
|
+
};
|
|
11
|
+
type OutputChannel = Omit<Channel, "input">;
|
|
12
|
+
/**
|
|
13
|
+
* An output channel with audio effects
|
|
14
|
+
* @private
|
|
15
|
+
*/
|
|
16
|
+
declare class Channel {
|
|
17
|
+
#private;
|
|
18
|
+
readonly context: BaseAudioContext;
|
|
19
|
+
readonly setVolume: (vol: number) => void;
|
|
20
|
+
readonly input: AudioNode;
|
|
21
|
+
constructor(context: BaseAudioContext, options: Partial<ChannelOptions>);
|
|
22
|
+
addInsert(effect: AudioNode | AudioInsert): void;
|
|
23
|
+
addEffect(name: string, effect: AudioNode | {
|
|
24
|
+
input: AudioNode;
|
|
25
|
+
}, mixValue: number): void;
|
|
26
|
+
sendEffect(name: string, mix: number): void;
|
|
27
|
+
disconnect(): void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
type StorageResponse = {
|
|
31
|
+
readonly status: number;
|
|
32
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
33
|
+
json(): Promise<any>;
|
|
34
|
+
text(): Promise<string>;
|
|
35
|
+
};
|
|
36
|
+
type Storage = {
|
|
37
|
+
fetch: (url: string) => Promise<StorageResponse>;
|
|
38
|
+
};
|
|
39
|
+
declare const HttpStorage: Storage;
|
|
40
|
+
declare class CacheStorage implements Storage {
|
|
41
|
+
#private;
|
|
42
|
+
constructor(name?: string);
|
|
43
|
+
fetch(url: string): Promise<StorageResponse>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
type AudioBuffers = Record<string | number, AudioBuffer | undefined>;
|
|
47
|
+
/**
|
|
48
|
+
* A function that downloads audio into a AudioBuffers
|
|
49
|
+
*/
|
|
50
|
+
type AudioBuffersLoader = (context: BaseAudioContext, buffers: AudioBuffers) => Promise<void>;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* A function to unsubscribe from an event or control
|
|
54
|
+
*/
|
|
55
|
+
type Unsubscribe = () => void;
|
|
56
|
+
/**
|
|
57
|
+
* A function that listener to event or control changes
|
|
58
|
+
*/
|
|
59
|
+
type Listener<T> = (value: T) => void;
|
|
60
|
+
/**
|
|
61
|
+
* A function to subscribe an trigger or control events
|
|
62
|
+
*/
|
|
63
|
+
type Subscribe<T> = (listener: Listener<T>) => Unsubscribe;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @private
|
|
67
|
+
*/
|
|
68
|
+
type InternalPlayer = {
|
|
69
|
+
readonly buffers: AudioBuffers;
|
|
70
|
+
readonly context: BaseAudioContext;
|
|
71
|
+
start(sample: SampleStart): (time?: number) => void;
|
|
72
|
+
stop(sample?: SampleStop): void;
|
|
73
|
+
disconnect(): void;
|
|
74
|
+
};
|
|
75
|
+
type SampleStop = {
|
|
76
|
+
stopId?: string | number;
|
|
77
|
+
time?: number;
|
|
78
|
+
};
|
|
79
|
+
type SampleOptions = {
|
|
80
|
+
decayTime?: number;
|
|
81
|
+
detune?: number;
|
|
82
|
+
duration?: number | null;
|
|
83
|
+
velocity?: number;
|
|
84
|
+
lpfCutoffHz?: number;
|
|
85
|
+
loop?: boolean;
|
|
86
|
+
loopStart?: number;
|
|
87
|
+
loopEnd?: number;
|
|
88
|
+
gainOffset?: number;
|
|
89
|
+
};
|
|
90
|
+
type SampleStart = {
|
|
91
|
+
name?: string;
|
|
92
|
+
note: string | number;
|
|
93
|
+
onEnded?: (sample: SampleStart) => void;
|
|
94
|
+
stop?: Subscribe<number>;
|
|
95
|
+
stopId?: string | number;
|
|
96
|
+
time?: number;
|
|
97
|
+
} & SampleOptions;
|
|
98
|
+
/**
|
|
99
|
+
* Heavily inspired by SFZ format
|
|
100
|
+
*/
|
|
101
|
+
type SampleRegion = {
|
|
102
|
+
sampleName: string;
|
|
103
|
+
/**
|
|
104
|
+
* This specifies the MIDI key number that corresponds to the sample's original pitch
|
|
105
|
+
*/
|
|
106
|
+
midiPitch: number;
|
|
107
|
+
/**
|
|
108
|
+
* This defines the lowest MIDI key number that will trigger this sample.
|
|
109
|
+
*/
|
|
110
|
+
midiLow?: number;
|
|
111
|
+
/**
|
|
112
|
+
* This specifies the highest MIDI key number that will trigger this sample.
|
|
113
|
+
*/
|
|
114
|
+
midiHigh?: number;
|
|
115
|
+
velLow?: number;
|
|
116
|
+
/**
|
|
117
|
+
* This determines the highest MIDI velocity at which this sample will be triggered.
|
|
118
|
+
*/
|
|
119
|
+
velHigh?: number;
|
|
120
|
+
/**
|
|
121
|
+
* These define the pitch bend range for the samples in this group. The values are given in cents
|
|
122
|
+
*/
|
|
123
|
+
bendUp?: number;
|
|
124
|
+
bendDown?: number;
|
|
125
|
+
/**
|
|
126
|
+
* Velocity-based amplitude scaling. [Vel, Gain] tells the sampler to play the sample
|
|
127
|
+
* at volume Gain when the note's velocity is Vel
|
|
128
|
+
*/
|
|
129
|
+
ampVelCurve?: [number, number];
|
|
130
|
+
/**
|
|
131
|
+
* Amplitude envelope release time in seconds.
|
|
132
|
+
* Stored here for convenience (flatness) but needs to be
|
|
133
|
+
* copied inside sample options before playback
|
|
134
|
+
*/
|
|
135
|
+
ampRelease?: number;
|
|
136
|
+
/**
|
|
137
|
+
* Attack time in seconds. Currently not implemented
|
|
138
|
+
*
|
|
139
|
+
* @see http://sfzformat.com/opcodes/amp_attack.html
|
|
140
|
+
*/
|
|
141
|
+
ampAttack?: number;
|
|
142
|
+
/**
|
|
143
|
+
* seqLength defines how many samples are in the sequence.
|
|
144
|
+
* When using the seqPosition and seqLength , you can set up round-robin
|
|
145
|
+
* or sequential sample playback.
|
|
146
|
+
*/
|
|
147
|
+
seqLength?: number;
|
|
148
|
+
/**
|
|
149
|
+
* Determine the position of this particular sample within the sequence
|
|
150
|
+
* 1 means first element of the sequence (not zero based!)
|
|
151
|
+
*/
|
|
152
|
+
seqPosition?: number;
|
|
153
|
+
/**
|
|
154
|
+
* This assigns the group to a specific number.
|
|
155
|
+
* Group numbers can be used in combination with groupOffBy to implement
|
|
156
|
+
* exclusive groups, where playing one sample can stop another sample from playing.
|
|
157
|
+
*/
|
|
158
|
+
group?: number;
|
|
159
|
+
/**
|
|
160
|
+
* Triggering a sample in this region will stop (or "turn off") any samples
|
|
161
|
+
* currently playing in the specified group number
|
|
162
|
+
*/
|
|
163
|
+
groupOffBy?: number;
|
|
164
|
+
/**
|
|
165
|
+
* Start offset (in samples). Not implemented (yet)
|
|
166
|
+
*/
|
|
167
|
+
offset?: number;
|
|
168
|
+
/**
|
|
169
|
+
* Adjust the playback pitch of a sample (in semitones)
|
|
170
|
+
*/
|
|
171
|
+
tune?: number;
|
|
172
|
+
/**
|
|
173
|
+
* The volume opcode in SFZ defines the default playback volume for a given region.
|
|
174
|
+
* It specifies an adjustment to the sample's original amplitude.
|
|
175
|
+
* The unit for the volume opcode is decibels (dB).
|
|
176
|
+
*/
|
|
177
|
+
volume?: number;
|
|
178
|
+
/**
|
|
179
|
+
* sample options for this particular region
|
|
180
|
+
*/
|
|
181
|
+
sample?: Partial<SampleOptions>;
|
|
182
|
+
};
|
|
183
|
+
type RegionGroup = {
|
|
184
|
+
regions: SampleRegion[];
|
|
185
|
+
sample: Partial<SampleOptions>;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
declare function getDrumMachineNames(): string[];
|
|
189
|
+
type DrumMachineConfig = ChannelOptions & SampleOptions & {
|
|
190
|
+
instrument: string;
|
|
191
|
+
storage?: Storage;
|
|
192
|
+
};
|
|
193
|
+
declare class DrumMachine {
|
|
194
|
+
#private;
|
|
195
|
+
private readonly player;
|
|
196
|
+
readonly load: Promise<this>;
|
|
197
|
+
readonly output: OutputChannel;
|
|
198
|
+
constructor(context: AudioContext, options?: Partial<DrumMachineConfig>);
|
|
199
|
+
loaded(): Promise<this>;
|
|
200
|
+
get sampleNames(): string[];
|
|
201
|
+
getVariations(name: string): string[];
|
|
202
|
+
start(sample: SampleStart): (time?: number | undefined) => void;
|
|
203
|
+
stop(sample: SampleStop): void;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
type SfzInstrument = {
|
|
207
|
+
name: string;
|
|
208
|
+
formats?: string[];
|
|
209
|
+
baseUrl?: string;
|
|
210
|
+
websfzUrl: string;
|
|
211
|
+
tags?: string[];
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
type Websfz = {
|
|
215
|
+
global: Record<string, string | number>;
|
|
216
|
+
groups: WebsfzGroup[];
|
|
217
|
+
meta: {
|
|
218
|
+
name?: string;
|
|
219
|
+
description?: string;
|
|
220
|
+
license?: string;
|
|
221
|
+
source?: string;
|
|
222
|
+
baseUrl?: string;
|
|
223
|
+
websfzUrl?: string;
|
|
224
|
+
formats?: string[];
|
|
225
|
+
tags?: string[];
|
|
226
|
+
};
|
|
227
|
+
};
|
|
228
|
+
type WebsfzGroup = {
|
|
229
|
+
group_label?: string;
|
|
230
|
+
group?: number;
|
|
231
|
+
hikey?: number;
|
|
232
|
+
hivel?: number;
|
|
233
|
+
lokey?: number;
|
|
234
|
+
lovel?: number;
|
|
235
|
+
off_by?: number;
|
|
236
|
+
off_mode?: "normal";
|
|
237
|
+
pitch_keycenter?: number;
|
|
238
|
+
regions: WebsfzRegion[];
|
|
239
|
+
seq_length?: number;
|
|
240
|
+
trigger?: "first" | "legato";
|
|
241
|
+
volume?: number;
|
|
242
|
+
amp_velcurve_83?: number;
|
|
243
|
+
locc64?: number;
|
|
244
|
+
hicc64?: number;
|
|
245
|
+
hicc107?: number;
|
|
246
|
+
locc107?: number;
|
|
247
|
+
pan_oncc122?: number;
|
|
248
|
+
tune_oncc123?: number;
|
|
249
|
+
eg06_time1_oncc109?: number;
|
|
250
|
+
ampeg_attack_oncc100?: number;
|
|
251
|
+
};
|
|
252
|
+
type WebsfzRegion = {
|
|
253
|
+
end?: number;
|
|
254
|
+
group?: number;
|
|
255
|
+
hivel?: number;
|
|
256
|
+
lovel?: number;
|
|
257
|
+
hikey?: number;
|
|
258
|
+
key?: number;
|
|
259
|
+
lokey?: number;
|
|
260
|
+
off_by?: number;
|
|
261
|
+
pitch_keycenter?: number;
|
|
262
|
+
region_label?: number;
|
|
263
|
+
sample: string;
|
|
264
|
+
seq_position?: number;
|
|
265
|
+
trigger?: "first" | "legato";
|
|
266
|
+
volume?: number;
|
|
267
|
+
locc64?: number;
|
|
268
|
+
hicc64?: number;
|
|
269
|
+
ampeg_attack_oncc100?: number;
|
|
270
|
+
eg06_time1_oncc109?: number;
|
|
271
|
+
pan_oncc122?: number;
|
|
272
|
+
tune_oncc123?: number;
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Splendid Grand Piano options
|
|
277
|
+
*/
|
|
278
|
+
type SfzSamplerConfig = {
|
|
279
|
+
instrument: SfzInstrument | Websfz | string;
|
|
280
|
+
storage?: Storage;
|
|
281
|
+
destination: AudioNode;
|
|
282
|
+
volume: number;
|
|
283
|
+
velocity: number;
|
|
284
|
+
detune: number;
|
|
285
|
+
decayTime: number;
|
|
286
|
+
lpfCutoffHz?: number;
|
|
287
|
+
};
|
|
288
|
+
declare class SfzSampler {
|
|
289
|
+
#private;
|
|
290
|
+
readonly context: AudioContext;
|
|
291
|
+
readonly options: Readonly<Partial<SfzSamplerConfig>>;
|
|
292
|
+
private readonly player;
|
|
293
|
+
readonly load: Promise<this>;
|
|
294
|
+
constructor(context: AudioContext, options: Partial<SfzSamplerConfig> & Pick<SfzSamplerConfig, "instrument">);
|
|
295
|
+
get output(): OutputChannel;
|
|
296
|
+
loaded(): Promise<this>;
|
|
297
|
+
start(sample: SampleStart | string | number): void;
|
|
298
|
+
stop(sample?: SampleStop | string | number): void;
|
|
299
|
+
disconnect(): void;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
declare function getElectricPianoNames(): string[];
|
|
303
|
+
declare class ElectricPiano extends SfzSampler {
|
|
304
|
+
readonly tremolo: Readonly<{
|
|
305
|
+
level: (value: number) => void;
|
|
306
|
+
}>;
|
|
307
|
+
constructor(context: AudioContext, options: Partial<SfzSamplerConfig> & {
|
|
308
|
+
instrument: string;
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
declare function getVersilianInstruments(): Promise<string[]>;
|
|
313
|
+
declare function VcslInstrumentLoader(instrument: string, buffers: AudioBuffers, group: RegionGroup): (context: BaseAudioContext, storage: Storage) => Promise<void[]>;
|
|
314
|
+
type VersilianConfig = {
|
|
315
|
+
instrument: string;
|
|
316
|
+
storage: Storage;
|
|
317
|
+
};
|
|
318
|
+
type VersilianOptions = Partial<VersilianConfig & SampleOptions & ChannelOptions>;
|
|
319
|
+
/**
|
|
320
|
+
* Versilian
|
|
321
|
+
*
|
|
322
|
+
* The Versilian Community Sample Library is an open CC0 general-purpose sample library created by Versilian Studios LLC
|
|
323
|
+
* for the purpose of introducing a set of quality, publicly available samples suitable for use in software and media of all kinds.
|
|
324
|
+
*/
|
|
325
|
+
declare class Versilian implements InternalPlayer {
|
|
326
|
+
private readonly player;
|
|
327
|
+
readonly load: Promise<this>;
|
|
328
|
+
private config;
|
|
329
|
+
constructor(context: BaseAudioContext, options?: VersilianOptions);
|
|
330
|
+
get output(): OutputChannel;
|
|
331
|
+
get buffers(): AudioBuffers;
|
|
332
|
+
get context(): BaseAudioContext;
|
|
333
|
+
start(sample: SampleStart | string | number): (time?: number | undefined) => void;
|
|
334
|
+
stop(sample?: SampleStop | string | number): void;
|
|
335
|
+
disconnect(): void;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
declare function getMalletNames(): string[];
|
|
339
|
+
declare class Mallet extends Versilian {
|
|
340
|
+
constructor(context: AudioContext, options: VersilianOptions);
|
|
341
|
+
}
|
|
342
|
+
declare const NAME_TO_PATH: Record<string, string | undefined>;
|
|
343
|
+
|
|
344
|
+
declare function getMellotronNames(): string[];
|
|
345
|
+
type MellotronConfig = {
|
|
346
|
+
instrument: string;
|
|
347
|
+
storage: Storage;
|
|
348
|
+
};
|
|
349
|
+
type MellotronOptions = Partial<SampleOptions & ChannelOptions & MellotronConfig>;
|
|
350
|
+
declare class Mellotron implements InternalPlayer {
|
|
351
|
+
readonly context: BaseAudioContext;
|
|
352
|
+
private readonly config;
|
|
353
|
+
private readonly player;
|
|
354
|
+
private readonly group;
|
|
355
|
+
readonly load: Promise<this>;
|
|
356
|
+
constructor(context: BaseAudioContext, options: MellotronOptions);
|
|
357
|
+
get buffers(): AudioBuffers;
|
|
358
|
+
get output(): OutputChannel;
|
|
359
|
+
start(sample: SampleStart | string | number): (time?: number | undefined) => void;
|
|
360
|
+
stop(sample?: SampleStop | string | number): void;
|
|
361
|
+
disconnect(): void;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
declare const PARAMS: readonly ["preDelay", "bandwidth", "inputDiffusion1", "inputDiffusion2", "decay", "decayDiffusion1", "decayDiffusion2", "damping", "excursionRate", "excursionDepth", "wet", "dry"];
|
|
365
|
+
declare class Reverb {
|
|
366
|
+
#private;
|
|
367
|
+
readonly input: AudioNode;
|
|
368
|
+
constructor(context: AudioContext);
|
|
369
|
+
get paramNames(): readonly ["preDelay", "bandwidth", "inputDiffusion1", "inputDiffusion2", "decay", "decayDiffusion1", "decayDiffusion2", "damping", "excursionRate", "excursionDepth", "wet", "dry"];
|
|
370
|
+
getParam(name: (typeof PARAMS)[number]): AudioParam | undefined;
|
|
371
|
+
get isReady(): boolean;
|
|
372
|
+
ready(): Promise<this>;
|
|
373
|
+
connect(output: AudioNode): void;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
type SamplerConfig = {
|
|
377
|
+
storage?: Storage;
|
|
378
|
+
detune: number;
|
|
379
|
+
volume: number;
|
|
380
|
+
velocity: number;
|
|
381
|
+
decayTime?: number;
|
|
382
|
+
lpfCutoffHz?: number;
|
|
383
|
+
destination: AudioNode;
|
|
384
|
+
buffers: Record<string | number, string | AudioBuffers> | AudioBuffersLoader;
|
|
385
|
+
volumeToGain: (volume: number) => number;
|
|
386
|
+
};
|
|
387
|
+
/**
|
|
388
|
+
* A Sampler instrument
|
|
389
|
+
*
|
|
390
|
+
* @private
|
|
391
|
+
*/
|
|
392
|
+
declare class Sampler {
|
|
393
|
+
#private;
|
|
394
|
+
readonly context: AudioContext;
|
|
395
|
+
private readonly player;
|
|
396
|
+
readonly load: Promise<this>;
|
|
397
|
+
constructor(context: AudioContext, options?: Partial<SamplerConfig>);
|
|
398
|
+
loaded(): Promise<this>;
|
|
399
|
+
get output(): OutputChannel;
|
|
400
|
+
start(sample: SampleStart | string | number): (time?: number | undefined) => void;
|
|
401
|
+
stop(sample?: SampleStop | string | number): void;
|
|
402
|
+
disconnect(): void;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
declare function getSmolkenNames(): string[];
|
|
406
|
+
type SmolkenConfig = {
|
|
407
|
+
instrument: string;
|
|
408
|
+
storage: Storage;
|
|
409
|
+
};
|
|
410
|
+
type SmolkenOptions = Partial<SmolkenConfig & SampleOptions & ChannelOptions>;
|
|
411
|
+
declare class Smolken implements InternalPlayer {
|
|
412
|
+
private readonly player;
|
|
413
|
+
private readonly group;
|
|
414
|
+
readonly load: Promise<this>;
|
|
415
|
+
private config;
|
|
416
|
+
private seqNum;
|
|
417
|
+
constructor(context: BaseAudioContext, options?: SmolkenOptions);
|
|
418
|
+
get output(): OutputChannel;
|
|
419
|
+
get buffers(): AudioBuffers;
|
|
420
|
+
get context(): BaseAudioContext;
|
|
421
|
+
start(sample: SampleStart | string | number): (time?: number) => void;
|
|
422
|
+
stop(sample?: SampleStop | string | number): void;
|
|
423
|
+
disconnect(): void;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
declare function getSoundfontKits(): string[];
|
|
427
|
+
declare function getSoundfontNames(): string[];
|
|
428
|
+
type SoundfontConfig = {
|
|
429
|
+
kit: "FluidR3_GM" | "MusyngKite" | string;
|
|
430
|
+
instrument?: string;
|
|
431
|
+
instrumentUrl: string;
|
|
432
|
+
storage: Storage;
|
|
433
|
+
extraGain: number;
|
|
434
|
+
loadLoopData: boolean;
|
|
435
|
+
loopDataUrl?: string;
|
|
436
|
+
};
|
|
437
|
+
type SoundfontOptions = Partial<SoundfontConfig & SampleOptions & ChannelOptions>;
|
|
438
|
+
declare class Soundfont {
|
|
439
|
+
#private;
|
|
440
|
+
readonly context: AudioContext;
|
|
441
|
+
readonly config: Readonly<SoundfontConfig>;
|
|
442
|
+
private readonly player;
|
|
443
|
+
readonly load: Promise<this>;
|
|
444
|
+
readonly group: RegionGroup;
|
|
445
|
+
constructor(context: AudioContext, options: SoundfontOptions);
|
|
446
|
+
get output(): OutputChannel;
|
|
447
|
+
get hasLoops(): boolean;
|
|
448
|
+
loaded(): Promise<this>;
|
|
449
|
+
disconnect(): void;
|
|
450
|
+
start(sample: SampleStart | string | number): (time?: number | undefined) => void;
|
|
451
|
+
stop(sample?: SampleStop | string | number): void;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Splendid Grand Piano options
|
|
456
|
+
*/
|
|
457
|
+
type SplendidGrandPianoConfig = {
|
|
458
|
+
baseUrl: string;
|
|
459
|
+
destination: AudioNode;
|
|
460
|
+
storage: Storage;
|
|
461
|
+
detune: number;
|
|
462
|
+
volume: number;
|
|
463
|
+
velocity: number;
|
|
464
|
+
decayTime?: number;
|
|
465
|
+
lpfCutoffHz?: number;
|
|
466
|
+
};
|
|
467
|
+
declare class SplendidGrandPiano {
|
|
468
|
+
#private;
|
|
469
|
+
readonly context: AudioContext;
|
|
470
|
+
options: Readonly<SplendidGrandPianoConfig>;
|
|
471
|
+
private readonly player;
|
|
472
|
+
readonly load: Promise<this>;
|
|
473
|
+
constructor(context: AudioContext, options?: Partial<SplendidGrandPianoConfig>);
|
|
474
|
+
get output(): OutputChannel;
|
|
475
|
+
get buffers(): AudioBuffers;
|
|
476
|
+
loaded(): Promise<this>;
|
|
477
|
+
start(sampleOrNote: SampleStart | number | string): (time?: number | undefined) => void;
|
|
478
|
+
stop(sample?: SampleStop | number | string): void;
|
|
479
|
+
}
|
|
480
|
+
declare const LAYERS: ({
|
|
481
|
+
name: string;
|
|
482
|
+
vel_range: number[];
|
|
483
|
+
cutoff: number;
|
|
484
|
+
samples: (string | number)[][];
|
|
485
|
+
} | {
|
|
486
|
+
name: string;
|
|
487
|
+
vel_range: number[];
|
|
488
|
+
samples: (string | number)[][];
|
|
489
|
+
cutoff?: undefined;
|
|
490
|
+
})[];
|
|
491
|
+
|
|
492
|
+
export { CacheStorage, DrumMachine, DrumMachineConfig, ElectricPiano, HttpStorage, LAYERS, Mallet, Mellotron, MellotronConfig, MellotronOptions, NAME_TO_PATH, Reverb, Sampler, SamplerConfig, Smolken, SmolkenConfig, SmolkenOptions, Soundfont, SoundfontOptions, SplendidGrandPiano, SplendidGrandPianoConfig, Storage, StorageResponse, VcslInstrumentLoader, Versilian, VersilianConfig, VersilianOptions, getDrumMachineNames, getElectricPianoNames, getMalletNames, getMellotronNames, getSmolkenNames, getSoundfontKits, getSoundfontNames, getVersilianInstruments };
|