@libraz/libsonare 1.1.0 → 1.2.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.
@@ -24,10 +24,44 @@ export type PitchClass = (typeof PitchClass)[keyof typeof PitchClass];
24
24
  export const Mode = {
25
25
  Major: 0,
26
26
  Minor: 1,
27
+ Dorian: 2,
28
+ Phrygian: 3,
29
+ Lydian: 4,
30
+ Mixolydian: 5,
31
+ Locrian: 6,
27
32
  } as const;
28
33
 
29
34
  export type Mode = (typeof Mode)[keyof typeof Mode];
30
35
 
36
+ export type TempogramMode = 'autocorrelation' | 'auto' | 'ac' | 'cosine' | 0 | 1;
37
+
38
+ export const KeyProfile = {
39
+ KrumhanslSchmuckler: 0,
40
+ Temperley: 1,
41
+ Shaath: 2,
42
+ FaraldoEDMT: 3,
43
+ FaraldoEDMA: 4,
44
+ FaraldoEDMM: 5,
45
+ BellmanBudge: 6,
46
+ } as const;
47
+
48
+ export type KeyProfile = (typeof KeyProfile)[keyof typeof KeyProfile];
49
+
50
+ export type KeyProfileName =
51
+ | 'ks'
52
+ | 'krumhansl'
53
+ | 'temperley'
54
+ | 'shaath'
55
+ | 'keyfinder'
56
+ | 'faraldo-edmt'
57
+ | 'edmt'
58
+ | 'faraldo-edma'
59
+ | 'edma'
60
+ | 'faraldo-edmm'
61
+ | 'edmm'
62
+ | 'bellman-budge'
63
+ | 'bellman';
64
+
31
65
  /**
32
66
  * Chord quality
33
67
  */
@@ -41,10 +75,134 @@ export const ChordQuality = {
41
75
  Minor7: 6,
42
76
  Sus2: 7,
43
77
  Sus4: 8,
78
+ Unknown: 9,
79
+ Add9: 10,
80
+ MinorAdd9: 11,
81
+ Dim7: 12,
82
+ HalfDim7: 13,
83
+ Major9: 14,
84
+ Dominant9: 15,
85
+ Sus2Add4: 16,
44
86
  } as const;
45
87
 
46
88
  export type ChordQuality = (typeof ChordQuality)[keyof typeof ChordQuality];
47
89
 
90
+ export type MasteringPreset =
91
+ | 'pop'
92
+ | 'edm'
93
+ | 'acoustic'
94
+ | 'hipHop'
95
+ | 'aiMusic'
96
+ | 'speech'
97
+ | 'streaming'
98
+ | 'youtube'
99
+ | 'broadcast'
100
+ | 'podcast'
101
+ | 'audiobook'
102
+ | 'cinema'
103
+ | 'jpop'
104
+ | 'ambient'
105
+ | 'lofi'
106
+ | 'classical'
107
+ | 'drumAndBass'
108
+ | 'techno'
109
+ | 'metal'
110
+ | 'trap'
111
+ | 'rnb'
112
+ | 'jazz'
113
+ | 'kpop'
114
+ | 'trance'
115
+ | 'gameOst';
116
+
117
+ export interface StreamingPlatform {
118
+ name: string;
119
+ targetLufs: number;
120
+ ceilingDb: number;
121
+ }
122
+
123
+ export type SoloProcessor =
124
+ | 'dynamics.brickwallLimiter'
125
+ | 'dynamics.compressor'
126
+ | 'dynamics.deesser'
127
+ | 'dynamics.expander'
128
+ | 'dynamics.gate'
129
+ | 'dynamics.limiter'
130
+ | 'dynamics.parallelComp'
131
+ | 'dynamics.sidechainRouter'
132
+ | 'dynamics.duckingProcessor'
133
+ | 'dynamics.transientShaper'
134
+ | 'dynamics.upwardCompressor'
135
+ | 'dynamics.upwardExpander'
136
+ | 'dynamics.vocalRider'
137
+ | 'eq.apiStyle'
138
+ | 'eq.bandPass'
139
+ | 'eq.cutFilter'
140
+ | 'eq.dynamic'
141
+ | 'eq.equalizer'
142
+ | 'eq.graphic'
143
+ | 'eq.linearPhase'
144
+ | 'eq.midSide'
145
+ | 'eq.minimumPhase'
146
+ | 'eq.parametric'
147
+ | 'eq.pultec'
148
+ | 'eq.shelving'
149
+ | 'eq.tilt'
150
+ | 'final.bitDepth'
151
+ | 'final.dither'
152
+ | 'final.outputChain'
153
+ | 'maximizer.adaptiveRelease'
154
+ | 'maximizer.loudnessOptimize'
155
+ | 'maximizer.maximizer'
156
+ | 'maximizer.softKneeMax'
157
+ | 'maximizer.truePeakLimiter'
158
+ | 'multiband.compressor'
159
+ | 'multiband.dynamicEq'
160
+ | 'multiband.expander'
161
+ | 'multiband.imager'
162
+ | 'multiband.limiter'
163
+ | 'multiband.saturation'
164
+ | 'repair.declick'
165
+ | 'repair.declip'
166
+ | 'repair.decrackle'
167
+ | 'repair.dehum'
168
+ | 'repair.denoiseClassical'
169
+ | 'repair.dereverbClassical'
170
+ | 'repair.trimSilence'
171
+ | 'saturation.bitcrusher'
172
+ | 'saturation.exciter'
173
+ | 'saturation.hardClipper'
174
+ | 'saturation.multibandExciter'
175
+ | 'saturation.softClipper'
176
+ | 'saturation.tape'
177
+ | 'saturation.transformer'
178
+ | 'saturation.tube'
179
+ | 'saturation.waveshaper'
180
+ | 'spectral.airBand'
181
+ | 'spectral.lowEndFocus'
182
+ | 'spectral.presenceEnhancer'
183
+ | 'spectral.spectralShaper'
184
+ | 'stereo.autoPan'
185
+ | 'stereo.haasEnhancer'
186
+ | 'stereo.imager'
187
+ | 'stereo.monoMaker'
188
+ | 'stereo.phaseAlign'
189
+ | 'stereo.stereoBalance';
190
+
191
+ export type PairProcessor =
192
+ | 'match.applyMatchEq'
193
+ | 'match.alignReferenceToSource'
194
+ | 'match.abSwitch'
195
+ | 'match.abCrossfade';
196
+
197
+ export type PairAnalysis =
198
+ | 'match.referenceLoudness'
199
+ | 'match.tonalBalance'
200
+ | 'match.tonalBalanceLogBands'
201
+ | 'match.matchEqCurve'
202
+ | 'match.estimateReferenceDelaySamples';
203
+
204
+ export type StereoAnalysis = 'stereo.monoCompatCheck' | 'stereo.monoCompatCheckLogBands';
205
+
48
206
  /**
49
207
  * Section type
50
208
  */
@@ -56,6 +214,7 @@ export const SectionType = {
56
214
  Bridge: 4,
57
215
  Instrumental: 5,
58
216
  Outro: 6,
217
+ Unknown: 7,
59
218
  } as const;
60
219
 
61
220
  export type SectionType = (typeof SectionType)[keyof typeof SectionType];
@@ -71,6 +230,44 @@ export interface Key {
71
230
  shortName: string;
72
231
  }
73
232
 
233
+ export interface KeyDetectionOptions {
234
+ nFft?: number;
235
+ hopLength?: number;
236
+ useHpss?: boolean;
237
+ loudnessWeighted?: boolean;
238
+ highPassHz?: number;
239
+ modes?:
240
+ | Mode[]
241
+ | ('major' | 'minor' | 'dorian' | 'phrygian' | 'lydian' | 'mixolydian' | 'locrian')[]
242
+ | 'major-minor'
243
+ | 'all'
244
+ | 'modal';
245
+ profile?: KeyProfile | KeyProfileName;
246
+ genreHint?: 'auto' | 'edm' | 'electronic' | 'dance' | 'pop' | 'classical' | 'jazz' | string;
247
+ }
248
+
249
+ export interface KeyCandidate {
250
+ key: Key;
251
+ correlation: number;
252
+ }
253
+
254
+ export interface ChordDetectionOptions {
255
+ minDuration?: number;
256
+ smoothingWindow?: number;
257
+ threshold?: number;
258
+ useTriadsOnly?: boolean;
259
+ nFft?: number;
260
+ hopLength?: number;
261
+ useBeatSync?: boolean;
262
+ useHmm?: boolean;
263
+ hmmBeamWidth?: number;
264
+ useKeyContext?: boolean;
265
+ keyRoot?: PitchClass;
266
+ keyMode?: Mode;
267
+ detectInversions?: boolean;
268
+ chromaMethod?: 'stft' | 'nnls';
269
+ }
270
+
74
271
  /**
75
272
  * Detected beat
76
273
  */
@@ -84,6 +281,7 @@ export interface Beat {
84
281
  */
85
282
  export interface Chord {
86
283
  root: PitchClass;
284
+ bass: PitchClass;
87
285
  quality: ChordQuality;
88
286
  start: number;
89
287
  end: number;
@@ -91,6 +289,10 @@ export interface Chord {
91
289
  name: string;
92
290
  }
93
291
 
292
+ export interface ChordAnalysisResult {
293
+ chords: Chord[];
294
+ }
295
+
94
296
  /**
95
297
  * Detected section
96
298
  */
@@ -103,6 +305,48 @@ export interface Section {
103
305
  name: string;
104
306
  }
105
307
 
308
+ /**
309
+ * A single melody contour point (mirrors the C `SonareMelodyPoint`).
310
+ */
311
+ export interface MelodyPoint {
312
+ /** Frame time in seconds. */
313
+ time: number;
314
+ /** Estimated fundamental frequency in Hz (0 when unvoiced). */
315
+ frequency: number;
316
+ /** Voicing confidence in `[0, 1]`. */
317
+ confidence: number;
318
+ }
319
+
320
+ /**
321
+ * Melody analysis result (mirrors the C `SonareMelodyResult`).
322
+ */
323
+ export interface MelodyResult {
324
+ points: MelodyPoint[];
325
+ pitchRangeOctaves: number;
326
+ pitchStability: number;
327
+ meanFrequency: number;
328
+ vibratoRate: number;
329
+ }
330
+
331
+ /**
332
+ * Constant-Q / Variable-Q transform magnitude result (mirrors the C
333
+ * `SonareCqtResult`).
334
+ */
335
+ export interface CqtResult {
336
+ /** Number of frequency bins. */
337
+ nBins: number;
338
+ /** Number of time frames. */
339
+ nFrames: number;
340
+ /** Hop length in samples. */
341
+ hopLength: number;
342
+ /** Sample rate in Hz. */
343
+ sampleRate: number;
344
+ /** Row-major `[nBins x nFrames]` magnitude matrix. */
345
+ magnitude: Float32Array;
346
+ /** Center frequency (Hz) of each of the `nBins` bins. */
347
+ frequencies: Float32Array;
348
+ }
349
+
106
350
  /**
107
351
  * Timbre characteristics
108
352
  */
@@ -160,6 +404,23 @@ export interface AnalysisResult {
160
404
  form: string;
161
405
  }
162
406
 
407
+ /**
408
+ * Room acoustic parameters from an impulse response
409
+ */
410
+ export interface AcousticResult {
411
+ rt60: number;
412
+ edt: number;
413
+ c50: number;
414
+ c80: number;
415
+ d50: number;
416
+ rt60Bands: Float32Array;
417
+ edtBands: Float32Array;
418
+ c50Bands: Float32Array;
419
+ c80Bands: Float32Array;
420
+ confidence: number;
421
+ isBlind: boolean;
422
+ }
423
+
163
424
  /**
164
425
  * HPSS (Harmonic-Percussive Source Separation) result
165
426
  */
@@ -183,6 +444,78 @@ export interface MasteringResult {
183
444
 
184
445
  export type MasteringProcessorParams = Record<string, number | boolean>;
185
446
 
447
+ export type PanMode = 'balance' | 'stereoPan' | 'stereo-pan' | 'dualPan' | 'dual-pan' | number;
448
+
449
+ export interface MixOptions {
450
+ inputTrimDb?: number | number[];
451
+ faderDb?: number | number[];
452
+ pan?: number | number[];
453
+ panMode?: PanMode | PanMode[];
454
+ width?: number | number[];
455
+ muted?: boolean | boolean[];
456
+ }
457
+
458
+ export interface MixMeterSnapshot {
459
+ peakDbL: number;
460
+ peakDbR: number;
461
+ rmsDbL: number;
462
+ rmsDbR: number;
463
+ correlation: number;
464
+ monoCompatWidth: number;
465
+ monoCompatPeak: number;
466
+ monoCompatSideRms: number;
467
+ likelyMonoCompatible: boolean;
468
+ momentaryLufs: number;
469
+ shortTermLufs: number;
470
+ integratedLufs: number;
471
+ gainReductionDb: number;
472
+ truePeakDbL: number;
473
+ truePeakDbR: number;
474
+ maxTruePeakDb: number;
475
+ seq: number;
476
+ }
477
+
478
+ export interface MixResult {
479
+ left: Float32Array;
480
+ right: Float32Array;
481
+ sampleRate: number;
482
+ meters: MixMeterSnapshot[];
483
+ }
484
+
485
+ /** Mixed stereo master returned by {@link Mixer.processStereo}. */
486
+ export interface MixerProcessResult {
487
+ left: Float32Array;
488
+ right: Float32Array;
489
+ sampleRate: number;
490
+ }
491
+
492
+ /**
493
+ * Interpolation curve for scheduled automation events
494
+ * (see {@link Mixer.scheduleInsertAutomation}).
495
+ */
496
+ export type AutomationCurve = 'linear' | 'exponential' | 'hold' | 's-curve';
497
+
498
+ /**
499
+ * Pan law applied when computing left/right gains from a pan position
500
+ * (see {@link Mixer.setPanLaw}). Maps to the underlying integer code.
501
+ */
502
+ export type PanLaw = 'const3dB' | 'const4.5dB' | 'const6dB' | 'linear0dB';
503
+
504
+ /**
505
+ * Meter tap point for reading a strip's meter snapshot
506
+ * (see {@link Mixer.meterTap} and {@link Mixer.stripMeter}).
507
+ */
508
+ export type MeterTap = 'preFader' | 'postFader';
509
+
510
+ /** Pre/post-fader send timing (see {@link Mixer.addSend}). */
511
+ export type SendTiming = 'preFader' | 'postFader';
512
+
513
+ /** A single goniometer (left/right) sample returned by {@link Mixer.readGoniometerLatest}. */
514
+ export interface GoniometerPoint {
515
+ left: number;
516
+ right: number;
517
+ }
518
+
186
519
  export interface MasteringChainConfig {
187
520
  repair?: {
188
521
  denoise?: boolean;
@@ -233,6 +566,7 @@ export interface MasteringChainConfig {
233
566
  attackMs?: number;
234
567
  releaseMs?: number;
235
568
  rangeDb?: number;
569
+ bandpassQ?: number;
236
570
  };
237
571
  transientShaper?: {
238
572
  attackGainDb?: number;
@@ -376,6 +710,24 @@ export interface MfccResult {
376
710
  coefficients: Float32Array;
377
711
  }
378
712
 
713
+ /**
714
+ * STFT power spectrogram result (from inverse Mel reconstruction)
715
+ */
716
+ export interface StftPowerResult {
717
+ nBins: number;
718
+ nFrames: number;
719
+ power: Float32Array;
720
+ }
721
+
722
+ /**
723
+ * Mel power spectrogram result (from inverse MFCC reconstruction)
724
+ */
725
+ export interface MelPowerResult {
726
+ nMels: number;
727
+ nFrames: number;
728
+ power: Float32Array;
729
+ }
730
+
379
731
  /**
380
732
  * Chroma features result
381
733
  */
@@ -399,3 +751,102 @@ export interface PitchResult {
399
751
  medianF0: number;
400
752
  meanF0: number;
401
753
  }
754
+
755
+ /**
756
+ * Loudness measurement result (EBU R128 / ITU-R BS.1770)
757
+ */
758
+ export interface LufsResult {
759
+ integratedLufs: number;
760
+ momentaryLufs: number;
761
+ shortTermLufs: number;
762
+ loudnessRange: number;
763
+ }
764
+
765
+ /**
766
+ * Realtime equalizer spectrum snapshot.
767
+ *
768
+ * Mirrors the C++ `EqualizerSpectrumSnapshot`: `preLeft`/`preRight` and
769
+ * `postLeft`/`postRight` are the pre- and post-EQ spectrum streams (trimmed to
770
+ * their valid count). `bandGainDb` holds per-band applied gain (24 entries),
771
+ * `profileDb` the smoothed magnitude profile (16 entries), `lastAutoGainDb`
772
+ * the latest auto-gain compensation, and `seq` increments each time a new
773
+ * snapshot is published.
774
+ */
775
+ export interface EqSpectrumSnapshot {
776
+ preLeft: Float32Array;
777
+ preRight: Float32Array;
778
+ postLeft: Float32Array;
779
+ postRight: Float32Array;
780
+ bandGainDb: Float32Array;
781
+ profileDb: Float32Array;
782
+ lastAutoGainDb: number;
783
+ seq: number;
784
+ }
785
+
786
+ /**
787
+ * Equalizer band type (string union mirroring `sonare::mastering::eq::EqBandType`).
788
+ */
789
+ export type EqBandType =
790
+ | 'Peak'
791
+ | 'LowShelf'
792
+ | 'HighShelf'
793
+ | 'LowPass'
794
+ | 'HighPass'
795
+ | 'BandPass'
796
+ | 'Notch'
797
+ | 'TiltShelf'
798
+ | 'FlatTilt';
799
+
800
+ /** Biquad coefficient design mode. */
801
+ export type EqCoeffMode = 'Rbj' | 'Vicanek';
802
+
803
+ /** Stereo placement for an EQ band. */
804
+ export type EqStereoPlacement = 'Stereo' | 'Left' | 'Right' | 'Mid' | 'Side';
805
+
806
+ /** Per-band phase behaviour. */
807
+ export type EqBandPhase = 'Inherit' | 'ZeroLatency' | 'NaturalPhase' | 'LinearPhase';
808
+
809
+ /**
810
+ * Equalizer band configuration accepted by {@link StreamingEqualizer.setBand}.
811
+ *
812
+ * All fields are optional; omitted values fall back to the C++ band defaults
813
+ * (Peak, 1000 Hz, 0 dB gain, Butterworth Q, disabled).
814
+ */
815
+ export interface EqBand {
816
+ type?: EqBandType;
817
+ frequencyHz?: number;
818
+ gainDb?: number;
819
+ q?: number;
820
+ enabled?: boolean;
821
+ coeffMode?: EqCoeffMode;
822
+ slopeDbOct?: number;
823
+ placement?: EqStereoPlacement;
824
+ phase?: EqBandPhase;
825
+ soloed?: boolean;
826
+ bypassed?: boolean;
827
+ proportionalQ?: boolean;
828
+ proportionalQStrength?: number;
829
+ dynamic?: boolean;
830
+ thresholdDb?: number;
831
+ autoThreshold?: boolean;
832
+ ratio?: number;
833
+ rangeDb?: number;
834
+ attackMs?: number;
835
+ releaseMs?: number;
836
+ lookaheadMs?: number;
837
+ externalSidechain?: boolean;
838
+ sidechainFreqHz?: number;
839
+ sidechainQ?: number;
840
+ }
841
+
842
+ /** Construction options for {@link StreamingEqualizer}. */
843
+ export interface StreamingEqualizerConfig {
844
+ sampleRate?: number;
845
+ maxBlockSize?: number;
846
+ }
847
+
848
+ /** Options for {@link StreamingEqualizer.match}. */
849
+ export interface EqMatchOptions {
850
+ sampleRate?: number;
851
+ maxBands?: number;
852
+ }
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Type definitions for the standalone realtime WASM module (`sonare-rt`).
3
+ *
4
+ * This is a DELIBERATELY REDUCED surface optimized for the AudioWorklet hot
5
+ * path: a thin C ABI over {@link RealtimeEngine} that avoids embind, JS `val`
6
+ * marshalling, and string handling so the audio render quantum stays
7
+ * allocation- and GC-free. Use the full {@link RealtimeEngine} class from the
8
+ * main `sonare` bundle when you need the complete feature set.
9
+ *
10
+ * Omitted here (available only on the full embind `RealtimeEngine`):
11
+ * - Parameter registry & automation: `addParameter`, `parameterInfo`,
12
+ * `setAutomationLane`, `automationLaneCount`, `setParameter`,
13
+ * `setParameterSmoothed`.
14
+ * - Transport read-back: `getTransportState` (transport is driven from the
15
+ * worklet; state is mirrored on the main thread there).
16
+ * - Markers beyond seek: `setMarkers`, `markerCount`, `marker`,
17
+ * `setLoopFromMarkers`, `setTimeSignature`, `countInEndSample`.
18
+ * - Graph topology: `setGraph`, `graphNodeCount`, `graphConnectionCount`.
19
+ * - Clip scheduling: `setClips`, `clipCount`, `freezeOffline`.
20
+ * - Capture read-back & offline rendering: `setCaptureBuffer`, `captureStatus`,
21
+ * `capturedAudio`, `resetCapture`, `renderOffline`, `bounceOffline`.
22
+ * - Meter telemetry: `drainMeterTelemetry`.
23
+ *
24
+ * The exposed surface intentionally covers only transport, tempo/loop, marker
25
+ * seek, metronome, capture arming/punch, block processing, and basic telemetry
26
+ * drain.
27
+ */
28
+ export interface SonareRtModuleOptions {
29
+ locateFile?: (path: string, scriptDirectory: string) => string;
30
+ wasmBinary?: ArrayBuffer | Uint8Array;
31
+ wasmMemory?: WebAssembly.Memory;
32
+ print?: (...args: unknown[]) => void;
33
+ printErr?: (...args: unknown[]) => void;
34
+ }
35
+
36
+ export interface SonareRtModule {
37
+ _malloc(size: number): number;
38
+ _free(ptr: number): void;
39
+ _sonare_rt_engine_abi_version(): number;
40
+ _sonare_rt_engine_create(): number;
41
+ _sonare_rt_engine_destroy(engine: number): void;
42
+ _sonare_rt_engine_prepare(
43
+ engine: number,
44
+ sampleRate: number,
45
+ maxBlockSize: number,
46
+ commandCapacity: number,
47
+ telemetryCapacity: number,
48
+ ): number;
49
+ _sonare_rt_engine_play(engine: number, renderFrame: bigint): number;
50
+ _sonare_rt_engine_stop(engine: number, renderFrame: bigint): number;
51
+ _sonare_rt_engine_seek_sample(
52
+ engine: number,
53
+ timelineSample: bigint,
54
+ renderFrame: bigint,
55
+ ): number;
56
+ _sonare_rt_engine_seek_ppq(engine: number, ppq: number, renderFrame: bigint): number;
57
+ _sonare_rt_engine_set_tempo(engine: number, bpm: number): number;
58
+ _sonare_rt_engine_set_loop(
59
+ engine: number,
60
+ startPpq: number,
61
+ endPpq: number,
62
+ enabled: number,
63
+ ): number;
64
+ _sonare_rt_engine_seek_marker(engine: number, markerId: number, renderFrame: bigint): number;
65
+ _sonare_rt_engine_set_metronome_enabled(
66
+ engine: number,
67
+ enabled: number,
68
+ beatGain: number,
69
+ accentGain: number,
70
+ clickSamples: number,
71
+ ): number;
72
+ _sonare_rt_engine_set_capture_armed(engine: number, armed: number): number;
73
+ _sonare_rt_engine_set_capture_punch(
74
+ engine: number,
75
+ startSample: bigint,
76
+ endSample: bigint,
77
+ enabled: number,
78
+ ): number;
79
+ _sonare_rt_engine_process(
80
+ engine: number,
81
+ channelsPtr: number,
82
+ numChannels: number,
83
+ numFrames: number,
84
+ ): void;
85
+ _sonare_rt_engine_drain_telemetry(
86
+ engine: number,
87
+ typesErrorsValuesPtr: number,
88
+ frameValuesPtr: number,
89
+ maxRecords: number,
90
+ ): number;
91
+ }
92
+
93
+ export default function SonareRt(options?: SonareRtModuleOptions): Promise<SonareRtModule>;