@libraz/libsonare 1.5.4 → 1.6.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/README.md +109 -20
- package/dist/analysis.d.ts +5730 -0
- package/dist/analysis.js +2464 -0
- package/dist/analysis.js.map +1 -0
- package/dist/index.d.ts +873 -63
- package/dist/index.js +1037 -265
- package/dist/index.js.map +1 -1
- package/dist/schemas/realtime-voice-changer-preset-pack.schema.json +27 -0
- package/dist/schemas/realtime-voice-changer-preset.schema.json +140 -0
- package/dist/sonare-analysis.js +2 -0
- package/dist/sonare-analysis.wasm +0 -0
- package/dist/sonare.js +1 -1
- package/dist/sonare.wasm +0 -0
- package/dist/worker.d.ts +65 -0
- package/dist/worker.js +707 -0
- package/dist/worker.js.map +1 -0
- package/dist/worklet.d.ts +596 -86
- package/dist/worklet.js +1658 -235
- package/dist/worklet.js.map +1 -1
- package/package.json +23 -11
- package/src/_chain_config.ts +5 -23
- package/src/analysis.ts +137 -0
- package/src/analysis_helpers.ts +29 -0
- package/src/audio.ts +5 -3
- package/src/clip_page_streamer.ts +62 -8
- package/src/codes.ts +51 -64
- package/src/effects_mastering.ts +1 -0
- package/src/effects_transform.ts +12 -6
- package/src/errors.ts +1 -0
- package/src/feature_core.ts +159 -3
- package/src/feature_music.ts +35 -16
- package/src/feature_pitch.ts +75 -6
- package/src/feature_spectral.ts +234 -8
- package/src/feature_spectrogram.ts +186 -5
- package/src/features.ts +16 -1
- package/src/index.ts +104 -7
- package/src/mastering_chain.ts +20 -8
- package/src/mastering_core.ts +7 -0
- package/src/mastering_dynamics.ts +7 -1
- package/src/metering.ts +51 -5
- package/src/mixer.ts +14 -1
- package/src/opfs_clip_pages.ts +26 -1
- package/src/project.ts +7 -0
- package/src/project_class.ts +74 -13
- package/src/project_internal.ts +24 -29
- package/src/project_types.ts +69 -10
- package/src/public_types.ts +68 -0
- package/src/public_types_mastering.ts +28 -0
- package/src/public_types_mixing.ts +11 -2
- package/src/public_types_music.ts +13 -0
- package/src/public_types_spectral.ts +43 -3
- package/src/quick_analysis.ts +48 -12
- package/src/realtime_engine.ts +162 -4
- package/src/realtime_voice_changer.ts +51 -77
- package/src/sonare-analysis.js.d.ts +8 -0
- package/src/sonare.js.d.ts +305 -9
- package/src/streaming_processors.ts +22 -1
- package/src/validation.ts +6 -0
- package/src/web_midi.ts +36 -4
- package/src/worker.ts +196 -0
- package/src/worker_client.ts +352 -0
- package/src/worker_protocol.ts +59 -0
- package/src/worklet/engine-automation.ts +2 -1
- package/src/worklet/engine-capture-facade.ts +13 -4
- package/src/worklet/engine-clips.ts +12 -3
- package/src/worklet/engine-node.ts +212 -4
- package/src/worklet/engine-offline.ts +7 -2
- package/src/worklet/engine-parameter-facade.ts +26 -5
- package/src/worklet/engine-processor.ts +383 -42
- package/src/worklet/engine-register.ts +8 -0
- package/src/worklet/engine-strips.ts +17 -1
- package/src/worklet/engine-sync.ts +2 -6
- package/src/worklet/engine-tempo-facade.ts +8 -6
- package/src/worklet/engine.ts +380 -13
- package/src/worklet/guards.ts +22 -1
- package/src/worklet/messages.ts +141 -9
- package/src/worklet/protocol.ts +303 -17
- package/src/worklet/voice-changer-processor.ts +12 -15
- package/src/worklet.ts +20 -1
package/dist/analysis.js
ADDED
|
@@ -0,0 +1,2464 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
|
|
3
|
+
ErrorCode2[ErrorCode2["Ok"] = 0] = "Ok";
|
|
4
|
+
ErrorCode2[ErrorCode2["FileNotFound"] = 1] = "FileNotFound";
|
|
5
|
+
ErrorCode2[ErrorCode2["InvalidFormat"] = 2] = "InvalidFormat";
|
|
6
|
+
ErrorCode2[ErrorCode2["DecodeFailed"] = 3] = "DecodeFailed";
|
|
7
|
+
ErrorCode2[ErrorCode2["InvalidParameter"] = 4] = "InvalidParameter";
|
|
8
|
+
ErrorCode2[ErrorCode2["OutOfMemory"] = 5] = "OutOfMemory";
|
|
9
|
+
ErrorCode2[ErrorCode2["NotSupported"] = 6] = "NotSupported";
|
|
10
|
+
ErrorCode2[ErrorCode2["InvalidState"] = 7] = "InvalidState";
|
|
11
|
+
ErrorCode2[ErrorCode2["Cancelled"] = 8] = "Cancelled";
|
|
12
|
+
ErrorCode2[ErrorCode2["Unknown"] = 99] = "Unknown";
|
|
13
|
+
return ErrorCode2;
|
|
14
|
+
})(ErrorCode || {});
|
|
15
|
+
var SonareError = class extends Error {
|
|
16
|
+
constructor(code, codeName, message) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = "SonareError";
|
|
19
|
+
this.code = code;
|
|
20
|
+
this.codeName = codeName;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
function isSonareError(value) {
|
|
24
|
+
return value instanceof Error && value.name === "SonareError" && typeof value.code === "number";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// src/module_state.ts
|
|
28
|
+
var wrappedModule = null;
|
|
29
|
+
function nativeExceptionPtr(error) {
|
|
30
|
+
if (typeof error === "number") {
|
|
31
|
+
return error;
|
|
32
|
+
}
|
|
33
|
+
if (error !== null && typeof error === "object") {
|
|
34
|
+
const ptr = error.excPtr;
|
|
35
|
+
if (typeof ptr === "number") {
|
|
36
|
+
return ptr;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
function makeSonareError(raw, thrown) {
|
|
42
|
+
let code = 99 /* Unknown */;
|
|
43
|
+
let codeName = "Unknown";
|
|
44
|
+
let message = `libsonare native exception (${thrown})`;
|
|
45
|
+
try {
|
|
46
|
+
const info = raw.sonareExceptionInfo?.(thrown);
|
|
47
|
+
if (info) {
|
|
48
|
+
code = info.code ?? code;
|
|
49
|
+
codeName = info.codeName ?? codeName;
|
|
50
|
+
message = info.message || message;
|
|
51
|
+
}
|
|
52
|
+
} catch {
|
|
53
|
+
}
|
|
54
|
+
return new SonareError(code, codeName, message);
|
|
55
|
+
}
|
|
56
|
+
function wrapModuleErrors(raw) {
|
|
57
|
+
const cache = /* @__PURE__ */ new Map();
|
|
58
|
+
const objectCache = /* @__PURE__ */ new WeakMap();
|
|
59
|
+
const convert = (error) => {
|
|
60
|
+
const ptr = nativeExceptionPtr(error);
|
|
61
|
+
if (ptr !== null) {
|
|
62
|
+
throw makeSonareError(raw, ptr);
|
|
63
|
+
}
|
|
64
|
+
throw error;
|
|
65
|
+
};
|
|
66
|
+
const wrapNativeObject = (value) => {
|
|
67
|
+
if (value === null || typeof value !== "object") {
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer || value instanceof Promise) {
|
|
71
|
+
return value;
|
|
72
|
+
}
|
|
73
|
+
const objectValue = value;
|
|
74
|
+
const cached = objectCache.get(objectValue);
|
|
75
|
+
if (cached) {
|
|
76
|
+
return cached;
|
|
77
|
+
}
|
|
78
|
+
const methodCache = /* @__PURE__ */ new Map();
|
|
79
|
+
const wrapped = new Proxy(objectValue, {
|
|
80
|
+
get(target, prop, receiver) {
|
|
81
|
+
const member = Reflect.get(target, prop, receiver);
|
|
82
|
+
if (typeof member !== "function") {
|
|
83
|
+
return member;
|
|
84
|
+
}
|
|
85
|
+
const cachedMethod = methodCache.get(prop);
|
|
86
|
+
if (cachedMethod) {
|
|
87
|
+
return cachedMethod;
|
|
88
|
+
}
|
|
89
|
+
const method = member;
|
|
90
|
+
const wrappedMethod = (...args) => {
|
|
91
|
+
try {
|
|
92
|
+
return wrapNativeObject(Reflect.apply(method, target, args));
|
|
93
|
+
} catch (error) {
|
|
94
|
+
return convert(error);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
methodCache.set(prop, wrappedMethod);
|
|
98
|
+
return wrappedMethod;
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
objectCache.set(objectValue, wrapped);
|
|
102
|
+
return wrapped;
|
|
103
|
+
};
|
|
104
|
+
const wrapFunction = (value) => {
|
|
105
|
+
const fnCache = /* @__PURE__ */ new Map();
|
|
106
|
+
return new Proxy(value, {
|
|
107
|
+
get(target, prop, receiver) {
|
|
108
|
+
const member = Reflect.get(target, prop, receiver);
|
|
109
|
+
if (typeof member !== "function") {
|
|
110
|
+
return member;
|
|
111
|
+
}
|
|
112
|
+
const cachedMember = fnCache.get(prop);
|
|
113
|
+
if (cachedMember) {
|
|
114
|
+
return cachedMember;
|
|
115
|
+
}
|
|
116
|
+
const fn = member;
|
|
117
|
+
const wrappedMember = (...args) => {
|
|
118
|
+
try {
|
|
119
|
+
return wrapNativeObject(Reflect.apply(fn, target, args));
|
|
120
|
+
} catch (error) {
|
|
121
|
+
return convert(error);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
fnCache.set(prop, wrappedMember);
|
|
125
|
+
return wrappedMember;
|
|
126
|
+
},
|
|
127
|
+
apply(t, thisArg, args) {
|
|
128
|
+
try {
|
|
129
|
+
return wrapNativeObject(Reflect.apply(t, thisArg, args));
|
|
130
|
+
} catch (error) {
|
|
131
|
+
return convert(error);
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
construct(t, args, newTarget) {
|
|
135
|
+
try {
|
|
136
|
+
return wrapNativeObject(Reflect.construct(t, args, newTarget));
|
|
137
|
+
} catch (error) {
|
|
138
|
+
return convert(error);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
return new Proxy(raw, {
|
|
144
|
+
get(target, prop, receiver) {
|
|
145
|
+
const value = Reflect.get(target, prop, receiver);
|
|
146
|
+
if (typeof value !== "function") {
|
|
147
|
+
return value;
|
|
148
|
+
}
|
|
149
|
+
const cached = cache.get(prop);
|
|
150
|
+
if (cached) {
|
|
151
|
+
return cached;
|
|
152
|
+
}
|
|
153
|
+
const wrapped = wrapFunction(value);
|
|
154
|
+
cache.set(prop, wrapped);
|
|
155
|
+
return wrapped;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
function setSonareModule(module2) {
|
|
160
|
+
wrappedModule = wrapModuleErrors(module2);
|
|
161
|
+
}
|
|
162
|
+
function getSonareModule() {
|
|
163
|
+
if (!wrappedModule) {
|
|
164
|
+
throw new Error("Module not initialized. Call init() first.");
|
|
165
|
+
}
|
|
166
|
+
return wrappedModule;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// src/feature_core.ts
|
|
170
|
+
function requireModule() {
|
|
171
|
+
return getSonareModule();
|
|
172
|
+
}
|
|
173
|
+
function tone(frequency = 440, sampleRate = 22050, duration = 1, phase = 0, amplitude = 1) {
|
|
174
|
+
const request = typeof frequency === "number" ? { frequency, sampleRate, duration, phase, amplitude } : frequency;
|
|
175
|
+
return requireModule().tone(
|
|
176
|
+
request.frequency ?? 440,
|
|
177
|
+
request.sampleRate ?? 22050,
|
|
178
|
+
request.duration ?? 1,
|
|
179
|
+
request.phase ?? 0,
|
|
180
|
+
request.amplitude ?? 1
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
function chirp(fmin = 440, fmax = 880, sampleRate = 22050, duration = 1, linear = true) {
|
|
184
|
+
const request = typeof fmin === "number" ? { fmin, fmax, sampleRate, duration, linear } : fmin;
|
|
185
|
+
return requireModule().chirp(
|
|
186
|
+
request.fmin ?? 440,
|
|
187
|
+
request.fmax ?? 880,
|
|
188
|
+
request.sampleRate ?? 22050,
|
|
189
|
+
request.duration ?? 1,
|
|
190
|
+
request.linear ?? true
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
function clicks(times, sampleRate = 22050, length = 0, frequency = 1e3, clickDuration = 0.1) {
|
|
194
|
+
const request = times instanceof Float32Array ? { times, sampleRate, length, frequency, clickDuration } : times;
|
|
195
|
+
return requireModule().clicks(
|
|
196
|
+
request.times,
|
|
197
|
+
request.sampleRate ?? 22050,
|
|
198
|
+
request.length ?? 0,
|
|
199
|
+
request.frequency ?? 1e3,
|
|
200
|
+
request.clickDuration ?? 0.1
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
function hzToMel(hz) {
|
|
204
|
+
return requireModule().hzToMel(hz);
|
|
205
|
+
}
|
|
206
|
+
function melToHz(mel) {
|
|
207
|
+
return requireModule().melToHz(mel);
|
|
208
|
+
}
|
|
209
|
+
function hzToMidi(hz) {
|
|
210
|
+
return requireModule().hzToMidi(hz);
|
|
211
|
+
}
|
|
212
|
+
function midiToHz(midi) {
|
|
213
|
+
return requireModule().midiToHz(midi);
|
|
214
|
+
}
|
|
215
|
+
function hzToNote(hz) {
|
|
216
|
+
return requireModule().hzToNote(hz);
|
|
217
|
+
}
|
|
218
|
+
function noteToHz(note) {
|
|
219
|
+
return requireModule().noteToHz(note);
|
|
220
|
+
}
|
|
221
|
+
function framesToTime(frames, sr = 22050, hopLength = 512) {
|
|
222
|
+
return requireModule().framesToTime(frames, sr, hopLength);
|
|
223
|
+
}
|
|
224
|
+
function timeToFrames(time, sr = 22050, hopLength = 512) {
|
|
225
|
+
return requireModule().timeToFrames(time, sr, hopLength);
|
|
226
|
+
}
|
|
227
|
+
function framesToSamples(frames, hopLength = 512, nFft = 0) {
|
|
228
|
+
return requireModule().framesToSamples(frames, hopLength, nFft);
|
|
229
|
+
}
|
|
230
|
+
function samplesToFrames(samples, hopLength = 512, nFft = 0) {
|
|
231
|
+
return requireModule().samplesToFrames(samples, hopLength, nFft);
|
|
232
|
+
}
|
|
233
|
+
function powerToDb(values, ref = 1, amin = 1e-10, topDb = 80) {
|
|
234
|
+
if (!(values instanceof Float32Array)) {
|
|
235
|
+
return powerToDb(values.values, values.ref, values.amin, values.topDb);
|
|
236
|
+
}
|
|
237
|
+
return requireModule().powerToDb(values, ref, amin, topDb);
|
|
238
|
+
}
|
|
239
|
+
function amplitudeToDb(values, ref = 1, amin = 1e-5, topDb = 80) {
|
|
240
|
+
if (!(values instanceof Float32Array)) {
|
|
241
|
+
return amplitudeToDb(values.values, values.ref, values.amin, values.topDb);
|
|
242
|
+
}
|
|
243
|
+
return requireModule().amplitudeToDb(values, ref, amin, topDb);
|
|
244
|
+
}
|
|
245
|
+
function dbToPower(values, ref = 1) {
|
|
246
|
+
return requireModule().dbToPower(values, ref);
|
|
247
|
+
}
|
|
248
|
+
function dbToAmplitude(values, ref = 1) {
|
|
249
|
+
return requireModule().dbToAmplitude(values, ref);
|
|
250
|
+
}
|
|
251
|
+
function preemphasis(samples, coef = 0.97, zi) {
|
|
252
|
+
if (!(samples instanceof Float32Array)) {
|
|
253
|
+
return preemphasis(samples.samples, samples.coef, samples.zi);
|
|
254
|
+
}
|
|
255
|
+
return requireModule().preemphasis(samples, coef, zi ?? null);
|
|
256
|
+
}
|
|
257
|
+
function deemphasis(samples, coef = 0.97, zi) {
|
|
258
|
+
if (!(samples instanceof Float32Array)) {
|
|
259
|
+
return deemphasis(samples.samples, samples.coef, samples.zi);
|
|
260
|
+
}
|
|
261
|
+
return requireModule().deemphasis(samples, coef, zi ?? null);
|
|
262
|
+
}
|
|
263
|
+
function trimSilence(samples, topDb = 60, frameLength = 2048, hopLength = 512) {
|
|
264
|
+
if (!(samples instanceof Float32Array)) {
|
|
265
|
+
return trimSilence(samples.samples, samples.topDb, samples.frameLength, samples.hopLength);
|
|
266
|
+
}
|
|
267
|
+
return requireModule().trimSilence(samples, topDb, frameLength, hopLength);
|
|
268
|
+
}
|
|
269
|
+
function splitSilence(samples, topDb = 60, frameLength = 2048, hopLength = 512) {
|
|
270
|
+
if (!(samples instanceof Float32Array)) {
|
|
271
|
+
return splitSilence(samples.samples, samples.topDb, samples.frameLength, samples.hopLength);
|
|
272
|
+
}
|
|
273
|
+
return requireModule().splitSilence(samples, topDb, frameLength, hopLength);
|
|
274
|
+
}
|
|
275
|
+
function frameSignal(samples, frameLength, hopLength) {
|
|
276
|
+
if (!(samples instanceof Float32Array)) {
|
|
277
|
+
return frameSignal(samples.samples, samples.frameLength, samples.hopLength);
|
|
278
|
+
}
|
|
279
|
+
return requireModule().frameSignal(samples, frameLength, hopLength);
|
|
280
|
+
}
|
|
281
|
+
function padCenter(values, targetSize, padValue = 0) {
|
|
282
|
+
if (!(values instanceof Float32Array)) {
|
|
283
|
+
return padCenter(values.values, values.targetSize, values.padValue);
|
|
284
|
+
}
|
|
285
|
+
return requireModule().padCenter(values, targetSize, padValue);
|
|
286
|
+
}
|
|
287
|
+
function fixLength(values, targetSize, padValue = 0) {
|
|
288
|
+
if (!(values instanceof Float32Array)) {
|
|
289
|
+
return fixLength(values.values, values.targetSize, values.padValue);
|
|
290
|
+
}
|
|
291
|
+
return requireModule().fixLength(values, targetSize, padValue);
|
|
292
|
+
}
|
|
293
|
+
function fixFrames(frames, xMin = 0, xMax = -1, pad = true) {
|
|
294
|
+
if (!(frames instanceof Int32Array)) {
|
|
295
|
+
return fixFrames(frames.frames, frames.xMin, frames.xMax, frames.pad);
|
|
296
|
+
}
|
|
297
|
+
return requireModule().fixFrames(frames, xMin, xMax, pad);
|
|
298
|
+
}
|
|
299
|
+
function onsetBacktrack(events, energy) {
|
|
300
|
+
if (!(events instanceof Int32Array)) {
|
|
301
|
+
return onsetBacktrack(events.events, events.energy);
|
|
302
|
+
}
|
|
303
|
+
return requireModule().onsetBacktrack(events, energy);
|
|
304
|
+
}
|
|
305
|
+
function peakPick(values, preMax, postMax, preAvg, postAvg, delta, wait) {
|
|
306
|
+
if (!(values instanceof Float32Array)) {
|
|
307
|
+
const r = values;
|
|
308
|
+
return peakPick(r.values, r.preMax, r.postMax, r.preAvg, r.postAvg, r.delta, r.wait);
|
|
309
|
+
}
|
|
310
|
+
return requireModule().peakPick(
|
|
311
|
+
values,
|
|
312
|
+
preMax,
|
|
313
|
+
postMax,
|
|
314
|
+
preAvg,
|
|
315
|
+
postAvg,
|
|
316
|
+
delta,
|
|
317
|
+
wait
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
function vectorNormalize(values, normType = 0, threshold = 0) {
|
|
321
|
+
if (!(values instanceof Float32Array)) {
|
|
322
|
+
return vectorNormalize(values.values, values.normType, values.threshold);
|
|
323
|
+
}
|
|
324
|
+
return requireModule().vectorNormalize(values, normType, threshold);
|
|
325
|
+
}
|
|
326
|
+
function pcen(values, nBins = 0, nFrames = 0, options = {}) {
|
|
327
|
+
if (!(values instanceof Float32Array)) {
|
|
328
|
+
const r = values;
|
|
329
|
+
const {
|
|
330
|
+
values: requestValues,
|
|
331
|
+
nBins: requestBins,
|
|
332
|
+
nFrames: requestFrames,
|
|
333
|
+
options: legacyOptions,
|
|
334
|
+
...flatOptions
|
|
335
|
+
} = r;
|
|
336
|
+
return pcen(requestValues, requestBins, requestFrames, {
|
|
337
|
+
...legacyOptions,
|
|
338
|
+
...flatOptions
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
return requireModule().pcen(values, nBins, nFrames, options);
|
|
342
|
+
}
|
|
343
|
+
function tonnetz(chromagram, nChroma, nFrames) {
|
|
344
|
+
if (!(chromagram instanceof Float32Array)) {
|
|
345
|
+
return tonnetz(chromagram.chromagram, chromagram.nChroma, chromagram.nFrames);
|
|
346
|
+
}
|
|
347
|
+
return requireModule().tonnetz(chromagram, nChroma, nFrames);
|
|
348
|
+
}
|
|
349
|
+
function tempogram(onsetEnvelope2, sampleRate = 22050, hopLength = 512, winLength = 384, mode = "autocorrelation", center = true, norm = true) {
|
|
350
|
+
if (!(onsetEnvelope2 instanceof Float32Array)) {
|
|
351
|
+
const r = onsetEnvelope2;
|
|
352
|
+
return tempogram(
|
|
353
|
+
r.onsetEnvelope,
|
|
354
|
+
r.sampleRate,
|
|
355
|
+
r.hopLength,
|
|
356
|
+
r.winLength,
|
|
357
|
+
r.mode,
|
|
358
|
+
r.center,
|
|
359
|
+
r.norm
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
return requireModule().tempogram(
|
|
363
|
+
onsetEnvelope2,
|
|
364
|
+
sampleRate,
|
|
365
|
+
hopLength,
|
|
366
|
+
winLength,
|
|
367
|
+
mode,
|
|
368
|
+
center,
|
|
369
|
+
norm
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
function cyclicTempogram(onsetEnvelope2, sampleRate = 22050, hopLength = 512, winLength = 384, bpmMin = 60, nBins = 60) {
|
|
373
|
+
if (!(onsetEnvelope2 instanceof Float32Array)) {
|
|
374
|
+
const r = onsetEnvelope2;
|
|
375
|
+
return cyclicTempogram(
|
|
376
|
+
r.onsetEnvelope,
|
|
377
|
+
r.sampleRate,
|
|
378
|
+
r.hopLength,
|
|
379
|
+
r.winLength,
|
|
380
|
+
r.bpmMin,
|
|
381
|
+
r.nBins
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
return requireModule().cyclicTempogram(
|
|
385
|
+
onsetEnvelope2,
|
|
386
|
+
sampleRate,
|
|
387
|
+
hopLength,
|
|
388
|
+
winLength,
|
|
389
|
+
bpmMin,
|
|
390
|
+
nBins
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
function plp(onsetEnvelope2, sampleRate = 22050, hopLength = 512, tempoMin = 30, tempoMax = 300, winLength = 384) {
|
|
394
|
+
if (!(onsetEnvelope2 instanceof Float32Array)) {
|
|
395
|
+
const r = onsetEnvelope2;
|
|
396
|
+
return plp(r.onsetEnvelope, r.sampleRate, r.hopLength, r.tempoMin, r.tempoMax, r.winLength);
|
|
397
|
+
}
|
|
398
|
+
return requireModule().plp(onsetEnvelope2, sampleRate, hopLength, tempoMin, tempoMax, winLength);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// src/validation.ts
|
|
402
|
+
var MIN_AUDIO_SAMPLE_RATE = 8e3;
|
|
403
|
+
var MAX_AUDIO_SAMPLE_RATE = 384e3;
|
|
404
|
+
function assertNonEmptySamples(fnName, samples, argName = "samples") {
|
|
405
|
+
if (samples.length === 0) {
|
|
406
|
+
throw new RangeError(`${fnName}: ${argName} must not be empty`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
function assertFiniteSamples(fnName, samples, validate, argName = "samples") {
|
|
410
|
+
if (!validate) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
for (let i = 0; i < samples.length; i++) {
|
|
414
|
+
const v = samples[i];
|
|
415
|
+
if (!Number.isFinite(v)) {
|
|
416
|
+
throw new RangeError(`${fnName}: ${argName} contains NaN or Inf at index ${i}`);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
function assertSamples(fnName, samples, validate, argName = "samples") {
|
|
421
|
+
assertNonEmptySamples(fnName, samples, argName);
|
|
422
|
+
assertFiniteSamples(fnName, samples, validate, argName);
|
|
423
|
+
}
|
|
424
|
+
function assertFiniteScalar(fnName, value, argName) {
|
|
425
|
+
if (!Number.isFinite(value)) {
|
|
426
|
+
throw new RangeError(`${fnName}: ${argName} must be a finite number`);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
function assertSampleRate(fnName, sampleRate) {
|
|
430
|
+
if (!Number.isInteger(sampleRate) || sampleRate < MIN_AUDIO_SAMPLE_RATE || sampleRate > MAX_AUDIO_SAMPLE_RATE) {
|
|
431
|
+
throw new RangeError(
|
|
432
|
+
`${fnName}: sampleRate out of supported range [${MIN_AUDIO_SAMPLE_RATE}, ${MAX_AUDIO_SAMPLE_RATE}]`
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
function assertNonNegativeInteger(fnName, value, argName) {
|
|
437
|
+
if (!Number.isInteger(value) || value < 0) {
|
|
438
|
+
throw new RangeError(`${fnName}: ${argName} must be a non-negative integer`);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
function assertPositiveInteger(fnName, value, argName) {
|
|
442
|
+
if (!Number.isInteger(value) || value <= 0) {
|
|
443
|
+
throw new RangeError(`${fnName}: ${argName} must be a positive integer`);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
function assertInterleavedSamples(fnName, samples, channels, validate) {
|
|
447
|
+
assertSamples(fnName, samples, validate);
|
|
448
|
+
assertPositiveInteger(fnName, channels, "channels");
|
|
449
|
+
if (samples.length % channels !== 0) {
|
|
450
|
+
throw new RangeError(`${fnName}: samples length must be a multiple of channels`);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// src/feature_music.ts
|
|
455
|
+
function requireModule2() {
|
|
456
|
+
return getSonareModule();
|
|
457
|
+
}
|
|
458
|
+
function validateMusicSamples(fnName, samples, sampleRate, options = {}) {
|
|
459
|
+
assertSampleRate(fnName, sampleRate);
|
|
460
|
+
assertSamples(fnName, samples, options.validate !== false);
|
|
461
|
+
}
|
|
462
|
+
function validatePositiveIntegers(fnName, values) {
|
|
463
|
+
for (const [name, value] of Object.entries(values)) {
|
|
464
|
+
assertPositiveInteger(fnName, value, name);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
function validateFrequencyBounds(fnName, fmin, fmax) {
|
|
468
|
+
assertFiniteScalar(fnName, fmin, "fmin");
|
|
469
|
+
if (fmin < 0) {
|
|
470
|
+
throw new RangeError(`${fnName}: fmin must be non-negative`);
|
|
471
|
+
}
|
|
472
|
+
if (fmax !== void 0) {
|
|
473
|
+
assertFiniteScalar(fnName, fmax, "fmax");
|
|
474
|
+
if (fmax <= fmin) {
|
|
475
|
+
throw new RangeError(`${fnName}: fmax must be greater than fmin`);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
function nnlsChroma(samples, sampleRate = 22050, options = {}) {
|
|
480
|
+
if (!(samples instanceof Float32Array)) {
|
|
481
|
+
return nnlsChroma(samples.samples, samples.sampleRate, samples);
|
|
482
|
+
}
|
|
483
|
+
validateMusicSamples("nnlsChroma", samples, sampleRate, options);
|
|
484
|
+
return requireModule2().nnlsChroma(
|
|
485
|
+
samples,
|
|
486
|
+
sampleRate,
|
|
487
|
+
options.enableStftBlend ?? true,
|
|
488
|
+
options.stftBlendWeight ?? 0.55,
|
|
489
|
+
options.stftBlendNFft ?? 4096
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
function cqt(samples, sampleRate = 22050, hopLength = 512, fmin = 32.70319566257483, nBins = 84, binsPerOctave = 12, options = {}) {
|
|
493
|
+
if (!(samples instanceof Float32Array)) {
|
|
494
|
+
const request = samples;
|
|
495
|
+
return cqt(
|
|
496
|
+
request.samples,
|
|
497
|
+
request.sampleRate,
|
|
498
|
+
request.hopLength,
|
|
499
|
+
request.fmin,
|
|
500
|
+
request.nBins,
|
|
501
|
+
request.binsPerOctave,
|
|
502
|
+
request
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
validateMusicSamples("cqt", samples, sampleRate, options);
|
|
506
|
+
validatePositiveIntegers("cqt", { hopLength, nBins, binsPerOctave });
|
|
507
|
+
validateFrequencyBounds("cqt", fmin);
|
|
508
|
+
return requireModule2().cqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave);
|
|
509
|
+
}
|
|
510
|
+
function pseudoCqt(samples, sampleRate = 22050, hopLength = 512, fmin = 32.70319566257483, nBins = 84, binsPerOctave = 12, options = {}) {
|
|
511
|
+
if (!(samples instanceof Float32Array)) {
|
|
512
|
+
const request = samples;
|
|
513
|
+
return pseudoCqt(
|
|
514
|
+
request.samples,
|
|
515
|
+
request.sampleRate,
|
|
516
|
+
request.hopLength,
|
|
517
|
+
request.fmin,
|
|
518
|
+
request.nBins,
|
|
519
|
+
request.binsPerOctave,
|
|
520
|
+
request
|
|
521
|
+
);
|
|
522
|
+
}
|
|
523
|
+
validateMusicSamples("pseudoCqt", samples, sampleRate, options);
|
|
524
|
+
validatePositiveIntegers("pseudoCqt", { hopLength, nBins, binsPerOctave });
|
|
525
|
+
validateFrequencyBounds("pseudoCqt", fmin);
|
|
526
|
+
return requireModule2().pseudoCqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave);
|
|
527
|
+
}
|
|
528
|
+
function hybridCqt(samples, sampleRate = 22050, hopLength = 512, fmin = 32.70319566257483, nBins = 84, binsPerOctave = 12, options = {}) {
|
|
529
|
+
if (!(samples instanceof Float32Array)) {
|
|
530
|
+
const request = samples;
|
|
531
|
+
return hybridCqt(
|
|
532
|
+
request.samples,
|
|
533
|
+
request.sampleRate,
|
|
534
|
+
request.hopLength,
|
|
535
|
+
request.fmin,
|
|
536
|
+
request.nBins,
|
|
537
|
+
request.binsPerOctave,
|
|
538
|
+
request
|
|
539
|
+
);
|
|
540
|
+
}
|
|
541
|
+
validateMusicSamples("hybridCqt", samples, sampleRate, options);
|
|
542
|
+
validatePositiveIntegers("hybridCqt", { hopLength, nBins, binsPerOctave });
|
|
543
|
+
validateFrequencyBounds("hybridCqt", fmin);
|
|
544
|
+
return requireModule2().hybridCqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave);
|
|
545
|
+
}
|
|
546
|
+
function vqt(samples, sampleRate = 22050, hopLength = 512, fmin = 32.70319566257483, nBins = 84, binsPerOctave = 12, gamma = -1, options = {}) {
|
|
547
|
+
if (!(samples instanceof Float32Array)) {
|
|
548
|
+
const request = samples;
|
|
549
|
+
return vqt(
|
|
550
|
+
request.samples,
|
|
551
|
+
request.sampleRate,
|
|
552
|
+
request.hopLength,
|
|
553
|
+
request.fmin,
|
|
554
|
+
request.nBins,
|
|
555
|
+
request.binsPerOctave,
|
|
556
|
+
request.gamma,
|
|
557
|
+
request
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
validateMusicSamples("vqt", samples, sampleRate, options);
|
|
561
|
+
validatePositiveIntegers("vqt", { hopLength, nBins, binsPerOctave });
|
|
562
|
+
validateFrequencyBounds("vqt", fmin);
|
|
563
|
+
assertFiniteScalar("vqt", gamma, "gamma");
|
|
564
|
+
return requireModule2().vqt(samples, sampleRate, hopLength, fmin, nBins, binsPerOctave, gamma);
|
|
565
|
+
}
|
|
566
|
+
function validateCqtInverse(fnName, magnitude, nBins, nFrames, sampleRate, hopLength, fmin, binsPerOctave, nIter, options) {
|
|
567
|
+
assertSampleRate(fnName, sampleRate);
|
|
568
|
+
validatePositiveIntegers(fnName, { nBins, nFrames, hopLength, binsPerOctave, nIter });
|
|
569
|
+
if (nIter > 256) {
|
|
570
|
+
throw new RangeError(`${fnName}: nIter must be at most 256`);
|
|
571
|
+
}
|
|
572
|
+
validateFrequencyBounds(fnName, fmin);
|
|
573
|
+
if (fmin === 0) {
|
|
574
|
+
throw new RangeError(`${fnName}: fmin must be positive`);
|
|
575
|
+
}
|
|
576
|
+
if (magnitude.length !== nBins * nFrames) {
|
|
577
|
+
throw new RangeError(`${fnName}: magnitude length must equal nBins * nFrames`);
|
|
578
|
+
}
|
|
579
|
+
assertSamples(fnName, magnitude, options.validate !== false);
|
|
580
|
+
}
|
|
581
|
+
function cqtToAudio(magnitude, nBins = 0, nFrames = 0, sampleRate = 22050, hopLength = 512, fmin = 32.70319566257483, binsPerOctave = 12, nIter = 32, options = {}) {
|
|
582
|
+
if (!(magnitude instanceof Float32Array)) {
|
|
583
|
+
const request = magnitude;
|
|
584
|
+
return cqtToAudio(
|
|
585
|
+
request.magnitude,
|
|
586
|
+
request.nBins,
|
|
587
|
+
request.nFrames,
|
|
588
|
+
request.sampleRate,
|
|
589
|
+
request.hopLength,
|
|
590
|
+
request.fmin,
|
|
591
|
+
request.binsPerOctave,
|
|
592
|
+
request.nIter,
|
|
593
|
+
request
|
|
594
|
+
);
|
|
595
|
+
}
|
|
596
|
+
validateCqtInverse(
|
|
597
|
+
"cqtToAudio",
|
|
598
|
+
magnitude,
|
|
599
|
+
nBins,
|
|
600
|
+
nFrames,
|
|
601
|
+
sampleRate,
|
|
602
|
+
hopLength,
|
|
603
|
+
fmin,
|
|
604
|
+
binsPerOctave,
|
|
605
|
+
nIter,
|
|
606
|
+
options
|
|
607
|
+
);
|
|
608
|
+
return requireModule2().cqtToAudio(
|
|
609
|
+
magnitude,
|
|
610
|
+
nBins,
|
|
611
|
+
nFrames,
|
|
612
|
+
sampleRate,
|
|
613
|
+
hopLength,
|
|
614
|
+
fmin,
|
|
615
|
+
binsPerOctave,
|
|
616
|
+
nIter
|
|
617
|
+
);
|
|
618
|
+
}
|
|
619
|
+
function vqtToAudio(magnitude, nBins = 0, nFrames = 0, sampleRate = 22050, hopLength = 512, fmin = 32.70319566257483, binsPerOctave = 12, gamma = -1, nIter = 32, options = {}) {
|
|
620
|
+
if (!(magnitude instanceof Float32Array)) {
|
|
621
|
+
const request = magnitude;
|
|
622
|
+
return vqtToAudio(
|
|
623
|
+
request.magnitude,
|
|
624
|
+
request.nBins,
|
|
625
|
+
request.nFrames,
|
|
626
|
+
request.sampleRate,
|
|
627
|
+
request.hopLength,
|
|
628
|
+
request.fmin,
|
|
629
|
+
request.binsPerOctave,
|
|
630
|
+
request.gamma,
|
|
631
|
+
request.nIter,
|
|
632
|
+
request
|
|
633
|
+
);
|
|
634
|
+
}
|
|
635
|
+
validateCqtInverse(
|
|
636
|
+
"vqtToAudio",
|
|
637
|
+
magnitude,
|
|
638
|
+
nBins,
|
|
639
|
+
nFrames,
|
|
640
|
+
sampleRate,
|
|
641
|
+
hopLength,
|
|
642
|
+
fmin,
|
|
643
|
+
binsPerOctave,
|
|
644
|
+
nIter,
|
|
645
|
+
options
|
|
646
|
+
);
|
|
647
|
+
assertFiniteScalar("vqtToAudio", gamma, "gamma");
|
|
648
|
+
return requireModule2().vqtToAudio(
|
|
649
|
+
magnitude,
|
|
650
|
+
nBins,
|
|
651
|
+
nFrames,
|
|
652
|
+
sampleRate,
|
|
653
|
+
hopLength,
|
|
654
|
+
fmin,
|
|
655
|
+
binsPerOctave,
|
|
656
|
+
gamma,
|
|
657
|
+
nIter
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
function analyzeSections(samples, sampleRate = 22050, options = {}) {
|
|
661
|
+
if (!(samples instanceof Float32Array)) {
|
|
662
|
+
const r = samples;
|
|
663
|
+
return analyzeSections(r.samples, r.sampleRate, r);
|
|
664
|
+
}
|
|
665
|
+
validateMusicSamples("analyzeSections", samples, sampleRate, options);
|
|
666
|
+
validatePositiveIntegers("analyzeSections", {
|
|
667
|
+
nFft: options.nFft ?? 2048,
|
|
668
|
+
hopLength: options.hopLength ?? 512
|
|
669
|
+
});
|
|
670
|
+
assertFiniteScalar("analyzeSections", options.minSectionSec ?? 4, "minSectionSec");
|
|
671
|
+
if ((options.minSectionSec ?? 4) < 0) {
|
|
672
|
+
throw new RangeError("analyzeSections: minSectionSec must be non-negative");
|
|
673
|
+
}
|
|
674
|
+
const sections = requireModule2().analyzeSections(
|
|
675
|
+
samples,
|
|
676
|
+
sampleRate,
|
|
677
|
+
options.nFft ?? 2048,
|
|
678
|
+
options.hopLength ?? 512,
|
|
679
|
+
options.minSectionSec ?? 4
|
|
680
|
+
);
|
|
681
|
+
return Array.from(sections, (s) => ({ ...s, type: s.type }));
|
|
682
|
+
}
|
|
683
|
+
function analyzeMelody(samples, sampleRate = 22050, options = {}) {
|
|
684
|
+
if (!(samples instanceof Float32Array)) {
|
|
685
|
+
const r = samples;
|
|
686
|
+
return analyzeMelody(r.samples, r.sampleRate, r);
|
|
687
|
+
}
|
|
688
|
+
validateMusicSamples("analyzeMelody", samples, sampleRate, options);
|
|
689
|
+
const fmin = options.fmin ?? 65;
|
|
690
|
+
const fmax = options.fmax ?? 2093;
|
|
691
|
+
validateFrequencyBounds("analyzeMelody", fmin, fmax);
|
|
692
|
+
if (fmin <= 0) {
|
|
693
|
+
throw new SonareError(
|
|
694
|
+
4 /* InvalidParameter */,
|
|
695
|
+
"InvalidParameter",
|
|
696
|
+
"analyzeMelody: fmin must be positive"
|
|
697
|
+
);
|
|
698
|
+
}
|
|
699
|
+
validatePositiveIntegers("analyzeMelody", {
|
|
700
|
+
frameLength: options.frameLength ?? 2048,
|
|
701
|
+
hopLength: options.hopLength ?? 256
|
|
702
|
+
});
|
|
703
|
+
const threshold = options.threshold ?? 0.1;
|
|
704
|
+
assertFiniteScalar("analyzeMelody", threshold, "threshold");
|
|
705
|
+
if (threshold <= 0) {
|
|
706
|
+
throw new SonareError(
|
|
707
|
+
4 /* InvalidParameter */,
|
|
708
|
+
"InvalidParameter",
|
|
709
|
+
"analyzeMelody: threshold must be positive"
|
|
710
|
+
);
|
|
711
|
+
}
|
|
712
|
+
return requireModule2().analyzeMelody(
|
|
713
|
+
samples,
|
|
714
|
+
sampleRate,
|
|
715
|
+
options.fmin ?? 65,
|
|
716
|
+
options.fmax ?? 2093,
|
|
717
|
+
options.frameLength ?? 2048,
|
|
718
|
+
options.hopLength ?? 256,
|
|
719
|
+
options.threshold ?? 0.1,
|
|
720
|
+
options.usePyin ?? false,
|
|
721
|
+
options.center ?? true
|
|
722
|
+
);
|
|
723
|
+
}
|
|
724
|
+
function onsetEnvelope(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, nMels = 128, options = {}) {
|
|
725
|
+
if (!(samples instanceof Float32Array)) {
|
|
726
|
+
const request = samples;
|
|
727
|
+
return onsetEnvelope(
|
|
728
|
+
request.samples,
|
|
729
|
+
request.sampleRate,
|
|
730
|
+
request.nFft,
|
|
731
|
+
request.hopLength,
|
|
732
|
+
request.nMels,
|
|
733
|
+
request
|
|
734
|
+
);
|
|
735
|
+
}
|
|
736
|
+
validateMusicSamples("onsetEnvelope", samples, sampleRate, options);
|
|
737
|
+
validatePositiveIntegers("onsetEnvelope", { nFft, hopLength, nMels });
|
|
738
|
+
return requireModule2().onsetEnvelope(samples, sampleRate, nFft, hopLength, nMels);
|
|
739
|
+
}
|
|
740
|
+
function onsetStrengthMulti(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, nMels = 128, nBands = 3, options = {}) {
|
|
741
|
+
if (!(samples instanceof Float32Array)) {
|
|
742
|
+
const request = samples;
|
|
743
|
+
return onsetStrengthMulti(
|
|
744
|
+
request.samples,
|
|
745
|
+
request.sampleRate,
|
|
746
|
+
request.nFft,
|
|
747
|
+
request.hopLength,
|
|
748
|
+
request.nMels,
|
|
749
|
+
request.nBands,
|
|
750
|
+
request
|
|
751
|
+
);
|
|
752
|
+
}
|
|
753
|
+
validateMusicSamples("onsetStrengthMulti", samples, sampleRate, options);
|
|
754
|
+
validatePositiveIntegers("onsetStrengthMulti", { nFft, hopLength, nMels, nBands });
|
|
755
|
+
return requireModule2().onsetStrengthMulti(samples, sampleRate, nFft, hopLength, nMels, nBands);
|
|
756
|
+
}
|
|
757
|
+
function fourierTempogram(onsetEnvelope2, sampleRate = 22050, hopLength = 512, winLength = 384, center = true, norm = true, options = {}) {
|
|
758
|
+
if (!(onsetEnvelope2 instanceof Float32Array)) {
|
|
759
|
+
const request = onsetEnvelope2;
|
|
760
|
+
return fourierTempogram(
|
|
761
|
+
request.onsetEnvelope,
|
|
762
|
+
request.sampleRate,
|
|
763
|
+
request.hopLength,
|
|
764
|
+
request.winLength,
|
|
765
|
+
request.center,
|
|
766
|
+
request.norm,
|
|
767
|
+
request
|
|
768
|
+
);
|
|
769
|
+
}
|
|
770
|
+
assertSampleRate("fourierTempogram", sampleRate);
|
|
771
|
+
assertSamples("fourierTempogram", onsetEnvelope2, options.validate !== false, "onsetEnvelope");
|
|
772
|
+
validatePositiveIntegers("fourierTempogram", { hopLength, winLength });
|
|
773
|
+
return requireModule2().fourierTempogram(
|
|
774
|
+
onsetEnvelope2,
|
|
775
|
+
sampleRate,
|
|
776
|
+
hopLength,
|
|
777
|
+
winLength,
|
|
778
|
+
center,
|
|
779
|
+
norm
|
|
780
|
+
);
|
|
781
|
+
}
|
|
782
|
+
function tempogramRatio(tempogramData, winLength = 384, sampleRate = 22050, hopLength = 512, factors, options = {}) {
|
|
783
|
+
if (!(tempogramData instanceof Float32Array)) {
|
|
784
|
+
const request = tempogramData;
|
|
785
|
+
return tempogramRatio(
|
|
786
|
+
request.tempogramData,
|
|
787
|
+
request.winLength,
|
|
788
|
+
request.sampleRate,
|
|
789
|
+
request.hopLength,
|
|
790
|
+
request.factors,
|
|
791
|
+
request
|
|
792
|
+
);
|
|
793
|
+
}
|
|
794
|
+
assertSampleRate("tempogramRatio", sampleRate);
|
|
795
|
+
assertSamples("tempogramRatio", tempogramData, options.validate !== false, "tempogramData");
|
|
796
|
+
validatePositiveIntegers("tempogramRatio", { winLength, hopLength });
|
|
797
|
+
return requireModule2().tempogramRatio(tempogramData, winLength, sampleRate, hopLength, factors);
|
|
798
|
+
}
|
|
799
|
+
function lufs(samples, sampleRate = 22050, options = {}) {
|
|
800
|
+
if (!(samples instanceof Float32Array)) {
|
|
801
|
+
const r = samples;
|
|
802
|
+
return lufs(r.samples, r.sampleRate, r);
|
|
803
|
+
}
|
|
804
|
+
assertSampleRate("lufs", sampleRate);
|
|
805
|
+
assertSamples("lufs", samples, options.validate !== false);
|
|
806
|
+
return requireModule2().lufs(samples, sampleRate);
|
|
807
|
+
}
|
|
808
|
+
function momentaryLufs(samples, sampleRate = 22050, options = {}) {
|
|
809
|
+
if (!(samples instanceof Float32Array)) {
|
|
810
|
+
const r = samples;
|
|
811
|
+
return momentaryLufs(r.samples, r.sampleRate, r);
|
|
812
|
+
}
|
|
813
|
+
assertSampleRate("momentaryLufs", sampleRate);
|
|
814
|
+
assertSamples("momentaryLufs", samples, options.validate !== false);
|
|
815
|
+
return requireModule2().momentaryLufs(samples, sampleRate);
|
|
816
|
+
}
|
|
817
|
+
function shortTermLufs(samples, sampleRate = 22050, options = {}) {
|
|
818
|
+
if (!(samples instanceof Float32Array)) {
|
|
819
|
+
const r = samples;
|
|
820
|
+
return shortTermLufs(r.samples, r.sampleRate, r);
|
|
821
|
+
}
|
|
822
|
+
assertSampleRate("shortTermLufs", sampleRate);
|
|
823
|
+
assertSamples("shortTermLufs", samples, options.validate !== false);
|
|
824
|
+
return requireModule2().shortTermLufs(samples, sampleRate);
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
// src/feature_pitch.ts
|
|
828
|
+
function requireModule3() {
|
|
829
|
+
return getSonareModule();
|
|
830
|
+
}
|
|
831
|
+
function piptrack(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, fmin = 150, fmax = 4e3, threshold = 0.1) {
|
|
832
|
+
if (!(samples instanceof Float32Array)) {
|
|
833
|
+
const request = samples;
|
|
834
|
+
return piptrack(
|
|
835
|
+
request.samples,
|
|
836
|
+
request.sampleRate,
|
|
837
|
+
request.nFft,
|
|
838
|
+
request.hopLength,
|
|
839
|
+
request.fmin,
|
|
840
|
+
request.fmax,
|
|
841
|
+
request.threshold
|
|
842
|
+
);
|
|
843
|
+
}
|
|
844
|
+
return requireModule3().piptrack(samples, sampleRate, nFft, hopLength, fmin, fmax, threshold);
|
|
845
|
+
}
|
|
846
|
+
function pitchYin(samples, sampleRate = 22050, frameLength = 2048, hopLength = 512, fmin = 65, fmax = 2093, threshold = 0.1, fillNa = false) {
|
|
847
|
+
if (!(samples instanceof Float32Array)) {
|
|
848
|
+
const request = samples;
|
|
849
|
+
return pitchYin(
|
|
850
|
+
request.samples,
|
|
851
|
+
request.sampleRate,
|
|
852
|
+
request.frameLength,
|
|
853
|
+
request.hopLength,
|
|
854
|
+
request.fmin,
|
|
855
|
+
request.fmax,
|
|
856
|
+
request.threshold,
|
|
857
|
+
request.fillNa
|
|
858
|
+
);
|
|
859
|
+
}
|
|
860
|
+
return requireModule3().pitchYin(
|
|
861
|
+
samples,
|
|
862
|
+
sampleRate,
|
|
863
|
+
frameLength,
|
|
864
|
+
hopLength,
|
|
865
|
+
fmin,
|
|
866
|
+
fmax,
|
|
867
|
+
threshold,
|
|
868
|
+
fillNa
|
|
869
|
+
);
|
|
870
|
+
}
|
|
871
|
+
function pitchPyin(samples, sampleRate = 22050, frameLength = 2048, hopLength = 512, fmin = 65, fmax = 2093, threshold = 0.1, fillNa = false) {
|
|
872
|
+
if (!(samples instanceof Float32Array)) {
|
|
873
|
+
const request = samples;
|
|
874
|
+
return pitchPyin(
|
|
875
|
+
request.samples,
|
|
876
|
+
request.sampleRate,
|
|
877
|
+
request.frameLength,
|
|
878
|
+
request.hopLength,
|
|
879
|
+
request.fmin,
|
|
880
|
+
request.fmax,
|
|
881
|
+
request.threshold,
|
|
882
|
+
request.fillNa
|
|
883
|
+
);
|
|
884
|
+
}
|
|
885
|
+
return requireModule3().pitchPyin(
|
|
886
|
+
samples,
|
|
887
|
+
sampleRate,
|
|
888
|
+
frameLength,
|
|
889
|
+
hopLength,
|
|
890
|
+
fmin,
|
|
891
|
+
fmax,
|
|
892
|
+
threshold,
|
|
893
|
+
fillNa
|
|
894
|
+
);
|
|
895
|
+
}
|
|
896
|
+
function noteSegments(request) {
|
|
897
|
+
return requireModule3().noteSegments(request.f0Hz, request.voicedProb, request.frameRate, {
|
|
898
|
+
segmentationThresholdCents: request.segmentationThresholdCents,
|
|
899
|
+
minNoteMs: request.minNoteMs,
|
|
900
|
+
referenceHz: request.referenceHz
|
|
901
|
+
});
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
// src/feature_resample.ts
|
|
905
|
+
function requireModule4() {
|
|
906
|
+
return getSonareModule();
|
|
907
|
+
}
|
|
908
|
+
function resample(samples, srcSr, targetSr) {
|
|
909
|
+
if (!(samples instanceof Float32Array)) {
|
|
910
|
+
return resample(samples.samples, samples.srcSr, samples.targetSr);
|
|
911
|
+
}
|
|
912
|
+
return requireModule4().resample(samples, srcSr, targetSr);
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
// src/feature_spectral.ts
|
|
916
|
+
function requireModule5() {
|
|
917
|
+
return getSonareModule();
|
|
918
|
+
}
|
|
919
|
+
function validateSegmentMatrix(fnName, data, rows, cols, dataName) {
|
|
920
|
+
assertPositiveInteger(fnName, rows, "rows");
|
|
921
|
+
assertPositiveInteger(fnName, cols, "cols");
|
|
922
|
+
assertSamples(fnName, data, true, dataName);
|
|
923
|
+
const expected = rows * cols;
|
|
924
|
+
if (!Number.isSafeInteger(expected) || data.length !== expected) {
|
|
925
|
+
throw new RangeError(`${fnName}: ${dataName} length must equal rows * cols`);
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
function spectralCentroid(samples, sampleRate = 22050, nFft = 2048, hopLength = 512) {
|
|
929
|
+
if (!(samples instanceof Float32Array)) {
|
|
930
|
+
return spectralCentroid(samples.samples, samples.sampleRate, samples.nFft, samples.hopLength);
|
|
931
|
+
}
|
|
932
|
+
return requireModule5().spectralCentroid(samples, sampleRate, nFft, hopLength);
|
|
933
|
+
}
|
|
934
|
+
function spectralContrast(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, nBands = 6, fmin = 200, quantile = 0.02) {
|
|
935
|
+
if (!(samples instanceof Float32Array)) {
|
|
936
|
+
const r = samples;
|
|
937
|
+
return spectralContrast(
|
|
938
|
+
r.samples,
|
|
939
|
+
r.sampleRate,
|
|
940
|
+
r.nFft,
|
|
941
|
+
r.hopLength,
|
|
942
|
+
r.nBands,
|
|
943
|
+
r.fmin,
|
|
944
|
+
r.quantile
|
|
945
|
+
);
|
|
946
|
+
}
|
|
947
|
+
return requireModule5().spectralContrast(
|
|
948
|
+
samples,
|
|
949
|
+
sampleRate,
|
|
950
|
+
nFft,
|
|
951
|
+
hopLength,
|
|
952
|
+
nBands,
|
|
953
|
+
fmin,
|
|
954
|
+
quantile
|
|
955
|
+
);
|
|
956
|
+
}
|
|
957
|
+
function polyFeatures(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, order = 1) {
|
|
958
|
+
if (!(samples instanceof Float32Array)) {
|
|
959
|
+
const r = samples;
|
|
960
|
+
return polyFeatures(r.samples, r.sampleRate, r.nFft, r.hopLength, r.order);
|
|
961
|
+
}
|
|
962
|
+
return requireModule5().polyFeatures(samples, sampleRate, nFft, hopLength, order);
|
|
963
|
+
}
|
|
964
|
+
function zeroCrossings(samples, threshold = 1e-10, refMagnitude = false, pad = true, zeroPos = true) {
|
|
965
|
+
if (!(samples instanceof Float32Array)) {
|
|
966
|
+
const r = samples;
|
|
967
|
+
return zeroCrossings(r.samples, r.threshold, r.refMagnitude, r.pad, r.zeroPos);
|
|
968
|
+
}
|
|
969
|
+
return requireModule5().zeroCrossings(samples, threshold, refMagnitude, pad, zeroPos);
|
|
970
|
+
}
|
|
971
|
+
function pitchTuning(frequencies, resolution = 0.01, binsPerOctave = 12) {
|
|
972
|
+
if (!(frequencies instanceof Float32Array)) {
|
|
973
|
+
const r = frequencies;
|
|
974
|
+
return pitchTuning(r.frequencies, r.resolution, r.binsPerOctave);
|
|
975
|
+
}
|
|
976
|
+
return requireModule5().pitchTuning(frequencies, resolution, binsPerOctave);
|
|
977
|
+
}
|
|
978
|
+
function estimateTuning(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, resolution = 0.01, binsPerOctave = 12) {
|
|
979
|
+
if (!(samples instanceof Float32Array)) {
|
|
980
|
+
const r = samples;
|
|
981
|
+
return estimateTuning(
|
|
982
|
+
r.samples,
|
|
983
|
+
r.sampleRate,
|
|
984
|
+
r.nFft,
|
|
985
|
+
r.hopLength,
|
|
986
|
+
r.resolution,
|
|
987
|
+
r.binsPerOctave
|
|
988
|
+
);
|
|
989
|
+
}
|
|
990
|
+
return requireModule5().estimateTuning(
|
|
991
|
+
samples,
|
|
992
|
+
sampleRate,
|
|
993
|
+
nFft,
|
|
994
|
+
hopLength,
|
|
995
|
+
resolution,
|
|
996
|
+
binsPerOctave
|
|
997
|
+
);
|
|
998
|
+
}
|
|
999
|
+
function decompose(s, nFeatures = 0, nFrames = 0, nComponents = 0, nIter = 50, beta = 2) {
|
|
1000
|
+
if (!(s instanceof Float32Array)) {
|
|
1001
|
+
const request = s;
|
|
1002
|
+
return decompose(
|
|
1003
|
+
request.s,
|
|
1004
|
+
request.nFeatures,
|
|
1005
|
+
request.nFrames,
|
|
1006
|
+
request.nComponents,
|
|
1007
|
+
request.nIter,
|
|
1008
|
+
request.beta
|
|
1009
|
+
);
|
|
1010
|
+
}
|
|
1011
|
+
return requireModule5().decompose(s, nFeatures, nFrames, nComponents, nIter, beta);
|
|
1012
|
+
}
|
|
1013
|
+
function decomposeWithInit(s, nFeatures = 0, nFrames = 0, nComponents = 0, nIter = 50, beta = 2, init2 = "random") {
|
|
1014
|
+
if (!(s instanceof Float32Array)) {
|
|
1015
|
+
const request = s;
|
|
1016
|
+
return decomposeWithInit(
|
|
1017
|
+
request.s,
|
|
1018
|
+
request.nFeatures,
|
|
1019
|
+
request.nFrames,
|
|
1020
|
+
request.nComponents,
|
|
1021
|
+
request.nIter,
|
|
1022
|
+
request.beta,
|
|
1023
|
+
request.init
|
|
1024
|
+
);
|
|
1025
|
+
}
|
|
1026
|
+
return requireModule5().decomposeWithInit(s, nFeatures, nFrames, nComponents, nIter, beta, init2);
|
|
1027
|
+
}
|
|
1028
|
+
function nnFilter(s, nFeatures = 0, nFrames = 0, aggregate = "mean", k = 7, width = 1) {
|
|
1029
|
+
if (!(s instanceof Float32Array)) {
|
|
1030
|
+
const r = s;
|
|
1031
|
+
return nnFilter(r.s, r.nFeatures, r.nFrames, r.aggregate, r.k, r.width);
|
|
1032
|
+
}
|
|
1033
|
+
return requireModule5().nnFilter(s, nFeatures, nFrames, aggregate, k, width);
|
|
1034
|
+
}
|
|
1035
|
+
function remix(samples, intervals, sampleRate = 22050, alignZeros = false) {
|
|
1036
|
+
if (!(samples instanceof Float32Array)) {
|
|
1037
|
+
const r = samples;
|
|
1038
|
+
return remix(r.samples, r.intervals, r.sampleRate, r.alignZeros);
|
|
1039
|
+
}
|
|
1040
|
+
const intervalsI32 = intervals instanceof Int32Array ? intervals : Int32Array.from(intervals, (v) => Math.trunc(v));
|
|
1041
|
+
return requireModule5().remix(samples, intervalsI32, sampleRate, alignZeros);
|
|
1042
|
+
}
|
|
1043
|
+
function phaseVocoder(samples, sampleRate = 22050, rate = 1, nFft = 2048, hopLength = 512) {
|
|
1044
|
+
if (!(samples instanceof Float32Array)) {
|
|
1045
|
+
const r = samples;
|
|
1046
|
+
return phaseVocoder(r.samples, r.sampleRate ?? 22050, r.rate, r.nFft, r.hopLength);
|
|
1047
|
+
}
|
|
1048
|
+
return requireModule5().phaseVocoder(samples, sampleRate, rate, nFft, hopLength);
|
|
1049
|
+
}
|
|
1050
|
+
function hpssWithResidual(samples, sampleRate = 22050, kernelHarmonic = 31, kernelPercussive = 31) {
|
|
1051
|
+
if (!(samples instanceof Float32Array)) {
|
|
1052
|
+
const r = samples;
|
|
1053
|
+
return hpssWithResidual(r.samples, r.sampleRate, r.kernelHarmonic, r.kernelPercussive);
|
|
1054
|
+
}
|
|
1055
|
+
return requireModule5().hpssWithResidual(samples, sampleRate, kernelHarmonic, kernelPercussive);
|
|
1056
|
+
}
|
|
1057
|
+
function lufsInterleaved(samples, channels = 0, sampleRate = 22050, options = {}) {
|
|
1058
|
+
if (!(samples instanceof Float32Array)) {
|
|
1059
|
+
const r = samples;
|
|
1060
|
+
return lufsInterleaved(r.samples, r.channels, r.sampleRate, r);
|
|
1061
|
+
}
|
|
1062
|
+
assertSampleRate("lufsInterleaved", sampleRate);
|
|
1063
|
+
assertInterleavedSamples("lufsInterleaved", samples, channels, options.validate !== false);
|
|
1064
|
+
return requireModule5().lufsInterleaved(samples, channels, sampleRate);
|
|
1065
|
+
}
|
|
1066
|
+
function ebur128LoudnessRange(samples, sampleRate = 22050) {
|
|
1067
|
+
if (!(samples instanceof Float32Array)) {
|
|
1068
|
+
return ebur128LoudnessRange(samples.samples, samples.sampleRate);
|
|
1069
|
+
}
|
|
1070
|
+
return requireModule5().ebur128LoudnessRange(samples, sampleRate);
|
|
1071
|
+
}
|
|
1072
|
+
function spectralBandwidth(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, p = 2) {
|
|
1073
|
+
if (!(samples instanceof Float32Array)) {
|
|
1074
|
+
return spectralBandwidth(
|
|
1075
|
+
samples.samples,
|
|
1076
|
+
samples.sampleRate,
|
|
1077
|
+
samples.nFft,
|
|
1078
|
+
samples.hopLength,
|
|
1079
|
+
samples.p
|
|
1080
|
+
);
|
|
1081
|
+
}
|
|
1082
|
+
return requireModule5().spectralBandwidth(samples, sampleRate, nFft, hopLength, p);
|
|
1083
|
+
}
|
|
1084
|
+
function spectralRolloff(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, rollPercent = 0.85) {
|
|
1085
|
+
if (!(samples instanceof Float32Array)) {
|
|
1086
|
+
return spectralRolloff(
|
|
1087
|
+
samples.samples,
|
|
1088
|
+
samples.sampleRate,
|
|
1089
|
+
samples.nFft,
|
|
1090
|
+
samples.hopLength,
|
|
1091
|
+
samples.rollPercent
|
|
1092
|
+
);
|
|
1093
|
+
}
|
|
1094
|
+
return requireModule5().spectralRolloff(samples, sampleRate, nFft, hopLength, rollPercent);
|
|
1095
|
+
}
|
|
1096
|
+
function spectralFlatness(samples, sampleRate = 22050, nFft = 2048, hopLength = 512) {
|
|
1097
|
+
if (!(samples instanceof Float32Array)) {
|
|
1098
|
+
return spectralFlatness(samples.samples, samples.sampleRate, samples.nFft, samples.hopLength);
|
|
1099
|
+
}
|
|
1100
|
+
return requireModule5().spectralFlatness(samples, sampleRate, nFft, hopLength);
|
|
1101
|
+
}
|
|
1102
|
+
function spectralFlux(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, lag = 1) {
|
|
1103
|
+
if (!(samples instanceof Float32Array)) {
|
|
1104
|
+
return spectralFlux(
|
|
1105
|
+
samples.samples,
|
|
1106
|
+
samples.sampleRate,
|
|
1107
|
+
samples.nFft,
|
|
1108
|
+
samples.hopLength,
|
|
1109
|
+
samples.lag
|
|
1110
|
+
);
|
|
1111
|
+
}
|
|
1112
|
+
return requireModule5().spectralFlux(samples, sampleRate, nFft, hopLength, lag);
|
|
1113
|
+
}
|
|
1114
|
+
function zeroCrossingRate(samples, sampleRate = 22050, frameLength = 2048, hopLength = 512) {
|
|
1115
|
+
if (!(samples instanceof Float32Array)) {
|
|
1116
|
+
return zeroCrossingRate(
|
|
1117
|
+
samples.samples,
|
|
1118
|
+
samples.sampleRate,
|
|
1119
|
+
samples.frameLength,
|
|
1120
|
+
samples.hopLength
|
|
1121
|
+
);
|
|
1122
|
+
}
|
|
1123
|
+
return requireModule5().zeroCrossingRate(samples, sampleRate, frameLength, hopLength);
|
|
1124
|
+
}
|
|
1125
|
+
function rmsEnergy(samples, sampleRate = 22050, frameLength = 2048, hopLength = 512) {
|
|
1126
|
+
if (!(samples instanceof Float32Array)) {
|
|
1127
|
+
return rmsEnergy(samples.samples, samples.sampleRate, samples.frameLength, samples.hopLength);
|
|
1128
|
+
}
|
|
1129
|
+
return requireModule5().rmsEnergy(samples, sampleRate, frameLength, hopLength);
|
|
1130
|
+
}
|
|
1131
|
+
function segmentCrossSimilarity(request) {
|
|
1132
|
+
validateSegmentMatrix("segmentCrossSimilarity", request.x, request.xRows, request.xCols, "x");
|
|
1133
|
+
validateSegmentMatrix("segmentCrossSimilarity", request.y, request.yRows, request.yCols, "y");
|
|
1134
|
+
if (request.xRows !== request.yRows) {
|
|
1135
|
+
throw new RangeError("segmentCrossSimilarity: feature dimensions must match");
|
|
1136
|
+
}
|
|
1137
|
+
assertNonNegativeInteger("segmentCrossSimilarity", request.k ?? 0, "k");
|
|
1138
|
+
return requireModule5().segmentCrossSimilarity(
|
|
1139
|
+
request.x,
|
|
1140
|
+
request.xRows,
|
|
1141
|
+
request.xCols,
|
|
1142
|
+
request.y,
|
|
1143
|
+
request.yRows,
|
|
1144
|
+
request.yCols,
|
|
1145
|
+
request.k ?? 0,
|
|
1146
|
+
request.metric ?? "cosine",
|
|
1147
|
+
request.mode ?? "connectivity"
|
|
1148
|
+
);
|
|
1149
|
+
}
|
|
1150
|
+
function segmentRecurrenceMatrix(request) {
|
|
1151
|
+
validateSegmentMatrix(
|
|
1152
|
+
"segmentRecurrenceMatrix",
|
|
1153
|
+
request.data,
|
|
1154
|
+
request.rows,
|
|
1155
|
+
request.cols,
|
|
1156
|
+
"data"
|
|
1157
|
+
);
|
|
1158
|
+
assertNonNegativeInteger("segmentRecurrenceMatrix", request.k ?? 0, "k");
|
|
1159
|
+
assertNonNegativeInteger("segmentRecurrenceMatrix", request.width ?? 1, "width");
|
|
1160
|
+
return requireModule5().segmentRecurrenceMatrix(
|
|
1161
|
+
request.data,
|
|
1162
|
+
request.rows,
|
|
1163
|
+
request.cols,
|
|
1164
|
+
request.k ?? 0,
|
|
1165
|
+
request.width ?? 1,
|
|
1166
|
+
request.sym ?? false,
|
|
1167
|
+
request.metric ?? "euclidean",
|
|
1168
|
+
request.mode ?? "connectivity"
|
|
1169
|
+
);
|
|
1170
|
+
}
|
|
1171
|
+
function segmentRecurrenceToLag(request) {
|
|
1172
|
+
validateSegmentMatrix(
|
|
1173
|
+
"segmentRecurrenceToLag",
|
|
1174
|
+
request.recurrence,
|
|
1175
|
+
request.n,
|
|
1176
|
+
request.n,
|
|
1177
|
+
"recurrence"
|
|
1178
|
+
);
|
|
1179
|
+
return requireModule5().segmentRecurrenceToLag(
|
|
1180
|
+
request.recurrence,
|
|
1181
|
+
request.n,
|
|
1182
|
+
request.pad ?? false
|
|
1183
|
+
);
|
|
1184
|
+
}
|
|
1185
|
+
function segmentLagToRecurrence(request) {
|
|
1186
|
+
validateSegmentMatrix("segmentLagToRecurrence", request.lag, request.rows, request.lags, "lag");
|
|
1187
|
+
return requireModule5().segmentLagToRecurrence(request.lag, request.rows, request.lags);
|
|
1188
|
+
}
|
|
1189
|
+
function segmentSubsegment(request) {
|
|
1190
|
+
validateSegmentMatrix("segmentSubsegment", request.data, request.rows, request.cols, "data");
|
|
1191
|
+
assertPositiveInteger("segmentSubsegment", request.nSegments ?? 4, "nSegments");
|
|
1192
|
+
return requireModule5().segmentSubsegment(
|
|
1193
|
+
request.data,
|
|
1194
|
+
request.rows,
|
|
1195
|
+
request.cols,
|
|
1196
|
+
request.boundaries,
|
|
1197
|
+
request.nSegments ?? 4
|
|
1198
|
+
);
|
|
1199
|
+
}
|
|
1200
|
+
function segmentAgglomerative(request) {
|
|
1201
|
+
validateSegmentMatrix("segmentAgglomerative", request.data, request.rows, request.cols, "data");
|
|
1202
|
+
assertPositiveInteger("segmentAgglomerative", request.k, "k");
|
|
1203
|
+
return requireModule5().segmentAgglomerative(
|
|
1204
|
+
request.data,
|
|
1205
|
+
request.rows,
|
|
1206
|
+
request.cols,
|
|
1207
|
+
request.k,
|
|
1208
|
+
request.linkage ?? "average"
|
|
1209
|
+
);
|
|
1210
|
+
}
|
|
1211
|
+
function segmentPathEnhance(request) {
|
|
1212
|
+
validateSegmentMatrix(
|
|
1213
|
+
"segmentPathEnhance",
|
|
1214
|
+
request.recurrence,
|
|
1215
|
+
request.n,
|
|
1216
|
+
request.n,
|
|
1217
|
+
"recurrence"
|
|
1218
|
+
);
|
|
1219
|
+
assertPositiveInteger("segmentPathEnhance", request.win, "win");
|
|
1220
|
+
assertPositiveInteger("segmentPathEnhance", request.maxRatio ?? 2, "maxRatio");
|
|
1221
|
+
assertNonNegativeInteger("segmentPathEnhance", request.minRatio ?? 0, "minRatio");
|
|
1222
|
+
assertPositiveInteger("segmentPathEnhance", request.nFilters ?? 7, "nFilters");
|
|
1223
|
+
return requireModule5().segmentPathEnhance(
|
|
1224
|
+
request.recurrence,
|
|
1225
|
+
request.n,
|
|
1226
|
+
request.win,
|
|
1227
|
+
request.maxRatio ?? 2,
|
|
1228
|
+
request.minRatio ?? 0,
|
|
1229
|
+
request.nFilters ?? 7
|
|
1230
|
+
);
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
// src/feature_spectrogram.ts
|
|
1234
|
+
function requireModule6() {
|
|
1235
|
+
return getSonareModule();
|
|
1236
|
+
}
|
|
1237
|
+
function validateSpectrogramSamples(fnName, samples, sampleRate, options = {}) {
|
|
1238
|
+
assertSampleRate(fnName, sampleRate);
|
|
1239
|
+
assertSamples(fnName, samples, options.validate !== false);
|
|
1240
|
+
}
|
|
1241
|
+
function validatePositiveIntegers2(fnName, values) {
|
|
1242
|
+
for (const [name, value] of Object.entries(values)) {
|
|
1243
|
+
assertPositiveInteger(fnName, value, name);
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
function validateMelFrequencyRange(fnName, fmin, fmax, sampleRate) {
|
|
1247
|
+
assertFiniteScalar(fnName, fmin, "fmin");
|
|
1248
|
+
assertFiniteScalar(fnName, fmax, "fmax");
|
|
1249
|
+
if (fmin < 0) {
|
|
1250
|
+
throw new RangeError(`${fnName}: fmin must be non-negative`);
|
|
1251
|
+
}
|
|
1252
|
+
if (fmax < 0) {
|
|
1253
|
+
throw new RangeError(`${fnName}: fmax must be non-negative`);
|
|
1254
|
+
}
|
|
1255
|
+
const effectiveFmax = fmax === 0 ? sampleRate / 2 : fmax;
|
|
1256
|
+
if (effectiveFmax <= fmin) {
|
|
1257
|
+
throw new RangeError(`${fnName}: fmax must be greater than fmin`);
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
function validateMatrix(fnName, data, rows, frames, dataName, rowName, options = {}) {
|
|
1261
|
+
validatePositiveIntegers2(fnName, { [rowName]: rows, nFrames: frames });
|
|
1262
|
+
assertSamples(fnName, data, options.validate !== false, dataName);
|
|
1263
|
+
const expectedLength = rows * frames;
|
|
1264
|
+
if (!Number.isSafeInteger(expectedLength) || data.length !== expectedLength) {
|
|
1265
|
+
throw new RangeError(`${fnName}: ${dataName} length must equal ${rowName} * nFrames`);
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
function trim(samples, sampleRate = 22050, thresholdDb = -60, options = {}) {
|
|
1269
|
+
if (!(samples instanceof Float32Array)) {
|
|
1270
|
+
const r = samples;
|
|
1271
|
+
return trim(r.samples, r.sampleRate, r.thresholdDb, r);
|
|
1272
|
+
}
|
|
1273
|
+
validateSpectrogramSamples("trim", samples, sampleRate, options);
|
|
1274
|
+
assertFiniteScalar("trim", thresholdDb, "thresholdDb");
|
|
1275
|
+
return requireModule6().trim(samples, sampleRate, thresholdDb);
|
|
1276
|
+
}
|
|
1277
|
+
function stft(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, options = {}) {
|
|
1278
|
+
if (!(samples instanceof Float32Array)) {
|
|
1279
|
+
const request = samples;
|
|
1280
|
+
return stft(request.samples, request.sampleRate, request.nFft, request.hopLength, request);
|
|
1281
|
+
}
|
|
1282
|
+
validateSpectrogramSamples("stft", samples, sampleRate, options);
|
|
1283
|
+
validatePositiveIntegers2("stft", { nFft, hopLength });
|
|
1284
|
+
return requireModule6().stft(samples, sampleRate, nFft, hopLength);
|
|
1285
|
+
}
|
|
1286
|
+
function stftDb(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, options = {}) {
|
|
1287
|
+
if (!(samples instanceof Float32Array)) {
|
|
1288
|
+
const request = samples;
|
|
1289
|
+
return stftDb(request.samples, request.sampleRate, request.nFft, request.hopLength, request);
|
|
1290
|
+
}
|
|
1291
|
+
validateSpectrogramSamples("stftDb", samples, sampleRate, options);
|
|
1292
|
+
validatePositiveIntegers2("stftDb", { nFft, hopLength });
|
|
1293
|
+
return requireModule6().stftDb(samples, sampleRate, nFft, hopLength);
|
|
1294
|
+
}
|
|
1295
|
+
function chromaCens(samples, sampleRate = 22050, hopLength = 512, nChroma = 12, binsPerOctave = 36, options = {}) {
|
|
1296
|
+
if (!(samples instanceof Float32Array)) {
|
|
1297
|
+
const request = samples;
|
|
1298
|
+
return chromaCens(
|
|
1299
|
+
request.samples,
|
|
1300
|
+
request.sampleRate,
|
|
1301
|
+
request.hopLength,
|
|
1302
|
+
request.nChroma,
|
|
1303
|
+
request.binsPerOctave,
|
|
1304
|
+
request
|
|
1305
|
+
);
|
|
1306
|
+
}
|
|
1307
|
+
validateSpectrogramSamples("chromaCens", samples, sampleRate, options);
|
|
1308
|
+
validatePositiveIntegers2("chromaCens", { hopLength, nChroma, binsPerOctave });
|
|
1309
|
+
if (binsPerOctave % nChroma !== 0) {
|
|
1310
|
+
throw new RangeError("chromaCens: binsPerOctave must be a multiple of nChroma");
|
|
1311
|
+
}
|
|
1312
|
+
return requireModule6().chromaCens(samples, sampleRate, hopLength, nChroma, binsPerOctave);
|
|
1313
|
+
}
|
|
1314
|
+
function chromaCqt(samples, sampleRate = 22050, hopLength = 512, nChroma = 12, binsPerOctave = 36, options = {}) {
|
|
1315
|
+
if (!(samples instanceof Float32Array)) {
|
|
1316
|
+
const request = samples;
|
|
1317
|
+
return chromaCqt(
|
|
1318
|
+
request.samples,
|
|
1319
|
+
request.sampleRate,
|
|
1320
|
+
request.hopLength,
|
|
1321
|
+
request.nChroma,
|
|
1322
|
+
request.binsPerOctave,
|
|
1323
|
+
request
|
|
1324
|
+
);
|
|
1325
|
+
}
|
|
1326
|
+
validateSpectrogramSamples("chromaCqt", samples, sampleRate, options);
|
|
1327
|
+
validatePositiveIntegers2("chromaCqt", { hopLength, nChroma, binsPerOctave });
|
|
1328
|
+
if (binsPerOctave % nChroma !== 0) {
|
|
1329
|
+
throw new RangeError("chromaCqt: binsPerOctave must be a multiple of nChroma");
|
|
1330
|
+
}
|
|
1331
|
+
return requireModule6().chromaCqt(samples, sampleRate, hopLength, nChroma, binsPerOctave);
|
|
1332
|
+
}
|
|
1333
|
+
function bassChroma(samples, sampleRate = 22050, hopLength = 512, nChroma = 12, options = {}) {
|
|
1334
|
+
if (!(samples instanceof Float32Array)) {
|
|
1335
|
+
const request = samples;
|
|
1336
|
+
return bassChroma(
|
|
1337
|
+
request.samples,
|
|
1338
|
+
request.sampleRate,
|
|
1339
|
+
request.hopLength,
|
|
1340
|
+
request.nChroma,
|
|
1341
|
+
request
|
|
1342
|
+
);
|
|
1343
|
+
}
|
|
1344
|
+
validateSpectrogramSamples("bassChroma", samples, sampleRate, options);
|
|
1345
|
+
validatePositiveIntegers2("bassChroma", { hopLength, nChroma });
|
|
1346
|
+
return requireModule6().bassChroma(samples, sampleRate, hopLength, nChroma);
|
|
1347
|
+
}
|
|
1348
|
+
function melSpectrogram(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, nMels = 128, fmin = 0, fmax = 0, htk = false, options = {}) {
|
|
1349
|
+
if (!(samples instanceof Float32Array)) {
|
|
1350
|
+
const request = samples;
|
|
1351
|
+
return melSpectrogram(
|
|
1352
|
+
request.samples,
|
|
1353
|
+
request.sampleRate,
|
|
1354
|
+
request.nFft,
|
|
1355
|
+
request.hopLength,
|
|
1356
|
+
request.nMels,
|
|
1357
|
+
request.fmin,
|
|
1358
|
+
request.fmax,
|
|
1359
|
+
request.htk,
|
|
1360
|
+
request
|
|
1361
|
+
);
|
|
1362
|
+
}
|
|
1363
|
+
validateSpectrogramSamples("melSpectrogram", samples, sampleRate, options);
|
|
1364
|
+
validatePositiveIntegers2("melSpectrogram", { nFft, hopLength, nMels });
|
|
1365
|
+
validateMelFrequencyRange("melSpectrogram", fmin, fmax, sampleRate);
|
|
1366
|
+
return requireModule6().melSpectrogram(
|
|
1367
|
+
samples,
|
|
1368
|
+
sampleRate,
|
|
1369
|
+
nFft,
|
|
1370
|
+
hopLength,
|
|
1371
|
+
nMels,
|
|
1372
|
+
fmin,
|
|
1373
|
+
fmax,
|
|
1374
|
+
htk
|
|
1375
|
+
);
|
|
1376
|
+
}
|
|
1377
|
+
function mfcc(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, nMels = 128, nMfcc = 20, fmin = 0, fmax = 0, htk = false, lifter = 0, options = {}) {
|
|
1378
|
+
if (!(samples instanceof Float32Array)) {
|
|
1379
|
+
const request = samples;
|
|
1380
|
+
return mfcc(
|
|
1381
|
+
request.samples,
|
|
1382
|
+
request.sampleRate,
|
|
1383
|
+
request.nFft,
|
|
1384
|
+
request.hopLength,
|
|
1385
|
+
request.nMels,
|
|
1386
|
+
request.nMfcc,
|
|
1387
|
+
request.fmin,
|
|
1388
|
+
request.fmax,
|
|
1389
|
+
request.htk,
|
|
1390
|
+
request.lifter,
|
|
1391
|
+
request
|
|
1392
|
+
);
|
|
1393
|
+
}
|
|
1394
|
+
validateSpectrogramSamples("mfcc", samples, sampleRate, options);
|
|
1395
|
+
validatePositiveIntegers2("mfcc", { nFft, hopLength, nMels, nMfcc });
|
|
1396
|
+
validateMelFrequencyRange("mfcc", fmin, fmax, sampleRate);
|
|
1397
|
+
return requireModule6().mfcc(
|
|
1398
|
+
samples,
|
|
1399
|
+
sampleRate,
|
|
1400
|
+
nFft,
|
|
1401
|
+
hopLength,
|
|
1402
|
+
nMels,
|
|
1403
|
+
nMfcc,
|
|
1404
|
+
fmin,
|
|
1405
|
+
fmax,
|
|
1406
|
+
htk,
|
|
1407
|
+
lifter
|
|
1408
|
+
);
|
|
1409
|
+
}
|
|
1410
|
+
function melDelta(features, nFeatures, nFrames, width = 9) {
|
|
1411
|
+
const request = features instanceof Float32Array ? { features, nFeatures: nFeatures ?? 0, nFrames: nFrames ?? 0, width } : features;
|
|
1412
|
+
assertPositiveInteger("melDelta", request.nFeatures, "nFeatures");
|
|
1413
|
+
assertPositiveInteger("melDelta", request.nFrames, "nFrames");
|
|
1414
|
+
assertPositiveInteger("melDelta", request.width ?? 9, "width");
|
|
1415
|
+
if ((request.width ?? 9) < 3 || (request.width ?? 9) % 2 === 0) {
|
|
1416
|
+
throw new RangeError("melDelta: width must be an odd integer of at least 3");
|
|
1417
|
+
}
|
|
1418
|
+
if (request.features.length !== request.nFeatures * request.nFrames) {
|
|
1419
|
+
throw new RangeError("melDelta: feature matrix length must equal nFeatures * nFrames");
|
|
1420
|
+
}
|
|
1421
|
+
return requireModule6().melDelta(
|
|
1422
|
+
request.features,
|
|
1423
|
+
request.nFeatures,
|
|
1424
|
+
request.nFrames,
|
|
1425
|
+
request.width ?? 9
|
|
1426
|
+
);
|
|
1427
|
+
}
|
|
1428
|
+
function reassignedSpectrogram(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, refPower = 1e-6, fillNan = false) {
|
|
1429
|
+
if (!(samples instanceof Float32Array)) {
|
|
1430
|
+
const request = samples;
|
|
1431
|
+
return reassignedSpectrogram(
|
|
1432
|
+
request.samples,
|
|
1433
|
+
request.sampleRate,
|
|
1434
|
+
request.nFft,
|
|
1435
|
+
request.hopLength,
|
|
1436
|
+
request.refPower,
|
|
1437
|
+
request.fillNan
|
|
1438
|
+
);
|
|
1439
|
+
}
|
|
1440
|
+
assertSamples("reassignedSpectrogram", samples, true);
|
|
1441
|
+
assertSampleRate("reassignedSpectrogram", sampleRate);
|
|
1442
|
+
assertPositiveInteger("reassignedSpectrogram", nFft, "nFft");
|
|
1443
|
+
assertPositiveInteger("reassignedSpectrogram", hopLength, "hopLength");
|
|
1444
|
+
assertFiniteScalar("reassignedSpectrogram", refPower, "refPower");
|
|
1445
|
+
if (refPower < 0) {
|
|
1446
|
+
throw new RangeError("reassignedSpectrogram: refPower must be non-negative");
|
|
1447
|
+
}
|
|
1448
|
+
return requireModule6().reassignedSpectrogram(
|
|
1449
|
+
samples,
|
|
1450
|
+
sampleRate,
|
|
1451
|
+
nFft,
|
|
1452
|
+
hopLength,
|
|
1453
|
+
refPower,
|
|
1454
|
+
fillNan
|
|
1455
|
+
);
|
|
1456
|
+
}
|
|
1457
|
+
function melToStft(melPower, nMels = 0, nFrames = 0, sampleRate = 22050, nFft = 2048, fmin = 0, fmax = 0, htk = false, options = {}) {
|
|
1458
|
+
if (!(melPower instanceof Float32Array)) {
|
|
1459
|
+
const request = melPower;
|
|
1460
|
+
return melToStft(
|
|
1461
|
+
request.melPower,
|
|
1462
|
+
request.nMels,
|
|
1463
|
+
request.nFrames,
|
|
1464
|
+
request.sampleRate,
|
|
1465
|
+
request.nFft,
|
|
1466
|
+
request.fmin,
|
|
1467
|
+
request.fmax,
|
|
1468
|
+
request.htk,
|
|
1469
|
+
request
|
|
1470
|
+
);
|
|
1471
|
+
}
|
|
1472
|
+
assertSampleRate("melToStft", sampleRate);
|
|
1473
|
+
validateMatrix("melToStft", melPower, nMels, nFrames, "melPower", "nMels", options);
|
|
1474
|
+
validatePositiveIntegers2("melToStft", { nFft });
|
|
1475
|
+
validateMelFrequencyRange("melToStft", fmin, fmax, sampleRate);
|
|
1476
|
+
return requireModule6().melToStft(melPower, nMels, nFrames, sampleRate, nFft, fmin, fmax, htk);
|
|
1477
|
+
}
|
|
1478
|
+
function melToAudio(melPower, nMels = 0, nFrames = 0, sampleRate = 22050, nFft = 2048, hopLength = 512, fmin = 0, fmax = 0, nIter = 32, htk = false, options = {}) {
|
|
1479
|
+
if (!(melPower instanceof Float32Array)) {
|
|
1480
|
+
const request = melPower;
|
|
1481
|
+
return melToAudio(
|
|
1482
|
+
request.melPower,
|
|
1483
|
+
request.nMels,
|
|
1484
|
+
request.nFrames,
|
|
1485
|
+
request.sampleRate,
|
|
1486
|
+
request.nFft,
|
|
1487
|
+
request.hopLength,
|
|
1488
|
+
request.fmin,
|
|
1489
|
+
request.fmax,
|
|
1490
|
+
request.nIter,
|
|
1491
|
+
request.htk,
|
|
1492
|
+
request
|
|
1493
|
+
);
|
|
1494
|
+
}
|
|
1495
|
+
assertSampleRate("melToAudio", sampleRate);
|
|
1496
|
+
validateMatrix("melToAudio", melPower, nMels, nFrames, "melPower", "nMels", options);
|
|
1497
|
+
validatePositiveIntegers2("melToAudio", { nFft, hopLength, nIter });
|
|
1498
|
+
validateMelFrequencyRange("melToAudio", fmin, fmax, sampleRate);
|
|
1499
|
+
return requireModule6().melToAudio(
|
|
1500
|
+
melPower,
|
|
1501
|
+
nMels,
|
|
1502
|
+
nFrames,
|
|
1503
|
+
sampleRate,
|
|
1504
|
+
nFft,
|
|
1505
|
+
hopLength,
|
|
1506
|
+
fmin,
|
|
1507
|
+
fmax,
|
|
1508
|
+
nIter,
|
|
1509
|
+
htk
|
|
1510
|
+
);
|
|
1511
|
+
}
|
|
1512
|
+
function griffinLim(magnitude, nBins = 0, nFrames = 0, sampleRate = 22050, nFft = 2048, hopLength = 512, nIter = 32, momentum = 0.99, options = {}) {
|
|
1513
|
+
if (!(magnitude instanceof Float32Array)) {
|
|
1514
|
+
const request = magnitude;
|
|
1515
|
+
return griffinLim(
|
|
1516
|
+
request.magnitude,
|
|
1517
|
+
request.nBins,
|
|
1518
|
+
request.nFrames,
|
|
1519
|
+
request.sampleRate,
|
|
1520
|
+
request.nFft,
|
|
1521
|
+
request.hopLength,
|
|
1522
|
+
request.nIter,
|
|
1523
|
+
request.momentum,
|
|
1524
|
+
request
|
|
1525
|
+
);
|
|
1526
|
+
}
|
|
1527
|
+
assertSampleRate("griffinLim", sampleRate);
|
|
1528
|
+
validateMatrix("griffinLim", magnitude, nBins, nFrames, "magnitude", "nBins", options);
|
|
1529
|
+
validatePositiveIntegers2("griffinLim", { nFft, hopLength, nIter });
|
|
1530
|
+
return requireModule6().griffinLim(
|
|
1531
|
+
magnitude,
|
|
1532
|
+
nBins,
|
|
1533
|
+
nFrames,
|
|
1534
|
+
sampleRate,
|
|
1535
|
+
nFft,
|
|
1536
|
+
hopLength,
|
|
1537
|
+
nIter,
|
|
1538
|
+
momentum
|
|
1539
|
+
);
|
|
1540
|
+
}
|
|
1541
|
+
function mfccToMel(mfccCoefficients, nMfcc = 0, nFrames = 0, nMels = 128, lifter = 0, options = {}) {
|
|
1542
|
+
if (!(mfccCoefficients instanceof Float32Array)) {
|
|
1543
|
+
const request = mfccCoefficients;
|
|
1544
|
+
return mfccToMel(
|
|
1545
|
+
request.mfccCoefficients,
|
|
1546
|
+
request.nMfcc,
|
|
1547
|
+
request.nFrames,
|
|
1548
|
+
request.nMels,
|
|
1549
|
+
request.lifter,
|
|
1550
|
+
request
|
|
1551
|
+
);
|
|
1552
|
+
}
|
|
1553
|
+
validateMatrix(
|
|
1554
|
+
"mfccToMel",
|
|
1555
|
+
mfccCoefficients,
|
|
1556
|
+
nMfcc,
|
|
1557
|
+
nFrames,
|
|
1558
|
+
"mfccCoefficients",
|
|
1559
|
+
"nMfcc",
|
|
1560
|
+
options
|
|
1561
|
+
);
|
|
1562
|
+
validatePositiveIntegers2("mfccToMel", { nMels });
|
|
1563
|
+
return requireModule6().mfccToMel(mfccCoefficients, nMfcc, nFrames, nMels, lifter);
|
|
1564
|
+
}
|
|
1565
|
+
function mfccToAudio(mfccCoefficients, nMfcc = 0, nFrames = 0, nMels = 128, sampleRate = 22050, nFft = 2048, hopLength = 512, fmin = 0, fmax = 0, nIter = 32, htk = false, lifter = 0, options = {}) {
|
|
1566
|
+
if (!(mfccCoefficients instanceof Float32Array)) {
|
|
1567
|
+
const request = mfccCoefficients;
|
|
1568
|
+
return mfccToAudio(
|
|
1569
|
+
request.mfccCoefficients,
|
|
1570
|
+
request.nMfcc,
|
|
1571
|
+
request.nFrames,
|
|
1572
|
+
request.nMels,
|
|
1573
|
+
request.sampleRate,
|
|
1574
|
+
request.nFft,
|
|
1575
|
+
request.hopLength,
|
|
1576
|
+
request.fmin,
|
|
1577
|
+
request.fmax,
|
|
1578
|
+
request.nIter,
|
|
1579
|
+
request.htk,
|
|
1580
|
+
request.lifter,
|
|
1581
|
+
request
|
|
1582
|
+
);
|
|
1583
|
+
}
|
|
1584
|
+
assertSampleRate("mfccToAudio", sampleRate);
|
|
1585
|
+
validateMatrix(
|
|
1586
|
+
"mfccToAudio",
|
|
1587
|
+
mfccCoefficients,
|
|
1588
|
+
nMfcc,
|
|
1589
|
+
nFrames,
|
|
1590
|
+
"mfccCoefficients",
|
|
1591
|
+
"nMfcc",
|
|
1592
|
+
options
|
|
1593
|
+
);
|
|
1594
|
+
validatePositiveIntegers2("mfccToAudio", { nMels, nFft, hopLength, nIter });
|
|
1595
|
+
validateMelFrequencyRange("mfccToAudio", fmin, fmax, sampleRate);
|
|
1596
|
+
return requireModule6().mfccToAudio(
|
|
1597
|
+
mfccCoefficients,
|
|
1598
|
+
nMfcc,
|
|
1599
|
+
nFrames,
|
|
1600
|
+
nMels,
|
|
1601
|
+
sampleRate,
|
|
1602
|
+
nFft,
|
|
1603
|
+
hopLength,
|
|
1604
|
+
fmin,
|
|
1605
|
+
fmax,
|
|
1606
|
+
nIter,
|
|
1607
|
+
htk,
|
|
1608
|
+
lifter
|
|
1609
|
+
);
|
|
1610
|
+
}
|
|
1611
|
+
function chroma(samples, sampleRate = 22050, nFft = 2048, hopLength = 512, options = {}) {
|
|
1612
|
+
if (!(samples instanceof Float32Array)) {
|
|
1613
|
+
const request = samples;
|
|
1614
|
+
return chroma(request.samples, request.sampleRate, request.nFft, request.hopLength, request);
|
|
1615
|
+
}
|
|
1616
|
+
validateSpectrogramSamples("chroma", samples, sampleRate, options);
|
|
1617
|
+
validatePositiveIntegers2("chroma", { nFft, hopLength });
|
|
1618
|
+
return requireModule6().chroma(samples, sampleRate, nFft, hopLength);
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
// src/metering.ts
|
|
1622
|
+
function assertOversampleFactor(fnName, factor) {
|
|
1623
|
+
const normalized = factor === 0 ? 4 : factor;
|
|
1624
|
+
if (!Number.isInteger(normalized) || normalized < 1 || normalized > 16 || (normalized & normalized - 1) !== 0) {
|
|
1625
|
+
throw new SonareError(
|
|
1626
|
+
4 /* InvalidParameter */,
|
|
1627
|
+
"InvalidParameter",
|
|
1628
|
+
`${fnName}: oversampleFactor must be 0 or a power of two from 1 to 16`
|
|
1629
|
+
);
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
function requireModule7() {
|
|
1633
|
+
return getSonareModule();
|
|
1634
|
+
}
|
|
1635
|
+
function meteringPeakDb(samples, sampleRate = 22050, options = {}) {
|
|
1636
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
1637
|
+
assertSamples("meteringPeakDb", request.samples, request.validate !== false);
|
|
1638
|
+
return requireModule7().meteringPeakDb(request.samples, request.sampleRate ?? 22050);
|
|
1639
|
+
}
|
|
1640
|
+
function meteringRmsDb(samples, sampleRate = 22050, options = {}) {
|
|
1641
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
1642
|
+
assertSamples("meteringRmsDb", request.samples, request.validate !== false);
|
|
1643
|
+
return requireModule7().meteringRmsDb(request.samples, request.sampleRate ?? 22050);
|
|
1644
|
+
}
|
|
1645
|
+
function meteringSilenceRatio(samples, sampleRate = 22050, thresholdDb = -45, frameLength = 1024, hopLength = 256, options = {}) {
|
|
1646
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, thresholdDb, frameLength, hopLength, ...options } : samples;
|
|
1647
|
+
assertSamples("meteringSilenceRatio", request.samples, request.validate !== false);
|
|
1648
|
+
return requireModule7().meteringSilenceRatio(
|
|
1649
|
+
request.samples,
|
|
1650
|
+
request.sampleRate ?? 22050,
|
|
1651
|
+
request.thresholdDb ?? -45,
|
|
1652
|
+
request.frameLength ?? 1024,
|
|
1653
|
+
request.hopLength ?? 256
|
|
1654
|
+
);
|
|
1655
|
+
}
|
|
1656
|
+
function meteringCrestFactorDb(samples, sampleRate = 22050, options = {}) {
|
|
1657
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
1658
|
+
assertSamples("meteringCrestFactorDb", request.samples, request.validate !== false);
|
|
1659
|
+
return requireModule7().meteringCrestFactorDb(request.samples, request.sampleRate ?? 22050);
|
|
1660
|
+
}
|
|
1661
|
+
function meteringDcOffset(samples, sampleRate = 22050, options = {}) {
|
|
1662
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
1663
|
+
assertSamples("meteringDcOffset", request.samples, request.validate !== false);
|
|
1664
|
+
return requireModule7().meteringDcOffset(request.samples, request.sampleRate ?? 22050);
|
|
1665
|
+
}
|
|
1666
|
+
function meteringTruePeakDb(samples, sampleRate = 22050, oversampleFactor = 4, options = {}) {
|
|
1667
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, oversampleFactor, ...options } : samples;
|
|
1668
|
+
assertSamples("meteringTruePeakDb", request.samples, request.validate !== false);
|
|
1669
|
+
const factor = request.oversampleFactor ?? 4;
|
|
1670
|
+
assertOversampleFactor("meteringTruePeakDb", factor);
|
|
1671
|
+
return requireModule7().meteringTruePeakDb(request.samples, request.sampleRate ?? 22050, factor);
|
|
1672
|
+
}
|
|
1673
|
+
function meteringDetectClipping(samples, sampleRate = 22050, options = {}) {
|
|
1674
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
1675
|
+
assertSamples("meteringDetectClipping", request.samples, request.validate !== false);
|
|
1676
|
+
const minRegionSamples = request.minRegionSamples ?? 1;
|
|
1677
|
+
if (!Number.isInteger(minRegionSamples) || minRegionSamples < 0) {
|
|
1678
|
+
throw new RangeError("meteringDetectClipping: minRegionSamples must be a non-negative integer");
|
|
1679
|
+
}
|
|
1680
|
+
return requireModule7().meteringDetectClipping(
|
|
1681
|
+
request.samples,
|
|
1682
|
+
request.sampleRate ?? 22050,
|
|
1683
|
+
request.threshold ?? 0.999,
|
|
1684
|
+
minRegionSamples
|
|
1685
|
+
);
|
|
1686
|
+
}
|
|
1687
|
+
function meteringDynamicRange(samples, sampleRate = 22050, options = {}) {
|
|
1688
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
1689
|
+
assertSamples("meteringDynamicRange", request.samples, request.validate !== false);
|
|
1690
|
+
return requireModule7().meteringDynamicRange(
|
|
1691
|
+
request.samples,
|
|
1692
|
+
request.sampleRate ?? 22050,
|
|
1693
|
+
request.windowSec ?? 0,
|
|
1694
|
+
request.hopSec ?? 0,
|
|
1695
|
+
request.lowPercentile ?? -1,
|
|
1696
|
+
request.highPercentile ?? -1
|
|
1697
|
+
);
|
|
1698
|
+
}
|
|
1699
|
+
function meteringStereoCorrelation(left, right, sampleRate = 22050, options = {}) {
|
|
1700
|
+
const request = left instanceof Float32Array ? { left, right, sampleRate, ...options } : left;
|
|
1701
|
+
const validate = request.validate !== false;
|
|
1702
|
+
assertSamples("meteringStereoCorrelation", request.left, validate, "left");
|
|
1703
|
+
assertSamples("meteringStereoCorrelation", request.right, validate, "right");
|
|
1704
|
+
return requireModule7().meteringStereoCorrelation(
|
|
1705
|
+
request.left,
|
|
1706
|
+
request.right,
|
|
1707
|
+
request.sampleRate ?? 22050
|
|
1708
|
+
);
|
|
1709
|
+
}
|
|
1710
|
+
function meteringStereoWidth(left, right, sampleRate = 22050, options = {}) {
|
|
1711
|
+
const request = left instanceof Float32Array ? { left, right, sampleRate, ...options } : left;
|
|
1712
|
+
const validate = request.validate !== false;
|
|
1713
|
+
assertSamples("meteringStereoWidth", request.left, validate, "left");
|
|
1714
|
+
assertSamples("meteringStereoWidth", request.right, validate, "right");
|
|
1715
|
+
return requireModule7().meteringStereoWidth(
|
|
1716
|
+
request.left,
|
|
1717
|
+
request.right,
|
|
1718
|
+
request.sampleRate ?? 22050
|
|
1719
|
+
);
|
|
1720
|
+
}
|
|
1721
|
+
function meteringVectorscope(left, right, sampleRate = 22050, options = {}) {
|
|
1722
|
+
const request = left instanceof Float32Array ? { left, right, sampleRate, ...options } : left;
|
|
1723
|
+
const validate = request.validate !== false;
|
|
1724
|
+
assertSamples("meteringVectorscope", request.left, validate, "left");
|
|
1725
|
+
assertSamples("meteringVectorscope", request.right, validate, "right");
|
|
1726
|
+
return requireModule7().meteringVectorscopeDecimated(
|
|
1727
|
+
request.left,
|
|
1728
|
+
request.right,
|
|
1729
|
+
request.sampleRate ?? 22050,
|
|
1730
|
+
request.maxPoints ?? 0
|
|
1731
|
+
);
|
|
1732
|
+
}
|
|
1733
|
+
function meteringVectorscopeDecimated(left, right, sampleRate = 22050, maxPoints = 0, options = {}) {
|
|
1734
|
+
const request = left instanceof Float32Array ? { left, right, sampleRate, maxPoints, ...options } : left;
|
|
1735
|
+
const validate = request.validate !== false;
|
|
1736
|
+
assertSamples("meteringVectorscopeDecimated", request.left, validate, "left");
|
|
1737
|
+
assertSamples("meteringVectorscopeDecimated", request.right, validate, "right");
|
|
1738
|
+
return requireModule7().meteringVectorscopeDecimated(
|
|
1739
|
+
request.left,
|
|
1740
|
+
request.right,
|
|
1741
|
+
request.sampleRate ?? 22050,
|
|
1742
|
+
request.maxPoints ?? 0
|
|
1743
|
+
);
|
|
1744
|
+
}
|
|
1745
|
+
function meteringPhaseScope(left, right, sampleRate = 22050, options = {}) {
|
|
1746
|
+
const request = left instanceof Float32Array ? { left, right, sampleRate, ...options } : left;
|
|
1747
|
+
const validate = request.validate !== false;
|
|
1748
|
+
assertSamples("meteringPhaseScope", request.left, validate, "left");
|
|
1749
|
+
assertSamples("meteringPhaseScope", request.right, validate, "right");
|
|
1750
|
+
return requireModule7().meteringPhaseScopeDecimated(
|
|
1751
|
+
request.left,
|
|
1752
|
+
request.right,
|
|
1753
|
+
request.sampleRate ?? 22050,
|
|
1754
|
+
request.maxPoints ?? 0
|
|
1755
|
+
);
|
|
1756
|
+
}
|
|
1757
|
+
function meteringPhaseScopeDecimated(left, right, sampleRate = 22050, maxPoints = 0, options = {}) {
|
|
1758
|
+
const request = left instanceof Float32Array ? { left, right, sampleRate, maxPoints, ...options } : left;
|
|
1759
|
+
const validate = request.validate !== false;
|
|
1760
|
+
assertSamples("meteringPhaseScopeDecimated", request.left, validate, "left");
|
|
1761
|
+
assertSamples("meteringPhaseScopeDecimated", request.right, validate, "right");
|
|
1762
|
+
return requireModule7().meteringPhaseScopeDecimated(
|
|
1763
|
+
request.left,
|
|
1764
|
+
request.right,
|
|
1765
|
+
request.sampleRate ?? 22050,
|
|
1766
|
+
request.maxPoints ?? 0
|
|
1767
|
+
);
|
|
1768
|
+
}
|
|
1769
|
+
function meteringSpectrum(samples, sampleRate = 22050, options = {}) {
|
|
1770
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
1771
|
+
assertSamples("meteringSpectrum", request.samples, request.validate !== false);
|
|
1772
|
+
return requireModule7().meteringSpectrum(request.samples, request.sampleRate ?? 22050, request);
|
|
1773
|
+
}
|
|
1774
|
+
function meteringSpectrumFrame(samples, sampleRate = 22050, frameOffset = 0, options = {}) {
|
|
1775
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, frameOffset, ...options } : samples;
|
|
1776
|
+
assertSamples("meteringSpectrumFrame", request.samples, request.validate !== false);
|
|
1777
|
+
return requireModule7().meteringSpectrumFrame(
|
|
1778
|
+
request.samples,
|
|
1779
|
+
request.sampleRate ?? 22050,
|
|
1780
|
+
request.frameOffset ?? 0,
|
|
1781
|
+
request
|
|
1782
|
+
);
|
|
1783
|
+
}
|
|
1784
|
+
function waveformPeaks(samples, channels, options = {}) {
|
|
1785
|
+
const request = samples instanceof Float32Array ? { samples, channels, ...options } : samples;
|
|
1786
|
+
assertSamples("waveformPeaks", request.samples, request.validate !== false);
|
|
1787
|
+
if (request.channels <= 0 || request.samples.length % request.channels !== 0) {
|
|
1788
|
+
throw new RangeError("waveformPeaks: samples length must be a multiple of channels");
|
|
1789
|
+
}
|
|
1790
|
+
const samplesPerBucket = request.samplesPerBucket ?? 512;
|
|
1791
|
+
if (samplesPerBucket <= 0) {
|
|
1792
|
+
throw new RangeError("waveformPeaks: samplesPerBucket must be > 0");
|
|
1793
|
+
}
|
|
1794
|
+
return requireModule7().waveformPeaks(request.samples, request.channels, samplesPerBucket);
|
|
1795
|
+
}
|
|
1796
|
+
function waveformPeakPyramid(samples, channels, options = {}) {
|
|
1797
|
+
const request = samples instanceof Float32Array ? { samples, channels, ...options } : samples;
|
|
1798
|
+
assertSamples("waveformPeakPyramid", request.samples, request.validate !== false);
|
|
1799
|
+
if (request.channels <= 0 || request.samples.length % request.channels !== 0) {
|
|
1800
|
+
throw new RangeError("waveformPeakPyramid: samples length must be a multiple of channels");
|
|
1801
|
+
}
|
|
1802
|
+
const levels = request.samplesPerBucketLevels ?? [512, 1024, 2048, 4096];
|
|
1803
|
+
if (levels.length === 0 || levels.some((level) => level <= 0)) {
|
|
1804
|
+
throw new RangeError("waveformPeakPyramid: samplesPerBucketLevels must be non-empty and > 0");
|
|
1805
|
+
}
|
|
1806
|
+
return requireModule7().waveformPeakPyramid(request.samples, request.channels, levels);
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
// src/public_types_music.ts
|
|
1810
|
+
var PitchClass = {
|
|
1811
|
+
C: 0,
|
|
1812
|
+
Cs: 1,
|
|
1813
|
+
D: 2,
|
|
1814
|
+
Ds: 3,
|
|
1815
|
+
E: 4,
|
|
1816
|
+
F: 5,
|
|
1817
|
+
Fs: 6,
|
|
1818
|
+
G: 7,
|
|
1819
|
+
Gs: 8,
|
|
1820
|
+
A: 9,
|
|
1821
|
+
As: 10,
|
|
1822
|
+
B: 11
|
|
1823
|
+
};
|
|
1824
|
+
var Mode = {
|
|
1825
|
+
Major: 0,
|
|
1826
|
+
Minor: 1,
|
|
1827
|
+
Dorian: 2,
|
|
1828
|
+
Phrygian: 3,
|
|
1829
|
+
Lydian: 4,
|
|
1830
|
+
Mixolydian: 5,
|
|
1831
|
+
Locrian: 6
|
|
1832
|
+
};
|
|
1833
|
+
var KeyProfile = {
|
|
1834
|
+
KrumhanslSchmuckler: 0,
|
|
1835
|
+
Temperley: 1,
|
|
1836
|
+
Shaath: 2,
|
|
1837
|
+
FaraldoEDMT: 3,
|
|
1838
|
+
FaraldoEDMA: 4,
|
|
1839
|
+
FaraldoEDMM: 5,
|
|
1840
|
+
BellmanBudge: 6
|
|
1841
|
+
};
|
|
1842
|
+
var ChordQuality = {
|
|
1843
|
+
Major: 0,
|
|
1844
|
+
Minor: 1,
|
|
1845
|
+
Diminished: 2,
|
|
1846
|
+
Augmented: 3,
|
|
1847
|
+
Dominant7: 4,
|
|
1848
|
+
Major7: 5,
|
|
1849
|
+
Minor7: 6,
|
|
1850
|
+
Sus2: 7,
|
|
1851
|
+
Sus4: 8,
|
|
1852
|
+
Unknown: 9,
|
|
1853
|
+
Add9: 10,
|
|
1854
|
+
MinorAdd9: 11,
|
|
1855
|
+
Dim7: 12,
|
|
1856
|
+
HalfDim7: 13,
|
|
1857
|
+
Major9: 14,
|
|
1858
|
+
Dominant9: 15,
|
|
1859
|
+
Sus2Add4: 16
|
|
1860
|
+
};
|
|
1861
|
+
var SectionType = {
|
|
1862
|
+
Intro: 0,
|
|
1863
|
+
Verse: 1,
|
|
1864
|
+
PreChorus: 2,
|
|
1865
|
+
Chorus: 3,
|
|
1866
|
+
Bridge: 4,
|
|
1867
|
+
Instrumental: 5,
|
|
1868
|
+
Outro: 6,
|
|
1869
|
+
Unknown: 7
|
|
1870
|
+
};
|
|
1871
|
+
|
|
1872
|
+
// src/analysis_helpers.ts
|
|
1873
|
+
var PITCH_CLASS_NAMES = [
|
|
1874
|
+
"C",
|
|
1875
|
+
"C#",
|
|
1876
|
+
"D",
|
|
1877
|
+
"D#",
|
|
1878
|
+
"E",
|
|
1879
|
+
"F",
|
|
1880
|
+
"F#",
|
|
1881
|
+
"G",
|
|
1882
|
+
"G#",
|
|
1883
|
+
"A",
|
|
1884
|
+
"A#",
|
|
1885
|
+
"B"
|
|
1886
|
+
];
|
|
1887
|
+
function pitchClassName(value) {
|
|
1888
|
+
return PITCH_CLASS_NAMES[value] ?? "C";
|
|
1889
|
+
}
|
|
1890
|
+
function convertKeyCandidate(wasm) {
|
|
1891
|
+
return {
|
|
1892
|
+
key: {
|
|
1893
|
+
root: wasm.key.root,
|
|
1894
|
+
mode: wasm.key.mode,
|
|
1895
|
+
confidence: wasm.key.confidence,
|
|
1896
|
+
name: wasm.key.name,
|
|
1897
|
+
shortName: wasm.key.shortName
|
|
1898
|
+
},
|
|
1899
|
+
correlation: wasm.correlation
|
|
1900
|
+
};
|
|
1901
|
+
}
|
|
1902
|
+
function keyModeValues(modes) {
|
|
1903
|
+
if (!modes) {
|
|
1904
|
+
return [];
|
|
1905
|
+
}
|
|
1906
|
+
if (modes === "major-minor") {
|
|
1907
|
+
return [Mode.Major, Mode.Minor];
|
|
1908
|
+
}
|
|
1909
|
+
if (modes === "all" || modes === "modal") {
|
|
1910
|
+
return [
|
|
1911
|
+
Mode.Major,
|
|
1912
|
+
Mode.Minor,
|
|
1913
|
+
Mode.Dorian,
|
|
1914
|
+
Mode.Phrygian,
|
|
1915
|
+
Mode.Lydian,
|
|
1916
|
+
Mode.Mixolydian,
|
|
1917
|
+
Mode.Locrian
|
|
1918
|
+
];
|
|
1919
|
+
}
|
|
1920
|
+
const names = {
|
|
1921
|
+
major: Mode.Major,
|
|
1922
|
+
minor: Mode.Minor,
|
|
1923
|
+
dorian: Mode.Dorian,
|
|
1924
|
+
phrygian: Mode.Phrygian,
|
|
1925
|
+
lydian: Mode.Lydian,
|
|
1926
|
+
mixolydian: Mode.Mixolydian,
|
|
1927
|
+
locrian: Mode.Locrian
|
|
1928
|
+
};
|
|
1929
|
+
return modes.map((mode) => typeof mode === "number" ? mode : names[mode]);
|
|
1930
|
+
}
|
|
1931
|
+
function keyProfileValue(profile) {
|
|
1932
|
+
if (profile === void 0) {
|
|
1933
|
+
return -1;
|
|
1934
|
+
}
|
|
1935
|
+
if (typeof profile === "number") {
|
|
1936
|
+
return profile;
|
|
1937
|
+
}
|
|
1938
|
+
const names = {
|
|
1939
|
+
ks: KeyProfile.KrumhanslSchmuckler,
|
|
1940
|
+
krumhansl: KeyProfile.KrumhanslSchmuckler,
|
|
1941
|
+
temperley: KeyProfile.Temperley,
|
|
1942
|
+
shaath: KeyProfile.Shaath,
|
|
1943
|
+
keyfinder: KeyProfile.Shaath,
|
|
1944
|
+
"faraldo-edmt": KeyProfile.FaraldoEDMT,
|
|
1945
|
+
edmt: KeyProfile.FaraldoEDMT,
|
|
1946
|
+
"faraldo-edma": KeyProfile.FaraldoEDMA,
|
|
1947
|
+
edma: KeyProfile.FaraldoEDMA,
|
|
1948
|
+
"faraldo-edmm": KeyProfile.FaraldoEDMM,
|
|
1949
|
+
edmm: KeyProfile.FaraldoEDMM,
|
|
1950
|
+
"bellman-budge": KeyProfile.BellmanBudge,
|
|
1951
|
+
bellman: KeyProfile.BellmanBudge
|
|
1952
|
+
};
|
|
1953
|
+
return names[profile];
|
|
1954
|
+
}
|
|
1955
|
+
function convertChordAnalysisResult(wasm) {
|
|
1956
|
+
return {
|
|
1957
|
+
chords: wasm.chords.map((c) => ({
|
|
1958
|
+
root: c.root,
|
|
1959
|
+
bass: c.bass,
|
|
1960
|
+
rootName: pitchClassName(c.root),
|
|
1961
|
+
bassName: pitchClassName(c.bass),
|
|
1962
|
+
quality: c.quality,
|
|
1963
|
+
start: c.start,
|
|
1964
|
+
end: c.end,
|
|
1965
|
+
confidence: c.confidence,
|
|
1966
|
+
name: c.name
|
|
1967
|
+
}))
|
|
1968
|
+
};
|
|
1969
|
+
}
|
|
1970
|
+
function chordChromaMethodValue(method) {
|
|
1971
|
+
if (method === "stft") {
|
|
1972
|
+
return 0;
|
|
1973
|
+
}
|
|
1974
|
+
if (method === "nnls") {
|
|
1975
|
+
return 1;
|
|
1976
|
+
}
|
|
1977
|
+
throw new Error(`Invalid chord chroma method: ${method}`);
|
|
1978
|
+
}
|
|
1979
|
+
function convertAnalysisResult(wasm) {
|
|
1980
|
+
const beatTimes = new Float32Array(wasm.beats.length);
|
|
1981
|
+
for (let i = 0; i < wasm.beats.length; i++) {
|
|
1982
|
+
beatTimes[i] = wasm.beats[i].time;
|
|
1983
|
+
}
|
|
1984
|
+
return {
|
|
1985
|
+
bpm: wasm.bpm,
|
|
1986
|
+
bpmConfidence: wasm.bpmConfidence,
|
|
1987
|
+
bpmCandidates: wasm.bpmCandidates.map((candidate) => ({
|
|
1988
|
+
value: candidate.value,
|
|
1989
|
+
confidence: candidate.confidence,
|
|
1990
|
+
relation: candidate.relation
|
|
1991
|
+
})),
|
|
1992
|
+
key: {
|
|
1993
|
+
root: wasm.key.root,
|
|
1994
|
+
mode: wasm.key.mode,
|
|
1995
|
+
confidence: wasm.key.confidence,
|
|
1996
|
+
name: wasm.key.name,
|
|
1997
|
+
shortName: wasm.key.shortName
|
|
1998
|
+
},
|
|
1999
|
+
timeSignature: wasm.timeSignature,
|
|
2000
|
+
timeSignatureCandidates: wasm.timeSignatureCandidates,
|
|
2001
|
+
beatTimes,
|
|
2002
|
+
beats: wasm.beats,
|
|
2003
|
+
chords: wasm.chords.map((c) => ({
|
|
2004
|
+
root: c.root,
|
|
2005
|
+
bass: c.bass,
|
|
2006
|
+
rootName: pitchClassName(c.root),
|
|
2007
|
+
bassName: pitchClassName(c.bass),
|
|
2008
|
+
quality: c.quality,
|
|
2009
|
+
start: c.start,
|
|
2010
|
+
end: c.end,
|
|
2011
|
+
confidence: c.confidence,
|
|
2012
|
+
name: c.name
|
|
2013
|
+
})),
|
|
2014
|
+
sections: wasm.sections.map((s) => ({
|
|
2015
|
+
type: s.type,
|
|
2016
|
+
start: s.start,
|
|
2017
|
+
end: s.end,
|
|
2018
|
+
energyLevel: s.energyLevel,
|
|
2019
|
+
confidence: s.confidence,
|
|
2020
|
+
name: s.name
|
|
2021
|
+
})),
|
|
2022
|
+
timbre: wasm.timbre,
|
|
2023
|
+
dynamics: wasm.dynamics,
|
|
2024
|
+
rhythm: wasm.rhythm,
|
|
2025
|
+
melody: wasm.melody,
|
|
2026
|
+
form: wasm.form
|
|
2027
|
+
};
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
// src/quick_analysis.ts
|
|
2031
|
+
function requireModule8() {
|
|
2032
|
+
return getSonareModule();
|
|
2033
|
+
}
|
|
2034
|
+
function validateAnalysisInput(fnName, samples, sampleRate, options = {}) {
|
|
2035
|
+
assertSampleRate(fnName, sampleRate);
|
|
2036
|
+
assertSamples(fnName, samples, options.validate !== false);
|
|
2037
|
+
}
|
|
2038
|
+
function detectBpm(samples, sampleRate = 22050, options = {}) {
|
|
2039
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
2040
|
+
validateAnalysisInput("detectBpm", request.samples, request.sampleRate ?? 22050, request);
|
|
2041
|
+
return requireModule8().detectBpm(request.samples, request.sampleRate ?? 22050);
|
|
2042
|
+
}
|
|
2043
|
+
function detectKey(samples, sampleRate = 22050, options = {}) {
|
|
2044
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
2045
|
+
validateAnalysisInput("detectKey", request.samples, request.sampleRate ?? 22050, request);
|
|
2046
|
+
const result = requireModule8()._detectKeyWithOptions(
|
|
2047
|
+
request.samples,
|
|
2048
|
+
request.sampleRate ?? 22050,
|
|
2049
|
+
request.nFft ?? 4096,
|
|
2050
|
+
request.hopLength ?? 512,
|
|
2051
|
+
request.useHpss ?? false,
|
|
2052
|
+
request.loudnessWeighted ?? false,
|
|
2053
|
+
request.highPassHz ?? 0,
|
|
2054
|
+
keyModeValues(request.modes),
|
|
2055
|
+
keyProfileValue(request.profile),
|
|
2056
|
+
request.genreHint ?? ""
|
|
2057
|
+
);
|
|
2058
|
+
return {
|
|
2059
|
+
root: result.root,
|
|
2060
|
+
mode: result.mode,
|
|
2061
|
+
confidence: result.confidence,
|
|
2062
|
+
name: result.name,
|
|
2063
|
+
shortName: result.shortName
|
|
2064
|
+
};
|
|
2065
|
+
}
|
|
2066
|
+
function detectKeyCandidates(samples, sampleRate = 22050, options = {}) {
|
|
2067
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
2068
|
+
validateAnalysisInput(
|
|
2069
|
+
"detectKeyCandidates",
|
|
2070
|
+
request.samples,
|
|
2071
|
+
request.sampleRate ?? 22050,
|
|
2072
|
+
request
|
|
2073
|
+
);
|
|
2074
|
+
const candidates = requireModule8()._detectKeyCandidates(
|
|
2075
|
+
request.samples,
|
|
2076
|
+
request.sampleRate ?? 22050,
|
|
2077
|
+
request.nFft ?? 4096,
|
|
2078
|
+
request.hopLength ?? 512,
|
|
2079
|
+
request.useHpss ?? false,
|
|
2080
|
+
request.loudnessWeighted ?? false,
|
|
2081
|
+
request.highPassHz ?? 0,
|
|
2082
|
+
keyModeValues(request.modes),
|
|
2083
|
+
keyProfileValue(request.profile),
|
|
2084
|
+
request.genreHint ?? ""
|
|
2085
|
+
);
|
|
2086
|
+
return Array.from(candidates, convertKeyCandidate);
|
|
2087
|
+
}
|
|
2088
|
+
function detectOnsets(samples, sampleRate = 22050, options = {}) {
|
|
2089
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
2090
|
+
validateAnalysisInput("detectOnsets", request.samples, request.sampleRate ?? 22050, request);
|
|
2091
|
+
return requireModule8().detectOnsets(request.samples, request.sampleRate ?? 22050, request);
|
|
2092
|
+
}
|
|
2093
|
+
function detectBeats(samples, sampleRate = 22050, options = {}) {
|
|
2094
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
2095
|
+
validateAnalysisInput("detectBeats", request.samples, request.sampleRate ?? 22050, request);
|
|
2096
|
+
return requireModule8().detectBeats(request.samples, request.sampleRate ?? 22050);
|
|
2097
|
+
}
|
|
2098
|
+
function detectDownbeats(samples, sampleRate = 22050, options = {}) {
|
|
2099
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
2100
|
+
validateAnalysisInput("detectDownbeats", request.samples, request.sampleRate ?? 22050, request);
|
|
2101
|
+
return requireModule8().detectDownbeats(request.samples, request.sampleRate ?? 22050);
|
|
2102
|
+
}
|
|
2103
|
+
function detectChords(samples, sampleRate = 22050, options = {}) {
|
|
2104
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
2105
|
+
validateAnalysisInput("detectChords", request.samples, request.sampleRate ?? 22050, request);
|
|
2106
|
+
const result = requireModule8().detectChords(
|
|
2107
|
+
request.samples,
|
|
2108
|
+
request.sampleRate ?? 22050,
|
|
2109
|
+
request.minDuration ?? 0.3,
|
|
2110
|
+
request.smoothingWindow ?? 2,
|
|
2111
|
+
request.threshold ?? 0.5,
|
|
2112
|
+
request.useTriadsOnly ?? false,
|
|
2113
|
+
request.nFft ?? 2048,
|
|
2114
|
+
request.hopLength ?? 512,
|
|
2115
|
+
request.useBeatSync ?? true,
|
|
2116
|
+
request.useHmm ?? false,
|
|
2117
|
+
request.hmmBeamWidth ?? 24,
|
|
2118
|
+
request.useKeyContext ?? false,
|
|
2119
|
+
request.keyRoot ?? PitchClass.C,
|
|
2120
|
+
request.keyMode ?? Mode.Major,
|
|
2121
|
+
request.detectInversions ?? false,
|
|
2122
|
+
chordChromaMethodValue(request.chromaMethod ?? "stft")
|
|
2123
|
+
);
|
|
2124
|
+
return convertChordAnalysisResult(result);
|
|
2125
|
+
}
|
|
2126
|
+
function chordFunctionalAnalysis(samples, keyRoot, keyMode, sampleRate = 22050, options = {}) {
|
|
2127
|
+
const request = samples instanceof Float32Array ? { samples, keyRoot, keyMode, sampleRate, ...options } : samples;
|
|
2128
|
+
validateAnalysisInput(
|
|
2129
|
+
"chordFunctionalAnalysis",
|
|
2130
|
+
request.samples,
|
|
2131
|
+
request.sampleRate ?? 22050,
|
|
2132
|
+
request
|
|
2133
|
+
);
|
|
2134
|
+
return requireModule8().chordFunctionalAnalysis(
|
|
2135
|
+
request.samples,
|
|
2136
|
+
request.keyRoot,
|
|
2137
|
+
request.keyMode ?? Mode.Major,
|
|
2138
|
+
request.sampleRate ?? 22050,
|
|
2139
|
+
request.minDuration ?? 0.3,
|
|
2140
|
+
request.smoothingWindow ?? 2,
|
|
2141
|
+
request.threshold ?? 0.5,
|
|
2142
|
+
request.useTriadsOnly ?? false,
|
|
2143
|
+
request.nFft ?? 2048,
|
|
2144
|
+
request.hopLength ?? 512,
|
|
2145
|
+
request.useBeatSync ?? true,
|
|
2146
|
+
request.useHmm ?? false,
|
|
2147
|
+
request.hmmBeamWidth ?? 24,
|
|
2148
|
+
request.useKeyContext ?? false,
|
|
2149
|
+
request.detectInversions ?? false,
|
|
2150
|
+
chordChromaMethodValue(request.chromaMethod ?? "stft")
|
|
2151
|
+
);
|
|
2152
|
+
}
|
|
2153
|
+
function analyze(samples, sampleRate = 22050, options = {}) {
|
|
2154
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
2155
|
+
validateAnalysisInput("analyze", request.samples, request.sampleRate ?? 22050, request);
|
|
2156
|
+
const result = requireModule8().analyze(request.samples, request.sampleRate ?? 22050, request);
|
|
2157
|
+
return convertAnalysisResult(result);
|
|
2158
|
+
}
|
|
2159
|
+
function analyzeImpulseResponse(samples, sampleRate = 48e3, nOctaveBands = 6) {
|
|
2160
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, nOctaveBands } : samples;
|
|
2161
|
+
validateAnalysisInput(
|
|
2162
|
+
"analyzeImpulseResponse",
|
|
2163
|
+
request.samples,
|
|
2164
|
+
request.sampleRate ?? 48e3,
|
|
2165
|
+
request
|
|
2166
|
+
);
|
|
2167
|
+
const result = requireModule8().analyzeImpulseResponse(
|
|
2168
|
+
request.samples,
|
|
2169
|
+
request.sampleRate ?? 48e3,
|
|
2170
|
+
request.nOctaveBands ?? 6
|
|
2171
|
+
);
|
|
2172
|
+
return result;
|
|
2173
|
+
}
|
|
2174
|
+
function detectAcoustic(samples, sampleRate = 48e3, options = {}) {
|
|
2175
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
2176
|
+
validateAnalysisInput("detectAcoustic", request.samples, request.sampleRate ?? 48e3, request);
|
|
2177
|
+
const result = requireModule8().detectAcoustic(
|
|
2178
|
+
request.samples,
|
|
2179
|
+
request.sampleRate ?? 48e3,
|
|
2180
|
+
request.nOctaveBands ?? 6,
|
|
2181
|
+
request.nThirdOctaveSubbands ?? 24,
|
|
2182
|
+
request.minDecayDb ?? 30,
|
|
2183
|
+
request.noiseFloorMarginDb ?? 10
|
|
2184
|
+
);
|
|
2185
|
+
return result;
|
|
2186
|
+
}
|
|
2187
|
+
function analyzeWithProgress(samples, sampleRate = 22050, onProgress) {
|
|
2188
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, onProgress } : samples;
|
|
2189
|
+
validateAnalysisInput(
|
|
2190
|
+
"analyzeWithProgress",
|
|
2191
|
+
request.samples,
|
|
2192
|
+
request.sampleRate ?? 22050,
|
|
2193
|
+
request
|
|
2194
|
+
);
|
|
2195
|
+
const result = requireModule8().analyzeWithProgress(
|
|
2196
|
+
request.samples,
|
|
2197
|
+
request.sampleRate ?? 22050,
|
|
2198
|
+
request.onProgress ?? (() => {
|
|
2199
|
+
}),
|
|
2200
|
+
request.cancel ?? (() => false)
|
|
2201
|
+
);
|
|
2202
|
+
return convertAnalysisResult(result);
|
|
2203
|
+
}
|
|
2204
|
+
function analyzeBpm(samples, sampleRate = 22050, options = {}) {
|
|
2205
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
2206
|
+
validateAnalysisInput("analyzeBpm", request.samples, request.sampleRate ?? 22050, request);
|
|
2207
|
+
assertNonNegativeInteger("analyzeBpm", request.maxCandidates ?? 5, "maxCandidates");
|
|
2208
|
+
return requireModule8().analyzeBpm(
|
|
2209
|
+
request.samples,
|
|
2210
|
+
request.sampleRate ?? 22050,
|
|
2211
|
+
request.bpmMin ?? 30,
|
|
2212
|
+
request.bpmMax ?? 300,
|
|
2213
|
+
request.startBpm ?? 120,
|
|
2214
|
+
request.nFft ?? 2048,
|
|
2215
|
+
request.hopLength ?? 512,
|
|
2216
|
+
request.maxCandidates ?? 5
|
|
2217
|
+
);
|
|
2218
|
+
}
|
|
2219
|
+
function analyzeRhythm(samples, sampleRate = 22050, options = {}) {
|
|
2220
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
2221
|
+
validateAnalysisInput("analyzeRhythm", request.samples, request.sampleRate ?? 22050, request);
|
|
2222
|
+
return requireModule8().analyzeRhythm(
|
|
2223
|
+
request.samples,
|
|
2224
|
+
request.sampleRate ?? 22050,
|
|
2225
|
+
request.bpmMin ?? 60,
|
|
2226
|
+
request.bpmMax ?? 200,
|
|
2227
|
+
request.startBpm ?? 120,
|
|
2228
|
+
request.nFft ?? 2048,
|
|
2229
|
+
request.hopLength ?? 512
|
|
2230
|
+
);
|
|
2231
|
+
}
|
|
2232
|
+
function analyzeDynamics(samples, sampleRate = 22050, options = {}) {
|
|
2233
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
2234
|
+
validateAnalysisInput("analyzeDynamics", request.samples, request.sampleRate ?? 22050, request);
|
|
2235
|
+
return requireModule8().analyzeDynamics(
|
|
2236
|
+
request.samples,
|
|
2237
|
+
request.sampleRate ?? 22050,
|
|
2238
|
+
request.windowSec ?? 0.4,
|
|
2239
|
+
request.hopLength ?? 512,
|
|
2240
|
+
request.compressionThreshold ?? 6
|
|
2241
|
+
);
|
|
2242
|
+
}
|
|
2243
|
+
function analyzeTimbre(samples, sampleRate = 22050, options = {}) {
|
|
2244
|
+
const request = samples instanceof Float32Array ? { samples, sampleRate, ...options } : samples;
|
|
2245
|
+
validateAnalysisInput("analyzeTimbre", request.samples, request.sampleRate ?? 22050, request);
|
|
2246
|
+
return requireModule8().analyzeTimbre(
|
|
2247
|
+
request.samples,
|
|
2248
|
+
request.sampleRate ?? 22050,
|
|
2249
|
+
request.nFft ?? 2048,
|
|
2250
|
+
request.hopLength ?? 512,
|
|
2251
|
+
request.nMels ?? 128,
|
|
2252
|
+
request.nMfcc ?? 13,
|
|
2253
|
+
request.windowSec ?? 0.5
|
|
2254
|
+
);
|
|
2255
|
+
}
|
|
2256
|
+
function hasFfmpegSupport() {
|
|
2257
|
+
return requireModule8().hasFfmpegSupport();
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2260
|
+
// src/analysis.ts
|
|
2261
|
+
var module = null;
|
|
2262
|
+
var initPromise = null;
|
|
2263
|
+
async function init(options) {
|
|
2264
|
+
if (module) {
|
|
2265
|
+
return;
|
|
2266
|
+
}
|
|
2267
|
+
if (initPromise) {
|
|
2268
|
+
return initPromise;
|
|
2269
|
+
}
|
|
2270
|
+
initPromise = (async () => {
|
|
2271
|
+
try {
|
|
2272
|
+
const createModule = options?.moduleFactory ?? (await import("./sonare-analysis.js")).default;
|
|
2273
|
+
module = await createModule(options);
|
|
2274
|
+
setSonareModule(module);
|
|
2275
|
+
} catch (error) {
|
|
2276
|
+
initPromise = null;
|
|
2277
|
+
throw error;
|
|
2278
|
+
}
|
|
2279
|
+
})();
|
|
2280
|
+
return initPromise;
|
|
2281
|
+
}
|
|
2282
|
+
function isInitialized() {
|
|
2283
|
+
return module !== null;
|
|
2284
|
+
}
|
|
2285
|
+
function version() {
|
|
2286
|
+
if (!module) {
|
|
2287
|
+
throw new Error("Module not initialized. Call init() first.");
|
|
2288
|
+
}
|
|
2289
|
+
return module.version();
|
|
2290
|
+
}
|
|
2291
|
+
function capabilities() {
|
|
2292
|
+
if (!module) {
|
|
2293
|
+
throw new Error("Module not initialized. Call init() first.");
|
|
2294
|
+
}
|
|
2295
|
+
return module.capabilities();
|
|
2296
|
+
}
|
|
2297
|
+
function abiVersion() {
|
|
2298
|
+
if (!module) {
|
|
2299
|
+
throw new Error("Module not initialized. Call init() first.");
|
|
2300
|
+
}
|
|
2301
|
+
return module.abiVersion();
|
|
2302
|
+
}
|
|
2303
|
+
function engineAbiVersion() {
|
|
2304
|
+
if (!module) {
|
|
2305
|
+
throw new Error("Module not initialized. Call init() first.");
|
|
2306
|
+
}
|
|
2307
|
+
return module.engineAbiVersion();
|
|
2308
|
+
}
|
|
2309
|
+
function voiceChangerAbiVersion() {
|
|
2310
|
+
if (!module) {
|
|
2311
|
+
throw new Error("Module not initialized. Call init() first.");
|
|
2312
|
+
}
|
|
2313
|
+
return module.voiceChangerAbiVersion();
|
|
2314
|
+
}
|
|
2315
|
+
export {
|
|
2316
|
+
ChordQuality,
|
|
2317
|
+
ErrorCode,
|
|
2318
|
+
KeyProfile,
|
|
2319
|
+
Mode,
|
|
2320
|
+
PitchClass,
|
|
2321
|
+
SectionType,
|
|
2322
|
+
SonareError,
|
|
2323
|
+
abiVersion,
|
|
2324
|
+
amplitudeToDb,
|
|
2325
|
+
analyze,
|
|
2326
|
+
analyzeBpm,
|
|
2327
|
+
analyzeDynamics,
|
|
2328
|
+
analyzeImpulseResponse,
|
|
2329
|
+
analyzeMelody,
|
|
2330
|
+
analyzeRhythm,
|
|
2331
|
+
analyzeSections,
|
|
2332
|
+
analyzeTimbre,
|
|
2333
|
+
analyzeWithProgress,
|
|
2334
|
+
bassChroma,
|
|
2335
|
+
capabilities,
|
|
2336
|
+
chirp,
|
|
2337
|
+
chordFunctionalAnalysis,
|
|
2338
|
+
chroma,
|
|
2339
|
+
chromaCens,
|
|
2340
|
+
chromaCqt,
|
|
2341
|
+
clicks,
|
|
2342
|
+
cqt,
|
|
2343
|
+
cqtToAudio,
|
|
2344
|
+
cyclicTempogram,
|
|
2345
|
+
dbToAmplitude,
|
|
2346
|
+
dbToPower,
|
|
2347
|
+
decompose,
|
|
2348
|
+
decomposeWithInit,
|
|
2349
|
+
deemphasis,
|
|
2350
|
+
detectAcoustic,
|
|
2351
|
+
detectBeats,
|
|
2352
|
+
detectBpm,
|
|
2353
|
+
detectChords,
|
|
2354
|
+
detectDownbeats,
|
|
2355
|
+
detectKey,
|
|
2356
|
+
detectKeyCandidates,
|
|
2357
|
+
detectOnsets,
|
|
2358
|
+
ebur128LoudnessRange,
|
|
2359
|
+
engineAbiVersion,
|
|
2360
|
+
estimateTuning,
|
|
2361
|
+
fixFrames,
|
|
2362
|
+
fixLength,
|
|
2363
|
+
fourierTempogram,
|
|
2364
|
+
frameSignal,
|
|
2365
|
+
framesToSamples,
|
|
2366
|
+
framesToTime,
|
|
2367
|
+
griffinLim,
|
|
2368
|
+
hasFfmpegSupport,
|
|
2369
|
+
hpssWithResidual,
|
|
2370
|
+
hybridCqt,
|
|
2371
|
+
hzToMel,
|
|
2372
|
+
hzToMidi,
|
|
2373
|
+
hzToNote,
|
|
2374
|
+
init,
|
|
2375
|
+
isInitialized,
|
|
2376
|
+
isSonareError,
|
|
2377
|
+
lufs,
|
|
2378
|
+
lufsInterleaved,
|
|
2379
|
+
melDelta,
|
|
2380
|
+
melSpectrogram,
|
|
2381
|
+
melToAudio,
|
|
2382
|
+
melToHz,
|
|
2383
|
+
melToStft,
|
|
2384
|
+
meteringCrestFactorDb,
|
|
2385
|
+
meteringDcOffset,
|
|
2386
|
+
meteringDetectClipping,
|
|
2387
|
+
meteringDynamicRange,
|
|
2388
|
+
meteringPeakDb,
|
|
2389
|
+
meteringPhaseScope,
|
|
2390
|
+
meteringPhaseScopeDecimated,
|
|
2391
|
+
meteringRmsDb,
|
|
2392
|
+
meteringSilenceRatio,
|
|
2393
|
+
meteringSpectrum,
|
|
2394
|
+
meteringSpectrumFrame,
|
|
2395
|
+
meteringStereoCorrelation,
|
|
2396
|
+
meteringStereoWidth,
|
|
2397
|
+
meteringTruePeakDb,
|
|
2398
|
+
meteringVectorscope,
|
|
2399
|
+
meteringVectorscopeDecimated,
|
|
2400
|
+
mfcc,
|
|
2401
|
+
mfccToAudio,
|
|
2402
|
+
mfccToMel,
|
|
2403
|
+
midiToHz,
|
|
2404
|
+
momentaryLufs,
|
|
2405
|
+
nnFilter,
|
|
2406
|
+
nnlsChroma,
|
|
2407
|
+
noteSegments,
|
|
2408
|
+
noteToHz,
|
|
2409
|
+
onsetBacktrack,
|
|
2410
|
+
onsetEnvelope,
|
|
2411
|
+
onsetStrengthMulti,
|
|
2412
|
+
padCenter,
|
|
2413
|
+
pcen,
|
|
2414
|
+
peakPick,
|
|
2415
|
+
phaseVocoder,
|
|
2416
|
+
piptrack,
|
|
2417
|
+
pitchPyin,
|
|
2418
|
+
pitchTuning,
|
|
2419
|
+
pitchYin,
|
|
2420
|
+
plp,
|
|
2421
|
+
polyFeatures,
|
|
2422
|
+
powerToDb,
|
|
2423
|
+
preemphasis,
|
|
2424
|
+
pseudoCqt,
|
|
2425
|
+
reassignedSpectrogram,
|
|
2426
|
+
remix,
|
|
2427
|
+
resample,
|
|
2428
|
+
rmsEnergy,
|
|
2429
|
+
samplesToFrames,
|
|
2430
|
+
segmentAgglomerative,
|
|
2431
|
+
segmentCrossSimilarity,
|
|
2432
|
+
segmentLagToRecurrence,
|
|
2433
|
+
segmentPathEnhance,
|
|
2434
|
+
segmentRecurrenceMatrix,
|
|
2435
|
+
segmentRecurrenceToLag,
|
|
2436
|
+
segmentSubsegment,
|
|
2437
|
+
shortTermLufs,
|
|
2438
|
+
spectralBandwidth,
|
|
2439
|
+
spectralCentroid,
|
|
2440
|
+
spectralContrast,
|
|
2441
|
+
spectralFlatness,
|
|
2442
|
+
spectralFlux,
|
|
2443
|
+
spectralRolloff,
|
|
2444
|
+
splitSilence,
|
|
2445
|
+
stft,
|
|
2446
|
+
stftDb,
|
|
2447
|
+
tempogram,
|
|
2448
|
+
tempogramRatio,
|
|
2449
|
+
timeToFrames,
|
|
2450
|
+
tone,
|
|
2451
|
+
tonnetz,
|
|
2452
|
+
trim,
|
|
2453
|
+
trimSilence,
|
|
2454
|
+
vectorNormalize,
|
|
2455
|
+
version,
|
|
2456
|
+
voiceChangerAbiVersion,
|
|
2457
|
+
vqt,
|
|
2458
|
+
vqtToAudio,
|
|
2459
|
+
waveformPeakPyramid,
|
|
2460
|
+
waveformPeaks,
|
|
2461
|
+
zeroCrossingRate,
|
|
2462
|
+
zeroCrossings
|
|
2463
|
+
};
|
|
2464
|
+
//# sourceMappingURL=analysis.js.map
|