@libraz/libsonare 1.6.0 → 1.7.1
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 +2 -2
- package/dist/analysis.d.ts +139 -11
- package/dist/analysis.js +162 -42
- package/dist/analysis.js.map +1 -1
- package/dist/index.d.ts +211 -39
- package/dist/index.js +501 -142
- package/dist/index.js.map +1 -1
- package/dist/schemas/realtime-voice-changer-preset.schema.json +2 -2
- package/dist/sonare-analysis.js +1 -1
- package/dist/sonare-analysis.wasm +0 -0
- package/dist/sonare.js +1 -1
- package/dist/sonare.wasm +0 -0
- package/dist/worker.js +56 -29
- package/dist/worker.js.map +1 -1
- package/dist/worklet.d.ts +67 -18
- package/dist/worklet.js +193 -42
- package/dist/worklet.js.map +1 -1
- package/package.json +3 -3
- package/src/_chain_config.ts +6 -1
- package/src/analysis_helpers.ts +34 -29
- package/src/audio.ts +7 -2
- package/src/codes.ts +47 -11
- package/src/effects_mastering.ts +5 -0
- package/src/effects_transform.ts +202 -22
- package/src/feature_music.ts +8 -1
- package/src/feature_spectral.ts +64 -2
- package/src/feature_spectrogram.ts +44 -3
- package/src/index.ts +28 -3
- package/src/mastering_core.ts +70 -0
- package/src/metering.ts +18 -0
- package/src/mixer.ts +3 -3
- package/src/project.ts +6 -0
- package/src/project_class.ts +143 -16
- package/src/project_internal.ts +14 -5
- package/src/project_types.ts +50 -9
- package/src/public_types_mastering.ts +9 -0
- package/src/public_types_mixing.ts +16 -0
- package/src/public_types_realtime.ts +23 -5
- package/src/public_types_spectral.ts +16 -2
- package/src/quick_analysis.ts +21 -3
- package/src/realtime_engine.ts +14 -3
- package/src/sonare.js.d.ts +87 -0
- package/src/stream_analyzer.ts +6 -1
- package/src/web_midi.ts +10 -7
- package/src/worklet/engine-node.ts +54 -19
- package/src/worklet/engine-parameter-facade.ts +30 -1
- package/src/worklet/engine-processor.ts +52 -20
- package/src/worklet/engine-register.ts +1 -1
- package/src/worklet/engine-strips.ts +2 -2
- package/src/worklet/engine.ts +10 -0
- package/src/worklet/guards.ts +99 -7
- package/src/worklet/messages.ts +41 -1
- package/src/worklet/protocol.ts +4 -0
package/dist/index.js
CHANGED
|
@@ -227,13 +227,66 @@ function assertInterleavedSamples(fnName, samples, channels, validate) {
|
|
|
227
227
|
function requireModule() {
|
|
228
228
|
return getSonareModule();
|
|
229
229
|
}
|
|
230
|
-
function
|
|
231
|
-
const
|
|
232
|
-
|
|
230
|
+
function toVoicedFloat32(voiced) {
|
|
231
|
+
const out = new Float32Array(voiced.length);
|
|
232
|
+
for (let index = 0; index < voiced.length; index += 1) {
|
|
233
|
+
out[index] = voiced[index] ? 1 : 0;
|
|
234
|
+
}
|
|
235
|
+
return out;
|
|
236
|
+
}
|
|
237
|
+
function resolveEffectFftOptions(fnName, nFft, hopLength) {
|
|
238
|
+
const resolvedNFft = nFft === void 0 ? 2048 : nFft;
|
|
239
|
+
const resolvedHopLength = hopLength === void 0 ? 512 : hopLength;
|
|
240
|
+
if (typeof resolvedNFft !== "number" || !Number.isInteger(resolvedNFft)) {
|
|
241
|
+
throw new TypeError(`${fnName}: nFft must be an integer`);
|
|
242
|
+
}
|
|
243
|
+
if (resolvedNFft < 2 || resolvedNFft > 2 ** 30) {
|
|
244
|
+
throw new RangeError(`${fnName}: nFft must be an even power of two >= 2`);
|
|
245
|
+
}
|
|
246
|
+
if ((resolvedNFft & resolvedNFft - 1) !== 0) {
|
|
247
|
+
throw new RangeError(`${fnName}: nFft must be an even power of two >= 2`);
|
|
248
|
+
}
|
|
249
|
+
if (typeof resolvedHopLength !== "number" || !Number.isInteger(resolvedHopLength)) {
|
|
250
|
+
throw new TypeError(`${fnName}: hopLength must be an integer`);
|
|
251
|
+
}
|
|
252
|
+
if (resolvedHopLength <= 0 || resolvedHopLength > 2 ** 31 - 1) {
|
|
253
|
+
throw new RangeError(`${fnName}: hopLength must be a positive integer`);
|
|
254
|
+
}
|
|
255
|
+
return { nFft: resolvedNFft, hopLength: resolvedHopLength };
|
|
256
|
+
}
|
|
257
|
+
function resolveNormalizeMode(value) {
|
|
258
|
+
if (value === void 0) {
|
|
259
|
+
return "peak";
|
|
260
|
+
}
|
|
261
|
+
if (typeof value !== "string") {
|
|
262
|
+
throw new TypeError("normalize: mode must be the string 'peak' or 'rms'");
|
|
263
|
+
}
|
|
264
|
+
if (value !== "peak" && value !== "rms") {
|
|
265
|
+
throw new RangeError("normalize: mode must be the string 'peak' or 'rms'");
|
|
266
|
+
}
|
|
267
|
+
return value;
|
|
268
|
+
}
|
|
269
|
+
function resolveHardMask(value, fnName) {
|
|
270
|
+
if (value === void 0) {
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
if (typeof value !== "boolean") {
|
|
274
|
+
throw new TypeError(`${fnName}: hardMask must be a boolean`);
|
|
275
|
+
}
|
|
276
|
+
return value;
|
|
277
|
+
}
|
|
278
|
+
function hpss(samples, sampleRate = 22050, kernelHarmonic = 31, kernelPercussive = 31, nFft, hopLength, hardMask) {
|
|
279
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, kernelHarmonic, kernelPercussive, nFft, hopLength, hardMask } : samples;
|
|
280
|
+
const fftOptions = resolveEffectFftOptions("hpss", request.nFft, request.hopLength);
|
|
281
|
+
const resolvedHardMask = resolveHardMask(request.hardMask, "hpss");
|
|
282
|
+
return requireModule().hpssEx(
|
|
233
283
|
request.samples,
|
|
234
284
|
request.sampleRate ?? 22050,
|
|
235
285
|
request.kernelHarmonic ?? 31,
|
|
236
|
-
request.kernelPercussive ?? 31
|
|
286
|
+
request.kernelPercussive ?? 31,
|
|
287
|
+
fftOptions.nFft,
|
|
288
|
+
fftOptions.hopLength,
|
|
289
|
+
resolvedHardMask
|
|
237
290
|
);
|
|
238
291
|
}
|
|
239
292
|
function harmonic(samples, sampleRate = 22050, options = {}) {
|
|
@@ -246,18 +299,58 @@ function percussive(samples, sampleRate = 22050, options = {}) {
|
|
|
246
299
|
assertSamples("percussive", request.samples, request.validate !== false);
|
|
247
300
|
return requireModule().percussive(request.samples, request.sampleRate ?? 22050);
|
|
248
301
|
}
|
|
249
|
-
function timeStretch(samples, sampleRate, rate, options = {}) {
|
|
250
|
-
|
|
302
|
+
function timeStretch(samples, sampleRate, rate, nFftOrOptions, hopLength, options = {}) {
|
|
303
|
+
if (nFftOrOptions !== void 0 && nFftOrOptions !== null && typeof nFftOrOptions !== "number" && typeof nFftOrOptions !== "object") {
|
|
304
|
+
throw new TypeError("timeStretch: nFft must be an integer or options object");
|
|
305
|
+
}
|
|
306
|
+
if (nFftOrOptions === null) {
|
|
307
|
+
throw new TypeError("timeStretch: nFft must be an integer or options object");
|
|
308
|
+
}
|
|
309
|
+
const positionalOptions = typeof nFftOrOptions === "object" && nFftOrOptions !== null ? nFftOrOptions : options;
|
|
310
|
+
const positionalNFft = typeof nFftOrOptions === "number" ? nFftOrOptions : void 0;
|
|
311
|
+
const request = samples instanceof Float32Array ? {
|
|
312
|
+
samples,
|
|
313
|
+
sampleRate,
|
|
314
|
+
rate,
|
|
315
|
+
nFft: positionalNFft,
|
|
316
|
+
hopLength,
|
|
317
|
+
...positionalOptions
|
|
318
|
+
} : samples;
|
|
251
319
|
assertSamples("timeStretch", request.samples, request.validate !== false);
|
|
252
|
-
|
|
320
|
+
const fftOptions = resolveEffectFftOptions("timeStretch", request.nFft, request.hopLength);
|
|
321
|
+
return requireModule().timeStretchEx(
|
|
322
|
+
request.samples,
|
|
323
|
+
request.sampleRate ?? 22050,
|
|
324
|
+
request.rate,
|
|
325
|
+
fftOptions.nFft,
|
|
326
|
+
fftOptions.hopLength
|
|
327
|
+
);
|
|
253
328
|
}
|
|
254
|
-
function pitchShift(samples, sampleRate, semitones, options = {}) {
|
|
255
|
-
|
|
329
|
+
function pitchShift(samples, sampleRate, semitones, nFftOrOptions, hopLength, options = {}) {
|
|
330
|
+
if (nFftOrOptions !== void 0 && nFftOrOptions !== null && typeof nFftOrOptions !== "number" && typeof nFftOrOptions !== "object") {
|
|
331
|
+
throw new TypeError("pitchShift: nFft must be an integer or options object");
|
|
332
|
+
}
|
|
333
|
+
if (nFftOrOptions === null) {
|
|
334
|
+
throw new TypeError("pitchShift: nFft must be an integer or options object");
|
|
335
|
+
}
|
|
336
|
+
const positionalOptions = typeof nFftOrOptions === "object" && nFftOrOptions !== null ? nFftOrOptions : options;
|
|
337
|
+
const positionalNFft = typeof nFftOrOptions === "number" ? nFftOrOptions : void 0;
|
|
338
|
+
const request = samples instanceof Float32Array ? {
|
|
339
|
+
samples,
|
|
340
|
+
sampleRate,
|
|
341
|
+
semitones,
|
|
342
|
+
nFft: positionalNFft,
|
|
343
|
+
hopLength,
|
|
344
|
+
...positionalOptions
|
|
345
|
+
} : samples;
|
|
256
346
|
assertSamples("pitchShift", request.samples, request.validate !== false);
|
|
257
|
-
|
|
347
|
+
const fftOptions = resolveEffectFftOptions("pitchShift", request.nFft, request.hopLength);
|
|
348
|
+
return requireModule().pitchShiftEx(
|
|
258
349
|
request.samples,
|
|
259
350
|
request.sampleRate ?? 22050,
|
|
260
|
-
request.semitones
|
|
351
|
+
request.semitones,
|
|
352
|
+
fftOptions.nFft,
|
|
353
|
+
fftOptions.hopLength
|
|
261
354
|
);
|
|
262
355
|
}
|
|
263
356
|
function pitchCorrectToMidi(samples, sampleRate = 22050, currentMidi = 69, targetMidi = 69, options = {}) {
|
|
@@ -288,7 +381,7 @@ function pitchCorrectToMidiTimevarying(samples, f0Hz, targetMidi, sampleRate = 2
|
|
|
288
381
|
if (request.voicedProb && request.voicedProb.length !== request.f0Hz.length) {
|
|
289
382
|
throw new RangeError("pitchCorrectToMidiTimevarying: voicedProb length must match f0Hz length");
|
|
290
383
|
}
|
|
291
|
-
const voicedF32 = request.voiced ?
|
|
384
|
+
const voicedF32 = request.voiced ? toVoicedFloat32(request.voiced) : void 0;
|
|
292
385
|
return requireModule().pitchCorrectToMidiTimevarying(
|
|
293
386
|
request.samples,
|
|
294
387
|
request.sampleRate ?? 22050,
|
|
@@ -310,7 +403,7 @@ function pitchCorrectTimevarying(samples, f0Hz, sampleRate = 22050, hopLength =
|
|
|
310
403
|
}
|
|
311
404
|
const nativeOptions = {
|
|
312
405
|
...request,
|
|
313
|
-
voiced: request.voiced ?
|
|
406
|
+
voiced: request.voiced ? toVoicedFloat32(request.voiced) : void 0
|
|
314
407
|
};
|
|
315
408
|
return requireModule().pitchCorrectTimevarying(
|
|
316
409
|
request.samples,
|
|
@@ -342,13 +435,23 @@ function noteMove(samples, sampleRate = 22050, options = {}) {
|
|
|
342
435
|
request.targetOnsetSample ?? 0
|
|
343
436
|
);
|
|
344
437
|
}
|
|
345
|
-
function normalize(samples, sampleRate, targetDb = 0, options = {}) {
|
|
346
|
-
|
|
438
|
+
function normalize(samples, sampleRate, targetDb = 0, modeOrOptions = "peak", options = {}) {
|
|
439
|
+
if (modeOrOptions !== void 0 && modeOrOptions !== null && typeof modeOrOptions !== "string" && typeof modeOrOptions !== "object") {
|
|
440
|
+
throw new TypeError("normalize: mode must be the string 'peak' or 'rms'");
|
|
441
|
+
}
|
|
442
|
+
if (modeOrOptions === null) {
|
|
443
|
+
throw new TypeError("normalize: mode must be the string 'peak' or 'rms'");
|
|
444
|
+
}
|
|
445
|
+
const positionalOptions = typeof modeOrOptions === "object" && modeOrOptions !== null ? modeOrOptions : options;
|
|
446
|
+
const positionalMode = typeof modeOrOptions === "string" ? modeOrOptions : void 0;
|
|
447
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, targetDb, mode: positionalMode, ...positionalOptions } : samples;
|
|
347
448
|
assertSamples("normalize", request.samples, request.validate !== false);
|
|
348
|
-
|
|
449
|
+
const mode = resolveNormalizeMode(request.mode);
|
|
450
|
+
return requireModule().normalizeEx(
|
|
349
451
|
request.samples,
|
|
350
452
|
request.sampleRate ?? 22050,
|
|
351
|
-
request.targetDb ?? 0
|
|
453
|
+
request.targetDb ?? 0,
|
|
454
|
+
mode
|
|
352
455
|
);
|
|
353
456
|
}
|
|
354
457
|
function spectralEdit(samples, sampleRate, ops = [], options = {}) {
|
|
@@ -760,6 +863,30 @@ function masteringStreamingPreview(samples, sampleRate = 22050, platforms = [])
|
|
|
760
863
|
request.platforms ?? []
|
|
761
864
|
);
|
|
762
865
|
}
|
|
866
|
+
function masteringAssistantSuggestStereo(request) {
|
|
867
|
+
return requireModule4().masteringAssistantSuggestStereo(
|
|
868
|
+
request.left,
|
|
869
|
+
request.right,
|
|
870
|
+
request.sampleRate ?? 22050,
|
|
871
|
+
request.params ?? {}
|
|
872
|
+
);
|
|
873
|
+
}
|
|
874
|
+
function masteringAudioProfileStereo(request) {
|
|
875
|
+
return requireModule4().masteringAudioProfileStereo(
|
|
876
|
+
request.left,
|
|
877
|
+
request.right,
|
|
878
|
+
request.sampleRate ?? 22050,
|
|
879
|
+
request.params ?? {}
|
|
880
|
+
);
|
|
881
|
+
}
|
|
882
|
+
function masteringStreamingPreviewStereo(request) {
|
|
883
|
+
return requireModule4().masteringStreamingPreviewStereo(
|
|
884
|
+
request.left,
|
|
885
|
+
request.right,
|
|
886
|
+
request.sampleRate ?? 22050,
|
|
887
|
+
request.platforms ?? []
|
|
888
|
+
);
|
|
889
|
+
}
|
|
763
890
|
|
|
764
891
|
// src/mastering_dynamics.ts
|
|
765
892
|
function requireModule5() {
|
|
@@ -1124,12 +1251,18 @@ function nnlsChroma(samples, sampleRate = 22050, options = {}) {
|
|
|
1124
1251
|
return nnlsChroma(samples.samples, samples.sampleRate, samples);
|
|
1125
1252
|
}
|
|
1126
1253
|
validateMusicSamples("nnlsChroma", samples, sampleRate, options);
|
|
1127
|
-
|
|
1254
|
+
const hopLength = options.hopLength === void 0 ? 512 : options.hopLength;
|
|
1255
|
+
assertPositiveInteger("nnlsChroma", hopLength, "hopLength");
|
|
1256
|
+
if (hopLength > 2 ** 31 - 1) {
|
|
1257
|
+
throw new RangeError("nnlsChroma: hopLength must fit in a signed 32-bit integer");
|
|
1258
|
+
}
|
|
1259
|
+
return requireModule9().nnlsChromaEx(
|
|
1128
1260
|
samples,
|
|
1129
1261
|
sampleRate,
|
|
1130
1262
|
options.enableStftBlend ?? true,
|
|
1131
1263
|
options.stftBlendWeight ?? 0.55,
|
|
1132
|
-
options.stftBlendNFft ?? 4096
|
|
1264
|
+
options.stftBlendNFft ?? 4096,
|
|
1265
|
+
hopLength
|
|
1133
1266
|
);
|
|
1134
1267
|
}
|
|
1135
1268
|
function cqt(samples, sampleRate = 22050, hopLength = 512, fmin = 32.70319566257483, nBins = 84, binsPerOctave = 12, options = {}) {
|
|
@@ -1559,6 +1692,35 @@ function resample(samples, srcSr, targetSr) {
|
|
|
1559
1692
|
function requireModule12() {
|
|
1560
1693
|
return getSonareModule();
|
|
1561
1694
|
}
|
|
1695
|
+
function resolveEffectFftOptions2(fnName, nFft, hopLength) {
|
|
1696
|
+
const resolvedNFft = nFft === void 0 ? 2048 : nFft;
|
|
1697
|
+
const resolvedHopLength = hopLength === void 0 ? 512 : hopLength;
|
|
1698
|
+
if (typeof resolvedNFft !== "number" || !Number.isInteger(resolvedNFft)) {
|
|
1699
|
+
throw new TypeError(`${fnName}: nFft must be an integer`);
|
|
1700
|
+
}
|
|
1701
|
+
if (resolvedNFft < 2 || resolvedNFft > 2 ** 30) {
|
|
1702
|
+
throw new RangeError(`${fnName}: nFft must be an even power of two >= 2`);
|
|
1703
|
+
}
|
|
1704
|
+
if ((resolvedNFft & resolvedNFft - 1) !== 0) {
|
|
1705
|
+
throw new RangeError(`${fnName}: nFft must be an even power of two >= 2`);
|
|
1706
|
+
}
|
|
1707
|
+
if (typeof resolvedHopLength !== "number" || !Number.isInteger(resolvedHopLength)) {
|
|
1708
|
+
throw new TypeError(`${fnName}: hopLength must be an integer`);
|
|
1709
|
+
}
|
|
1710
|
+
if (resolvedHopLength <= 0 || resolvedHopLength > 2 ** 31 - 1) {
|
|
1711
|
+
throw new RangeError(`${fnName}: hopLength must be a positive integer`);
|
|
1712
|
+
}
|
|
1713
|
+
return { nFft: resolvedNFft, hopLength: resolvedHopLength };
|
|
1714
|
+
}
|
|
1715
|
+
function resolveHardMask2(fnName, value) {
|
|
1716
|
+
if (value === void 0) {
|
|
1717
|
+
return false;
|
|
1718
|
+
}
|
|
1719
|
+
if (typeof value !== "boolean") {
|
|
1720
|
+
throw new TypeError(`${fnName}: hardMask must be a boolean`);
|
|
1721
|
+
}
|
|
1722
|
+
return value;
|
|
1723
|
+
}
|
|
1562
1724
|
function validateSegmentMatrix(fnName, data, rows, cols, dataName) {
|
|
1563
1725
|
assertPositiveInteger(fnName, rows, "rows");
|
|
1564
1726
|
assertPositiveInteger(fnName, cols, "cols");
|
|
@@ -1690,12 +1852,30 @@ function phaseVocoder(samples, sampleRate = 22050, rate = 1, nFft = 2048, hopLen
|
|
|
1690
1852
|
}
|
|
1691
1853
|
return requireModule12().phaseVocoder(samples, sampleRate, rate, nFft, hopLength);
|
|
1692
1854
|
}
|
|
1693
|
-
function hpssWithResidual(samples, sampleRate = 22050, kernelHarmonic = 31, kernelPercussive = 31) {
|
|
1855
|
+
function hpssWithResidual(samples, sampleRate = 22050, kernelHarmonic = 31, kernelPercussive = 31, nFft, hopLength, hardMask) {
|
|
1694
1856
|
if (!(samples instanceof Float32Array)) {
|
|
1695
1857
|
const r = samples;
|
|
1696
|
-
return hpssWithResidual(
|
|
1858
|
+
return hpssWithResidual(
|
|
1859
|
+
r.samples,
|
|
1860
|
+
r.sampleRate,
|
|
1861
|
+
r.kernelHarmonic,
|
|
1862
|
+
r.kernelPercussive,
|
|
1863
|
+
r.nFft,
|
|
1864
|
+
r.hopLength,
|
|
1865
|
+
r.hardMask
|
|
1866
|
+
);
|
|
1697
1867
|
}
|
|
1698
|
-
|
|
1868
|
+
const fftOptions = resolveEffectFftOptions2("hpssWithResidual", nFft, hopLength);
|
|
1869
|
+
const resolvedHardMask = resolveHardMask2("hpssWithResidual", hardMask);
|
|
1870
|
+
return requireModule12().hpssWithResidualEx(
|
|
1871
|
+
samples,
|
|
1872
|
+
sampleRate,
|
|
1873
|
+
kernelHarmonic,
|
|
1874
|
+
kernelPercussive,
|
|
1875
|
+
fftOptions.nFft,
|
|
1876
|
+
fftOptions.hopLength,
|
|
1877
|
+
resolvedHardMask
|
|
1878
|
+
);
|
|
1699
1879
|
}
|
|
1700
1880
|
function lufsInterleaved(samples, channels = 0, sampleRate = 22050, options = {}) {
|
|
1701
1881
|
if (!(samples instanceof Float32Array)) {
|
|
@@ -1908,14 +2088,35 @@ function validateMatrix(fnName, data, rows, frames, dataName, rowName, options =
|
|
|
1908
2088
|
throw new RangeError(`${fnName}: ${dataName} length must equal ${rowName} * nFrames`);
|
|
1909
2089
|
}
|
|
1910
2090
|
}
|
|
1911
|
-
function trim(samples, sampleRate = 22050, thresholdDb = -60, options = {}) {
|
|
2091
|
+
function trim(samples, sampleRate = 22050, thresholdDb = -60, frameLengthOrOptions, hopLength, options = {}) {
|
|
1912
2092
|
if (!(samples instanceof Float32Array)) {
|
|
1913
2093
|
const r = samples;
|
|
1914
|
-
return trim(r.samples, r.sampleRate, r.thresholdDb, r);
|
|
2094
|
+
return trim(r.samples, r.sampleRate, r.thresholdDb, r.frameLength, r.hopLength, r);
|
|
2095
|
+
}
|
|
2096
|
+
if (frameLengthOrOptions === null) {
|
|
2097
|
+
throw new TypeError("trim: frameLength must be an integer or options object");
|
|
1915
2098
|
}
|
|
1916
|
-
|
|
2099
|
+
if (frameLengthOrOptions !== void 0 && typeof frameLengthOrOptions !== "number" && typeof frameLengthOrOptions !== "object") {
|
|
2100
|
+
throw new TypeError("trim: frameLength must be an integer or options object");
|
|
2101
|
+
}
|
|
2102
|
+
const positionalOptions = typeof frameLengthOrOptions === "object" && frameLengthOrOptions !== null ? frameLengthOrOptions : options;
|
|
2103
|
+
const positionalFrameLength = typeof frameLengthOrOptions === "number" ? frameLengthOrOptions : void 0;
|
|
2104
|
+
const resolvedFrameLength = positionalFrameLength ?? 2048;
|
|
2105
|
+
const resolvedHopLength = hopLength === void 0 ? 512 : hopLength;
|
|
2106
|
+
validateSpectrogramSamples("trim", samples, sampleRate, positionalOptions);
|
|
1917
2107
|
assertFiniteScalar("trim", thresholdDb, "thresholdDb");
|
|
1918
|
-
|
|
2108
|
+
assertPositiveInteger("trim", resolvedFrameLength, "frameLength");
|
|
2109
|
+
assertPositiveInteger("trim", resolvedHopLength, "hopLength");
|
|
2110
|
+
if (resolvedFrameLength > 2 ** 31 - 1 || resolvedHopLength > 2 ** 31 - 1) {
|
|
2111
|
+
throw new RangeError("trim: frameLength and hopLength must fit in a signed 32-bit integer");
|
|
2112
|
+
}
|
|
2113
|
+
return requireModule13().trimEx(
|
|
2114
|
+
samples,
|
|
2115
|
+
sampleRate,
|
|
2116
|
+
thresholdDb,
|
|
2117
|
+
resolvedFrameLength,
|
|
2118
|
+
resolvedHopLength
|
|
2119
|
+
);
|
|
1919
2120
|
}
|
|
1920
2121
|
function stft(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, options = {}) {
|
|
1921
2122
|
if (!(samples instanceof Float32Array)) {
|
|
@@ -2261,6 +2462,88 @@ function chroma(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, optio
|
|
|
2261
2462
|
return requireModule13().chroma(samples, sampleRate, nFft, hopLength);
|
|
2262
2463
|
}
|
|
2263
2464
|
|
|
2465
|
+
// src/codes.ts
|
|
2466
|
+
function resolveOrdinalInRange(value, min, max, enumName) {
|
|
2467
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < min || value > max) {
|
|
2468
|
+
throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
|
|
2469
|
+
}
|
|
2470
|
+
return value;
|
|
2471
|
+
}
|
|
2472
|
+
function resolveEnumOrdinal(value, values, enumName) {
|
|
2473
|
+
if (typeof value === "number") {
|
|
2474
|
+
const ordinals = Object.values(values);
|
|
2475
|
+
const ordinal = resolveOrdinalInRange(
|
|
2476
|
+
value,
|
|
2477
|
+
Math.min(...ordinals),
|
|
2478
|
+
Math.max(...ordinals),
|
|
2479
|
+
enumName
|
|
2480
|
+
);
|
|
2481
|
+
if (!ordinals.includes(ordinal)) {
|
|
2482
|
+
throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
|
|
2483
|
+
}
|
|
2484
|
+
return ordinal;
|
|
2485
|
+
}
|
|
2486
|
+
if (typeof value === "string") {
|
|
2487
|
+
const ordinal = values[value];
|
|
2488
|
+
if (ordinal !== void 0) {
|
|
2489
|
+
return ordinal;
|
|
2490
|
+
}
|
|
2491
|
+
}
|
|
2492
|
+
throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
|
|
2493
|
+
}
|
|
2494
|
+
var AUTOMATION_CURVE_VALUES = {
|
|
2495
|
+
linear: 0,
|
|
2496
|
+
exponential: 1,
|
|
2497
|
+
hold: 2,
|
|
2498
|
+
"s-curve": 3
|
|
2499
|
+
};
|
|
2500
|
+
var PAN_LAW_VALUES = {
|
|
2501
|
+
const3db: 0,
|
|
2502
|
+
"const-3db": 0,
|
|
2503
|
+
"-3db": 0,
|
|
2504
|
+
"const4.5db": 1,
|
|
2505
|
+
"const-4.5db": 1,
|
|
2506
|
+
"-4.5db": 1,
|
|
2507
|
+
const6db: 2,
|
|
2508
|
+
"const-6db": 2,
|
|
2509
|
+
"-6db": 2,
|
|
2510
|
+
linear0db: 3,
|
|
2511
|
+
"linear-0db": 3,
|
|
2512
|
+
linear: 3,
|
|
2513
|
+
"0db": 3
|
|
2514
|
+
};
|
|
2515
|
+
var PAN_MODE_VALUES = {
|
|
2516
|
+
balance: 0,
|
|
2517
|
+
pan: 1,
|
|
2518
|
+
stereopan: 1,
|
|
2519
|
+
"stereo-pan": 1,
|
|
2520
|
+
dualpan: 2,
|
|
2521
|
+
"dual-pan": 2
|
|
2522
|
+
};
|
|
2523
|
+
var METER_TAP_VALUES = { preFader: 0, postFader: 1 };
|
|
2524
|
+
var SEND_TIMING_VALUES = { postFader: 0, preFader: 1 };
|
|
2525
|
+
var TRACK_MONITOR_MODE_VALUES = { off: 0, pfl: 1, afl: 2 };
|
|
2526
|
+
function automationCurveCode(curve) {
|
|
2527
|
+
return resolveEnumOrdinal(curve, AUTOMATION_CURVE_VALUES, "automation curve");
|
|
2528
|
+
}
|
|
2529
|
+
function panLawCode(panLaw) {
|
|
2530
|
+
const normalized = typeof panLaw === "string" ? panLaw.toLowerCase().replace(/_/g, "-") : panLaw;
|
|
2531
|
+
return resolveEnumOrdinal(normalized, PAN_LAW_VALUES, "pan law");
|
|
2532
|
+
}
|
|
2533
|
+
function panModeCode(panMode) {
|
|
2534
|
+
const normalized = typeof panMode === "string" ? panMode.replace(/_/g, "-").toLowerCase() : panMode;
|
|
2535
|
+
return resolveEnumOrdinal(normalized, PAN_MODE_VALUES, "pan mode");
|
|
2536
|
+
}
|
|
2537
|
+
function meterTapCode(tap) {
|
|
2538
|
+
return resolveEnumOrdinal(tap, METER_TAP_VALUES, "meter tap");
|
|
2539
|
+
}
|
|
2540
|
+
function sendTimingCode(timing) {
|
|
2541
|
+
return resolveEnumOrdinal(timing, SEND_TIMING_VALUES, "send timing");
|
|
2542
|
+
}
|
|
2543
|
+
function trackMonitorModeCode(mode) {
|
|
2544
|
+
return resolveEnumOrdinal(mode, TRACK_MONITOR_MODE_VALUES, "track monitor mode");
|
|
2545
|
+
}
|
|
2546
|
+
|
|
2264
2547
|
// src/public_types_music.ts
|
|
2265
2548
|
var PitchClass = {
|
|
2266
2549
|
C: 0,
|
|
@@ -2354,6 +2637,30 @@ function convertKeyCandidate(wasm) {
|
|
|
2354
2637
|
correlation: wasm.correlation
|
|
2355
2638
|
};
|
|
2356
2639
|
}
|
|
2640
|
+
var KEY_MODE_VALUES = {
|
|
2641
|
+
major: Mode.Major,
|
|
2642
|
+
minor: Mode.Minor,
|
|
2643
|
+
dorian: Mode.Dorian,
|
|
2644
|
+
phrygian: Mode.Phrygian,
|
|
2645
|
+
lydian: Mode.Lydian,
|
|
2646
|
+
mixolydian: Mode.Mixolydian,
|
|
2647
|
+
locrian: Mode.Locrian
|
|
2648
|
+
};
|
|
2649
|
+
var KEY_PROFILE_VALUES = {
|
|
2650
|
+
ks: KeyProfile.KrumhanslSchmuckler,
|
|
2651
|
+
krumhansl: KeyProfile.KrumhanslSchmuckler,
|
|
2652
|
+
temperley: KeyProfile.Temperley,
|
|
2653
|
+
shaath: KeyProfile.Shaath,
|
|
2654
|
+
keyfinder: KeyProfile.Shaath,
|
|
2655
|
+
"faraldo-edmt": KeyProfile.FaraldoEDMT,
|
|
2656
|
+
edmt: KeyProfile.FaraldoEDMT,
|
|
2657
|
+
"faraldo-edma": KeyProfile.FaraldoEDMA,
|
|
2658
|
+
edma: KeyProfile.FaraldoEDMA,
|
|
2659
|
+
"faraldo-edmm": KeyProfile.FaraldoEDMM,
|
|
2660
|
+
edmm: KeyProfile.FaraldoEDMM,
|
|
2661
|
+
"bellman-budge": KeyProfile.BellmanBudge,
|
|
2662
|
+
bellman: KeyProfile.BellmanBudge
|
|
2663
|
+
};
|
|
2357
2664
|
function keyModeValues(modes) {
|
|
2358
2665
|
if (!modes) {
|
|
2359
2666
|
return [];
|
|
@@ -2372,40 +2679,13 @@ function keyModeValues(modes) {
|
|
|
2372
2679
|
Mode.Locrian
|
|
2373
2680
|
];
|
|
2374
2681
|
}
|
|
2375
|
-
|
|
2376
|
-
major: Mode.Major,
|
|
2377
|
-
minor: Mode.Minor,
|
|
2378
|
-
dorian: Mode.Dorian,
|
|
2379
|
-
phrygian: Mode.Phrygian,
|
|
2380
|
-
lydian: Mode.Lydian,
|
|
2381
|
-
mixolydian: Mode.Mixolydian,
|
|
2382
|
-
locrian: Mode.Locrian
|
|
2383
|
-
};
|
|
2384
|
-
return modes.map((mode) => typeof mode === "number" ? mode : names[mode]);
|
|
2682
|
+
return modes.map((mode) => resolveEnumOrdinal(mode, KEY_MODE_VALUES, "key mode"));
|
|
2385
2683
|
}
|
|
2386
2684
|
function keyProfileValue(profile) {
|
|
2387
2685
|
if (profile === void 0) {
|
|
2388
2686
|
return -1;
|
|
2389
2687
|
}
|
|
2390
|
-
|
|
2391
|
-
return profile;
|
|
2392
|
-
}
|
|
2393
|
-
const names = {
|
|
2394
|
-
ks: KeyProfile.KrumhanslSchmuckler,
|
|
2395
|
-
krumhansl: KeyProfile.KrumhanslSchmuckler,
|
|
2396
|
-
temperley: KeyProfile.Temperley,
|
|
2397
|
-
shaath: KeyProfile.Shaath,
|
|
2398
|
-
keyfinder: KeyProfile.Shaath,
|
|
2399
|
-
"faraldo-edmt": KeyProfile.FaraldoEDMT,
|
|
2400
|
-
edmt: KeyProfile.FaraldoEDMT,
|
|
2401
|
-
"faraldo-edma": KeyProfile.FaraldoEDMA,
|
|
2402
|
-
edma: KeyProfile.FaraldoEDMA,
|
|
2403
|
-
"faraldo-edmm": KeyProfile.FaraldoEDMM,
|
|
2404
|
-
edmm: KeyProfile.FaraldoEDMM,
|
|
2405
|
-
"bellman-budge": KeyProfile.BellmanBudge,
|
|
2406
|
-
bellman: KeyProfile.BellmanBudge
|
|
2407
|
-
};
|
|
2408
|
-
return names[profile];
|
|
2688
|
+
return resolveEnumOrdinal(profile, KEY_PROFILE_VALUES, "key profile");
|
|
2409
2689
|
}
|
|
2410
2690
|
function convertChordAnalysisResult(wasm) {
|
|
2411
2691
|
return {
|
|
@@ -2611,18 +2891,27 @@ function analyze(samples, sampleRate = 22050, options = {}) {
|
|
|
2611
2891
|
const result = requireModule14().analyze(request.samples, request.sampleRate ?? 22050, request);
|
|
2612
2892
|
return convertAnalysisResult(result);
|
|
2613
2893
|
}
|
|
2614
|
-
function analyzeImpulseResponse(samples, sampleRate = 48e3, nOctaveBands = 6) {
|
|
2615
|
-
const request = samples instanceof Float32Array ? { samples, sampleRate, nOctaveBands } : samples;
|
|
2894
|
+
function analyzeImpulseResponse(samples, sampleRate = 48e3, nOctaveBands = 6, minDecayDb) {
|
|
2895
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, nOctaveBands, minDecayDb } : samples;
|
|
2896
|
+
if (request.minDecayDb === null) {
|
|
2897
|
+
throw new TypeError("analyzeImpulseResponse: minDecayDb must be a finite number");
|
|
2898
|
+
}
|
|
2899
|
+
const resolvedMinDecayDb = request.minDecayDb === void 0 ? 30 : request.minDecayDb;
|
|
2900
|
+
assertFiniteScalar("analyzeImpulseResponse", resolvedMinDecayDb, "minDecayDb");
|
|
2901
|
+
if (resolvedMinDecayDb <= 0) {
|
|
2902
|
+
throw new RangeError("analyzeImpulseResponse: minDecayDb must be greater than zero");
|
|
2903
|
+
}
|
|
2616
2904
|
validateAnalysisInput(
|
|
2617
2905
|
"analyzeImpulseResponse",
|
|
2618
2906
|
request.samples,
|
|
2619
2907
|
request.sampleRate ?? 48e3,
|
|
2620
2908
|
request
|
|
2621
2909
|
);
|
|
2622
|
-
const result = requireModule14().
|
|
2910
|
+
const result = requireModule14().analyzeImpulseResponseEx(
|
|
2623
2911
|
request.samples,
|
|
2624
2912
|
request.sampleRate ?? 48e3,
|
|
2625
|
-
request.nOctaveBands ?? 6
|
|
2913
|
+
request.nOctaveBands ?? 6,
|
|
2914
|
+
resolvedMinDecayDb
|
|
2626
2915
|
);
|
|
2627
2916
|
return result;
|
|
2628
2917
|
}
|
|
@@ -2831,9 +3120,14 @@ var Audio = class _Audio {
|
|
|
2831
3120
|
}
|
|
2832
3121
|
}
|
|
2833
3122
|
}
|
|
2834
|
-
/**
|
|
3123
|
+
/**
|
|
3124
|
+
* A copy of the raw audio samples. Mirrors Node's `getData()` contract: the
|
|
3125
|
+
* returned array is independent of the Audio's internal buffer, so mutating
|
|
3126
|
+
* it (or transferring it to a Worker) does not affect subsequent facade
|
|
3127
|
+
* calls, which all read the internal snapshot directly.
|
|
3128
|
+
*/
|
|
2835
3129
|
get data() {
|
|
2836
|
-
return this._samples;
|
|
3130
|
+
return this._samples.slice();
|
|
2837
3131
|
}
|
|
2838
3132
|
/** Number of samples. */
|
|
2839
3133
|
get length() {
|
|
@@ -3477,6 +3771,15 @@ function meteringCrestFactorDb(samples, sampleRate = 22050, options = {}) {
|
|
|
3477
3771
|
assertSamples("meteringCrestFactorDb", request.samples, request.validate !== false);
|
|
3478
3772
|
return requireModule15().meteringCrestFactorDb(request.samples, request.sampleRate ?? 22050);
|
|
3479
3773
|
}
|
|
3774
|
+
function meteringCrestFactorDbStereo(request) {
|
|
3775
|
+
assertSamples("meteringCrestFactorDbStereo", request.left, request.validate !== false);
|
|
3776
|
+
assertSamples("meteringCrestFactorDbStereo", request.right, request.validate !== false);
|
|
3777
|
+
return requireModule15().meteringCrestFactorDbStereo(
|
|
3778
|
+
request.left,
|
|
3779
|
+
request.right,
|
|
3780
|
+
request.sampleRate ?? 22050
|
|
3781
|
+
);
|
|
3782
|
+
}
|
|
3480
3783
|
function meteringDcOffset(samples, sampleRate = 22050, options = {}) {
|
|
3481
3784
|
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
3482
3785
|
assertSamples("meteringDcOffset", request.samples, request.validate !== false);
|
|
@@ -3625,61 +3928,6 @@ function waveformPeakPyramid(samples, channels, options = {}) {
|
|
|
3625
3928
|
return requireModule15().waveformPeakPyramid(request.samples, request.channels, levels);
|
|
3626
3929
|
}
|
|
3627
3930
|
|
|
3628
|
-
// src/codes.ts
|
|
3629
|
-
function resolveEnumOrdinal(value, values, enumName) {
|
|
3630
|
-
if (typeof value === "number") {
|
|
3631
|
-
if (!Number.isSafeInteger(value) || !Object.values(values).includes(value)) {
|
|
3632
|
-
throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
|
|
3633
|
-
}
|
|
3634
|
-
return value;
|
|
3635
|
-
}
|
|
3636
|
-
if (typeof value === "string") {
|
|
3637
|
-
const ordinal = values[value];
|
|
3638
|
-
if (ordinal !== void 0) {
|
|
3639
|
-
return ordinal;
|
|
3640
|
-
}
|
|
3641
|
-
}
|
|
3642
|
-
throw new RangeError(`Invalid ${enumName}: ${String(value)}`);
|
|
3643
|
-
}
|
|
3644
|
-
var AUTOMATION_CURVE_VALUES = {
|
|
3645
|
-
linear: 0,
|
|
3646
|
-
exponential: 1,
|
|
3647
|
-
hold: 2,
|
|
3648
|
-
"s-curve": 3
|
|
3649
|
-
};
|
|
3650
|
-
var PAN_LAW_VALUES = {
|
|
3651
|
-
const3dB: 0,
|
|
3652
|
-
"const4.5dB": 1,
|
|
3653
|
-
const6dB: 2,
|
|
3654
|
-
linear0dB: 3
|
|
3655
|
-
};
|
|
3656
|
-
var PAN_MODE_VALUES = {
|
|
3657
|
-
balance: 0,
|
|
3658
|
-
pan: 0,
|
|
3659
|
-
stereopan: 1,
|
|
3660
|
-
"stereo-pan": 1,
|
|
3661
|
-
dualpan: 2,
|
|
3662
|
-
"dual-pan": 2
|
|
3663
|
-
};
|
|
3664
|
-
var METER_TAP_VALUES = { preFader: 0, postFader: 1 };
|
|
3665
|
-
var SEND_TIMING_VALUES = { postFader: 0, preFader: 1 };
|
|
3666
|
-
function automationCurveCode(curve) {
|
|
3667
|
-
return resolveEnumOrdinal(curve, AUTOMATION_CURVE_VALUES, "automation curve");
|
|
3668
|
-
}
|
|
3669
|
-
function panLawCode(panLaw) {
|
|
3670
|
-
return resolveEnumOrdinal(panLaw, PAN_LAW_VALUES, "pan law");
|
|
3671
|
-
}
|
|
3672
|
-
function panModeCode(panMode) {
|
|
3673
|
-
const normalized = typeof panMode === "string" ? panMode.replace(/_/g, "-").toLowerCase() : panMode;
|
|
3674
|
-
return resolveEnumOrdinal(normalized, PAN_MODE_VALUES, "pan mode");
|
|
3675
|
-
}
|
|
3676
|
-
function meterTapCode(tap) {
|
|
3677
|
-
return resolveEnumOrdinal(tap, METER_TAP_VALUES, "meter tap");
|
|
3678
|
-
}
|
|
3679
|
-
function sendTimingCode(timing) {
|
|
3680
|
-
return resolveEnumOrdinal(timing, SEND_TIMING_VALUES, "send timing");
|
|
3681
|
-
}
|
|
3682
|
-
|
|
3683
3931
|
// src/project_internal.ts
|
|
3684
3932
|
function projectModule() {
|
|
3685
3933
|
const candidate = getSonareModule();
|
|
@@ -3748,6 +3996,13 @@ function assertProjectMidiEvents(fnName, events) {
|
|
|
3748
3996
|
function projectTrackKindValue(kind) {
|
|
3749
3997
|
return resolveEnumOrdinal(kind ?? "audio", { audio: 0, midi: 1, aux: 2 }, "project track kind");
|
|
3750
3998
|
}
|
|
3999
|
+
function projectAutomationTargetKindValue(kind) {
|
|
4000
|
+
return resolveEnumOrdinal(
|
|
4001
|
+
kind,
|
|
4002
|
+
{ opaque: 0, "track-fader-db": 1, "track-pan": 2 },
|
|
4003
|
+
"project automation target kind"
|
|
4004
|
+
);
|
|
4005
|
+
}
|
|
3751
4006
|
function projectWarpModeValue(mode) {
|
|
3752
4007
|
return resolveEnumOrdinal(
|
|
3753
4008
|
mode ?? "off",
|
|
@@ -3760,10 +4015,40 @@ function projectLoopModeValue(mode) {
|
|
|
3760
4015
|
}
|
|
3761
4016
|
|
|
3762
4017
|
// src/project_class.ts
|
|
4018
|
+
function validateAssistSidecarUint32(value, field) {
|
|
4019
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0 || value > 4294967295) {
|
|
4020
|
+
throw new RangeError(`Project.setAssistSidecar: ${field} must be a uint32`);
|
|
4021
|
+
}
|
|
4022
|
+
return value;
|
|
4023
|
+
}
|
|
4024
|
+
function validateAssistSidecarPpq(value, field) {
|
|
4025
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
|
|
4026
|
+
throw new RangeError(
|
|
4027
|
+
`Project.setAssistSidecar: ${field} must be a finite, non-negative number`
|
|
4028
|
+
);
|
|
4029
|
+
}
|
|
4030
|
+
return value;
|
|
4031
|
+
}
|
|
4032
|
+
function validateAssistSidecarPayload(value) {
|
|
4033
|
+
if (!(value instanceof Uint8Array)) {
|
|
4034
|
+
throw new TypeError("Project.setAssistSidecar: payload must be a Uint8Array");
|
|
4035
|
+
}
|
|
4036
|
+
return value;
|
|
4037
|
+
}
|
|
4038
|
+
function validateAssistSidecarModuleId(value) {
|
|
4039
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
4040
|
+
throw new TypeError("Project.setAssistSidecar: moduleId must be a non-empty string");
|
|
4041
|
+
}
|
|
4042
|
+
return value;
|
|
4043
|
+
}
|
|
3763
4044
|
var Project = class _Project {
|
|
3764
4045
|
constructor() {
|
|
3765
4046
|
this.native = new (projectModule()).Project();
|
|
3766
4047
|
}
|
|
4048
|
+
/** Create a new empty project. */
|
|
4049
|
+
static create() {
|
|
4050
|
+
return new _Project();
|
|
4051
|
+
}
|
|
3767
4052
|
/** Pack a MIDI 1.0 note-on event accepted by {@link setMidiEvents}. */
|
|
3768
4053
|
static midiNoteOn(ppq, group, channel, note, velocity) {
|
|
3769
4054
|
return projectMidi1Event("Project.midiNoteOn", ppq, group, 9, channel, note, velocity);
|
|
@@ -4027,6 +4312,18 @@ var Project = class _Project {
|
|
|
4027
4312
|
}
|
|
4028
4313
|
this.native.setMaxUndoDepth(depth);
|
|
4029
4314
|
}
|
|
4315
|
+
/** Set the combined undo/redo history byte cap. Zero disables retention. */
|
|
4316
|
+
setMaxHistoryBytes(bytes) {
|
|
4317
|
+
if (typeof bytes !== "number") {
|
|
4318
|
+
throw new TypeError("Project.setMaxHistoryBytes: bytes must be a number");
|
|
4319
|
+
}
|
|
4320
|
+
if (!Number.isFinite(bytes) || !Number.isInteger(bytes) || bytes < 0 || bytes > 4294967295) {
|
|
4321
|
+
throw new RangeError(
|
|
4322
|
+
"Project.setMaxHistoryBytes: bytes must be a finite integer in the uint32 range"
|
|
4323
|
+
);
|
|
4324
|
+
}
|
|
4325
|
+
this.native.setMaxHistoryBytes(bytes);
|
|
4326
|
+
}
|
|
4030
4327
|
/** Replace a MIDI clip's entire event list. */
|
|
4031
4328
|
setMidiEvents(clipId, events) {
|
|
4032
4329
|
assertProjectMidiEvents("Project.setMidiEvents", events);
|
|
@@ -4157,8 +4454,11 @@ var Project = class _Project {
|
|
|
4157
4454
|
* Karplus-Strong / modal / additive / percussion / extended-waveguide-piano
|
|
4158
4455
|
* engines plus the realism layer). Pass a {@link SynthPatch}, a preset-name
|
|
4159
4456
|
* string (`'saw-lead'` / `'va:saw-lead'`; see {@link synthPresetNames}), or
|
|
4160
|
-
* an array of either; each object entry may carry
|
|
4161
|
-
*
|
|
4457
|
+
* an array of either; each object entry may carry `destinationId` (default
|
|
4458
|
+
* 0) and `useGmPrograms` (default `false`) binding conveniences, neither of
|
|
4459
|
+
* which is part of the NativeSynth patch itself. When enabled, MIDI program
|
|
4460
|
+
* changes select the corresponding General MIDI voice while the patch remains
|
|
4461
|
+
* the fallback.
|
|
4162
4462
|
* Because the parameter defaults to `{}`, omission and explicit `undefined`
|
|
4163
4463
|
* both create one default binding. Use an explicitly empty array `[]` (or
|
|
4164
4464
|
* runtime `null`) for zero bindings. Unknown preset names throw.
|
|
@@ -4232,6 +4532,10 @@ var Project = class _Project {
|
|
|
4232
4532
|
setSourceAudio(sourceId, audio, channels, sampleRate) {
|
|
4233
4533
|
this.native.setSourceAudio(sourceId, audio, channels, sampleRate);
|
|
4234
4534
|
}
|
|
4535
|
+
/** Replace an audio source's metadata strings as one undoable edit. */
|
|
4536
|
+
setAudioSourceMetadata(sourceId, contentHash, externalStemRole) {
|
|
4537
|
+
this.native.setAudioSourceMetadata(sourceId, contentHash, externalStemRole);
|
|
4538
|
+
}
|
|
4235
4539
|
/** Replace a clip's take list and active take id (undoable). */
|
|
4236
4540
|
setClipTakes(clipId, takes, activeTakeId = 0) {
|
|
4237
4541
|
this.native.setClipTakes(clipId, takes, activeTakeId);
|
|
@@ -4275,17 +4579,29 @@ var Project = class _Project {
|
|
|
4275
4579
|
}
|
|
4276
4580
|
/** Append an automation lane; returns its stable target parameter id (undoable). */
|
|
4277
4581
|
addAutomationLane(trackId, desc) {
|
|
4278
|
-
|
|
4279
|
-
targetParamId
|
|
4280
|
-
|
|
4281
|
-
}
|
|
4582
|
+
if (desc.targetParamId === 0) {
|
|
4583
|
+
throw new RangeError("project automation lane targetParamId must be non-zero");
|
|
4584
|
+
}
|
|
4585
|
+
const nativeDesc = { ...desc };
|
|
4586
|
+
if (Object.keys(desc).includes("targetKind")) {
|
|
4587
|
+
nativeDesc.targetKind = projectAutomationTargetKindValue(
|
|
4588
|
+
desc.targetKind
|
|
4589
|
+
);
|
|
4590
|
+
}
|
|
4591
|
+
return this.native.addAutomationLane(trackId, nativeDesc);
|
|
4282
4592
|
}
|
|
4283
4593
|
/** Replace the lane identified by its stable target parameter id (undoable). */
|
|
4284
4594
|
editAutomationLane(trackId, targetParamId, desc) {
|
|
4285
|
-
|
|
4286
|
-
targetParamId
|
|
4287
|
-
|
|
4288
|
-
}
|
|
4595
|
+
if (desc.targetParamId === 0) {
|
|
4596
|
+
throw new RangeError("project automation lane targetParamId must be non-zero");
|
|
4597
|
+
}
|
|
4598
|
+
const nativeDesc = { ...desc };
|
|
4599
|
+
if (Object.keys(desc).includes("targetKind")) {
|
|
4600
|
+
nativeDesc.targetKind = projectAutomationTargetKindValue(
|
|
4601
|
+
desc.targetKind
|
|
4602
|
+
);
|
|
4603
|
+
}
|
|
4604
|
+
this.native.editAutomationLane(trackId, targetParamId, nativeDesc);
|
|
4289
4605
|
}
|
|
4290
4606
|
/** Remove the lane identified by its stable target parameter id (undoable). */
|
|
4291
4607
|
removeAutomationLane(trackId, targetParamId) {
|
|
@@ -4299,15 +4615,33 @@ var Project = class _Project {
|
|
|
4299
4615
|
annotateChords(chords) {
|
|
4300
4616
|
this.native.annotateChords(chords);
|
|
4301
4617
|
}
|
|
4302
|
-
|
|
4303
|
-
|
|
4618
|
+
setAssistSidecar(sidecarOrModuleId, schemaVersion, targetTrackId, regionStartPpq, regionEndPpq, payload) {
|
|
4619
|
+
if (typeof sidecarOrModuleId === "string") {
|
|
4620
|
+
if (schemaVersion === void 0 || targetTrackId === void 0 || regionStartPpq === void 0 || regionEndPpq === void 0 || payload === void 0) {
|
|
4621
|
+
throw new TypeError("Project.setAssistSidecar: positional form requires six arguments");
|
|
4622
|
+
}
|
|
4623
|
+
this.native.setAssistSidecar(
|
|
4624
|
+
validateAssistSidecarModuleId(sidecarOrModuleId),
|
|
4625
|
+
validateAssistSidecarUint32(schemaVersion, "schemaVersion"),
|
|
4626
|
+
validateAssistSidecarUint32(targetTrackId, "targetTrackId"),
|
|
4627
|
+
validateAssistSidecarPpq(regionStartPpq, "regionStartPpq"),
|
|
4628
|
+
validateAssistSidecarPpq(regionEndPpq, "regionEndPpq"),
|
|
4629
|
+
validateAssistSidecarPayload(payload)
|
|
4630
|
+
);
|
|
4631
|
+
return;
|
|
4632
|
+
}
|
|
4633
|
+
if (sidecarOrModuleId === null || typeof sidecarOrModuleId !== "object" || Array.isArray(sidecarOrModuleId)) {
|
|
4634
|
+
throw new TypeError("Project.setAssistSidecar: expected a sidecar descriptor object");
|
|
4635
|
+
}
|
|
4636
|
+
const sidecar = sidecarOrModuleId;
|
|
4637
|
+
const moduleId = validateAssistSidecarModuleId(sidecar.moduleId);
|
|
4304
4638
|
this.native.setAssistSidecar(
|
|
4305
4639
|
moduleId,
|
|
4306
|
-
schemaVersion,
|
|
4307
|
-
targetTrackId,
|
|
4308
|
-
regionStartPpq,
|
|
4309
|
-
regionEndPpq,
|
|
4310
|
-
payload
|
|
4640
|
+
validateAssistSidecarUint32(sidecar.schemaVersion ?? 0, "schemaVersion"),
|
|
4641
|
+
validateAssistSidecarUint32(sidecar.targetTrackId ?? 0, "targetTrackId"),
|
|
4642
|
+
validateAssistSidecarPpq(sidecar.regionStartPpq ?? 0, "regionStartPpq"),
|
|
4643
|
+
validateAssistSidecarPpq(sidecar.regionEndPpq ?? 0, "regionEndPpq"),
|
|
4644
|
+
validateAssistSidecarPayload(sidecar.payload ?? new Uint8Array())
|
|
4311
4645
|
);
|
|
4312
4646
|
}
|
|
4313
4647
|
/** Number of assist sidecars currently stored on the project. */
|
|
@@ -4318,6 +4652,11 @@ var Project = class _Project {
|
|
|
4318
4652
|
getAssistSidecar(index) {
|
|
4319
4653
|
return this.native.getAssistSidecar(index);
|
|
4320
4654
|
}
|
|
4655
|
+
/** Read every stored assist sidecar in the same order as the index getter. */
|
|
4656
|
+
assistSidecars() {
|
|
4657
|
+
const count = this.assistSidecarCount();
|
|
4658
|
+
return Array.from({ length: count }, (_, index) => this.getAssistSidecar(index));
|
|
4659
|
+
}
|
|
4321
4660
|
/** Set the project's clip-overlap policy (SonareProjectOverlapPolicy ordinal). */
|
|
4322
4661
|
setOverlapPolicy(policy) {
|
|
4323
4662
|
this.native.setOverlapPolicy(policy);
|
|
@@ -4500,6 +4839,14 @@ var SYNTH_MOD_DESTINATIONS = [
|
|
|
4500
4839
|
"amp-gain",
|
|
4501
4840
|
"pan-units"
|
|
4502
4841
|
];
|
|
4842
|
+
var AutomationTargetKind = {
|
|
4843
|
+
opaque: 0,
|
|
4844
|
+
trackFaderDb: 1,
|
|
4845
|
+
trackPan: 2
|
|
4846
|
+
};
|
|
4847
|
+
var PROJECT_AUTOMATION_TARGET_OPAQUE = AutomationTargetKind.opaque;
|
|
4848
|
+
var PROJECT_AUTOMATION_TARGET_TRACK_FADER_DB = AutomationTargetKind.trackFaderDb;
|
|
4849
|
+
var PROJECT_AUTOMATION_TARGET_TRACK_PAN = AutomationTargetKind.trackPan;
|
|
4503
4850
|
|
|
4504
4851
|
// src/realtime_engine.ts
|
|
4505
4852
|
var EXPECTED_ENGINE_ABI_VERSION = 3;
|
|
@@ -4563,6 +4910,10 @@ var RealtimeEngine = class {
|
|
|
4563
4910
|
setSoloMute(laneIndex, solo, mute, renderFrame = -1) {
|
|
4564
4911
|
this.native.setSoloMute(laneIndex, solo, mute, renderFrame);
|
|
4565
4912
|
}
|
|
4913
|
+
/** Queue a per-track PFL/AFL monitor tap mode change. */
|
|
4914
|
+
setTrackMonitorMode(laneIndex, mode, renderFrame = -1) {
|
|
4915
|
+
this.native.setTrackMonitorMode(laneIndex, trackMonitorModeCode(mode), renderFrame);
|
|
4916
|
+
}
|
|
4566
4917
|
setMidiClips(clips) {
|
|
4567
4918
|
this.native.setMidiClips(clips);
|
|
4568
4919
|
}
|
|
@@ -5276,6 +5627,7 @@ var StreamAnalyzer = class {
|
|
|
5276
5627
|
if (config.outputFormat !== void 0 && (typeof config.outputFormat !== "number" || !Number.isFinite(config.outputFormat) || !Number.isInteger(config.outputFormat) || config.outputFormat !== 0)) {
|
|
5277
5628
|
throw new TypeError("outputFormat must be the integer 0 (Float32)");
|
|
5278
5629
|
}
|
|
5630
|
+
const window = config.window === void 0 ? void 0 : resolveOrdinalInRange(config.window, 0, 3, "stream analyzer window");
|
|
5279
5631
|
const module2 = getSonareModule();
|
|
5280
5632
|
const defaults = streamAnalyzerConfigDefaults();
|
|
5281
5633
|
this.analyzer = new module2.StreamAnalyzer(
|
|
@@ -5297,7 +5649,7 @@ var StreamAnalyzer = class {
|
|
|
5297
5649
|
config.maxProgressionEntries ?? defaults.maxProgressionEntries,
|
|
5298
5650
|
config.keyUpdateIntervalSec ?? defaults.keyUpdateIntervalSec,
|
|
5299
5651
|
config.bpmUpdateIntervalSec ?? defaults.bpmUpdateIntervalSec,
|
|
5300
|
-
|
|
5652
|
+
window ?? defaults.window,
|
|
5301
5653
|
config.outputFormat ?? defaults.outputFormat
|
|
5302
5654
|
);
|
|
5303
5655
|
}
|
|
@@ -5725,7 +6077,7 @@ var Mixer = class _Mixer {
|
|
|
5725
6077
|
setPolarityInvert(stripIndex, invertLeft, invertRight) {
|
|
5726
6078
|
this.mixer.setPolarityInvert(stripIndex, invertLeft, invertRight);
|
|
5727
6079
|
}
|
|
5728
|
-
/** Set the strip's pan law. */
|
|
6080
|
+
/** Set the strip's pan law (a {@link PanLawName} alias or raw C ABI ordinal). */
|
|
5729
6081
|
setPanLaw(stripIndex, panLaw) {
|
|
5730
6082
|
this.mixer.setPanLaw(stripIndex, panLawCode(panLaw));
|
|
5731
6083
|
}
|
|
@@ -6430,7 +6782,6 @@ async function bindWebMidi(engine, options = {}) {
|
|
|
6430
6782
|
for (const [, input] of iterInputs(access)) {
|
|
6431
6783
|
bindInput(input);
|
|
6432
6784
|
}
|
|
6433
|
-
notify();
|
|
6434
6785
|
};
|
|
6435
6786
|
const stateListener = (event) => {
|
|
6436
6787
|
if (closed) {
|
|
@@ -6449,6 +6800,7 @@ async function bindWebMidi(engine, options = {}) {
|
|
|
6449
6800
|
notify();
|
|
6450
6801
|
};
|
|
6451
6802
|
refreshInputs();
|
|
6803
|
+
notify();
|
|
6452
6804
|
if (access.addEventListener) {
|
|
6453
6805
|
access.addEventListener("statechange", stateListener);
|
|
6454
6806
|
} else {
|
|
@@ -6550,12 +6902,8 @@ function dispatchUmpMessage(engine, words, portTimeSamples) {
|
|
|
6550
6902
|
if (status === 8) {
|
|
6551
6903
|
engine.pushMidiInputNoteOff(group, channel, data1, word1 >>> 25 & 127, portTimeSamples);
|
|
6552
6904
|
} else if (status === 9) {
|
|
6553
|
-
const velocity = word1 >>> 25 & 127;
|
|
6554
|
-
|
|
6555
|
-
engine.pushMidiInputNoteOff(group, channel, data1, 0, portTimeSamples);
|
|
6556
|
-
} else {
|
|
6557
|
-
engine.pushMidiInputNoteOn(group, channel, data1, velocity, portTimeSamples);
|
|
6558
|
-
}
|
|
6905
|
+
const velocity = Math.max(1, word1 >>> 25 & 127);
|
|
6906
|
+
engine.pushMidiInputNoteOn(group, channel, data1, velocity, portTimeSamples);
|
|
6559
6907
|
} else if (status === 11) {
|
|
6560
6908
|
engine.pushMidiInputCc(group, channel, data1, word1 >>> 25 & 127, portTimeSamples);
|
|
6561
6909
|
}
|
|
@@ -6874,6 +7222,9 @@ function voiceCharacterPresetId(preset) {
|
|
|
6874
7222
|
if (!module) {
|
|
6875
7223
|
throw new Error("Module not initialized. Call init() first.");
|
|
6876
7224
|
}
|
|
7225
|
+
if (typeof preset === "number" && (!Number.isSafeInteger(preset) || preset < 0 || preset >= VOICE_PRESET_ORDINALS.length)) {
|
|
7226
|
+
return null;
|
|
7227
|
+
}
|
|
6877
7228
|
return module.voiceCharacterPresetId(resolveVoicePresetOrdinal(preset));
|
|
6878
7229
|
}
|
|
6879
7230
|
function realtimeVoiceChangerPresetConfig(preset) {
|
|
@@ -6884,6 +7235,7 @@ function realtimeVoiceChangerPresetConfig(preset) {
|
|
|
6884
7235
|
}
|
|
6885
7236
|
export {
|
|
6886
7237
|
Audio,
|
|
7238
|
+
AutomationTargetKind,
|
|
6887
7239
|
BUILTIN_SYNTH_WAVEFORMS,
|
|
6888
7240
|
ChordQuality,
|
|
6889
7241
|
ClipPageProvider,
|
|
@@ -6897,6 +7249,9 @@ export {
|
|
|
6897
7249
|
Mode,
|
|
6898
7250
|
OfflineWorkerClient,
|
|
6899
7251
|
OfflineWorkerTask,
|
|
7252
|
+
PROJECT_AUTOMATION_TARGET_OPAQUE,
|
|
7253
|
+
PROJECT_AUTOMATION_TARGET_TRACK_FADER_DB,
|
|
7254
|
+
PROJECT_AUTOMATION_TARGET_TRACK_PAN,
|
|
6900
7255
|
PitchClass as Pitch,
|
|
6901
7256
|
PitchClass,
|
|
6902
7257
|
Project,
|
|
@@ -6988,7 +7343,9 @@ export {
|
|
|
6988
7343
|
masterAudioWithProgress,
|
|
6989
7344
|
mastering,
|
|
6990
7345
|
masteringAssistantSuggest,
|
|
7346
|
+
masteringAssistantSuggestStereo,
|
|
6991
7347
|
masteringAudioProfile,
|
|
7348
|
+
masteringAudioProfileStereo,
|
|
6992
7349
|
masteringChain,
|
|
6993
7350
|
masteringChainStereo,
|
|
6994
7351
|
masteringChainStereoWithProgress,
|
|
@@ -7018,12 +7375,14 @@ export {
|
|
|
7018
7375
|
masteringStereoAnalysisNames,
|
|
7019
7376
|
masteringStereoAnalyze,
|
|
7020
7377
|
masteringStreamingPreview,
|
|
7378
|
+
masteringStreamingPreviewStereo,
|
|
7021
7379
|
melDelta,
|
|
7022
7380
|
melSpectrogram,
|
|
7023
7381
|
melToAudio,
|
|
7024
7382
|
melToHz,
|
|
7025
7383
|
melToStft,
|
|
7026
7384
|
meteringCrestFactorDb,
|
|
7385
|
+
meteringCrestFactorDbStereo,
|
|
7027
7386
|
meteringDcOffset,
|
|
7028
7387
|
meteringDetectClipping,
|
|
7029
7388
|
meteringDynamicRange,
|