@siteed/audio-studio 3.0.1 → 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.
@@ -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
- // Same WASM module as mel spectrogram (now includes audio features)
44
- // @ts-expect-error -- prebuilt Emscripten JS glue has no .d.ts
45
- const mod = await Promise.resolve().then(() => __importStar(require('../../prebuilt/wasm/mel-spectrogram.js')));
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
- // Dynamic import of the prebuilt SINGLE_FILE Emscripten module
44
- // @ts-expect-error -- prebuilt Emscripten JS glue has no .d.ts
45
- const mod = await Promise.resolve().then(() => __importStar(require('../../prebuilt/wasm/mel-spectrogram.js')));
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,oDA+BC;AAMD,kDA4BC;AAMD,8DA2EC;AAhLD,IAAI,aAAa,GAA6C,IAAI,CAAA;AAElE,SAAS,SAAS;IACd,IAAI,CAAC,aAAa,EAAE,CAAC;QACjB,aAAa,GAAG,CAAC,KAAK,IAAI,EAAE;YACxB,+DAA+D;YAC/D,+DAA+D;YAC/D,MAAM,GAAG,GAAG,wDAAa,wCAAwC,GAAC,CAAA;YAClE,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'\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,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"]}
@@ -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
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,eAAe;;;;;;;;;;;;;;;;;;;;AAEf,+EAG6C;AA2CzC,sGA7CA,4CAAqB,OA6CA;AACrB,qGA7CA,2CAAoB,OA6CA;AA3CxB,uEAAmE;AA8C/D,iGA9CK,mCAAgB,OA8CL;AA7CpB,iFAG8C;AA2C1C,sGA7CA,6CAAqB,OA6CA;AAGrB,gGA/CA,uCAAe,OA+CA;AA7CnB,mEAA+D;AAuC3D,+FAvCK,+BAAc,OAuCL;AAtClB,2EAG2C;AAuCvC,qGAzCA,yCAAoB,OAyCA;AACpB,oGAzCA,wCAAmB,OAyCA;AAvCvB,qEAGiC;AA2B7B,sGA7BA,8CAAqB,OA6BA;AAYrB,uGAxCA,+CAAsB,OAwCA;AAtC1B,4EAAmD;AA2B/C,4BA3BG,2BAAiB,CA2BH;AA1BrB,2CAAuC;AA8BnC,0FA9BK,qBAAS,OA8BL;AA7Bb,yDAAqD;AAmCjD,iGAnCK,mCAAgB,OAmCL;AAjCpB,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;AAsBxB,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 {\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,+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
- // 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');
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":"AAWA,IAAI,aAAa,GAA4C,IAAI,CAAA;AAEjE,SAAS,SAAS;IACd,IAAI,CAAC,aAAa,EAAE,CAAC;QACjB,aAAa,GAAG,CAAC,KAAK,IAAI,EAAE;YACxB,oEAAoE;YACpE,+DAA+D;YAC/D,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,wCAAwC,CAAC,CAAA;YAClE,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAA;YAClC,OAAO,OAAO,EAAsC,CAAA;QACxD,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,0DAA0D;AAC1D,+CAA+C;AAC/C,+CAA+C;AAC/C,+CAA+C;AAC/C,+CAA+C;AAC/C,uDAAuD;AACvD,+CAA+C;AAC/C,uDAAuD;AACvD,+CAA+C;AAC/C,MAAM,WAAW,GAAG,EAAE,CAAA;AAEtB,SAAS,UAAU,CACf,MAA+B,EAC/B,GAAW;IAEX,MAAM,gBAAgB,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IACtD,MAAM,gBAAgB,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,EAAE,OAAO,CAAC,CAAA;IAC1D,MAAM,eAAe,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,EAAE,OAAO,CAAC,CAAA;IACzD,MAAM,iBAAiB,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,EAAE,EAAE,OAAO,CAAC,CAAA;IAE5D,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,EAAE,EAAE,KAAK,CAAC,CAAA;IAChD,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,EAAE,EAAE,KAAK,CAAC,CAAA;IAClD,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,EAAE,EAAE,KAAK,CAAC,CAAA;IAClD,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,EAAE,EAAE,KAAK,CAAC,CAAA;IAEpD,MAAM,IAAI,GAAa,EAAE,CAAA;IACzB,IAAI,OAAO,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,CAAA;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;QACzC,CAAC;IACL,CAAC;IAED,MAAM,UAAU,GAAa,EAAE,CAAA;IAC/B,IAAI,SAAS,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,CAAA;QAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;QAC/C,CAAC;IACL,CAAC;IAED,OAAO;QACH,gBAAgB;QAChB,gBAAgB;QAChB,eAAe;QACf,iBAAiB;QACjB,IAAI;QACJ,UAAU;KACb,CAAA;AACL,CAAC;AAED,oCAAoC;AAEpC,IAAI,eAAe,GAAmC,IAAI,CAAA;AAC1D,IAAI,iBAAiB,GAAG,CAAC,CAAA;AACzB,IAAI,sBAAsB,GAAG,CAAC,CAAA;AAC9B,IAAI,kBAAkB,GAAG,CAAC,CAAA;AAE1B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACvC,UAAkB,EAClB,SAAS,GAAG,IAAI,EAChB,KAAK,GAAG,EAAE,EACV,WAAW,GAAG,EAAE,EAChB,WAAW,GAAG,IAAI,EAClB,aAAa,GAAG,IAAI;IAEpB,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAA;IAChC,eAAe,GAAG,MAAM,CAAA;IAExB,MAAM,CAAC,oBAAoB,CACvB,UAAU,EACV,SAAS,EACT,KAAK,EACL,WAAW,EACX,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACnB,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACxB,CAAA;IAED,0CAA0C;IAC1C,IAAI,kBAAkB;QAAE,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAA;IACxD,kBAAkB,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;IAChD,mEAAmE;IACnE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,kBAAkB,EAAE,kBAAkB,GAAG,WAAW,CAAC,CAAA;IAE3E,yCAAyC;IACzC,sBAAsB,GAAG,CAAC,CAAA;IAC1B,iBAAiB,GAAG,CAAC,CAAA;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,6BAA6B,CACzC,OAAqB;IAErB,IAAI,CAAC,eAAe,IAAI,CAAC,kBAAkB;QAAE,OAAO,IAAI,CAAA;IACxD,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,6BAA6B,CAC3C,iBAAiB,EACjB,OAAO,CAAC,MAAM,EACd,kBAAkB,CACrB,CAAA;IACD,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAA;IAEpB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;IAErD,yDAAyD;IACzD,MAAM,CAAC,2BAA2B,CAAC,kBAAkB,CAAC,CAAA;IAEtD,OAAO,MAAM,CAAA;AACjB,CAAC;AAED,oBAAoB;AAEpB;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC1C,SAAuB,EACvB,UAAkB,EAClB,SAAS,GAAG,IAAI,EAChB,KAAK,GAAG,EAAE,EACV,WAAW,GAAG,EAAE,EAChB,WAAW,GAAG,IAAI,EAClB,aAAa,GAAG,IAAI;IAEpB,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAA;IAEhC,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAA;IACnC,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC,CAAA;IAC/C,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,IAAI,CAAC,CAAC,CAAA;IAE5C,MAAM,SAAS,GAAG,MAAM,CAAC,uBAAuB,CAC5C,QAAQ,EACR,UAAU,EACV,UAAU,EACV,SAAS,EACT,KAAK,EACL,WAAW,EACX,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACnB,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACxB,CAAA;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;IAEtB,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAA;IAC3D,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC5C,MAAM,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAA;IAEtC,OAAO,MAAM,CAAA;AACjB,CAAC","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
- // Dynamic import of the prebuilt SINGLE_FILE Emscripten module
6
- // @ts-expect-error -- prebuilt Emscripten JS glue has no .d.ts
7
- const mod = await import('../../prebuilt/wasm/mel-spectrogram.js');
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';
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,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,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'\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"]}
@@ -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;
@@ -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":"AAEA,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
+ {"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":"AA4BA;;;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"}
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,4 @@
1
+ export declare function _registerModuleReset(fn: () => void): void;
2
+ export declare function setMelSpectrogramWasmUrl(url: string): void;
3
+ export declare function getMelSpectrogramWasmUrl(): string;
4
+ //# sourceMappingURL=wasmConfig.d.ts.map
@@ -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"}
@@ -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.1",
3
+ "version": "3.0.2-beta.1",
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",
@@ -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
- // Same WASM module as mel spectrogram (now includes audio features)
18
- // @ts-expect-error -- prebuilt Emscripten JS glue has no .d.ts
19
- const mod = await import('../../prebuilt/wasm/mel-spectrogram.js')
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
- // Dynamic import of the prebuilt SINGLE_FILE Emscripten module
9
- // @ts-expect-error -- prebuilt Emscripten JS glue has no .d.ts
10
- const mod = await import('../../prebuilt/wasm/mel-spectrogram.js')
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'
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,