@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.
Files changed (47) hide show
  1. package/README.md +2 -2
  2. package/dist/analysis.d.ts +88 -9
  3. package/dist/analysis.js +152 -42
  4. package/dist/analysis.js.map +1 -1
  5. package/dist/index.d.ts +129 -24
  6. package/dist/index.js +455 -140
  7. package/dist/index.js.map +1 -1
  8. package/dist/schemas/realtime-voice-changer-preset.schema.json +2 -2
  9. package/dist/sonare-analysis.js +1 -1
  10. package/dist/sonare-analysis.wasm +0 -0
  11. package/dist/sonare.js +1 -1
  12. package/dist/sonare.wasm +0 -0
  13. package/dist/worker.js +56 -29
  14. package/dist/worker.js.map +1 -1
  15. package/dist/worklet.d.ts +62 -10
  16. package/dist/worklet.js +193 -42
  17. package/dist/worklet.js.map +1 -1
  18. package/package.json +3 -3
  19. package/src/analysis_helpers.ts +34 -29
  20. package/src/audio.ts +7 -2
  21. package/src/codes.ts +47 -11
  22. package/src/effects_transform.ts +179 -10
  23. package/src/feature_music.ts +8 -1
  24. package/src/feature_spectral.ts +64 -2
  25. package/src/feature_spectrogram.ts +44 -3
  26. package/src/index.ts +21 -3
  27. package/src/mixer.ts +3 -3
  28. package/src/project.ts +6 -0
  29. package/src/project_class.ts +143 -16
  30. package/src/project_internal.ts +14 -5
  31. package/src/project_types.ts +45 -1
  32. package/src/public_types_mixing.ts +16 -0
  33. package/src/public_types_realtime.ts +23 -5
  34. package/src/quick_analysis.ts +21 -3
  35. package/src/realtime_engine.ts +14 -3
  36. package/src/sonare.js.d.ts +64 -0
  37. package/src/stream_analyzer.ts +6 -1
  38. package/src/web_midi.ts +10 -7
  39. package/src/worklet/engine-node.ts +54 -19
  40. package/src/worklet/engine-parameter-facade.ts +30 -1
  41. package/src/worklet/engine-processor.ts +52 -20
  42. package/src/worklet/engine-register.ts +1 -1
  43. package/src/worklet/engine-strips.ts +2 -2
  44. package/src/worklet/engine.ts +10 -0
  45. package/src/worklet/guards.ts +99 -7
  46. package/src/worklet/messages.ts +41 -1
  47. 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 hpss(samples, sampleRate = 22050, kernelHarmonic = 31, kernelPercussive = 31) {
231
- const request = samples instanceof Float32Array ? { samples, sampleRate, kernelHarmonic, kernelPercussive } : samples;
232
- return requireModule().hpss(
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
- const request = samples instanceof Float32Array ? { samples, sampleRate, rate, ...options } : samples;
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
- return requireModule().timeStretch(request.samples, request.sampleRate ?? 22050, request.rate);
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
- const request = samples instanceof Float32Array ? { samples, sampleRate, semitones, ...options } : samples;
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
- return requireModule().pitchShift(
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
- const request = samples instanceof Float32Array ? { samples, sampleRate, targetDb, ...options } : samples;
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
- return requireModule().normalize(
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
- return requireModule9().nnlsChroma(
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(r.samples, r.sampleRate, r.kernelHarmonic, r.kernelPercussive);
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
- return requireModule12().hpssWithResidual(samples, sampleRate, kernelHarmonic, kernelPercussive);
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
- validateSpectrogramSamples("trim", samples, sampleRate, options);
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
- return requireModule13().trim(samples, sampleRate, thresholdDb);
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
- const names = {
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
- if (typeof profile === "number") {
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().analyzeImpulseResponse(
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
- /** The raw audio samples. */
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 a `destinationId` binding
4161
- * convenience (default 0), which is not part of the NativeSynth patch itself.
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
- return this.native.addAutomationLane(trackId, {
4279
- targetParamId: desc.targetParamId,
4280
- points: desc.points
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
- this.native.editAutomationLane(trackId, targetParamId, {
4286
- targetParamId: desc.targetParamId,
4287
- points: desc.points
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
- /** Add or update an opaque assist sidecar by module id + target scope (undoable). */
4303
- setAssistSidecar(moduleId, schemaVersion, targetTrackId, regionStartPpq, regionEndPpq, payload) {
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
- config.window ?? defaults.window,
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
- if (velocity === 0) {
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,