smplr 0.11.2 → 0.12.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 +45 -0
- package/dist/index.d.mts +31 -59
- package/dist/index.d.ts +31 -59
- package/dist/index.js +26 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +26 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -126,6 +126,27 @@ All instruments share some configuration options that are passed as second argum
|
|
|
126
126
|
- `onStart`: a function that is called when starting a note. It receives the note started as parameter. Bear in mind that the time this function is called is not precise, and it's determined by lookahead.
|
|
127
127
|
- `onEnded`: a function that is called when the note ends. It receives the started note as parameter.
|
|
128
128
|
|
|
129
|
+
#### Usage with standardized-audio-context
|
|
130
|
+
|
|
131
|
+
This package should be compatible with [standardized-audio-context](https://github.com/chrisguttandin/standardized-audio-context):
|
|
132
|
+
|
|
133
|
+
```js
|
|
134
|
+
import { AudioContext } from "standardized-audio-context";
|
|
135
|
+
|
|
136
|
+
const context = new AudioContext();
|
|
137
|
+
const piano = new SplendidGrandPiano(context);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
However, if you are using Typescript, you might need to "force cast" the types:
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
import { Soundfont } from "smplr";
|
|
144
|
+
import { AudioContext as StandardizedAudioContext } from "standardized-audio-context";
|
|
145
|
+
|
|
146
|
+
const context = new StandardizedAudioContext() as unknown as AudioContext;
|
|
147
|
+
const marimba = new Soundfont(context, { instrument: "marimba" });
|
|
148
|
+
```
|
|
149
|
+
|
|
129
150
|
### Play
|
|
130
151
|
|
|
131
152
|
#### Start and stop notes
|
|
@@ -350,6 +371,30 @@ const piano = new SplendidGrandPiano(new AudioContext());
|
|
|
350
371
|
piano.start({ note: "C4" });
|
|
351
372
|
```
|
|
352
373
|
|
|
374
|
+
#### SplendidGrandPiano constructor
|
|
375
|
+
|
|
376
|
+
The second argument of the constructor accepts the following options:
|
|
377
|
+
|
|
378
|
+
- `baseUrl`:
|
|
379
|
+
- `detune`: global detune in cents (0 if not specified)
|
|
380
|
+
- `velocity`: default velocity (100 if not specified)
|
|
381
|
+
- `volume`: default volume (100 if not specified)
|
|
382
|
+
- `decayTime`: default decay time (0.5 seconds)
|
|
383
|
+
- `notesToLoad`: an object with the following shape: `{ notes: number[], velocityRange: [number, number]}` to specify a subset of notes to load
|
|
384
|
+
|
|
385
|
+
Example:
|
|
386
|
+
|
|
387
|
+
```ts
|
|
388
|
+
const piano = new SplendidGrandPiano(context, {
|
|
389
|
+
detune: -20,
|
|
390
|
+
volume: 80,
|
|
391
|
+
notesToLoad: {
|
|
392
|
+
notes: [60],
|
|
393
|
+
velocityRange: [1, 127],
|
|
394
|
+
},
|
|
395
|
+
});
|
|
396
|
+
```
|
|
397
|
+
|
|
353
398
|
### Electric Piano
|
|
354
399
|
|
|
355
400
|
A sampled electric pianos. Samples from https://github.com/sfzinstruments/GregSullivan.E-Pianos
|
package/dist/index.d.mts
CHANGED
|
@@ -49,34 +49,6 @@ type AudioBuffers = Record<string | number, AudioBuffer | undefined>;
|
|
|
49
49
|
*/
|
|
50
50
|
type AudioBuffersLoader = (context: BaseAudioContext, buffers: AudioBuffers) => Promise<void>;
|
|
51
51
|
|
|
52
|
-
type StorageResponse$1 = {
|
|
53
|
-
readonly status: number;
|
|
54
|
-
arrayBuffer(): Promise<ArrayBuffer>;
|
|
55
|
-
json(): Promise<any>;
|
|
56
|
-
text(): Promise<string>;
|
|
57
|
-
};
|
|
58
|
-
type Storage$1 = {
|
|
59
|
-
fetch: (url: string) => Promise<StorageResponse$1>;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
type AudioBuffers$1 = Record<string | number, AudioBuffer | undefined>;
|
|
63
|
-
/**
|
|
64
|
-
* A function that downloads audio into a AudioBuffers
|
|
65
|
-
*/
|
|
66
|
-
type AudioBuffersLoader$1 = (context: BaseAudioContext, buffers: AudioBuffers$1) => Promise<void>;
|
|
67
|
-
|
|
68
|
-
type SamplerConfig$1 = {
|
|
69
|
-
storage?: Storage$1;
|
|
70
|
-
detune: number;
|
|
71
|
-
volume: number;
|
|
72
|
-
velocity: number;
|
|
73
|
-
decayTime?: number;
|
|
74
|
-
lpfCutoffHz?: number;
|
|
75
|
-
destination: AudioNode;
|
|
76
|
-
buffers: Record<string | number, string | AudioBuffers$1> | AudioBuffersLoader$1;
|
|
77
|
-
volumeToGain: (volume: number) => number;
|
|
78
|
-
};
|
|
79
|
-
|
|
80
52
|
/**
|
|
81
53
|
* A function to unsubscribe from an event or control
|
|
82
54
|
*/
|
|
@@ -214,6 +186,35 @@ type RegionGroup = {
|
|
|
214
186
|
sample: Partial<SampleOptions>;
|
|
215
187
|
};
|
|
216
188
|
|
|
189
|
+
type SamplerConfig = {
|
|
190
|
+
storage?: Storage;
|
|
191
|
+
detune: number;
|
|
192
|
+
volume: number;
|
|
193
|
+
velocity: number;
|
|
194
|
+
decayTime?: number;
|
|
195
|
+
lpfCutoffHz?: number;
|
|
196
|
+
destination: AudioNode;
|
|
197
|
+
buffers: Record<string | number, string | AudioBuffers> | AudioBuffersLoader;
|
|
198
|
+
volumeToGain: (volume: number) => number;
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* A Sampler instrument
|
|
202
|
+
*
|
|
203
|
+
* @private
|
|
204
|
+
*/
|
|
205
|
+
declare class Sampler {
|
|
206
|
+
#private;
|
|
207
|
+
readonly context: AudioContext;
|
|
208
|
+
private readonly player;
|
|
209
|
+
readonly load: Promise<this>;
|
|
210
|
+
constructor(context: AudioContext, options?: Partial<SamplerConfig>);
|
|
211
|
+
loaded(): Promise<this>;
|
|
212
|
+
get output(): OutputChannel;
|
|
213
|
+
start(sample: SampleStart | string | number): (time?: number | undefined) => void;
|
|
214
|
+
stop(sample?: SampleStop | string | number): void;
|
|
215
|
+
disconnect(): void;
|
|
216
|
+
}
|
|
217
|
+
|
|
217
218
|
type QueuedPlayerConfig = {
|
|
218
219
|
scheduleLookaheadMs: number;
|
|
219
220
|
scheduleIntervalMs: number;
|
|
@@ -221,7 +222,7 @@ type QueuedPlayerConfig = {
|
|
|
221
222
|
onEnded?: (sample: SampleStart) => void;
|
|
222
223
|
};
|
|
223
224
|
|
|
224
|
-
type DefaultPlayerConfig = ChannelConfig & SamplerConfig
|
|
225
|
+
type DefaultPlayerConfig = ChannelConfig & SamplerConfig & QueuedPlayerConfig;
|
|
225
226
|
|
|
226
227
|
declare function getDrumMachineNames(): string[];
|
|
227
228
|
type DrumMachineConfig = {
|
|
@@ -410,35 +411,6 @@ declare class Reverb {
|
|
|
410
411
|
connect(output: AudioNode): void;
|
|
411
412
|
}
|
|
412
413
|
|
|
413
|
-
type SamplerConfig = {
|
|
414
|
-
storage?: Storage;
|
|
415
|
-
detune: number;
|
|
416
|
-
volume: number;
|
|
417
|
-
velocity: number;
|
|
418
|
-
decayTime?: number;
|
|
419
|
-
lpfCutoffHz?: number;
|
|
420
|
-
destination: AudioNode;
|
|
421
|
-
buffers: Record<string | number, string | AudioBuffers> | AudioBuffersLoader;
|
|
422
|
-
volumeToGain: (volume: number) => number;
|
|
423
|
-
};
|
|
424
|
-
/**
|
|
425
|
-
* A Sampler instrument
|
|
426
|
-
*
|
|
427
|
-
* @private
|
|
428
|
-
*/
|
|
429
|
-
declare class Sampler {
|
|
430
|
-
#private;
|
|
431
|
-
readonly context: AudioContext;
|
|
432
|
-
private readonly player;
|
|
433
|
-
readonly load: Promise<this>;
|
|
434
|
-
constructor(context: AudioContext, options?: Partial<SamplerConfig>);
|
|
435
|
-
loaded(): Promise<this>;
|
|
436
|
-
get output(): OutputChannel;
|
|
437
|
-
start(sample: SampleStart | string | number): (time?: number | undefined) => void;
|
|
438
|
-
stop(sample?: SampleStop | string | number): void;
|
|
439
|
-
disconnect(): void;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
414
|
declare function getSmolkenNames(): string[];
|
|
443
415
|
type SmolkenConfig = {
|
|
444
416
|
instrument: string;
|
|
@@ -523,4 +495,4 @@ declare const LAYERS: ({
|
|
|
523
495
|
cutoff?: undefined;
|
|
524
496
|
})[];
|
|
525
497
|
|
|
526
|
-
export { CacheStorage, DrumMachine, DrumMachineOptions, 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 };
|
|
498
|
+
export { CacheStorage, DrumMachine, type DrumMachineOptions, ElectricPiano, HttpStorage, LAYERS, Mallet, Mellotron, type MellotronConfig, type MellotronOptions, NAME_TO_PATH, Reverb, Sampler, type SamplerConfig, Smolken, type SmolkenConfig, type SmolkenOptions, Soundfont, type SoundfontOptions, SplendidGrandPiano, type SplendidGrandPianoConfig, type Storage, type StorageResponse, VcslInstrumentLoader, Versilian, type VersilianConfig, type VersilianOptions, getDrumMachineNames, getElectricPianoNames, getMalletNames, getMellotronNames, getSmolkenNames, getSoundfontKits, getSoundfontNames, getVersilianInstruments };
|
package/dist/index.d.ts
CHANGED
|
@@ -49,34 +49,6 @@ type AudioBuffers = Record<string | number, AudioBuffer | undefined>;
|
|
|
49
49
|
*/
|
|
50
50
|
type AudioBuffersLoader = (context: BaseAudioContext, buffers: AudioBuffers) => Promise<void>;
|
|
51
51
|
|
|
52
|
-
type StorageResponse$1 = {
|
|
53
|
-
readonly status: number;
|
|
54
|
-
arrayBuffer(): Promise<ArrayBuffer>;
|
|
55
|
-
json(): Promise<any>;
|
|
56
|
-
text(): Promise<string>;
|
|
57
|
-
};
|
|
58
|
-
type Storage$1 = {
|
|
59
|
-
fetch: (url: string) => Promise<StorageResponse$1>;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
type AudioBuffers$1 = Record<string | number, AudioBuffer | undefined>;
|
|
63
|
-
/**
|
|
64
|
-
* A function that downloads audio into a AudioBuffers
|
|
65
|
-
*/
|
|
66
|
-
type AudioBuffersLoader$1 = (context: BaseAudioContext, buffers: AudioBuffers$1) => Promise<void>;
|
|
67
|
-
|
|
68
|
-
type SamplerConfig$1 = {
|
|
69
|
-
storage?: Storage$1;
|
|
70
|
-
detune: number;
|
|
71
|
-
volume: number;
|
|
72
|
-
velocity: number;
|
|
73
|
-
decayTime?: number;
|
|
74
|
-
lpfCutoffHz?: number;
|
|
75
|
-
destination: AudioNode;
|
|
76
|
-
buffers: Record<string | number, string | AudioBuffers$1> | AudioBuffersLoader$1;
|
|
77
|
-
volumeToGain: (volume: number) => number;
|
|
78
|
-
};
|
|
79
|
-
|
|
80
52
|
/**
|
|
81
53
|
* A function to unsubscribe from an event or control
|
|
82
54
|
*/
|
|
@@ -214,6 +186,35 @@ type RegionGroup = {
|
|
|
214
186
|
sample: Partial<SampleOptions>;
|
|
215
187
|
};
|
|
216
188
|
|
|
189
|
+
type SamplerConfig = {
|
|
190
|
+
storage?: Storage;
|
|
191
|
+
detune: number;
|
|
192
|
+
volume: number;
|
|
193
|
+
velocity: number;
|
|
194
|
+
decayTime?: number;
|
|
195
|
+
lpfCutoffHz?: number;
|
|
196
|
+
destination: AudioNode;
|
|
197
|
+
buffers: Record<string | number, string | AudioBuffers> | AudioBuffersLoader;
|
|
198
|
+
volumeToGain: (volume: number) => number;
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* A Sampler instrument
|
|
202
|
+
*
|
|
203
|
+
* @private
|
|
204
|
+
*/
|
|
205
|
+
declare class Sampler {
|
|
206
|
+
#private;
|
|
207
|
+
readonly context: AudioContext;
|
|
208
|
+
private readonly player;
|
|
209
|
+
readonly load: Promise<this>;
|
|
210
|
+
constructor(context: AudioContext, options?: Partial<SamplerConfig>);
|
|
211
|
+
loaded(): Promise<this>;
|
|
212
|
+
get output(): OutputChannel;
|
|
213
|
+
start(sample: SampleStart | string | number): (time?: number | undefined) => void;
|
|
214
|
+
stop(sample?: SampleStop | string | number): void;
|
|
215
|
+
disconnect(): void;
|
|
216
|
+
}
|
|
217
|
+
|
|
217
218
|
type QueuedPlayerConfig = {
|
|
218
219
|
scheduleLookaheadMs: number;
|
|
219
220
|
scheduleIntervalMs: number;
|
|
@@ -221,7 +222,7 @@ type QueuedPlayerConfig = {
|
|
|
221
222
|
onEnded?: (sample: SampleStart) => void;
|
|
222
223
|
};
|
|
223
224
|
|
|
224
|
-
type DefaultPlayerConfig = ChannelConfig & SamplerConfig
|
|
225
|
+
type DefaultPlayerConfig = ChannelConfig & SamplerConfig & QueuedPlayerConfig;
|
|
225
226
|
|
|
226
227
|
declare function getDrumMachineNames(): string[];
|
|
227
228
|
type DrumMachineConfig = {
|
|
@@ -410,35 +411,6 @@ declare class Reverb {
|
|
|
410
411
|
connect(output: AudioNode): void;
|
|
411
412
|
}
|
|
412
413
|
|
|
413
|
-
type SamplerConfig = {
|
|
414
|
-
storage?: Storage;
|
|
415
|
-
detune: number;
|
|
416
|
-
volume: number;
|
|
417
|
-
velocity: number;
|
|
418
|
-
decayTime?: number;
|
|
419
|
-
lpfCutoffHz?: number;
|
|
420
|
-
destination: AudioNode;
|
|
421
|
-
buffers: Record<string | number, string | AudioBuffers> | AudioBuffersLoader;
|
|
422
|
-
volumeToGain: (volume: number) => number;
|
|
423
|
-
};
|
|
424
|
-
/**
|
|
425
|
-
* A Sampler instrument
|
|
426
|
-
*
|
|
427
|
-
* @private
|
|
428
|
-
*/
|
|
429
|
-
declare class Sampler {
|
|
430
|
-
#private;
|
|
431
|
-
readonly context: AudioContext;
|
|
432
|
-
private readonly player;
|
|
433
|
-
readonly load: Promise<this>;
|
|
434
|
-
constructor(context: AudioContext, options?: Partial<SamplerConfig>);
|
|
435
|
-
loaded(): Promise<this>;
|
|
436
|
-
get output(): OutputChannel;
|
|
437
|
-
start(sample: SampleStart | string | number): (time?: number | undefined) => void;
|
|
438
|
-
stop(sample?: SampleStop | string | number): void;
|
|
439
|
-
disconnect(): void;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
414
|
declare function getSmolkenNames(): string[];
|
|
443
415
|
type SmolkenConfig = {
|
|
444
416
|
instrument: string;
|
|
@@ -523,4 +495,4 @@ declare const LAYERS: ({
|
|
|
523
495
|
cutoff?: undefined;
|
|
524
496
|
})[];
|
|
525
497
|
|
|
526
|
-
export { CacheStorage, DrumMachine, DrumMachineOptions, 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 };
|
|
498
|
+
export { CacheStorage, DrumMachine, type DrumMachineOptions, ElectricPiano, HttpStorage, LAYERS, Mallet, Mellotron, type MellotronConfig, type MellotronOptions, NAME_TO_PATH, Reverb, Sampler, type SamplerConfig, Smolken, type SmolkenConfig, type SmolkenOptions, Soundfont, type SoundfontOptions, SplendidGrandPiano, type SplendidGrandPianoConfig, type Storage, type StorageResponse, VcslInstrumentLoader, Versilian, type VersilianConfig, type VersilianOptions, getDrumMachineNames, getElectricPianoNames, getMalletNames, getMellotronNames, getSmolkenNames, getSoundfontKits, getSoundfontNames, getVersilianInstruments };
|
package/dist/index.js
CHANGED
|
@@ -226,7 +226,7 @@ var Channel = class {
|
|
|
226
226
|
if (__privateGet(this, _disconnected)) {
|
|
227
227
|
throw Error("Can't add effect to disconnected channel");
|
|
228
228
|
}
|
|
229
|
-
const mix =
|
|
229
|
+
const mix = this.context.createGain();
|
|
230
230
|
mix.gain.value = mixValue;
|
|
231
231
|
const input = "input" in effect ? effect.input : effect;
|
|
232
232
|
const disconnect = connectSerial([__privateGet(this, _volume), mix, input]);
|
|
@@ -446,12 +446,18 @@ var SamplePlayer = class {
|
|
|
446
446
|
}
|
|
447
447
|
const source = context.createBufferSource();
|
|
448
448
|
source.buffer = buffer;
|
|
449
|
-
|
|
449
|
+
const cents = (_b = (_a = sample.detune) != null ? _a : this.options.detune) != null ? _b : 0;
|
|
450
|
+
if (source.detune) {
|
|
451
|
+
source.detune.value = cents;
|
|
452
|
+
} else if (source.playbackRate) {
|
|
453
|
+
source.playbackRate.value = Math.pow(2, cents / 1200);
|
|
454
|
+
}
|
|
450
455
|
const lpfCutoffHz = (_c = sample.lpfCutoffHz) != null ? _c : this.options.lpfCutoffHz;
|
|
451
|
-
const lpf = lpfCutoffHz ?
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
456
|
+
const lpf = lpfCutoffHz ? context.createBiquadFilter() : void 0;
|
|
457
|
+
if (lpfCutoffHz && lpf) {
|
|
458
|
+
lpf.type = "lowpass";
|
|
459
|
+
lpf.frequency.value = lpfCutoffHz;
|
|
460
|
+
}
|
|
455
461
|
const volume = context.createGain();
|
|
456
462
|
const velocity = (_e = (_d = sample.velocity) != null ? _d : this.options.velocity) != null ? _e : 100;
|
|
457
463
|
volume.gain.value = __privateGet(this, _config3).velocityToGain(velocity);
|
|
@@ -472,7 +478,10 @@ var SamplePlayer = class {
|
|
|
472
478
|
source.stop(stopAt);
|
|
473
479
|
}
|
|
474
480
|
}
|
|
475
|
-
const gainCompensation = sample.gainOffset ?
|
|
481
|
+
const gainCompensation = sample.gainOffset ? context.createGain() : void 0;
|
|
482
|
+
if (gainCompensation && sample.gainOffset) {
|
|
483
|
+
gainCompensation.gain.value = sample.gainOffset;
|
|
484
|
+
}
|
|
476
485
|
const stopId = (_j = sample.stopId) != null ? _j : sample.note;
|
|
477
486
|
const cleanup = unsubscribeAll([
|
|
478
487
|
connectSerial([
|
|
@@ -525,7 +534,8 @@ _disconnected2 = new WeakMap();
|
|
|
525
534
|
_stop = new WeakMap();
|
|
526
535
|
function createDecayEnvelope(context, envelopeTime = 0.2) {
|
|
527
536
|
let stopAt = 0;
|
|
528
|
-
const envelope =
|
|
537
|
+
const envelope = context.createGain();
|
|
538
|
+
envelope.gain.value = 1;
|
|
529
539
|
function start(time) {
|
|
530
540
|
if (stopAt)
|
|
531
541
|
return stopAt;
|
|
@@ -992,26 +1002,26 @@ startLayers_fn = function(sample) {
|
|
|
992
1002
|
|
|
993
1003
|
// src/tremolo.ts
|
|
994
1004
|
function createTremolo(context, depth) {
|
|
995
|
-
const input =
|
|
996
|
-
const output =
|
|
1005
|
+
const input = context.createGain();
|
|
1006
|
+
const output = context.createGain();
|
|
997
1007
|
input.channelCount = 2;
|
|
998
1008
|
input.channelCountMode = "explicit";
|
|
999
1009
|
const splitter = new ChannelSplitterNode(context, { numberOfOutputs: 2 });
|
|
1000
|
-
const ampL =
|
|
1001
|
-
const ampR =
|
|
1010
|
+
const ampL = context.createGain();
|
|
1011
|
+
const ampR = context.createGain();
|
|
1002
1012
|
const merger = new ChannelMergerNode(context, { numberOfInputs: 2 });
|
|
1003
1013
|
const lfoL = new OscillatorNode(context, {
|
|
1004
1014
|
type: "sine",
|
|
1005
1015
|
frequency: 1
|
|
1006
1016
|
});
|
|
1007
1017
|
lfoL.start();
|
|
1008
|
-
const lfoLAmp =
|
|
1018
|
+
const lfoLAmp = context.createGain();
|
|
1009
1019
|
const lfoR = new OscillatorNode(context, {
|
|
1010
1020
|
type: "sine",
|
|
1011
1021
|
frequency: 1.1
|
|
1012
1022
|
});
|
|
1013
1023
|
lfoR.start();
|
|
1014
|
-
const lfoRAmp =
|
|
1024
|
+
const lfoRAmp = context.createGain();
|
|
1015
1025
|
input.connect(splitter);
|
|
1016
1026
|
splitter.connect(ampL, 0);
|
|
1017
1027
|
splitter.connect(ampR, 1);
|
|
@@ -2041,7 +2051,8 @@ var Soundfont = class {
|
|
|
2041
2051
|
__privateSet(this, _hasLoops, hasLoops);
|
|
2042
2052
|
return this;
|
|
2043
2053
|
});
|
|
2044
|
-
const gain =
|
|
2054
|
+
const gain = context.createGain();
|
|
2055
|
+
gain.gain.value = this.config.extraGain;
|
|
2045
2056
|
this.player.output.addInsert(gain);
|
|
2046
2057
|
}
|
|
2047
2058
|
get output() {
|