@siteed/audio-studio 3.0.2 → 3.0.4

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.
Files changed (89) hide show
  1. package/CHANGELOG.md +19 -1
  2. package/android/src/main/java/net/siteed/audiostudio/AudioRecorderManager.kt +41 -35
  3. package/android/src/main/java/net/siteed/audiostudio/AudioStudioModule.kt +500 -479
  4. package/build/cjs/AudioAnalysis/AudioAnalysis.types.js.map +1 -1
  5. package/build/cjs/AudioAnalysis/audioFeaturesWasm.js +10 -7
  6. package/build/cjs/AudioAnalysis/audioFeaturesWasm.js.map +1 -1
  7. package/build/cjs/AudioAnalysis/audioFeaturesWasm.web.js +78 -97
  8. package/build/cjs/AudioAnalysis/audioFeaturesWasm.web.js.map +1 -1
  9. package/build/cjs/AudioAnalysis/extractAudioAnalysis.js +15 -12
  10. package/build/cjs/AudioAnalysis/extractAudioAnalysis.js.map +1 -1
  11. package/build/cjs/AudioAnalysis/extractAudioData.js +144 -2
  12. package/build/cjs/AudioAnalysis/extractAudioData.js.map +1 -1
  13. package/build/cjs/AudioAnalysis/melSpectrogramWasm.web.js +9 -56
  14. package/build/cjs/AudioAnalysis/melSpectrogramWasm.web.js.map +1 -1
  15. package/build/cjs/AudioAnalysis/wasmConfig.js +4 -4
  16. package/build/cjs/AudioAnalysis/wasmConfig.js.map +1 -1
  17. package/build/cjs/AudioAnalysis/wasmLoader.web.js +79 -0
  18. package/build/cjs/AudioAnalysis/wasmLoader.web.js.map +1 -0
  19. package/build/cjs/AudioStudioModule.js +4 -599
  20. package/build/cjs/AudioStudioModule.js.map +1 -1
  21. package/build/cjs/trimAudio.js +227 -0
  22. package/build/cjs/trimAudio.js.map +1 -1
  23. package/build/cjs/utils/encodeCompressedAudio.web.js +65 -0
  24. package/build/cjs/utils/encodeCompressedAudio.web.js.map +1 -0
  25. package/build/cjs/utils/resampleAudioBuffer.web.js +25 -0
  26. package/build/cjs/utils/resampleAudioBuffer.web.js.map +1 -0
  27. package/build/esm/AudioAnalysis/AudioAnalysis.types.js.map +1 -1
  28. package/build/esm/AudioAnalysis/audioFeaturesWasm.js +8 -5
  29. package/build/esm/AudioAnalysis/audioFeaturesWasm.js.map +1 -1
  30. package/build/esm/AudioAnalysis/audioFeaturesWasm.web.js +76 -62
  31. package/build/esm/AudioAnalysis/audioFeaturesWasm.web.js.map +1 -1
  32. package/build/esm/AudioAnalysis/extractAudioAnalysis.js +15 -12
  33. package/build/esm/AudioAnalysis/extractAudioAnalysis.js.map +1 -1
  34. package/build/esm/AudioAnalysis/extractAudioData.js +144 -2
  35. package/build/esm/AudioAnalysis/extractAudioData.js.map +1 -1
  36. package/build/esm/AudioAnalysis/melSpectrogramWasm.web.js +9 -23
  37. package/build/esm/AudioAnalysis/melSpectrogramWasm.web.js.map +1 -1
  38. package/build/esm/AudioAnalysis/wasmConfig.js +4 -4
  39. package/build/esm/AudioAnalysis/wasmConfig.js.map +1 -1
  40. package/build/esm/AudioAnalysis/wasmLoader.web.js +43 -0
  41. package/build/esm/AudioAnalysis/wasmLoader.web.js.map +1 -0
  42. package/build/esm/AudioStudioModule.js +4 -596
  43. package/build/esm/AudioStudioModule.js.map +1 -1
  44. package/build/esm/trimAudio.js +227 -0
  45. package/build/esm/trimAudio.js.map +1 -1
  46. package/build/esm/utils/encodeCompressedAudio.web.js +62 -0
  47. package/build/esm/utils/encodeCompressedAudio.web.js.map +1 -0
  48. package/build/esm/utils/resampleAudioBuffer.web.js +22 -0
  49. package/build/esm/utils/resampleAudioBuffer.web.js.map +1 -0
  50. package/build/types/AudioAnalysis/AudioAnalysis.types.d.ts +11 -0
  51. package/build/types/AudioAnalysis/AudioAnalysis.types.d.ts.map +1 -1
  52. package/build/types/AudioAnalysis/audioFeaturesWasm.d.ts +5 -9
  53. package/build/types/AudioAnalysis/audioFeaturesWasm.d.ts.map +1 -1
  54. package/build/types/AudioAnalysis/audioFeaturesWasm.web.d.ts +35 -16
  55. package/build/types/AudioAnalysis/audioFeaturesWasm.web.d.ts.map +1 -1
  56. package/build/types/AudioAnalysis/extractAudioAnalysis.d.ts.map +1 -1
  57. package/build/types/AudioAnalysis/extractAudioData.d.ts +2 -2
  58. package/build/types/AudioAnalysis/extractAudioData.d.ts.map +1 -1
  59. package/build/types/AudioAnalysis/melSpectrogramWasm.web.d.ts.map +1 -1
  60. package/build/types/AudioAnalysis/wasmLoader.web.d.ts +3 -0
  61. package/build/types/AudioAnalysis/wasmLoader.web.d.ts.map +1 -0
  62. package/build/types/AudioStudioModule.d.ts.map +1 -1
  63. package/build/types/trimAudio.d.ts.map +1 -1
  64. package/build/types/utils/encodeCompressedAudio.web.d.ts +10 -0
  65. package/build/types/utils/encodeCompressedAudio.web.d.ts.map +1 -0
  66. package/build/types/utils/resampleAudioBuffer.web.d.ts +2 -0
  67. package/build/types/utils/resampleAudioBuffer.web.d.ts.map +1 -0
  68. package/ios/AudioStreamManager.swift +135 -89
  69. package/ios/AudioStudioModule.swift +239 -216
  70. package/package.json +1 -1
  71. package/src/AudioAnalysis/AudioAnalysis.types.ts +12 -0
  72. package/src/AudioAnalysis/audioFeaturesWasm.ts +17 -22
  73. package/src/AudioAnalysis/audioFeaturesWasm.web.ts +102 -94
  74. package/src/AudioAnalysis/extractAudioAnalysis.ts +23 -20
  75. package/src/AudioAnalysis/extractAudioData.ts +186 -4
  76. package/src/AudioAnalysis/melSpectrogramWasm.web.ts +10 -27
  77. package/src/AudioAnalysis/wasmConfig.ts +4 -4
  78. package/src/AudioAnalysis/wasmLoader.web.ts +53 -0
  79. package/src/AudioStudioModule.ts +6 -854
  80. package/src/trimAudio.ts +351 -0
  81. package/src/utils/encodeCompressedAudio.web.ts +78 -0
  82. package/src/utils/resampleAudioBuffer.web.ts +39 -0
  83. package/build/cjs/AudioAnalysis/extractWaveform.js +0 -18
  84. package/build/cjs/AudioAnalysis/extractWaveform.js.map +0 -1
  85. package/build/esm/AudioAnalysis/extractWaveform.js +0 -11
  86. package/build/esm/AudioAnalysis/extractWaveform.js.map +0 -1
  87. package/build/types/AudioAnalysis/extractWaveform.d.ts +0 -8
  88. package/build/types/AudioAnalysis/extractWaveform.d.ts.map +0 -1
  89. package/src/AudioAnalysis/extractWaveform.ts +0 -22
@@ -1 +1 @@
1
- {"version":3,"file":"extractAudioData.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractAudioData.ts"],"names":[],"mappings":"AACA,OAAO,iBAAiB,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAA;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAEhE,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,KAA8B,EAAE,EAAE;IACrE,IAAI,KAAK,EAAE,CAAC;QACR,qEAAqE;QACrE,OAAO,MAAM,iBAAiB,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;IAC1D,CAAC;IACD,yEAAyE;IACzE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,EAAE,GAAG,KAAK,CAAA;IACnD,8DAA8D;IAC9D,OAAO,MAAM,iBAAiB,CAAC,gBAAgB,CAC3C,kBAAkB,CAAC,aAAa,CAAC,CACpC,CAAA;AACL,CAAC,CAAA","sourcesContent":["import { ExtractAudioDataOptions } from '../AudioStudio.types'\nimport AudioStudioModule from '../AudioStudioModule'\nimport { isWeb } from '../constants'\nimport { cleanNativeOptions } from '../utils/cleanNativeOptions'\n\nexport const extractAudioData = async (props: ExtractAudioDataOptions) => {\n if (isWeb) {\n // Web implementation handles logger natively in AudioStudioModule.ts\n return await AudioStudioModule.extractAudioData(props)\n }\n // Native: only pass serializable fields — logger causes crash on Android\n const { logger: _logger, ...nativeOptions } = props\n // Clean undefined values to avoid Android Kotlin bridge crash\n return await AudioStudioModule.extractAudioData(\n cleanNativeOptions(nativeOptions)\n )\n}\n"]}
1
+ {"version":3,"file":"extractAudioData.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractAudioData.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BitDepth,\n ExtractAudioDataOptions,\n ExtractedAudioData,\n} from '../AudioStudio.types'\nimport AudioStudioModule from '../AudioStudioModule'\nimport { isWeb } from '../constants'\nimport { processAudioBuffer } from '../utils/audioProcessing'\nimport { cleanNativeOptions } from '../utils/cleanNativeOptions'\nimport crc32 from '../utils/crc32'\nimport { writeWavHeader } from '../utils/writeWavHeader'\n\nexport const extractAudioData = async (\n props: ExtractAudioDataOptions\n): Promise<ExtractedAudioData> => {\n if (isWeb) {\n try {\n const {\n fileUri,\n position,\n length,\n startTimeMs,\n endTimeMs,\n decodingOptions,\n includeNormalizedData,\n includeBase64Data,\n includeWavHeader = false,\n logger,\n } = props\n\n logger?.debug('EXTRACT AUDIO - Step 1: Initial request', {\n fileUri,\n extractionParams: {\n position,\n length,\n startTimeMs,\n endTimeMs,\n },\n decodingOptions: {\n targetSampleRate:\n decodingOptions?.targetSampleRate ?? 16000,\n targetChannels: decodingOptions?.targetChannels ?? 1,\n targetBitDepth: decodingOptions?.targetBitDepth ?? 16,\n normalizeAudio: decodingOptions?.normalizeAudio ?? false,\n },\n outputOptions: {\n includeNormalizedData,\n includeBase64Data,\n includeWavHeader,\n },\n })\n\n // Process the audio using shared helper function\n const processedBuffer = await processAudioBuffer({\n fileUri,\n targetSampleRate: decodingOptions?.targetSampleRate ?? 16000,\n targetChannels: decodingOptions?.targetChannels ?? 1,\n normalizeAudio: decodingOptions?.normalizeAudio ?? false,\n position,\n length,\n startTimeMs,\n endTimeMs,\n logger,\n })\n\n logger?.debug('EXTRACT AUDIO - Step 2: Audio processing complete', {\n processedData: {\n samples: processedBuffer.samples,\n sampleRate: processedBuffer.sampleRate,\n channels: processedBuffer.channels,\n durationMs: processedBuffer.durationMs,\n },\n })\n\n const channelData = processedBuffer.channelData\n const bitDepth = (decodingOptions?.targetBitDepth ?? 16) as BitDepth\n const bytesPerSample = bitDepth / 8\n const numSamples = processedBuffer.samples\n\n logger?.debug('EXTRACT AUDIO - Step 3: PCM conversion setup', {\n channelData: {\n length: channelData.length,\n first: channelData[0],\n last: channelData[channelData.length - 1],\n },\n calculation: {\n bitDepth,\n bytesPerSample,\n numSamples,\n expectedBytes: numSamples * bytesPerSample,\n },\n })\n\n // Create PCM data with correct length based on original byte length\n const pcmData = new Uint8Array(numSamples * bytesPerSample)\n let offset = 0\n\n // Convert Float32 samples to PCM format\n for (let i = 0; i < numSamples; i++) {\n const sample = channelData[i]\n const value = Math.max(-1, Math.min(1, sample))\n // Convert to 16-bit signed integer\n let intValue = Math.round(value * 32767)\n\n // Handle negative values correctly\n if (intValue < 0) {\n intValue = 65536 + intValue\n }\n\n // Write as little-endian\n pcmData[offset++] = intValue & 255 // Low byte\n pcmData[offset++] = (intValue >> 8) & 255 // High byte\n }\n\n const durationMs = Math.round(\n (numSamples / processedBuffer.sampleRate) * 1000\n )\n\n logger?.debug('EXTRACT AUDIO - Step 4: Final output', {\n pcmData: {\n length: pcmData.length,\n first: pcmData[0],\n last: pcmData[pcmData.length - 1],\n },\n timing: {\n numSamples,\n sampleRate: processedBuffer.sampleRate,\n durationMs,\n shouldBe3000ms: endTimeMs\n ? endTimeMs - (startTimeMs ?? 0) === 3000\n : undefined,\n },\n })\n\n const result: ExtractedAudioData = {\n pcmData: new Uint8Array(pcmData.buffer),\n sampleRate: processedBuffer.sampleRate,\n channels: processedBuffer.channels,\n bitDepth,\n durationMs,\n format: `pcm_${bitDepth}bit` as const,\n samples: numSamples,\n }\n\n // Add WAV header if requested\n if (includeWavHeader) {\n logger?.debug('EXTRACT AUDIO - Step 5: Adding WAV header', {\n originalLength: pcmData.length,\n newLength: result.pcmData.length,\n firstBytes: Array.from(result.pcmData.slice(0, 44)), // WAV header is 44 bytes\n })\n const wavBuffer = writeWavHeader({\n buffer: pcmData.buffer.slice(0, pcmData.length),\n sampleRate: processedBuffer.sampleRate,\n numChannels: processedBuffer.channels,\n bitDepth,\n })\n result.pcmData = new Uint8Array(wavBuffer)\n result.hasWavHeader = true\n }\n\n if (includeNormalizedData) {\n result.normalizedData = channelData\n }\n\n if (includeBase64Data) {\n result.base64Data = btoa(\n String.fromCharCode(...new Uint8Array(pcmData.buffer))\n )\n }\n\n if (props.computeChecksum) {\n result.checksum = crc32.buf(pcmData)\n }\n\n logger?.debug('EXTRACT AUDIO - Step 3: PCM conversion complete', {\n pcmStats: {\n length: pcmData.length,\n bytesPerSample,\n totalSamples: numSamples,\n firstBytes: Array.from(pcmData.slice(0, 16)),\n lastBytes: Array.from(pcmData.slice(-16)),\n },\n })\n\n return result\n } catch (error) {\n props.logger?.error('EXTRACT AUDIO - Error:', error)\n throw error\n }\n }\n\n // Native: only pass serializable fields — logger causes crash on Android\n const { logger: _logger, ...nativeOptions } = props\n // Clean undefined values to avoid Android Kotlin bridge crash\n return await AudioStudioModule.extractAudioData(\n cleanNativeOptions(nativeOptions)\n )\n}\n"]}
@@ -1,24 +1,4 @@
1
- import { getMelSpectrogramWasmUrl, _registerModuleReset } from './wasmConfig';
2
- let modulePromise = null;
3
- _registerModuleReset(() => {
4
- modulePromise = null;
5
- });
6
- function getModule() {
7
- if (!modulePromise) {
8
- modulePromise = (async () => {
9
- const url = getMelSpectrogramWasmUrl();
10
- // webpackIgnore + @vite-ignore prevent bundlers from trying to resolve the URL
11
- const mod = await import(
12
- /* webpackIgnore: true */ /* @vite-ignore */ url);
13
- const factory = mod.default ?? mod;
14
- return factory();
15
- })().catch((err) => {
16
- modulePromise = null;
17
- throw err;
18
- });
19
- }
20
- return modulePromise;
21
- }
1
+ import { getWasmModule } from './wasmLoader.web';
22
2
  // --- Streaming (per-frame) API for live mel spectrogram ---
23
3
  let streamingModule = null;
24
4
  let streamingNMels = 0;
@@ -30,11 +10,17 @@ let streamingFrameCapacity = 0;
30
10
  * Re-initialises only when config changes.
31
11
  */
32
12
  export async function initMelStreamingWasm(sampleRate, nMels = 128, fftLength = 2048, windowSizeSamples = 400, hopLengthSamples = 160, fMin = 0, fMax = 0) {
33
- const Module = await getModule();
13
+ const Module = (await getWasmModule());
34
14
  streamingModule = Module;
35
15
  const actualFMax = fMax > 0 ? fMax : sampleRate / 2;
36
16
  Module._mel_spectrogram_init(sampleRate, fftLength, windowSizeSamples, hopLengthSamples, nMels, fMin, actualFMax, 0 /* hann */);
37
17
  streamingNMels = nMels;
18
+ // Free frame buffer from previous session (if any) to avoid leak on re-init
19
+ if (streamingFramePtr) {
20
+ Module._free(streamingFramePtr);
21
+ streamingFramePtr = 0;
22
+ streamingFrameCapacity = 0;
23
+ }
38
24
  // Pre-allocate output buffer (fixed size)
39
25
  if (streamingMelPtr)
40
26
  Module._free(streamingMelPtr);
@@ -76,7 +62,7 @@ export function computeMelFrameWasm(samples) {
76
62
  * Lazy-loads the WASM module on first call.
77
63
  */
78
64
  export async function computeMelSpectrogramWasm(audioData, sampleRate, nMels, windowSizeSamples, hopLengthSamples, fMin, fMax, windowType, normalize, logScale) {
79
- const Module = await getModule();
65
+ const Module = (await getWasmModule());
80
66
  const fftLength = 2048;
81
67
  const windowTypeInt = windowType === 'hamming' ? 1 : 0;
82
68
  // Allocate input buffer on WASM heap
@@ -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'\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(\n /* webpackIgnore: true */ /* @vite-ignore */ url\n )\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 { getWasmModule } from './wasmLoader.web'\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 getWasmModule()) as MelSpectrogramWasmModule\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 // Free frame buffer from previous session (if any) to avoid leak on re-init\n if (streamingFramePtr) {\n Module._free(streamingFramePtr)\n streamingFramePtr = 0\n streamingFrameCapacity = 0\n }\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 getWasmModule()) as MelSpectrogramWasmModule\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,19 +1,19 @@
1
1
  // Version is inlined here — keep in sync with package.json when releasing.
2
2
  // The publish.sh script should bump this string alongside package.json.
3
- const WASM_VERSION = '3.0.2-beta.1';
3
+ const WASM_VERSION = '3.0.2';
4
4
  // jsDelivr syncs from npm automatically within ~5 min of publish.
5
5
  // GitHub release fallback (attach mel-spectrogram.js as a release asset):
6
6
  // https://github.com/deeeed/audiolab/releases/download/@siteed/audio-studio@VERSION/mel-spectrogram.js
7
7
  // To use the fallback: setMelSpectrogramWasmUrl('<url>') before any mel-spectrogram API call.
8
8
  const DEFAULT_WASM_CDN = `https://cdn.jsdelivr.net/npm/@siteed/audio-studio@${WASM_VERSION}/prebuilt/wasm/mel-spectrogram.js`;
9
9
  let _wasmUrl = DEFAULT_WASM_CDN;
10
- let _modulePromiseReset = null;
10
+ const _resetListeners = [];
11
11
  export function _registerModuleReset(fn) {
12
- _modulePromiseReset = fn;
12
+ _resetListeners.push(fn);
13
13
  }
14
14
  export function setMelSpectrogramWasmUrl(url) {
15
15
  _wasmUrl = url;
16
- _modulePromiseReset?.(); // invalidate cached module so next call re-fetches
16
+ _resetListeners.forEach((fn) => fn());
17
17
  }
18
18
  export function getMelSpectrogramWasmUrl() {
19
19
  return _wasmUrl;
@@ -1 +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"]}
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,MAAM,eAAe,GAAmB,EAAE,CAAA;AAE1C,MAAM,UAAU,oBAAoB,CAAC,EAAc;IAC/C,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAC5B,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,GAAW;IAChD,QAAQ,GAAG,GAAG,CAAA;IACd,eAAe,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA;AACzC,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\nconst _resetListeners: (() => void)[] = []\n\nexport function _registerModuleReset(fn: () => void): void {\n _resetListeners.push(fn)\n}\n\nexport function setMelSpectrogramWasmUrl(url: string): void {\n _wasmUrl = url\n _resetListeners.forEach((fn) => fn())\n}\n\nexport function getMelSpectrogramWasmUrl(): string {\n return _wasmUrl\n}\n"]}
@@ -0,0 +1,43 @@
1
+ import { getMelSpectrogramWasmUrl, _registerModuleReset } from './wasmConfig';
2
+ // Global factory name for the shared WASM binary. Despite the name referring to
3
+ // mel spectrogram, this single binary also exports all audio-features functions.
4
+ const WASM_GLOBAL_NAME = 'createMelSpectrogramModule';
5
+ let modulePromise = null;
6
+ _registerModuleReset(() => {
7
+ modulePromise = null;
8
+ });
9
+ function loadScriptTag(url) {
10
+ return new Promise((resolve, reject) => {
11
+ const script = document.createElement('script');
12
+ script.src = url;
13
+ script.onload = () => resolve();
14
+ script.onerror = () => reject(new Error(`Failed to load script: ${url}`));
15
+ document.head.appendChild(script);
16
+ });
17
+ }
18
+ export function getWasmModule() {
19
+ if (!modulePromise) {
20
+ modulePromise = (async () => {
21
+ const url = getMelSpectrogramWasmUrl();
22
+ // Try ESM import first; fall back to <script> tag for UMD modules
23
+ const mod = await import(
24
+ /* webpackIgnore: true */ /* @vite-ignore */ url);
25
+ let factory = mod.default ?? mod;
26
+ if (typeof factory !== 'function') {
27
+ // UMD fallback: load via <script> tag so the top-level `var` becomes a global and
28
+ // document.currentScript.src is set (Emscripten uses it to locate the .wasm binary).
29
+ await loadScriptTag(url);
30
+ factory = globalThis[WASM_GLOBAL_NAME];
31
+ }
32
+ if (typeof factory !== 'function') {
33
+ throw new TypeError(`WASM factory '${WASM_GLOBAL_NAME}' not found after loading ${url}`);
34
+ }
35
+ return factory();
36
+ })().catch((err) => {
37
+ modulePromise = null;
38
+ throw err;
39
+ });
40
+ }
41
+ return modulePromise;
42
+ }
43
+ //# sourceMappingURL=wasmLoader.web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wasmLoader.web.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/wasmLoader.web.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAE7E,gFAAgF;AAChF,iFAAiF;AACjF,MAAM,gBAAgB,GAAG,4BAA4B,CAAA;AACrD,IAAI,aAAa,GAA4C,IAAI,CAAA;AAEjE,oBAAoB,CAAC,GAAG,EAAE;IACtB,aAAa,GAAG,IAAI,CAAA;AACxB,CAAC,CAAC,CAAA;AAEF,SAAS,aAAa,CAAC,GAAW;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnC,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;QAC/C,MAAM,CAAC,GAAG,GAAG,GAAG,CAAA;QAChB,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,EAAE,CAAA;QAC/B,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE,CAClB,MAAM,CAAC,IAAI,KAAK,CAAC,0BAA0B,GAAG,EAAE,CAAC,CAAC,CAAA;QACtD,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;IACrC,CAAC,CAAC,CAAA;AACN,CAAC;AAED,MAAM,UAAU,aAAa;IACzB,IAAI,CAAC,aAAa,EAAE,CAAC;QACjB,aAAa,GAAG,CAAC,KAAK,IAAI,EAAE;YACxB,MAAM,GAAG,GAAG,wBAAwB,EAAE,CAAA;YACtC,kEAAkE;YAClE,MAAM,GAAG,GAAG,MAAM,MAAM;YACpB,yBAAyB,CAAC,kBAAkB,CAAC,GAAG,CACnD,CAAA;YACD,IAAI,OAAO,GAAY,GAAG,CAAC,OAAO,IAAI,GAAG,CAAA;YACzC,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;gBAChC,kFAAkF;gBAClF,qFAAqF;gBACrF,MAAM,aAAa,CAAC,GAAG,CAAC,CAAA;gBACxB,OAAO,GAAI,UAAsC,CAC7C,gBAAgB,CACnB,CAAA;YACL,CAAC;YACD,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;gBAChC,MAAM,IAAI,SAAS,CACf,iBAAiB,gBAAgB,6BAA6B,GAAG,EAAE,CACtE,CAAA;YACL,CAAC;YACD,OAAQ,OAAkD,EAAE,CAAA;QAChE,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","sourcesContent":["import type { AudioFeaturesWasmModule } from './audio-features-wasm'\nimport { getMelSpectrogramWasmUrl, _registerModuleReset } from './wasmConfig'\n\n// Global factory name for the shared WASM binary. Despite the name referring to\n// mel spectrogram, this single binary also exports all audio-features functions.\nconst WASM_GLOBAL_NAME = 'createMelSpectrogramModule'\nlet modulePromise: Promise<AudioFeaturesWasmModule> | null = null\n\n_registerModuleReset(() => {\n modulePromise = null\n})\n\nfunction loadScriptTag(url: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script')\n script.src = url\n script.onload = () => resolve()\n script.onerror = () =>\n reject(new Error(`Failed to load script: ${url}`))\n document.head.appendChild(script)\n })\n}\n\nexport function getWasmModule(): Promise<AudioFeaturesWasmModule> {\n if (!modulePromise) {\n modulePromise = (async () => {\n const url = getMelSpectrogramWasmUrl()\n // Try ESM import first; fall back to <script> tag for UMD modules\n const mod = await import(\n /* webpackIgnore: true */ /* @vite-ignore */ url\n )\n let factory: unknown = mod.default ?? mod\n if (typeof factory !== 'function') {\n // UMD fallback: load via <script> tag so the top-level `var` becomes a global and\n // document.currentScript.src is set (Emscripten uses it to locate the .wasm binary).\n await loadScriptTag(url)\n factory = (globalThis as Record<string, unknown>)[\n WASM_GLOBAL_NAME\n ]\n }\n if (typeof factory !== 'function') {\n throw new TypeError(\n `WASM factory '${WASM_GLOBAL_NAME}' not found after loading ${url}`\n )\n }\n return (factory as () => Promise<AudioFeaturesWasmModule>)()\n })().catch((err) => {\n modulePromise = null\n throw err\n })\n }\n return modulePromise\n}\n"]}