@libraz/libsonare 1.0.4 → 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.
package/dist/index.d.ts CHANGED
@@ -1,32 +1,7 @@
1
- /**
2
- * sonare - Audio Analysis Library
3
- *
4
- * @example
5
- * ```typescript
6
- * import { init, detectBpm, detectKey, analyze } from '@libraz/sonare';
7
- *
8
- * await init();
9
- *
10
- * // Detect BPM from audio samples
11
- * const bpm = detectBpm(samples, sampleRate);
12
- *
13
- * // Detect musical key
14
- * const key = detectKey(samples, sampleRate);
15
- *
16
- * // Full analysis
17
- * const result = analyze(samples, sampleRate);
18
- * ```
19
- */
20
- /**
21
- * Progress callback for analysis progress reporting.
22
- * @param progress - Progress value (0.0 to 1.0)
23
- * @param stage - Current analysis stage name
24
- */
25
- export type ProgressCallback = (progress: number, stage: string) => void;
26
1
  /**
27
2
  * Pitch class enum (C=0, C#=1, ..., B=11)
28
3
  */
29
- export declare const PitchClass: {
4
+ declare const PitchClass: {
30
5
  readonly C: 0;
31
6
  readonly Cs: 1;
32
7
  readonly D: 2;
@@ -40,19 +15,36 @@ export declare const PitchClass: {
40
15
  readonly As: 10;
41
16
  readonly B: 11;
42
17
  };
43
- export type PitchClass = (typeof PitchClass)[keyof typeof PitchClass];
18
+ type PitchClass = (typeof PitchClass)[keyof typeof PitchClass];
44
19
  /**
45
20
  * Musical mode
46
21
  */
47
- export declare const Mode: {
22
+ declare const Mode: {
48
23
  readonly Major: 0;
49
24
  readonly Minor: 1;
25
+ readonly Dorian: 2;
26
+ readonly Phrygian: 3;
27
+ readonly Lydian: 4;
28
+ readonly Mixolydian: 5;
29
+ readonly Locrian: 6;
50
30
  };
51
- export type Mode = (typeof Mode)[keyof typeof Mode];
31
+ type Mode = (typeof Mode)[keyof typeof Mode];
32
+ type TempogramMode = 'autocorrelation' | 'auto' | 'ac' | 'cosine' | 0 | 1;
33
+ declare const KeyProfile: {
34
+ readonly KrumhanslSchmuckler: 0;
35
+ readonly Temperley: 1;
36
+ readonly Shaath: 2;
37
+ readonly FaraldoEDMT: 3;
38
+ readonly FaraldoEDMA: 4;
39
+ readonly FaraldoEDMM: 5;
40
+ readonly BellmanBudge: 6;
41
+ };
42
+ type KeyProfile = (typeof KeyProfile)[keyof typeof KeyProfile];
43
+ type KeyProfileName = 'ks' | 'krumhansl' | 'temperley' | 'shaath' | 'keyfinder' | 'faraldo-edmt' | 'edmt' | 'faraldo-edma' | 'edma' | 'faraldo-edmm' | 'edmm' | 'bellman-budge' | 'bellman';
52
44
  /**
53
45
  * Chord quality
54
46
  */
55
- export declare const ChordQuality: {
47
+ declare const ChordQuality: {
56
48
  readonly Major: 0;
57
49
  readonly Minor: 1;
58
50
  readonly Diminished: 2;
@@ -62,12 +54,30 @@ export declare const ChordQuality: {
62
54
  readonly Minor7: 6;
63
55
  readonly Sus2: 7;
64
56
  readonly Sus4: 8;
57
+ readonly Unknown: 9;
58
+ readonly Add9: 10;
59
+ readonly MinorAdd9: 11;
60
+ readonly Dim7: 12;
61
+ readonly HalfDim7: 13;
62
+ readonly Major9: 14;
63
+ readonly Dominant9: 15;
64
+ readonly Sus2Add4: 16;
65
65
  };
66
- export type ChordQuality = (typeof ChordQuality)[keyof typeof ChordQuality];
66
+ type ChordQuality = (typeof ChordQuality)[keyof typeof ChordQuality];
67
+ type MasteringPreset = 'pop' | 'edm' | 'acoustic' | 'hipHop' | 'aiMusic' | 'speech' | 'streaming' | 'youtube' | 'broadcast' | 'podcast' | 'audiobook' | 'cinema' | 'jpop' | 'ambient' | 'lofi' | 'classical' | 'drumAndBass' | 'techno' | 'metal' | 'trap' | 'rnb' | 'jazz' | 'kpop' | 'trance' | 'gameOst';
68
+ interface StreamingPlatform {
69
+ name: string;
70
+ targetLufs: number;
71
+ ceilingDb: number;
72
+ }
73
+ type SoloProcessor = 'dynamics.brickwallLimiter' | 'dynamics.compressor' | 'dynamics.deesser' | 'dynamics.expander' | 'dynamics.gate' | 'dynamics.limiter' | 'dynamics.parallelComp' | 'dynamics.sidechainRouter' | 'dynamics.duckingProcessor' | 'dynamics.transientShaper' | 'dynamics.upwardCompressor' | 'dynamics.upwardExpander' | 'dynamics.vocalRider' | 'eq.apiStyle' | 'eq.bandPass' | 'eq.cutFilter' | 'eq.dynamic' | 'eq.equalizer' | 'eq.graphic' | 'eq.linearPhase' | 'eq.midSide' | 'eq.minimumPhase' | 'eq.parametric' | 'eq.pultec' | 'eq.shelving' | 'eq.tilt' | 'final.bitDepth' | 'final.dither' | 'final.outputChain' | 'maximizer.adaptiveRelease' | 'maximizer.loudnessOptimize' | 'maximizer.maximizer' | 'maximizer.softKneeMax' | 'maximizer.truePeakLimiter' | 'multiband.compressor' | 'multiband.dynamicEq' | 'multiband.expander' | 'multiband.imager' | 'multiband.limiter' | 'multiband.saturation' | 'repair.declick' | 'repair.declip' | 'repair.decrackle' | 'repair.dehum' | 'repair.denoiseClassical' | 'repair.dereverbClassical' | 'repair.trimSilence' | 'saturation.bitcrusher' | 'saturation.exciter' | 'saturation.hardClipper' | 'saturation.multibandExciter' | 'saturation.softClipper' | 'saturation.tape' | 'saturation.transformer' | 'saturation.tube' | 'saturation.waveshaper' | 'spectral.airBand' | 'spectral.lowEndFocus' | 'spectral.presenceEnhancer' | 'spectral.spectralShaper' | 'stereo.autoPan' | 'stereo.haasEnhancer' | 'stereo.imager' | 'stereo.monoMaker' | 'stereo.phaseAlign' | 'stereo.stereoBalance';
74
+ type PairProcessor = 'match.applyMatchEq' | 'match.alignReferenceToSource' | 'match.abSwitch' | 'match.abCrossfade';
75
+ type PairAnalysis = 'match.referenceLoudness' | 'match.tonalBalance' | 'match.tonalBalanceLogBands' | 'match.matchEqCurve' | 'match.estimateReferenceDelaySamples';
76
+ type StereoAnalysis = 'stereo.monoCompatCheck' | 'stereo.monoCompatCheckLogBands';
67
77
  /**
68
78
  * Section type
69
79
  */
70
- export declare const SectionType: {
80
+ declare const SectionType: {
71
81
  readonly Intro: 0;
72
82
  readonly Verse: 1;
73
83
  readonly PreChorus: 2;
@@ -75,40 +85,75 @@ export declare const SectionType: {
75
85
  readonly Bridge: 4;
76
86
  readonly Instrumental: 5;
77
87
  readonly Outro: 6;
88
+ readonly Unknown: 7;
78
89
  };
79
- export type SectionType = (typeof SectionType)[keyof typeof SectionType];
90
+ type SectionType = (typeof SectionType)[keyof typeof SectionType];
80
91
  /**
81
92
  * Detected musical key
82
93
  */
83
- export interface Key {
94
+ interface Key {
84
95
  root: PitchClass;
85
96
  mode: Mode;
86
97
  confidence: number;
87
98
  name: string;
88
99
  shortName: string;
89
100
  }
101
+ interface KeyDetectionOptions {
102
+ nFft?: number;
103
+ hopLength?: number;
104
+ useHpss?: boolean;
105
+ loudnessWeighted?: boolean;
106
+ highPassHz?: number;
107
+ modes?: Mode[] | ('major' | 'minor' | 'dorian' | 'phrygian' | 'lydian' | 'mixolydian' | 'locrian')[] | 'major-minor' | 'all' | 'modal';
108
+ profile?: KeyProfile | KeyProfileName;
109
+ genreHint?: 'auto' | 'edm' | 'electronic' | 'dance' | 'pop' | 'classical' | 'jazz' | string;
110
+ }
111
+ interface KeyCandidate {
112
+ key: Key;
113
+ correlation: number;
114
+ }
115
+ interface ChordDetectionOptions {
116
+ minDuration?: number;
117
+ smoothingWindow?: number;
118
+ threshold?: number;
119
+ useTriadsOnly?: boolean;
120
+ nFft?: number;
121
+ hopLength?: number;
122
+ useBeatSync?: boolean;
123
+ useHmm?: boolean;
124
+ hmmBeamWidth?: number;
125
+ useKeyContext?: boolean;
126
+ keyRoot?: PitchClass;
127
+ keyMode?: Mode;
128
+ detectInversions?: boolean;
129
+ chromaMethod?: 'stft' | 'nnls';
130
+ }
90
131
  /**
91
132
  * Detected beat
92
133
  */
93
- export interface Beat {
134
+ interface Beat {
94
135
  time: number;
95
136
  strength: number;
96
137
  }
97
138
  /**
98
139
  * Detected chord
99
140
  */
100
- export interface Chord {
141
+ interface Chord {
101
142
  root: PitchClass;
143
+ bass: PitchClass;
102
144
  quality: ChordQuality;
103
145
  start: number;
104
146
  end: number;
105
147
  confidence: number;
106
148
  name: string;
107
149
  }
150
+ interface ChordAnalysisResult {
151
+ chords: Chord[];
152
+ }
108
153
  /**
109
154
  * Detected section
110
155
  */
111
- export interface Section {
156
+ interface Section {
112
157
  type: SectionType;
113
158
  start: number;
114
159
  end: number;
@@ -116,10 +161,49 @@ export interface Section {
116
161
  confidence: number;
117
162
  name: string;
118
163
  }
164
+ /**
165
+ * A single melody contour point (mirrors the C `SonareMelodyPoint`).
166
+ */
167
+ interface MelodyPoint {
168
+ /** Frame time in seconds. */
169
+ time: number;
170
+ /** Estimated fundamental frequency in Hz (0 when unvoiced). */
171
+ frequency: number;
172
+ /** Voicing confidence in `[0, 1]`. */
173
+ confidence: number;
174
+ }
175
+ /**
176
+ * Melody analysis result (mirrors the C `SonareMelodyResult`).
177
+ */
178
+ interface MelodyResult {
179
+ points: MelodyPoint[];
180
+ pitchRangeOctaves: number;
181
+ pitchStability: number;
182
+ meanFrequency: number;
183
+ vibratoRate: number;
184
+ }
185
+ /**
186
+ * Constant-Q / Variable-Q transform magnitude result (mirrors the C
187
+ * `SonareCqtResult`).
188
+ */
189
+ interface CqtResult {
190
+ /** Number of frequency bins. */
191
+ nBins: number;
192
+ /** Number of time frames. */
193
+ nFrames: number;
194
+ /** Hop length in samples. */
195
+ hopLength: number;
196
+ /** Sample rate in Hz. */
197
+ sampleRate: number;
198
+ /** Row-major `[nBins x nFrames]` magnitude matrix. */
199
+ magnitude: Float32Array;
200
+ /** Center frequency (Hz) of each of the `nBins` bins. */
201
+ frequencies: Float32Array;
202
+ }
119
203
  /**
120
204
  * Timbre characteristics
121
205
  */
122
- export interface Timbre {
206
+ interface Timbre {
123
207
  brightness: number;
124
208
  warmth: number;
125
209
  density: number;
@@ -129,7 +213,7 @@ export interface Timbre {
129
213
  /**
130
214
  * Dynamics characteristics
131
215
  */
132
- export interface Dynamics {
216
+ interface Dynamics {
133
217
  dynamicRangeDb: number;
134
218
  loudnessRangeDb: number;
135
219
  crestFactor: number;
@@ -138,7 +222,7 @@ export interface Dynamics {
138
222
  /**
139
223
  * Time signature
140
224
  */
141
- export interface TimeSignature {
225
+ interface TimeSignature {
142
226
  numerator: number;
143
227
  denominator: number;
144
228
  confidence: number;
@@ -146,7 +230,7 @@ export interface TimeSignature {
146
230
  /**
147
231
  * Rhythm features
148
232
  */
149
- export interface RhythmFeatures {
233
+ interface RhythmFeatures {
150
234
  syncopation: number;
151
235
  grooveType: string;
152
236
  patternRegularity: number;
@@ -154,7 +238,7 @@ export interface RhythmFeatures {
154
238
  /**
155
239
  * Complete analysis result
156
240
  */
157
- export interface AnalysisResult {
241
+ interface AnalysisResult {
158
242
  bpm: number;
159
243
  bpmConfidence: number;
160
244
  key: Key;
@@ -168,18 +252,264 @@ export interface AnalysisResult {
168
252
  rhythm: RhythmFeatures;
169
253
  form: string;
170
254
  }
255
+ /**
256
+ * Room acoustic parameters from an impulse response
257
+ */
258
+ interface AcousticResult {
259
+ rt60: number;
260
+ edt: number;
261
+ c50: number;
262
+ c80: number;
263
+ d50: number;
264
+ rt60Bands: Float32Array;
265
+ edtBands: Float32Array;
266
+ c50Bands: Float32Array;
267
+ c80Bands: Float32Array;
268
+ confidence: number;
269
+ isBlind: boolean;
270
+ }
171
271
  /**
172
272
  * HPSS (Harmonic-Percussive Source Separation) result
173
273
  */
174
- export interface HpssResult {
274
+ interface HpssResult {
175
275
  harmonic: Float32Array;
176
276
  percussive: Float32Array;
177
277
  sampleRate: number;
178
278
  }
279
+ /**
280
+ * Mastering loudness/true-peak processing result
281
+ */
282
+ interface MasteringResult {
283
+ samples: Float32Array;
284
+ sampleRate: number;
285
+ inputLufs: number;
286
+ outputLufs: number;
287
+ appliedGainDb: number;
288
+ latencySamples?: number;
289
+ }
290
+ type MasteringProcessorParams = Record<string, number | boolean>;
291
+ type PanMode = 'balance' | 'stereoPan' | 'stereo-pan' | 'dualPan' | 'dual-pan' | number;
292
+ interface MixOptions {
293
+ inputTrimDb?: number | number[];
294
+ faderDb?: number | number[];
295
+ pan?: number | number[];
296
+ panMode?: PanMode | PanMode[];
297
+ width?: number | number[];
298
+ muted?: boolean | boolean[];
299
+ }
300
+ interface MixMeterSnapshot {
301
+ peakDbL: number;
302
+ peakDbR: number;
303
+ rmsDbL: number;
304
+ rmsDbR: number;
305
+ correlation: number;
306
+ monoCompatWidth: number;
307
+ monoCompatPeak: number;
308
+ monoCompatSideRms: number;
309
+ likelyMonoCompatible: boolean;
310
+ momentaryLufs: number;
311
+ shortTermLufs: number;
312
+ integratedLufs: number;
313
+ gainReductionDb: number;
314
+ truePeakDbL: number;
315
+ truePeakDbR: number;
316
+ maxTruePeakDb: number;
317
+ seq: number;
318
+ }
319
+ interface MixResult {
320
+ left: Float32Array;
321
+ right: Float32Array;
322
+ sampleRate: number;
323
+ meters: MixMeterSnapshot[];
324
+ }
325
+ /** Mixed stereo master returned by {@link Mixer.processStereo}. */
326
+ interface MixerProcessResult {
327
+ left: Float32Array;
328
+ right: Float32Array;
329
+ sampleRate: number;
330
+ }
331
+ /**
332
+ * Interpolation curve for scheduled automation events
333
+ * (see {@link Mixer.scheduleInsertAutomation}).
334
+ */
335
+ type AutomationCurve = 'linear' | 'exponential' | 'hold' | 's-curve';
336
+ /**
337
+ * Pan law applied when computing left/right gains from a pan position
338
+ * (see {@link Mixer.setPanLaw}). Maps to the underlying integer code.
339
+ */
340
+ type PanLaw = 'const3dB' | 'const4.5dB' | 'const6dB' | 'linear0dB';
341
+ /**
342
+ * Meter tap point for reading a strip's meter snapshot
343
+ * (see {@link Mixer.meterTap} and {@link Mixer.stripMeter}).
344
+ */
345
+ type MeterTap = 'preFader' | 'postFader';
346
+ /** Pre/post-fader send timing (see {@link Mixer.addSend}). */
347
+ type SendTiming = 'preFader' | 'postFader';
348
+ /** A single goniometer (left/right) sample returned by {@link Mixer.readGoniometerLatest}. */
349
+ interface GoniometerPoint {
350
+ left: number;
351
+ right: number;
352
+ }
353
+ interface MasteringChainConfig {
354
+ repair?: {
355
+ denoise?: boolean;
356
+ nFft?: number;
357
+ hopLength?: number;
358
+ ddAlpha?: number;
359
+ gainFloor?: number;
360
+ declick?: {
361
+ threshold?: number;
362
+ neighborRatio?: number;
363
+ maxClickSamples?: number;
364
+ lpcOrder?: number;
365
+ residualRatio?: number;
366
+ };
367
+ dereverb?: {
368
+ threshold?: number;
369
+ attenuation?: number;
370
+ nFft?: number;
371
+ hopLength?: number;
372
+ t60Sec?: number;
373
+ lateDelayMs?: number;
374
+ overSubtraction?: number;
375
+ spectralFloor?: number;
376
+ wpeEnabled?: boolean;
377
+ wpeIterations?: number;
378
+ wpeTaps?: number;
379
+ wpeStrength?: number;
380
+ };
381
+ };
382
+ eq?: {
383
+ tiltDb?: number;
384
+ pivotHz?: number;
385
+ };
386
+ dynamics?: {
387
+ compressor?: {
388
+ thresholdDb?: number;
389
+ ratio?: number;
390
+ attackMs?: number;
391
+ releaseMs?: number;
392
+ kneeDb?: number;
393
+ makeupGainDb?: number;
394
+ autoMakeup?: boolean;
395
+ };
396
+ deesser?: {
397
+ frequencyHz?: number;
398
+ thresholdDb?: number;
399
+ ratio?: number;
400
+ attackMs?: number;
401
+ releaseMs?: number;
402
+ rangeDb?: number;
403
+ bandpassQ?: number;
404
+ };
405
+ transientShaper?: {
406
+ attackGainDb?: number;
407
+ sustainGainDb?: number;
408
+ fastAttackMs?: number;
409
+ fastReleaseMs?: number;
410
+ slowAttackMs?: number;
411
+ slowReleaseMs?: number;
412
+ sensitivity?: number;
413
+ maxGainDb?: number;
414
+ gainSmoothingMs?: number;
415
+ lookaheadMs?: number;
416
+ };
417
+ multibandComp?: {
418
+ lowCutoffHz?: number;
419
+ highCutoffHz?: number;
420
+ lowThresholdDb?: number;
421
+ lowRatio?: number;
422
+ lowAttackMs?: number;
423
+ lowReleaseMs?: number;
424
+ midThresholdDb?: number;
425
+ midRatio?: number;
426
+ midAttackMs?: number;
427
+ midReleaseMs?: number;
428
+ highThresholdDb?: number;
429
+ highRatio?: number;
430
+ highAttackMs?: number;
431
+ highReleaseMs?: number;
432
+ };
433
+ };
434
+ saturation?: {
435
+ tape?: {
436
+ driveDb?: number;
437
+ saturation?: number;
438
+ hysteresis?: number;
439
+ outputGainDb?: number;
440
+ speedIps?: number;
441
+ headBumpDb?: number;
442
+ bias?: number;
443
+ gapLoss?: number;
444
+ };
445
+ exciter?: {
446
+ frequencyHz?: number;
447
+ driveDb?: number;
448
+ amount?: number;
449
+ q?: number;
450
+ evenOddMix?: number;
451
+ };
452
+ };
453
+ spectral?: {
454
+ airBand?: {
455
+ amount?: number;
456
+ shelfFrequencyHz?: number;
457
+ dynamicThresholdDb?: number;
458
+ dynamicRangeDb?: number;
459
+ };
460
+ };
461
+ stereo?: {
462
+ imager?: {
463
+ width?: number;
464
+ outputGainDb?: number;
465
+ decorrelationAmount?: number;
466
+ preserveEnergy?: boolean;
467
+ };
468
+ monoMaker?: {
469
+ amount?: number;
470
+ };
471
+ };
472
+ maximizer?: {
473
+ truePeakLimiter?: {
474
+ ceilingDb?: number;
475
+ lookaheadMs?: number;
476
+ releaseMs?: number;
477
+ oversampleFactor?: number;
478
+ applyGainAtInputRate?: boolean;
479
+ };
480
+ };
481
+ loudness?: {
482
+ targetLufs?: number;
483
+ ceilingDb?: number;
484
+ truePeakOversample?: number;
485
+ };
486
+ }
487
+ interface MasteringChainResult extends MasteringResult {
488
+ stages: string[];
489
+ }
490
+ interface MasteringStereoChainResult {
491
+ left: Float32Array;
492
+ right: Float32Array;
493
+ sampleRate: number;
494
+ inputLufs: number;
495
+ outputLufs: number;
496
+ appliedGainDb: number;
497
+ stages: string[];
498
+ latencySamples?: number;
499
+ }
500
+ interface MasteringStereoResult {
501
+ left: Float32Array;
502
+ right: Float32Array;
503
+ sampleRate: number;
504
+ inputLufs: number;
505
+ outputLufs: number;
506
+ appliedGainDb: number;
507
+ latencySamples: number;
508
+ }
179
509
  /**
180
510
  * STFT (Short-Time Fourier Transform) result
181
511
  */
182
- export interface StftResult {
512
+ interface StftResult {
183
513
  nBins: number;
184
514
  nFrames: number;
185
515
  nFft: number;
@@ -191,7 +521,7 @@ export interface StftResult {
191
521
  /**
192
522
  * Mel spectrogram result
193
523
  */
194
- export interface MelSpectrogramResult {
524
+ interface MelSpectrogramResult {
195
525
  nMels: number;
196
526
  nFrames: number;
197
527
  sampleRate: number;
@@ -202,15 +532,31 @@ export interface MelSpectrogramResult {
202
532
  /**
203
533
  * MFCC result
204
534
  */
205
- export interface MfccResult {
535
+ interface MfccResult {
206
536
  nMfcc: number;
207
537
  nFrames: number;
208
538
  coefficients: Float32Array;
209
539
  }
540
+ /**
541
+ * STFT power spectrogram result (from inverse Mel reconstruction)
542
+ */
543
+ interface StftPowerResult {
544
+ nBins: number;
545
+ nFrames: number;
546
+ power: Float32Array;
547
+ }
548
+ /**
549
+ * Mel power spectrogram result (from inverse MFCC reconstruction)
550
+ */
551
+ interface MelPowerResult {
552
+ nMels: number;
553
+ nFrames: number;
554
+ power: Float32Array;
555
+ }
210
556
  /**
211
557
  * Chroma features result
212
558
  */
213
- export interface ChromaResult {
559
+ interface ChromaResult {
214
560
  nChroma: number;
215
561
  nFrames: number;
216
562
  sampleRate: number;
@@ -221,7 +567,7 @@ export interface ChromaResult {
221
567
  /**
222
568
  * Pitch detection result
223
569
  */
224
- export interface PitchResult {
570
+ interface PitchResult {
225
571
  f0: Float32Array;
226
572
  voicedProb: Float32Array;
227
573
  voicedFlag: boolean[];
@@ -229,6 +575,437 @@ export interface PitchResult {
229
575
  medianF0: number;
230
576
  meanF0: number;
231
577
  }
578
+ /**
579
+ * Loudness measurement result (EBU R128 / ITU-R BS.1770)
580
+ */
581
+ interface LufsResult {
582
+ integratedLufs: number;
583
+ momentaryLufs: number;
584
+ shortTermLufs: number;
585
+ loudnessRange: number;
586
+ }
587
+ /**
588
+ * Realtime equalizer spectrum snapshot.
589
+ *
590
+ * Mirrors the C++ `EqualizerSpectrumSnapshot`: `preLeft`/`preRight` and
591
+ * `postLeft`/`postRight` are the pre- and post-EQ spectrum streams (trimmed to
592
+ * their valid count). `bandGainDb` holds per-band applied gain (24 entries),
593
+ * `profileDb` the smoothed magnitude profile (16 entries), `lastAutoGainDb`
594
+ * the latest auto-gain compensation, and `seq` increments each time a new
595
+ * snapshot is published.
596
+ */
597
+ interface EqSpectrumSnapshot {
598
+ preLeft: Float32Array;
599
+ preRight: Float32Array;
600
+ postLeft: Float32Array;
601
+ postRight: Float32Array;
602
+ bandGainDb: Float32Array;
603
+ profileDb: Float32Array;
604
+ lastAutoGainDb: number;
605
+ seq: number;
606
+ }
607
+ /**
608
+ * Equalizer band type (string union mirroring `sonare::mastering::eq::EqBandType`).
609
+ */
610
+ type EqBandType = 'Peak' | 'LowShelf' | 'HighShelf' | 'LowPass' | 'HighPass' | 'BandPass' | 'Notch' | 'TiltShelf' | 'FlatTilt';
611
+ /** Biquad coefficient design mode. */
612
+ type EqCoeffMode = 'Rbj' | 'Vicanek';
613
+ /** Stereo placement for an EQ band. */
614
+ type EqStereoPlacement = 'Stereo' | 'Left' | 'Right' | 'Mid' | 'Side';
615
+ /** Per-band phase behaviour. */
616
+ type EqBandPhase = 'Inherit' | 'ZeroLatency' | 'NaturalPhase' | 'LinearPhase';
617
+ /**
618
+ * Equalizer band configuration accepted by {@link StreamingEqualizer.setBand}.
619
+ *
620
+ * All fields are optional; omitted values fall back to the C++ band defaults
621
+ * (Peak, 1000 Hz, 0 dB gain, Butterworth Q, disabled).
622
+ */
623
+ interface EqBand {
624
+ type?: EqBandType;
625
+ frequencyHz?: number;
626
+ gainDb?: number;
627
+ q?: number;
628
+ enabled?: boolean;
629
+ coeffMode?: EqCoeffMode;
630
+ slopeDbOct?: number;
631
+ placement?: EqStereoPlacement;
632
+ phase?: EqBandPhase;
633
+ soloed?: boolean;
634
+ bypassed?: boolean;
635
+ proportionalQ?: boolean;
636
+ proportionalQStrength?: number;
637
+ dynamic?: boolean;
638
+ thresholdDb?: number;
639
+ autoThreshold?: boolean;
640
+ ratio?: number;
641
+ rangeDb?: number;
642
+ attackMs?: number;
643
+ releaseMs?: number;
644
+ lookaheadMs?: number;
645
+ externalSidechain?: boolean;
646
+ sidechainFreqHz?: number;
647
+ sidechainQ?: number;
648
+ }
649
+ /** Construction options for {@link StreamingEqualizer}. */
650
+ interface StreamingEqualizerConfig {
651
+ sampleRate?: number;
652
+ maxBlockSize?: number;
653
+ }
654
+ /** Options for {@link StreamingEqualizer.match}. */
655
+ interface EqMatchOptions {
656
+ sampleRate?: number;
657
+ maxBands?: number;
658
+ }
659
+
660
+ /**
661
+ * A detected chord change in the progression
662
+ */
663
+ interface ChordChange {
664
+ root: PitchClass;
665
+ quality: ChordQuality;
666
+ startTime: number;
667
+ confidence: number;
668
+ }
669
+ /**
670
+ * A chord detected at bar boundary (beat-synchronized)
671
+ */
672
+ interface BarChord {
673
+ barIndex: number;
674
+ root: PitchClass;
675
+ quality: ChordQuality;
676
+ startTime: number;
677
+ confidence: number;
678
+ }
679
+ /**
680
+ * Pattern score for known chord progressions
681
+ */
682
+ interface PatternScore {
683
+ name: string;
684
+ score: number;
685
+ }
686
+ /**
687
+ * Progressive estimation results for BPM, Key, and Chord
688
+ */
689
+ interface ProgressiveEstimate {
690
+ bpm: number;
691
+ bpmConfidence: number;
692
+ bpmCandidateCount: number;
693
+ key: PitchClass;
694
+ keyMinor: boolean;
695
+ keyConfidence: number;
696
+ chordRoot: PitchClass;
697
+ chordQuality: ChordQuality;
698
+ chordConfidence: number;
699
+ chordStartTime: number;
700
+ chordProgression: ChordChange[];
701
+ barChordProgression: BarChord[];
702
+ currentBar: number;
703
+ barDuration: number;
704
+ votedPattern: BarChord[];
705
+ patternLength: number;
706
+ detectedPatternName: string;
707
+ detectedPatternScore: number;
708
+ allPatternScores: PatternScore[];
709
+ accumulatedSeconds: number;
710
+ usedFrames: number;
711
+ updated: boolean;
712
+ }
713
+ /**
714
+ * Statistics and current state of the analyzer
715
+ */
716
+ interface AnalyzerStats {
717
+ totalFrames: number;
718
+ totalSamples: number;
719
+ durationSeconds: number;
720
+ estimate: ProgressiveEstimate;
721
+ }
722
+ /**
723
+ * Frame buffer with analysis results
724
+ */
725
+ interface FrameBuffer {
726
+ nFrames: number;
727
+ timestamps: Float32Array;
728
+ mel: Float32Array;
729
+ chroma: Float32Array;
730
+ onsetStrength: Float32Array;
731
+ rmsEnergy: Float32Array;
732
+ spectralCentroid: Float32Array;
733
+ spectralFlatness: Float32Array;
734
+ chordRoot: Int32Array;
735
+ chordQuality: Int32Array;
736
+ chordConfidence: Float32Array;
737
+ }
738
+ interface StreamFramesU8 {
739
+ nFrames: number;
740
+ nMels: number;
741
+ timestamps: Float32Array;
742
+ mel: Uint8Array;
743
+ chroma: Uint8Array;
744
+ onsetStrength: Uint8Array;
745
+ rmsEnergy: Uint8Array;
746
+ spectralCentroid: Uint8Array;
747
+ spectralFlatness: Uint8Array;
748
+ }
749
+ interface StreamFramesI16 {
750
+ nFrames: number;
751
+ nMels: number;
752
+ timestamps: Float32Array;
753
+ mel: Int16Array;
754
+ chroma: Int16Array;
755
+ onsetStrength: Int16Array;
756
+ rmsEnergy: Int16Array;
757
+ spectralCentroid: Int16Array;
758
+ spectralFlatness: Int16Array;
759
+ }
760
+ /**
761
+ * Configuration for StreamAnalyzer
762
+ */
763
+ interface StreamConfig {
764
+ sampleRate: number;
765
+ nFft?: number;
766
+ hopLength?: number;
767
+ nMels?: number;
768
+ fmin?: number;
769
+ fmax?: number;
770
+ tuningRefHz?: number;
771
+ computeMagnitude?: boolean;
772
+ computeMel?: boolean;
773
+ computeChroma?: boolean;
774
+ computeOnset?: boolean;
775
+ computeSpectral?: boolean;
776
+ emitEveryNFrames?: number;
777
+ magnitudeDownsample?: number;
778
+ keyUpdateIntervalSec?: number;
779
+ bpmUpdateIntervalSec?: number;
780
+ window?: number;
781
+ outputFormat?: number;
782
+ }
783
+
784
+ type ProgressCallback = (progress: number, stage: string) => void;
785
+ interface WasmTrimResult {
786
+ audio: Float32Array;
787
+ startSample: number;
788
+ endSample: number;
789
+ }
790
+ interface WasmFrameResult {
791
+ nFrames: number;
792
+ frames: Float32Array;
793
+ }
794
+ interface WasmTempogramResult {
795
+ nFrames: number;
796
+ winLength: number;
797
+ data: Float32Array;
798
+ }
799
+ interface WasmCyclicTempogramResult {
800
+ nFrames: number;
801
+ nBins: number;
802
+ data: Float32Array;
803
+ }
804
+ interface WasmFourierTempogramResult {
805
+ nBins: number;
806
+ nFrames: number;
807
+ data: Float32Array;
808
+ }
809
+ interface WasmNnlsChromaResult {
810
+ nChroma: number;
811
+ nFrames: number;
812
+ data: Float32Array;
813
+ }
814
+ interface WasmEngineClip {
815
+ id?: number;
816
+ channels: Float32Array[];
817
+ startPpq: number;
818
+ lengthSamples?: number;
819
+ clipOffsetSamples?: number;
820
+ loop?: boolean;
821
+ gain?: number;
822
+ fadeInSamples?: number;
823
+ fadeOutSamples?: number;
824
+ }
825
+ interface WasmEngineParameterInfo {
826
+ id: number;
827
+ name: string;
828
+ unit: string;
829
+ minValue: number;
830
+ maxValue: number;
831
+ defaultValue: number;
832
+ rtSafe: boolean;
833
+ defaultCurve: number;
834
+ }
835
+ interface WasmEngineAutomationPoint {
836
+ ppq: number;
837
+ value: number;
838
+ curveToNext?: number;
839
+ }
840
+ interface WasmEngineMarker {
841
+ id: number;
842
+ ppq: number;
843
+ name?: string;
844
+ }
845
+ interface WasmEngineMetronomeConfig {
846
+ enabled: boolean;
847
+ beatGain?: number;
848
+ accentGain?: number;
849
+ clickSamples?: number;
850
+ }
851
+ interface WasmEngineGraphNode {
852
+ id: string;
853
+ type?: number;
854
+ gainDb?: number;
855
+ numPorts?: number;
856
+ }
857
+ interface WasmEngineGraphConnection {
858
+ sourceNode: string;
859
+ sourcePort: number;
860
+ destNode: string;
861
+ destPort: number;
862
+ mix?: number;
863
+ }
864
+ interface WasmEngineGraphParameterBinding {
865
+ paramId: number;
866
+ nodeId: string;
867
+ }
868
+ interface WasmEngineGraphSpec {
869
+ nodes: WasmEngineGraphNode[];
870
+ connections: WasmEngineGraphConnection[];
871
+ inputNode: string;
872
+ outputNode: string;
873
+ numChannels: number;
874
+ parameterBindings?: WasmEngineGraphParameterBinding[];
875
+ }
876
+ interface WasmEngineTelemetry {
877
+ type: number;
878
+ error: number;
879
+ renderFrame: number;
880
+ timelineSample: number;
881
+ audibleTimelineSample: number;
882
+ graphLatencySamplesQ8: number;
883
+ value: number;
884
+ }
885
+ interface WasmEngineMeterTelemetry {
886
+ targetId: number;
887
+ renderFrame: number;
888
+ seq: number;
889
+ peakDbL: number;
890
+ peakDbR: number;
891
+ rmsDbL: number;
892
+ rmsDbR: number;
893
+ truePeakDbL: number;
894
+ truePeakDbR: number;
895
+ maxTruePeakDb: number;
896
+ correlation: number;
897
+ monoCompatWidth: number;
898
+ momentaryLufs: number;
899
+ shortTermLufs: number;
900
+ integratedLufs: number;
901
+ gainReductionDb: number;
902
+ droppedRecords: number;
903
+ }
904
+ interface WasmEngineCaptureStatus {
905
+ capturedFrames: number;
906
+ overflowCount: number;
907
+ armed: boolean;
908
+ punchEnabled: boolean;
909
+ }
910
+ interface WasmEngineTransportState {
911
+ playing: boolean;
912
+ looping: boolean;
913
+ renderFrame: number;
914
+ samplePosition: number;
915
+ ppq: number;
916
+ bpm: number;
917
+ loopStartPpq: number;
918
+ loopEndPpq: number;
919
+ sampleRate: number;
920
+ }
921
+ interface WasmEngineBounceOptions {
922
+ totalFrames: number;
923
+ blockSize?: number;
924
+ numChannels?: number;
925
+ targetSampleRate?: number;
926
+ sourceSampleRate?: number;
927
+ normalizeLufs?: boolean;
928
+ targetLufs?: number;
929
+ dither?: 0 | 1 | 2 | 3;
930
+ ditherBits?: number;
931
+ ditherSeed?: number;
932
+ }
933
+ interface WasmEngineBounceResult {
934
+ interleaved: Float32Array;
935
+ frames: number;
936
+ numChannels: number;
937
+ sampleRate: number;
938
+ integratedLufs: number;
939
+ }
940
+ interface WasmEngineFreezeOptions {
941
+ totalFrames: number;
942
+ blockSize?: number;
943
+ numChannels?: number;
944
+ clipId?: number;
945
+ startPpq?: number;
946
+ gain?: number;
947
+ }
948
+ interface WasmEngineFreezeResult {
949
+ clipId: number;
950
+ frames: number;
951
+ numChannels: number;
952
+ }
953
+ interface WasmEngineProcessWithMonitorResult {
954
+ output: Float32Array[];
955
+ monitor: Float32Array[];
956
+ }
957
+
958
+ /**
959
+ * sonare - Audio Analysis Library
960
+ *
961
+ * @example
962
+ * ```typescript
963
+ * import { init, detectBpm, detectKey, analyze } from '@libraz/sonare';
964
+ *
965
+ * await init();
966
+ *
967
+ * // Detect BPM from audio samples
968
+ * const bpm = detectBpm(samples, sampleRate);
969
+ *
970
+ * // Detect musical key
971
+ * const key = detectKey(samples, sampleRate);
972
+ *
973
+ * // Full analysis
974
+ * const result = analyze(samples, sampleRate);
975
+ * ```
976
+ */
977
+
978
+ type EngineClip = WasmEngineClip;
979
+ type EngineParameterInfo = WasmEngineParameterInfo;
980
+ type EngineAutomationPoint = WasmEngineAutomationPoint;
981
+ type EngineMarker = WasmEngineMarker;
982
+ type EngineMetronomeConfig = WasmEngineMetronomeConfig;
983
+ type EngineGraphSpec = WasmEngineGraphSpec;
984
+ type EngineCaptureStatus = WasmEngineCaptureStatus;
985
+ type EngineBounceOptions = WasmEngineBounceOptions;
986
+ type EngineBounceResult = WasmEngineBounceResult;
987
+ type EngineFreezeOptions = WasmEngineFreezeOptions;
988
+ type EngineFreezeResult = WasmEngineFreezeResult;
989
+ type EngineTelemetry = WasmEngineTelemetry;
990
+ type EngineMeterTelemetry = WasmEngineMeterTelemetry;
991
+ type EngineTransportState = WasmEngineTransportState;
992
+ declare const EXPECTED_ENGINE_ABI_VERSION = 2;
993
+ interface EngineCapabilities {
994
+ engineAbiVersion: number;
995
+ expectedEngineAbiVersion: number;
996
+ abiCompatible: boolean;
997
+ sharedArrayBuffer: boolean;
998
+ atomics: boolean;
999
+ audioWorklet: boolean;
1000
+ mode: 'sab' | 'postMessage';
1001
+ }
1002
+ interface MixerRealtimeBuffer {
1003
+ leftInputs: Float32Array[];
1004
+ rightInputs: Float32Array[];
1005
+ outLeft: Float32Array;
1006
+ outRight: Float32Array;
1007
+ process: (numSamples?: number) => void;
1008
+ }
232
1009
  /**
233
1010
  * Initialize the WASM module.
234
1011
  * Must be called before using any analysis functions.
@@ -236,17 +1013,71 @@ export interface PitchResult {
236
1013
  * @param options - Optional module configuration
237
1014
  * @returns Promise that resolves when initialization is complete
238
1015
  */
239
- export declare function init(options?: {
1016
+ declare function init(options?: {
240
1017
  locateFile?: (path: string, prefix: string) => string;
241
1018
  }): Promise<void>;
242
1019
  /**
243
1020
  * Check if the module is initialized.
244
1021
  */
245
- export declare function isInitialized(): boolean;
1022
+ declare function isInitialized(): boolean;
246
1023
  /**
247
1024
  * Get the library version.
248
1025
  */
249
- export declare function version(): string;
1026
+ declare function version(): string;
1027
+ declare function engineAbiVersion(): number;
1028
+ declare function engineCapabilities(): EngineCapabilities;
1029
+ declare class RealtimeEngine {
1030
+ private native;
1031
+ constructor(sampleRate?: number, maxBlockSize?: number, commandCapacity?: number, telemetryCapacity?: number);
1032
+ prepare(sampleRate: number, maxBlockSize: number, commandCapacity?: number, telemetryCapacity?: number): void;
1033
+ /** Queue a sample-accurate parameter change (engine kSetParam). */
1034
+ setParameter(paramId: number, value: number, renderFrame?: number): void;
1035
+ /** Queue a smoothed parameter change (engine kSetParamSmoothed). */
1036
+ setParameterSmoothed(paramId: number, value: number, renderFrame?: number): void;
1037
+ /** Read back the current transport state snapshot. */
1038
+ getTransportState(): EngineTransportState;
1039
+ play(renderFrame?: number): void;
1040
+ stop(renderFrame?: number): void;
1041
+ seekSample(timelineSample: number, renderFrame?: number): void;
1042
+ seekPpq(ppq: number, renderFrame?: number): void;
1043
+ setTempo(bpm: number): void;
1044
+ setTimeSignature(numerator: number, denominator: number): void;
1045
+ setLoop(startPpq: number, endPpq: number, enabled?: boolean): void;
1046
+ addParameter(info: EngineParameterInfo): void;
1047
+ parameterCount(): number;
1048
+ parameterInfoByIndex(index: number): EngineParameterInfo;
1049
+ parameterInfo(id: number): EngineParameterInfo;
1050
+ setAutomationLane(paramId: number, points: EngineAutomationPoint[]): void;
1051
+ automationLaneCount(): number;
1052
+ setMarkers(markers: EngineMarker[]): void;
1053
+ markerCount(): number;
1054
+ markerByIndex(index: number): EngineMarker;
1055
+ marker(id: number): EngineMarker;
1056
+ seekMarker(markerId: number, renderFrame?: number): void;
1057
+ setLoopFromMarkers(startMarkerId: number, endMarkerId: number): void;
1058
+ setMetronome(config: EngineMetronomeConfig): void;
1059
+ metronome(): Required<EngineMetronomeConfig>;
1060
+ countInEndSample(startSample: number, bars: number): number;
1061
+ setGraph(spec: EngineGraphSpec): void;
1062
+ graphNodeCount(): number;
1063
+ graphConnectionCount(): number;
1064
+ setClips(clips: EngineClip[]): void;
1065
+ clipCount(): number;
1066
+ setCaptureBuffer(numChannels: number, capacityFrames: number): void;
1067
+ armCapture(armed?: boolean): void;
1068
+ setCapturePunch(startSample: number, endSample: number, enabled?: boolean): void;
1069
+ resetCapture(): void;
1070
+ captureStatus(): EngineCaptureStatus;
1071
+ capturedAudio(): Float32Array[];
1072
+ process(channels: Float32Array[]): Float32Array[];
1073
+ processWithMonitor(channels: Float32Array[]): WasmEngineProcessWithMonitorResult;
1074
+ renderOffline(channels: Float32Array[], blockSize?: number): Float32Array[];
1075
+ bounceOffline(options: EngineBounceOptions): EngineBounceResult;
1076
+ freezeOffline(options: EngineFreezeOptions): EngineFreezeResult;
1077
+ drainTelemetry(maxRecords?: number): EngineTelemetry[];
1078
+ drainMeterTelemetry(maxRecords?: number): EngineMeterTelemetry[];
1079
+ destroy(): void;
1080
+ }
250
1081
  /**
251
1082
  * Detect BPM from audio samples.
252
1083
  *
@@ -254,7 +1085,7 @@ export declare function version(): string;
254
1085
  * @param sampleRate - Sample rate in Hz
255
1086
  * @returns Detected BPM
256
1087
  */
257
- export declare function detectBpm(samples: Float32Array, sampleRate: number): number;
1088
+ declare function detectBpm(samples: Float32Array, sampleRate: number): number;
258
1089
  /**
259
1090
  * Detect musical key from audio samples.
260
1091
  *
@@ -262,7 +1093,8 @@ export declare function detectBpm(samples: Float32Array, sampleRate: number): nu
262
1093
  * @param sampleRate - Sample rate in Hz
263
1094
  * @returns Detected key
264
1095
  */
265
- export declare function detectKey(samples: Float32Array, sampleRate: number): Key;
1096
+ declare function detectKey(samples: Float32Array, sampleRate: number, options?: KeyDetectionOptions): Key;
1097
+ declare function detectKeyCandidates(samples: Float32Array, sampleRate: number, options?: KeyDetectionOptions): KeyCandidate[];
266
1098
  /**
267
1099
  * Detect onset times from audio samples.
268
1100
  *
@@ -270,7 +1102,7 @@ export declare function detectKey(samples: Float32Array, sampleRate: number): Ke
270
1102
  * @param sampleRate - Sample rate in Hz
271
1103
  * @returns Array of onset times in seconds
272
1104
  */
273
- export declare function detectOnsets(samples: Float32Array, sampleRate: number): Float32Array;
1105
+ declare function detectOnsets(samples: Float32Array, sampleRate: number): Float32Array;
274
1106
  /**
275
1107
  * Detect beat times from audio samples.
276
1108
  *
@@ -278,7 +1110,24 @@ export declare function detectOnsets(samples: Float32Array, sampleRate: number):
278
1110
  * @param sampleRate - Sample rate in Hz
279
1111
  * @returns Array of beat times in seconds
280
1112
  */
281
- export declare function detectBeats(samples: Float32Array, sampleRate: number): Float32Array;
1113
+ declare function detectBeats(samples: Float32Array, sampleRate: number): Float32Array;
1114
+ /**
1115
+ * Detect downbeat times from audio samples.
1116
+ *
1117
+ * @param samples - Audio samples (mono, float32)
1118
+ * @param sampleRate - Sample rate in Hz
1119
+ * @returns Array of downbeat times in seconds
1120
+ */
1121
+ declare function detectDownbeats(samples: Float32Array, sampleRate: number): Float32Array;
1122
+ /**
1123
+ * Detect chords from audio samples.
1124
+ *
1125
+ * @param samples - Audio samples (mono, float32)
1126
+ * @param sampleRate - Sample rate in Hz
1127
+ * @param options - Optional chord detection settings
1128
+ * @returns Detected chord segments
1129
+ */
1130
+ declare function detectChords(samples: Float32Array, sampleRate: number, options?: ChordDetectionOptions): ChordAnalysisResult;
282
1131
  /**
283
1132
  * Perform complete music analysis.
284
1133
  *
@@ -286,7 +1135,9 @@ export declare function detectBeats(samples: Float32Array, sampleRate: number):
286
1135
  * @param sampleRate - Sample rate in Hz
287
1136
  * @returns Complete analysis result
288
1137
  */
289
- export declare function analyze(samples: Float32Array, sampleRate: number): AnalysisResult;
1138
+ declare function analyze(samples: Float32Array, sampleRate: number): AnalysisResult;
1139
+ declare function analyzeImpulseResponse(samples: Float32Array, sampleRate: number, nOctaveBands?: number): AcousticResult;
1140
+ declare function detectAcoustic(samples: Float32Array, sampleRate: number, nOctaveBands?: number, nThirdOctaveSubbands?: number, minDecayDb?: number, noiseFloorMarginDb?: number): AcousticResult;
290
1141
  /**
291
1142
  * Perform complete music analysis with progress reporting.
292
1143
  *
@@ -295,7 +1146,7 @@ export declare function analyze(samples: Float32Array, sampleRate: number): Anal
295
1146
  * @param onProgress - Progress callback (progress: 0-1, stage: string)
296
1147
  * @returns Complete analysis result
297
1148
  */
298
- export declare function analyzeWithProgress(samples: Float32Array, sampleRate: number, onProgress: ProgressCallback): AnalysisResult;
1149
+ declare function analyzeWithProgress(samples: Float32Array, sampleRate: number, onProgress: ProgressCallback): AnalysisResult;
299
1150
  /**
300
1151
  * Perform Harmonic-Percussive Source Separation (HPSS).
301
1152
  *
@@ -305,7 +1156,7 @@ export declare function analyzeWithProgress(samples: Float32Array, sampleRate: n
305
1156
  * @param kernelPercussive - Vertical median filter size for percussive (default: 31)
306
1157
  * @returns Separated harmonic and percussive components
307
1158
  */
308
- export declare function hpss(samples: Float32Array, sampleRate: number, kernelHarmonic?: number, kernelPercussive?: number): HpssResult;
1159
+ declare function hpss(samples: Float32Array, sampleRate: number, kernelHarmonic?: number, kernelPercussive?: number): HpssResult;
309
1160
  /**
310
1161
  * Extract harmonic component from audio.
311
1162
  *
@@ -313,42 +1164,525 @@ export declare function hpss(samples: Float32Array, sampleRate: number, kernelHa
313
1164
  * @param sampleRate - Sample rate in Hz
314
1165
  * @returns Harmonic component
315
1166
  */
316
- export declare function harmonic(samples: Float32Array, sampleRate: number): Float32Array;
1167
+ declare function harmonic(samples: Float32Array, sampleRate: number): Float32Array;
1168
+ /**
1169
+ * Extract percussive component from audio.
1170
+ *
1171
+ * @param samples - Audio samples (mono, float32)
1172
+ * @param sampleRate - Sample rate in Hz
1173
+ * @returns Percussive component
1174
+ */
1175
+ declare function percussive(samples: Float32Array, sampleRate: number): Float32Array;
1176
+ /**
1177
+ * Time-stretch audio without changing pitch.
1178
+ *
1179
+ * @param samples - Audio samples (mono, float32)
1180
+ * @param sampleRate - Sample rate in Hz
1181
+ * @param rate - Time stretch rate (0.5 = double duration, 2.0 = half duration)
1182
+ * @returns Time-stretched audio
1183
+ */
1184
+ declare function timeStretch(samples: Float32Array, sampleRate: number, rate: number): Float32Array;
1185
+ /**
1186
+ * Pitch-shift audio without changing duration.
1187
+ *
1188
+ * @param samples - Audio samples (mono, float32)
1189
+ * @param sampleRate - Sample rate in Hz
1190
+ * @param semitones - Pitch shift in semitones (+12 = one octave up, -12 = one octave down)
1191
+ * @returns Pitch-shifted audio
1192
+ */
1193
+ declare function pitchShift(samples: Float32Array, sampleRate: number, semitones: number): Float32Array;
1194
+ /**
1195
+ * Pitch-correct audio from a current MIDI note to a target MIDI note.
1196
+ *
1197
+ * @param samples - Audio samples (mono, float32)
1198
+ * @param sampleRate - Sample rate in Hz
1199
+ * @param currentMidi - Detected/current MIDI note number
1200
+ * @param targetMidi - Desired MIDI note number
1201
+ * @returns Pitch-corrected audio
1202
+ */
1203
+ declare function pitchCorrectToMidi(samples: Float32Array, sampleRate: number, currentMidi: number, targetMidi: number): Float32Array;
1204
+ /**
1205
+ * Time-stretch a note region between two sample offsets without changing pitch.
1206
+ *
1207
+ * @param samples - Audio samples (mono, float32)
1208
+ * @param sampleRate - Sample rate in Hz
1209
+ * @param onsetSample - Note onset position in samples
1210
+ * @param offsetSample - Note offset position in samples
1211
+ * @param stretchRatio - Stretch ratio (0.5 = double duration, 2.0 = half duration)
1212
+ * @returns Audio with the note region stretched
1213
+ */
1214
+ declare function noteStretch(samples: Float32Array, sampleRate: number, onsetSample: number, offsetSample: number, stretchRatio: number): Float32Array;
1215
+ /**
1216
+ * Apply a voice change by shifting pitch and formants independently.
1217
+ *
1218
+ * @param samples - Audio samples (mono, float32)
1219
+ * @param sampleRate - Sample rate in Hz
1220
+ * @param pitchSemitones - Pitch shift in semitones
1221
+ * @param formantFactor - Formant scaling factor (1.0 = unchanged)
1222
+ * @returns Voice-changed audio
1223
+ */
1224
+ declare function voiceChange(samples: Float32Array, sampleRate: number, pitchSemitones: number, formantFactor: number): Float32Array;
1225
+ /**
1226
+ * Normalize audio to target peak level.
1227
+ *
1228
+ * @param samples - Audio samples (mono, float32)
1229
+ * @param sampleRate - Sample rate in Hz
1230
+ * @param targetDb - Target peak level in dB (default: 0 dB = full scale)
1231
+ * @returns Normalized audio
1232
+ */
1233
+ declare function normalize(samples: Float32Array, sampleRate: number, targetDb?: number): Float32Array;
1234
+ /**
1235
+ * Apply mastering loudness normalization with a true-peak ceiling.
1236
+ *
1237
+ * @param samples - Audio samples (mono, float32)
1238
+ * @param sampleRate - Sample rate in Hz
1239
+ * @param targetLufs - Target integrated LUFS (default: -14)
1240
+ * @param ceilingDb - True/sample peak ceiling in dBFS (default: -1)
1241
+ * @param truePeakOversample - Oversampling factor used for peak estimation
1242
+ * @returns Processed audio and loudness metadata
1243
+ */
1244
+ declare function mastering(samples: Float32Array, sampleRate: number, targetLufs?: number, ceilingDb?: number, truePeakOversample?: number): MasteringResult;
1245
+ declare function masteringProcessorNames(): SoloProcessor[];
1246
+ declare function masteringPairProcessorNames(): PairProcessor[];
1247
+ declare function masteringPairAnalysisNames(): PairAnalysis[];
1248
+ declare function masteringStereoAnalysisNames(): StereoAnalysis[];
1249
+ declare function masteringProcess(processorName: SoloProcessor, samples: Float32Array, sampleRate: number, params?: MasteringProcessorParams): MasteringResult;
1250
+ declare function masteringProcessStereo(processorName: SoloProcessor, left: Float32Array, right: Float32Array, sampleRate: number, params?: MasteringProcessorParams): MasteringStereoResult;
1251
+ declare function masteringPairProcess(processorName: PairProcessor, source: Float32Array, reference: Float32Array, sampleRate: number, params?: MasteringProcessorParams): MasteringResult;
1252
+ declare function masteringPairAnalyze(analysisName: PairAnalysis, source: Float32Array, reference: Float32Array, sampleRate: number, params?: MasteringProcessorParams): string;
1253
+ declare function masteringStereoAnalyze(analysisName: StereoAnalysis, left: Float32Array, right: Float32Array, sampleRate: number, params?: MasteringProcessorParams): string;
1254
+ declare function masteringAssistantSuggest(samples: Float32Array, sampleRate: number, params?: MasteringProcessorParams): string;
1255
+ declare function masteringAudioProfile(samples: Float32Array, sampleRate: number, params?: MasteringProcessorParams): string;
1256
+ declare function masteringStreamingPreview(samples: Float32Array, sampleRate: number, platforms?: StreamingPlatform[]): string;
1257
+ /**
1258
+ * Apply a configurable mastering chain in WASM.
1259
+ *
1260
+ * @param samples - Audio samples (mono, float32)
1261
+ * @param sampleRate - Sample rate in Hz
1262
+ * @param config - Chain stage configuration
1263
+ * @returns Processed audio, loudness metadata, and applied stage names
1264
+ */
1265
+ declare function masteringChain(samples: Float32Array, sampleRate: number, config: MasteringChainConfig): MasteringChainResult;
1266
+ /**
1267
+ * Apply a configurable stereo mastering chain in WASM.
1268
+ *
1269
+ * @param left - Left channel samples
1270
+ * @param right - Right channel samples
1271
+ * @param sampleRate - Sample rate in Hz
1272
+ * @param config - Chain stage configuration
1273
+ * @returns Processed stereo audio, loudness metadata, and applied stage names
1274
+ */
1275
+ declare function masteringChainStereo(left: Float32Array, right: Float32Array, sampleRate: number, config: MasteringChainConfig): MasteringStereoChainResult;
1276
+ /**
1277
+ * Apply a configurable mastering chain in WASM with progress reporting.
1278
+ *
1279
+ * @param samples - Audio samples (mono, float32)
1280
+ * @param sampleRate - Sample rate in Hz
1281
+ * @param config - Chain stage configuration
1282
+ * @param onProgress - Progress callback (progress: 0-1, stage: string)
1283
+ * @returns Processed audio, loudness metadata, and applied stage names
1284
+ */
1285
+ declare function masteringChainWithProgress(samples: Float32Array, sampleRate: number, config: MasteringChainConfig, onProgress: ProgressCallback): MasteringChainResult;
1286
+ /**
1287
+ * Apply a configurable stereo mastering chain in WASM with progress reporting.
1288
+ *
1289
+ * @param left - Left channel samples
1290
+ * @param right - Right channel samples
1291
+ * @param sampleRate - Sample rate in Hz
1292
+ * @param config - Chain stage configuration
1293
+ * @param onProgress - Progress callback (progress: 0-1, stage: string)
1294
+ * @returns Processed stereo audio, loudness metadata, and applied stage names
1295
+ */
1296
+ declare function masteringChainStereoWithProgress(left: Float32Array, right: Float32Array, sampleRate: number, config: MasteringChainConfig, onProgress: ProgressCallback): MasteringStereoChainResult;
1297
+ /**
1298
+ * List built-in mastering preset identifiers.
1299
+ *
1300
+ * @returns Preset names in display order (e.g. "pop", "edm", "aiMusic")
1301
+ */
1302
+ declare function masteringPresetNames(): MasteringPreset[];
1303
+ /**
1304
+ * Apply a named mastering preset chain to mono audio.
1305
+ *
1306
+ * @param samples - Audio samples (mono, float32)
1307
+ * @param sampleRate - Sample rate in Hz
1308
+ * @param presetName - Preset identifier from {@link masteringPresetNames}
1309
+ * @param overrides - Optional flat overrides (dot-notation, e.g. `'loudness.targetLufs'`) applied on top of the preset. Pass `null` for preset defaults.
1310
+ * @returns Processed audio, loudness metadata, and applied stage names
1311
+ */
1312
+ declare function masterAudio(samples: Float32Array, sampleRate: number, presetName: MasteringPreset, overrides?: Record<string, number | boolean> | null): MasteringChainResult;
1313
+ /**
1314
+ * Apply a named mastering preset chain to stereo audio.
1315
+ *
1316
+ * @param left - Left channel samples
1317
+ * @param right - Right channel samples
1318
+ * @param sampleRate - Sample rate in Hz
1319
+ * @param presetName - Preset identifier from {@link masteringPresetNames}
1320
+ * @param overrides - Optional flat overrides (dot-notation, e.g. `'loudness.targetLufs'`) applied on top of the preset. Pass `null` for preset defaults.
1321
+ * @returns Processed stereo audio, loudness metadata, and applied stage names
1322
+ */
1323
+ declare function masterAudioStereo(left: Float32Array, right: Float32Array, sampleRate: number, presetName: MasteringPreset, overrides?: Record<string, number | boolean> | null): MasteringStereoChainResult;
1324
+ declare function mixingScenePresetNames(): string[];
1325
+ /**
1326
+ * Get a built-in mixing scene preset serialized as JSON. This is the canonical
1327
+ * name shared with the Node and Python bindings; the returned JSON loads
1328
+ * directly into a {@link Mixer} via {@link Mixer.fromSceneJson}.
1329
+ *
1330
+ * @param preset - Preset name (see {@link mixingScenePresetNames})
1331
+ * @returns Scene JSON string
1332
+ */
1333
+ declare function mixingScenePresetJson(preset: string): string;
1334
+ declare function mixStereo(leftChannels: Float32Array[], rightChannels: Float32Array[], sampleRate?: number, options?: MixOptions): MixResult;
1335
+ /**
1336
+ * Block-by-block streaming variant of {@link masteringChain}.
1337
+ *
1338
+ * Maintains processor state across {@link processMono}/{@link processStereo}
1339
+ * calls. Only ProcessorBase-backed stages are supported. Configurations that
1340
+ * enable `repair.denoise` or `loudness` throw at construction.
1341
+ *
1342
+ * Call {@link delete} (or use a `try/finally`) to release the underlying WASM
1343
+ * object — the embind handle is not garbage-collected automatically.
1344
+ *
1345
+ * @example
1346
+ * ```typescript
1347
+ * const chain = new StreamingMasteringChain({ eq: { tiltDb: 1.0 } });
1348
+ * try {
1349
+ * chain.prepare(44100, 512, 1);
1350
+ * const out = chain.processMono(blockSamples);
1351
+ * } finally {
1352
+ * chain.delete();
1353
+ * }
1354
+ * ```
1355
+ */
1356
+ declare class StreamingMasteringChain {
1357
+ private chain;
1358
+ constructor(config: MasteringChainConfig);
1359
+ /**
1360
+ * Initialize processors for the given sample rate and block layout.
1361
+ *
1362
+ * @param sampleRate - Sample rate in Hz
1363
+ * @param maxBlockSize - Maximum block size per process call
1364
+ * @param numChannels - 1 (mono) or 2 (stereo)
1365
+ */
1366
+ prepare(sampleRate: number, maxBlockSize: number, numChannels: number): void;
1367
+ /**
1368
+ * Process one mono block, returning the processed samples (same length).
1369
+ */
1370
+ processMono(samples: Float32Array): Float32Array;
1371
+ /**
1372
+ * Process one stereo block, returning the processed channels.
1373
+ */
1374
+ processStereo(left: Float32Array, right: Float32Array): {
1375
+ left: Float32Array;
1376
+ right: Float32Array;
1377
+ };
1378
+ /** Reset all processor state without rebuilding. */
1379
+ reset(): void;
1380
+ /** Total reported latency in samples across all active processors. */
1381
+ latencySamples(): number;
1382
+ /** Ordered stage names that will run (e.g. `"eq.tilt"`). */
1383
+ stageNames(): string[];
1384
+ /** Release the underlying WASM object. Safe to call only once. */
1385
+ delete(): void;
1386
+ }
317
1387
  /**
318
- * Extract percussive component from audio.
1388
+ * Block-by-block streaming equalizer wrapping the unified C++
1389
+ * `EqualizerProcessor` (up to 24 bands, RBJ/Vicanek biquads, dynamic EQ,
1390
+ * linear-phase FIR, mid/side processing, and auto-gain).
319
1391
  *
320
- * @param samples - Audio samples (mono, float32)
321
- * @param sampleRate - Sample rate in Hz
322
- * @returns Percussive component
323
- */
324
- export declare function percussive(samples: Float32Array, sampleRate: number): Float32Array;
325
- /**
326
- * Time-stretch audio without changing pitch.
1392
+ * State is maintained across {@link processMono}/{@link processStereo} calls.
1393
+ * Call {@link delete} (or use `try/finally`) to release the underlying WASM
1394
+ * object the embind handle is not garbage-collected automatically.
327
1395
  *
328
- * @param samples - Audio samples (mono, float32)
329
- * @param sampleRate - Sample rate in Hz
330
- * @param rate - Time stretch rate (0.5 = double duration, 2.0 = half duration)
331
- * @returns Time-stretched audio
1396
+ * @example
1397
+ * ```typescript
1398
+ * const eq = new StreamingEqualizer({ sampleRate: 48000, maxBlockSize: 512 });
1399
+ * try {
1400
+ * eq.setBand(0, { type: 'HighShelf', frequencyHz: 8000, gainDb: 6, enabled: true });
1401
+ * const out = eq.processStereo(left, right);
1402
+ * const snapshot = eq.spectrum();
1403
+ * } finally {
1404
+ * eq.delete();
1405
+ * }
1406
+ * ```
332
1407
  */
333
- export declare function timeStretch(samples: Float32Array, sampleRate: number, rate: number): Float32Array;
1408
+ declare class StreamingEqualizer {
1409
+ private eq;
1410
+ constructor(config?: StreamingEqualizerConfig);
1411
+ /**
1412
+ * Configure the band at `index` (0..23). Omitted fields use C++ defaults.
1413
+ */
1414
+ setBand(index: number, band: EqBand): void;
1415
+ /** Disable and reset every band. */
1416
+ clear(): void;
1417
+ /**
1418
+ * Set the global phase mode: 1=ZeroLatency, 2=NaturalPhase, 3=LinearPhase.
1419
+ */
1420
+ setPhaseMode(mode: number): void;
1421
+ /** Enable or disable output auto-gain compensation. */
1422
+ setAutoGain(enabled: boolean): void;
1423
+ /** Set all-band EQ gain scale as a 0.0..2.0 multiplier. */
1424
+ setGainScale(scale: number): void;
1425
+ /** Set post-EQ output gain in dB. */
1426
+ setOutputGainDb(gainDb: number): void;
1427
+ /** Set post-EQ stereo balance in -1.0..1.0; mono input ignores pan. */
1428
+ setOutputPan(pan: number): void;
1429
+ /**
1430
+ * Provide a mono external sidechain key for dynamic bands that opt into
1431
+ * `external_sidechain`. The samples are copied into an owned buffer.
1432
+ */
1433
+ setSidechainMono(samples: Float32Array): void;
1434
+ /**
1435
+ * Provide a stereo external sidechain key. Both channels must match length.
1436
+ */
1437
+ setSidechainStereo(left: Float32Array, right: Float32Array): void;
1438
+ /** Release any borrowed external sidechain buffers. */
1439
+ clearSidechain(): void;
1440
+ /** Auto-gain applied on the most recent block, in dB. */
1441
+ lastAutoGainDb(): number;
1442
+ /** Reported processing latency in samples (non-zero for linear-phase bands). */
1443
+ latencySamples(): number;
1444
+ /**
1445
+ * Process one mono block, returning the equalized samples (same length).
1446
+ */
1447
+ processMono(samples: Float32Array): Float32Array;
1448
+ /**
1449
+ * Process one stereo block, returning the equalized channels.
1450
+ */
1451
+ processStereo(left: Float32Array, right: Float32Array): {
1452
+ left: Float32Array;
1453
+ right: Float32Array;
1454
+ };
1455
+ /**
1456
+ * Read the latest pre/post spectrum snapshot for metering. `seq` increments
1457
+ * each time a new snapshot is published.
1458
+ */
1459
+ spectrum(): EqSpectrumSnapshot;
1460
+ /**
1461
+ * Configure bands so the source spectrum matches the reference spectrum.
1462
+ *
1463
+ * @param source - Source audio (mono samples)
1464
+ * @param reference - Reference audio (mono samples)
1465
+ * @param options - `sampleRate` (default 48000) and `maxBands` (default 8)
1466
+ */
1467
+ match(source: Float32Array, reference: Float32Array, options?: EqMatchOptions): void;
1468
+ /** Release the underlying WASM object. Safe to call only once. */
1469
+ delete(): void;
1470
+ }
334
1471
  /**
335
- * Pitch-shift audio without changing duration.
1472
+ * Get a built-in mixing scene preset serialized as JSON, normalized through the
1473
+ * C mixer API (the same path {@link Mixer.fromSceneJson} uses to load it).
336
1474
  *
337
- * @param samples - Audio samples (mono, float32)
338
- * @param sampleRate - Sample rate in Hz
339
- * @param semitones - Pitch shift in semitones (+12 = one octave up, -12 = one octave down)
340
- * @returns Pitch-shifted audio
1475
+ * @deprecated Use {@link mixingScenePresetJson}, the canonical name shared with
1476
+ * the Node and Python bindings. This alias is retained for backwards
1477
+ * compatibility and may be removed in a future release. Both functions return a
1478
+ * scene JSON string that loads cleanly into a {@link Mixer}.
1479
+ *
1480
+ * @param preset - Preset name (see {@link mixingScenePresetNames})
1481
+ * @returns Scene JSON string
341
1482
  */
342
- export declare function pitchShift(samples: Float32Array, sampleRate: number, semitones: number): Float32Array;
1483
+ declare function mixerScenePresetJson(preset: string): string;
343
1484
  /**
344
- * Normalize audio to target peak level.
1485
+ * Persistent, scene-based stereo mixer.
345
1486
  *
346
- * @param samples - Audio samples (mono, float32)
347
- * @param sampleRate - Sample rate in Hz
348
- * @param targetDb - Target peak level in dB (default: 0 dB = full scale)
349
- * @returns Normalized audio
1487
+ * Build one from a scene JSON string (e.g. {@link mixerScenePresetJson} or a
1488
+ * hand-authored scene), then feed per-strip stereo blocks through
1489
+ * {@link processStereo} to get the routed stereo master. Strips, sends, buses,
1490
+ * and inserts are described entirely by the scene; the routing graph is
1491
+ * compiled lazily on the first {@link processStereo} call (or eagerly via
1492
+ * {@link compile}).
1493
+ *
1494
+ * Call {@link delete} (or use a `try/finally`) to release the underlying WASM
1495
+ * object — the embind handle is not garbage-collected automatically.
1496
+ *
1497
+ * @example
1498
+ * ```typescript
1499
+ * const mixer = Mixer.fromSceneJson(mixerScenePresetJson('basicStereo'), 48000, 512);
1500
+ * try {
1501
+ * const out = mixer.processStereo([stripL], [stripR]);
1502
+ * } finally {
1503
+ * mixer.delete();
1504
+ * }
1505
+ * ```
350
1506
  */
351
- export declare function normalize(samples: Float32Array, sampleRate: number, targetDb?: number): Float32Array;
1507
+ declare class Mixer {
1508
+ private mixer;
1509
+ private constructor();
1510
+ /**
1511
+ * Build a mixer from a scene JSON string.
1512
+ *
1513
+ * @param json - Scene JSON (strips, buses, sends, connections, inserts)
1514
+ * @param sampleRate - Sample rate in Hz (default: 48000)
1515
+ * @param blockSize - Maximum block size per {@link processStereo} call (default: 512)
1516
+ */
1517
+ static fromSceneJson(json: string, sampleRate?: number, blockSize?: number): Mixer;
1518
+ /** Rebuild and compile the routing graph from the current scene topology. */
1519
+ compile(): void;
1520
+ /**
1521
+ * Mix one block of per-strip stereo audio into the stereo master.
1522
+ *
1523
+ * @param leftChannels - `leftChannels[i]` is the left channel of strip `i`
1524
+ * @param rightChannels - `rightChannels[i]` is the right channel of strip `i`
1525
+ * @returns Mixed stereo master (`left`, `right`, `sampleRate`)
1526
+ */
1527
+ processStereo(leftChannels: Float32Array[], rightChannels: Float32Array[]): MixerProcessResult;
1528
+ /**
1529
+ * Mix one block into caller-owned output arrays.
1530
+ *
1531
+ * This avoids allocating the result object and result `Float32Array`s. It is
1532
+ * intended for realtime bridges such as AudioWorklet; the input channel count
1533
+ * must match the scene strip count and all arrays must have the same length.
1534
+ */
1535
+ processStereoInto(leftChannels: Float32Array[], rightChannels: Float32Array[], outLeft: Float32Array, outRight: Float32Array): void;
1536
+ /**
1537
+ * Create reusable WASM-heap input/output views for realtime-style processing.
1538
+ *
1539
+ * Fill `leftInputs[i]` / `rightInputs[i]`, call `process()`, then read
1540
+ * `outLeft` / `outRight`. The views are owned by this mixer and become invalid
1541
+ * after {@link delete}.
1542
+ */
1543
+ createRealtimeBuffer(): MixerRealtimeBuffer;
1544
+ /** Number of strips in the mixer (e.g. strips loaded from the scene). */
1545
+ stripCount(): number;
1546
+ /**
1547
+ * Schedule sample-accurate insert-parameter automation on a strip's insert.
1548
+ *
1549
+ * @param stripIndex - Strip index in `[0, stripCount())`
1550
+ * @param insertIndex - Index into the strip's combined insert sequence
1551
+ * (`[pre-inserts... post-inserts...]`)
1552
+ * @param paramId - Processor-specific parameter id
1553
+ * @param samplePos - Absolute samples from the start of processing (the mixer
1554
+ * advances an internal position from 0 on the first {@link processStereo}
1555
+ * call; recompiling resets it to 0)
1556
+ * @param value - Target parameter value
1557
+ * @param curve - Interpolation curve (default: `'linear'`)
1558
+ * @throws If the strip index is out of range or the schedule call fails
1559
+ * (unknown curve, out-of-range insert index, or full event lane)
1560
+ */
1561
+ scheduleInsertAutomation(stripIndex: number, insertIndex: number, paramId: number, samplePos: number, value: number, curve?: AutomationCurve): void;
1562
+ /**
1563
+ * Resolve a strip's index in `[0, stripCount())` from its scene id, or `null`
1564
+ * when no strip with that id exists (matches the Node binding's `number | null`).
1565
+ */
1566
+ stripById(id: string): number | null;
1567
+ /**
1568
+ * Add a bus to the mixer topology. `role` is one of `'master'`, `'aux'`, or
1569
+ * `'submix'` (defaults to `'aux'`). Marks the routing graph dirty; call
1570
+ * {@link compile} (or {@link processStereo}) to rebuild.
1571
+ */
1572
+ addBus(id: string, role?: string): void;
1573
+ /** Remove a bus by id. Marks the routing graph dirty. */
1574
+ removeBus(id: string): void;
1575
+ /** Number of buses in the mixer topology. */
1576
+ busCount(): number;
1577
+ /**
1578
+ * Add a VCA group with the given gain offset (dB). `members` is a list of
1579
+ * strip ids governed by the group (may be empty).
1580
+ */
1581
+ addVcaGroup(id: string, gainDb?: number, members?: string[]): void;
1582
+ /** Remove a VCA group by id. */
1583
+ removeVcaGroup(id: string): void;
1584
+ /** Number of VCA groups in the mixer topology. */
1585
+ vcaGroupCount(): number;
1586
+ /**
1587
+ * Set a strip's solo state. Takes effect on the next process without a
1588
+ * graph recompile.
1589
+ */
1590
+ setSoloed(stripIndex: number, soloed: boolean): void;
1591
+ /**
1592
+ * Mark a strip solo-safe so it is never implied-muted by another strip's
1593
+ * solo. Takes effect on the next process without a graph recompile.
1594
+ */
1595
+ setSoloSafe(stripIndex: number, soloSafe: boolean): void;
1596
+ /** Invert the polarity of the left and/or right channel of a strip. */
1597
+ setPolarityInvert(stripIndex: number, invertLeft: boolean, invertRight: boolean): void;
1598
+ /** Set the strip's pan law. */
1599
+ setPanLaw(stripIndex: number, panLaw: PanLaw | number): void;
1600
+ /**
1601
+ * Set a per-strip channel delay in samples. This changes the strip's reported
1602
+ * latency; recompile to re-run latency compensation.
1603
+ */
1604
+ setChannelDelaySamples(stripIndex: number, delaySamples: number): void;
1605
+ /** Set the strip's live VCA gain offset in dB (not persisted to the scene). */
1606
+ setVcaOffsetDb(stripIndex: number, offsetDb: number): void;
1607
+ /** Set independent left/right pan positions (dual-pan mode). */
1608
+ setDualPan(stripIndex: number, leftPan: number, rightPan: number): void;
1609
+ /**
1610
+ * Add a send to a strip after construction.
1611
+ *
1612
+ * @param stripIndex - Strip index in `[0, stripCount())`
1613
+ * @param id - Send id
1614
+ * @param destinationBusId - Destination bus id
1615
+ * @param sendDb - Initial send level in dB
1616
+ * @param timing - `'preFader'` or `'postFader'` (default: `'postFader'`)
1617
+ * @returns The new send's index
1618
+ */
1619
+ addSend(stripIndex: number, id: string, destinationBusId: string, sendDb: number, timing?: SendTiming | number): number;
1620
+ /** Set the send level (in dB) for an existing send by index. */
1621
+ setSendDb(stripIndex: number, sendIndex: number, sendDb: number): void;
1622
+ /**
1623
+ * Read a strip's meter snapshot at the given tap point.
1624
+ *
1625
+ * @param stripIndex - Strip index in `[0, stripCount())`
1626
+ * @param tap - `'preFader'` or `'postFader'` (default: `'postFader'`)
1627
+ */
1628
+ meterTap(stripIndex: number, tap?: MeterTap): MixMeterSnapshot;
1629
+ /**
1630
+ * Read a strip's meter snapshot. Alias of {@link meterTap}, provided for
1631
+ * cross-binding (Node/Python) parity.
1632
+ *
1633
+ * @param stripIndex - Strip index in `[0, stripCount())`
1634
+ * @param tap - `'preFader'` or `'postFader'` (default: `'postFader'`)
1635
+ */
1636
+ stripMeter(stripIndex: number, tap?: MeterTap): MixMeterSnapshot;
1637
+ /**
1638
+ * Schedule sample-accurate fader automation on a strip.
1639
+ *
1640
+ * @param stripIndex - Strip index in `[0, stripCount())`
1641
+ * @param samplePos - Absolute samples from the start of processing
1642
+ * @param faderDb - Target fader level in dB
1643
+ * @param curve - Interpolation curve (default: `'linear'`)
1644
+ */
1645
+ scheduleFaderAutomation(stripIndex: number, samplePos: number, faderDb: number, curve?: AutomationCurve): void;
1646
+ /**
1647
+ * Schedule sample-accurate pan automation on a strip.
1648
+ *
1649
+ * @param stripIndex - Strip index in `[0, stripCount())`
1650
+ * @param samplePos - Absolute samples from the start of processing
1651
+ * @param pan - Target pan position
1652
+ * @param curve - Interpolation curve (default: `'linear'`)
1653
+ */
1654
+ schedulePanAutomation(stripIndex: number, samplePos: number, pan: number, curve?: AutomationCurve): void;
1655
+ /**
1656
+ * Schedule sample-accurate width automation on a strip.
1657
+ *
1658
+ * @param stripIndex - Strip index in `[0, stripCount())`
1659
+ * @param samplePos - Absolute samples from the start of processing
1660
+ * @param width - Target stereo width
1661
+ * @param curve - Interpolation curve (default: `'linear'`)
1662
+ */
1663
+ scheduleWidthAutomation(stripIndex: number, samplePos: number, width: number, curve?: AutomationCurve): void;
1664
+ /**
1665
+ * Schedule sample-accurate send-level automation on a strip's send.
1666
+ *
1667
+ * @param stripIndex - Strip index in `[0, stripCount())`
1668
+ * @param sendIndex - Send index in the strip's add order
1669
+ * @param samplePos - Absolute samples from the start of processing
1670
+ * @param db - Target send level in dB
1671
+ * @param curve - Interpolation curve (default: `'linear'`)
1672
+ */
1673
+ scheduleSendAutomation(stripIndex: number, sendIndex: number, samplePos: number, db: number, curve?: AutomationCurve): void;
1674
+ /**
1675
+ * Read up to `maxPoints` of a strip's most recent goniometer samples
1676
+ * (oldest to newest).
1677
+ */
1678
+ readGoniometerLatest(stripIndex: number, maxPoints: number): GoniometerPoint[];
1679
+ /** Serialize the current scene (strips, buses, sends, connections) to JSON. */
1680
+ toSceneJson(): string;
1681
+ /** Release the underlying WASM object. Safe to call only once. */
1682
+ delete(): void;
1683
+ /** Alias for {@link delete}, provided for cross-binding (Node) compatibility. */
1684
+ destroy(): void;
1685
+ }
352
1686
  /**
353
1687
  * Trim silence from beginning and end of audio.
354
1688
  *
@@ -357,7 +1691,7 @@ export declare function normalize(samples: Float32Array, sampleRate: number, tar
357
1691
  * @param thresholdDb - Silence threshold in dB (default: -60 dB)
358
1692
  * @returns Trimmed audio
359
1693
  */
360
- export declare function trim(samples: Float32Array, sampleRate: number, thresholdDb?: number): Float32Array;
1694
+ declare function trim(samples: Float32Array, sampleRate: number, thresholdDb?: number): Float32Array;
361
1695
  /**
362
1696
  * Compute Short-Time Fourier Transform (STFT).
363
1697
  *
@@ -367,7 +1701,7 @@ export declare function trim(samples: Float32Array, sampleRate: number, threshol
367
1701
  * @param hopLength - Hop length (default: 512)
368
1702
  * @returns STFT result with magnitude and power spectrograms
369
1703
  */
370
- export declare function stft(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number): StftResult;
1704
+ declare function stft(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number): StftResult;
371
1705
  /**
372
1706
  * Compute STFT and return magnitude in decibels.
373
1707
  *
@@ -377,7 +1711,7 @@ export declare function stft(samples: Float32Array, sampleRate: number, nFft?: n
377
1711
  * @param hopLength - Hop length (default: 512)
378
1712
  * @returns STFT result with dB values
379
1713
  */
380
- export declare function stftDb(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number): {
1714
+ declare function stftDb(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number): {
381
1715
  nBins: number;
382
1716
  nFrames: number;
383
1717
  db: Float32Array;
@@ -392,7 +1726,7 @@ export declare function stftDb(samples: Float32Array, sampleRate: number, nFft?:
392
1726
  * @param nMels - Number of Mel bands (default: 128)
393
1727
  * @returns Mel spectrogram result
394
1728
  */
395
- export declare function melSpectrogram(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number, nMels?: number): MelSpectrogramResult;
1729
+ declare function melSpectrogram(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number, nMels?: number): MelSpectrogramResult;
396
1730
  /**
397
1731
  * Compute MFCC (Mel-Frequency Cepstral Coefficients).
398
1732
  *
@@ -404,7 +1738,60 @@ export declare function melSpectrogram(samples: Float32Array, sampleRate: number
404
1738
  * @param nMfcc - Number of MFCC coefficients (default: 13)
405
1739
  * @returns MFCC result
406
1740
  */
407
- export declare function mfcc(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number, nMels?: number, nMfcc?: number): MfccResult;
1741
+ declare function mfcc(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number, nMels?: number, nMfcc?: number): MfccResult;
1742
+ /**
1743
+ * Approximate inverse of a Mel filterbank: Mel power spectrogram -> STFT power
1744
+ * spectrogram. Mirrors `feature::mel_to_stft`.
1745
+ *
1746
+ * @param melPower - Mel power spectrogram [nMels x nFrames] row-major
1747
+ * @param nMels - Number of Mel bands
1748
+ * @param nFrames - Number of time frames
1749
+ * @param sampleRate - Sample rate in Hz
1750
+ * @param nFft - FFT size (default: 2048)
1751
+ * @param hopLength - Hop length (default: 512)
1752
+ * @returns STFT power spectrogram result
1753
+ */
1754
+ declare function melToStft(melPower: Float32Array, nMels: number, nFrames: number, sampleRate: number, nFft?: number, hopLength?: number, fmin?: number, fmax?: number): StftPowerResult;
1755
+ /**
1756
+ * Reconstruct audio from a Mel power spectrogram via Griffin-Lim. Mirrors
1757
+ * `feature::mel_to_audio`.
1758
+ *
1759
+ * @param melPower - Mel power spectrogram [nMels x nFrames] row-major
1760
+ * @param nMels - Number of Mel bands
1761
+ * @param nFrames - Number of time frames
1762
+ * @param sampleRate - Sample rate in Hz
1763
+ * @param nFft - FFT size (default: 2048)
1764
+ * @param hopLength - Hop length (default: 512)
1765
+ * @param nIter - Griffin-Lim iterations (default: 32)
1766
+ * @returns Reconstructed audio samples (mono, float32)
1767
+ */
1768
+ declare function melToAudio(melPower: Float32Array, nMels: number, nFrames: number, sampleRate: number, nFft?: number, hopLength?: number, nIter?: number, fmin?: number, fmax?: number): Float32Array;
1769
+ /**
1770
+ * Invert MFCC coefficients back to a Mel power spectrogram. Mirrors
1771
+ * `feature::mfcc_to_mel`.
1772
+ *
1773
+ * @param mfccCoefficients - MFCC matrix [nMfcc x nFrames] row-major
1774
+ * @param nMfcc - Number of MFCC coefficients
1775
+ * @param nFrames - Number of time frames
1776
+ * @param nMels - Number of Mel bins to reconstruct (default: 128)
1777
+ * @returns Mel power spectrogram result
1778
+ */
1779
+ declare function mfccToMel(mfccCoefficients: Float32Array, nMfcc: number, nFrames: number, nMels?: number): MelPowerResult;
1780
+ /**
1781
+ * Reconstruct audio directly from MFCC coefficients via Griffin-Lim. Mirrors
1782
+ * `feature::mfcc_to_audio`.
1783
+ *
1784
+ * @param mfccCoefficients - MFCC matrix [nMfcc x nFrames] row-major
1785
+ * @param nMfcc - Number of MFCC coefficients
1786
+ * @param nFrames - Number of time frames
1787
+ * @param nMels - Number of Mel bins (default: 128)
1788
+ * @param sampleRate - Sample rate in Hz
1789
+ * @param nFft - FFT size (default: 2048)
1790
+ * @param hopLength - Hop length (default: 512)
1791
+ * @param nIter - Griffin-Lim iterations (default: 32)
1792
+ * @returns Reconstructed audio samples (mono, float32)
1793
+ */
1794
+ declare function mfccToAudio(mfccCoefficients: Float32Array, nMfcc: number, nFrames: number, nMels: number, sampleRate: number, nFft?: number, hopLength?: number, nIter?: number, fmin?: number, fmax?: number): Float32Array;
408
1795
  /**
409
1796
  * Compute chromagram (pitch class distribution).
410
1797
  *
@@ -414,7 +1801,7 @@ export declare function mfcc(samples: Float32Array, sampleRate: number, nFft?: n
414
1801
  * @param hopLength - Hop length (default: 512)
415
1802
  * @returns Chroma features result
416
1803
  */
417
- export declare function chroma(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number): ChromaResult;
1804
+ declare function chroma(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number): ChromaResult;
418
1805
  /**
419
1806
  * Compute spectral centroid (center of mass of spectrum).
420
1807
  *
@@ -424,7 +1811,7 @@ export declare function chroma(samples: Float32Array, sampleRate: number, nFft?:
424
1811
  * @param hopLength - Hop length (default: 512)
425
1812
  * @returns Spectral centroid in Hz for each frame
426
1813
  */
427
- export declare function spectralCentroid(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number): Float32Array;
1814
+ declare function spectralCentroid(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number): Float32Array;
428
1815
  /**
429
1816
  * Compute spectral bandwidth.
430
1817
  *
@@ -434,7 +1821,7 @@ export declare function spectralCentroid(samples: Float32Array, sampleRate: numb
434
1821
  * @param hopLength - Hop length (default: 512)
435
1822
  * @returns Spectral bandwidth in Hz for each frame
436
1823
  */
437
- export declare function spectralBandwidth(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number): Float32Array;
1824
+ declare function spectralBandwidth(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number): Float32Array;
438
1825
  /**
439
1826
  * Compute spectral rolloff frequency.
440
1827
  *
@@ -445,7 +1832,7 @@ export declare function spectralBandwidth(samples: Float32Array, sampleRate: num
445
1832
  * @param rollPercent - Percentage threshold (default: 0.85)
446
1833
  * @returns Rolloff frequency in Hz for each frame
447
1834
  */
448
- export declare function spectralRolloff(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number, rollPercent?: number): Float32Array;
1835
+ declare function spectralRolloff(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number, rollPercent?: number): Float32Array;
449
1836
  /**
450
1837
  * Compute spectral flatness.
451
1838
  *
@@ -455,7 +1842,7 @@ export declare function spectralRolloff(samples: Float32Array, sampleRate: numbe
455
1842
  * @param hopLength - Hop length (default: 512)
456
1843
  * @returns Spectral flatness for each frame (0 = tonal, 1 = noise-like)
457
1844
  */
458
- export declare function spectralFlatness(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number): Float32Array;
1845
+ declare function spectralFlatness(samples: Float32Array, sampleRate: number, nFft?: number, hopLength?: number): Float32Array;
459
1846
  /**
460
1847
  * Compute zero crossing rate.
461
1848
  *
@@ -465,7 +1852,7 @@ export declare function spectralFlatness(samples: Float32Array, sampleRate: numb
465
1852
  * @param hopLength - Hop length (default: 512)
466
1853
  * @returns Zero crossing rate for each frame
467
1854
  */
468
- export declare function zeroCrossingRate(samples: Float32Array, sampleRate: number, frameLength?: number, hopLength?: number): Float32Array;
1855
+ declare function zeroCrossingRate(samples: Float32Array, sampleRate: number, frameLength?: number, hopLength?: number): Float32Array;
469
1856
  /**
470
1857
  * Compute RMS energy.
471
1858
  *
@@ -475,7 +1862,7 @@ export declare function zeroCrossingRate(samples: Float32Array, sampleRate: numb
475
1862
  * @param hopLength - Hop length (default: 512)
476
1863
  * @returns RMS energy for each frame
477
1864
  */
478
- export declare function rmsEnergy(samples: Float32Array, sampleRate: number, frameLength?: number, hopLength?: number): Float32Array;
1865
+ declare function rmsEnergy(samples: Float32Array, sampleRate: number, frameLength?: number, hopLength?: number): Float32Array;
479
1866
  /**
480
1867
  * Detect pitch using YIN algorithm.
481
1868
  *
@@ -488,7 +1875,7 @@ export declare function rmsEnergy(samples: Float32Array, sampleRate: number, fra
488
1875
  * @param threshold - YIN threshold (default: 0.3)
489
1876
  * @returns Pitch detection result
490
1877
  */
491
- export declare function pitchYin(samples: Float32Array, sampleRate: number, frameLength?: number, hopLength?: number, fmin?: number, fmax?: number, threshold?: number): PitchResult;
1878
+ declare function pitchYin(samples: Float32Array, sampleRate: number, frameLength?: number, hopLength?: number, fmin?: number, fmax?: number, threshold?: number): PitchResult;
492
1879
  /**
493
1880
  * Detect pitch using pYIN algorithm (probabilistic YIN with HMM smoothing).
494
1881
  *
@@ -501,49 +1888,49 @@ export declare function pitchYin(samples: Float32Array, sampleRate: number, fram
501
1888
  * @param threshold - YIN threshold (default: 0.3)
502
1889
  * @returns Pitch detection result
503
1890
  */
504
- export declare function pitchPyin(samples: Float32Array, sampleRate: number, frameLength?: number, hopLength?: number, fmin?: number, fmax?: number, threshold?: number): PitchResult;
1891
+ declare function pitchPyin(samples: Float32Array, sampleRate: number, frameLength?: number, hopLength?: number, fmin?: number, fmax?: number, threshold?: number): PitchResult;
505
1892
  /**
506
1893
  * Convert frequency in Hz to Mel scale.
507
1894
  *
508
1895
  * @param hz - Frequency in Hz
509
1896
  * @returns Mel frequency
510
1897
  */
511
- export declare function hzToMel(hz: number): number;
1898
+ declare function hzToMel(hz: number): number;
512
1899
  /**
513
1900
  * Convert Mel scale to frequency in Hz.
514
1901
  *
515
1902
  * @param mel - Mel frequency
516
1903
  * @returns Frequency in Hz
517
1904
  */
518
- export declare function melToHz(mel: number): number;
1905
+ declare function melToHz(mel: number): number;
519
1906
  /**
520
1907
  * Convert frequency in Hz to MIDI note number.
521
1908
  *
522
1909
  * @param hz - Frequency in Hz
523
1910
  * @returns MIDI note number (A4 = 440 Hz = 69)
524
1911
  */
525
- export declare function hzToMidi(hz: number): number;
1912
+ declare function hzToMidi(hz: number): number;
526
1913
  /**
527
1914
  * Convert MIDI note number to frequency in Hz.
528
1915
  *
529
1916
  * @param midi - MIDI note number
530
1917
  * @returns Frequency in Hz
531
1918
  */
532
- export declare function midiToHz(midi: number): number;
1919
+ declare function midiToHz(midi: number): number;
533
1920
  /**
534
1921
  * Convert frequency in Hz to note name.
535
1922
  *
536
1923
  * @param hz - Frequency in Hz
537
1924
  * @returns Note name (e.g., "A4", "C#5")
538
1925
  */
539
- export declare function hzToNote(hz: number): string;
1926
+ declare function hzToNote(hz: number): string;
540
1927
  /**
541
1928
  * Convert note name to frequency in Hz.
542
1929
  *
543
1930
  * @param note - Note name (e.g., "A4", "C#5")
544
1931
  * @returns Frequency in Hz
545
1932
  */
546
- export declare function noteToHz(note: string): number;
1933
+ declare function noteToHz(note: string): number;
547
1934
  /**
548
1935
  * Convert frame index to time in seconds.
549
1936
  *
@@ -552,7 +1939,7 @@ export declare function noteToHz(note: string): number;
552
1939
  * @param hopLength - Hop length in samples
553
1940
  * @returns Time in seconds
554
1941
  */
555
- export declare function framesToTime(frames: number, sr: number, hopLength: number): number;
1942
+ declare function framesToTime(frames: number, sr: number, hopLength: number): number;
556
1943
  /**
557
1944
  * Convert time in seconds to frame index.
558
1945
  *
@@ -561,7 +1948,140 @@ export declare function framesToTime(frames: number, sr: number, hopLength: numb
561
1948
  * @param hopLength - Hop length in samples
562
1949
  * @returns Frame index
563
1950
  */
564
- export declare function timeToFrames(time: number, sr: number, hopLength: number): number;
1951
+ declare function timeToFrames(time: number, sr: number, hopLength: number): number;
1952
+ declare function framesToSamples(frames: number, hopLength?: number, nFft?: number): number;
1953
+ declare function samplesToFrames(samples: number, hopLength?: number, nFft?: number): number;
1954
+ declare function powerToDb(values: Float32Array, ref?: number, amin?: number, topDb?: number): Float32Array;
1955
+ declare function amplitudeToDb(values: Float32Array, ref?: number, amin?: number, topDb?: number): Float32Array;
1956
+ declare function dbToPower(values: Float32Array, ref?: number): Float32Array;
1957
+ declare function dbToAmplitude(values: Float32Array, ref?: number): Float32Array;
1958
+ declare function preemphasis(samples: Float32Array, coef?: number, zi?: number): Float32Array;
1959
+ declare function deemphasis(samples: Float32Array, coef?: number, zi?: number): Float32Array;
1960
+ declare function trimSilence(samples: Float32Array, topDb?: number, frameLength?: number, hopLength?: number): WasmTrimResult;
1961
+ declare function splitSilence(samples: Float32Array, topDb?: number, frameLength?: number, hopLength?: number): Int32Array;
1962
+ declare function frameSignal(samples: Float32Array, frameLength: number, hopLength: number): WasmFrameResult;
1963
+ declare function padCenter(values: Float32Array, size: number, padValue?: number): Float32Array;
1964
+ declare function fixLength(values: Float32Array, size: number, padValue?: number): Float32Array;
1965
+ declare function fixFrames(frames: Int32Array, xMin?: number, xMax?: number, pad?: boolean): Int32Array;
1966
+ declare function peakPick(values: Float32Array, preMax: number, postMax: number, preAvg: number, postAvg: number, delta: number, wait: number): Int32Array;
1967
+ declare function vectorNormalize(values: Float32Array, normType?: number, threshold?: number): Float32Array;
1968
+ declare function pcen(values: Float32Array, nBins: number, nFrames: number, options?: Record<string, number>): Float32Array;
1969
+ declare function tonnetz(chromagram: Float32Array, nChroma: number, nFrames: number): Float32Array;
1970
+ declare function tempogram(onsetEnvelope: Float32Array, sampleRate: number, hopLength?: number, winLength?: number, mode?: TempogramMode): WasmTempogramResult;
1971
+ declare function cyclicTempogram(onsetEnvelope: Float32Array, sampleRate: number, hopLength?: number, winLength?: number, bpmMin?: number, nBins?: number): WasmCyclicTempogramResult;
1972
+ declare function plp(onsetEnvelope: Float32Array, sampleRate: number, hopLength?: number, tempoMin?: number, tempoMax?: number, winLength?: number): Float32Array;
1973
+ /**
1974
+ * Compute NNLS (non-negative least squares) chromagram.
1975
+ *
1976
+ * @param samples - Audio samples (mono, float32)
1977
+ * @param sampleRate - Sample rate in Hz (default: 22050)
1978
+ * @returns NNLS chroma result
1979
+ */
1980
+ declare function nnlsChroma(samples: Float32Array, sampleRate?: number): WasmNnlsChromaResult;
1981
+ /**
1982
+ * Compute the Constant-Q Transform magnitude.
1983
+ *
1984
+ * @param samples - Audio samples (mono, float32)
1985
+ * @param sampleRate - Sample rate in Hz (default: 22050)
1986
+ * @param hopLength - Hop length (default: 512)
1987
+ * @param fmin - Minimum frequency in Hz (default: 32.70319566257483, C1)
1988
+ * @param nBins - Number of frequency bins (default: 84)
1989
+ * @param binsPerOctave - Bins per octave (default: 12)
1990
+ * @returns CQT magnitude result
1991
+ */
1992
+ declare function cqt(samples: Float32Array, sampleRate?: number, hopLength?: number, fmin?: number, nBins?: number, binsPerOctave?: number): CqtResult;
1993
+ /**
1994
+ * Compute the Variable-Q Transform magnitude (gamma controls Q).
1995
+ *
1996
+ * @param samples - Audio samples (mono, float32)
1997
+ * @param sampleRate - Sample rate in Hz (default: 22050)
1998
+ * @param hopLength - Hop length (default: 512)
1999
+ * @param fmin - Minimum frequency in Hz (default: 32.70319566257483, C1)
2000
+ * @param nBins - Number of frequency bins (default: 84)
2001
+ * @param binsPerOctave - Bins per octave (default: 12)
2002
+ * @param gamma - Bandwidth offset; 0 is equivalent to CQT (default: 0)
2003
+ * @returns VQT magnitude result (same shape as CQT)
2004
+ */
2005
+ declare function vqt(samples: Float32Array, sampleRate?: number, hopLength?: number, fmin?: number, nBins?: number, binsPerOctave?: number, gamma?: number): CqtResult;
2006
+ /**
2007
+ * Detect song-structure sections (intro/verse/chorus/...).
2008
+ *
2009
+ * @param samples - Audio samples (mono, float32)
2010
+ * @param sampleRate - Sample rate in Hz (default: 22050)
2011
+ * @param nFft - FFT size (default: 2048)
2012
+ * @param hopLength - Hop length (default: 512)
2013
+ * @param minSectionSec - Minimum section duration in seconds (default: 8.0)
2014
+ * @returns Array of detected sections
2015
+ */
2016
+ declare function analyzeSections(samples: Float32Array, sampleRate?: number, nFft?: number, hopLength?: number, minSectionSec?: number): Section[];
2017
+ /**
2018
+ * Extract the melody contour from monophonic audio via YIN.
2019
+ *
2020
+ * @param samples - Audio samples (mono, float32)
2021
+ * @param sampleRate - Sample rate in Hz (default: 22050)
2022
+ * @param fmin - Minimum frequency in Hz (default: 65.0)
2023
+ * @param fmax - Maximum frequency in Hz (default: 2093.0)
2024
+ * @param frameLength - Frame length in samples (default: 2048)
2025
+ * @param hopLength - Hop length (default: 512)
2026
+ * @param threshold - YIN threshold; lower is stricter (default: 0.1)
2027
+ * @returns Melody contour with per-frame pitch points and summary stats
2028
+ */
2029
+ declare function analyzeMelody(samples: Float32Array, sampleRate?: number, fmin?: number, fmax?: number, frameLength?: number, hopLength?: number, threshold?: number): MelodyResult;
2030
+ /**
2031
+ * Compute the onset strength envelope.
2032
+ *
2033
+ * @param samples - Audio samples (mono, float32)
2034
+ * @param sampleRate - Sample rate in Hz (default: 22050)
2035
+ * @param nFft - FFT size (default: 2048)
2036
+ * @param hopLength - Hop length (default: 512)
2037
+ * @param nMels - Number of Mel bands (default: 128)
2038
+ * @returns Onset envelope for each frame
2039
+ */
2040
+ declare function onsetEnvelope(samples: Float32Array, sampleRate?: number, nFft?: number, hopLength?: number, nMels?: number): Float32Array;
2041
+ /**
2042
+ * Compute the Fourier tempogram from an onset envelope.
2043
+ *
2044
+ * @param onsetEnvelope - Onset strength envelope (float32)
2045
+ * @param sampleRate - Sample rate in Hz (default: 22050)
2046
+ * @param hopLength - Hop length (default: 512)
2047
+ * @param winLength - Window length in frames (default: 384)
2048
+ * @returns Fourier tempogram result
2049
+ */
2050
+ declare function fourierTempogram(onsetEnvelope: Float32Array, sampleRate?: number, hopLength?: number, winLength?: number): WasmFourierTempogramResult;
2051
+ /**
2052
+ * Compute tempogram ratio features.
2053
+ *
2054
+ * @param tempogramData - Tempogram data (float32)
2055
+ * @param winLength - Window length in frames (default: 384)
2056
+ * @param sampleRate - Sample rate in Hz (default: 22050)
2057
+ * @param hopLength - Hop length (default: 512)
2058
+ * @returns Tempogram ratio features
2059
+ */
2060
+ declare function tempogramRatio(tempogramData: Float32Array, winLength?: number, sampleRate?: number, hopLength?: number): Float32Array;
2061
+ /**
2062
+ * Measure loudness (EBU R128 / ITU-R BS.1770).
2063
+ *
2064
+ * @param samples - Audio samples (mono, float32)
2065
+ * @param sampleRate - Sample rate in Hz (default: 22050)
2066
+ * @returns Loudness measurement result
2067
+ */
2068
+ declare function lufs(samples: Float32Array, sampleRate?: number): LufsResult;
2069
+ /**
2070
+ * Compute the momentary loudness (LUFS) over time.
2071
+ *
2072
+ * @param samples - Audio samples (mono, float32)
2073
+ * @param sampleRate - Sample rate in Hz (default: 22050)
2074
+ * @returns Momentary LUFS values over time
2075
+ */
2076
+ declare function momentaryLufs(samples: Float32Array, sampleRate?: number): Float32Array;
2077
+ /**
2078
+ * Compute the short-term loudness (LUFS) over time.
2079
+ *
2080
+ * @param samples - Audio samples (mono, float32)
2081
+ * @param sampleRate - Sample rate in Hz (default: 22050)
2082
+ * @returns Short-term LUFS values over time
2083
+ */
2084
+ declare function shortTermLufs(samples: Float32Array, sampleRate?: number): Float32Array;
565
2085
  /**
566
2086
  * Resample audio to a different sample rate.
567
2087
  *
@@ -570,7 +2090,7 @@ export declare function timeToFrames(time: number, sr: number, hopLength: number
570
2090
  * @param targetSr - Target sample rate in Hz
571
2091
  * @returns Resampled audio
572
2092
  */
573
- export declare function resample(samples: Float32Array, srcSr: number, targetSr: number): Float32Array;
2093
+ declare function resample(samples: Float32Array, srcSr: number, targetSr: number): Float32Array;
574
2094
  /**
575
2095
  * Wrapper around audio data that exposes all analysis and feature functions as instance methods.
576
2096
  *
@@ -587,7 +2107,7 @@ export declare function resample(samples: Float32Array, srcSr: number, targetSr:
587
2107
  * const mel = audio.melSpectrogram();
588
2108
  * ```
589
2109
  */
590
- export declare class Audio {
2110
+ declare class Audio {
591
2111
  private _samples;
592
2112
  private _sampleRate;
593
2113
  private constructor();
@@ -602,9 +2122,12 @@ export declare class Audio {
602
2122
  /** Duration in seconds. */
603
2123
  get duration(): number;
604
2124
  detectBpm(): number;
605
- detectKey(): Key;
2125
+ detectKey(options?: KeyDetectionOptions): Key;
2126
+ detectKeyCandidates(options?: KeyDetectionOptions): KeyCandidate[];
606
2127
  detectOnsets(): Float32Array;
607
2128
  detectBeats(): Float32Array;
2129
+ detectDownbeats(): Float32Array;
2130
+ detectChords(options?: ChordDetectionOptions): ChordAnalysisResult;
608
2131
  analyze(): AnalysisResult;
609
2132
  analyzeWithProgress(onProgress: ProgressCallback): AnalysisResult;
610
2133
  hpss(kernelHarmonic?: number, kernelPercussive?: number): HpssResult;
@@ -612,7 +2135,14 @@ export declare class Audio {
612
2135
  percussive(): Float32Array;
613
2136
  timeStretch(rate: number): Float32Array;
614
2137
  pitchShift(semitones: number): Float32Array;
2138
+ pitchCorrectToMidi(currentMidi: number, targetMidi: number): Float32Array;
2139
+ noteStretch(onsetSample: number, offsetSample: number, stretchRatio: number): Float32Array;
2140
+ voiceChange(pitchSemitones: number, formantFactor: number): Float32Array;
615
2141
  normalize(targetDb?: number): Float32Array;
2142
+ mastering(targetLufs?: number, ceilingDb?: number, truePeakOversample?: number): MasteringResult;
2143
+ masteringChain(config: MasteringChainConfig): MasteringChainResult;
2144
+ masterAudio(presetName: MasteringPreset, overrides?: Record<string, number | boolean> | null): MasteringChainResult;
2145
+ masteringProcess(processorName: SoloProcessor, params?: MasteringProcessorParams): MasteringResult;
616
2146
  trim(thresholdDb?: number): Float32Array;
617
2147
  stft(nFft?: number, hopLength?: number): StftResult;
618
2148
  stftDb(nFft?: number, hopLength?: number): {
@@ -623,6 +2153,11 @@ export declare class Audio {
623
2153
  melSpectrogram(nFft?: number, hopLength?: number, nMels?: number): MelSpectrogramResult;
624
2154
  mfcc(nFft?: number, hopLength?: number, nMels?: number, nMfcc?: number): MfccResult;
625
2155
  chroma(nFft?: number, hopLength?: number): ChromaResult;
2156
+ nnlsChroma(): WasmNnlsChromaResult;
2157
+ onsetEnvelope(nFft?: number, hopLength?: number, nMels?: number): Float32Array;
2158
+ lufs(): LufsResult;
2159
+ momentaryLufs(): Float32Array;
2160
+ shortTermLufs(): Float32Array;
626
2161
  spectralCentroid(nFft?: number, hopLength?: number): Float32Array;
627
2162
  spectralBandwidth(nFft?: number, hopLength?: number): Float32Array;
628
2163
  spectralRolloff(nFft?: number, hopLength?: number, rollPercent?: number): Float32Array;
@@ -633,96 +2168,6 @@ export declare class Audio {
633
2168
  pitchPyin(frameLength?: number, hopLength?: number, fmin?: number, fmax?: number, threshold?: number): PitchResult;
634
2169
  resample(targetSr: number): Float32Array;
635
2170
  }
636
- /**
637
- * A detected chord change in the progression
638
- */
639
- export interface ChordChange {
640
- root: PitchClass;
641
- quality: ChordQuality;
642
- startTime: number;
643
- confidence: number;
644
- }
645
- /**
646
- * A chord detected at bar boundary (beat-synchronized)
647
- */
648
- export interface BarChord {
649
- barIndex: number;
650
- root: PitchClass;
651
- quality: ChordQuality;
652
- startTime: number;
653
- confidence: number;
654
- }
655
- /**
656
- * Pattern score for known chord progressions
657
- */
658
- export interface PatternScore {
659
- name: string;
660
- score: number;
661
- }
662
- /**
663
- * Progressive estimation results for BPM, Key, and Chord
664
- */
665
- export interface ProgressiveEstimate {
666
- bpm: number;
667
- bpmConfidence: number;
668
- bpmCandidateCount: number;
669
- key: PitchClass;
670
- keyMinor: boolean;
671
- keyConfidence: number;
672
- chordRoot: PitchClass;
673
- chordQuality: ChordQuality;
674
- chordConfidence: number;
675
- chordProgression: ChordChange[];
676
- barChordProgression: BarChord[];
677
- currentBar: number;
678
- barDuration: number;
679
- votedPattern: BarChord[];
680
- patternLength: number;
681
- detectedPatternName: string;
682
- detectedPatternScore: number;
683
- allPatternScores: PatternScore[];
684
- accumulatedSeconds: number;
685
- usedFrames: number;
686
- updated: boolean;
687
- }
688
- /**
689
- * Statistics and current state of the analyzer
690
- */
691
- export interface AnalyzerStats {
692
- totalFrames: number;
693
- totalSamples: number;
694
- durationSeconds: number;
695
- estimate: ProgressiveEstimate;
696
- }
697
- /**
698
- * Frame buffer with analysis results
699
- */
700
- export interface FrameBuffer {
701
- nFrames: number;
702
- timestamps: Float32Array;
703
- mel: Float32Array;
704
- chroma: Float32Array;
705
- onsetStrength: Float32Array;
706
- rmsEnergy: Float32Array;
707
- spectralCentroid: Float32Array;
708
- spectralFlatness: Float32Array;
709
- chordRoot: Int32Array;
710
- chordQuality: Int32Array;
711
- chordConfidence: Float32Array;
712
- }
713
- /**
714
- * Configuration for StreamAnalyzer
715
- */
716
- export interface StreamConfig {
717
- sampleRate: number;
718
- nFft?: number;
719
- hopLength?: number;
720
- nMels?: number;
721
- computeMel?: boolean;
722
- computeChroma?: boolean;
723
- computeOnset?: boolean;
724
- emitEveryNFrames?: number;
725
- }
726
2171
  /**
727
2172
  * Real-time streaming audio analyzer.
728
2173
  *
@@ -744,7 +2189,7 @@ export interface StreamConfig {
744
2189
  * console.log('Chord progression:', stats.estimate.chordProgression);
745
2190
  * ```
746
2191
  */
747
- export declare class StreamAnalyzer {
2192
+ declare class StreamAnalyzer {
748
2193
  private analyzer;
749
2194
  /**
750
2195
  * Create a new StreamAnalyzer.
@@ -776,6 +2221,8 @@ export declare class StreamAnalyzer {
776
2221
  * @returns Frame buffer with analysis results
777
2222
  */
778
2223
  readFrames(maxFrames: number): FrameBuffer;
2224
+ readFramesU8(maxFrames: number): StreamFramesU8;
2225
+ readFramesI16(maxFrames: number): StreamFramesI16;
779
2226
  /**
780
2227
  * Reset the analyzer state.
781
2228
  *
@@ -828,5 +2275,5 @@ export declare class StreamAnalyzer {
828
2275
  */
829
2276
  dispose(): void;
830
2277
  }
831
- export { PitchClass as Pitch };
832
- //# sourceMappingURL=index.d.ts.map
2278
+
2279
+ export { type AcousticResult, type AnalysisResult, type AnalyzerStats, Audio, type AutomationCurve, type BarChord, type Beat, type Chord, type ChordAnalysisResult, type ChordChange, type ChordDetectionOptions, ChordQuality, type ChromaResult, type CqtResult, type Dynamics, EXPECTED_ENGINE_ABI_VERSION, type EngineAutomationPoint, type EngineBounceOptions, type EngineBounceResult, type EngineCapabilities, type EngineCaptureStatus, type EngineClip, type EngineFreezeOptions, type EngineFreezeResult, type EngineGraphSpec, type EngineMarker, type EngineMeterTelemetry, type EngineMetronomeConfig, type EngineParameterInfo, type EngineTelemetry, type EngineTransportState, type EqBand, type EqBandPhase, type EqBandType, type EqCoeffMode, type EqMatchOptions, type EqSpectrumSnapshot, type EqStereoPlacement, type FrameBuffer, type GoniometerPoint, type HpssResult, type Key, type KeyCandidate, type KeyDetectionOptions, KeyProfile, type KeyProfileName, type LufsResult, type MasteringChainConfig, type MasteringChainResult, type MasteringPreset, type MasteringProcessorParams, type MasteringResult, type MasteringStereoChainResult, type MasteringStereoResult, type MelSpectrogramResult, type MelodyPoint, type MelodyResult, type MeterTap, type MfccResult, type MixMeterSnapshot, type MixOptions, type MixResult, Mixer, type MixerProcessResult, type MixerRealtimeBuffer, Mode, type PairAnalysis, type PairProcessor, type PanLaw, type PanMode, type PatternScore, PitchClass as Pitch, PitchClass, type PitchResult, type ProgressCallback, type ProgressiveEstimate, RealtimeEngine, type RhythmFeatures, type Section, SectionType, type SendTiming, type SoloProcessor, type StereoAnalysis, type StftResult, StreamAnalyzer, type StreamConfig, type StreamFramesI16, type StreamFramesU8, StreamingEqualizer, type StreamingEqualizerConfig, StreamingMasteringChain, type StreamingPlatform, type Timbre, type TimeSignature, amplitudeToDb, analyze, analyzeImpulseResponse, analyzeMelody, analyzeSections, analyzeWithProgress, chroma, cqt, cyclicTempogram, dbToAmplitude, dbToPower, deemphasis, detectAcoustic, detectBeats, detectBpm, detectChords, detectDownbeats, detectKey, detectKeyCandidates, detectOnsets, engineAbiVersion, engineCapabilities, fixFrames, fixLength, fourierTempogram, frameSignal, framesToSamples, framesToTime, harmonic, hpss, hzToMel, hzToMidi, hzToNote, init, isInitialized, lufs, masterAudio, masterAudioStereo, mastering, masteringAssistantSuggest, masteringAudioProfile, masteringChain, masteringChainStereo, masteringChainStereoWithProgress, masteringChainWithProgress, masteringPairAnalysisNames, masteringPairAnalyze, masteringPairProcess, masteringPairProcessorNames, masteringPresetNames, masteringProcess, masteringProcessStereo, masteringProcessorNames, masteringStereoAnalysisNames, masteringStereoAnalyze, masteringStreamingPreview, melSpectrogram, melToAudio, melToHz, melToStft, mfcc, mfccToAudio, mfccToMel, midiToHz, mixStereo, mixerScenePresetJson, mixingScenePresetJson, mixingScenePresetNames, momentaryLufs, nnlsChroma, normalize, noteStretch, noteToHz, onsetEnvelope, padCenter, pcen, peakPick, percussive, pitchCorrectToMidi, pitchPyin, pitchShift, pitchYin, plp, powerToDb, preemphasis, resample, rmsEnergy, samplesToFrames, shortTermLufs, spectralBandwidth, spectralCentroid, spectralFlatness, spectralRolloff, splitSilence, stft, stftDb, tempogram, tempogramRatio, timeStretch, timeToFrames, tonnetz, trim, trimSilence, vectorNormalize, version, voiceChange, vqt, zeroCrossingRate };