@libraz/libsonare 1.3.1 → 1.3.3
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 +277 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +333 -55
- package/dist/index.js.map +1 -1
- package/dist/sonare-rt-module.js +1 -1
- package/dist/sonare-rt.js +1 -1
- package/dist/sonare-rt.wasm +0 -0
- package/dist/sonare.js +1 -1
- package/dist/sonare.wasm +0 -0
- package/dist/worklet.d.ts +397 -9
- package/dist/worklet.js +1259 -87
- package/dist/worklet.js.map +1 -1
- package/package.json +1 -1
- package/src/effects_mastering.ts +16 -0
- package/src/errors.ts +44 -0
- package/src/index.ts +15 -1
- package/src/mixer.ts +11 -0
- package/src/module_state.ts +180 -4
- package/src/opfs_clip_pages.ts +43 -9
- package/src/realtime_engine.ts +174 -109
- package/src/sonare.js.d.ts +65 -0
- package/src/web_midi.ts +15 -11
- package/src/worklet.ts +1402 -66
package/dist/index.js
CHANGED
|
@@ -1,13 +1,168 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
|
|
3
|
+
ErrorCode2[ErrorCode2["Ok"] = 0] = "Ok";
|
|
4
|
+
ErrorCode2[ErrorCode2["FileNotFound"] = 1] = "FileNotFound";
|
|
5
|
+
ErrorCode2[ErrorCode2["InvalidFormat"] = 2] = "InvalidFormat";
|
|
6
|
+
ErrorCode2[ErrorCode2["DecodeFailed"] = 3] = "DecodeFailed";
|
|
7
|
+
ErrorCode2[ErrorCode2["InvalidParameter"] = 4] = "InvalidParameter";
|
|
8
|
+
ErrorCode2[ErrorCode2["OutOfMemory"] = 5] = "OutOfMemory";
|
|
9
|
+
ErrorCode2[ErrorCode2["NotSupported"] = 6] = "NotSupported";
|
|
10
|
+
ErrorCode2[ErrorCode2["InvalidState"] = 7] = "InvalidState";
|
|
11
|
+
ErrorCode2[ErrorCode2["Unknown"] = 99] = "Unknown";
|
|
12
|
+
return ErrorCode2;
|
|
13
|
+
})(ErrorCode || {});
|
|
14
|
+
var SonareError = class extends Error {
|
|
15
|
+
constructor(code, codeName, message) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.name = "SonareError";
|
|
18
|
+
this.code = code;
|
|
19
|
+
this.codeName = codeName;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
function isSonareError(value) {
|
|
23
|
+
return value instanceof Error && value.name === "SonareError" && typeof value.code === "number";
|
|
24
|
+
}
|
|
25
|
+
|
|
1
26
|
// src/module_state.ts
|
|
2
|
-
var
|
|
27
|
+
var wrappedModule = null;
|
|
28
|
+
function nativeExceptionPtr(error) {
|
|
29
|
+
if (typeof error === "number") {
|
|
30
|
+
return error;
|
|
31
|
+
}
|
|
32
|
+
if (error !== null && typeof error === "object") {
|
|
33
|
+
const ptr = error.excPtr;
|
|
34
|
+
if (typeof ptr === "number") {
|
|
35
|
+
return ptr;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
function makeSonareError(raw, thrown) {
|
|
41
|
+
let code = 99 /* Unknown */;
|
|
42
|
+
let codeName = "Unknown";
|
|
43
|
+
let message = `libsonare native exception (${thrown})`;
|
|
44
|
+
try {
|
|
45
|
+
const info = raw.sonareExceptionInfo?.(thrown);
|
|
46
|
+
if (info) {
|
|
47
|
+
code = info.code ?? code;
|
|
48
|
+
codeName = info.codeName ?? codeName;
|
|
49
|
+
message = info.message || message;
|
|
50
|
+
}
|
|
51
|
+
} catch {
|
|
52
|
+
}
|
|
53
|
+
return new SonareError(code, codeName, message);
|
|
54
|
+
}
|
|
55
|
+
function wrapModuleErrors(raw) {
|
|
56
|
+
const cache = /* @__PURE__ */ new Map();
|
|
57
|
+
const objectCache = /* @__PURE__ */ new WeakMap();
|
|
58
|
+
const convert = (error) => {
|
|
59
|
+
const ptr = nativeExceptionPtr(error);
|
|
60
|
+
if (ptr !== null) {
|
|
61
|
+
throw makeSonareError(raw, ptr);
|
|
62
|
+
}
|
|
63
|
+
throw error;
|
|
64
|
+
};
|
|
65
|
+
const wrapNativeObject = (value) => {
|
|
66
|
+
if (value === null || typeof value !== "object") {
|
|
67
|
+
return value;
|
|
68
|
+
}
|
|
69
|
+
if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer || value instanceof Promise) {
|
|
70
|
+
return value;
|
|
71
|
+
}
|
|
72
|
+
const objectValue = value;
|
|
73
|
+
const cached = objectCache.get(objectValue);
|
|
74
|
+
if (cached) {
|
|
75
|
+
return cached;
|
|
76
|
+
}
|
|
77
|
+
const methodCache = /* @__PURE__ */ new Map();
|
|
78
|
+
const wrapped = new Proxy(objectValue, {
|
|
79
|
+
get(target, prop, receiver) {
|
|
80
|
+
const member = Reflect.get(target, prop, receiver);
|
|
81
|
+
if (typeof member !== "function") {
|
|
82
|
+
return member;
|
|
83
|
+
}
|
|
84
|
+
const cachedMethod = methodCache.get(prop);
|
|
85
|
+
if (cachedMethod) {
|
|
86
|
+
return cachedMethod;
|
|
87
|
+
}
|
|
88
|
+
const method = member;
|
|
89
|
+
const wrappedMethod = (...args) => {
|
|
90
|
+
try {
|
|
91
|
+
return wrapNativeObject(Reflect.apply(method, target, args));
|
|
92
|
+
} catch (error) {
|
|
93
|
+
return convert(error);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
methodCache.set(prop, wrappedMethod);
|
|
97
|
+
return wrappedMethod;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
objectCache.set(objectValue, wrapped);
|
|
101
|
+
return wrapped;
|
|
102
|
+
};
|
|
103
|
+
const wrapFunction = (value) => {
|
|
104
|
+
const fnCache = /* @__PURE__ */ new Map();
|
|
105
|
+
return new Proxy(value, {
|
|
106
|
+
get(target, prop, receiver) {
|
|
107
|
+
const member = Reflect.get(target, prop, receiver);
|
|
108
|
+
if (typeof member !== "function") {
|
|
109
|
+
return member;
|
|
110
|
+
}
|
|
111
|
+
const cachedMember = fnCache.get(prop);
|
|
112
|
+
if (cachedMember) {
|
|
113
|
+
return cachedMember;
|
|
114
|
+
}
|
|
115
|
+
const fn = member;
|
|
116
|
+
const wrappedMember = (...args) => {
|
|
117
|
+
try {
|
|
118
|
+
return wrapNativeObject(Reflect.apply(fn, target, args));
|
|
119
|
+
} catch (error) {
|
|
120
|
+
return convert(error);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
fnCache.set(prop, wrappedMember);
|
|
124
|
+
return wrappedMember;
|
|
125
|
+
},
|
|
126
|
+
apply(t, thisArg, args) {
|
|
127
|
+
try {
|
|
128
|
+
return wrapNativeObject(Reflect.apply(t, thisArg, args));
|
|
129
|
+
} catch (error) {
|
|
130
|
+
return convert(error);
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
construct(t, args, newTarget) {
|
|
134
|
+
try {
|
|
135
|
+
return wrapNativeObject(Reflect.construct(t, args, newTarget));
|
|
136
|
+
} catch (error) {
|
|
137
|
+
return convert(error);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
return new Proxy(raw, {
|
|
143
|
+
get(target, prop, receiver) {
|
|
144
|
+
const value = Reflect.get(target, prop, receiver);
|
|
145
|
+
if (typeof value !== "function") {
|
|
146
|
+
return value;
|
|
147
|
+
}
|
|
148
|
+
const cached = cache.get(prop);
|
|
149
|
+
if (cached) {
|
|
150
|
+
return cached;
|
|
151
|
+
}
|
|
152
|
+
const wrapped = wrapFunction(value);
|
|
153
|
+
cache.set(prop, wrapped);
|
|
154
|
+
return wrapped;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
3
158
|
function setSonareModule(module2) {
|
|
4
|
-
|
|
159
|
+
wrappedModule = wrapModuleErrors(module2);
|
|
5
160
|
}
|
|
6
161
|
function getSonareModule() {
|
|
7
|
-
if (!
|
|
162
|
+
if (!wrappedModule) {
|
|
8
163
|
throw new Error("Module not initialized. Call init() first.");
|
|
9
164
|
}
|
|
10
|
-
return
|
|
165
|
+
return wrappedModule;
|
|
11
166
|
}
|
|
12
167
|
|
|
13
168
|
// src/codes.ts
|
|
@@ -82,6 +237,16 @@ var Mixer = class _Mixer {
|
|
|
82
237
|
compile() {
|
|
83
238
|
this.mixer.compile();
|
|
84
239
|
}
|
|
240
|
+
/**
|
|
241
|
+
* Non-fatal warnings captured when this mixer was built from scene JSON: one
|
|
242
|
+
* entry per channel-strip insert that was handed param keys it does not read
|
|
243
|
+
* (a likely typo, or a key meant for a different processor). The scene still
|
|
244
|
+
* loaded; these keys simply took no effect. Empty when every key was consumed.
|
|
245
|
+
* Use {@link masteringInsertParamNames} to discover the keys an insert accepts.
|
|
246
|
+
*/
|
|
247
|
+
sceneWarnings() {
|
|
248
|
+
return this.mixer.sceneWarnings();
|
|
249
|
+
}
|
|
85
250
|
/**
|
|
86
251
|
* Mix one block of per-strip stereo audio into the stereo master.
|
|
87
252
|
*
|
|
@@ -1019,6 +1184,9 @@ function masteringProcessorNames() {
|
|
|
1019
1184
|
function masteringInsertNames() {
|
|
1020
1185
|
return requireModule().masteringInsertNames();
|
|
1021
1186
|
}
|
|
1187
|
+
function masteringInsertParamNames(name) {
|
|
1188
|
+
return requireModule().masteringInsertParamNames(name);
|
|
1189
|
+
}
|
|
1022
1190
|
function masteringPairProcessorNames() {
|
|
1023
1191
|
return requireModule().masteringPairProcessorNames();
|
|
1024
1192
|
}
|
|
@@ -2503,10 +2671,25 @@ function waveformPeakPyramid(samples, channels, options = {}) {
|
|
|
2503
2671
|
|
|
2504
2672
|
// src/opfs_clip_pages.ts
|
|
2505
2673
|
var opfsClipPageWorkerSource = `
|
|
2674
|
+
const sonareClipPageReadQueues = new Map();
|
|
2675
|
+
|
|
2676
|
+
function sonareEnqueueClipPageRead(key, task) {
|
|
2677
|
+
const previous = sonareClipPageReadQueues.get(key) || Promise.resolve();
|
|
2678
|
+
const next = previous.catch(() => undefined).then(task);
|
|
2679
|
+
const queued = next.finally(() => {
|
|
2680
|
+
if (sonareClipPageReadQueues.get(key) === queued) {
|
|
2681
|
+
sonareClipPageReadQueues.delete(key);
|
|
2682
|
+
}
|
|
2683
|
+
});
|
|
2684
|
+
sonareClipPageReadQueues.set(key, queued);
|
|
2685
|
+
return next;
|
|
2686
|
+
}
|
|
2687
|
+
|
|
2506
2688
|
self.onmessage = async (event) => {
|
|
2507
2689
|
const message = event.data;
|
|
2508
2690
|
if (!message || message.type !== 'sonare:read-clip-page') return;
|
|
2509
2691
|
const { requestId, path, pageIndex, numChannels, numSamples, pageFrames, dataOffsetBytes = 0 } = message;
|
|
2692
|
+
await sonareEnqueueClipPageRead(String(path), async () => {
|
|
2510
2693
|
try {
|
|
2511
2694
|
if (pageIndex < 0) {
|
|
2512
2695
|
self.postMessage({ type: 'sonare:clip-page', requestId, pageIndex, ok: false });
|
|
@@ -2569,6 +2752,7 @@ self.onmessage = async (event) => {
|
|
|
2569
2752
|
error: error instanceof Error ? error.message : String(error),
|
|
2570
2753
|
});
|
|
2571
2754
|
}
|
|
2755
|
+
});
|
|
2572
2756
|
};
|
|
2573
2757
|
`;
|
|
2574
2758
|
function createOpfsClipPageWorker() {
|
|
@@ -2588,6 +2772,7 @@ function createOpfsClipPageProvider(engine, options) {
|
|
|
2588
2772
|
const ownsWorker = options.worker === void 0 || options.terminateWorkerOnClose === true;
|
|
2589
2773
|
let nextRequestId = 1;
|
|
2590
2774
|
let closed = false;
|
|
2775
|
+
let readQueue = Promise.resolve();
|
|
2591
2776
|
const pending = /* @__PURE__ */ new Map();
|
|
2592
2777
|
const onMessage = (event) => {
|
|
2593
2778
|
const response = event.data;
|
|
@@ -2627,15 +2812,29 @@ function createOpfsClipPageProvider(engine, options) {
|
|
|
2627
2812
|
const promise = new Promise((resolve, reject) => {
|
|
2628
2813
|
pending.set(requestId, { resolve, reject });
|
|
2629
2814
|
});
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2815
|
+
readQueue = readQueue.catch(() => void 0).then(() => {
|
|
2816
|
+
if (closed) {
|
|
2817
|
+
const entry = pending.get(requestId);
|
|
2818
|
+
pending.delete(requestId);
|
|
2819
|
+
entry?.reject(new Error("OpfsClipPageProvider is closed"));
|
|
2820
|
+
return;
|
|
2821
|
+
}
|
|
2822
|
+
worker.postMessage({
|
|
2823
|
+
type: "sonare:read-clip-page",
|
|
2824
|
+
requestId,
|
|
2825
|
+
path: options.path,
|
|
2826
|
+
pageIndex,
|
|
2827
|
+
numChannels: options.numChannels,
|
|
2828
|
+
numSamples: options.numSamples,
|
|
2829
|
+
pageFrames: options.pageFrames,
|
|
2830
|
+
dataOffsetBytes: options.dataOffsetBytes ?? 0
|
|
2831
|
+
});
|
|
2832
|
+
return promise.then(
|
|
2833
|
+
() => void 0,
|
|
2834
|
+
() => void 0
|
|
2835
|
+
);
|
|
2836
|
+
});
|
|
2837
|
+
readQueue.catch(() => {
|
|
2639
2838
|
});
|
|
2640
2839
|
return promise;
|
|
2641
2840
|
};
|
|
@@ -3386,9 +3585,6 @@ function engineCapabilities() {
|
|
|
3386
3585
|
};
|
|
3387
3586
|
}
|
|
3388
3587
|
var RealtimeEngine = class {
|
|
3389
|
-
nativeExt() {
|
|
3390
|
-
return this.native;
|
|
3391
|
-
}
|
|
3392
3588
|
constructor(sampleRate = 48e3, maxBlockSize = 128, commandCapacity = 1024, telemetryCapacity = 1024) {
|
|
3393
3589
|
const module2 = getSonareModule();
|
|
3394
3590
|
const capabilities = engineCapabilities();
|
|
@@ -3415,8 +3611,14 @@ var RealtimeEngine = class {
|
|
|
3415
3611
|
setParameterSmoothed(paramId, value, renderFrame = -1) {
|
|
3416
3612
|
this.native.setParameterSmoothed(paramId, value, renderFrame);
|
|
3417
3613
|
}
|
|
3614
|
+
setSoloMute(laneIndex, solo, mute, renderFrame = -1) {
|
|
3615
|
+
this.native.setSoloMute(laneIndex, solo, mute, renderFrame);
|
|
3616
|
+
}
|
|
3617
|
+
setMidiClips(clips) {
|
|
3618
|
+
this.native.setMidiClips(clips);
|
|
3619
|
+
}
|
|
3418
3620
|
setBuiltinInstrument(config = {}, destinationId = config.destinationId ?? 0) {
|
|
3419
|
-
this.
|
|
3621
|
+
this.native.setBuiltinInstrument(destinationId, config);
|
|
3420
3622
|
}
|
|
3421
3623
|
/**
|
|
3422
3624
|
* Bind the patch-driven NativeSynth to a realtime MIDI destination. `patch`
|
|
@@ -3428,7 +3630,7 @@ var RealtimeEngine = class {
|
|
|
3428
3630
|
* binding convenience, not part of the NativeSynth patch itself.
|
|
3429
3631
|
*/
|
|
3430
3632
|
setSynthInstrument(patch = {}, destinationId = (typeof patch === "object" ? patch.destinationId : void 0) ?? 0) {
|
|
3431
|
-
this.
|
|
3633
|
+
this.native.setSynthInstrument(destinationId, patch);
|
|
3432
3634
|
}
|
|
3433
3635
|
/**
|
|
3434
3636
|
* Load (parse) SoundFont 2 bytes into the engine so SF2 instruments can be
|
|
@@ -3437,7 +3639,7 @@ var RealtimeEngine = class {
|
|
|
3437
3639
|
* not referenced afterwards. Replaces any previously loaded SoundFont.
|
|
3438
3640
|
*/
|
|
3439
3641
|
loadSoundFont(data) {
|
|
3440
|
-
this.
|
|
3642
|
+
this.native.loadSoundFont(data);
|
|
3441
3643
|
}
|
|
3442
3644
|
/**
|
|
3443
3645
|
* Bind a GS-compatible SoundFont player to a realtime MIDI destination, fed
|
|
@@ -3449,13 +3651,13 @@ var RealtimeEngine = class {
|
|
|
3449
3651
|
* synthesizer GM fallback bank (the data-free floor).
|
|
3450
3652
|
*/
|
|
3451
3653
|
setSf2Instrument(config = {}, destinationId = config.destinationId ?? 0) {
|
|
3452
|
-
this.
|
|
3654
|
+
this.native.setSf2Instrument(destinationId, config);
|
|
3453
3655
|
}
|
|
3454
3656
|
clearMidiInstrument(destinationId = 0) {
|
|
3455
|
-
this.
|
|
3657
|
+
this.native.clearMidiInstrument(destinationId);
|
|
3456
3658
|
}
|
|
3457
3659
|
midiInstrumentCount() {
|
|
3458
|
-
return this.
|
|
3660
|
+
return this.native.midiInstrumentCount();
|
|
3459
3661
|
}
|
|
3460
3662
|
/**
|
|
3461
3663
|
* Bind a live MIDI CC to an engine automation parameter. The MIDI event still
|
|
@@ -3463,7 +3665,7 @@ var RealtimeEngine = class {
|
|
|
3463
3665
|
* mapped into [minValue, maxValue] for `paramId`.
|
|
3464
3666
|
*/
|
|
3465
3667
|
bindMidiCc(channel, controller, paramId, options = {}) {
|
|
3466
|
-
this.
|
|
3668
|
+
this.native.bindMidiCc(
|
|
3467
3669
|
channel,
|
|
3468
3670
|
controller,
|
|
3469
3671
|
paramId,
|
|
@@ -3472,42 +3674,42 @@ var RealtimeEngine = class {
|
|
|
3472
3674
|
);
|
|
3473
3675
|
}
|
|
3474
3676
|
clearMidiCcBindings() {
|
|
3475
|
-
this.
|
|
3677
|
+
this.native.clearMidiCcBindings();
|
|
3476
3678
|
}
|
|
3477
3679
|
midiCcBindingCount() {
|
|
3478
|
-
return this.
|
|
3680
|
+
return this.native.midiCcBindingCount();
|
|
3479
3681
|
}
|
|
3480
3682
|
/** Install/replace a live non-destructive MIDI-FX insert for one destination. */
|
|
3481
3683
|
setMidiFx(destinationId, configJson) {
|
|
3482
|
-
this.
|
|
3684
|
+
this.native.setMidiFx(destinationId, configJson);
|
|
3483
3685
|
}
|
|
3484
3686
|
clearMidiFx(destinationId = 0) {
|
|
3485
|
-
this.
|
|
3687
|
+
this.native.clearMidiFx(destinationId);
|
|
3486
3688
|
}
|
|
3487
3689
|
/** Enable the engine-owned live MIDI input source for a destination. */
|
|
3488
3690
|
setMidiInputSource(destinationId = 0) {
|
|
3489
|
-
this.
|
|
3691
|
+
this.native.setMidiInputSource(destinationId);
|
|
3490
3692
|
}
|
|
3491
3693
|
clearMidiInputSource() {
|
|
3492
|
-
this.
|
|
3694
|
+
this.native.clearMidiInputSource();
|
|
3493
3695
|
}
|
|
3494
3696
|
midiInputPendingCount() {
|
|
3495
|
-
return this.
|
|
3697
|
+
return this.native.midiInputPendingCount();
|
|
3496
3698
|
}
|
|
3497
3699
|
pushMidiInputNoteOn(group, channel, note, velocity, portTimeSamples = 0) {
|
|
3498
|
-
this.
|
|
3700
|
+
this.native.pushMidiInputNoteOn(group, channel, note, velocity, portTimeSamples);
|
|
3499
3701
|
}
|
|
3500
3702
|
pushMidiInputNoteOff(group, channel, note, velocity = 0, portTimeSamples = 0) {
|
|
3501
|
-
this.
|
|
3703
|
+
this.native.pushMidiInputNoteOff(group, channel, note, velocity, portTimeSamples);
|
|
3502
3704
|
}
|
|
3503
3705
|
pushMidiInputCc(group, channel, controller, value, portTimeSamples = 0) {
|
|
3504
|
-
this.
|
|
3706
|
+
this.native.pushMidiInputCc(group, channel, controller, value, portTimeSamples);
|
|
3505
3707
|
}
|
|
3506
3708
|
pushMidiNoteOn(destinationId, group, channel, note, velocity, renderFrame = -1) {
|
|
3507
|
-
this.
|
|
3709
|
+
this.native.pushMidiNoteOn(destinationId, group, channel, note, velocity, renderFrame);
|
|
3508
3710
|
}
|
|
3509
3711
|
pushMidiNoteOff(destinationId, group, channel, note, velocity = 0, renderFrame = -1) {
|
|
3510
|
-
this.
|
|
3712
|
+
this.native.pushMidiNoteOff(destinationId, group, channel, note, velocity, renderFrame);
|
|
3511
3713
|
}
|
|
3512
3714
|
/**
|
|
3513
3715
|
* Queue an immediate (live) MIDI control change to a MIDI destination
|
|
@@ -3516,21 +3718,21 @@ var RealtimeEngine = class {
|
|
|
3516
3718
|
* immediate. Mirrors the Node/Python/C-ABI `pushMidiCc`.
|
|
3517
3719
|
*/
|
|
3518
3720
|
pushMidiCc(destinationId, group, channel, controller, value, renderFrame = -1) {
|
|
3519
|
-
this.
|
|
3721
|
+
this.native.pushMidiCc(destinationId, group, channel, controller, value, renderFrame);
|
|
3520
3722
|
}
|
|
3521
3723
|
/**
|
|
3522
3724
|
* Queue a MIDI panic (all-notes-off) releasing every sounding note at
|
|
3523
3725
|
* `renderFrame` (-1 = immediate). Mirrors the C-ABI `pushMidiPanic`.
|
|
3524
3726
|
*/
|
|
3525
3727
|
pushMidiPanic(renderFrame = -1) {
|
|
3526
|
-
this.
|
|
3728
|
+
this.native.pushMidiPanic(renderFrame);
|
|
3527
3729
|
}
|
|
3528
3730
|
/**
|
|
3529
3731
|
* Remove all registered parameters (and their automation lanes). Control-thread
|
|
3530
3732
|
* only; not realtime-safe. Mirrors the C-ABI `clearParameters`.
|
|
3531
3733
|
*/
|
|
3532
3734
|
clearParameters() {
|
|
3533
|
-
this.
|
|
3735
|
+
this.native.clearParameters();
|
|
3534
3736
|
}
|
|
3535
3737
|
/** Read back the current transport state snapshot. */
|
|
3536
3738
|
getTransportState() {
|
|
@@ -3551,9 +3753,18 @@ var RealtimeEngine = class {
|
|
|
3551
3753
|
setTempo(bpm) {
|
|
3552
3754
|
this.native.setTempo(bpm);
|
|
3553
3755
|
}
|
|
3756
|
+
setTempoSegments(segments) {
|
|
3757
|
+
this.native.setTempoSegments([...segments]);
|
|
3758
|
+
}
|
|
3554
3759
|
setTimeSignature(numerator, denominator) {
|
|
3555
3760
|
this.native.setTimeSignature(numerator, denominator);
|
|
3556
3761
|
}
|
|
3762
|
+
setTimeSignatureSegments(segments) {
|
|
3763
|
+
this.native.setTimeSignatureSegments([...segments]);
|
|
3764
|
+
}
|
|
3765
|
+
sampleAtPpq(ppq) {
|
|
3766
|
+
return Number(this.native.sampleAtPpq(ppq));
|
|
3767
|
+
}
|
|
3557
3768
|
setLoop(startPpq, endPpq, enabled = true) {
|
|
3558
3769
|
this.native.setLoop(startPpq, endPpq, enabled);
|
|
3559
3770
|
}
|
|
@@ -3622,21 +3833,81 @@ var RealtimeEngine = class {
|
|
|
3622
3833
|
clipCount() {
|
|
3623
3834
|
return this.native.clipCount();
|
|
3624
3835
|
}
|
|
3836
|
+
setTrackLanes(lanes) {
|
|
3837
|
+
this.native.setTrackLanes(
|
|
3838
|
+
lanes.map((lane) => typeof lane === "number" ? { trackId: lane } : lane)
|
|
3839
|
+
);
|
|
3840
|
+
}
|
|
3841
|
+
setTrackBuses(buses) {
|
|
3842
|
+
this.native.setTrackBuses(buses);
|
|
3843
|
+
}
|
|
3844
|
+
setBusStripJson(busId, sceneJson) {
|
|
3845
|
+
try {
|
|
3846
|
+
JSON.parse(sceneJson);
|
|
3847
|
+
} catch (error) {
|
|
3848
|
+
const message = error instanceof Error ? error.message : "invalid bus strip JSON";
|
|
3849
|
+
throw new SonareError(2 /* InvalidFormat */, "InvalidFormat", message);
|
|
3850
|
+
}
|
|
3851
|
+
this.native.setBusStripJson(busId, sceneJson);
|
|
3852
|
+
}
|
|
3853
|
+
setTrackStripJson(trackId, sceneJson) {
|
|
3854
|
+
try {
|
|
3855
|
+
JSON.parse(sceneJson);
|
|
3856
|
+
} catch (error) {
|
|
3857
|
+
const message = error instanceof Error ? error.message : "invalid track strip JSON";
|
|
3858
|
+
throw new SonareError(2 /* InvalidFormat */, "InvalidFormat", message);
|
|
3859
|
+
}
|
|
3860
|
+
this.native.setTrackStripJson(trackId, sceneJson);
|
|
3861
|
+
}
|
|
3862
|
+
setTrackStripEqBand(trackId, bandIndex, band) {
|
|
3863
|
+
this.native.setTrackStripEqBandJson(
|
|
3864
|
+
trackId,
|
|
3865
|
+
bandIndex,
|
|
3866
|
+
typeof band === "string" ? band : JSON.stringify(band)
|
|
3867
|
+
);
|
|
3868
|
+
}
|
|
3869
|
+
setTrackStripEqBandJson(trackId, bandIndex, bandJson) {
|
|
3870
|
+
this.native.setTrackStripEqBandJson(trackId, bandIndex, bandJson);
|
|
3871
|
+
}
|
|
3872
|
+
setTrackStripInsertBypassed(trackId, insertIndex, bypassed, resetOnBypass = false) {
|
|
3873
|
+
this.native.setTrackStripInsertBypassed(trackId, insertIndex, bypassed, resetOnBypass);
|
|
3874
|
+
}
|
|
3875
|
+
setMasterStripJson(sceneJson) {
|
|
3876
|
+
try {
|
|
3877
|
+
JSON.parse(sceneJson);
|
|
3878
|
+
} catch (error) {
|
|
3879
|
+
const message = error instanceof Error ? error.message : "invalid master strip JSON";
|
|
3880
|
+
throw new SonareError(2 /* InvalidFormat */, "InvalidFormat", message);
|
|
3881
|
+
}
|
|
3882
|
+
this.native.setMasterStripJson(sceneJson);
|
|
3883
|
+
}
|
|
3884
|
+
setMasterStripEqBand(bandIndex, band) {
|
|
3885
|
+
this.native.setMasterStripEqBandJson(
|
|
3886
|
+
bandIndex,
|
|
3887
|
+
typeof band === "string" ? band : JSON.stringify(band)
|
|
3888
|
+
);
|
|
3889
|
+
}
|
|
3890
|
+
setMasterStripEqBandJson(bandIndex, bandJson) {
|
|
3891
|
+
this.native.setMasterStripEqBandJson(bandIndex, bandJson);
|
|
3892
|
+
}
|
|
3893
|
+
setMasterStripInsertBypassed(insertIndex, bypassed, resetOnBypass = false) {
|
|
3894
|
+
this.native.setMasterStripInsertBypassed(insertIndex, bypassed, resetOnBypass);
|
|
3895
|
+
}
|
|
3625
3896
|
createClipPageProvider(numChannels, numSamples, pageFrames) {
|
|
3626
|
-
const id = this.
|
|
3897
|
+
const id = this.native.createClipPageProvider(numChannels, numSamples, pageFrames);
|
|
3627
3898
|
return new ClipPageProvider(this, id);
|
|
3628
3899
|
}
|
|
3629
3900
|
supplyClipPage(providerId, pageIndex, channels) {
|
|
3630
|
-
this.
|
|
3901
|
+
this.native.supplyClipPage(providerId, pageIndex, channels);
|
|
3631
3902
|
}
|
|
3632
3903
|
clearClipPage(providerId, pageIndex) {
|
|
3633
|
-
this.
|
|
3904
|
+
this.native.clearClipPage(providerId, pageIndex);
|
|
3634
3905
|
}
|
|
3635
3906
|
destroyClipPageProvider(providerId) {
|
|
3636
|
-
this.
|
|
3907
|
+
this.native.destroyClipPageProvider(providerId);
|
|
3637
3908
|
}
|
|
3638
3909
|
popClipPageRequest() {
|
|
3639
|
-
return this.
|
|
3910
|
+
return this.native.popClipPageRequest();
|
|
3640
3911
|
}
|
|
3641
3912
|
setCaptureBuffer(numChannels, capacityFrames) {
|
|
3642
3913
|
this.native.setCaptureBuffer(numChannels, capacityFrames);
|
|
@@ -3999,7 +4270,6 @@ async function bindWebMidi(engine, options = {}) {
|
|
|
3999
4270
|
engine.setMidiInputSource(destinationId);
|
|
4000
4271
|
const bound = /* @__PURE__ */ new Map();
|
|
4001
4272
|
let closed = false;
|
|
4002
|
-
let runningStatus = 0;
|
|
4003
4273
|
const shouldBind = (input) => input.state !== "disconnected" && (selectedIds.size === 0 || selectedIds.has(input.id));
|
|
4004
4274
|
const snapshotInputs = () => Array.from(iterInputs(access), ([id, input]) => ({
|
|
4005
4275
|
id,
|
|
@@ -4012,22 +4282,26 @@ async function bindWebMidi(engine, options = {}) {
|
|
|
4012
4282
|
if (bound.has(input.id) || !shouldBind(input)) {
|
|
4013
4283
|
return;
|
|
4014
4284
|
}
|
|
4015
|
-
const
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4285
|
+
const entry = {
|
|
4286
|
+
input,
|
|
4287
|
+
listener: (event) => {
|
|
4288
|
+
entry.runningStatus = dispatchMidiMessage(
|
|
4289
|
+
engine,
|
|
4290
|
+
event,
|
|
4291
|
+
group,
|
|
4292
|
+
entry.runningStatus,
|
|
4293
|
+
options.timestampToSamples
|
|
4294
|
+
);
|
|
4295
|
+
},
|
|
4296
|
+
runningStatus: 0
|
|
4024
4297
|
};
|
|
4298
|
+
const listener = entry.listener;
|
|
4025
4299
|
if (input.addEventListener) {
|
|
4026
4300
|
input.addEventListener("midimessage", listener);
|
|
4027
4301
|
} else {
|
|
4028
4302
|
input.onmidimessage = listener;
|
|
4029
4303
|
}
|
|
4030
|
-
bound.set(input.id,
|
|
4304
|
+
bound.set(input.id, entry);
|
|
4031
4305
|
};
|
|
4032
4306
|
const unbindInput = (input) => {
|
|
4033
4307
|
const entry = bound.get(input.id);
|
|
@@ -4212,7 +4486,7 @@ async function init(options) {
|
|
|
4212
4486
|
}
|
|
4213
4487
|
initPromise = (async () => {
|
|
4214
4488
|
try {
|
|
4215
|
-
const createModule = (await import("./sonare.js")).default;
|
|
4489
|
+
const createModule = options?.moduleFactory ?? (await import("./sonare.js")).default;
|
|
4216
4490
|
module = await createModule(options);
|
|
4217
4491
|
setSonareModule(module);
|
|
4218
4492
|
} catch (error) {
|
|
@@ -4278,6 +4552,7 @@ export {
|
|
|
4278
4552
|
ChordQuality,
|
|
4279
4553
|
EXPECTED_ENGINE_ABI_VERSION,
|
|
4280
4554
|
EXPECTED_PROJECT_ABI_VERSION,
|
|
4555
|
+
ErrorCode,
|
|
4281
4556
|
KeyProfile,
|
|
4282
4557
|
Mixer,
|
|
4283
4558
|
Mode,
|
|
@@ -4294,6 +4569,7 @@ export {
|
|
|
4294
4569
|
SYNTH_MOD_SOURCES,
|
|
4295
4570
|
SYNTH_OSC_WAVEFORMS,
|
|
4296
4571
|
SectionType,
|
|
4572
|
+
SonareError,
|
|
4297
4573
|
StreamAnalyzer,
|
|
4298
4574
|
StreamingEqualizer,
|
|
4299
4575
|
StreamingMasteringChain,
|
|
@@ -4352,6 +4628,7 @@ export {
|
|
|
4352
4628
|
hzToNote,
|
|
4353
4629
|
init,
|
|
4354
4630
|
isInitialized,
|
|
4631
|
+
isSonareError,
|
|
4355
4632
|
isWebMidiAvailable,
|
|
4356
4633
|
lufs,
|
|
4357
4634
|
lufsInterleaved,
|
|
@@ -4370,6 +4647,7 @@ export {
|
|
|
4370
4647
|
masteringDynamicsGate,
|
|
4371
4648
|
masteringDynamicsTransientShaper,
|
|
4372
4649
|
masteringInsertNames,
|
|
4650
|
+
masteringInsertParamNames,
|
|
4373
4651
|
masteringPairAnalysisNames,
|
|
4374
4652
|
masteringPairAnalyze,
|
|
4375
4653
|
masteringPairProcess,
|