@libraz/libsonare 1.5.5 → 1.7.0
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 +109 -20
- package/dist/analysis.d.ts +5809 -0
- package/dist/analysis.js +2574 -0
- package/dist/analysis.js.map +1 -0
- package/dist/index.d.ts +884 -55
- package/dist/index.js +1302 -292
- package/dist/index.js.map +1 -1
- package/dist/schemas/realtime-voice-changer-preset-pack.schema.json +27 -0
- package/dist/schemas/realtime-voice-changer-preset.schema.json +140 -0
- package/dist/sonare-analysis.js +2 -0
- package/dist/sonare-analysis.wasm +0 -0
- package/dist/sonare.js +1 -1
- package/dist/sonare.wasm +0 -0
- package/dist/worker.d.ts +65 -0
- package/dist/worker.js +734 -0
- package/dist/worker.js.map +1 -0
- package/dist/worklet.d.ts +628 -88
- package/dist/worklet.js +1816 -266
- package/dist/worklet.js.map +1 -1
- package/package.json +23 -11
- package/src/_chain_config.ts +5 -3
- package/src/analysis.ts +137 -0
- package/src/analysis_helpers.ts +40 -29
- package/src/audio.ts +7 -2
- package/src/clip_page_streamer.ts +62 -8
- package/src/codes.ts +87 -64
- package/src/effects_mastering.ts +1 -0
- package/src/effects_transform.ts +179 -10
- package/src/errors.ts +1 -0
- package/src/feature_core.ts +140 -2
- package/src/feature_music.ts +25 -3
- package/src/feature_pitch.ts +70 -1
- package/src/feature_spectral.ts +295 -7
- package/src/feature_spectrogram.ts +203 -3
- package/src/features.ts +16 -1
- package/src/index.ts +120 -8
- package/src/mastering_chain.ts +20 -8
- package/src/mastering_core.ts +5 -0
- package/src/mastering_dynamics.ts +7 -1
- package/src/metering.ts +6 -1
- package/src/mixer.ts +3 -3
- package/src/opfs_clip_pages.ts +26 -1
- package/src/project.ts +13 -0
- package/src/project_class.ts +204 -23
- package/src/project_internal.ts +38 -34
- package/src/project_types.ts +114 -11
- package/src/public_types.ts +68 -0
- package/src/public_types_mastering.ts +22 -0
- package/src/public_types_mixing.ts +27 -2
- package/src/public_types_music.ts +9 -0
- package/src/public_types_realtime.ts +23 -5
- package/src/public_types_spectral.ts +33 -0
- package/src/quick_analysis.ts +46 -10
- package/src/realtime_engine.ts +167 -6
- package/src/realtime_voice_changer.ts +51 -77
- package/src/sonare-analysis.js.d.ts +8 -0
- package/src/sonare.js.d.ts +340 -6
- package/src/stream_analyzer.ts +6 -1
- package/src/streaming_processors.ts +15 -0
- package/src/web_midi.ts +46 -11
- package/src/worker.ts +196 -0
- package/src/worker_client.ts +352 -0
- package/src/worker_protocol.ts +59 -0
- package/src/worklet/engine-automation.ts +2 -1
- package/src/worklet/engine-capture-facade.ts +13 -4
- package/src/worklet/engine-clips.ts +12 -3
- package/src/worklet/engine-node.ts +264 -21
- package/src/worklet/engine-offline.ts +7 -2
- package/src/worklet/engine-parameter-facade.ts +55 -5
- package/src/worklet/engine-processor.ts +435 -62
- package/src/worklet/engine-register.ts +9 -1
- package/src/worklet/engine-strips.ts +19 -3
- package/src/worklet/engine-sync.ts +2 -6
- package/src/worklet/engine-tempo-facade.ts +8 -6
- package/src/worklet/engine.ts +390 -13
- package/src/worklet/guards.ts +121 -8
- package/src/worklet/messages.ts +166 -8
- package/src/worklet/protocol.ts +305 -17
- package/src/worklet/voice-changer-processor.ts +12 -15
- package/src/worklet.ts +20 -1
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
|
|
|
8
8
|
ErrorCode2[ErrorCode2["OutOfMemory"] = 5] = "OutOfMemory";
|
|
9
9
|
ErrorCode2[ErrorCode2["NotSupported"] = 6] = "NotSupported";
|
|
10
10
|
ErrorCode2[ErrorCode2["InvalidState"] = 7] = "InvalidState";
|
|
11
|
+
ErrorCode2[ErrorCode2["Cancelled"] = 8] = "Cancelled";
|
|
11
12
|
ErrorCode2[ErrorCode2["Unknown"] = 99] = "Unknown";
|
|
12
13
|
return ErrorCode2;
|
|
13
14
|
})(ErrorCode || {});
|
|
@@ -226,13 +227,59 @@ function assertInterleavedSamples(fnName, samples, channels, validate) {
|
|
|
226
227
|
function requireModule() {
|
|
227
228
|
return getSonareModule();
|
|
228
229
|
}
|
|
229
|
-
function
|
|
230
|
-
const
|
|
231
|
-
|
|
230
|
+
function resolveEffectFftOptions(fnName, nFft, hopLength) {
|
|
231
|
+
const resolvedNFft = nFft === void 0 ? 2048 : nFft;
|
|
232
|
+
const resolvedHopLength = hopLength === void 0 ? 512 : hopLength;
|
|
233
|
+
if (typeof resolvedNFft !== "number" || !Number.isInteger(resolvedNFft)) {
|
|
234
|
+
throw new TypeError(`${fnName}: nFft must be an integer`);
|
|
235
|
+
}
|
|
236
|
+
if (resolvedNFft < 2 || resolvedNFft > 2 ** 30) {
|
|
237
|
+
throw new RangeError(`${fnName}: nFft must be an even power of two >= 2`);
|
|
238
|
+
}
|
|
239
|
+
if ((resolvedNFft & resolvedNFft - 1) !== 0) {
|
|
240
|
+
throw new RangeError(`${fnName}: nFft must be an even power of two >= 2`);
|
|
241
|
+
}
|
|
242
|
+
if (typeof resolvedHopLength !== "number" || !Number.isInteger(resolvedHopLength)) {
|
|
243
|
+
throw new TypeError(`${fnName}: hopLength must be an integer`);
|
|
244
|
+
}
|
|
245
|
+
if (resolvedHopLength <= 0 || resolvedHopLength > 2 ** 31 - 1) {
|
|
246
|
+
throw new RangeError(`${fnName}: hopLength must be a positive integer`);
|
|
247
|
+
}
|
|
248
|
+
return { nFft: resolvedNFft, hopLength: resolvedHopLength };
|
|
249
|
+
}
|
|
250
|
+
function resolveNormalizeMode(value) {
|
|
251
|
+
if (value === void 0) {
|
|
252
|
+
return "peak";
|
|
253
|
+
}
|
|
254
|
+
if (typeof value !== "string") {
|
|
255
|
+
throw new TypeError("normalize: mode must be the string 'peak' or 'rms'");
|
|
256
|
+
}
|
|
257
|
+
if (value !== "peak" && value !== "rms") {
|
|
258
|
+
throw new RangeError("normalize: mode must be the string 'peak' or 'rms'");
|
|
259
|
+
}
|
|
260
|
+
return value;
|
|
261
|
+
}
|
|
262
|
+
function resolveHardMask(value, fnName) {
|
|
263
|
+
if (value === void 0) {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
if (typeof value !== "boolean") {
|
|
267
|
+
throw new TypeError(`${fnName}: hardMask must be a boolean`);
|
|
268
|
+
}
|
|
269
|
+
return value;
|
|
270
|
+
}
|
|
271
|
+
function hpss(samples, sampleRate = 22050, kernelHarmonic = 31, kernelPercussive = 31, nFft, hopLength, hardMask) {
|
|
272
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, kernelHarmonic, kernelPercussive, nFft, hopLength, hardMask } : samples;
|
|
273
|
+
const fftOptions = resolveEffectFftOptions("hpss", request.nFft, request.hopLength);
|
|
274
|
+
const resolvedHardMask = resolveHardMask(request.hardMask, "hpss");
|
|
275
|
+
return requireModule().hpssEx(
|
|
232
276
|
request.samples,
|
|
233
277
|
request.sampleRate ?? 22050,
|
|
234
278
|
request.kernelHarmonic ?? 31,
|
|
235
|
-
request.kernelPercussive ?? 31
|
|
279
|
+
request.kernelPercussive ?? 31,
|
|
280
|
+
fftOptions.nFft,
|
|
281
|
+
fftOptions.hopLength,
|
|
282
|
+
resolvedHardMask
|
|
236
283
|
);
|
|
237
284
|
}
|
|
238
285
|
function harmonic(samples, sampleRate = 22050, options = {}) {
|
|
@@ -245,18 +292,58 @@ function percussive(samples, sampleRate = 22050, options = {}) {
|
|
|
245
292
|
assertSamples("percussive", request.samples, request.validate !== false);
|
|
246
293
|
return requireModule().percussive(request.samples, request.sampleRate ?? 22050);
|
|
247
294
|
}
|
|
248
|
-
function timeStretch(samples, sampleRate, rate, options = {}) {
|
|
249
|
-
|
|
295
|
+
function timeStretch(samples, sampleRate, rate, nFftOrOptions, hopLength, options = {}) {
|
|
296
|
+
if (nFftOrOptions !== void 0 && nFftOrOptions !== null && typeof nFftOrOptions !== "number" && typeof nFftOrOptions !== "object") {
|
|
297
|
+
throw new TypeError("timeStretch: nFft must be an integer or options object");
|
|
298
|
+
}
|
|
299
|
+
if (nFftOrOptions === null) {
|
|
300
|
+
throw new TypeError("timeStretch: nFft must be an integer or options object");
|
|
301
|
+
}
|
|
302
|
+
const positionalOptions = typeof nFftOrOptions === "object" && nFftOrOptions !== null ? nFftOrOptions : options;
|
|
303
|
+
const positionalNFft = typeof nFftOrOptions === "number" ? nFftOrOptions : void 0;
|
|
304
|
+
const request = samples instanceof Float32Array ? {
|
|
305
|
+
samples,
|
|
306
|
+
sampleRate,
|
|
307
|
+
rate,
|
|
308
|
+
nFft: positionalNFft,
|
|
309
|
+
hopLength,
|
|
310
|
+
...positionalOptions
|
|
311
|
+
} : samples;
|
|
250
312
|
assertSamples("timeStretch", request.samples, request.validate !== false);
|
|
251
|
-
|
|
313
|
+
const fftOptions = resolveEffectFftOptions("timeStretch", request.nFft, request.hopLength);
|
|
314
|
+
return requireModule().timeStretchEx(
|
|
315
|
+
request.samples,
|
|
316
|
+
request.sampleRate ?? 22050,
|
|
317
|
+
request.rate,
|
|
318
|
+
fftOptions.nFft,
|
|
319
|
+
fftOptions.hopLength
|
|
320
|
+
);
|
|
252
321
|
}
|
|
253
|
-
function pitchShift(samples, sampleRate, semitones, options = {}) {
|
|
254
|
-
|
|
322
|
+
function pitchShift(samples, sampleRate, semitones, nFftOrOptions, hopLength, options = {}) {
|
|
323
|
+
if (nFftOrOptions !== void 0 && nFftOrOptions !== null && typeof nFftOrOptions !== "number" && typeof nFftOrOptions !== "object") {
|
|
324
|
+
throw new TypeError("pitchShift: nFft must be an integer or options object");
|
|
325
|
+
}
|
|
326
|
+
if (nFftOrOptions === null) {
|
|
327
|
+
throw new TypeError("pitchShift: nFft must be an integer or options object");
|
|
328
|
+
}
|
|
329
|
+
const positionalOptions = typeof nFftOrOptions === "object" && nFftOrOptions !== null ? nFftOrOptions : options;
|
|
330
|
+
const positionalNFft = typeof nFftOrOptions === "number" ? nFftOrOptions : void 0;
|
|
331
|
+
const request = samples instanceof Float32Array ? {
|
|
332
|
+
samples,
|
|
333
|
+
sampleRate,
|
|
334
|
+
semitones,
|
|
335
|
+
nFft: positionalNFft,
|
|
336
|
+
hopLength,
|
|
337
|
+
...positionalOptions
|
|
338
|
+
} : samples;
|
|
255
339
|
assertSamples("pitchShift", request.samples, request.validate !== false);
|
|
256
|
-
|
|
340
|
+
const fftOptions = resolveEffectFftOptions("pitchShift", request.nFft, request.hopLength);
|
|
341
|
+
return requireModule().pitchShiftEx(
|
|
257
342
|
request.samples,
|
|
258
343
|
request.sampleRate ?? 22050,
|
|
259
|
-
request.semitones
|
|
344
|
+
request.semitones,
|
|
345
|
+
fftOptions.nFft,
|
|
346
|
+
fftOptions.hopLength
|
|
260
347
|
);
|
|
261
348
|
}
|
|
262
349
|
function pitchCorrectToMidi(samples, sampleRate = 22050, currentMidi = 69, targetMidi = 69, options = {}) {
|
|
@@ -341,13 +428,23 @@ function noteMove(samples, sampleRate = 22050, options = {}) {
|
|
|
341
428
|
request.targetOnsetSample ?? 0
|
|
342
429
|
);
|
|
343
430
|
}
|
|
344
|
-
function normalize(samples, sampleRate, targetDb = 0, options = {}) {
|
|
345
|
-
|
|
431
|
+
function normalize(samples, sampleRate, targetDb = 0, modeOrOptions = "peak", options = {}) {
|
|
432
|
+
if (modeOrOptions !== void 0 && modeOrOptions !== null && typeof modeOrOptions !== "string" && typeof modeOrOptions !== "object") {
|
|
433
|
+
throw new TypeError("normalize: mode must be the string 'peak' or 'rms'");
|
|
434
|
+
}
|
|
435
|
+
if (modeOrOptions === null) {
|
|
436
|
+
throw new TypeError("normalize: mode must be the string 'peak' or 'rms'");
|
|
437
|
+
}
|
|
438
|
+
const positionalOptions = typeof modeOrOptions === "object" && modeOrOptions !== null ? modeOrOptions : options;
|
|
439
|
+
const positionalMode = typeof modeOrOptions === "string" ? modeOrOptions : void 0;
|
|
440
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, targetDb, mode: positionalMode, ...positionalOptions } : samples;
|
|
346
441
|
assertSamples("normalize", request.samples, request.validate !== false);
|
|
347
|
-
|
|
442
|
+
const mode = resolveNormalizeMode(request.mode);
|
|
443
|
+
return requireModule().normalizeEx(
|
|
348
444
|
request.samples,
|
|
349
445
|
request.sampleRate ?? 22050,
|
|
350
|
-
request.targetDb ?? 0
|
|
446
|
+
request.targetDb ?? 0,
|
|
447
|
+
mode
|
|
351
448
|
);
|
|
352
449
|
}
|
|
353
450
|
function spectralEdit(samples, sampleRate, ops = [], options = {}) {
|
|
@@ -405,6 +502,8 @@ function flattenChainConfig(config) {
|
|
|
405
502
|
out[path] = value;
|
|
406
503
|
} else if (value !== null && typeof value === "object") {
|
|
407
504
|
walk(value, path);
|
|
505
|
+
} else if (value !== void 0) {
|
|
506
|
+
throw new TypeError(`Mastering override '${path}' must be a number or boolean.`);
|
|
408
507
|
}
|
|
409
508
|
}
|
|
410
509
|
};
|
|
@@ -446,12 +545,14 @@ function masterAudioStereoRequest(requestOrLeft, right, sampleRate, preset, over
|
|
|
446
545
|
}
|
|
447
546
|
function masteringChain(samples, sampleRate = 22050, config = {}, onProgress) {
|
|
448
547
|
const request = samples instanceof Float32Array ? { samples, sampleRate, config, onProgress } : samples;
|
|
449
|
-
if (request.onProgress) {
|
|
548
|
+
if (request.onProgress || request.cancel) {
|
|
450
549
|
return requireModule3().masteringChainWithProgress(
|
|
451
550
|
request.samples,
|
|
452
551
|
request.sampleRate ?? 22050,
|
|
453
552
|
canonicalChainConfig(request.config ?? {}),
|
|
454
|
-
request.onProgress
|
|
553
|
+
request.onProgress ?? (() => {
|
|
554
|
+
}),
|
|
555
|
+
request.cancel ?? (() => false)
|
|
455
556
|
);
|
|
456
557
|
}
|
|
457
558
|
return requireModule3().masteringChain(
|
|
@@ -465,13 +566,15 @@ function masteringChainStereo(left, right, sampleRate = 22050, config = {}, onPr
|
|
|
465
566
|
if (request.left.length !== request.right.length) {
|
|
466
567
|
throw new Error("Stereo channel lengths must match.");
|
|
467
568
|
}
|
|
468
|
-
if (request.onProgress) {
|
|
569
|
+
if (request.onProgress || request.cancel) {
|
|
469
570
|
return requireModule3().masteringChainStereoWithProgress(
|
|
470
571
|
request.left,
|
|
471
572
|
request.right,
|
|
472
573
|
request.sampleRate ?? 22050,
|
|
473
574
|
canonicalChainConfig(request.config ?? {}),
|
|
474
|
-
request.onProgress
|
|
575
|
+
request.onProgress ?? (() => {
|
|
576
|
+
}),
|
|
577
|
+
request.cancel ?? (() => false)
|
|
475
578
|
);
|
|
476
579
|
}
|
|
477
580
|
return requireModule3().masteringChainStereo(
|
|
@@ -490,7 +593,8 @@ function masteringChainWithProgress(samples, sampleRate = 22050, config = {}, on
|
|
|
490
593
|
request.samples,
|
|
491
594
|
request.sampleRate ?? 22050,
|
|
492
595
|
canonicalChainConfig(request.config ?? {}),
|
|
493
|
-
request.onProgress
|
|
596
|
+
request.onProgress,
|
|
597
|
+
request.cancel ?? (() => false)
|
|
494
598
|
);
|
|
495
599
|
}
|
|
496
600
|
function masteringChainStereoWithProgress(left, right, sampleRate = 22050, config = {}, onProgress) {
|
|
@@ -506,7 +610,8 @@ function masteringChainStereoWithProgress(left, right, sampleRate = 22050, confi
|
|
|
506
610
|
request.right,
|
|
507
611
|
request.sampleRate ?? 22050,
|
|
508
612
|
canonicalChainConfig(request.config ?? {}),
|
|
509
|
-
request.onProgress
|
|
613
|
+
request.onProgress,
|
|
614
|
+
request.cancel ?? (() => false)
|
|
510
615
|
);
|
|
511
616
|
}
|
|
512
617
|
function masteringPresetNames() {
|
|
@@ -515,13 +620,15 @@ function masteringPresetNames() {
|
|
|
515
620
|
function masterAudio(samples, sampleRate = 22050, presetName = "pop", overrides = {}, onProgress) {
|
|
516
621
|
const request = masterAudioRequest(samples, sampleRate, presetName, overrides, onProgress);
|
|
517
622
|
const flat = flattenChainConfig(request.overrides ?? {});
|
|
518
|
-
if (request.onProgress) {
|
|
623
|
+
if (request.onProgress || request.cancel) {
|
|
519
624
|
return requireModule3().masterAudioWithProgress(
|
|
520
625
|
request.preset ?? "pop",
|
|
521
626
|
request.samples,
|
|
522
627
|
request.sampleRate ?? 22050,
|
|
523
628
|
flat,
|
|
524
|
-
request.onProgress
|
|
629
|
+
request.onProgress ?? (() => {
|
|
630
|
+
}),
|
|
631
|
+
request.cancel ?? (() => false)
|
|
525
632
|
);
|
|
526
633
|
}
|
|
527
634
|
return requireModule3().masterAudio(
|
|
@@ -544,14 +651,16 @@ function masterAudioStereo(left, right = void 0, sampleRate = 22050, presetName
|
|
|
544
651
|
if (request.left.length !== request.right.length) {
|
|
545
652
|
throw new Error("Stereo channel lengths must match.");
|
|
546
653
|
}
|
|
547
|
-
if (request.onProgress) {
|
|
654
|
+
if (request.onProgress || request.cancel) {
|
|
548
655
|
return requireModule3().masterAudioStereoWithProgress(
|
|
549
656
|
request.preset ?? "pop",
|
|
550
657
|
request.left,
|
|
551
658
|
request.right,
|
|
552
659
|
request.sampleRate ?? 22050,
|
|
553
660
|
flat,
|
|
554
|
-
request.onProgress
|
|
661
|
+
request.onProgress ?? (() => {
|
|
662
|
+
}),
|
|
663
|
+
request.cancel ?? (() => false)
|
|
555
664
|
);
|
|
556
665
|
}
|
|
557
666
|
return requireModule3().masterAudioStereo(
|
|
@@ -572,7 +681,8 @@ function masterAudioWithProgress(samples, sampleRate = 22050, presetName = "pop"
|
|
|
572
681
|
request.samples,
|
|
573
682
|
request.sampleRate ?? 22050,
|
|
574
683
|
flattenChainConfig(request.overrides ?? {}),
|
|
575
|
-
request.onProgress
|
|
684
|
+
request.onProgress,
|
|
685
|
+
request.cancel ?? (() => false)
|
|
576
686
|
);
|
|
577
687
|
}
|
|
578
688
|
function masterAudioStereoWithProgress(left, right = void 0, sampleRate = 22050, presetName = "pop", overrides = null, onProgress) {
|
|
@@ -596,7 +706,8 @@ function masterAudioStereoWithProgress(left, right = void 0, sampleRate = 22050,
|
|
|
596
706
|
request.right,
|
|
597
707
|
request.sampleRate ?? 22050,
|
|
598
708
|
flattenChainConfig(request.overrides ?? {}),
|
|
599
|
-
request.onProgress
|
|
709
|
+
request.onProgress,
|
|
710
|
+
request.cancel ?? (() => false)
|
|
600
711
|
);
|
|
601
712
|
}
|
|
602
713
|
|
|
@@ -759,7 +870,10 @@ function masteringDynamicsCompressor(samples, sampleRate, options = {}) {
|
|
|
759
870
|
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
760
871
|
assertSamples("masteringDynamicsCompressor", request.samples, request.validate !== false);
|
|
761
872
|
const detector = typeof request.detector === "string" ? COMPRESSOR_DETECTOR_MAP[request.detector] : request.detector;
|
|
762
|
-
const opts =
|
|
873
|
+
const opts = Object.assign(
|
|
874
|
+
Object.create(Object.getPrototypeOf(request)),
|
|
875
|
+
request
|
|
876
|
+
);
|
|
763
877
|
if (detector !== void 0) {
|
|
764
878
|
opts.detector = detector;
|
|
765
879
|
}
|
|
@@ -848,6 +962,36 @@ function mixStereo(leftChannels, rightChannels, sampleRate = 48e3, options = {})
|
|
|
848
962
|
function requireModule8() {
|
|
849
963
|
return getSonareModule();
|
|
850
964
|
}
|
|
965
|
+
function tone(frequency = 440, sampleRate = 22050, duration = 1, phase = 0, amplitude = 1) {
|
|
966
|
+
const request = typeof frequency === "number" ? { frequency, sampleRate, duration, phase, amplitude } : frequency;
|
|
967
|
+
return requireModule8().tone(
|
|
968
|
+
request.frequency ?? 440,
|
|
969
|
+
request.sampleRate ?? 22050,
|
|
970
|
+
request.duration ?? 1,
|
|
971
|
+
request.phase ?? 0,
|
|
972
|
+
request.amplitude ?? 1
|
|
973
|
+
);
|
|
974
|
+
}
|
|
975
|
+
function chirp(fmin = 440, fmax = 880, sampleRate = 22050, duration = 1, linear = true) {
|
|
976
|
+
const request = typeof fmin === "number" ? { fmin, fmax, sampleRate, duration, linear } : fmin;
|
|
977
|
+
return requireModule8().chirp(
|
|
978
|
+
request.fmin ?? 440,
|
|
979
|
+
request.fmax ?? 880,
|
|
980
|
+
request.sampleRate ?? 22050,
|
|
981
|
+
request.duration ?? 1,
|
|
982
|
+
request.linear ?? true
|
|
983
|
+
);
|
|
984
|
+
}
|
|
985
|
+
function clicks(times, sampleRate = 22050, length = 0, frequency = 1e3, clickDuration = 0.1) {
|
|
986
|
+
const request = times instanceof Float32Array ? { times, sampleRate, length, frequency, clickDuration } : times;
|
|
987
|
+
return requireModule8().clicks(
|
|
988
|
+
request.times,
|
|
989
|
+
request.sampleRate ?? 22050,
|
|
990
|
+
request.length ?? 0,
|
|
991
|
+
request.frequency ?? 1e3,
|
|
992
|
+
request.clickDuration ?? 0.1
|
|
993
|
+
);
|
|
994
|
+
}
|
|
851
995
|
function hzToMel(hz) {
|
|
852
996
|
return requireModule8().hzToMel(hz);
|
|
853
997
|
}
|
|
@@ -944,6 +1088,12 @@ function fixFrames(frames, xMin = 0, xMax = -1, pad = true) {
|
|
|
944
1088
|
}
|
|
945
1089
|
return requireModule8().fixFrames(frames, xMin, xMax, pad);
|
|
946
1090
|
}
|
|
1091
|
+
function onsetBacktrack(events, energy) {
|
|
1092
|
+
if (!(events instanceof Int32Array)) {
|
|
1093
|
+
return onsetBacktrack(events.events, events.energy);
|
|
1094
|
+
}
|
|
1095
|
+
return requireModule8().onsetBacktrack(events, energy);
|
|
1096
|
+
}
|
|
947
1097
|
function peakPick(values, preMax, postMax, preAvg, postAvg, delta, wait) {
|
|
948
1098
|
if (!(values instanceof Float32Array)) {
|
|
949
1099
|
const r = values;
|
|
@@ -988,12 +1138,28 @@ function tonnetz(chromagram, nChroma, nFrames) {
|
|
|
988
1138
|
}
|
|
989
1139
|
return requireModule8().tonnetz(chromagram, nChroma, nFrames);
|
|
990
1140
|
}
|
|
991
|
-
function tempogram(onsetEnvelope2, sampleRate = 22050, hopLength = 512, winLength = 384, mode = "autocorrelation") {
|
|
1141
|
+
function tempogram(onsetEnvelope2, sampleRate = 22050, hopLength = 512, winLength = 384, mode = "autocorrelation", center = true, norm = true) {
|
|
992
1142
|
if (!(onsetEnvelope2 instanceof Float32Array)) {
|
|
993
1143
|
const r = onsetEnvelope2;
|
|
994
|
-
return tempogram(
|
|
1144
|
+
return tempogram(
|
|
1145
|
+
r.onsetEnvelope,
|
|
1146
|
+
r.sampleRate,
|
|
1147
|
+
r.hopLength,
|
|
1148
|
+
r.winLength,
|
|
1149
|
+
r.mode,
|
|
1150
|
+
r.center,
|
|
1151
|
+
r.norm
|
|
1152
|
+
);
|
|
995
1153
|
}
|
|
996
|
-
return requireModule8().tempogram(
|
|
1154
|
+
return requireModule8().tempogram(
|
|
1155
|
+
onsetEnvelope2,
|
|
1156
|
+
sampleRate,
|
|
1157
|
+
hopLength,
|
|
1158
|
+
winLength,
|
|
1159
|
+
mode,
|
|
1160
|
+
center,
|
|
1161
|
+
norm
|
|
1162
|
+
);
|
|
997
1163
|
}
|
|
998
1164
|
function cyclicTempogram(onsetEnvelope2, sampleRate = 22050, hopLength = 512, winLength = 384, bpmMin = 60, nBins = 60) {
|
|
999
1165
|
if (!(onsetEnvelope2 instanceof Float32Array)) {
|
|
@@ -1054,12 +1220,18 @@ function nnlsChroma(samples, sampleRate = 22050, options = {}) {
|
|
|
1054
1220
|
return nnlsChroma(samples.samples, samples.sampleRate, samples);
|
|
1055
1221
|
}
|
|
1056
1222
|
validateMusicSamples("nnlsChroma", samples, sampleRate, options);
|
|
1057
|
-
|
|
1223
|
+
const hopLength = options.hopLength === void 0 ? 512 : options.hopLength;
|
|
1224
|
+
assertPositiveInteger("nnlsChroma", hopLength, "hopLength");
|
|
1225
|
+
if (hopLength > 2 ** 31 - 1) {
|
|
1226
|
+
throw new RangeError("nnlsChroma: hopLength must fit in a signed 32-bit integer");
|
|
1227
|
+
}
|
|
1228
|
+
return requireModule9().nnlsChromaEx(
|
|
1058
1229
|
samples,
|
|
1059
1230
|
sampleRate,
|
|
1060
1231
|
options.enableStftBlend ?? true,
|
|
1061
1232
|
options.stftBlendWeight ?? 0.55,
|
|
1062
|
-
options.stftBlendNFft ?? 4096
|
|
1233
|
+
options.stftBlendNFft ?? 4096,
|
|
1234
|
+
hopLength
|
|
1063
1235
|
);
|
|
1064
1236
|
}
|
|
1065
1237
|
function cqt(samples, sampleRate = 22050, hopLength = 512, fmin = 32.70319566257483, nBins = 84, binsPerOctave = 12, options = {}) {
|
|
@@ -1327,7 +1499,7 @@ function onsetStrengthMulti(samples, sampleRate = 22050, nFft = 2048, hopLength
|
|
|
1327
1499
|
validatePositiveIntegers("onsetStrengthMulti", { nFft, hopLength, nMels, nBands });
|
|
1328
1500
|
return requireModule9().onsetStrengthMulti(samples, sampleRate, nFft, hopLength, nMels, nBands);
|
|
1329
1501
|
}
|
|
1330
|
-
function fourierTempogram(onsetEnvelope2, sampleRate = 22050, hopLength = 512, winLength = 384, options = {}) {
|
|
1502
|
+
function fourierTempogram(onsetEnvelope2, sampleRate = 22050, hopLength = 512, winLength = 384, center = true, norm = true, options = {}) {
|
|
1331
1503
|
if (!(onsetEnvelope2 instanceof Float32Array)) {
|
|
1332
1504
|
const request = onsetEnvelope2;
|
|
1333
1505
|
return fourierTempogram(
|
|
@@ -1335,13 +1507,22 @@ function fourierTempogram(onsetEnvelope2, sampleRate = 22050, hopLength = 512, w
|
|
|
1335
1507
|
request.sampleRate,
|
|
1336
1508
|
request.hopLength,
|
|
1337
1509
|
request.winLength,
|
|
1510
|
+
request.center,
|
|
1511
|
+
request.norm,
|
|
1338
1512
|
request
|
|
1339
1513
|
);
|
|
1340
1514
|
}
|
|
1341
1515
|
assertSampleRate("fourierTempogram", sampleRate);
|
|
1342
1516
|
assertSamples("fourierTempogram", onsetEnvelope2, options.validate !== false, "onsetEnvelope");
|
|
1343
1517
|
validatePositiveIntegers("fourierTempogram", { hopLength, winLength });
|
|
1344
|
-
return requireModule9().fourierTempogram(
|
|
1518
|
+
return requireModule9().fourierTempogram(
|
|
1519
|
+
onsetEnvelope2,
|
|
1520
|
+
sampleRate,
|
|
1521
|
+
hopLength,
|
|
1522
|
+
winLength,
|
|
1523
|
+
center,
|
|
1524
|
+
norm
|
|
1525
|
+
);
|
|
1345
1526
|
}
|
|
1346
1527
|
function tempogramRatio(tempogramData, winLength = 384, sampleRate = 22050, hopLength = 512, factors, options = {}) {
|
|
1347
1528
|
if (!(tempogramData instanceof Float32Array)) {
|
|
@@ -1392,6 +1573,21 @@ function shortTermLufs(samples, sampleRate = 22050, options = {}) {
|
|
|
1392
1573
|
function requireModule10() {
|
|
1393
1574
|
return getSonareModule();
|
|
1394
1575
|
}
|
|
1576
|
+
function piptrack(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, fmin = 150, fmax = 4e3, threshold = 0.1) {
|
|
1577
|
+
if (!(samples instanceof Float32Array)) {
|
|
1578
|
+
const request = samples;
|
|
1579
|
+
return piptrack(
|
|
1580
|
+
request.samples,
|
|
1581
|
+
request.sampleRate,
|
|
1582
|
+
request.nFft,
|
|
1583
|
+
request.hopLength,
|
|
1584
|
+
request.fmin,
|
|
1585
|
+
request.fmax,
|
|
1586
|
+
request.threshold
|
|
1587
|
+
);
|
|
1588
|
+
}
|
|
1589
|
+
return requireModule10().piptrack(samples, sampleRate, nFft, hopLength, fmin, fmax, threshold);
|
|
1590
|
+
}
|
|
1395
1591
|
function pitchYin(samples, sampleRate = 22050, frameLength = 2048, hopLength = 512, fmin = 65, fmax = 2093, threshold = 0.1, fillNa = false) {
|
|
1396
1592
|
if (!(samples instanceof Float32Array)) {
|
|
1397
1593
|
const request = samples;
|
|
@@ -1442,6 +1638,13 @@ function pitchPyin(samples, sampleRate = 22050, frameLength = 2048, hopLength =
|
|
|
1442
1638
|
fillNa
|
|
1443
1639
|
);
|
|
1444
1640
|
}
|
|
1641
|
+
function noteSegments(request) {
|
|
1642
|
+
return requireModule10().noteSegments(request.f0Hz, request.voicedProb, request.frameRate, {
|
|
1643
|
+
segmentationThresholdCents: request.segmentationThresholdCents,
|
|
1644
|
+
minNoteMs: request.minNoteMs,
|
|
1645
|
+
referenceHz: request.referenceHz
|
|
1646
|
+
});
|
|
1647
|
+
}
|
|
1445
1648
|
|
|
1446
1649
|
// src/feature_resample.ts
|
|
1447
1650
|
function requireModule11() {
|
|
@@ -1458,6 +1661,44 @@ function resample(samples, srcSr, targetSr) {
|
|
|
1458
1661
|
function requireModule12() {
|
|
1459
1662
|
return getSonareModule();
|
|
1460
1663
|
}
|
|
1664
|
+
function resolveEffectFftOptions2(fnName, nFft, hopLength) {
|
|
1665
|
+
const resolvedNFft = nFft === void 0 ? 2048 : nFft;
|
|
1666
|
+
const resolvedHopLength = hopLength === void 0 ? 512 : hopLength;
|
|
1667
|
+
if (typeof resolvedNFft !== "number" || !Number.isInteger(resolvedNFft)) {
|
|
1668
|
+
throw new TypeError(`${fnName}: nFft must be an integer`);
|
|
1669
|
+
}
|
|
1670
|
+
if (resolvedNFft < 2 || resolvedNFft > 2 ** 30) {
|
|
1671
|
+
throw new RangeError(`${fnName}: nFft must be an even power of two >= 2`);
|
|
1672
|
+
}
|
|
1673
|
+
if ((resolvedNFft & resolvedNFft - 1) !== 0) {
|
|
1674
|
+
throw new RangeError(`${fnName}: nFft must be an even power of two >= 2`);
|
|
1675
|
+
}
|
|
1676
|
+
if (typeof resolvedHopLength !== "number" || !Number.isInteger(resolvedHopLength)) {
|
|
1677
|
+
throw new TypeError(`${fnName}: hopLength must be an integer`);
|
|
1678
|
+
}
|
|
1679
|
+
if (resolvedHopLength <= 0 || resolvedHopLength > 2 ** 31 - 1) {
|
|
1680
|
+
throw new RangeError(`${fnName}: hopLength must be a positive integer`);
|
|
1681
|
+
}
|
|
1682
|
+
return { nFft: resolvedNFft, hopLength: resolvedHopLength };
|
|
1683
|
+
}
|
|
1684
|
+
function resolveHardMask2(fnName, value) {
|
|
1685
|
+
if (value === void 0) {
|
|
1686
|
+
return false;
|
|
1687
|
+
}
|
|
1688
|
+
if (typeof value !== "boolean") {
|
|
1689
|
+
throw new TypeError(`${fnName}: hardMask must be a boolean`);
|
|
1690
|
+
}
|
|
1691
|
+
return value;
|
|
1692
|
+
}
|
|
1693
|
+
function validateSegmentMatrix(fnName, data, rows, cols, dataName) {
|
|
1694
|
+
assertPositiveInteger(fnName, rows, "rows");
|
|
1695
|
+
assertPositiveInteger(fnName, cols, "cols");
|
|
1696
|
+
assertSamples(fnName, data, true, dataName);
|
|
1697
|
+
const expected = rows * cols;
|
|
1698
|
+
if (!Number.isSafeInteger(expected) || data.length !== expected) {
|
|
1699
|
+
throw new RangeError(`${fnName}: ${dataName} length must equal rows * cols`);
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1461
1702
|
function spectralCentroid(samples, sampleRate = 22050, nFft = 2048, hopLength = 512) {
|
|
1462
1703
|
if (!(samples instanceof Float32Array)) {
|
|
1463
1704
|
return spectralCentroid(samples.samples, samples.sampleRate, samples.nFft, samples.hopLength);
|
|
@@ -1580,12 +1821,30 @@ function phaseVocoder(samples, sampleRate = 22050, rate = 1, nFft = 2048, hopLen
|
|
|
1580
1821
|
}
|
|
1581
1822
|
return requireModule12().phaseVocoder(samples, sampleRate, rate, nFft, hopLength);
|
|
1582
1823
|
}
|
|
1583
|
-
function hpssWithResidual(samples, sampleRate = 22050, kernelHarmonic = 31, kernelPercussive = 31) {
|
|
1824
|
+
function hpssWithResidual(samples, sampleRate = 22050, kernelHarmonic = 31, kernelPercussive = 31, nFft, hopLength, hardMask) {
|
|
1584
1825
|
if (!(samples instanceof Float32Array)) {
|
|
1585
1826
|
const r = samples;
|
|
1586
|
-
return hpssWithResidual(
|
|
1827
|
+
return hpssWithResidual(
|
|
1828
|
+
r.samples,
|
|
1829
|
+
r.sampleRate,
|
|
1830
|
+
r.kernelHarmonic,
|
|
1831
|
+
r.kernelPercussive,
|
|
1832
|
+
r.nFft,
|
|
1833
|
+
r.hopLength,
|
|
1834
|
+
r.hardMask
|
|
1835
|
+
);
|
|
1587
1836
|
}
|
|
1588
|
-
|
|
1837
|
+
const fftOptions = resolveEffectFftOptions2("hpssWithResidual", nFft, hopLength);
|
|
1838
|
+
const resolvedHardMask = resolveHardMask2("hpssWithResidual", hardMask);
|
|
1839
|
+
return requireModule12().hpssWithResidualEx(
|
|
1840
|
+
samples,
|
|
1841
|
+
sampleRate,
|
|
1842
|
+
kernelHarmonic,
|
|
1843
|
+
kernelPercussive,
|
|
1844
|
+
fftOptions.nFft,
|
|
1845
|
+
fftOptions.hopLength,
|
|
1846
|
+
resolvedHardMask
|
|
1847
|
+
);
|
|
1589
1848
|
}
|
|
1590
1849
|
function lufsInterleaved(samples, channels = 0, sampleRate = 22050, options = {}) {
|
|
1591
1850
|
if (!(samples instanceof Float32Array)) {
|
|
@@ -1602,11 +1861,17 @@ function ebur128LoudnessRange(samples, sampleRate = 22050) {
|
|
|
1602
1861
|
}
|
|
1603
1862
|
return requireModule12().ebur128LoudnessRange(samples, sampleRate);
|
|
1604
1863
|
}
|
|
1605
|
-
function spectralBandwidth(samples, sampleRate = 22050, nFft = 2048, hopLength = 512) {
|
|
1864
|
+
function spectralBandwidth(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, p = 2) {
|
|
1606
1865
|
if (!(samples instanceof Float32Array)) {
|
|
1607
|
-
return spectralBandwidth(
|
|
1866
|
+
return spectralBandwidth(
|
|
1867
|
+
samples.samples,
|
|
1868
|
+
samples.sampleRate,
|
|
1869
|
+
samples.nFft,
|
|
1870
|
+
samples.hopLength,
|
|
1871
|
+
samples.p
|
|
1872
|
+
);
|
|
1608
1873
|
}
|
|
1609
|
-
return requireModule12().spectralBandwidth(samples, sampleRate, nFft, hopLength);
|
|
1874
|
+
return requireModule12().spectralBandwidth(samples, sampleRate, nFft, hopLength, p);
|
|
1610
1875
|
}
|
|
1611
1876
|
function spectralRolloff(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, rollPercent = 0.85) {
|
|
1612
1877
|
if (!(samples instanceof Float32Array)) {
|
|
@@ -1626,6 +1891,18 @@ function spectralFlatness(samples, sampleRate = 22050, nFft = 2048, hopLength =
|
|
|
1626
1891
|
}
|
|
1627
1892
|
return requireModule12().spectralFlatness(samples, sampleRate, nFft, hopLength);
|
|
1628
1893
|
}
|
|
1894
|
+
function spectralFlux(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, lag = 1) {
|
|
1895
|
+
if (!(samples instanceof Float32Array)) {
|
|
1896
|
+
return spectralFlux(
|
|
1897
|
+
samples.samples,
|
|
1898
|
+
samples.sampleRate,
|
|
1899
|
+
samples.nFft,
|
|
1900
|
+
samples.hopLength,
|
|
1901
|
+
samples.lag
|
|
1902
|
+
);
|
|
1903
|
+
}
|
|
1904
|
+
return requireModule12().spectralFlux(samples, sampleRate, nFft, hopLength, lag);
|
|
1905
|
+
}
|
|
1629
1906
|
function zeroCrossingRate(samples, sampleRate = 22050, frameLength = 2048, hopLength = 512) {
|
|
1630
1907
|
if (!(samples instanceof Float32Array)) {
|
|
1631
1908
|
return zeroCrossingRate(
|
|
@@ -1643,6 +1920,107 @@ function rmsEnergy(samples, sampleRate = 22050, frameLength = 2048, hopLength =
|
|
|
1643
1920
|
}
|
|
1644
1921
|
return requireModule12().rmsEnergy(samples, sampleRate, frameLength, hopLength);
|
|
1645
1922
|
}
|
|
1923
|
+
function segmentCrossSimilarity(request) {
|
|
1924
|
+
validateSegmentMatrix("segmentCrossSimilarity", request.x, request.xRows, request.xCols, "x");
|
|
1925
|
+
validateSegmentMatrix("segmentCrossSimilarity", request.y, request.yRows, request.yCols, "y");
|
|
1926
|
+
if (request.xRows !== request.yRows) {
|
|
1927
|
+
throw new RangeError("segmentCrossSimilarity: feature dimensions must match");
|
|
1928
|
+
}
|
|
1929
|
+
assertNonNegativeInteger("segmentCrossSimilarity", request.k ?? 0, "k");
|
|
1930
|
+
return requireModule12().segmentCrossSimilarity(
|
|
1931
|
+
request.x,
|
|
1932
|
+
request.xRows,
|
|
1933
|
+
request.xCols,
|
|
1934
|
+
request.y,
|
|
1935
|
+
request.yRows,
|
|
1936
|
+
request.yCols,
|
|
1937
|
+
request.k ?? 0,
|
|
1938
|
+
request.metric ?? "cosine",
|
|
1939
|
+
request.mode ?? "connectivity"
|
|
1940
|
+
);
|
|
1941
|
+
}
|
|
1942
|
+
function segmentRecurrenceMatrix(request) {
|
|
1943
|
+
validateSegmentMatrix(
|
|
1944
|
+
"segmentRecurrenceMatrix",
|
|
1945
|
+
request.data,
|
|
1946
|
+
request.rows,
|
|
1947
|
+
request.cols,
|
|
1948
|
+
"data"
|
|
1949
|
+
);
|
|
1950
|
+
assertNonNegativeInteger("segmentRecurrenceMatrix", request.k ?? 0, "k");
|
|
1951
|
+
assertNonNegativeInteger("segmentRecurrenceMatrix", request.width ?? 1, "width");
|
|
1952
|
+
return requireModule12().segmentRecurrenceMatrix(
|
|
1953
|
+
request.data,
|
|
1954
|
+
request.rows,
|
|
1955
|
+
request.cols,
|
|
1956
|
+
request.k ?? 0,
|
|
1957
|
+
request.width ?? 1,
|
|
1958
|
+
request.sym ?? false,
|
|
1959
|
+
request.metric ?? "euclidean",
|
|
1960
|
+
request.mode ?? "connectivity"
|
|
1961
|
+
);
|
|
1962
|
+
}
|
|
1963
|
+
function segmentRecurrenceToLag(request) {
|
|
1964
|
+
validateSegmentMatrix(
|
|
1965
|
+
"segmentRecurrenceToLag",
|
|
1966
|
+
request.recurrence,
|
|
1967
|
+
request.n,
|
|
1968
|
+
request.n,
|
|
1969
|
+
"recurrence"
|
|
1970
|
+
);
|
|
1971
|
+
return requireModule12().segmentRecurrenceToLag(
|
|
1972
|
+
request.recurrence,
|
|
1973
|
+
request.n,
|
|
1974
|
+
request.pad ?? false
|
|
1975
|
+
);
|
|
1976
|
+
}
|
|
1977
|
+
function segmentLagToRecurrence(request) {
|
|
1978
|
+
validateSegmentMatrix("segmentLagToRecurrence", request.lag, request.rows, request.lags, "lag");
|
|
1979
|
+
return requireModule12().segmentLagToRecurrence(request.lag, request.rows, request.lags);
|
|
1980
|
+
}
|
|
1981
|
+
function segmentSubsegment(request) {
|
|
1982
|
+
validateSegmentMatrix("segmentSubsegment", request.data, request.rows, request.cols, "data");
|
|
1983
|
+
assertPositiveInteger("segmentSubsegment", request.nSegments ?? 4, "nSegments");
|
|
1984
|
+
return requireModule12().segmentSubsegment(
|
|
1985
|
+
request.data,
|
|
1986
|
+
request.rows,
|
|
1987
|
+
request.cols,
|
|
1988
|
+
request.boundaries,
|
|
1989
|
+
request.nSegments ?? 4
|
|
1990
|
+
);
|
|
1991
|
+
}
|
|
1992
|
+
function segmentAgglomerative(request) {
|
|
1993
|
+
validateSegmentMatrix("segmentAgglomerative", request.data, request.rows, request.cols, "data");
|
|
1994
|
+
assertPositiveInteger("segmentAgglomerative", request.k, "k");
|
|
1995
|
+
return requireModule12().segmentAgglomerative(
|
|
1996
|
+
request.data,
|
|
1997
|
+
request.rows,
|
|
1998
|
+
request.cols,
|
|
1999
|
+
request.k,
|
|
2000
|
+
request.linkage ?? "average"
|
|
2001
|
+
);
|
|
2002
|
+
}
|
|
2003
|
+
function segmentPathEnhance(request) {
|
|
2004
|
+
validateSegmentMatrix(
|
|
2005
|
+
"segmentPathEnhance",
|
|
2006
|
+
request.recurrence,
|
|
2007
|
+
request.n,
|
|
2008
|
+
request.n,
|
|
2009
|
+
"recurrence"
|
|
2010
|
+
);
|
|
2011
|
+
assertPositiveInteger("segmentPathEnhance", request.win, "win");
|
|
2012
|
+
assertPositiveInteger("segmentPathEnhance", request.maxRatio ?? 2, "maxRatio");
|
|
2013
|
+
assertNonNegativeInteger("segmentPathEnhance", request.minRatio ?? 0, "minRatio");
|
|
2014
|
+
assertPositiveInteger("segmentPathEnhance", request.nFilters ?? 7, "nFilters");
|
|
2015
|
+
return requireModule12().segmentPathEnhance(
|
|
2016
|
+
request.recurrence,
|
|
2017
|
+
request.n,
|
|
2018
|
+
request.win,
|
|
2019
|
+
request.maxRatio ?? 2,
|
|
2020
|
+
request.minRatio ?? 0,
|
|
2021
|
+
request.nFilters ?? 7
|
|
2022
|
+
);
|
|
2023
|
+
}
|
|
1646
2024
|
|
|
1647
2025
|
// src/feature_spectrogram.ts
|
|
1648
2026
|
function requireModule13() {
|
|
@@ -1679,14 +2057,35 @@ function validateMatrix(fnName, data, rows, frames, dataName, rowName, options =
|
|
|
1679
2057
|
throw new RangeError(`${fnName}: ${dataName} length must equal ${rowName} * nFrames`);
|
|
1680
2058
|
}
|
|
1681
2059
|
}
|
|
1682
|
-
function trim(samples, sampleRate = 22050, thresholdDb = -60, options = {}) {
|
|
2060
|
+
function trim(samples, sampleRate = 22050, thresholdDb = -60, frameLengthOrOptions, hopLength, options = {}) {
|
|
1683
2061
|
if (!(samples instanceof Float32Array)) {
|
|
1684
2062
|
const r = samples;
|
|
1685
|
-
return trim(r.samples, r.sampleRate, r.thresholdDb, r);
|
|
2063
|
+
return trim(r.samples, r.sampleRate, r.thresholdDb, r.frameLength, r.hopLength, r);
|
|
2064
|
+
}
|
|
2065
|
+
if (frameLengthOrOptions === null) {
|
|
2066
|
+
throw new TypeError("trim: frameLength must be an integer or options object");
|
|
2067
|
+
}
|
|
2068
|
+
if (frameLengthOrOptions !== void 0 && typeof frameLengthOrOptions !== "number" && typeof frameLengthOrOptions !== "object") {
|
|
2069
|
+
throw new TypeError("trim: frameLength must be an integer or options object");
|
|
1686
2070
|
}
|
|
1687
|
-
|
|
2071
|
+
const positionalOptions = typeof frameLengthOrOptions === "object" && frameLengthOrOptions !== null ? frameLengthOrOptions : options;
|
|
2072
|
+
const positionalFrameLength = typeof frameLengthOrOptions === "number" ? frameLengthOrOptions : void 0;
|
|
2073
|
+
const resolvedFrameLength = positionalFrameLength ?? 2048;
|
|
2074
|
+
const resolvedHopLength = hopLength === void 0 ? 512 : hopLength;
|
|
2075
|
+
validateSpectrogramSamples("trim", samples, sampleRate, positionalOptions);
|
|
1688
2076
|
assertFiniteScalar("trim", thresholdDb, "thresholdDb");
|
|
1689
|
-
|
|
2077
|
+
assertPositiveInteger("trim", resolvedFrameLength, "frameLength");
|
|
2078
|
+
assertPositiveInteger("trim", resolvedHopLength, "hopLength");
|
|
2079
|
+
if (resolvedFrameLength > 2 ** 31 - 1 || resolvedHopLength > 2 ** 31 - 1) {
|
|
2080
|
+
throw new RangeError("trim: frameLength and hopLength must fit in a signed 32-bit integer");
|
|
2081
|
+
}
|
|
2082
|
+
return requireModule13().trimEx(
|
|
2083
|
+
samples,
|
|
2084
|
+
sampleRate,
|
|
2085
|
+
thresholdDb,
|
|
2086
|
+
resolvedFrameLength,
|
|
2087
|
+
resolvedHopLength
|
|
2088
|
+
);
|
|
1690
2089
|
}
|
|
1691
2090
|
function stft(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, options = {}) {
|
|
1692
2091
|
if (!(samples instanceof Float32Array)) {
|
|
@@ -1821,6 +2220,53 @@ function mfcc(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, nMels =
|
|
|
1821
2220
|
lifter
|
|
1822
2221
|
);
|
|
1823
2222
|
}
|
|
2223
|
+
function melDelta(features, nFeatures, nFrames, width = 9) {
|
|
2224
|
+
const request = features instanceof Float32Array ? { features, nFeatures: nFeatures ?? 0, nFrames: nFrames ?? 0, width } : features;
|
|
2225
|
+
assertPositiveInteger("melDelta", request.nFeatures, "nFeatures");
|
|
2226
|
+
assertPositiveInteger("melDelta", request.nFrames, "nFrames");
|
|
2227
|
+
assertPositiveInteger("melDelta", request.width ?? 9, "width");
|
|
2228
|
+
if ((request.width ?? 9) < 3 || (request.width ?? 9) % 2 === 0) {
|
|
2229
|
+
throw new RangeError("melDelta: width must be an odd integer of at least 3");
|
|
2230
|
+
}
|
|
2231
|
+
if (request.features.length !== request.nFeatures * request.nFrames) {
|
|
2232
|
+
throw new RangeError("melDelta: feature matrix length must equal nFeatures * nFrames");
|
|
2233
|
+
}
|
|
2234
|
+
return requireModule13().melDelta(
|
|
2235
|
+
request.features,
|
|
2236
|
+
request.nFeatures,
|
|
2237
|
+
request.nFrames,
|
|
2238
|
+
request.width ?? 9
|
|
2239
|
+
);
|
|
2240
|
+
}
|
|
2241
|
+
function reassignedSpectrogram(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, refPower = 1e-6, fillNan = false) {
|
|
2242
|
+
if (!(samples instanceof Float32Array)) {
|
|
2243
|
+
const request = samples;
|
|
2244
|
+
return reassignedSpectrogram(
|
|
2245
|
+
request.samples,
|
|
2246
|
+
request.sampleRate,
|
|
2247
|
+
request.nFft,
|
|
2248
|
+
request.hopLength,
|
|
2249
|
+
request.refPower,
|
|
2250
|
+
request.fillNan
|
|
2251
|
+
);
|
|
2252
|
+
}
|
|
2253
|
+
assertSamples("reassignedSpectrogram", samples, true);
|
|
2254
|
+
assertSampleRate("reassignedSpectrogram", sampleRate);
|
|
2255
|
+
assertPositiveInteger("reassignedSpectrogram", nFft, "nFft");
|
|
2256
|
+
assertPositiveInteger("reassignedSpectrogram", hopLength, "hopLength");
|
|
2257
|
+
assertFiniteScalar("reassignedSpectrogram", refPower, "refPower");
|
|
2258
|
+
if (refPower < 0) {
|
|
2259
|
+
throw new RangeError("reassignedSpectrogram: refPower must be non-negative");
|
|
2260
|
+
}
|
|
2261
|
+
return requireModule13().reassignedSpectrogram(
|
|
2262
|
+
samples,
|
|
2263
|
+
sampleRate,
|
|
2264
|
+
nFft,
|
|
2265
|
+
hopLength,
|
|
2266
|
+
refPower,
|
|
2267
|
+
fillNan
|
|
2268
|
+
);
|
|
2269
|
+
}
|
|
1824
2270
|
function melToStft(melPower, nMels = 0, nFrames = 0, sampleRate = 22050, nFft = 2048, fmin = 0, fmax = 0, htk = false, options = {}) {
|
|
1825
2271
|
if (!(melPower instanceof Float32Array)) {
|
|
1826
2272
|
const request = melPower;
|
|
@@ -1876,6 +2322,35 @@ function melToAudio(melPower, nMels = 0, nFrames = 0, sampleRate = 22050, nFft =
|
|
|
1876
2322
|
htk
|
|
1877
2323
|
);
|
|
1878
2324
|
}
|
|
2325
|
+
function griffinLim(magnitude, nBins = 0, nFrames = 0, sampleRate = 22050, nFft = 2048, hopLength = 512, nIter = 32, momentum = 0.99, options = {}) {
|
|
2326
|
+
if (!(magnitude instanceof Float32Array)) {
|
|
2327
|
+
const request = magnitude;
|
|
2328
|
+
return griffinLim(
|
|
2329
|
+
request.magnitude,
|
|
2330
|
+
request.nBins,
|
|
2331
|
+
request.nFrames,
|
|
2332
|
+
request.sampleRate,
|
|
2333
|
+
request.nFft,
|
|
2334
|
+
request.hopLength,
|
|
2335
|
+
request.nIter,
|
|
2336
|
+
request.momentum,
|
|
2337
|
+
request
|
|
2338
|
+
);
|
|
2339
|
+
}
|
|
2340
|
+
assertSampleRate("griffinLim", sampleRate);
|
|
2341
|
+
validateMatrix("griffinLim", magnitude, nBins, nFrames, "magnitude", "nBins", options);
|
|
2342
|
+
validatePositiveIntegers2("griffinLim", { nFft, hopLength, nIter });
|
|
2343
|
+
return requireModule13().griffinLim(
|
|
2344
|
+
magnitude,
|
|
2345
|
+
nBins,
|
|
2346
|
+
nFrames,
|
|
2347
|
+
sampleRate,
|
|
2348
|
+
nFft,
|
|
2349
|
+
hopLength,
|
|
2350
|
+
nIter,
|
|
2351
|
+
momentum
|
|
2352
|
+
);
|
|
2353
|
+
}
|
|
1879
2354
|
function mfccToMel(mfccCoefficients, nMfcc = 0, nFrames = 0, nMels = 128, lifter = 0, options = {}) {
|
|
1880
2355
|
if (!(mfccCoefficients instanceof Float32Array)) {
|
|
1881
2356
|
const request = mfccCoefficients;
|
|
@@ -1956,6 +2431,88 @@ function chroma(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, optio
|
|
|
1956
2431
|
return requireModule13().chroma(samples, sampleRate, nFft, hopLength);
|
|
1957
2432
|
}
|
|
1958
2433
|
|
|
2434
|
+
// src/codes.ts
|
|
2435
|
+
function resolveOrdinalInRange(value, min, max, enumName) {
|
|
2436
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < min || value > max) {
|
|
2437
|
+
throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
|
|
2438
|
+
}
|
|
2439
|
+
return value;
|
|
2440
|
+
}
|
|
2441
|
+
function resolveEnumOrdinal(value, values, enumName) {
|
|
2442
|
+
if (typeof value === "number") {
|
|
2443
|
+
const ordinals = Object.values(values);
|
|
2444
|
+
const ordinal = resolveOrdinalInRange(
|
|
2445
|
+
value,
|
|
2446
|
+
Math.min(...ordinals),
|
|
2447
|
+
Math.max(...ordinals),
|
|
2448
|
+
enumName
|
|
2449
|
+
);
|
|
2450
|
+
if (!ordinals.includes(ordinal)) {
|
|
2451
|
+
throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
|
|
2452
|
+
}
|
|
2453
|
+
return ordinal;
|
|
2454
|
+
}
|
|
2455
|
+
if (typeof value === "string") {
|
|
2456
|
+
const ordinal = values[value];
|
|
2457
|
+
if (ordinal !== void 0) {
|
|
2458
|
+
return ordinal;
|
|
2459
|
+
}
|
|
2460
|
+
}
|
|
2461
|
+
throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
|
|
2462
|
+
}
|
|
2463
|
+
var AUTOMATION_CURVE_VALUES = {
|
|
2464
|
+
linear: 0,
|
|
2465
|
+
exponential: 1,
|
|
2466
|
+
hold: 2,
|
|
2467
|
+
"s-curve": 3
|
|
2468
|
+
};
|
|
2469
|
+
var PAN_LAW_VALUES = {
|
|
2470
|
+
const3db: 0,
|
|
2471
|
+
"const-3db": 0,
|
|
2472
|
+
"-3db": 0,
|
|
2473
|
+
"const4.5db": 1,
|
|
2474
|
+
"const-4.5db": 1,
|
|
2475
|
+
"-4.5db": 1,
|
|
2476
|
+
const6db: 2,
|
|
2477
|
+
"const-6db": 2,
|
|
2478
|
+
"-6db": 2,
|
|
2479
|
+
linear0db: 3,
|
|
2480
|
+
"linear-0db": 3,
|
|
2481
|
+
linear: 3,
|
|
2482
|
+
"0db": 3
|
|
2483
|
+
};
|
|
2484
|
+
var PAN_MODE_VALUES = {
|
|
2485
|
+
balance: 0,
|
|
2486
|
+
pan: 1,
|
|
2487
|
+
stereopan: 1,
|
|
2488
|
+
"stereo-pan": 1,
|
|
2489
|
+
dualpan: 2,
|
|
2490
|
+
"dual-pan": 2
|
|
2491
|
+
};
|
|
2492
|
+
var METER_TAP_VALUES = { preFader: 0, postFader: 1 };
|
|
2493
|
+
var SEND_TIMING_VALUES = { postFader: 0, preFader: 1 };
|
|
2494
|
+
var TRACK_MONITOR_MODE_VALUES = { off: 0, pfl: 1, afl: 2 };
|
|
2495
|
+
function automationCurveCode(curve) {
|
|
2496
|
+
return resolveEnumOrdinal(curve, AUTOMATION_CURVE_VALUES, "automation curve");
|
|
2497
|
+
}
|
|
2498
|
+
function panLawCode(panLaw) {
|
|
2499
|
+
const normalized = typeof panLaw === "string" ? panLaw.toLowerCase().replace(/_/g, "-") : panLaw;
|
|
2500
|
+
return resolveEnumOrdinal(normalized, PAN_LAW_VALUES, "pan law");
|
|
2501
|
+
}
|
|
2502
|
+
function panModeCode(panMode) {
|
|
2503
|
+
const normalized = typeof panMode === "string" ? panMode.replace(/_/g, "-").toLowerCase() : panMode;
|
|
2504
|
+
return resolveEnumOrdinal(normalized, PAN_MODE_VALUES, "pan mode");
|
|
2505
|
+
}
|
|
2506
|
+
function meterTapCode(tap) {
|
|
2507
|
+
return resolveEnumOrdinal(tap, METER_TAP_VALUES, "meter tap");
|
|
2508
|
+
}
|
|
2509
|
+
function sendTimingCode(timing) {
|
|
2510
|
+
return resolveEnumOrdinal(timing, SEND_TIMING_VALUES, "send timing");
|
|
2511
|
+
}
|
|
2512
|
+
function trackMonitorModeCode(mode) {
|
|
2513
|
+
return resolveEnumOrdinal(mode, TRACK_MONITOR_MODE_VALUES, "track monitor mode");
|
|
2514
|
+
}
|
|
2515
|
+
|
|
1959
2516
|
// src/public_types_music.ts
|
|
1960
2517
|
var PitchClass = {
|
|
1961
2518
|
C: 0,
|
|
@@ -2049,6 +2606,30 @@ function convertKeyCandidate(wasm) {
|
|
|
2049
2606
|
correlation: wasm.correlation
|
|
2050
2607
|
};
|
|
2051
2608
|
}
|
|
2609
|
+
var KEY_MODE_VALUES = {
|
|
2610
|
+
major: Mode.Major,
|
|
2611
|
+
minor: Mode.Minor,
|
|
2612
|
+
dorian: Mode.Dorian,
|
|
2613
|
+
phrygian: Mode.Phrygian,
|
|
2614
|
+
lydian: Mode.Lydian,
|
|
2615
|
+
mixolydian: Mode.Mixolydian,
|
|
2616
|
+
locrian: Mode.Locrian
|
|
2617
|
+
};
|
|
2618
|
+
var KEY_PROFILE_VALUES = {
|
|
2619
|
+
ks: KeyProfile.KrumhanslSchmuckler,
|
|
2620
|
+
krumhansl: KeyProfile.KrumhanslSchmuckler,
|
|
2621
|
+
temperley: KeyProfile.Temperley,
|
|
2622
|
+
shaath: KeyProfile.Shaath,
|
|
2623
|
+
keyfinder: KeyProfile.Shaath,
|
|
2624
|
+
"faraldo-edmt": KeyProfile.FaraldoEDMT,
|
|
2625
|
+
edmt: KeyProfile.FaraldoEDMT,
|
|
2626
|
+
"faraldo-edma": KeyProfile.FaraldoEDMA,
|
|
2627
|
+
edma: KeyProfile.FaraldoEDMA,
|
|
2628
|
+
"faraldo-edmm": KeyProfile.FaraldoEDMM,
|
|
2629
|
+
edmm: KeyProfile.FaraldoEDMM,
|
|
2630
|
+
"bellman-budge": KeyProfile.BellmanBudge,
|
|
2631
|
+
bellman: KeyProfile.BellmanBudge
|
|
2632
|
+
};
|
|
2052
2633
|
function keyModeValues(modes) {
|
|
2053
2634
|
if (!modes) {
|
|
2054
2635
|
return [];
|
|
@@ -2067,40 +2648,13 @@ function keyModeValues(modes) {
|
|
|
2067
2648
|
Mode.Locrian
|
|
2068
2649
|
];
|
|
2069
2650
|
}
|
|
2070
|
-
|
|
2071
|
-
major: Mode.Major,
|
|
2072
|
-
minor: Mode.Minor,
|
|
2073
|
-
dorian: Mode.Dorian,
|
|
2074
|
-
phrygian: Mode.Phrygian,
|
|
2075
|
-
lydian: Mode.Lydian,
|
|
2076
|
-
mixolydian: Mode.Mixolydian,
|
|
2077
|
-
locrian: Mode.Locrian
|
|
2078
|
-
};
|
|
2079
|
-
return modes.map((mode) => typeof mode === "number" ? mode : names[mode]);
|
|
2651
|
+
return modes.map((mode) => resolveEnumOrdinal(mode, KEY_MODE_VALUES, "key mode"));
|
|
2080
2652
|
}
|
|
2081
2653
|
function keyProfileValue(profile) {
|
|
2082
2654
|
if (profile === void 0) {
|
|
2083
2655
|
return -1;
|
|
2084
2656
|
}
|
|
2085
|
-
|
|
2086
|
-
return profile;
|
|
2087
|
-
}
|
|
2088
|
-
const names = {
|
|
2089
|
-
ks: KeyProfile.KrumhanslSchmuckler,
|
|
2090
|
-
krumhansl: KeyProfile.KrumhanslSchmuckler,
|
|
2091
|
-
temperley: KeyProfile.Temperley,
|
|
2092
|
-
shaath: KeyProfile.Shaath,
|
|
2093
|
-
keyfinder: KeyProfile.Shaath,
|
|
2094
|
-
"faraldo-edmt": KeyProfile.FaraldoEDMT,
|
|
2095
|
-
edmt: KeyProfile.FaraldoEDMT,
|
|
2096
|
-
"faraldo-edma": KeyProfile.FaraldoEDMA,
|
|
2097
|
-
edma: KeyProfile.FaraldoEDMA,
|
|
2098
|
-
"faraldo-edmm": KeyProfile.FaraldoEDMM,
|
|
2099
|
-
edmm: KeyProfile.FaraldoEDMM,
|
|
2100
|
-
"bellman-budge": KeyProfile.BellmanBudge,
|
|
2101
|
-
bellman: KeyProfile.BellmanBudge
|
|
2102
|
-
};
|
|
2103
|
-
return names[profile];
|
|
2657
|
+
return resolveEnumOrdinal(profile, KEY_PROFILE_VALUES, "key profile");
|
|
2104
2658
|
}
|
|
2105
2659
|
function convertChordAnalysisResult(wasm) {
|
|
2106
2660
|
return {
|
|
@@ -2134,6 +2688,11 @@ function convertAnalysisResult(wasm) {
|
|
|
2134
2688
|
return {
|
|
2135
2689
|
bpm: wasm.bpm,
|
|
2136
2690
|
bpmConfidence: wasm.bpmConfidence,
|
|
2691
|
+
bpmCandidates: wasm.bpmCandidates.map((candidate) => ({
|
|
2692
|
+
value: candidate.value,
|
|
2693
|
+
confidence: candidate.confidence,
|
|
2694
|
+
relation: candidate.relation
|
|
2695
|
+
})),
|
|
2137
2696
|
key: {
|
|
2138
2697
|
root: wasm.key.root,
|
|
2139
2698
|
mode: wasm.key.mode,
|
|
@@ -2142,6 +2701,7 @@ function convertAnalysisResult(wasm) {
|
|
|
2142
2701
|
shortName: wasm.key.shortName
|
|
2143
2702
|
},
|
|
2144
2703
|
timeSignature: wasm.timeSignature,
|
|
2704
|
+
timeSignatureCandidates: wasm.timeSignatureCandidates,
|
|
2145
2705
|
beatTimes,
|
|
2146
2706
|
beats: wasm.beats,
|
|
2147
2707
|
chords: wasm.chords.map((c) => ({
|
|
@@ -2232,7 +2792,7 @@ function detectKeyCandidates(samples, sampleRate = 22050, options = {}) {
|
|
|
2232
2792
|
function detectOnsets(samples, sampleRate = 22050, options = {}) {
|
|
2233
2793
|
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
2234
2794
|
validateAnalysisInput("detectOnsets", request.samples, request.sampleRate ?? 22050, request);
|
|
2235
|
-
return requireModule14().detectOnsets(request.samples, request.sampleRate ?? 22050);
|
|
2795
|
+
return requireModule14().detectOnsets(request.samples, request.sampleRate ?? 22050, request);
|
|
2236
2796
|
}
|
|
2237
2797
|
function detectBeats(samples, sampleRate = 22050, options = {}) {
|
|
2238
2798
|
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
@@ -2300,18 +2860,27 @@ function analyze(samples, sampleRate = 22050, options = {}) {
|
|
|
2300
2860
|
const result = requireModule14().analyze(request.samples, request.sampleRate ?? 22050, request);
|
|
2301
2861
|
return convertAnalysisResult(result);
|
|
2302
2862
|
}
|
|
2303
|
-
function analyzeImpulseResponse(samples, sampleRate = 48e3, nOctaveBands = 6) {
|
|
2304
|
-
const request = samples instanceof Float32Array ? { samples, sampleRate, nOctaveBands } : samples;
|
|
2863
|
+
function analyzeImpulseResponse(samples, sampleRate = 48e3, nOctaveBands = 6, minDecayDb) {
|
|
2864
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, nOctaveBands, minDecayDb } : samples;
|
|
2865
|
+
if (request.minDecayDb === null) {
|
|
2866
|
+
throw new TypeError("analyzeImpulseResponse: minDecayDb must be a finite number");
|
|
2867
|
+
}
|
|
2868
|
+
const resolvedMinDecayDb = request.minDecayDb === void 0 ? 30 : request.minDecayDb;
|
|
2869
|
+
assertFiniteScalar("analyzeImpulseResponse", resolvedMinDecayDb, "minDecayDb");
|
|
2870
|
+
if (resolvedMinDecayDb <= 0) {
|
|
2871
|
+
throw new RangeError("analyzeImpulseResponse: minDecayDb must be greater than zero");
|
|
2872
|
+
}
|
|
2305
2873
|
validateAnalysisInput(
|
|
2306
2874
|
"analyzeImpulseResponse",
|
|
2307
2875
|
request.samples,
|
|
2308
2876
|
request.sampleRate ?? 48e3,
|
|
2309
2877
|
request
|
|
2310
2878
|
);
|
|
2311
|
-
const result = requireModule14().
|
|
2879
|
+
const result = requireModule14().analyzeImpulseResponseEx(
|
|
2312
2880
|
request.samples,
|
|
2313
2881
|
request.sampleRate ?? 48e3,
|
|
2314
|
-
request.nOctaveBands ?? 6
|
|
2882
|
+
request.nOctaveBands ?? 6,
|
|
2883
|
+
resolvedMinDecayDb
|
|
2315
2884
|
);
|
|
2316
2885
|
return result;
|
|
2317
2886
|
}
|
|
@@ -2364,7 +2933,9 @@ function analyzeWithProgress(samples, sampleRate = 22050, onProgress) {
|
|
|
2364
2933
|
const result = requireModule14().analyzeWithProgress(
|
|
2365
2934
|
request.samples,
|
|
2366
2935
|
request.sampleRate ?? 22050,
|
|
2367
|
-
request.onProgress
|
|
2936
|
+
request.onProgress ?? (() => {
|
|
2937
|
+
}),
|
|
2938
|
+
request.cancel ?? (() => false)
|
|
2368
2939
|
);
|
|
2369
2940
|
return convertAnalysisResult(result);
|
|
2370
2941
|
}
|
|
@@ -2518,9 +3089,14 @@ var Audio = class _Audio {
|
|
|
2518
3089
|
}
|
|
2519
3090
|
}
|
|
2520
3091
|
}
|
|
2521
|
-
/**
|
|
3092
|
+
/**
|
|
3093
|
+
* A copy of the raw audio samples. Mirrors Node's `getData()` contract: the
|
|
3094
|
+
* returned array is independent of the Audio's internal buffer, so mutating
|
|
3095
|
+
* it (or transferring it to a Worker) does not affect subsequent facade
|
|
3096
|
+
* calls, which all read the internal snapshot directly.
|
|
3097
|
+
*/
|
|
2522
3098
|
get data() {
|
|
2523
|
-
return this._samples;
|
|
3099
|
+
return this._samples.slice();
|
|
2524
3100
|
}
|
|
2525
3101
|
/** Number of samples. */
|
|
2526
3102
|
get length() {
|
|
@@ -2788,7 +3364,12 @@ self.onmessage = async (event) => {
|
|
|
2788
3364
|
`;
|
|
2789
3365
|
function createOpfsClipPageWorker() {
|
|
2790
3366
|
const blob = new Blob([opfsClipPageWorkerSource], { type: "text/javascript" });
|
|
2791
|
-
|
|
3367
|
+
const url = URL.createObjectURL(blob);
|
|
3368
|
+
try {
|
|
3369
|
+
return new Worker(url);
|
|
3370
|
+
} finally {
|
|
3371
|
+
URL.revokeObjectURL(url);
|
|
3372
|
+
}
|
|
2792
3373
|
}
|
|
2793
3374
|
function createOpfsClipPageProvider(engine, options) {
|
|
2794
3375
|
if (options.numChannels <= 0 || options.numSamples <= 0 || options.pageFrames <= 0) {
|
|
@@ -2828,6 +3409,7 @@ function createOpfsClipPageProvider(engine, options) {
|
|
|
2828
3409
|
}
|
|
2829
3410
|
try {
|
|
2830
3411
|
provider.supply(response.pageIndex, channels);
|
|
3412
|
+
options.onPageSupplied?.(response.pageIndex, channels);
|
|
2831
3413
|
} catch {
|
|
2832
3414
|
entry.resolve(false);
|
|
2833
3415
|
return;
|
|
@@ -2875,6 +3457,13 @@ function createOpfsClipPageProvider(engine, options) {
|
|
|
2875
3457
|
supplyRequest(request) {
|
|
2876
3458
|
return supplyPage(Math.floor(request.sample / options.pageFrames));
|
|
2877
3459
|
},
|
|
3460
|
+
clearPage(pageIndex) {
|
|
3461
|
+
if (closed) {
|
|
3462
|
+
return;
|
|
3463
|
+
}
|
|
3464
|
+
provider.clear(pageIndex);
|
|
3465
|
+
options.onPageCleared?.(pageIndex);
|
|
3466
|
+
},
|
|
2878
3467
|
close() {
|
|
2879
3468
|
if (closed) {
|
|
2880
3469
|
return;
|
|
@@ -2886,6 +3475,7 @@ function createOpfsClipPageProvider(engine, options) {
|
|
|
2886
3475
|
}
|
|
2887
3476
|
pending.clear();
|
|
2888
3477
|
provider.destroy();
|
|
3478
|
+
options.onClose?.();
|
|
2889
3479
|
if (ownsWorker) {
|
|
2890
3480
|
worker.terminate();
|
|
2891
3481
|
}
|
|
@@ -2963,7 +3553,10 @@ var ClipPageStreamer = class {
|
|
|
2963
3553
|
if (!state) {
|
|
2964
3554
|
continue;
|
|
2965
3555
|
}
|
|
2966
|
-
const page = Math.floor(request.sample / state.source.pageFrames);
|
|
3556
|
+
const page = request.pageIndex !== void 0 ? request.pageIndex : Math.floor((request.sample ?? Number.NaN) / state.source.pageFrames);
|
|
3557
|
+
if (!Number.isInteger(page) || page < 0 || page > state.lastPage) {
|
|
3558
|
+
continue;
|
|
3559
|
+
}
|
|
2967
3560
|
frontiers.set(request.clipId, page);
|
|
2968
3561
|
}
|
|
2969
3562
|
const fetches = [];
|
|
@@ -2998,7 +3591,7 @@ var ClipPageStreamer = class {
|
|
|
2998
3591
|
const high = Math.min(state.lastPage, frontier + this.readAheadPages);
|
|
2999
3592
|
for (const page of state.resident.keys()) {
|
|
3000
3593
|
if (page < low || page > high) {
|
|
3001
|
-
|
|
3594
|
+
this.clearPage(state, page);
|
|
3002
3595
|
state.resident.delete(page);
|
|
3003
3596
|
}
|
|
3004
3597
|
}
|
|
@@ -3013,7 +3606,7 @@ var ClipPageStreamer = class {
|
|
|
3013
3606
|
state.source.binding.supplyPage(pageIndex).then(
|
|
3014
3607
|
(ok) => {
|
|
3015
3608
|
if (state.generation !== generation) {
|
|
3016
|
-
|
|
3609
|
+
this.clearPage(state, pageIndex);
|
|
3017
3610
|
} else if (!ok && state.resident.get(pageIndex) === generation) {
|
|
3018
3611
|
state.resident.delete(pageIndex);
|
|
3019
3612
|
}
|
|
@@ -3034,12 +3627,28 @@ var ClipPageStreamer = class {
|
|
|
3034
3627
|
state.generation += 1;
|
|
3035
3628
|
state.lastFrontier = null;
|
|
3036
3629
|
for (const page of state.resident.keys()) {
|
|
3037
|
-
|
|
3630
|
+
this.clearPage(state, page);
|
|
3038
3631
|
}
|
|
3039
3632
|
state.resident.clear();
|
|
3040
3633
|
}
|
|
3634
|
+
clearPage(state, pageIndex) {
|
|
3635
|
+
if (state.source.binding.clearPage) {
|
|
3636
|
+
state.source.binding.clearPage(pageIndex);
|
|
3637
|
+
} else {
|
|
3638
|
+
state.source.binding.provider.clear(pageIndex);
|
|
3639
|
+
}
|
|
3640
|
+
}
|
|
3041
3641
|
};
|
|
3042
|
-
async function attachOpfsClipStream(
|
|
3642
|
+
async function attachOpfsClipStream(streamerOrEngine, engineOrOptions, maybeOptions) {
|
|
3643
|
+
if (!(streamerOrEngine instanceof ClipPageStreamer)) {
|
|
3644
|
+
return streamerOrEngine.attachOpfsClipStream(engineOrOptions);
|
|
3645
|
+
}
|
|
3646
|
+
const streamer = streamerOrEngine;
|
|
3647
|
+
const engine = engineOrOptions;
|
|
3648
|
+
const options = maybeOptions;
|
|
3649
|
+
if (!options) {
|
|
3650
|
+
throw new Error("attachOpfsClipStream requires options.");
|
|
3651
|
+
}
|
|
3043
3652
|
const { clipId, primePages = 1, ...providerOptions } = options;
|
|
3044
3653
|
const binding = createOpfsClipPageProvider(engine, providerOptions);
|
|
3045
3654
|
const lastPage = Math.ceil(providerOptions.numSamples / providerOptions.pageFrames) - 1;
|
|
@@ -3095,7 +3704,11 @@ async function bindMicrophoneInput(context, engine, options = {}) {
|
|
|
3095
3704
|
function assertOversampleFactor(fnName, factor) {
|
|
3096
3705
|
const normalized = factor === 0 ? 4 : factor;
|
|
3097
3706
|
if (!Number.isInteger(normalized) || normalized < 1 || normalized > 16 || (normalized & normalized - 1) !== 0) {
|
|
3098
|
-
throw new
|
|
3707
|
+
throw new SonareError(
|
|
3708
|
+
4 /* InvalidParameter */,
|
|
3709
|
+
"InvalidParameter",
|
|
3710
|
+
`${fnName}: oversampleFactor must be 0 or a power of two from 1 to 16`
|
|
3711
|
+
);
|
|
3099
3712
|
}
|
|
3100
3713
|
}
|
|
3101
3714
|
function requireModule15() {
|
|
@@ -3341,44 +3954,61 @@ function assertProjectMidiEvents(fnName, events) {
|
|
|
3341
3954
|
});
|
|
3342
3955
|
}
|
|
3343
3956
|
function projectTrackKindValue(kind) {
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
}
|
|
3353
|
-
return kind;
|
|
3957
|
+
return resolveEnumOrdinal(kind ?? "audio", { audio: 0, midi: 1, aux: 2 }, "project track kind");
|
|
3958
|
+
}
|
|
3959
|
+
function projectAutomationTargetKindValue(kind) {
|
|
3960
|
+
return resolveEnumOrdinal(
|
|
3961
|
+
kind,
|
|
3962
|
+
{ opaque: 0, "track-fader-db": 1, "track-pan": 2 },
|
|
3963
|
+
"project automation target kind"
|
|
3964
|
+
);
|
|
3354
3965
|
}
|
|
3355
3966
|
function projectWarpModeValue(mode) {
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3967
|
+
return resolveEnumOrdinal(
|
|
3968
|
+
mode ?? "off",
|
|
3969
|
+
{ off: 0, repitch: 1, "tempo-sync": 2 },
|
|
3970
|
+
"project warp mode"
|
|
3971
|
+
);
|
|
3972
|
+
}
|
|
3973
|
+
function projectLoopModeValue(mode) {
|
|
3974
|
+
return resolveEnumOrdinal(mode ?? "off", { off: 0, loop: 1 }, "project loop mode");
|
|
3975
|
+
}
|
|
3976
|
+
|
|
3977
|
+
// src/project_class.ts
|
|
3978
|
+
function validateAssistSidecarUint32(value, field) {
|
|
3979
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0 || value > 4294967295) {
|
|
3980
|
+
throw new RangeError(`Project.setAssistSidecar: ${field} must be a uint32`);
|
|
3361
3981
|
}
|
|
3362
|
-
|
|
3363
|
-
|
|
3982
|
+
return value;
|
|
3983
|
+
}
|
|
3984
|
+
function validateAssistSidecarPpq(value, field) {
|
|
3985
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
|
|
3986
|
+
throw new RangeError(
|
|
3987
|
+
`Project.setAssistSidecar: ${field} must be a finite, non-negative number`
|
|
3988
|
+
);
|
|
3364
3989
|
}
|
|
3365
|
-
return
|
|
3990
|
+
return value;
|
|
3366
3991
|
}
|
|
3367
|
-
function
|
|
3368
|
-
if (
|
|
3369
|
-
|
|
3992
|
+
function validateAssistSidecarPayload(value) {
|
|
3993
|
+
if (!(value instanceof Uint8Array)) {
|
|
3994
|
+
throw new TypeError("Project.setAssistSidecar: payload must be a Uint8Array");
|
|
3370
3995
|
}
|
|
3371
|
-
|
|
3372
|
-
|
|
3996
|
+
return value;
|
|
3997
|
+
}
|
|
3998
|
+
function validateAssistSidecarModuleId(value) {
|
|
3999
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
4000
|
+
throw new TypeError("Project.setAssistSidecar: moduleId must be a non-empty string");
|
|
3373
4001
|
}
|
|
3374
|
-
return
|
|
4002
|
+
return value;
|
|
3375
4003
|
}
|
|
3376
|
-
|
|
3377
|
-
// src/project_class.ts
|
|
3378
4004
|
var Project = class _Project {
|
|
3379
4005
|
constructor() {
|
|
3380
4006
|
this.native = new (projectModule()).Project();
|
|
3381
4007
|
}
|
|
4008
|
+
/** Create a new empty project. */
|
|
4009
|
+
static create() {
|
|
4010
|
+
return new _Project();
|
|
4011
|
+
}
|
|
3382
4012
|
/** Pack a MIDI 1.0 note-on event accepted by {@link setMidiEvents}. */
|
|
3383
4013
|
static midiNoteOn(ppq, group, channel, note, velocity) {
|
|
3384
4014
|
return projectMidi1Event("Project.midiNoteOn", ppq, group, 9, channel, note, velocity);
|
|
@@ -3544,6 +4174,16 @@ var Project = class _Project {
|
|
|
3544
4174
|
addClip(desc) {
|
|
3545
4175
|
return this.native.addClip(desc);
|
|
3546
4176
|
}
|
|
4177
|
+
/** Import host-separated PCM through the normal audio-track/clip path. */
|
|
4178
|
+
importExternalStems(request) {
|
|
4179
|
+
return this.native.importExternalStems({
|
|
4180
|
+
...request,
|
|
4181
|
+
stems: request.stems.map((stem) => ({
|
|
4182
|
+
...stem,
|
|
4183
|
+
layout: stem.layout === "mono" ? 1 : stem.layout === "stereo" ? 2 : stem.layout
|
|
4184
|
+
}))
|
|
4185
|
+
});
|
|
4186
|
+
}
|
|
3547
4187
|
/** Split captured loop-recording audio into takes and add one clip. */
|
|
3548
4188
|
addLoopRecordingTakes(desc) {
|
|
3549
4189
|
return this.native.addLoopRecordingTakes(desc);
|
|
@@ -3588,7 +4228,11 @@ var Project = class _Project {
|
|
|
3588
4228
|
* Route a track's MIDI to host-instrument `destinationId` (0 = default). The
|
|
3589
4229
|
* compiler stamps every MIDI clip on the track with this id so the engine
|
|
3590
4230
|
* dispatches its events to the instrument registered for that destination.
|
|
3591
|
-
* Routes through an undoable edit command.
|
|
4231
|
+
* Routes through an undoable edit command. Builtin, NativeSynth, and SF2
|
|
4232
|
+
* instruments retain source-track provenance inside a shared destination
|
|
4233
|
+
* voice pool. With only zero-latency instruments bound, live lanes and
|
|
4234
|
+
* channel-strip bounces remain aligned. Configure one live lane per source
|
|
4235
|
+
* track that needs strip processing.
|
|
3592
4236
|
*/
|
|
3593
4237
|
setTrackMidiDestination(trackId, destinationId) {
|
|
3594
4238
|
this.native.setTrackMidiDestination(trackId, destinationId);
|
|
@@ -3628,6 +4272,18 @@ var Project = class _Project {
|
|
|
3628
4272
|
}
|
|
3629
4273
|
this.native.setMaxUndoDepth(depth);
|
|
3630
4274
|
}
|
|
4275
|
+
/** Set the combined undo/redo history byte cap. Zero disables retention. */
|
|
4276
|
+
setMaxHistoryBytes(bytes) {
|
|
4277
|
+
if (typeof bytes !== "number") {
|
|
4278
|
+
throw new TypeError("Project.setMaxHistoryBytes: bytes must be a number");
|
|
4279
|
+
}
|
|
4280
|
+
if (!Number.isFinite(bytes) || !Number.isInteger(bytes) || bytes < 0 || bytes > 4294967295) {
|
|
4281
|
+
throw new RangeError(
|
|
4282
|
+
"Project.setMaxHistoryBytes: bytes must be a finite integer in the uint32 range"
|
|
4283
|
+
);
|
|
4284
|
+
}
|
|
4285
|
+
this.native.setMaxHistoryBytes(bytes);
|
|
4286
|
+
}
|
|
3631
4287
|
/** Replace a MIDI clip's entire event list. */
|
|
3632
4288
|
setMidiEvents(clipId, events) {
|
|
3633
4289
|
assertProjectMidiEvents("Project.setMidiEvents", events);
|
|
@@ -3758,8 +4414,11 @@ var Project = class _Project {
|
|
|
3758
4414
|
* Karplus-Strong / modal / additive / percussion / extended-waveguide-piano
|
|
3759
4415
|
* engines plus the realism layer). Pass a {@link SynthPatch}, a preset-name
|
|
3760
4416
|
* string (`'saw-lead'` / `'va:saw-lead'`; see {@link synthPresetNames}), or
|
|
3761
|
-
* an array of either; each object entry may carry
|
|
3762
|
-
*
|
|
4417
|
+
* an array of either; each object entry may carry `destinationId` (default
|
|
4418
|
+
* 0) and `useGmPrograms` (default `false`) binding conveniences, neither of
|
|
4419
|
+
* which is part of the NativeSynth patch itself. When enabled, MIDI program
|
|
4420
|
+
* changes select the corresponding General MIDI voice while the patch remains
|
|
4421
|
+
* the fallback.
|
|
3763
4422
|
* Because the parameter defaults to `{}`, omission and explicit `undefined`
|
|
3764
4423
|
* both create one default binding. Use an explicitly empty array `[]` (or
|
|
3765
4424
|
* runtime `null`) for zero bindings. Unknown preset names throw.
|
|
@@ -3825,6 +4484,18 @@ var Project = class _Project {
|
|
|
3825
4484
|
setClipFade(clipId, fadeIn = {}, fadeOut = {}) {
|
|
3826
4485
|
this.native.setClipFade(clipId, fadeIn, fadeOut);
|
|
3827
4486
|
}
|
|
4487
|
+
/** Audio source ids that need decoded PCM after deserialization. */
|
|
4488
|
+
unresolvedAudioSourceIds() {
|
|
4489
|
+
return this.native.unresolvedAudioSourceIds();
|
|
4490
|
+
}
|
|
4491
|
+
/** Register decoded interleaved PCM for an existing audio source (undoable). */
|
|
4492
|
+
setSourceAudio(sourceId, audio, channels, sampleRate) {
|
|
4493
|
+
this.native.setSourceAudio(sourceId, audio, channels, sampleRate);
|
|
4494
|
+
}
|
|
4495
|
+
/** Replace an audio source's metadata strings as one undoable edit. */
|
|
4496
|
+
setAudioSourceMetadata(sourceId, contentHash, externalStemRole) {
|
|
4497
|
+
this.native.setAudioSourceMetadata(sourceId, contentHash, externalStemRole);
|
|
4498
|
+
}
|
|
3828
4499
|
/** Replace a clip's take list and active take id (undoable). */
|
|
3829
4500
|
setClipTakes(clipId, takes, activeTakeId = 0) {
|
|
3830
4501
|
this.native.setClipTakes(clipId, takes, activeTakeId);
|
|
@@ -3866,23 +4537,35 @@ var Project = class _Project {
|
|
|
3866
4537
|
setTrackRoute(trackId, channelStripRef, outputTarget) {
|
|
3867
4538
|
this.native.setTrackRoute(trackId, channelStripRef ?? "", outputTarget ?? "");
|
|
3868
4539
|
}
|
|
3869
|
-
/** Append an automation lane
|
|
4540
|
+
/** Append an automation lane; returns its stable target parameter id (undoable). */
|
|
3870
4541
|
addAutomationLane(trackId, desc) {
|
|
3871
|
-
|
|
3872
|
-
targetParamId
|
|
3873
|
-
|
|
3874
|
-
}
|
|
4542
|
+
if (desc.targetParamId === 0) {
|
|
4543
|
+
throw new RangeError("project automation lane targetParamId must be non-zero");
|
|
4544
|
+
}
|
|
4545
|
+
const nativeDesc = { ...desc };
|
|
4546
|
+
if (Object.keys(desc).includes("targetKind")) {
|
|
4547
|
+
nativeDesc.targetKind = projectAutomationTargetKindValue(
|
|
4548
|
+
desc.targetKind
|
|
4549
|
+
);
|
|
4550
|
+
}
|
|
4551
|
+
return this.native.addAutomationLane(trackId, nativeDesc);
|
|
3875
4552
|
}
|
|
3876
|
-
/** Replace
|
|
3877
|
-
editAutomationLane(trackId,
|
|
3878
|
-
|
|
3879
|
-
targetParamId
|
|
3880
|
-
|
|
3881
|
-
}
|
|
4553
|
+
/** Replace the lane identified by its stable target parameter id (undoable). */
|
|
4554
|
+
editAutomationLane(trackId, targetParamId, desc) {
|
|
4555
|
+
if (desc.targetParamId === 0) {
|
|
4556
|
+
throw new RangeError("project automation lane targetParamId must be non-zero");
|
|
4557
|
+
}
|
|
4558
|
+
const nativeDesc = { ...desc };
|
|
4559
|
+
if (Object.keys(desc).includes("targetKind")) {
|
|
4560
|
+
nativeDesc.targetKind = projectAutomationTargetKindValue(
|
|
4561
|
+
desc.targetKind
|
|
4562
|
+
);
|
|
4563
|
+
}
|
|
4564
|
+
this.native.editAutomationLane(trackId, targetParamId, nativeDesc);
|
|
3882
4565
|
}
|
|
3883
|
-
/** Remove
|
|
3884
|
-
removeAutomationLane(trackId,
|
|
3885
|
-
this.native.removeAutomationLane(trackId,
|
|
4566
|
+
/** Remove the lane identified by its stable target parameter id (undoable). */
|
|
4567
|
+
removeAutomationLane(trackId, targetParamId) {
|
|
4568
|
+
this.native.removeAutomationLane(trackId, targetParamId);
|
|
3886
4569
|
}
|
|
3887
4570
|
/** Replace the project's key annotation stream (undoable). */
|
|
3888
4571
|
annotateKeys(keys) {
|
|
@@ -3892,15 +4575,33 @@ var Project = class _Project {
|
|
|
3892
4575
|
annotateChords(chords) {
|
|
3893
4576
|
this.native.annotateChords(chords);
|
|
3894
4577
|
}
|
|
3895
|
-
|
|
3896
|
-
|
|
4578
|
+
setAssistSidecar(sidecarOrModuleId, schemaVersion, targetTrackId, regionStartPpq, regionEndPpq, payload) {
|
|
4579
|
+
if (typeof sidecarOrModuleId === "string") {
|
|
4580
|
+
if (schemaVersion === void 0 || targetTrackId === void 0 || regionStartPpq === void 0 || regionEndPpq === void 0 || payload === void 0) {
|
|
4581
|
+
throw new TypeError("Project.setAssistSidecar: positional form requires six arguments");
|
|
4582
|
+
}
|
|
4583
|
+
this.native.setAssistSidecar(
|
|
4584
|
+
validateAssistSidecarModuleId(sidecarOrModuleId),
|
|
4585
|
+
validateAssistSidecarUint32(schemaVersion, "schemaVersion"),
|
|
4586
|
+
validateAssistSidecarUint32(targetTrackId, "targetTrackId"),
|
|
4587
|
+
validateAssistSidecarPpq(regionStartPpq, "regionStartPpq"),
|
|
4588
|
+
validateAssistSidecarPpq(regionEndPpq, "regionEndPpq"),
|
|
4589
|
+
validateAssistSidecarPayload(payload)
|
|
4590
|
+
);
|
|
4591
|
+
return;
|
|
4592
|
+
}
|
|
4593
|
+
if (sidecarOrModuleId === null || typeof sidecarOrModuleId !== "object" || Array.isArray(sidecarOrModuleId)) {
|
|
4594
|
+
throw new TypeError("Project.setAssistSidecar: expected a sidecar descriptor object");
|
|
4595
|
+
}
|
|
4596
|
+
const sidecar = sidecarOrModuleId;
|
|
4597
|
+
const moduleId = validateAssistSidecarModuleId(sidecar.moduleId);
|
|
3897
4598
|
this.native.setAssistSidecar(
|
|
3898
4599
|
moduleId,
|
|
3899
|
-
schemaVersion,
|
|
3900
|
-
targetTrackId,
|
|
3901
|
-
regionStartPpq,
|
|
3902
|
-
regionEndPpq,
|
|
3903
|
-
payload
|
|
4600
|
+
validateAssistSidecarUint32(sidecar.schemaVersion ?? 0, "schemaVersion"),
|
|
4601
|
+
validateAssistSidecarUint32(sidecar.targetTrackId ?? 0, "targetTrackId"),
|
|
4602
|
+
validateAssistSidecarPpq(sidecar.regionStartPpq ?? 0, "regionStartPpq"),
|
|
4603
|
+
validateAssistSidecarPpq(sidecar.regionEndPpq ?? 0, "regionEndPpq"),
|
|
4604
|
+
validateAssistSidecarPayload(sidecar.payload ?? new Uint8Array())
|
|
3904
4605
|
);
|
|
3905
4606
|
}
|
|
3906
4607
|
/** Number of assist sidecars currently stored on the project. */
|
|
@@ -3911,6 +4612,11 @@ var Project = class _Project {
|
|
|
3911
4612
|
getAssistSidecar(index) {
|
|
3912
4613
|
return this.native.getAssistSidecar(index);
|
|
3913
4614
|
}
|
|
4615
|
+
/** Read every stored assist sidecar in the same order as the index getter. */
|
|
4616
|
+
assistSidecars() {
|
|
4617
|
+
const count = this.assistSidecarCount();
|
|
4618
|
+
return Array.from({ length: count }, (_, index) => this.getAssistSidecar(index));
|
|
4619
|
+
}
|
|
3914
4620
|
/** Set the project's clip-overlap policy (SonareProjectOverlapPolicy ordinal). */
|
|
3915
4621
|
setOverlapPolicy(policy) {
|
|
3916
4622
|
this.native.setOverlapPolicy(policy);
|
|
@@ -3946,6 +4652,18 @@ var Project = class _Project {
|
|
|
3946
4652
|
markerByIndex(index) {
|
|
3947
4653
|
return this.native.markerByIndex(index);
|
|
3948
4654
|
}
|
|
4655
|
+
/** Read a stored project track by 0-based index. */
|
|
4656
|
+
trackByIndex(index) {
|
|
4657
|
+
return this.native.trackByIndex(index);
|
|
4658
|
+
}
|
|
4659
|
+
/** Read a stored project clip by 0-based index. */
|
|
4660
|
+
clipByIndex(index) {
|
|
4661
|
+
return this.native.clipByIndex(index);
|
|
4662
|
+
}
|
|
4663
|
+
/** Read a stored project source by 0-based index. */
|
|
4664
|
+
sourceByIndex(index) {
|
|
4665
|
+
return this.native.sourceByIndex(index);
|
|
4666
|
+
}
|
|
3949
4667
|
/** Number of markers in the project. */
|
|
3950
4668
|
markerCount() {
|
|
3951
4669
|
return this.native.markerCount();
|
|
@@ -4019,6 +4737,7 @@ var MarkerKind = {
|
|
|
4019
4737
|
cuePoint: 3,
|
|
4020
4738
|
keySignature: 4
|
|
4021
4739
|
};
|
|
4740
|
+
var BUILTIN_SYNTH_WAVEFORMS = ["sine", "saw", "sawtooth", "square", "triangle"];
|
|
4022
4741
|
var SYNTH_ENGINE_MODES = [
|
|
4023
4742
|
"default",
|
|
4024
4743
|
"subtractive",
|
|
@@ -4080,82 +4799,14 @@ var SYNTH_MOD_DESTINATIONS = [
|
|
|
4080
4799
|
"amp-gain",
|
|
4081
4800
|
"pan-units"
|
|
4082
4801
|
];
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
case "hold":
|
|
4092
|
-
return 2;
|
|
4093
|
-
case "s-curve":
|
|
4094
|
-
return 3;
|
|
4095
|
-
default:
|
|
4096
|
-
throw new Error(`Invalid automation curve: ${curve}`);
|
|
4097
|
-
}
|
|
4098
|
-
}
|
|
4099
|
-
function panLawCode(panLaw) {
|
|
4100
|
-
if (typeof panLaw === "number") {
|
|
4101
|
-
return panLaw;
|
|
4102
|
-
}
|
|
4103
|
-
switch (panLaw) {
|
|
4104
|
-
case "const3dB":
|
|
4105
|
-
return 0;
|
|
4106
|
-
case "const4.5dB":
|
|
4107
|
-
return 1;
|
|
4108
|
-
case "const6dB":
|
|
4109
|
-
return 2;
|
|
4110
|
-
case "linear0dB":
|
|
4111
|
-
return 3;
|
|
4112
|
-
default:
|
|
4113
|
-
throw new Error(`Invalid pan law: ${panLaw}`);
|
|
4114
|
-
}
|
|
4115
|
-
}
|
|
4116
|
-
function panModeCode(panMode) {
|
|
4117
|
-
if (typeof panMode === "number") {
|
|
4118
|
-
return panMode;
|
|
4119
|
-
}
|
|
4120
|
-
switch (panMode) {
|
|
4121
|
-
case "balance":
|
|
4122
|
-
return 0;
|
|
4123
|
-
case "stereoPan":
|
|
4124
|
-
case "stereo-pan":
|
|
4125
|
-
return 1;
|
|
4126
|
-
case "dualPan":
|
|
4127
|
-
case "dual-pan":
|
|
4128
|
-
return 2;
|
|
4129
|
-
default:
|
|
4130
|
-
throw new Error(`Invalid pan mode: ${panMode}`);
|
|
4131
|
-
}
|
|
4132
|
-
}
|
|
4133
|
-
function meterTapCode(tap) {
|
|
4134
|
-
if (typeof tap === "number") {
|
|
4135
|
-
return tap;
|
|
4136
|
-
}
|
|
4137
|
-
switch (tap) {
|
|
4138
|
-
case "preFader":
|
|
4139
|
-
return 0;
|
|
4140
|
-
case "postFader":
|
|
4141
|
-
return 1;
|
|
4142
|
-
default:
|
|
4143
|
-
throw new Error(`Invalid meter tap: ${tap}`);
|
|
4144
|
-
}
|
|
4145
|
-
}
|
|
4146
|
-
function sendTimingCode(timing) {
|
|
4147
|
-
if (typeof timing === "number") {
|
|
4148
|
-
return timing;
|
|
4149
|
-
}
|
|
4150
|
-
switch (timing) {
|
|
4151
|
-
case "postFader":
|
|
4152
|
-
return 0;
|
|
4153
|
-
case "preFader":
|
|
4154
|
-
return 1;
|
|
4155
|
-
default:
|
|
4156
|
-
throw new Error(`Invalid send timing: ${timing}`);
|
|
4157
|
-
}
|
|
4158
|
-
}
|
|
4802
|
+
var AutomationTargetKind = {
|
|
4803
|
+
opaque: 0,
|
|
4804
|
+
trackFaderDb: 1,
|
|
4805
|
+
trackPan: 2
|
|
4806
|
+
};
|
|
4807
|
+
var PROJECT_AUTOMATION_TARGET_OPAQUE = AutomationTargetKind.opaque;
|
|
4808
|
+
var PROJECT_AUTOMATION_TARGET_TRACK_FADER_DB = AutomationTargetKind.trackFaderDb;
|
|
4809
|
+
var PROJECT_AUTOMATION_TARGET_TRACK_PAN = AutomationTargetKind.trackPan;
|
|
4159
4810
|
|
|
4160
4811
|
// src/realtime_engine.ts
|
|
4161
4812
|
var EXPECTED_ENGINE_ABI_VERSION = 3;
|
|
@@ -4175,23 +4826,30 @@ function engineCapabilities() {
|
|
|
4175
4826
|
};
|
|
4176
4827
|
}
|
|
4177
4828
|
var RealtimeEngine = class {
|
|
4178
|
-
constructor(sampleRate = 48e3, maxBlockSize = 128, commandCapacity = 1024, telemetryCapacity = 1024) {
|
|
4829
|
+
constructor(sampleRate = 48e3, maxBlockSize = 128, commandCapacity = 1024, telemetryCapacity = 1024, maxChannels = 64) {
|
|
4179
4830
|
const module2 = getSonareModule();
|
|
4180
|
-
const
|
|
4181
|
-
if (!
|
|
4831
|
+
const capabilities2 = engineCapabilities();
|
|
4832
|
+
if (!capabilities2.abiCompatible) {
|
|
4182
4833
|
throw new Error(
|
|
4183
|
-
`Engine ABI mismatch: wasm=${
|
|
4834
|
+
`Engine ABI mismatch: wasm=${capabilities2.engineAbiVersion}, expected=${capabilities2.expectedEngineAbiVersion}`
|
|
4184
4835
|
);
|
|
4185
4836
|
}
|
|
4186
4837
|
this.native = new module2.RealtimeEngine(
|
|
4187
4838
|
sampleRate,
|
|
4188
4839
|
maxBlockSize,
|
|
4189
4840
|
commandCapacity,
|
|
4190
|
-
telemetryCapacity
|
|
4841
|
+
telemetryCapacity,
|
|
4842
|
+
maxChannels
|
|
4191
4843
|
);
|
|
4192
4844
|
}
|
|
4193
|
-
prepare(sampleRate, maxBlockSize, commandCapacity = 1024, telemetryCapacity = 1024) {
|
|
4194
|
-
this.native.
|
|
4845
|
+
prepare(sampleRate, maxBlockSize, commandCapacity = 1024, telemetryCapacity = 1024, maxChannels = 64) {
|
|
4846
|
+
this.native.prepareWithChannels(
|
|
4847
|
+
sampleRate,
|
|
4848
|
+
maxBlockSize,
|
|
4849
|
+
commandCapacity,
|
|
4850
|
+
telemetryCapacity,
|
|
4851
|
+
maxChannels
|
|
4852
|
+
);
|
|
4195
4853
|
}
|
|
4196
4854
|
/** Queue a sample-accurate parameter change (engine kSetParam). */
|
|
4197
4855
|
setParameter(paramId, value, renderFrame = -1) {
|
|
@@ -4212,6 +4870,10 @@ var RealtimeEngine = class {
|
|
|
4212
4870
|
setSoloMute(laneIndex, solo, mute, renderFrame = -1) {
|
|
4213
4871
|
this.native.setSoloMute(laneIndex, solo, mute, renderFrame);
|
|
4214
4872
|
}
|
|
4873
|
+
/** Queue a per-track PFL/AFL monitor tap mode change. */
|
|
4874
|
+
setTrackMonitorMode(laneIndex, mode, renderFrame = -1) {
|
|
4875
|
+
this.native.setTrackMonitorMode(laneIndex, trackMonitorModeCode(mode), renderFrame);
|
|
4876
|
+
}
|
|
4215
4877
|
setMidiClips(clips) {
|
|
4216
4878
|
this.native.setMidiClips(clips);
|
|
4217
4879
|
}
|
|
@@ -4317,6 +4979,9 @@ var RealtimeEngine = class {
|
|
|
4317
4979
|
externalMidiDroppedCount() {
|
|
4318
4980
|
return this.native.externalMidiDroppedCount();
|
|
4319
4981
|
}
|
|
4982
|
+
externalMidiPendingCount() {
|
|
4983
|
+
return this.native.externalMidiPendingCount();
|
|
4984
|
+
}
|
|
4320
4985
|
/**
|
|
4321
4986
|
* Drain queued external-MIDI events, already lowered to MIDI 1.0 byte
|
|
4322
4987
|
* messages ready to write to a Web MIDI output port. Call once per audio
|
|
@@ -4327,6 +4992,25 @@ var RealtimeEngine = class {
|
|
|
4327
4992
|
drainExternalMidi(maxRecords = 1024) {
|
|
4328
4993
|
return this.native.drainExternalMidi(maxRecords);
|
|
4329
4994
|
}
|
|
4995
|
+
/** Scalar, allocation-free external-MIDI drain for AudioWorklet SAB output. */
|
|
4996
|
+
popExternalMidiToScratch() {
|
|
4997
|
+
return this.native.popExternalMidiToScratch();
|
|
4998
|
+
}
|
|
4999
|
+
externalMidiScratchDestinationId() {
|
|
5000
|
+
return this.native.externalMidiScratchDestinationId();
|
|
5001
|
+
}
|
|
5002
|
+
externalMidiScratchRenderFrame() {
|
|
5003
|
+
return this.native.externalMidiScratchRenderFrame();
|
|
5004
|
+
}
|
|
5005
|
+
externalMidiScratchByteWord() {
|
|
5006
|
+
return this.native.externalMidiScratchByteWord();
|
|
5007
|
+
}
|
|
5008
|
+
externalMidiScratchByteCount() {
|
|
5009
|
+
return this.native.externalMidiScratchByteCount();
|
|
5010
|
+
}
|
|
5011
|
+
consumeExternalMidiScratch() {
|
|
5012
|
+
this.native.consumeExternalMidiScratch();
|
|
5013
|
+
}
|
|
4330
5014
|
pushMidiInputNoteOn(group, channel, note, velocity, portTimeSamples = 0) {
|
|
4331
5015
|
this.native.pushMidiInputNoteOn(group, channel, note, velocity, portTimeSamples);
|
|
4332
5016
|
}
|
|
@@ -4351,6 +5035,10 @@ var RealtimeEngine = class {
|
|
|
4351
5035
|
pushMidiCc(destinationId, group, channel, controller, value, renderFrame = -1) {
|
|
4352
5036
|
this.native.pushMidiCc(destinationId, group, channel, controller, value, renderFrame);
|
|
4353
5037
|
}
|
|
5038
|
+
/** Queue one immediate MIDI 1.0 channel-voice UMP word for a destination. */
|
|
5039
|
+
pushMidiUmp(destinationId, word0, renderFrame = -1) {
|
|
5040
|
+
this.native.pushMidiUmp(destinationId, word0, renderFrame);
|
|
5041
|
+
}
|
|
4354
5042
|
/**
|
|
4355
5043
|
* Queue an immediate (live) MIDI SysEx frame to a MIDI destination. `data` is
|
|
4356
5044
|
* the full message including the leading 0xF0 and trailing 0xF7 (1..512
|
|
@@ -4396,6 +5084,10 @@ var RealtimeEngine = class {
|
|
|
4396
5084
|
settleParameters() {
|
|
4397
5085
|
this.native.settleParameters();
|
|
4398
5086
|
}
|
|
5087
|
+
/** Drains queued commands on an offline/control-only engine immediately. */
|
|
5088
|
+
flushControlCommands() {
|
|
5089
|
+
this.native.flushControlCommands();
|
|
5090
|
+
}
|
|
4399
5091
|
seekPpq(ppq, renderFrame = -1) {
|
|
4400
5092
|
this.native.seekPpq(ppq, renderFrame);
|
|
4401
5093
|
}
|
|
@@ -4650,6 +5342,23 @@ var RealtimeEngine = class {
|
|
|
4650
5342
|
popClipPageRequest() {
|
|
4651
5343
|
return this.native.popClipPageRequest();
|
|
4652
5344
|
}
|
|
5345
|
+
/**
|
|
5346
|
+
* Moves one native request into the binding's persistent scalar scratch.
|
|
5347
|
+
* This avoids creating an embind JS object in AudioWorklet process().
|
|
5348
|
+
*/
|
|
5349
|
+
popClipPageRequestToScratch() {
|
|
5350
|
+
return this.native.popClipPageRequestToScratch();
|
|
5351
|
+
}
|
|
5352
|
+
clipPageRequestScratchClipId() {
|
|
5353
|
+
return this.native.clipPageRequestScratchClipId();
|
|
5354
|
+
}
|
|
5355
|
+
clipPageRequestScratchSample() {
|
|
5356
|
+
return this.native.clipPageRequestScratchSample();
|
|
5357
|
+
}
|
|
5358
|
+
/** Cumulative page misses dropped because the native bounded request queue was full. */
|
|
5359
|
+
clipPageRequestOverflowCount() {
|
|
5360
|
+
return this.native.clipPageRequestOverflowCount();
|
|
5361
|
+
}
|
|
4653
5362
|
setCaptureBuffer(numChannels, capacityFrames) {
|
|
4654
5363
|
this.native.setCaptureBuffer(numChannels, capacityFrames);
|
|
4655
5364
|
}
|
|
@@ -4678,6 +5387,10 @@ var RealtimeEngine = class {
|
|
|
4678
5387
|
capturedAudio() {
|
|
4679
5388
|
return this.native.capturedAudio();
|
|
4680
5389
|
}
|
|
5390
|
+
/**
|
|
5391
|
+
* Renders in place, adding engine output to `channels`. Zero each plane first
|
|
5392
|
+
* when it contains no upstream input.
|
|
5393
|
+
*/
|
|
4681
5394
|
process(channels) {
|
|
4682
5395
|
return this.native.process(channels);
|
|
4683
5396
|
}
|
|
@@ -4700,6 +5413,7 @@ var RealtimeEngine = class {
|
|
|
4700
5413
|
}
|
|
4701
5414
|
/**
|
|
4702
5415
|
* Runs the engine in place over the prepared per-channel scratch buffers.
|
|
5416
|
+
* Zero each active span first when it contains no upstream input.
|
|
4703
5417
|
* Allocation-free: safe to call on the AudioWorklet render thread after
|
|
4704
5418
|
* `prepareChannels`.
|
|
4705
5419
|
*/
|
|
@@ -4721,6 +5435,42 @@ var RealtimeEngine = class {
|
|
|
4721
5435
|
drainTelemetry(maxRecords = 1024) {
|
|
4722
5436
|
return this.native.drainTelemetry(maxRecords);
|
|
4723
5437
|
}
|
|
5438
|
+
popTelemetryToScratch() {
|
|
5439
|
+
return this.native.popTelemetryToScratch();
|
|
5440
|
+
}
|
|
5441
|
+
telemetryScratchType() {
|
|
5442
|
+
return this.native.telemetryScratchType();
|
|
5443
|
+
}
|
|
5444
|
+
telemetryScratchError() {
|
|
5445
|
+
return this.native.telemetryScratchError();
|
|
5446
|
+
}
|
|
5447
|
+
telemetryScratchRenderFrame() {
|
|
5448
|
+
return Number(this.native.telemetryScratchRenderFrame());
|
|
5449
|
+
}
|
|
5450
|
+
telemetryScratchTimelineSample() {
|
|
5451
|
+
return Number(this.native.telemetryScratchTimelineSample());
|
|
5452
|
+
}
|
|
5453
|
+
telemetryScratchAudibleTimelineSample() {
|
|
5454
|
+
return Number(this.native.telemetryScratchAudibleTimelineSample());
|
|
5455
|
+
}
|
|
5456
|
+
telemetryScratchGraphLatencySamplesQ8() {
|
|
5457
|
+
return this.native.telemetryScratchGraphLatencySamplesQ8();
|
|
5458
|
+
}
|
|
5459
|
+
telemetryScratchValue() {
|
|
5460
|
+
return this.native.telemetryScratchValue();
|
|
5461
|
+
}
|
|
5462
|
+
popMeterTelemetryToScratch() {
|
|
5463
|
+
return this.native.popMeterTelemetryToScratch();
|
|
5464
|
+
}
|
|
5465
|
+
meterScratchTargetId() {
|
|
5466
|
+
return this.native.meterScratchTargetId();
|
|
5467
|
+
}
|
|
5468
|
+
meterScratchRenderFrame() {
|
|
5469
|
+
return Number(this.native.meterScratchRenderFrame());
|
|
5470
|
+
}
|
|
5471
|
+
meterScratchValue(field) {
|
|
5472
|
+
return this.native.meterScratchValue(field);
|
|
5473
|
+
}
|
|
4724
5474
|
drainMeterTelemetry(maxRecords = 1024) {
|
|
4725
5475
|
return this.native.drainMeterTelemetry(maxRecords);
|
|
4726
5476
|
}
|
|
@@ -4748,6 +5498,30 @@ var RealtimeEngine = class {
|
|
|
4748
5498
|
drainScopeTelemetry(maxRecords = 1024) {
|
|
4749
5499
|
return this.native.drainScopeTelemetry(maxRecords);
|
|
4750
5500
|
}
|
|
5501
|
+
popScopeTelemetryToScratch() {
|
|
5502
|
+
return this.native.popScopeTelemetryToScratch();
|
|
5503
|
+
}
|
|
5504
|
+
scopeScratchTargetId() {
|
|
5505
|
+
return this.native.scopeScratchTargetId();
|
|
5506
|
+
}
|
|
5507
|
+
scopeScratchRenderFrame() {
|
|
5508
|
+
return Number(this.native.scopeScratchRenderFrame());
|
|
5509
|
+
}
|
|
5510
|
+
scopeScratchBandCount() {
|
|
5511
|
+
return this.native.scopeScratchBandCount();
|
|
5512
|
+
}
|
|
5513
|
+
scopeScratchBand(index) {
|
|
5514
|
+
return this.native.scopeScratchBand(index);
|
|
5515
|
+
}
|
|
5516
|
+
scopeScratchPointCount() {
|
|
5517
|
+
return this.native.scopeScratchPointCount();
|
|
5518
|
+
}
|
|
5519
|
+
scopeScratchPointLeft(index) {
|
|
5520
|
+
return this.native.scopeScratchPointLeft(index);
|
|
5521
|
+
}
|
|
5522
|
+
scopeScratchPointRight(index) {
|
|
5523
|
+
return this.native.scopeScratchPointRight(index);
|
|
5524
|
+
}
|
|
4751
5525
|
destroy() {
|
|
4752
5526
|
this.native.delete();
|
|
4753
5527
|
}
|
|
@@ -4813,6 +5587,7 @@ var StreamAnalyzer = class {
|
|
|
4813
5587
|
if (config.outputFormat !== void 0 && (typeof config.outputFormat !== "number" || !Number.isFinite(config.outputFormat) || !Number.isInteger(config.outputFormat) || config.outputFormat !== 0)) {
|
|
4814
5588
|
throw new TypeError("outputFormat must be the integer 0 (Float32)");
|
|
4815
5589
|
}
|
|
5590
|
+
const window = config.window === void 0 ? void 0 : resolveOrdinalInRange(config.window, 0, 3, "stream analyzer window");
|
|
4816
5591
|
const module2 = getSonareModule();
|
|
4817
5592
|
const defaults = streamAnalyzerConfigDefaults();
|
|
4818
5593
|
this.analyzer = new module2.StreamAnalyzer(
|
|
@@ -4834,7 +5609,7 @@ var StreamAnalyzer = class {
|
|
|
4834
5609
|
config.maxProgressionEntries ?? defaults.maxProgressionEntries,
|
|
4835
5610
|
config.keyUpdateIntervalSec ?? defaults.keyUpdateIntervalSec,
|
|
4836
5611
|
config.bpmUpdateIntervalSec ?? defaults.bpmUpdateIntervalSec,
|
|
4837
|
-
|
|
5612
|
+
window ?? defaults.window,
|
|
4838
5613
|
config.outputFormat ?? defaults.outputFormat
|
|
4839
5614
|
);
|
|
4840
5615
|
}
|
|
@@ -5262,7 +6037,7 @@ var Mixer = class _Mixer {
|
|
|
5262
6037
|
setPolarityInvert(stripIndex, invertLeft, invertRight) {
|
|
5263
6038
|
this.mixer.setPolarityInvert(stripIndex, invertLeft, invertRight);
|
|
5264
6039
|
}
|
|
5265
|
-
/** Set the strip's pan law. */
|
|
6040
|
+
/** Set the strip's pan law (a {@link PanLawName} alias or raw C ABI ordinal). */
|
|
5266
6041
|
setPanLaw(stripIndex, panLaw) {
|
|
5267
6042
|
this.mixer.setPanLaw(stripIndex, panLawCode(panLaw));
|
|
5268
6043
|
}
|
|
@@ -5449,65 +6224,18 @@ var Mixer = class _Mixer {
|
|
|
5449
6224
|
};
|
|
5450
6225
|
|
|
5451
6226
|
// src/realtime_voice_changer.ts
|
|
5452
|
-
function isFlatVoiceChangerPod(config) {
|
|
5453
|
-
return typeof config === "object" && config !== null && "retuneSemitones" in config;
|
|
5454
|
-
}
|
|
5455
|
-
function flatVoiceChangerPodToNested(pod) {
|
|
5456
|
-
return {
|
|
5457
|
-
inputGainDb: pod.inputGainDb,
|
|
5458
|
-
outputGainDb: pod.outputGainDb,
|
|
5459
|
-
wetMix: pod.wetMix,
|
|
5460
|
-
retune: { semitones: pod.retuneSemitones, mix: pod.retuneMix, grainSize: pod.retuneGrainSize },
|
|
5461
|
-
formant: {
|
|
5462
|
-
factor: pod.formantFactor,
|
|
5463
|
-
amount: pod.formantAmount,
|
|
5464
|
-
body: pod.formantBody,
|
|
5465
|
-
brightness: pod.formantBrightness,
|
|
5466
|
-
nasal: pod.formantNasal
|
|
5467
|
-
},
|
|
5468
|
-
eq: {
|
|
5469
|
-
highpassHz: pod.eqHighpassHz,
|
|
5470
|
-
bodyDb: pod.eqBodyDb,
|
|
5471
|
-
presenceDb: pod.eqPresenceDb,
|
|
5472
|
-
airDb: pod.eqAirDb
|
|
5473
|
-
},
|
|
5474
|
-
gate: {
|
|
5475
|
-
thresholdDb: pod.gateThresholdDb,
|
|
5476
|
-
attackMs: pod.gateAttackMs,
|
|
5477
|
-
releaseMs: pod.gateReleaseMs,
|
|
5478
|
-
rangeDb: pod.gateRangeDb
|
|
5479
|
-
},
|
|
5480
|
-
compressor: {
|
|
5481
|
-
thresholdDb: pod.compressorThresholdDb,
|
|
5482
|
-
ratio: pod.compressorRatio,
|
|
5483
|
-
attackMs: pod.compressorAttackMs,
|
|
5484
|
-
releaseMs: pod.compressorReleaseMs,
|
|
5485
|
-
makeupGainDb: pod.compressorMakeupGainDb
|
|
5486
|
-
},
|
|
5487
|
-
deesser: {
|
|
5488
|
-
frequencyHz: pod.deesserFrequencyHz,
|
|
5489
|
-
thresholdDb: pod.deesserThresholdDb,
|
|
5490
|
-
ratio: pod.deesserRatio,
|
|
5491
|
-
rangeDb: pod.deesserRangeDb
|
|
5492
|
-
},
|
|
5493
|
-
reverb: {
|
|
5494
|
-
mix: pod.reverbMix,
|
|
5495
|
-
timeMs: pod.reverbTimeMs,
|
|
5496
|
-
damping: pod.reverbDamping,
|
|
5497
|
-
seed: pod.reverbSeed
|
|
5498
|
-
},
|
|
5499
|
-
limiter: {
|
|
5500
|
-
ceilingDb: pod.limiterCeilingDb,
|
|
5501
|
-
releaseMs: pod.limiterReleaseMs,
|
|
5502
|
-
enableIspLimiter: pod.limiterEnableIspLimiter,
|
|
5503
|
-
ispCeilingDbtp: pod.limiterIspCeilingDbtp
|
|
5504
|
-
}
|
|
5505
|
-
};
|
|
5506
|
-
}
|
|
5507
6227
|
var RealtimeVoiceChanger = class {
|
|
5508
|
-
|
|
6228
|
+
/**
|
|
6229
|
+
* Creates a voice changer. Supplying `sampleRate` prepares it immediately,
|
|
6230
|
+
* matching the Node and Python constructors; omitting it preserves the
|
|
6231
|
+
* explicit {@link prepare} lifecycle for callers that configure later.
|
|
6232
|
+
*/
|
|
6233
|
+
constructor(config = "neutral-monitor", sampleRate, maxBlockSize = 128, channels = 1) {
|
|
5509
6234
|
const module2 = getSonareModule();
|
|
5510
6235
|
this.changer = module2.createRealtimeVoiceChanger(config);
|
|
6236
|
+
if (sampleRate !== void 0) {
|
|
6237
|
+
this.changer.prepare(sampleRate, maxBlockSize, channels);
|
|
6238
|
+
}
|
|
5511
6239
|
}
|
|
5512
6240
|
prepare(sampleRate, maxBlockSize = 128, channels = 1) {
|
|
5513
6241
|
this.changer.prepare(sampleRate, maxBlockSize, channels);
|
|
@@ -5516,8 +6244,15 @@ var RealtimeVoiceChanger = class {
|
|
|
5516
6244
|
this.changer.reset();
|
|
5517
6245
|
}
|
|
5518
6246
|
setConfig(config) {
|
|
5519
|
-
|
|
5520
|
-
|
|
6247
|
+
this.changer.setConfig(config);
|
|
6248
|
+
}
|
|
6249
|
+
/**
|
|
6250
|
+
* Apply a flat, pre-normalized config without JSON serialization. Intended
|
|
6251
|
+
* for AudioWorklet control messages whose sender prepared the POD on the
|
|
6252
|
+
* main thread.
|
|
6253
|
+
*/
|
|
6254
|
+
setPodConfig(config) {
|
|
6255
|
+
this.changer.setPodConfig(config);
|
|
5521
6256
|
}
|
|
5522
6257
|
configJson() {
|
|
5523
6258
|
return this.changer.configJson();
|
|
@@ -5525,6 +6260,13 @@ var RealtimeVoiceChanger = class {
|
|
|
5525
6260
|
latencySamples() {
|
|
5526
6261
|
return this.changer.latencySamples();
|
|
5527
6262
|
}
|
|
6263
|
+
/**
|
|
6264
|
+
* Monotonically increases whenever {@link prepare} can replace the native
|
|
6265
|
+
* scratch buffers. Cached WASM heap views must be reacquired after it changes.
|
|
6266
|
+
*/
|
|
6267
|
+
bufferGeneration() {
|
|
6268
|
+
return this.changer.bufferGeneration();
|
|
6269
|
+
}
|
|
5528
6270
|
processMono(samples) {
|
|
5529
6271
|
return this.changer.processMono(samples);
|
|
5530
6272
|
}
|
|
@@ -5601,10 +6343,12 @@ var RealtimeVoiceChanger = class {
|
|
|
5601
6343
|
createRealtimeMonoBuffer(numSamples) {
|
|
5602
6344
|
let input = this.getMonoInputBuffer(numSamples);
|
|
5603
6345
|
let output = this.getMonoOutputBuffer(numSamples);
|
|
6346
|
+
let generation = this.bufferGeneration();
|
|
5604
6347
|
const reacquireIfDetached = () => {
|
|
5605
|
-
if (input.byteLength === 0 || output.byteLength === 0) {
|
|
6348
|
+
if (generation !== this.bufferGeneration() || input.byteLength === 0 || output.byteLength === 0) {
|
|
5606
6349
|
input = this.getMonoInputBuffer(numSamples);
|
|
5607
6350
|
output = this.getMonoOutputBuffer(numSamples);
|
|
6351
|
+
generation = this.bufferGeneration();
|
|
5608
6352
|
}
|
|
5609
6353
|
};
|
|
5610
6354
|
return {
|
|
@@ -5626,10 +6370,12 @@ var RealtimeVoiceChanger = class {
|
|
|
5626
6370
|
createRealtimeInterleavedBuffer(numFrames, numChannels) {
|
|
5627
6371
|
let input = this.getInterleavedInputBuffer(numFrames, numChannels);
|
|
5628
6372
|
let output = this.getInterleavedOutputBuffer(numFrames, numChannels);
|
|
6373
|
+
let generation = this.bufferGeneration();
|
|
5629
6374
|
const reacquireIfDetached = () => {
|
|
5630
|
-
if (input.byteLength === 0 || output.byteLength === 0) {
|
|
6375
|
+
if (generation !== this.bufferGeneration() || input.byteLength === 0 || output.byteLength === 0) {
|
|
5631
6376
|
input = this.getInterleavedInputBuffer(numFrames, numChannels);
|
|
5632
6377
|
output = this.getInterleavedOutputBuffer(numFrames, numChannels);
|
|
6378
|
+
generation = this.bufferGeneration();
|
|
5633
6379
|
}
|
|
5634
6380
|
};
|
|
5635
6381
|
return {
|
|
@@ -5656,15 +6402,17 @@ var RealtimeVoiceChanger = class {
|
|
|
5656
6402
|
*/
|
|
5657
6403
|
createRealtimePlanarBuffer(numFrames, numChannels) {
|
|
5658
6404
|
let channels = [];
|
|
6405
|
+
let generation = this.bufferGeneration();
|
|
5659
6406
|
const acquire = () => {
|
|
5660
6407
|
channels = [];
|
|
5661
6408
|
for (let ch = 0; ch < numChannels; ch++) {
|
|
5662
6409
|
channels.push(this.getPlanarChannelBuffer(ch, numFrames));
|
|
5663
6410
|
}
|
|
6411
|
+
generation = this.bufferGeneration();
|
|
5664
6412
|
};
|
|
5665
6413
|
acquire();
|
|
5666
6414
|
const reacquireIfDetached = () => {
|
|
5667
|
-
if ((channels[0]?.byteLength ?? 0) === 0) {
|
|
6415
|
+
if (generation !== this.bufferGeneration() || (channels[0]?.byteLength ?? 0) === 0) {
|
|
5668
6416
|
acquire();
|
|
5669
6417
|
}
|
|
5670
6418
|
};
|
|
@@ -5740,6 +6488,19 @@ var StreamingMasteringChain = class {
|
|
|
5740
6488
|
}
|
|
5741
6489
|
return this.chain.processStereo(left, right);
|
|
5742
6490
|
}
|
|
6491
|
+
/**
|
|
6492
|
+
* Emit delayed audio and finite processor tails after the final mono block.
|
|
6493
|
+
* Call until this returns an empty array. The initial `latencySamples()`
|
|
6494
|
+
* samples of the concatenated stream are delayed and should be discarded for
|
|
6495
|
+
* time-aligned output.
|
|
6496
|
+
*/
|
|
6497
|
+
flushMono() {
|
|
6498
|
+
return this.chain.flushMono();
|
|
6499
|
+
}
|
|
6500
|
+
/** Stereo counterpart of {@link flushMono}. */
|
|
6501
|
+
flushStereo() {
|
|
6502
|
+
return this.chain.flushStereo();
|
|
6503
|
+
}
|
|
5743
6504
|
/** Reset all processor state without rebuilding. */
|
|
5744
6505
|
reset() {
|
|
5745
6506
|
this.chain.reset();
|
|
@@ -5981,7 +6742,6 @@ async function bindWebMidi(engine, options = {}) {
|
|
|
5981
6742
|
for (const [, input] of iterInputs(access)) {
|
|
5982
6743
|
bindInput(input);
|
|
5983
6744
|
}
|
|
5984
|
-
notify();
|
|
5985
6745
|
};
|
|
5986
6746
|
const stateListener = (event) => {
|
|
5987
6747
|
if (closed) {
|
|
@@ -6000,6 +6760,7 @@ async function bindWebMidi(engine, options = {}) {
|
|
|
6000
6760
|
notify();
|
|
6001
6761
|
};
|
|
6002
6762
|
refreshInputs();
|
|
6763
|
+
notify();
|
|
6003
6764
|
if (access.addEventListener) {
|
|
6004
6765
|
access.addEventListener("statechange", stateListener);
|
|
6005
6766
|
} else {
|
|
@@ -6101,12 +6862,8 @@ function dispatchUmpMessage(engine, words, portTimeSamples) {
|
|
|
6101
6862
|
if (status === 8) {
|
|
6102
6863
|
engine.pushMidiInputNoteOff(group, channel, data1, word1 >>> 25 & 127, portTimeSamples);
|
|
6103
6864
|
} else if (status === 9) {
|
|
6104
|
-
const velocity = word1 >>> 25 & 127;
|
|
6105
|
-
|
|
6106
|
-
engine.pushMidiInputNoteOff(group, channel, data1, 0, portTimeSamples);
|
|
6107
|
-
} else {
|
|
6108
|
-
engine.pushMidiInputNoteOn(group, channel, data1, velocity, portTimeSamples);
|
|
6109
|
-
}
|
|
6865
|
+
const velocity = Math.max(1, word1 >>> 25 & 127);
|
|
6866
|
+
engine.pushMidiInputNoteOn(group, channel, data1, velocity, portTimeSamples);
|
|
6110
6867
|
} else if (status === 11) {
|
|
6111
6868
|
engine.pushMidiInputCc(group, channel, data1, word1 >>> 25 & 127, portTimeSamples);
|
|
6112
6869
|
}
|
|
@@ -6131,6 +6888,214 @@ function iterInputs(access) {
|
|
|
6131
6888
|
return access.inputs instanceof Map ? access.inputs.entries() : access.inputs;
|
|
6132
6889
|
}
|
|
6133
6890
|
|
|
6891
|
+
// src/worker_client.ts
|
|
6892
|
+
var OfflineWorkerTask = class {
|
|
6893
|
+
constructor(result, cancelRequest) {
|
|
6894
|
+
this.result = result;
|
|
6895
|
+
this.cancelRequest = cancelRequest;
|
|
6896
|
+
}
|
|
6897
|
+
cancel() {
|
|
6898
|
+
this.cancelRequest();
|
|
6899
|
+
}
|
|
6900
|
+
// biome-ignore lint/suspicious/noThenProperty: this intentionally implements PromiseLike so callers can await a task and cancel it.
|
|
6901
|
+
then(onfulfilled, onrejected) {
|
|
6902
|
+
return this.result.then(onfulfilled, onrejected);
|
|
6903
|
+
}
|
|
6904
|
+
catch(onrejected) {
|
|
6905
|
+
return this.result.catch(onrejected);
|
|
6906
|
+
}
|
|
6907
|
+
finally(onfinally) {
|
|
6908
|
+
return this.result.finally(onfinally);
|
|
6909
|
+
}
|
|
6910
|
+
};
|
|
6911
|
+
function cloneForWorker(value, copy, transfers, transferred = /* @__PURE__ */ new Set()) {
|
|
6912
|
+
if (value instanceof Float32Array) {
|
|
6913
|
+
const samples = copy ? value.slice() : value;
|
|
6914
|
+
const buffer = samples.buffer;
|
|
6915
|
+
if (!(buffer instanceof ArrayBuffer)) {
|
|
6916
|
+
throw new TypeError(
|
|
6917
|
+
"OfflineWorkerClient only transfers Float32Array values backed by ArrayBuffer"
|
|
6918
|
+
);
|
|
6919
|
+
}
|
|
6920
|
+
if (!transferred.has(buffer)) {
|
|
6921
|
+
transferred.add(buffer);
|
|
6922
|
+
transfers.push(buffer);
|
|
6923
|
+
}
|
|
6924
|
+
return samples;
|
|
6925
|
+
}
|
|
6926
|
+
if (Array.isArray(value)) {
|
|
6927
|
+
return value.map((item) => cloneForWorker(item, copy, transfers, transferred));
|
|
6928
|
+
}
|
|
6929
|
+
if (value !== null && typeof value === "object") {
|
|
6930
|
+
return Object.fromEntries(
|
|
6931
|
+
Object.entries(value).map(([key, item]) => [
|
|
6932
|
+
key,
|
|
6933
|
+
cloneForWorker(item, copy, transfers, transferred)
|
|
6934
|
+
])
|
|
6935
|
+
);
|
|
6936
|
+
}
|
|
6937
|
+
return value;
|
|
6938
|
+
}
|
|
6939
|
+
function cancellationFlag() {
|
|
6940
|
+
if (typeof SharedArrayBuffer === "undefined") {
|
|
6941
|
+
return void 0;
|
|
6942
|
+
}
|
|
6943
|
+
return new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
|
|
6944
|
+
}
|
|
6945
|
+
function workerError(message) {
|
|
6946
|
+
if (message.error.code !== void 0) {
|
|
6947
|
+
return new SonareError(
|
|
6948
|
+
message.error.code,
|
|
6949
|
+
message.error.codeName ?? "Unknown",
|
|
6950
|
+
message.error.message
|
|
6951
|
+
);
|
|
6952
|
+
}
|
|
6953
|
+
const error = new Error(message.error.message);
|
|
6954
|
+
error.name = message.error.name;
|
|
6955
|
+
return error;
|
|
6956
|
+
}
|
|
6957
|
+
var OfflineWorkerClient = class {
|
|
6958
|
+
constructor(options = {}) {
|
|
6959
|
+
this.pending = /* @__PURE__ */ new Map();
|
|
6960
|
+
this.nextId = 1;
|
|
6961
|
+
this.closed = false;
|
|
6962
|
+
this.usesEventTarget = false;
|
|
6963
|
+
this.onMessage = (event) => {
|
|
6964
|
+
const message = event.data;
|
|
6965
|
+
const pending = this.pending.get(message.id);
|
|
6966
|
+
if (!pending) {
|
|
6967
|
+
return;
|
|
6968
|
+
}
|
|
6969
|
+
if (message.type === "sonare:offline-progress") {
|
|
6970
|
+
pending.onProgress?.({ progress: message.progress, stage: message.stage });
|
|
6971
|
+
return;
|
|
6972
|
+
}
|
|
6973
|
+
this.pending.delete(message.id);
|
|
6974
|
+
if (message.type === "sonare:offline-result") {
|
|
6975
|
+
pending.resolve(message.result);
|
|
6976
|
+
return;
|
|
6977
|
+
}
|
|
6978
|
+
pending.reject(workerError(message));
|
|
6979
|
+
};
|
|
6980
|
+
this.onError = (event) => {
|
|
6981
|
+
const error = new Error(event.message || "Offline Worker failed");
|
|
6982
|
+
for (const { reject } of this.pending.values()) {
|
|
6983
|
+
reject(error);
|
|
6984
|
+
}
|
|
6985
|
+
this.pending.clear();
|
|
6986
|
+
};
|
|
6987
|
+
this.onNodeMessage = (data) => {
|
|
6988
|
+
this.onMessage({ data });
|
|
6989
|
+
};
|
|
6990
|
+
this.onNodeError = (error) => {
|
|
6991
|
+
this.onError(
|
|
6992
|
+
error instanceof Error ? { message: error.message } : { message: String(error) }
|
|
6993
|
+
);
|
|
6994
|
+
};
|
|
6995
|
+
this.ownsWorker = options.worker === void 0 || options.terminateWorkerOnDispose === true;
|
|
6996
|
+
if (options.worker) {
|
|
6997
|
+
this.worker = options.worker;
|
|
6998
|
+
} else {
|
|
6999
|
+
if (!options.workerFactory && typeof Worker === "undefined") {
|
|
7000
|
+
throw new Error("OfflineWorkerClient requires a browser Worker implementation");
|
|
7001
|
+
}
|
|
7002
|
+
const url = options.workerUrl === void 0 ? new URL("./worker.js", import.meta.url) : new URL(options.workerUrl, import.meta.url);
|
|
7003
|
+
this.worker = options.workerFactory?.(url) ?? new Worker(url, { type: "module", name: "sonare-offline" });
|
|
7004
|
+
}
|
|
7005
|
+
if (this.worker.addEventListener) {
|
|
7006
|
+
this.usesEventTarget = true;
|
|
7007
|
+
this.worker.addEventListener("message", this.onMessage);
|
|
7008
|
+
this.worker.addEventListener("error", this.onError);
|
|
7009
|
+
} else if (this.worker.on) {
|
|
7010
|
+
this.worker.on("message", this.onNodeMessage);
|
|
7011
|
+
this.worker.on("error", this.onNodeError);
|
|
7012
|
+
} else {
|
|
7013
|
+
throw new TypeError("OfflineWorkerClient requires Worker event listeners");
|
|
7014
|
+
}
|
|
7015
|
+
}
|
|
7016
|
+
/** Dispatch full music analysis to the Worker. */
|
|
7017
|
+
analyze(request, options) {
|
|
7018
|
+
return this.call("analyze", request, options);
|
|
7019
|
+
}
|
|
7020
|
+
/** Dispatch BPM detection to the Worker. */
|
|
7021
|
+
detectBpm(request, options) {
|
|
7022
|
+
return this.call("detectBpm", request, options);
|
|
7023
|
+
}
|
|
7024
|
+
/** Dispatch key detection to the Worker. */
|
|
7025
|
+
detectKey(request, options) {
|
|
7026
|
+
return this.call("detectKey", request, options);
|
|
7027
|
+
}
|
|
7028
|
+
/** Dispatch chord detection to the Worker. */
|
|
7029
|
+
detectChords(request, options) {
|
|
7030
|
+
return this.call("detectChords", request, options);
|
|
7031
|
+
}
|
|
7032
|
+
/** Dispatch mono preset mastering to the Worker. */
|
|
7033
|
+
masterAudio(request, options) {
|
|
7034
|
+
return this.call("masterAudio", request, options);
|
|
7035
|
+
}
|
|
7036
|
+
/** Dispatch stereo preset mastering to the Worker. */
|
|
7037
|
+
masterAudioStereo(request, options) {
|
|
7038
|
+
return this.call("masterAudioStereo", request, options);
|
|
7039
|
+
}
|
|
7040
|
+
/** Stop accepting calls, reject outstanding work, and release the Worker if owned. */
|
|
7041
|
+
dispose() {
|
|
7042
|
+
if (this.closed) {
|
|
7043
|
+
return;
|
|
7044
|
+
}
|
|
7045
|
+
this.closed = true;
|
|
7046
|
+
if (this.usesEventTarget) {
|
|
7047
|
+
this.worker.removeEventListener?.("message", this.onMessage);
|
|
7048
|
+
this.worker.removeEventListener?.("error", this.onError);
|
|
7049
|
+
} else {
|
|
7050
|
+
this.worker.off?.("message", this.onNodeMessage);
|
|
7051
|
+
this.worker.off?.("error", this.onNodeError);
|
|
7052
|
+
}
|
|
7053
|
+
for (const { reject } of this.pending.values()) {
|
|
7054
|
+
reject(new Error("OfflineWorkerClient was disposed"));
|
|
7055
|
+
}
|
|
7056
|
+
this.pending.clear();
|
|
7057
|
+
if (this.ownsWorker) {
|
|
7058
|
+
this.worker.terminate();
|
|
7059
|
+
}
|
|
7060
|
+
}
|
|
7061
|
+
call(operation, request, options = {}) {
|
|
7062
|
+
if (this.closed) {
|
|
7063
|
+
throw new Error("OfflineWorkerClient was disposed");
|
|
7064
|
+
}
|
|
7065
|
+
const id = this.nextId++;
|
|
7066
|
+
const transfers = [];
|
|
7067
|
+
const preparedRequest = cloneForWorker(request, options.copy === true, transfers);
|
|
7068
|
+
const cancelFlag = cancellationFlag();
|
|
7069
|
+
const result = new Promise((resolve, reject) => {
|
|
7070
|
+
this.pending.set(id, {
|
|
7071
|
+
resolve: (value) => resolve(value),
|
|
7072
|
+
reject,
|
|
7073
|
+
onProgress: options.onProgress,
|
|
7074
|
+
cancelFlag
|
|
7075
|
+
});
|
|
7076
|
+
});
|
|
7077
|
+
this.worker.postMessage(
|
|
7078
|
+
{
|
|
7079
|
+
type: "sonare:offline-run",
|
|
7080
|
+
id,
|
|
7081
|
+
operation,
|
|
7082
|
+
request: preparedRequest,
|
|
7083
|
+
...cancelFlag ? { cancelBuffer: cancelFlag.buffer } : {}
|
|
7084
|
+
},
|
|
7085
|
+
transfers
|
|
7086
|
+
);
|
|
7087
|
+
return new OfflineWorkerTask(result, () => {
|
|
7088
|
+
if (!this.pending.has(id)) {
|
|
7089
|
+
return;
|
|
7090
|
+
}
|
|
7091
|
+
if (cancelFlag) {
|
|
7092
|
+
Atomics.store(cancelFlag, 0, 1);
|
|
7093
|
+
}
|
|
7094
|
+
this.worker.postMessage({ type: "sonare:offline-cancel", id });
|
|
7095
|
+
});
|
|
7096
|
+
}
|
|
7097
|
+
};
|
|
7098
|
+
|
|
6134
7099
|
// src/index.ts
|
|
6135
7100
|
var module = null;
|
|
6136
7101
|
var initPromise = null;
|
|
@@ -6162,6 +7127,18 @@ function version() {
|
|
|
6162
7127
|
}
|
|
6163
7128
|
return module.version();
|
|
6164
7129
|
}
|
|
7130
|
+
function capabilities() {
|
|
7131
|
+
if (!module) {
|
|
7132
|
+
throw new Error("Module not initialized. Call init() first.");
|
|
7133
|
+
}
|
|
7134
|
+
return module.capabilities();
|
|
7135
|
+
}
|
|
7136
|
+
function capabilityCatalog() {
|
|
7137
|
+
if (!module) {
|
|
7138
|
+
throw new Error("Module not initialized. Call init() first.");
|
|
7139
|
+
}
|
|
7140
|
+
return JSON.parse(module.capabilityCatalog());
|
|
7141
|
+
}
|
|
6165
7142
|
function abiVersion() {
|
|
6166
7143
|
if (!module) {
|
|
6167
7144
|
throw new Error("Module not initialized. Call init() first.");
|
|
@@ -6190,6 +7167,9 @@ var VOICE_PRESET_ORDINALS = [
|
|
|
6190
7167
|
];
|
|
6191
7168
|
function resolveVoicePresetOrdinal(preset) {
|
|
6192
7169
|
if (typeof preset === "number") {
|
|
7170
|
+
if (!Number.isSafeInteger(preset) || preset < 0 || preset >= VOICE_PRESET_ORDINALS.length) {
|
|
7171
|
+
throw new RangeError(`Unknown voice-character preset ordinal: ${String(preset)}`);
|
|
7172
|
+
}
|
|
6193
7173
|
return preset;
|
|
6194
7174
|
}
|
|
6195
7175
|
const ordinal = VOICE_PRESET_ORDINALS.indexOf(preset);
|
|
@@ -6202,6 +7182,9 @@ function voiceCharacterPresetId(preset) {
|
|
|
6202
7182
|
if (!module) {
|
|
6203
7183
|
throw new Error("Module not initialized. Call init() first.");
|
|
6204
7184
|
}
|
|
7185
|
+
if (typeof preset === "number" && (!Number.isSafeInteger(preset) || preset < 0 || preset >= VOICE_PRESET_ORDINALS.length)) {
|
|
7186
|
+
return null;
|
|
7187
|
+
}
|
|
6205
7188
|
return module.voiceCharacterPresetId(resolveVoicePresetOrdinal(preset));
|
|
6206
7189
|
}
|
|
6207
7190
|
function realtimeVoiceChangerPresetConfig(preset) {
|
|
@@ -6212,7 +7195,10 @@ function realtimeVoiceChangerPresetConfig(preset) {
|
|
|
6212
7195
|
}
|
|
6213
7196
|
export {
|
|
6214
7197
|
Audio,
|
|
7198
|
+
AutomationTargetKind,
|
|
7199
|
+
BUILTIN_SYNTH_WAVEFORMS,
|
|
6215
7200
|
ChordQuality,
|
|
7201
|
+
ClipPageProvider,
|
|
6216
7202
|
ClipPageStreamer,
|
|
6217
7203
|
EXPECTED_ENGINE_ABI_VERSION,
|
|
6218
7204
|
EXPECTED_PROJECT_ABI_VERSION,
|
|
@@ -6221,6 +7207,11 @@ export {
|
|
|
6221
7207
|
MarkerKind,
|
|
6222
7208
|
Mixer,
|
|
6223
7209
|
Mode,
|
|
7210
|
+
OfflineWorkerClient,
|
|
7211
|
+
OfflineWorkerTask,
|
|
7212
|
+
PROJECT_AUTOMATION_TARGET_OPAQUE,
|
|
7213
|
+
PROJECT_AUTOMATION_TARGET_TRACK_FADER_DB,
|
|
7214
|
+
PROJECT_AUTOMATION_TARGET_TRACK_PAN,
|
|
6224
7215
|
PitchClass as Pitch,
|
|
6225
7216
|
PitchClass,
|
|
6226
7217
|
Project,
|
|
@@ -6254,10 +7245,14 @@ export {
|
|
|
6254
7245
|
bassChroma,
|
|
6255
7246
|
bindMicrophoneInput,
|
|
6256
7247
|
bindWebMidi,
|
|
7248
|
+
capabilities,
|
|
7249
|
+
capabilityCatalog,
|
|
7250
|
+
chirp,
|
|
6257
7251
|
chordFunctionalAnalysis,
|
|
6258
7252
|
chroma,
|
|
6259
7253
|
chromaCens,
|
|
6260
7254
|
chromaCqt,
|
|
7255
|
+
clicks,
|
|
6261
7256
|
cqt,
|
|
6262
7257
|
cqtToAudio,
|
|
6263
7258
|
createOpfsClipPageProvider,
|
|
@@ -6287,6 +7282,7 @@ export {
|
|
|
6287
7282
|
frameSignal,
|
|
6288
7283
|
framesToSamples,
|
|
6289
7284
|
framesToTime,
|
|
7285
|
+
griffinLim,
|
|
6290
7286
|
harmonic,
|
|
6291
7287
|
hasFfmpegSupport,
|
|
6292
7288
|
hpss,
|
|
@@ -6337,6 +7333,7 @@ export {
|
|
|
6337
7333
|
masteringStereoAnalysisNames,
|
|
6338
7334
|
masteringStereoAnalyze,
|
|
6339
7335
|
masteringStreamingPreview,
|
|
7336
|
+
melDelta,
|
|
6340
7337
|
melSpectrogram,
|
|
6341
7338
|
melToAudio,
|
|
6342
7339
|
melToHz,
|
|
@@ -6369,8 +7366,10 @@ export {
|
|
|
6369
7366
|
nnlsChroma,
|
|
6370
7367
|
normalize,
|
|
6371
7368
|
noteMove,
|
|
7369
|
+
noteSegments,
|
|
6372
7370
|
noteStretch,
|
|
6373
7371
|
noteToHz,
|
|
7372
|
+
onsetBacktrack,
|
|
6374
7373
|
onsetEnvelope,
|
|
6375
7374
|
onsetStrengthMulti,
|
|
6376
7375
|
opfsClipPageWorkerSource,
|
|
@@ -6379,6 +7378,7 @@ export {
|
|
|
6379
7378
|
peakPick,
|
|
6380
7379
|
percussive,
|
|
6381
7380
|
phaseVocoder,
|
|
7381
|
+
piptrack,
|
|
6382
7382
|
pitchCorrectTimevarying,
|
|
6383
7383
|
pitchCorrectToMidi,
|
|
6384
7384
|
pitchCorrectToMidiTimevarying,
|
|
@@ -6395,6 +7395,7 @@ export {
|
|
|
6395
7395
|
realtimeVoiceChangerPresetConfig,
|
|
6396
7396
|
realtimeVoiceChangerPresetJson,
|
|
6397
7397
|
realtimeVoiceChangerPresetNames,
|
|
7398
|
+
reassignedSpectrogram,
|
|
6398
7399
|
remix,
|
|
6399
7400
|
resample,
|
|
6400
7401
|
rmsEnergy,
|
|
@@ -6403,12 +7404,20 @@ export {
|
|
|
6403
7404
|
scaleCorrectionSemitones,
|
|
6404
7405
|
scalePitchClassEnabled,
|
|
6405
7406
|
scaleQuantizeMidi,
|
|
7407
|
+
segmentAgglomerative,
|
|
7408
|
+
segmentCrossSimilarity,
|
|
7409
|
+
segmentLagToRecurrence,
|
|
7410
|
+
segmentPathEnhance,
|
|
7411
|
+
segmentRecurrenceMatrix,
|
|
7412
|
+
segmentRecurrenceToLag,
|
|
7413
|
+
segmentSubsegment,
|
|
6406
7414
|
shortTermLufs,
|
|
6407
7415
|
spectralBandwidth,
|
|
6408
7416
|
spectralCentroid,
|
|
6409
7417
|
spectralContrast,
|
|
6410
7418
|
spectralEdit,
|
|
6411
7419
|
spectralFlatness,
|
|
7420
|
+
spectralFlux,
|
|
6412
7421
|
spectralRolloff,
|
|
6413
7422
|
splitSilence,
|
|
6414
7423
|
stft,
|
|
@@ -6422,6 +7431,7 @@ export {
|
|
|
6422
7431
|
tempogramRatio,
|
|
6423
7432
|
timeStretch,
|
|
6424
7433
|
timeToFrames,
|
|
7434
|
+
tone,
|
|
6425
7435
|
tonnetz,
|
|
6426
7436
|
trim,
|
|
6427
7437
|
trimSilence,
|