@libraz/libsonare 1.5.5 → 1.6.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 (75) hide show
  1. package/README.md +109 -20
  2. package/dist/analysis.d.ts +5730 -0
  3. package/dist/analysis.js +2464 -0
  4. package/dist/analysis.js.map +1 -0
  5. package/dist/index.d.ts +759 -35
  6. package/dist/index.js +904 -209
  7. package/dist/index.js.map +1 -1
  8. package/dist/schemas/realtime-voice-changer-preset-pack.schema.json +27 -0
  9. package/dist/schemas/realtime-voice-changer-preset.schema.json +140 -0
  10. package/dist/sonare-analysis.js +2 -0
  11. package/dist/sonare-analysis.wasm +0 -0
  12. package/dist/sonare.js +1 -1
  13. package/dist/sonare.wasm +0 -0
  14. package/dist/worker.d.ts +65 -0
  15. package/dist/worker.js +707 -0
  16. package/dist/worker.js.map +1 -0
  17. package/dist/worklet.d.ts +574 -86
  18. package/dist/worklet.js +1634 -235
  19. package/dist/worklet.js.map +1 -1
  20. package/package.json +23 -11
  21. package/src/_chain_config.ts +5 -3
  22. package/src/analysis.ts +137 -0
  23. package/src/analysis_helpers.ts +6 -0
  24. package/src/clip_page_streamer.ts +62 -8
  25. package/src/codes.ts +51 -64
  26. package/src/effects_mastering.ts +1 -0
  27. package/src/errors.ts +1 -0
  28. package/src/feature_core.ts +140 -2
  29. package/src/feature_music.ts +17 -2
  30. package/src/feature_pitch.ts +70 -1
  31. package/src/feature_spectral.ts +231 -5
  32. package/src/feature_spectrogram.ts +159 -0
  33. package/src/features.ts +16 -1
  34. package/src/index.ts +101 -7
  35. package/src/mastering_chain.ts +20 -8
  36. package/src/mastering_core.ts +5 -0
  37. package/src/mastering_dynamics.ts +7 -1
  38. package/src/metering.ts +6 -1
  39. package/src/opfs_clip_pages.ts +26 -1
  40. package/src/project.ts +7 -0
  41. package/src/project_class.ts +62 -8
  42. package/src/project_internal.ts +24 -29
  43. package/src/project_types.ts +69 -10
  44. package/src/public_types.ts +68 -0
  45. package/src/public_types_mastering.ts +22 -0
  46. package/src/public_types_mixing.ts +11 -2
  47. package/src/public_types_music.ts +9 -0
  48. package/src/public_types_spectral.ts +33 -0
  49. package/src/quick_analysis.ts +25 -7
  50. package/src/realtime_engine.ts +153 -3
  51. package/src/realtime_voice_changer.ts +51 -77
  52. package/src/sonare-analysis.js.d.ts +8 -0
  53. package/src/sonare.js.d.ts +276 -6
  54. package/src/streaming_processors.ts +15 -0
  55. package/src/web_midi.ts +36 -4
  56. package/src/worker.ts +196 -0
  57. package/src/worker_client.ts +352 -0
  58. package/src/worker_protocol.ts +59 -0
  59. package/src/worklet/engine-automation.ts +2 -1
  60. package/src/worklet/engine-capture-facade.ts +13 -4
  61. package/src/worklet/engine-clips.ts +12 -3
  62. package/src/worklet/engine-node.ts +212 -4
  63. package/src/worklet/engine-offline.ts +7 -2
  64. package/src/worklet/engine-parameter-facade.ts +26 -5
  65. package/src/worklet/engine-processor.ts +383 -42
  66. package/src/worklet/engine-register.ts +8 -0
  67. package/src/worklet/engine-strips.ts +17 -1
  68. package/src/worklet/engine-sync.ts +2 -6
  69. package/src/worklet/engine-tempo-facade.ts +8 -6
  70. package/src/worklet/engine.ts +380 -13
  71. package/src/worklet/guards.ts +22 -1
  72. package/src/worklet/messages.ts +125 -7
  73. package/src/worklet/protocol.ts +301 -17
  74. package/src/worklet/voice-changer-processor.ts +12 -15
  75. package/src/worklet.ts +20 -1
package/dist/worklet.d.ts CHANGED
@@ -1,71 +1,4 @@
1
- import { WasmEngineTempoSegment, WasmEngineClip, WasmEngineMarker, WasmEngineMetronomeConfig, WasmEngineAutomationPoint, WasmEngineTimeSignatureSegment, WasmEngineCaptureStatus, WasmExternalMidiEvent, WasmEngineTransportState, WasmEngineParameterInfo, WasmEngineGraphSpec, WasmClipPageRequest, WasmEngineProcessWithMonitorResult, WasmEngineBounceOptions, WasmEngineBounceResult, WasmEngineFreezeOptions, WasmEngineFreezeResult, WasmEngineTelemetry, WasmEngineMeterTelemetry, WasmEngineMeterTelemetryWide, WasmEngineScopeTelemetry, SonareModule } from './sonare.js';
2
-
3
- type PanMode = 'balance' | 'stereoPan' | 'stereo-pan' | 'dualPan' | 'dual-pan' | number;
4
- /**
5
- * Interpolation curve for scheduled automation events
6
- * (see {@link Mixer.scheduleInsertAutomation}).
7
- */
8
- type AutomationCurve = 'linear' | 'exponential' | 'hold' | 's-curve';
9
- /**
10
- * Pan law applied when computing left/right gains from a pan position
11
- * (see {@link Mixer.setPanLaw}). Maps to the underlying integer code.
12
- */
13
- type PanLaw = 'const3dB' | 'const4.5dB' | 'const6dB' | 'linear0dB';
14
- /** Pre/post-fader send timing (see {@link Mixer.addSend}). */
15
- type SendTiming = 'preFader' | 'postFader';
16
-
17
- /**
18
- * Equalizer band type (string union mirroring `sonare::mastering::eq::EqBandType`).
19
- */
20
- type EqBandType = 'Peak' | 'LowShelf' | 'HighShelf' | 'LowPass' | 'HighPass' | 'BandPass' | 'Notch' | 'TiltShelf' | 'FlatTilt';
21
- /** Biquad coefficient design mode. */
22
- type EqCoeffMode = 'Rbj' | 'Vicanek';
23
- /** Stereo placement for an EQ band. */
24
- type EqStereoPlacement = 'Stereo' | 'Left' | 'Right' | 'Mid' | 'Side';
25
- /** Per-band phase behaviour. */
26
- type EqBandPhase = 'Inherit' | 'ZeroLatency' | 'NaturalPhase' | 'LinearPhase';
27
- /**
28
- * Equalizer band configuration accepted by {@link StreamingEqualizer.setBand}.
29
- *
30
- * All fields are optional; omitted values fall back to the C++ band defaults
31
- * (Peak, 1000 Hz, 0 dB gain, Butterworth Q, disabled).
32
- */
33
- interface EqBand {
34
- type?: EqBandType;
35
- frequencyHz?: number;
36
- gainDb?: number;
37
- q?: number;
38
- enabled?: boolean;
39
- coeffMode?: EqCoeffMode;
40
- slopeDbOct?: number;
41
- placement?: EqStereoPlacement;
42
- phase?: EqBandPhase;
43
- soloed?: boolean;
44
- bypassed?: boolean;
45
- proportionalQ?: boolean;
46
- proportionalQStrength?: number;
47
- dynamic?: boolean;
48
- thresholdDb?: number;
49
- autoThreshold?: boolean;
50
- ratio?: number;
51
- rangeDb?: number;
52
- attackMs?: number;
53
- releaseMs?: number;
54
- lookaheadMs?: number;
55
- externalSidechain?: boolean;
56
- sidechainFreqHz?: number;
57
- sidechainQ?: number;
58
- }
59
- type VoicePresetId = 'neutral-monitor' | 'bright-idol' | 'soft-whisper' | 'deep-narrator' | 'robot-mascot' | 'dark-villain';
60
- interface RealtimeVoiceChangerPreset {
61
- schemaVersion: 1;
62
- id?: string;
63
- name?: string;
64
- description?: string;
65
- macros?: Record<string, number>;
66
- dsp?: Record<string, unknown>;
67
- }
68
- type RealtimeVoiceChangerConfigInput = VoicePresetId | RealtimeVoiceChangerPreset;
1
+ import { WasmExternalMidiEvent, WasmEngineTransportState, WasmEngineTempoSegment, WasmEngineTimeSignatureSegment, WasmEngineParameterInfo, WasmEngineAutomationPoint, WasmEngineMarker, WasmEngineMetronomeConfig, WasmEngineGraphSpec, WasmEngineClip, WasmClipPageRequest, WasmEngineCaptureStatus, WasmEngineProcessWithMonitorResult, WasmEngineBounceOptions, WasmEngineBounceResult, WasmEngineFreezeOptions, WasmEngineFreezeResult, WasmEngineTelemetry, WasmEngineMeterTelemetry, WasmEngineMeterTelemetryWide, WasmEngineScopeTelemetry, SonareModule } from './sonare.js';
69
2
 
70
3
  declare const SYNTH_ENGINE_MODES: readonly ["default", "subtractive", "fm", "karplus-strong", "modal", "additive", "percussion", "piano", "pipe-organ", "bowed-string", "reed", "brass", "flute", "plucked-string", "vocal", "free-reed"];
71
4
  declare const SYNTH_OSC_WAVEFORMS: readonly ["default", "sine", "saw", "square", "triangle", "noise"];
@@ -182,6 +115,120 @@ interface ProjectMidiCcBinding {
182
115
  maxValue: number;
183
116
  }
184
117
 
118
+ type PanMode = 'balance' | 'pan' | 'stereoPan' | 'stereo-pan' | 'dualPan' | 'dual-pan' | number;
119
+ /**
120
+ * Interpolation curve for scheduled automation events
121
+ * (see {@link Mixer.scheduleInsertAutomation}).
122
+ */
123
+ type AutomationCurve = 'linear' | 'exponential' | 'hold' | 's-curve';
124
+ /**
125
+ * Pan law applied when computing left/right gains from a pan position
126
+ * (see {@link Mixer.setPanLaw}). On mono strips it changes the centre gain;
127
+ * on stereo Balance strips it changes only the far-channel taper, while centre
128
+ * remains unity. Maps to the underlying integer code.
129
+ */
130
+ type PanLaw = 'const3dB' | 'const4.5dB' | 'const6dB' | 'linear0dB';
131
+ /** Pre/post-fader send timing (see {@link Mixer.addSend}). */
132
+ type SendTiming = 'preFader' | 'postFader';
133
+
134
+ /**
135
+ * Equalizer band type (string union mirroring `sonare::mastering::eq::EqBandType`).
136
+ */
137
+ type EqBandType = 'Peak' | 'LowShelf' | 'HighShelf' | 'LowPass' | 'HighPass' | 'BandPass' | 'Notch' | 'TiltShelf' | 'FlatTilt';
138
+ /** Biquad coefficient design mode. */
139
+ type EqCoeffMode = 'Rbj' | 'Vicanek';
140
+ /** Stereo placement for an EQ band. */
141
+ type EqStereoPlacement = 'Stereo' | 'Left' | 'Right' | 'Mid' | 'Side';
142
+ /** Per-band phase behaviour. */
143
+ type EqBandPhase = 'Inherit' | 'ZeroLatency' | 'NaturalPhase' | 'LinearPhase';
144
+ /**
145
+ * Equalizer band configuration accepted by {@link StreamingEqualizer.setBand}.
146
+ *
147
+ * All fields are optional; omitted values fall back to the C++ band defaults
148
+ * (Peak, 1000 Hz, 0 dB gain, Butterworth Q, disabled).
149
+ */
150
+ interface EqBand {
151
+ type?: EqBandType;
152
+ frequencyHz?: number;
153
+ gainDb?: number;
154
+ q?: number;
155
+ enabled?: boolean;
156
+ coeffMode?: EqCoeffMode;
157
+ slopeDbOct?: number;
158
+ placement?: EqStereoPlacement;
159
+ phase?: EqBandPhase;
160
+ soloed?: boolean;
161
+ bypassed?: boolean;
162
+ proportionalQ?: boolean;
163
+ proportionalQStrength?: number;
164
+ dynamic?: boolean;
165
+ thresholdDb?: number;
166
+ autoThreshold?: boolean;
167
+ ratio?: number;
168
+ rangeDb?: number;
169
+ attackMs?: number;
170
+ releaseMs?: number;
171
+ lookaheadMs?: number;
172
+ externalSidechain?: boolean;
173
+ sidechainFreqHz?: number;
174
+ sidechainQ?: number;
175
+ }
176
+ type VoicePresetId = 'neutral-monitor' | 'bright-idol' | 'soft-whisper' | 'deep-narrator' | 'robot-mascot' | 'dark-villain';
177
+ interface RealtimeVoiceChangerPreset {
178
+ schemaVersion: 1;
179
+ id?: string;
180
+ name?: string;
181
+ description?: string;
182
+ macros?: Record<string, number>;
183
+ dsp?: Record<string, unknown>;
184
+ }
185
+ type RealtimeVoiceChangerConfigInput = VoicePresetId | RealtimeVoiceChangerPreset;
186
+ /**
187
+ * Flat (POD) realtime voice-changer configuration. Keys are camelCase to match
188
+ * the Node addon getter, so a preset config reads identically across both JS
189
+ * surfaces (the underlying C ABI / Python POD uses the snake_case equivalents).
190
+ */
191
+ interface RealtimeVoiceChangerPodConfig {
192
+ inputGainDb: number;
193
+ outputGainDb: number;
194
+ wetMix: number;
195
+ retuneSemitones: number;
196
+ retuneMix: number;
197
+ retuneGrainSize: number;
198
+ formantFactor: number;
199
+ formantAmount: number;
200
+ formantBody: number;
201
+ formantBrightness: number;
202
+ formantNasal: number;
203
+ eqHighpassHz: number;
204
+ eqBodyDb: number;
205
+ eqPresenceDb: number;
206
+ eqAirDb: number;
207
+ gateThresholdDb: number;
208
+ gateAttackMs: number;
209
+ gateReleaseMs: number;
210
+ gateRangeDb: number;
211
+ compressorThresholdDb: number;
212
+ compressorRatio: number;
213
+ compressorAttackMs: number;
214
+ compressorReleaseMs: number;
215
+ compressorMakeupGainDb: number;
216
+ deesserFrequencyHz: number;
217
+ deesserThresholdDb: number;
218
+ deesserRatio: number;
219
+ deesserRangeDb: number;
220
+ reverbMix: number;
221
+ reverbTimeMs: number;
222
+ reverbDamping: number;
223
+ reverbSeed: number;
224
+ limiterCeilingDb: number;
225
+ limiterReleaseMs: number;
226
+ /** Non-zero enables the 4x-oversampled inter-sample-peak limiter (default enabled). */
227
+ limiterEnableIspLimiter: boolean;
228
+ /** True-peak ceiling in dBTP applied by the ISP limiter (default -1.0). */
229
+ limiterIspCeilingDbtp: number;
230
+ }
231
+
185
232
  type EngineClip = WasmEngineClip;
186
233
  type ClipPageRequest = WasmClipPageRequest;
187
234
  type EngineParameterInfo = WasmEngineParameterInfo;
@@ -190,6 +237,7 @@ type EngineMarker = WasmEngineMarker;
190
237
  type EngineMetronomeConfig = WasmEngineMetronomeConfig;
191
238
  type EngineGraphSpec = WasmEngineGraphSpec;
192
239
  type EngineCaptureStatus = WasmEngineCaptureStatus;
240
+ type EngineCaptureSource = EngineCaptureStatus['source'] | number;
193
241
  type EngineBounceOptions = WasmEngineBounceOptions;
194
242
  type EngineBounceResult = WasmEngineBounceResult;
195
243
  type EngineFreezeOptions = WasmEngineFreezeOptions;
@@ -269,8 +317,8 @@ interface MidiCcBindOptions {
269
317
  }
270
318
  declare class RealtimeEngine {
271
319
  private native;
272
- constructor(sampleRate?: number, maxBlockSize?: number, commandCapacity?: number, telemetryCapacity?: number);
273
- prepare(sampleRate: number, maxBlockSize: number, commandCapacity?: number, telemetryCapacity?: number): void;
320
+ constructor(sampleRate?: number, maxBlockSize?: number, commandCapacity?: number, telemetryCapacity?: number, maxChannels?: number);
321
+ prepare(sampleRate: number, maxBlockSize: number, commandCapacity?: number, telemetryCapacity?: number, maxChannels?: number): void;
274
322
  /** Queue a sample-accurate parameter change (engine kSetParam). */
275
323
  setParameter(paramId: number, value: number, renderFrame?: number): void;
276
324
  /** Queue a smoothed parameter change (engine kSetParamSmoothed). */
@@ -316,6 +364,7 @@ declare class RealtimeEngine {
316
364
  destinationId?: number;
317
365
  gain?: number;
318
366
  polyphony?: number;
367
+ preferModelForModeledFamilies?: boolean;
319
368
  }, destinationId?: number): void;
320
369
  clearMidiInstrument(destinationId?: number): void;
321
370
  midiInstrumentCount(): number;
@@ -349,6 +398,7 @@ declare class RealtimeEngine {
349
398
  setExternalMidiClockEnabled(enabled: boolean): void;
350
399
  /** Count of external-MIDI events dropped because the output queue was full. */
351
400
  externalMidiDroppedCount(): number;
401
+ externalMidiPendingCount(): number;
352
402
  /**
353
403
  * Drain queued external-MIDI events, already lowered to MIDI 1.0 byte
354
404
  * messages ready to write to a Web MIDI output port. Call once per audio
@@ -357,6 +407,13 @@ declare class RealtimeEngine {
357
407
  * queued for the next call (lossless); call again to drain the rest.
358
408
  */
359
409
  drainExternalMidi(maxRecords?: number): WasmExternalMidiEvent[];
410
+ /** Scalar, allocation-free external-MIDI drain for AudioWorklet SAB output. */
411
+ popExternalMidiToScratch(): boolean;
412
+ externalMidiScratchDestinationId(): number;
413
+ externalMidiScratchRenderFrame(): number;
414
+ externalMidiScratchByteWord(): number;
415
+ externalMidiScratchByteCount(): number;
416
+ consumeExternalMidiScratch(): void;
360
417
  pushMidiInputNoteOn(group: number, channel: number, note: number, velocity: number, portTimeSamples?: number): void;
361
418
  pushMidiInputNoteOff(group: number, channel: number, note: number, velocity?: number, portTimeSamples?: number): void;
362
419
  pushMidiInputCc(group: number, channel: number, controller: number, value: number, portTimeSamples?: number): void;
@@ -369,6 +426,8 @@ declare class RealtimeEngine {
369
426
  * immediate. Mirrors the Node/Python/C-ABI `pushMidiCc`.
370
427
  */
371
428
  pushMidiCc(destinationId: number, group: number, channel: number, controller: number, value: number, renderFrame?: number): void;
429
+ /** Queue one immediate MIDI 1.0 channel-voice UMP word for a destination. */
430
+ pushMidiUmp(destinationId: number, word0: number, renderFrame?: number): void;
372
431
  /**
373
432
  * Queue an immediate (live) MIDI SysEx frame to a MIDI destination. `data` is
374
433
  * the full message including the leading 0xF0 and trailing 0xF7 (1..512
@@ -398,6 +457,8 @@ declare class RealtimeEngine {
398
457
  * settled values instead of ramping in from defaults.
399
458
  */
400
459
  settleParameters(): void;
460
+ /** Drains queued commands on an offline/control-only engine immediately. */
461
+ flushControlCommands(): void;
401
462
  seekPpq(ppq: number, renderFrame?: number): void;
402
463
  /** Set a finite tempo in the range (0, 100000] BPM. */
403
464
  setTempo(bpm: number): void;
@@ -490,16 +551,29 @@ declare class RealtimeEngine {
490
551
  clearClipPage(providerId: number, pageIndex: number): void;
491
552
  destroyClipPageProvider(providerId: number): void;
492
553
  popClipPageRequest(): ClipPageRequest | null;
554
+ /**
555
+ * Moves one native request into the binding's persistent scalar scratch.
556
+ * This avoids creating an embind JS object in AudioWorklet process().
557
+ */
558
+ popClipPageRequestToScratch(): boolean;
559
+ clipPageRequestScratchClipId(): number;
560
+ clipPageRequestScratchSample(): number;
561
+ /** Cumulative page misses dropped because the native bounded request queue was full. */
562
+ clipPageRequestOverflowCount(): number;
493
563
  setCaptureBuffer(numChannels: number, capacityFrames: number): void;
494
564
  armCapture(armed?: boolean): void;
495
565
  setCapturePunch(startSample: number, endSample: number, enabled?: boolean): void;
496
- setCaptureSource(source: EngineCaptureStatus['source']): void;
566
+ setCaptureSource(source: EngineCaptureSource): void;
497
567
  /** Positive values delay capture relative to the punch window. */
498
568
  setRecordOffsetSamples(offsetSamples: number): void;
499
569
  setInputMonitor(enabled: boolean, gain?: number): void;
500
570
  resetCapture(): void;
501
571
  captureStatus(): EngineCaptureStatus;
502
572
  capturedAudio(): Float32Array[];
573
+ /**
574
+ * Renders in place, adding engine output to `channels`. Zero each plane first
575
+ * when it contains no upstream input.
576
+ */
503
577
  process(channels: Float32Array[]): Float32Array[];
504
578
  /**
505
579
  * Allocates persistent per-channel WASM-heap scratch for the zero-copy
@@ -516,6 +590,7 @@ declare class RealtimeEngine {
516
590
  getChannelBuffer(channel: number, numFrames: number): Float32Array;
517
591
  /**
518
592
  * Runs the engine in place over the prepared per-channel scratch buffers.
593
+ * Zero each active span first when it contains no upstream input.
519
594
  * Allocation-free: safe to call on the AudioWorklet render thread after
520
595
  * `prepareChannels`.
521
596
  */
@@ -525,6 +600,18 @@ declare class RealtimeEngine {
525
600
  bounceOffline(options: EngineBounceOptions): EngineBounceResult;
526
601
  freezeOffline(options: EngineFreezeOptions): EngineFreezeResult;
527
602
  drainTelemetry(maxRecords?: number): EngineTelemetry[];
603
+ popTelemetryToScratch(): boolean;
604
+ telemetryScratchType(): number;
605
+ telemetryScratchError(): number;
606
+ telemetryScratchRenderFrame(): number;
607
+ telemetryScratchTimelineSample(): number;
608
+ telemetryScratchAudibleTimelineSample(): number;
609
+ telemetryScratchGraphLatencySamplesQ8(): number;
610
+ telemetryScratchValue(): number;
611
+ popMeterTelemetryToScratch(): boolean;
612
+ meterScratchTargetId(): number;
613
+ meterScratchRenderFrame(): number;
614
+ meterScratchValue(field: number): number;
528
615
  drainMeterTelemetry(maxRecords?: number): EngineMeterTelemetry[];
529
616
  /**
530
617
  * Drains pending meter telemetry as per-plane (wide) records for a surround
@@ -544,6 +631,14 @@ declare class RealtimeEngine {
544
631
  configureScopeTelemetry(intervalFrames: number, bandCount: number): number;
545
632
  /** Drains pending spectrum + vectorscope snapshots (per mix target). */
546
633
  drainScopeTelemetry(maxRecords?: number): EngineScopeTelemetry[];
634
+ popScopeTelemetryToScratch(): boolean;
635
+ scopeScratchTargetId(): number;
636
+ scopeScratchRenderFrame(): number;
637
+ scopeScratchBandCount(): number;
638
+ scopeScratchBand(index: number): number;
639
+ scopeScratchPointCount(): number;
640
+ scopeScratchPointLeft(index: number): number;
641
+ scopeScratchPointRight(index: number): number;
547
642
  destroy(): void;
548
643
  }
549
644
  declare class ClipPageProvider {
@@ -556,6 +651,161 @@ declare class ClipPageProvider {
556
651
  destroy(): void;
557
652
  }
558
653
 
654
+ interface OpfsClipPageProviderOptions {
655
+ path: string;
656
+ numChannels: number;
657
+ numSamples: number;
658
+ pageFrames: number;
659
+ dataOffsetBytes?: number;
660
+ worker?: Worker;
661
+ terminateWorkerOnClose?: boolean;
662
+ /** Internal bridge hook used to mirror a supplied page into an AudioWorklet. */
663
+ onPageSupplied?: (pageIndex: number, channels: Float32Array[]) => void;
664
+ /** Internal bridge hook used to mirror an eviction into an AudioWorklet. */
665
+ onPageCleared?: (pageIndex: number) => void;
666
+ /** Internal bridge hook called after the local provider is destroyed. */
667
+ onClose?: () => void;
668
+ }
669
+ interface OpfsClipPageProviderBinding {
670
+ provider: ClipPageProvider;
671
+ supplyPage(pageIndex: number): Promise<boolean>;
672
+ supplyRequest(request: ClipPageRequest): Promise<boolean>;
673
+ /** Evict one resident page from every configured consumer. */
674
+ clearPage?(pageIndex: number): void;
675
+ close(): void;
676
+ }
677
+
678
+ /**
679
+ * Minimal engine surface the streamer drives. {@link RealtimeEngine} satisfies
680
+ * this structurally; tests can supply a lightweight stand-in.
681
+ */
682
+ interface ClipPageStreamerEngine {
683
+ /** Drain one pending audio-thread page-miss request, or `null` when empty. */
684
+ popClipPageRequest(): ClipPageStreamerRequest | null;
685
+ }
686
+ /**
687
+ * A page miss reported by either a direct engine (`sample`) or the worklet
688
+ * bridge (`pageIndex`). Exactly one position form is required.
689
+ */
690
+ interface ClipPageStreamerRequest {
691
+ clipId: number;
692
+ sample?: number;
693
+ pageIndex?: number;
694
+ }
695
+ /** A paged clip the streamer keeps fed from its backing store. */
696
+ interface ClipPageStreamSource {
697
+ /** Clip schedule id passed to `setClips` (matches {@link ClipPageRequest.clipId}). */
698
+ clipId: number;
699
+ /** OPFS-backed page provider binding for this clip. */
700
+ binding: OpfsClipPageProviderBinding;
701
+ /** Page size in frames (must equal the provider's `pageFrames`). */
702
+ pageFrames: number;
703
+ /** Total sample count of the clip source. */
704
+ numSamples: number;
705
+ }
706
+ interface ClipPageStreamerOptions {
707
+ /**
708
+ * Pages to prefetch ahead of the page a miss was reported for. Larger values
709
+ * hide fetch latency at the cost of more resident memory. Default 2.
710
+ */
711
+ readAheadPages?: number;
712
+ /**
713
+ * Pages to retain behind the playback frontier before eviction, so a small
714
+ * backward seek does not immediately miss. Default 1.
715
+ */
716
+ retainBehindPages?: number;
717
+ /**
718
+ * Upper bound on requests drained per {@link ClipPageStreamer.pump} call, so a
719
+ * burst of misses cannot spin unbounded. Default 256.
720
+ */
721
+ maxRequestsPerPump?: number;
722
+ }
723
+ /**
724
+ * Keeps OPFS-paged clips fed within a bounded sliding window around the live
725
+ * playback position, so a multitrack arrangement never holds its full PCM in
726
+ * WASM memory.
727
+ *
728
+ * The audio thread reports a page miss whenever the {@link ClipPlayer} reads a
729
+ * sample whose page is not resident. {@link pump} drains those requests, fetches
730
+ * the missing page plus a read-ahead window from each clip's backing store, and
731
+ * evicts pages that fall outside the window via the provider's `clear`. The
732
+ * resident set per clip is therefore bounded to
733
+ * `retainBehindPages + readAheadPages + 1` pages regardless of clip length.
734
+ *
735
+ * Call {@link pump} on a cadence that keeps up with playback — typically once
736
+ * per animation frame or per worklet control tick on the main/control thread
737
+ * (never the audio thread; fetches are asynchronous).
738
+ */
739
+ declare class ClipPageStreamer {
740
+ private readonly engine;
741
+ private readonly readAheadPages;
742
+ private readonly retainBehindPages;
743
+ private readonly maxRequestsPerPump;
744
+ private readonly sources;
745
+ private closed;
746
+ constructor(engine: ClipPageStreamerEngine, options?: ClipPageStreamerOptions);
747
+ /**
748
+ * Register a paged clip. Pages already supplied to the provider before
749
+ * registration (for example a primed first page) should be passed in
750
+ * `initialResidentPages` so they participate in eviction.
751
+ */
752
+ addSource(source: ClipPageStreamSource, initialResidentPages?: Iterable<number>): void;
753
+ /** Stop tracking a clip. Does not close its binding (the caller owns that). */
754
+ removeSource(clipId: number): void;
755
+ /**
756
+ * Explicitly start a new playback generation after a host seek/loop. Resident
757
+ * pages are evicted and any older in-flight fetch is cleared when it settles.
758
+ * The next miss establishes the new bounded window.
759
+ */
760
+ resetSource(clipId: number): void;
761
+ /**
762
+ * Drain pending page-miss requests, fetch the missing pages plus their
763
+ * read-ahead window, and evict out-of-window pages. Resolves once this round's
764
+ * fetches settle. Concurrent fetches are serialized inside each binding.
765
+ */
766
+ pump(): Promise<void>;
767
+ /** Close every registered clip's binding and stop tracking. */
768
+ close(): void;
769
+ private serviceFrontier;
770
+ private resetState;
771
+ private clearPage;
772
+ }
773
+ interface OpfsClipStreamOptions extends OpfsClipPageProviderOptions {
774
+ /** Clip schedule id used in `setClips` (matches the page-miss request clipId). */
775
+ clipId: number;
776
+ /**
777
+ * Leading pages fetched synchronously before returning, so playback can start
778
+ * without an immediate miss. Default 1.
779
+ */
780
+ primePages?: number;
781
+ }
782
+ interface OpfsClipStream {
783
+ binding: OpfsClipPageProviderBinding;
784
+ /** Pass as `addClip`'s buffer argument to schedule the streaming clip. */
785
+ provider: ClipPageProvider;
786
+ }
787
+ /** Structural seam implemented by the AudioWorklet-backed `SonareEngine`. */
788
+ interface WorkletOpfsClipStreamHost {
789
+ attachOpfsClipStream(options: OpfsClipStreamOptions): Promise<OpfsClipStream>;
790
+ }
791
+ /**
792
+ * One-call wiring of an OPFS-backed streaming clip: creates the page provider,
793
+ * primes the leading pages, and registers it with `streamer` so later misses are
794
+ * serviced within the bounded window. Returns the binding (for `close`) and the
795
+ * provider to schedule via `addClip(trackId, provider, startPpq, { id: clipId })`.
796
+ *
797
+ * @param streamer Shared streamer pumped on the control thread.
798
+ * @param engine Engine the provider is created on (the same one `streamer` drives).
799
+ * @param options Provider options plus `clipId` and optional `primePages`.
800
+ */
801
+ declare function attachOpfsClipStream(streamer: ClipPageStreamer, engine: RealtimeEngine, options: OpfsClipStreamOptions): Promise<OpfsClipStream>;
802
+ /**
803
+ * Worklet overload: delegates to `SonareEngine.attachOpfsClipStream`, which
804
+ * creates the remote provider and drives this same sliding-window policy from
805
+ * worklet page-miss messages.
806
+ */
807
+ declare function attachOpfsClipStream(engine: WorkletOpfsClipStreamHost, options: OpfsClipStreamOptions): Promise<OpfsClipStream>;
808
+
559
809
  /**
560
810
  * sonare - Audio Analysis Library
561
811
  *
@@ -630,6 +880,10 @@ declare function decodeFrame(lo: number, hi: number): number;
630
880
  declare const SONARE_ENGINE_RING_HEADER_INTS = 5;
631
881
  declare const SONARE_ENGINE_COMMAND_RECORD_BYTES = 32;
632
882
  declare const SONARE_ENGINE_TELEMETRY_RECORD_BYTES = 48;
883
+ declare const SONARE_CLIP_PAGE_REQUEST_RING_HEADER_INTS = 5;
884
+ declare const SONARE_CLIP_PAGE_REQUEST_RING_RECORD_UINT32S = 2;
885
+ declare const SONARE_EXTERNAL_MIDI_RING_HEADER_INTS = 5;
886
+ declare const SONARE_EXTERNAL_MIDI_RING_RECORD_UINT32S = 4;
633
887
  declare enum SonareEngineCommandType {
634
888
  SetParam = 0,
635
889
  SetParamSmoothed = 1,
@@ -673,7 +927,8 @@ declare enum SonareEngineTelemetryError {
673
927
  ClipPageUnderrun = 15,
674
928
  InsertAutomationOverflow = 16,
675
929
  MidiClockOverflow = 17,
676
- MetronomeOverflow = 18
930
+ MetronomeOverflow = 18,
931
+ InvalidCommand = 19
677
932
  }
678
933
  interface SonareMeterRingBuffer {
679
934
  sharedBuffer: SharedArrayBuffer;
@@ -724,6 +979,27 @@ interface SonareScopeRingReadResult {
724
979
  nextReadIndex: number;
725
980
  scopes: SonareWorkletScopeSnapshot[];
726
981
  }
982
+ interface SonareExternalMidiRingEvent {
983
+ destinationId: number;
984
+ renderFrame: number;
985
+ byteWord: number;
986
+ byteCount: number;
987
+ }
988
+ interface SonareExternalMidiRingBuffer {
989
+ sharedBuffer: SharedArrayBuffer;
990
+ header: Int32Array;
991
+ records: Uint32Array;
992
+ capacity: number;
993
+ }
994
+ interface SharedExternalMidiRingWriter {
995
+ header: Int32Array;
996
+ records: Uint32Array;
997
+ capacity: number;
998
+ }
999
+ interface SonareExternalMidiRingReadResult {
1000
+ events: SonareExternalMidiRingEvent[];
1001
+ dropped: number;
1002
+ }
727
1003
  interface SonareEngineCommandRecord {
728
1004
  type: SonareEngineCommandType | number;
729
1005
  targetId?: number;
@@ -756,6 +1032,26 @@ interface SonareEngineTelemetryRingReadResult {
756
1032
  nextReadIndex: number;
757
1033
  telemetry: SonareEngineTelemetryRecord[];
758
1034
  }
1035
+ interface SonareClipPageRequest {
1036
+ clipId: number;
1037
+ pageIndex: number;
1038
+ }
1039
+ interface SonareClipPageRequestRingBuffer {
1040
+ sharedBuffer: SharedArrayBuffer;
1041
+ header: Int32Array;
1042
+ records: Uint32Array;
1043
+ capacity: number;
1044
+ }
1045
+ interface SharedClipPageRequestRingWriter {
1046
+ header: Int32Array;
1047
+ records: Uint32Array;
1048
+ capacity: number;
1049
+ }
1050
+ interface SonareClipPageRequestRingReadResult {
1051
+ requests: SonareClipPageRequest[];
1052
+ /** Cumulative uint32 drop count for native and SAB-ring overflows. */
1053
+ dropped: number;
1054
+ }
759
1055
  declare function sonareMeterRingBufferByteLength(capacity: number): number;
760
1056
  declare function createSonareMeterRingBuffer(capacity?: number): SonareMeterRingBuffer;
761
1057
  declare function readSonareMeterRingBuffer(ring: SonareMeterRingBuffer, readIndex?: number): SonareMeterRingReadResult;
@@ -767,6 +1063,22 @@ declare function createSonareScopeRingBuffer(capacity?: number, bands?: number,
767
1063
  declare function readSonareScopeRingBuffer(ring: SonareScopeRingBuffer, readIndex?: number): SonareScopeRingReadResult;
768
1064
  declare function sonareEngineCommandRingBufferByteLength(capacity: number): number;
769
1065
  declare function sonareEngineTelemetryRingBufferByteLength(capacity: number): number;
1066
+ declare function sonareClipPageRequestRingBufferByteLength(capacity: number): number;
1067
+ declare function sonareExternalMidiRingBufferByteLength(capacity: number): number;
1068
+ declare function createSonareExternalMidiRingBuffer(capacity?: number): SonareExternalMidiRingBuffer;
1069
+ /** Write one lowered MIDI-1 event without allocations from the audio worklet. */
1070
+ declare function pushSonareExternalMidiRingBuffer(ring: SharedExternalMidiRingWriter, destinationId: number, renderFrame: number, byteWord: number, byteCount: number): boolean;
1071
+ /** Main-thread drain. It is intentionally the only place MIDI byte arrays are built. */
1072
+ declare function readSonareExternalMidiRingBuffer(ring: SonareExternalMidiRingBuffer): SonareExternalMidiRingReadResult;
1073
+ declare function createSonareClipPageRequestRingBuffer(capacity?: number): SonareClipPageRequestRingBuffer;
1074
+ /**
1075
+ * Writes one request without allocating. Invalid uint32 coordinates and a full
1076
+ * ring are counted as drops so the main thread can surface a bounded-loss
1077
+ * diagnostic without receiving a worklet postMessage.
1078
+ */
1079
+ declare function pushSonareClipPageRequestRingBuffer(ring: SharedClipPageRequestRingWriter, clipId: number, pageIndex: number): boolean;
1080
+ /** Drains the SPSC request ring on the main thread. Object creation is here, never in process(). */
1081
+ declare function readSonareClipPageRequestRingBuffer(ring: SonareClipPageRequestRingBuffer): SonareClipPageRequestRingReadResult;
770
1082
  declare function createSonareEngineCommandRingBuffer(capacity?: number): SonareEngineCommandRingBuffer;
771
1083
  declare function createSonareEngineTelemetryRingBuffer(capacity?: number): SonareEngineTelemetryRingBuffer;
772
1084
  declare function pushSonareEngineCommandRingBuffer(ring: SonareEngineCommandRingBuffer, command: SonareEngineCommandRecord): boolean;
@@ -805,6 +1117,16 @@ interface SonareRealtimeEngineWorkletProcessorOptions {
805
1117
  scopeBands?: number;
806
1118
  scopeSharedBuffer?: SharedArrayBuffer;
807
1119
  scopeRingCapacity?: number;
1120
+ /**
1121
+ * Lock-free SPSC queue for clip-page cache misses. Supplying this is required
1122
+ * for realtime-safe OPFS streaming: it avoids both embind object creation and
1123
+ * postMessage structured cloning from AudioWorklet process().
1124
+ */
1125
+ clipPageRequestSharedBuffer?: SharedArrayBuffer;
1126
+ clipPageRequestRingCapacity?: number;
1127
+ /** Lock-free worklet-to-main-thread MIDI-1 output ring. */
1128
+ externalMidiSharedBuffer?: SharedArrayBuffer;
1129
+ externalMidiRingCapacity?: number;
808
1130
  }
809
1131
  interface SonareRealtimeVoiceChangerWorkletProcessorOptions {
810
1132
  preset?: RealtimeVoiceChangerConfigInput;
@@ -814,7 +1136,8 @@ interface SonareRealtimeVoiceChangerWorkletProcessorOptions {
814
1136
  }
815
1137
  interface SonareRealtimeVoiceChangerSetConfigMessage {
816
1138
  type: 'setConfig';
817
- preset: RealtimeVoiceChangerConfigInput;
1139
+ /** Pre-normalized by the main thread; never JSON parsed in the worklet. */
1140
+ config: RealtimeVoiceChangerPodConfig;
818
1141
  }
819
1142
  interface SonareRealtimeVoiceChangerResetMessage {
820
1143
  type: 'reset';
@@ -829,6 +1152,10 @@ interface SonareRealtimeEngineNodeCapabilities {
829
1152
  sharedArrayBuffer: boolean;
830
1153
  atomics: boolean;
831
1154
  audioWorklet: boolean;
1155
+ /** True only when clip-page misses use the bounded SAB ring. */
1156
+ clipPageRequestsRealtimeSafe: boolean;
1157
+ /** True when external MIDI uses the SAB output ring rather than postMessage. */
1158
+ externalMidiRealtimeSafe: boolean;
832
1159
  engineAbiVersion?: number;
833
1160
  expectedEngineAbiVersion?: number;
834
1161
  abiCompatible?: boolean;
@@ -885,9 +1212,15 @@ interface SonareWorkletExternalMidiMessage {
885
1212
  type: 'externalMidi';
886
1213
  events: SonareWorkletExternalMidiEvent[];
887
1214
  }
888
- type SonareWorkletTransportMessage = SonareWorkletMeterSnapshot | SonareWorkletSpectrumSnapshot | SonareWorkletExternalMidiMessage | SonareEngineTelemetryRecord;
1215
+ /** A control-plane sync message that the worklet rejected without crashing. */
1216
+ interface SonareEngineSyncErrorMessage {
1217
+ type: 'syncError';
1218
+ syncType: SonareEngineSyncMessage['type'];
1219
+ message: string;
1220
+ }
1221
+ type SonareWorkletTransportMessage = SonareWorkletMeterSnapshot | SonareWorkletSpectrumSnapshot | SonareWorkletExternalMidiMessage | SonareEngineClipPageRequestMessage | SonareEngineTelemetryRecord;
889
1222
  interface WorkletTransport {
890
- postMessage?: (message: SonareWorkletTransportMessage | SonareEngineCaptureResponseMessage | SonareEngineTransportResponseMessage, transfer?: Transferable[]) => void;
1223
+ postMessage?: (message: SonareWorkletTransportMessage | SonareEngineCaptureResponseMessage | SonareEngineTransportResponseMessage | SonareEngineSyncErrorMessage, transfer?: Transferable[]) => void;
891
1224
  onMeter?: (meter: SonareWorkletMeterSnapshot) => void;
892
1225
  onSpectrum?: (spectrum: SonareWorkletSpectrumSnapshot) => void;
893
1226
  }
@@ -904,7 +1237,8 @@ interface SonareEngineSyncClipsDeltaMessage {
904
1237
  interface SonareEngineSyncClipPageProviderMessage {
905
1238
  type: 'syncClipPageProvider';
906
1239
  clipId: number;
907
- clip: EngineClip;
1240
+ /** Omitted when an OPFS stream is primed before its clip is scheduled. */
1241
+ clip?: EngineClip;
908
1242
  numChannels: number;
909
1243
  numSamples: number;
910
1244
  pageFrames: number;
@@ -916,10 +1250,41 @@ interface SonareEngineSyncClipPageMessage {
916
1250
  pageIndex: number;
917
1251
  channels: Float32Array[];
918
1252
  }
1253
+ /** Evicts one page after the main-thread sliding window advances. */
1254
+ interface SonareEngineSyncClipPageClearMessage {
1255
+ type: 'syncClipPageClear';
1256
+ clipId: number;
1257
+ pageIndex: number;
1258
+ }
1259
+ /** Releases a provider whose clip was removed or whose stream was closed. */
1260
+ interface SonareEngineSyncClipPageDestroyMessage {
1261
+ type: 'syncClipPageDestroy';
1262
+ clipId: number;
1263
+ }
919
1264
  /** Makes a fully supplied paged clip visible to the audio engine. */
920
1265
  interface SonareEngineSyncClipPageCommitMessage {
921
1266
  type: 'syncClipPageCommit';
922
1267
  clipId: number;
1268
+ /**
1269
+ * Clip schedule to publish with a provider that was primed before its
1270
+ * schedule was known. The original pre-baked push path supplies it on the
1271
+ * provider message instead.
1272
+ */
1273
+ clip?: EngineClip;
1274
+ }
1275
+ /**
1276
+ * A bounded batch of page misses emitted by the AudioWorklet. The main thread
1277
+ * resolves these from OPFS and responds with `syncClipPage`; a missing page is
1278
+ * silent until that response arrives.
1279
+ */
1280
+ interface SonareEngineClipPageRequestMessage {
1281
+ type: 'clipPageRequest';
1282
+ requests: Array<{
1283
+ clipId: number;
1284
+ pageIndex: number;
1285
+ }>;
1286
+ /** Number of misses dropped because a bounded native or SAB request queue was full. */
1287
+ dropped?: number;
923
1288
  }
924
1289
  interface SonareEngineSyncMidiClipsMessage {
925
1290
  type: 'syncMidiClips';
@@ -938,6 +1303,11 @@ interface SonareEngineSyncAutomationMessage {
938
1303
  paramId: number;
939
1304
  points: EngineAutomationPoint[];
940
1305
  }
1306
+ /** Replaces the live engine's registered custom-parameter set. */
1307
+ interface SonareEngineSyncParametersMessage {
1308
+ type: 'syncParameters';
1309
+ parameters: EngineParameterInfo[];
1310
+ }
941
1311
  interface SonareEngineSyncTempoMessage {
942
1312
  type: 'syncTempo';
943
1313
  bpm: number;
@@ -1068,6 +1438,7 @@ interface SonareEngineSyncSf2InstrumentMessage {
1068
1438
  destinationId?: number;
1069
1439
  gain?: number;
1070
1440
  polyphony?: number;
1441
+ preferModelForModeledFamilies?: boolean;
1071
1442
  };
1072
1443
  }
1073
1444
  interface SonareEngineSyncLoadSoundFontMessage {
@@ -1098,6 +1469,12 @@ interface SonareEngineSyncMidiCcMessage {
1098
1469
  value: number;
1099
1470
  renderFrame: number;
1100
1471
  }
1472
+ interface SonareEngineSyncMidiUmpMessage {
1473
+ type: 'syncMidiUmp';
1474
+ destinationId: number;
1475
+ word0: number;
1476
+ renderFrame: number;
1477
+ }
1101
1478
  interface SonareEngineSyncMidiSysexMessage {
1102
1479
  type: 'syncMidiSysex';
1103
1480
  destinationId: number;
@@ -1117,7 +1494,31 @@ interface SonareEngineSyncExternalMidiClockMessage {
1117
1494
  type: 'syncExternalMidiClock';
1118
1495
  enabled: boolean;
1119
1496
  }
1120
- type SonareEngineSyncMessage = SonareEngineSyncClipsMessage | SonareEngineSyncClipsDeltaMessage | SonareEngineSyncClipPageProviderMessage | SonareEngineSyncClipPageMessage | SonareEngineSyncClipPageCommitMessage | SonareEngineSyncMidiClipsMessage | SonareEngineSyncMarkersMessage | SonareEngineSyncMetronomeMessage | SonareEngineSyncAutomationMessage | SonareEngineSyncTempoMessage | SonareEngineSyncMixerMessage | SonareEngineSyncCaptureMessage | SonareEngineSyncTrackStripEqBandMessage | SonareEngineSyncMasterStripEqBandMessage | SonareEngineSyncTrackStripInsertBypassedMessage | SonareEngineSyncMasterStripInsertBypassedMessage | SonareEngineSyncTrackStripInsertParamByNameMessage | SonareEngineSyncMasterStripInsertParamByNameMessage | SonareEngineSyncBusStripInsertParamByNameMessage | SonareEngineSyncTrackStripPanMessage | SonareEngineSyncTrackStripPanLawMessage | SonareEngineSyncTrackStripPanModeMessage | SonareEngineSyncTrackStripDualPanMessage | SonareEngineSyncTrackStripChannelDelaySamplesMessage | SonareEngineSyncBuiltinInstrumentMessage | SonareEngineSyncSynthInstrumentMessage | SonareEngineSyncSf2InstrumentMessage | SonareEngineSyncLoadSoundFontMessage | SonareEngineSyncMidiFxMessage | SonareEngineSyncMidiNoteMessage | SonareEngineSyncMidiCcMessage | SonareEngineSyncMidiSysexMessage | SonareEngineSyncMidiPanicMessage | SonareEngineSyncMidiDestinationExternalMessage | SonareEngineSyncExternalMidiClockMessage;
1497
+ interface SonareEngineSyncMidiInputSourceMessage {
1498
+ type: 'syncMidiInputSource' | 'syncClearMidiInputSource';
1499
+ destinationId?: number;
1500
+ }
1501
+ interface SonareEngineSyncMidiCcBindingMessage {
1502
+ type: 'syncMidiCcBinding';
1503
+ channel: number;
1504
+ controller: number;
1505
+ paramId: number;
1506
+ minValue: number;
1507
+ maxValue: number;
1508
+ }
1509
+ interface SonareEngineSyncMidiInputEventMessage {
1510
+ type: 'syncMidiInputNoteOn' | 'syncMidiInputNoteOff' | 'syncMidiInputCc';
1511
+ group: number;
1512
+ channel: number;
1513
+ data0: number;
1514
+ data1: number;
1515
+ portTimeSamples: number;
1516
+ }
1517
+ /** Releases the realtime engine and all worklet-owned clip buffers. */
1518
+ interface SonareEngineDestroyMessage {
1519
+ type: 'destroy';
1520
+ }
1521
+ type SonareEngineSyncMessage = SonareEngineSyncClipsMessage | SonareEngineSyncClipsDeltaMessage | SonareEngineSyncClipPageProviderMessage | SonareEngineSyncClipPageMessage | SonareEngineSyncClipPageClearMessage | SonareEngineSyncClipPageCommitMessage | SonareEngineSyncClipPageDestroyMessage | SonareEngineSyncMidiClipsMessage | SonareEngineSyncMarkersMessage | SonareEngineSyncMetronomeMessage | SonareEngineSyncAutomationMessage | SonareEngineSyncParametersMessage | SonareEngineSyncTempoMessage | SonareEngineSyncMixerMessage | SonareEngineSyncCaptureMessage | SonareEngineSyncTrackStripEqBandMessage | SonareEngineSyncMasterStripEqBandMessage | SonareEngineSyncTrackStripInsertBypassedMessage | SonareEngineSyncMasterStripInsertBypassedMessage | SonareEngineSyncTrackStripInsertParamByNameMessage | SonareEngineSyncMasterStripInsertParamByNameMessage | SonareEngineSyncBusStripInsertParamByNameMessage | SonareEngineSyncTrackStripPanMessage | SonareEngineSyncTrackStripPanLawMessage | SonareEngineSyncTrackStripPanModeMessage | SonareEngineSyncTrackStripDualPanMessage | SonareEngineSyncTrackStripChannelDelaySamplesMessage | SonareEngineSyncBuiltinInstrumentMessage | SonareEngineSyncSynthInstrumentMessage | SonareEngineSyncSf2InstrumentMessage | SonareEngineSyncLoadSoundFontMessage | SonareEngineSyncMidiFxMessage | SonareEngineSyncMidiNoteMessage | SonareEngineSyncMidiCcMessage | SonareEngineSyncMidiUmpMessage | SonareEngineSyncMidiSysexMessage | SonareEngineSyncMidiPanicMessage | SonareEngineSyncMidiDestinationExternalMessage | SonareEngineSyncExternalMidiClockMessage | SonareEngineSyncMidiInputSourceMessage | SonareEngineSyncMidiCcBindingMessage | SonareEngineSyncMidiInputEventMessage | SonareEngineDestroyMessage;
1121
1522
  interface SonareEngineCaptureRequestMessage {
1122
1523
  type: 'captureRequest';
1123
1524
  requestId: number;
@@ -1194,6 +1595,12 @@ declare class SonareEngine {
1194
1595
  private nextMarkerId;
1195
1596
  private transportPlaying;
1196
1597
  private readonly pendingInstrumentSync;
1598
+ private readonly workletClipPageRequests;
1599
+ private readonly workletPageProviderClipIds;
1600
+ private workletClipStreamer;
1601
+ private workletClipPump;
1602
+ private workletClipPagePollTimer;
1603
+ private unsubscribeWorkletClipRequests;
1197
1604
  private destroyed;
1198
1605
  private constructor();
1199
1606
  static create(context: BaseAudioContext, options?: SonareEngineOptions): Promise<SonareEngine>;
@@ -1275,6 +1682,10 @@ declare class SonareEngine {
1275
1682
  */
1276
1683
  automationLaneCount(): number;
1277
1684
  listParameters(): EngineParameterInfo[];
1685
+ /** Registers a custom parameter on the offline mirror and worklet engine. */
1686
+ addParameter(info: EngineParameterInfo): void;
1687
+ /** Clears custom parameters and their automation lanes on both engines. */
1688
+ clearParameters(): void;
1278
1689
  setSoloMute(target: string | number, solo: boolean, mute: boolean): boolean;
1279
1690
  setStripGain(target: string | number, db: number): boolean;
1280
1691
  setStripPan(target: string | number, pan: number): boolean;
@@ -1324,7 +1735,18 @@ declare class SonareEngine {
1324
1735
  setBusStripInsertParamByName(busId: number, insertIndex: number, paramName: string, value: number): void;
1325
1736
  setStripInsertParamByName(target: string | number, insertIndex: number, paramName: string, value: number): void;
1326
1737
  setMasterChain(sceneJson: string): void;
1327
- addClip(trackId: string | number, buffer: Float32Array[], startPpq: number, opts?: Partial<Omit<EngineClip, 'channels' | 'startPpq'>>): number;
1738
+ /**
1739
+ * Creates and primes an OPFS-backed page provider for this live worklet
1740
+ * engine. Pass the returned `provider` to {@link addClip} in place of a
1741
+ * `Float32Array[]`; the `clipId` in `options` must equal that clip's explicit
1742
+ * `opts.id`. Subsequent cache misses are fetched on the main thread and
1743
+ * supplied back to the worklet through its bounded pull protocol.
1744
+ */
1745
+ attachOpfsClipStream(options: OpfsClipStreamOptions): Promise<{
1746
+ binding: OpfsClipPageProviderBinding;
1747
+ provider: ClipPageProvider;
1748
+ }>;
1749
+ addClip(trackId: string | number, buffer: Float32Array[] | ClipPageProvider, startPpq: number, opts?: Partial<Omit<EngineClip, 'channels' | 'pageProvider' | 'startPpq'>>): number;
1328
1750
  removeClip(clipId: number): void;
1329
1751
  setMidiClips(schedules: readonly EngineMidiClipSchedule[]): void;
1330
1752
  setBuiltinInstrument(trackId: string | number, config?: {
@@ -1336,6 +1758,7 @@ declare class SonareEngine {
1336
1758
  destinationId?: number;
1337
1759
  gain?: number;
1338
1760
  polyphony?: number;
1761
+ preferModelForModeledFamilies?: boolean;
1339
1762
  }): void;
1340
1763
  /**
1341
1764
  * Route a track's MIDI to the external output (drained via {@link onMidiOut})
@@ -1363,9 +1786,20 @@ declare class SonareEngine {
1363
1786
  pushMidiNoteOn(trackId: string | number, group: number, channel: number, note: number, velocity: number, renderFrame?: number): void;
1364
1787
  pushMidiNoteOff(trackId: string | number, group: number, channel: number, note: number, velocity?: number, renderFrame?: number): void;
1365
1788
  pushMidiCc(trackId: string | number, group: number, channel: number, controller: number, value: number, renderFrame?: number): void;
1789
+ pushMidiUmp(trackId: string | number, word0: number, renderFrame?: number): void;
1366
1790
  pushMidiSysex(trackId: string | number, data: Uint8Array, renderFrame?: number): void;
1791
+ bindMidiCc(channel: number, controller: number, paramId: number, options?: MidiCcBindOptions): void;
1792
+ setMidiInputSource(destinationId?: number): void;
1793
+ clearMidiInputSource(): void;
1794
+ pushMidiInputNoteOn(group: number, channel: number, note: number, velocity: number, portTimeSamples?: number): void;
1795
+ pushMidiInputNoteOff(group: number, channel: number, note: number, velocity?: number, portTimeSamples?: number): void;
1796
+ pushMidiInputCc(group: number, channel: number, controller: number, value: number, portTimeSamples?: number): void;
1367
1797
  pushMidiPanic(renderFrame?: number): void;
1368
1798
  configureCapture(options: CaptureOptions): void;
1799
+ /**
1800
+ * Arms the engine-global capture path. `trackId` is retained for source
1801
+ * compatibility and must be `0`; per-track capture is not implemented.
1802
+ */
1369
1803
  armRecord(trackId: string | number, enabled: boolean): boolean;
1370
1804
  punch(inPpq: number, outPpq: number): boolean;
1371
1805
  captureStatus(): Promise<EngineCaptureStatus>;
@@ -1402,11 +1836,24 @@ declare class SonareEngine {
1402
1836
  pollMeters(): SonareWorkletMeterSnapshot[];
1403
1837
  pollScope(): SonareWorkletScopeSnapshot[];
1404
1838
  destroy(): void;
1839
+ private ensureWorkletClipStreamer;
1840
+ /**
1841
+ * SAB requests have no postMessage wake-up by design. Polling on the main
1842
+ * thread is therefore intentionally outside the audio callback; 8 ms keeps
1843
+ * the bounded OPFS prefetch frontier responsive without adding worklet GC.
1844
+ */
1845
+ private startWorkletClipPagePolling;
1846
+ private pumpWorkletClipPages;
1847
+ private enqueueWorkletClipPageRequest;
1848
+ private popWorkletClipPageRequest;
1849
+ private commitWorkletClipPageProvider;
1405
1850
  private mixerLanes;
1406
1851
  private syncMixer;
1407
1852
  private postInstrumentSync;
1408
1853
  private flushPendingInstrumentSync;
1409
1854
  private postSync;
1855
+ private flushOfflineMirror;
1856
+ private sendMirroredCommand;
1410
1857
  private get mixerContext();
1411
1858
  private get stripContext();
1412
1859
  private get automationContext();
@@ -1418,6 +1865,7 @@ declare class SonareEngine {
1418
1865
  private stripParamId;
1419
1866
  private sendSmoothedParam;
1420
1867
  private resolveParamId;
1868
+ private syncParameters;
1421
1869
  private resolveTargetId;
1422
1870
  private ensureTrackLane;
1423
1871
  private ensureBus;
@@ -1430,14 +1878,20 @@ declare class SonareRealtimeEngineNode {
1430
1878
  readonly telemetryRing?: SonareEngineTelemetryRingBuffer;
1431
1879
  readonly meterRing?: SonareMeterRingBuffer;
1432
1880
  readonly scopeRing?: SonareScopeRingBuffer;
1881
+ readonly clipPageRequestRing?: SonareClipPageRequestRingBuffer;
1882
+ readonly externalMidiRing?: SonareExternalMidiRingBuffer;
1433
1883
  readonly ready: Promise<void>;
1434
1884
  private telemetryReadIndex;
1435
1885
  private meterReadIndex;
1436
1886
  private scopeReadIndex;
1887
+ private clipPageRequestDroppedRead;
1888
+ private ringPollTimer;
1437
1889
  private telemetryListeners;
1438
1890
  private meterListeners;
1439
1891
  private scopeListeners;
1440
1892
  private midiOutListeners;
1893
+ private clipPageRequestListeners;
1894
+ private syncErrorListeners;
1441
1895
  private captureRequestId;
1442
1896
  private readonly captureRequests;
1443
1897
  private transportRequestId;
@@ -1446,6 +1900,8 @@ declare class SonareRealtimeEngineNode {
1446
1900
  private rejectReady;
1447
1901
  private destroyed;
1448
1902
  private constructor();
1903
+ /** Subscribes to control-plane sync rejections reported by the worklet. */
1904
+ onSyncError(listener: (message: SonareEngineSyncErrorMessage) => void): () => void;
1449
1905
  static create(context: BaseAudioContext, options?: SonareRealtimeEngineNodeOptions): Promise<SonareRealtimeEngineNode>;
1450
1906
  play(sampleTime?: number): boolean;
1451
1907
  stop(sampleTime?: number): boolean;
@@ -1459,6 +1915,14 @@ declare class SonareRealtimeEngineNode {
1459
1915
  pollTelemetry(): SonareEngineTelemetryRecord[];
1460
1916
  pollMeters(): SonareWorkletMeterSnapshot[];
1461
1917
  pollScope(): SonareWorkletScopeSnapshot[];
1918
+ /** Drain lowered MIDI-1 records from the SAB ring on the main thread. */
1919
+ pollMidiOut(): SonareWorkletExternalMidiEvent[];
1920
+ /**
1921
+ * Drains bounded paged-clip misses from the SAB ring and forwards one batch
1922
+ * to subscribers. In postMessage mode the legacy handler remains available,
1923
+ * but that degraded path is not realtime-safe for OPFS streaming.
1924
+ */
1925
+ pollClipPageRequests(): SonareEngineClipPageRequestMessage | undefined;
1462
1926
  onTelemetry(callback: (telemetry: SonareEngineTelemetryRecord) => void): () => void;
1463
1927
  onMeter(callback: (meter: SonareWorkletMeterSnapshot) => void): () => void;
1464
1928
  onScope(callback: (scope: SonareWorkletScopeSnapshot) => void): () => void;
@@ -1468,10 +1932,18 @@ declare class SonareRealtimeEngineNode {
1468
1932
  * Web MIDI output port. Returns an unsubscribe function.
1469
1933
  */
1470
1934
  onMidiOut(callback: (events: SonareWorkletExternalMidiEvent[]) => void): () => void;
1935
+ /**
1936
+ * Subscribe to bounded batches of paged-clip misses from the worklet. The
1937
+ * callback runs on the main thread and may initiate asynchronous OPFS I/O.
1938
+ */
1939
+ onClipPageRequests(callback: (message: SonareEngineClipPageRequestMessage) => void): () => void;
1471
1940
  destroy(): void;
1472
1941
  private emitTelemetry;
1942
+ private startRingPolling;
1943
+ private stopRingPollingIfUnused;
1473
1944
  private emitMeter;
1474
1945
  private emitMidiOut;
1946
+ private emitClipPageRequests;
1475
1947
  private emitScope;
1476
1948
  private sendCaptureRequest;
1477
1949
  private sendTransportRequest;
@@ -1496,6 +1968,8 @@ declare class SonareRealtimeEngineWorkletProcessor {
1496
1968
  private telemetryRing?;
1497
1969
  private meterRing?;
1498
1970
  private scopeRing?;
1971
+ private clipPageRequestRing?;
1972
+ private externalMidiRing?;
1499
1973
  private transport?;
1500
1974
  private meterIntervalFrames;
1501
1975
  private lastMeterFrame;
@@ -1503,24 +1977,40 @@ declare class SonareRealtimeEngineWorkletProcessor {
1503
1977
  private channelBuffers;
1504
1978
  private readonly liveClips;
1505
1979
  private readonly pagedClipProviders;
1980
+ private readonly pagedClipPageFrames;
1506
1981
  private readonly pendingPagedClips;
1982
+ private readonly clipPageRequestClipIds;
1983
+ private readonly clipPageRequestPageIndices;
1984
+ private clipPageRequestOverflowReported;
1507
1985
  constructor(options?: SonareRealtimeEngineWorkletProcessorOptions, transport?: WorkletTransport);
1508
1986
  process(inputs: WorkletInput, outputs: WorkletOutput): boolean;
1509
1987
  private reacquireChannelBuffers;
1510
1988
  receiveCommand(command: SonareEngineCommandRecord): void;
1511
1989
  receiveSync(message: SonareEngineSyncMessage): void;
1990
+ private applySync;
1512
1991
  receiveCaptureRequest(message: SonareEngineCaptureRequestMessage): void;
1513
1992
  receiveTransportRequest(message: SonareEngineTransportRequestMessage): void;
1514
1993
  destroy(): void;
1515
1994
  private drainCommands;
1995
+ private safeApplyCommand;
1516
1996
  private applyCommand;
1517
1997
  private publishTelemetry;
1998
+ private writeTelemetryScratch;
1518
1999
  private publishTelemetryRecord;
1519
2000
  private publishMeters;
2001
+ private writeMeterScratch;
1520
2002
  private writeMeterRing;
1521
2003
  private publishScope;
2004
+ private writeScopeScratch;
1522
2005
  private publishExternalMidi;
1523
- private writeScopeRing;
2006
+ /**
2007
+ * Forward a bounded batch of native page misses to the main thread. This
2008
+ * deliberately runs after audio rendering: a cache miss is silence for this
2009
+ * block, and OPFS I/O must never delay `process()`.
2010
+ */
2011
+ private publishClipPageRequests;
2012
+ private removePagedClipProvider;
2013
+ private clearPagedClipProviders;
1524
2014
  private commandRingFromSharedBuffer;
1525
2015
  private telemetryRingFromSharedBuffer;
1526
2016
  }
@@ -1571,16 +2061,14 @@ declare class SonareRealtimeVoiceChangerWorkletProcessor {
1571
2061
  private readonly channelCount;
1572
2062
  private monoInput;
1573
2063
  private monoOutput;
2064
+ private bufferGeneration;
1574
2065
  private planarChannels;
1575
2066
  private destroyed;
1576
2067
  constructor(options?: SonareRealtimeVoiceChangerWorkletProcessorOptions);
1577
2068
  /**
1578
- * Handles a control-plane message from the main thread. Runs on the
1579
- * AudioWorklet global scope but OUTSIDE of `process()` (i.e. outside the
1580
- * realtime audio callback), so it is safe to perform JSON parsing and
1581
- * DSP coefficient recomputation here. `setConfig` MUST NOT be deferred
1582
- * into `process()` because that would block the audio thread for longer
1583
- * than one render quantum (e.g. 128 samples / 44.1 kHz = ~2.9 ms).
2069
+ * Handles a control-plane message from the main thread. AudioWorklet port
2070
+ * handlers run on the same audio rendering thread as `process()`: this path
2071
+ * therefore accepts only a pre-normalized POD and never parses JSON.
1584
2072
  */
1585
2073
  receiveMessage(message: SonareRealtimeVoiceChangerMessage): void;
1586
2074
  process(inputs: WorkletInput, outputs: WorkletOutput): boolean;
@@ -1602,4 +2090,4 @@ declare class SonareRealtimeVoiceChangerWorkletProcessor {
1602
2090
  }
1603
2091
  declare function registerSonareRealtimeVoiceChangerWorkletProcessor(name?: string): void;
1604
2092
 
1605
- export { SONARE_ENGINE_COMMAND_RECORD_BYTES, SONARE_ENGINE_RING_HEADER_INTS, SONARE_ENGINE_TELEMETRY_RECORD_BYTES, SONARE_METER_RING_HEADER_INTS, SONARE_METER_RING_RECORD_FLOATS, SONARE_SCOPE_RING_HEADER_INTS, SONARE_SPECTRUM_RING_HEADER_INTS, SonareEngine, type SonareEngineCaptureRequestMessage, type SonareEngineCaptureResponseMessage, type SonareEngineCommandRecord, type SonareEngineCommandRingBuffer, SonareEngineCommandType, type SonareEngineOptions, type SonareEngineSyncAutomationMessage, type SonareEngineSyncBuiltinInstrumentMessage, type SonareEngineSyncCaptureMessage, type SonareEngineSyncClipsDeltaMessage, type SonareEngineSyncClipsMessage, type SonareEngineSyncLoadSoundFontMessage, type SonareEngineSyncMarkersMessage, type SonareEngineSyncMasterStripEqBandMessage, type SonareEngineSyncMasterStripInsertBypassedMessage, type SonareEngineSyncMessage, type SonareEngineSyncMetronomeMessage, type SonareEngineSyncMidiCcMessage, type SonareEngineSyncMidiClipsMessage, type SonareEngineSyncMidiNoteMessage, type SonareEngineSyncMidiPanicMessage, type SonareEngineSyncMixerMessage, type SonareEngineSyncSf2InstrumentMessage, type SonareEngineSyncSynthInstrumentMessage, type SonareEngineSyncTempoMessage, type SonareEngineSyncTrackStripEqBandMessage, type SonareEngineSyncTrackStripInsertBypassedMessage, SonareEngineTelemetryError, type SonareEngineTelemetryRecord, type SonareEngineTelemetryRingBuffer, type SonareEngineTelemetryRingReadResult, SonareEngineTelemetryType, type SonareEngineTransportFacade, type SonareEngineTransportRequestMessage, type SonareEngineTransportResponseMessage, type SonareMeterRingBuffer, type SonareMeterRingReadResult, SonareRealtimeEngineNode, type SonareRealtimeEngineNodeCapabilities, type SonareRealtimeEngineNodeOptions, SonareRealtimeEngineWorkletProcessor, type SonareRealtimeEngineWorkletProcessorOptions, type SonareRealtimeVoiceChangerDestroyMessage, type SonareRealtimeVoiceChangerMessage, type SonareRealtimeVoiceChangerResetMessage, type SonareRealtimeVoiceChangerSetConfigMessage, SonareRealtimeVoiceChangerWorkletProcessor, type SonareRealtimeVoiceChangerWorkletProcessorOptions, type SonareScopeRingBuffer, type SonareScopeRingReadResult, type SonareSpectrumRingBuffer, type SonareSpectrumRingReadResult, type SonareWorkletDestroyMessage, type SonareWorkletMessage, type SonareWorkletMeterSnapshot, SonareWorkletProcessor, type SonareWorkletProcessorOptions, type SonareWorkletScheduleInsertAutomationMessage, type SonareWorkletScopeSnapshot, type SonareWorkletSetMeterIntervalMessage, type SonareWorkletSpectrumSnapshot, type SonareWorkletTransportMessage, createSonareEngineCommandRingBuffer, createSonareEngineTelemetryRingBuffer, createSonareMeterRingBuffer, createSonareScopeRingBuffer, createSonareSpectrumRingBuffer, decodeFrame, encodeFrameHi, encodeFrameLo, init, isInitialized, popSonareEngineCommandRingBuffer, pushSonareEngineCommandRingBuffer, readSonareEngineTelemetryRingBuffer, readSonareMeterRingBuffer, readSonareScopeRingBuffer, readSonareSpectrumRingBuffer, registerSonareRealtimeEngineWorkletProcessor, registerSonareRealtimeVoiceChangerWorkletProcessor, registerSonareWorkletProcessor, sonareEngineCommandRingBufferByteLength, sonareEngineTelemetryRingBufferByteLength, sonareMeterRingBufferByteLength, sonareScopeRingBufferByteLength, sonareSpectrumRingBufferByteLength, writeSonareEngineTelemetryRingBuffer };
2093
+ export { type OpfsClipStream, type OpfsClipStreamOptions, SONARE_CLIP_PAGE_REQUEST_RING_HEADER_INTS, SONARE_CLIP_PAGE_REQUEST_RING_RECORD_UINT32S, SONARE_ENGINE_COMMAND_RECORD_BYTES, SONARE_ENGINE_RING_HEADER_INTS, SONARE_ENGINE_TELEMETRY_RECORD_BYTES, SONARE_EXTERNAL_MIDI_RING_HEADER_INTS, SONARE_EXTERNAL_MIDI_RING_RECORD_UINT32S, SONARE_METER_RING_HEADER_INTS, SONARE_METER_RING_RECORD_FLOATS, SONARE_SCOPE_RING_HEADER_INTS, SONARE_SPECTRUM_RING_HEADER_INTS, type SonareClipPageRequest, type SonareClipPageRequestRingBuffer, type SonareClipPageRequestRingReadResult, SonareEngine, type SonareEngineCaptureRequestMessage, type SonareEngineCaptureResponseMessage, type SonareEngineClipPageRequestMessage, type SonareEngineCommandRecord, type SonareEngineCommandRingBuffer, SonareEngineCommandType, type SonareEngineOptions, type SonareEngineSyncAutomationMessage, type SonareEngineSyncBuiltinInstrumentMessage, type SonareEngineSyncCaptureMessage, type SonareEngineSyncClipsDeltaMessage, type SonareEngineSyncClipsMessage, type SonareEngineSyncLoadSoundFontMessage, type SonareEngineSyncMarkersMessage, type SonareEngineSyncMasterStripEqBandMessage, type SonareEngineSyncMasterStripInsertBypassedMessage, type SonareEngineSyncMessage, type SonareEngineSyncMetronomeMessage, type SonareEngineSyncMidiCcMessage, type SonareEngineSyncMidiClipsMessage, type SonareEngineSyncMidiNoteMessage, type SonareEngineSyncMidiPanicMessage, type SonareEngineSyncMixerMessage, type SonareEngineSyncSf2InstrumentMessage, type SonareEngineSyncSynthInstrumentMessage, type SonareEngineSyncTempoMessage, type SonareEngineSyncTrackStripEqBandMessage, type SonareEngineSyncTrackStripInsertBypassedMessage, SonareEngineTelemetryError, type SonareEngineTelemetryRecord, type SonareEngineTelemetryRingBuffer, type SonareEngineTelemetryRingReadResult, SonareEngineTelemetryType, type SonareEngineTransportFacade, type SonareEngineTransportRequestMessage, type SonareEngineTransportResponseMessage, type SonareExternalMidiRingBuffer, type SonareExternalMidiRingReadResult, type SonareMeterRingBuffer, type SonareMeterRingReadResult, SonareRealtimeEngineNode, type SonareRealtimeEngineNodeCapabilities, type SonareRealtimeEngineNodeOptions, SonareRealtimeEngineWorkletProcessor, type SonareRealtimeEngineWorkletProcessorOptions, type SonareRealtimeVoiceChangerDestroyMessage, type SonareRealtimeVoiceChangerMessage, type SonareRealtimeVoiceChangerResetMessage, type SonareRealtimeVoiceChangerSetConfigMessage, SonareRealtimeVoiceChangerWorkletProcessor, type SonareRealtimeVoiceChangerWorkletProcessorOptions, type SonareScopeRingBuffer, type SonareScopeRingReadResult, type SonareSpectrumRingBuffer, type SonareSpectrumRingReadResult, type SonareWorkletDestroyMessage, type SonareWorkletMessage, type SonareWorkletMeterSnapshot, SonareWorkletProcessor, type SonareWorkletProcessorOptions, type SonareWorkletScheduleInsertAutomationMessage, type SonareWorkletScopeSnapshot, type SonareWorkletSetMeterIntervalMessage, type SonareWorkletSpectrumSnapshot, type SonareWorkletTransportMessage, attachOpfsClipStream, createSonareClipPageRequestRingBuffer, createSonareEngineCommandRingBuffer, createSonareEngineTelemetryRingBuffer, createSonareExternalMidiRingBuffer, createSonareMeterRingBuffer, createSonareScopeRingBuffer, createSonareSpectrumRingBuffer, decodeFrame, encodeFrameHi, encodeFrameLo, init, isInitialized, popSonareEngineCommandRingBuffer, pushSonareClipPageRequestRingBuffer, pushSonareEngineCommandRingBuffer, pushSonareExternalMidiRingBuffer, readSonareClipPageRequestRingBuffer, readSonareEngineTelemetryRingBuffer, readSonareExternalMidiRingBuffer, readSonareMeterRingBuffer, readSonareScopeRingBuffer, readSonareSpectrumRingBuffer, registerSonareRealtimeEngineWorkletProcessor, registerSonareRealtimeVoiceChangerWorkletProcessor, registerSonareWorkletProcessor, sonareClipPageRequestRingBufferByteLength, sonareEngineCommandRingBufferByteLength, sonareEngineTelemetryRingBufferByteLength, sonareExternalMidiRingBufferByteLength, sonareMeterRingBufferByteLength, sonareScopeRingBufferByteLength, sonareSpectrumRingBufferByteLength, writeSonareEngineTelemetryRingBuffer };