@libraz/libsonare 1.3.3 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,461 @@
1
+ import type {
2
+ EngineAutomationPoint,
3
+ EngineBus,
4
+ EngineCaptureStatus,
5
+ EngineClip,
6
+ EngineMarker,
7
+ EngineMetronomeConfig,
8
+ EngineMidiClipSchedule,
9
+ EngineTempoSegment,
10
+ EngineTimeSignatureSegment,
11
+ EngineTrackLane,
12
+ EngineTransportState,
13
+ RealtimeVoiceChangerConfigInput,
14
+ } from '../index';
15
+ import type { AutomationCurve } from '../public_types';
16
+ import type { SonareRtModule } from '../sonare-rt';
17
+ import type {
18
+ SonareEngineCommandRecord,
19
+ SonareEngineTelemetryRecord,
20
+ SonareWorkletMeterSnapshot,
21
+ SonareWorkletSpectrumSnapshot,
22
+ } from './protocol';
23
+
24
+ export interface SonareWorkletProcessorOptions {
25
+ sceneJson: string;
26
+ sampleRate?: number;
27
+ blockSize?: number;
28
+ stripCount?: number;
29
+ meterIntervalFrames?: number;
30
+ meterSharedBuffer?: SharedArrayBuffer;
31
+ meterRingCapacity?: number;
32
+ spectrumIntervalFrames?: number;
33
+ spectrumBands?: number;
34
+ spectrumSharedBuffer?: SharedArrayBuffer;
35
+ spectrumRingCapacity?: number;
36
+ }
37
+
38
+ export interface SonareRealtimeEngineWorkletProcessorOptions {
39
+ runtimeTarget?: 'embind' | 'sonare-rt';
40
+ rtModuleUrl?: string;
41
+ rtWasmBinary?: ArrayBuffer | Uint8Array;
42
+ wasmBinary?: ArrayBuffer | Uint8Array;
43
+ initialSyncMessages?: SonareEngineSyncMessage[];
44
+ initialCommands?: SonareEngineCommandRecord[];
45
+ sampleRate?: number;
46
+ blockSize?: number;
47
+ channelCount?: number;
48
+ meterIntervalFrames?: number;
49
+ commandSharedBuffer?: SharedArrayBuffer;
50
+ commandRingCapacity?: number;
51
+ telemetrySharedBuffer?: SharedArrayBuffer;
52
+ telemetryRingCapacity?: number;
53
+ meterSharedBuffer?: SharedArrayBuffer;
54
+ meterRingCapacity?: number;
55
+ // Scope telemetry (FFT spectrum + goniometer): opt-in. The ring is created
56
+ // only when scopeIntervalFrames > 0, since the per-block FFT is heavier than
57
+ // the meter path. scopeBands selects the linear band resolution.
58
+ scopeIntervalFrames?: number;
59
+ scopeBands?: number;
60
+ scopeSharedBuffer?: SharedArrayBuffer;
61
+ scopeRingCapacity?: number;
62
+ }
63
+
64
+ export interface SonareRealtimeVoiceChangerWorkletProcessorOptions {
65
+ preset?: RealtimeVoiceChangerConfigInput;
66
+ sampleRate?: number;
67
+ blockSize?: number;
68
+ channelCount?: number;
69
+ }
70
+
71
+ export interface SonareRealtimeVoiceChangerSetConfigMessage {
72
+ type: 'setConfig';
73
+ preset: RealtimeVoiceChangerConfigInput;
74
+ }
75
+
76
+ export interface SonareRealtimeVoiceChangerResetMessage {
77
+ type: 'reset';
78
+ }
79
+
80
+ export interface SonareRealtimeVoiceChangerDestroyMessage {
81
+ type: 'destroy';
82
+ }
83
+
84
+ export type SonareRealtimeVoiceChangerMessage =
85
+ | SonareRealtimeVoiceChangerSetConfigMessage
86
+ | SonareRealtimeVoiceChangerResetMessage
87
+ | SonareRealtimeVoiceChangerDestroyMessage;
88
+
89
+ export interface SonareRealtimeEngineNodeCapabilities {
90
+ mode: 'sab' | 'postMessage';
91
+ runtimeTarget: 'embind' | 'sonare-rt';
92
+ sharedArrayBuffer: boolean;
93
+ atomics: boolean;
94
+ audioWorklet: boolean;
95
+ engineAbiVersion?: number;
96
+ expectedEngineAbiVersion?: number;
97
+ abiCompatible?: boolean;
98
+ degradedReason?: string;
99
+ readyMessage?: boolean;
100
+ }
101
+
102
+ export interface SonareRealtimeEngineNodeOptions
103
+ extends SonareRealtimeEngineWorkletProcessorOptions {
104
+ processorName?: string;
105
+ moduleUrl?: string | URL;
106
+ rtModuleUrl?: string;
107
+ mode?: 'auto' | 'sab' | 'postMessage';
108
+ engineAbiVersion?: number;
109
+ expectedEngineAbiVersion?: number;
110
+ requireAbiCompatible?: boolean;
111
+ nodeFactory?: (
112
+ context: BaseAudioContext,
113
+ processorName: string,
114
+ options: AudioWorkletNodeOptions,
115
+ ) => AudioWorkletNode;
116
+ }
117
+
118
+ export interface SonareRtRealtimeEngineRuntimeOptions {
119
+ module: SonareRtModule;
120
+ memory: WebAssembly.Memory;
121
+ sampleRate?: number;
122
+ blockSize?: number;
123
+ channelCount?: number;
124
+ commandSharedBuffer?: SharedArrayBuffer;
125
+ commandRingCapacity?: number;
126
+ telemetrySharedBuffer?: SharedArrayBuffer;
127
+ telemetryRingCapacity?: number;
128
+ }
129
+
130
+ export interface SonareEngineTransportFacade {
131
+ play(sampleTime?: number): boolean;
132
+ stop(sampleTime?: number): boolean;
133
+ seekPpq(ppq: number, sampleTime?: number): boolean;
134
+ seekSeconds(seconds: number, sampleTime?: number): boolean;
135
+ setTempo(bpm: number): void;
136
+ setTempoSegments(segments: readonly EngineTempoSegment[]): void;
137
+ setLoop(startPpq: number, endPpq: number, enabled?: boolean): boolean;
138
+ }
139
+
140
+ export interface SonareWorkletScheduleInsertAutomationMessage {
141
+ type: 'scheduleInsertAutomation';
142
+ stripIndex: number;
143
+ insertIndex: number;
144
+ paramId: number;
145
+ value: number;
146
+ samplePos?: number;
147
+ curve?: AutomationCurve;
148
+ }
149
+
150
+ export interface SonareWorkletSetMeterIntervalMessage {
151
+ type: 'setMeterInterval';
152
+ frames: number;
153
+ }
154
+
155
+ export interface SonareWorkletDestroyMessage {
156
+ type: 'destroy';
157
+ }
158
+
159
+ export type SonareWorkletMessage =
160
+ | SonareWorkletScheduleInsertAutomationMessage
161
+ | SonareWorkletSetMeterIntervalMessage
162
+ | SonareWorkletDestroyMessage;
163
+
164
+ export type SonareWorkletTransportMessage =
165
+ | SonareWorkletMeterSnapshot
166
+ | SonareWorkletSpectrumSnapshot
167
+ | SonareEngineTelemetryRecord;
168
+
169
+ export interface WorkletTransport {
170
+ postMessage?: (
171
+ message:
172
+ | SonareWorkletTransportMessage
173
+ | SonareEngineCaptureResponseMessage
174
+ | SonareEngineTransportResponseMessage,
175
+ transfer?: Transferable[],
176
+ ) => void;
177
+ onMeter?: (meter: SonareWorkletMeterSnapshot) => void;
178
+ onSpectrum?: (spectrum: SonareWorkletSpectrumSnapshot) => void;
179
+ }
180
+
181
+ export interface ResolvedMetronomeConfig {
182
+ beatGain: number;
183
+ accentGain: number;
184
+ clickSamples: number;
185
+ }
186
+
187
+ // Fallback metronome gains/click length used by the worklet consumer until the
188
+ // host posts a 'syncMetronome' config. Aligned with the embind setMetronome
189
+ // defaults (src/wasm/bindings.cpp) so offline and realtime metronomes match.
190
+ export const DEFAULT_METRONOME_CONFIG: ResolvedMetronomeConfig = {
191
+ beatGain: 0.35,
192
+ accentGain: 0.7,
193
+ clickSamples: 96,
194
+ };
195
+
196
+ export function resolveMetronomeConfig(config: EngineMetronomeConfig): ResolvedMetronomeConfig {
197
+ return {
198
+ beatGain: config.beatGain ?? DEFAULT_METRONOME_CONFIG.beatGain,
199
+ accentGain: config.accentGain ?? DEFAULT_METRONOME_CONFIG.accentGain,
200
+ clickSamples: config.clickSamples ?? DEFAULT_METRONOME_CONFIG.clickSamples,
201
+ };
202
+ }
203
+
204
+ // Out-of-band control messages posted from the main-thread SonareEngine facade
205
+ // to the worklet engine processor over node.port. Unlike SonareEngineCommandRecord
206
+ // (a small POD POSTed/ringed every block) these carry bulk/structured payloads
207
+ // (clip audio buffers, marker lists, metronome config) that cannot fit the
208
+ // fixed-size SAB command record, so they are applied OUTSIDE process() — the
209
+ // audio-thread equivalent of the engine's control-thread RtPublisher setters.
210
+ export interface SonareEngineSyncClipsMessage {
211
+ type: 'syncClips';
212
+ clips: EngineClip[];
213
+ }
214
+
215
+ export interface SonareEngineSyncClipsDeltaMessage {
216
+ type: 'syncClipsDelta';
217
+ upserts: EngineClip[];
218
+ removeIds: number[];
219
+ }
220
+
221
+ export interface SonareEngineSyncMidiClipsMessage {
222
+ type: 'syncMidiClips';
223
+ clips: EngineMidiClipSchedule[];
224
+ }
225
+
226
+ export interface SonareEngineSyncMarkersMessage {
227
+ type: 'syncMarkers';
228
+ markers: EngineMarker[];
229
+ }
230
+
231
+ export interface SonareEngineSyncMetronomeMessage {
232
+ type: 'syncMetronome';
233
+ config: EngineMetronomeConfig;
234
+ }
235
+
236
+ export interface SonareEngineSyncAutomationMessage {
237
+ type: 'syncAutomation';
238
+ paramId: number;
239
+ points: EngineAutomationPoint[];
240
+ }
241
+
242
+ export interface SonareEngineSyncTempoMessage {
243
+ type: 'syncTempo';
244
+ bpm: number;
245
+ timeSignature: { numerator: number; denominator: number };
246
+ tempoSegments?: EngineTempoSegment[];
247
+ timeSignatureSegments?: EngineTimeSignatureSegment[];
248
+ }
249
+
250
+ export interface SonareEngineSyncMixerMessage {
251
+ type: 'syncMixer';
252
+ lanes: EngineTrackLane[];
253
+ buses?: EngineBus[];
254
+ trackStrips?: Array<{ trackId: number; sceneJson: string }>;
255
+ busStrips?: Array<{ busId: number; sceneJson: string }>;
256
+ masterStripJson?: string;
257
+ /** Lane insert sidechain bindings (replayed after lanes/strips). */
258
+ laneSidechains?: Array<{ trackId: number; insertIndex: number; sourceTrackId: number }>;
259
+ }
260
+
261
+ export interface SonareEngineSyncCaptureMessage {
262
+ type: 'syncCapture';
263
+ bufferFrames: number;
264
+ channels: number;
265
+ source: EngineCaptureStatus['source'];
266
+ recordOffsetSamples: number;
267
+ inputMonitor: { enabled: boolean; gain: number };
268
+ }
269
+
270
+ export interface SonareEngineSyncTrackStripEqBandMessage {
271
+ type: 'syncTrackStripEqBand';
272
+ trackId: number;
273
+ bandIndex: number;
274
+ bandJson: string;
275
+ }
276
+
277
+ export interface SonareEngineSyncMasterStripEqBandMessage {
278
+ type: 'syncMasterStripEqBand';
279
+ bandIndex: number;
280
+ bandJson: string;
281
+ }
282
+
283
+ export interface SonareEngineSyncTrackStripInsertBypassedMessage {
284
+ type: 'syncTrackStripInsertBypassed';
285
+ trackId: number;
286
+ insertIndex: number;
287
+ bypassed: boolean;
288
+ resetOnBypass: boolean;
289
+ }
290
+
291
+ export interface SonareEngineSyncMasterStripInsertBypassedMessage {
292
+ type: 'syncMasterStripInsertBypassed';
293
+ insertIndex: number;
294
+ bypassed: boolean;
295
+ resetOnBypass: boolean;
296
+ }
297
+
298
+ export interface SonareEngineSyncTrackStripInsertParamByNameMessage {
299
+ type: 'syncTrackStripInsertParamByName';
300
+ trackId: number;
301
+ insertIndex: number;
302
+ paramName: string;
303
+ value: number;
304
+ }
305
+
306
+ export interface SonareEngineSyncMasterStripInsertParamByNameMessage {
307
+ type: 'syncMasterStripInsertParamByName';
308
+ insertIndex: number;
309
+ paramName: string;
310
+ value: number;
311
+ }
312
+
313
+ export interface SonareEngineSyncTrackStripPanMessage {
314
+ type: 'syncTrackStripPan';
315
+ trackId: number;
316
+ pan: number;
317
+ }
318
+
319
+ export interface SonareEngineSyncTrackStripPanLawMessage {
320
+ type: 'syncTrackStripPanLaw';
321
+ trackId: number;
322
+ panLaw: number;
323
+ }
324
+
325
+ export interface SonareEngineSyncTrackStripPanModeMessage {
326
+ type: 'syncTrackStripPanMode';
327
+ trackId: number;
328
+ panMode: number;
329
+ }
330
+
331
+ export interface SonareEngineSyncTrackStripDualPanMessage {
332
+ type: 'syncTrackStripDualPan';
333
+ trackId: number;
334
+ leftPan: number;
335
+ rightPan: number;
336
+ }
337
+
338
+ export interface SonareEngineSyncTrackStripChannelDelaySamplesMessage {
339
+ type: 'syncTrackStripChannelDelaySamples';
340
+ trackId: number;
341
+ delaySamples: number;
342
+ }
343
+
344
+ export interface SonareEngineSyncBuiltinInstrumentMessage {
345
+ type: 'syncBuiltinInstrument';
346
+ destinationId: number;
347
+ config: { destinationId?: number } & Record<string, unknown>;
348
+ }
349
+
350
+ export interface SonareEngineSyncSynthInstrumentMessage {
351
+ type: 'syncSynthInstrument';
352
+ destinationId: number;
353
+ patch: Record<string, unknown> | string;
354
+ }
355
+
356
+ export interface SonareEngineSyncSf2InstrumentMessage {
357
+ type: 'syncSf2Instrument';
358
+ destinationId: number;
359
+ config: { destinationId?: number; gain?: number; polyphony?: number };
360
+ }
361
+
362
+ export interface SonareEngineSyncLoadSoundFontMessage {
363
+ type: 'syncLoadSoundFont';
364
+ data: Uint8Array;
365
+ }
366
+
367
+ export interface SonareEngineSyncMidiNoteMessage {
368
+ type: 'syncMidiNoteOn' | 'syncMidiNoteOff';
369
+ destinationId: number;
370
+ group: number;
371
+ channel: number;
372
+ note: number;
373
+ velocity: number;
374
+ renderFrame: number;
375
+ }
376
+
377
+ export interface SonareEngineSyncMidiCcMessage {
378
+ type: 'syncMidiCc';
379
+ destinationId: number;
380
+ group: number;
381
+ channel: number;
382
+ controller: number;
383
+ value: number;
384
+ renderFrame: number;
385
+ }
386
+
387
+ export interface SonareEngineSyncMidiPanicMessage {
388
+ type: 'syncMidiPanic';
389
+ renderFrame: number;
390
+ }
391
+
392
+ export type SonareEngineInstrumentSyncMessage =
393
+ | SonareEngineSyncBuiltinInstrumentMessage
394
+ | SonareEngineSyncSynthInstrumentMessage
395
+ | SonareEngineSyncSf2InstrumentMessage
396
+ | SonareEngineSyncLoadSoundFontMessage;
397
+
398
+ export type SonareEngineSyncMessage =
399
+ | SonareEngineSyncClipsMessage
400
+ | SonareEngineSyncClipsDeltaMessage
401
+ | SonareEngineSyncMidiClipsMessage
402
+ | SonareEngineSyncMarkersMessage
403
+ | SonareEngineSyncMetronomeMessage
404
+ | SonareEngineSyncAutomationMessage
405
+ | SonareEngineSyncTempoMessage
406
+ | SonareEngineSyncMixerMessage
407
+ | SonareEngineSyncCaptureMessage
408
+ | SonareEngineSyncTrackStripEqBandMessage
409
+ | SonareEngineSyncMasterStripEqBandMessage
410
+ | SonareEngineSyncTrackStripInsertBypassedMessage
411
+ | SonareEngineSyncMasterStripInsertBypassedMessage
412
+ | SonareEngineSyncTrackStripInsertParamByNameMessage
413
+ | SonareEngineSyncMasterStripInsertParamByNameMessage
414
+ | SonareEngineSyncTrackStripPanMessage
415
+ | SonareEngineSyncTrackStripPanLawMessage
416
+ | SonareEngineSyncTrackStripPanModeMessage
417
+ | SonareEngineSyncTrackStripDualPanMessage
418
+ | SonareEngineSyncTrackStripChannelDelaySamplesMessage
419
+ | SonareEngineSyncBuiltinInstrumentMessage
420
+ | SonareEngineSyncSynthInstrumentMessage
421
+ | SonareEngineSyncSf2InstrumentMessage
422
+ | SonareEngineSyncLoadSoundFontMessage
423
+ | SonareEngineSyncMidiNoteMessage
424
+ | SonareEngineSyncMidiCcMessage
425
+ | SonareEngineSyncMidiPanicMessage;
426
+
427
+ export interface WorkletPort {
428
+ postMessage?: (message: unknown, transfer?: Transferable[]) => void;
429
+ onmessage?: (event: { data: unknown }) => void;
430
+ addEventListener?: (type: 'message', listener: (event: { data: unknown }) => void) => void;
431
+ start?: () => void;
432
+ }
433
+
434
+ export interface SonareEngineCaptureRequestMessage {
435
+ type: 'captureRequest';
436
+ requestId: number;
437
+ op: 'status' | 'read' | 'reset';
438
+ }
439
+
440
+ export interface SonareEngineCaptureResponseMessage {
441
+ type: 'captureResponse';
442
+ requestId: number;
443
+ ok: boolean;
444
+ status?: EngineCaptureStatus;
445
+ channels?: Float32Array[] | number[][];
446
+ error?: string;
447
+ }
448
+
449
+ export interface SonareEngineTransportRequestMessage {
450
+ type: 'transportRequest';
451
+ requestId: number;
452
+ op: 'state';
453
+ }
454
+
455
+ export interface SonareEngineTransportResponseMessage {
456
+ type: 'transportResponse';
457
+ requestId: number;
458
+ ok: boolean;
459
+ state?: EngineTransportState;
460
+ error?: string;
461
+ }