@libraz/libsonare 1.2.3 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +38 -1
  2. package/dist/index.d.ts +1 -2842
  3. package/dist/index.js +3667 -1984
  4. package/dist/index.js.map +1 -1
  5. package/dist/sonare-rt-module.js +1 -1
  6. package/dist/sonare-rt.js +1 -1
  7. package/dist/sonare-rt.wasm +0 -0
  8. package/dist/sonare.js +1 -1
  9. package/dist/sonare.wasm +0 -0
  10. package/dist/worklet.d.ts +4816 -483
  11. package/dist/worklet.js +747 -440
  12. package/dist/worklet.js.map +1 -1
  13. package/package.json +2 -1
  14. package/src/analysis_helpers.ts +152 -0
  15. package/src/audio.ts +493 -0
  16. package/src/codes.ts +56 -0
  17. package/src/effects_mastering.ts +964 -0
  18. package/src/feature_core.ts +248 -0
  19. package/src/feature_music.ts +419 -0
  20. package/src/feature_pitch.ts +80 -0
  21. package/src/feature_resample.ts +21 -0
  22. package/src/feature_spectral.ts +330 -0
  23. package/src/feature_spectrogram.ts +454 -0
  24. package/src/features.ts +84 -0
  25. package/src/index.ts +341 -4963
  26. package/src/live_audio.ts +47 -0
  27. package/src/metering.ts +380 -0
  28. package/src/mixer.ts +523 -0
  29. package/src/module_state.ts +14 -0
  30. package/src/opfs_clip_pages.ts +203 -0
  31. package/src/project.ts +1614 -0
  32. package/src/public_types.ts +177 -2
  33. package/src/quick_analysis.ts +508 -0
  34. package/src/realtime_engine.ts +667 -0
  35. package/src/realtime_voice_changer.ts +275 -0
  36. package/src/scale.ts +42 -0
  37. package/src/sonare.js.d.ts +302 -4
  38. package/src/stream_analyzer.ts +275 -0
  39. package/src/stream_types.ts +26 -1
  40. package/src/streaming_mixing.ts +18 -0
  41. package/src/streaming_processors.ts +335 -0
  42. package/src/validation.ts +82 -0
  43. package/src/web_midi.ts +366 -0
@@ -0,0 +1,454 @@
1
+ import { getSonareModule } from './module_state';
2
+ import type {
3
+ ChromaResult,
4
+ MelPowerResult,
5
+ MelSpectrogramResult,
6
+ MfccResult,
7
+ StftPowerResult,
8
+ StftResult,
9
+ } from './public_types';
10
+ import type { ValidateOptions } from './validation';
11
+ import {
12
+ assertFiniteScalar,
13
+ assertPositiveInteger,
14
+ assertSampleRate,
15
+ assertSamples,
16
+ } from './validation';
17
+
18
+ function requireModule() {
19
+ return getSonareModule();
20
+ }
21
+
22
+ type GuardedOptions = ValidateOptions;
23
+
24
+ function validateSpectrogramSamples(
25
+ fnName: string,
26
+ samples: Float32Array,
27
+ sampleRate: number,
28
+ options: GuardedOptions = {},
29
+ ): void {
30
+ assertSampleRate(fnName, sampleRate);
31
+ assertSamples(fnName, samples, options.validate !== false);
32
+ }
33
+
34
+ function validatePositiveIntegers(fnName: string, values: Record<string, number>): void {
35
+ for (const [name, value] of Object.entries(values)) {
36
+ assertPositiveInteger(fnName, value, name);
37
+ }
38
+ }
39
+
40
+ function validateMelFrequencyRange(
41
+ fnName: string,
42
+ fmin: number,
43
+ fmax: number,
44
+ sampleRate: number,
45
+ ): void {
46
+ assertFiniteScalar(fnName, fmin, 'fmin');
47
+ assertFiniteScalar(fnName, fmax, 'fmax');
48
+ if (fmin < 0) {
49
+ throw new RangeError(`${fnName}: fmin must be non-negative`);
50
+ }
51
+ if (fmax < 0) {
52
+ throw new RangeError(`${fnName}: fmax must be non-negative`);
53
+ }
54
+ const effectiveFmax = fmax === 0 ? sampleRate / 2 : fmax;
55
+ if (effectiveFmax <= fmin) {
56
+ throw new RangeError(`${fnName}: fmax must be greater than fmin`);
57
+ }
58
+ }
59
+
60
+ function validateMatrix(
61
+ fnName: string,
62
+ data: Float32Array,
63
+ rows: number,
64
+ frames: number,
65
+ dataName: string,
66
+ rowName: string,
67
+ options: GuardedOptions = {},
68
+ ): void {
69
+ validatePositiveIntegers(fnName, { [rowName]: rows, nFrames: frames });
70
+ assertSamples(fnName, data, options.validate !== false, dataName);
71
+ const expectedLength = rows * frames;
72
+ if (!Number.isSafeInteger(expectedLength) || data.length !== expectedLength) {
73
+ throw new RangeError(`${fnName}: ${dataName} length must equal ${rowName} * nFrames`);
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Trim silence from beginning and end of audio.
79
+ *
80
+ * @param samples - Audio samples (mono, float32)
81
+ * @param sampleRate - Sample rate in Hz
82
+ * @param thresholdDb - Silence threshold in dB (default: -60 dB)
83
+ * @returns Trimmed audio
84
+ */
85
+ export function trim(
86
+ samples: Float32Array,
87
+ sampleRate: number,
88
+ thresholdDb = -60.0,
89
+ options: GuardedOptions = {},
90
+ ): Float32Array {
91
+ validateSpectrogramSamples('trim', samples, sampleRate, options);
92
+ assertFiniteScalar('trim', thresholdDb, 'thresholdDb');
93
+ return requireModule().trim(samples, sampleRate, thresholdDb);
94
+ }
95
+
96
+ // ============================================================================
97
+ // Features - Spectrogram
98
+ // ============================================================================
99
+
100
+ /**
101
+ * Compute Short-Time Fourier Transform (STFT).
102
+ *
103
+ * @param samples - Audio samples (mono, float32)
104
+ * @param sampleRate - Sample rate in Hz (default: 22050)
105
+ * @param nFft - FFT size (default: 2048)
106
+ * @param hopLength - Hop length (default: 512)
107
+ * @returns STFT result with magnitude and power spectrograms
108
+ */
109
+ export function stft(
110
+ samples: Float32Array,
111
+ sampleRate = 22050,
112
+ nFft = 2048,
113
+ hopLength = 512,
114
+ options: GuardedOptions = {},
115
+ ): StftResult {
116
+ validateSpectrogramSamples('stft', samples, sampleRate, options);
117
+ validatePositiveIntegers('stft', { nFft, hopLength });
118
+ return requireModule().stft(samples, sampleRate, nFft, hopLength);
119
+ }
120
+
121
+ /**
122
+ * Compute STFT and return magnitude in decibels.
123
+ *
124
+ * @param samples - Audio samples (mono, float32)
125
+ * @param sampleRate - Sample rate in Hz (default: 22050)
126
+ * @param nFft - FFT size (default: 2048)
127
+ * @param hopLength - Hop length (default: 512)
128
+ * @returns STFT result with dB values
129
+ */
130
+ export function stftDb(
131
+ samples: Float32Array,
132
+ sampleRate = 22050,
133
+ nFft = 2048,
134
+ hopLength = 512,
135
+ options: GuardedOptions = {},
136
+ ): { nBins: number; nFrames: number; db: Float32Array } {
137
+ validateSpectrogramSamples('stftDb', samples, sampleRate, options);
138
+ validatePositiveIntegers('stftDb', { nFft, hopLength });
139
+ return requireModule().stftDb(samples, sampleRate, nFft, hopLength);
140
+ }
141
+
142
+ /**
143
+ * Compute Chroma Energy Normalized Statistics.
144
+ *
145
+ * @param samples - Audio samples (mono, float32)
146
+ * @param sampleRate - Sample rate in Hz (default: 22050)
147
+ * @param hopLength - Hop length (default: 512)
148
+ * @param nChroma - Number of chroma bins (default: 12)
149
+ * @returns Chroma result
150
+ */
151
+ export function chromaCens(
152
+ samples: Float32Array,
153
+ sampleRate = 22050,
154
+ hopLength = 512,
155
+ nChroma = 12,
156
+ options: GuardedOptions = {},
157
+ ): ChromaResult {
158
+ validateSpectrogramSamples('chromaCens', samples, sampleRate, options);
159
+ validatePositiveIntegers('chromaCens', { hopLength, nChroma });
160
+ return requireModule().chromaCens(samples, sampleRate, hopLength, nChroma);
161
+ }
162
+
163
+ /**
164
+ * Compute low-frequency bass chroma.
165
+ *
166
+ * @param samples - Audio samples (mono, float32)
167
+ * @param sampleRate - Sample rate in Hz (default: 22050)
168
+ * @param hopLength - Hop length (default: 512)
169
+ * @param nChroma - Number of chroma bins (default: 12)
170
+ * @returns Chroma result
171
+ */
172
+ export function bassChroma(
173
+ samples: Float32Array,
174
+ sampleRate = 22050,
175
+ hopLength = 512,
176
+ nChroma = 12,
177
+ options: GuardedOptions = {},
178
+ ): ChromaResult {
179
+ validateSpectrogramSamples('bassChroma', samples, sampleRate, options);
180
+ validatePositiveIntegers('bassChroma', { hopLength, nChroma });
181
+ return requireModule().bassChroma(samples, sampleRate, hopLength, nChroma);
182
+ }
183
+
184
+ // ============================================================================
185
+ // Features - Mel Spectrogram
186
+ // ============================================================================
187
+
188
+ /**
189
+ * Compute Mel spectrogram.
190
+ *
191
+ * @param samples - Audio samples (mono, float32)
192
+ * @param sampleRate - Sample rate in Hz (default: 22050)
193
+ * @param nFft - FFT size (default: 2048)
194
+ * @param hopLength - Hop length (default: 512)
195
+ * @param nMels - Number of Mel bands (default: 128)
196
+ * @param fmin - Minimum Mel frequency in Hz (default: 0 = librosa default).
197
+ * Set with `fmax` to round-trip with `melToStft` / `melToAudio`.
198
+ * @param fmax - Maximum Mel frequency in Hz (default: 0 = sampleRate / 2)
199
+ * @param htk - Use the HTK Mel formula instead of Slaney (default: false)
200
+ * @returns Mel spectrogram result
201
+ */
202
+ export function melSpectrogram(
203
+ samples: Float32Array,
204
+ sampleRate = 22050,
205
+ nFft = 2048,
206
+ hopLength = 512,
207
+ nMels = 128,
208
+ fmin = 0,
209
+ fmax = 0,
210
+ htk = false,
211
+ options: GuardedOptions = {},
212
+ ): MelSpectrogramResult {
213
+ validateSpectrogramSamples('melSpectrogram', samples, sampleRate, options);
214
+ validatePositiveIntegers('melSpectrogram', { nFft, hopLength, nMels });
215
+ validateMelFrequencyRange('melSpectrogram', fmin, fmax, sampleRate);
216
+ return requireModule().melSpectrogram(
217
+ samples,
218
+ sampleRate,
219
+ nFft,
220
+ hopLength,
221
+ nMels,
222
+ fmin,
223
+ fmax,
224
+ htk,
225
+ );
226
+ }
227
+
228
+ /**
229
+ * Compute MFCC (Mel-Frequency Cepstral Coefficients).
230
+ *
231
+ * @param samples - Audio samples (mono, float32)
232
+ * @param sampleRate - Sample rate in Hz (default: 22050)
233
+ * @param nFft - FFT size (default: 2048)
234
+ * @param hopLength - Hop length (default: 512)
235
+ * @param nMels - Number of Mel bands (default: 128)
236
+ * @param nMfcc - Number of MFCC coefficients (default: 20)
237
+ * @param fmin - Minimum Mel frequency in Hz (default: 0 = librosa default)
238
+ * @param fmax - Maximum Mel frequency in Hz (default: 0 = sampleRate / 2)
239
+ * @param htk - Use the HTK Mel formula instead of Slaney (default: false)
240
+ * @returns MFCC result
241
+ */
242
+ export function mfcc(
243
+ samples: Float32Array,
244
+ sampleRate = 22050,
245
+ nFft = 2048,
246
+ hopLength = 512,
247
+ nMels = 128,
248
+ nMfcc = 20,
249
+ fmin = 0,
250
+ fmax = 0,
251
+ htk = false,
252
+ options: GuardedOptions = {},
253
+ ): MfccResult {
254
+ validateSpectrogramSamples('mfcc', samples, sampleRate, options);
255
+ validatePositiveIntegers('mfcc', { nFft, hopLength, nMels, nMfcc });
256
+ validateMelFrequencyRange('mfcc', fmin, fmax, sampleRate);
257
+ return requireModule().mfcc(samples, sampleRate, nFft, hopLength, nMels, nMfcc, fmin, fmax, htk);
258
+ }
259
+
260
+ // ============================================================================
261
+ // Features - Inverse reconstruction
262
+ // ============================================================================
263
+
264
+ /**
265
+ * Approximate inverse of a Mel filterbank: Mel power spectrogram -> STFT power
266
+ * spectrogram. Mirrors `feature::mel_to_stft`.
267
+ *
268
+ * @param melPower - Mel power spectrogram [nMels x nFrames] row-major
269
+ * @param nMels - Number of Mel bands
270
+ * @param nFrames - Number of time frames
271
+ * @param sampleRate - Sample rate in Hz
272
+ * @param nFft - FFT size (default: 2048)
273
+ * @param fmin - Lower Mel band edge in Hz (default: 0)
274
+ * @param fmax - Upper Mel band edge in Hz (default: sr/2 when 0)
275
+ * @param htk - Use the HTK Mel formula instead of Slaney (default: false)
276
+ * @returns STFT power spectrogram result
277
+ */
278
+ export function melToStft(
279
+ melPower: Float32Array,
280
+ nMels: number,
281
+ nFrames: number,
282
+ sampleRate = 22050,
283
+ nFft = 2048,
284
+ fmin = 0,
285
+ fmax = 0,
286
+ htk = false,
287
+ options: GuardedOptions = {},
288
+ ): StftPowerResult {
289
+ assertSampleRate('melToStft', sampleRate);
290
+ validateMatrix('melToStft', melPower, nMels, nFrames, 'melPower', 'nMels', options);
291
+ validatePositiveIntegers('melToStft', { nFft });
292
+ validateMelFrequencyRange('melToStft', fmin, fmax, sampleRate);
293
+ return requireModule().melToStft(melPower, nMels, nFrames, sampleRate, nFft, fmin, fmax, htk);
294
+ }
295
+
296
+ /**
297
+ * Reconstruct audio from a Mel power spectrogram via Griffin-Lim. Mirrors
298
+ * `feature::mel_to_audio`.
299
+ *
300
+ * @param melPower - Mel power spectrogram [nMels x nFrames] row-major
301
+ * @param nMels - Number of Mel bands
302
+ * @param nFrames - Number of time frames
303
+ * @param sampleRate - Sample rate in Hz
304
+ * @param nFft - FFT size (default: 2048)
305
+ * @param hopLength - Hop length (default: 512)
306
+ * @param fmin - Minimum Mel frequency in Hz (default: 0)
307
+ * @param fmax - Maximum Mel frequency in Hz (default: 0 = sr/2)
308
+ * @param nIter - Griffin-Lim iterations (default: 32)
309
+ * @param htk - Use the HTK Mel formula instead of Slaney (default: false)
310
+ * @returns Reconstructed audio samples (mono, float32)
311
+ */
312
+ export function melToAudio(
313
+ melPower: Float32Array,
314
+ nMels: number,
315
+ nFrames: number,
316
+ sampleRate = 22050,
317
+ nFft = 2048,
318
+ hopLength = 512,
319
+ fmin = 0,
320
+ fmax = 0,
321
+ nIter = 32,
322
+ htk = false,
323
+ options: GuardedOptions = {},
324
+ ): Float32Array {
325
+ assertSampleRate('melToAudio', sampleRate);
326
+ validateMatrix('melToAudio', melPower, nMels, nFrames, 'melPower', 'nMels', options);
327
+ validatePositiveIntegers('melToAudio', { nFft, hopLength, nIter });
328
+ validateMelFrequencyRange('melToAudio', fmin, fmax, sampleRate);
329
+ return requireModule().melToAudio(
330
+ melPower,
331
+ nMels,
332
+ nFrames,
333
+ sampleRate,
334
+ nFft,
335
+ hopLength,
336
+ fmin,
337
+ fmax,
338
+ nIter,
339
+ htk,
340
+ );
341
+ }
342
+
343
+ /**
344
+ * Invert MFCC coefficients back to a Mel power spectrogram. Mirrors
345
+ * `feature::mfcc_to_mel`.
346
+ *
347
+ * @param mfccCoefficients - MFCC matrix [nMfcc x nFrames] row-major
348
+ * @param nMfcc - Number of MFCC coefficients
349
+ * @param nFrames - Number of time frames
350
+ * @param nMels - Number of Mel bins to reconstruct (default: 128)
351
+ * @returns Mel power spectrogram result
352
+ */
353
+ export function mfccToMel(
354
+ mfccCoefficients: Float32Array,
355
+ nMfcc: number,
356
+ nFrames: number,
357
+ nMels = 128,
358
+ options: GuardedOptions = {},
359
+ ): MelPowerResult {
360
+ validateMatrix(
361
+ 'mfccToMel',
362
+ mfccCoefficients,
363
+ nMfcc,
364
+ nFrames,
365
+ 'mfccCoefficients',
366
+ 'nMfcc',
367
+ options,
368
+ );
369
+ validatePositiveIntegers('mfccToMel', { nMels });
370
+ return requireModule().mfccToMel(mfccCoefficients, nMfcc, nFrames, nMels);
371
+ }
372
+
373
+ /**
374
+ * Reconstruct audio directly from MFCC coefficients via Griffin-Lim. Mirrors
375
+ * `feature::mfcc_to_audio`.
376
+ *
377
+ * @param mfccCoefficients - MFCC matrix [nMfcc x nFrames] row-major
378
+ * @param nMfcc - Number of MFCC coefficients
379
+ * @param nFrames - Number of time frames
380
+ * @param nMels - Number of Mel bins (default: 128)
381
+ * @param sampleRate - Sample rate in Hz (default: 22050)
382
+ * @param nFft - FFT size (default: 2048)
383
+ * @param hopLength - Hop length (default: 512)
384
+ * @param fmin - Minimum Mel frequency in Hz (default: 0)
385
+ * @param fmax - Maximum Mel frequency in Hz (default: 0 = sr/2)
386
+ * @param nIter - Griffin-Lim iterations (default: 32)
387
+ * @param htk - Use the HTK Mel formula instead of Slaney (default: false)
388
+ * @returns Reconstructed audio samples (mono, float32)
389
+ */
390
+ export function mfccToAudio(
391
+ mfccCoefficients: Float32Array,
392
+ nMfcc: number,
393
+ nFrames: number,
394
+ nMels = 128,
395
+ sampleRate = 22050,
396
+ nFft = 2048,
397
+ hopLength = 512,
398
+ fmin = 0,
399
+ fmax = 0,
400
+ nIter = 32,
401
+ htk = false,
402
+ options: GuardedOptions = {},
403
+ ): Float32Array {
404
+ assertSampleRate('mfccToAudio', sampleRate);
405
+ validateMatrix(
406
+ 'mfccToAudio',
407
+ mfccCoefficients,
408
+ nMfcc,
409
+ nFrames,
410
+ 'mfccCoefficients',
411
+ 'nMfcc',
412
+ options,
413
+ );
414
+ validatePositiveIntegers('mfccToAudio', { nMels, nFft, hopLength, nIter });
415
+ validateMelFrequencyRange('mfccToAudio', fmin, fmax, sampleRate);
416
+ return requireModule().mfccToAudio(
417
+ mfccCoefficients,
418
+ nMfcc,
419
+ nFrames,
420
+ nMels,
421
+ sampleRate,
422
+ nFft,
423
+ hopLength,
424
+ fmin,
425
+ fmax,
426
+ nIter,
427
+ htk,
428
+ );
429
+ }
430
+
431
+ // ============================================================================
432
+ // Features - Chroma
433
+ // ============================================================================
434
+
435
+ /**
436
+ * Compute chromagram (pitch class distribution).
437
+ *
438
+ * @param samples - Audio samples (mono, float32)
439
+ * @param sampleRate - Sample rate in Hz (default: 22050)
440
+ * @param nFft - FFT size (default: 2048)
441
+ * @param hopLength - Hop length (default: 512)
442
+ * @returns Chroma features result
443
+ */
444
+ export function chroma(
445
+ samples: Float32Array,
446
+ sampleRate = 22050,
447
+ nFft = 2048,
448
+ hopLength = 512,
449
+ options: GuardedOptions = {},
450
+ ): ChromaResult {
451
+ validateSpectrogramSamples('chroma', samples, sampleRate, options);
452
+ validatePositiveIntegers('chroma', { nFft, hopLength });
453
+ return requireModule().chroma(samples, sampleRate, nFft, hopLength);
454
+ }
@@ -0,0 +1,84 @@
1
+ export {
2
+ amplitudeToDb,
3
+ cyclicTempogram,
4
+ dbToAmplitude,
5
+ dbToPower,
6
+ deemphasis,
7
+ fixFrames,
8
+ fixLength,
9
+ frameSignal,
10
+ framesToSamples,
11
+ framesToTime,
12
+ hzToMel,
13
+ hzToMidi,
14
+ hzToNote,
15
+ melToHz,
16
+ midiToHz,
17
+ noteToHz,
18
+ padCenter,
19
+ pcen,
20
+ peakPick,
21
+ plp,
22
+ powerToDb,
23
+ preemphasis,
24
+ samplesToFrames,
25
+ splitSilence,
26
+ tempogram,
27
+ timeToFrames,
28
+ tonnetz,
29
+ trimSilence,
30
+ vectorNormalize,
31
+ } from './feature_core';
32
+ export {
33
+ analyzeMelody,
34
+ analyzeSections,
35
+ cqt,
36
+ fourierTempogram,
37
+ hybridCqt,
38
+ lufs,
39
+ momentaryLufs,
40
+ nnlsChroma,
41
+ onsetEnvelope,
42
+ onsetStrengthMulti,
43
+ pseudoCqt,
44
+ shortTermLufs,
45
+ tempogramRatio,
46
+ vqt,
47
+ } from './feature_music';
48
+ export { pitchPyin, pitchYin } from './feature_pitch';
49
+ export { resample } from './feature_resample';
50
+ export {
51
+ decompose,
52
+ decomposeWithInit,
53
+ ebur128LoudnessRange,
54
+ estimateTuning,
55
+ hpssWithResidual,
56
+ lufsInterleaved,
57
+ nnFilter,
58
+ phaseVocoder,
59
+ pitchTuning,
60
+ polyFeatures,
61
+ remix,
62
+ rmsEnergy,
63
+ spectralBandwidth,
64
+ spectralCentroid,
65
+ spectralContrast,
66
+ spectralFlatness,
67
+ spectralRolloff,
68
+ zeroCrossingRate,
69
+ zeroCrossings,
70
+ } from './feature_spectral';
71
+ export {
72
+ bassChroma,
73
+ chroma,
74
+ chromaCens,
75
+ melSpectrogram,
76
+ melToAudio,
77
+ melToStft,
78
+ mfcc,
79
+ mfccToAudio,
80
+ mfccToMel,
81
+ stft,
82
+ stftDb,
83
+ trim,
84
+ } from './feature_spectrogram';