@libraz/libsonare 1.6.0 → 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 +2 -2
- package/dist/analysis.d.ts +88 -9
- package/dist/analysis.js +152 -42
- package/dist/analysis.js.map +1 -1
- package/dist/index.d.ts +129 -24
- package/dist/index.js +455 -140
- 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 +62 -10
- package/dist/worklet.js +193 -42
- package/dist/worklet.js.map +1 -1
- package/package.json +3 -3
- package/src/analysis_helpers.ts +34 -29
- package/src/audio.ts +7 -2
- package/src/codes.ts +47 -11
- package/src/effects_transform.ts +179 -10
- 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 +21 -3
- 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 +45 -1
- package/src/public_types_mixing.ts +16 -0
- package/src/public_types_realtime.ts +23 -5
- package/src/quick_analysis.ts +21 -3
- package/src/realtime_engine.ts +14 -3
- package/src/sonare.js.d.ts +64 -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,59 @@ function assertInterleavedSamples(fnName, samples, channels, validate) {
|
|
|
227
227
|
function requireModule() {
|
|
228
228
|
return getSonareModule();
|
|
229
229
|
}
|
|
230
|
-
function
|
|
231
|
-
const
|
|
232
|
-
|
|
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(
|
|
233
276
|
request.samples,
|
|
234
277
|
request.sampleRate ?? 22050,
|
|
235
278
|
request.kernelHarmonic ?? 31,
|
|
236
|
-
request.kernelPercussive ?? 31
|
|
279
|
+
request.kernelPercussive ?? 31,
|
|
280
|
+
fftOptions.nFft,
|
|
281
|
+
fftOptions.hopLength,
|
|
282
|
+
resolvedHardMask
|
|
237
283
|
);
|
|
238
284
|
}
|
|
239
285
|
function harmonic(samples, sampleRate = 22050, options = {}) {
|
|
@@ -246,18 +292,58 @@ function percussive(samples, sampleRate = 22050, options = {}) {
|
|
|
246
292
|
assertSamples("percussive", request.samples, request.validate !== false);
|
|
247
293
|
return requireModule().percussive(request.samples, request.sampleRate ?? 22050);
|
|
248
294
|
}
|
|
249
|
-
function timeStretch(samples, sampleRate, rate, options = {}) {
|
|
250
|
-
|
|
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;
|
|
251
312
|
assertSamples("timeStretch", request.samples, request.validate !== false);
|
|
252
|
-
|
|
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
|
+
);
|
|
253
321
|
}
|
|
254
|
-
function pitchShift(samples, sampleRate, semitones, options = {}) {
|
|
255
|
-
|
|
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;
|
|
256
339
|
assertSamples("pitchShift", request.samples, request.validate !== false);
|
|
257
|
-
|
|
340
|
+
const fftOptions = resolveEffectFftOptions("pitchShift", request.nFft, request.hopLength);
|
|
341
|
+
return requireModule().pitchShiftEx(
|
|
258
342
|
request.samples,
|
|
259
343
|
request.sampleRate ?? 22050,
|
|
260
|
-
request.semitones
|
|
344
|
+
request.semitones,
|
|
345
|
+
fftOptions.nFft,
|
|
346
|
+
fftOptions.hopLength
|
|
261
347
|
);
|
|
262
348
|
}
|
|
263
349
|
function pitchCorrectToMidi(samples, sampleRate = 22050, currentMidi = 69, targetMidi = 69, options = {}) {
|
|
@@ -342,13 +428,23 @@ function noteMove(samples, sampleRate = 22050, options = {}) {
|
|
|
342
428
|
request.targetOnsetSample ?? 0
|
|
343
429
|
);
|
|
344
430
|
}
|
|
345
|
-
function normalize(samples, sampleRate, targetDb = 0, options = {}) {
|
|
346
|
-
|
|
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;
|
|
347
441
|
assertSamples("normalize", request.samples, request.validate !== false);
|
|
348
|
-
|
|
442
|
+
const mode = resolveNormalizeMode(request.mode);
|
|
443
|
+
return requireModule().normalizeEx(
|
|
349
444
|
request.samples,
|
|
350
445
|
request.sampleRate ?? 22050,
|
|
351
|
-
request.targetDb ?? 0
|
|
446
|
+
request.targetDb ?? 0,
|
|
447
|
+
mode
|
|
352
448
|
);
|
|
353
449
|
}
|
|
354
450
|
function spectralEdit(samples, sampleRate, ops = [], options = {}) {
|
|
@@ -1124,12 +1220,18 @@ function nnlsChroma(samples, sampleRate = 22050, options = {}) {
|
|
|
1124
1220
|
return nnlsChroma(samples.samples, samples.sampleRate, samples);
|
|
1125
1221
|
}
|
|
1126
1222
|
validateMusicSamples("nnlsChroma", samples, sampleRate, options);
|
|
1127
|
-
|
|
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(
|
|
1128
1229
|
samples,
|
|
1129
1230
|
sampleRate,
|
|
1130
1231
|
options.enableStftBlend ?? true,
|
|
1131
1232
|
options.stftBlendWeight ?? 0.55,
|
|
1132
|
-
options.stftBlendNFft ?? 4096
|
|
1233
|
+
options.stftBlendNFft ?? 4096,
|
|
1234
|
+
hopLength
|
|
1133
1235
|
);
|
|
1134
1236
|
}
|
|
1135
1237
|
function cqt(samples, sampleRate = 22050, hopLength = 512, fmin = 32.70319566257483, nBins = 84, binsPerOctave = 12, options = {}) {
|
|
@@ -1559,6 +1661,35 @@ function resample(samples, srcSr, targetSr) {
|
|
|
1559
1661
|
function requireModule12() {
|
|
1560
1662
|
return getSonareModule();
|
|
1561
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
|
+
}
|
|
1562
1693
|
function validateSegmentMatrix(fnName, data, rows, cols, dataName) {
|
|
1563
1694
|
assertPositiveInteger(fnName, rows, "rows");
|
|
1564
1695
|
assertPositiveInteger(fnName, cols, "cols");
|
|
@@ -1690,12 +1821,30 @@ function phaseVocoder(samples, sampleRate = 22050, rate = 1, nFft = 2048, hopLen
|
|
|
1690
1821
|
}
|
|
1691
1822
|
return requireModule12().phaseVocoder(samples, sampleRate, rate, nFft, hopLength);
|
|
1692
1823
|
}
|
|
1693
|
-
function hpssWithResidual(samples, sampleRate = 22050, kernelHarmonic = 31, kernelPercussive = 31) {
|
|
1824
|
+
function hpssWithResidual(samples, sampleRate = 22050, kernelHarmonic = 31, kernelPercussive = 31, nFft, hopLength, hardMask) {
|
|
1694
1825
|
if (!(samples instanceof Float32Array)) {
|
|
1695
1826
|
const r = samples;
|
|
1696
|
-
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
|
+
);
|
|
1697
1836
|
}
|
|
1698
|
-
|
|
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
|
+
);
|
|
1699
1848
|
}
|
|
1700
1849
|
function lufsInterleaved(samples, channels = 0, sampleRate = 22050, options = {}) {
|
|
1701
1850
|
if (!(samples instanceof Float32Array)) {
|
|
@@ -1908,14 +2057,35 @@ function validateMatrix(fnName, data, rows, frames, dataName, rowName, options =
|
|
|
1908
2057
|
throw new RangeError(`${fnName}: ${dataName} length must equal ${rowName} * nFrames`);
|
|
1909
2058
|
}
|
|
1910
2059
|
}
|
|
1911
|
-
function trim(samples, sampleRate = 22050, thresholdDb = -60, options = {}) {
|
|
2060
|
+
function trim(samples, sampleRate = 22050, thresholdDb = -60, frameLengthOrOptions, hopLength, options = {}) {
|
|
1912
2061
|
if (!(samples instanceof Float32Array)) {
|
|
1913
2062
|
const r = samples;
|
|
1914
|
-
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");
|
|
1915
2067
|
}
|
|
1916
|
-
|
|
2068
|
+
if (frameLengthOrOptions !== void 0 && typeof frameLengthOrOptions !== "number" && typeof frameLengthOrOptions !== "object") {
|
|
2069
|
+
throw new TypeError("trim: frameLength must be an integer or options object");
|
|
2070
|
+
}
|
|
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);
|
|
1917
2076
|
assertFiniteScalar("trim", thresholdDb, "thresholdDb");
|
|
1918
|
-
|
|
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
|
+
);
|
|
1919
2089
|
}
|
|
1920
2090
|
function stft(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, options = {}) {
|
|
1921
2091
|
if (!(samples instanceof Float32Array)) {
|
|
@@ -2261,6 +2431,88 @@ function chroma(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, optio
|
|
|
2261
2431
|
return requireModule13().chroma(samples, sampleRate, nFft, hopLength);
|
|
2262
2432
|
}
|
|
2263
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
|
+
|
|
2264
2516
|
// src/public_types_music.ts
|
|
2265
2517
|
var PitchClass = {
|
|
2266
2518
|
C: 0,
|
|
@@ -2354,6 +2606,30 @@ function convertKeyCandidate(wasm) {
|
|
|
2354
2606
|
correlation: wasm.correlation
|
|
2355
2607
|
};
|
|
2356
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
|
+
};
|
|
2357
2633
|
function keyModeValues(modes) {
|
|
2358
2634
|
if (!modes) {
|
|
2359
2635
|
return [];
|
|
@@ -2372,40 +2648,13 @@ function keyModeValues(modes) {
|
|
|
2372
2648
|
Mode.Locrian
|
|
2373
2649
|
];
|
|
2374
2650
|
}
|
|
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]);
|
|
2651
|
+
return modes.map((mode) => resolveEnumOrdinal(mode, KEY_MODE_VALUES, "key mode"));
|
|
2385
2652
|
}
|
|
2386
2653
|
function keyProfileValue(profile) {
|
|
2387
2654
|
if (profile === void 0) {
|
|
2388
2655
|
return -1;
|
|
2389
2656
|
}
|
|
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];
|
|
2657
|
+
return resolveEnumOrdinal(profile, KEY_PROFILE_VALUES, "key profile");
|
|
2409
2658
|
}
|
|
2410
2659
|
function convertChordAnalysisResult(wasm) {
|
|
2411
2660
|
return {
|
|
@@ -2611,18 +2860,27 @@ function analyze(samples, sampleRate = 22050, options = {}) {
|
|
|
2611
2860
|
const result = requireModule14().analyze(request.samples, request.sampleRate ?? 22050, request);
|
|
2612
2861
|
return convertAnalysisResult(result);
|
|
2613
2862
|
}
|
|
2614
|
-
function analyzeImpulseResponse(samples, sampleRate = 48e3, nOctaveBands = 6) {
|
|
2615
|
-
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
|
+
}
|
|
2616
2873
|
validateAnalysisInput(
|
|
2617
2874
|
"analyzeImpulseResponse",
|
|
2618
2875
|
request.samples,
|
|
2619
2876
|
request.sampleRate ?? 48e3,
|
|
2620
2877
|
request
|
|
2621
2878
|
);
|
|
2622
|
-
const result = requireModule14().
|
|
2879
|
+
const result = requireModule14().analyzeImpulseResponseEx(
|
|
2623
2880
|
request.samples,
|
|
2624
2881
|
request.sampleRate ?? 48e3,
|
|
2625
|
-
request.nOctaveBands ?? 6
|
|
2882
|
+
request.nOctaveBands ?? 6,
|
|
2883
|
+
resolvedMinDecayDb
|
|
2626
2884
|
);
|
|
2627
2885
|
return result;
|
|
2628
2886
|
}
|
|
@@ -2831,9 +3089,14 @@ var Audio = class _Audio {
|
|
|
2831
3089
|
}
|
|
2832
3090
|
}
|
|
2833
3091
|
}
|
|
2834
|
-
/**
|
|
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
|
+
*/
|
|
2835
3098
|
get data() {
|
|
2836
|
-
return this._samples;
|
|
3099
|
+
return this._samples.slice();
|
|
2837
3100
|
}
|
|
2838
3101
|
/** Number of samples. */
|
|
2839
3102
|
get length() {
|
|
@@ -3625,61 +3888,6 @@ function waveformPeakPyramid(samples, channels, options = {}) {
|
|
|
3625
3888
|
return requireModule15().waveformPeakPyramid(request.samples, request.channels, levels);
|
|
3626
3889
|
}
|
|
3627
3890
|
|
|
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
3891
|
// src/project_internal.ts
|
|
3684
3892
|
function projectModule() {
|
|
3685
3893
|
const candidate = getSonareModule();
|
|
@@ -3748,6 +3956,13 @@ function assertProjectMidiEvents(fnName, events) {
|
|
|
3748
3956
|
function projectTrackKindValue(kind) {
|
|
3749
3957
|
return resolveEnumOrdinal(kind ?? "audio", { audio: 0, midi: 1, aux: 2 }, "project track kind");
|
|
3750
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
|
+
);
|
|
3965
|
+
}
|
|
3751
3966
|
function projectWarpModeValue(mode) {
|
|
3752
3967
|
return resolveEnumOrdinal(
|
|
3753
3968
|
mode ?? "off",
|
|
@@ -3760,10 +3975,40 @@ function projectLoopModeValue(mode) {
|
|
|
3760
3975
|
}
|
|
3761
3976
|
|
|
3762
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`);
|
|
3981
|
+
}
|
|
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
|
+
);
|
|
3989
|
+
}
|
|
3990
|
+
return value;
|
|
3991
|
+
}
|
|
3992
|
+
function validateAssistSidecarPayload(value) {
|
|
3993
|
+
if (!(value instanceof Uint8Array)) {
|
|
3994
|
+
throw new TypeError("Project.setAssistSidecar: payload must be a Uint8Array");
|
|
3995
|
+
}
|
|
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");
|
|
4001
|
+
}
|
|
4002
|
+
return value;
|
|
4003
|
+
}
|
|
3763
4004
|
var Project = class _Project {
|
|
3764
4005
|
constructor() {
|
|
3765
4006
|
this.native = new (projectModule()).Project();
|
|
3766
4007
|
}
|
|
4008
|
+
/** Create a new empty project. */
|
|
4009
|
+
static create() {
|
|
4010
|
+
return new _Project();
|
|
4011
|
+
}
|
|
3767
4012
|
/** Pack a MIDI 1.0 note-on event accepted by {@link setMidiEvents}. */
|
|
3768
4013
|
static midiNoteOn(ppq, group, channel, note, velocity) {
|
|
3769
4014
|
return projectMidi1Event("Project.midiNoteOn", ppq, group, 9, channel, note, velocity);
|
|
@@ -4027,6 +4272,18 @@ var Project = class _Project {
|
|
|
4027
4272
|
}
|
|
4028
4273
|
this.native.setMaxUndoDepth(depth);
|
|
4029
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
|
+
}
|
|
4030
4287
|
/** Replace a MIDI clip's entire event list. */
|
|
4031
4288
|
setMidiEvents(clipId, events) {
|
|
4032
4289
|
assertProjectMidiEvents("Project.setMidiEvents", events);
|
|
@@ -4157,8 +4414,11 @@ var Project = class _Project {
|
|
|
4157
4414
|
* Karplus-Strong / modal / additive / percussion / extended-waveguide-piano
|
|
4158
4415
|
* engines plus the realism layer). Pass a {@link SynthPatch}, a preset-name
|
|
4159
4416
|
* string (`'saw-lead'` / `'va:saw-lead'`; see {@link synthPresetNames}), or
|
|
4160
|
-
* an array of either; each object entry may carry
|
|
4161
|
-
*
|
|
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.
|
|
4162
4422
|
* Because the parameter defaults to `{}`, omission and explicit `undefined`
|
|
4163
4423
|
* both create one default binding. Use an explicitly empty array `[]` (or
|
|
4164
4424
|
* runtime `null`) for zero bindings. Unknown preset names throw.
|
|
@@ -4232,6 +4492,10 @@ var Project = class _Project {
|
|
|
4232
4492
|
setSourceAudio(sourceId, audio, channels, sampleRate) {
|
|
4233
4493
|
this.native.setSourceAudio(sourceId, audio, channels, sampleRate);
|
|
4234
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
|
+
}
|
|
4235
4499
|
/** Replace a clip's take list and active take id (undoable). */
|
|
4236
4500
|
setClipTakes(clipId, takes, activeTakeId = 0) {
|
|
4237
4501
|
this.native.setClipTakes(clipId, takes, activeTakeId);
|
|
@@ -4275,17 +4539,29 @@ var Project = class _Project {
|
|
|
4275
4539
|
}
|
|
4276
4540
|
/** Append an automation lane; returns its stable target parameter id (undoable). */
|
|
4277
4541
|
addAutomationLane(trackId, desc) {
|
|
4278
|
-
|
|
4279
|
-
targetParamId
|
|
4280
|
-
|
|
4281
|
-
}
|
|
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);
|
|
4282
4552
|
}
|
|
4283
4553
|
/** Replace the lane identified by its stable target parameter id (undoable). */
|
|
4284
4554
|
editAutomationLane(trackId, targetParamId, desc) {
|
|
4285
|
-
|
|
4286
|
-
targetParamId
|
|
4287
|
-
|
|
4288
|
-
}
|
|
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);
|
|
4289
4565
|
}
|
|
4290
4566
|
/** Remove the lane identified by its stable target parameter id (undoable). */
|
|
4291
4567
|
removeAutomationLane(trackId, targetParamId) {
|
|
@@ -4299,15 +4575,33 @@ var Project = class _Project {
|
|
|
4299
4575
|
annotateChords(chords) {
|
|
4300
4576
|
this.native.annotateChords(chords);
|
|
4301
4577
|
}
|
|
4302
|
-
|
|
4303
|
-
|
|
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);
|
|
4304
4598
|
this.native.setAssistSidecar(
|
|
4305
4599
|
moduleId,
|
|
4306
|
-
schemaVersion,
|
|
4307
|
-
targetTrackId,
|
|
4308
|
-
regionStartPpq,
|
|
4309
|
-
regionEndPpq,
|
|
4310
|
-
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())
|
|
4311
4605
|
);
|
|
4312
4606
|
}
|
|
4313
4607
|
/** Number of assist sidecars currently stored on the project. */
|
|
@@ -4318,6 +4612,11 @@ var Project = class _Project {
|
|
|
4318
4612
|
getAssistSidecar(index) {
|
|
4319
4613
|
return this.native.getAssistSidecar(index);
|
|
4320
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
|
+
}
|
|
4321
4620
|
/** Set the project's clip-overlap policy (SonareProjectOverlapPolicy ordinal). */
|
|
4322
4621
|
setOverlapPolicy(policy) {
|
|
4323
4622
|
this.native.setOverlapPolicy(policy);
|
|
@@ -4500,6 +4799,14 @@ var SYNTH_MOD_DESTINATIONS = [
|
|
|
4500
4799
|
"amp-gain",
|
|
4501
4800
|
"pan-units"
|
|
4502
4801
|
];
|
|
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;
|
|
4503
4810
|
|
|
4504
4811
|
// src/realtime_engine.ts
|
|
4505
4812
|
var EXPECTED_ENGINE_ABI_VERSION = 3;
|
|
@@ -4563,6 +4870,10 @@ var RealtimeEngine = class {
|
|
|
4563
4870
|
setSoloMute(laneIndex, solo, mute, renderFrame = -1) {
|
|
4564
4871
|
this.native.setSoloMute(laneIndex, solo, mute, renderFrame);
|
|
4565
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
|
+
}
|
|
4566
4877
|
setMidiClips(clips) {
|
|
4567
4878
|
this.native.setMidiClips(clips);
|
|
4568
4879
|
}
|
|
@@ -5276,6 +5587,7 @@ var StreamAnalyzer = class {
|
|
|
5276
5587
|
if (config.outputFormat !== void 0 && (typeof config.outputFormat !== "number" || !Number.isFinite(config.outputFormat) || !Number.isInteger(config.outputFormat) || config.outputFormat !== 0)) {
|
|
5277
5588
|
throw new TypeError("outputFormat must be the integer 0 (Float32)");
|
|
5278
5589
|
}
|
|
5590
|
+
const window = config.window === void 0 ? void 0 : resolveOrdinalInRange(config.window, 0, 3, "stream analyzer window");
|
|
5279
5591
|
const module2 = getSonareModule();
|
|
5280
5592
|
const defaults = streamAnalyzerConfigDefaults();
|
|
5281
5593
|
this.analyzer = new module2.StreamAnalyzer(
|
|
@@ -5297,7 +5609,7 @@ var StreamAnalyzer = class {
|
|
|
5297
5609
|
config.maxProgressionEntries ?? defaults.maxProgressionEntries,
|
|
5298
5610
|
config.keyUpdateIntervalSec ?? defaults.keyUpdateIntervalSec,
|
|
5299
5611
|
config.bpmUpdateIntervalSec ?? defaults.bpmUpdateIntervalSec,
|
|
5300
|
-
|
|
5612
|
+
window ?? defaults.window,
|
|
5301
5613
|
config.outputFormat ?? defaults.outputFormat
|
|
5302
5614
|
);
|
|
5303
5615
|
}
|
|
@@ -5725,7 +6037,7 @@ var Mixer = class _Mixer {
|
|
|
5725
6037
|
setPolarityInvert(stripIndex, invertLeft, invertRight) {
|
|
5726
6038
|
this.mixer.setPolarityInvert(stripIndex, invertLeft, invertRight);
|
|
5727
6039
|
}
|
|
5728
|
-
/** Set the strip's pan law. */
|
|
6040
|
+
/** Set the strip's pan law (a {@link PanLawName} alias or raw C ABI ordinal). */
|
|
5729
6041
|
setPanLaw(stripIndex, panLaw) {
|
|
5730
6042
|
this.mixer.setPanLaw(stripIndex, panLawCode(panLaw));
|
|
5731
6043
|
}
|
|
@@ -6430,7 +6742,6 @@ async function bindWebMidi(engine, options = {}) {
|
|
|
6430
6742
|
for (const [, input] of iterInputs(access)) {
|
|
6431
6743
|
bindInput(input);
|
|
6432
6744
|
}
|
|
6433
|
-
notify();
|
|
6434
6745
|
};
|
|
6435
6746
|
const stateListener = (event) => {
|
|
6436
6747
|
if (closed) {
|
|
@@ -6449,6 +6760,7 @@ async function bindWebMidi(engine, options = {}) {
|
|
|
6449
6760
|
notify();
|
|
6450
6761
|
};
|
|
6451
6762
|
refreshInputs();
|
|
6763
|
+
notify();
|
|
6452
6764
|
if (access.addEventListener) {
|
|
6453
6765
|
access.addEventListener("statechange", stateListener);
|
|
6454
6766
|
} else {
|
|
@@ -6550,12 +6862,8 @@ function dispatchUmpMessage(engine, words, portTimeSamples) {
|
|
|
6550
6862
|
if (status === 8) {
|
|
6551
6863
|
engine.pushMidiInputNoteOff(group, channel, data1, word1 >>> 25 & 127, portTimeSamples);
|
|
6552
6864
|
} 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
|
-
}
|
|
6865
|
+
const velocity = Math.max(1, word1 >>> 25 & 127);
|
|
6866
|
+
engine.pushMidiInputNoteOn(group, channel, data1, velocity, portTimeSamples);
|
|
6559
6867
|
} else if (status === 11) {
|
|
6560
6868
|
engine.pushMidiInputCc(group, channel, data1, word1 >>> 25 & 127, portTimeSamples);
|
|
6561
6869
|
}
|
|
@@ -6874,6 +7182,9 @@ function voiceCharacterPresetId(preset) {
|
|
|
6874
7182
|
if (!module) {
|
|
6875
7183
|
throw new Error("Module not initialized. Call init() first.");
|
|
6876
7184
|
}
|
|
7185
|
+
if (typeof preset === "number" && (!Number.isSafeInteger(preset) || preset < 0 || preset >= VOICE_PRESET_ORDINALS.length)) {
|
|
7186
|
+
return null;
|
|
7187
|
+
}
|
|
6877
7188
|
return module.voiceCharacterPresetId(resolveVoicePresetOrdinal(preset));
|
|
6878
7189
|
}
|
|
6879
7190
|
function realtimeVoiceChangerPresetConfig(preset) {
|
|
@@ -6884,6 +7195,7 @@ function realtimeVoiceChangerPresetConfig(preset) {
|
|
|
6884
7195
|
}
|
|
6885
7196
|
export {
|
|
6886
7197
|
Audio,
|
|
7198
|
+
AutomationTargetKind,
|
|
6887
7199
|
BUILTIN_SYNTH_WAVEFORMS,
|
|
6888
7200
|
ChordQuality,
|
|
6889
7201
|
ClipPageProvider,
|
|
@@ -6897,6 +7209,9 @@ export {
|
|
|
6897
7209
|
Mode,
|
|
6898
7210
|
OfflineWorkerClient,
|
|
6899
7211
|
OfflineWorkerTask,
|
|
7212
|
+
PROJECT_AUTOMATION_TARGET_OPAQUE,
|
|
7213
|
+
PROJECT_AUTOMATION_TARGET_TRACK_FADER_DB,
|
|
7214
|
+
PROJECT_AUTOMATION_TARGET_TRACK_PAN,
|
|
6900
7215
|
PitchClass as Pitch,
|
|
6901
7216
|
PitchClass,
|
|
6902
7217
|
Project,
|