@libraz/libsonare 1.8.1 → 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/analysis.js +2 -0
- package/dist/analysis.js.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1927 -140
- 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 +3 -2
- package/dist/mastering_core.d.ts.map +1 -1
- package/dist/mixer.d.ts +2 -2
- 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 +10 -1
- 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 +1 -1
- package/dist/public_types_mastering.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 +57 -10
- 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 +53 -0
- package/dist/sonare.js +1 -1
- package/dist/sonare.wasm +0 -0
- 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 +2 -1
- package/dist/worklet/engine-mixer-facade.d.ts.map +1 -1
- package/dist/worklet/engine-node.d.ts +8 -0
- package/dist/worklet/engine-node.d.ts.map +1 -1
- package/dist/worklet/engine-processor.d.ts +2 -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 +4 -2
- package/dist/worklet/engine-strips.d.ts.map +1 -1
- package/dist/worklet/engine.d.ts +15 -3
- package/dist/worklet/engine.d.ts.map +1 -1
- package/dist/worklet/guards.d.ts +3 -1
- package/dist/worklet/guards.d.ts.map +1 -1
- package/dist/worklet/messages.d.ts +50 -5
- package/dist/worklet/messages.d.ts.map +1 -1
- package/dist/worklet/protocol.d.ts +10 -0
- 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 +223 -16
- package/dist/worklet.js.map +1 -1
- package/package.json +6 -1
- package/src/index.ts +33 -0
- package/src/instrument_types.ts +29 -3
- package/src/mastering_core.ts +3 -2
- package/src/mixer.ts +2 -2
- 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 +11 -1
- package/src/public_types.ts +1 -0
- package/src/public_types_mastering.ts +2 -0
- package/src/public_types_vocal_edit.ts +289 -0
- package/src/public_types_vocal_project.ts +69 -0
- package/src/realtime_engine.ts +86 -9
- package/src/repair_dereverb.ts +1 -0
- package/src/repair_noise.ts +1 -0
- package/src/sonare.js.d.ts +53 -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 +2 -1
- package/src/worklet/engine-node.ts +47 -0
- package/src/worklet/engine-processor.ts +46 -1
- package/src/worklet/engine-register.ts +3 -0
- package/src/worklet/engine-strips.ts +31 -4
- package/src/worklet/engine.ts +27 -3
- package/src/worklet/guards.ts +26 -0
- package/src/worklet/messages.ts +59 -2
- package/src/worklet/protocol.ts +10 -0
- 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) {
|
|
@@ -764,11 +806,11 @@ function mergeNotes(request) {
|
|
|
764
806
|
);
|
|
765
807
|
}
|
|
766
808
|
function noteTargetsFromSmf(request) {
|
|
767
|
-
const
|
|
768
|
-
if (typeof
|
|
809
|
+
const module3 = requireModule();
|
|
810
|
+
if (typeof module3.noteTargetsFromSmf !== "function") {
|
|
769
811
|
throw new Error("libsonare was built without arrangement support");
|
|
770
812
|
}
|
|
771
|
-
return
|
|
813
|
+
return module3.noteTargetsFromSmf(request.data, request.trackIndex ?? 0);
|
|
772
814
|
}
|
|
773
815
|
function assignNoteTargets(request) {
|
|
774
816
|
return requireModule().assignNoteTargets(
|
|
@@ -4005,29 +4047,29 @@ function detectAcoustic(samples, sampleRate = 48e3, options = {}) {
|
|
|
4005
4047
|
return result;
|
|
4006
4048
|
}
|
|
4007
4049
|
function synthesizeRir(options = {}) {
|
|
4008
|
-
const
|
|
4009
|
-
if (typeof
|
|
4050
|
+
const module3 = requireModule25();
|
|
4051
|
+
if (typeof module3.synthesizeRir !== "function") {
|
|
4010
4052
|
throw new Error("libsonare was built without acoustic-simulation support");
|
|
4011
4053
|
}
|
|
4012
|
-
return
|
|
4054
|
+
return module3.synthesizeRir(options);
|
|
4013
4055
|
}
|
|
4014
4056
|
function estimateRoom(samples, sampleRate = 48e3, options = {}) {
|
|
4015
|
-
const
|
|
4016
|
-
if (typeof
|
|
4057
|
+
const module3 = requireModule25();
|
|
4058
|
+
if (typeof module3.estimateRoom !== "function") {
|
|
4017
4059
|
throw new Error("libsonare was built without acoustic-simulation support");
|
|
4018
4060
|
}
|
|
4019
4061
|
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
4020
4062
|
validateAnalysisInput("estimateRoom", request.samples, request.sampleRate ?? 48e3, request);
|
|
4021
|
-
return
|
|
4063
|
+
return module3.estimateRoom(request.samples, request.sampleRate ?? 48e3, request);
|
|
4022
4064
|
}
|
|
4023
4065
|
function roomMorph(samples, sampleRate, options = {}) {
|
|
4024
|
-
const
|
|
4025
|
-
if (typeof
|
|
4066
|
+
const module3 = requireModule25();
|
|
4067
|
+
if (typeof module3.roomMorph !== "function") {
|
|
4026
4068
|
throw new Error("libsonare was built without acoustic-simulation support");
|
|
4027
4069
|
}
|
|
4028
4070
|
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
4029
4071
|
validateAnalysisInput("roomMorph", request.samples, request.sampleRate, request);
|
|
4030
|
-
return
|
|
4072
|
+
return module3.roomMorph(request.samples, request.sampleRate, request);
|
|
4031
4073
|
}
|
|
4032
4074
|
function analyzeWithProgress(samples, sampleRate = 22050, onProgress, options) {
|
|
4033
4075
|
const request = samples instanceof Float32Array ? { samples, sampleRate, onProgress, options } : samples;
|
|
@@ -4910,8 +4952,8 @@ function suggestJson(fnName, request, sceneOnly) {
|
|
|
4910
4952
|
const { left, right, ids, names } = planarTracks(request.tracks);
|
|
4911
4953
|
const sampleRate = request.sampleRate;
|
|
4912
4954
|
const params = request.options ?? {};
|
|
4913
|
-
const
|
|
4914
|
-
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);
|
|
4915
4957
|
}
|
|
4916
4958
|
function suggestMixScene(request) {
|
|
4917
4959
|
return JSON.parse(suggestJson("suggestMixScene", request, false));
|
|
@@ -5097,8 +5139,8 @@ var PolyphonicAnalysis = class {
|
|
|
5097
5139
|
constructor(request) {
|
|
5098
5140
|
assertSamples("analyzePolyphonic", request.samples, request.validate !== false);
|
|
5099
5141
|
assertSampleRate("analyzePolyphonic", request.sampleRate);
|
|
5100
|
-
const
|
|
5101
|
-
this.native =
|
|
5142
|
+
const module3 = getSonareModule();
|
|
5143
|
+
this.native = module3.createPolyphonicAnalysis(
|
|
5102
5144
|
request.samples,
|
|
5103
5145
|
request.sampleRate,
|
|
5104
5146
|
request
|
|
@@ -5374,9 +5416,261 @@ var CONTROLLER_AXES = [
|
|
|
5374
5416
|
"vibrato-depth"
|
|
5375
5417
|
];
|
|
5376
5418
|
var ARTICULATIONS = ["poly", "mono-retrigger", "mono-legato"];
|
|
5419
|
+
var PART_RIG_MODES = ["bank", "none", "chain"];
|
|
5420
|
+
var PART_RIG_ALL_PARTS = 255;
|
|
5377
5421
|
var MPE_DIMENSIONS = ["bend", "pressure", "timbre"];
|
|
5378
5422
|
var NOTE_TRACKINGS = ["last", "lowest", "highest", "all"];
|
|
5379
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
|
+
|
|
5380
5674
|
// src/project_class.ts
|
|
5381
5675
|
function normalizeMidiFxBakeRequest(clipIdOrRequest, configJson) {
|
|
5382
5676
|
if (typeof clipIdOrRequest === "number") {
|
|
@@ -5445,11 +5739,57 @@ function midi2Byte(fnName, value, argName) {
|
|
|
5445
5739
|
assertBoundedInteger(fnName, value, argName, 0, 255);
|
|
5446
5740
|
return value;
|
|
5447
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
|
+
};
|
|
5448
5769
|
var Project = class _Project {
|
|
5449
5770
|
constructor() {
|
|
5450
5771
|
this.released = false;
|
|
5772
|
+
this.deleteRequested = false;
|
|
5773
|
+
this.activeVocalRehydrateCalls = 0;
|
|
5451
5774
|
this.native = new (projectModule()).Project();
|
|
5452
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
|
+
}
|
|
5453
5793
|
/** Create a new empty project. */
|
|
5454
5794
|
static create() {
|
|
5455
5795
|
return new _Project();
|
|
@@ -5818,6 +6158,26 @@ var Project = class _Project {
|
|
|
5818
6158
|
setTrackGain(trackId, gain) {
|
|
5819
6159
|
this.native.setTrackGain(trackId, gain);
|
|
5820
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
|
+
}
|
|
5821
6181
|
/** Set a track's mute flag via an undoable edit (a muted track is silent). */
|
|
5822
6182
|
setTrackMute(trackId, mute) {
|
|
5823
6183
|
this.native.setTrackMute(trackId, mute);
|
|
@@ -6023,6 +6383,16 @@ var Project = class _Project {
|
|
|
6023
6383
|
compile() {
|
|
6024
6384
|
return this.native.compile();
|
|
6025
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
|
+
}
|
|
6026
6396
|
/**
|
|
6027
6397
|
* Compile + render the project offline to interleaved float audio. MIDI
|
|
6028
6398
|
* tracks render silently here (no instrument is bound) — use
|
|
@@ -6395,12 +6765,20 @@ var Project = class _Project {
|
|
|
6395
6765
|
lastBounceCompileResult() {
|
|
6396
6766
|
return this.native.lastBounceCompileResult();
|
|
6397
6767
|
}
|
|
6398
|
-
/**
|
|
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
|
+
*/
|
|
6399
6773
|
delete() {
|
|
6400
6774
|
if (this.released) {
|
|
6401
6775
|
return;
|
|
6402
6776
|
}
|
|
6403
6777
|
this.released = true;
|
|
6778
|
+
if (this.activeVocalRehydrateCalls !== 0) {
|
|
6779
|
+
this.deleteRequested = true;
|
|
6780
|
+
return;
|
|
6781
|
+
}
|
|
6404
6782
|
this.native.delete();
|
|
6405
6783
|
}
|
|
6406
6784
|
/** Alias for {@link delete}, provided for cross-binding (Node) compatibility. */
|
|
@@ -6500,14 +6878,14 @@ function engineCapabilities() {
|
|
|
6500
6878
|
var RealtimeEngine = class _RealtimeEngine {
|
|
6501
6879
|
constructor(sampleRate = 48e3, maxBlockSize = 128, commandCapacity = 1024, telemetryCapacity = 1024, maxChannels = 64) {
|
|
6502
6880
|
this.released = false;
|
|
6503
|
-
const
|
|
6881
|
+
const module3 = getSonareModule();
|
|
6504
6882
|
const capabilities2 = engineCapabilities();
|
|
6505
6883
|
if (!capabilities2.abiCompatible) {
|
|
6506
6884
|
throw new Error(
|
|
6507
6885
|
`Engine ABI mismatch: wasm=${capabilities2.engineAbiVersion}, expected=${capabilities2.expectedEngineAbiVersion}`
|
|
6508
6886
|
);
|
|
6509
6887
|
}
|
|
6510
|
-
this.native = new
|
|
6888
|
+
this.native = new module3.RealtimeEngine(
|
|
6511
6889
|
sampleRate,
|
|
6512
6890
|
maxBlockSize,
|
|
6513
6891
|
commandCapacity,
|
|
@@ -6711,6 +7089,17 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
6711
7089
|
setArticulation(destinationId, channel, articulation) {
|
|
6712
7090
|
this.native.setArticulation(destinationId, channel, articulation);
|
|
6713
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
|
+
}
|
|
6714
7103
|
/**
|
|
6715
7104
|
* Read back {@link setArticulation} as the canonical name. An ordinal this
|
|
6716
7105
|
* build cannot spell is handed back as the number, the way every other enum
|
|
@@ -7121,10 +7510,40 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
7121
7510
|
/**
|
|
7122
7511
|
* Keys one insert of a lane strip from another lane's post-strip audio
|
|
7123
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.
|
|
7124
7519
|
*/
|
|
7125
7520
|
setLaneSidechain(trackId, insertIndex, sourceTrackId) {
|
|
7126
7521
|
this.native.setLaneSidechain(trackId, insertIndex, sourceTrackId);
|
|
7127
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
|
+
}
|
|
7128
7547
|
setTrackBuses(buses) {
|
|
7129
7548
|
this.native.setTrackBuses(
|
|
7130
7549
|
Array.isArray(buses) ? buses.map((bus) => ({
|
|
@@ -7326,12 +7745,9 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
7326
7745
|
* return `-1`: they resize voice pools or swap DSP topology, which is not
|
|
7327
7746
|
* audio-thread safe. Rebind the instrument with a new patch instead.
|
|
7328
7747
|
*
|
|
7329
|
-
*
|
|
7330
|
-
*
|
|
7331
|
-
*
|
|
7332
|
-
* note-on and take effect from the next note, so a lane that moves one of
|
|
7333
|
-
* them under a held note looks inert until the next one speaks — that is the
|
|
7334
|
-
* 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.
|
|
7335
7751
|
*
|
|
7336
7752
|
* The id survives an unbind/rebind of the same destination and applies
|
|
7337
7753
|
* nothing while that destination is unbound.
|
|
@@ -7355,6 +7771,16 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
7355
7771
|
setTrackStripDualPan(trackId, leftPan, rightPan) {
|
|
7356
7772
|
this.native.setTrackStripDualPan(trackId, leftPan, rightPan);
|
|
7357
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
|
+
}
|
|
7358
7784
|
/**
|
|
7359
7785
|
* Sets a bus strip's output pan position in realtime (glitch-free). Throws
|
|
7360
7786
|
* for an unknown bus or one wider than stereo.
|
|
@@ -7375,8 +7801,9 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
7375
7801
|
this.native.setBusStripDualPan(busId, leftPan, rightPan);
|
|
7376
7802
|
}
|
|
7377
7803
|
/**
|
|
7378
|
-
* Sets a track lane strip's
|
|
7379
|
-
*
|
|
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.
|
|
7380
7807
|
*/
|
|
7381
7808
|
setTrackStripChannelDelaySamples(trackId, delaySamples) {
|
|
7382
7809
|
this.native.setTrackStripChannelDelaySamples(trackId, delaySamples);
|
|
@@ -7644,6 +8071,15 @@ var RealtimeEngine = class _RealtimeEngine {
|
|
|
7644
8071
|
drainMeterTelemetryWide(maxRecords = 1024) {
|
|
7645
8072
|
return this.native.drainMeterTelemetryWide(maxRecords);
|
|
7646
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
|
+
}
|
|
7647
8083
|
/**
|
|
7648
8084
|
* Enables per-target spectrum + vectorscope capture. @param intervalFrames is
|
|
7649
8085
|
* the minimum render-frame gap between snapshots (0 disables). @param bandCount
|
|
@@ -7757,9 +8193,9 @@ var StreamAnalyzer = class {
|
|
|
7757
8193
|
throw new TypeError("outputFormat must be the integer 0 (Float32)");
|
|
7758
8194
|
}
|
|
7759
8195
|
const window = config.window === void 0 ? void 0 : resolveOrdinalInRange(config.window, 0, 3, "stream analyzer window");
|
|
7760
|
-
const
|
|
8196
|
+
const module3 = getSonareModule();
|
|
7761
8197
|
const defaults = streamAnalyzerConfigDefaults();
|
|
7762
|
-
this.analyzer = new
|
|
8198
|
+
this.analyzer = new module3.StreamAnalyzer(
|
|
7763
8199
|
config.sampleRate ?? defaults.sampleRate,
|
|
7764
8200
|
config.nFft ?? defaults.nFft,
|
|
7765
8201
|
config.hopLength ?? defaults.hopLength,
|
|
@@ -8019,8 +8455,8 @@ var Mixer = class _Mixer {
|
|
|
8019
8455
|
* @param blockSize - Maximum block size per {@link processStereo} call (default: 512)
|
|
8020
8456
|
*/
|
|
8021
8457
|
static fromSceneJson(json, sampleRate = 48e3, blockSize = 512) {
|
|
8022
|
-
const
|
|
8023
|
-
return new _Mixer(
|
|
8458
|
+
const module3 = getSonareModule();
|
|
8459
|
+
return new _Mixer(module3.createMixerFromSceneJson(json, sampleRate, blockSize), blockSize);
|
|
8024
8460
|
}
|
|
8025
8461
|
/**
|
|
8026
8462
|
* Rebuild and compile the routing graph without resetting its absolute
|
|
@@ -8347,8 +8783,8 @@ var Mixer = class _Mixer {
|
|
|
8347
8783
|
this.mixer.setPanLaw(stripIndex, panLawCode(panLaw));
|
|
8348
8784
|
}
|
|
8349
8785
|
/**
|
|
8350
|
-
* Set a per-strip channel delay in samples
|
|
8351
|
-
*
|
|
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.
|
|
8352
8788
|
*/
|
|
8353
8789
|
setChannelDelaySamples(stripIndex, delaySamples) {
|
|
8354
8790
|
this.mixer.setChannelDelaySamples(stripIndex, delaySamples);
|
|
@@ -8602,8 +9038,8 @@ var RealtimeVoiceChanger = class {
|
|
|
8602
9038
|
*/
|
|
8603
9039
|
constructor(config = "neutral-monitor", sampleRate, maxBlockSize = 128, channels = 1) {
|
|
8604
9040
|
this.released = false;
|
|
8605
|
-
const
|
|
8606
|
-
this.changer =
|
|
9041
|
+
const module3 = getSonareModule();
|
|
9042
|
+
this.changer = module3.createRealtimeVoiceChanger(config);
|
|
8607
9043
|
if (sampleRate !== void 0) {
|
|
8608
9044
|
let prepared = false;
|
|
8609
9045
|
try {
|
|
@@ -8879,9 +9315,9 @@ var EQ_PHASE_MODES = {
|
|
|
8879
9315
|
var StreamingMasteringChain = class {
|
|
8880
9316
|
constructor(config) {
|
|
8881
9317
|
this.released = false;
|
|
8882
|
-
const
|
|
9318
|
+
const module3 = getSonareModule();
|
|
8883
9319
|
const { loudnessStaticGainDb, loudnessStaticGainPeakDb, ...chainConfig } = config;
|
|
8884
|
-
this.chain =
|
|
9320
|
+
this.chain = module3.createStreamingMasteringChain({
|
|
8885
9321
|
__flatParams: flattenChainConfig(chainConfig),
|
|
8886
9322
|
loudnessStaticGainDb,
|
|
8887
9323
|
loudnessStaticGainPeakDb
|
|
@@ -9017,8 +9453,8 @@ var StreamingMasteringChain = class {
|
|
|
9017
9453
|
var StreamingEqualizer = class {
|
|
9018
9454
|
constructor(config = {}) {
|
|
9019
9455
|
this.released = false;
|
|
9020
|
-
const
|
|
9021
|
-
this.eq =
|
|
9456
|
+
const module3 = getSonareModule();
|
|
9457
|
+
this.eq = module3.createEqualizer(config);
|
|
9022
9458
|
}
|
|
9023
9459
|
/**
|
|
9024
9460
|
* Configure the band at `index` (0..23). Omitted fields use C++ defaults.
|
|
@@ -9187,8 +9623,8 @@ var StreamingEqualizer = class {
|
|
|
9187
9623
|
var StreamingRetune = class {
|
|
9188
9624
|
constructor(config = {}) {
|
|
9189
9625
|
this.released = false;
|
|
9190
|
-
const
|
|
9191
|
-
this.retune =
|
|
9626
|
+
const module3 = getSonareModule();
|
|
9627
|
+
this.retune = module3.createStreamingRetune(config);
|
|
9192
9628
|
}
|
|
9193
9629
|
/**
|
|
9194
9630
|
* Allocate and initialize native state for the given sample rate and maximum
|
|
@@ -9252,77 +9688,1341 @@ function transcribe(request) {
|
|
|
9252
9688
|
);
|
|
9253
9689
|
}
|
|
9254
9690
|
|
|
9255
|
-
// src/
|
|
9256
|
-
|
|
9257
|
-
|
|
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
|
+
}
|
|
9258
9718
|
}
|
|
9259
|
-
|
|
9260
|
-
const
|
|
9261
|
-
if (
|
|
9262
|
-
|
|
9719
|
+
function module() {
|
|
9720
|
+
const source = getSonareModule();
|
|
9721
|
+
if (source === cachedModuleSource && cachedVocalModule !== null) {
|
|
9722
|
+
return cachedVocalModule;
|
|
9263
9723
|
}
|
|
9264
|
-
const
|
|
9265
|
-
|
|
9266
|
-
|
|
9267
|
-
|
|
9268
|
-
|
|
9269
|
-
sysex: options.sysex ?? false,
|
|
9270
|
-
software: options.software ?? true
|
|
9271
|
-
});
|
|
9272
|
-
for (const binding of options.ccBindings ?? []) {
|
|
9273
|
-
engine.bindMidiCc(binding.channel, binding.controller, binding.paramId, binding.options);
|
|
9724
|
+
const detailReader = source.vocalEditLastErrorDetail;
|
|
9725
|
+
if (typeof detailReader !== "function") {
|
|
9726
|
+
cachedModuleSource = source;
|
|
9727
|
+
cachedVocalModule = source;
|
|
9728
|
+
return source;
|
|
9274
9729
|
}
|
|
9275
|
-
|
|
9276
|
-
const
|
|
9277
|
-
|
|
9278
|
-
|
|
9279
|
-
|
|
9280
|
-
|
|
9281
|
-
|
|
9282
|
-
|
|
9283
|
-
|
|
9284
|
-
|
|
9285
|
-
|
|
9286
|
-
|
|
9287
|
-
|
|
9288
|
-
|
|
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;
|
|
9289
9764
|
}
|
|
9290
|
-
|
|
9291
|
-
|
|
9292
|
-
|
|
9293
|
-
|
|
9294
|
-
|
|
9295
|
-
|
|
9296
|
-
|
|
9297
|
-
|
|
9298
|
-
|
|
9299
|
-
|
|
9765
|
+
});
|
|
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`);
|
|
9773
|
+
}
|
|
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 }
|
|
9300
9852
|
},
|
|
9301
|
-
|
|
9302
|
-
|
|
9303
|
-
const listener = entry.listener;
|
|
9304
|
-
if (input.addEventListener) {
|
|
9305
|
-
input.addEventListener("midimessage", listener);
|
|
9306
|
-
} else {
|
|
9307
|
-
input.onmidimessage = listener;
|
|
9853
|
+
amplitudeEnvelope: Array.from(note.edit.amplitudeEnvelope),
|
|
9854
|
+
formant: { ...note.edit.formant }
|
|
9308
9855
|
}
|
|
9309
|
-
|
|
9856
|
+
}));
|
|
9857
|
+
return {
|
|
9858
|
+
notes,
|
|
9859
|
+
transitions: Array.from(value.transitions, (transition) => ({ ...transition }))
|
|
9310
9860
|
};
|
|
9311
|
-
|
|
9312
|
-
|
|
9313
|
-
|
|
9314
|
-
|
|
9315
|
-
|
|
9316
|
-
|
|
9317
|
-
|
|
9318
|
-
|
|
9319
|
-
|
|
9320
|
-
|
|
9321
|
-
|
|
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
|
|
9322
9883
|
};
|
|
9323
|
-
|
|
9324
|
-
|
|
9325
|
-
|
|
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();
|
|
10977
|
+
let closed = false;
|
|
10978
|
+
const shouldBind = (input) => input.state !== "disconnected" && (selectedIds.size === 0 || selectedIds.has(input.id));
|
|
10979
|
+
const snapshotInputs = () => Array.from(iterInputs(access), ([id, input]) => ({
|
|
10980
|
+
id,
|
|
10981
|
+
name: input.name ?? "",
|
|
10982
|
+
manufacturer: input.manufacturer ?? "",
|
|
10983
|
+
state: input.state ?? "connected"
|
|
10984
|
+
}));
|
|
10985
|
+
const notify = () => options.onInputsChanged?.(snapshotInputs());
|
|
10986
|
+
const bindInput = (input) => {
|
|
10987
|
+
if (bound.has(input.id) || !shouldBind(input)) {
|
|
10988
|
+
return;
|
|
10989
|
+
}
|
|
10990
|
+
const entry = {
|
|
10991
|
+
input,
|
|
10992
|
+
listener: (event) => {
|
|
10993
|
+
entry.runningStatus = dispatchMidiMessage(
|
|
10994
|
+
engine,
|
|
10995
|
+
event,
|
|
10996
|
+
group,
|
|
10997
|
+
entry.runningStatus,
|
|
10998
|
+
options.timestampToSamples
|
|
10999
|
+
);
|
|
11000
|
+
},
|
|
11001
|
+
runningStatus: 0
|
|
11002
|
+
};
|
|
11003
|
+
const listener = entry.listener;
|
|
11004
|
+
if (input.addEventListener) {
|
|
11005
|
+
input.addEventListener("midimessage", listener);
|
|
11006
|
+
} else {
|
|
11007
|
+
input.onmidimessage = listener;
|
|
11008
|
+
}
|
|
11009
|
+
bound.set(input.id, entry);
|
|
11010
|
+
};
|
|
11011
|
+
const unbindInput = (input) => {
|
|
11012
|
+
const entry = bound.get(input.id);
|
|
11013
|
+
if (!entry) {
|
|
11014
|
+
return;
|
|
11015
|
+
}
|
|
11016
|
+
if (entry.input.removeEventListener) {
|
|
11017
|
+
entry.input.removeEventListener("midimessage", entry.listener);
|
|
11018
|
+
} else if (entry.input.onmidimessage === entry.listener) {
|
|
11019
|
+
entry.input.onmidimessage = null;
|
|
11020
|
+
}
|
|
11021
|
+
bound.delete(input.id);
|
|
11022
|
+
};
|
|
11023
|
+
const refreshInputs = () => {
|
|
11024
|
+
for (const [, entry] of bound) {
|
|
11025
|
+
if (!shouldBind(entry.input)) {
|
|
9326
11026
|
unbindInput(entry.input);
|
|
9327
11027
|
}
|
|
9328
11028
|
}
|
|
@@ -9376,8 +11076,8 @@ function dispatchMidiMessage(engine, event, group, runningStatus, timestampToSam
|
|
|
9376
11076
|
return 0;
|
|
9377
11077
|
}
|
|
9378
11078
|
const first = data[0];
|
|
9379
|
-
if (first > 255) {
|
|
9380
|
-
|
|
11079
|
+
if (first > 255 || data instanceof Uint32Array) {
|
|
11080
|
+
dispatchUmpMessages(
|
|
9381
11081
|
engine,
|
|
9382
11082
|
data,
|
|
9383
11083
|
timestampToSamples?.(event.receivedTime ?? event.timeStamp ?? 0) ?? 0
|
|
@@ -9400,8 +11100,12 @@ function dispatchMidiMessage(engine, event, group, runningStatus, timestampToSam
|
|
|
9400
11100
|
return status >= 248 ? runningStatus : 0;
|
|
9401
11101
|
}
|
|
9402
11102
|
const a = readU7(data, offset);
|
|
9403
|
-
|
|
9404
|
-
|
|
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) {
|
|
9405
11109
|
return status;
|
|
9406
11110
|
}
|
|
9407
11111
|
const portTimeSamples = timestampToSamples ? timestampToSamples(event.receivedTime ?? event.timeStamp ?? 0) : 0;
|
|
@@ -9415,13 +11119,42 @@ function dispatchMidiMessage(engine, event, group, runningStatus, timestampToSam
|
|
|
9415
11119
|
}
|
|
9416
11120
|
} else if (message === 176 && b >= 0) {
|
|
9417
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);
|
|
9418
11128
|
}
|
|
9419
11129
|
return status;
|
|
9420
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
|
+
}
|
|
9421
11147
|
function dispatchUmpMessage(engine, words, portTimeSamples) {
|
|
9422
11148
|
const word0 = words[0] >>> 0;
|
|
9423
11149
|
const messageType = word0 >>> 28;
|
|
9424
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
|
+
}
|
|
9425
11158
|
if (messageType === 2) {
|
|
9426
11159
|
const status = word0 >>> 16 & 255;
|
|
9427
11160
|
const message = status & 240;
|
|
@@ -9438,6 +11171,12 @@ function dispatchUmpMessage(engine, words, portTimeSamples) {
|
|
|
9438
11171
|
}
|
|
9439
11172
|
} else if (message === 176) {
|
|
9440
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);
|
|
9441
11180
|
}
|
|
9442
11181
|
return;
|
|
9443
11182
|
}
|
|
@@ -9453,7 +11192,40 @@ function dispatchUmpMessage(engine, words, portTimeSamples) {
|
|
|
9453
11192
|
engine.pushMidiInputNoteOn(group, channel, data1, velocity, portTimeSamples);
|
|
9454
11193
|
} else if (status === 11) {
|
|
9455
11194
|
engine.pushMidiInputCc(group, channel, data1, word1 >>> 25 & 127, portTimeSamples);
|
|
9456
|
-
}
|
|
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;
|
|
9457
11229
|
}
|
|
9458
11230
|
}
|
|
9459
11231
|
function readU7(data, index) {
|
|
@@ -9490,7 +11262,7 @@ var OfflineWorkerTask = class {
|
|
|
9490
11262
|
return this.result.finally(onfinally);
|
|
9491
11263
|
}
|
|
9492
11264
|
};
|
|
9493
|
-
function
|
|
11265
|
+
function cloneForWorker2(value, copy, transfers, transferred = /* @__PURE__ */ new Set()) {
|
|
9494
11266
|
if (value instanceof Float32Array) {
|
|
9495
11267
|
const samples = copy ? value.slice() : value;
|
|
9496
11268
|
const buffer = samples.buffer;
|
|
@@ -9506,25 +11278,25 @@ function cloneForWorker(value, copy, transfers, transferred = /* @__PURE__ */ ne
|
|
|
9506
11278
|
return samples;
|
|
9507
11279
|
}
|
|
9508
11280
|
if (Array.isArray(value)) {
|
|
9509
|
-
return value.map((item) =>
|
|
11281
|
+
return value.map((item) => cloneForWorker2(item, copy, transfers, transferred));
|
|
9510
11282
|
}
|
|
9511
11283
|
if (value !== null && typeof value === "object") {
|
|
9512
11284
|
return Object.fromEntries(
|
|
9513
11285
|
Object.entries(value).map(([key, item]) => [
|
|
9514
11286
|
key,
|
|
9515
|
-
|
|
11287
|
+
cloneForWorker2(item, copy, transfers, transferred)
|
|
9516
11288
|
])
|
|
9517
11289
|
);
|
|
9518
11290
|
}
|
|
9519
11291
|
return value;
|
|
9520
11292
|
}
|
|
9521
|
-
function
|
|
11293
|
+
function cancellationFlag2() {
|
|
9522
11294
|
if (typeof SharedArrayBuffer === "undefined") {
|
|
9523
11295
|
return void 0;
|
|
9524
11296
|
}
|
|
9525
11297
|
return new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
|
|
9526
11298
|
}
|
|
9527
|
-
function
|
|
11299
|
+
function workerError2(message) {
|
|
9528
11300
|
if (message.error.code !== void 0) {
|
|
9529
11301
|
return new SonareError(
|
|
9530
11302
|
message.error.code,
|
|
@@ -9557,7 +11329,7 @@ var OfflineWorkerClient = class {
|
|
|
9557
11329
|
pending.resolve(message.result);
|
|
9558
11330
|
return;
|
|
9559
11331
|
}
|
|
9560
|
-
pending.reject(
|
|
11332
|
+
pending.reject(workerError2(message));
|
|
9561
11333
|
};
|
|
9562
11334
|
this.onError = (event) => {
|
|
9563
11335
|
const error = new Error(event.message || "Offline Worker failed");
|
|
@@ -9646,8 +11418,8 @@ var OfflineWorkerClient = class {
|
|
|
9646
11418
|
}
|
|
9647
11419
|
const id = this.nextId++;
|
|
9648
11420
|
const transfers = [];
|
|
9649
|
-
const preparedRequest =
|
|
9650
|
-
const cancelFlag =
|
|
11421
|
+
const preparedRequest = cloneForWorker2(request, options.copy === true, transfers);
|
|
11422
|
+
const cancelFlag = cancellationFlag2();
|
|
9651
11423
|
const result = new Promise((resolve, reject) => {
|
|
9652
11424
|
this.pending.set(id, {
|
|
9653
11425
|
resolve: (value) => resolve(value),
|
|
@@ -9679,10 +11451,10 @@ var OfflineWorkerClient = class {
|
|
|
9679
11451
|
};
|
|
9680
11452
|
|
|
9681
11453
|
// src/index.ts
|
|
9682
|
-
var
|
|
11454
|
+
var module2 = null;
|
|
9683
11455
|
var initPromise = null;
|
|
9684
11456
|
async function init(options) {
|
|
9685
|
-
if (
|
|
11457
|
+
if (module2) {
|
|
9686
11458
|
return;
|
|
9687
11459
|
}
|
|
9688
11460
|
if (initPromise) {
|
|
@@ -9691,8 +11463,8 @@ async function init(options) {
|
|
|
9691
11463
|
initPromise = (async () => {
|
|
9692
11464
|
try {
|
|
9693
11465
|
const createModule = options?.moduleFactory ?? (await import("./sonare.js")).default;
|
|
9694
|
-
|
|
9695
|
-
setSonareModule(
|
|
11466
|
+
module2 = await createModule(options);
|
|
11467
|
+
setSonareModule(module2);
|
|
9696
11468
|
} catch (error) {
|
|
9697
11469
|
initPromise = null;
|
|
9698
11470
|
throw error;
|
|
@@ -9701,43 +11473,43 @@ async function init(options) {
|
|
|
9701
11473
|
return initPromise;
|
|
9702
11474
|
}
|
|
9703
11475
|
function isInitialized() {
|
|
9704
|
-
return
|
|
11476
|
+
return module2 !== null;
|
|
9705
11477
|
}
|
|
9706
11478
|
function version() {
|
|
9707
|
-
if (!
|
|
11479
|
+
if (!module2) {
|
|
9708
11480
|
throw new Error("Module not initialized. Call init() first.");
|
|
9709
11481
|
}
|
|
9710
|
-
return
|
|
11482
|
+
return module2.version();
|
|
9711
11483
|
}
|
|
9712
11484
|
function capabilities() {
|
|
9713
|
-
if (!
|
|
11485
|
+
if (!module2) {
|
|
9714
11486
|
throw new Error("Module not initialized. Call init() first.");
|
|
9715
11487
|
}
|
|
9716
|
-
return
|
|
11488
|
+
return module2.capabilities();
|
|
9717
11489
|
}
|
|
9718
11490
|
function capabilityCatalog() {
|
|
9719
|
-
if (!
|
|
11491
|
+
if (!module2) {
|
|
9720
11492
|
throw new Error("Module not initialized. Call init() first.");
|
|
9721
11493
|
}
|
|
9722
|
-
return JSON.parse(
|
|
11494
|
+
return JSON.parse(module2.capabilityCatalog());
|
|
9723
11495
|
}
|
|
9724
11496
|
function abiVersion() {
|
|
9725
|
-
if (!
|
|
11497
|
+
if (!module2) {
|
|
9726
11498
|
throw new Error("Module not initialized. Call init() first.");
|
|
9727
11499
|
}
|
|
9728
|
-
return
|
|
11500
|
+
return module2.abiVersion();
|
|
9729
11501
|
}
|
|
9730
11502
|
function engineAbiVersion() {
|
|
9731
|
-
if (!
|
|
11503
|
+
if (!module2) {
|
|
9732
11504
|
throw new Error("Module not initialized. Call init() first.");
|
|
9733
11505
|
}
|
|
9734
|
-
return
|
|
11506
|
+
return module2.engineAbiVersion();
|
|
9735
11507
|
}
|
|
9736
11508
|
function voiceChangerAbiVersion() {
|
|
9737
|
-
if (!
|
|
11509
|
+
if (!module2) {
|
|
9738
11510
|
throw new Error("Module not initialized. Call init() first.");
|
|
9739
11511
|
}
|
|
9740
|
-
return
|
|
11512
|
+
return module2.voiceChangerAbiVersion();
|
|
9741
11513
|
}
|
|
9742
11514
|
var VOICE_PRESET_ORDINALS = [
|
|
9743
11515
|
"neutral-monitor",
|
|
@@ -9761,19 +11533,19 @@ function resolveVoicePresetOrdinal(preset) {
|
|
|
9761
11533
|
return ordinal;
|
|
9762
11534
|
}
|
|
9763
11535
|
function voiceCharacterPresetId(preset) {
|
|
9764
|
-
if (!
|
|
11536
|
+
if (!module2) {
|
|
9765
11537
|
throw new Error("Module not initialized. Call init() first.");
|
|
9766
11538
|
}
|
|
9767
11539
|
if (typeof preset === "number" && (!Number.isSafeInteger(preset) || preset < 0 || preset >= VOICE_PRESET_ORDINALS.length)) {
|
|
9768
11540
|
return null;
|
|
9769
11541
|
}
|
|
9770
|
-
return
|
|
11542
|
+
return module2.voiceCharacterPresetId(resolveVoicePresetOrdinal(preset));
|
|
9771
11543
|
}
|
|
9772
11544
|
function realtimeVoiceChangerPresetConfig(preset) {
|
|
9773
|
-
if (!
|
|
11545
|
+
if (!module2) {
|
|
9774
11546
|
throw new Error("Module not initialized. Call init() first.");
|
|
9775
11547
|
}
|
|
9776
|
-
return
|
|
11548
|
+
return module2.realtimeVoiceChangerPresetConfig(resolveVoicePresetOrdinal(preset));
|
|
9777
11549
|
}
|
|
9778
11550
|
export {
|
|
9779
11551
|
ARTICULATIONS,
|
|
@@ -9797,6 +11569,8 @@ export {
|
|
|
9797
11569
|
NOTE_TRACKINGS,
|
|
9798
11570
|
OfflineWorkerClient,
|
|
9799
11571
|
OfflineWorkerTask,
|
|
11572
|
+
PART_RIG_ALL_PARTS,
|
|
11573
|
+
PART_RIG_MODES,
|
|
9800
11574
|
PROJECT_AUTOMATION_TARGET_OPAQUE,
|
|
9801
11575
|
PROJECT_AUTOMATION_TARGET_TRACK_FADER_DB,
|
|
9802
11576
|
PROJECT_AUTOMATION_TARGET_TRACK_PAN,
|
|
@@ -9806,6 +11580,7 @@ export {
|
|
|
9806
11580
|
PlaybackRenderer,
|
|
9807
11581
|
PolyphonicAnalysis,
|
|
9808
11582
|
Project,
|
|
11583
|
+
ProjectTimeline,
|
|
9809
11584
|
RealtimeEngine,
|
|
9810
11585
|
RealtimeVoiceChanger,
|
|
9811
11586
|
SAMPLE_KEY_TRACKS,
|
|
@@ -9825,6 +11600,14 @@ export {
|
|
|
9825
11600
|
StreamingEqualizer,
|
|
9826
11601
|
StreamingMasteringChain,
|
|
9827
11602
|
StreamingRetune,
|
|
11603
|
+
VocalEditDraft,
|
|
11604
|
+
VocalEditSession,
|
|
11605
|
+
VocalEditWorkerClient,
|
|
11606
|
+
VocalEditWorkerSession,
|
|
11607
|
+
VocalEditWorkerStaleResultError,
|
|
11608
|
+
VocalEditWorkerTask,
|
|
11609
|
+
VocalRenderJob,
|
|
11610
|
+
VocalRenderSnapshot,
|
|
9828
11611
|
abiVersion,
|
|
9829
11612
|
alignTakeToReference,
|
|
9830
11613
|
amplitudeToDb,
|
|
@@ -9856,6 +11639,7 @@ export {
|
|
|
9856
11639
|
cqtToAudio,
|
|
9857
11640
|
createOpfsClipPageProvider,
|
|
9858
11641
|
createOpfsClipPageWorker,
|
|
11642
|
+
createVocalEditSession,
|
|
9859
11643
|
cyclicTempogram,
|
|
9860
11644
|
dbToAmplitude,
|
|
9861
11645
|
dbToPower,
|
|
@@ -10046,6 +11830,7 @@ export {
|
|
|
10046
11830
|
renderPercussiveEvents,
|
|
10047
11831
|
renderPlayback,
|
|
10048
11832
|
resample,
|
|
11833
|
+
restoreVocalEditSession,
|
|
10049
11834
|
rmsEnergy,
|
|
10050
11835
|
roomMorph,
|
|
10051
11836
|
samplesToFrames,
|
|
@@ -10095,6 +11880,8 @@ export {
|
|
|
10095
11880
|
validateRealtimeVoiceChangerPresetJson,
|
|
10096
11881
|
vectorNormalize,
|
|
10097
11882
|
version,
|
|
11883
|
+
vocalEditApiVersion,
|
|
11884
|
+
vocalEditAvailable,
|
|
10098
11885
|
voiceChange,
|
|
10099
11886
|
voiceChangeRealtime,
|
|
10100
11887
|
voiceChangerAbiVersion,
|