@siteed/audio-studio 3.0.1 → 3.0.2-beta.2
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 +153 -871
- package/build/cjs/AudioAnalysis/audioFeaturesWasm.web.js +4 -3
- package/build/cjs/AudioAnalysis/audioFeaturesWasm.web.js.map +1 -1
- package/build/cjs/AudioAnalysis/melSpectrogramWasm.web.js +7 -3
- package/build/cjs/AudioAnalysis/melSpectrogramWasm.web.js.map +1 -1
- 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/esm/AudioAnalysis/audioFeaturesWasm.web.js +4 -3
- package/build/esm/AudioAnalysis/audioFeaturesWasm.web.js.map +1 -1
- package/build/esm/AudioAnalysis/melSpectrogramWasm.web.js +7 -3
- package/build/esm/AudioAnalysis/melSpectrogramWasm.web.js.map +1 -1
- 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/types/AudioAnalysis/audioFeaturesWasm.web.d.ts.map +1 -1
- package/build/types/AudioAnalysis/melSpectrogramWasm.web.d.ts.map +1 -1
- 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 +2 -2
- package/src/AudioAnalysis/audioFeaturesWasm.web.ts +4 -3
- package/src/AudioAnalysis/melSpectrogramWasm.web.ts +8 -3
- package/src/AudioAnalysis/wasmConfig.ts +24 -0
- package/src/index.ts +2 -0
|
@@ -36,13 +36,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.initAudioFeaturesWasm = initAudioFeaturesWasm;
|
|
37
37
|
exports.computeAudioFeaturesFrameWasm = computeAudioFeaturesFrameWasm;
|
|
38
38
|
exports.computeAudioFeaturesWasm = computeAudioFeaturesWasm;
|
|
39
|
+
const wasmConfig_1 = require("./wasmConfig");
|
|
39
40
|
let modulePromise = null;
|
|
40
41
|
function getModule() {
|
|
41
42
|
if (!modulePromise) {
|
|
42
43
|
modulePromise = (async () => {
|
|
43
|
-
|
|
44
|
-
// @
|
|
45
|
-
const mod = await Promise.resolve().then(
|
|
44
|
+
const url = (0, wasmConfig_1.getMelSpectrogramWasmUrl)();
|
|
45
|
+
// webpackIgnore + @vite-ignore prevent bundlers from trying to resolve the URL
|
|
46
|
+
const mod = await Promise.resolve(`${url}`).then(s => __importStar(require(s)));
|
|
46
47
|
const factory = mod.default ?? mod;
|
|
47
48
|
return factory();
|
|
48
49
|
})().catch((err) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audioFeaturesWasm.web.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/audioFeaturesWasm.web.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.web.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/audioFeaturesWasm.web.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AudioFeaturesWasmModule } from './audio-features-wasm'\nimport { getMelSpectrogramWasmUrl } from './wasmConfig'\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 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<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"]}
|
|
@@ -36,13 +36,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.initMelStreamingWasm = initMelStreamingWasm;
|
|
37
37
|
exports.computeMelFrameWasm = computeMelFrameWasm;
|
|
38
38
|
exports.computeMelSpectrogramWasm = computeMelSpectrogramWasm;
|
|
39
|
+
const wasmConfig_1 = require("./wasmConfig");
|
|
39
40
|
let modulePromise = null;
|
|
41
|
+
(0, wasmConfig_1._registerModuleReset)(() => {
|
|
42
|
+
modulePromise = null;
|
|
43
|
+
});
|
|
40
44
|
function getModule() {
|
|
41
45
|
if (!modulePromise) {
|
|
42
46
|
modulePromise = (async () => {
|
|
43
|
-
|
|
44
|
-
// @
|
|
45
|
-
const mod = await Promise.resolve().then(
|
|
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)));
|
|
46
50
|
const factory = mod.default ?? mod;
|
|
47
51
|
return factory();
|
|
48
52
|
})().catch((err) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"melSpectrogramWasm.web.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/melSpectrogramWasm.web.ts"],"names":[],"mappings":"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","sourcesContent":["import type { MelSpectrogramWasmModule } from './mel-spectrogram-wasm'\n\nlet modulePromise: Promise<MelSpectrogramWasmModule> | null = null\n\nfunction getModule(): Promise<MelSpectrogramWasmModule> {\n if (!modulePromise) {\n modulePromise = (async () => {\n // Dynamic import of the prebuilt SINGLE_FILE Emscripten module\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<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"]}
|
|
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-beta.1';
|
|
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,cAAc,CAAA;AACnC,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-beta.1'\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"]}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { getMelSpectrogramWasmUrl } from './wasmConfig';
|
|
1
2
|
let modulePromise = null;
|
|
2
3
|
function getModule() {
|
|
3
4
|
if (!modulePromise) {
|
|
4
5
|
modulePromise = (async () => {
|
|
5
|
-
|
|
6
|
-
// @
|
|
7
|
-
const mod = await import(
|
|
6
|
+
const url = getMelSpectrogramWasmUrl();
|
|
7
|
+
// webpackIgnore + @vite-ignore prevent bundlers from trying to resolve the URL
|
|
8
|
+
const mod = await import(/* webpackIgnore: true */ /* @vite-ignore */ url);
|
|
8
9
|
const factory = mod.default ?? mod;
|
|
9
10
|
return factory();
|
|
10
11
|
})().catch((err) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audioFeaturesWasm.web.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/audioFeaturesWasm.web.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.web.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/audioFeaturesWasm.web.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AudioFeaturesWasmModule } from './audio-features-wasm'\nimport { getMelSpectrogramWasmUrl } from './wasmConfig'\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 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<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,10 +1,14 @@
|
|
|
1
|
+
import { getMelSpectrogramWasmUrl, _registerModuleReset } from './wasmConfig';
|
|
1
2
|
let modulePromise = null;
|
|
3
|
+
_registerModuleReset(() => {
|
|
4
|
+
modulePromise = null;
|
|
5
|
+
});
|
|
2
6
|
function getModule() {
|
|
3
7
|
if (!modulePromise) {
|
|
4
8
|
modulePromise = (async () => {
|
|
5
|
-
|
|
6
|
-
// @
|
|
7
|
-
const mod = await import(
|
|
9
|
+
const url = getMelSpectrogramWasmUrl();
|
|
10
|
+
// webpackIgnore + @vite-ignore prevent bundlers from trying to resolve the URL
|
|
11
|
+
const mod = await import(/* webpackIgnore: true */ /* @vite-ignore */ url);
|
|
8
12
|
const factory = mod.default ?? mod;
|
|
9
13
|
return factory();
|
|
10
14
|
})().catch((err) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"melSpectrogramWasm.web.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/melSpectrogramWasm.web.ts"],"names":[],"mappings":"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","sourcesContent":["import type { MelSpectrogramWasmModule } from './mel-spectrogram-wasm'\n\nlet modulePromise: Promise<MelSpectrogramWasmModule> | null = null\n\nfunction getModule(): Promise<MelSpectrogramWasmModule> {\n if (!modulePromise) {\n modulePromise = (async () => {\n // Dynamic import of the prebuilt SINGLE_FILE Emscripten module\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<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"]}
|
|
1
|
+
{"version":3,"file":"melSpectrogramWasm.web.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/melSpectrogramWasm.web.ts"],"names":[],"mappings":"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","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,21 @@
|
|
|
1
|
+
// Version is inlined here — keep in sync with package.json when releasing.
|
|
2
|
+
// The publish.sh script should bump this string alongside package.json.
|
|
3
|
+
const WASM_VERSION = '3.0.2-beta.1';
|
|
4
|
+
// jsDelivr syncs from npm automatically within ~5 min of publish.
|
|
5
|
+
// GitHub release fallback (attach mel-spectrogram.js as a release asset):
|
|
6
|
+
// https://github.com/deeeed/audiolab/releases/download/@siteed/audio-studio@VERSION/mel-spectrogram.js
|
|
7
|
+
// To use the fallback: setMelSpectrogramWasmUrl('<url>') before any mel-spectrogram API call.
|
|
8
|
+
const DEFAULT_WASM_CDN = `https://cdn.jsdelivr.net/npm/@siteed/audio-studio@${WASM_VERSION}/prebuilt/wasm/mel-spectrogram.js`;
|
|
9
|
+
let _wasmUrl = DEFAULT_WASM_CDN;
|
|
10
|
+
let _modulePromiseReset = null;
|
|
11
|
+
export function _registerModuleReset(fn) {
|
|
12
|
+
_modulePromiseReset = fn;
|
|
13
|
+
}
|
|
14
|
+
export function setMelSpectrogramWasmUrl(url) {
|
|
15
|
+
_wasmUrl = url;
|
|
16
|
+
_modulePromiseReset?.(); // invalidate cached module so next call re-fetches
|
|
17
|
+
}
|
|
18
|
+
export function getMelSpectrogramWasmUrl() {
|
|
19
|
+
return _wasmUrl;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=wasmConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wasmConfig.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/wasmConfig.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,wEAAwE;AACxE,MAAM,YAAY,GAAG,cAAc,CAAA;AACnC,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,MAAM,UAAU,oBAAoB,CAAC,EAAc;IAC/C,mBAAmB,GAAG,EAAE,CAAA;AAC5B,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,GAAW;IAChD,QAAQ,GAAG,GAAG,CAAA;IACd,mBAAmB,EAAE,EAAE,CAAA,CAAC,mDAAmD;AAC/E,CAAC;AAED,MAAM,UAAU,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-beta.1'\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/esm/index.js
CHANGED
|
@@ -17,6 +17,7 @@ export { getPlatformCapabilities, isEncodingSupported, isBitDepthSupported, getF
|
|
|
17
17
|
export { AudioDeviceManager, audioDeviceManager } from './AudioDeviceManager';
|
|
18
18
|
// Export useAudioDevices hook
|
|
19
19
|
export { useAudioDevices } from './hooks/useAudioDevices';
|
|
20
|
+
export { setMelSpectrogramWasmUrl } from './AudioAnalysis/wasmConfig';
|
|
20
21
|
export { AudioRecorderProvider, AudioStudioModule, extractRawWavAnalysis, extractAudioAnalysis, extractPreview, trimAudio, extractAudioData, extractMelSpectrogram, initMelStreamingWasm, computeMelFrameWasm, MAX_DURATION_MS, useAudioRecorder, useSharedAudioRecorder, };
|
|
21
22
|
/** @deprecated Use AudioStudioModule instead */
|
|
22
23
|
export const ExpoAudioStreamModule = AudioStudioModule;
|
package/build/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AAEf,OAAO,EACH,qBAAqB,EACrB,oBAAoB,GACvB,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,EACH,qBAAqB,EACrB,eAAe,GAClB,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EACH,oBAAoB,EACpB,mBAAmB,GACtB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EACH,qBAAqB,EACrB,sBAAsB,GACzB,MAAM,0BAA0B,CAAA;AACjC,OAAO,iBAAiB,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAErD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AAEtC,+BAA+B;AAC/B,OAAO,EACH,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,GAE1B,MAAM,iCAAiC,CAAA;AAExC,4BAA4B;AAC5B,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAE7E,8BAA8B;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAEzD,OAAO,EACH,qBAAqB,EACrB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,sBAAsB,GACzB,CAAA;AAMD,gDAAgD;AAChD,MAAM,CAAC,MAAM,qBAAqB,GAAG,iBAAiB,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 {\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"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AAEf,OAAO,EACH,qBAAqB,EACrB,oBAAoB,GACvB,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,EACH,qBAAqB,EACrB,eAAe,GAClB,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EACH,oBAAoB,EACpB,mBAAmB,GACtB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EACH,qBAAqB,EACrB,sBAAsB,GACzB,MAAM,0BAA0B,CAAA;AACjC,OAAO,iBAAiB,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAErD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AAEtC,+BAA+B;AAC/B,OAAO,EACH,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,GAE1B,MAAM,iCAAiC,CAAA;AAExC,4BAA4B;AAC5B,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAE7E,8BAA8B;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAEzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AAErE,OAAO,EACH,qBAAqB,EACrB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,sBAAsB,GACzB,CAAA;AAMD,gDAAgD;AAChD,MAAM,CAAC,MAAM,qBAAqB,GAAG,iBAAiB,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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audioFeaturesWasm.web.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/audioFeaturesWasm.web.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"audioFeaturesWasm.web.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/audioFeaturesWasm.web.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,uBAAuB;IACpC,gBAAgB,EAAE,MAAM,CAAA;IACxB,gBAAgB,EAAE,MAAM,CAAA;IACxB,eAAe,EAAE,MAAM,CAAA;IACvB,iBAAiB,EAAE,MAAM,CAAA;IACzB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,UAAU,EAAE,MAAM,EAAE,CAAA;CACvB;AA8ED;;;GAGG;AACH,wBAAsB,qBAAqB,CACvC,UAAU,EAAE,MAAM,EAClB,SAAS,SAAO,EAChB,KAAK,SAAK,EACV,WAAW,SAAK,EAChB,WAAW,UAAO,EAClB,aAAa,UAAO,GACrB,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CACzC,OAAO,EAAE,YAAY,GACtB,uBAAuB,GAAG,IAAI,CA2BhC;AAID;;;GAGG;AACH,wBAAsB,wBAAwB,CAC1C,SAAS,EAAE,YAAY,EACvB,UAAU,EAAE,MAAM,EAClB,SAAS,SAAO,EAChB,KAAK,SAAK,EACV,WAAW,SAAK,EAChB,WAAW,UAAO,EAClB,aAAa,UAAO,GACrB,OAAO,CAAC,uBAAuB,CAAC,CA4BlC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"melSpectrogramWasm.web.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/melSpectrogramWasm.web.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"melSpectrogramWasm.web.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/melSpectrogramWasm.web.ts"],"names":[],"mappings":"AAiCA;;;GAGG;AACH,wBAAsB,oBAAoB,CACtC,UAAU,EAAE,MAAM,EAClB,KAAK,SAAM,EACX,SAAS,SAAO,EAChB,iBAAiB,SAAM,EACvB,gBAAgB,SAAM,EACtB,IAAI,SAAI,EACR,IAAI,SAAI,GACT,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,EAAE,GAAG,IAAI,CA4B1E;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAC3C,SAAS,EAAE,YAAY,EACvB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,iBAAiB,EAAE,MAAM,EACzB,gBAAgB,EAAE,MAAM,EACxB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,SAAS,EAAE,OAAO,EAClB,QAAQ,EAAE,OAAO,GAClB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAgErB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wasmConfig.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/wasmConfig.ts"],"names":[],"mappings":"AAYA,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAEzD;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAG1D;AAED,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD"}
|
package/build/types/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export * from './utils/writeWavHeader';
|
|
|
13
13
|
export { getPlatformCapabilities, isEncodingSupported, isBitDepthSupported, getFallbackEncoding, getFallbackBitDepth, validateRecordingConfig, type PlatformCapabilities, } from './constants/platformLimitations';
|
|
14
14
|
export { AudioDeviceManager, audioDeviceManager } from './AudioDeviceManager';
|
|
15
15
|
export { useAudioDevices } from './hooks/useAudioDevices';
|
|
16
|
+
export { setMelSpectrogramWasmUrl } from './AudioAnalysis/wasmConfig';
|
|
16
17
|
export { AudioRecorderProvider, AudioStudioModule, extractRawWavAnalysis, extractAudioAnalysis, extractPreview, trimAudio, extractAudioData, extractMelSpectrogram, initMelStreamingWasm, computeMelFrameWasm, MAX_DURATION_MS, useAudioRecorder, useSharedAudioRecorder, };
|
|
17
18
|
export type * from './AudioAnalysis/AudioAnalysis.types';
|
|
18
19
|
export type * from './AudioStudio.types';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,qBAAqB,EACrB,oBAAoB,EACvB,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,EACH,qBAAqB,EACrB,eAAe,EAClB,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EACH,oBAAoB,EACpB,mBAAmB,EACtB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EACH,qBAAqB,EACrB,sBAAsB,EACzB,MAAM,0BAA0B,CAAA;AACjC,OAAO,iBAAiB,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAErD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AAGtC,OAAO,EACH,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,EACvB,KAAK,oBAAoB,GAC5B,MAAM,iCAAiC,CAAA;AAGxC,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAG7E,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAEzD,OAAO,EACH,qBAAqB,EACrB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,sBAAsB,GACzB,CAAA;AAGD,mBAAmB,qCAAqC,CAAA;AACxD,mBAAmB,qBAAqB,CAAA;AAExC,gDAAgD;AAChD,eAAO,MAAM,qBAAqB,KAAoB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,qBAAqB,EACrB,oBAAoB,EACvB,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,EACH,qBAAqB,EACrB,eAAe,EAClB,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EACH,oBAAoB,EACpB,mBAAmB,EACtB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EACH,qBAAqB,EACrB,sBAAsB,EACzB,MAAM,0BAA0B,CAAA;AACjC,OAAO,iBAAiB,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAErD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AAGtC,OAAO,EACH,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,EACvB,KAAK,oBAAoB,GAC5B,MAAM,iCAAiC,CAAA;AAGxC,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAG7E,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAEzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AAErE,OAAO,EACH,qBAAqB,EACrB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,sBAAsB,GACzB,CAAA;AAGD,mBAAmB,qCAAqC,CAAA;AACxD,mBAAmB,qBAAqB,CAAA;AAExC,gDAAgD;AAChD,eAAO,MAAM,qBAAqB,KAAoB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@siteed/audio-studio",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.2-beta.2",
|
|
4
4
|
"description": "Comprehensive audio processing library for React Native and Expo with recording, analysis, visualization, and streaming capabilities across iOS, Android, and web",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -144,4 +144,4 @@
|
|
|
144
144
|
"access": "public",
|
|
145
145
|
"registry": "https://registry.npmjs.org"
|
|
146
146
|
}
|
|
147
|
-
}
|
|
147
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AudioFeaturesWasmModule } from './audio-features-wasm'
|
|
2
|
+
import { getMelSpectrogramWasmUrl } from './wasmConfig'
|
|
2
3
|
|
|
3
4
|
export interface AudioFeaturesWasmResult {
|
|
4
5
|
spectralCentroid: number
|
|
@@ -14,9 +15,9 @@ let modulePromise: Promise<AudioFeaturesWasmModule> | null = null
|
|
|
14
15
|
function getModule(): Promise<AudioFeaturesWasmModule> {
|
|
15
16
|
if (!modulePromise) {
|
|
16
17
|
modulePromise = (async () => {
|
|
17
|
-
|
|
18
|
-
// @
|
|
19
|
-
const mod = await import(
|
|
18
|
+
const url = getMelSpectrogramWasmUrl()
|
|
19
|
+
// webpackIgnore + @vite-ignore prevent bundlers from trying to resolve the URL
|
|
20
|
+
const mod = await import(/* webpackIgnore: true */ /* @vite-ignore */ url)
|
|
20
21
|
const factory = mod.default ?? mod
|
|
21
22
|
return factory() as Promise<AudioFeaturesWasmModule>
|
|
22
23
|
})().catch((err) => {
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import type { MelSpectrogramWasmModule } from './mel-spectrogram-wasm'
|
|
2
|
+
import { getMelSpectrogramWasmUrl, _registerModuleReset } from './wasmConfig'
|
|
2
3
|
|
|
3
4
|
let modulePromise: Promise<MelSpectrogramWasmModule> | null = null
|
|
4
5
|
|
|
6
|
+
_registerModuleReset(() => {
|
|
7
|
+
modulePromise = null
|
|
8
|
+
})
|
|
9
|
+
|
|
5
10
|
function getModule(): Promise<MelSpectrogramWasmModule> {
|
|
6
11
|
if (!modulePromise) {
|
|
7
12
|
modulePromise = (async () => {
|
|
8
|
-
|
|
9
|
-
// @
|
|
10
|
-
const mod = await import(
|
|
13
|
+
const url = getMelSpectrogramWasmUrl()
|
|
14
|
+
// webpackIgnore + @vite-ignore prevent bundlers from trying to resolve the URL
|
|
15
|
+
const mod = await import(/* webpackIgnore: true */ /* @vite-ignore */ url)
|
|
11
16
|
const factory = mod.default ?? mod
|
|
12
17
|
return factory() as Promise<MelSpectrogramWasmModule>
|
|
13
18
|
})().catch((err) => {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Version is inlined here — keep in sync with package.json when releasing.
|
|
2
|
+
// The publish.sh script should bump this string alongside package.json.
|
|
3
|
+
const WASM_VERSION = '3.0.2-beta.1'
|
|
4
|
+
// jsDelivr syncs from npm automatically within ~5 min of publish.
|
|
5
|
+
// GitHub release fallback (attach mel-spectrogram.js as a release asset):
|
|
6
|
+
// https://github.com/deeeed/audiolab/releases/download/@siteed/audio-studio@VERSION/mel-spectrogram.js
|
|
7
|
+
// To use the fallback: setMelSpectrogramWasmUrl('<url>') before any mel-spectrogram API call.
|
|
8
|
+
const DEFAULT_WASM_CDN = `https://cdn.jsdelivr.net/npm/@siteed/audio-studio@${WASM_VERSION}/prebuilt/wasm/mel-spectrogram.js`
|
|
9
|
+
|
|
10
|
+
let _wasmUrl: string = DEFAULT_WASM_CDN
|
|
11
|
+
let _modulePromiseReset: (() => void) | null = null
|
|
12
|
+
|
|
13
|
+
export function _registerModuleReset(fn: () => void): void {
|
|
14
|
+
_modulePromiseReset = fn
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function setMelSpectrogramWasmUrl(url: string): void {
|
|
18
|
+
_wasmUrl = url
|
|
19
|
+
_modulePromiseReset?.() // invalidate cached module so next call re-fetches
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function getMelSpectrogramWasmUrl(): string {
|
|
23
|
+
return _wasmUrl
|
|
24
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -43,6 +43,8 @@ export { AudioDeviceManager, audioDeviceManager } from './AudioDeviceManager'
|
|
|
43
43
|
// Export useAudioDevices hook
|
|
44
44
|
export { useAudioDevices } from './hooks/useAudioDevices'
|
|
45
45
|
|
|
46
|
+
export { setMelSpectrogramWasmUrl } from './AudioAnalysis/wasmConfig'
|
|
47
|
+
|
|
46
48
|
export {
|
|
47
49
|
AudioRecorderProvider,
|
|
48
50
|
AudioStudioModule,
|