@libraz/libsonare 1.8.0 → 1.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/README.md +5 -5
  2. package/dist/_effects_common.d.ts +2 -1
  3. package/dist/_effects_common.d.ts.map +1 -1
  4. package/dist/analysis.js +3 -0
  5. package/dist/analysis.js.map +1 -1
  6. package/dist/effects_mastering.d.ts +2 -2
  7. package/dist/effects_mastering.d.ts.map +1 -1
  8. package/dist/effects_note_ops.d.ts +55 -30
  9. package/dist/effects_note_ops.d.ts.map +1 -1
  10. package/dist/effects_timepitch.d.ts +17 -12
  11. package/dist/effects_timepitch.d.ts.map +1 -1
  12. package/dist/feature_decompose.d.ts +1 -1
  13. package/dist/feature_decompose.d.ts.map +1 -1
  14. package/dist/index.d.ts +11 -5
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +2098 -155
  17. package/dist/index.js.map +1 -1
  18. package/dist/instrument_types.d.ts +27 -3
  19. package/dist/instrument_types.d.ts.map +1 -1
  20. package/dist/mastering_core.d.ts +30 -3
  21. package/dist/mastering_core.d.ts.map +1 -1
  22. package/dist/mixer.d.ts +2 -2
  23. package/dist/mixer.d.ts.map +1 -1
  24. package/dist/project.d.ts +5 -4
  25. package/dist/project.d.ts.map +1 -1
  26. package/dist/project_class.d.ts +57 -3
  27. package/dist/project_class.d.ts.map +1 -1
  28. package/dist/project_internal.d.ts +35 -1
  29. package/dist/project_internal.d.ts.map +1 -1
  30. package/dist/project_types.d.ts +17 -6
  31. package/dist/project_types.d.ts.map +1 -1
  32. package/dist/public_types.d.ts +1 -0
  33. package/dist/public_types.d.ts.map +1 -1
  34. package/dist/public_types_mastering.d.ts +19 -1
  35. package/dist/public_types_mastering.d.ts.map +1 -1
  36. package/dist/public_types_playback.d.ts +1 -0
  37. package/dist/public_types_playback.d.ts.map +1 -1
  38. package/dist/public_types_spectral.d.ts +5 -5
  39. package/dist/public_types_spectral.d.ts.map +1 -1
  40. package/dist/public_types_vocal_edit.d.ts +250 -0
  41. package/dist/public_types_vocal_edit.d.ts.map +1 -0
  42. package/dist/public_types_vocal_project.d.ts +63 -0
  43. package/dist/public_types_vocal_project.d.ts.map +1 -0
  44. package/dist/realtime_engine.d.ts +106 -16
  45. package/dist/realtime_engine.d.ts.map +1 -1
  46. package/dist/repair_dereverb.d.ts +1 -0
  47. package/dist/repair_dereverb.d.ts.map +1 -1
  48. package/dist/repair_noise.d.ts +1 -0
  49. package/dist/repair_noise.d.ts.map +1 -1
  50. package/dist/sonare-analysis.wasm +0 -0
  51. package/dist/sonare.d.ts +89 -0
  52. package/dist/sonare.js +1 -1
  53. package/dist/sonare.wasm +0 -0
  54. package/dist/streaming_processors.d.ts +5 -0
  55. package/dist/streaming_processors.d.ts.map +1 -1
  56. package/dist/vocal_edit.d.ts +131 -0
  57. package/dist/vocal_edit.d.ts.map +1 -0
  58. package/dist/vocal_edit_worker.d.ts +51 -0
  59. package/dist/vocal_edit_worker.d.ts.map +1 -0
  60. package/dist/vocal_edit_worker.js +1462 -0
  61. package/dist/vocal_edit_worker.js.map +1 -0
  62. package/dist/vocal_edit_worker_client.d.ts +118 -0
  63. package/dist/vocal_edit_worker_client.d.ts.map +1 -0
  64. package/dist/vocal_edit_worker_protocol.d.ts +139 -0
  65. package/dist/vocal_edit_worker_protocol.d.ts.map +1 -0
  66. package/dist/vocal_project.d.ts +17 -0
  67. package/dist/vocal_project.d.ts.map +1 -0
  68. package/dist/web_midi.d.ts +4 -0
  69. package/dist/web_midi.d.ts.map +1 -1
  70. package/dist/worker.js.map +1 -1
  71. package/dist/worklet/engine-mixer-facade.d.ts +42 -5
  72. package/dist/worklet/engine-mixer-facade.d.ts.map +1 -1
  73. package/dist/worklet/engine-node.d.ts +10 -0
  74. package/dist/worklet/engine-node.d.ts.map +1 -1
  75. package/dist/worklet/engine-processor.d.ts +6 -1
  76. package/dist/worklet/engine-processor.d.ts.map +1 -1
  77. package/dist/worklet/engine-register.d.ts.map +1 -1
  78. package/dist/worklet/engine-strips.d.ts +8 -4
  79. package/dist/worklet/engine-strips.d.ts.map +1 -1
  80. package/dist/worklet/engine-sync.d.ts +4 -2
  81. package/dist/worklet/engine-sync.d.ts.map +1 -1
  82. package/dist/worklet/engine.d.ts +42 -9
  83. package/dist/worklet/engine.d.ts.map +1 -1
  84. package/dist/worklet/guards.d.ts +10 -2
  85. package/dist/worklet/guards.d.ts.map +1 -1
  86. package/dist/worklet/messages.d.ts +54 -9
  87. package/dist/worklet/messages.d.ts.map +1 -1
  88. package/dist/worklet/mixer-processor.d.ts +2 -2
  89. package/dist/worklet/mixer-processor.d.ts.map +1 -1
  90. package/dist/worklet/protocol.d.ts +20 -2
  91. package/dist/worklet/protocol.d.ts.map +1 -1
  92. package/dist/worklet.d.ts +1 -1
  93. package/dist/worklet.d.ts.map +1 -1
  94. package/dist/worklet.js +808 -204
  95. package/dist/worklet.js.map +1 -1
  96. package/package.json +6 -1
  97. package/src/_effects_common.ts +36 -6
  98. package/src/effects_mastering.ts +4 -0
  99. package/src/effects_note_ops.ts +92 -44
  100. package/src/effects_timepitch.ts +42 -31
  101. package/src/feature_decompose.ts +2 -2
  102. package/src/index.ts +39 -0
  103. package/src/instrument_types.ts +29 -3
  104. package/src/mastering_core.ts +98 -2
  105. package/src/mixer.ts +41 -21
  106. package/src/project.ts +8 -1
  107. package/src/project_class.ts +136 -1
  108. package/src/project_internal.ts +90 -0
  109. package/src/project_types.ts +18 -6
  110. package/src/public_types.ts +1 -0
  111. package/src/public_types_mastering.ts +23 -0
  112. package/src/public_types_playback.ts +1 -0
  113. package/src/public_types_spectral.ts +5 -5
  114. package/src/public_types_vocal_edit.ts +289 -0
  115. package/src/public_types_vocal_project.ts +69 -0
  116. package/src/realtime_engine.ts +157 -24
  117. package/src/repair_dereverb.ts +1 -0
  118. package/src/repair_noise.ts +1 -0
  119. package/src/sonare.js.d.ts +89 -0
  120. package/src/streaming_processors.ts +8 -0
  121. package/src/vocal_edit.ts +885 -0
  122. package/src/vocal_edit_worker.ts +832 -0
  123. package/src/vocal_edit_worker_client.ts +812 -0
  124. package/src/vocal_edit_worker_protocol.ts +206 -0
  125. package/src/vocal_project.ts +327 -0
  126. package/src/web_midi.ts +100 -5
  127. package/src/worklet/engine-mixer-facade.ts +422 -87
  128. package/src/worklet/engine-node.ts +69 -4
  129. package/src/worklet/engine-processor.ts +129 -34
  130. package/src/worklet/engine-register.ts +3 -0
  131. package/src/worklet/engine-strips.ts +36 -14
  132. package/src/worklet/engine-sync.ts +6 -1
  133. package/src/worklet/engine.ts +76 -40
  134. package/src/worklet/guards.ts +81 -0
  135. package/src/worklet/messages.ts +63 -4
  136. package/src/worklet/mixer-processor.ts +10 -3
  137. package/src/worklet/protocol.ts +39 -8
  138. package/src/worklet.ts +2 -0
@@ -12,16 +12,24 @@ import type {
12
12
  ControllerBinding,
13
13
  MpeDimension,
14
14
  NoteTracking,
15
+ PartRigInsert,
16
+ PartRigMode,
15
17
  ProjectMidiCcBinding,
16
18
  SynthPatch,
17
19
  } from './project';
18
- import { normalizeSynthInstrument } from './project_internal';
20
+ import type { ProjectTimeline } from './project_class';
21
+ import {
22
+ normalizeSynthInstrument,
23
+ partRigInsertsJson,
24
+ projectTimelineNativeId,
25
+ } from './project_internal';
19
26
  import type {
20
27
  EqBand,
21
28
  PanLawInput,
22
29
  PanMode,
23
30
  SendTiming,
24
31
  SidechainSourceKind,
32
+ SurroundPan,
25
33
  UmpWords,
26
34
  } from './public_types';
27
35
  import type {
@@ -29,6 +37,7 @@ import type {
29
37
  WasmEngineAutomationPoint,
30
38
  WasmEngineBounceOptions,
31
39
  WasmEngineBounceResult,
40
+ WasmEngineBus,
32
41
  WasmEngineCaptureStatus,
33
42
  WasmEngineClip,
34
43
  WasmEngineFreezeOptions,
@@ -44,6 +53,7 @@ import type {
44
53
  WasmEngineTelemetry,
45
54
  WasmEngineTempoSegment,
46
55
  WasmEngineTimeSignatureSegment,
56
+ WasmEngineTrackSend,
47
57
  WasmEngineTransportState,
48
58
  WasmExternalMidiEvent,
49
59
  WasmRealtimeEngine,
@@ -574,6 +584,23 @@ export class RealtimeEngine {
574
584
  this.native.setArticulation(destinationId, channel, articulation);
575
585
  }
576
586
 
587
+ /**
588
+ * Set the rig of one part (0-15), or of the destination's default when `part`
589
+ * is `PART_RIG_ALL_PARTS`, on the instrument bound to `destinationId`. A
590
+ * direct call, not a stored edit: a destination with no instrument is an
591
+ * invalid parameter, and an instrument without part rigs (a builtin, a
592
+ * host-callback instrument) is refused as not implemented rather than
593
+ * succeeding quietly. `'chain'` takes 1-8 `inserts`; no other mode does.
594
+ */
595
+ setPartRig(
596
+ destinationId: number,
597
+ part: number,
598
+ mode: PartRigMode | number,
599
+ inserts?: PartRigInsert[],
600
+ ): void {
601
+ this.native.setPartRig(destinationId, part, mode, partRigInsertsJson(inserts));
602
+ }
603
+
577
604
  /**
578
605
  * Read back {@link setArticulation} as the canonical name. An ordinal this
579
606
  * build cannot spell is handed back as the number, the way every other enum
@@ -626,7 +653,10 @@ export class RealtimeEngine {
626
653
  /**
627
654
  * Route a destination's (track lane's) MIDI to the external output queue
628
655
  * instead of the internal instrument rack, so the track plays an external
629
- * device. Clearing it restores internal-synth playback.
656
+ * device. Clearing it restores internal-synth playback. Control-thread only.
657
+ * The change takes effect at the next processed block; switching a
658
+ * destination's route first releases its notes and resets its controllers
659
+ * through the old route, and drops its pending MIDI-FX events. Single writer.
630
660
  */
631
661
  setMidiDestinationExternal(destinationId: number, external: boolean): void {
632
662
  this.native.setMidiDestinationExternal(destinationId, external);
@@ -883,8 +913,11 @@ export class RealtimeEngine {
883
913
  /**
884
914
  * Queue an immediate (live) MIDI SysEx frame to a MIDI destination. `data` is
885
915
  * the full message including the leading 0xF0 and trailing 0xF7 (1..512
886
- * bytes). `renderFrame` is the frame to fire at, or -1 for immediate. Mirrors
887
- * the Node/Python/C-ABI `pushMidiSysex`.
916
+ * bytes). `renderFrame` is the frame to fire at, or -1 for immediate. Throws
917
+ * `InvalidParameter` when the destination instrument cannot prepare
918
+ * the SysEx (retrying cannot help), and `OutOfMemory` when the payload
919
+ * slots or the command queue are full (retry after a processed block).
920
+ * Mirrors the Node/Python/C-ABI `pushMidiSysex`.
888
921
  */
889
922
  pushMidiSysex(destinationId: number, data: Uint8Array, renderFrame = -1): void {
890
923
  this.native.pushMidiSysex(destinationId, data, renderFrame);
@@ -911,14 +944,34 @@ export class RealtimeEngine {
911
944
  return this.native.getTransportState();
912
945
  }
913
946
 
947
+ /** Queues an integrated-loudness reset; short-term and momentary windows are retained. */
948
+ resetMasterLoudnessMeter(renderFrame = -1): void {
949
+ this.native.resetMasterLoudnessMeter(renderFrame);
950
+ }
951
+
952
+ /** Reads the immutable factory value for a resolved insert parameter id. */
953
+ insertParameterConstructedValue(paramId: number): number {
954
+ return this.native.insertParameterConstructedValue(paramId);
955
+ }
956
+
914
957
  play(renderFrame = -1): void {
915
958
  this.native.play(renderFrame);
916
959
  }
917
960
 
961
+ /**
962
+ * A loop wrap, seek or stop sends note-offs plus CC64=0, CC121, CC123 and a
963
+ * centred pitch bend on every channel played since the last reset, so
964
+ * controller values set before a loop region are not restored at the wrap.
965
+ */
918
966
  stop(renderFrame = -1): void {
919
967
  this.native.stop(renderFrame);
920
968
  }
921
969
 
970
+ /**
971
+ * A loop wrap, seek or stop sends note-offs plus CC64=0, CC121, CC123 and a
972
+ * centred pitch bend on every channel played since the last reset, so
973
+ * controller values set before a loop region are not restored at the wrap.
974
+ */
922
975
  seekSample(timelineSample: number, renderFrame = -1): void {
923
976
  this.native.seekSample(timelineSample, renderFrame);
924
977
  }
@@ -948,6 +1001,11 @@ export class RealtimeEngine {
948
1001
  this.native.applyCommandsDueNowPreservingFuture();
949
1002
  }
950
1003
 
1004
+ /**
1005
+ * A loop wrap, seek or stop sends note-offs plus CC64=0, CC121, CC123 and a
1006
+ * centred pitch bend on every channel played since the last reset, so
1007
+ * controller values set before a loop region are not restored at the wrap.
1008
+ */
951
1009
  seekPpq(ppq: number, renderFrame = -1): void {
952
1010
  this.native.seekPpq(ppq, renderFrame);
953
1011
  }
@@ -973,6 +1031,11 @@ export class RealtimeEngine {
973
1031
  return Number(this.native.sampleAtPpq(ppq));
974
1032
  }
975
1033
 
1034
+ /**
1035
+ * A loop wrap, seek or stop sends note-offs plus CC64=0, CC121, CC123 and a
1036
+ * centred pitch bend on every channel played since the last reset, so
1037
+ * controller values set before a loop region are not restored at the wrap.
1038
+ */
976
1039
  setLoop(startPpq: number, endPpq: number, enabled = true): void {
977
1040
  this.native.setLoop(startPpq, endPpq, enabled);
978
1041
  }
@@ -1079,7 +1142,7 @@ export class RealtimeEngine {
1079
1142
  * reads (defaults to post-fader when omitted). Shared by track lanes and
1080
1143
  * buses, which carry the same send shape.
1081
1144
  */
1082
- private static normalizeSends(sends: EngineTrackSend[]): EngineTrackSend[] {
1145
+ private static normalizeSends(sends: EngineTrackSend[]): WasmEngineTrackSend[] {
1083
1146
  return sends.map((send) => ({
1084
1147
  ...send,
1085
1148
  // Post-fader (0) is the default for an omitted sendTiming.
@@ -1093,10 +1156,10 @@ export class RealtimeEngine {
1093
1156
  if (typeof lane === 'number') {
1094
1157
  return { trackId: lane };
1095
1158
  }
1096
- if (!lane.sends) {
1097
- return lane;
1098
- }
1099
- return { ...lane, sends: RealtimeEngine.normalizeSends(lane.sends) };
1159
+ return {
1160
+ ...lane,
1161
+ sends: lane.sends ? RealtimeEngine.normalizeSends(lane.sends) : undefined,
1162
+ };
1100
1163
  }),
1101
1164
  );
1102
1165
  }
@@ -1104,11 +1167,44 @@ export class RealtimeEngine {
1104
1167
  /**
1105
1168
  * Keys one insert of a lane strip from another lane's post-strip audio
1106
1169
  * (ducking/sidechainRouter inserts). sourceTrackId 0 removes the binding.
1170
+ * Lanes are processed in key order and the key is delay-compensated to the
1171
+ * destination strip input, so the result depends on neither the lane order
1172
+ * nor the block size. Throws, leaving the bindings unchanged, for a lane
1173
+ * keying itself, a binding that would close a cycle over the lane bindings,
1174
+ * a full binding table and an alignment past the delay ceiling. Not callable
1175
+ * while a block is being processed.
1107
1176
  */
1108
1177
  setLaneSidechain(trackId: number, insertIndex: number, sourceTrackId: number): void {
1109
1178
  this.native.setLaneSidechain(trackId, insertIndex, sourceTrackId);
1110
1179
  }
1111
1180
 
1181
+ /**
1182
+ * Installs a compiled project timeline into this stopped engine, all or
1183
+ * nothing: tempo and time-signature segments, markers, track lanes, track
1184
+ * automation, audio and MIDI clips, and the per-track strips of the project's
1185
+ * mixer scene are replaced in full (a later low-level setter on those domains
1186
+ * is overwritten by the next apply). Instruments, buses, the master strip,
1187
+ * metronome, loop and capture are not touched; bind instruments separately.
1188
+ *
1189
+ * Throws while the transport is playing, for a timeline the engine cannot
1190
+ * hold, and for a scene strip routed from several tracks. A validation
1191
+ * failure leaves the engine unchanged. The engine keeps its own reference, so
1192
+ * {@link ProjectTimeline.dispose} may follow immediately.
1193
+ *
1194
+ * Also throws on an unprepared engine and on a timeline whose sample rate
1195
+ * differs from the engine's. Once a timeline is applied, a later prepare at
1196
+ * another rate is refused until the timeline's clips are cleared.
1197
+ */
1198
+ applyProjectTimeline(timeline: ProjectTimeline): void {
1199
+ // Resolve through the identity registry so no raw native handle crosses the
1200
+ // facade boundary and the realtime bundle needs no value class import.
1201
+ const timelineId = projectTimelineNativeId(timeline);
1202
+ if (timelineId === undefined) {
1203
+ throw new TypeError('timeline must be a ProjectTimeline instance');
1204
+ }
1205
+ this.native.applyProjectTimeline(timelineId);
1206
+ }
1207
+
1112
1208
  setTrackBuses(buses: EngineBus[]): void {
1113
1209
  // Array.isArray guards a caller-fabricated array-like (e.g. `{ length }`)
1114
1210
  // meant to probe the native array-length read: passing it through
@@ -1116,10 +1212,11 @@ export class RealtimeEngine {
1116
1212
  // failing here on a `.map` that array-likes do not implement.
1117
1213
  this.native.setTrackBuses(
1118
1214
  Array.isArray(buses)
1119
- ? buses.map((bus) =>
1120
- bus.sends ? { ...bus, sends: RealtimeEngine.normalizeSends(bus.sends) } : bus,
1121
- )
1122
- : buses,
1215
+ ? buses.map((bus) => ({
1216
+ ...bus,
1217
+ sends: bus.sends ? RealtimeEngine.normalizeSends(bus.sends) : undefined,
1218
+ }))
1219
+ : (buses as WasmEngineBus[]),
1123
1220
  );
1124
1221
  }
1125
1222
 
@@ -1357,6 +1454,16 @@ export class RealtimeEngine {
1357
1454
  * stages of the offline mastering chain (`repair.*`, `loudness`, and the
1358
1455
  * match stages) have no insert form and no automation id: they buffer the
1359
1456
  * entire signal by construction and do not run on the realtime path.
1457
+ *
1458
+ * The returned id uses the track's current positional lane selector. When
1459
+ * `setTrackLanes` successfully changes lane order or membership, the engine
1460
+ * remaps already queued and published track automation by track id, but it
1461
+ * cannot update a numeric id retained by the caller. Re-resolve every track
1462
+ * insert id after such a topology change before passing it to
1463
+ * `setAutomationLane`, `setParameter`, or `setParameterSmoothed`. Use
1464
+ * `setTrackStripInsertParamByName` when the operation needs a stable track
1465
+ * identity. Master and bus insert ids are separate and are not invalidated by
1466
+ * track-lane changes.
1360
1467
  */
1361
1468
  resolveTrackInsertAutomationId(trackId: number, insertIndex: number, paramName: string): number {
1362
1469
  return this.native.resolveTrackInsertAutomationId(trackId, insertIndex, paramName);
@@ -1392,12 +1499,9 @@ export class RealtimeEngine {
1392
1499
  * return `-1`: they resize voice pools or swap DSP topology, which is not
1393
1500
  * audio-thread safe. Rebind the instrument with a new patch instead.
1394
1501
  *
1395
- * `gain`, `busDrive`, `cutoffHz`, `resonanceQ`, `envToCutoffCents`,
1396
- * `lfoToPitchCents` and `pitchOffsetCents` reach voices that are already
1397
- * sounding from the next block; the rest are cached into per-voice state at
1398
- * note-on and take effect from the next note, so a lane that moves one of
1399
- * them under a held note looks inert until the next one speaks — that is the
1400
- * behaviour, not a dropped write.
1502
+ * All automatable parameters of a NativeSynth reach already-sounding voices
1503
+ * from the next processed block. Voices using GM program patches are
1504
+ * unaffected; parameters apply to NativeSynth's own patch only.
1401
1505
  *
1402
1506
  * The id survives an unbind/rebind of the same destination and applies
1403
1507
  * nothing while that destination is unbound.
@@ -1426,6 +1530,17 @@ export class RealtimeEngine {
1426
1530
  this.native.setTrackStripDualPan(trackId, leftPan, rightPan);
1427
1531
  }
1428
1532
 
1533
+ /**
1534
+ * Sets a track lane strip's surround placement in realtime (glitch-free; a
1535
+ * constant-power 5 ms one-pole glide). Used when the destination has more than
1536
+ * two channels. Omitted fields default to a centered point source
1537
+ * (`distance` 1); a `distance` of 0 or less is treated as 1. Throws for an
1538
+ * unknown track, a track without a lane strip, or a non-finite field.
1539
+ */
1540
+ setTrackStripSurroundPan(trackId: number, pan: SurroundPan): void {
1541
+ this.native.setTrackStripSurroundPan(trackId, pan);
1542
+ }
1543
+
1429
1544
  /**
1430
1545
  * Sets a bus strip's output pan position in realtime (glitch-free). Throws
1431
1546
  * for an unknown bus or one wider than stereo.
@@ -1450,8 +1565,9 @@ export class RealtimeEngine {
1450
1565
  }
1451
1566
 
1452
1567
  /**
1453
- * Sets a track lane strip's inter-channel alignment delay (whole samples).
1454
- * Adjusts strip latency, so PDC and reported graph latency are refreshed.
1568
+ * Sets a track lane strip's alignment delay (whole samples), moving this lane
1569
+ * later relative to every other lane. It is not latency: PDC does not
1570
+ * compensate it and the reported graph latency is unchanged.
1455
1571
  */
1456
1572
  setTrackStripChannelDelaySamples(trackId: number, delaySamples: number): void {
1457
1573
  this.native.setTrackStripChannelDelaySamples(trackId, delaySamples);
@@ -1757,6 +1873,12 @@ export class RealtimeEngine {
1757
1873
  meterScratchRenderFrame(): number {
1758
1874
  return Number(this.native.meterScratchRenderFrame());
1759
1875
  }
1876
+ meterScratchInputPeakDbL(): number {
1877
+ return this.native.meterScratchInputPeakDbL();
1878
+ }
1879
+ meterScratchInputPeakDbR(): number {
1880
+ return this.native.meterScratchInputPeakDbR();
1881
+ }
1760
1882
  meterScratchValue(field: number): number {
1761
1883
  return this.native.meterScratchValue(field);
1762
1884
  }
@@ -1768,15 +1890,26 @@ export class RealtimeEngine {
1768
1890
  /**
1769
1891
  * Drains pending meter telemetry as per-plane (wide) records for a surround
1770
1892
  * target. Use this for a surround mix target; {@link drainMeterTelemetry}
1771
- * stays the stereo fast path. The two share one queue — call only one per
1772
- * target. The live AudioWorklet path owns the queue via the stereo drain, so
1773
- * this wide drain is for an offline (non-worklet) engine instance; per-plane
1893
+ * stays the stereo fast path. The two share one queue and each consumes every
1894
+ * target's records, so an engine uses only one of them. The live AudioWorklet
1895
+ * path owns the queue via the stereo drain, so this wide drain is for an
1896
+ * offline (non-worklet) engine instance; per-plane
1774
1897
  * surround meters are not delivered over the live worklet meter ring.
1775
1898
  */
1776
1899
  drainMeterTelemetryWide(maxRecords = 1024): EngineMeterTelemetryWide[] {
1777
1900
  return this.native.drainMeterTelemetryWide(maxRecords);
1778
1901
  }
1779
1902
 
1903
+ /**
1904
+ * Per-insert gain reduction in dB (each <= 0) of a meter target's strip from the
1905
+ * last rendered block, in combined pre-to-post insert order. `targetId` uses the
1906
+ * meter-record encoding (0 master, 1..32 lanes, 33..40 buses; 0xFFFF monitor
1907
+ * yields an empty array). Throws for an id outside that range.
1908
+ */
1909
+ meterTargetInsertGainReduction(targetId: number): number[] {
1910
+ return this.native.meterTargetInsertGainReduction(targetId);
1911
+ }
1912
+
1780
1913
  /**
1781
1914
  * Enables per-target spectrum + vectorscope capture. @param intervalFrames is
1782
1915
  * the minimum render-frame gap between snapshots (0 disables). @param bandCount
@@ -19,6 +19,7 @@ export interface DereverbClassicalOptions {
19
19
  threshold?: number;
20
20
  attenuation?: number;
21
21
  nFft?: number;
22
+ /** Hop in samples, in (0, nFft / 2]. */
22
23
  hopLength?: number;
23
24
  t60Sec?: number;
24
25
  lateDelayMs?: number;
@@ -26,6 +26,7 @@ export interface DenoiseClassicalOptions {
26
26
  mode?: DenoiseClassicalMode;
27
27
  noiseEstimator?: DenoiseClassicalNoiseEstimator;
28
28
  nFft?: number;
29
+ /** Hop in samples, in (0, nFft / 2]. */
29
30
  hopLength?: number;
30
31
  ddAlpha?: number;
31
32
  reductionDb?: number;
@@ -25,6 +25,7 @@ import type {
25
25
  SpectralRegionOp,
26
26
  SurroundPan,
27
27
  } from './public_types';
28
+ import type { VocalWasmExports } from './vocal_edit';
28
29
 
29
30
  export interface SonareModuleOptions {
30
31
  locateFile?: (path: string, prefix: string) => string;
@@ -829,6 +830,11 @@ export interface WasmLoudnessMatchResult {
829
830
  matchedTruePeakDbtp: number;
830
831
  }
831
832
 
833
+ export interface WasmLoudnessMatchStereoResult extends Omit<WasmLoudnessMatchResult, 'samples'> {
834
+ left: Float32Array;
835
+ right: Float32Array;
836
+ }
837
+
832
838
  export interface WasmStageGainReduction {
833
839
  stage: string;
834
840
  gainReductionDb: number;
@@ -965,6 +971,8 @@ export interface WasmEngineTrackSend {
965
971
  busId: number;
966
972
  levelDb?: number;
967
973
  enabled?: boolean;
974
+ /** Native send tap: 0 post-fader (default), 1 pre-fader. */
975
+ sendTiming?: number;
968
976
  }
969
977
 
970
978
  export interface WasmEngineTrackLane {
@@ -1165,6 +1173,10 @@ export interface WasmEngineMeterTelemetry {
1165
1173
  shortTermLufs: number;
1166
1174
  integratedLufs: number;
1167
1175
  gainReductionDb: number;
1176
+ /** Maximum pre-trim input peak for the left channel, in dBFS. */
1177
+ inputPeakDbL: number;
1178
+ /** Maximum pre-trim input peak for the right channel, in dBFS. */
1179
+ inputPeakDbR: number;
1168
1180
  droppedRecords: number;
1169
1181
  }
1170
1182
 
@@ -1199,6 +1211,8 @@ export interface WasmEngineMeterTelemetryWide {
1199
1211
  shortTermLufs: number;
1200
1212
  integratedLufs: number;
1201
1213
  gainReductionDb: number;
1214
+ /** Pre-trim input peak for each valid plane, in dBFS. */
1215
+ inputPeakDb: number[];
1202
1216
  droppedRecords: number;
1203
1217
  }
1204
1218
 
@@ -1275,7 +1289,17 @@ export interface WasmEngineBounceOptions {
1275
1289
  totalFrames: number;
1276
1290
  blockSize?: number;
1277
1291
  numChannels?: number;
1292
+ /**
1293
+ * Output sample rate. Omitting it (or `0`) keeps the source rate, so nothing
1294
+ * is resampled; a different rate resamples. The result's `sampleRate`
1295
+ * reports the rate of the returned audio.
1296
+ */
1278
1297
  targetSampleRate?: number;
1298
+ /**
1299
+ * Rate `totalFrames` is counted in. Omitting it (or `0`) means the engine's
1300
+ * prepared rate; a different value throws an `InvalidParameter` `SonareError`,
1301
+ * because the render always runs at the prepared rate.
1302
+ */
1279
1303
  sourceSampleRate?: number;
1280
1304
  normalizeLufs?: boolean;
1281
1305
  /**
@@ -1363,6 +1387,8 @@ export interface WasmRealtimeEngine {
1363
1387
  getTransportState: () => WasmEngineTransportState;
1364
1388
  play: (renderFrame?: number) => void;
1365
1389
  stop: (renderFrame?: number) => void;
1390
+ resetMasterLoudnessMeter: (renderFrame?: number) => void;
1391
+ insertParameterConstructedValue: (paramId: number) => number;
1366
1392
  seekSample: (timelineSample: number, renderFrame?: number) => void;
1367
1393
  settleParameters: () => void;
1368
1394
  settleInsertParameters: () => void;
@@ -1398,6 +1424,7 @@ export interface WasmRealtimeEngine {
1398
1424
  clipCount: () => number;
1399
1425
  setTrackLanes: (lanes: Array<number | WasmEngineTrackLane>) => void;
1400
1426
  setLaneSidechain: (trackId: number, insertIndex: number, sourceTrackId: number) => void;
1427
+ applyProjectTimeline: (timelineId: number) => void;
1401
1428
  setTrackBuses: (buses: WasmEngineBus[]) => void;
1402
1429
  setBusSidechain: (
1403
1430
  busId: number,
@@ -1491,6 +1518,7 @@ export interface WasmRealtimeEngine {
1491
1518
  setTrackStripPanLaw: (trackId: number, panLaw: number) => void;
1492
1519
  setTrackStripPanMode: (trackId: number, panMode: number) => void;
1493
1520
  setTrackStripDualPan: (trackId: number, leftPan: number, rightPan: number) => void;
1521
+ setTrackStripSurroundPan: (trackId: number, pan: SurroundPan) => void;
1494
1522
  setBusStripPan: (busId: number, pan: number) => void;
1495
1523
  setBusStripPanLaw: (busId: number, panLaw: number) => void;
1496
1524
  setBusStripPanMode: (busId: number, panMode: number) => void;
@@ -1564,6 +1592,12 @@ export interface WasmRealtimeEngine {
1564
1592
  channel: number,
1565
1593
  ) => import('./instrument_types').Articulation | number;
1566
1594
  legatoFallbackCount: (destinationId: number) => number;
1595
+ setPartRig: (
1596
+ destinationId: number,
1597
+ part: number,
1598
+ mode: import('./instrument_types').PartRigMode | number,
1599
+ insertsJson: string | undefined,
1600
+ ) => void;
1567
1601
  setMidiFx: (destinationId: number, configJson: string) => void;
1568
1602
  clearMidiFx: (destinationId: number) => void;
1569
1603
  setMidiInputSource: (destinationId: number) => void;
@@ -1707,8 +1741,11 @@ export interface WasmRealtimeEngine {
1707
1741
  meterScratchTargetId: () => number;
1708
1742
  meterScratchRenderFrame: () => number;
1709
1743
  meterScratchValue: (field: number) => number;
1744
+ meterScratchInputPeakDbL: () => number;
1745
+ meterScratchInputPeakDbR: () => number;
1710
1746
  drainMeterTelemetry: (maxRecords: number) => WasmEngineMeterTelemetry[];
1711
1747
  drainMeterTelemetryWide: (maxRecords: number) => WasmEngineMeterTelemetryWide[];
1748
+ meterTargetInsertGainReduction: (targetId: number) => number[];
1712
1749
  configureScopeTelemetry: (intervalFrames: number, bandCount: number) => number;
1713
1750
  drainScopeTelemetry: (maxRecords: number) => WasmEngineScopeTelemetry[];
1714
1751
  popScopeTelemetryToScratch: () => boolean;
@@ -1742,6 +1779,39 @@ export interface WasmSynthEnumTables {
1742
1779
  }
1743
1780
 
1744
1781
  export interface SonareModule {
1782
+ vocalEditApiVersion: VocalWasmExports['vocalEditApiVersion'];
1783
+ vocalEditAvailable: VocalWasmExports['vocalEditAvailable'];
1784
+ vocalEditSessionCreate: VocalWasmExports['vocalEditSessionCreate'];
1785
+ vocalEditSessionRestore: VocalWasmExports['vocalEditSessionRestore'];
1786
+ vocalEditSessionDestroy: VocalWasmExports['vocalEditSessionDestroy'];
1787
+ vocalEditSessionNotes: VocalWasmExports['vocalEditSessionNotes'];
1788
+ vocalEditDraftNotes: VocalWasmExports['vocalEditDraftNotes'];
1789
+ vocalEditSessionToken: VocalWasmExports['vocalEditSessionToken'];
1790
+ vocalEditDraftToken: VocalWasmExports['vocalEditDraftToken'];
1791
+ vocalEditSessionAnalysis: VocalWasmExports['vocalEditSessionAnalysis'];
1792
+ vocalEditSessionCapabilities: VocalWasmExports['vocalEditSessionCapabilities'];
1793
+ vocalEditSessionOutputLength: VocalWasmExports['vocalEditSessionOutputLength'];
1794
+ vocalEditSessionHistory: VocalWasmExports['vocalEditSessionHistory'];
1795
+ vocalEditSessionBeginEdit: VocalWasmExports['vocalEditSessionBeginEdit'];
1796
+ vocalEditDraftApply: VocalWasmExports['vocalEditDraftApply'];
1797
+ vocalEditDraftCommit: VocalWasmExports['vocalEditDraftCommit'];
1798
+ vocalEditDraftCancel: VocalWasmExports['vocalEditDraftCancel'];
1799
+ vocalEditDraftDestroy: VocalWasmExports['vocalEditDraftDestroy'];
1800
+ vocalEditSessionApplyHistory: VocalWasmExports['vocalEditSessionApplyHistory'];
1801
+ vocalEditEvaluatePitch: VocalWasmExports['vocalEditEvaluatePitch'];
1802
+ vocalEditMapCoordinate: VocalWasmExports['vocalEditMapCoordinate'];
1803
+ vocalEditCaptureSnapshot: VocalWasmExports['vocalEditCaptureSnapshot'];
1804
+ vocalEditSnapshotDestroy: VocalWasmExports['vocalEditSnapshotDestroy'];
1805
+ vocalEditSnapshotOutputLength: VocalWasmExports['vocalEditSnapshotOutputLength'];
1806
+ vocalEditSnapshotRender: VocalWasmExports['vocalEditSnapshotRender'];
1807
+ vocalEditRenderJobBegin: VocalWasmExports['vocalEditRenderJobBegin'];
1808
+ vocalEditRenderJobNext: VocalWasmExports['vocalEditRenderJobNext'];
1809
+ vocalEditRenderJobFinalize: VocalWasmExports['vocalEditRenderJobFinalize'];
1810
+ vocalEditRenderJobAbort: VocalWasmExports['vocalEditRenderJobAbort'];
1811
+ vocalEditRenderJobDestroy: VocalWasmExports['vocalEditRenderJobDestroy'];
1812
+ vocalEditSessionExportState: VocalWasmExports['vocalEditSessionExportState'];
1813
+ vocalEditLastErrorDetail: VocalWasmExports['vocalEditLastErrorDetail'];
1814
+
1745
1815
  audioFromMemory: (bytes: Uint8Array) => WasmAudioFromMemoryResult;
1746
1816
 
1747
1817
  // Quick API (high-level)
@@ -2329,12 +2399,14 @@ export interface SonareModule {
2329
2399
  options: {
2330
2400
  fadeMs?: number;
2331
2401
  f0Hz?: Float32Array;
2402
+ voiced?: Float32Array;
2332
2403
  frameRate?: number;
2333
2404
  vibratoCutoffHz?: number;
2334
2405
  },
2335
2406
  ) => Float32Array;
2336
2407
  decomposeNotePitch: (
2337
2408
  f0Hz: Float32Array,
2409
+ voiced: Float32Array | undefined,
2338
2410
  frameRate: number,
2339
2411
  medianHz: number,
2340
2412
  vibratoCutoffHz: number,
@@ -2493,11 +2565,27 @@ export interface SonareModule {
2493
2565
  sampleRate: number,
2494
2566
  params: Record<string, number | boolean>,
2495
2567
  ) => string;
2568
+ masteringPairProcessStereo: (
2569
+ processorName: string,
2570
+ sourceLeft: Float32Array,
2571
+ sourceRight: Float32Array,
2572
+ referenceLeft: Float32Array,
2573
+ referenceRight: Float32Array,
2574
+ sampleRate: number,
2575
+ params: Record<string, number | boolean>,
2576
+ ) => WasmMasteringStereoResult;
2496
2577
  masteringAbMatchLoudness: (
2497
2578
  source: Float32Array,
2498
2579
  reference: Float32Array,
2499
2580
  sampleRate: number,
2500
2581
  ) => WasmLoudnessMatchResult;
2582
+ masteringAbMatchLoudnessStereo: (
2583
+ sourceLeft: Float32Array,
2584
+ sourceRight: Float32Array,
2585
+ referenceLeft: Float32Array,
2586
+ referenceRight: Float32Array,
2587
+ sampleRate: number,
2588
+ ) => WasmLoudnessMatchStereoResult;
2501
2589
  masteringStereoAnalyze: (
2502
2590
  analysisName: string,
2503
2591
  left: Float32Array,
@@ -3521,6 +3609,7 @@ export interface WasmPolyphonicAnalysis {
3521
3609
 
3522
3610
  export interface WasmStreamingMasteringChain {
3523
3611
  prepare: (sampleRate: number, maxBlockSize: number, numChannels: number) => void;
3612
+ setParameter: (key: string, value: number) => void;
3524
3613
  processMono: (samples: Float32Array) => Float32Array;
3525
3614
  processStereo: (
3526
3615
  left: Float32Array,
@@ -171,6 +171,14 @@ export class StreamingMasteringChain {
171
171
  this.chain.reset();
172
172
  }
173
173
 
174
+ /**
175
+ * Set one realtime-safe full-chain parameter at a serialized block boundary.
176
+ * Structural, disabled-stage and unknown parameters are rejected.
177
+ */
178
+ setParameter(key: string, value: number): void {
179
+ this.chain.setParameter(key, value);
180
+ }
181
+
174
182
  /** Total reported latency in samples across all active processors. */
175
183
  latencySamples(): number {
176
184
  return this.chain.latencySamples();