@sudobility/music_player 0.1.9 → 0.1.10
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/dist/playback/channel-allocator.d.ts.map +1 -0
- package/dist/{web/playback → playback}/channel-allocator.js +1 -1
- package/dist/playback/channel-allocator.js.map +1 -0
- package/dist/playback/clock.d.ts.map +1 -0
- package/dist/playback/clock.js.map +1 -0
- package/dist/playback/governor.d.ts.map +1 -0
- package/dist/playback/governor.js.map +1 -0
- package/dist/{web/playback → playback}/soundfont-engine.d.ts +5 -37
- package/dist/playback/soundfont-engine.d.ts.map +1 -0
- package/dist/{web/playback → playback}/soundfont-engine.js +66 -92
- package/dist/playback/soundfont-engine.js.map +1 -0
- package/dist/playback/synth-backend.d.ts +99 -0
- package/dist/playback/synth-backend.d.ts.map +1 -0
- package/dist/playback/synth-backend.js +2 -0
- package/dist/playback/synth-backend.js.map +1 -0
- package/dist/rn/index.d.ts +10 -0
- package/dist/rn/index.d.ts.map +1 -1
- package/dist/rn/index.js +8 -0
- package/dist/rn/index.js.map +1 -1
- package/dist/rn/playback/native-backend.d.ts +61 -0
- package/dist/rn/playback/native-backend.d.ts.map +1 -0
- package/dist/rn/playback/native-backend.js +139 -0
- package/dist/rn/playback/native-backend.js.map +1 -0
- package/dist/rn/playback/native-synth-api.d.ts +120 -0
- package/dist/rn/playback/native-synth-api.d.ts.map +1 -0
- package/dist/rn/playback/native-synth-api.js +24 -0
- package/dist/rn/playback/native-synth-api.js.map +1 -0
- package/dist/web/audio/offline-synth.js +1 -1
- package/dist/web/audio/offline-synth.js.map +1 -1
- package/dist/web/audio/soundfont-render.js +1 -1
- package/dist/web/audio/soundfont-render.js.map +1 -1
- package/dist/web/index.d.ts.map +1 -1
- package/dist/web/index.js +10 -7
- package/dist/web/index.js.map +1 -1
- package/dist/web/playback/quiet-stub-notices.d.ts.map +1 -1
- package/dist/web/playback/quiet-stub-notices.js.map +1 -1
- package/dist/web/playback/soundfont-loader.d.ts.map +1 -1
- package/dist/web/playback/soundfont-loader.js +4 -1
- package/dist/web/playback/soundfont-loader.js.map +1 -1
- package/dist/web/playback/synth-host.d.ts.map +1 -1
- package/dist/web/playback/synth-host.js +3 -2
- package/dist/web/playback/synth-host.js.map +1 -1
- package/dist/web/playback/web-backend.d.ts +78 -0
- package/dist/web/playback/web-backend.d.ts.map +1 -0
- package/dist/web/playback/web-backend.js +111 -0
- package/dist/web/playback/web-backend.js.map +1 -0
- package/package.json +3 -3
- package/dist/web/playback/channel-allocator.d.ts.map +0 -1
- package/dist/web/playback/channel-allocator.js.map +0 -1
- package/dist/web/playback/clock.d.ts.map +0 -1
- package/dist/web/playback/clock.js.map +0 -1
- package/dist/web/playback/governor.d.ts.map +0 -1
- package/dist/web/playback/governor.js.map +0 -1
- package/dist/web/playback/soundfont-engine.d.ts.map +0 -1
- package/dist/web/playback/soundfont-engine.js.map +0 -1
- /package/dist/{web/playback → playback}/channel-allocator.d.ts +0 -0
- /package/dist/{web/playback → playback}/clock.d.ts +0 -0
- /package/dist/{web/playback → playback}/clock.js +0 -0
- /package/dist/{web/playback → playback}/governor.d.ts +0 -0
- /package/dist/{web/playback → playback}/governor.js +0 -0
package/dist/rn/index.d.ts
CHANGED
|
@@ -13,6 +13,16 @@ import { MusicPlayer } from '../player.js';
|
|
|
13
13
|
export * from '../types.js';
|
|
14
14
|
export * from '../singleton.js';
|
|
15
15
|
export { MusicPlayer, RNSamplePlaybackEngine, createRNSoundfontRenderer };
|
|
16
|
+
/**
|
|
17
|
+
* The native soundfont path: a `SynthBackend` over a platform synth, driven by
|
|
18
|
+
* the same scheduler the browser uses. Beside the sample engine rather than
|
|
19
|
+
* replacing it — that one needs no native module at all, which is what makes
|
|
20
|
+
* it the right default on a phone.
|
|
21
|
+
*/
|
|
22
|
+
export { NativeSynthBackend } from './playback/native-backend.js';
|
|
23
|
+
export type { NativeSynth, NativeSynthApi, NativeSynthSettings, } from './playback/native-synth-api.js';
|
|
24
|
+
export { SoundfontPlaybackEngine } from '../playback/soundfont-engine.js';
|
|
25
|
+
export type { SynthBackend, ScheduledClick, PrepareResult, } from '../playback/synth-backend.js';
|
|
16
26
|
export { renderEvents } from '../shared/render-events.js';
|
|
17
27
|
export { playbackPlan, playbackTracks, resolveVoice } from '../shared/plan.js';
|
|
18
28
|
/**
|
package/dist/rn/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rn/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/E;;;;;;GAMG;AAEH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,gFAAgF;AAChF,wBAAgB,iBAAiB,CAC/B,OAAO,GAAE,oBAAyB,GACjC,WAAW,CAOb;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,mHAK/D"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rn/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,CAAC;AAC1E;;;;;GAKG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,YAAY,EACV,WAAW,EACX,cAAc,EACd,mBAAmB,GACpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,YAAY,EACV,YAAY,EACZ,cAAc,EACd,aAAa,GACd,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/E;;;;;;GAMG;AAEH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,gFAAgF;AAChF,wBAAgB,iBAAiB,CAC/B,OAAO,GAAE,oBAAyB,GACjC,WAAW,CAOb;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,mHAK/D"}
|
package/dist/rn/index.js
CHANGED
|
@@ -13,6 +13,14 @@ import { MusicPlayer } from '../player.js';
|
|
|
13
13
|
export * from '../types.js';
|
|
14
14
|
export * from '../singleton.js';
|
|
15
15
|
export { MusicPlayer, RNSamplePlaybackEngine, createRNSoundfontRenderer };
|
|
16
|
+
/**
|
|
17
|
+
* The native soundfont path: a `SynthBackend` over a platform synth, driven by
|
|
18
|
+
* the same scheduler the browser uses. Beside the sample engine rather than
|
|
19
|
+
* replacing it — that one needs no native module at all, which is what makes
|
|
20
|
+
* it the right default on a phone.
|
|
21
|
+
*/
|
|
22
|
+
export { NativeSynthBackend } from './playback/native-backend.js';
|
|
23
|
+
export { SoundfontPlaybackEngine } from '../playback/soundfont-engine.js';
|
|
16
24
|
export { renderEvents } from '../shared/render-events.js';
|
|
17
25
|
export { playbackPlan, playbackTracks, resolveVoice } from '../shared/plan.js';
|
|
18
26
|
/** The React Native player, built fresh. Hand it to `initializeMusicPlayer`. */
|
package/dist/rn/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rn/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAwB/E,gFAAgF;AAChF,MAAM,UAAU,iBAAiB,CAC/B,UAAgC,EAAE;IAElC,OAAO,IAAI,WAAW,CACpB,IAAI,sBAAsB,CAAC;QACzB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,UAAgC,EAAE;IAC9D,OAAO,yBAAyB,CAAC;QAC/B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CAAC,MAAM,CAAC;AACZ,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rn/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,CAAC;AAC1E;;;;;GAKG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAMlE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAM1E,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAwB/E,gFAAgF;AAChF,MAAM,UAAU,iBAAiB,CAC/B,UAAgC,EAAE;IAElC,OAAO,IAAI,WAAW,CACpB,IAAI,sBAAsB,CAAC;QACzB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,UAAgC,EAAE;IAC9D,OAAO,yBAAyB,CAAC;QAC/B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CAAC,MAAM,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A `SynthBackend` over the native soundfont synth — macOS today, and any
|
|
3
|
+
* platform whose module satisfies `NativeSynthApi`.
|
|
4
|
+
*
|
|
5
|
+
* There is no engine here. The scheduler in `playback/soundfont-engine.ts` —
|
|
6
|
+
* the tempo map, the lookahead, the loop, the seek, the governor, the sounding
|
|
7
|
+
* set — is the same one the browser runs; this supplies only the sound, the
|
|
8
|
+
* clock and the click. That is the whole reason `SynthBackend` exists.
|
|
9
|
+
*/
|
|
10
|
+
import type { PrepareResult, ScheduledClick, SynthBackend } from '../../playback/synth-backend.js';
|
|
11
|
+
import type { PlaybackLoadState } from '@sudobility/music_types';
|
|
12
|
+
import type { NativeSynthApi } from './native-synth-api.js';
|
|
13
|
+
export declare class NativeSynthBackend implements SynthBackend {
|
|
14
|
+
private readonly api;
|
|
15
|
+
private readonly soundfontUri;
|
|
16
|
+
private synth;
|
|
17
|
+
/**
|
|
18
|
+
* The instance the metronome owns, and nothing else does.
|
|
19
|
+
*
|
|
20
|
+
* One synth is reserved past whatever the score needs, so switching the
|
|
21
|
+
* click off can drop everything scheduled on it without touching a note —
|
|
22
|
+
* and so a percussion track that has selected some other kit cannot change
|
|
23
|
+
* what the click sounds like.
|
|
24
|
+
*/
|
|
25
|
+
private clickInstance;
|
|
26
|
+
constructor(options: {
|
|
27
|
+
api: NativeSynthApi;
|
|
28
|
+
soundfontUri: string;
|
|
29
|
+
});
|
|
30
|
+
prepare({ instanceCount, onProgress, }: {
|
|
31
|
+
instanceCount: number;
|
|
32
|
+
onProgress: (state: PlaybackLoadState) => void;
|
|
33
|
+
}): Promise<PrepareResult>;
|
|
34
|
+
ensureInstances(count: number): Promise<void>;
|
|
35
|
+
/** The click sits past the last instance the score uses, on the drum channel. */
|
|
36
|
+
private adoptClickInstance;
|
|
37
|
+
now(): number;
|
|
38
|
+
outputLatency(): number | undefined;
|
|
39
|
+
scheduleClick(atSeconds: number, accent: boolean): ScheduledClick;
|
|
40
|
+
noteAt(i: number, c: number, m: number, v: number, delay: number, dur: number): void;
|
|
41
|
+
noteOn(i: number, c: number, m: number, v: number): void;
|
|
42
|
+
noteOff(i: number, c: number, m: number): void;
|
|
43
|
+
programSelect(i: number, c: number, program: number): void;
|
|
44
|
+
setChannelPercussion(i: number, c: number, kit?: number): void;
|
|
45
|
+
controlChange(i: number, c: number, control: number, value: number): void;
|
|
46
|
+
allSoundOff(): void;
|
|
47
|
+
setInterpolation(order: number): void;
|
|
48
|
+
setMasterVolume(volume: number): void;
|
|
49
|
+
/**
|
|
50
|
+
* Nothing to do: the native synth applies no per-track headroom of its own.
|
|
51
|
+
*
|
|
52
|
+
* Declared rather than omitted because the interface requires it, and a
|
|
53
|
+
* backend that quietly did nothing where the web one trims gain would be a
|
|
54
|
+
* difference nobody could see. The trim lives in `shared/mix.ts` and reaches
|
|
55
|
+
* both backends through the plan.
|
|
56
|
+
*/
|
|
57
|
+
setTrackCount(): void;
|
|
58
|
+
dispose(): void;
|
|
59
|
+
private require;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=native-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-backend.d.ts","sourceRoot":"","sources":["../../../src/rn/playback/native-backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,YAAY,EACb,MAAM,iCAAiC,CAAC;AAEzC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAEV,cAAc,EAEf,MAAM,uBAAuB,CAAC;AA+B/B,qBAAa,kBAAmB,YAAW,YAAY;IACrD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAiB;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,KAAK,CAA4B;IACzC;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa,CAAK;gBAEd,OAAO,EAAE;QAAE,GAAG,EAAE,cAAc,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE;IAK5D,OAAO,CAAC,EACZ,aAAa,EACb,UAAU,GACX,EAAE;QACD,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;KAChD,GAAG,OAAO,CAAC,aAAa,CAAC;IAkBpB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD,iFAAiF;IACjF,OAAO,CAAC,kBAAkB;IAK1B,GAAG,IAAI,MAAM;IAIb,aAAa,IAAI,MAAM,GAAG,SAAS;IAInC,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,cAAc;IAqBjE,MAAM,CACJ,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,GACV,IAAI;IAGP,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAGxD,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAG9C,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAG1D,oBAAoB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAG9D,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAGzE,WAAW,IAAI,IAAI;IAGnB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAGrC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAGrC;;;;;;;OAOG;IACH,aAAa,IAAI,IAAI;IAErB,OAAO,IAAI,IAAI;IAKf,OAAO,CAAC,OAAO;CAIhB"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { CHANNELS_PER_INSTANCE } from '../../playback/channel-allocator.js';
|
|
2
|
+
import { PERCUSSION_CHANNEL } from '@sudobility/music_types';
|
|
3
|
+
/**
|
|
4
|
+
* Matched to the web host's, so a score sounds the same on both.
|
|
5
|
+
*
|
|
6
|
+
* These are not defaults inherited by omission: every one is stated because a
|
|
7
|
+
* setting left out is fluidsynth's own silently adopted, which is how the web
|
|
8
|
+
* synth once ran on sixteen channels while the allocator handed out channel 25.
|
|
9
|
+
*/
|
|
10
|
+
const SETTINGS = {
|
|
11
|
+
midiChannelCount: CHANNELS_PER_INSTANCE,
|
|
12
|
+
polyphony: 2048,
|
|
13
|
+
initialGain: 0.2,
|
|
14
|
+
chorusActive: true,
|
|
15
|
+
reverbActive: true,
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* The click, as General MIDI percussion.
|
|
19
|
+
*
|
|
20
|
+
* The web click is a tuned sine built from oscillators, which has no native
|
|
21
|
+
* counterpart short of writing one — so the metronome is played through the
|
|
22
|
+
* synth that is already there. Wood blocks because that is what a metronome
|
|
23
|
+
* sounds like, and because they are short: a click that rings would smear
|
|
24
|
+
* against the beat it is marking.
|
|
25
|
+
*/
|
|
26
|
+
const CLICK_ACCENT_MIDI = 76;
|
|
27
|
+
const CLICK_BEAT_MIDI = 77;
|
|
28
|
+
const CLICK_VELOCITY = 100;
|
|
29
|
+
const CLICK_SECONDS = 0.05;
|
|
30
|
+
export class NativeSynthBackend {
|
|
31
|
+
api;
|
|
32
|
+
soundfontUri;
|
|
33
|
+
synth = null;
|
|
34
|
+
/**
|
|
35
|
+
* The instance the metronome owns, and nothing else does.
|
|
36
|
+
*
|
|
37
|
+
* One synth is reserved past whatever the score needs, so switching the
|
|
38
|
+
* click off can drop everything scheduled on it without touching a note —
|
|
39
|
+
* and so a percussion track that has selected some other kit cannot change
|
|
40
|
+
* what the click sounds like.
|
|
41
|
+
*/
|
|
42
|
+
clickInstance = 0;
|
|
43
|
+
constructor(options) {
|
|
44
|
+
this.api = options.api;
|
|
45
|
+
this.soundfontUri = options.soundfontUri;
|
|
46
|
+
}
|
|
47
|
+
async prepare({ instanceCount, onProgress, }) {
|
|
48
|
+
if (!this.api.isSupported()) {
|
|
49
|
+
throw new Error('No native synth on this platform');
|
|
50
|
+
}
|
|
51
|
+
this.synth ??= this.api.createSynth();
|
|
52
|
+
onProgress({ status: 'loading', fraction: 0 });
|
|
53
|
+
await this.synth.initialize({
|
|
54
|
+
soundfontUri: this.soundfontUri,
|
|
55
|
+
instanceCount: instanceCount + 1,
|
|
56
|
+
settings: SETTINGS,
|
|
57
|
+
onProgress: fraction => onProgress({ status: 'loading', fraction }),
|
|
58
|
+
});
|
|
59
|
+
this.adoptClickInstance(instanceCount);
|
|
60
|
+
// No deferred case: nothing here waits on a user gesture the way a
|
|
61
|
+
// browser's suspended AudioContext does.
|
|
62
|
+
return 'ready';
|
|
63
|
+
}
|
|
64
|
+
async ensureInstances(count) {
|
|
65
|
+
await this.require().ensureInstances(count + 1);
|
|
66
|
+
this.adoptClickInstance(count);
|
|
67
|
+
}
|
|
68
|
+
/** The click sits past the last instance the score uses, on the drum channel. */
|
|
69
|
+
adoptClickInstance(instanceCount) {
|
|
70
|
+
this.clickInstance = instanceCount;
|
|
71
|
+
this.require().setChannelPercussion(this.clickInstance, PERCUSSION_CHANNEL);
|
|
72
|
+
}
|
|
73
|
+
now() {
|
|
74
|
+
return this.synth?.currentTime() ?? 0;
|
|
75
|
+
}
|
|
76
|
+
outputLatency() {
|
|
77
|
+
return this.synth?.outputLatency();
|
|
78
|
+
}
|
|
79
|
+
scheduleClick(atSeconds, accent) {
|
|
80
|
+
const synth = this.synth;
|
|
81
|
+
const endsAt = atSeconds + CLICK_SECONDS;
|
|
82
|
+
if (!synth)
|
|
83
|
+
return { endsAt, cancel: () => undefined };
|
|
84
|
+
synth.noteAt(this.clickInstance, PERCUSSION_CHANNEL, accent ? CLICK_ACCENT_MIDI : CLICK_BEAT_MIDI, CLICK_VELOCITY, Math.max(0, atSeconds - synth.currentTime()), CLICK_SECONDS);
|
|
85
|
+
return {
|
|
86
|
+
endsAt,
|
|
87
|
+
// Everything queued on the click's own instance, which is only ever
|
|
88
|
+
// clicks. Per-click cancellation would need the native side to hand back
|
|
89
|
+
// a handle per event, for no gain: they are all being taken back at once.
|
|
90
|
+
cancel: () => synth.cancelScheduledOn(this.clickInstance),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
noteAt(i, c, m, v, delay, dur) {
|
|
94
|
+
this.require().noteAt(i, c, m, v, delay, dur);
|
|
95
|
+
}
|
|
96
|
+
noteOn(i, c, m, v) {
|
|
97
|
+
this.require().noteOn(i, c, m, v);
|
|
98
|
+
}
|
|
99
|
+
noteOff(i, c, m) {
|
|
100
|
+
this.require().noteOff(i, c, m);
|
|
101
|
+
}
|
|
102
|
+
programSelect(i, c, program) {
|
|
103
|
+
this.require().programSelect(i, c, program);
|
|
104
|
+
}
|
|
105
|
+
setChannelPercussion(i, c, kit) {
|
|
106
|
+
this.require().setChannelPercussion(i, c, kit);
|
|
107
|
+
}
|
|
108
|
+
controlChange(i, c, control, value) {
|
|
109
|
+
this.require().controlChange(i, c, control, value);
|
|
110
|
+
}
|
|
111
|
+
allSoundOff() {
|
|
112
|
+
this.synth?.allSoundOff();
|
|
113
|
+
}
|
|
114
|
+
setInterpolation(order) {
|
|
115
|
+
this.synth?.setInterpolation(order);
|
|
116
|
+
}
|
|
117
|
+
setMasterVolume(volume) {
|
|
118
|
+
this.synth?.setMasterVolume(volume);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Nothing to do: the native synth applies no per-track headroom of its own.
|
|
122
|
+
*
|
|
123
|
+
* Declared rather than omitted because the interface requires it, and a
|
|
124
|
+
* backend that quietly did nothing where the web one trims gain would be a
|
|
125
|
+
* difference nobody could see. The trim lives in `shared/mix.ts` and reaches
|
|
126
|
+
* both backends through the plan.
|
|
127
|
+
*/
|
|
128
|
+
setTrackCount() { }
|
|
129
|
+
dispose() {
|
|
130
|
+
this.synth?.dispose();
|
|
131
|
+
this.synth = null;
|
|
132
|
+
}
|
|
133
|
+
require() {
|
|
134
|
+
if (!this.synth)
|
|
135
|
+
throw new Error('Native synth not prepared');
|
|
136
|
+
return this.synth;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=native-backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-backend.js","sourceRoot":"","sources":["../../../src/rn/playback/native-backend.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The slice of the native soundfont synth this package drives.
|
|
3
|
+
*
|
|
4
|
+
* Declared structurally, like `audio-api.ts` beside it and `skia-api.ts` in
|
|
5
|
+
* music_drawing: nothing here imports the native module, so it can be driven
|
|
6
|
+
* in a test with a fake and this package's dev tree needs no React Native.
|
|
7
|
+
*
|
|
8
|
+
* **This is a synth, not a player.** It owns sound and a clock and knows
|
|
9
|
+
* nothing about plans, repeats, loops, tempo maps or which notes are sounding.
|
|
10
|
+
* All of that already exists once, in the scheduler `soundfont-engine.ts`
|
|
11
|
+
* drives through `SynthHostLike` — so this contract is deliberately shaped to
|
|
12
|
+
* what *that* interface needs, and `native-synth-host.ts` adapts one to the
|
|
13
|
+
* other. A native module that scheduled a `PlaybackPlan` itself would be a
|
|
14
|
+
* second copy of the whole transport, in C++, where none of the existing tests
|
|
15
|
+
* can reach.
|
|
16
|
+
*
|
|
17
|
+
* **Instances and channels come from the caller.** libfluidsynth runs a fixed
|
|
18
|
+
* number of MIDI channels per synth, so the scheduler allocates across several
|
|
19
|
+
* instances (`channel-allocator.ts`) and addresses every call by both. The
|
|
20
|
+
* native side allocates nothing and keeps no catalogue: which kit a percussion
|
|
21
|
+
* program means is resolved before it gets here, exactly as on the web.
|
|
22
|
+
*/
|
|
23
|
+
export type NativeSynthSettings = {
|
|
24
|
+
/** int [16-256] and a multiple of 16, as fluidsynth requires. */
|
|
25
|
+
midiChannelCount: number;
|
|
26
|
+
/** Maximum simultaneous voices before the synth steals by its own priority. */
|
|
27
|
+
polyphony: number;
|
|
28
|
+
/** Output level before our own master gain. */
|
|
29
|
+
initialGain: number;
|
|
30
|
+
/** Both colour every note; on, for parity with the web engine's output. */
|
|
31
|
+
chorusActive: boolean;
|
|
32
|
+
reverbActive: boolean;
|
|
33
|
+
};
|
|
34
|
+
export type NativeSynth = {
|
|
35
|
+
/**
|
|
36
|
+
* Brings up the audio device and `instanceCount` synths, and loads the
|
|
37
|
+
* soundfont.
|
|
38
|
+
*
|
|
39
|
+
* The font is named by **file URI, not bytes**: it is ~23MB, and copying it
|
|
40
|
+
* through the bridge would cost more than reading it does — where the web
|
|
41
|
+
* host is handed an `ArrayBuffer` because a browser has no path to give it.
|
|
42
|
+
* The host supplies the URI, for the same reason it supplies the web host's
|
|
43
|
+
* worklet URLs: a library cannot know how an app bundles its assets.
|
|
44
|
+
*
|
|
45
|
+
* `onProgress` reports the load, because the first press of Play waits on it
|
|
46
|
+
* — that is what `PlaybackLoadState` and the "Preparing instruments" readout
|
|
47
|
+
* exist for, and a native load is no faster than a fetch.
|
|
48
|
+
*/
|
|
49
|
+
initialize(options: {
|
|
50
|
+
soundfontUri: string;
|
|
51
|
+
instanceCount: number;
|
|
52
|
+
settings: NativeSynthSettings;
|
|
53
|
+
onProgress?: (fraction: number) => void;
|
|
54
|
+
}): Promise<void>;
|
|
55
|
+
/** Grows the pool. Never shrinks it: a sounding note must not lose its synth. */
|
|
56
|
+
ensureInstances(count: number): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* The synth's own clock, in seconds, monotonic while running.
|
|
59
|
+
*
|
|
60
|
+
* `noteAt`'s delay is measured from this. Deliberately not a JS timer: those
|
|
61
|
+
* drift against the audio device, and a playhead is exactly what reveals it.
|
|
62
|
+
*/
|
|
63
|
+
currentTime(): number;
|
|
64
|
+
/**
|
|
65
|
+
* Seconds between an event sounding and it reaching the speaker, so lit keys
|
|
66
|
+
* can match the ear rather than the scheduler — `shared/visual-sync.ts`
|
|
67
|
+
* already does this arithmetic for the web engine.
|
|
68
|
+
*/
|
|
69
|
+
outputLatency(): number;
|
|
70
|
+
/**
|
|
71
|
+
* A note that starts `delaySeconds` from now and releases itself after
|
|
72
|
+
* `durationSeconds`.
|
|
73
|
+
*
|
|
74
|
+
* The scheduled-playback call, and the reason every event is timestamped.
|
|
75
|
+
* The web host hands the same thing to fluidsynth's sequencer, which runs on
|
|
76
|
+
* the audio thread; here it crosses a bridge, so a bare "play now" would put
|
|
77
|
+
* the bridge's jitter onto the notes instead of onto the scheduler.
|
|
78
|
+
* Self-releasing for the same reason: a separate note-off would be a second
|
|
79
|
+
* crossing that can arrive late on its own.
|
|
80
|
+
*/
|
|
81
|
+
noteAt(instance: number, channel: number, midi: number, velocity: number, delaySeconds: number, durationSeconds: number): void;
|
|
82
|
+
/** Sounds now and holds — auditioning a key, independent of the transport. */
|
|
83
|
+
noteOn(instance: number, channel: number, midi: number, velocity: number): void;
|
|
84
|
+
noteOff(instance: number, channel: number, midi: number): void;
|
|
85
|
+
programSelect(instance: number, channel: number, program: number): void;
|
|
86
|
+
/** A percussion channel addresses a drum bank; `kit` is resolved by the caller. */
|
|
87
|
+
setChannelPercussion(instance: number, channel: number, kit?: number): void;
|
|
88
|
+
controlChange(instance: number, channel: number, control: number, value: number): void;
|
|
89
|
+
/**
|
|
90
|
+
* Drops everything scheduled on one instance, without touching the others.
|
|
91
|
+
*
|
|
92
|
+
* The metronome's, and the reason it is not just `allSoundOff`: switching the
|
|
93
|
+
* click off must not silence the music. The click gets an instance of its
|
|
94
|
+
* own precisely so this can be a blunt instrument — see `native-backend.ts`.
|
|
95
|
+
*/
|
|
96
|
+
cancelScheduledOn(instance: number): void;
|
|
97
|
+
/**
|
|
98
|
+
* Silences everything sounding and drops everything scheduled.
|
|
99
|
+
*
|
|
100
|
+
* One call rather than a note-off per voice: a stop or a seek has to undo a
|
|
101
|
+
* whole lookahead window, and walking it from JS would send a burst of
|
|
102
|
+
* bridge calls at the moment the user is waiting on the transport.
|
|
103
|
+
*/
|
|
104
|
+
allSoundOff(): void;
|
|
105
|
+
/** Interpolation order, lowered under load — see `governor.ts`. */
|
|
106
|
+
setInterpolation(order: number): void;
|
|
107
|
+
setMasterVolume(volume: number): void;
|
|
108
|
+
dispose(): void;
|
|
109
|
+
};
|
|
110
|
+
/** What the host needs from the module, and nothing else. */
|
|
111
|
+
export type NativeSynthApi = {
|
|
112
|
+
createSynth(): NativeSynth;
|
|
113
|
+
/**
|
|
114
|
+
* False where no native synth is built in, so the caller can say so rather
|
|
115
|
+
* than fail obscurely — the same courtesy `MidiInput` does with
|
|
116
|
+
* `isSupported()` in music_io.
|
|
117
|
+
*/
|
|
118
|
+
isSupported(): boolean;
|
|
119
|
+
};
|
|
120
|
+
//# sourceMappingURL=native-synth-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-synth-api.d.ts","sourceRoot":"","sources":["../../../src/rn/playback/native-synth-api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,MAAM,mBAAmB,GAAG;IAChC,iEAAiE;IACjE,gBAAgB,EAAE,MAAM,CAAC;IACzB,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB;;;;;;;;;;;;;OAaG;IACH,UAAU,CAAC,OAAO,EAAE;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,mBAAmB,CAAC;QAC9B,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;KACzC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClB,iFAAiF;IACjF,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9C;;;;;OAKG;IACH,WAAW,IAAI,MAAM,CAAC;IACtB;;;;OAIG;IACH,aAAa,IAAI,MAAM,CAAC;IAExB;;;;;;;;;;OAUG;IACH,MAAM,CACJ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,GACtB,IAAI,CAAC;IACR,8EAA8E;IAC9E,MAAM,CACJ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,IAAI,CAAC;IACR,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAE/D,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACxE,mFAAmF;IACnF,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5E,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GACZ,IAAI,CAAC;IAER;;;;;;OAMG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C;;;;;;OAMG;IACH,WAAW,IAAI,IAAI,CAAC;IACpB,mEAAmE;IACnE,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,OAAO,IAAI,IAAI,CAAC;CACjB,CAAC;AAEF,6DAA6D;AAC7D,MAAM,MAAM,cAAc,GAAG;IAC3B,WAAW,IAAI,WAAW,CAAC;IAC3B;;;;OAIG;IACH,WAAW,IAAI,OAAO,CAAC;CACxB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The slice of the native soundfont synth this package drives.
|
|
3
|
+
*
|
|
4
|
+
* Declared structurally, like `audio-api.ts` beside it and `skia-api.ts` in
|
|
5
|
+
* music_drawing: nothing here imports the native module, so it can be driven
|
|
6
|
+
* in a test with a fake and this package's dev tree needs no React Native.
|
|
7
|
+
*
|
|
8
|
+
* **This is a synth, not a player.** It owns sound and a clock and knows
|
|
9
|
+
* nothing about plans, repeats, loops, tempo maps or which notes are sounding.
|
|
10
|
+
* All of that already exists once, in the scheduler `soundfont-engine.ts`
|
|
11
|
+
* drives through `SynthHostLike` — so this contract is deliberately shaped to
|
|
12
|
+
* what *that* interface needs, and `native-synth-host.ts` adapts one to the
|
|
13
|
+
* other. A native module that scheduled a `PlaybackPlan` itself would be a
|
|
14
|
+
* second copy of the whole transport, in C++, where none of the existing tests
|
|
15
|
+
* can reach.
|
|
16
|
+
*
|
|
17
|
+
* **Instances and channels come from the caller.** libfluidsynth runs a fixed
|
|
18
|
+
* number of MIDI channels per synth, so the scheduler allocates across several
|
|
19
|
+
* instances (`channel-allocator.ts`) and addresses every call by both. The
|
|
20
|
+
* native side allocates nothing and keeps no catalogue: which kit a percussion
|
|
21
|
+
* program means is resolved before it gets here, exactly as on the web.
|
|
22
|
+
*/
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=native-synth-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-synth-api.js","sourceRoot":"","sources":["../../../src/rn/playback/native-synth-api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG"}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* This one runs on the main thread rather than in a worklet, which is fine
|
|
17
17
|
* precisely because it is offline — there is no audio callback to starve.
|
|
18
18
|
*/
|
|
19
|
-
import { CHANNELS_PER_INSTANCE } from '
|
|
19
|
+
import { CHANNELS_PER_INSTANCE } from '../../playback/channel-allocator.js';
|
|
20
20
|
import { seedMainThreadQuietModule } from '../playback/quiet-stub-notices.js';
|
|
21
21
|
/** Matches playback's ceiling, so an export sounds like what was heard. */
|
|
22
22
|
const OFFLINE_POLYPHONY = 2048;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"offline-synth.js","sourceRoot":"","sources":["../../../src/web/audio/offline-synth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"offline-synth.js","sourceRoot":"","sources":["../../../src/web/audio/offline-synth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CC_PAN, CC_VOLUME } from '@sudobility/music_types';
|
|
2
2
|
import { DRUM_BANK } from '@sudobility/music_types';
|
|
3
|
-
import { allocateChannels } from '
|
|
3
|
+
import { allocateChannels } from '../../playback/channel-allocator.js';
|
|
4
4
|
import { headroomTrimFor, limitPeaks } from '../../shared/mix.js';
|
|
5
5
|
import { getOfflineSynth } from './offline-synth.js';
|
|
6
6
|
const SAMPLE_RATE = 44100;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"soundfont-render.js","sourceRoot":"","sources":["../../../src/web/audio/soundfont-render.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"soundfont-render.js","sourceRoot":"","sources":["../../../src/web/audio/soundfont-render.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAElE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAarD,MAAM,WAAW,GAAG,KAAK,CAAC;AAC1B,+DAA+D;AAC/D,MAAM,YAAY,GAAG,CAAC,CAAC;AACvB,wEAAwE;AACxE,MAAM,YAAY,GAAG,GAAG,CAAC;AACzB,MAAM,MAAM,GAAG,GAAG,CAAC;AACnB,uEAAuE;AACvE,MAAM,YAAY,GAAG,CAAC,CAAC;AAIvB,MAAM,UAAU,uBAAuB,CACrC,MAA+B;IAE/B,MAAM,OAAO,GACX,MAAM,CAAC,YAAY;QACnB,CAAC,CAAC,UAAkB,EAAE,EAAE,CACtB,eAAe,CAAC;YACd,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;YAC/C,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,UAAU;SACX,CAAC,CAAC,CAAC;IAER,OAAO,KAAK,UAAU,MAAM,CAAC,IAAgB;QAC3C,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;QAClE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,GAAG,YAAY,CAAC,GAAG,UAAU,CAAC,CAAC;QAE3F,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,gBAAgB,CACrD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CACrE,CAAC;QAEF,sEAAsE;QACtE,yEAAyE;QACzE,yEAAyE;QACzE,2EAA2E;QAC3E,uEAAuE;QACvE,6EAA6E;QAC7E,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAErD,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,WAAW,CAAC,CAAC;QAC9C,wEAAwE;QACxE,wEAAwE;QACxE,wEAAwE;QACxE,2EAA2E;QAC3E,yEAAyE;QACzE,yEAAyE;QACzE,qBAAqB;QACrB,KAAK,IAAI,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,aAAa,EAAE,QAAQ,IAAI,CAAC,EAAE,CAAC;YAC/D,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC;QACtF,CAAC;QAED,KAAK,CAAC,gBAAgB,EAAE,CAAC;QACzB,0EAA0E;QAC1E,2EAA2E;QAC3E,2EAA2E;QAC3E,+BAA+B;QAC/B,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAChC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;QAE/B,+EAA+E;QAC/E,SAAS,UAAU,CAAC,MAA4B;YAC9C,MAAM,UAAU,GAAG,IAAI,GAAG,EAA6B,CAAC;YACxD,yEAAyE;YACzE,6DAA6D;YAC7D,KAAK,CAAC,gBAAgB,EAAE,CAAC;YACzB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAC7C,IAAI,CAAC,UAAU;oBAAE,SAAS;gBAC1B,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;gBACrC,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;gBAE/B,IAAI,KAAK,CAAC,YAAY,IAAI,UAAU,CAAC,mBAAmB,EAAE,CAAC;oBACzD,oEAAoE;oBACpE,qEAAqE;oBACrE,oEAAoE;oBACpE,oEAAoE;oBACpE,8DAA8D;oBAC9D,eAAe;oBACf,IAAI,OAAO,KAAK,CAAC;wBAAE,KAAK,CAAC,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;oBAC3D,oEAAoE;oBACpE,+DAA+D;oBAC/D,oEAAoE;oBACpE,8BAA8B;oBAC9B,KAAK,CAAC,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;oBACnE,IAAI,KAAK,CAAC,WAAW,KAAK,YAAY,EAAE,CAAC;wBACvC,KAAK,CAAC,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;oBAC1E,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,KAAK,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;oBACzC,KAAK,CAAC,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;gBAClE,CAAC;gBACD,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;gBACzE,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;YACzD,CAAC;YAED,+DAA+D;YAC/D,MAAM,QAAQ,GAAiB,EAAE,CAAC;YAClC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChC,MAAM,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACjD,IAAI,CAAC,UAAU;oBAAE,SAAS,CAAC,+DAA+D;gBAC1F,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;gBAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBACpF,QAAQ,CAAC,IAAI,CAAC;oBACZ,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC;oBAChD,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC;iBAC3D,CAAC,CAAC;gBACH,QAAQ,CAAC,IAAI,CAAC;oBACZ,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,UAAU,CAAC;oBACtE,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC;iBAClD,CAAC,CAAC;YACL,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;YAE/C,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,YAAY,CAAC,CAAC;YAC5C,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,YAAY,CAAC,CAAC;YAC7C,IAAI,IAAI,GAAG,CAAC,CAAC;YAEb,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,WAAW,EAAE,KAAK,IAAI,YAAY,EAAE,CAAC;gBAC/D,MAAM,QAAQ,GAAG,KAAK,GAAG,YAAY,CAAC;gBACtC,OAAO,IAAI,GAAG,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,QAAQ;oBAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;gBAE3F,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;gBAE5B,qEAAqE;gBACrE,oEAAoE;gBACpE,mEAAmE;gBACnE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,WAAW,GAAG,KAAK,CAAC,CAAC;gBAC1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;oBAClC,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,QAAQ,CAAC;gBAC9D,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;AACzE,CAAC"}
|
package/dist/web/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/web/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/web/index.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAgB/E;;;;;;;;;;GAUG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,mEAAmE;IACnE,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,uEAAuE;AACvE,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,GACV,EAAE;IACD,SAAS,EAAE,eAAe,CAAC;CAC5B,GAAG,WAAW,CAad;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,eAAe,mHAOvD"}
|
package/dist/web/index.js
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* Resolved by any bundler that is not Metro, through the `default` branch of
|
|
5
5
|
* this package's export condition.
|
|
6
6
|
*/
|
|
7
|
-
import { SoundfontPlaybackEngine } from '
|
|
7
|
+
import { SoundfontPlaybackEngine } from '../playback/soundfont-engine.js';
|
|
8
|
+
import { WebSynthBackend } from './playback/web-backend.js';
|
|
8
9
|
import { SynthHost } from './playback/synth-host.js';
|
|
9
10
|
import { loadSoundfont, openSoundfontCache, } from './playback/soundfont-loader.js';
|
|
10
11
|
import { createSoundfontRenderer } from './audio/soundfont-render.js';
|
|
@@ -30,12 +31,14 @@ async function createWorkletSynth() {
|
|
|
30
31
|
/** The web player, built fresh. Hand it to `initializeMusicPlayer`. */
|
|
31
32
|
export function createMusicPlayer({ soundfont, }) {
|
|
32
33
|
return new MusicPlayer(new SoundfontPlaybackEngine({
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
backend: new WebSynthBackend({
|
|
35
|
+
host: new SynthHost({ createSynth: createWorkletSynth }),
|
|
36
|
+
moduleUrls: {
|
|
37
|
+
fluidsynth: soundfont.fluidsynthModuleUrl,
|
|
38
|
+
worklet: soundfont.workletModuleUrl,
|
|
39
|
+
},
|
|
40
|
+
fontUrl: soundfont.fontUrl,
|
|
41
|
+
}),
|
|
39
42
|
}));
|
|
40
43
|
}
|
|
41
44
|
/**
|
package/dist/web/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/web/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/web/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,OAAO,EACL,aAAa,EACb,kBAAkB,GACnB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE/E;;;;;;;;GAQG;AACH,KAAK,UAAU,kBAAkB;IAC/B,MAAM,EAAE,2BAA2B,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACvE,OAAO,IAAI,2BAA2B,EAA8B,CAAC;AACvE,CAAC;AAoBD,uEAAuE;AACvE,MAAM,UAAU,iBAAiB,CAAC,EAChC,SAAS,GAGV;IACC,OAAO,IAAI,WAAW,CACpB,IAAI,uBAAuB,CAAC;QAC1B,OAAO,EAAE,IAAI,eAAe,CAAC;YAC3B,IAAI,EAAE,IAAI,SAAS,CAAC,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;YACxD,UAAU,EAAE;gBACV,UAAU,EAAE,SAAS,CAAC,mBAAmB;gBACzC,OAAO,EAAE,SAAS,CAAC,gBAAgB;aACpC;YACD,OAAO,EAAE,SAAS,CAAC,OAAO;SAC3B,CAAC;KACH,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAAC,SAA0B;IACtD,OAAO,uBAAuB,CAAC;QAC7B,mBAAmB,EAAE,SAAS,CAAC,mBAAmB;QAClD,OAAO,EAAE,SAAS,CAAC,OAAO;QAC1B,QAAQ,EAAE,KAAK,EAAC,GAAG,EAAC,EAAE,CACpB,aAAa,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,kBAAkB,EAAE,EAAE,CAAC;KAC5D,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quiet-stub-notices.d.ts","sourceRoot":"","sources":["../../../src/web/playback/quiet-stub-notices.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,oFAAoF;AACpF,eAAO,MAAM,mBAAmB,QAA2B,CAAC;AAE5D,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAEnD;AA0BD;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,IAAI,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"quiet-stub-notices.d.ts","sourceRoot":"","sources":["../../../src/web/playback/quiet-stub-notices.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,oFAAoF;AACpF,eAAO,MAAM,mBAAmB,QAA2B,CAAC;AAE5D,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAEnD;AA0BD;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,IAAI,MAAM,GAAG,IAAI,CAM3D;AAED,qFAAqF;AACrF,wBAAgB,yBAAyB,IAAI,IAAI,CAQhD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quiet-stub-notices.js","sourceRoot":"","sources":["../../../src/web/playback/quiet-stub-notices.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,oFAAoF;AACpF,MAAM,CAAC,MAAM,mBAAmB,GAAG,wBAAwB,CAAC;AAE5D,MAAM,UAAU,YAAY,CAAC,IAAa;IACxC,OAAO,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,SAAS,UAAU;IACjB,yEAAyE;IACzE,OAAO;kBACS,mBAAmB,CAAC,QAAQ,EAAE;;;;;;;;;;;;;MAa1C,CAAC;AACP,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,2BAA2B;IACzC,IAAI,OAAO,IAAI,KAAK,WAAW,IAAI,OAAO,GAAG,EAAE,eAAe,KAAK,UAAU;
|
|
1
|
+
{"version":3,"file":"quiet-stub-notices.js","sourceRoot":"","sources":["../../../src/web/playback/quiet-stub-notices.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,oFAAoF;AACpF,MAAM,CAAC,MAAM,mBAAmB,GAAG,wBAAwB,CAAC;AAE5D,MAAM,UAAU,YAAY,CAAC,IAAa;IACxC,OAAO,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,SAAS,UAAU;IACjB,yEAAyE;IACzE,OAAO;kBACS,mBAAmB,CAAC,QAAQ,EAAE;;;;;;;;;;;;;MAa1C,CAAC;AACP,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,2BAA2B;IACzC,IAAI,OAAO,IAAI,KAAK,WAAW,IAAI,OAAO,GAAG,EAAE,eAAe,KAAK,UAAU;QAC3E,OAAO,IAAI,CAAC;IACd,OAAO,GAAG,CAAC,eAAe,CACxB,IAAI,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,CACtD,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,yBAAyB;IACvC,MAAM,KAAK,GAAG,UAA6D,CAAC;IAC5E,KAAK,CAAC,MAAM,GAAG;QACb,GAAG,KAAK,CAAC,MAAM;QACf,QAAQ,EAAE,CAAC,IAAa,EAAE,EAAE;YAC1B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;gBAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/C,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"soundfont-loader.d.ts","sourceRoot":"","sources":["../../../src/web/playback/soundfont-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,YAAY,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAK7D;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAOhE;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;
|
|
1
|
+
{"version":3,"file":"soundfont-loader.d.ts","sourceRoot":"","sources":["../../../src/web/playback/soundfont-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,YAAY,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAK7D;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAOhE;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IACJ,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;IAC9C,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;CACjB,GACL,OAAO,CAAC,WAAW,CAAC,CA2BtB"}
|
|
@@ -32,7 +32,10 @@ export async function loadSoundfont(url, opts = {}) {
|
|
|
32
32
|
// Rebuilt rather than cloned: the body has already been consumed to report
|
|
33
33
|
// progress, and a body can only be read once.
|
|
34
34
|
await opts.cache?.put(url, new Response(buffer, { headers: response.headers }));
|
|
35
|
-
opts.onProgress?.({
|
|
35
|
+
opts.onProgress?.({
|
|
36
|
+
loaded: buffer.byteLength,
|
|
37
|
+
total: declared || buffer.byteLength,
|
|
38
|
+
});
|
|
36
39
|
return buffer;
|
|
37
40
|
}
|
|
38
41
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"soundfont-loader.js","sourceRoot":"","sources":["../../../src/web/playback/soundfont-loader.ts"],"names":[],"mappings":"AAcA,oFAAoF;AACpF,MAAM,UAAU,GAAG,oBAAoB,CAAC;AAExC;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAC/C,IAAI,CAAC;QACH,OAAO,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,CAAC,qDAAqD;IACpE,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAW,EACX,
|
|
1
|
+
{"version":3,"file":"soundfont-loader.js","sourceRoot":"","sources":["../../../src/web/playback/soundfont-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"synth-host.d.ts","sourceRoot":"","sources":["../../../src/web/playback/synth-host.ts"],"names":[],"mappings":"AAoBA;;;;;GAKG;AACH;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,0CAA0C;IAC1C,gBAAgB,EAAE,MAAM,CAAC;IACzB,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;OAOG;IACH,cAAc,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC;IAC3C;;;;;;;;OAQG;IACH,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAKF,iEAAiE;AACjE,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;OAIG;IACH,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACzD;;;;;;;;;;OAUG;IACH,eAAe,
|
|
1
|
+
{"version":3,"file":"synth-host.d.ts","sourceRoot":"","sources":["../../../src/web/playback/synth-host.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* percussion guard below is the one that most needs it.
|
|
15
15
|
*/
|
|
16
16
|
import { headroomTrimFor, LIMITER_CEILING_DB } from '../../shared/mix.js';
|
|
17
|
-
import { CHANNELS_PER_INSTANCE } from '
|
|
17
|
+
import { CHANNELS_PER_INSTANCE } from '../../playback/channel-allocator.js';
|
|
18
18
|
import { createWorkletQuietModuleUrl } from './quiet-stub-notices.js';
|
|
19
19
|
import { DRUM_BANK, PERCUSSION_CHANNEL } from '@sudobility/music_types';
|
|
20
20
|
/** Every channel, for the calls that would otherwise take an implicit one. */
|
|
@@ -295,7 +295,8 @@ export class SynthHost {
|
|
|
295
295
|
}
|
|
296
296
|
applyMasterGain() {
|
|
297
297
|
if (this.master)
|
|
298
|
-
this.master.gain.value =
|
|
298
|
+
this.master.gain.value =
|
|
299
|
+
this.masterVolume * headroomTrimFor(this.trackCount);
|
|
299
300
|
}
|
|
300
301
|
dispose() {
|
|
301
302
|
for (const sequencer of this.sequencers)
|