@sudobility/music_player 0.1.8 → 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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel-allocator.d.ts","sourceRoot":"","sources":["../../src/playback/channel-allocator.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnE;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAOzC,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,GAAG;IACnE,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC5C,aAAa,EAAE,MAAM,CAAC;CACvB,CA4EA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel-allocator.js","sourceRoot":"","sources":["../../src/playback/channel-allocator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clock.d.ts","sourceRoot":"","sources":["../../src/playback/clock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,qBAAa,aAAa;IAMZ,OAAO,CAAC,QAAQ,CAAC,GAAG;IALhC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,IAAI,CAAK;gBAEY,GAAG,EAAE,MAAM,MAAM;IAE9C,oFAAoF;IACpF,KAAK,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAMjC,KAAK,IAAI,IAAI;IAMb,IAAI,IAAI,IAAI;IAMZ,wEAAwE;IACxE,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAK3B;;;;;;OAMG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM3B,IAAI,eAAe,IAAI,MAAM,CAG5B;IAED,IAAI,SAAS,IAAI,OAAO,CAEvB;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clock.js","sourceRoot":"","sources":["../../src/playback/clock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,OAAO,aAAa;IAMK;IALrB,OAAO,GAAG,KAAK,CAAC;IAChB,SAAS,GAAG,CAAC,CAAC;IACd,cAAc,GAAG,CAAC,CAAC;IACnB,IAAI,GAAG,CAAC,CAAC;IAEjB,YAA6B,GAAiB;QAAjB,QAAG,GAAH,GAAG,CAAc;IAAG,CAAC;IAElD,oFAAoF;IACpF,KAAK,CAAC,WAAoB;QACxB,IAAI,CAAC,cAAc,GAAG,WAAW,IAAI,IAAI,CAAC,eAAe,CAAC;QAC1D,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAC1B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC;QAC3C,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,IAAI;QACF,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC9B,CAAC;IAED,wEAAwE;IACxE,IAAI,CAAC,OAAe;QAClB,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC;QAC9B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC9B,CAAC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,IAAY;QAClB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC;QAC3C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,IAAI,eAAe;QACjB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC,cAAc,CAAC;QAC9C,OAAO,IAAI,CAAC,cAAc,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;IACzE,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"governor.d.ts","sourceRoot":"","sources":["../../src/playback/governor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,EAAE,CAAC,kBAAkB,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD,CAAC;AAOF,qBAAa,QAAQ;IAGP,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,OAAO,CAAC,UAAU,CAAK;gBAEM,OAAO,GAAE,eAAoB;IAE1D,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,wEAAwE;IACxE,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED;;;;;;OAMG;IACH,MAAM,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;CAOpC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"governor.js","sourceRoot":"","sources":["../../src/playback/governor.ts"],"names":[],"mappings":"AA6BA,qDAAqD;AACrD,MAAM,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5B,iEAAiE;AACjE,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAEnC,MAAM,OAAO,QAAQ;IAGU;IAFrB,UAAU,GAAG,CAAC,CAAC;IAEvB,YAA6B,UAA2B,EAAE;QAA7B,YAAO,GAAP,OAAO,CAAsB;IAAG,CAAC;IAE9D,IAAI,aAAa;QACf,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC;IAED,wEAAwE;IACxE,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,aAAqB;QAC1B,IAAI,aAAa,GAAG,sBAAsB,EAAE,CAAC;YAC3C,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;IACtB,CAAC;CACF"}
|
|
@@ -15,39 +15,12 @@
|
|
|
15
15
|
* last one accumulated four silent-failure bugs.
|
|
16
16
|
*/
|
|
17
17
|
import type { PlaybackPlan, PlaybackTrack, ScoreRange } from '@sudobility/music_types';
|
|
18
|
-
import type { AuditionVoice, PlaybackEngine, PlaybackObserver } from '
|
|
19
|
-
import type {
|
|
20
|
-
/** The slice of `SynthHost` this engine drives, so tests can pass a stub. */
|
|
21
|
-
export type SynthHostLike = {
|
|
22
|
-
init(context: BaseAudioContext, options: {
|
|
23
|
-
fluidsynthModuleUrl: string;
|
|
24
|
-
workletModuleUrl: string;
|
|
25
|
-
soundfont: ArrayBuffer;
|
|
26
|
-
instanceCount: number;
|
|
27
|
-
}): Promise<void>;
|
|
28
|
-
ensureInstances(count: number): Promise<void>;
|
|
29
|
-
setChannelPercussion(instance: number, channel: number, kit?: number): void;
|
|
30
|
-
programSelect(instance: number, channel: number, program: number): void;
|
|
31
|
-
noteOn(instance: number, channel: number, midi: number, velocity: number): void;
|
|
32
|
-
noteAt(instance: number, channel: number, midi: number, velocity: number, delaySeconds: number, durationSeconds: number): void;
|
|
33
|
-
noteOff(instance: number, channel: number, midi: number): void;
|
|
34
|
-
controlChange(instance: number, channel: number, control: number, value: number): void;
|
|
35
|
-
allSoundOff(): void;
|
|
36
|
-
setInterpolation(order: number): void;
|
|
37
|
-
setMasterVolume(volume: number): void;
|
|
38
|
-
setTrackCount(count: number): void;
|
|
39
|
-
dispose(): void;
|
|
40
|
-
};
|
|
18
|
+
import type { AuditionVoice, PlaybackEngine, PlaybackObserver } from '../engine.js';
|
|
19
|
+
import type { SynthBackend } from './synth-backend.js';
|
|
41
20
|
export type SoundfontEngineDeps = {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
worklet: string;
|
|
46
|
-
};
|
|
47
|
-
fontUrl: string;
|
|
48
|
-
loadFont?: (url: string, onProgress?: (progress: LoadProgress) => void) => Promise<ArrayBuffer>;
|
|
49
|
-
createContext?: () => AudioContext;
|
|
50
|
-
/** Defaults to the audio context's own clock, which is what the audio is rendered against. */
|
|
21
|
+
/** Everything that makes sound: the synths, the clock, the font, the click. */
|
|
22
|
+
backend: SynthBackend;
|
|
23
|
+
/** Defaults to the backend's own clock, which is what the audio is rendered against. */
|
|
51
24
|
now?: () => number;
|
|
52
25
|
/** Starts the pump and returns a function that stops it. */
|
|
53
26
|
startPump?: (tick: () => void, intervalMs: number) => () => void;
|
|
@@ -59,7 +32,6 @@ export declare class SoundfontPlaybackEngine implements PlaybackEngine {
|
|
|
59
32
|
private nextPumpDueAt;
|
|
60
33
|
private readonly clock;
|
|
61
34
|
private readonly deps;
|
|
62
|
-
private context;
|
|
63
35
|
private plan;
|
|
64
36
|
/** Replaced on every `load`. The default is 120 BPM at ppq 480, as before. */
|
|
65
37
|
private tempo;
|
|
@@ -146,10 +118,6 @@ export declare class SoundfontPlaybackEngine implements PlaybackEngine {
|
|
|
146
118
|
private bringUp;
|
|
147
119
|
/** Only on change, so a progress stream does not become a store-update stream. */
|
|
148
120
|
private reportLoad;
|
|
149
|
-
/** Best effort: without a user gesture behind it this is allowed to fail. */
|
|
150
|
-
private resumeContext;
|
|
151
|
-
/** A stub context in a test has no `state`; only a real suspended one blocks. */
|
|
152
|
-
private contextCanRun;
|
|
153
121
|
load(plan: PlaybackPlan): Promise<void>;
|
|
154
122
|
/**
|
|
155
123
|
* A channel no track owns, searched from the top down because tracks fill
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"soundfont-engine.d.ts","sourceRoot":"","sources":["../../src/playback/soundfont-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAGV,YAAY,EACZ,aAAa,EACb,UAAU,EAEX,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,gBAAgB,EACjB,MAAM,cAAc,CAAC;AActB,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvE,MAAM,MAAM,mBAAmB,GAAG;IAChC,+EAA+E;IAC/E,OAAO,EAAE,YAAY,CAAC;IACtB,wFAAwF;IACxF,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,MAAM,IAAI,CAAC;CAClE,CAAC;AAoDF,qBAAa,uBAAwB,YAAW,cAAc;IAC5D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,4EAA4E;IAC5E,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,IAAI,CACC;IAEtB,OAAO,CAAC,IAAI,CAA6B;IACzC,8EAA8E;IAC9E,OAAO,CAAC,KAAK,CAGX;IACF,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,kBAAkB,CAA6B;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,WAAW,CAAS;IAC5B,mEAAmE;IACnE,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,SAAS,CAAyC;IAC1D,sFAAsF;IACtF,OAAO,CAAC,YAAY,CAAK;IACzB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,gBAAgB,CAAS;IACjC,gFAAgF;IAChF,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,WAAW,CAAK;IACxB;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa,CAAwB;IAC7C,mFAAmF;IACnF,OAAO,CAAC,YAAY,CAAwC;IAC5D,oEAAoE;IACpE,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,eAAe,CAAK;IAC5B;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe,CAIrB;gBAEU,IAAI,EAAE,mBAAmB;IAkBrC,OAAO,CAAC,GAAG;IAKX,OAAO,CAAC,cAAc;IAItB;;;;;;;;;;;;;;OAcG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YASnB,OAAO;IA2BrB,kFAAkF;IAClF,OAAO,CAAC,UAAU;IAaZ,IAAI,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IA0C7C;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,mBAAmB;IAyB3B,2EAA2E;IAC3E,OAAO,CAAC,eAAe;IAkCvB,sEAAsE;IACtE,OAAO,CAAC,gBAAgB;IAcxB;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACG,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB5C,KAAK,IAAI,IAAI;IAQb,IAAI,IAAI,IAAI;IAaZ,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAwBxB;;;;;;;;;OASG;IACH,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAU5C,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI;IAIvC,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAOnD,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI;IAOlD;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI;IAiBhD,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAOpC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAIrC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI;IAmChD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAO3B,WAAW,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,GAAG,IAAI;IAIpD,OAAO,IAAI,IAAI;IAaf,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,OAAO;IAOf;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,IAAI;IAgBZ,OAAO,CAAC,YAAY;IA8CpB;;;;;;;;OAQG;IACH,OAAO,CAAC,WAAW;IAMnB;;;;;;OAMG;IACH,OAAO,CAAC,eAAe;IAQvB;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAyBrB,qFAAqF;IACrF,OAAO,CAAC,mBAAmB;IAO3B,qFAAqF;IACrF,OAAO,CAAC,cAAc;IAItB,OAAO,KAAK,aAAa,GAExB;IAED,OAAO,CAAC,SAAS;IAOjB;;;;;;;OAOG;IACH,OAAO,CAAC,MAAM;IA+Bd;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;IAQtB,wEAAwE;IACxE,OAAO,CAAC,aAAa;CAKtB"}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { allocateChannels, CHANNELS_PER_INSTANCE } from './channel-allocator.js';
|
|
1
|
+
import { allocateChannels, CHANNELS_PER_INSTANCE, } from './channel-allocator.js';
|
|
2
2
|
import { PlaybackClock } from './clock.js';
|
|
3
|
-
import { NoteQueue } from '
|
|
4
|
-
import { SoundingSet } from '
|
|
5
|
-
import { SOUNDING_INTERVAL_MS, visualSoundingOffsetSeconds, } from '
|
|
6
|
-
import { scheduleClick } from './click.js';
|
|
3
|
+
import { NoteQueue } from '../shared/note-queue.js';
|
|
4
|
+
import { SoundingSet } from '../shared/sounding-set.js';
|
|
5
|
+
import { SOUNDING_INTERVAL_MS, visualSoundingOffsetSeconds, } from '../shared/visual-sync.js';
|
|
7
6
|
import { Governor } from './governor.js';
|
|
8
|
-
import { loadSoundfont, openSoundfontCache } from './soundfont-loader.js';
|
|
9
7
|
import { CC_PAN, CC_VOLUME } from '@sudobility/music_types';
|
|
10
8
|
/** How often the pump runs. */
|
|
11
9
|
const PUMP_INTERVAL_MS = 50;
|
|
@@ -41,15 +39,6 @@ const MAX_CC = 127;
|
|
|
41
39
|
// taken on a sixteen-track score, and handed auditions a channel a track owned.
|
|
42
40
|
/** General MIDI's drum channel, which an audition must not borrow. */
|
|
43
41
|
const GM_PERCUSSION_CHANNEL = 9;
|
|
44
|
-
/**
|
|
45
|
-
* How much of the progress bar the download accounts for.
|
|
46
|
-
*
|
|
47
|
-
* The rest is the synth digesting the font, which is the longer half and
|
|
48
|
-
* reports nothing. Measured at roughly five seconds against a download that is
|
|
49
|
-
* near-instant on a fast connection, so this is deliberately conservative — a
|
|
50
|
-
* bar that reaches the end and then waits is worse than one that stops early.
|
|
51
|
-
*/
|
|
52
|
-
const FETCH_SHARE = 0.5;
|
|
53
42
|
/** A pump failing every tick must not also flood the console twenty times a second. */
|
|
54
43
|
const MAX_REPORTED_TICK_FAILURES = 3;
|
|
55
44
|
/** Percent granularity: finer changes are not worth a store update. */
|
|
@@ -63,12 +52,11 @@ export class SoundfontPlaybackEngine {
|
|
|
63
52
|
nextPumpDueAt = null;
|
|
64
53
|
clock;
|
|
65
54
|
deps;
|
|
66
|
-
context = null;
|
|
67
55
|
plan = null;
|
|
68
56
|
/** Replaced on every `load`. The default is 120 BPM at ppq 480, as before. */
|
|
69
57
|
tempo = {
|
|
70
|
-
ticksToSeconds:
|
|
71
|
-
secondsToTicks:
|
|
58
|
+
ticksToSeconds: tick => tick / 960,
|
|
59
|
+
secondsToTicks: seconds => seconds * 960,
|
|
72
60
|
};
|
|
73
61
|
tracks = new Map();
|
|
74
62
|
observer = null;
|
|
@@ -130,12 +118,14 @@ export class SoundfontPlaybackEngine {
|
|
|
130
118
|
* on it and left that part playing the wrong instrument until the next edit
|
|
131
119
|
* reloaded the score.
|
|
132
120
|
*/
|
|
133
|
-
auditionChannel = {
|
|
121
|
+
auditionChannel = {
|
|
122
|
+
instance: 0,
|
|
123
|
+
channel: 15,
|
|
124
|
+
needsDrumTypeSwitch: false,
|
|
125
|
+
};
|
|
134
126
|
constructor(deps) {
|
|
135
127
|
this.deps = {
|
|
136
128
|
...deps,
|
|
137
|
-
loadFont: deps.loadFont ??
|
|
138
|
-
(async (url, onProgress) => loadSoundfont(url, { cache: await openSoundfontCache(), onProgress })),
|
|
139
129
|
startPump: deps.startPump ??
|
|
140
130
|
((tick, ms) => {
|
|
141
131
|
const id = setInterval(tick, ms);
|
|
@@ -145,12 +135,14 @@ export class SoundfontPlaybackEngine {
|
|
|
145
135
|
this.clock = new PlaybackClock(() => this.now());
|
|
146
136
|
// The governor's only knob is interpolation order; see governor.ts for why
|
|
147
137
|
// polyphony is not a second rung.
|
|
148
|
-
this.governor = new Governor({
|
|
138
|
+
this.governor = new Governor({
|
|
139
|
+
onChange: order => this.deps.backend.setInterpolation(order),
|
|
140
|
+
});
|
|
149
141
|
}
|
|
150
142
|
now() {
|
|
151
143
|
if (this.deps.now)
|
|
152
144
|
return this.deps.now();
|
|
153
|
-
return this.
|
|
145
|
+
return this.deps.backend.now();
|
|
154
146
|
}
|
|
155
147
|
secondsForTick(tick) {
|
|
156
148
|
return this.tempo.ticksToSeconds(tick);
|
|
@@ -181,32 +173,19 @@ export class SoundfontPlaybackEngine {
|
|
|
181
173
|
async bringUp() {
|
|
182
174
|
if (this.initialized)
|
|
183
175
|
return;
|
|
184
|
-
this.context ??= this.deps.createContext?.() ?? new AudioContext();
|
|
185
|
-
await this.resumeContext();
|
|
186
|
-
if (!this.contextCanRun())
|
|
187
|
-
return;
|
|
188
176
|
try {
|
|
189
|
-
this.
|
|
190
|
-
const soundfont = await this.deps.loadFont(this.deps.fontUrl, ({ loaded, total }) => {
|
|
191
|
-
// Fetching is the measurable half. Held below 1 so the bar does not sit
|
|
192
|
-
// at "done" through the seconds of decoding that follow.
|
|
193
|
-
this.reportLoad({ status: 'loading', fraction: total > 0 ? (loaded / total) * FETCH_SHARE : null });
|
|
194
|
-
});
|
|
195
|
-
// Handing the font to fluidsynth takes seconds and reports nothing along
|
|
196
|
-
// the way, so this is the honest answer: busy, no idea how long.
|
|
197
|
-
this.reportLoad({ status: 'loading', fraction: null });
|
|
198
|
-
await this.deps.host.init(this.context, {
|
|
199
|
-
fluidsynthModuleUrl: this.deps.moduleUrls.fluidsynth,
|
|
200
|
-
workletModuleUrl: this.deps.moduleUrls.worklet,
|
|
201
|
-
soundfont,
|
|
202
|
-
// What the score already loaded needs, not a fixed one: a score with
|
|
203
|
-
// more parts than a single synth can address puts tracks on instance 1,
|
|
204
|
-
// and a synth that was never opened plays them silently.
|
|
177
|
+
const result = await this.deps.backend.prepare({
|
|
205
178
|
instanceCount: this.instanceCount,
|
|
179
|
+
onProgress: state => this.reportLoad(state),
|
|
206
180
|
});
|
|
181
|
+
// Not a failure: the backend could not come up yet and said so, which on
|
|
182
|
+
// the web means a context still waiting for a user gesture. `play()` and
|
|
183
|
+
// `noteOn()` are gestures and will get it running.
|
|
184
|
+
if (result === 'deferred')
|
|
185
|
+
return;
|
|
207
186
|
this.initialized = true;
|
|
208
|
-
// The score may have arrived while the
|
|
209
|
-
//
|
|
187
|
+
// The score may have arrived while the backend was still deferred; it
|
|
188
|
+
// has not been told about it yet.
|
|
210
189
|
if (this.plan)
|
|
211
190
|
this.applyPlanToHost(this.plan.tracks);
|
|
212
191
|
this.reportLoad({ status: 'ready' });
|
|
@@ -214,7 +193,10 @@ export class SoundfontPlaybackEngine {
|
|
|
214
193
|
catch (error) {
|
|
215
194
|
// Reported rather than swallowed: a font that will not load is the
|
|
216
195
|
// difference between silence-with-a-reason and silence.
|
|
217
|
-
this.reportLoad({
|
|
196
|
+
this.reportLoad({
|
|
197
|
+
status: 'failed',
|
|
198
|
+
message: error instanceof Error ? error.message : String(error),
|
|
199
|
+
});
|
|
218
200
|
throw error;
|
|
219
201
|
}
|
|
220
202
|
}
|
|
@@ -229,41 +211,29 @@ export class SoundfontPlaybackEngine {
|
|
|
229
211
|
this.loadState = state;
|
|
230
212
|
this.observer?.onLoadStateChange?.(state);
|
|
231
213
|
}
|
|
232
|
-
/** Best effort: without a user gesture behind it this is allowed to fail. */
|
|
233
|
-
async resumeContext() {
|
|
234
|
-
const context = this.context;
|
|
235
|
-
if (!context?.resume || context.state === 'running')
|
|
236
|
-
return;
|
|
237
|
-
try {
|
|
238
|
-
await context.resume();
|
|
239
|
-
}
|
|
240
|
-
catch {
|
|
241
|
-
// No gesture yet. `contextCanRun` will see it and defer the rest.
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
/** A stub context in a test has no `state`; only a real suspended one blocks. */
|
|
245
|
-
contextCanRun() {
|
|
246
|
-
const state = this.context?.state;
|
|
247
|
-
return state === undefined || state === 'running';
|
|
248
|
-
}
|
|
249
214
|
async load(plan) {
|
|
250
215
|
this.plan = plan;
|
|
251
216
|
this.tempo = plan.tempo;
|
|
252
217
|
const notes = plan.notes;
|
|
253
218
|
this.queue.load(notes);
|
|
254
219
|
this.lastNoteEndSeconds = notes.reduce((end, n) => Math.max(end, this.secondsForTick(n.tick + n.durTicks)), 0);
|
|
255
|
-
this.sounding.load(notes,
|
|
220
|
+
this.sounding.load(notes, tick => this.secondsForTick(tick));
|
|
256
221
|
this.clicks = plan.clicks;
|
|
257
222
|
this.clickCursor = 0;
|
|
258
223
|
this.seek(0);
|
|
259
|
-
const { assignments, instanceCount } = allocateChannels(plan.tracks.map(
|
|
224
|
+
const { assignments, instanceCount } = allocateChannels(plan.tracks.map(t => ({ id: t.id, isPercussion: t.isPercussion })));
|
|
260
225
|
this.instanceCount = instanceCount;
|
|
261
226
|
this.tracks = new Map();
|
|
262
227
|
for (const track of plan.tracks) {
|
|
263
228
|
const assignment = assignments.get(track.id);
|
|
264
229
|
if (!assignment)
|
|
265
230
|
continue;
|
|
266
|
-
this.tracks.set(track.id, {
|
|
231
|
+
this.tracks.set(track.id, {
|
|
232
|
+
assignment,
|
|
233
|
+
volume: track.volume,
|
|
234
|
+
muted: track.muted,
|
|
235
|
+
solo: track.solo,
|
|
236
|
+
});
|
|
267
237
|
}
|
|
268
238
|
this.auditionChannel = this.pickAuditionChannel();
|
|
269
239
|
// Only once there is a synth to tell. Before the fix above this ran inline,
|
|
@@ -271,7 +241,7 @@ export class SoundfontPlaybackEngine {
|
|
|
271
241
|
if (this.initialized) {
|
|
272
242
|
// A score can grow past what the open synths can address, and the tracks
|
|
273
243
|
// beyond them are silent until this resolves.
|
|
274
|
-
await this.deps.
|
|
244
|
+
await this.deps.backend.ensureInstances(this.instanceCount);
|
|
275
245
|
this.applyPlanToHost(plan.tracks);
|
|
276
246
|
}
|
|
277
247
|
else
|
|
@@ -290,7 +260,7 @@ export class SoundfontPlaybackEngine {
|
|
|
290
260
|
* disturbs one track's program beats a keyboard that makes no sound.
|
|
291
261
|
*/
|
|
292
262
|
pickAuditionChannel() {
|
|
293
|
-
const owned = new Set([...this.tracks.values()].map(
|
|
263
|
+
const owned = new Set([...this.tracks.values()].map(t => `${t.assignment.instance}:${t.assignment.channel}`));
|
|
294
264
|
for (let instance = 0; instance < this.instanceCount; instance += 1) {
|
|
295
265
|
for (let channel = CHANNELS_PER_INSTANCE - 1; channel >= 0; channel -= 1) {
|
|
296
266
|
if (channel === GM_PERCUSSION_CHANNEL)
|
|
@@ -300,7 +270,11 @@ export class SoundfontPlaybackEngine {
|
|
|
300
270
|
}
|
|
301
271
|
}
|
|
302
272
|
}
|
|
303
|
-
return {
|
|
273
|
+
return {
|
|
274
|
+
instance: 0,
|
|
275
|
+
channel: CHANNELS_PER_INSTANCE - 1,
|
|
276
|
+
needsDrumTypeSwitch: false,
|
|
277
|
+
};
|
|
304
278
|
}
|
|
305
279
|
/** Tells the host each track's program, percussion flag, pan and level. */
|
|
306
280
|
applyPlanToHost(tracks) {
|
|
@@ -311,26 +285,26 @@ export class SoundfontPlaybackEngine {
|
|
|
311
285
|
if (assignment.needsDrumTypeSwitch || track.isPercussion) {
|
|
312
286
|
// General MIDI selects the drum kit with a program change on the drum
|
|
313
287
|
// channel, so the track's program is its kit — Room, TR-808, Jazz.
|
|
314
|
-
this.deps.
|
|
288
|
+
this.deps.backend.setChannelPercussion(assignment.instance, assignment.channel, track.midiProgram);
|
|
315
289
|
}
|
|
316
290
|
else {
|
|
317
291
|
// A soundfont needs only the GM program number. The program-versus-name
|
|
318
292
|
// rule the old engine used existed to choose among hand-built synth
|
|
319
293
|
// voices and has no meaning here.
|
|
320
|
-
this.deps.
|
|
294
|
+
this.deps.backend.programSelect(assignment.instance, assignment.channel, track.midiProgram);
|
|
321
295
|
}
|
|
322
|
-
this.deps.
|
|
296
|
+
this.deps.backend.controlChange(assignment.instance, assignment.channel, CC_PAN, panToCc(track.pan));
|
|
323
297
|
}
|
|
324
|
-
this.deps.
|
|
298
|
+
this.deps.backend.setTrackCount(tracks.length);
|
|
325
299
|
this.applyTrackLevels();
|
|
326
300
|
}
|
|
327
301
|
/** Volume, mute and solo all resolve to one CC7 value per channel. */
|
|
328
302
|
applyTrackLevels() {
|
|
329
|
-
const anySolo = [...this.tracks.values()].some(
|
|
303
|
+
const anySolo = [...this.tracks.values()].some(t => t.solo);
|
|
330
304
|
for (const state of this.tracks.values()) {
|
|
331
305
|
const audible = anySolo ? state.solo : !state.muted;
|
|
332
306
|
const value = audible ? Math.round(state.volume * MAX_CC) : 0;
|
|
333
|
-
this.deps.
|
|
307
|
+
this.deps.backend.controlChange(state.assignment.instance, state.assignment.channel, CC_VOLUME, value);
|
|
334
308
|
}
|
|
335
309
|
}
|
|
336
310
|
/**
|
|
@@ -388,7 +362,7 @@ export class SoundfontPlaybackEngine {
|
|
|
388
362
|
this.startAtSeconds = null;
|
|
389
363
|
this.clock.stop();
|
|
390
364
|
this.endPump();
|
|
391
|
-
this.deps.
|
|
365
|
+
this.deps.backend.allSoundOff();
|
|
392
366
|
this.cancelPendingClicks();
|
|
393
367
|
this.clearSounding(0);
|
|
394
368
|
this.queue.seekToTick(0);
|
|
@@ -400,10 +374,10 @@ export class SoundfontPlaybackEngine {
|
|
|
400
374
|
const seconds = this.secondsForTick(tick);
|
|
401
375
|
this.clock.seek(seconds);
|
|
402
376
|
this.queue.seekToTick(tick);
|
|
403
|
-
this.clickCursor = this.clicks.findIndex(
|
|
377
|
+
this.clickCursor = this.clicks.findIndex(c => c.tick >= tick);
|
|
404
378
|
if (this.clickCursor < 0)
|
|
405
379
|
this.clickCursor = this.clicks.length;
|
|
406
|
-
this.deps.
|
|
380
|
+
this.deps.backend.allSoundOff();
|
|
407
381
|
this.cancelPendingClicks();
|
|
408
382
|
this.clearSounding(seconds);
|
|
409
383
|
// Report where we landed. Nothing else writes the store's position —
|
|
@@ -477,7 +451,7 @@ export class SoundfontPlaybackEngine {
|
|
|
477
451
|
state.volume = track.volume;
|
|
478
452
|
state.muted = track.muted;
|
|
479
453
|
state.solo = track.solo;
|
|
480
|
-
this.deps.
|
|
454
|
+
this.deps.backend.controlChange(state.assignment.instance, state.assignment.channel, CC_PAN, panToCc(track.pan));
|
|
481
455
|
}
|
|
482
456
|
this.applyTrackLevels();
|
|
483
457
|
}
|
|
@@ -489,7 +463,7 @@ export class SoundfontPlaybackEngine {
|
|
|
489
463
|
this.cancelPendingClicks();
|
|
490
464
|
}
|
|
491
465
|
setMasterVolume(volume) {
|
|
492
|
-
this.deps.
|
|
466
|
+
this.deps.backend.setMasterVolume(volume);
|
|
493
467
|
}
|
|
494
468
|
noteOn(midi, voice) {
|
|
495
469
|
// Tapping a key is a user gesture, so it is also a chance to get the synth
|
|
@@ -504,13 +478,13 @@ export class SoundfontPlaybackEngine {
|
|
|
504
478
|
if (voice.isPercussion) {
|
|
505
479
|
// `voice.program` is the kit, resolved by the caller, so this sounds the
|
|
506
480
|
// kit the track actually plays rather than whatever Standard it had.
|
|
507
|
-
this.deps.
|
|
481
|
+
this.deps.backend.setChannelPercussion(assignment.instance, assignment.channel, voice.program);
|
|
508
482
|
}
|
|
509
483
|
else {
|
|
510
484
|
// Switches the channel back off drums first, if the last audition was one.
|
|
511
|
-
this.deps.
|
|
485
|
+
this.deps.backend.programSelect(assignment.instance, assignment.channel, voice.program);
|
|
512
486
|
}
|
|
513
|
-
this.deps.
|
|
487
|
+
this.deps.backend.noteOn(assignment.instance, assignment.channel, midi, 100);
|
|
514
488
|
this.auditionHeld.set(midi, assignment);
|
|
515
489
|
}
|
|
516
490
|
noteOff(midi) {
|
|
@@ -518,7 +492,7 @@ export class SoundfontPlaybackEngine {
|
|
|
518
492
|
if (!assignment)
|
|
519
493
|
return;
|
|
520
494
|
this.auditionHeld.delete(midi);
|
|
521
|
-
this.deps.
|
|
495
|
+
this.deps.backend.noteOff(assignment.instance, assignment.channel, midi);
|
|
522
496
|
}
|
|
523
497
|
setObserver(observer) {
|
|
524
498
|
this.observer = observer;
|
|
@@ -526,9 +500,8 @@ export class SoundfontPlaybackEngine {
|
|
|
526
500
|
dispose() {
|
|
527
501
|
this.endPump();
|
|
528
502
|
this.cancelPendingClicks();
|
|
529
|
-
this.deps.
|
|
530
|
-
this.
|
|
531
|
-
this.context = null;
|
|
503
|
+
this.deps.backend.dispose();
|
|
504
|
+
this.deps.backend.dispose();
|
|
532
505
|
this.plan = null;
|
|
533
506
|
this.observer = null;
|
|
534
507
|
this.initialized = false;
|
|
@@ -598,7 +571,7 @@ export class SoundfontPlaybackEngine {
|
|
|
598
571
|
const { instance, channel } = state.assignment;
|
|
599
572
|
const atSeconds = this.secondsForTick(note.tick);
|
|
600
573
|
const endSeconds = this.secondsForTick(note.tick + note.durTicks);
|
|
601
|
-
this.deps.
|
|
574
|
+
this.deps.backend.noteAt(instance, channel, note.midi, clampVelocity(note.velocity),
|
|
602
575
|
// Clamped to zero in `noteAt`: a note whose moment passed during a
|
|
603
576
|
// stall sounds at once rather than being dropped, because the sequencer
|
|
604
577
|
// still holds its release.
|
|
@@ -657,9 +630,9 @@ export class SoundfontPlaybackEngine {
|
|
|
657
630
|
// Forget the ones that have finished sounding, so the list tracks what is
|
|
658
631
|
// still cancellable rather than growing for the length of the piece.
|
|
659
632
|
if (this.pendingClicks.length > 0) {
|
|
660
|
-
this.pendingClicks = this.pendingClicks.filter(
|
|
633
|
+
this.pendingClicks = this.pendingClicks.filter(click => click.endsAt > now);
|
|
661
634
|
}
|
|
662
|
-
if (!this.metronomeEnabled
|
|
635
|
+
if (!this.metronomeEnabled)
|
|
663
636
|
return;
|
|
664
637
|
while (this.clickCursor < this.clicks.length) {
|
|
665
638
|
const click = this.clicks[this.clickCursor];
|
|
@@ -669,7 +642,7 @@ export class SoundfontPlaybackEngine {
|
|
|
669
642
|
this.clickCursor += 1;
|
|
670
643
|
if (atSeconds < position)
|
|
671
644
|
continue; // already gone by; do not stack it up
|
|
672
|
-
this.pendingClicks.push(
|
|
645
|
+
this.pendingClicks.push(this.deps.backend.scheduleClick(now + Math.max(0, (atSeconds - position) / this.playbackSpeed), click.accent));
|
|
673
646
|
}
|
|
674
647
|
}
|
|
675
648
|
/** Takes back every click still queued — a stop, a seek, or the switch going off. */
|
|
@@ -739,7 +712,8 @@ export class SoundfontPlaybackEngine {
|
|
|
739
712
|
* caret, which interpolates and does not.
|
|
740
713
|
*/
|
|
741
714
|
reportSounding() {
|
|
742
|
-
const at = this.clock.positionSeconds +
|
|
715
|
+
const at = this.clock.positionSeconds +
|
|
716
|
+
visualSoundingOffsetSeconds(this.deps.backend.outputLatency());
|
|
743
717
|
const sounding = this.sounding.advanceTo(at);
|
|
744
718
|
if (sounding)
|
|
745
719
|
this.observer?.onActiveNotes(sounding);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"soundfont-engine.js","sourceRoot":"","sources":["../../src/playback/soundfont-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Everything the soundfont scheduler needs from the thing that makes sound.
|
|
3
|
+
*
|
|
4
|
+
* This is `SynthHostLike` grown up. That interface was already almost
|
|
5
|
+
* platform-free — instances, channels, programs, timestamped notes — but the
|
|
6
|
+
* engine reached around it for four things that are not: it created its own
|
|
7
|
+
* `AudioContext` for a clock, fetched the soundfont itself, handed the host
|
|
8
|
+
* web-only worklet URLs, and synthesized the metronome click with Web Audio
|
|
9
|
+
* oscillators. Each of those is a different answer on a platform with no
|
|
10
|
+
* `AudioContext` at all, and each was the reason a second engine looked
|
|
11
|
+
* necessary.
|
|
12
|
+
*
|
|
13
|
+
* They are all here instead, so the scheduler — the tempo map, the lookahead,
|
|
14
|
+
* the loop, the seek, the governor, the sounding set — exists once and runs
|
|
15
|
+
* unchanged wherever a backend can be built. `web/playback/web-backend.ts`
|
|
16
|
+
* builds one over `AudioContext` and js-synthesizer; `rn/playback/native-backend.ts`
|
|
17
|
+
* builds one over the native synth.
|
|
18
|
+
*/
|
|
19
|
+
import type { PlaybackLoadState } from '@sudobility/music_types';
|
|
20
|
+
/**
|
|
21
|
+
* A click that has been placed in the future.
|
|
22
|
+
*
|
|
23
|
+
* Abstract because a click is a tuned oscillator on the web and a percussion
|
|
24
|
+
* note natively; the scheduler only ever needs to know when it has finished
|
|
25
|
+
* sounding and how to take it back.
|
|
26
|
+
*/
|
|
27
|
+
export type ScheduledClick = {
|
|
28
|
+
/** When it has finished sounding, so a caller knows when to forget it. */
|
|
29
|
+
readonly endsAt: number;
|
|
30
|
+
/** Silences it from `atSeconds`, whether or not it has begun. */
|
|
31
|
+
cancel(atSeconds: number): void;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Whether the backend actually came up.
|
|
35
|
+
*
|
|
36
|
+
* `deferred` is not a failure: a browser starts an `AudioContext` suspended
|
|
37
|
+
* unless it was created inside a user gesture, and a suspended context never
|
|
38
|
+
* runs its `AudioWorklet` — so the font load would hang rather than fail. The
|
|
39
|
+
* scheduler does the cheap part and tries again from the next gesture. A
|
|
40
|
+
* backend with no such rule simply never returns it.
|
|
41
|
+
*/
|
|
42
|
+
export type PrepareResult = 'ready' | 'deferred';
|
|
43
|
+
export type SynthBackend = {
|
|
44
|
+
/**
|
|
45
|
+
* Brings up the device, the synths and the soundfont, reporting progress.
|
|
46
|
+
*
|
|
47
|
+
* The backend owns the font: a browser fetches bytes and hands them to a
|
|
48
|
+
* worklet, while a native synth is given a file URI and reads it itself —
|
|
49
|
+
* copying 23MB through a bridge would cost more than reading it does. The
|
|
50
|
+
* scheduler only forwards what comes back to `PlaybackLoadState`, which is
|
|
51
|
+
* what the "Preparing instruments" readout shows.
|
|
52
|
+
*/
|
|
53
|
+
prepare(options: {
|
|
54
|
+
instanceCount: number;
|
|
55
|
+
onProgress: (state: PlaybackLoadState) => void;
|
|
56
|
+
}): Promise<PrepareResult>;
|
|
57
|
+
/** Grows the pool. Never shrinks: a sounding note must not lose its synth. */
|
|
58
|
+
ensureInstances(count: number): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* The clock every scheduled time below is measured against.
|
|
61
|
+
*
|
|
62
|
+
* The audio device's own, not a JS timer: those drift against it, and a
|
|
63
|
+
* playhead is exactly what reveals the drift.
|
|
64
|
+
*/
|
|
65
|
+
now(): number;
|
|
66
|
+
/**
|
|
67
|
+
* Seconds between a sound being scheduled and it reaching the speaker, or
|
|
68
|
+
* `undefined` where the platform does not report it. `shared/visual-sync.ts`
|
|
69
|
+
* turns it into the offset that makes lit keys match the ear.
|
|
70
|
+
*/
|
|
71
|
+
outputLatency(): number | undefined;
|
|
72
|
+
/**
|
|
73
|
+
* A note that starts `delaySeconds` from `now()` and releases itself after
|
|
74
|
+
* `durationSeconds` — the scheduled-playback call.
|
|
75
|
+
*
|
|
76
|
+
* Self-releasing so that a note needs one crossing rather than two: on the
|
|
77
|
+
* web the pair goes to fluidsynth's sequencer on the audio thread, and
|
|
78
|
+
* natively it goes over a bridge, where a separate note-off could arrive
|
|
79
|
+
* 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
|
+
/** Places a click at `atSeconds` on `now()`'s clock. */
|
|
90
|
+
scheduleClick(atSeconds: number, accent: boolean): ScheduledClick;
|
|
91
|
+
allSoundOff(): void;
|
|
92
|
+
/** Interpolation order, lowered under load — see `governor.ts`. */
|
|
93
|
+
setInterpolation(order: number): void;
|
|
94
|
+
setMasterVolume(volume: number): void;
|
|
95
|
+
/** How many tracks are playing, for whatever headroom the backend applies. */
|
|
96
|
+
setTrackCount(count: number): void;
|
|
97
|
+
dispose(): void;
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=synth-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synth-backend.d.ts","sourceRoot":"","sources":["../../src/playback/synth-backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,iEAAiE;IACjE,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,UAAU,CAAC;AAEjD,MAAM,MAAM,YAAY,GAAG;IACzB;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO,EAAE;QACf,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;KAChD,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3B,8EAA8E;IAC9E,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9C;;;;;OAKG;IACH,GAAG,IAAI,MAAM,CAAC;IACd;;;;OAIG;IACH,aAAa,IAAI,MAAM,GAAG,SAAS,CAAC;IAEpC;;;;;;;;OAQG;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,wDAAwD;IACxD,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,cAAc,CAAC;IAElE,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,8EAA8E;IAC9E,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,OAAO,IAAI,IAAI,CAAC;CACjB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"synth-backend.js","sourceRoot":"","sources":["../../src/playback/synth-backend.ts"],"names":[],"mappings":""}
|