@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
@@ -4,6 +4,7 @@ import type {
4
4
  MelPowerResult,
5
5
  MelSpectrogramResult,
6
6
  MfccResult,
7
+ ReassignedSpectrogramResult,
7
8
  StftPowerResult,
8
9
  StftResult,
9
10
  } from './public_types';
@@ -49,6 +50,17 @@ export interface MfccRequest extends MelSpectrogramRequest {
49
50
  lifter?: number;
50
51
  }
51
52
 
53
+ export interface MelDeltaRequest extends GuardedOptions {
54
+ features: Float32Array;
55
+ nFeatures: number;
56
+ nFrames: number;
57
+ width?: number;
58
+ }
59
+ export interface ReassignedSpectrogramRequest extends SpectrogramRequest {
60
+ refPower?: number;
61
+ fillNan?: boolean;
62
+ }
63
+
52
64
  export interface MfccToMelRequest extends GuardedOptions {
53
65
  mfccCoefficients: Float32Array;
54
66
  nMfcc: number;
@@ -75,6 +87,16 @@ export interface MelToAudioRequest extends MelToStftRequest {
75
87
  hopLength?: number;
76
88
  nIter?: number;
77
89
  }
90
+ export interface GriffinLimRequest extends GuardedOptions {
91
+ magnitude: Float32Array;
92
+ nBins: number;
93
+ nFrames: number;
94
+ sampleRate?: number;
95
+ nFft?: number;
96
+ hopLength?: number;
97
+ nIter?: number;
98
+ momentum?: number;
99
+ }
78
100
 
79
101
  /** Canonical request form for Griffin-Lim reconstruction from MFCCs. */
80
102
  export interface MfccToAudioRequest extends MfccToMelRequest {
@@ -524,6 +546,90 @@ export function mfcc(
524
546
  );
525
547
  }
526
548
 
549
+ /** First-order regression delta of a row-major feature matrix. */
550
+ export function melDelta(request: MelDeltaRequest): Float32Array;
551
+ export function melDelta(
552
+ features: Float32Array,
553
+ nFeatures: number,
554
+ nFrames: number,
555
+ width?: number,
556
+ ): Float32Array;
557
+ export function melDelta(
558
+ features: Float32Array | MelDeltaRequest,
559
+ nFeatures?: number,
560
+ nFrames?: number,
561
+ width = 9,
562
+ ): Float32Array {
563
+ const request: MelDeltaRequest =
564
+ features instanceof Float32Array
565
+ ? { features, nFeatures: nFeatures ?? 0, nFrames: nFrames ?? 0, width }
566
+ : features;
567
+ assertPositiveInteger('melDelta', request.nFeatures, 'nFeatures');
568
+ assertPositiveInteger('melDelta', request.nFrames, 'nFrames');
569
+ assertPositiveInteger('melDelta', request.width ?? 9, 'width');
570
+ if ((request.width ?? 9) < 3 || (request.width ?? 9) % 2 === 0) {
571
+ throw new RangeError('melDelta: width must be an odd integer of at least 3');
572
+ }
573
+ if (request.features.length !== request.nFeatures * request.nFrames) {
574
+ throw new RangeError('melDelta: feature matrix length must equal nFeatures * nFrames');
575
+ }
576
+ return requireModule().melDelta(
577
+ request.features,
578
+ request.nFeatures,
579
+ request.nFrames,
580
+ request.width ?? 9,
581
+ );
582
+ }
583
+
584
+ /** Auger-Flandrin reassigned spectrogram (row-major [nBins x nFrames] arrays). */
585
+ export function reassignedSpectrogram(
586
+ request: ReassignedSpectrogramRequest,
587
+ ): ReassignedSpectrogramResult;
588
+ export function reassignedSpectrogram(
589
+ samples: Float32Array,
590
+ sampleRate?: number,
591
+ nFft?: number,
592
+ hopLength?: number,
593
+ refPower?: number,
594
+ fillNan?: boolean,
595
+ ): ReassignedSpectrogramResult;
596
+ export function reassignedSpectrogram(
597
+ samples: Float32Array | ReassignedSpectrogramRequest,
598
+ sampleRate = 22050,
599
+ nFft = 2048,
600
+ hopLength = 512,
601
+ refPower = 1e-6,
602
+ fillNan = false,
603
+ ): ReassignedSpectrogramResult {
604
+ if (!(samples instanceof Float32Array)) {
605
+ const request = samples;
606
+ return reassignedSpectrogram(
607
+ request.samples,
608
+ request.sampleRate,
609
+ request.nFft,
610
+ request.hopLength,
611
+ request.refPower,
612
+ request.fillNan,
613
+ );
614
+ }
615
+ assertSamples('reassignedSpectrogram', samples, true);
616
+ assertSampleRate('reassignedSpectrogram', sampleRate);
617
+ assertPositiveInteger('reassignedSpectrogram', nFft, 'nFft');
618
+ assertPositiveInteger('reassignedSpectrogram', hopLength, 'hopLength');
619
+ assertFiniteScalar('reassignedSpectrogram', refPower, 'refPower');
620
+ if (refPower < 0) {
621
+ throw new RangeError('reassignedSpectrogram: refPower must be non-negative');
622
+ }
623
+ return requireModule().reassignedSpectrogram(
624
+ samples,
625
+ sampleRate,
626
+ nFft,
627
+ hopLength,
628
+ refPower,
629
+ fillNan,
630
+ );
631
+ }
632
+
527
633
  // ============================================================================
528
634
  // Features - Inverse reconstruction
529
635
  // ============================================================================
@@ -663,6 +769,59 @@ export function melToAudio(
663
769
  );
664
770
  }
665
771
 
772
+ /** Reconstruct audio from an STFT magnitude matrix via Griffin-Lim. */
773
+ export function griffinLim(request: GriffinLimRequest): Float32Array;
774
+ export function griffinLim(
775
+ magnitude: Float32Array,
776
+ nBins: number,
777
+ nFrames: number,
778
+ sampleRate?: number,
779
+ nFft?: number,
780
+ hopLength?: number,
781
+ nIter?: number,
782
+ momentum?: number,
783
+ options?: GuardedOptions,
784
+ ): Float32Array;
785
+ export function griffinLim(
786
+ magnitude: Float32Array | GriffinLimRequest,
787
+ nBins = 0,
788
+ nFrames = 0,
789
+ sampleRate = 22050,
790
+ nFft = 2048,
791
+ hopLength = 512,
792
+ nIter = 32,
793
+ momentum = 0.99,
794
+ options: GuardedOptions = {},
795
+ ): Float32Array {
796
+ if (!(magnitude instanceof Float32Array)) {
797
+ const request = magnitude;
798
+ return griffinLim(
799
+ request.magnitude,
800
+ request.nBins,
801
+ request.nFrames,
802
+ request.sampleRate,
803
+ request.nFft,
804
+ request.hopLength,
805
+ request.nIter,
806
+ request.momentum,
807
+ request,
808
+ );
809
+ }
810
+ assertSampleRate('griffinLim', sampleRate);
811
+ validateMatrix('griffinLim', magnitude, nBins, nFrames, 'magnitude', 'nBins', options);
812
+ validatePositiveIntegers('griffinLim', { nFft, hopLength, nIter });
813
+ return requireModule().griffinLim(
814
+ magnitude,
815
+ nBins,
816
+ nFrames,
817
+ sampleRate,
818
+ nFft,
819
+ hopLength,
820
+ nIter,
821
+ momentum,
822
+ );
823
+ }
824
+
666
825
  /**
667
826
  * Invert MFCC coefficients back to a Mel power spectrogram. Mirrors
668
827
  * `feature::mfcc_to_mel`.
package/src/features.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export {
2
2
  amplitudeToDb,
3
+ chirp,
4
+ clicks,
3
5
  cyclicTempogram,
4
6
  dbToAmplitude,
5
7
  dbToPower,
@@ -15,6 +17,7 @@ export {
15
17
  melToHz,
16
18
  midiToHz,
17
19
  noteToHz,
20
+ onsetBacktrack,
18
21
  padCenter,
19
22
  pcen,
20
23
  peakPick,
@@ -25,6 +28,7 @@ export {
25
28
  splitSilence,
26
29
  tempogram,
27
30
  timeToFrames,
31
+ tone,
28
32
  tonnetz,
29
33
  trimSilence,
30
34
  vectorNormalize,
@@ -47,7 +51,7 @@ export {
47
51
  vqt,
48
52
  vqtToAudio,
49
53
  } from './feature_music';
50
- export { pitchPyin, pitchYin } from './feature_pitch';
54
+ export { noteSegments, piptrack, pitchPyin, pitchYin } from './feature_pitch';
51
55
  export { resample } from './feature_resample';
52
56
  export {
53
57
  decompose,
@@ -62,10 +66,18 @@ export {
62
66
  polyFeatures,
63
67
  remix,
64
68
  rmsEnergy,
69
+ segmentAgglomerative,
70
+ segmentCrossSimilarity,
71
+ segmentLagToRecurrence,
72
+ segmentPathEnhance,
73
+ segmentRecurrenceMatrix,
74
+ segmentRecurrenceToLag,
75
+ segmentSubsegment,
65
76
  spectralBandwidth,
66
77
  spectralCentroid,
67
78
  spectralContrast,
68
79
  spectralFlatness,
80
+ spectralFlux,
69
81
  spectralRolloff,
70
82
  zeroCrossingRate,
71
83
  zeroCrossings,
@@ -75,12 +87,15 @@ export {
75
87
  chroma,
76
88
  chromaCens,
77
89
  chromaCqt,
90
+ griffinLim,
91
+ melDelta,
78
92
  melSpectrogram,
79
93
  melToAudio,
80
94
  melToStft,
81
95
  mfcc,
82
96
  mfccToAudio,
83
97
  mfccToMel,
98
+ reassignedSpectrogram,
84
99
  stft,
85
100
  stftDb,
86
101
  trim,
package/src/index.ts CHANGED
@@ -19,7 +19,12 @@
19
19
  */
20
20
 
21
21
  import { setSonareModule } from './module_state';
22
- import type { RealtimeVoiceChangerPodConfig, VoicePresetId } from './public_types';
22
+ import type {
23
+ CapabilityCatalog,
24
+ RealtimeVoiceChangerPodConfig,
25
+ SonareCapabilities,
26
+ VoicePresetId,
27
+ } from './public_types';
23
28
  import type {
24
29
  SonareModule,
25
30
  WasmDecomposeResult,
@@ -32,9 +37,11 @@ export { Audio } from './audio';
32
37
  export type {
33
38
  ClipPageStreamerEngine,
34
39
  ClipPageStreamerOptions,
40
+ ClipPageStreamerRequest,
35
41
  ClipPageStreamSource,
36
42
  OpfsClipStream,
37
43
  OpfsClipStreamOptions,
44
+ WorkletOpfsClipStreamHost,
38
45
  } from './clip_page_streamer';
39
46
  export { attachOpfsClipStream, ClipPageStreamer } from './clip_page_streamer';
40
47
  export type {
@@ -61,6 +68,7 @@ export type {
61
68
  MasteringProcessorCatalogEntry,
62
69
  MasteringProcessRequest,
63
70
  MasteringProcessStereoRequest,
71
+ MasteringRealtimeCost,
64
72
  MasteringRepairDeclickRequest,
65
73
  MasteringRepairDeclipRequest,
66
74
  MasteringRepairDecrackleRequest,
@@ -151,18 +159,22 @@ export type {
151
159
  } from './effects_transform';
152
160
  export { ErrorCode, isSonareError, SonareError } from './errors';
153
161
  export type {
162
+ ChirpRequest,
163
+ ClicksRequest,
154
164
  CyclicTempogramRequest,
155
165
  DbConversionRequest,
156
166
  EmphasisRequest,
157
167
  FixFramesRequest,
158
168
  FixLengthRequest,
159
169
  FrameSignalRequest,
170
+ OnsetBacktrackRequest,
160
171
  PadCenterRequest,
161
172
  PcenRequest,
162
173
  PeakPickRequest,
163
174
  PlpRequest,
164
175
  SilenceRequest,
165
176
  TempogramRequest,
177
+ ToneRequest,
166
178
  TonnetzRequest,
167
179
  VectorNormalizeRequest,
168
180
  } from './feature_core';
@@ -181,7 +193,12 @@ export type {
181
193
  VqtRequest,
182
194
  VqtToAudioRequest,
183
195
  } from './feature_music';
184
- export type { PitchPyinRequest, PitchYinRequest } from './feature_pitch';
196
+ export type {
197
+ NoteSegmentsRequest,
198
+ PiptrackRequest,
199
+ PitchPyinRequest,
200
+ PitchYinRequest,
201
+ } from './feature_pitch';
185
202
  export type { ResampleRequest } from './feature_resample';
186
203
  export type {
187
204
  DecomposeRequest,
@@ -195,6 +212,13 @@ export type {
195
212
  PitchTuningRequest,
196
213
  PolyFeaturesRequest,
197
214
  RemixRequest,
215
+ SegmentAgglomerativeRequest,
216
+ SegmentCrossSimilarityRequest,
217
+ SegmentLagToRecurrenceRequest,
218
+ SegmentPathEnhanceRequest,
219
+ SegmentRecurrenceMatrixRequest,
220
+ SegmentRecurrenceToLagRequest,
221
+ SegmentSubsegmentRequest,
198
222
  SpectralContrastRequest,
199
223
  SpectralFrameRequest,
200
224
  SpectralRolloffRequest,
@@ -203,12 +227,15 @@ export type {
203
227
  } from './feature_spectral';
204
228
  export type {
205
229
  ChromaSpectrogramRequest,
230
+ GriffinLimRequest,
231
+ MelDeltaRequest,
206
232
  MelSpectrogramRequest,
207
233
  MelToAudioRequest,
208
234
  MelToStftRequest,
209
235
  MfccRequest,
210
236
  MfccToAudioRequest,
211
237
  MfccToMelRequest,
238
+ ReassignedSpectrogramRequest,
212
239
  SpectrogramRequest,
213
240
  TrimRequest,
214
241
  } from './feature_spectrogram';
@@ -217,9 +244,11 @@ export {
217
244
  analyzeMelody,
218
245
  analyzeSections,
219
246
  bassChroma,
247
+ chirp,
220
248
  chroma,
221
249
  chromaCens,
222
250
  chromaCqt,
251
+ clicks,
223
252
  cqt,
224
253
  cqtToAudio,
225
254
  cyclicTempogram,
@@ -236,6 +265,7 @@ export {
236
265
  frameSignal,
237
266
  framesToSamples,
238
267
  framesToTime,
268
+ griffinLim,
239
269
  hpssWithResidual,
240
270
  hybridCqt,
241
271
  hzToMel,
@@ -243,6 +273,7 @@ export {
243
273
  hzToNote,
244
274
  lufs,
245
275
  lufsInterleaved,
276
+ melDelta,
246
277
  melSpectrogram,
247
278
  melToAudio,
248
279
  melToHz,
@@ -254,13 +285,16 @@ export {
254
285
  momentaryLufs,
255
286
  nnFilter,
256
287
  nnlsChroma,
288
+ noteSegments,
257
289
  noteToHz,
290
+ onsetBacktrack,
258
291
  onsetEnvelope,
259
292
  onsetStrengthMulti,
260
293
  padCenter,
261
294
  pcen,
262
295
  peakPick,
263
296
  phaseVocoder,
297
+ piptrack,
264
298
  pitchPyin,
265
299
  pitchTuning,
266
300
  pitchYin,
@@ -269,15 +303,24 @@ export {
269
303
  powerToDb,
270
304
  preemphasis,
271
305
  pseudoCqt,
306
+ reassignedSpectrogram,
272
307
  remix,
273
308
  resample,
274
309
  rmsEnergy,
275
310
  samplesToFrames,
311
+ segmentAgglomerative,
312
+ segmentCrossSimilarity,
313
+ segmentLagToRecurrence,
314
+ segmentPathEnhance,
315
+ segmentRecurrenceMatrix,
316
+ segmentRecurrenceToLag,
317
+ segmentSubsegment,
276
318
  shortTermLufs,
277
319
  spectralBandwidth,
278
320
  spectralCentroid,
279
321
  spectralContrast,
280
322
  spectralFlatness,
323
+ spectralFlux,
281
324
  spectralRolloff,
282
325
  splitSilence,
283
326
  stft,
@@ -285,6 +328,7 @@ export {
285
328
  tempogram,
286
329
  tempogramRatio,
287
330
  timeToFrames,
331
+ tone,
288
332
  tonnetz,
289
333
  trim,
290
334
  trimSilence,
@@ -361,6 +405,9 @@ export type {
361
405
  BuiltinSynthBinding,
362
406
  BuiltinSynthConfig,
363
407
  BuiltinSynthWaveform,
408
+ ExternalSeparatedStem,
409
+ ExternalSeparatedStemImportRequest,
410
+ ExternalSeparatedStemImportResult,
364
411
  MidiCcLearnOptions,
365
412
  ProjectAssistSidecar,
366
413
  ProjectAutomationCurve,
@@ -368,6 +415,7 @@ export type {
368
415
  ProjectAutomationPoint,
369
416
  ProjectBounceOptions,
370
417
  ProjectChordSymbol,
418
+ ProjectClip,
371
419
  ProjectClipCompSegment,
372
420
  ProjectClipDesc,
373
421
  ProjectClipFade,
@@ -382,6 +430,8 @@ export type {
382
430
  ProjectMidiClipResult,
383
431
  ProjectMidiEvent,
384
432
  ProjectNotePairValidation,
433
+ ProjectSource,
434
+ ProjectTrack,
385
435
  ProjectTrackDesc,
386
436
  ProjectTrackKind,
387
437
  ProjectWarpAnchor,
@@ -401,6 +451,7 @@ export type {
401
451
  SynthPatch,
402
452
  } from './project';
403
453
  export {
454
+ BUILTIN_SYNTH_WAVEFORMS,
404
455
  EXPECTED_PROJECT_ABI_VERSION,
405
456
  MarkerKind,
406
457
  Project,
@@ -427,6 +478,7 @@ export type {
427
478
  AnalyzeTimbreOptions,
428
479
  AutomationCurve,
429
480
  Beat,
481
+ BpmHypothesis,
430
482
  Chord,
431
483
  ChordAnalysisResult,
432
484
  ChordDetectionOptions,
@@ -450,9 +502,11 @@ export type {
450
502
  MasteringChainConfig,
451
503
  MasteringChainResult,
452
504
  MasteringChainStereoResult,
505
+ MasteringLoudnessSummary,
453
506
  MasteringOptions,
454
507
  MasteringPreset,
455
508
  MasteringProcessorParams,
509
+ MasteringReport,
456
510
  MasteringResult,
457
511
  MasteringStereoChainResult,
458
512
  MasteringStereoResult,
@@ -466,6 +520,7 @@ export type {
466
520
  MixMeterSnapshot,
467
521
  MixOptions,
468
522
  MixResult,
523
+ NoteSegment,
469
524
  NoteStretchOptions,
470
525
  PairAnalysis,
471
526
  PairProcessor,
@@ -483,8 +538,10 @@ export type {
483
538
  RoomGeometryOptions,
484
539
  RoomMorphOptions,
485
540
  Section,
541
+ SegmentMatrix,
486
542
  SendTiming,
487
543
  SoloProcessor,
544
+ SonareCapabilities,
488
545
  SpectralEditMode,
489
546
  SpectralEditOptions,
490
547
  SpectralEditWindow,
@@ -522,6 +579,7 @@ export type {
522
579
  DetectAcousticRequest,
523
580
  DetectChordsRequest,
524
581
  DetectKeyRequest,
582
+ DetectOnsetsRequest,
525
583
  DynamicsAnalysisResult,
526
584
  EstimateRoomRequest,
527
585
  MusicAnalyzeRequest,
@@ -560,6 +618,7 @@ export type {
560
618
  EngineBounceResult,
561
619
  EngineBus,
562
620
  EngineCapabilities,
621
+ EngineCaptureSource,
563
622
  EngineCaptureStatus,
564
623
  EngineClip,
565
624
  EngineFreezeOptions,
@@ -582,7 +641,12 @@ export type {
582
641
  ExternalMidiEvent,
583
642
  MidiCcBindOptions,
584
643
  } from './realtime_engine';
585
- export { EXPECTED_ENGINE_ABI_VERSION, engineCapabilities, RealtimeEngine } from './realtime_engine';
644
+ export {
645
+ ClipPageProvider,
646
+ EXPECTED_ENGINE_ABI_VERSION,
647
+ engineCapabilities,
648
+ RealtimeEngine,
649
+ } from './realtime_engine';
586
650
  export { scaleCorrectionSemitones, scalePitchClassEnabled, scaleQuantizeMidi } from './scale';
587
651
  export type { ProgressCallback } from './sonare.js';
588
652
  export { StreamAnalyzer, streamAnalyzerConfigDefaults } from './stream_analyzer';
@@ -623,6 +687,13 @@ export type {
623
687
  WebMidiInputInfo,
624
688
  } from './web_midi';
625
689
  export { bindWebMidi, isWebMidiAvailable } from './web_midi';
690
+ export type {
691
+ OfflineWorker,
692
+ OfflineWorkerCallOptions,
693
+ OfflineWorkerClientOptions,
694
+ OfflineWorkerProgress,
695
+ } from './worker_client';
696
+ export { OfflineWorkerClient, OfflineWorkerTask } from './worker_client';
626
697
 
627
698
  /** Row-major 2-D matrix as a flat buffer plus its dimensions. */
628
699
  export type Matrix2dResult = WasmMatrix2dResult;
@@ -696,6 +767,26 @@ export function version(): string {
696
767
  return module.version();
697
768
  }
698
769
 
770
+ /**
771
+ * Return the capabilities of the loaded WASM build.
772
+ *
773
+ * This is synchronous and only describes the already-initialized module.
774
+ */
775
+ export function capabilities(): SonareCapabilities {
776
+ if (!module) {
777
+ throw new Error('Module not initialized. Call init() first.');
778
+ }
779
+ return module.capabilities();
780
+ }
781
+
782
+ /** Return the initialized module's processors, parameters, and presets. */
783
+ export function capabilityCatalog(): CapabilityCatalog {
784
+ if (!module) {
785
+ throw new Error('Module not initialized. Call init() first.');
786
+ }
787
+ return JSON.parse(module.capabilityCatalog()) as CapabilityCatalog;
788
+ }
789
+
699
790
  /**
700
791
  * Aggregate native ABI version: the per-subsystem ABI macros folded into one
701
792
  * 32-bit value. It bumps whenever any flat C POD layout changes, so callers can
@@ -735,6 +826,9 @@ const VOICE_PRESET_ORDINALS: readonly VoicePresetId[] = [
735
826
 
736
827
  function resolveVoicePresetOrdinal(preset: VoicePresetId | number): number {
737
828
  if (typeof preset === 'number') {
829
+ if (!Number.isSafeInteger(preset) || preset < 0 || preset >= VOICE_PRESET_ORDINALS.length) {
830
+ throw new RangeError(`Unknown voice-character preset ordinal: ${String(preset)}`);
831
+ }
738
832
  return preset;
739
833
  }
740
834
  const ordinal = VOICE_PRESET_ORDINALS.indexOf(preset);
@@ -746,9 +840,9 @@ function resolveVoicePresetOrdinal(preset: VoicePresetId | number): number {
746
840
 
747
841
  /**
748
842
  * Map a voice-character preset ordinal (or canonical id) to its canonical id
749
- * string (e.g. `'bright-idol'`). Returns `null` for an out-of-range ordinal.
843
+ * string (e.g. `'bright-idol'`). Invalid ordinals throw.
750
844
  */
751
- export function voiceCharacterPresetId(preset: VoicePresetId | number): string | null {
845
+ export function voiceCharacterPresetId(preset: VoicePresetId | number): string {
752
846
  if (!module) {
753
847
  throw new Error('Module not initialized. Call init() first.');
754
848
  }
@@ -758,11 +852,11 @@ export function voiceCharacterPresetId(preset: VoicePresetId | number): string |
758
852
  /**
759
853
  * Return the canonical (normalized) flat POD config for a built-in voice
760
854
  * preset, skipping the JSON round-trip. Accepts a canonical preset id or its
761
- * integer ordinal. Returns `null` for an out-of-range ordinal.
855
+ * integer ordinal. Invalid ordinals throw.
762
856
  */
763
857
  export function realtimeVoiceChangerPresetConfig(
764
858
  preset: VoicePresetId | number,
765
- ): RealtimeVoiceChangerPodConfig | null {
859
+ ): RealtimeVoiceChangerPodConfig {
766
860
  if (!module) {
767
861
  throw new Error('Module not initialized. Call init() first.');
768
862
  }