smplr 0.6.1 → 0.8.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 +82 -37
- package/dist/index.d.ts +151 -79
- package/dist/index.js +1023 -504
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1021 -504
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,6 +34,10 @@ piano.start({ note: "C4" });
|
|
|
34
34
|
|
|
35
35
|
See demo: https://danigb.github.io/smplr/
|
|
36
36
|
|
|
37
|
+
`smplr` is still under development and features are considered unstable until v 1.0
|
|
38
|
+
|
|
39
|
+
Read [CHANGELOG](https://github.com/danigb/smplr/blob/main/CHANGELOG.md) for changes.
|
|
40
|
+
|
|
37
41
|
#### Library goals
|
|
38
42
|
|
|
39
43
|
- No setup: specifically, all samples are online, so no need for a server.
|
|
@@ -48,13 +52,11 @@ Install with npm or your favourite package manager:
|
|
|
48
52
|
npm i smplr
|
|
49
53
|
```
|
|
50
54
|
|
|
51
|
-
Samples are
|
|
52
|
-
|
|
53
|
-
`smplr` is still under development and features are considered unstable. See [CHANGELOG](https://github.com/danigb/smplr/blob/main/CHANGELOG.md) for changes.
|
|
55
|
+
Samples are stored at https://github.com/danigb/samples and there is no need to install them. Kudos to all samplers 🙌
|
|
54
56
|
|
|
55
57
|
## Documentation
|
|
56
58
|
|
|
57
|
-
### Create an instrument
|
|
59
|
+
### Create and load an instrument
|
|
58
60
|
|
|
59
61
|
All instruments follows the same pattern: `new Instrument(context, options?)`. For example:
|
|
60
62
|
|
|
@@ -68,10 +70,10 @@ const marimba = new Soundfont(context, { instrument: "marimba" });
|
|
|
68
70
|
|
|
69
71
|
#### Wait for audio loading
|
|
70
72
|
|
|
71
|
-
You can start playing notes as soon as one audio is loaded. But if you want to wait for all of them, you can use the `
|
|
73
|
+
You can start playing notes as soon as one audio is loaded. But if you want to wait for all of them, you can use the `load` property that returns a promise:
|
|
72
74
|
|
|
73
75
|
```js
|
|
74
|
-
piano.
|
|
76
|
+
piano.load.then(() => {
|
|
75
77
|
// now the piano is fully loaded
|
|
76
78
|
});
|
|
77
79
|
```
|
|
@@ -79,28 +81,9 @@ piano.loaded().then(() => {
|
|
|
79
81
|
Since the promise returns the instrument instance, you can create and wait in a single line:
|
|
80
82
|
|
|
81
83
|
```js
|
|
82
|
-
const piano = await new SplendidGrandPiano(context).
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
#### Cache requests
|
|
86
|
-
|
|
87
|
-
[Experimental]
|
|
88
|
-
|
|
89
|
-
If you use default samples, they are stored at github pages. Github rate limits the number of requests per second. That could be a problem, specially if you're using a development environment with hot reload (like most React frameworks).
|
|
90
|
-
|
|
91
|
-
If you want to cache samples on the browser you can use a `CacheStorage` object:
|
|
92
|
-
|
|
93
|
-
```ts
|
|
94
|
-
import { SplendidGrandPiano, CacheStorage } from "smplr";
|
|
95
|
-
|
|
96
|
-
const context = new AudioContext();
|
|
97
|
-
const storage = new CacheStorage();
|
|
98
|
-
// First time the instrument loads, will fetch the samples from http. Subsequent times from cache.
|
|
99
|
-
const piano = new SplendidGrandPiano(context, { storage });
|
|
84
|
+
const piano = await new SplendidGrandPiano(context).load;
|
|
100
85
|
```
|
|
101
86
|
|
|
102
|
-
⚠️ `CacheStorage` is based on [Cache API](https://developer.mozilla.org/en-US/docs/Web/API/Cache) and only works in secure environments that runs with `https`. Read your framework documentation for setup instructions. For example, in nextjs you can use https://www.npmjs.com/package/next-dev-https. For vite there's https://github.com/liuweiGL/vite-plugin-mkcert. Find the appropriate solution for your environment.
|
|
103
|
-
|
|
104
87
|
### Play
|
|
105
88
|
|
|
106
89
|
#### Start and stop notes
|
|
@@ -149,23 +132,23 @@ const now = context.currentTime;
|
|
|
149
132
|
});
|
|
150
133
|
```
|
|
151
134
|
|
|
152
|
-
####
|
|
135
|
+
#### Looping
|
|
153
136
|
|
|
154
|
-
You can
|
|
137
|
+
You can loop a note by using `loop`, `loopStart` and `loopEnd`:
|
|
155
138
|
|
|
156
139
|
```js
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
140
|
+
const sampler = new Sampler(audioContext, { string: "mi-long-sample.mp3" });
|
|
141
|
+
sampler.start({
|
|
142
|
+
note: "string",
|
|
143
|
+
loop: "true",
|
|
144
|
+
loopStart: 1.0,
|
|
145
|
+
loopEnd: 9.0,
|
|
163
146
|
});
|
|
164
147
|
```
|
|
165
148
|
|
|
166
|
-
|
|
149
|
+
If `loopStart` or `loopEnd` is not specified it will be use by default 0 and total duration respectively.
|
|
167
150
|
|
|
168
|
-
|
|
151
|
+
#### Change volume
|
|
169
152
|
|
|
170
153
|
Instrument `output` attribute represents the main output of the instrument. `output.setVolume` method accepts a number where 0 means no volume, and 127 is max volume without amplification:
|
|
171
154
|
|
|
@@ -194,6 +177,41 @@ To change the mix level, use `output.sendEffect(name, mix)`:
|
|
|
194
177
|
piano.output.sendEffect("reverb", 0.5);
|
|
195
178
|
```
|
|
196
179
|
|
|
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
|
+
### Experimental features
|
|
197
|
+
|
|
198
|
+
#### Cache requests
|
|
199
|
+
|
|
200
|
+
If you use default samples, they are stored at github pages. Github rate limits the number of requests per second. That could be a problem, specially if you're using a development environment with hot reload (like most React frameworks).
|
|
201
|
+
|
|
202
|
+
If you want to cache samples on the browser you can use a `CacheStorage` object:
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
import { SplendidGrandPiano, CacheStorage } from "smplr";
|
|
206
|
+
|
|
207
|
+
const context = new AudioContext();
|
|
208
|
+
const storage = new CacheStorage();
|
|
209
|
+
// First time the instrument loads, will fetch the samples from http. Subsequent times from cache.
|
|
210
|
+
const piano = new SplendidGrandPiano(context, { storage });
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
⚠️ `CacheStorage` is based on [Cache API](https://developer.mozilla.org/en-US/docs/Web/API/Cache) and only works in secure environments that runs with `https`. Read your framework documentation for setup instructions. For example, in nextjs you can use https://www.npmjs.com/package/next-dev-https. For vite there's https://github.com/liuweiGL/vite-plugin-mkcert. Find the appropriate solution for your environment.
|
|
214
|
+
|
|
197
215
|
## Instruments
|
|
198
216
|
|
|
199
217
|
### Sampler
|
|
@@ -242,11 +260,24 @@ Alternatively, you can pass your custom url as the instrument. In that case, the
|
|
|
242
260
|
|
|
243
261
|
```js
|
|
244
262
|
const marimba = new Soundfont(context, {
|
|
245
|
-
|
|
263
|
+
instrumentUrl:
|
|
246
264
|
"https://gleitz.github.io/midi-js-soundfonts/MusyngKite/marimba-mp3.js",
|
|
247
265
|
});
|
|
248
266
|
```
|
|
249
267
|
|
|
268
|
+
#### Looping (experimental)
|
|
269
|
+
|
|
270
|
+
You can enable note looping to make note names indefinitely long by loading loop data:
|
|
271
|
+
|
|
272
|
+
```js
|
|
273
|
+
const marimba = new Soundfont(context, {
|
|
274
|
+
instrument: "cello",
|
|
275
|
+
loadLoopData: true,
|
|
276
|
+
});
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Bear in mind that currently that feature produces click on lot of instruments.
|
|
280
|
+
|
|
250
281
|
### Piano
|
|
251
282
|
|
|
252
283
|
A sampled acoustic piano. It uses Steinway samples with 4 velocity layers from
|
|
@@ -299,6 +330,20 @@ const mallet = new Mallet(new AudioContext(), {
|
|
|
299
330
|
});
|
|
300
331
|
```
|
|
301
332
|
|
|
333
|
+
### Mellotron
|
|
334
|
+
|
|
335
|
+
Samples from [archive.org](https://archive.org/details/mellotron-archive-cd-rom-nki-wav.-7z)
|
|
336
|
+
|
|
337
|
+
```js
|
|
338
|
+
import { Mellotron, getMellotronNames } from "smplr";
|
|
339
|
+
|
|
340
|
+
const instruments = getMellotronNames();
|
|
341
|
+
|
|
342
|
+
const mallet = new Mellotron(new AudioContext(), {
|
|
343
|
+
instrument: instruments[0],
|
|
344
|
+
});
|
|
345
|
+
```
|
|
346
|
+
|
|
302
347
|
### Drum Machines
|
|
303
348
|
|
|
304
349
|
Sampled drum machines. Samples from different sources:
|
package/dist/index.d.ts
CHANGED
|
@@ -1,19 +1,3 @@
|
|
|
1
|
-
type StorageResponse = {
|
|
2
|
-
readonly status: number;
|
|
3
|
-
arrayBuffer(): Promise<ArrayBuffer>;
|
|
4
|
-
json(): Promise<any>;
|
|
5
|
-
text(): Promise<string>;
|
|
6
|
-
};
|
|
7
|
-
type Storage = {
|
|
8
|
-
fetch: (url: string) => Promise<StorageResponse>;
|
|
9
|
-
};
|
|
10
|
-
declare const HttpStorage: Storage;
|
|
11
|
-
declare class CacheStorage implements Storage {
|
|
12
|
-
#private;
|
|
13
|
-
constructor(name?: string);
|
|
14
|
-
fetch(url: string): Promise<StorageResponse>;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
1
|
type AudioInsert = {
|
|
18
2
|
input: AudioNode;
|
|
19
3
|
output: AudioNode;
|
|
@@ -24,15 +8,17 @@ type ChannelOptions = {
|
|
|
24
8
|
volume: number;
|
|
25
9
|
volumeToGain: (volume: number) => number;
|
|
26
10
|
};
|
|
11
|
+
type OutputChannel = Omit<Channel, "input">;
|
|
27
12
|
/**
|
|
13
|
+
* An output channel with audio effects
|
|
28
14
|
* @private
|
|
29
15
|
*/
|
|
30
16
|
declare class Channel {
|
|
31
17
|
#private;
|
|
32
|
-
readonly context:
|
|
18
|
+
readonly context: BaseAudioContext;
|
|
33
19
|
readonly setVolume: (vol: number) => void;
|
|
34
20
|
readonly input: AudioNode;
|
|
35
|
-
constructor(context:
|
|
21
|
+
constructor(context: BaseAudioContext, options: Partial<ChannelOptions>);
|
|
36
22
|
addInsert(effect: AudioNode | AudioInsert): void;
|
|
37
23
|
addEffect(name: string, effect: AudioNode | {
|
|
38
24
|
input: AudioNode;
|
|
@@ -41,72 +27,90 @@ declare class Channel {
|
|
|
41
27
|
disconnect(): void;
|
|
42
28
|
}
|
|
43
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
|
+
|
|
44
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>;
|
|
45
51
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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;
|
|
50
64
|
|
|
51
65
|
/**
|
|
52
|
-
*
|
|
66
|
+
* @private
|
|
53
67
|
*/
|
|
54
|
-
type
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
decayTime?: number;
|
|
61
|
-
lpfCutoffHz?: number;
|
|
62
|
-
destination: AudioNode;
|
|
63
|
-
buffers: Record<string | number, string | AudioBuffers> | SamplerAudioLoader;
|
|
64
|
-
volumeToGain: (volume: number) => number;
|
|
65
|
-
noteToSample: (note: SamplerNote, buffers: AudioBuffers, config: SamplerConfig) => [string | number, number];
|
|
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;
|
|
66
74
|
};
|
|
67
|
-
type
|
|
75
|
+
type SampleStop = {
|
|
76
|
+
stopId?: string | number;
|
|
77
|
+
time?: number;
|
|
78
|
+
};
|
|
79
|
+
type SampleOptions = {
|
|
68
80
|
decayTime?: number;
|
|
69
81
|
detune?: number;
|
|
70
|
-
duration?: number;
|
|
82
|
+
duration?: number | null;
|
|
83
|
+
velocity?: number;
|
|
71
84
|
lpfCutoffHz?: number;
|
|
85
|
+
loop?: boolean;
|
|
86
|
+
loopStart?: number;
|
|
87
|
+
loopEnd?: number;
|
|
88
|
+
};
|
|
89
|
+
type SampleStart = {
|
|
90
|
+
name?: string;
|
|
72
91
|
note: string | number;
|
|
73
|
-
onEnded?: (
|
|
92
|
+
onEnded?: (sample: SampleStart) => void;
|
|
93
|
+
stop?: Subscribe<number>;
|
|
74
94
|
stopId?: string | number;
|
|
75
95
|
time?: number;
|
|
76
|
-
|
|
77
|
-
};
|
|
78
|
-
/**
|
|
79
|
-
* A Sampler instrument
|
|
80
|
-
*
|
|
81
|
-
* @private
|
|
82
|
-
*/
|
|
83
|
-
declare class Sampler {
|
|
84
|
-
#private;
|
|
85
|
-
readonly context: AudioContext;
|
|
86
|
-
readonly output: Omit<Channel, "input">;
|
|
87
|
-
readonly buffers: AudioBuffers;
|
|
88
|
-
constructor(context: AudioContext, options?: Partial<SamplerConfig>);
|
|
89
|
-
loaded(): Promise<this>;
|
|
90
|
-
start(note: SamplerNote | string | number): (time?: number | undefined) => void;
|
|
91
|
-
stop(note?: StopSample | string | number): void;
|
|
92
|
-
}
|
|
96
|
+
} & SampleOptions;
|
|
93
97
|
|
|
94
98
|
declare function getDrumMachineNames(): string[];
|
|
95
|
-
type DrumMachineConfig = {
|
|
99
|
+
type DrumMachineConfig = ChannelOptions & SampleOptions & {
|
|
96
100
|
instrument: string;
|
|
97
|
-
destination: AudioNode;
|
|
98
101
|
storage?: Storage;
|
|
99
|
-
detune: number;
|
|
100
|
-
volume: number;
|
|
101
|
-
velocity: number;
|
|
102
|
-
decayTime?: number;
|
|
103
|
-
lpfCutoffHz?: number;
|
|
104
102
|
};
|
|
105
|
-
declare class DrumMachine
|
|
103
|
+
declare class DrumMachine {
|
|
106
104
|
#private;
|
|
105
|
+
private readonly player;
|
|
106
|
+
readonly load: Promise<this>;
|
|
107
|
+
readonly output: OutputChannel;
|
|
107
108
|
constructor(context: AudioContext, options?: Partial<DrumMachineConfig>);
|
|
109
|
+
loaded(): Promise<this>;
|
|
108
110
|
get sampleNames(): string[];
|
|
109
111
|
getVariations(name: string): string[];
|
|
112
|
+
start(sample: SampleStart): (time?: number | undefined) => void;
|
|
113
|
+
stop(sample: SampleStop): void;
|
|
110
114
|
}
|
|
111
115
|
|
|
112
116
|
type SfzInstrument = {
|
|
@@ -194,12 +198,14 @@ type SfzSamplerConfig = {
|
|
|
194
198
|
declare class SfzSampler {
|
|
195
199
|
#private;
|
|
196
200
|
readonly context: AudioContext;
|
|
197
|
-
readonly
|
|
198
|
-
readonly
|
|
201
|
+
readonly options: Readonly<Partial<SfzSamplerConfig>>;
|
|
202
|
+
private readonly player;
|
|
203
|
+
readonly load: Promise<this>;
|
|
199
204
|
constructor(context: AudioContext, options: Partial<SfzSamplerConfig> & Pick<SfzSamplerConfig, "instrument">);
|
|
205
|
+
get output(): OutputChannel;
|
|
200
206
|
loaded(): Promise<this>;
|
|
201
|
-
start(
|
|
202
|
-
stop(
|
|
207
|
+
start(sample: SampleStart | string | number): void;
|
|
208
|
+
stop(sample?: SampleStop | string | number): void;
|
|
203
209
|
disconnect(): void;
|
|
204
210
|
}
|
|
205
211
|
|
|
@@ -221,6 +227,26 @@ declare class Mallet extends SfzSampler {
|
|
|
221
227
|
}
|
|
222
228
|
declare const NAME_TO_PATH: Record<string, string | undefined>;
|
|
223
229
|
|
|
230
|
+
declare function getMellotronNames(): string[];
|
|
231
|
+
type MellotronConfig = {
|
|
232
|
+
instrument: string;
|
|
233
|
+
storage: Storage;
|
|
234
|
+
};
|
|
235
|
+
type MellotronOptions = Partial<SampleOptions & ChannelOptions & MellotronConfig>;
|
|
236
|
+
declare class Mellotron implements InternalPlayer {
|
|
237
|
+
readonly context: BaseAudioContext;
|
|
238
|
+
private readonly config;
|
|
239
|
+
private readonly player;
|
|
240
|
+
private readonly layer;
|
|
241
|
+
readonly load: Promise<this>;
|
|
242
|
+
constructor(context: BaseAudioContext, options: MellotronOptions);
|
|
243
|
+
get buffers(): AudioBuffers;
|
|
244
|
+
get output(): OutputChannel;
|
|
245
|
+
start(sample: SampleStart | string | number): (time?: number | undefined) => void;
|
|
246
|
+
stop(sample?: SampleStop | string | number): void;
|
|
247
|
+
disconnect(): void;
|
|
248
|
+
}
|
|
249
|
+
|
|
224
250
|
declare const PARAMS: readonly ["preDelay", "bandwidth", "inputDiffusion1", "inputDiffusion2", "decay", "decayDiffusion1", "decayDiffusion2", "damping", "excursionRate", "excursionDepth", "wet", "dry"];
|
|
225
251
|
declare class Reverb {
|
|
226
252
|
#private;
|
|
@@ -233,25 +259,61 @@ declare class Reverb {
|
|
|
233
259
|
connect(output: AudioNode): void;
|
|
234
260
|
}
|
|
235
261
|
|
|
236
|
-
type
|
|
237
|
-
kit: "FluidR3_GM" | "MusyngKite" | string;
|
|
238
|
-
instrument: string;
|
|
262
|
+
type SamplerConfig = {
|
|
239
263
|
storage?: Storage;
|
|
240
|
-
destination: AudioNode;
|
|
241
264
|
detune: number;
|
|
242
265
|
volume: number;
|
|
243
266
|
velocity: number;
|
|
244
267
|
decayTime?: number;
|
|
245
268
|
lpfCutoffHz?: number;
|
|
246
|
-
|
|
269
|
+
destination: AudioNode;
|
|
270
|
+
buffers: Record<string | number, string | AudioBuffers> | AudioBuffersLoader;
|
|
271
|
+
volumeToGain: (volume: number) => number;
|
|
247
272
|
};
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
273
|
+
/**
|
|
274
|
+
* A Sampler instrument
|
|
275
|
+
*
|
|
276
|
+
* @private
|
|
277
|
+
*/
|
|
278
|
+
declare class Sampler {
|
|
279
|
+
#private;
|
|
280
|
+
readonly context: AudioContext;
|
|
281
|
+
private readonly player;
|
|
282
|
+
readonly load: Promise<this>;
|
|
283
|
+
constructor(context: AudioContext, options?: Partial<SamplerConfig>);
|
|
284
|
+
loaded(): Promise<this>;
|
|
285
|
+
get output(): OutputChannel;
|
|
286
|
+
start(sample: SampleStart | string | number): (time?: number | undefined) => void;
|
|
287
|
+
stop(sample?: SampleStop | string | number): void;
|
|
288
|
+
disconnect(): void;
|
|
252
289
|
}
|
|
290
|
+
|
|
253
291
|
declare function getSoundfontKits(): string[];
|
|
254
292
|
declare function getSoundfontNames(): string[];
|
|
293
|
+
type SoundfontConfig = {
|
|
294
|
+
kit: "FluidR3_GM" | "MusyngKite" | string;
|
|
295
|
+
instrument?: string;
|
|
296
|
+
instrumentUrl: string;
|
|
297
|
+
storage: Storage;
|
|
298
|
+
extraGain: number;
|
|
299
|
+
loadLoopData: boolean;
|
|
300
|
+
loopDataUrl?: string;
|
|
301
|
+
};
|
|
302
|
+
type SoundfontOptions = Partial<SoundfontConfig & SampleOptions & ChannelOptions>;
|
|
303
|
+
declare class Soundfont {
|
|
304
|
+
#private;
|
|
305
|
+
readonly context: AudioContext;
|
|
306
|
+
readonly config: Readonly<SoundfontConfig>;
|
|
307
|
+
private readonly player;
|
|
308
|
+
readonly load: Promise<unknown>;
|
|
309
|
+
constructor(context: AudioContext, options: SoundfontOptions);
|
|
310
|
+
get output(): OutputChannel;
|
|
311
|
+
loaded(): Promise<unknown>;
|
|
312
|
+
get hasLoops(): boolean;
|
|
313
|
+
disconnect(): void;
|
|
314
|
+
start(sample: SampleStart): (time?: number | undefined) => void;
|
|
315
|
+
stop(sample?: SampleStop | string | number): void;
|
|
316
|
+
}
|
|
255
317
|
|
|
256
318
|
/**
|
|
257
319
|
* Splendid Grand Piano options
|
|
@@ -259,15 +321,25 @@ declare function getSoundfontNames(): string[];
|
|
|
259
321
|
type SplendidGrandPianoConfig = {
|
|
260
322
|
baseUrl: string;
|
|
261
323
|
destination: AudioNode;
|
|
262
|
-
storage
|
|
324
|
+
storage: Storage;
|
|
263
325
|
detune: number;
|
|
264
326
|
volume: number;
|
|
265
327
|
velocity: number;
|
|
266
328
|
decayTime?: number;
|
|
267
329
|
lpfCutoffHz?: number;
|
|
268
330
|
};
|
|
269
|
-
declare class SplendidGrandPiano
|
|
331
|
+
declare class SplendidGrandPiano {
|
|
332
|
+
#private;
|
|
333
|
+
readonly context: AudioContext;
|
|
334
|
+
options: Readonly<SplendidGrandPianoConfig>;
|
|
335
|
+
private readonly player;
|
|
336
|
+
readonly load: Promise<this>;
|
|
270
337
|
constructor(context: AudioContext, options?: Partial<SplendidGrandPianoConfig>);
|
|
338
|
+
get output(): OutputChannel;
|
|
339
|
+
get buffers(): AudioBuffers;
|
|
340
|
+
loaded(): Promise<this>;
|
|
341
|
+
start(sampleOrNote: SampleStart | number | string): (time?: number | undefined) => void;
|
|
342
|
+
stop(sample?: SampleStop | number | string): void;
|
|
271
343
|
}
|
|
272
344
|
declare const LAYERS: ({
|
|
273
345
|
name: string;
|
|
@@ -281,4 +353,4 @@ declare const LAYERS: ({
|
|
|
281
353
|
cutoff?: undefined;
|
|
282
354
|
})[];
|
|
283
355
|
|
|
284
|
-
export { CacheStorage, DrumMachine, DrumMachineConfig, ElectricPiano, HttpStorage, LAYERS, Mallet, NAME_TO_PATH, Reverb, Sampler,
|
|
356
|
+
export { CacheStorage, DrumMachine, DrumMachineConfig, ElectricPiano, HttpStorage, LAYERS, Mallet, Mellotron, MellotronConfig, MellotronOptions, NAME_TO_PATH, Reverb, Sampler, SamplerConfig, Soundfont, SoundfontOptions, SplendidGrandPiano, SplendidGrandPianoConfig, Storage, StorageResponse, getDrumMachineNames, getElectricPianoNames, getMalletNames, getMellotronNames, getSoundfontKits, getSoundfontNames };
|