@libraz/libsonare 1.8.0 → 1.8.2
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 +5 -5
- package/dist/_effects_common.d.ts +2 -1
- package/dist/_effects_common.d.ts.map +1 -1
- package/dist/analysis.js +3 -0
- package/dist/analysis.js.map +1 -1
- package/dist/effects_mastering.d.ts +2 -2
- package/dist/effects_mastering.d.ts.map +1 -1
- package/dist/effects_note_ops.d.ts +55 -30
- package/dist/effects_note_ops.d.ts.map +1 -1
- package/dist/effects_timepitch.d.ts +17 -12
- package/dist/effects_timepitch.d.ts.map +1 -1
- package/dist/feature_decompose.d.ts +1 -1
- package/dist/feature_decompose.d.ts.map +1 -1
- package/dist/index.d.ts +11 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2098 -155
- package/dist/index.js.map +1 -1
- package/dist/instrument_types.d.ts +27 -3
- package/dist/instrument_types.d.ts.map +1 -1
- package/dist/mastering_core.d.ts +30 -3
- package/dist/mastering_core.d.ts.map +1 -1
- package/dist/mixer.d.ts +2 -2
- package/dist/mixer.d.ts.map +1 -1
- package/dist/project.d.ts +5 -4
- package/dist/project.d.ts.map +1 -1
- package/dist/project_class.d.ts +57 -3
- package/dist/project_class.d.ts.map +1 -1
- package/dist/project_internal.d.ts +35 -1
- package/dist/project_internal.d.ts.map +1 -1
- package/dist/project_types.d.ts +17 -6
- package/dist/project_types.d.ts.map +1 -1
- package/dist/public_types.d.ts +1 -0
- package/dist/public_types.d.ts.map +1 -1
- package/dist/public_types_mastering.d.ts +19 -1
- package/dist/public_types_mastering.d.ts.map +1 -1
- package/dist/public_types_playback.d.ts +1 -0
- package/dist/public_types_playback.d.ts.map +1 -1
- package/dist/public_types_spectral.d.ts +5 -5
- package/dist/public_types_spectral.d.ts.map +1 -1
- package/dist/public_types_vocal_edit.d.ts +250 -0
- package/dist/public_types_vocal_edit.d.ts.map +1 -0
- package/dist/public_types_vocal_project.d.ts +63 -0
- package/dist/public_types_vocal_project.d.ts.map +1 -0
- package/dist/realtime_engine.d.ts +106 -16
- package/dist/realtime_engine.d.ts.map +1 -1
- package/dist/repair_dereverb.d.ts +1 -0
- package/dist/repair_dereverb.d.ts.map +1 -1
- package/dist/repair_noise.d.ts +1 -0
- package/dist/repair_noise.d.ts.map +1 -1
- package/dist/sonare-analysis.wasm +0 -0
- package/dist/sonare.d.ts +89 -0
- package/dist/sonare.js +1 -1
- package/dist/sonare.wasm +0 -0
- package/dist/streaming_processors.d.ts +5 -0
- package/dist/streaming_processors.d.ts.map +1 -1
- package/dist/vocal_edit.d.ts +131 -0
- package/dist/vocal_edit.d.ts.map +1 -0
- package/dist/vocal_edit_worker.d.ts +51 -0
- package/dist/vocal_edit_worker.d.ts.map +1 -0
- package/dist/vocal_edit_worker.js +1462 -0
- package/dist/vocal_edit_worker.js.map +1 -0
- package/dist/vocal_edit_worker_client.d.ts +118 -0
- package/dist/vocal_edit_worker_client.d.ts.map +1 -0
- package/dist/vocal_edit_worker_protocol.d.ts +139 -0
- package/dist/vocal_edit_worker_protocol.d.ts.map +1 -0
- package/dist/vocal_project.d.ts +17 -0
- package/dist/vocal_project.d.ts.map +1 -0
- package/dist/web_midi.d.ts +4 -0
- package/dist/web_midi.d.ts.map +1 -1
- package/dist/worker.js.map +1 -1
- package/dist/worklet/engine-mixer-facade.d.ts +42 -5
- package/dist/worklet/engine-mixer-facade.d.ts.map +1 -1
- package/dist/worklet/engine-node.d.ts +10 -0
- package/dist/worklet/engine-node.d.ts.map +1 -1
- package/dist/worklet/engine-processor.d.ts +6 -1
- package/dist/worklet/engine-processor.d.ts.map +1 -1
- package/dist/worklet/engine-register.d.ts.map +1 -1
- package/dist/worklet/engine-strips.d.ts +8 -4
- package/dist/worklet/engine-strips.d.ts.map +1 -1
- package/dist/worklet/engine-sync.d.ts +4 -2
- package/dist/worklet/engine-sync.d.ts.map +1 -1
- package/dist/worklet/engine.d.ts +42 -9
- package/dist/worklet/engine.d.ts.map +1 -1
- package/dist/worklet/guards.d.ts +10 -2
- package/dist/worklet/guards.d.ts.map +1 -1
- package/dist/worklet/messages.d.ts +54 -9
- package/dist/worklet/messages.d.ts.map +1 -1
- package/dist/worklet/mixer-processor.d.ts +2 -2
- package/dist/worklet/mixer-processor.d.ts.map +1 -1
- package/dist/worklet/protocol.d.ts +20 -2
- package/dist/worklet/protocol.d.ts.map +1 -1
- package/dist/worklet.d.ts +1 -1
- package/dist/worklet.d.ts.map +1 -1
- package/dist/worklet.js +808 -204
- package/dist/worklet.js.map +1 -1
- package/package.json +6 -1
- package/src/_effects_common.ts +36 -6
- package/src/effects_mastering.ts +4 -0
- package/src/effects_note_ops.ts +92 -44
- package/src/effects_timepitch.ts +42 -31
- package/src/feature_decompose.ts +2 -2
- package/src/index.ts +39 -0
- package/src/instrument_types.ts +29 -3
- package/src/mastering_core.ts +98 -2
- package/src/mixer.ts +41 -21
- package/src/project.ts +8 -1
- package/src/project_class.ts +136 -1
- package/src/project_internal.ts +90 -0
- package/src/project_types.ts +18 -6
- package/src/public_types.ts +1 -0
- package/src/public_types_mastering.ts +23 -0
- package/src/public_types_playback.ts +1 -0
- package/src/public_types_spectral.ts +5 -5
- package/src/public_types_vocal_edit.ts +289 -0
- package/src/public_types_vocal_project.ts +69 -0
- package/src/realtime_engine.ts +157 -24
- package/src/repair_dereverb.ts +1 -0
- package/src/repair_noise.ts +1 -0
- package/src/sonare.js.d.ts +89 -0
- package/src/streaming_processors.ts +8 -0
- package/src/vocal_edit.ts +885 -0
- package/src/vocal_edit_worker.ts +832 -0
- package/src/vocal_edit_worker_client.ts +812 -0
- package/src/vocal_edit_worker_protocol.ts +206 -0
- package/src/vocal_project.ts +327 -0
- package/src/web_midi.ts +100 -5
- package/src/worklet/engine-mixer-facade.ts +422 -87
- package/src/worklet/engine-node.ts +69 -4
- package/src/worklet/engine-processor.ts +129 -34
- package/src/worklet/engine-register.ts +3 -0
- package/src/worklet/engine-strips.ts +36 -14
- package/src/worklet/engine-sync.ts +6 -1
- package/src/worklet/engine.ts +76 -40
- package/src/worklet/guards.ts +81 -0
- package/src/worklet/messages.ts +63 -4
- package/src/worklet/mixer-processor.ts +10 -3
- package/src/worklet/protocol.ts +39 -8
- package/src/worklet.ts +2 -0
package/dist/index.js
CHANGED
|
@@ -177,8 +177,8 @@ function wrapModuleErrors(raw) {
|
|
|
177
177
|
}
|
|
178
178
|
});
|
|
179
179
|
}
|
|
180
|
-
function setSonareModule(
|
|
181
|
-
wrappedModule = wrapModuleErrors(
|
|
180
|
+
function setSonareModule(module3) {
|
|
181
|
+
wrappedModule = wrapModuleErrors(module3);
|
|
182
182
|
}
|
|
183
183
|
function getSonareModule() {
|
|
184
184
|
if (!wrappedModule) {
|
|
@@ -518,6 +518,19 @@ function assertInterleavedSamples(fnName, samples, channels, validate) {
|
|
|
518
518
|
}
|
|
519
519
|
|
|
520
520
|
// src/project_internal.ts
|
|
521
|
+
var projectTimelineHandles = /* @__PURE__ */ new WeakMap();
|
|
522
|
+
function registerProjectTimeline(owner, native) {
|
|
523
|
+
projectTimelineHandles.set(owner, native);
|
|
524
|
+
}
|
|
525
|
+
function unregisterProjectTimeline(owner) {
|
|
526
|
+
projectTimelineHandles.delete(owner);
|
|
527
|
+
}
|
|
528
|
+
function projectTimelineNativeId(owner) {
|
|
529
|
+
if (owner === null || typeof owner !== "object" && typeof owner !== "function") {
|
|
530
|
+
return void 0;
|
|
531
|
+
}
|
|
532
|
+
return projectTimelineHandles.get(owner)?.id;
|
|
533
|
+
}
|
|
521
534
|
function normalizeSynthInstrument(patch) {
|
|
522
535
|
if (patch === null || typeof patch !== "object") {
|
|
523
536
|
return patch;
|
|
@@ -534,6 +547,35 @@ function normalizeSynthInstrument(patch) {
|
|
|
534
547
|
}
|
|
535
548
|
return { ...rest, sampleBankId: sampleBank.nativeId };
|
|
536
549
|
}
|
|
550
|
+
function partRigInsertsJson(inserts) {
|
|
551
|
+
if (inserts === void 0 || inserts === null) {
|
|
552
|
+
return void 0;
|
|
553
|
+
}
|
|
554
|
+
if (!Array.isArray(inserts)) {
|
|
555
|
+
throw new TypeError("inserts must be an array");
|
|
556
|
+
}
|
|
557
|
+
return JSON.stringify(
|
|
558
|
+
inserts.map((insert) => {
|
|
559
|
+
const { processor, params } = insert;
|
|
560
|
+
return params === void 0 ? { processor } : { processor, params: typeof params === "string" ? params : JSON.stringify(params) };
|
|
561
|
+
})
|
|
562
|
+
);
|
|
563
|
+
}
|
|
564
|
+
function partRigFromNative(native) {
|
|
565
|
+
if (native === null) {
|
|
566
|
+
return null;
|
|
567
|
+
}
|
|
568
|
+
if (native.insertsJson === null) {
|
|
569
|
+
return { mode: native.mode };
|
|
570
|
+
}
|
|
571
|
+
const inserts = JSON.parse(native.insertsJson).map(
|
|
572
|
+
({ processor, params }) => ({
|
|
573
|
+
processor,
|
|
574
|
+
params: JSON.parse(params)
|
|
575
|
+
})
|
|
576
|
+
);
|
|
577
|
+
return { mode: native.mode, inserts };
|
|
578
|
+
}
|
|
537
579
|
function projectModule() {
|
|
538
580
|
const candidate = getSonareModule();
|
|
539
581
|
if (typeof candidate.projectAbiVersion !== "function" || candidate.Project === void 0) {
|
|
@@ -624,13 +666,30 @@ function alignTakeToReference(request) {
|
|
|
624
666
|
}
|
|
625
667
|
|
|
626
668
|
// src/_effects_common.ts
|
|
627
|
-
function toVoicedFloat32(voiced) {
|
|
669
|
+
function toVoicedFloat32(fnName, voiced) {
|
|
670
|
+
if (!(voiced instanceof Int32Array || voiced instanceof Uint8Array || voiced instanceof Float32Array || Array.isArray(voiced))) {
|
|
671
|
+
throw new TypeError(
|
|
672
|
+
`${fnName}: voiced must be an Int32Array, Uint8Array, Float32Array, number[], or boolean[]`
|
|
673
|
+
);
|
|
674
|
+
}
|
|
628
675
|
const out = new Float32Array(voiced.length);
|
|
629
676
|
for (let index = 0; index < voiced.length; index += 1) {
|
|
630
|
-
|
|
677
|
+
const value = voiced[index];
|
|
678
|
+
if (typeof value !== "number" && typeof value !== "boolean") {
|
|
679
|
+
throw new TypeError(`${fnName}: voiced array entries must be numbers or booleans`);
|
|
680
|
+
}
|
|
681
|
+
out[index] = value ? 1 : 0;
|
|
631
682
|
}
|
|
632
683
|
return out;
|
|
633
684
|
}
|
|
685
|
+
function assertPitchTrackLengths(fnName, f0Hz, voiced, voicedProb) {
|
|
686
|
+
if (voiced != null && voiced.length !== f0Hz.length) {
|
|
687
|
+
throw new RangeError(`${fnName}: voiced must have the same length as f0Hz`);
|
|
688
|
+
}
|
|
689
|
+
if (voiced == null && voicedProb != null && voicedProb.length !== f0Hz.length) {
|
|
690
|
+
throw new RangeError(`${fnName}: voicedProb must have the same length as f0Hz`);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
634
693
|
|
|
635
694
|
// src/effects_note_ops.ts
|
|
636
695
|
function requireModule() {
|
|
@@ -639,13 +698,9 @@ function requireModule() {
|
|
|
639
698
|
function assertNoteTrack(fnName, request) {
|
|
640
699
|
assertSamples(fnName, request.samples, request.validate !== false);
|
|
641
700
|
assertSampleRate(fnName, request.sampleRate);
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
if (request.voicedProb && request.voicedProb.length !== request.f0Hz.length) {
|
|
646
|
-
throw new RangeError(`${fnName}: voicedProb length must match f0Hz length`);
|
|
647
|
-
}
|
|
648
|
-
return request.voiced ? toVoicedFloat32(request.voiced) : void 0;
|
|
701
|
+
const voicedF32 = request.voiced == null ? void 0 : toVoicedFloat32(fnName, request.voiced);
|
|
702
|
+
assertPitchTrackLengths(fnName, request.f0Hz, request.voiced, request.voicedProb);
|
|
703
|
+
return voicedF32;
|
|
649
704
|
}
|
|
650
705
|
function noteStretch(samples, sampleRate = 22050, options = {}) {
|
|
651
706
|
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
@@ -675,20 +730,46 @@ function extractNotes(request) {
|
|
|
675
730
|
request.samples,
|
|
676
731
|
request.sampleRate,
|
|
677
732
|
request.f0Hz,
|
|
678
|
-
request.voicedProb,
|
|
733
|
+
request.voiced == null ? request.voicedProb ?? void 0 : void 0,
|
|
679
734
|
voicedF32,
|
|
680
735
|
request.frameRate,
|
|
681
736
|
request
|
|
682
737
|
);
|
|
683
738
|
}
|
|
684
739
|
function renderNotes(request) {
|
|
685
|
-
assertSamples("renderNotes", request.samples, request.validate !== false);
|
|
686
740
|
assertSampleRate("renderNotes", request.sampleRate);
|
|
687
|
-
|
|
741
|
+
if (!Array.isArray(request.notes)) {
|
|
742
|
+
throw new TypeError("renderNotes: notes must be an array");
|
|
743
|
+
}
|
|
744
|
+
const f0Hz = request.f0Hz;
|
|
745
|
+
if (f0Hz !== void 0 && !(f0Hz instanceof Float32Array)) {
|
|
746
|
+
throw new TypeError("renderNotes: f0Hz must be a Float32Array");
|
|
747
|
+
}
|
|
748
|
+
if (f0Hz !== void 0) {
|
|
749
|
+
assertFiniteScalar("renderNotes", request.frameRate, "frameRate");
|
|
750
|
+
}
|
|
751
|
+
const { voiced: publicVoiced, ...withoutVoiced } = request;
|
|
752
|
+
const voiced = publicVoiced == null ? void 0 : toVoicedFloat32("renderNotes", publicVoiced);
|
|
753
|
+
if (publicVoiced != null && f0Hz === void 0) {
|
|
754
|
+
throw new RangeError("renderNotes: voiced requires f0Hz");
|
|
755
|
+
}
|
|
756
|
+
if (f0Hz !== void 0) {
|
|
757
|
+
assertPitchTrackLengths("renderNotes", f0Hz, publicVoiced);
|
|
758
|
+
}
|
|
759
|
+
assertSamples("renderNotes", request.samples, request.validate !== false);
|
|
760
|
+
const options = { ...withoutVoiced, voiced };
|
|
761
|
+
return requireModule().renderNotes(request.samples, request.sampleRate, request.notes, options);
|
|
688
762
|
}
|
|
689
763
|
function decomposeNotePitch(request) {
|
|
764
|
+
if (!(request.f0Hz instanceof Float32Array)) {
|
|
765
|
+
throw new TypeError("decomposeNotePitch: f0Hz must be a Float32Array");
|
|
766
|
+
}
|
|
767
|
+
assertFiniteScalar("decomposeNotePitch", request.frameRate, "frameRate");
|
|
768
|
+
const voiced = request.voiced == null ? void 0 : toVoicedFloat32("decomposeNotePitch", request.voiced);
|
|
769
|
+
assertPitchTrackLengths("decomposeNotePitch", request.f0Hz, request.voiced);
|
|
690
770
|
return requireModule().decomposeNotePitch(
|
|
691
771
|
request.f0Hz,
|
|
772
|
+
voiced,
|
|
692
773
|
request.frameRate,
|
|
693
774
|
request.medianHz,
|
|
694
775
|
request.vibratoCutoffHz ?? 0
|
|
@@ -700,7 +781,7 @@ function splitNote(request) {
|
|
|
700
781
|
request.samples,
|
|
701
782
|
request.sampleRate,
|
|
702
783
|
request.f0Hz,
|
|
703
|
-
request.voicedProb,
|
|
784
|
+
request.voiced == null ? request.voicedProb ?? void 0 : void 0,
|
|
704
785
|
voicedF32,
|
|
705
786
|
request.frameRate,
|
|
706
787
|
request.notes,
|
|
@@ -715,7 +796,7 @@ function mergeNotes(request) {
|
|
|
715
796
|
request.samples,
|
|
716
797
|
request.sampleRate,
|
|
717
798
|
request.f0Hz,
|
|
718
|
-
request.voicedProb,
|
|
799
|
+
request.voiced == null ? request.voicedProb ?? void 0 : void 0,
|
|
719
800
|
voicedF32,
|
|
720
801
|
request.frameRate,
|
|
721
802
|
request.notes,
|
|
@@ -725,11 +806,11 @@ function mergeNotes(request) {
|
|
|
725
806
|
);
|
|
726
807
|
}
|
|
727
808
|
function noteTargetsFromSmf(request) {
|
|
728
|
-
const
|
|
729
|
-
if (typeof
|
|
809
|
+
const module3 = requireModule();
|
|
810
|
+
if (typeof module3.noteTargetsFromSmf !== "function") {
|
|
730
811
|
throw new Error("libsonare was built without arrangement support");
|
|
731
812
|
}
|
|
732
|
-
return
|
|
813
|
+
return module3.noteTargetsFromSmf(request.data, request.trackIndex ?? 0);
|
|
733
814
|
}
|
|
734
815
|
function assignNoteTargets(request) {
|
|
735
816
|
return requireModule().assignNoteTargets(
|
|
@@ -912,13 +993,13 @@ function pitchCorrectToMidiTimevarying(samples, f0Hz, targetMidi, sampleRate = 2
|
|
|
912
993
|
...options
|
|
913
994
|
} : samples;
|
|
914
995
|
assertSamples("pitchCorrectToMidiTimevarying", request.samples, request.validate !== false);
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
996
|
+
const voicedF32 = request.voiced == null ? void 0 : toVoicedFloat32("pitchCorrectToMidiTimevarying", request.voiced);
|
|
997
|
+
assertPitchTrackLengths(
|
|
998
|
+
"pitchCorrectToMidiTimevarying",
|
|
999
|
+
request.f0Hz,
|
|
1000
|
+
request.voiced,
|
|
1001
|
+
request.voicedProb
|
|
1002
|
+
);
|
|
922
1003
|
return requireModule5().pitchCorrectToMidiTimevarying(
|
|
923
1004
|
request.samples,
|
|
924
1005
|
request.sampleRate ?? 22050,
|
|
@@ -926,21 +1007,23 @@ function pitchCorrectToMidiTimevarying(samples, f0Hz, targetMidi, sampleRate = 2
|
|
|
926
1007
|
request.targetMidi,
|
|
927
1008
|
request.hopLength ?? 512,
|
|
928
1009
|
voicedF32,
|
|
929
|
-
request.voicedProb
|
|
1010
|
+
request.voiced == null ? request.voicedProb ?? void 0 : void 0
|
|
930
1011
|
);
|
|
931
1012
|
}
|
|
932
1013
|
function pitchCorrectTimevarying(samples, f0Hz, sampleRate = 22050, hopLength = 512, options = {}) {
|
|
933
1014
|
const request = samples instanceof Float32Array ? { samples, f0Hz, sampleRate, hopLength, ...options } : samples;
|
|
934
1015
|
assertSamples("pitchCorrectTimevarying", request.samples, request.validate !== false);
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
1016
|
+
const voicedF32 = request.voiced == null ? void 0 : toVoicedFloat32("pitchCorrectTimevarying", request.voiced);
|
|
1017
|
+
assertPitchTrackLengths(
|
|
1018
|
+
"pitchCorrectTimevarying",
|
|
1019
|
+
request.f0Hz,
|
|
1020
|
+
request.voiced,
|
|
1021
|
+
request.voicedProb
|
|
1022
|
+
);
|
|
941
1023
|
const nativeOptions = {
|
|
942
1024
|
...request,
|
|
943
|
-
voiced:
|
|
1025
|
+
voiced: voicedF32,
|
|
1026
|
+
voicedProb: request.voiced == null ? request.voicedProb ?? void 0 : void 0
|
|
944
1027
|
};
|
|
945
1028
|
return requireModule5().pitchCorrectTimevarying(
|
|
946
1029
|
request.samples,
|
|
@@ -1369,6 +1452,32 @@ function masteringPairProcess(processorName, source, reference, sampleRate = 220
|
|
|
1369
1452
|
request.params ?? {}
|
|
1370
1453
|
);
|
|
1371
1454
|
}
|
|
1455
|
+
function masteringPairProcessStereo(processorName, sourceLeft, sourceRight, referenceLeft, referenceRight, sampleRate = 22050, params = {}) {
|
|
1456
|
+
const request = typeof processorName === "string" ? {
|
|
1457
|
+
processorName,
|
|
1458
|
+
sourceLeft,
|
|
1459
|
+
sourceRight,
|
|
1460
|
+
referenceLeft,
|
|
1461
|
+
referenceRight,
|
|
1462
|
+
sampleRate,
|
|
1463
|
+
params
|
|
1464
|
+
} : processorName;
|
|
1465
|
+
if (request.sourceLeft.length !== request.sourceRight.length) {
|
|
1466
|
+
throw new Error("Source left and right channel lengths must match.");
|
|
1467
|
+
}
|
|
1468
|
+
if (request.referenceLeft.length !== request.referenceRight.length) {
|
|
1469
|
+
throw new Error("Reference left and right channel lengths must match.");
|
|
1470
|
+
}
|
|
1471
|
+
return requireModule8().masteringPairProcessStereo(
|
|
1472
|
+
request.processorName,
|
|
1473
|
+
request.sourceLeft,
|
|
1474
|
+
request.sourceRight,
|
|
1475
|
+
request.referenceLeft,
|
|
1476
|
+
request.referenceRight,
|
|
1477
|
+
request.sampleRate ?? 22050,
|
|
1478
|
+
request.params ?? {}
|
|
1479
|
+
);
|
|
1480
|
+
}
|
|
1372
1481
|
function masteringPairAnalyze(analysisName, source, reference, sampleRate = 22050, params = {}) {
|
|
1373
1482
|
const request = typeof analysisName === "string" ? {
|
|
1374
1483
|
analysisName,
|
|
@@ -1392,6 +1501,21 @@ function masteringAbMatchLoudness(request) {
|
|
|
1392
1501
|
request.sampleRate ?? 22050
|
|
1393
1502
|
);
|
|
1394
1503
|
}
|
|
1504
|
+
function masteringAbMatchLoudnessStereo(request) {
|
|
1505
|
+
if (request.sourceLeft.length !== request.sourceRight.length) {
|
|
1506
|
+
throw new Error("Source left and right channel lengths must match.");
|
|
1507
|
+
}
|
|
1508
|
+
if (request.referenceLeft.length !== request.referenceRight.length) {
|
|
1509
|
+
throw new Error("Reference left and right channel lengths must match.");
|
|
1510
|
+
}
|
|
1511
|
+
return requireModule8().masteringAbMatchLoudnessStereo(
|
|
1512
|
+
request.sourceLeft,
|
|
1513
|
+
request.sourceRight,
|
|
1514
|
+
request.referenceLeft,
|
|
1515
|
+
request.referenceRight,
|
|
1516
|
+
request.sampleRate ?? 22050
|
|
1517
|
+
);
|
|
1518
|
+
}
|
|
1395
1519
|
function masteringStereoAnalyze(analysisName, left, right, sampleRate = 22050, params = {}) {
|
|
1396
1520
|
const request = typeof analysisName === "string" ? {
|
|
1397
1521
|
analysisName,
|
|
@@ -2029,7 +2153,7 @@ function decomposeWithInit(s, nFeatures = 0, nFrames = 0, nComponents = 0, nIter
|
|
|
2029
2153
|
return requireModule16().decomposeWithInit(s, nFeatures, nFrames, nComponents, nIter, beta, init2);
|
|
2030
2154
|
}
|
|
2031
2155
|
function decomposeStems(request) {
|
|
2032
|
-
return requireModule16().decomposeStems(request.samples, request.sampleRate, {
|
|
2156
|
+
return requireModule16().decomposeStems(request.samples, request.sampleRate ?? 22050, {
|
|
2033
2157
|
nComponents: request.nComponents,
|
|
2034
2158
|
nFft: request.nFft,
|
|
2035
2159
|
hopLength: request.hopLength,
|
|
@@ -3923,29 +4047,29 @@ function detectAcoustic(samples, sampleRate = 48e3, options = {}) {
|
|
|
3923
4047
|
return result;
|
|
3924
4048
|
}
|
|
3925
4049
|
function synthesizeRir(options = {}) {
|
|
3926
|
-
const
|
|
3927
|
-
if (typeof
|
|
4050
|
+
const module3 = requireModule25();
|
|
4051
|
+
if (typeof module3.synthesizeRir !== "function") {
|
|
3928
4052
|
throw new Error("libsonare was built without acoustic-simulation support");
|
|
3929
4053
|
}
|
|
3930
|
-
return
|
|
4054
|
+
return module3.synthesizeRir(options);
|
|
3931
4055
|
}
|
|
3932
4056
|
function estimateRoom(samples, sampleRate = 48e3, options = {}) {
|
|
3933
|
-
const
|
|
3934
|
-
if (typeof
|
|
4057
|
+
const module3 = requireModule25();
|
|
4058
|
+
if (typeof module3.estimateRoom !== "function") {
|
|
3935
4059
|
throw new Error("libsonare was built without acoustic-simulation support");
|
|
3936
4060
|
}
|
|
3937
4061
|
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
3938
4062
|
validateAnalysisInput("estimateRoom", request.samples, request.sampleRate ?? 48e3, request);
|
|
3939
|
-
return
|
|
4063
|
+
return module3.estimateRoom(request.samples, request.sampleRate ?? 48e3, request);
|
|
3940
4064
|
}
|
|
3941
4065
|
function roomMorph(samples, sampleRate, options = {}) {
|
|
3942
|
-
const
|
|
3943
|
-
if (typeof
|
|
4066
|
+
const module3 = requireModule25();
|
|
4067
|
+
if (typeof module3.roomMorph !== "function") {
|
|
3944
4068
|
throw new Error("libsonare was built without acoustic-simulation support");
|
|
3945
4069
|
}
|
|
3946
4070
|
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
3947
4071
|
validateAnalysisInput("roomMorph", request.samples, request.sampleRate, request);
|
|
3948
|
-
return
|
|
4072
|
+
return module3.roomMorph(request.samples, request.sampleRate, request);
|
|
3949
4073
|
}
|
|
3950
4074
|
function analyzeWithProgress(samples, sampleRate = 22050, onProgress, options) {
|
|
3951
4075
|
const request = samples instanceof Float32Array ? { samples, sampleRate, onProgress, options } : samples;
|
|
@@ -4828,8 +4952,8 @@ function suggestJson(fnName, request, sceneOnly) {
|
|
|
4828
4952
|
const { left, right, ids, names } = planarTracks(request.tracks);
|
|
4829
4953
|
const sampleRate = request.sampleRate;
|
|
4830
4954
|
const params = request.options ?? {};
|
|
4831
|
-
const
|
|
4832
|
-
return sceneOnly ?
|
|
4955
|
+
const module3 = requireModule26();
|
|
4956
|
+
return sceneOnly ? module3.mixingAssistantSuggestSceneJson(left, right, ids, names, sampleRate, params) : module3.mixingAssistantSuggest(left, right, ids, names, sampleRate, params);
|
|
4833
4957
|
}
|
|
4834
4958
|
function suggestMixScene(request) {
|
|
4835
4959
|
return JSON.parse(suggestJson("suggestMixScene", request, false));
|
|
@@ -5015,8 +5139,8 @@ var PolyphonicAnalysis = class {
|
|
|
5015
5139
|
constructor(request) {
|
|
5016
5140
|
assertSamples("analyzePolyphonic", request.samples, request.validate !== false);
|
|
5017
5141
|
assertSampleRate("analyzePolyphonic", request.sampleRate);
|
|
5018
|
-
const
|
|
5019
|
-
this.native =
|
|
5142
|
+
const module3 = getSonareModule();
|
|
5143
|
+
this.native = module3.createPolyphonicAnalysis(
|
|
5020
5144
|
request.samples,
|
|
5021
5145
|
request.sampleRate,
|
|
5022
5146
|
request
|
|
@@ -5292,9 +5416,261 @@ var CONTROLLER_AXES = [
|
|
|
5292
5416
|
"vibrato-depth"
|
|
5293
5417
|
];
|
|
5294
5418
|
var ARTICULATIONS = ["poly", "mono-retrigger", "mono-legato"];
|
|
5419
|
+
var PART_RIG_MODES = ["bank", "none", "chain"];
|
|
5420
|
+
var PART_RIG_ALL_PARTS = 255;
|
|
5295
5421
|
var MPE_DIMENSIONS = ["bend", "pressure", "timbre"];
|
|
5296
5422
|
var NOTE_TRACKINGS = ["last", "lowest", "highest", "all"];
|
|
5297
5423
|
|
|
5424
|
+
// src/vocal_project.ts
|
|
5425
|
+
var UINT32_MAX = 4294967295;
|
|
5426
|
+
var PROJECT_ID_MAX = UINT32_MAX - 1;
|
|
5427
|
+
var UINT64_MAX = "18446744073709551615";
|
|
5428
|
+
function requireObject(value, field) {
|
|
5429
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
5430
|
+
throw new TypeError(`${field} must be an object`);
|
|
5431
|
+
}
|
|
5432
|
+
return value;
|
|
5433
|
+
}
|
|
5434
|
+
function uint32(value, field, allowZero = true) {
|
|
5435
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < (allowZero ? 0 : 1) || value > PROJECT_ID_MAX) {
|
|
5436
|
+
throw new RangeError(`${field} must be a uint32 project id`);
|
|
5437
|
+
}
|
|
5438
|
+
return value;
|
|
5439
|
+
}
|
|
5440
|
+
function nativeUint32(value, field) {
|
|
5441
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0 || value > UINT32_MAX) {
|
|
5442
|
+
throw new RangeError(`${field} must be a native uint32`);
|
|
5443
|
+
}
|
|
5444
|
+
return value;
|
|
5445
|
+
}
|
|
5446
|
+
function nativeInt64(value, field) {
|
|
5447
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value)) {
|
|
5448
|
+
throw new RangeError(`${field} must be a safe integer`);
|
|
5449
|
+
}
|
|
5450
|
+
return value;
|
|
5451
|
+
}
|
|
5452
|
+
function positiveSampleCount(value, field) {
|
|
5453
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0) {
|
|
5454
|
+
throw new RangeError(`${field} must be a positive safe integer`);
|
|
5455
|
+
}
|
|
5456
|
+
return value;
|
|
5457
|
+
}
|
|
5458
|
+
function finite(value, field) {
|
|
5459
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
5460
|
+
throw new RangeError(`${field} must be finite`);
|
|
5461
|
+
}
|
|
5462
|
+
return value;
|
|
5463
|
+
}
|
|
5464
|
+
function decimalUint64(value, field) {
|
|
5465
|
+
if (typeof value !== "string" || !/^(0|[1-9]\d*)$/.test(value)) {
|
|
5466
|
+
throw new RangeError(`${field} must be a canonical decimal uint64 string`);
|
|
5467
|
+
}
|
|
5468
|
+
if (value.length > UINT64_MAX.length || value.length === UINT64_MAX.length && value > UINT64_MAX) {
|
|
5469
|
+
throw new RangeError(`${field} must fit uint64`);
|
|
5470
|
+
}
|
|
5471
|
+
return value;
|
|
5472
|
+
}
|
|
5473
|
+
function hexSha256(value, field) {
|
|
5474
|
+
if (typeof value !== "string" || !/^[0-9a-fA-F]{64}$/.test(value)) {
|
|
5475
|
+
throw new TypeError(`${field} must be 64 hexadecimal characters`);
|
|
5476
|
+
}
|
|
5477
|
+
return value.toLowerCase();
|
|
5478
|
+
}
|
|
5479
|
+
function finiteMono(value, field) {
|
|
5480
|
+
if (!(value instanceof Float32Array) || value.length === 0) {
|
|
5481
|
+
throw new TypeError(`${field} must be a non-empty Float32Array`);
|
|
5482
|
+
}
|
|
5483
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
5484
|
+
if (!Number.isFinite(value[index])) {
|
|
5485
|
+
throw new RangeError(`${field} must contain only finite samples`);
|
|
5486
|
+
}
|
|
5487
|
+
}
|
|
5488
|
+
return new Float32Array(value);
|
|
5489
|
+
}
|
|
5490
|
+
function sve1(value) {
|
|
5491
|
+
if (!(value instanceof Uint8Array) || value.length === 0) {
|
|
5492
|
+
throw new TypeError("sve1 must be a non-empty Uint8Array");
|
|
5493
|
+
}
|
|
5494
|
+
return new Uint8Array(value);
|
|
5495
|
+
}
|
|
5496
|
+
function copyToken(value) {
|
|
5497
|
+
const source = requireObject(value, "renderToken");
|
|
5498
|
+
return {
|
|
5499
|
+
sessionEpoch: decimalUint64(source.sessionEpoch, "renderToken.sessionEpoch"),
|
|
5500
|
+
revision: decimalUint64(source.revision, "renderToken.revision"),
|
|
5501
|
+
draftId: decimalUint64(source.draftId, "renderToken.draftId"),
|
|
5502
|
+
generation: decimalUint64(source.generation, "renderToken.generation"),
|
|
5503
|
+
requestId: decimalUint64(source.requestId, "renderToken.requestId"),
|
|
5504
|
+
profileId: uint32(source.profileId, "renderToken.profileId")
|
|
5505
|
+
};
|
|
5506
|
+
}
|
|
5507
|
+
function copyApplyRequest(request) {
|
|
5508
|
+
const source = requireObject(request, "request");
|
|
5509
|
+
const renderedMono = finiteMono(source.renderedMono, "renderedMono");
|
|
5510
|
+
const expectedSourceSampleCount = positiveSampleCount(
|
|
5511
|
+
source.expectedSourceSampleCount,
|
|
5512
|
+
"expectedSourceSampleCount"
|
|
5513
|
+
);
|
|
5514
|
+
if (renderedMono.length !== expectedSourceSampleCount) {
|
|
5515
|
+
throw new RangeError(
|
|
5516
|
+
`renderedMono length must equal expectedSourceSampleCount (${renderedMono.length} != ${expectedSourceSampleCount})`
|
|
5517
|
+
);
|
|
5518
|
+
}
|
|
5519
|
+
const expectedSourceSampleRate = finite(
|
|
5520
|
+
source.expectedSourceSampleRate,
|
|
5521
|
+
"expectedSourceSampleRate"
|
|
5522
|
+
);
|
|
5523
|
+
assertSampleRate("Project.applyVocalEdit", expectedSourceSampleRate);
|
|
5524
|
+
const renderedSampleRate = finite(source.renderedSampleRate, "renderedSampleRate");
|
|
5525
|
+
assertSampleRate("Project.applyVocalEdit", renderedSampleRate, "renderedSampleRate");
|
|
5526
|
+
if (renderedSampleRate !== expectedSourceSampleRate) {
|
|
5527
|
+
throw new RangeError("renderedSampleRate must equal expectedSourceSampleRate");
|
|
5528
|
+
}
|
|
5529
|
+
const renderedStartSample = source.renderedStartSample ?? 0;
|
|
5530
|
+
if (renderedStartSample !== 0) {
|
|
5531
|
+
throw new RangeError("renderedStartSample must be zero for the v1 Project vocal API");
|
|
5532
|
+
}
|
|
5533
|
+
const renderToken = copyToken(source.renderToken);
|
|
5534
|
+
if (renderToken.draftId !== "0" || renderToken.generation !== "0") {
|
|
5535
|
+
throw new RangeError("renderToken must be a committed session token");
|
|
5536
|
+
}
|
|
5537
|
+
return {
|
|
5538
|
+
clipId: uint32(source.clipId, "clipId", false),
|
|
5539
|
+
takeId: uint32(source.takeId ?? 0, "takeId"),
|
|
5540
|
+
expectedSourceId: uint32(source.expectedSourceId, "expectedSourceId", false),
|
|
5541
|
+
expectedSourceSampleRate,
|
|
5542
|
+
expectedSourceSampleCount,
|
|
5543
|
+
expectedSourceSha256: hexSha256(source.expectedSourceSha256, "expectedSourceSha256"),
|
|
5544
|
+
expectedClipLengthPpq: finite(source.expectedClipLengthPpq, "expectedClipLengthPpq"),
|
|
5545
|
+
expectedSourceOffsetPpq: finite(source.expectedSourceOffsetPpq, "expectedSourceOffsetPpq"),
|
|
5546
|
+
renderedMono,
|
|
5547
|
+
renderedSampleRate,
|
|
5548
|
+
renderedStartSample: 0,
|
|
5549
|
+
renderToken,
|
|
5550
|
+
sve1: sve1(source.sve1)
|
|
5551
|
+
};
|
|
5552
|
+
}
|
|
5553
|
+
function copyApplyResult(value) {
|
|
5554
|
+
const source = requireObject(value, "applyVocalEdit result");
|
|
5555
|
+
return {
|
|
5556
|
+
clipId: uint32(source.clipId, "result.clipId", false),
|
|
5557
|
+
takeId: uint32(source.takeId, "result.takeId"),
|
|
5558
|
+
originalSourceId: uint32(source.originalSourceId, "result.originalSourceId", false),
|
|
5559
|
+
derivedSourceId: uint32(source.derivedSourceId, "result.derivedSourceId", false),
|
|
5560
|
+
committedRevision: decimalUint64(source.committedRevision, "result.committedRevision"),
|
|
5561
|
+
profileId: uint32(source.profileId, "result.profileId"),
|
|
5562
|
+
derivedSourceSha256: hexSha256(source.derivedSourceSha256, "result.derivedSourceSha256"),
|
|
5563
|
+
sidecarKey: typeof source.sidecarKey === "string" ? source.sidecarKey : (() => {
|
|
5564
|
+
throw new TypeError("result.sidecarKey must be a string");
|
|
5565
|
+
})()
|
|
5566
|
+
};
|
|
5567
|
+
}
|
|
5568
|
+
function copyDependency(value) {
|
|
5569
|
+
const source = requireObject(value, "vocal edit dependency");
|
|
5570
|
+
const reason = nativeUint32(source.reason, "dependency.reason");
|
|
5571
|
+
return {
|
|
5572
|
+
clipId: nativeUint32(source.clipId, "dependency.clipId"),
|
|
5573
|
+
takeId: nativeUint32(source.takeId, "dependency.takeId"),
|
|
5574
|
+
originalSourceId: nativeUint32(source.originalSourceId, "dependency.originalSourceId"),
|
|
5575
|
+
derivedSourceId: nativeUint32(source.derivedSourceId, "dependency.derivedSourceId"),
|
|
5576
|
+
sourceSampleRate: nativeUint32(source.sourceSampleRate, "dependency.sourceSampleRate"),
|
|
5577
|
+
profileId: nativeUint32(source.profileId, "dependency.profileId"),
|
|
5578
|
+
sourceSampleCount: nativeInt64(source.sourceSampleCount, "dependency.sourceSampleCount"),
|
|
5579
|
+
committedRevision: decimalUint64(source.committedRevision, "dependency.committedRevision"),
|
|
5580
|
+
originalSourceSha256: hexSha256(source.originalSourceSha256, "dependency.originalSourceSha256"),
|
|
5581
|
+
derivedSourceSha256: hexSha256(source.derivedSourceSha256, "dependency.derivedSourceSha256"),
|
|
5582
|
+
originalPcmAvailable: source.originalPcmAvailable === true,
|
|
5583
|
+
derivedPcmAvailable: source.derivedPcmAvailable === true,
|
|
5584
|
+
reason,
|
|
5585
|
+
sidecarKey: typeof source.sidecarKey === "string" ? source.sidecarKey : (() => {
|
|
5586
|
+
throw new TypeError("dependency.sidecarKey must be a string");
|
|
5587
|
+
})()
|
|
5588
|
+
};
|
|
5589
|
+
}
|
|
5590
|
+
function copyRehydrateItem(value) {
|
|
5591
|
+
const source = requireObject(value, "vocal rehydrate item");
|
|
5592
|
+
const status = source.status;
|
|
5593
|
+
if (typeof status !== "number" || !Number.isSafeInteger(status) || status < 0 || status > 2) {
|
|
5594
|
+
throw new RangeError("rehydrate.status must be one of 0, 1, or 2");
|
|
5595
|
+
}
|
|
5596
|
+
const reason = nativeUint32(source.reason, "rehydrate.reason");
|
|
5597
|
+
return {
|
|
5598
|
+
clipId: nativeUint32(source.clipId, "rehydrate.clipId"),
|
|
5599
|
+
takeId: nativeUint32(source.takeId, "rehydrate.takeId"),
|
|
5600
|
+
derivedSourceId: nativeUint32(source.derivedSourceId, "rehydrate.derivedSourceId"),
|
|
5601
|
+
status,
|
|
5602
|
+
reason
|
|
5603
|
+
};
|
|
5604
|
+
}
|
|
5605
|
+
function copyOriginalSources(originals) {
|
|
5606
|
+
if (!Array.isArray(originals)) {
|
|
5607
|
+
throw new TypeError("originals must be an array");
|
|
5608
|
+
}
|
|
5609
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5610
|
+
return originals.map((original, index) => {
|
|
5611
|
+
const source = requireObject(original, `originals[${index}]`);
|
|
5612
|
+
const sourceId = uint32(source.sourceId, `originals[${index}].sourceId`, false);
|
|
5613
|
+
if (seen.has(sourceId)) {
|
|
5614
|
+
throw new RangeError(`originals contains duplicate sourceId ${sourceId}`);
|
|
5615
|
+
}
|
|
5616
|
+
seen.add(sourceId);
|
|
5617
|
+
const sampleRate = finite(source.sampleRate, `originals[${index}].sampleRate`);
|
|
5618
|
+
assertSampleRate("Project.rehydrateVocalEdits", sampleRate, `originals[${index}].sampleRate`);
|
|
5619
|
+
return {
|
|
5620
|
+
sourceId,
|
|
5621
|
+
mono: finiteMono(source.mono, `originals[${index}].mono`),
|
|
5622
|
+
sampleRate
|
|
5623
|
+
};
|
|
5624
|
+
});
|
|
5625
|
+
}
|
|
5626
|
+
function projectApplyVocalEdit(native, request) {
|
|
5627
|
+
const normalized = copyApplyRequest(request);
|
|
5628
|
+
return copyApplyResult(native.applyVocalEdit(normalized));
|
|
5629
|
+
}
|
|
5630
|
+
function projectGetVocalEditDependencies(native) {
|
|
5631
|
+
const value = native.getVocalEditDependencies();
|
|
5632
|
+
if (!Array.isArray(value)) {
|
|
5633
|
+
throw new TypeError("native vocal dependencies must be an array");
|
|
5634
|
+
}
|
|
5635
|
+
return value.map(copyDependency);
|
|
5636
|
+
}
|
|
5637
|
+
function projectRehydrateVocalEdits(native, originals, cancel) {
|
|
5638
|
+
if (cancel !== void 0 && typeof cancel !== "function") {
|
|
5639
|
+
throw new TypeError("cancel must be a function");
|
|
5640
|
+
}
|
|
5641
|
+
const normalized = copyOriginalSources(originals);
|
|
5642
|
+
let callbackFailed = false;
|
|
5643
|
+
let callbackFailure;
|
|
5644
|
+
const guardedCancel = cancel === void 0 ? void 0 : () => {
|
|
5645
|
+
try {
|
|
5646
|
+
return cancel();
|
|
5647
|
+
} catch (error) {
|
|
5648
|
+
callbackFailed = true;
|
|
5649
|
+
callbackFailure = error;
|
|
5650
|
+
return true;
|
|
5651
|
+
}
|
|
5652
|
+
};
|
|
5653
|
+
let value;
|
|
5654
|
+
try {
|
|
5655
|
+
value = native.rehydrateVocalEdits(normalized, guardedCancel);
|
|
5656
|
+
} catch (error) {
|
|
5657
|
+
if (callbackFailed) {
|
|
5658
|
+
throw callbackFailure;
|
|
5659
|
+
}
|
|
5660
|
+
throw error;
|
|
5661
|
+
}
|
|
5662
|
+
if (callbackFailed) {
|
|
5663
|
+
throw callbackFailure;
|
|
5664
|
+
}
|
|
5665
|
+
if (value !== null && typeof value === "object" && "cancelFailure" in value) {
|
|
5666
|
+
throw value.cancelFailure;
|
|
5667
|
+
}
|
|
5668
|
+
if (!Array.isArray(value)) {
|
|
5669
|
+
throw new TypeError("native vocal rehydrate result must be an array");
|
|
5670
|
+
}
|
|
5671
|
+
return value.map(copyRehydrateItem);
|
|
5672
|
+
}
|
|
5673
|
+
|
|
5298
5674
|
// src/project_class.ts
|
|
5299
5675
|
function normalizeMidiFxBakeRequest(clipIdOrRequest, configJson) {
|
|
5300
5676
|
if (typeof clipIdOrRequest === "number") {
|
|
@@ -5363,11 +5739,57 @@ function midi2Byte(fnName, value, argName) {
|
|
|
5363
5739
|
assertBoundedInteger(fnName, value, argName, 0, 255);
|
|
5364
5740
|
return value;
|
|
5365
5741
|
}
|
|
5742
|
+
var ProjectTimeline = class {
|
|
5743
|
+
/** @internal */
|
|
5744
|
+
constructor(native) {
|
|
5745
|
+
this.native = native;
|
|
5746
|
+
registerProjectTimeline(this, native);
|
|
5747
|
+
}
|
|
5748
|
+
/**
|
|
5749
|
+
* Identity an engine names this timeline by, so no raw pointer crosses into JS.
|
|
5750
|
+
*
|
|
5751
|
+
* @internal
|
|
5752
|
+
*/
|
|
5753
|
+
get nativeId() {
|
|
5754
|
+
if (this.native === null) {
|
|
5755
|
+
throw new TypeError("ProjectTimeline is disposed");
|
|
5756
|
+
}
|
|
5757
|
+
return this.native.id;
|
|
5758
|
+
}
|
|
5759
|
+
/** Release the underlying WASM object. Idempotent. */
|
|
5760
|
+
dispose() {
|
|
5761
|
+
if (this.native === null) {
|
|
5762
|
+
return;
|
|
5763
|
+
}
|
|
5764
|
+
unregisterProjectTimeline(this);
|
|
5765
|
+
this.native.delete();
|
|
5766
|
+
this.native = null;
|
|
5767
|
+
}
|
|
5768
|
+
};
|
|
5366
5769
|
var Project = class _Project {
|
|
5367
5770
|
constructor() {
|
|
5368
5771
|
this.released = false;
|
|
5772
|
+
this.deleteRequested = false;
|
|
5773
|
+
this.activeVocalRehydrateCalls = 0;
|
|
5369
5774
|
this.native = new (projectModule()).Project();
|
|
5370
5775
|
}
|
|
5776
|
+
applyVocalEdit(request) {
|
|
5777
|
+
return projectApplyVocalEdit(this.native, request);
|
|
5778
|
+
}
|
|
5779
|
+
getVocalEditDependencies() {
|
|
5780
|
+
return projectGetVocalEditDependencies(this.native);
|
|
5781
|
+
}
|
|
5782
|
+
rehydrateVocalEdits(originals, cancel) {
|
|
5783
|
+
this.activeVocalRehydrateCalls += 1;
|
|
5784
|
+
try {
|
|
5785
|
+
return projectRehydrateVocalEdits(this.native, originals, cancel);
|
|
5786
|
+
} finally {
|
|
5787
|
+
this.activeVocalRehydrateCalls -= 1;
|
|
5788
|
+
if (this.activeVocalRehydrateCalls === 0 && this.deleteRequested) {
|
|
5789
|
+
this.native.delete();
|
|
5790
|
+
}
|
|
5791
|
+
}
|
|
5792
|
+
}
|
|
5371
5793
|
/** Create a new empty project. */
|
|
5372
5794
|
static create() {
|
|
5373
5795
|
return new _Project();
|
|
@@ -5736,6 +6158,26 @@ var Project = class _Project {
|
|
|
5736
6158
|
setTrackGain(trackId, gain) {
|
|
5737
6159
|
this.native.setTrackGain(trackId, gain);
|
|
5738
6160
|
}
|
|
6161
|
+
/**
|
|
6162
|
+
* Set the rig of one part (0-15), or of the destination's default when `part`
|
|
6163
|
+
* is {@link PART_RIG_ALL_PARTS}, on MIDI destination `destinationId`, via an
|
|
6164
|
+
* undoable edit. `'chain'` takes 1-8 `inserts` and is the only mode that does;
|
|
6165
|
+
* a destination no track references is stored and read back all the same.
|
|
6166
|
+
* Refused: a malformed insert document (invalid format), an out-of-range part,
|
|
6167
|
+
* an unknown mode or processor, or inserts on a non-chain mode (invalid
|
|
6168
|
+
* parameter), and an insert chain in a build without mastering.
|
|
6169
|
+
*/
|
|
6170
|
+
setPartRig(destinationId, part, mode, inserts) {
|
|
6171
|
+
this.native.setPartRig(destinationId, part, mode, partRigInsertsJson(inserts));
|
|
6172
|
+
}
|
|
6173
|
+
/** The stored rig for `(destinationId, part)`, or null when none is stored. */
|
|
6174
|
+
getPartRig(destinationId, part) {
|
|
6175
|
+
return partRigFromNative(this.native.getPartRig(destinationId, part));
|
|
6176
|
+
}
|
|
6177
|
+
/** Remove the stored rig for `(destinationId, part)` via an undoable edit (no-op when absent). */
|
|
6178
|
+
clearPartRig(destinationId, part) {
|
|
6179
|
+
this.native.clearPartRig(destinationId, part);
|
|
6180
|
+
}
|
|
5739
6181
|
/** Set a track's mute flag via an undoable edit (a muted track is silent). */
|
|
5740
6182
|
setTrackMute(trackId, mute) {
|
|
5741
6183
|
this.native.setTrackMute(trackId, mute);
|
|
@@ -5941,6 +6383,16 @@ var Project = class _Project {
|
|
|
5941
6383
|
compile() {
|
|
5942
6384
|
return this.native.compile();
|
|
5943
6385
|
}
|
|
6386
|
+
/**
|
|
6387
|
+
* Compile the project and keep the resulting timeline. The result is
|
|
6388
|
+
* {@link compile}'s plus `timeline`: a {@link ProjectTimeline} to install with
|
|
6389
|
+
* `RealtimeEngine.applyProjectTimeline`, or `null` when an error diagnostic
|
|
6390
|
+
* means nothing compiled.
|
|
6391
|
+
*/
|
|
6392
|
+
compileTimeline() {
|
|
6393
|
+
const { timeline, ...result } = this.native.compileTimeline();
|
|
6394
|
+
return { ...result, timeline: timeline === null ? null : new ProjectTimeline(timeline) };
|
|
6395
|
+
}
|
|
5944
6396
|
/**
|
|
5945
6397
|
* Compile + render the project offline to interleaved float audio. MIDI
|
|
5946
6398
|
* tracks render silently here (no instrument is bound) — use
|
|
@@ -6313,12 +6765,20 @@ var Project = class _Project {
|
|
|
6313
6765
|
lastBounceCompileResult() {
|
|
6314
6766
|
return this.native.lastBounceCompileResult();
|
|
6315
6767
|
}
|
|
6316
|
-
/**
|
|
6768
|
+
/**
|
|
6769
|
+
* Release the underlying WASM object. Idempotent, as the Node facade is.
|
|
6770
|
+
* Called from a rehydrate cancel callback, the release happens when the
|
|
6771
|
+
* outermost {@link rehydrateVocalEdits} call returns.
|
|
6772
|
+
*/
|
|
6317
6773
|
delete() {
|
|
6318
6774
|
if (this.released) {
|
|
6319
6775
|
return;
|
|
6320
6776
|
}
|
|
6321
6777
|
this.released = true;
|
|
6778
|
+
if (this.activeVocalRehydrateCalls !== 0) {
|
|
6779
|
+
this.deleteRequested = true;
|
|
6780
|
+
return;
|
|
6781
|
+
}
|
|
6322
6782
|
this.native.delete();
|
|
6323
6783
|
}
|
|
6324
6784
|
/** Alias for {@link delete}, provided for cross-binding (Node) compatibility. */
|
|
@@ -6418,14 +6878,14 @@ function engineCapabilities() {
|
|
|
6418
6878
|
var RealtimeEngine = class _RealtimeEngine {
|
|
6419
6879
|
constructor(sampleRate = 48e3, maxBlockSize = 128, commandCapacity = 1024, telemetryCapacity = 1024, maxChannels = 64) {
|
|
6420
6880
|
this.released = false;
|
|
6421
|
-
const
|
|
6881
|
+
const module3 = getSonareModule();
|
|
6422
6882
|
const capabilities2 = engineCapabilities();
|
|
6423
6883
|
if (!capabilities2.abiCompatible) {
|
|
6424
6884
|
throw new Error(
|
|
6425
6885
|
`Engine ABI mismatch: wasm=${capabilities2.engineAbiVersion}, expected=${capabilities2.expectedEngineAbiVersion}`
|
|
6426
6886
|
);
|
|
6427
6887
|
}
|
|
6428
|
-
this.native = new
|
|
6888
|
+
this.native = new module3.RealtimeEngine(
|
|
6429
6889
|
sampleRate,
|
|
6430
6890
|
maxBlockSize,
|
|
6431
6891
|
commandCapacity,
|
|
@@ -6629,6 +7089,17 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
6629
7089
|
setArticulation(destinationId, channel, articulation) {
|
|
6630
7090
|
this.native.setArticulation(destinationId, channel, articulation);
|
|
6631
7091
|
}
|
|
7092
|
+
/**
|
|
7093
|
+
* Set the rig of one part (0-15), or of the destination's default when `part`
|
|
7094
|
+
* is `PART_RIG_ALL_PARTS`, on the instrument bound to `destinationId`. A
|
|
7095
|
+
* direct call, not a stored edit: a destination with no instrument is an
|
|
7096
|
+
* invalid parameter, and an instrument without part rigs (a builtin, a
|
|
7097
|
+
* host-callback instrument) is refused as not implemented rather than
|
|
7098
|
+
* succeeding quietly. `'chain'` takes 1-8 `inserts`; no other mode does.
|
|
7099
|
+
*/
|
|
7100
|
+
setPartRig(destinationId, part, mode, inserts) {
|
|
7101
|
+
this.native.setPartRig(destinationId, part, mode, partRigInsertsJson(inserts));
|
|
7102
|
+
}
|
|
6632
7103
|
/**
|
|
6633
7104
|
* Read back {@link setArticulation} as the canonical name. An ordinal this
|
|
6634
7105
|
* build cannot spell is handed back as the number, the way every other enum
|
|
@@ -6674,7 +7145,10 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
6674
7145
|
/**
|
|
6675
7146
|
* Route a destination's (track lane's) MIDI to the external output queue
|
|
6676
7147
|
* instead of the internal instrument rack, so the track plays an external
|
|
6677
|
-
* device. Clearing it restores internal-synth playback.
|
|
7148
|
+
* device. Clearing it restores internal-synth playback. Control-thread only.
|
|
7149
|
+
* The change takes effect at the next processed block; switching a
|
|
7150
|
+
* destination's route first releases its notes and resets its controllers
|
|
7151
|
+
* through the old route, and drops its pending MIDI-FX events. Single writer.
|
|
6678
7152
|
*/
|
|
6679
7153
|
setMidiDestinationExternal(destinationId, external) {
|
|
6680
7154
|
this.native.setMidiDestinationExternal(destinationId, external);
|
|
@@ -6828,8 +7302,11 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
6828
7302
|
/**
|
|
6829
7303
|
* Queue an immediate (live) MIDI SysEx frame to a MIDI destination. `data` is
|
|
6830
7304
|
* the full message including the leading 0xF0 and trailing 0xF7 (1..512
|
|
6831
|
-
* bytes). `renderFrame` is the frame to fire at, or -1 for immediate.
|
|
6832
|
-
* the
|
|
7305
|
+
* bytes). `renderFrame` is the frame to fire at, or -1 for immediate. Throws
|
|
7306
|
+
* `InvalidParameter` when the destination instrument cannot prepare
|
|
7307
|
+
* the SysEx (retrying cannot help), and `OutOfMemory` when the payload
|
|
7308
|
+
* slots or the command queue are full (retry after a processed block).
|
|
7309
|
+
* Mirrors the Node/Python/C-ABI `pushMidiSysex`.
|
|
6833
7310
|
*/
|
|
6834
7311
|
pushMidiSysex(destinationId, data, renderFrame = -1) {
|
|
6835
7312
|
this.native.pushMidiSysex(destinationId, data, renderFrame);
|
|
@@ -6852,12 +7329,30 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
6852
7329
|
getTransportState() {
|
|
6853
7330
|
return this.native.getTransportState();
|
|
6854
7331
|
}
|
|
7332
|
+
/** Queues an integrated-loudness reset; short-term and momentary windows are retained. */
|
|
7333
|
+
resetMasterLoudnessMeter(renderFrame = -1) {
|
|
7334
|
+
this.native.resetMasterLoudnessMeter(renderFrame);
|
|
7335
|
+
}
|
|
7336
|
+
/** Reads the immutable factory value for a resolved insert parameter id. */
|
|
7337
|
+
insertParameterConstructedValue(paramId) {
|
|
7338
|
+
return this.native.insertParameterConstructedValue(paramId);
|
|
7339
|
+
}
|
|
6855
7340
|
play(renderFrame = -1) {
|
|
6856
7341
|
this.native.play(renderFrame);
|
|
6857
7342
|
}
|
|
7343
|
+
/**
|
|
7344
|
+
* A loop wrap, seek or stop sends note-offs plus CC64=0, CC121, CC123 and a
|
|
7345
|
+
* centred pitch bend on every channel played since the last reset, so
|
|
7346
|
+
* controller values set before a loop region are not restored at the wrap.
|
|
7347
|
+
*/
|
|
6858
7348
|
stop(renderFrame = -1) {
|
|
6859
7349
|
this.native.stop(renderFrame);
|
|
6860
7350
|
}
|
|
7351
|
+
/**
|
|
7352
|
+
* A loop wrap, seek or stop sends note-offs plus CC64=0, CC121, CC123 and a
|
|
7353
|
+
* centred pitch bend on every channel played since the last reset, so
|
|
7354
|
+
* controller values set before a loop region are not restored at the wrap.
|
|
7355
|
+
*/
|
|
6861
7356
|
seekSample(timelineSample, renderFrame = -1) {
|
|
6862
7357
|
this.native.seekSample(timelineSample, renderFrame);
|
|
6863
7358
|
}
|
|
@@ -6882,6 +7377,11 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
6882
7377
|
applyCommandsDueNowPreservingFuture() {
|
|
6883
7378
|
this.native.applyCommandsDueNowPreservingFuture();
|
|
6884
7379
|
}
|
|
7380
|
+
/**
|
|
7381
|
+
* A loop wrap, seek or stop sends note-offs plus CC64=0, CC121, CC123 and a
|
|
7382
|
+
* centred pitch bend on every channel played since the last reset, so
|
|
7383
|
+
* controller values set before a loop region are not restored at the wrap.
|
|
7384
|
+
*/
|
|
6885
7385
|
seekPpq(ppq, renderFrame = -1) {
|
|
6886
7386
|
this.native.seekPpq(ppq, renderFrame);
|
|
6887
7387
|
}
|
|
@@ -6901,6 +7401,11 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
6901
7401
|
sampleAtPpq(ppq) {
|
|
6902
7402
|
return Number(this.native.sampleAtPpq(ppq));
|
|
6903
7403
|
}
|
|
7404
|
+
/**
|
|
7405
|
+
* A loop wrap, seek or stop sends note-offs plus CC64=0, CC121, CC123 and a
|
|
7406
|
+
* centred pitch bend on every channel played since the last reset, so
|
|
7407
|
+
* controller values set before a loop region are not restored at the wrap.
|
|
7408
|
+
*/
|
|
6904
7409
|
setLoop(startPpq, endPpq, enabled = true) {
|
|
6905
7410
|
this.native.setLoop(startPpq, endPpq, enabled);
|
|
6906
7411
|
}
|
|
@@ -6995,25 +7500,56 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
6995
7500
|
if (typeof lane === "number") {
|
|
6996
7501
|
return { trackId: lane };
|
|
6997
7502
|
}
|
|
6998
|
-
|
|
6999
|
-
|
|
7000
|
-
|
|
7001
|
-
|
|
7503
|
+
return {
|
|
7504
|
+
...lane,
|
|
7505
|
+
sends: lane.sends ? _RealtimeEngine.normalizeSends(lane.sends) : void 0
|
|
7506
|
+
};
|
|
7002
7507
|
})
|
|
7003
7508
|
);
|
|
7004
7509
|
}
|
|
7005
7510
|
/**
|
|
7006
7511
|
* Keys one insert of a lane strip from another lane's post-strip audio
|
|
7007
7512
|
* (ducking/sidechainRouter inserts). sourceTrackId 0 removes the binding.
|
|
7513
|
+
* Lanes are processed in key order and the key is delay-compensated to the
|
|
7514
|
+
* destination strip input, so the result depends on neither the lane order
|
|
7515
|
+
* nor the block size. Throws, leaving the bindings unchanged, for a lane
|
|
7516
|
+
* keying itself, a binding that would close a cycle over the lane bindings,
|
|
7517
|
+
* a full binding table and an alignment past the delay ceiling. Not callable
|
|
7518
|
+
* while a block is being processed.
|
|
7008
7519
|
*/
|
|
7009
7520
|
setLaneSidechain(trackId, insertIndex, sourceTrackId) {
|
|
7010
7521
|
this.native.setLaneSidechain(trackId, insertIndex, sourceTrackId);
|
|
7011
7522
|
}
|
|
7523
|
+
/**
|
|
7524
|
+
* Installs a compiled project timeline into this stopped engine, all or
|
|
7525
|
+
* nothing: tempo and time-signature segments, markers, track lanes, track
|
|
7526
|
+
* automation, audio and MIDI clips, and the per-track strips of the project's
|
|
7527
|
+
* mixer scene are replaced in full (a later low-level setter on those domains
|
|
7528
|
+
* is overwritten by the next apply). Instruments, buses, the master strip,
|
|
7529
|
+
* metronome, loop and capture are not touched; bind instruments separately.
|
|
7530
|
+
*
|
|
7531
|
+
* Throws while the transport is playing, for a timeline the engine cannot
|
|
7532
|
+
* hold, and for a scene strip routed from several tracks. A validation
|
|
7533
|
+
* failure leaves the engine unchanged. The engine keeps its own reference, so
|
|
7534
|
+
* {@link ProjectTimeline.dispose} may follow immediately.
|
|
7535
|
+
*
|
|
7536
|
+
* Also throws on an unprepared engine and on a timeline whose sample rate
|
|
7537
|
+
* differs from the engine's. Once a timeline is applied, a later prepare at
|
|
7538
|
+
* another rate is refused until the timeline's clips are cleared.
|
|
7539
|
+
*/
|
|
7540
|
+
applyProjectTimeline(timeline) {
|
|
7541
|
+
const timelineId = projectTimelineNativeId(timeline);
|
|
7542
|
+
if (timelineId === void 0) {
|
|
7543
|
+
throw new TypeError("timeline must be a ProjectTimeline instance");
|
|
7544
|
+
}
|
|
7545
|
+
this.native.applyProjectTimeline(timelineId);
|
|
7546
|
+
}
|
|
7012
7547
|
setTrackBuses(buses) {
|
|
7013
7548
|
this.native.setTrackBuses(
|
|
7014
|
-
Array.isArray(buses) ? buses.map(
|
|
7015
|
-
|
|
7016
|
-
|
|
7549
|
+
Array.isArray(buses) ? buses.map((bus) => ({
|
|
7550
|
+
...bus,
|
|
7551
|
+
sends: bus.sends ? _RealtimeEngine.normalizeSends(bus.sends) : void 0
|
|
7552
|
+
})) : buses
|
|
7017
7553
|
);
|
|
7018
7554
|
}
|
|
7019
7555
|
/**
|
|
@@ -7167,6 +7703,16 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
7167
7703
|
* stages of the offline mastering chain (`repair.*`, `loudness`, and the
|
|
7168
7704
|
* match stages) have no insert form and no automation id: they buffer the
|
|
7169
7705
|
* entire signal by construction and do not run on the realtime path.
|
|
7706
|
+
*
|
|
7707
|
+
* The returned id uses the track's current positional lane selector. When
|
|
7708
|
+
* `setTrackLanes` successfully changes lane order or membership, the engine
|
|
7709
|
+
* remaps already queued and published track automation by track id, but it
|
|
7710
|
+
* cannot update a numeric id retained by the caller. Re-resolve every track
|
|
7711
|
+
* insert id after such a topology change before passing it to
|
|
7712
|
+
* `setAutomationLane`, `setParameter`, or `setParameterSmoothed`. Use
|
|
7713
|
+
* `setTrackStripInsertParamByName` when the operation needs a stable track
|
|
7714
|
+
* identity. Master and bus insert ids are separate and are not invalidated by
|
|
7715
|
+
* track-lane changes.
|
|
7170
7716
|
*/
|
|
7171
7717
|
resolveTrackInsertAutomationId(trackId, insertIndex, paramName) {
|
|
7172
7718
|
return this.native.resolveTrackInsertAutomationId(trackId, insertIndex, paramName);
|
|
@@ -7199,12 +7745,9 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
7199
7745
|
* return `-1`: they resize voice pools or swap DSP topology, which is not
|
|
7200
7746
|
* audio-thread safe. Rebind the instrument with a new patch instead.
|
|
7201
7747
|
*
|
|
7202
|
-
*
|
|
7203
|
-
*
|
|
7204
|
-
*
|
|
7205
|
-
* note-on and take effect from the next note, so a lane that moves one of
|
|
7206
|
-
* them under a held note looks inert until the next one speaks — that is the
|
|
7207
|
-
* behaviour, not a dropped write.
|
|
7748
|
+
* All automatable parameters of a NativeSynth reach already-sounding voices
|
|
7749
|
+
* from the next processed block. Voices using GM program patches are
|
|
7750
|
+
* unaffected; parameters apply to NativeSynth's own patch only.
|
|
7208
7751
|
*
|
|
7209
7752
|
* The id survives an unbind/rebind of the same destination and applies
|
|
7210
7753
|
* nothing while that destination is unbound.
|
|
@@ -7228,6 +7771,16 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
7228
7771
|
setTrackStripDualPan(trackId, leftPan, rightPan) {
|
|
7229
7772
|
this.native.setTrackStripDualPan(trackId, leftPan, rightPan);
|
|
7230
7773
|
}
|
|
7774
|
+
/**
|
|
7775
|
+
* Sets a track lane strip's surround placement in realtime (glitch-free; a
|
|
7776
|
+
* constant-power 5 ms one-pole glide). Used when the destination has more than
|
|
7777
|
+
* two channels. Omitted fields default to a centered point source
|
|
7778
|
+
* (`distance` 1); a `distance` of 0 or less is treated as 1. Throws for an
|
|
7779
|
+
* unknown track, a track without a lane strip, or a non-finite field.
|
|
7780
|
+
*/
|
|
7781
|
+
setTrackStripSurroundPan(trackId, pan) {
|
|
7782
|
+
this.native.setTrackStripSurroundPan(trackId, pan);
|
|
7783
|
+
}
|
|
7231
7784
|
/**
|
|
7232
7785
|
* Sets a bus strip's output pan position in realtime (glitch-free). Throws
|
|
7233
7786
|
* for an unknown bus or one wider than stereo.
|
|
@@ -7248,8 +7801,9 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
7248
7801
|
this.native.setBusStripDualPan(busId, leftPan, rightPan);
|
|
7249
7802
|
}
|
|
7250
7803
|
/**
|
|
7251
|
-
* Sets a track lane strip's
|
|
7252
|
-
*
|
|
7804
|
+
* Sets a track lane strip's alignment delay (whole samples), moving this lane
|
|
7805
|
+
* later relative to every other lane. It is not latency: PDC does not
|
|
7806
|
+
* compensate it and the reported graph latency is unchanged.
|
|
7253
7807
|
*/
|
|
7254
7808
|
setTrackStripChannelDelaySamples(trackId, delaySamples) {
|
|
7255
7809
|
this.native.setTrackStripChannelDelaySamples(trackId, delaySamples);
|
|
@@ -7493,6 +8047,12 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
7493
8047
|
meterScratchRenderFrame() {
|
|
7494
8048
|
return Number(this.native.meterScratchRenderFrame());
|
|
7495
8049
|
}
|
|
8050
|
+
meterScratchInputPeakDbL() {
|
|
8051
|
+
return this.native.meterScratchInputPeakDbL();
|
|
8052
|
+
}
|
|
8053
|
+
meterScratchInputPeakDbR() {
|
|
8054
|
+
return this.native.meterScratchInputPeakDbR();
|
|
8055
|
+
}
|
|
7496
8056
|
meterScratchValue(field) {
|
|
7497
8057
|
return this.native.meterScratchValue(field);
|
|
7498
8058
|
}
|
|
@@ -7502,14 +8062,24 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
7502
8062
|
/**
|
|
7503
8063
|
* Drains pending meter telemetry as per-plane (wide) records for a surround
|
|
7504
8064
|
* target. Use this for a surround mix target; {@link drainMeterTelemetry}
|
|
7505
|
-
* stays the stereo fast path. The two share one queue
|
|
7506
|
-
* target
|
|
7507
|
-
* this wide drain is for an
|
|
8065
|
+
* stays the stereo fast path. The two share one queue and each consumes every
|
|
8066
|
+
* target's records, so an engine uses only one of them. The live AudioWorklet
|
|
8067
|
+
* path owns the queue via the stereo drain, so this wide drain is for an
|
|
8068
|
+
* offline (non-worklet) engine instance; per-plane
|
|
7508
8069
|
* surround meters are not delivered over the live worklet meter ring.
|
|
7509
8070
|
*/
|
|
7510
8071
|
drainMeterTelemetryWide(maxRecords = 1024) {
|
|
7511
8072
|
return this.native.drainMeterTelemetryWide(maxRecords);
|
|
7512
8073
|
}
|
|
8074
|
+
/**
|
|
8075
|
+
* Per-insert gain reduction in dB (each <= 0) of a meter target's strip from the
|
|
8076
|
+
* last rendered block, in combined pre-to-post insert order. `targetId` uses the
|
|
8077
|
+
* meter-record encoding (0 master, 1..32 lanes, 33..40 buses; 0xFFFF monitor
|
|
8078
|
+
* yields an empty array). Throws for an id outside that range.
|
|
8079
|
+
*/
|
|
8080
|
+
meterTargetInsertGainReduction(targetId) {
|
|
8081
|
+
return this.native.meterTargetInsertGainReduction(targetId);
|
|
8082
|
+
}
|
|
7513
8083
|
/**
|
|
7514
8084
|
* Enables per-target spectrum + vectorscope capture. @param intervalFrames is
|
|
7515
8085
|
* the minimum render-frame gap between snapshots (0 disables). @param bandCount
|
|
@@ -7623,9 +8193,9 @@ var StreamAnalyzer = class {
|
|
|
7623
8193
|
throw new TypeError("outputFormat must be the integer 0 (Float32)");
|
|
7624
8194
|
}
|
|
7625
8195
|
const window = config.window === void 0 ? void 0 : resolveOrdinalInRange(config.window, 0, 3, "stream analyzer window");
|
|
7626
|
-
const
|
|
8196
|
+
const module3 = getSonareModule();
|
|
7627
8197
|
const defaults = streamAnalyzerConfigDefaults();
|
|
7628
|
-
this.analyzer = new
|
|
8198
|
+
this.analyzer = new module3.StreamAnalyzer(
|
|
7629
8199
|
config.sampleRate ?? defaults.sampleRate,
|
|
7630
8200
|
config.nFft ?? defaults.nFft,
|
|
7631
8201
|
config.hopLength ?? defaults.hopLength,
|
|
@@ -7885,8 +8455,8 @@ var Mixer = class _Mixer {
|
|
|
7885
8455
|
* @param blockSize - Maximum block size per {@link processStereo} call (default: 512)
|
|
7886
8456
|
*/
|
|
7887
8457
|
static fromSceneJson(json, sampleRate = 48e3, blockSize = 512) {
|
|
7888
|
-
const
|
|
7889
|
-
return new _Mixer(
|
|
8458
|
+
const module3 = getSonareModule();
|
|
8459
|
+
return new _Mixer(module3.createMixerFromSceneJson(json, sampleRate, blockSize), blockSize);
|
|
7890
8460
|
}
|
|
7891
8461
|
/**
|
|
7892
8462
|
* Rebuild and compile the routing graph without resetting its absolute
|
|
@@ -7942,47 +8512,60 @@ var Mixer = class _Mixer {
|
|
|
7942
8512
|
* after {@link delete}.
|
|
7943
8513
|
*/
|
|
7944
8514
|
createRealtimeBuffer() {
|
|
7945
|
-
const
|
|
7946
|
-
|
|
7947
|
-
let rightInputs = [];
|
|
8515
|
+
const leftInputs = [];
|
|
8516
|
+
const rightInputs = [];
|
|
7948
8517
|
let outLeft = this.mixer.outputLeftView();
|
|
7949
8518
|
let outRight = this.mixer.outputRightView();
|
|
8519
|
+
let acquiredStripCount = -1;
|
|
8520
|
+
const viewsDetached = () => outLeft.byteLength === 0 || outRight.byteLength === 0;
|
|
7950
8521
|
const acquire = () => {
|
|
7951
|
-
|
|
7952
|
-
|
|
7953
|
-
|
|
8522
|
+
const stripCount = this.stripCount();
|
|
8523
|
+
const detached = viewsDetached();
|
|
8524
|
+
if (detached) {
|
|
8525
|
+
leftInputs.length = 0;
|
|
8526
|
+
rightInputs.length = 0;
|
|
8527
|
+
} else {
|
|
8528
|
+
leftInputs.length = Math.min(leftInputs.length, stripCount);
|
|
8529
|
+
rightInputs.length = Math.min(rightInputs.length, stripCount);
|
|
8530
|
+
}
|
|
8531
|
+
for (let index = leftInputs.length; index < stripCount; index++) {
|
|
7954
8532
|
leftInputs.push(this.mixer.inputLeftView(index));
|
|
8533
|
+
}
|
|
8534
|
+
for (let index = rightInputs.length; index < stripCount; index++) {
|
|
7955
8535
|
rightInputs.push(this.mixer.inputRightView(index));
|
|
7956
8536
|
}
|
|
7957
|
-
|
|
7958
|
-
|
|
8537
|
+
if (detached) {
|
|
8538
|
+
outLeft = this.mixer.outputLeftView();
|
|
8539
|
+
outRight = this.mixer.outputRightView();
|
|
8540
|
+
}
|
|
8541
|
+
acquiredStripCount = stripCount;
|
|
7959
8542
|
};
|
|
7960
8543
|
acquire();
|
|
7961
|
-
const
|
|
7962
|
-
if (
|
|
8544
|
+
const acquireIfNeeded = () => {
|
|
8545
|
+
if (acquiredStripCount !== this.stripCount() || viewsDetached()) {
|
|
7963
8546
|
acquire();
|
|
7964
8547
|
}
|
|
7965
8548
|
};
|
|
7966
8549
|
return {
|
|
7967
8550
|
get leftInputs() {
|
|
7968
|
-
|
|
8551
|
+
acquireIfNeeded();
|
|
7969
8552
|
return leftInputs;
|
|
7970
8553
|
},
|
|
7971
8554
|
get rightInputs() {
|
|
7972
|
-
|
|
8555
|
+
acquireIfNeeded();
|
|
7973
8556
|
return rightInputs;
|
|
7974
8557
|
},
|
|
7975
8558
|
get outLeft() {
|
|
7976
|
-
|
|
8559
|
+
acquireIfNeeded();
|
|
7977
8560
|
return outLeft;
|
|
7978
8561
|
},
|
|
7979
8562
|
get outRight() {
|
|
7980
|
-
|
|
8563
|
+
acquireIfNeeded();
|
|
7981
8564
|
return outRight;
|
|
7982
8565
|
},
|
|
7983
|
-
process: (numSamples
|
|
7984
|
-
|
|
7985
|
-
this.mixer.processPreparedStereo(numSamples);
|
|
8566
|
+
process: (numSamples) => {
|
|
8567
|
+
acquireIfNeeded();
|
|
8568
|
+
this.mixer.processPreparedStereo(numSamples ?? outLeft.length);
|
|
7986
8569
|
}
|
|
7987
8570
|
};
|
|
7988
8571
|
}
|
|
@@ -8200,8 +8783,8 @@ var Mixer = class _Mixer {
|
|
|
8200
8783
|
this.mixer.setPanLaw(stripIndex, panLawCode(panLaw));
|
|
8201
8784
|
}
|
|
8202
8785
|
/**
|
|
8203
|
-
* Set a per-strip channel delay in samples
|
|
8204
|
-
*
|
|
8786
|
+
* Set a per-strip channel delay in samples, moving the strip later relative to
|
|
8787
|
+
* the others. It is not latency: latency compensation does not undo it.
|
|
8205
8788
|
*/
|
|
8206
8789
|
setChannelDelaySamples(stripIndex, delaySamples) {
|
|
8207
8790
|
this.mixer.setChannelDelaySamples(stripIndex, delaySamples);
|
|
@@ -8455,8 +9038,8 @@ var RealtimeVoiceChanger = class {
|
|
|
8455
9038
|
*/
|
|
8456
9039
|
constructor(config = "neutral-monitor", sampleRate, maxBlockSize = 128, channels = 1) {
|
|
8457
9040
|
this.released = false;
|
|
8458
|
-
const
|
|
8459
|
-
this.changer =
|
|
9041
|
+
const module3 = getSonareModule();
|
|
9042
|
+
this.changer = module3.createRealtimeVoiceChanger(config);
|
|
8460
9043
|
if (sampleRate !== void 0) {
|
|
8461
9044
|
let prepared = false;
|
|
8462
9045
|
try {
|
|
@@ -8732,9 +9315,9 @@ var EQ_PHASE_MODES = {
|
|
|
8732
9315
|
var StreamingMasteringChain = class {
|
|
8733
9316
|
constructor(config) {
|
|
8734
9317
|
this.released = false;
|
|
8735
|
-
const
|
|
9318
|
+
const module3 = getSonareModule();
|
|
8736
9319
|
const { loudnessStaticGainDb, loudnessStaticGainPeakDb, ...chainConfig } = config;
|
|
8737
|
-
this.chain =
|
|
9320
|
+
this.chain = module3.createStreamingMasteringChain({
|
|
8738
9321
|
__flatParams: flattenChainConfig(chainConfig),
|
|
8739
9322
|
loudnessStaticGainDb,
|
|
8740
9323
|
loudnessStaticGainPeakDb
|
|
@@ -8782,6 +9365,13 @@ var StreamingMasteringChain = class {
|
|
|
8782
9365
|
reset() {
|
|
8783
9366
|
this.chain.reset();
|
|
8784
9367
|
}
|
|
9368
|
+
/**
|
|
9369
|
+
* Set one realtime-safe full-chain parameter at a serialized block boundary.
|
|
9370
|
+
* Structural, disabled-stage and unknown parameters are rejected.
|
|
9371
|
+
*/
|
|
9372
|
+
setParameter(key, value) {
|
|
9373
|
+
this.chain.setParameter(key, value);
|
|
9374
|
+
}
|
|
8785
9375
|
/** Total reported latency in samples across all active processors. */
|
|
8786
9376
|
latencySamples() {
|
|
8787
9377
|
return this.chain.latencySamples();
|
|
@@ -8863,8 +9453,8 @@ var StreamingMasteringChain = class {
|
|
|
8863
9453
|
var StreamingEqualizer = class {
|
|
8864
9454
|
constructor(config = {}) {
|
|
8865
9455
|
this.released = false;
|
|
8866
|
-
const
|
|
8867
|
-
this.eq =
|
|
9456
|
+
const module3 = getSonareModule();
|
|
9457
|
+
this.eq = module3.createEqualizer(config);
|
|
8868
9458
|
}
|
|
8869
9459
|
/**
|
|
8870
9460
|
* Configure the band at `index` (0..23). Omitted fields use C++ defaults.
|
|
@@ -9033,8 +9623,8 @@ var StreamingEqualizer = class {
|
|
|
9033
9623
|
var StreamingRetune = class {
|
|
9034
9624
|
constructor(config = {}) {
|
|
9035
9625
|
this.released = false;
|
|
9036
|
-
const
|
|
9037
|
-
this.retune =
|
|
9626
|
+
const module3 = getSonareModule();
|
|
9627
|
+
this.retune = module3.createStreamingRetune(config);
|
|
9038
9628
|
}
|
|
9039
9629
|
/**
|
|
9040
9630
|
* Allocate and initialize native state for the given sample rate and maximum
|
|
@@ -9098,28 +9688,1292 @@ function transcribe(request) {
|
|
|
9098
9688
|
);
|
|
9099
9689
|
}
|
|
9100
9690
|
|
|
9101
|
-
// src/
|
|
9102
|
-
|
|
9103
|
-
|
|
9691
|
+
// src/vocal_edit.ts
|
|
9692
|
+
var vocalErrorFields = [
|
|
9693
|
+
"reason",
|
|
9694
|
+
"field",
|
|
9695
|
+
"expected",
|
|
9696
|
+
"actual",
|
|
9697
|
+
"expectedText",
|
|
9698
|
+
"actualText"
|
|
9699
|
+
];
|
|
9700
|
+
var cachedModuleSource = null;
|
|
9701
|
+
var cachedVocalModule = null;
|
|
9702
|
+
function addVocalErrorDetail(error, detail) {
|
|
9703
|
+
if (error === null || typeof error !== "object") {
|
|
9704
|
+
return;
|
|
9705
|
+
}
|
|
9706
|
+
const candidate = error;
|
|
9707
|
+
if (candidate.name !== "SonareError" || typeof candidate.code !== "number") {
|
|
9708
|
+
return;
|
|
9709
|
+
}
|
|
9710
|
+
for (const field of vocalErrorFields) {
|
|
9711
|
+
Object.defineProperty(candidate, field, {
|
|
9712
|
+
configurable: true,
|
|
9713
|
+
enumerable: true,
|
|
9714
|
+
value: detail[field],
|
|
9715
|
+
writable: false
|
|
9716
|
+
});
|
|
9717
|
+
}
|
|
9104
9718
|
}
|
|
9105
|
-
|
|
9106
|
-
const
|
|
9107
|
-
if (
|
|
9108
|
-
|
|
9719
|
+
function module() {
|
|
9720
|
+
const source = getSonareModule();
|
|
9721
|
+
if (source === cachedModuleSource && cachedVocalModule !== null) {
|
|
9722
|
+
return cachedVocalModule;
|
|
9109
9723
|
}
|
|
9110
|
-
const
|
|
9111
|
-
|
|
9112
|
-
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
|
|
9116
|
-
|
|
9724
|
+
const detailReader = source.vocalEditLastErrorDetail;
|
|
9725
|
+
if (typeof detailReader !== "function") {
|
|
9726
|
+
cachedModuleSource = source;
|
|
9727
|
+
cachedVocalModule = source;
|
|
9728
|
+
return source;
|
|
9729
|
+
}
|
|
9730
|
+
const functionCache = /* @__PURE__ */ new Map();
|
|
9731
|
+
const wrapped = new Proxy(source, {
|
|
9732
|
+
get(target, property, receiver) {
|
|
9733
|
+
const member = Reflect.get(target, property, receiver);
|
|
9734
|
+
if (property === "vocalEditLastErrorDetail" || typeof property !== "string" || !property.startsWith("vocalEdit") || typeof member !== "function") {
|
|
9735
|
+
return member;
|
|
9736
|
+
}
|
|
9737
|
+
const cached = functionCache.get(property);
|
|
9738
|
+
if (cached !== void 0) {
|
|
9739
|
+
return cached;
|
|
9740
|
+
}
|
|
9741
|
+
const wrappedMember = (...args) => {
|
|
9742
|
+
let beforeSequence;
|
|
9743
|
+
try {
|
|
9744
|
+
beforeSequence = detailReader.call(target).sequence;
|
|
9745
|
+
} catch {
|
|
9746
|
+
}
|
|
9747
|
+
try {
|
|
9748
|
+
return Reflect.apply(member, target, args);
|
|
9749
|
+
} catch (error) {
|
|
9750
|
+
if (beforeSequence !== void 0) {
|
|
9751
|
+
try {
|
|
9752
|
+
const detail = detailReader.call(target);
|
|
9753
|
+
if (detail.sequence !== beforeSequence) {
|
|
9754
|
+
addVocalErrorDetail(error, detail);
|
|
9755
|
+
}
|
|
9756
|
+
} catch {
|
|
9757
|
+
}
|
|
9758
|
+
}
|
|
9759
|
+
throw error;
|
|
9760
|
+
}
|
|
9761
|
+
};
|
|
9762
|
+
functionCache.set(property, wrappedMember);
|
|
9763
|
+
return wrappedMember;
|
|
9764
|
+
}
|
|
9117
9765
|
});
|
|
9118
|
-
|
|
9119
|
-
|
|
9766
|
+
cachedModuleSource = source;
|
|
9767
|
+
cachedVocalModule = wrapped;
|
|
9768
|
+
return wrapped;
|
|
9769
|
+
}
|
|
9770
|
+
function requireHandle(handle, subject) {
|
|
9771
|
+
if (!Number.isSafeInteger(handle) || handle <= 0) {
|
|
9772
|
+
throw new TypeError(`${subject} has already been disposed`);
|
|
9120
9773
|
}
|
|
9121
|
-
|
|
9122
|
-
|
|
9774
|
+
}
|
|
9775
|
+
function requireFinite(value, field) {
|
|
9776
|
+
if (!Number.isFinite(value)) {
|
|
9777
|
+
throw new RangeError(`${field} must be finite`);
|
|
9778
|
+
}
|
|
9779
|
+
return value;
|
|
9780
|
+
}
|
|
9781
|
+
function requireSample(value, field) {
|
|
9782
|
+
requireFinite(value, field);
|
|
9783
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
9784
|
+
throw new RangeError(`${field} must be a non-negative safe integer`);
|
|
9785
|
+
}
|
|
9786
|
+
return value;
|
|
9787
|
+
}
|
|
9788
|
+
function requireUint32(value, field) {
|
|
9789
|
+
requireSample(value, field);
|
|
9790
|
+
if (value > 4294967295) {
|
|
9791
|
+
throw new RangeError(`${field} must fit uint32`);
|
|
9792
|
+
}
|
|
9793
|
+
return value;
|
|
9794
|
+
}
|
|
9795
|
+
function requireSampleRate(value) {
|
|
9796
|
+
requireSample(value, "sampleRate");
|
|
9797
|
+
if (value < 8e3 || value > 384e3) {
|
|
9798
|
+
throw new RangeError("sampleRate must be an integer in [8000, 384000]");
|
|
9799
|
+
}
|
|
9800
|
+
return value;
|
|
9801
|
+
}
|
|
9802
|
+
function requireToken(value, field, fallback = "0") {
|
|
9803
|
+
const token = value ?? fallback;
|
|
9804
|
+
if (typeof token !== "string" || !/^(0|[1-9]\d*)$/.test(token)) {
|
|
9805
|
+
throw new RangeError(`${field} must be a canonical decimal uint64 string`);
|
|
9806
|
+
}
|
|
9807
|
+
if (token.length > 20 || token.length === 20 && token > "18446744073709551615") {
|
|
9808
|
+
throw new RangeError(`${field} must fit uint64`);
|
|
9809
|
+
}
|
|
9810
|
+
return token;
|
|
9811
|
+
}
|
|
9812
|
+
function resolveRevision(argument, fallback) {
|
|
9813
|
+
const value = typeof argument === "string" ? argument : argument?.expectedRevision;
|
|
9814
|
+
return requireToken(value, "expectedRevision", fallback);
|
|
9815
|
+
}
|
|
9816
|
+
function requireRange(range) {
|
|
9817
|
+
if (!range || typeof range !== "object") {
|
|
9818
|
+
throw new TypeError("range must be an object");
|
|
9819
|
+
}
|
|
9820
|
+
const startSample = requireSample(range.startSample, "range.startSample");
|
|
9821
|
+
const endSample = requireSample(range.endSample, "range.endSample");
|
|
9822
|
+
if (endSample < startSample) {
|
|
9823
|
+
throw new RangeError("range.endSample must be >= startSample");
|
|
9824
|
+
}
|
|
9825
|
+
return { startSample, endSample };
|
|
9826
|
+
}
|
|
9827
|
+
function copyToken2(token) {
|
|
9828
|
+
return {
|
|
9829
|
+
sessionEpoch: requireToken(token.sessionEpoch, "sessionEpoch"),
|
|
9830
|
+
revision: requireToken(token.revision, "revision"),
|
|
9831
|
+
draftId: requireToken(token.draftId, "draftId"),
|
|
9832
|
+
generation: requireToken(token.generation, "generation"),
|
|
9833
|
+
requestId: requireToken(token.requestId, "requestId"),
|
|
9834
|
+
profileId: token.profileId
|
|
9835
|
+
};
|
|
9836
|
+
}
|
|
9837
|
+
function copyRange(range) {
|
|
9838
|
+
return { startSample: range.startSample, endSample: range.endSample };
|
|
9839
|
+
}
|
|
9840
|
+
function copyNotes(value) {
|
|
9841
|
+
const notes = Array.from(value.notes, (note) => ({
|
|
9842
|
+
...note,
|
|
9843
|
+
amplitude: new Float32Array(note.amplitude),
|
|
9844
|
+
edit: {
|
|
9845
|
+
...note.edit,
|
|
9846
|
+
pitch: {
|
|
9847
|
+
...note.edit.pitch,
|
|
9848
|
+
target: note.edit.pitch.target.mode === "curve" ? {
|
|
9849
|
+
mode: "curve",
|
|
9850
|
+
points: note.edit.pitch.target.points.map((point) => ({ ...point }))
|
|
9851
|
+
} : { ...note.edit.pitch.target }
|
|
9852
|
+
},
|
|
9853
|
+
amplitudeEnvelope: Array.from(note.edit.amplitudeEnvelope),
|
|
9854
|
+
formant: { ...note.edit.formant }
|
|
9855
|
+
}
|
|
9856
|
+
}));
|
|
9857
|
+
return {
|
|
9858
|
+
notes,
|
|
9859
|
+
transitions: Array.from(value.transitions, (transition) => ({ ...transition }))
|
|
9860
|
+
};
|
|
9861
|
+
}
|
|
9862
|
+
function copyAnalysis(value) {
|
|
9863
|
+
return {
|
|
9864
|
+
frameOriginSample: value.frameOriginSample,
|
|
9865
|
+
samplesPerFrame: value.samplesPerFrame,
|
|
9866
|
+
frameLengthSamples: value.frameLengthSamples,
|
|
9867
|
+
f0Hz: new Float32Array(value.f0Hz),
|
|
9868
|
+
voiced: new Uint8Array(value.voiced),
|
|
9869
|
+
algorithmId: value.algorithmId,
|
|
9870
|
+
algorithmVersion: value.algorithmVersion,
|
|
9871
|
+
sourceLengthSamples: value.sourceLengthSamples,
|
|
9872
|
+
sampleRate: value.sampleRate,
|
|
9873
|
+
sourceSha256: value.sourceSha256,
|
|
9874
|
+
analysisSha256: value.analysisSha256,
|
|
9875
|
+
fminHz: value.fminHz,
|
|
9876
|
+
fmaxHz: value.fmaxHz,
|
|
9877
|
+
yinThreshold: value.yinThreshold,
|
|
9878
|
+
voicedThreshold: value.voicedThreshold,
|
|
9879
|
+
centered: value.centered,
|
|
9880
|
+
segmentationThresholdCents: value.segmentationThresholdCents,
|
|
9881
|
+
minNoteMs: value.minNoteMs,
|
|
9882
|
+
referenceHz: value.referenceHz
|
|
9883
|
+
};
|
|
9884
|
+
}
|
|
9885
|
+
function copyPitch(value) {
|
|
9886
|
+
return {
|
|
9887
|
+
sourceSamples: new Float64Array(value.sourceSamples),
|
|
9888
|
+
measuredMidi: new Float64Array(value.measuredMidi),
|
|
9889
|
+
targetMidi: new Float64Array(value.targetMidi),
|
|
9890
|
+
effectiveMidi: new Float64Array(value.effectiveMidi),
|
|
9891
|
+
voiced: new Uint8Array(value.voiced),
|
|
9892
|
+
hasTarget: new Uint8Array(value.hasTarget)
|
|
9893
|
+
};
|
|
9894
|
+
}
|
|
9895
|
+
function copyRender(value) {
|
|
9896
|
+
return {
|
|
9897
|
+
samples: new Float32Array(value.samples),
|
|
9898
|
+
startSample: value.startSample,
|
|
9899
|
+
token: copyToken2(value.token),
|
|
9900
|
+
processedRanges: Array.from(value.processedRanges, copyRange),
|
|
9901
|
+
cacheHitUnits: requireToken(value.cacheHitUnits, "cacheHitUnits"),
|
|
9902
|
+
dryPassedFrames: requireToken(value.dryPassedFrames, "dryPassedFrames"),
|
|
9903
|
+
limitedCorrectionFrames: requireToken(value.limitedCorrectionFrames, "limitedCorrectionFrames")
|
|
9904
|
+
};
|
|
9905
|
+
}
|
|
9906
|
+
function validateSessionLimits(limits) {
|
|
9907
|
+
if (limits === void 0) {
|
|
9908
|
+
return;
|
|
9909
|
+
}
|
|
9910
|
+
if (limits.maxHistoryBytes !== void 0) {
|
|
9911
|
+
requireToken(limits.maxHistoryBytes, "limits.maxHistoryBytes");
|
|
9912
|
+
}
|
|
9913
|
+
if (limits.maxCacheBytes !== void 0) {
|
|
9914
|
+
requireToken(limits.maxCacheBytes, "limits.maxCacheBytes");
|
|
9915
|
+
}
|
|
9916
|
+
}
|
|
9917
|
+
function copyEditResult(value) {
|
|
9918
|
+
return {
|
|
9919
|
+
token: copyToken2(value.token),
|
|
9920
|
+
dirtyRanges: Array.from(value.dirtyRanges, copyRange),
|
|
9921
|
+
idChanges: Array.from(value.idChanges, (change) => ({
|
|
9922
|
+
operationIndex: change.operationIndex,
|
|
9923
|
+
retiredId: change.retiredId,
|
|
9924
|
+
newIds: Array.from(change.newIds)
|
|
9925
|
+
}))
|
|
9926
|
+
};
|
|
9927
|
+
}
|
|
9928
|
+
function validateCreate(request) {
|
|
9929
|
+
if (!request || typeof request !== "object") {
|
|
9930
|
+
throw new TypeError("request must be an object");
|
|
9931
|
+
}
|
|
9932
|
+
if (!(request.samples instanceof Float32Array) || request.samples.length === 0) {
|
|
9933
|
+
throw new TypeError("samples must be a non-empty Float32Array");
|
|
9934
|
+
}
|
|
9935
|
+
for (const sample of request.samples) {
|
|
9936
|
+
requireFinite(sample, "samples");
|
|
9937
|
+
}
|
|
9938
|
+
requireSampleRate(request.sampleRate);
|
|
9939
|
+
if (request.outputLengthSamples !== void 0) {
|
|
9940
|
+
requireSample(request.outputLengthSamples, "outputLengthSamples");
|
|
9941
|
+
}
|
|
9942
|
+
validateSessionLimits(request.limits);
|
|
9943
|
+
if (request.analysis) {
|
|
9944
|
+
const analysis = request.analysis;
|
|
9945
|
+
if (analysis.algorithmId !== void 0) {
|
|
9946
|
+
if (typeof analysis.algorithmId !== "string") {
|
|
9947
|
+
throw new TypeError("analysis.algorithmId must be a string");
|
|
9948
|
+
}
|
|
9949
|
+
if (analysis.algorithmId.includes("\0")) {
|
|
9950
|
+
throw new RangeError("analysis.algorithmId must not contain NUL");
|
|
9951
|
+
}
|
|
9952
|
+
}
|
|
9953
|
+
requireFinite(analysis.frameOriginSample, "analysis.frameOriginSample");
|
|
9954
|
+
requireFinite(analysis.samplesPerFrame, "analysis.samplesPerFrame");
|
|
9955
|
+
if (analysis.samplesPerFrame <= 0) {
|
|
9956
|
+
throw new RangeError("analysis.samplesPerFrame must be positive");
|
|
9957
|
+
}
|
|
9958
|
+
requireSample(analysis.frameLengthSamples, "analysis.frameLengthSamples");
|
|
9959
|
+
if (analysis.frameLengthSamples === 0) {
|
|
9960
|
+
throw new RangeError("analysis.frameLengthSamples must be positive");
|
|
9961
|
+
}
|
|
9962
|
+
if (!(analysis.f0Hz instanceof Float32Array) || !(analysis.voiced instanceof Uint8Array)) {
|
|
9963
|
+
throw new TypeError("analysis arrays must be Float32Array and Uint8Array");
|
|
9964
|
+
}
|
|
9965
|
+
if (analysis.f0Hz.length !== analysis.voiced.length) {
|
|
9966
|
+
throw new RangeError("analysis arrays must have equal lengths");
|
|
9967
|
+
}
|
|
9968
|
+
}
|
|
9969
|
+
}
|
|
9970
|
+
function normalizeRequest(request, outputLengthSamples) {
|
|
9971
|
+
const range = request.range === void 0 ? { startSample: 0, endSample: requireSample(outputLengthSamples, "outputLengthSamples") } : requireRange(request.range);
|
|
9972
|
+
const requestId = requireToken(request.requestId, "requestId");
|
|
9973
|
+
return { range, requestId };
|
|
9974
|
+
}
|
|
9975
|
+
function vocalEditAvailable() {
|
|
9976
|
+
const raw = module();
|
|
9977
|
+
return typeof raw.vocalEditAvailable === "function" && raw.vocalEditAvailable() !== 0;
|
|
9978
|
+
}
|
|
9979
|
+
function vocalEditApiVersion() {
|
|
9980
|
+
const raw = module();
|
|
9981
|
+
return typeof raw.vocalEditApiVersion === "function" ? raw.vocalEditApiVersion() : 0;
|
|
9982
|
+
}
|
|
9983
|
+
function createVocalEditSession(request) {
|
|
9984
|
+
validateCreate(request);
|
|
9985
|
+
if (!vocalEditAvailable()) {
|
|
9986
|
+
throw new Error("vocal edit is unavailable in this WASM build");
|
|
9987
|
+
}
|
|
9988
|
+
return new VocalEditSession(
|
|
9989
|
+
module().vocalEditSessionCreate(request.samples, request.sampleRate, request)
|
|
9990
|
+
);
|
|
9991
|
+
}
|
|
9992
|
+
function restoreVocalEditSession(request) {
|
|
9993
|
+
if (!(request.samples instanceof Float32Array) || request.samples.length === 0) {
|
|
9994
|
+
throw new TypeError("samples must be a non-empty Float32Array");
|
|
9995
|
+
}
|
|
9996
|
+
if (!(request.state instanceof Uint8Array)) {
|
|
9997
|
+
throw new TypeError("state must be a Uint8Array");
|
|
9998
|
+
}
|
|
9999
|
+
for (const sample of request.samples) {
|
|
10000
|
+
requireFinite(sample, "samples");
|
|
10001
|
+
}
|
|
10002
|
+
requireSampleRate(request.sampleRate);
|
|
10003
|
+
validateSessionLimits(request.limits);
|
|
10004
|
+
if (!vocalEditAvailable()) {
|
|
10005
|
+
throw new Error("vocal edit is unavailable in this WASM build");
|
|
10006
|
+
}
|
|
10007
|
+
return new VocalEditSession(
|
|
10008
|
+
module().vocalEditSessionRestore(request.samples, request.sampleRate, request.state, request)
|
|
10009
|
+
);
|
|
10010
|
+
}
|
|
10011
|
+
var VocalEditSession = class {
|
|
10012
|
+
/** @internal Instances are created by {@link createVocalEditSession} and {@link restoreVocalEditSession}. */
|
|
10013
|
+
constructor(handle) {
|
|
10014
|
+
this.drafts = /* @__PURE__ */ new Set();
|
|
10015
|
+
this.disposed = false;
|
|
10016
|
+
requireHandle(handle, "session");
|
|
10017
|
+
this.handle = handle;
|
|
10018
|
+
}
|
|
10019
|
+
dispose() {
|
|
10020
|
+
if (this.disposed) {
|
|
10021
|
+
return;
|
|
10022
|
+
}
|
|
10023
|
+
for (const draft of this.drafts) {
|
|
10024
|
+
draft.dispose();
|
|
10025
|
+
}
|
|
10026
|
+
this.drafts.clear();
|
|
10027
|
+
module().vocalEditSessionDestroy(this.handle);
|
|
10028
|
+
this.handle = 0;
|
|
10029
|
+
this.disposed = true;
|
|
10030
|
+
}
|
|
10031
|
+
delete() {
|
|
10032
|
+
this.dispose();
|
|
10033
|
+
}
|
|
10034
|
+
destroy() {
|
|
10035
|
+
this.dispose();
|
|
10036
|
+
}
|
|
10037
|
+
native() {
|
|
10038
|
+
if (this.disposed) {
|
|
10039
|
+
throw new TypeError("session has already been disposed");
|
|
10040
|
+
}
|
|
10041
|
+
requireHandle(this.handle, "session");
|
|
10042
|
+
return this.handle;
|
|
10043
|
+
}
|
|
10044
|
+
token() {
|
|
10045
|
+
return copyToken2(module().vocalEditSessionToken(this.native()));
|
|
10046
|
+
}
|
|
10047
|
+
revision() {
|
|
10048
|
+
return this.token().revision;
|
|
10049
|
+
}
|
|
10050
|
+
notes() {
|
|
10051
|
+
return copyNotes(module().vocalEditSessionNotes(this.native()));
|
|
10052
|
+
}
|
|
10053
|
+
analysis() {
|
|
10054
|
+
return copyAnalysis(module().vocalEditSessionAnalysis(this.native()));
|
|
10055
|
+
}
|
|
10056
|
+
capabilities() {
|
|
10057
|
+
return { ...module().vocalEditSessionCapabilities(this.native()) };
|
|
10058
|
+
}
|
|
10059
|
+
outputLengthSamples() {
|
|
10060
|
+
return requireSample(
|
|
10061
|
+
module().vocalEditSessionOutputLength(this.native()),
|
|
10062
|
+
"outputLengthSamples"
|
|
10063
|
+
);
|
|
10064
|
+
}
|
|
10065
|
+
history() {
|
|
10066
|
+
const value = module().vocalEditSessionHistory(this.native());
|
|
10067
|
+
return { canUndo: value.canUndo === true, canRedo: value.canRedo === true };
|
|
10068
|
+
}
|
|
10069
|
+
beginEdit(options = {}) {
|
|
10070
|
+
const draft = new VocalEditDraft(
|
|
10071
|
+
module().vocalEditSessionBeginEdit(this.native(), resolveRevision(options, this.revision())),
|
|
10072
|
+
this
|
|
10073
|
+
);
|
|
10074
|
+
this.drafts.add(draft);
|
|
10075
|
+
return draft;
|
|
10076
|
+
}
|
|
10077
|
+
undo(options = {}) {
|
|
10078
|
+
return copyEditResult(
|
|
10079
|
+
module().vocalEditSessionApplyHistory(
|
|
10080
|
+
this.native(),
|
|
10081
|
+
resolveRevision(options, this.revision()),
|
|
10082
|
+
false
|
|
10083
|
+
)
|
|
10084
|
+
);
|
|
10085
|
+
}
|
|
10086
|
+
redo(options = {}) {
|
|
10087
|
+
return copyEditResult(
|
|
10088
|
+
module().vocalEditSessionApplyHistory(
|
|
10089
|
+
this.native(),
|
|
10090
|
+
resolveRevision(options, this.revision()),
|
|
10091
|
+
true
|
|
10092
|
+
)
|
|
10093
|
+
);
|
|
10094
|
+
}
|
|
10095
|
+
evaluatePitch(noteId) {
|
|
10096
|
+
return copyPitch(
|
|
10097
|
+
module().vocalEditEvaluatePitch(this.native(), requireUint32(noteId, "noteId"), false)
|
|
10098
|
+
);
|
|
10099
|
+
}
|
|
10100
|
+
sourceSampleToDestinationSample(noteId, sourceSample) {
|
|
10101
|
+
requireFinite(sourceSample, "sourceSample");
|
|
10102
|
+
return module().vocalEditMapCoordinate(
|
|
10103
|
+
this.native(),
|
|
10104
|
+
requireUint32(noteId, "noteId"),
|
|
10105
|
+
sourceSample,
|
|
10106
|
+
false,
|
|
10107
|
+
false
|
|
10108
|
+
);
|
|
10109
|
+
}
|
|
10110
|
+
destinationSampleToSourceSample(noteId, destinationSample) {
|
|
10111
|
+
requireFinite(destinationSample, "destinationSample");
|
|
10112
|
+
return module().vocalEditMapCoordinate(
|
|
10113
|
+
this.native(),
|
|
10114
|
+
requireUint32(noteId, "noteId"),
|
|
10115
|
+
destinationSample,
|
|
10116
|
+
false,
|
|
10117
|
+
true
|
|
10118
|
+
);
|
|
10119
|
+
}
|
|
10120
|
+
captureRenderSnapshot() {
|
|
10121
|
+
return new VocalRenderSnapshot(module().vocalEditCaptureSnapshot(this.native(), false));
|
|
10122
|
+
}
|
|
10123
|
+
exportState() {
|
|
10124
|
+
return new Uint8Array(module().vocalEditSessionExportState(this.native()));
|
|
10125
|
+
}
|
|
10126
|
+
/** @internal Used by the draft to remove itself from the owner set. */
|
|
10127
|
+
_forgetDraft(draft) {
|
|
10128
|
+
this.drafts.delete(draft);
|
|
10129
|
+
}
|
|
10130
|
+
};
|
|
10131
|
+
var VocalEditDraft = class {
|
|
10132
|
+
/** @internal Instances are created by {@link VocalEditSession.beginEdit}. */
|
|
10133
|
+
constructor(handle, owner) {
|
|
10134
|
+
this.disposed = false;
|
|
10135
|
+
requireHandle(handle, "draft");
|
|
10136
|
+
this.handle = handle;
|
|
10137
|
+
this.owner = owner;
|
|
10138
|
+
}
|
|
10139
|
+
native() {
|
|
10140
|
+
if (this.disposed) {
|
|
10141
|
+
throw new TypeError("draft has already been disposed");
|
|
10142
|
+
}
|
|
10143
|
+
requireHandle(this.handle, "draft");
|
|
10144
|
+
return this.handle;
|
|
10145
|
+
}
|
|
10146
|
+
token() {
|
|
10147
|
+
return copyToken2(module().vocalEditDraftToken(this.native()));
|
|
10148
|
+
}
|
|
10149
|
+
notes() {
|
|
10150
|
+
return copyNotes(module().vocalEditDraftNotes(this.native()));
|
|
10151
|
+
}
|
|
10152
|
+
apply(request) {
|
|
10153
|
+
if (request.expectedGeneration === void 0) {
|
|
10154
|
+
throw new TypeError("expectedGeneration is required");
|
|
10155
|
+
}
|
|
10156
|
+
const generation = requireToken(request.expectedGeneration, "expectedGeneration");
|
|
10157
|
+
if (!Array.isArray(request.operations)) {
|
|
10158
|
+
throw new TypeError("operations must be an array");
|
|
10159
|
+
}
|
|
10160
|
+
return copyEditResult(
|
|
10161
|
+
module().vocalEditDraftApply(this.native(), generation, request.operations)
|
|
10162
|
+
);
|
|
10163
|
+
}
|
|
10164
|
+
commit(options = {}) {
|
|
10165
|
+
const result = copyEditResult(
|
|
10166
|
+
module().vocalEditDraftCommit(this.native(), resolveRevision(options, this.owner.revision()))
|
|
10167
|
+
);
|
|
10168
|
+
this.dispose();
|
|
10169
|
+
return result;
|
|
10170
|
+
}
|
|
10171
|
+
cancel() {
|
|
10172
|
+
if (this.disposed) {
|
|
10173
|
+
return;
|
|
10174
|
+
}
|
|
10175
|
+
module().vocalEditDraftCancel(this.native());
|
|
10176
|
+
this.dispose();
|
|
10177
|
+
}
|
|
10178
|
+
evaluatePitch(noteId) {
|
|
10179
|
+
return copyPitch(
|
|
10180
|
+
module().vocalEditEvaluatePitch(this.native(), requireUint32(noteId, "noteId"), true)
|
|
10181
|
+
);
|
|
10182
|
+
}
|
|
10183
|
+
sourceSampleToDestinationSample(noteId, sourceSample) {
|
|
10184
|
+
requireFinite(sourceSample, "sourceSample");
|
|
10185
|
+
return module().vocalEditMapCoordinate(
|
|
10186
|
+
this.native(),
|
|
10187
|
+
requireUint32(noteId, "noteId"),
|
|
10188
|
+
sourceSample,
|
|
10189
|
+
true,
|
|
10190
|
+
false
|
|
10191
|
+
);
|
|
10192
|
+
}
|
|
10193
|
+
destinationSampleToSourceSample(noteId, destinationSample) {
|
|
10194
|
+
requireFinite(destinationSample, "destinationSample");
|
|
10195
|
+
return module().vocalEditMapCoordinate(
|
|
10196
|
+
this.native(),
|
|
10197
|
+
requireUint32(noteId, "noteId"),
|
|
10198
|
+
destinationSample,
|
|
10199
|
+
true,
|
|
10200
|
+
true
|
|
10201
|
+
);
|
|
10202
|
+
}
|
|
10203
|
+
captureRenderSnapshot() {
|
|
10204
|
+
return new VocalRenderSnapshot(module().vocalEditCaptureSnapshot(this.native(), true));
|
|
10205
|
+
}
|
|
10206
|
+
dispose() {
|
|
10207
|
+
if (this.disposed) {
|
|
10208
|
+
return;
|
|
10209
|
+
}
|
|
10210
|
+
module().vocalEditDraftDestroy(this.handle);
|
|
10211
|
+
this.handle = 0;
|
|
10212
|
+
this.disposed = true;
|
|
10213
|
+
this.owner._forgetDraft(this);
|
|
10214
|
+
}
|
|
10215
|
+
delete() {
|
|
10216
|
+
this.dispose();
|
|
10217
|
+
}
|
|
10218
|
+
destroy() {
|
|
10219
|
+
this.dispose();
|
|
10220
|
+
}
|
|
10221
|
+
};
|
|
10222
|
+
var VocalRenderSnapshot = class {
|
|
10223
|
+
/** @internal Instances are created by a session or draft. */
|
|
10224
|
+
constructor(handle) {
|
|
10225
|
+
this.disposed = false;
|
|
10226
|
+
requireHandle(handle, "snapshot");
|
|
10227
|
+
this.handle = handle;
|
|
10228
|
+
}
|
|
10229
|
+
native() {
|
|
10230
|
+
if (this.disposed) {
|
|
10231
|
+
throw new TypeError("snapshot has already been disposed");
|
|
10232
|
+
}
|
|
10233
|
+
requireHandle(this.handle, "snapshot");
|
|
10234
|
+
return this.handle;
|
|
10235
|
+
}
|
|
10236
|
+
outputLengthSamples() {
|
|
10237
|
+
return requireSample(
|
|
10238
|
+
module().vocalEditSnapshotOutputLength(this.native()),
|
|
10239
|
+
"outputLengthSamples"
|
|
10240
|
+
);
|
|
10241
|
+
}
|
|
10242
|
+
render(request) {
|
|
10243
|
+
const handle = this.native();
|
|
10244
|
+
if (request.signal?.aborted) {
|
|
10245
|
+
throw new DOMException("The render was aborted", "AbortError");
|
|
10246
|
+
}
|
|
10247
|
+
const normalized = normalizeRequest(request, this.outputLengthSamples());
|
|
10248
|
+
return copyRender(
|
|
10249
|
+
module().vocalEditSnapshotRender(
|
|
10250
|
+
handle,
|
|
10251
|
+
normalized.range.startSample,
|
|
10252
|
+
normalized.range.endSample,
|
|
10253
|
+
normalized.requestId
|
|
10254
|
+
)
|
|
10255
|
+
);
|
|
10256
|
+
}
|
|
10257
|
+
beginRenderJob(request) {
|
|
10258
|
+
const handle = this.native();
|
|
10259
|
+
if (request.signal?.aborted) {
|
|
10260
|
+
throw new DOMException("The render was aborted", "AbortError");
|
|
10261
|
+
}
|
|
10262
|
+
const normalized = normalizeRequest(request, this.outputLengthSamples());
|
|
10263
|
+
return new VocalRenderJob(
|
|
10264
|
+
module().vocalEditRenderJobBegin(
|
|
10265
|
+
handle,
|
|
10266
|
+
normalized.range.startSample,
|
|
10267
|
+
normalized.range.endSample,
|
|
10268
|
+
normalized.requestId
|
|
10269
|
+
)
|
|
10270
|
+
);
|
|
10271
|
+
}
|
|
10272
|
+
/**
|
|
10273
|
+
* Render one native work unit per macrotask so `request.signal` can stop the
|
|
10274
|
+
* job between units. A cancelled job publishes no partial PCM.
|
|
10275
|
+
*/
|
|
10276
|
+
renderAsync(request) {
|
|
10277
|
+
this.native();
|
|
10278
|
+
const signal = request.signal;
|
|
10279
|
+
if (signal?.aborted) {
|
|
10280
|
+
return Promise.reject(new DOMException("The render was aborted", "AbortError"));
|
|
10281
|
+
}
|
|
10282
|
+
const job = this.beginRenderJob(request);
|
|
10283
|
+
return (async () => {
|
|
10284
|
+
try {
|
|
10285
|
+
while (true) {
|
|
10286
|
+
if (signal?.aborted) {
|
|
10287
|
+
job.abort();
|
|
10288
|
+
throw new DOMException("The render was aborted", "AbortError");
|
|
10289
|
+
}
|
|
10290
|
+
if (job.next().complete) {
|
|
10291
|
+
return job.finalize();
|
|
10292
|
+
}
|
|
10293
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
10294
|
+
}
|
|
10295
|
+
} catch (error) {
|
|
10296
|
+
job.abort();
|
|
10297
|
+
throw error;
|
|
10298
|
+
} finally {
|
|
10299
|
+
job.dispose();
|
|
10300
|
+
}
|
|
10301
|
+
})();
|
|
10302
|
+
}
|
|
10303
|
+
dispose() {
|
|
10304
|
+
if (this.disposed) {
|
|
10305
|
+
return;
|
|
10306
|
+
}
|
|
10307
|
+
module().vocalEditSnapshotDestroy(this.handle);
|
|
10308
|
+
this.handle = 0;
|
|
10309
|
+
this.disposed = true;
|
|
10310
|
+
}
|
|
10311
|
+
delete() {
|
|
10312
|
+
this.dispose();
|
|
10313
|
+
}
|
|
10314
|
+
destroy() {
|
|
10315
|
+
this.dispose();
|
|
10316
|
+
}
|
|
10317
|
+
};
|
|
10318
|
+
var VocalRenderJob = class {
|
|
10319
|
+
/** @internal Instances are created by {@link VocalRenderSnapshot.beginRenderJob}. */
|
|
10320
|
+
constructor(handle) {
|
|
10321
|
+
this.disposed = false;
|
|
10322
|
+
requireHandle(handle, "render job");
|
|
10323
|
+
this.handle = handle;
|
|
10324
|
+
}
|
|
10325
|
+
native() {
|
|
10326
|
+
if (this.disposed) {
|
|
10327
|
+
throw new TypeError("render job has already been disposed");
|
|
10328
|
+
}
|
|
10329
|
+
requireHandle(this.handle, "render job");
|
|
10330
|
+
return this.handle;
|
|
10331
|
+
}
|
|
10332
|
+
next() {
|
|
10333
|
+
return { complete: module().vocalEditRenderJobNext(this.native()) };
|
|
10334
|
+
}
|
|
10335
|
+
finalize() {
|
|
10336
|
+
const result = copyRender(module().vocalEditRenderJobFinalize(this.native()));
|
|
10337
|
+
this.dispose();
|
|
10338
|
+
return result;
|
|
10339
|
+
}
|
|
10340
|
+
abort() {
|
|
10341
|
+
if (!this.disposed) {
|
|
10342
|
+
module().vocalEditRenderJobAbort(this.handle);
|
|
10343
|
+
}
|
|
10344
|
+
}
|
|
10345
|
+
dispose() {
|
|
10346
|
+
if (this.disposed) {
|
|
10347
|
+
return;
|
|
10348
|
+
}
|
|
10349
|
+
module().vocalEditRenderJobDestroy(this.handle);
|
|
10350
|
+
this.handle = 0;
|
|
10351
|
+
this.disposed = true;
|
|
10352
|
+
}
|
|
10353
|
+
delete() {
|
|
10354
|
+
this.dispose();
|
|
10355
|
+
}
|
|
10356
|
+
destroy() {
|
|
10357
|
+
this.dispose();
|
|
10358
|
+
}
|
|
10359
|
+
};
|
|
10360
|
+
|
|
10361
|
+
// src/vocal_edit_worker_protocol.ts
|
|
10362
|
+
function stateTokenEquals(a, b) {
|
|
10363
|
+
if (!a || !b) {
|
|
10364
|
+
return a === b;
|
|
10365
|
+
}
|
|
10366
|
+
return a.sessionEpoch === b.sessionEpoch && a.revision === b.revision && a.draftId === b.draftId && a.generation === b.generation && a.profileId === b.profileId;
|
|
10367
|
+
}
|
|
10368
|
+
function compareUint64(a, b) {
|
|
10369
|
+
const left = a.replace(/^0+(?=\d)/, "");
|
|
10370
|
+
const right = b.replace(/^0+(?=\d)/, "");
|
|
10371
|
+
if (left.length !== right.length) {
|
|
10372
|
+
return left.length < right.length ? -1 : 1;
|
|
10373
|
+
}
|
|
10374
|
+
if (left === right) {
|
|
10375
|
+
return 0;
|
|
10376
|
+
}
|
|
10377
|
+
return left < right ? -1 : 1;
|
|
10378
|
+
}
|
|
10379
|
+
|
|
10380
|
+
// src/vocal_edit_worker_client.ts
|
|
10381
|
+
var VocalEditWorkerStaleResultError = class extends Error {
|
|
10382
|
+
constructor(message = "A vocal edit Worker result is stale") {
|
|
10383
|
+
super(message);
|
|
10384
|
+
this.name = "StaleResultError";
|
|
10385
|
+
}
|
|
10386
|
+
};
|
|
10387
|
+
var VocalEditWorkerTask = class {
|
|
10388
|
+
constructor(result, cancelRequest) {
|
|
10389
|
+
this.result = result;
|
|
10390
|
+
this.cancelRequest = cancelRequest;
|
|
10391
|
+
}
|
|
10392
|
+
cancel() {
|
|
10393
|
+
this.cancelRequest();
|
|
10394
|
+
}
|
|
10395
|
+
// biome-ignore lint/suspicious/noThenProperty: PromiseLike intentionally exposes then.
|
|
10396
|
+
then(onfulfilled, onrejected) {
|
|
10397
|
+
return this.result.then(onfulfilled, onrejected);
|
|
10398
|
+
}
|
|
10399
|
+
catch(onrejected) {
|
|
10400
|
+
return this.result.catch(onrejected);
|
|
10401
|
+
}
|
|
10402
|
+
finally(onfinally) {
|
|
10403
|
+
return this.result.finally(onfinally);
|
|
10404
|
+
}
|
|
10405
|
+
};
|
|
10406
|
+
function resolveRevision2(argument, fallback) {
|
|
10407
|
+
const value = typeof argument === "string" ? argument : argument?.expectedRevision;
|
|
10408
|
+
return value ?? fallback;
|
|
10409
|
+
}
|
|
10410
|
+
function incrementDecimal(value) {
|
|
10411
|
+
if (compareUint64(value, "18446744073709551615") >= 0) {
|
|
10412
|
+
throw new RangeError("vocal Worker intent sequence exhausted uint64");
|
|
10413
|
+
}
|
|
10414
|
+
const digits = value.split("").map((digit) => digit.charCodeAt(0) - 48);
|
|
10415
|
+
let carry = 1;
|
|
10416
|
+
for (let i = digits.length - 1; i >= 0; i--) {
|
|
10417
|
+
const next = digits[i] + carry;
|
|
10418
|
+
digits[i] = next % 10;
|
|
10419
|
+
carry = Math.floor(next / 10);
|
|
10420
|
+
}
|
|
10421
|
+
if (carry !== 0) {
|
|
10422
|
+
digits.unshift(carry);
|
|
10423
|
+
}
|
|
10424
|
+
return digits.join("");
|
|
10425
|
+
}
|
|
10426
|
+
function cancellationFlag() {
|
|
10427
|
+
if (typeof SharedArrayBuffer === "undefined") {
|
|
10428
|
+
return void 0;
|
|
10429
|
+
}
|
|
10430
|
+
return new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
|
|
10431
|
+
}
|
|
10432
|
+
function cloneForWorker(value, copy, transfers, transferred = /* @__PURE__ */ new Set()) {
|
|
10433
|
+
if (value instanceof Float32Array) {
|
|
10434
|
+
const next = copy ? value.slice() : value;
|
|
10435
|
+
if (next.buffer instanceof ArrayBuffer && !transferred.has(next.buffer)) {
|
|
10436
|
+
transferred.add(next.buffer);
|
|
10437
|
+
transfers.push(next.buffer);
|
|
10438
|
+
}
|
|
10439
|
+
return next;
|
|
10440
|
+
}
|
|
10441
|
+
if (value instanceof Uint8Array) {
|
|
10442
|
+
const next = copy ? value.slice() : value;
|
|
10443
|
+
if (next.buffer instanceof ArrayBuffer && !transferred.has(next.buffer)) {
|
|
10444
|
+
transferred.add(next.buffer);
|
|
10445
|
+
transfers.push(next.buffer);
|
|
10446
|
+
}
|
|
10447
|
+
return next;
|
|
10448
|
+
}
|
|
10449
|
+
if (Array.isArray(value)) {
|
|
10450
|
+
return value.map((item) => cloneForWorker(item, copy, transfers, transferred));
|
|
10451
|
+
}
|
|
10452
|
+
if (value !== null && typeof value === "object") {
|
|
10453
|
+
return Object.fromEntries(
|
|
10454
|
+
Object.entries(value).map(([key, item]) => [
|
|
10455
|
+
key,
|
|
10456
|
+
cloneForWorker(item, copy, transfers, transferred)
|
|
10457
|
+
])
|
|
10458
|
+
);
|
|
10459
|
+
}
|
|
10460
|
+
return value;
|
|
10461
|
+
}
|
|
10462
|
+
function cloneRequest(request, copy, transfers) {
|
|
10463
|
+
return cloneForWorker(request, copy, transfers);
|
|
10464
|
+
}
|
|
10465
|
+
function workerError(message) {
|
|
10466
|
+
if (message.error.name === "StaleResultError") {
|
|
10467
|
+
return new VocalEditWorkerStaleResultError(message.error.message);
|
|
10468
|
+
}
|
|
10469
|
+
const { code, codeName } = message.error;
|
|
10470
|
+
const error = message.error.name === "SonareError" && typeof code === "number" ? new SonareError(code, codeName ?? "", message.error.message) : new Error(message.error.message);
|
|
10471
|
+
error.name = message.error.name;
|
|
10472
|
+
for (const key of [
|
|
10473
|
+
"code",
|
|
10474
|
+
"reason",
|
|
10475
|
+
"field",
|
|
10476
|
+
"expected",
|
|
10477
|
+
"actual",
|
|
10478
|
+
"expectedText",
|
|
10479
|
+
"actualText"
|
|
10480
|
+
]) {
|
|
10481
|
+
const value = message.error[key];
|
|
10482
|
+
if (value !== void 0) {
|
|
10483
|
+
Object.defineProperty(error, key, { value, enumerable: true, configurable: true });
|
|
10484
|
+
}
|
|
10485
|
+
}
|
|
10486
|
+
return error;
|
|
10487
|
+
}
|
|
10488
|
+
function sameSessionToken(a, b) {
|
|
10489
|
+
return a.sessionEpoch === b.sessionEpoch && a.profileId === b.profileId;
|
|
10490
|
+
}
|
|
10491
|
+
function nextSessionId(counter) {
|
|
10492
|
+
return `vocal-${counter.toString(36)}`;
|
|
10493
|
+
}
|
|
10494
|
+
function abortError() {
|
|
10495
|
+
return new DOMException("The operation was aborted", "AbortError");
|
|
10496
|
+
}
|
|
10497
|
+
var VocalEditWorkerClient = class {
|
|
10498
|
+
constructor(options = {}) {
|
|
10499
|
+
this.pending = /* @__PURE__ */ new Map();
|
|
10500
|
+
this.latestIntent = /* @__PURE__ */ new Map();
|
|
10501
|
+
this.sessions = /* @__PURE__ */ new Set();
|
|
10502
|
+
this.nextId = 1;
|
|
10503
|
+
this.nextSession = 1;
|
|
10504
|
+
this.closed = false;
|
|
10505
|
+
this.usesEventTarget = false;
|
|
10506
|
+
this.onMessage = (event) => {
|
|
10507
|
+
const message = event.data;
|
|
10508
|
+
if (message.type === "sonare:vocal-progress") {
|
|
10509
|
+
return;
|
|
10510
|
+
}
|
|
10511
|
+
const pending = this.pending.get(message.id);
|
|
10512
|
+
if (!pending) {
|
|
10513
|
+
return;
|
|
10514
|
+
}
|
|
10515
|
+
this.pending.delete(message.id);
|
|
10516
|
+
if (pending.abortListener && pending.signal) {
|
|
10517
|
+
pending.signal.removeEventListener("abort", pending.abortListener);
|
|
10518
|
+
}
|
|
10519
|
+
if (!pending.preview && pending.session && message.token && pending.baseToken && sameSessionToken(message.token, pending.baseToken)) {
|
|
10520
|
+
pending.session.updateToken(message.token);
|
|
10521
|
+
}
|
|
10522
|
+
const latest = this.latestIntent.get(pending.sessionId) ?? pending.intent;
|
|
10523
|
+
if (compareUint64(pending.intent, latest) < 0) {
|
|
10524
|
+
pending.reject(new VocalEditWorkerStaleResultError());
|
|
10525
|
+
return;
|
|
10526
|
+
}
|
|
10527
|
+
if (message.token && pending.baseToken) {
|
|
10528
|
+
const tokenMatches = pending.preview && pending.session ? stateTokenEquals(message.token, pending.session.latestToken()) : sameSessionToken(message.token, pending.baseToken);
|
|
10529
|
+
if (!tokenMatches) {
|
|
10530
|
+
pending.reject(new VocalEditWorkerStaleResultError());
|
|
10531
|
+
return;
|
|
10532
|
+
}
|
|
10533
|
+
}
|
|
10534
|
+
if (pending.preview && !message.token) {
|
|
10535
|
+
pending.reject(new VocalEditWorkerStaleResultError());
|
|
10536
|
+
return;
|
|
10537
|
+
}
|
|
10538
|
+
if (message.type === "sonare:vocal-error") {
|
|
10539
|
+
pending.reject(workerError(message));
|
|
10540
|
+
return;
|
|
10541
|
+
}
|
|
10542
|
+
pending.resolve({ result: message.result, token: message.token });
|
|
10543
|
+
};
|
|
10544
|
+
this.onError = (event) => {
|
|
10545
|
+
const error = new Error(event.message || "Vocal edit Worker failed");
|
|
10546
|
+
for (const pending of this.pending.values()) {
|
|
10547
|
+
pending.abortListener && pending.signal?.removeEventListener("abort", pending.abortListener);
|
|
10548
|
+
pending.reject(error);
|
|
10549
|
+
}
|
|
10550
|
+
this.pending.clear();
|
|
10551
|
+
};
|
|
10552
|
+
this.onNodeMessage = (data) => {
|
|
10553
|
+
this.onMessage({ data });
|
|
10554
|
+
};
|
|
10555
|
+
this.onNodeError = (error) => {
|
|
10556
|
+
this.onError({ message: error instanceof Error ? error.message : String(error) });
|
|
10557
|
+
};
|
|
10558
|
+
this.ownsWorker = options.worker === void 0 || options.terminateWorkerOnDispose === true;
|
|
10559
|
+
if (options.worker) {
|
|
10560
|
+
this.worker = options.worker;
|
|
10561
|
+
} else {
|
|
10562
|
+
if (!options.workerFactory && typeof Worker === "undefined") {
|
|
10563
|
+
throw new Error("VocalEditWorkerClient requires a Worker implementation");
|
|
10564
|
+
}
|
|
10565
|
+
const url = options.workerUrl === void 0 ? new URL("./vocal_edit_worker.js", import.meta.url) : new URL(options.workerUrl, import.meta.url);
|
|
10566
|
+
this.worker = options.workerFactory?.(url) ?? new Worker(url, { type: "module", name: "sonare-vocal-edit" });
|
|
10567
|
+
}
|
|
10568
|
+
if (this.worker.addEventListener) {
|
|
10569
|
+
this.usesEventTarget = true;
|
|
10570
|
+
this.worker.addEventListener("message", this.onMessage);
|
|
10571
|
+
this.worker.addEventListener("error", this.onError);
|
|
10572
|
+
} else if (this.worker.on) {
|
|
10573
|
+
this.worker.on("message", this.onNodeMessage);
|
|
10574
|
+
this.worker.on("error", this.onNodeError);
|
|
10575
|
+
} else {
|
|
10576
|
+
throw new TypeError("VocalEditWorkerClient requires Worker event listeners");
|
|
10577
|
+
}
|
|
10578
|
+
}
|
|
10579
|
+
create(request, options = {}) {
|
|
10580
|
+
return this.openSession({ kind: "create", request }, options);
|
|
10581
|
+
}
|
|
10582
|
+
restore(request, options = {}) {
|
|
10583
|
+
return this.openSession({ kind: "restore", request }, options);
|
|
10584
|
+
}
|
|
10585
|
+
postDisposeMessage(sessionId, clientIntentSequence) {
|
|
10586
|
+
try {
|
|
10587
|
+
this.worker.postMessage({
|
|
10588
|
+
type: "sonare:vocal-dispose",
|
|
10589
|
+
id: this.nextId++,
|
|
10590
|
+
sessionId,
|
|
10591
|
+
clientIntentSequence
|
|
10592
|
+
});
|
|
10593
|
+
} catch {
|
|
10594
|
+
}
|
|
10595
|
+
}
|
|
10596
|
+
postCancelMessage(id, pending) {
|
|
10597
|
+
if (pending.cancelFlag) {
|
|
10598
|
+
Atomics.store(pending.cancelFlag, 0, 1);
|
|
10599
|
+
}
|
|
10600
|
+
try {
|
|
10601
|
+
this.worker.postMessage({
|
|
10602
|
+
type: "sonare:vocal-cancel",
|
|
10603
|
+
id,
|
|
10604
|
+
sessionId: pending.sessionId,
|
|
10605
|
+
clientIntentSequence: pending.intent
|
|
10606
|
+
});
|
|
10607
|
+
} catch {
|
|
10608
|
+
}
|
|
10609
|
+
}
|
|
10610
|
+
dispose() {
|
|
10611
|
+
if (this.closed) {
|
|
10612
|
+
return;
|
|
10613
|
+
}
|
|
10614
|
+
const pendingEntries = [...this.pending.entries()];
|
|
10615
|
+
const sessionIntents = /* @__PURE__ */ new Map();
|
|
10616
|
+
for (const session of this.sessions) {
|
|
10617
|
+
sessionIntents.set(session.sessionId, this.latestIntent.get(session.sessionId) ?? "0");
|
|
10618
|
+
}
|
|
10619
|
+
for (const [, pending] of pendingEntries) {
|
|
10620
|
+
if (!sessionIntents.has(pending.sessionId)) {
|
|
10621
|
+
sessionIntents.set(pending.sessionId, pending.intent);
|
|
10622
|
+
}
|
|
10623
|
+
}
|
|
10624
|
+
this.closed = true;
|
|
10625
|
+
for (const [id, pending] of pendingEntries) {
|
|
10626
|
+
this.postCancelMessage(id, pending);
|
|
10627
|
+
}
|
|
10628
|
+
for (const [sessionId, intent] of sessionIntents) {
|
|
10629
|
+
this.postDisposeMessage(sessionId, intent);
|
|
10630
|
+
}
|
|
10631
|
+
if (this.usesEventTarget) {
|
|
10632
|
+
this.worker.removeEventListener?.("message", this.onMessage);
|
|
10633
|
+
this.worker.removeEventListener?.("error", this.onError);
|
|
10634
|
+
} else {
|
|
10635
|
+
this.worker.off?.("message", this.onNodeMessage);
|
|
10636
|
+
this.worker.off?.("error", this.onNodeError);
|
|
10637
|
+
}
|
|
10638
|
+
for (const [, pending] of pendingEntries) {
|
|
10639
|
+
pending.abortListener && pending.signal?.removeEventListener("abort", pending.abortListener);
|
|
10640
|
+
pending.reject(new Error("VocalEditWorkerClient was disposed"));
|
|
10641
|
+
}
|
|
10642
|
+
this.pending.clear();
|
|
10643
|
+
this.sessions.clear();
|
|
10644
|
+
this.latestIntent.clear();
|
|
10645
|
+
if (this.ownsWorker) {
|
|
10646
|
+
this.worker.terminate();
|
|
10647
|
+
}
|
|
10648
|
+
}
|
|
10649
|
+
/** @internal Called by VocalEditWorkerSession. */
|
|
10650
|
+
disposeSession(session) {
|
|
10651
|
+
const task = this.call({
|
|
10652
|
+
type: "sonare:vocal-dispose",
|
|
10653
|
+
id: 0,
|
|
10654
|
+
sessionId: session.sessionId,
|
|
10655
|
+
clientIntentSequence: this.intent(session.sessionId)
|
|
10656
|
+
});
|
|
10657
|
+
const result = task.result.then(() => {
|
|
10658
|
+
this.sessions.delete(session);
|
|
10659
|
+
this.latestIntent.delete(session.sessionId);
|
|
10660
|
+
return null;
|
|
10661
|
+
});
|
|
10662
|
+
return new VocalEditWorkerTask(result, () => task.cancel());
|
|
10663
|
+
}
|
|
10664
|
+
/** @internal */
|
|
10665
|
+
callMutation(session, mutation, options = {}) {
|
|
10666
|
+
const message = {
|
|
10667
|
+
type: "sonare:vocal-mutate",
|
|
10668
|
+
id: 0,
|
|
10669
|
+
sessionId: session.sessionId,
|
|
10670
|
+
clientIntentSequence: this.intent(session.sessionId),
|
|
10671
|
+
baseToken: session.currentToken(),
|
|
10672
|
+
mutation
|
|
10673
|
+
};
|
|
10674
|
+
const task = this.call(message, { copy: options.copy }, session);
|
|
10675
|
+
const result = task.result.then((response) => response.result);
|
|
10676
|
+
return new VocalEditWorkerTask(result, () => {
|
|
10677
|
+
});
|
|
10678
|
+
}
|
|
10679
|
+
/** @internal */
|
|
10680
|
+
callPreview(session, request, options = {}) {
|
|
10681
|
+
const signal = request.signal;
|
|
10682
|
+
const { signal: _ignoredSignal, ...portableRequest } = request;
|
|
10683
|
+
const message = {
|
|
10684
|
+
type: "sonare:vocal-preview",
|
|
10685
|
+
id: 0,
|
|
10686
|
+
sessionId: session.sessionId,
|
|
10687
|
+
clientIntentSequence: this.intent(session.sessionId),
|
|
10688
|
+
baseToken: session.currentToken(),
|
|
10689
|
+
request: portableRequest
|
|
10690
|
+
};
|
|
10691
|
+
const task = this.call(message, { signal, copy: options.copy }, session);
|
|
10692
|
+
const result = task.result.then((response) => response.result);
|
|
10693
|
+
return new VocalEditWorkerTask(result, () => task.cancel());
|
|
10694
|
+
}
|
|
10695
|
+
intent(sessionId) {
|
|
10696
|
+
const next = incrementDecimal(this.latestIntent.get(sessionId) ?? "0");
|
|
10697
|
+
this.latestIntent.set(sessionId, next);
|
|
10698
|
+
return next;
|
|
10699
|
+
}
|
|
10700
|
+
openSession(request, options) {
|
|
10701
|
+
const sessionId = nextSessionId(this.nextSession++);
|
|
10702
|
+
let cancelled = false;
|
|
10703
|
+
const task = this.callCreate(sessionId, request, options);
|
|
10704
|
+
const result = task.result.then((value) => {
|
|
10705
|
+
const session = new VocalEditWorkerSession(this, sessionId, value.token, value);
|
|
10706
|
+
if (cancelled || options.signal?.aborted) {
|
|
10707
|
+
if (!this.closed) {
|
|
10708
|
+
session.dispose().result.catch(() => {
|
|
10709
|
+
});
|
|
10710
|
+
}
|
|
10711
|
+
throw abortError();
|
|
10712
|
+
}
|
|
10713
|
+
this.sessions.add(session);
|
|
10714
|
+
return session;
|
|
10715
|
+
});
|
|
10716
|
+
return new VocalEditWorkerTask(result, () => {
|
|
10717
|
+
cancelled = true;
|
|
10718
|
+
task.cancel();
|
|
10719
|
+
});
|
|
10720
|
+
}
|
|
10721
|
+
callCreate(sessionId, request, options) {
|
|
10722
|
+
const message = {
|
|
10723
|
+
type: "sonare:vocal-create",
|
|
10724
|
+
id: 0,
|
|
10725
|
+
sessionId,
|
|
10726
|
+
clientIntentSequence: this.intent(sessionId),
|
|
10727
|
+
request
|
|
10728
|
+
};
|
|
10729
|
+
const task = this.call(message, options);
|
|
10730
|
+
const result = task.result.then((response) => response.result);
|
|
10731
|
+
return new VocalEditWorkerTask(result, () => task.cancel());
|
|
10732
|
+
}
|
|
10733
|
+
call(input, options = {}, session) {
|
|
10734
|
+
if (this.closed) {
|
|
10735
|
+
throw new Error("VocalEditWorkerClient was disposed");
|
|
10736
|
+
}
|
|
10737
|
+
const id = this.nextId++;
|
|
10738
|
+
const transfers = [];
|
|
10739
|
+
const message = cloneRequest(
|
|
10740
|
+
{ ...input, id },
|
|
10741
|
+
options.copy === true,
|
|
10742
|
+
transfers
|
|
10743
|
+
);
|
|
10744
|
+
const cancelFlag = cancellationFlag();
|
|
10745
|
+
if (cancelFlag) {
|
|
10746
|
+
message.cancelBuffer = cancelFlag.buffer;
|
|
10747
|
+
}
|
|
10748
|
+
const result = new Promise((resolve, reject) => {
|
|
10749
|
+
if (options.signal?.aborted) {
|
|
10750
|
+
reject(abortError());
|
|
10751
|
+
return;
|
|
10752
|
+
}
|
|
10753
|
+
const pending = {
|
|
10754
|
+
resolve: (value) => resolve(value),
|
|
10755
|
+
reject,
|
|
10756
|
+
sessionId: message.sessionId,
|
|
10757
|
+
intent: message.clientIntentSequence,
|
|
10758
|
+
baseToken: message.type === "sonare:vocal-mutate" || message.type === "sonare:vocal-preview" ? message.baseToken : void 0,
|
|
10759
|
+
preview: message.type === "sonare:vocal-preview",
|
|
10760
|
+
session,
|
|
10761
|
+
cancelFlag,
|
|
10762
|
+
signal: options.signal
|
|
10763
|
+
};
|
|
10764
|
+
if (options.signal) {
|
|
10765
|
+
pending.abortListener = () => {
|
|
10766
|
+
if (cancelFlag) {
|
|
10767
|
+
Atomics.store(cancelFlag, 0, 1);
|
|
10768
|
+
}
|
|
10769
|
+
this.worker.postMessage({
|
|
10770
|
+
type: "sonare:vocal-cancel",
|
|
10771
|
+
id,
|
|
10772
|
+
sessionId: message.sessionId,
|
|
10773
|
+
clientIntentSequence: message.clientIntentSequence
|
|
10774
|
+
});
|
|
10775
|
+
};
|
|
10776
|
+
options.signal.addEventListener("abort", pending.abortListener, { once: true });
|
|
10777
|
+
}
|
|
10778
|
+
this.pending.set(id, pending);
|
|
10779
|
+
});
|
|
10780
|
+
if (!options.signal?.aborted) {
|
|
10781
|
+
try {
|
|
10782
|
+
this.worker.postMessage(message, transfers);
|
|
10783
|
+
} catch (error) {
|
|
10784
|
+
const pending = this.pending.get(id);
|
|
10785
|
+
if (pending) {
|
|
10786
|
+
this.pending.delete(id);
|
|
10787
|
+
if (pending.abortListener && pending.signal) {
|
|
10788
|
+
pending.signal.removeEventListener("abort", pending.abortListener);
|
|
10789
|
+
}
|
|
10790
|
+
pending.reject(error);
|
|
10791
|
+
}
|
|
10792
|
+
}
|
|
10793
|
+
}
|
|
10794
|
+
return new VocalEditWorkerTask(result, () => {
|
|
10795
|
+
const pending = this.pending.get(id);
|
|
10796
|
+
if (!pending) {
|
|
10797
|
+
return;
|
|
10798
|
+
}
|
|
10799
|
+
if (pending.cancelFlag) {
|
|
10800
|
+
Atomics.store(pending.cancelFlag, 0, 1);
|
|
10801
|
+
}
|
|
10802
|
+
this.worker.postMessage({
|
|
10803
|
+
type: "sonare:vocal-cancel",
|
|
10804
|
+
id,
|
|
10805
|
+
sessionId: pending.sessionId,
|
|
10806
|
+
clientIntentSequence: pending.intent
|
|
10807
|
+
});
|
|
10808
|
+
});
|
|
10809
|
+
}
|
|
10810
|
+
};
|
|
10811
|
+
var VocalEditWorkerSession = class {
|
|
10812
|
+
/** @internal Created by VocalEditWorkerClient.create/restore. */
|
|
10813
|
+
constructor(client, sessionId, token, created) {
|
|
10814
|
+
this.disposed = false;
|
|
10815
|
+
this.client = client;
|
|
10816
|
+
this.sessionId = sessionId;
|
|
10817
|
+
this.tokenValue = token;
|
|
10818
|
+
this.created = created;
|
|
10819
|
+
}
|
|
10820
|
+
currentToken() {
|
|
10821
|
+
this.requireAlive();
|
|
10822
|
+
return this.tokenValue;
|
|
10823
|
+
}
|
|
10824
|
+
updateToken(token) {
|
|
10825
|
+
this.tokenValue = token;
|
|
10826
|
+
}
|
|
10827
|
+
/** @internal The adopted token, readable after dispose for reply checks. */
|
|
10828
|
+
latestToken() {
|
|
10829
|
+
return this.tokenValue;
|
|
10830
|
+
}
|
|
10831
|
+
token() {
|
|
10832
|
+
this.requireAlive();
|
|
10833
|
+
return { ...this.tokenValue };
|
|
10834
|
+
}
|
|
10835
|
+
/** The adopted revision; like {@link token}, it follows replies already received. */
|
|
10836
|
+
revision() {
|
|
10837
|
+
return this.token().revision;
|
|
10838
|
+
}
|
|
10839
|
+
notes() {
|
|
10840
|
+
this.requireAlive();
|
|
10841
|
+
return this.client.callMutation(this, { kind: "notes" });
|
|
10842
|
+
}
|
|
10843
|
+
analysis() {
|
|
10844
|
+
this.requireAlive();
|
|
10845
|
+
return this.client.callMutation(this, { kind: "analysis" });
|
|
10846
|
+
}
|
|
10847
|
+
capabilities() {
|
|
10848
|
+
this.requireAlive();
|
|
10849
|
+
return this.client.callMutation(this, { kind: "capabilities" });
|
|
10850
|
+
}
|
|
10851
|
+
outputLengthSamples() {
|
|
10852
|
+
this.requireAlive();
|
|
10853
|
+
return this.client.callMutation(this, { kind: "outputLength" });
|
|
10854
|
+
}
|
|
10855
|
+
history() {
|
|
10856
|
+
this.requireAlive();
|
|
10857
|
+
return this.client.callMutation(this, { kind: "history" });
|
|
10858
|
+
}
|
|
10859
|
+
/** Token of the open draft; rejects when no draft is open. */
|
|
10860
|
+
draftToken() {
|
|
10861
|
+
this.requireAlive();
|
|
10862
|
+
return this.client.callMutation(this, { kind: "draftToken" });
|
|
10863
|
+
}
|
|
10864
|
+
evaluatePitch(noteId, options = {}) {
|
|
10865
|
+
this.requireAlive();
|
|
10866
|
+
return this.client.callMutation(this, {
|
|
10867
|
+
kind: "evaluatePitch",
|
|
10868
|
+
noteId,
|
|
10869
|
+
draft: options.draft === true
|
|
10870
|
+
});
|
|
10871
|
+
}
|
|
10872
|
+
sourceSampleToDestinationSample(noteId, sourceSample, options = {}) {
|
|
10873
|
+
this.requireAlive();
|
|
10874
|
+
return this.client.callMutation(this, {
|
|
10875
|
+
kind: "mapCoordinate",
|
|
10876
|
+
noteId,
|
|
10877
|
+
sample: sourceSample,
|
|
10878
|
+
inverse: false,
|
|
10879
|
+
draft: options.draft === true
|
|
10880
|
+
});
|
|
10881
|
+
}
|
|
10882
|
+
destinationSampleToSourceSample(noteId, destinationSample, options = {}) {
|
|
10883
|
+
this.requireAlive();
|
|
10884
|
+
return this.client.callMutation(this, {
|
|
10885
|
+
kind: "mapCoordinate",
|
|
10886
|
+
noteId,
|
|
10887
|
+
sample: destinationSample,
|
|
10888
|
+
inverse: true,
|
|
10889
|
+
draft: options.draft === true
|
|
10890
|
+
});
|
|
10891
|
+
}
|
|
10892
|
+
beginEdit(options = {}) {
|
|
10893
|
+
this.requireAlive();
|
|
10894
|
+
return this.client.callMutation(this, {
|
|
10895
|
+
kind: "beginEdit",
|
|
10896
|
+
expectedRevision: resolveRevision2(options, this.tokenValue.revision)
|
|
10897
|
+
});
|
|
10898
|
+
}
|
|
10899
|
+
apply(request, options = {}) {
|
|
10900
|
+
this.requireAlive();
|
|
10901
|
+
if (request.expectedGeneration === void 0) {
|
|
10902
|
+
throw new TypeError("expectedGeneration is required");
|
|
10903
|
+
}
|
|
10904
|
+
return this.client.callMutation(this, { kind: "apply", request }, options);
|
|
10905
|
+
}
|
|
10906
|
+
commit(options = {}) {
|
|
10907
|
+
this.requireAlive();
|
|
10908
|
+
return this.client.callMutation(this, {
|
|
10909
|
+
kind: "commit",
|
|
10910
|
+
expectedRevision: resolveRevision2(options, this.tokenValue.revision)
|
|
10911
|
+
});
|
|
10912
|
+
}
|
|
10913
|
+
cancel() {
|
|
10914
|
+
this.requireAlive();
|
|
10915
|
+
return this.client.callMutation(this, { kind: "cancel" });
|
|
10916
|
+
}
|
|
10917
|
+
undo(options = {}) {
|
|
10918
|
+
this.requireAlive();
|
|
10919
|
+
return this.client.callMutation(this, {
|
|
10920
|
+
kind: "undo",
|
|
10921
|
+
expectedRevision: resolveRevision2(options, this.tokenValue.revision)
|
|
10922
|
+
});
|
|
10923
|
+
}
|
|
10924
|
+
redo(options = {}) {
|
|
10925
|
+
this.requireAlive();
|
|
10926
|
+
return this.client.callMutation(this, {
|
|
10927
|
+
kind: "redo",
|
|
10928
|
+
expectedRevision: resolveRevision2(options, this.tokenValue.revision)
|
|
10929
|
+
});
|
|
10930
|
+
}
|
|
10931
|
+
exportState() {
|
|
10932
|
+
this.requireAlive();
|
|
10933
|
+
return this.client.callMutation(this, { kind: "exportState" });
|
|
10934
|
+
}
|
|
10935
|
+
preview(request, options = {}) {
|
|
10936
|
+
this.requireAlive();
|
|
10937
|
+
return this.client.callPreview(this, request, options);
|
|
10938
|
+
}
|
|
10939
|
+
/** Releases the Worker session and any open draft; later calls on it are rejected. */
|
|
10940
|
+
dispose() {
|
|
10941
|
+
if (this.disposed) {
|
|
10942
|
+
return new VocalEditWorkerTask(Promise.resolve(null), () => {
|
|
10943
|
+
});
|
|
10944
|
+
}
|
|
10945
|
+
this.disposed = true;
|
|
10946
|
+
return this.client.disposeSession(this);
|
|
10947
|
+
}
|
|
10948
|
+
requireAlive() {
|
|
10949
|
+
if (this.disposed) {
|
|
10950
|
+
throw new TypeError("vocal Worker session has already been disposed");
|
|
10951
|
+
}
|
|
10952
|
+
}
|
|
10953
|
+
};
|
|
10954
|
+
|
|
10955
|
+
// src/web_midi.ts
|
|
10956
|
+
function isWebMidiAvailable() {
|
|
10957
|
+
return typeof globalThis.navigator?.requestMIDIAccess === "function";
|
|
10958
|
+
}
|
|
10959
|
+
async function bindWebMidi(engine, options = {}) {
|
|
10960
|
+
const navigatorWithMidi = globalThis.navigator;
|
|
10961
|
+
if (typeof navigatorWithMidi?.requestMIDIAccess !== "function") {
|
|
10962
|
+
throw new Error("Web MIDI is not available in this environment");
|
|
10963
|
+
}
|
|
10964
|
+
const group = options.group ?? 0;
|
|
10965
|
+
assertNibble("bindWebMidi", group, "group");
|
|
10966
|
+
const destinationId = options.destinationId ?? 0;
|
|
10967
|
+
const selectedIds = new Set(options.inputIds ?? []);
|
|
10968
|
+
const access = await navigatorWithMidi.requestMIDIAccess({
|
|
10969
|
+
sysex: options.sysex ?? false,
|
|
10970
|
+
software: options.software ?? true
|
|
10971
|
+
});
|
|
10972
|
+
for (const binding of options.ccBindings ?? []) {
|
|
10973
|
+
engine.bindMidiCc(binding.channel, binding.controller, binding.paramId, binding.options);
|
|
10974
|
+
}
|
|
10975
|
+
engine.setMidiInputSource(destinationId);
|
|
10976
|
+
const bound = /* @__PURE__ */ new Map();
|
|
9123
10977
|
let closed = false;
|
|
9124
10978
|
const shouldBind = (input) => input.state !== "disconnected" && (selectedIds.size === 0 || selectedIds.has(input.id));
|
|
9125
10979
|
const snapshotInputs = () => Array.from(iterInputs(access), ([id, input]) => ({
|
|
@@ -9222,8 +11076,8 @@ function dispatchMidiMessage(engine, event, group, runningStatus, timestampToSam
|
|
|
9222
11076
|
return 0;
|
|
9223
11077
|
}
|
|
9224
11078
|
const first = data[0];
|
|
9225
|
-
if (first > 255) {
|
|
9226
|
-
|
|
11079
|
+
if (first > 255 || data instanceof Uint32Array) {
|
|
11080
|
+
dispatchUmpMessages(
|
|
9227
11081
|
engine,
|
|
9228
11082
|
data,
|
|
9229
11083
|
timestampToSamples?.(event.receivedTime ?? event.timeStamp ?? 0) ?? 0
|
|
@@ -9246,8 +11100,12 @@ function dispatchMidiMessage(engine, event, group, runningStatus, timestampToSam
|
|
|
9246
11100
|
return status >= 248 ? runningStatus : 0;
|
|
9247
11101
|
}
|
|
9248
11102
|
const a = readU7(data, offset);
|
|
9249
|
-
|
|
9250
|
-
|
|
11103
|
+
if (a < 0) {
|
|
11104
|
+
return status;
|
|
11105
|
+
}
|
|
11106
|
+
const oneDataByteMessage = message === 192 || message === 208;
|
|
11107
|
+
const b = oneDataByteMessage ? -1 : readU7(data, offset + 1);
|
|
11108
|
+
if (!oneDataByteMessage && b < 0) {
|
|
9251
11109
|
return status;
|
|
9252
11110
|
}
|
|
9253
11111
|
const portTimeSamples = timestampToSamples ? timestampToSamples(event.receivedTime ?? event.timeStamp ?? 0) : 0;
|
|
@@ -9261,13 +11119,42 @@ function dispatchMidiMessage(engine, event, group, runningStatus, timestampToSam
|
|
|
9261
11119
|
}
|
|
9262
11120
|
} else if (message === 176 && b >= 0) {
|
|
9263
11121
|
engine.pushMidiInputCc(group, channel, a, b, portTimeSamples);
|
|
11122
|
+
} else if (message === 160 && b >= 0) {
|
|
11123
|
+
engine.pushMidiInputPolyPressure?.(group, channel, a, b, portTimeSamples);
|
|
11124
|
+
} else if (message === 208) {
|
|
11125
|
+
engine.pushMidiInputChannelPressure?.(group, channel, a, portTimeSamples);
|
|
11126
|
+
} else if (message === 224 && b >= 0) {
|
|
11127
|
+
engine.pushMidiInputPitchBend?.(group, channel, a | b << 7, portTimeSamples);
|
|
9264
11128
|
}
|
|
9265
11129
|
return status;
|
|
9266
11130
|
}
|
|
11131
|
+
function dispatchUmpMessages(engine, words, portTimeSamples) {
|
|
11132
|
+
let offset = 0;
|
|
11133
|
+
while (offset < words.length) {
|
|
11134
|
+
const word0 = words[offset] >>> 0;
|
|
11135
|
+
const wordCount = umpWordCount(word0 >>> 28);
|
|
11136
|
+
if (words.length - offset < wordCount) {
|
|
11137
|
+
return;
|
|
11138
|
+
}
|
|
11139
|
+
const packet = new Uint32Array(wordCount);
|
|
11140
|
+
for (let index = 0; index < wordCount; index++) {
|
|
11141
|
+
packet[index] = words[offset + index] >>> 0;
|
|
11142
|
+
}
|
|
11143
|
+
dispatchUmpMessage(engine, packet, portTimeSamples);
|
|
11144
|
+
offset += wordCount;
|
|
11145
|
+
}
|
|
11146
|
+
}
|
|
9267
11147
|
function dispatchUmpMessage(engine, words, portTimeSamples) {
|
|
9268
11148
|
const word0 = words[0] >>> 0;
|
|
9269
11149
|
const messageType = word0 >>> 28;
|
|
9270
11150
|
const group = word0 >>> 24 & 15;
|
|
11151
|
+
if (messageType === 3 || messageType === 5) {
|
|
11152
|
+
return;
|
|
11153
|
+
}
|
|
11154
|
+
if (engine.pushMidiInputUmp) {
|
|
11155
|
+
engine.pushMidiInputUmp(words, portTimeSamples);
|
|
11156
|
+
return;
|
|
11157
|
+
}
|
|
9271
11158
|
if (messageType === 2) {
|
|
9272
11159
|
const status = word0 >>> 16 & 255;
|
|
9273
11160
|
const message = status & 240;
|
|
@@ -9284,6 +11171,12 @@ function dispatchUmpMessage(engine, words, portTimeSamples) {
|
|
|
9284
11171
|
}
|
|
9285
11172
|
} else if (message === 176) {
|
|
9286
11173
|
engine.pushMidiInputCc(group, channel, a, b, portTimeSamples);
|
|
11174
|
+
} else if (message === 160) {
|
|
11175
|
+
engine.pushMidiInputPolyPressure?.(group, channel, a, b, portTimeSamples);
|
|
11176
|
+
} else if (message === 208) {
|
|
11177
|
+
engine.pushMidiInputChannelPressure?.(group, channel, a, portTimeSamples);
|
|
11178
|
+
} else if (message === 224) {
|
|
11179
|
+
engine.pushMidiInputPitchBend?.(group, channel, a | b << 7, portTimeSamples);
|
|
9287
11180
|
}
|
|
9288
11181
|
return;
|
|
9289
11182
|
}
|
|
@@ -9299,7 +11192,40 @@ function dispatchUmpMessage(engine, words, portTimeSamples) {
|
|
|
9299
11192
|
engine.pushMidiInputNoteOn(group, channel, data1, velocity, portTimeSamples);
|
|
9300
11193
|
} else if (status === 11) {
|
|
9301
11194
|
engine.pushMidiInputCc(group, channel, data1, word1 >>> 25 & 127, portTimeSamples);
|
|
9302
|
-
}
|
|
11195
|
+
} else if (status === 10) {
|
|
11196
|
+
engine.pushMidiInputPolyPressure?.(
|
|
11197
|
+
group,
|
|
11198
|
+
channel,
|
|
11199
|
+
data1,
|
|
11200
|
+
word1 >>> 25 & 127,
|
|
11201
|
+
portTimeSamples
|
|
11202
|
+
);
|
|
11203
|
+
} else if (status === 13) {
|
|
11204
|
+
engine.pushMidiInputChannelPressure?.(group, channel, word1 >>> 25 & 127, portTimeSamples);
|
|
11205
|
+
} else if (status === 14) {
|
|
11206
|
+
engine.pushMidiInputPitchBend?.(group, channel, word1 >>> 18, portTimeSamples);
|
|
11207
|
+
}
|
|
11208
|
+
}
|
|
11209
|
+
}
|
|
11210
|
+
function umpWordCount(messageType) {
|
|
11211
|
+
switch (messageType & 15) {
|
|
11212
|
+
case 0:
|
|
11213
|
+
case 1:
|
|
11214
|
+
case 2:
|
|
11215
|
+
case 6:
|
|
11216
|
+
case 7:
|
|
11217
|
+
return 1;
|
|
11218
|
+
case 3:
|
|
11219
|
+
case 4:
|
|
11220
|
+
case 8:
|
|
11221
|
+
case 9:
|
|
11222
|
+
case 10:
|
|
11223
|
+
return 2;
|
|
11224
|
+
case 11:
|
|
11225
|
+
case 12:
|
|
11226
|
+
return 3;
|
|
11227
|
+
default:
|
|
11228
|
+
return 4;
|
|
9303
11229
|
}
|
|
9304
11230
|
}
|
|
9305
11231
|
function readU7(data, index) {
|
|
@@ -9336,7 +11262,7 @@ var OfflineWorkerTask = class {
|
|
|
9336
11262
|
return this.result.finally(onfinally);
|
|
9337
11263
|
}
|
|
9338
11264
|
};
|
|
9339
|
-
function
|
|
11265
|
+
function cloneForWorker2(value, copy, transfers, transferred = /* @__PURE__ */ new Set()) {
|
|
9340
11266
|
if (value instanceof Float32Array) {
|
|
9341
11267
|
const samples = copy ? value.slice() : value;
|
|
9342
11268
|
const buffer = samples.buffer;
|
|
@@ -9352,25 +11278,25 @@ function cloneForWorker(value, copy, transfers, transferred = /* @__PURE__ */ ne
|
|
|
9352
11278
|
return samples;
|
|
9353
11279
|
}
|
|
9354
11280
|
if (Array.isArray(value)) {
|
|
9355
|
-
return value.map((item) =>
|
|
11281
|
+
return value.map((item) => cloneForWorker2(item, copy, transfers, transferred));
|
|
9356
11282
|
}
|
|
9357
11283
|
if (value !== null && typeof value === "object") {
|
|
9358
11284
|
return Object.fromEntries(
|
|
9359
11285
|
Object.entries(value).map(([key, item]) => [
|
|
9360
11286
|
key,
|
|
9361
|
-
|
|
11287
|
+
cloneForWorker2(item, copy, transfers, transferred)
|
|
9362
11288
|
])
|
|
9363
11289
|
);
|
|
9364
11290
|
}
|
|
9365
11291
|
return value;
|
|
9366
11292
|
}
|
|
9367
|
-
function
|
|
11293
|
+
function cancellationFlag2() {
|
|
9368
11294
|
if (typeof SharedArrayBuffer === "undefined") {
|
|
9369
11295
|
return void 0;
|
|
9370
11296
|
}
|
|
9371
11297
|
return new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
|
|
9372
11298
|
}
|
|
9373
|
-
function
|
|
11299
|
+
function workerError2(message) {
|
|
9374
11300
|
if (message.error.code !== void 0) {
|
|
9375
11301
|
return new SonareError(
|
|
9376
11302
|
message.error.code,
|
|
@@ -9403,7 +11329,7 @@ var OfflineWorkerClient = class {
|
|
|
9403
11329
|
pending.resolve(message.result);
|
|
9404
11330
|
return;
|
|
9405
11331
|
}
|
|
9406
|
-
pending.reject(
|
|
11332
|
+
pending.reject(workerError2(message));
|
|
9407
11333
|
};
|
|
9408
11334
|
this.onError = (event) => {
|
|
9409
11335
|
const error = new Error(event.message || "Offline Worker failed");
|
|
@@ -9492,8 +11418,8 @@ var OfflineWorkerClient = class {
|
|
|
9492
11418
|
}
|
|
9493
11419
|
const id = this.nextId++;
|
|
9494
11420
|
const transfers = [];
|
|
9495
|
-
const preparedRequest =
|
|
9496
|
-
const cancelFlag =
|
|
11421
|
+
const preparedRequest = cloneForWorker2(request, options.copy === true, transfers);
|
|
11422
|
+
const cancelFlag = cancellationFlag2();
|
|
9497
11423
|
const result = new Promise((resolve, reject) => {
|
|
9498
11424
|
this.pending.set(id, {
|
|
9499
11425
|
resolve: (value) => resolve(value),
|
|
@@ -9525,10 +11451,10 @@ var OfflineWorkerClient = class {
|
|
|
9525
11451
|
};
|
|
9526
11452
|
|
|
9527
11453
|
// src/index.ts
|
|
9528
|
-
var
|
|
11454
|
+
var module2 = null;
|
|
9529
11455
|
var initPromise = null;
|
|
9530
11456
|
async function init(options) {
|
|
9531
|
-
if (
|
|
11457
|
+
if (module2) {
|
|
9532
11458
|
return;
|
|
9533
11459
|
}
|
|
9534
11460
|
if (initPromise) {
|
|
@@ -9537,8 +11463,8 @@ async function init(options) {
|
|
|
9537
11463
|
initPromise = (async () => {
|
|
9538
11464
|
try {
|
|
9539
11465
|
const createModule = options?.moduleFactory ?? (await import("./sonare.js")).default;
|
|
9540
|
-
|
|
9541
|
-
setSonareModule(
|
|
11466
|
+
module2 = await createModule(options);
|
|
11467
|
+
setSonareModule(module2);
|
|
9542
11468
|
} catch (error) {
|
|
9543
11469
|
initPromise = null;
|
|
9544
11470
|
throw error;
|
|
@@ -9547,43 +11473,43 @@ async function init(options) {
|
|
|
9547
11473
|
return initPromise;
|
|
9548
11474
|
}
|
|
9549
11475
|
function isInitialized() {
|
|
9550
|
-
return
|
|
11476
|
+
return module2 !== null;
|
|
9551
11477
|
}
|
|
9552
11478
|
function version() {
|
|
9553
|
-
if (!
|
|
11479
|
+
if (!module2) {
|
|
9554
11480
|
throw new Error("Module not initialized. Call init() first.");
|
|
9555
11481
|
}
|
|
9556
|
-
return
|
|
11482
|
+
return module2.version();
|
|
9557
11483
|
}
|
|
9558
11484
|
function capabilities() {
|
|
9559
|
-
if (!
|
|
11485
|
+
if (!module2) {
|
|
9560
11486
|
throw new Error("Module not initialized. Call init() first.");
|
|
9561
11487
|
}
|
|
9562
|
-
return
|
|
11488
|
+
return module2.capabilities();
|
|
9563
11489
|
}
|
|
9564
11490
|
function capabilityCatalog() {
|
|
9565
|
-
if (!
|
|
11491
|
+
if (!module2) {
|
|
9566
11492
|
throw new Error("Module not initialized. Call init() first.");
|
|
9567
11493
|
}
|
|
9568
|
-
return JSON.parse(
|
|
11494
|
+
return JSON.parse(module2.capabilityCatalog());
|
|
9569
11495
|
}
|
|
9570
11496
|
function abiVersion() {
|
|
9571
|
-
if (!
|
|
11497
|
+
if (!module2) {
|
|
9572
11498
|
throw new Error("Module not initialized. Call init() first.");
|
|
9573
11499
|
}
|
|
9574
|
-
return
|
|
11500
|
+
return module2.abiVersion();
|
|
9575
11501
|
}
|
|
9576
11502
|
function engineAbiVersion() {
|
|
9577
|
-
if (!
|
|
11503
|
+
if (!module2) {
|
|
9578
11504
|
throw new Error("Module not initialized. Call init() first.");
|
|
9579
11505
|
}
|
|
9580
|
-
return
|
|
11506
|
+
return module2.engineAbiVersion();
|
|
9581
11507
|
}
|
|
9582
11508
|
function voiceChangerAbiVersion() {
|
|
9583
|
-
if (!
|
|
11509
|
+
if (!module2) {
|
|
9584
11510
|
throw new Error("Module not initialized. Call init() first.");
|
|
9585
11511
|
}
|
|
9586
|
-
return
|
|
11512
|
+
return module2.voiceChangerAbiVersion();
|
|
9587
11513
|
}
|
|
9588
11514
|
var VOICE_PRESET_ORDINALS = [
|
|
9589
11515
|
"neutral-monitor",
|
|
@@ -9607,19 +11533,19 @@ function resolveVoicePresetOrdinal(preset) {
|
|
|
9607
11533
|
return ordinal;
|
|
9608
11534
|
}
|
|
9609
11535
|
function voiceCharacterPresetId(preset) {
|
|
9610
|
-
if (!
|
|
11536
|
+
if (!module2) {
|
|
9611
11537
|
throw new Error("Module not initialized. Call init() first.");
|
|
9612
11538
|
}
|
|
9613
11539
|
if (typeof preset === "number" && (!Number.isSafeInteger(preset) || preset < 0 || preset >= VOICE_PRESET_ORDINALS.length)) {
|
|
9614
11540
|
return null;
|
|
9615
11541
|
}
|
|
9616
|
-
return
|
|
11542
|
+
return module2.voiceCharacterPresetId(resolveVoicePresetOrdinal(preset));
|
|
9617
11543
|
}
|
|
9618
11544
|
function realtimeVoiceChangerPresetConfig(preset) {
|
|
9619
|
-
if (!
|
|
11545
|
+
if (!module2) {
|
|
9620
11546
|
throw new Error("Module not initialized. Call init() first.");
|
|
9621
11547
|
}
|
|
9622
|
-
return
|
|
11548
|
+
return module2.realtimeVoiceChangerPresetConfig(resolveVoicePresetOrdinal(preset));
|
|
9623
11549
|
}
|
|
9624
11550
|
export {
|
|
9625
11551
|
ARTICULATIONS,
|
|
@@ -9643,6 +11569,8 @@ export {
|
|
|
9643
11569
|
NOTE_TRACKINGS,
|
|
9644
11570
|
OfflineWorkerClient,
|
|
9645
11571
|
OfflineWorkerTask,
|
|
11572
|
+
PART_RIG_ALL_PARTS,
|
|
11573
|
+
PART_RIG_MODES,
|
|
9646
11574
|
PROJECT_AUTOMATION_TARGET_OPAQUE,
|
|
9647
11575
|
PROJECT_AUTOMATION_TARGET_TRACK_FADER_DB,
|
|
9648
11576
|
PROJECT_AUTOMATION_TARGET_TRACK_PAN,
|
|
@@ -9652,6 +11580,7 @@ export {
|
|
|
9652
11580
|
PlaybackRenderer,
|
|
9653
11581
|
PolyphonicAnalysis,
|
|
9654
11582
|
Project,
|
|
11583
|
+
ProjectTimeline,
|
|
9655
11584
|
RealtimeEngine,
|
|
9656
11585
|
RealtimeVoiceChanger,
|
|
9657
11586
|
SAMPLE_KEY_TRACKS,
|
|
@@ -9671,6 +11600,14 @@ export {
|
|
|
9671
11600
|
StreamingEqualizer,
|
|
9672
11601
|
StreamingMasteringChain,
|
|
9673
11602
|
StreamingRetune,
|
|
11603
|
+
VocalEditDraft,
|
|
11604
|
+
VocalEditSession,
|
|
11605
|
+
VocalEditWorkerClient,
|
|
11606
|
+
VocalEditWorkerSession,
|
|
11607
|
+
VocalEditWorkerStaleResultError,
|
|
11608
|
+
VocalEditWorkerTask,
|
|
11609
|
+
VocalRenderJob,
|
|
11610
|
+
VocalRenderSnapshot,
|
|
9674
11611
|
abiVersion,
|
|
9675
11612
|
alignTakeToReference,
|
|
9676
11613
|
amplitudeToDb,
|
|
@@ -9702,6 +11639,7 @@ export {
|
|
|
9702
11639
|
cqtToAudio,
|
|
9703
11640
|
createOpfsClipPageProvider,
|
|
9704
11641
|
createOpfsClipPageWorker,
|
|
11642
|
+
createVocalEditSession,
|
|
9705
11643
|
cyclicTempogram,
|
|
9706
11644
|
dbToAmplitude,
|
|
9707
11645
|
dbToPower,
|
|
@@ -9756,6 +11694,7 @@ export {
|
|
|
9756
11694
|
masterAudioWithProgress,
|
|
9757
11695
|
mastering,
|
|
9758
11696
|
masteringAbMatchLoudness,
|
|
11697
|
+
masteringAbMatchLoudnessStereo,
|
|
9759
11698
|
masteringAmpPresetCatalog,
|
|
9760
11699
|
masteringAssistantSuggest,
|
|
9761
11700
|
masteringAssistantSuggestChain,
|
|
@@ -9777,6 +11716,7 @@ export {
|
|
|
9777
11716
|
masteringPairAnalysisNames,
|
|
9778
11717
|
masteringPairAnalyze,
|
|
9779
11718
|
masteringPairProcess,
|
|
11719
|
+
masteringPairProcessStereo,
|
|
9780
11720
|
masteringPairProcessorNames,
|
|
9781
11721
|
masteringPlatformNames,
|
|
9782
11722
|
masteringPresetNames,
|
|
@@ -9890,6 +11830,7 @@ export {
|
|
|
9890
11830
|
renderPercussiveEvents,
|
|
9891
11831
|
renderPlayback,
|
|
9892
11832
|
resample,
|
|
11833
|
+
restoreVocalEditSession,
|
|
9893
11834
|
rmsEnergy,
|
|
9894
11835
|
roomMorph,
|
|
9895
11836
|
samplesToFrames,
|
|
@@ -9939,6 +11880,8 @@ export {
|
|
|
9939
11880
|
validateRealtimeVoiceChangerPresetJson,
|
|
9940
11881
|
vectorNormalize,
|
|
9941
11882
|
version,
|
|
11883
|
+
vocalEditApiVersion,
|
|
11884
|
+
vocalEditAvailable,
|
|
9942
11885
|
voiceChange,
|
|
9943
11886
|
voiceChangeRealtime,
|
|
9944
11887
|
voiceChangerAbiVersion,
|