@libraz/libsonare 1.5.1 → 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.
- package/README.md +18 -3
- package/dist/index.d.ts +1165 -178
- package/dist/index.js +4830 -3871
- package/dist/index.js.map +1 -1
- package/dist/sonare.js +1 -1
- package/dist/sonare.wasm +0 -0
- package/dist/worklet.d.ts +29 -1
- package/dist/worklet.js +1068 -974
- package/dist/worklet.js.map +1 -1
- package/package.json +2 -1
- package/src/_chain_config.ts +46 -0
- package/src/audio.ts +24 -4
- package/src/effects_mastering.ts +25 -1
- package/src/effects_transform.ts +283 -43
- package/src/effects_voice_change.ts +46 -53
- package/src/feature_core.ts +316 -12
- package/src/feature_music.ts +462 -0
- package/src/feature_pitch.ts +61 -0
- package/src/feature_resample.ts +17 -2
- package/src/feature_spectral.ts +349 -2
- package/src/feature_spectrogram.ts +336 -0
- package/src/features.ts +2 -0
- package/src/index.ts +133 -1
- package/src/mastering_chain.ts +305 -50
- package/src/mastering_core.ts +242 -16
- package/src/mastering_dynamics.ts +66 -10
- package/src/mastering_repair.ts +119 -7
- package/src/metering.ts +366 -81
- package/src/mixer.ts +10 -3
- package/src/mixing_oneshot.ts +25 -5
- package/src/module_state.ts +1 -1
- package/src/project_class.ts +17 -6
- package/src/project_internal.ts +10 -2
- package/src/project_types.ts +25 -2
- package/src/public_types_mastering.ts +114 -4
- package/src/public_types_music.ts +1 -0
- package/src/public_types_spectral.ts +7 -0
- package/src/quick_analysis.ts +325 -117
- package/src/realtime_engine.ts +8 -0
- package/src/sonare.js.d.ts +56 -0
- package/src/stream_analyzer.ts +25 -2
- package/src/stream_types.ts +16 -1
- package/src/validation.ts +17 -2
- package/src/worklet/engine-clips.ts +67 -2
- package/src/worklet/engine-processor.ts +33 -5
- package/src/worklet/engine.ts +7 -3
- package/src/worklet/guards.ts +3 -0
- package/src/worklet/messages.ts +27 -0
package/src/feature_music.ts
CHANGED
|
@@ -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);
|
|
@@ -180,6 +353,165 @@ export function vqt(
|
|
|
180
353
|
return requireModule().vqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave, gamma);
|
|
181
354
|
}
|
|
182
355
|
|
|
356
|
+
function validateCqtInverse(
|
|
357
|
+
fnName: string,
|
|
358
|
+
magnitude: Float32Array,
|
|
359
|
+
nBins: number,
|
|
360
|
+
nFrames: number,
|
|
361
|
+
sampleRate: number,
|
|
362
|
+
hopLength: number,
|
|
363
|
+
fmin: number,
|
|
364
|
+
binsPerOctave: number,
|
|
365
|
+
nIter: number,
|
|
366
|
+
options: GuardedOptions,
|
|
367
|
+
): void {
|
|
368
|
+
assertSampleRate(fnName, sampleRate);
|
|
369
|
+
validatePositiveIntegers(fnName, { nBins, nFrames, hopLength, binsPerOctave, nIter });
|
|
370
|
+
if (nIter > 256) {
|
|
371
|
+
throw new RangeError(`${fnName}: nIter must be at most 256`);
|
|
372
|
+
}
|
|
373
|
+
validateFrequencyBounds(fnName, fmin);
|
|
374
|
+
if (fmin === 0) {
|
|
375
|
+
throw new RangeError(`${fnName}: fmin must be positive`);
|
|
376
|
+
}
|
|
377
|
+
if (magnitude.length !== nBins * nFrames) {
|
|
378
|
+
throw new RangeError(`${fnName}: magnitude length must equal nBins * nFrames`);
|
|
379
|
+
}
|
|
380
|
+
assertSamples(fnName, magnitude, options.validate !== false);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/** Reconstruct mono audio from row-major CQT magnitude via Griffin-Lim. */
|
|
384
|
+
export function cqtToAudio(request: CqtToAudioRequest): Float32Array;
|
|
385
|
+
export function cqtToAudio(
|
|
386
|
+
magnitude: Float32Array,
|
|
387
|
+
nBins: number,
|
|
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,
|
|
400
|
+
sampleRate = 22050,
|
|
401
|
+
hopLength = 512,
|
|
402
|
+
fmin = 32.70319566257483,
|
|
403
|
+
binsPerOctave = 12,
|
|
404
|
+
nIter = 32,
|
|
405
|
+
options: GuardedOptions = {},
|
|
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
|
+
}
|
|
421
|
+
validateCqtInverse(
|
|
422
|
+
'cqtToAudio',
|
|
423
|
+
magnitude,
|
|
424
|
+
nBins,
|
|
425
|
+
nFrames,
|
|
426
|
+
sampleRate,
|
|
427
|
+
hopLength,
|
|
428
|
+
fmin,
|
|
429
|
+
binsPerOctave,
|
|
430
|
+
nIter,
|
|
431
|
+
options,
|
|
432
|
+
);
|
|
433
|
+
return requireModule().cqtToAudio(
|
|
434
|
+
magnitude,
|
|
435
|
+
nBins,
|
|
436
|
+
nFrames,
|
|
437
|
+
sampleRate,
|
|
438
|
+
hopLength,
|
|
439
|
+
fmin,
|
|
440
|
+
binsPerOctave,
|
|
441
|
+
nIter,
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/** Reconstruct mono audio from row-major VQT magnitude via Griffin-Lim. */
|
|
446
|
+
export function vqtToAudio(request: VqtToAudioRequest): Float32Array;
|
|
447
|
+
export function vqtToAudio(
|
|
448
|
+
magnitude: Float32Array,
|
|
449
|
+
nBins: number,
|
|
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,
|
|
463
|
+
sampleRate = 22050,
|
|
464
|
+
hopLength = 512,
|
|
465
|
+
fmin = 32.70319566257483,
|
|
466
|
+
binsPerOctave = 12,
|
|
467
|
+
gamma = 0,
|
|
468
|
+
nIter = 32,
|
|
469
|
+
options: GuardedOptions = {},
|
|
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
|
+
}
|
|
486
|
+
validateCqtInverse(
|
|
487
|
+
'vqtToAudio',
|
|
488
|
+
magnitude,
|
|
489
|
+
nBins,
|
|
490
|
+
nFrames,
|
|
491
|
+
sampleRate,
|
|
492
|
+
hopLength,
|
|
493
|
+
fmin,
|
|
494
|
+
binsPerOctave,
|
|
495
|
+
nIter,
|
|
496
|
+
options,
|
|
497
|
+
);
|
|
498
|
+
assertFiniteScalar('vqtToAudio', gamma, 'gamma');
|
|
499
|
+
if (gamma < 0) {
|
|
500
|
+
throw new RangeError('vqtToAudio: gamma must be non-negative');
|
|
501
|
+
}
|
|
502
|
+
return requireModule().vqtToAudio(
|
|
503
|
+
magnitude,
|
|
504
|
+
nBins,
|
|
505
|
+
nFrames,
|
|
506
|
+
sampleRate,
|
|
507
|
+
hopLength,
|
|
508
|
+
fmin,
|
|
509
|
+
binsPerOctave,
|
|
510
|
+
gamma,
|
|
511
|
+
nIter,
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
|
|
183
515
|
/**
|
|
184
516
|
* Detect song-structure sections (intro/verse/chorus/...).
|
|
185
517
|
*
|
|
@@ -190,11 +522,21 @@ export function vqt(
|
|
|
190
522
|
* @param minSectionSec - Minimum section duration in seconds (default: 4.0)
|
|
191
523
|
* @returns Array of detected sections
|
|
192
524
|
*/
|
|
525
|
+
export function analyzeSections(request: AnalyzeSectionsRequest): Section[];
|
|
193
526
|
export function analyzeSections(
|
|
194
527
|
samples: Float32Array,
|
|
528
|
+
sampleRate?: number,
|
|
529
|
+
options?: AnalyzeSectionsGuardedOptions,
|
|
530
|
+
): Section[];
|
|
531
|
+
export function analyzeSections(
|
|
532
|
+
samples: Float32Array | AnalyzeSectionsRequest,
|
|
195
533
|
sampleRate = 22050,
|
|
196
534
|
options: AnalyzeSectionsGuardedOptions = {},
|
|
197
535
|
): Section[] {
|
|
536
|
+
if (!(samples instanceof Float32Array)) {
|
|
537
|
+
const r = samples;
|
|
538
|
+
return analyzeSections(r.samples, r.sampleRate, r);
|
|
539
|
+
}
|
|
198
540
|
validateMusicSamples('analyzeSections', samples, sampleRate, options);
|
|
199
541
|
validatePositiveIntegers('analyzeSections', {
|
|
200
542
|
nFft: options.nFft ?? 2048,
|
|
@@ -252,11 +594,21 @@ export interface MelodyOptions {
|
|
|
252
594
|
* @param options - Tracker + tuning options ({@link MelodyOptions})
|
|
253
595
|
* @returns Melody contour with per-frame pitch points and summary stats
|
|
254
596
|
*/
|
|
597
|
+
export function analyzeMelody(request: AnalyzeMelodyRequest): MelodyResult;
|
|
255
598
|
export function analyzeMelody(
|
|
256
599
|
samples: Float32Array,
|
|
600
|
+
sampleRate?: number,
|
|
601
|
+
options?: MelodyGuardedOptions,
|
|
602
|
+
): MelodyResult;
|
|
603
|
+
export function analyzeMelody(
|
|
604
|
+
samples: Float32Array | AnalyzeMelodyRequest,
|
|
257
605
|
sampleRate = 22050,
|
|
258
606
|
options: MelodyGuardedOptions = {},
|
|
259
607
|
): MelodyResult {
|
|
608
|
+
if (!(samples instanceof Float32Array)) {
|
|
609
|
+
const r = samples;
|
|
610
|
+
return analyzeMelody(r.samples, r.sampleRate, r);
|
|
611
|
+
}
|
|
260
612
|
validateMusicSamples('analyzeMelody', samples, sampleRate, options);
|
|
261
613
|
const fmin = options.fmin ?? 65.0;
|
|
262
614
|
const fmax = options.fmax ?? 2093.0;
|
|
@@ -299,14 +651,34 @@ export function analyzeMelody(
|
|
|
299
651
|
* @param nMels - Number of Mel bands (default: 128)
|
|
300
652
|
* @returns Onset envelope for each frame
|
|
301
653
|
*/
|
|
654
|
+
export function onsetEnvelope(request: OnsetEnvelopeRequest): Float32Array;
|
|
302
655
|
export function onsetEnvelope(
|
|
303
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,
|
|
304
665
|
sampleRate = 22050,
|
|
305
666
|
nFft = 2048,
|
|
306
667
|
hopLength = 512,
|
|
307
668
|
nMels = 128,
|
|
308
669
|
options: GuardedOptions = {},
|
|
309
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
|
+
}
|
|
310
682
|
validateMusicSamples('onsetEnvelope', samples, sampleRate, options);
|
|
311
683
|
validatePositiveIntegers('onsetEnvelope', { nFft, hopLength, nMels });
|
|
312
684
|
return requireModule().onsetEnvelope(samples, sampleRate, nFft, hopLength, nMels);
|
|
@@ -323,8 +695,18 @@ export function onsetEnvelope(
|
|
|
323
695
|
* @param nBands - Number of onset bands (default: 3)
|
|
324
696
|
* @returns Multi-band onset matrix
|
|
325
697
|
*/
|
|
698
|
+
export function onsetStrengthMulti(request: OnsetStrengthMultiRequest): OnsetStrengthMultiResult;
|
|
326
699
|
export function onsetStrengthMulti(
|
|
327
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,
|
|
328
710
|
sampleRate = 22050,
|
|
329
711
|
nFft = 2048,
|
|
330
712
|
hopLength = 512,
|
|
@@ -332,6 +714,18 @@ export function onsetStrengthMulti(
|
|
|
332
714
|
nBands = 3,
|
|
333
715
|
options: GuardedOptions = {},
|
|
334
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
|
+
}
|
|
335
729
|
validateMusicSamples('onsetStrengthMulti', samples, sampleRate, options);
|
|
336
730
|
validatePositiveIntegers('onsetStrengthMulti', { nFft, hopLength, nMels, nBands });
|
|
337
731
|
return requireModule().onsetStrengthMulti(samples, sampleRate, nFft, hopLength, nMels, nBands);
|
|
@@ -346,13 +740,31 @@ export function onsetStrengthMulti(
|
|
|
346
740
|
* @param winLength - Window length in frames (default: 384)
|
|
347
741
|
* @returns Fourier tempogram result
|
|
348
742
|
*/
|
|
743
|
+
export function fourierTempogram(request: FourierTempogramRequest): WasmFourierTempogramResult;
|
|
349
744
|
export function fourierTempogram(
|
|
350
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,
|
|
351
753
|
sampleRate = 22050,
|
|
352
754
|
hopLength = 512,
|
|
353
755
|
winLength = 384,
|
|
354
756
|
options: GuardedOptions = {},
|
|
355
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
|
+
}
|
|
356
768
|
assertSampleRate('fourierTempogram', sampleRate);
|
|
357
769
|
assertSamples('fourierTempogram', onsetEnvelope, options.validate !== false, 'onsetEnvelope');
|
|
358
770
|
validatePositiveIntegers('fourierTempogram', { hopLength, winLength });
|
|
@@ -370,14 +782,34 @@ export function fourierTempogram(
|
|
|
370
782
|
* default {0.5, 1, 2, 3, 4} is used.
|
|
371
783
|
* @returns Tempogram ratio features (one value per factor)
|
|
372
784
|
*/
|
|
785
|
+
export function tempogramRatio(request: TempogramRatioRequest): Float32Array;
|
|
373
786
|
export function tempogramRatio(
|
|
374
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,
|
|
375
796
|
winLength = 384,
|
|
376
797
|
sampleRate = 22050,
|
|
377
798
|
hopLength = 512,
|
|
378
799
|
factors?: Float32Array | number[],
|
|
379
800
|
options: GuardedOptions = {},
|
|
380
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
|
+
}
|
|
381
813
|
assertSampleRate('tempogramRatio', sampleRate);
|
|
382
814
|
assertSamples('tempogramRatio', tempogramData, options.validate !== false, 'tempogramData');
|
|
383
815
|
validatePositiveIntegers('tempogramRatio', { winLength, hopLength });
|
|
@@ -393,11 +825,21 @@ export function tempogramRatio(
|
|
|
393
825
|
* dependent and a wrong rate yields wrong loudness.
|
|
394
826
|
* @returns Loudness measurement result
|
|
395
827
|
*/
|
|
828
|
+
export function lufs(request: LufsRequest): LufsResult;
|
|
396
829
|
export function lufs(
|
|
397
830
|
samples: Float32Array,
|
|
831
|
+
sampleRate?: number,
|
|
832
|
+
options?: ValidateOptions,
|
|
833
|
+
): LufsResult;
|
|
834
|
+
export function lufs(
|
|
835
|
+
samples: Float32Array | LufsRequest,
|
|
398
836
|
sampleRate = 22050,
|
|
399
837
|
options: ValidateOptions = {},
|
|
400
838
|
): LufsResult {
|
|
839
|
+
if (!(samples instanceof Float32Array)) {
|
|
840
|
+
const r = samples;
|
|
841
|
+
return lufs(r.samples, r.sampleRate, r);
|
|
842
|
+
}
|
|
401
843
|
assertSampleRate('lufs', sampleRate);
|
|
402
844
|
assertSamples('lufs', samples, options.validate !== false);
|
|
403
845
|
return requireModule().lufs(samples, sampleRate);
|
|
@@ -411,11 +853,21 @@ export function lufs(
|
|
|
411
853
|
* K-weighting is sample-rate dependent; pass the buffer's actual rate.
|
|
412
854
|
* @returns Momentary LUFS values over time
|
|
413
855
|
*/
|
|
856
|
+
export function momentaryLufs(request: LufsRequest): Float32Array;
|
|
414
857
|
export function momentaryLufs(
|
|
415
858
|
samples: Float32Array,
|
|
859
|
+
sampleRate?: number,
|
|
860
|
+
options?: ValidateOptions,
|
|
861
|
+
): Float32Array;
|
|
862
|
+
export function momentaryLufs(
|
|
863
|
+
samples: Float32Array | LufsRequest,
|
|
416
864
|
sampleRate = 22050,
|
|
417
865
|
options: ValidateOptions = {},
|
|
418
866
|
): Float32Array {
|
|
867
|
+
if (!(samples instanceof Float32Array)) {
|
|
868
|
+
const r = samples;
|
|
869
|
+
return momentaryLufs(r.samples, r.sampleRate, r);
|
|
870
|
+
}
|
|
419
871
|
assertSampleRate('momentaryLufs', sampleRate);
|
|
420
872
|
assertSamples('momentaryLufs', samples, options.validate !== false);
|
|
421
873
|
return requireModule().momentaryLufs(samples, sampleRate);
|
|
@@ -429,11 +881,21 @@ export function momentaryLufs(
|
|
|
429
881
|
* K-weighting is sample-rate dependent; pass the buffer's actual rate.
|
|
430
882
|
* @returns Short-term LUFS values over time
|
|
431
883
|
*/
|
|
884
|
+
export function shortTermLufs(request: LufsRequest): Float32Array;
|
|
432
885
|
export function shortTermLufs(
|
|
433
886
|
samples: Float32Array,
|
|
887
|
+
sampleRate?: number,
|
|
888
|
+
options?: ValidateOptions,
|
|
889
|
+
): Float32Array;
|
|
890
|
+
export function shortTermLufs(
|
|
891
|
+
samples: Float32Array | LufsRequest,
|
|
434
892
|
sampleRate = 22050,
|
|
435
893
|
options: ValidateOptions = {},
|
|
436
894
|
): Float32Array {
|
|
895
|
+
if (!(samples instanceof Float32Array)) {
|
|
896
|
+
const r = samples;
|
|
897
|
+
return shortTermLufs(r.samples, r.sampleRate, r);
|
|
898
|
+
}
|
|
437
899
|
assertSampleRate('shortTermLufs', sampleRate);
|
|
438
900
|
assertSamples('shortTermLufs', samples, options.validate !== false);
|
|
439
901
|
return requireModule().shortTermLufs(samples, sampleRate);
|