@libraz/libsonare 1.5.2 → 1.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +18 -3
  2. package/dist/index.d.ts +1147 -181
  3. package/dist/index.js +4826 -3941
  4. package/dist/index.js.map +1 -1
  5. package/dist/sonare.js +1 -1
  6. package/dist/sonare.wasm +0 -0
  7. package/dist/worklet.d.ts +29 -1
  8. package/dist/worklet.js +1067 -973
  9. package/dist/worklet.js.map +1 -1
  10. package/package.json +2 -1
  11. package/src/_chain_config.ts +46 -0
  12. package/src/audio.ts +24 -4
  13. package/src/effects_mastering.ts +25 -1
  14. package/src/effects_transform.ts +283 -43
  15. package/src/effects_voice_change.ts +46 -53
  16. package/src/feature_core.ts +316 -12
  17. package/src/feature_music.ts +357 -0
  18. package/src/feature_pitch.ts +61 -0
  19. package/src/feature_resample.ts +17 -2
  20. package/src/feature_spectral.ts +349 -2
  21. package/src/feature_spectrogram.ts +336 -0
  22. package/src/index.ts +130 -1
  23. package/src/mastering_chain.ts +305 -50
  24. package/src/mastering_core.ts +232 -16
  25. package/src/mastering_dynamics.ts +66 -10
  26. package/src/mastering_repair.ts +119 -7
  27. package/src/metering.ts +366 -81
  28. package/src/mixer.ts +9 -2
  29. package/src/mixing_oneshot.ts +25 -5
  30. package/src/module_state.ts +1 -1
  31. package/src/project_class.ts +17 -6
  32. package/src/project_internal.ts +10 -2
  33. package/src/project_types.ts +25 -2
  34. package/src/public_types_mastering.ts +114 -4
  35. package/src/public_types_spectral.ts +7 -0
  36. package/src/quick_analysis.ts +325 -117
  37. package/src/realtime_engine.ts +8 -0
  38. package/src/sonare.js.d.ts +31 -0
  39. package/src/stream_analyzer.ts +20 -1
  40. package/src/stream_types.ts +12 -1
  41. package/src/validation.ts +17 -2
  42. package/src/worklet/engine-clips.ts +67 -2
  43. package/src/worklet/engine-processor.ts +33 -5
  44. package/src/worklet/engine.ts +7 -3
  45. package/src/worklet/guards.ts +3 -0
  46. package/src/worklet/messages.ts +27 -0
@@ -25,6 +25,80 @@ type GuardedOptions = ValidateOptions;
25
25
  type AnalyzeSectionsGuardedOptions = AnalyzeSectionsOptions & ValidateOptions;
26
26
  type MelodyGuardedOptions = MelodyOptions & ValidateOptions;
27
27
 
28
+ /** Canonical request form shared by the Constant-Q transform variants. */
29
+ export interface CqtRequest extends GuardedOptions {
30
+ samples: Float32Array;
31
+ sampleRate?: number;
32
+ hopLength?: number;
33
+ fmin?: number;
34
+ nBins?: number;
35
+ binsPerOctave?: number;
36
+ }
37
+
38
+ /** Canonical request form for {@link vqt}. */
39
+ export interface VqtRequest extends CqtRequest {
40
+ gamma?: number;
41
+ }
42
+
43
+ export interface OnsetEnvelopeRequest extends GuardedOptions {
44
+ samples: Float32Array;
45
+ sampleRate?: number;
46
+ nFft?: number;
47
+ hopLength?: number;
48
+ nMels?: number;
49
+ }
50
+
51
+ export interface OnsetStrengthMultiRequest extends OnsetEnvelopeRequest {
52
+ nBands?: number;
53
+ }
54
+
55
+ export interface FourierTempogramRequest extends GuardedOptions {
56
+ onsetEnvelope: Float32Array;
57
+ sampleRate?: number;
58
+ hopLength?: number;
59
+ winLength?: number;
60
+ }
61
+
62
+ export interface TempogramRatioRequest extends GuardedOptions {
63
+ tempogramData: Float32Array;
64
+ winLength?: number;
65
+ sampleRate?: number;
66
+ hopLength?: number;
67
+ factors?: Float32Array | number[];
68
+ }
69
+
70
+ export interface CqtToAudioRequest extends GuardedOptions {
71
+ magnitude: Float32Array;
72
+ nBins: number;
73
+ nFrames: number;
74
+ sampleRate?: number;
75
+ hopLength?: number;
76
+ fmin?: number;
77
+ binsPerOctave?: number;
78
+ nIter?: number;
79
+ }
80
+
81
+ export interface VqtToAudioRequest extends CqtToAudioRequest {
82
+ gamma?: number;
83
+ }
84
+
85
+ export interface AnalyzeSectionsRequest extends AnalyzeSectionsGuardedOptions {
86
+ samples: Float32Array;
87
+ sampleRate?: number;
88
+ }
89
+ export interface AnalyzeMelodyRequest extends MelodyGuardedOptions {
90
+ samples: Float32Array;
91
+ sampleRate?: number;
92
+ }
93
+ export interface LufsRequest extends ValidateOptions {
94
+ samples: Float32Array;
95
+ sampleRate?: number;
96
+ }
97
+ export interface NnlsChromaRequest extends GuardedOptions {
98
+ samples: Float32Array;
99
+ sampleRate?: number;
100
+ }
101
+
28
102
  function validateMusicSamples(
29
103
  fnName: string,
30
104
  samples: Float32Array,
@@ -61,11 +135,20 @@ function validateFrequencyBounds(fnName: string, fmin: number, fmax?: number): v
61
135
  * @param sampleRate - Sample rate in Hz (default: 22050)
62
136
  * @returns NNLS chroma result
63
137
  */
138
+ export function nnlsChroma(request: NnlsChromaRequest): WasmNnlsChromaResult;
64
139
  export function nnlsChroma(
65
140
  samples: Float32Array,
141
+ sampleRate?: number,
142
+ options?: GuardedOptions,
143
+ ): WasmNnlsChromaResult;
144
+ export function nnlsChroma(
145
+ samples: Float32Array | NnlsChromaRequest,
66
146
  sampleRate = 22050,
67
147
  options: GuardedOptions = {},
68
148
  ): WasmNnlsChromaResult {
149
+ if (!(samples instanceof Float32Array)) {
150
+ return nnlsChroma(samples.samples, samples.sampleRate, samples);
151
+ }
69
152
  validateMusicSamples('nnlsChroma', samples, sampleRate, options);
70
153
  return requireModule().nnlsChroma(samples, sampleRate);
71
154
  }
@@ -81,8 +164,18 @@ export function nnlsChroma(
81
164
  * @param binsPerOctave - Bins per octave (default: 12)
82
165
  * @returns CQT magnitude result
83
166
  */
167
+ export function cqt(request: CqtRequest): CqtResult;
84
168
  export function cqt(
85
169
  samples: Float32Array,
170
+ sampleRate?: number,
171
+ hopLength?: number,
172
+ fmin?: number,
173
+ nBins?: number,
174
+ binsPerOctave?: number,
175
+ options?: GuardedOptions,
176
+ ): CqtResult;
177
+ export function cqt(
178
+ samples: Float32Array | CqtRequest,
86
179
  sampleRate = 22050,
87
180
  hopLength = 512,
88
181
  fmin = 32.70319566257483,
@@ -90,6 +183,18 @@ export function cqt(
90
183
  binsPerOctave = 12,
91
184
  options: GuardedOptions = {},
92
185
  ): CqtResult {
186
+ if (!(samples instanceof Float32Array)) {
187
+ const request = samples;
188
+ return cqt(
189
+ request.samples,
190
+ request.sampleRate,
191
+ request.hopLength,
192
+ request.fmin,
193
+ request.nBins,
194
+ request.binsPerOctave,
195
+ request,
196
+ );
197
+ }
93
198
  validateMusicSamples('cqt', samples, sampleRate, options);
94
199
  validatePositiveIntegers('cqt', { hopLength, nBins, binsPerOctave });
95
200
  validateFrequencyBounds('cqt', fmin);
@@ -107,8 +212,18 @@ export function cqt(
107
212
  * @param binsPerOctave - Bins per octave (default: 12)
108
213
  * @returns CQT magnitude result
109
214
  */
215
+ export function pseudoCqt(request: CqtRequest): CqtResult;
110
216
  export function pseudoCqt(
111
217
  samples: Float32Array,
218
+ sampleRate?: number,
219
+ hopLength?: number,
220
+ fmin?: number,
221
+ nBins?: number,
222
+ binsPerOctave?: number,
223
+ options?: GuardedOptions,
224
+ ): CqtResult;
225
+ export function pseudoCqt(
226
+ samples: Float32Array | CqtRequest,
112
227
  sampleRate = 22050,
113
228
  hopLength = 512,
114
229
  fmin = 32.70319566257483,
@@ -116,6 +231,18 @@ export function pseudoCqt(
116
231
  binsPerOctave = 12,
117
232
  options: GuardedOptions = {},
118
233
  ): CqtResult {
234
+ if (!(samples instanceof Float32Array)) {
235
+ const request = samples;
236
+ return pseudoCqt(
237
+ request.samples,
238
+ request.sampleRate,
239
+ request.hopLength,
240
+ request.fmin,
241
+ request.nBins,
242
+ request.binsPerOctave,
243
+ request,
244
+ );
245
+ }
119
246
  validateMusicSamples('pseudoCqt', samples, sampleRate, options);
120
247
  validatePositiveIntegers('pseudoCqt', { hopLength, nBins, binsPerOctave });
121
248
  validateFrequencyBounds('pseudoCqt', fmin);
@@ -133,8 +260,18 @@ export function pseudoCqt(
133
260
  * @param binsPerOctave - Bins per octave (default: 12)
134
261
  * @returns CQT magnitude result
135
262
  */
263
+ export function hybridCqt(request: CqtRequest): CqtResult;
136
264
  export function hybridCqt(
137
265
  samples: Float32Array,
266
+ sampleRate?: number,
267
+ hopLength?: number,
268
+ fmin?: number,
269
+ nBins?: number,
270
+ binsPerOctave?: number,
271
+ options?: GuardedOptions,
272
+ ): CqtResult;
273
+ export function hybridCqt(
274
+ samples: Float32Array | CqtRequest,
138
275
  sampleRate = 22050,
139
276
  hopLength = 512,
140
277
  fmin = 32.70319566257483,
@@ -142,6 +279,18 @@ export function hybridCqt(
142
279
  binsPerOctave = 12,
143
280
  options: GuardedOptions = {},
144
281
  ): CqtResult {
282
+ if (!(samples instanceof Float32Array)) {
283
+ const request = samples;
284
+ return hybridCqt(
285
+ request.samples,
286
+ request.sampleRate,
287
+ request.hopLength,
288
+ request.fmin,
289
+ request.nBins,
290
+ request.binsPerOctave,
291
+ request,
292
+ );
293
+ }
145
294
  validateMusicSamples('hybridCqt', samples, sampleRate, options);
146
295
  validatePositiveIntegers('hybridCqt', { hopLength, nBins, binsPerOctave });
147
296
  validateFrequencyBounds('hybridCqt', fmin);
@@ -160,8 +309,19 @@ export function hybridCqt(
160
309
  * @param gamma - Bandwidth offset; 0 is equivalent to CQT (default: 0)
161
310
  * @returns VQT magnitude result (same shape as CQT)
162
311
  */
312
+ export function vqt(request: VqtRequest): CqtResult;
163
313
  export function vqt(
164
314
  samples: Float32Array,
315
+ sampleRate?: number,
316
+ hopLength?: number,
317
+ fmin?: number,
318
+ nBins?: number,
319
+ binsPerOctave?: number,
320
+ gamma?: number,
321
+ options?: GuardedOptions,
322
+ ): CqtResult;
323
+ export function vqt(
324
+ samples: Float32Array | VqtRequest,
165
325
  sampleRate = 22050,
166
326
  hopLength = 512,
167
327
  fmin = 32.70319566257483,
@@ -170,6 +330,19 @@ export function vqt(
170
330
  gamma = 0,
171
331
  options: GuardedOptions = {},
172
332
  ): CqtResult {
333
+ if (!(samples instanceof Float32Array)) {
334
+ const request = samples;
335
+ return vqt(
336
+ request.samples,
337
+ request.sampleRate,
338
+ request.hopLength,
339
+ request.fmin,
340
+ request.nBins,
341
+ request.binsPerOctave,
342
+ request.gamma,
343
+ request,
344
+ );
345
+ }
173
346
  validateMusicSamples('vqt', samples, sampleRate, options);
174
347
  validatePositiveIntegers('vqt', { hopLength, nBins, binsPerOctave });
175
348
  validateFrequencyBounds('vqt', fmin);
@@ -208,10 +381,22 @@ function validateCqtInverse(
208
381
  }
209
382
 
210
383
  /** Reconstruct mono audio from row-major CQT magnitude via Griffin-Lim. */
384
+ export function cqtToAudio(request: CqtToAudioRequest): Float32Array;
211
385
  export function cqtToAudio(
212
386
  magnitude: Float32Array,
213
387
  nBins: number,
214
388
  nFrames: number,
389
+ sampleRate?: number,
390
+ hopLength?: number,
391
+ fmin?: number,
392
+ binsPerOctave?: number,
393
+ nIter?: number,
394
+ options?: GuardedOptions,
395
+ ): Float32Array;
396
+ export function cqtToAudio(
397
+ magnitude: Float32Array | CqtToAudioRequest,
398
+ nBins = 0,
399
+ nFrames = 0,
215
400
  sampleRate = 22050,
216
401
  hopLength = 512,
217
402
  fmin = 32.70319566257483,
@@ -219,6 +404,20 @@ export function cqtToAudio(
219
404
  nIter = 32,
220
405
  options: GuardedOptions = {},
221
406
  ): Float32Array {
407
+ if (!(magnitude instanceof Float32Array)) {
408
+ const request = magnitude;
409
+ return cqtToAudio(
410
+ request.magnitude,
411
+ request.nBins,
412
+ request.nFrames,
413
+ request.sampleRate,
414
+ request.hopLength,
415
+ request.fmin,
416
+ request.binsPerOctave,
417
+ request.nIter,
418
+ request,
419
+ );
420
+ }
222
421
  validateCqtInverse(
223
422
  'cqtToAudio',
224
423
  magnitude,
@@ -244,10 +443,23 @@ export function cqtToAudio(
244
443
  }
245
444
 
246
445
  /** Reconstruct mono audio from row-major VQT magnitude via Griffin-Lim. */
446
+ export function vqtToAudio(request: VqtToAudioRequest): Float32Array;
247
447
  export function vqtToAudio(
248
448
  magnitude: Float32Array,
249
449
  nBins: number,
250
450
  nFrames: number,
451
+ sampleRate?: number,
452
+ hopLength?: number,
453
+ fmin?: number,
454
+ binsPerOctave?: number,
455
+ gamma?: number,
456
+ nIter?: number,
457
+ options?: GuardedOptions,
458
+ ): Float32Array;
459
+ export function vqtToAudio(
460
+ magnitude: Float32Array | VqtToAudioRequest,
461
+ nBins = 0,
462
+ nFrames = 0,
251
463
  sampleRate = 22050,
252
464
  hopLength = 512,
253
465
  fmin = 32.70319566257483,
@@ -256,6 +468,21 @@ export function vqtToAudio(
256
468
  nIter = 32,
257
469
  options: GuardedOptions = {},
258
470
  ): Float32Array {
471
+ if (!(magnitude instanceof Float32Array)) {
472
+ const request = magnitude;
473
+ return vqtToAudio(
474
+ request.magnitude,
475
+ request.nBins,
476
+ request.nFrames,
477
+ request.sampleRate,
478
+ request.hopLength,
479
+ request.fmin,
480
+ request.binsPerOctave,
481
+ request.gamma,
482
+ request.nIter,
483
+ request,
484
+ );
485
+ }
259
486
  validateCqtInverse(
260
487
  'vqtToAudio',
261
488
  magnitude,
@@ -295,11 +522,21 @@ export function vqtToAudio(
295
522
  * @param minSectionSec - Minimum section duration in seconds (default: 4.0)
296
523
  * @returns Array of detected sections
297
524
  */
525
+ export function analyzeSections(request: AnalyzeSectionsRequest): Section[];
298
526
  export function analyzeSections(
299
527
  samples: Float32Array,
528
+ sampleRate?: number,
529
+ options?: AnalyzeSectionsGuardedOptions,
530
+ ): Section[];
531
+ export function analyzeSections(
532
+ samples: Float32Array | AnalyzeSectionsRequest,
300
533
  sampleRate = 22050,
301
534
  options: AnalyzeSectionsGuardedOptions = {},
302
535
  ): Section[] {
536
+ if (!(samples instanceof Float32Array)) {
537
+ const r = samples;
538
+ return analyzeSections(r.samples, r.sampleRate, r);
539
+ }
303
540
  validateMusicSamples('analyzeSections', samples, sampleRate, options);
304
541
  validatePositiveIntegers('analyzeSections', {
305
542
  nFft: options.nFft ?? 2048,
@@ -357,11 +594,21 @@ export interface MelodyOptions {
357
594
  * @param options - Tracker + tuning options ({@link MelodyOptions})
358
595
  * @returns Melody contour with per-frame pitch points and summary stats
359
596
  */
597
+ export function analyzeMelody(request: AnalyzeMelodyRequest): MelodyResult;
360
598
  export function analyzeMelody(
361
599
  samples: Float32Array,
600
+ sampleRate?: number,
601
+ options?: MelodyGuardedOptions,
602
+ ): MelodyResult;
603
+ export function analyzeMelody(
604
+ samples: Float32Array | AnalyzeMelodyRequest,
362
605
  sampleRate = 22050,
363
606
  options: MelodyGuardedOptions = {},
364
607
  ): MelodyResult {
608
+ if (!(samples instanceof Float32Array)) {
609
+ const r = samples;
610
+ return analyzeMelody(r.samples, r.sampleRate, r);
611
+ }
365
612
  validateMusicSamples('analyzeMelody', samples, sampleRate, options);
366
613
  const fmin = options.fmin ?? 65.0;
367
614
  const fmax = options.fmax ?? 2093.0;
@@ -404,14 +651,34 @@ export function analyzeMelody(
404
651
  * @param nMels - Number of Mel bands (default: 128)
405
652
  * @returns Onset envelope for each frame
406
653
  */
654
+ export function onsetEnvelope(request: OnsetEnvelopeRequest): Float32Array;
407
655
  export function onsetEnvelope(
408
656
  samples: Float32Array,
657
+ sampleRate?: number,
658
+ nFft?: number,
659
+ hopLength?: number,
660
+ nMels?: number,
661
+ options?: GuardedOptions,
662
+ ): Float32Array;
663
+ export function onsetEnvelope(
664
+ samples: Float32Array | OnsetEnvelopeRequest,
409
665
  sampleRate = 22050,
410
666
  nFft = 2048,
411
667
  hopLength = 512,
412
668
  nMels = 128,
413
669
  options: GuardedOptions = {},
414
670
  ): Float32Array {
671
+ if (!(samples instanceof Float32Array)) {
672
+ const request = samples;
673
+ return onsetEnvelope(
674
+ request.samples,
675
+ request.sampleRate,
676
+ request.nFft,
677
+ request.hopLength,
678
+ request.nMels,
679
+ request,
680
+ );
681
+ }
415
682
  validateMusicSamples('onsetEnvelope', samples, sampleRate, options);
416
683
  validatePositiveIntegers('onsetEnvelope', { nFft, hopLength, nMels });
417
684
  return requireModule().onsetEnvelope(samples, sampleRate, nFft, hopLength, nMels);
@@ -428,8 +695,18 @@ export function onsetEnvelope(
428
695
  * @param nBands - Number of onset bands (default: 3)
429
696
  * @returns Multi-band onset matrix
430
697
  */
698
+ export function onsetStrengthMulti(request: OnsetStrengthMultiRequest): OnsetStrengthMultiResult;
431
699
  export function onsetStrengthMulti(
432
700
  samples: Float32Array,
701
+ sampleRate?: number,
702
+ nFft?: number,
703
+ hopLength?: number,
704
+ nMels?: number,
705
+ nBands?: number,
706
+ options?: GuardedOptions,
707
+ ): OnsetStrengthMultiResult;
708
+ export function onsetStrengthMulti(
709
+ samples: Float32Array | OnsetStrengthMultiRequest,
433
710
  sampleRate = 22050,
434
711
  nFft = 2048,
435
712
  hopLength = 512,
@@ -437,6 +714,18 @@ export function onsetStrengthMulti(
437
714
  nBands = 3,
438
715
  options: GuardedOptions = {},
439
716
  ): OnsetStrengthMultiResult {
717
+ if (!(samples instanceof Float32Array)) {
718
+ const request = samples;
719
+ return onsetStrengthMulti(
720
+ request.samples,
721
+ request.sampleRate,
722
+ request.nFft,
723
+ request.hopLength,
724
+ request.nMels,
725
+ request.nBands,
726
+ request,
727
+ );
728
+ }
440
729
  validateMusicSamples('onsetStrengthMulti', samples, sampleRate, options);
441
730
  validatePositiveIntegers('onsetStrengthMulti', { nFft, hopLength, nMels, nBands });
442
731
  return requireModule().onsetStrengthMulti(samples, sampleRate, nFft, hopLength, nMels, nBands);
@@ -451,13 +740,31 @@ export function onsetStrengthMulti(
451
740
  * @param winLength - Window length in frames (default: 384)
452
741
  * @returns Fourier tempogram result
453
742
  */
743
+ export function fourierTempogram(request: FourierTempogramRequest): WasmFourierTempogramResult;
454
744
  export function fourierTempogram(
455
745
  onsetEnvelope: Float32Array,
746
+ sampleRate?: number,
747
+ hopLength?: number,
748
+ winLength?: number,
749
+ options?: GuardedOptions,
750
+ ): WasmFourierTempogramResult;
751
+ export function fourierTempogram(
752
+ onsetEnvelope: Float32Array | FourierTempogramRequest,
456
753
  sampleRate = 22050,
457
754
  hopLength = 512,
458
755
  winLength = 384,
459
756
  options: GuardedOptions = {},
460
757
  ): WasmFourierTempogramResult {
758
+ if (!(onsetEnvelope instanceof Float32Array)) {
759
+ const request = onsetEnvelope;
760
+ return fourierTempogram(
761
+ request.onsetEnvelope,
762
+ request.sampleRate,
763
+ request.hopLength,
764
+ request.winLength,
765
+ request,
766
+ );
767
+ }
461
768
  assertSampleRate('fourierTempogram', sampleRate);
462
769
  assertSamples('fourierTempogram', onsetEnvelope, options.validate !== false, 'onsetEnvelope');
463
770
  validatePositiveIntegers('fourierTempogram', { hopLength, winLength });
@@ -475,14 +782,34 @@ export function fourierTempogram(
475
782
  * default {0.5, 1, 2, 3, 4} is used.
476
783
  * @returns Tempogram ratio features (one value per factor)
477
784
  */
785
+ export function tempogramRatio(request: TempogramRatioRequest): Float32Array;
478
786
  export function tempogramRatio(
479
787
  tempogramData: Float32Array,
788
+ winLength?: number,
789
+ sampleRate?: number,
790
+ hopLength?: number,
791
+ factors?: Float32Array | number[],
792
+ options?: GuardedOptions,
793
+ ): Float32Array;
794
+ export function tempogramRatio(
795
+ tempogramData: Float32Array | TempogramRatioRequest,
480
796
  winLength = 384,
481
797
  sampleRate = 22050,
482
798
  hopLength = 512,
483
799
  factors?: Float32Array | number[],
484
800
  options: GuardedOptions = {},
485
801
  ): Float32Array {
802
+ if (!(tempogramData instanceof Float32Array)) {
803
+ const request = tempogramData;
804
+ return tempogramRatio(
805
+ request.tempogramData,
806
+ request.winLength,
807
+ request.sampleRate,
808
+ request.hopLength,
809
+ request.factors,
810
+ request,
811
+ );
812
+ }
486
813
  assertSampleRate('tempogramRatio', sampleRate);
487
814
  assertSamples('tempogramRatio', tempogramData, options.validate !== false, 'tempogramData');
488
815
  validatePositiveIntegers('tempogramRatio', { winLength, hopLength });
@@ -498,11 +825,21 @@ export function tempogramRatio(
498
825
  * dependent and a wrong rate yields wrong loudness.
499
826
  * @returns Loudness measurement result
500
827
  */
828
+ export function lufs(request: LufsRequest): LufsResult;
501
829
  export function lufs(
502
830
  samples: Float32Array,
831
+ sampleRate?: number,
832
+ options?: ValidateOptions,
833
+ ): LufsResult;
834
+ export function lufs(
835
+ samples: Float32Array | LufsRequest,
503
836
  sampleRate = 22050,
504
837
  options: ValidateOptions = {},
505
838
  ): LufsResult {
839
+ if (!(samples instanceof Float32Array)) {
840
+ const r = samples;
841
+ return lufs(r.samples, r.sampleRate, r);
842
+ }
506
843
  assertSampleRate('lufs', sampleRate);
507
844
  assertSamples('lufs', samples, options.validate !== false);
508
845
  return requireModule().lufs(samples, sampleRate);
@@ -516,11 +853,21 @@ export function lufs(
516
853
  * K-weighting is sample-rate dependent; pass the buffer's actual rate.
517
854
  * @returns Momentary LUFS values over time
518
855
  */
856
+ export function momentaryLufs(request: LufsRequest): Float32Array;
519
857
  export function momentaryLufs(
520
858
  samples: Float32Array,
859
+ sampleRate?: number,
860
+ options?: ValidateOptions,
861
+ ): Float32Array;
862
+ export function momentaryLufs(
863
+ samples: Float32Array | LufsRequest,
521
864
  sampleRate = 22050,
522
865
  options: ValidateOptions = {},
523
866
  ): Float32Array {
867
+ if (!(samples instanceof Float32Array)) {
868
+ const r = samples;
869
+ return momentaryLufs(r.samples, r.sampleRate, r);
870
+ }
524
871
  assertSampleRate('momentaryLufs', sampleRate);
525
872
  assertSamples('momentaryLufs', samples, options.validate !== false);
526
873
  return requireModule().momentaryLufs(samples, sampleRate);
@@ -534,11 +881,21 @@ export function momentaryLufs(
534
881
  * K-weighting is sample-rate dependent; pass the buffer's actual rate.
535
882
  * @returns Short-term LUFS values over time
536
883
  */
884
+ export function shortTermLufs(request: LufsRequest): Float32Array;
537
885
  export function shortTermLufs(
538
886
  samples: Float32Array,
887
+ sampleRate?: number,
888
+ options?: ValidateOptions,
889
+ ): Float32Array;
890
+ export function shortTermLufs(
891
+ samples: Float32Array | LufsRequest,
539
892
  sampleRate = 22050,
540
893
  options: ValidateOptions = {},
541
894
  ): Float32Array {
895
+ if (!(samples instanceof Float32Array)) {
896
+ const r = samples;
897
+ return shortTermLufs(r.samples, r.sampleRate, r);
898
+ }
542
899
  assertSampleRate('shortTermLufs', sampleRate);
543
900
  assertSamples('shortTermLufs', samples, options.validate !== false);
544
901
  return requireModule().shortTermLufs(samples, sampleRate);
@@ -22,8 +22,30 @@ function requireModule() {
22
22
  * @param fillNa - If true, return 0 for unvoiced f0 frames; otherwise keep NaN (default: false)
23
23
  * @returns Pitch detection result
24
24
  */
25
+ export interface PitchYinRequest {
26
+ samples: Float32Array;
27
+ sampleRate?: number;
28
+ frameLength?: number;
29
+ hopLength?: number;
30
+ fmin?: number;
31
+ fmax?: number;
32
+ threshold?: number;
33
+ fillNa?: boolean;
34
+ }
35
+
36
+ export function pitchYin(request: PitchYinRequest): PitchResult;
25
37
  export function pitchYin(
26
38
  samples: Float32Array,
39
+ sampleRate?: number,
40
+ frameLength?: number,
41
+ hopLength?: number,
42
+ fmin?: number,
43
+ fmax?: number,
44
+ threshold?: number,
45
+ fillNa?: boolean,
46
+ ): PitchResult;
47
+ export function pitchYin(
48
+ samples: Float32Array | PitchYinRequest,
27
49
  sampleRate = 22050,
28
50
  frameLength = 2048,
29
51
  hopLength = 512,
@@ -32,6 +54,19 @@ export function pitchYin(
32
54
  threshold = 0.3,
33
55
  fillNa = false,
34
56
  ): PitchResult {
57
+ if (!(samples instanceof Float32Array)) {
58
+ const request = samples;
59
+ return pitchYin(
60
+ request.samples,
61
+ request.sampleRate,
62
+ request.frameLength,
63
+ request.hopLength,
64
+ request.fmin,
65
+ request.fmax,
66
+ request.threshold,
67
+ request.fillNa,
68
+ );
69
+ }
35
70
  return requireModule().pitchYin(
36
71
  samples,
37
72
  sampleRate,
@@ -57,8 +92,21 @@ export function pitchYin(
57
92
  * @param fillNa - If true, return 0 for unvoiced f0 frames; otherwise keep NaN (default: false)
58
93
  * @returns Pitch detection result
59
94
  */
95
+ export interface PitchPyinRequest extends PitchYinRequest {}
96
+
97
+ export function pitchPyin(request: PitchPyinRequest): PitchResult;
60
98
  export function pitchPyin(
61
99
  samples: Float32Array,
100
+ sampleRate?: number,
101
+ frameLength?: number,
102
+ hopLength?: number,
103
+ fmin?: number,
104
+ fmax?: number,
105
+ threshold?: number,
106
+ fillNa?: boolean,
107
+ ): PitchResult;
108
+ export function pitchPyin(
109
+ samples: Float32Array | PitchPyinRequest,
62
110
  sampleRate = 22050,
63
111
  frameLength = 2048,
64
112
  hopLength = 512,
@@ -67,6 +115,19 @@ export function pitchPyin(
67
115
  threshold = 0.3,
68
116
  fillNa = false,
69
117
  ): PitchResult {
118
+ if (!(samples instanceof Float32Array)) {
119
+ const request = samples;
120
+ return pitchPyin(
121
+ request.samples,
122
+ request.sampleRate,
123
+ request.frameLength,
124
+ request.hopLength,
125
+ request.fmin,
126
+ request.fmax,
127
+ request.threshold,
128
+ request.fillNa,
129
+ );
130
+ }
70
131
  return requireModule().pitchPyin(
71
132
  samples,
72
133
  sampleRate,
@@ -16,6 +16,21 @@ function requireModule() {
16
16
  * @param targetSr - Target sample rate in Hz
17
17
  * @returns Resampled audio
18
18
  */
19
- export function resample(samples: Float32Array, srcSr: number, targetSr: number): Float32Array {
20
- return requireModule().resample(samples, srcSr, targetSr);
19
+ export interface ResampleRequest {
20
+ samples: Float32Array;
21
+ srcSr: number;
22
+ targetSr: number;
23
+ }
24
+
25
+ export function resample(request: ResampleRequest): Float32Array;
26
+ export function resample(samples: Float32Array, srcSr: number, targetSr: number): Float32Array;
27
+ export function resample(
28
+ samples: Float32Array | ResampleRequest,
29
+ srcSr?: number,
30
+ targetSr?: number,
31
+ ): Float32Array {
32
+ if (!(samples instanceof Float32Array)) {
33
+ return resample(samples.samples, samples.srcSr, samples.targetSr);
34
+ }
35
+ return requireModule().resample(samples, srcSr as number, targetSr as number);
21
36
  }