@siteed/audio-studio 3.0.0 → 3.0.2-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +356 -415
- package/README.md +1 -1
- package/android/src/main/CMakeLists.txt +3 -0
- package/build/cjs/AudioAnalysis/audioFeaturesWasm.js +7 -155
- package/build/cjs/AudioAnalysis/audioFeaturesWasm.js.map +1 -1
- package/build/cjs/AudioAnalysis/audioFeaturesWasm.web.js +165 -0
- package/build/cjs/AudioAnalysis/audioFeaturesWasm.web.js.map +1 -0
- package/build/cjs/AudioAnalysis/melSpectrogramWasm.js +8 -140
- package/build/cjs/AudioAnalysis/melSpectrogramWasm.js.map +1 -1
- package/build/cjs/AudioAnalysis/melSpectrogramWasm.web.js +153 -0
- package/build/cjs/AudioAnalysis/melSpectrogramWasm.web.js.map +1 -0
- package/build/cjs/AudioAnalysis/wasmConfig.js +26 -0
- package/build/cjs/AudioAnalysis/wasmConfig.js.map +1 -0
- package/build/cjs/index.js +3 -1
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/prebuilt/wasm/mel-spectrogram.js +18 -0
- package/build/esm/AudioAnalysis/audioFeaturesWasm.js +7 -122
- package/build/esm/AudioAnalysis/audioFeaturesWasm.js.map +1 -1
- package/build/esm/AudioAnalysis/audioFeaturesWasm.web.js +127 -0
- package/build/esm/AudioAnalysis/audioFeaturesWasm.web.js.map +1 -0
- package/build/esm/AudioAnalysis/melSpectrogramWasm.js +8 -107
- package/build/esm/AudioAnalysis/melSpectrogramWasm.js.map +1 -1
- package/build/esm/AudioAnalysis/melSpectrogramWasm.web.js +115 -0
- package/build/esm/AudioAnalysis/melSpectrogramWasm.web.js.map +1 -0
- package/build/esm/AudioAnalysis/wasmConfig.js +21 -0
- package/build/esm/AudioAnalysis/wasmConfig.js.map +1 -0
- package/build/esm/index.js +1 -0
- package/build/esm/index.js.map +1 -1
- package/build/esm/prebuilt/wasm/mel-spectrogram.js +18 -0
- package/build/types/AudioAnalysis/audioFeaturesWasm.d.ts +3 -15
- package/build/types/AudioAnalysis/audioFeaturesWasm.d.ts.map +1 -1
- package/build/types/AudioAnalysis/audioFeaturesWasm.web.d.ts +24 -0
- package/build/types/AudioAnalysis/audioFeaturesWasm.web.d.ts.map +1 -0
- package/build/types/AudioAnalysis/melSpectrogramWasm.d.ts +3 -15
- package/build/types/AudioAnalysis/melSpectrogramWasm.d.ts.map +1 -1
- package/build/types/AudioAnalysis/melSpectrogramWasm.web.d.ts +16 -0
- package/build/types/AudioAnalysis/melSpectrogramWasm.web.d.ts.map +1 -0
- package/build/types/AudioAnalysis/wasmConfig.d.ts +4 -0
- package/build/types/AudioAnalysis/wasmConfig.d.ts.map +1 -0
- package/build/types/index.d.ts +1 -0
- package/build/types/index.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/AudioAnalysis/audioFeaturesWasm.ts +18 -179
- package/src/AudioAnalysis/audioFeaturesWasm.web.ts +201 -0
- package/src/AudioAnalysis/melSpectrogramWasm.ts +23 -169
- package/src/AudioAnalysis/melSpectrogramWasm.web.ts +184 -0
- package/src/AudioAnalysis/wasmConfig.ts +24 -0
- package/src/index.ts +2 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.initMelStreamingWasm = initMelStreamingWasm;
|
|
37
|
+
exports.computeMelFrameWasm = computeMelFrameWasm;
|
|
38
|
+
exports.computeMelSpectrogramWasm = computeMelSpectrogramWasm;
|
|
39
|
+
const wasmConfig_1 = require("./wasmConfig");
|
|
40
|
+
let modulePromise = null;
|
|
41
|
+
(0, wasmConfig_1._registerModuleReset)(() => {
|
|
42
|
+
modulePromise = null;
|
|
43
|
+
});
|
|
44
|
+
function getModule() {
|
|
45
|
+
if (!modulePromise) {
|
|
46
|
+
modulePromise = (async () => {
|
|
47
|
+
const url = (0, wasmConfig_1.getMelSpectrogramWasmUrl)();
|
|
48
|
+
// webpackIgnore + @vite-ignore prevent bundlers from trying to resolve the URL
|
|
49
|
+
const mod = await Promise.resolve(`${url}`).then(s => __importStar(require(s)));
|
|
50
|
+
const factory = mod.default ?? mod;
|
|
51
|
+
return factory();
|
|
52
|
+
})().catch((err) => {
|
|
53
|
+
modulePromise = null;
|
|
54
|
+
throw err;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return modulePromise;
|
|
58
|
+
}
|
|
59
|
+
// --- Streaming (per-frame) API for live mel spectrogram ---
|
|
60
|
+
let streamingModule = null;
|
|
61
|
+
let streamingNMels = 0;
|
|
62
|
+
let streamingFramePtr = 0;
|
|
63
|
+
let streamingMelPtr = 0;
|
|
64
|
+
let streamingFrameCapacity = 0;
|
|
65
|
+
/**
|
|
66
|
+
* Initialise the WASM streaming processor. Call once before computeMelFrame().
|
|
67
|
+
* Re-initialises only when config changes.
|
|
68
|
+
*/
|
|
69
|
+
async function initMelStreamingWasm(sampleRate, nMels = 128, fftLength = 2048, windowSizeSamples = 400, hopLengthSamples = 160, fMin = 0, fMax = 0) {
|
|
70
|
+
const Module = await getModule();
|
|
71
|
+
streamingModule = Module;
|
|
72
|
+
const actualFMax = fMax > 0 ? fMax : sampleRate / 2;
|
|
73
|
+
Module._mel_spectrogram_init(sampleRate, fftLength, windowSizeSamples, hopLengthSamples, nMels, fMin, actualFMax, 0 /* hann */);
|
|
74
|
+
streamingNMels = nMels;
|
|
75
|
+
// Pre-allocate output buffer (fixed size)
|
|
76
|
+
if (streamingMelPtr)
|
|
77
|
+
Module._free(streamingMelPtr);
|
|
78
|
+
streamingMelPtr = Module._malloc(nMels * 4);
|
|
79
|
+
// Frame input buffer allocated on demand in computeMelFrame
|
|
80
|
+
streamingFrameCapacity = 0;
|
|
81
|
+
streamingFramePtr = 0;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Compute a single mel spectrogram frame from raw PCM samples via WASM C++.
|
|
85
|
+
* Returns null if not initialised or on error.
|
|
86
|
+
*/
|
|
87
|
+
function computeMelFrameWasm(samples) {
|
|
88
|
+
if (!streamingModule || !streamingMelPtr)
|
|
89
|
+
return null;
|
|
90
|
+
const Module = streamingModule;
|
|
91
|
+
// (Re-)allocate frame input buffer if needed
|
|
92
|
+
if (samples.length > streamingFrameCapacity) {
|
|
93
|
+
if (streamingFramePtr)
|
|
94
|
+
Module._free(streamingFramePtr);
|
|
95
|
+
streamingFramePtr = Module._malloc(samples.length * 4);
|
|
96
|
+
streamingFrameCapacity = samples.length;
|
|
97
|
+
}
|
|
98
|
+
// Copy samples to WASM heap
|
|
99
|
+
Module.HEAPF32.set(samples, streamingFramePtr >> 2);
|
|
100
|
+
const ok = Module._mel_spectrogram_compute_frame(streamingFramePtr, samples.length, streamingMelPtr);
|
|
101
|
+
if (!ok)
|
|
102
|
+
return null;
|
|
103
|
+
// Read mel output from WASM heap
|
|
104
|
+
const offset = streamingMelPtr >> 2;
|
|
105
|
+
const result = new Array(streamingNMels);
|
|
106
|
+
for (let i = 0; i < streamingNMels; i++) {
|
|
107
|
+
result[i] = Module.HEAPF32[offset + i];
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Computes a mel spectrogram via the WASM-compiled C++ implementation.
|
|
113
|
+
* Lazy-loads the WASM module on first call.
|
|
114
|
+
*/
|
|
115
|
+
async function computeMelSpectrogramWasm(audioData, sampleRate, nMels, windowSizeSamples, hopLengthSamples, fMin, fMax, windowType, normalize, logScale) {
|
|
116
|
+
const Module = await getModule();
|
|
117
|
+
const fftLength = 2048;
|
|
118
|
+
const windowTypeInt = windowType === 'hamming' ? 1 : 0;
|
|
119
|
+
// Allocate input buffer on WASM heap
|
|
120
|
+
const numSamples = audioData.length;
|
|
121
|
+
const inputPtr = Module._malloc(numSamples * 4); // 4 bytes per float
|
|
122
|
+
Module.HEAPF32.set(audioData, inputPtr >> 2);
|
|
123
|
+
// Call the C bridge
|
|
124
|
+
const resultPtr = Module._mel_spectrogram_compute(inputPtr, numSamples, sampleRate, fftLength, windowSizeSamples, hopLengthSamples, nMels, fMin, fMax, windowTypeInt, logScale ? 1 : 0, normalize ? 1 : 0);
|
|
125
|
+
// Free input buffer
|
|
126
|
+
Module._free(inputPtr);
|
|
127
|
+
if (resultPtr === 0) {
|
|
128
|
+
throw new Error('mel_spectrogram_compute returned null (too few samples?)');
|
|
129
|
+
}
|
|
130
|
+
// Read CMelSpectrogramResult struct (wasm32 pointers are 4 bytes)
|
|
131
|
+
// struct layout: { float* data (offset 0), int timeSteps (offset 4), int nMels (offset 8) }
|
|
132
|
+
const dataPtr = Module.getValue(resultPtr, 'i32');
|
|
133
|
+
const timeSteps = Module.getValue(resultPtr + 4, 'i32');
|
|
134
|
+
const resultNMels = Module.getValue(resultPtr + 8, 'i32');
|
|
135
|
+
if (!dataPtr || timeSteps <= 0 || resultNMels <= 0) {
|
|
136
|
+
Module._mel_spectrogram_free(resultPtr);
|
|
137
|
+
throw new Error('mel_spectrogram_compute returned invalid result struct');
|
|
138
|
+
}
|
|
139
|
+
// Copy spectrogram data to JS arrays
|
|
140
|
+
const spectrogram = [];
|
|
141
|
+
const heapOffset = dataPtr >> 2; // float32 offset into HEAPF32
|
|
142
|
+
for (let t = 0; t < timeSteps; t++) {
|
|
143
|
+
const row = new Array(resultNMels);
|
|
144
|
+
for (let m = 0; m < resultNMels; m++) {
|
|
145
|
+
row[m] = Module.HEAPF32[heapOffset + t * resultNMels + m];
|
|
146
|
+
}
|
|
147
|
+
spectrogram.push(row);
|
|
148
|
+
}
|
|
149
|
+
// Free the C result
|
|
150
|
+
Module._mel_spectrogram_free(resultPtr);
|
|
151
|
+
return spectrogram;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=melSpectrogramWasm.web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"melSpectrogramWasm.web.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/melSpectrogramWasm.web.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,oDA+BC;AAMD,kDA4BC;AAMD,8DA2EC;AAtLD,6CAA6E;AAE7E,IAAI,aAAa,GAA6C,IAAI,CAAA;AAElE,IAAA,iCAAoB,EAAC,GAAG,EAAE;IACtB,aAAa,GAAG,IAAI,CAAA;AACxB,CAAC,CAAC,CAAA;AAEF,SAAS,SAAS;IACd,IAAI,CAAC,aAAa,EAAE,CAAC;QACjB,aAAa,GAAG,CAAC,KAAK,IAAI,EAAE;YACxB,MAAM,GAAG,GAAG,IAAA,qCAAwB,GAAE,CAAA;YACtC,+EAA+E;YAC/E,MAAM,GAAG,GAAG,yBAA0D,GAAG,uCAAC,CAAA;YAC1E,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAA;YAClC,OAAO,OAAO,EAAuC,CAAA;QACzD,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACf,aAAa,GAAG,IAAI,CAAA;YACpB,MAAM,GAAG,CAAA;QACb,CAAC,CAAC,CAAA;IACN,CAAC;IACD,OAAO,aAAa,CAAA;AACxB,CAAC;AAED,6DAA6D;AAE7D,IAAI,eAAe,GAAoC,IAAI,CAAA;AAC3D,IAAI,cAAc,GAAG,CAAC,CAAA;AACtB,IAAI,iBAAiB,GAAG,CAAC,CAAA;AACzB,IAAI,eAAe,GAAG,CAAC,CAAA;AACvB,IAAI,sBAAsB,GAAG,CAAC,CAAA;AAE9B;;;GAGG;AACI,KAAK,UAAU,oBAAoB,CACtC,UAAkB,EAClB,KAAK,GAAG,GAAG,EACX,SAAS,GAAG,IAAI,EAChB,iBAAiB,GAAG,GAAG,EACvB,gBAAgB,GAAG,GAAG,EACtB,IAAI,GAAG,CAAC,EACR,IAAI,GAAG,CAAC;IAER,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAA;IAChC,eAAe,GAAG,MAAM,CAAA;IACxB,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAA;IACnD,MAAM,CAAC,qBAAqB,CACxB,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,EACL,IAAI,EACJ,UAAU,EACV,CAAC,CAAC,UAAU,CACf,CAAA;IACD,cAAc,GAAG,KAAK,CAAA;IAEtB,0CAA0C;IAC1C,IAAI,eAAe;QAAE,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAA;IAClD,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;IAE3C,4DAA4D;IAC5D,sBAAsB,GAAG,CAAC,CAAA;IAC1B,iBAAiB,GAAG,CAAC,CAAA;AACzB,CAAC;AAED;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,OAAqB;IACrD,IAAI,CAAC,eAAe,IAAI,CAAC,eAAe;QAAE,OAAO,IAAI,CAAA;IACrD,MAAM,MAAM,GAAG,eAAe,CAAA;IAE9B,6CAA6C;IAC7C,IAAI,OAAO,CAAC,MAAM,GAAG,sBAAsB,EAAE,CAAC;QAC1C,IAAI,iBAAiB;YAAE,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACtD,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QACtD,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAA;IAC3C,CAAC;IAED,4BAA4B;IAC5B,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,iBAAiB,IAAI,CAAC,CAAC,CAAA;IAEnD,MAAM,EAAE,GAAG,MAAM,CAAC,8BAA8B,CAC5C,iBAAiB,EACjB,OAAO,CAAC,MAAM,EACd,eAAe,CAClB,CAAA;IACD,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAA;IAEpB,iCAAiC;IACjC,MAAM,MAAM,GAAG,eAAe,IAAI,CAAC,CAAA;IACnC,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,cAAc,CAAC,CAAA;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAC1C,CAAC;IACD,OAAO,MAAM,CAAA;AACjB,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,yBAAyB,CAC3C,SAAuB,EACvB,UAAkB,EAClB,KAAa,EACb,iBAAyB,EACzB,gBAAwB,EACxB,IAAY,EACZ,IAAY,EACZ,UAA8B,EAC9B,SAAkB,EAClB,QAAiB;IAEjB,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAA;IAEhC,MAAM,SAAS,GAAG,IAAI,CAAA;IACtB,MAAM,aAAa,GAAG,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAEtD,qCAAqC;IACrC,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAA;IACnC,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC,CAAA,CAAC,oBAAoB;IACpE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,IAAI,CAAC,CAAC,CAAA;IAE5C,oBAAoB;IACpB,MAAM,SAAS,GAAG,MAAM,CAAC,wBAAwB,CAC7C,QAAQ,EACR,UAAU,EACV,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,aAAa,EACb,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAChB,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACpB,CAAA;IAED,oBAAoB;IACpB,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;IAEtB,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACX,0DAA0D,CAC7D,CAAA;IACL,CAAC;IAED,kEAAkE;IAClE,4FAA4F;IAC5F,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;IACjD,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,GAAG,CAAC,EAAE,KAAK,CAAC,CAAA;IACvD,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,GAAG,CAAC,EAAE,KAAK,CAAC,CAAA;IAEzD,IAAI,CAAC,OAAO,IAAI,SAAS,IAAI,CAAC,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;QACjD,MAAM,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAA;QACvC,MAAM,IAAI,KAAK,CACX,wDAAwD,CAC3D,CAAA;IACL,CAAC;IAED,qCAAqC;IACrC,MAAM,WAAW,GAAe,EAAE,CAAA;IAClC,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,CAAA,CAAC,8BAA8B;IAC9D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,CAAA;QAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC,GAAG,WAAW,GAAG,CAAC,CAAC,CAAA;QAC7D,CAAC;QACD,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC;IAED,oBAAoB;IACpB,MAAM,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAA;IAEvC,OAAO,WAAW,CAAA;AACtB,CAAC","sourcesContent":["import type { MelSpectrogramWasmModule } from './mel-spectrogram-wasm'\nimport { getMelSpectrogramWasmUrl, _registerModuleReset } from './wasmConfig'\n\nlet modulePromise: Promise<MelSpectrogramWasmModule> | null = null\n\n_registerModuleReset(() => {\n modulePromise = null\n})\n\nfunction getModule(): Promise<MelSpectrogramWasmModule> {\n if (!modulePromise) {\n modulePromise = (async () => {\n const url = getMelSpectrogramWasmUrl()\n // webpackIgnore + @vite-ignore prevent bundlers from trying to resolve the URL\n const mod = await import(/* webpackIgnore: true */ /* @vite-ignore */ url)\n const factory = mod.default ?? mod\n return factory() as Promise<MelSpectrogramWasmModule>\n })().catch((err) => {\n modulePromise = null\n throw err\n })\n }\n return modulePromise\n}\n\n// --- Streaming (per-frame) API for live mel spectrogram ---\n\nlet streamingModule: MelSpectrogramWasmModule | null = null\nlet streamingNMels = 0\nlet streamingFramePtr = 0\nlet streamingMelPtr = 0\nlet streamingFrameCapacity = 0\n\n/**\n * Initialise the WASM streaming processor. Call once before computeMelFrame().\n * Re-initialises only when config changes.\n */\nexport async function initMelStreamingWasm(\n sampleRate: number,\n nMels = 128,\n fftLength = 2048,\n windowSizeSamples = 400,\n hopLengthSamples = 160,\n fMin = 0,\n fMax = 0\n): Promise<void> {\n const Module = await getModule()\n streamingModule = Module\n const actualFMax = fMax > 0 ? fMax : sampleRate / 2\n Module._mel_spectrogram_init(\n sampleRate,\n fftLength,\n windowSizeSamples,\n hopLengthSamples,\n nMels,\n fMin,\n actualFMax,\n 0 /* hann */\n )\n streamingNMels = nMels\n\n // Pre-allocate output buffer (fixed size)\n if (streamingMelPtr) Module._free(streamingMelPtr)\n streamingMelPtr = Module._malloc(nMels * 4)\n\n // Frame input buffer allocated on demand in computeMelFrame\n streamingFrameCapacity = 0\n streamingFramePtr = 0\n}\n\n/**\n * Compute a single mel spectrogram frame from raw PCM samples via WASM C++.\n * Returns null if not initialised or on error.\n */\nexport function computeMelFrameWasm(samples: Float32Array): number[] | null {\n if (!streamingModule || !streamingMelPtr) return null\n const Module = streamingModule\n\n // (Re-)allocate frame input buffer if needed\n if (samples.length > streamingFrameCapacity) {\n if (streamingFramePtr) Module._free(streamingFramePtr)\n streamingFramePtr = Module._malloc(samples.length * 4)\n streamingFrameCapacity = samples.length\n }\n\n // Copy samples to WASM heap\n Module.HEAPF32.set(samples, streamingFramePtr >> 2)\n\n const ok = Module._mel_spectrogram_compute_frame(\n streamingFramePtr,\n samples.length,\n streamingMelPtr\n )\n if (!ok) return null\n\n // Read mel output from WASM heap\n const offset = streamingMelPtr >> 2\n const result = new Array(streamingNMels)\n for (let i = 0; i < streamingNMels; i++) {\n result[i] = Module.HEAPF32[offset + i]\n }\n return result\n}\n\n/**\n * Computes a mel spectrogram via the WASM-compiled C++ implementation.\n * Lazy-loads the WASM module on first call.\n */\nexport async function computeMelSpectrogramWasm(\n audioData: Float32Array,\n sampleRate: number,\n nMels: number,\n windowSizeSamples: number,\n hopLengthSamples: number,\n fMin: number,\n fMax: number,\n windowType: 'hann' | 'hamming',\n normalize: boolean,\n logScale: boolean\n): Promise<number[][]> {\n const Module = await getModule()\n\n const fftLength = 2048\n const windowTypeInt = windowType === 'hamming' ? 1 : 0\n\n // Allocate input buffer on WASM heap\n const numSamples = audioData.length\n const inputPtr = Module._malloc(numSamples * 4) // 4 bytes per float\n Module.HEAPF32.set(audioData, inputPtr >> 2)\n\n // Call the C bridge\n const resultPtr = Module._mel_spectrogram_compute(\n inputPtr,\n numSamples,\n sampleRate,\n fftLength,\n windowSizeSamples,\n hopLengthSamples,\n nMels,\n fMin,\n fMax,\n windowTypeInt,\n logScale ? 1 : 0,\n normalize ? 1 : 0\n )\n\n // Free input buffer\n Module._free(inputPtr)\n\n if (resultPtr === 0) {\n throw new Error(\n 'mel_spectrogram_compute returned null (too few samples?)'\n )\n }\n\n // Read CMelSpectrogramResult struct (wasm32 pointers are 4 bytes)\n // struct layout: { float* data (offset 0), int timeSteps (offset 4), int nMels (offset 8) }\n const dataPtr = Module.getValue(resultPtr, 'i32')\n const timeSteps = Module.getValue(resultPtr + 4, 'i32')\n const resultNMels = Module.getValue(resultPtr + 8, 'i32')\n\n if (!dataPtr || timeSteps <= 0 || resultNMels <= 0) {\n Module._mel_spectrogram_free(resultPtr)\n throw new Error(\n 'mel_spectrogram_compute returned invalid result struct'\n )\n }\n\n // Copy spectrogram data to JS arrays\n const spectrogram: number[][] = []\n const heapOffset = dataPtr >> 2 // float32 offset into HEAPF32\n for (let t = 0; t < timeSteps; t++) {\n const row = new Array(resultNMels)\n for (let m = 0; m < resultNMels; m++) {\n row[m] = Module.HEAPF32[heapOffset + t * resultNMels + m]\n }\n spectrogram.push(row)\n }\n\n // Free the C result\n Module._mel_spectrogram_free(resultPtr)\n\n return spectrogram\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports._registerModuleReset = _registerModuleReset;
|
|
4
|
+
exports.setMelSpectrogramWasmUrl = setMelSpectrogramWasmUrl;
|
|
5
|
+
exports.getMelSpectrogramWasmUrl = getMelSpectrogramWasmUrl;
|
|
6
|
+
// Version is inlined here — keep in sync with package.json when releasing.
|
|
7
|
+
// The publish.sh script should bump this string alongside package.json.
|
|
8
|
+
const WASM_VERSION = '3.0.2';
|
|
9
|
+
// jsDelivr syncs from npm automatically within ~5 min of publish.
|
|
10
|
+
// GitHub release fallback (attach mel-spectrogram.js as a release asset):
|
|
11
|
+
// https://github.com/deeeed/audiolab/releases/download/@siteed/audio-studio@VERSION/mel-spectrogram.js
|
|
12
|
+
// To use the fallback: setMelSpectrogramWasmUrl('<url>') before any mel-spectrogram API call.
|
|
13
|
+
const DEFAULT_WASM_CDN = `https://cdn.jsdelivr.net/npm/@siteed/audio-studio@${WASM_VERSION}/prebuilt/wasm/mel-spectrogram.js`;
|
|
14
|
+
let _wasmUrl = DEFAULT_WASM_CDN;
|
|
15
|
+
let _modulePromiseReset = null;
|
|
16
|
+
function _registerModuleReset(fn) {
|
|
17
|
+
_modulePromiseReset = fn;
|
|
18
|
+
}
|
|
19
|
+
function setMelSpectrogramWasmUrl(url) {
|
|
20
|
+
_wasmUrl = url;
|
|
21
|
+
_modulePromiseReset?.(); // invalidate cached module so next call re-fetches
|
|
22
|
+
}
|
|
23
|
+
function getMelSpectrogramWasmUrl() {
|
|
24
|
+
return _wasmUrl;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=wasmConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wasmConfig.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/wasmConfig.ts"],"names":[],"mappings":";;AAYA,oDAEC;AAED,4DAGC;AAED,4DAEC;AAvBD,2EAA2E;AAC3E,wEAAwE;AACxE,MAAM,YAAY,GAAG,OAAO,CAAA;AAC5B,kEAAkE;AAClE,0EAA0E;AAC1E,yGAAyG;AACzG,8FAA8F;AAC9F,MAAM,gBAAgB,GAAG,qDAAqD,YAAY,mCAAmC,CAAA;AAE7H,IAAI,QAAQ,GAAW,gBAAgB,CAAA;AACvC,IAAI,mBAAmB,GAAwB,IAAI,CAAA;AAEnD,SAAgB,oBAAoB,CAAC,EAAc;IAC/C,mBAAmB,GAAG,EAAE,CAAA;AAC5B,CAAC;AAED,SAAgB,wBAAwB,CAAC,GAAW;IAChD,QAAQ,GAAG,GAAG,CAAA;IACd,mBAAmB,EAAE,EAAE,CAAA,CAAC,mDAAmD;AAC/E,CAAC;AAED,SAAgB,wBAAwB;IACpC,OAAO,QAAQ,CAAA;AACnB,CAAC","sourcesContent":["// Version is inlined here — keep in sync with package.json when releasing.\n// The publish.sh script should bump this string alongside package.json.\nconst WASM_VERSION = '3.0.2'\n// jsDelivr syncs from npm automatically within ~5 min of publish.\n// GitHub release fallback (attach mel-spectrogram.js as a release asset):\n// https://github.com/deeeed/audiolab/releases/download/@siteed/audio-studio@VERSION/mel-spectrogram.js\n// To use the fallback: setMelSpectrogramWasmUrl('<url>') before any mel-spectrogram API call.\nconst DEFAULT_WASM_CDN = `https://cdn.jsdelivr.net/npm/@siteed/audio-studio@${WASM_VERSION}/prebuilt/wasm/mel-spectrogram.js`\n\nlet _wasmUrl: string = DEFAULT_WASM_CDN\nlet _modulePromiseReset: (() => void) | null = null\n\nexport function _registerModuleReset(fn: () => void): void {\n _modulePromiseReset = fn\n}\n\nexport function setMelSpectrogramWasmUrl(url: string): void {\n _wasmUrl = url\n _modulePromiseReset?.() // invalidate cached module so next call re-fetches\n}\n\nexport function getMelSpectrogramWasmUrl(): string {\n return _wasmUrl\n}\n"]}
|
package/build/cjs/index.js
CHANGED
|
@@ -18,7 +18,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
18
18
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
19
|
};
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
exports.ExpoAudioStreamModule = exports.useSharedAudioRecorder = exports.useAudioRecorder = exports.MAX_DURATION_MS = exports.computeMelFrameWasm = exports.initMelStreamingWasm = exports.extractMelSpectrogram = exports.extractAudioData = exports.trimAudio = exports.extractPreview = exports.extractAudioAnalysis = exports.extractRawWavAnalysis = exports.AudioStudioModule = exports.AudioRecorderProvider = exports.useAudioDevices = exports.audioDeviceManager = exports.AudioDeviceManager = exports.validateRecordingConfig = exports.getFallbackBitDepth = exports.getFallbackEncoding = exports.isBitDepthSupported = exports.isEncodingSupported = exports.getPlatformCapabilities = void 0;
|
|
21
|
+
exports.ExpoAudioStreamModule = exports.useSharedAudioRecorder = exports.useAudioRecorder = exports.MAX_DURATION_MS = exports.computeMelFrameWasm = exports.initMelStreamingWasm = exports.extractMelSpectrogram = exports.extractAudioData = exports.trimAudio = exports.extractPreview = exports.extractAudioAnalysis = exports.extractRawWavAnalysis = exports.AudioStudioModule = exports.AudioRecorderProvider = exports.setMelSpectrogramWasmUrl = exports.useAudioDevices = exports.audioDeviceManager = exports.AudioDeviceManager = exports.validateRecordingConfig = exports.getFallbackBitDepth = exports.getFallbackEncoding = exports.isBitDepthSupported = exports.isEncodingSupported = exports.getPlatformCapabilities = void 0;
|
|
22
22
|
const extractAudioAnalysis_1 = require("./AudioAnalysis/extractAudioAnalysis");
|
|
23
23
|
Object.defineProperty(exports, "extractRawWavAnalysis", { enumerable: true, get: function () { return extractAudioAnalysis_1.extractRawWavAnalysis; } });
|
|
24
24
|
Object.defineProperty(exports, "extractAudioAnalysis", { enumerable: true, get: function () { return extractAudioAnalysis_1.extractAudioAnalysis; } });
|
|
@@ -59,6 +59,8 @@ Object.defineProperty(exports, "audioDeviceManager", { enumerable: true, get: fu
|
|
|
59
59
|
// Export useAudioDevices hook
|
|
60
60
|
var useAudioDevices_1 = require("./hooks/useAudioDevices");
|
|
61
61
|
Object.defineProperty(exports, "useAudioDevices", { enumerable: true, get: function () { return useAudioDevices_1.useAudioDevices; } });
|
|
62
|
+
var wasmConfig_1 = require("./AudioAnalysis/wasmConfig");
|
|
63
|
+
Object.defineProperty(exports, "setMelSpectrogramWasmUrl", { enumerable: true, get: function () { return wasmConfig_1.setMelSpectrogramWasmUrl; } });
|
|
62
64
|
/** @deprecated Use AudioStudioModule instead */
|
|
63
65
|
exports.ExpoAudioStreamModule = AudioStudioModule_1.default;
|
|
64
66
|
//# sourceMappingURL=index.js.map
|
package/build/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,eAAe;;;;;;;;;;;;;;;;;;;;AAEf,+EAG6C;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,eAAe;;;;;;;;;;;;;;;;;;;;AAEf,+EAG6C;AA6CzC,sGA/CA,4CAAqB,OA+CA;AACrB,qGA/CA,2CAAoB,OA+CA;AA7CxB,uEAAmE;AAgD/D,iGAhDK,mCAAgB,OAgDL;AA/CpB,iFAG8C;AA6C1C,sGA/CA,6CAAqB,OA+CA;AAGrB,gGAjDA,uCAAe,OAiDA;AA/CnB,mEAA+D;AAyC3D,+FAzCK,+BAAc,OAyCL;AAxClB,2EAG2C;AAyCvC,qGA3CA,yCAAoB,OA2CA;AACpB,oGA3CA,wCAAmB,OA2CA;AAzCvB,qEAGiC;AA6B7B,sGA/BA,8CAAqB,OA+BA;AAYrB,uGA1CA,+CAAsB,OA0CA;AAxC1B,4EAAmD;AA6B/C,4BA7BG,2BAAiB,CA6BH;AA5BrB,2CAAuC;AAgCnC,0FAhCK,qBAAS,OAgCL;AA/Bb,yDAAqD;AAqCjD,iGArCK,mCAAgB,OAqCL;AAnCpB,8DAA2C;AAC3C,yDAAsC;AACtC,yDAAsC;AAEtC,+BAA+B;AAC/B,uEAQwC;AAPpC,8HAAA,uBAAuB,OAAA;AACvB,0HAAA,mBAAmB,OAAA;AACnB,0HAAA,mBAAmB,OAAA;AACnB,0HAAA,mBAAmB,OAAA;AACnB,0HAAA,mBAAmB,OAAA;AACnB,8HAAA,uBAAuB,OAAA;AAI3B,4BAA4B;AAC5B,2DAA6E;AAApE,wHAAA,kBAAkB,OAAA;AAAE,wHAAA,kBAAkB,OAAA;AAE/C,8BAA8B;AAC9B,2DAAyD;AAAhD,kHAAA,eAAe,OAAA;AAExB,yDAAqE;AAA5D,sHAAA,wBAAwB,OAAA;AAsBjC,gDAAgD;AACnC,QAAA,qBAAqB,GAAG,2BAAiB,CAAA","sourcesContent":["// src/index.ts\n\nimport {\n extractRawWavAnalysis,\n extractAudioAnalysis,\n} from './AudioAnalysis/extractAudioAnalysis'\nimport { extractAudioData } from './AudioAnalysis/extractAudioData'\nimport {\n extractMelSpectrogram,\n MAX_DURATION_MS,\n} from './AudioAnalysis/extractMelSpectrogram'\nimport { extractPreview } from './AudioAnalysis/extractPreview'\nimport {\n initMelStreamingWasm,\n computeMelFrameWasm,\n} from './AudioAnalysis/melSpectrogramWasm'\nimport {\n AudioRecorderProvider,\n useSharedAudioRecorder,\n} from './AudioRecorder.provider'\nimport AudioStudioModule from './AudioStudioModule'\nimport { trimAudio } from './trimAudio'\nimport { useAudioRecorder } from './useAudioRecorder'\n\nexport * from './utils/convertPCMToFloat32'\nexport * from './utils/getWavFileInfo'\nexport * from './utils/writeWavHeader'\n\n// Export platform capabilities\nexport {\n getPlatformCapabilities,\n isEncodingSupported,\n isBitDepthSupported,\n getFallbackEncoding,\n getFallbackBitDepth,\n validateRecordingConfig,\n type PlatformCapabilities,\n} from './constants/platformLimitations'\n\n// Export AudioDeviceManager\nexport { AudioDeviceManager, audioDeviceManager } from './AudioDeviceManager'\n\n// Export useAudioDevices hook\nexport { useAudioDevices } from './hooks/useAudioDevices'\n\nexport { setMelSpectrogramWasmUrl } from './AudioAnalysis/wasmConfig'\n\nexport {\n AudioRecorderProvider,\n AudioStudioModule,\n extractRawWavAnalysis,\n extractAudioAnalysis,\n extractPreview,\n trimAudio,\n extractAudioData,\n extractMelSpectrogram,\n initMelStreamingWasm,\n computeMelFrameWasm,\n MAX_DURATION_MS,\n useAudioRecorder,\n useSharedAudioRecorder,\n}\n\n// Export all types\nexport type * from './AudioAnalysis/AudioAnalysis.types'\nexport type * from './AudioStudio.types'\n\n/** @deprecated Use AudioStudioModule instead */\nexport const ExpoAudioStreamModule = AudioStudioModule\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
var createMelSpectrogramModule = (() => {
|
|
3
|
+
var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
|
|
4
|
+
|
|
5
|
+
return (
|
|
6
|
+
function(moduleArg = {}) {
|
|
7
|
+
|
|
8
|
+
var Module=moduleArg;var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.startsWith("blob:")){scriptDirectory=""}else{scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}{read_=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=(url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.error.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(typeof WebAssembly!="object"){abort("no native wasm support detected")}function intArrayFromBase64(s){var decoded=atob(s);var bytes=new Uint8Array(decoded.length);for(var i=0;i<decoded.length;++i){bytes[i]=decoded.charCodeAt(i)}return bytes}function tryParseAsDataURI(filename){if(!isDataURI(filename)){return}return intArrayFromBase64(filename.slice(dataURIPrefix.length))}var wasmMemory;var ABORT=false;var EXITSTATUS;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAPU16"]=HEAPU16=new Uint16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);Module["HEAPF32"]=HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b)}var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";var isDataURI=filename=>filename.startsWith(dataURIPrefix);var wasmBinaryFile;wasmBinaryFile="data:application/octet-stream;base64,AGFzbQEAAAABvAEcYAF/AX9gAX8AYAN/f38Bf2ADf39/AGAGf39/f39/AGAEf39/fwBgAX0BfWAAAGACf38Bf2AFf39/f38AYAV/f39/fwF/YAJ/fwBgAAF/YAF8AXxgAXwBfWABfwF9YAN/fn8BfmAEf39/fwF/YAx/f39/f39/fX1/f38Bf2AIf39/f399fX8AYAh/f39/f39/fwF/YAJ8fAF8YAJ8fwF/YAN8fH8BfGACf30BfWABfQF/YAABfWACfH8BfAK8AQcDZW52C19fY3hhX3Rocm93AAMDZW52FGVtc2NyaXB0ZW5fbWVtY3B5X2pzAAMWd2FzaV9zbmFwc2hvdF9wcmV2aWV3MQhmZF9jbG9zZQAAFndhc2lfc25hcHNob3RfcHJldmlldzEIZmRfd3JpdGUAEQNlbnYWZW1zY3JpcHRlbl9yZXNpemVfaGVhcAAAA2VudgVhYm9ydAAHFndhc2lfc25hcHNob3RfcHJldmlldzEHZmRfc2VlawAKA11cBwMEAAMICwsHAwsABwEBEgETAgwIAAUBFAEBBAIMFQoWFw0ODgYCCBgGDw8ZAAEBAgMGGgYGBhsNAAACEAAAAAEAAAABAgIIAwUFBQMJCQQEAAAAAAABAAwBAAoEBQFwAR8fBQcBAYACgIACBg0CfwFB0LgEC38BQQALB7sDFQZtZW1vcnkCABFfX3dhc21fY2FsbF9jdG9ycwAHBm1hbGxvYwBGBGZyZWUARxlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQAXbWVsX3NwZWN0cm9ncmFtX2NvbXB1dGUAFhRtZWxfc3BlY3Ryb2dyYW1fZnJlZQAXFG1lbF9zcGVjdHJvZ3JhbV9pbml0ABgdbWVsX3NwZWN0cm9ncmFtX2NvbXB1dGVfZnJhbWUAGRptZWxfc3BlY3Ryb2dyYW1fZ2V0X25fbWVscwAaFmF1ZGlvX2ZlYXR1cmVzX2NvbXB1dGUAHxNhdWRpb19mZWF0dXJlc19mcmVlACAaYXVkaW9fZmVhdHVyZXNfZnJlZV9hcnJheXMAIRNhdWRpb19mZWF0dXJlc19pbml0ACIcYXVkaW9fZmVhdHVyZXNfY29tcHV0ZV9mcmFtZQAjGWF1ZGlvX2ZlYXR1cmVzX2dldF9uX21mY2MAJAlzdGFja1NhdmUAXwxzdGFj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ACABIAMgAkQAAGAaYbTQPaIiAKEiBSACRHNwAy6KGaM7oiADIAWhIAChoSIEoSIAOQMAIAkgAL1CNIinQf8PcWtBMkgEQCAFIQMMAQsgASAFIAJEAAAALooZozuiIgChIgMgAkTBSSAlmoN7OaIgBSADoSAAoaEiBKEiADkDAAsgASADIAChIAShOQMIDAELIAhBgIDA/wdPBEAgASAAIAChIgA5AwAgASAAOQMIQQAhBgwBCyALQv////////8Hg0KAgICAgICAsMEAhL8hAEEAIQZBASEJA0AgB0EQaiAGQQN0agJ/IACZRAAAAAAAAOBBYwRAIACqDAELQYCAgIB4C7ciAjkDACAAIAKhRAAAAAAAAHBBoiEAQQEhBiAJQQFxIQpBACEJIAoNAAsgByAAOQMgQQIhBgNAIAYiCUEBayEGIAdBEGogCUEDdGorAwBEAAAAAAAAAABhDQALIAdBEGogByAIQRR2QZYIayAJQQFqQQEQJiEGIAcrAwAhACALQgBTBEAgASAAmjkDACABIAcrAwiaOQMIQQAgBmshBgwBCyABIAA5AwAgASAHKwMIOQMICyAHQTBqJAAgBguZAQEDfCAAIACiIgMgAyADoqIgA0R81c9aOtnlPaJE65wriublWr6goiADIANEff6xV+Mdxz6iRNVhwRmgASq/oKJEpvgQERERgT+goCEFIAMgAKIhBCACRQRAIAQgAyAFokRJVVVVVVXFv6CiIACgDwsgACADIAFEAAAAAAAA4D+iIAUgBKKhoiABoSAERElVVVVVVcU/oqChC70BAgF8An8jAEEQayICJAACfCAAvUIgiKdB/////wdxIgNB+8Ok/wNNBEBEAAAAAAAA8D8gA0GewZryA0kNARogAEQAAAAAAAAAABAlDAELIAAgAKEgA0GAgMD/B08NABogACACECchAyACKwMIIQAgAisDACEBAkACQAJAAkAgA0EDcQ4DAAECAwsgASAAECUMAwsgASAAQQEQKJoMAgsgASAAECWaDAELIAEgAEEBECgLIQEgAkEQaiQAIAELTwEBfCAAIACiIgAgACAAoiIBoiAARGlQ7uBCk/k+okQnHg/oh8BWv6CiIAFEQjoF4VNVpT+iIABEgV4M/f//37+iRAAAAAAAAPA/oKCgtgtLAQJ8IAAgAKIiASAAoiICIAEgAaKiIAFE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NgIMIAAgA2ogBzYCAEH0NEH0NCgCAEEBayIDQX8gAxs2AgALCzUBAX9BASAAIABBAU0bIQECQANAIAEQRiIADQFBxDgoAgAiAARAIAARBwAMAQsLEAUACyAACwwAIABB2C82AgAgAAsOACAAQdAAahBGQdAAagsGACAAEEcLdAEBfyACRQRAIAAoAgQgASgCBEYPCyAAIAFGBEBBAQ8LIAEoAgQiAi0AACEBAkAgACgCBCIDLQAAIgBFDQAgACABRw0AA0AgAi0AASEBIAMtAAEiAEUNASACQQFqIQIgA0EBaiEDIAAgAUYNAAsLIAAgAUYLmgEBAX8jAEFAaiIDJAACf0EBIAAgAUEAEEwNABpBACABRQ0AGkEAIAFBuC0QTiIBRQ0AGiADQQxqQTQQLhogA0EBNgI4IANBfzYCFCADIAA2AhAgAyABNgIIIAEgA0EIaiACKAIAQQEgASgCACgCHBEFACADKAIgIgBBAUYEQCACIAMoAhg2AgALIABBAUYLIQAgA0FAayQAIAALhQMBBH8jAEHwAGsiAiQAIAAoAgAiA0EEaygCACEEIANBCGsoAgAhAyACQgA3AlAgAkIANwJYIAJCADcCYCACQgA3AGcgAkIANwJIIAJBADYCRCACQYgtNgJAIAIgADYCPCACIAE2AjggACADaiEFAkAgBCABQQAQTARAQQAgBSADGyEADAELIAAgBU4EQCACQgA3AC8gAkEYaiIDQgA3AgAgAkIANwIgIAJCADcCKCACQgA3AhAgAkEANgIMIAIgATYCCCACIAA2AgQgAiAENgIAIAJBATYCMCAEIAIgBSAFQQFBACAEKAIAKAIUEQQAIAMoAgANAQtBACEAIAQgAkE4aiAFQQFBACAEKAIAKAIYEQkAAkACQCACKAJcDgIAAQILIAIoAkxBACACKAJYQQFGG0EAIAIoAlRBAUYbQQAgAigCYEEBRhshAAwBCyACKAJQQQFHBEAgAigCYA0BIAIoAlRBAUcNASACKAJYQQFHDQELIAIoAkghAAsgAkHwAGokACAAC10BAX8gACgCECIDRQRAIABBATYCJCAAIAI2AhggACABNgIQDwsCQCABIANGBEAgACgCGEECRw0BIAAgAjYCGA8LIABBAToANiAAQQI2AhggACAAKAIkQQFqNgIkCwsYACAAIAEoAghBABBMBEAgASACIAMQTwsLMQAgACABKAIIQQAQTARAIAEgAiADEE8PCyAAKAIIIgAgASACIAMgACgCACgCHBEFAAuaAQAgAEEBOgA1AkAgACgCBCACRw0AIABBAToANAJAIAAoAhAiAkUEQCAAQQE2AiQgACADNgIYIAAgATYCECADQQFHDQIgACgCMEEBRg0BDAILIAEgAkYEQCAAKAIYIgJBAkYEQCAAIAM2AhggAyECCyAAKAIwQQFHDQIgAkEBRg0BDAILIAAgACgCJEEBajYCJAsgAEEBOgA2CwsgAAJAIAAoAgQgAUcNACAAKAIcQQFGDQAgACACNgIcCwvyAQAgACABKAIIIAQQTARAIAEgAiADEFMPCwJAIAAgASgCACAEEEwEQAJAIAIgASgCEEcEQCABKAIUIAJHDQELIANBAUcNAiABQQE2AiAPCyABIAM2AiACQCABKAIsQQRGDQAgAUEAOwE0IAAoAggiACABIAIgAkEBIAQgACgCACgCFBEEACABLQA1BEAgAUEDNgIsIAEtADRFDQEMAwsgAUEENgIsCyABIAI2AhQgASABKAIoQQFqNgIoIAEoAiRBAUcNASABKAIYQQJHDQEgAUEBOgA2DwsgACgCCCIAIAEgAiADIAQgACgCACgCGBEJAAsLkQEAIAAgASgCCCAEEEwEQCABIAIgAxBTDwsCQCAAIAEoAgAgBBBMRQ0AAkAgAiABKAIQRwRAIAEoAhQgAkcNAQsgA0EBRw0BIAFBATYCIA8LIAEgAjYCFCABIAM2AiAgASABKAIoQQFqNgIoAkAgASgCJEEBRw0AIAEoAhhBAkcNACABQQE6ADYLIAFBBDYCLAsLNwAgACABKAIIIAUQTARAIAEgAiADIAQQUg8LIAAoAggiACABIAIgAyAEIAUgACgCACgCFBEEAAsaACAAIAEoAgggBRBMBEAgASACIAMgBBBSCwsVACAARQRAQQAPCyAAQZguEE5BAEcLBQBBhwgLBQBBvQgLBQBBlggLOQECfyAAQcgwNgIAIABBBGooAgBBDGsiAkEIaiIBIAEoAgBBAWsiATYCACABQQBIBEAgAhBHCyAACwsAIAAQXBogABBHCwoAIABBBGooAgALBAAjAAsGACAAJAALEAAjACAAa0FwcSIAJAAgAAsiAQF+IAEgAq0gA61CIIaEIAQgABEQACIFQiCIpyQBIAWnCwv3KQkAQYAIC4cFdmVjdG9yAHN0ZDo6ZXhjZXB0aW9uAGJhZF9hcnJheV9uZXdfbGVuZ3RoAG11dGV4IGxvY2sgZmFpbGVkAHN0ZDo6YmFkX2FsbG9jAGtpc3MgZmZ0IHVzYWdlIGVycm9yOiBpbXByb3BlciBhbGxvYwBNZW1vcnkgYWxsb2NhdGlvbiBlcnJvci4AUmVhbCBGRlQgb3B0aW1pemF0aW9uIG11c3QgYmUgZXZlbi4ATWVtb3J5IGFsbG9jYXRpb24gZmFpbGVkLgBmb3V0IGJ1ZmZlciBOVUxMLgBbRVJST1JdIC9Vc2Vycy9kZWVlZWQvZGV2L2F1ZGlvbGFiL3BhY2thZ2VzL2F1ZGlvLXN0dWRpby9jcHAva2lzc19mZnQva2lzc19mZnQuYzozODcgAFtFUlJPUl0gL1VzZXJzL2RlZWVlZC9kZXYvYXVkaW9sYWIvcGFja2FnZXMvYXVkaW8tc3R1ZGlvL2NwcC9raXNzX2ZmdC9raXNzX2ZmdC5jOjIwNyAAW0VSUk9SXSAvVXNlcnMvZGVlZWVkL2Rldi9hdWRpb2xhYi9wYWNrYWdlcy9hdWRpby1zdHVkaW8vY3BwL2tpc3NfZmZ0L2tpc3NfZmZ0LmM6MzgxIABbRVJST1JdIC9Vc2Vycy9kZWVlZWQvZGV2L2F1ZGlvbGFiL3BhY2thZ2VzL2F1ZGlvLXN0dWRpby9jcHAva2lzc19mZnQva2lzc19mZnRyLmM6NzAgAFtFUlJPUl0gL1VzZXJzL2RlZWVlZC9kZXYvYXVkaW9sYWIvcGFja2FnZXMvYXVkaW8tc3R1ZGlvL2NwcC9raXNzX2ZmdC9raXNzX2ZmdHIuYzozMCAAQZANC9cVAwAAAAQAAAAEAAAABgAAAIP5ogBETm4A/CkVANFXJwDdNPUAYtvAADyZlQBBkEMAY1H+ALveqwC3YcUAOm4kANJNQgBJBuAACeouAByS0QDrHf4AKbEcAOg+pwD1NYIARLsuAJzphAC0JnAAQX5fANaROQBTgzkAnPQ5AItfhAAo+b0A+B87AN7/lwAPmAUAES/vAApaiwBtH20Az342AAnLJwBGT7cAnmY/AC3qXwC6J3UA5evHAD178QD3OQcAklKKAPtr6gAfsV8ACF2NADADVgB7/EYA8KtrACC8zwA29JoA46kdAF5hkQAIG+YAhZllAKAUXwCNQGgAgNj/ACdzTQAGBjEAylYVAMmocwB74mAAa4zAABnERwDNZ8MACejcAFmDKgCLdsQAphyWAESv3QAZV9EApT4FAAUH/wAzfj8AwjLoAJhP3gC7fTIAJj3DAB5r7wCf+F4ANR86AH/yygDxhx0AfJAhAGokfADVbvoAMC13ABU7QwC1FMYAwxmdAK3EwgAsTUEADABdAIZ9RgDjcS0Am8aaADNiAAC00nwAtKeXADdV1QDXPvYAoxAYAE12/ABknSoAcNerAGN8+AB6sFcAFxXnAMBJVgA71tkAp4Q4ACQjywDWincAWlQjAAAfuQDxChsAGc7fAJ8x/wBmHmoAmVdhAKz7RwB+f9gAImW3ADLoiQDmv2AA78TNAGw2CQBdP9QAFt7XAFg73gDem5IA0iIoACiG6ADiWE0AxsoyAAjjFgDgfcsAF8BQAPMdpwAY4FsALhM0AIMSYgCDSAEA9Y5bAK2wfwAe6fIASEpDABBn0wCq3dgArl9CAGphzgAKKKQA05m0AAam8gBcd38Ao8KDAGE8iACKc3gAr4xaAG/XvQAtpmMA9L/LAI2B7wAmwWcAVcpFAMrZNgAoqNIAwmGNABLJdwAEJhQAEkabAMRZxADIxUQATbKRAAAX8wDUQ60AKUnlAP3VEAAAvvwAHpTMAHDO7gATPvUA7PGAALPnwwDH+CgAkwWUAMFxPgAuCbMAC0XzAIgSnACrIHsALrWfAEeSwgB7Mi8ADFVtAHKnkABr5x8AMcuWAHkWSgBBeeIA9N+JAOiUlwDi5oQAmTGXAIjtawBfXzYAu/0OAEiatABnpGwAcXJCAI1dMgCfFbgAvOUJAI0xJQD3dDkAMAUcAA0MAQBLCGgALO5YAEeqkAB05wIAvdYkAPd9pgBuSHIAnxbvAI6UpgC0kfYA0VNRAM8K8gAgmDMA9Ut+ALJjaADdPl8AQF0DAIWJfwBVUikAN2TAAG3YEAAySDIAW0x1AE5x1ABFVG4ACwnBACr1aQAUZtUAJwedAF0EUAC0O9sA6nbFAIf5FwBJa30AHSe6AJZpKQDGzKwArRRUAJDiagCI2YkALHJQAASkvgB3B5QA8zBwAAD8JwDqcagAZsJJAGTgPQCX3YMAoz+XAEOU/QANhowAMUHeAJI5nQDdcIwAF7fnAAjfOwAVNysAXICgAFqAkwAQEZIAD+jYAGyArwDb/0sAOJAPAFkYdgBipRUAYcu7AMeJuQAQQL0A0vIEAEl1JwDrtvYA2yK7AAoUqgCJJi8AZIN2AAk7MwAOlBoAUTqqAB2jwgCv7a4AXCYSAG3CTQAtepwAwFaXAAM/gwAJ8PYAK0CMAG0xmQA5tAcADCAVANjDWwD1ksQAxq1LAE7KpQCnN80A5qk2AKuSlADdQmgAGWPeAHaM7wBoi1IA/Ns3AK6hqwDfFTEAAK6hAAz72gBkTWYA7QW3ACllMABXVr8AR/86AGr5uQB1vvMAKJPfAKuAMABmjPYABMsVAPoiBgDZ5B0APbOkAFcbjwA2zQkATkLpABO+pAAzI7UA8KoaAE9lqADSwaUACz8PAFt4zQAj+XYAe4sEAIkXcgDGplMAb27iAO/rAACbSlgAxNq3AKpmugB2z88A0QIdALHxLQCMmcEAw613AIZI2gD3XaAAxoD0AKzwLwDd7JoAP1y8ANDebQCQxx8AKtu2AKMlOgAAr5oArVOTALZXBAApLbQAS4B+ANoHpwB2qg4Ae1mhABYSKgDcty0A+uX9AInb/gCJvv0A5HZsAAap/AA+gHAAhW4VAP2H/wAoPgcAYWczACoYhgBNveoAs+evAI9tbgCVZzkAMb9bAITXSAAw3xYAxy1DACVhNQDJcM4AMMu4AL9s/QCkAKIABWzkAFrdoAAhb0cAYhLSALlchABwYUkAa1bgAJlSAQBQVTcAHtW3ADPxxAATbl8AXTDkAIUuqQAdssMAoTI2AAi3pADqsdQAFvchAI9p5AAn/3cADAOAAI1ALQBPzaAAIKWZALOi0wAvXQoAtPlCABHaywB9vtAAm9vBAKsXvQDKooEACGpcAC5VFwAnAFUAfxTwAOEHhgAUC2QAlkGNAIe+3gDa/SoAayW2AHuJNAAF8/4Aub+eAGhqTwBKKqgAT8RaAC34vADXWpgA9MeVAA1NjQAgOqYApFdfABQ/sQCAOJUAzCABAHHdhgDJ3rYAv2D1AE1lEQABB2sAjLCsALLA0ABRVUgAHvsOAJVywwCjBjsAwEA1AAbcewDgRcwATin6ANbKyADo80EAfGTeAJtk2ADZvjEApJfDAHdY1ABp48UA8NoTALo6PABGGEYAVXVfANK99QBuksYArC5dAA5E7QAcPkIAYcSHACn96QDn1vMAInzKAG+RNQAI4MUA/9eNAG5q4gCw/cYAkwjBAHxddABrrbIAzW6dAD5yewDGEWoA98+pAClz3wC1yboAtwBRAOKyDQB0uiQA5X1gAHTYigANFSwAgRgMAH5mlAABKRYAn3p2AP39vgBWRe8A2X42AOzZEwCLurkAxJf8ADGoJwDxbsMAlMU2ANioVgC0qLUAz8wOABKJLQBvVzQALFaJAJnO4wDWILkAa16qAD4qnAARX8wA/QtKAOH0+wCOO20A4oYsAOnUhAD8tKkA7+7RAC41yQAvOWEAOCFEABvZyACB/AoA+0pqAC8c2ABTtIQATpmMAFQizAAqVdwAwMbWAAsZlgAacLgAaZVkACZaYAA/Uu4AfxEPAPS1EQD8y/UANLwtADS87gDoXcwA3V5gAGeOmwCSM+8AyRe4AGFYmwDhV7wAUYPGANg+EADdcUgALRzdAK8YoQAhLEYAWfPXANl6mACeVMAAT4b6AFYG/ADlea4AiSI2ADitIgBnk9wAVeiqAIImOADK55sAUQ2kAJkzsQCp1w4AaQVIAGWy8AB/iKcAiEyXAPnRNgAhkrMAe4JKAJjPIQBAn9wA3EdVAOF0OgBn60IA/p3fAF7UXwB7Z6QAuqx6AFX2ogAriCMAQbpVAFluCAAhKoYAOUeDAInj5gDlntQASftAAP9W6QAcD8oAxVmKAJT6KwDTwcUAD8XPANtargBHxYYAhUNiACGGOwAseZQAEGGHACpMewCALBoAQ78SAIgmkAB4PIkAqMTkAOXbewDEOsIAJvTqAPdnigANkr8AZaMrAD2TsQC9fAsApFHcACfdYwBp4d0AmpQZAKgplQBozigACe20AESfIABOmMoAcIJjAH58IwAPuTIAp/WOABRW5wAh8QgAtZ0qAG9+TQClGVEAtfmrAILf1gCW3WEAFjYCAMQ6nwCDoqEAcu1tADmNegCCuKkAazJcAEYnWwAANO0A0gB3APz0VQABWU0A4HGAAEHzIgvHDkD7Ifk/AAAAAC1EdD4AAACAmEb4PAAAAGBRzHg7AAAAgIMb8DkAAABAICV6OAAAAIAiguM2AAAAAB3zaTUAAAAAAADwP3SFFdOw2e8/D4n5bFi17z9RWxLQAZPvP3tRfTy4cu8/qrloMYdU7z84YnVuejjvP+HeH/WdHu8/FbcxCv4G7z/LqTo3p/HuPyI0Ekym3u4/LYlhYAjO7j8nKjbV2r/uP4JPnVYrtO4/KVRI3Qer7j+FVTqwfqTuP807f2aeoO4/dF/s6HWf7j+HAetzFKHuPxPOTJmJpe4/26AqQuWs7j/lxc2wN7fuP5Dwo4KRxO4/XSU+sgPV7j+t01qZn+juP0de+/J2/+4/nFKF3ZsZ7z9pkO/cIDfvP4ek+9wYWO8/X5t7M5d87z/akKSir6TvP0BFblt20O8/AAAAAAAA6EKUI5FL+GqsP/PE+lDOv84/1lIM/0Iu5j8AAAAAAAA4Q/6CK2VHFUdAlCORS/hqvD7zxPpQzr8uP9ZSDP9CLpY/vvP4eexh9j8ZMJZbxv7evz2Ir0rtcfU/pPzUMmgL27+wEPDwOZX0P3u3HwqLQde/hQO4sJXJ8z97z20a6Z3Tv6VkiAwZDfM/Mbby85sd0L+gjgt7Il7yP/B6OxsdfMm/PzQaSkq78T+fPK+T4/nCv7rlivBYI/E/XI14v8tgub+nAJlBP5XwP85fR7adb6q/AAAAAAAA8D8AAAAAAAAAAKxHmv2MYO4/PfUkn8o4sz+gagIfs6TsP7qROFSpdsQ/5vxqVzYg6z/S5MRKC4TOPy2qoWPRwuk/HGXG8EUG1D/tQXgD5oboP/ifGyycjtg/YkhT9dxn5z/Me7FOpODcP01+Cve2Ete/4DJoSb/K3j/e4/qfRxXnv7jINV9HFfc/vvP4eexh9j/eqoyA93vVvz2Ir0rtcfU/223Ap/C+0r+wEPDwOZX0P2c6UX+uHtC/hQO4sJXJ8z/pJIKm2DHLv6VkiAwZDfM/WHfACk9Xxr+gjgt7Il7yPwCBnMcrqsG/PzQaSkq78T9eDozOdk66v7rlivBYI/E/zBxhWjyXsb+nAJlBP5XwPx4M4Tj0UqK/AAAAAAAA8D8AAAAAAAAAAKxHmv2MYO4/hFnyXaqlqj+gagIfs6TsP7QuNqpTXrw/5vxqVzYg6z8I2yB35SbFPy2qoWPRwuk/cEciDYbCyz/tQXgD5oboP+F+oMiLBdE/YkhT9dxn5z8J7rZXMATUP+85+v5CLuY/NIO4SKMO0L9qC+ALW1fVPyNBCvL+/9+/vvP4eexh9j8ZMJZbxv7evz2Ir0rtcfU/pPzUMmgL27+wEPDwOZX0P3u3HwqLQde/hQO4sJXJ8z97z20a6Z3Tv6VkiAwZDfM/Mbby85sd0L+gjgt7Il7yP/B6OxsdfMm/PzQaSkq78T+fPK+T4/nCv7rlivBYI/E/XI14v8tgub+nAJlBP5XwP85fR7adb6q/AAAAAAAA8D8AAAAAAAAAAKxHmv2MYO4/PfUkn8o4sz+gagIfs6TsP7qROFSpdsQ/5vxqVzYg6z/S5MRKC4TOPy2qoWPRwuk/HGXG8EUG1D/tQXgD5oboP/ifGyycjtg/YkhT9dxn5z/Me7FOpODcPwtuSckWdtI/esZ1oGkZ17/duqdsCsfeP8j2vkhHFee/K7gqZUcV9z/AGAAATjEwX19jeHhhYml2MTE2X19zaGltX3R5cGVfaW5mb0UAAAAAVBcAAGQWAAC0GAAATjEwX19jeHhhYml2MTE3X19jbGFzc190eXBlX2luZm9FAAAAVBcAAJQWAACIFgAATjEwX19jeHhhYml2MTE3X19wYmFzZV90eXBlX2luZm9FAAAAVBcAAMQWAACIFgAATjEwX19jeHhhYml2MTE5X19wb2ludGVyX3R5cGVfaW5mb0UAVBcAAPQWAADoFgAAAAAAALgWAAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAAAAAAACcFwAACgAAABIAAAAMAAAADQAAAA4AAAATAAAAFAAAABUAAABOMTBfX2N4eGFiaXYxMjBfX3NpX2NsYXNzX3R5cGVfaW5mb0UAAAAAVBcAAHQXAAC4FgAAAAAAAAwYAAABAAAAFgAAABcAAAAAAAAANBgAAAEAAAAYAAAAGQAAAAAAAAD0FwAAAQAAABoAAAAbAAAAU3Q5ZXhjZXB0aW9uAAAAACwXAADkFwAAU3Q5YmFkX2FsbG9jAAAAAFQXAAD8FwAA9BcAAFN0MjBiYWRfYXJyYXlfbmV3X2xlbmd0aAAAAABUFwAAGBgAAAwYAAAAAAAAZBgAAAIAAAAcAAAAHQAAAFN0MTFsb2dpY19lcnJvcgBUFwAAVBgAAPQXAAAAAAAAmBgAAAIAAAAeAAAAHQAAAFN0MTJsZW5ndGhfZXJyb3IAAAAAVBcAAIQYAABkGAAAU3Q5dHlwZV9pbmZvAAAAACwXAACkGABBwDELAQUAQcwxCwEHAEHkMQsKCAAAAAkAAABQGgBB/DELAQIAQYwyCwj//////////wBB0DILA1AcAQ==";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}var binary=tryParseAsDataURI(file);if(binary){return binary}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}function getBinaryPromise(binaryFile){return Promise.resolve().then(()=>getBinarySync(binaryFile))}function instantiateArrayBuffer(binaryFile,imports,receiver){return getBinaryPromise(binaryFile).then(binary=>WebAssembly.instantiate(binary,imports)).then(instance=>instance).then(receiver,reason=>{err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)})}function instantiateAsync(binary,binaryFile,imports,callback){return instantiateArrayBuffer(binaryFile,imports,callback)}function createWasm(){var info={"env":wasmImports,"wasi_snapshot_preview1":wasmImports};function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["memory"];updateMemoryViews();addOnInit(wasmExports["__wasm_call_ctors"]);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err(`Module.instantiateWasm callback failed with error: ${e}`);readyPromiseReject(e)}}instantiateAsync(wasmBinary,wasmBinaryFile,info,receiveInstantiationResult).catch(readyPromiseReject);return{}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};function getValue(ptr,type="i8"){if(type.endsWith("*"))type="*";switch(type){case"i1":return HEAP8[ptr>>0];case"i8":return HEAP8[ptr>>0];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":abort("to do getValue(i64) use WASM_BIGINT");case"float":return HEAPF32[ptr>>2];case"double":return HEAPF64[ptr>>3];case"*":return HEAPU32[ptr>>2];default:abort(`invalid type for getValue: ${type}`)}}var noExitRuntime=Module["noExitRuntime"]||true;class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12>>0]=caught}get_caught(){return HEAP8[this.ptr+12>>0]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13>>0]=rethrown}get_rethrown(){return HEAP8[this.ptr+13>>0]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}get_exception_ptr(){var isPointer=___cxa_is_pointer_type(this.get_type());if(isPointer){return HEAPU32[this.excPtr>>2]}var adjusted=this.get_adjusted_ptr();if(adjusted!==0)return adjusted;return this.excPtr}}var exceptionLast=0;var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast};var _abort=()=>{abort("")};var _emscripten_memcpy_js=(dest,src,num)=>HEAPU8.copyWithin(dest,src,src+num);var getHeapMax=()=>2147483648;var growMemory=size=>{var b=wasmMemory.buffer;var pages=(size-b.byteLength+65535)/65536;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}var alignUp=(x,multiple)=>x+(multiple-x%multiple)%multiple;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var _fd_close=fd=>52;var convertI32PairToI53Checked=(lo,hi)=>hi+2097152>>>0<4194305-!!lo?(lo>>>0)+hi*4294967296:NaN;function _fd_seek(fd,offset_low,offset_high,whence,newOffset){var offset=convertI32PairToI53Checked(offset_low,offset_high);return 70}var printCharBuffers=[null,[],[]];var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):undefined;var UTF8ArrayToString=(heapOrArray,idx,maxBytesToRead)=>{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx<endPtr){var u0=heapOrArray[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heapOrArray[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heapOrArray[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heapOrArray[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}return str};var printChar=(stream,curr)=>{var buffer=printCharBuffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}};var UTF8ToString=(ptr,maxBytesToRead)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):"";var SYSCALLS={varargs:undefined,get(){var ret=HEAP32[+SYSCALLS.varargs>>2];SYSCALLS.varargs+=4;return ret},getp(){return SYSCALLS.get()},getStr(ptr){var ret=UTF8ToString(ptr);return ret}};var _fd_write=(fd,iov,iovcnt,pnum)=>{var num=0;for(var i=0;i<iovcnt;i++){var ptr=HEAPU32[iov>>2];var len=HEAPU32[iov+4>>2];iov+=8;for(var j=0;j<len;j++){printChar(fd,HEAPU8[ptr+j])}num+=len}HEAPU32[pnum>>2]=num;return 0};var getCFunc=ident=>{var func=Module["_"+ident];return func};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer)};var lengthBytesUTF8=str=>{var len=0;for(var i=0;i<str.length;++i){var c=str.charCodeAt(i);if(c<=127){len++}else if(c<=2047){len+=2}else if(c>=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var stringToUTF8OnStack=str=>{var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret};var ccall=(ident,returnType,argTypes,args,opts)=>{var toC={"string":str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},"array":arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i<args.length;i++){var converter=toC[argTypes[i]];if(converter){if(stack===0)stack=stackSave();cArgs[i]=converter(args[i])}else{cArgs[i]=args[i]}}}var ret=func.apply(null,cArgs);function onDone(ret){if(stack!==0)stackRestore(stack);return convertReturnValue(ret)}ret=onDone(ret);return ret};var cwrap=(ident,returnType,argTypes,opts)=>{var numericArgs=!argTypes||argTypes.every(type=>type==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return function(){return ccall(ident,returnType,argTypes,arguments,opts)}};var wasmImports={__cxa_throw:___cxa_throw,abort:_abort,emscripten_memcpy_js:_emscripten_memcpy_js,emscripten_resize_heap:_emscripten_resize_heap,fd_close:_fd_close,fd_seek:_fd_seek,fd_write:_fd_write};var wasmExports=createWasm();var ___wasm_call_ctors=()=>(___wasm_call_ctors=wasmExports["__wasm_call_ctors"])();var _malloc=Module["_malloc"]=a0=>(_malloc=Module["_malloc"]=wasmExports["malloc"])(a0);var _free=Module["_free"]=a0=>(_free=Module["_free"]=wasmExports["free"])(a0);var _mel_spectrogram_compute=Module["_mel_spectrogram_compute"]=(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11)=>(_mel_spectrogram_compute=Module["_mel_spectrogram_compute"]=wasmExports["mel_spectrogram_compute"])(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11);var _mel_spectrogram_free=Module["_mel_spectrogram_free"]=a0=>(_mel_spectrogram_free=Module["_mel_spectrogram_free"]=wasmExports["mel_spectrogram_free"])(a0);var _mel_spectrogram_init=Module["_mel_spectrogram_init"]=(a0,a1,a2,a3,a4,a5,a6,a7)=>(_mel_spectrogram_init=Module["_mel_spectrogram_init"]=wasmExports["mel_spectrogram_init"])(a0,a1,a2,a3,a4,a5,a6,a7);var _mel_spectrogram_compute_frame=Module["_mel_spectrogram_compute_frame"]=(a0,a1,a2)=>(_mel_spectrogram_compute_frame=Module["_mel_spectrogram_compute_frame"]=wasmExports["mel_spectrogram_compute_frame"])(a0,a1,a2);var _mel_spectrogram_get_n_mels=Module["_mel_spectrogram_get_n_mels"]=()=>(_mel_spectrogram_get_n_mels=Module["_mel_spectrogram_get_n_mels"]=wasmExports["mel_spectrogram_get_n_mels"])();var _audio_features_compute=Module["_audio_features_compute"]=(a0,a1,a2,a3,a4,a5,a6,a7)=>(_audio_features_compute=Module["_audio_features_compute"]=wasmExports["audio_features_compute"])(a0,a1,a2,a3,a4,a5,a6,a7);var _audio_features_free=Module["_audio_features_free"]=a0=>(_audio_features_free=Module["_audio_features_free"]=wasmExports["audio_features_free"])(a0);var _audio_features_free_arrays=Module["_audio_features_free_arrays"]=a0=>(_audio_features_free_arrays=Module["_audio_features_free_arrays"]=wasmExports["audio_features_free_arrays"])(a0);var _audio_features_init=Module["_audio_features_init"]=(a0,a1,a2,a3,a4,a5)=>(_audio_features_init=Module["_audio_features_init"]=wasmExports["audio_features_init"])(a0,a1,a2,a3,a4,a5);var _audio_features_compute_frame=Module["_audio_features_compute_frame"]=(a0,a1,a2)=>(_audio_features_compute_frame=Module["_audio_features_compute_frame"]=wasmExports["audio_features_compute_frame"])(a0,a1,a2);var _audio_features_get_n_mfcc=Module["_audio_features_get_n_mfcc"]=()=>(_audio_features_get_n_mfcc=Module["_audio_features_get_n_mfcc"]=wasmExports["audio_features_get_n_mfcc"])();var stackSave=()=>(stackSave=wasmExports["stackSave"])();var stackRestore=a0=>(stackRestore=wasmExports["stackRestore"])(a0);var stackAlloc=a0=>(stackAlloc=wasmExports["stackAlloc"])(a0);var ___cxa_is_pointer_type=a0=>(___cxa_is_pointer_type=wasmExports["__cxa_is_pointer_type"])(a0);var dynCall_jiji=Module["dynCall_jiji"]=(a0,a1,a2,a3,a4)=>(dynCall_jiji=Module["dynCall_jiji"]=wasmExports["dynCall_jiji"])(a0,a1,a2,a3,a4);Module["ccall"]=ccall;Module["cwrap"]=cwrap;Module["getValue"]=getValue;var calledRun;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(){if(runDependencies>0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run();
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
return moduleArg.ready
|
|
12
|
+
}
|
|
13
|
+
);
|
|
14
|
+
})();
|
|
15
|
+
if (typeof exports === 'object' && typeof module === 'object')
|
|
16
|
+
module.exports = createMelSpectrogramModule;
|
|
17
|
+
else if (typeof define === 'function' && define['amd'])
|
|
18
|
+
define([], () => createMelSpectrogramModule);
|
|
@@ -1,126 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
function
|
|
3
|
-
|
|
4
|
-
modulePromise = (async () => {
|
|
5
|
-
// Same WASM module as mel spectrogram (now includes audio features)
|
|
6
|
-
// @ts-expect-error -- prebuilt Emscripten JS glue has no .d.ts
|
|
7
|
-
const mod = await import('../../prebuilt/wasm/mel-spectrogram.js');
|
|
8
|
-
const factory = mod.default ?? mod;
|
|
9
|
-
return factory();
|
|
10
|
-
})().catch((err) => {
|
|
11
|
-
modulePromise = null;
|
|
12
|
-
throw err;
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
return modulePromise;
|
|
1
|
+
// Native stub — WASM audio features is web-only.
|
|
2
|
+
export async function initAudioFeaturesWasm(_sampleRate, _fftLength, _nMfcc, _nMelFilters, _computeMfcc, _computeChroma) {
|
|
3
|
+
throw new Error('WASM audio features is not available on native');
|
|
16
4
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// Offset 4: float spectralFlatness (4 bytes)
|
|
20
|
-
// Offset 8: float spectralRolloff (4 bytes)
|
|
21
|
-
// Offset 12: float spectralBandwidth (4 bytes)
|
|
22
|
-
// Offset 16: float* mfcc (4 bytes pointer)
|
|
23
|
-
// Offset 20: int mfccCount (4 bytes)
|
|
24
|
-
// Offset 24: float* chromagram (4 bytes pointer)
|
|
25
|
-
// Offset 28: int chromagramCount (4 bytes)
|
|
26
|
-
const STRUCT_SIZE = 32;
|
|
27
|
-
function readResult(Module, ptr) {
|
|
28
|
-
const spectralCentroid = Module.getValue(ptr, 'float');
|
|
29
|
-
const spectralFlatness = Module.getValue(ptr + 4, 'float');
|
|
30
|
-
const spectralRolloff = Module.getValue(ptr + 8, 'float');
|
|
31
|
-
const spectralBandwidth = Module.getValue(ptr + 12, 'float');
|
|
32
|
-
const mfccPtr = Module.getValue(ptr + 16, 'i32');
|
|
33
|
-
const mfccCount = Module.getValue(ptr + 20, 'i32');
|
|
34
|
-
const chromaPtr = Module.getValue(ptr + 24, 'i32');
|
|
35
|
-
const chromaCount = Module.getValue(ptr + 28, 'i32');
|
|
36
|
-
const mfcc = [];
|
|
37
|
-
if (mfccPtr && mfccCount > 0) {
|
|
38
|
-
const offset = mfccPtr >> 2;
|
|
39
|
-
for (let i = 0; i < mfccCount; i++) {
|
|
40
|
-
mfcc.push(Module.HEAPF32[offset + i]);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
const chromagram = [];
|
|
44
|
-
if (chromaPtr && chromaCount > 0) {
|
|
45
|
-
const offset = chromaPtr >> 2;
|
|
46
|
-
for (let i = 0; i < chromaCount; i++) {
|
|
47
|
-
chromagram.push(Module.HEAPF32[offset + i]);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return {
|
|
51
|
-
spectralCentroid,
|
|
52
|
-
spectralFlatness,
|
|
53
|
-
spectralRolloff,
|
|
54
|
-
spectralBandwidth,
|
|
55
|
-
mfcc,
|
|
56
|
-
chromagram,
|
|
57
|
-
};
|
|
5
|
+
export function computeAudioFeaturesFrameWasm(_samples) {
|
|
6
|
+
return null;
|
|
58
7
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
let streamingFramePtr = 0;
|
|
62
|
-
let streamingFrameCapacity = 0;
|
|
63
|
-
let streamingResultPtr = 0;
|
|
64
|
-
/**
|
|
65
|
-
* Initialise the WASM streaming audio features processor.
|
|
66
|
-
* Call once before computeAudioFeaturesFrameWasm().
|
|
67
|
-
*/
|
|
68
|
-
export async function initAudioFeaturesWasm(sampleRate, fftLength = 1024, nMfcc = 13, nMelFilters = 26, computeMfcc = true, computeChroma = true) {
|
|
69
|
-
const Module = await getModule();
|
|
70
|
-
streamingModule = Module;
|
|
71
|
-
Module._audio_features_init(sampleRate, fftLength, nMfcc, nMelFilters, computeMfcc ? 1 : 0, computeChroma ? 1 : 0);
|
|
72
|
-
// Pre-allocate result struct on WASM heap
|
|
73
|
-
if (streamingResultPtr)
|
|
74
|
-
Module._free(streamingResultPtr);
|
|
75
|
-
streamingResultPtr = Module._malloc(STRUCT_SIZE);
|
|
76
|
-
// Zero-initialize to prevent freeing garbage pointers on first use
|
|
77
|
-
Module.HEAPU8.fill(0, streamingResultPtr, streamingResultPtr + STRUCT_SIZE);
|
|
78
|
-
// Frame input buffer allocated on demand
|
|
79
|
-
streamingFrameCapacity = 0;
|
|
80
|
-
streamingFramePtr = 0;
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Compute audio features for a single frame via WASM C++.
|
|
84
|
-
* Returns null if not initialised or on error.
|
|
85
|
-
*/
|
|
86
|
-
export function computeAudioFeaturesFrameWasm(samples) {
|
|
87
|
-
if (!streamingModule || !streamingResultPtr)
|
|
88
|
-
return null;
|
|
89
|
-
const Module = streamingModule;
|
|
90
|
-
// (Re-)allocate frame input buffer if needed
|
|
91
|
-
if (samples.length > streamingFrameCapacity) {
|
|
92
|
-
if (streamingFramePtr)
|
|
93
|
-
Module._free(streamingFramePtr);
|
|
94
|
-
streamingFramePtr = Module._malloc(samples.length * 4);
|
|
95
|
-
streamingFrameCapacity = samples.length;
|
|
96
|
-
}
|
|
97
|
-
// Copy samples to WASM heap
|
|
98
|
-
Module.HEAPF32.set(samples, streamingFramePtr >> 2);
|
|
99
|
-
const ok = Module._audio_features_compute_frame(streamingFramePtr, samples.length, streamingResultPtr);
|
|
100
|
-
if (!ok)
|
|
101
|
-
return null;
|
|
102
|
-
const result = readResult(Module, streamingResultPtr);
|
|
103
|
-
// Free internal arrays (mfcc, chromagram) allocated by C
|
|
104
|
-
Module._audio_features_free_arrays(streamingResultPtr);
|
|
105
|
-
return result;
|
|
106
|
-
}
|
|
107
|
-
// --- Batch API ---
|
|
108
|
-
/**
|
|
109
|
-
* Compute audio features for a buffer of samples via WASM C++.
|
|
110
|
-
* Lazy-loads the WASM module on first call.
|
|
111
|
-
*/
|
|
112
|
-
export async function computeAudioFeaturesWasm(audioData, sampleRate, fftLength = 1024, nMfcc = 13, nMelFilters = 26, computeMfcc = true, computeChroma = true) {
|
|
113
|
-
const Module = await getModule();
|
|
114
|
-
const numSamples = audioData.length;
|
|
115
|
-
const inputPtr = Module._malloc(numSamples * 4);
|
|
116
|
-
Module.HEAPF32.set(audioData, inputPtr >> 2);
|
|
117
|
-
const resultPtr = Module._audio_features_compute(inputPtr, numSamples, sampleRate, fftLength, nMfcc, nMelFilters, computeMfcc ? 1 : 0, computeChroma ? 1 : 0);
|
|
118
|
-
Module._free(inputPtr);
|
|
119
|
-
if (resultPtr === 0) {
|
|
120
|
-
throw new Error('audio_features_compute returned null');
|
|
121
|
-
}
|
|
122
|
-
const result = readResult(Module, resultPtr);
|
|
123
|
-
Module._audio_features_free(resultPtr);
|
|
124
|
-
return result;
|
|
8
|
+
export async function computeAudioFeaturesWasm(_audioData, _sampleRate, _fftLength, _nMfcc, _nMelFilters, _computeMfcc, _computeChroma) {
|
|
9
|
+
throw new Error('WASM audio features is not available on native');
|
|
125
10
|
}
|
|
126
11
|
//# sourceMappingURL=audioFeaturesWasm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audioFeaturesWasm.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/audioFeaturesWasm.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AudioFeaturesWasmModule } from './audio-features-wasm'\n\nexport interface AudioFeaturesWasmResult {\n spectralCentroid: number\n spectralFlatness: number\n spectralRolloff: number\n spectralBandwidth: number\n mfcc: number[]\n chromagram: number[]\n}\n\nlet modulePromise: Promise<AudioFeaturesWasmModule> | null = null\n\nfunction getModule(): Promise<AudioFeaturesWasmModule> {\n if (!modulePromise) {\n modulePromise = (async () => {\n // Same WASM module as mel spectrogram (now includes audio features)\n // @ts-expect-error -- prebuilt Emscripten JS glue has no .d.ts\n const mod = await import('../../prebuilt/wasm/mel-spectrogram.js')\n const factory = mod.default ?? mod\n return factory() as Promise<AudioFeaturesWasmModule>\n })().catch((err) => {\n modulePromise = null\n throw err\n })\n }\n return modulePromise\n}\n\n// --- Struct layout for CAudioFeaturesResult (wasm32) ---\n// Offset 0: float spectralCentroid (4 bytes)\n// Offset 4: float spectralFlatness (4 bytes)\n// Offset 8: float spectralRolloff (4 bytes)\n// Offset 12: float spectralBandwidth (4 bytes)\n// Offset 16: float* mfcc (4 bytes pointer)\n// Offset 20: int mfccCount (4 bytes)\n// Offset 24: float* chromagram (4 bytes pointer)\n// Offset 28: int chromagramCount (4 bytes)\nconst STRUCT_SIZE = 32\n\nfunction readResult(\n Module: AudioFeaturesWasmModule,\n ptr: number\n): AudioFeaturesWasmResult {\n const spectralCentroid = Module.getValue(ptr, 'float')\n const spectralFlatness = Module.getValue(ptr + 4, 'float')\n const spectralRolloff = Module.getValue(ptr + 8, 'float')\n const spectralBandwidth = Module.getValue(ptr + 12, 'float')\n\n const mfccPtr = Module.getValue(ptr + 16, 'i32')\n const mfccCount = Module.getValue(ptr + 20, 'i32')\n const chromaPtr = Module.getValue(ptr + 24, 'i32')\n const chromaCount = Module.getValue(ptr + 28, 'i32')\n\n const mfcc: number[] = []\n if (mfccPtr && mfccCount > 0) {\n const offset = mfccPtr >> 2\n for (let i = 0; i < mfccCount; i++) {\n mfcc.push(Module.HEAPF32[offset + i])\n }\n }\n\n const chromagram: number[] = []\n if (chromaPtr && chromaCount > 0) {\n const offset = chromaPtr >> 2\n for (let i = 0; i < chromaCount; i++) {\n chromagram.push(Module.HEAPF32[offset + i])\n }\n }\n\n return {\n spectralCentroid,\n spectralFlatness,\n spectralRolloff,\n spectralBandwidth,\n mfcc,\n chromagram,\n }\n}\n\n// --- Streaming (per-frame) API ---\n\nlet streamingModule: AudioFeaturesWasmModule | null = null\nlet streamingFramePtr = 0\nlet streamingFrameCapacity = 0\nlet streamingResultPtr = 0\n\n/**\n * Initialise the WASM streaming audio features processor.\n * Call once before computeAudioFeaturesFrameWasm().\n */\nexport async function initAudioFeaturesWasm(\n sampleRate: number,\n fftLength = 1024,\n nMfcc = 13,\n nMelFilters = 26,\n computeMfcc = true,\n computeChroma = true\n): Promise<void> {\n const Module = await getModule()\n streamingModule = Module\n\n Module._audio_features_init(\n sampleRate,\n fftLength,\n nMfcc,\n nMelFilters,\n computeMfcc ? 1 : 0,\n computeChroma ? 1 : 0\n )\n\n // Pre-allocate result struct on WASM heap\n if (streamingResultPtr) Module._free(streamingResultPtr)\n streamingResultPtr = Module._malloc(STRUCT_SIZE)\n // Zero-initialize to prevent freeing garbage pointers on first use\n Module.HEAPU8.fill(0, streamingResultPtr, streamingResultPtr + STRUCT_SIZE)\n\n // Frame input buffer allocated on demand\n streamingFrameCapacity = 0\n streamingFramePtr = 0\n}\n\n/**\n * Compute audio features for a single frame via WASM C++.\n * Returns null if not initialised or on error.\n */\nexport function computeAudioFeaturesFrameWasm(\n samples: Float32Array\n): AudioFeaturesWasmResult | null {\n if (!streamingModule || !streamingResultPtr) return null\n const Module = streamingModule\n\n // (Re-)allocate frame input buffer if needed\n if (samples.length > streamingFrameCapacity) {\n if (streamingFramePtr) Module._free(streamingFramePtr)\n streamingFramePtr = Module._malloc(samples.length * 4)\n streamingFrameCapacity = samples.length\n }\n\n // Copy samples to WASM heap\n Module.HEAPF32.set(samples, streamingFramePtr >> 2)\n\n const ok = Module._audio_features_compute_frame(\n streamingFramePtr,\n samples.length,\n streamingResultPtr\n )\n if (!ok) return null\n\n const result = readResult(Module, streamingResultPtr)\n\n // Free internal arrays (mfcc, chromagram) allocated by C\n Module._audio_features_free_arrays(streamingResultPtr)\n\n return result\n}\n\n// --- Batch API ---\n\n/**\n * Compute audio features for a buffer of samples via WASM C++.\n * Lazy-loads the WASM module on first call.\n */\nexport async function computeAudioFeaturesWasm(\n audioData: Float32Array,\n sampleRate: number,\n fftLength = 1024,\n nMfcc = 13,\n nMelFilters = 26,\n computeMfcc = true,\n computeChroma = true\n): Promise<AudioFeaturesWasmResult> {\n const Module = await getModule()\n\n const numSamples = audioData.length\n const inputPtr = Module._malloc(numSamples * 4)\n Module.HEAPF32.set(audioData, inputPtr >> 2)\n\n const resultPtr = Module._audio_features_compute(\n inputPtr,\n numSamples,\n sampleRate,\n fftLength,\n nMfcc,\n nMelFilters,\n computeMfcc ? 1 : 0,\n computeChroma ? 1 : 0\n )\n\n Module._free(inputPtr)\n\n if (resultPtr === 0) {\n throw new Error('audio_features_compute returned null')\n }\n\n const result = readResult(Module, resultPtr)\n Module._audio_features_free(resultPtr)\n\n return result\n}\n"]}
|
|
1
|
+
{"version":3,"file":"audioFeaturesWasm.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/audioFeaturesWasm.ts"],"names":[],"mappings":"AAAA,iDAAiD;AAWjD,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACvC,WAAmB,EACnB,UAAmB,EACnB,MAAe,EACf,YAAqB,EACrB,YAAsB,EACtB,cAAwB;IAExB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAA;AACrE,CAAC;AAED,MAAM,UAAU,6BAA6B,CACzC,QAAsB;IAEtB,OAAO,IAAI,CAAA;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC1C,UAAwB,EACxB,WAAmB,EACnB,UAAmB,EACnB,MAAe,EACf,YAAqB,EACrB,YAAsB,EACtB,cAAwB;IAExB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAA;AACrE,CAAC","sourcesContent":["// Native stub — WASM audio features is web-only.\n\nexport interface AudioFeaturesWasmResult {\n spectralCentroid: number\n spectralFlatness: number\n spectralRolloff: number\n spectralBandwidth: number\n mfcc: number[]\n chromagram: number[]\n}\n\nexport async function initAudioFeaturesWasm(\n _sampleRate: number,\n _fftLength?: number,\n _nMfcc?: number,\n _nMelFilters?: number,\n _computeMfcc?: boolean,\n _computeChroma?: boolean\n): Promise<void> {\n throw new Error('WASM audio features is not available on native')\n}\n\nexport function computeAudioFeaturesFrameWasm(\n _samples: Float32Array\n): AudioFeaturesWasmResult | null {\n return null\n}\n\nexport async function computeAudioFeaturesWasm(\n _audioData: Float32Array,\n _sampleRate: number,\n _fftLength?: number,\n _nMfcc?: number,\n _nMelFilters?: number,\n _computeMfcc?: boolean,\n _computeChroma?: boolean\n): Promise<AudioFeaturesWasmResult> {\n throw new Error('WASM audio features is not available on native')\n}\n"]}
|