@siteed/expo-audio-studio 2.8.3 → 2.8.5

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 (35) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/build/cjs/AudioAnalysis/extractAudioAnalysis.js +2 -2
  3. package/build/cjs/AudioAnalysis/extractAudioAnalysis.js.map +1 -1
  4. package/build/cjs/AudioAnalysis/extractMelSpectrogram.js +1 -2
  5. package/build/cjs/AudioAnalysis/extractMelSpectrogram.js.map +1 -1
  6. package/build/cjs/AudioAnalysis/extractPreview.js +1 -2
  7. package/build/cjs/AudioAnalysis/extractPreview.js.map +1 -1
  8. package/build/cjs/AudioRecorder.provider.js +17 -7
  9. package/build/cjs/AudioRecorder.provider.js.map +1 -1
  10. package/build/cjs/events.js +3 -4
  11. package/build/cjs/events.js.map +1 -1
  12. package/build/cjs/hooks/useAudioDevices.js +1 -2
  13. package/build/cjs/hooks/useAudioDevices.js.map +1 -1
  14. package/build/cjs/trimAudio.js +2 -3
  15. package/build/cjs/trimAudio.js.map +1 -1
  16. package/build/cjs/useAudioRecorder.js +1 -2
  17. package/build/cjs/useAudioRecorder.js.map +1 -1
  18. package/build/cjs/utils/audioProcessing.js +1 -2
  19. package/build/cjs/utils/audioProcessing.js.map +1 -1
  20. package/build/types/AudioAnalysis/extractAudioAnalysis.d.ts.map +1 -1
  21. package/build/types/AudioAnalysis/extractAudioData.d.ts.map +1 -1
  22. package/build/types/AudioAnalysis/extractWaveform.d.ts.map +1 -1
  23. package/build/types/hooks/useAudioDevices.d.ts.map +1 -1
  24. package/build/types/utils/BlobFix.d.ts.map +1 -1
  25. package/build/types/utils/concatenateBuffers.d.ts.map +1 -1
  26. package/build/types/utils/convertPCMToFloat32.d.ts +2 -2
  27. package/build/types/utils/convertPCMToFloat32.d.ts.map +1 -1
  28. package/build/types/utils/encodingToBitDepth.d.ts.map +1 -1
  29. package/build/types/utils/getWavFileInfo.d.ts.map +1 -1
  30. package/build/types/utils/writeWavHeader.d.ts.map +1 -1
  31. package/ios/siteedexpoaudiostudio.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  32. package/ios/siteedexpoaudiostudio.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  33. package/package.json +7 -17
  34. package/plugin/tsconfig.tsbuildinfo +1 -0
  35. package/app.plugin.cjs +0 -15
package/CHANGELOG.md CHANGED
@@ -8,6 +8,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
  ## [Unreleased]
9
9
 
10
10
 
11
+ ## [2.8.5] - 2025-05-11
12
+ ### Changed
13
+ - chore(expo-audio-studio): remove exports field from package.json ([9dd5029](https://github.com/deeeed/expo-audio-stream/commit/9dd5029d81fcc3a4d5b95ee5956beb8481f3950a))
14
+ - chore(expo-audio-studio): release @siteed/expo-audio-studio@2.8.4 ([e86a373](https://github.com/deeeed/expo-audio-stream/commit/e86a373939ed3a371095cbfe09d664f2b4b16b9d))
15
+ ## [2.8.4] - 2025-05-11
16
+ ### Changed
17
+ - fix(expo-audio-studio): expo plugin setup ([78810c1](https://github.com/deeeed/expo-audio-stream/commit/78810c1682fc357ed79297971d53d61de88b901f))
11
18
  ## [2.8.3] - 2025-05-06
12
19
  ### Changed
13
20
  - chore(expo-audio-studio): update plugin configuration to use ESM format and streamline build process ([97432eb](https://github.com/deeeed/expo-audio-stream/commit/97432eb2944f43e03a1464fdc166a49392582b08))
@@ -234,7 +241,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
234
241
  - Feature: Audio features extraction during recording.
235
242
  - Feature: Consistent WAV PCM recording format across all platforms.
236
243
 
237
- [unreleased]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-studio@2.8.3...HEAD
244
+ [unreleased]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-studio@2.8.5...HEAD
245
+ [2.8.5]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-studio@2.8.4...@siteed/expo-audio-studio@2.8.5
246
+ [2.8.4]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-studio@2.8.3...@siteed/expo-audio-studio@2.8.4
238
247
  [2.8.3]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-studio@2.8.2...@siteed/expo-audio-studio@2.8.3
239
248
  [2.8.2]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-studio@2.8.1...@siteed/expo-audio-studio@2.8.2
240
249
  [2.8.1]: https://github.com/deeeed/expo-audio-stream/compare/@siteed/expo-audio-studio@2.8.0...@siteed/expo-audio-studio@2.8.1
@@ -3,7 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.extractRawWavAnalysis = exports.extractAudioAnalysis = void 0;
6
+ exports.extractRawWavAnalysis = void 0;
7
+ exports.extractAudioAnalysis = extractAudioAnalysis;
7
8
  const ExpoAudioStreamModule_1 = __importDefault(require("../ExpoAudioStreamModule"));
8
9
  const constants_1 = require("../constants");
9
10
  const audioProcessing_1 = require("../utils/audioProcessing");
@@ -116,7 +117,6 @@ async function extractAudioAnalysis(props) {
116
117
  return await ExpoAudioStreamModule_1.default.extractAudioAnalysis(props);
117
118
  }
118
119
  }
119
- exports.extractAudioAnalysis = extractAudioAnalysis;
120
120
  /**
121
121
  * Analyzes WAV files without decoding, preserving original PCM values.
122
122
  * Use this function when you need to ensure the analysis matches other software by avoiding any transformations.
@@ -1 +1 @@
1
- {"version":3,"file":"extractAudioAnalysis.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractAudioAnalysis.ts"],"names":[],"mappings":"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","sourcesContent":["// packages/expo-audio-stream/src/AudioAnalysis/extractAudioAnalysis.ts\n/**\n * This module provides functions for extracting and analyzing audio data.\n * - `extractAudioAnalysis`: For detailed analysis with customizable ranges and decoding options.\n * - `extractWavAudioAnalysis`: For analyzing WAV files without decoding, preserving original PCM values.\n * - `extractPreview`: For generating quick previews of audio waveforms, optimized for UI rendering.\n */\nimport { ConsoleLike } from '../ExpoAudioStream.types'\nimport ExpoAudioStreamModule from '../ExpoAudioStreamModule'\nimport { isWeb } from '../constants'\nimport {\n AudioAnalysis,\n AudioFeaturesOptions,\n DataPoint,\n DecodingConfig,\n} from './AudioAnalysis.types'\nimport { processAudioBuffer } from '../utils/audioProcessing'\nimport { convertPCMToFloat32 } from '../utils/convertPCMToFloat32'\nimport crc32 from '../utils/crc32'\nimport { getWavFileInfo, WavFileInfo } from '../utils/getWavFileInfo'\nimport { InlineFeaturesExtractor } from '../workers/InlineFeaturesExtractor.web'\n\nfunction calculateCRC32ForDataPoint(data: Float32Array): number {\n // Convert float array to byte array for CRC32\n const byteArray = new Uint8Array(data.length * 4)\n const dataView = new DataView(byteArray.buffer)\n\n for (let i = 0; i < data.length; i++) {\n dataView.setFloat32(i * 4, data[i], true)\n }\n\n return crc32.buf(byteArray)\n}\n\nexport interface ExtractWavAudioAnalysisProps {\n fileUri?: string // should provide either fileUri or arrayBuffer\n wavMetadata?: WavFileInfo\n arrayBuffer?: ArrayBuffer\n bitDepth?: number\n durationMs?: number\n sampleRate?: number\n numberOfChannels?: number\n position?: number // Optional number of bytes to skip. Default is 0\n length?: number // Optional number of bytes to read.\n segmentDurationMs?: number // Optional number of points per second. Use to reduce the number of points and compute the number of datapoints to return.\n features?: AudioFeaturesOptions\n featuresExtratorUrl?: string\n logger?: ConsoleLike\n decodingOptions?: DecodingConfig\n}\n\n// Define base options interface with common properties\ninterface BaseExtractOptions {\n fileUri?: string\n arrayBuffer?: ArrayBuffer\n /**\n * Duration of each analysis segment in milliseconds. Defaults to 100ms if not specified.\n */\n segmentDurationMs?: number\n features?: AudioFeaturesOptions\n decodingOptions?: DecodingConfig\n logger?: ConsoleLike\n}\n\n// Time-based range options\ninterface TimeRangeOptions extends BaseExtractOptions {\n startTimeMs?: number\n endTimeMs?: number\n position?: never\n length?: never\n}\n\n// Byte-based range options\ninterface ByteRangeOptions extends BaseExtractOptions {\n position?: number\n length?: number\n startTimeMs?: never\n endTimeMs?: never\n}\n\n/**\n * Options for extracting audio analysis.\n * - For time-based analysis, provide `startTimeMs` and `endTimeMs`.\n * - For byte-based analysis, provide `position` and `length`.\n * - Do not mix time and byte ranges.\n */\nexport type ExtractAudioAnalysisProps = TimeRangeOptions | ByteRangeOptions\n\n/**\n * Extracts detailed audio analysis from the specified audio file or buffer.\n * Supports either time-based or byte-based ranges for flexibility in analysis.\n *\n * @param props - The options for extraction, including file URI, ranges, and decoding settings.\n * @returns A promise that resolves to the audio analysis data.\n * @throws {Error} If both time and byte ranges are provided or if required parameters are missing.\n */\nexport async function extractAudioAnalysis(\n props: ExtractAudioAnalysisProps\n): Promise<AudioAnalysis> {\n const {\n fileUri,\n arrayBuffer,\n decodingOptions,\n logger,\n segmentDurationMs = 100,\n features,\n } = props\n\n if (isWeb) {\n try {\n // Create AudioContext here\n const audioContext = new (window.AudioContext ||\n (window as any).webkitAudioContext)({\n sampleRate: decodingOptions?.targetSampleRate ?? 16000,\n })\n\n try {\n const processedBuffer = await processAudioBuffer({\n arrayBuffer,\n fileUri,\n targetSampleRate:\n decodingOptions?.targetSampleRate ?? 16000,\n targetChannels: decodingOptions?.targetChannels ?? 1,\n normalizeAudio: decodingOptions?.normalizeAudio ?? false,\n startTimeMs:\n 'startTimeMs' in props ? props.startTimeMs : undefined,\n endTimeMs:\n 'endTimeMs' in props ? props.endTimeMs : undefined,\n position: 'position' in props ? props.position : undefined,\n length: 'length' in props ? props.length : undefined,\n audioContext, // Pass the context we created\n logger,\n })\n\n const channelData = processedBuffer.buffer.getChannelData(0)\n\n // Create and initialize the worker\n const blob = new Blob([InlineFeaturesExtractor], {\n type: 'application/javascript',\n })\n const workerUrl = URL.createObjectURL(blob)\n const worker = new Worker(workerUrl)\n\n return new Promise((resolve, reject) => {\n worker.onmessage = (event) => {\n if (event.data.error) {\n reject(new Error(event.data.error))\n return\n }\n\n const result: AudioAnalysis = event.data.result\n // Calculate CRC32 after worker completes if requested\n if (features?.crc32) {\n const samplesPerSegment = Math.floor(\n (processedBuffer.sampleRate *\n segmentDurationMs) /\n 1000\n )\n\n result.dataPoints = result.dataPoints.map(\n (point: DataPoint, index: number) => {\n const startSample =\n index * samplesPerSegment\n const segmentData = channelData.slice(\n startSample,\n startSample + samplesPerSegment\n )\n\n return {\n ...point,\n features: {\n ...point.features,\n crc32: calculateCRC32ForDataPoint(\n segmentData\n ),\n },\n }\n }\n )\n }\n\n URL.revokeObjectURL(workerUrl)\n worker.terminate()\n resolve(result)\n }\n\n worker.onerror = (error) => {\n URL.revokeObjectURL(workerUrl)\n worker.terminate()\n reject(error)\n }\n\n worker.postMessage({\n channelData,\n sampleRate: processedBuffer.sampleRate,\n segmentDurationMs,\n bitDepth: decodingOptions?.targetBitDepth ?? 32,\n numberOfChannels: processedBuffer.channels,\n fullAudioDurationMs: processedBuffer.durationMs,\n // enableLogging: !!logger,\n features,\n })\n })\n } finally {\n await audioContext.close()\n }\n } catch (error) {\n logger?.error('Failed to process audio:', error)\n throw error\n }\n } else {\n return await ExpoAudioStreamModule.extractAudioAnalysis(props)\n }\n}\n\n/**\n * Analyzes WAV files without decoding, preserving original PCM values.\n * Use this function when you need to ensure the analysis matches other software by avoiding any transformations.\n *\n * @param props - The options for WAV analysis, including file URI and range.\n * @returns A promise that resolves to the audio analysis data.\n */\nexport const extractRawWavAnalysis = async ({\n fileUri,\n segmentDurationMs = 100, // Default to 100ms\n arrayBuffer,\n bitDepth,\n durationMs,\n sampleRate,\n numberOfChannels,\n features,\n logger,\n position = 0,\n length,\n}: ExtractWavAudioAnalysisProps): Promise<AudioAnalysis> => {\n if (isWeb) {\n if (!arrayBuffer && !fileUri) {\n throw new Error('Either arrayBuffer or fileUri must be provided')\n }\n\n if (!arrayBuffer) {\n logger?.log(`fetching fileUri`, fileUri)\n const response = await fetch(fileUri!)\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch fileUri: ${response.statusText}`\n )\n }\n\n arrayBuffer = await response.arrayBuffer()\n logger?.log(`fetched fileUri`, arrayBuffer.byteLength, arrayBuffer)\n }\n\n // Create a new copy of the ArrayBuffer to avoid detachment issues\n const bufferCopy = arrayBuffer.slice(0)\n logger?.log(\n `extractAudioAnalysis bitDepth=${bitDepth} len=${bufferCopy.byteLength}`,\n bufferCopy.slice(0, 100)\n )\n\n let actualBitDepth = bitDepth\n if (!actualBitDepth) {\n logger?.log(\n `extractAudioAnalysis bitDepth not provided -- getting wav file info`\n )\n const fileInfo = await getWavFileInfo(bufferCopy)\n actualBitDepth = fileInfo.bitDepth\n }\n logger?.log(`extractAudioAnalysis actualBitDepth=${actualBitDepth}`)\n\n const {\n pcmValues: channelData,\n min,\n max,\n } = await convertPCMToFloat32({\n buffer: arrayBuffer,\n bitDepth: actualBitDepth,\n })\n logger?.log(\n `extractAudioAnalysis convertPCMToFloat32 length=${channelData.length} range: [ ${min} :: ${max} ]`\n )\n\n // Apply position and length constraints to channelData if specified\n const startIndex = position\n const endIndex = length ? startIndex + length : channelData.length\n const constrainedChannelData = channelData.slice(startIndex, endIndex)\n\n return new Promise((resolve, reject) => {\n const blob = new Blob([InlineFeaturesExtractor], {\n type: 'application/javascript',\n })\n const url = URL.createObjectURL(blob)\n const worker = new Worker(url)\n\n worker.onmessage = (event) => {\n resolve(event.data.result)\n }\n\n worker.onerror = (error) => {\n reject(error)\n }\n\n worker.postMessage({\n command: 'process',\n channelData: constrainedChannelData,\n sampleRate,\n segmentDurationMs,\n logger,\n bitDepth,\n fullAudioDurationMs: durationMs,\n numberOfChannels,\n })\n })\n } else {\n if (!fileUri) {\n throw new Error('fileUri is required')\n }\n logger?.log(`extractAudioAnalysis`, {\n fileUri,\n segmentDurationMs,\n })\n const res = await ExpoAudioStreamModule.extractAudioAnalysis({\n fileUri,\n segmentDurationMs,\n features,\n position,\n length,\n })\n logger?.log(`extractAudioAnalysis`, res)\n return res\n }\n}\n"]}
1
+ {"version":3,"file":"extractAudioAnalysis.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractAudioAnalysis.ts"],"names":[],"mappings":"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","sourcesContent":["// packages/expo-audio-stream/src/AudioAnalysis/extractAudioAnalysis.ts\n/**\n * This module provides functions for extracting and analyzing audio data.\n * - `extractAudioAnalysis`: For detailed analysis with customizable ranges and decoding options.\n * - `extractWavAudioAnalysis`: For analyzing WAV files without decoding, preserving original PCM values.\n * - `extractPreview`: For generating quick previews of audio waveforms, optimized for UI rendering.\n */\nimport { ConsoleLike } from '../ExpoAudioStream.types'\nimport ExpoAudioStreamModule from '../ExpoAudioStreamModule'\nimport { isWeb } from '../constants'\nimport {\n AudioAnalysis,\n AudioFeaturesOptions,\n DataPoint,\n DecodingConfig,\n} from './AudioAnalysis.types'\nimport { processAudioBuffer } from '../utils/audioProcessing'\nimport { convertPCMToFloat32 } from '../utils/convertPCMToFloat32'\nimport crc32 from '../utils/crc32'\nimport { getWavFileInfo, WavFileInfo } from '../utils/getWavFileInfo'\nimport { InlineFeaturesExtractor } from '../workers/InlineFeaturesExtractor.web'\n\nfunction calculateCRC32ForDataPoint(data: Float32Array): number {\n // Convert float array to byte array for CRC32\n const byteArray = new Uint8Array(data.length * 4)\n const dataView = new DataView(byteArray.buffer)\n\n for (let i = 0; i < data.length; i++) {\n dataView.setFloat32(i * 4, data[i], true)\n }\n\n return crc32.buf(byteArray)\n}\n\nexport interface ExtractWavAudioAnalysisProps {\n fileUri?: string // should provide either fileUri or arrayBuffer\n wavMetadata?: WavFileInfo\n arrayBuffer?: ArrayBuffer\n bitDepth?: number\n durationMs?: number\n sampleRate?: number\n numberOfChannels?: number\n position?: number // Optional number of bytes to skip. Default is 0\n length?: number // Optional number of bytes to read.\n segmentDurationMs?: number // Optional number of points per second. Use to reduce the number of points and compute the number of datapoints to return.\n features?: AudioFeaturesOptions\n featuresExtratorUrl?: string\n logger?: ConsoleLike\n decodingOptions?: DecodingConfig\n}\n\n// Define base options interface with common properties\ninterface BaseExtractOptions {\n fileUri?: string\n arrayBuffer?: ArrayBuffer\n /**\n * Duration of each analysis segment in milliseconds. Defaults to 100ms if not specified.\n */\n segmentDurationMs?: number\n features?: AudioFeaturesOptions\n decodingOptions?: DecodingConfig\n logger?: ConsoleLike\n}\n\n// Time-based range options\ninterface TimeRangeOptions extends BaseExtractOptions {\n startTimeMs?: number\n endTimeMs?: number\n position?: never\n length?: never\n}\n\n// Byte-based range options\ninterface ByteRangeOptions extends BaseExtractOptions {\n position?: number\n length?: number\n startTimeMs?: never\n endTimeMs?: never\n}\n\n/**\n * Options for extracting audio analysis.\n * - For time-based analysis, provide `startTimeMs` and `endTimeMs`.\n * - For byte-based analysis, provide `position` and `length`.\n * - Do not mix time and byte ranges.\n */\nexport type ExtractAudioAnalysisProps = TimeRangeOptions | ByteRangeOptions\n\n/**\n * Extracts detailed audio analysis from the specified audio file or buffer.\n * Supports either time-based or byte-based ranges for flexibility in analysis.\n *\n * @param props - The options for extraction, including file URI, ranges, and decoding settings.\n * @returns A promise that resolves to the audio analysis data.\n * @throws {Error} If both time and byte ranges are provided or if required parameters are missing.\n */\nexport async function extractAudioAnalysis(\n props: ExtractAudioAnalysisProps\n): Promise<AudioAnalysis> {\n const {\n fileUri,\n arrayBuffer,\n decodingOptions,\n logger,\n segmentDurationMs = 100,\n features,\n } = props\n\n if (isWeb) {\n try {\n // Create AudioContext here\n const audioContext = new (window.AudioContext ||\n (window as any).webkitAudioContext)({\n sampleRate: decodingOptions?.targetSampleRate ?? 16000,\n })\n\n try {\n const processedBuffer = await processAudioBuffer({\n arrayBuffer,\n fileUri,\n targetSampleRate:\n decodingOptions?.targetSampleRate ?? 16000,\n targetChannels: decodingOptions?.targetChannels ?? 1,\n normalizeAudio: decodingOptions?.normalizeAudio ?? false,\n startTimeMs:\n 'startTimeMs' in props ? props.startTimeMs : undefined,\n endTimeMs:\n 'endTimeMs' in props ? props.endTimeMs : undefined,\n position: 'position' in props ? props.position : undefined,\n length: 'length' in props ? props.length : undefined,\n audioContext, // Pass the context we created\n logger,\n })\n\n const channelData = processedBuffer.buffer.getChannelData(0)\n\n // Create and initialize the worker\n const blob = new Blob([InlineFeaturesExtractor], {\n type: 'application/javascript',\n })\n const workerUrl = URL.createObjectURL(blob)\n const worker = new Worker(workerUrl)\n\n return new Promise((resolve, reject) => {\n worker.onmessage = (event) => {\n if (event.data.error) {\n reject(new Error(event.data.error))\n return\n }\n\n const result: AudioAnalysis = event.data.result\n // Calculate CRC32 after worker completes if requested\n if (features?.crc32) {\n const samplesPerSegment = Math.floor(\n (processedBuffer.sampleRate *\n segmentDurationMs) /\n 1000\n )\n\n result.dataPoints = result.dataPoints.map(\n (point: DataPoint, index: number) => {\n const startSample =\n index * samplesPerSegment\n const segmentData = channelData.slice(\n startSample,\n startSample + samplesPerSegment\n )\n\n return {\n ...point,\n features: {\n ...point.features,\n crc32: calculateCRC32ForDataPoint(\n segmentData\n ),\n },\n }\n }\n )\n }\n\n URL.revokeObjectURL(workerUrl)\n worker.terminate()\n resolve(result)\n }\n\n worker.onerror = (error) => {\n URL.revokeObjectURL(workerUrl)\n worker.terminate()\n reject(error)\n }\n\n worker.postMessage({\n channelData,\n sampleRate: processedBuffer.sampleRate,\n segmentDurationMs,\n bitDepth: decodingOptions?.targetBitDepth ?? 32,\n numberOfChannels: processedBuffer.channels,\n fullAudioDurationMs: processedBuffer.durationMs,\n // enableLogging: !!logger,\n features,\n })\n })\n } finally {\n await audioContext.close()\n }\n } catch (error) {\n logger?.error('Failed to process audio:', error)\n throw error\n }\n } else {\n return await ExpoAudioStreamModule.extractAudioAnalysis(props)\n }\n}\n\n/**\n * Analyzes WAV files without decoding, preserving original PCM values.\n * Use this function when you need to ensure the analysis matches other software by avoiding any transformations.\n *\n * @param props - The options for WAV analysis, including file URI and range.\n * @returns A promise that resolves to the audio analysis data.\n */\nexport const extractRawWavAnalysis = async ({\n fileUri,\n segmentDurationMs = 100, // Default to 100ms\n arrayBuffer,\n bitDepth,\n durationMs,\n sampleRate,\n numberOfChannels,\n features,\n logger,\n position = 0,\n length,\n}: ExtractWavAudioAnalysisProps): Promise<AudioAnalysis> => {\n if (isWeb) {\n if (!arrayBuffer && !fileUri) {\n throw new Error('Either arrayBuffer or fileUri must be provided')\n }\n\n if (!arrayBuffer) {\n logger?.log(`fetching fileUri`, fileUri)\n const response = await fetch(fileUri!)\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch fileUri: ${response.statusText}`\n )\n }\n\n arrayBuffer = await response.arrayBuffer()\n logger?.log(`fetched fileUri`, arrayBuffer.byteLength, arrayBuffer)\n }\n\n // Create a new copy of the ArrayBuffer to avoid detachment issues\n const bufferCopy = arrayBuffer.slice(0)\n logger?.log(\n `extractAudioAnalysis bitDepth=${bitDepth} len=${bufferCopy.byteLength}`,\n bufferCopy.slice(0, 100)\n )\n\n let actualBitDepth = bitDepth\n if (!actualBitDepth) {\n logger?.log(\n `extractAudioAnalysis bitDepth not provided -- getting wav file info`\n )\n const fileInfo = await getWavFileInfo(bufferCopy)\n actualBitDepth = fileInfo.bitDepth\n }\n logger?.log(`extractAudioAnalysis actualBitDepth=${actualBitDepth}`)\n\n const {\n pcmValues: channelData,\n min,\n max,\n } = await convertPCMToFloat32({\n buffer: arrayBuffer,\n bitDepth: actualBitDepth,\n })\n logger?.log(\n `extractAudioAnalysis convertPCMToFloat32 length=${channelData.length} range: [ ${min} :: ${max} ]`\n )\n\n // Apply position and length constraints to channelData if specified\n const startIndex = position\n const endIndex = length ? startIndex + length : channelData.length\n const constrainedChannelData = channelData.slice(startIndex, endIndex)\n\n return new Promise((resolve, reject) => {\n const blob = new Blob([InlineFeaturesExtractor], {\n type: 'application/javascript',\n })\n const url = URL.createObjectURL(blob)\n const worker = new Worker(url)\n\n worker.onmessage = (event) => {\n resolve(event.data.result)\n }\n\n worker.onerror = (error) => {\n reject(error)\n }\n\n worker.postMessage({\n command: 'process',\n channelData: constrainedChannelData,\n sampleRate,\n segmentDurationMs,\n logger,\n bitDepth,\n fullAudioDurationMs: durationMs,\n numberOfChannels,\n })\n })\n } else {\n if (!fileUri) {\n throw new Error('fileUri is required')\n }\n logger?.log(`extractAudioAnalysis`, {\n fileUri,\n segmentDurationMs,\n })\n const res = await ExpoAudioStreamModule.extractAudioAnalysis({\n fileUri,\n segmentDurationMs,\n features,\n position,\n length,\n })\n logger?.log(`extractAudioAnalysis`, res)\n return res\n }\n}\n"]}
@@ -4,7 +4,7 @@
4
4
  * The API may change in future versions. The web implementation is a placeholder.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.extractMelSpectrogram = void 0;
7
+ exports.extractMelSpectrogram = extractMelSpectrogram;
8
8
  const __1 = require("..");
9
9
  const constants_1 = require("../constants");
10
10
  const audioProcessing_1 = require("../utils/audioProcessing");
@@ -61,7 +61,6 @@ async function extractMelSpectrogram(options) {
61
61
  }
62
62
  return __1.ExpoAudioStreamModule.extractMelSpectrogram(options);
63
63
  }
64
- exports.extractMelSpectrogram = extractMelSpectrogram;
65
64
  /**
66
65
  * Computes a mel spectrogram from audio data
67
66
  *
@@ -1 +1 @@
1
- {"version":3,"file":"extractMelSpectrogram.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractMelSpectrogram.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @experimental This feature is experimental and currently only available on Android.\n * The API may change in future versions. The web implementation is a placeholder.\n */\n\nimport { ExpoAudioStreamModule } from '..'\nimport { isWeb } from '../constants'\nimport {\n ExtractMelSpectrogramOptions,\n MelSpectrogram,\n} from './AudioAnalysis.types'\nimport {\n processAudioBuffer,\n ProcessedAudioData,\n} from '../utils/audioProcessing'\n\n/**\n * Extracts a mel spectrogram from audio data\n *\n * @experimental This feature is experimental and currently only available on Android.\n * The iOS implementation will throw an \"UNSUPPORTED_PLATFORM\" error.\n * The web implementation is a placeholder that returns dummy data.\n */\nexport async function extractMelSpectrogram(\n options: ExtractMelSpectrogramOptions\n): Promise<MelSpectrogram> {\n const {\n fileUri,\n arrayBuffer,\n windowSizeMs,\n hopLengthMs,\n nMels,\n fMin = 0,\n fMax,\n windowType = 'hann',\n normalize = false,\n logScale = true,\n decodingOptions,\n startTimeMs,\n endTimeMs,\n logger,\n } = options\n\n if (isWeb) {\n // Create audio context\n const audioContext = new (window.AudioContext ||\n (window as any).webkitAudioContext)()\n\n try {\n // Process audio data using the existing utility\n const processedAudio: ProcessedAudioData = await processAudioBuffer(\n {\n arrayBuffer,\n fileUri,\n targetSampleRate:\n decodingOptions?.targetSampleRate || 16000,\n targetChannels: decodingOptions?.targetChannels || 1,\n normalizeAudio: decodingOptions?.normalizeAudio ?? false,\n startTimeMs,\n endTimeMs,\n audioContext,\n logger: options.logger,\n }\n )\n\n // Calculate window and hop size in samples\n const sampleRate = processedAudio.sampleRate\n const windowSize = Math.floor((windowSizeMs * sampleRate) / 1000)\n const hopLength = Math.floor((hopLengthMs * sampleRate) / 1000)\n const maxFreq = fMax || sampleRate / 2\n\n // Extract the mel spectrogram from the processed audio\n const spectrogram = computeMelSpectrogram(\n processedAudio.channelData,\n sampleRate,\n nMels,\n windowSize,\n hopLength,\n fMin,\n maxFreq,\n windowType,\n normalize,\n logScale\n )\n\n const timeSteps = spectrogram.length\n\n return {\n spectrogram,\n sampleRate,\n nMels,\n timeSteps,\n durationMs: processedAudio.durationMs,\n }\n } catch (error) {\n logger?.error('Error extracting mel spectrogram:', error)\n throw error\n } finally {\n // Close the audio context\n await audioContext.close()\n }\n }\n return ExpoAudioStreamModule.extractMelSpectrogram(options)\n}\n\n/**\n * Computes a mel spectrogram from audio data\n *\n * @experimental This is a placeholder implementation that returns dummy data.\n * The actual implementation will be added in a future version.\n */\nfunction computeMelSpectrogram(\n audioData: Float32Array,\n sampleRate: number,\n nMels: number,\n windowSize: number,\n hopLength: number,\n fMin: number,\n fMax: number,\n windowType: 'hann' | 'hamming',\n normalize: boolean,\n logScale: boolean\n): number[][] {\n // Placeholder for the actual implementation\n // This would include:\n // 1. Windowing the audio data using the specified window type\n // 2. Computing the STFT (Short-Time Fourier Transform)\n // 3. Converting to power spectrogram\n // 4. Applying mel filterbanks\n // 5. Taking the logarithm if logScale is true\n // 6. Normalizing if normalize is true\n\n // For now, return a dummy implementation\n const numFrames =\n Math.floor((audioData.length - windowSize) / hopLength) + 1\n const spectrogram: number[][] = []\n\n // Create dummy mel spectrogram data\n for (let i = 0; i < numFrames; i++) {\n spectrogram.push(Array(nMels).fill(0))\n }\n\n return spectrogram\n}\n"]}
1
+ {"version":3,"file":"extractMelSpectrogram.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractMelSpectrogram.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @experimental This feature is experimental and currently only available on Android.\n * The API may change in future versions. The web implementation is a placeholder.\n */\n\nimport { ExpoAudioStreamModule } from '..'\nimport { isWeb } from '../constants'\nimport {\n ExtractMelSpectrogramOptions,\n MelSpectrogram,\n} from './AudioAnalysis.types'\nimport {\n processAudioBuffer,\n ProcessedAudioData,\n} from '../utils/audioProcessing'\n\n/**\n * Extracts a mel spectrogram from audio data\n *\n * @experimental This feature is experimental and currently only available on Android.\n * The iOS implementation will throw an \"UNSUPPORTED_PLATFORM\" error.\n * The web implementation is a placeholder that returns dummy data.\n */\nexport async function extractMelSpectrogram(\n options: ExtractMelSpectrogramOptions\n): Promise<MelSpectrogram> {\n const {\n fileUri,\n arrayBuffer,\n windowSizeMs,\n hopLengthMs,\n nMels,\n fMin = 0,\n fMax,\n windowType = 'hann',\n normalize = false,\n logScale = true,\n decodingOptions,\n startTimeMs,\n endTimeMs,\n logger,\n } = options\n\n if (isWeb) {\n // Create audio context\n const audioContext = new (window.AudioContext ||\n (window as any).webkitAudioContext)()\n\n try {\n // Process audio data using the existing utility\n const processedAudio: ProcessedAudioData = await processAudioBuffer(\n {\n arrayBuffer,\n fileUri,\n targetSampleRate:\n decodingOptions?.targetSampleRate || 16000,\n targetChannels: decodingOptions?.targetChannels || 1,\n normalizeAudio: decodingOptions?.normalizeAudio ?? false,\n startTimeMs,\n endTimeMs,\n audioContext,\n logger: options.logger,\n }\n )\n\n // Calculate window and hop size in samples\n const sampleRate = processedAudio.sampleRate\n const windowSize = Math.floor((windowSizeMs * sampleRate) / 1000)\n const hopLength = Math.floor((hopLengthMs * sampleRate) / 1000)\n const maxFreq = fMax || sampleRate / 2\n\n // Extract the mel spectrogram from the processed audio\n const spectrogram = computeMelSpectrogram(\n processedAudio.channelData,\n sampleRate,\n nMels,\n windowSize,\n hopLength,\n fMin,\n maxFreq,\n windowType,\n normalize,\n logScale\n )\n\n const timeSteps = spectrogram.length\n\n return {\n spectrogram,\n sampleRate,\n nMels,\n timeSteps,\n durationMs: processedAudio.durationMs,\n }\n } catch (error) {\n logger?.error('Error extracting mel spectrogram:', error)\n throw error\n } finally {\n // Close the audio context\n await audioContext.close()\n }\n }\n return ExpoAudioStreamModule.extractMelSpectrogram(options)\n}\n\n/**\n * Computes a mel spectrogram from audio data\n *\n * @experimental This is a placeholder implementation that returns dummy data.\n * The actual implementation will be added in a future version.\n */\nfunction computeMelSpectrogram(\n audioData: Float32Array,\n sampleRate: number,\n nMels: number,\n windowSize: number,\n hopLength: number,\n fMin: number,\n fMax: number,\n windowType: 'hann' | 'hamming',\n normalize: boolean,\n logScale: boolean\n): number[][] {\n // Placeholder for the actual implementation\n // This would include:\n // 1. Windowing the audio data using the specified window type\n // 2. Computing the STFT (Short-Time Fourier Transform)\n // 3. Converting to power spectrogram\n // 4. Applying mel filterbanks\n // 5. Taking the logarithm if logScale is true\n // 6. Normalizing if normalize is true\n\n // For now, return a dummy implementation\n const numFrames =\n Math.floor((audioData.length - windowSize) / hopLength) + 1\n const spectrogram: number[][] = []\n\n // Create dummy mel spectrogram data\n for (let i = 0; i < numFrames; i++) {\n spectrogram.push(Array(nMels).fill(0))\n }\n\n return spectrogram\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.extractPreview = void 0;
3
+ exports.extractPreview = extractPreview;
4
4
  const extractAudioAnalysis_1 = require("./extractAudioAnalysis");
5
5
  /**
6
6
  * Generates a simplified preview of the audio waveform for quick visualization.
@@ -25,5 +25,4 @@ decodingOptions, logger, }) {
25
25
  // Transform the result into AudioPreview format
26
26
  return analysis;
27
27
  }
28
- exports.extractPreview = extractPreview;
29
28
  //# sourceMappingURL=extractPreview.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"extractPreview.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractPreview.ts"],"names":[],"mappings":";;;AACA,iEAA6D;AAE7D;;;;;;GAMG;AACI,KAAK,UAAU,cAAc,CAAC,EACjC,OAAO,EACP,cAAc,GAAG,GAAG,EACpB,WAAW,GAAG,CAAC,EACf,SAAS,GAAG,KAAK,EAAE,mBAAmB;AACtC,eAAe,EACf,MAAM,GACO;IACb,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,CAAA;IAC1C,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,cAAc,CAAC,CAAA;IAEjE,uDAAuD;IACvD,MAAM,QAAQ,GAAG,MAAM,IAAA,2CAAoB,EAAC;QACxC,OAAO;QACP,WAAW;QACX,SAAS;QACT,MAAM;QACN,iBAAiB;QACjB,eAAe;KAClB,CAAC,CAAA;IAEF,gDAAgD;IAChD,OAAO,QAAQ,CAAA;AACnB,CAAC;AAvBD,wCAuBC","sourcesContent":["import { PreviewOptions, AudioAnalysis } from './AudioAnalysis.types'\nimport { extractAudioAnalysis } from './extractAudioAnalysis'\n\n/**\n * Generates a simplified preview of the audio waveform for quick visualization.\n * Ideal for UI rendering with a specified number of points.\n *\n * @param options - The options for the preview, including file URI and time range.\n * @returns A promise that resolves to the audio preview data.\n */\nexport async function extractPreview({\n fileUri,\n numberOfPoints = 100,\n startTimeMs = 0,\n endTimeMs = 30000, // First 30 seconds\n decodingOptions,\n logger,\n}: PreviewOptions): Promise<AudioAnalysis> {\n const durationMs = endTimeMs - startTimeMs\n const segmentDurationMs = Math.floor(durationMs / numberOfPoints)\n\n // Call extractAudioAnalysis with calculated parameters\n const analysis = await extractAudioAnalysis({\n fileUri,\n startTimeMs,\n endTimeMs,\n logger,\n segmentDurationMs,\n decodingOptions,\n })\n\n // Transform the result into AudioPreview format\n return analysis\n}\n"]}
1
+ {"version":3,"file":"extractPreview.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractPreview.ts"],"names":[],"mappings":";;AAUA,wCAuBC;AAhCD,iEAA6D;AAE7D;;;;;;GAMG;AACI,KAAK,UAAU,cAAc,CAAC,EACjC,OAAO,EACP,cAAc,GAAG,GAAG,EACpB,WAAW,GAAG,CAAC,EACf,SAAS,GAAG,KAAK,EAAE,mBAAmB;AACtC,eAAe,EACf,MAAM,GACO;IACb,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,CAAA;IAC1C,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,cAAc,CAAC,CAAA;IAEjE,uDAAuD;IACvD,MAAM,QAAQ,GAAG,MAAM,IAAA,2CAAoB,EAAC;QACxC,OAAO;QACP,WAAW;QACX,SAAS;QACT,MAAM;QACN,iBAAiB;QACjB,eAAe;KAClB,CAAC,CAAA;IAEF,gDAAgD;IAChD,OAAO,QAAQ,CAAA;AACnB,CAAC","sourcesContent":["import { PreviewOptions, AudioAnalysis } from './AudioAnalysis.types'\nimport { extractAudioAnalysis } from './extractAudioAnalysis'\n\n/**\n * Generates a simplified preview of the audio waveform for quick visualization.\n * Ideal for UI rendering with a specified number of points.\n *\n * @param options - The options for the preview, including file URI and time range.\n * @returns A promise that resolves to the audio preview data.\n */\nexport async function extractPreview({\n fileUri,\n numberOfPoints = 100,\n startTimeMs = 0,\n endTimeMs = 30000, // First 30 seconds\n decodingOptions,\n logger,\n}: PreviewOptions): Promise<AudioAnalysis> {\n const durationMs = endTimeMs - startTimeMs\n const segmentDurationMs = Math.floor(durationMs / numberOfPoints)\n\n // Call extractAudioAnalysis with calculated parameters\n const analysis = await extractAudioAnalysis({\n fileUri,\n startTimeMs,\n endTimeMs,\n logger,\n segmentDurationMs,\n decodingOptions,\n })\n\n // Transform the result into AudioPreview format\n return analysis\n}\n"]}
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
25
35
  Object.defineProperty(exports, "__esModule", { value: true });
26
36
  exports.useSharedAudioRecorder = exports.AudioRecorderProvider = void 0;
27
37
  // packages/expo-audio-stream/src/AudioRecorder.provider.tsx
@@ -1 +1 @@
1
- {"version":3,"file":"AudioRecorder.provider.js","sourceRoot":"","sources":["../../src/AudioRecorder.provider.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4DAA4D;AAC5D,+CAAwD;AAGxD,yDAA4E;AAE5E,MAAM,WAAW,GAA0B;IACvC,WAAW,EAAE,KAAK;IAClB,QAAQ,EAAE,KAAK;IACf,UAAU,EAAE,CAAC;IACb,IAAI,EAAE,CAAC;IACP,WAAW,EAAE,SAAS;IACtB,cAAc,EAAE,KAAK,IAAI,EAAE;QACvB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IACtD,CAAC;IACD,aAAa,EAAE,KAAK,IAAI,EAAE;QACtB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IACtD,CAAC;IACD,cAAc,EAAE,KAAK,IAAI,EAAE;QACvB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IACtD,CAAC;IACD,eAAe,EAAE,KAAK,IAAI,EAAE;QACxB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IACtD,CAAC;IACD,gBAAgB,EAAE,KAAK,IAAI,EAAE;QACzB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IACtD,CAAC;CACJ,CAAA;AAED,MAAM,oBAAoB,GAAG,IAAA,qBAAa,EAAwB,WAAW,CAAC,CAAA;AAOvE,MAAM,qBAAqB,GAAyC,CAAC,EACxE,QAAQ,EACR,MAAM,GAAG,EAAE,GACd,EAAE,EAAE;IACD,MAAM,aAAa,GAAG,IAAA,mCAAgB,EAAC,MAAM,CAAC,CAAA;IAC9C,OAAO,CACH,CAAC,oBAAoB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,CAChD;YAAA,CAAC,QAAQ,CACb;QAAA,EAAE,oBAAoB,CAAC,QAAQ,CAAC,CACnC,CAAA;AACL,CAAC,CAAA;AAVY,QAAA,qBAAqB,yBAUjC;AAEM,MAAM,sBAAsB,GAAG,GAAG,EAAE;IACvC,MAAM,OAAO,GAAG,IAAA,kBAAU,EAAC,oBAAoB,CAAC,CAAA;IAChD,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACX,qEAAqE,CACxE,CAAA;IACL,CAAC;IACD,OAAO,OAAO,CAAA;AAClB,CAAC,CAAA;AARY,QAAA,sBAAsB,0BAQlC","sourcesContent":["// packages/expo-audio-stream/src/AudioRecorder.provider.tsx\nimport React, { createContext, useContext } from 'react'\n\nimport { UseAudioRecorderState } from './ExpoAudioStream.types'\nimport { UseAudioRecorderProps, useAudioRecorder } from './useAudioRecorder'\n\nconst initContext: UseAudioRecorderState = {\n isRecording: false,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined,\n startRecording: async () => {\n throw new Error('AudioRecorderProvider not found')\n },\n stopRecording: async () => {\n throw new Error('AudioRecorderProvider not found')\n },\n pauseRecording: async () => {\n throw new Error('AudioRecorderProvider not found')\n },\n resumeRecording: async () => {\n throw new Error('AudioRecorderProvider not found')\n },\n prepareRecording: async () => {\n throw new Error('AudioRecorderProvider not found')\n },\n}\n\nconst AudioRecorderContext = createContext<UseAudioRecorderState>(initContext)\n\ninterface AudioRecorderProviderProps {\n children: React.ReactNode\n config?: UseAudioRecorderProps\n}\n\nexport const AudioRecorderProvider: React.FC<AudioRecorderProviderProps> = ({\n children,\n config = {},\n}) => {\n const audioRecorder = useAudioRecorder(config)\n return (\n <AudioRecorderContext.Provider value={audioRecorder}>\n {children}\n </AudioRecorderContext.Provider>\n )\n}\n\nexport const useSharedAudioRecorder = () => {\n const context = useContext(AudioRecorderContext)\n if (!context) {\n throw new Error(\n 'useSharedAudioRecorder must be used within an AudioRecorderProvider'\n )\n }\n return context\n}\n"]}
1
+ {"version":3,"file":"AudioRecorder.provider.js","sourceRoot":"","sources":["../../src/AudioRecorder.provider.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4DAA4D;AAC5D,+CAAwD;AAGxD,yDAA4E;AAE5E,MAAM,WAAW,GAA0B;IACvC,WAAW,EAAE,KAAK;IAClB,QAAQ,EAAE,KAAK;IACf,UAAU,EAAE,CAAC;IACb,IAAI,EAAE,CAAC;IACP,WAAW,EAAE,SAAS;IACtB,cAAc,EAAE,KAAK,IAAI,EAAE;QACvB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IACtD,CAAC;IACD,aAAa,EAAE,KAAK,IAAI,EAAE;QACtB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IACtD,CAAC;IACD,cAAc,EAAE,KAAK,IAAI,EAAE;QACvB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IACtD,CAAC;IACD,eAAe,EAAE,KAAK,IAAI,EAAE;QACxB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IACtD,CAAC;IACD,gBAAgB,EAAE,KAAK,IAAI,EAAE;QACzB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IACtD,CAAC;CACJ,CAAA;AAED,MAAM,oBAAoB,GAAG,IAAA,qBAAa,EAAwB,WAAW,CAAC,CAAA;AAOvE,MAAM,qBAAqB,GAAyC,CAAC,EACxE,QAAQ,EACR,MAAM,GAAG,EAAE,GACd,EAAE,EAAE;IACD,MAAM,aAAa,GAAG,IAAA,mCAAgB,EAAC,MAAM,CAAC,CAAA;IAC9C,OAAO,CACH,CAAC,oBAAoB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,CAChD;YAAA,CAAC,QAAQ,CACb;QAAA,EAAE,oBAAoB,CAAC,QAAQ,CAAC,CACnC,CAAA;AACL,CAAC,CAAA;AAVY,QAAA,qBAAqB,yBAUjC;AAEM,MAAM,sBAAsB,GAAG,GAAG,EAAE;IACvC,MAAM,OAAO,GAAG,IAAA,kBAAU,EAAC,oBAAoB,CAAC,CAAA;IAChD,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACX,qEAAqE,CACxE,CAAA;IACL,CAAC;IACD,OAAO,OAAO,CAAA;AAClB,CAAC,CAAA;AARY,QAAA,sBAAsB,0BAQlC","sourcesContent":["// packages/expo-audio-stream/src/AudioRecorder.provider.tsx\nimport React, { createContext, useContext } from 'react'\n\nimport { UseAudioRecorderState } from './ExpoAudioStream.types'\nimport { UseAudioRecorderProps, useAudioRecorder } from './useAudioRecorder'\n\nconst initContext: UseAudioRecorderState = {\n isRecording: false,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined,\n startRecording: async () => {\n throw new Error('AudioRecorderProvider not found')\n },\n stopRecording: async () => {\n throw new Error('AudioRecorderProvider not found')\n },\n pauseRecording: async () => {\n throw new Error('AudioRecorderProvider not found')\n },\n resumeRecording: async () => {\n throw new Error('AudioRecorderProvider not found')\n },\n prepareRecording: async () => {\n throw new Error('AudioRecorderProvider not found')\n },\n}\n\nconst AudioRecorderContext = createContext<UseAudioRecorderState>(initContext)\n\ninterface AudioRecorderProviderProps {\n children: React.ReactNode\n config?: UseAudioRecorderProps\n}\n\nexport const AudioRecorderProvider: React.FC<AudioRecorderProviderProps> = ({\n children,\n config = {},\n}) => {\n const audioRecorder = useAudioRecorder(config)\n return (\n <AudioRecorderContext.Provider value={audioRecorder}>\n {children}\n </AudioRecorderContext.Provider>\n )\n}\n\nexport const useSharedAudioRecorder = () => {\n const context = useContext(AudioRecorderContext)\n if (!context) {\n throw new Error(\n 'useSharedAudioRecorder must be used within an AudioRecorderProvider'\n )\n }\n return context\n}\n"]}
@@ -4,18 +4,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
5
  };
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.addRecordingInterruptionListener = exports.addAudioAnalysisListener = exports.addAudioEventListener = void 0;
7
+ exports.addAudioEventListener = addAudioEventListener;
8
+ exports.addAudioAnalysisListener = addAudioAnalysisListener;
9
+ exports.addRecordingInterruptionListener = addRecordingInterruptionListener;
8
10
  const expo_modules_core_1 = require("expo-modules-core");
9
11
  const ExpoAudioStreamModule_1 = __importDefault(require("./ExpoAudioStreamModule"));
10
12
  const emitter = new expo_modules_core_1.LegacyEventEmitter(ExpoAudioStreamModule_1.default);
11
13
  function addAudioEventListener(listener) {
12
14
  return emitter.addListener('AudioData', listener);
13
15
  }
14
- exports.addAudioEventListener = addAudioEventListener;
15
16
  function addAudioAnalysisListener(listener) {
16
17
  return emitter.addListener('AudioAnalysis', listener);
17
18
  }
18
- exports.addAudioAnalysisListener = addAudioAnalysisListener;
19
19
  function addRecordingInterruptionListener(listener) {
20
20
  // Add debug logging
21
21
  console.debug('Adding recording interruption listener');
@@ -26,5 +26,4 @@ function addRecordingInterruptionListener(listener) {
26
26
  });
27
27
  return subscription;
28
28
  }
29
- exports.addRecordingInterruptionListener = addRecordingInterruptionListener;
30
29
  //# sourceMappingURL=events.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/events.ts"],"names":[],"mappings":";AAAA,2CAA2C;;;;;;AAE3C,yDAA8E;AAI9E,oFAA2D;AAE3D,MAAM,OAAO,GAAG,IAAI,sCAAkB,CAAC,+BAAqB,CAAC,CAAA;AAqB7D,SAAgB,qBAAqB,CACjC,QAAqD;IAErD,OAAO,OAAO,CAAC,WAAW,CAAoB,WAAW,EAAE,QAAQ,CAAC,CAAA;AACxE,CAAC;AAJD,sDAIC;AAKD,SAAgB,wBAAwB,CACpC,QAAsD;IAEtD,OAAO,OAAO,CAAC,WAAW,CAAqB,eAAe,EAAE,QAAQ,CAAC,CAAA;AAC7E,CAAC;AAJD,4DAIC;AAED,SAAgB,gCAAgC,CAC5C,QAAqD;IAErD,oBAAoB;IACpB,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAA;IAEvD,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,CACpC,wBAAwB,EAAE,+CAA+C;IACzE,CAAC,KAAK,EAAE,EAAE;QACN,OAAO,CAAC,KAAK,CAAC,wCAAwC,EAAE,KAAK,CAAC,CAAA;QAC9D,QAAQ,CAAC,KAAK,CAAC,CAAA;IACnB,CAAC,CACJ,CAAA;IAED,OAAO,YAAY,CAAA;AACvB,CAAC;AAfD,4EAeC","sourcesContent":["// packages/expo-audio-stream/src/events.ts\n\nimport { LegacyEventEmitter, type EventSubscription } from 'expo-modules-core'\n\nimport { AudioAnalysis } from './AudioAnalysis/AudioAnalysis.types'\nimport { RecordingInterruptionEvent } from './ExpoAudioStream.types'\nimport ExpoAudioStreamModule from './ExpoAudioStreamModule'\n\nconst emitter = new LegacyEventEmitter(ExpoAudioStreamModule)\n\n// Internal event payload from native module\nexport interface AudioEventPayload {\n encoded?: string\n buffer?: Float32Array\n fileUri: string\n lastEmittedSize: number\n position: number\n deltaSize: number\n totalSize: number\n mimeType: string\n streamUuid: string\n compression?: {\n data?: string | Blob // Base64 (native) or Float32Array (web) encoded compressed data chunk\n position: number\n eventDataSize: number\n totalSize: number\n }\n}\n\nexport function addAudioEventListener(\n listener: (event: AudioEventPayload) => Promise<void>\n): EventSubscription {\n return emitter.addListener<AudioEventPayload>('AudioData', listener)\n}\n\n// Only aliasing the AudioAnalysis type for the event payload\nexport interface AudioAnalysisEvent extends AudioAnalysis {}\n\nexport function addAudioAnalysisListener(\n listener: (event: AudioAnalysisEvent) => Promise<void>\n): EventSubscription {\n return emitter.addListener<AudioAnalysisEvent>('AudioAnalysis', listener)\n}\n\nexport function addRecordingInterruptionListener(\n listener: (event: RecordingInterruptionEvent) => void\n): EventSubscription {\n // Add debug logging\n console.debug('Adding recording interruption listener')\n\n const subscription = emitter.addListener<RecordingInterruptionEvent>(\n 'onRecordingInterrupted', // Make sure this matches the native event name\n (event) => {\n console.debug('Recording interruption event received:', event)\n listener(event)\n }\n )\n\n return subscription\n}\n"]}
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/events.ts"],"names":[],"mappings":";AAAA,2CAA2C;;;;;AA6B3C,sDAIC;AAKD,4DAIC;AAED,4EAeC;AAzDD,yDAA8E;AAI9E,oFAA2D;AAE3D,MAAM,OAAO,GAAG,IAAI,sCAAkB,CAAC,+BAAqB,CAAC,CAAA;AAqB7D,SAAgB,qBAAqB,CACjC,QAAqD;IAErD,OAAO,OAAO,CAAC,WAAW,CAAoB,WAAW,EAAE,QAAQ,CAAC,CAAA;AACxE,CAAC;AAKD,SAAgB,wBAAwB,CACpC,QAAsD;IAEtD,OAAO,OAAO,CAAC,WAAW,CAAqB,eAAe,EAAE,QAAQ,CAAC,CAAA;AAC7E,CAAC;AAED,SAAgB,gCAAgC,CAC5C,QAAqD;IAErD,oBAAoB;IACpB,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAA;IAEvD,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,CACpC,wBAAwB,EAAE,+CAA+C;IACzE,CAAC,KAAK,EAAE,EAAE;QACN,OAAO,CAAC,KAAK,CAAC,wCAAwC,EAAE,KAAK,CAAC,CAAA;QAC9D,QAAQ,CAAC,KAAK,CAAC,CAAA;IACnB,CAAC,CACJ,CAAA;IAED,OAAO,YAAY,CAAA;AACvB,CAAC","sourcesContent":["// packages/expo-audio-stream/src/events.ts\n\nimport { LegacyEventEmitter, type EventSubscription } from 'expo-modules-core'\n\nimport { AudioAnalysis } from './AudioAnalysis/AudioAnalysis.types'\nimport { RecordingInterruptionEvent } from './ExpoAudioStream.types'\nimport ExpoAudioStreamModule from './ExpoAudioStreamModule'\n\nconst emitter = new LegacyEventEmitter(ExpoAudioStreamModule)\n\n// Internal event payload from native module\nexport interface AudioEventPayload {\n encoded?: string\n buffer?: Float32Array\n fileUri: string\n lastEmittedSize: number\n position: number\n deltaSize: number\n totalSize: number\n mimeType: string\n streamUuid: string\n compression?: {\n data?: string | Blob // Base64 (native) or Float32Array (web) encoded compressed data chunk\n position: number\n eventDataSize: number\n totalSize: number\n }\n}\n\nexport function addAudioEventListener(\n listener: (event: AudioEventPayload) => Promise<void>\n): EventSubscription {\n return emitter.addListener<AudioEventPayload>('AudioData', listener)\n}\n\n// Only aliasing the AudioAnalysis type for the event payload\nexport interface AudioAnalysisEvent extends AudioAnalysis {}\n\nexport function addAudioAnalysisListener(\n listener: (event: AudioAnalysisEvent) => Promise<void>\n): EventSubscription {\n return emitter.addListener<AudioAnalysisEvent>('AudioAnalysis', listener)\n}\n\nexport function addRecordingInterruptionListener(\n listener: (event: RecordingInterruptionEvent) => void\n): EventSubscription {\n // Add debug logging\n console.debug('Adding recording interruption listener')\n\n const subscription = emitter.addListener<RecordingInterruptionEvent>(\n 'onRecordingInterrupted', // Make sure this matches the native event name\n (event) => {\n console.debug('Recording interruption event received:', event)\n listener(event)\n }\n )\n\n return subscription\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useAudioDevices = void 0;
3
+ exports.useAudioDevices = useAudioDevices;
4
4
  const react_1 = require("react");
5
5
  const AudioDeviceManager_1 = require("../AudioDeviceManager");
6
6
  /**
@@ -151,5 +151,4 @@ function useAudioDevices() {
151
151
  refreshDevices,
152
152
  };
153
153
  }
154
- exports.useAudioDevices = useAudioDevices;
155
154
  //# sourceMappingURL=useAudioDevices.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useAudioDevices.js","sourceRoot":"","sources":["../../../src/hooks/useAudioDevices.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useState } from 'react'\n\nimport { audioDeviceManager } from '../AudioDeviceManager'\nimport { AudioDevice } from '../ExpoAudioStream.types'\n\n/**\n * React hook for managing audio input devices\n */\nexport function useAudioDevices() {\n const [devices, setDevices] = useState<AudioDevice[]>([])\n const [currentDevice, setCurrentDevice] = useState<AudioDevice | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n\n // Load devices on mount\n useEffect(() => {\n let isMounted = true\n\n const loadDevices = async () => {\n try {\n setLoading(true)\n setError(null)\n\n // Load available devices\n const availableDevices =\n await audioDeviceManager.getAvailableDevices()\n if (isMounted) setDevices(availableDevices)\n\n // Get current device\n const device = await audioDeviceManager.getCurrentDevice()\n if (isMounted) setCurrentDevice(device)\n } catch (err) {\n console.error('Failed to load audio devices:', err)\n if (isMounted)\n setError(\n err instanceof Error\n ? err\n : new Error('Failed to load audio devices')\n )\n } finally {\n if (isMounted) setLoading(false)\n }\n }\n\n loadDevices()\n\n // Set up device change listener\n const removeListener = audioDeviceManager.addDeviceChangeListener(\n (updatedDevices: AudioDevice[]) => {\n if (isMounted) {\n setDevices(updatedDevices)\n\n // If our current device is no longer available, update it\n if (\n currentDevice &&\n !updatedDevices.some(\n (d: AudioDevice) => d.id === currentDevice.id\n )\n ) {\n audioDeviceManager\n .getCurrentDevice()\n .then((newDevice: AudioDevice | null) => {\n if (isMounted) setCurrentDevice(newDevice)\n })\n }\n }\n }\n )\n\n return () => {\n isMounted = false\n removeListener()\n }\n }, [])\n\n /**\n * Select a specific audio input device\n * @param deviceId The ID of the device to select\n * @returns Promise resolving to a boolean indicating success\n */\n const selectDevice = useCallback(\n async (deviceId: string): Promise<boolean> => {\n try {\n setLoading(true)\n setError(null)\n\n const success = await audioDeviceManager.selectDevice(deviceId)\n\n if (success) {\n // Get the updated current device after selection\n const device = await audioDeviceManager.getCurrentDevice()\n setCurrentDevice(device)\n }\n\n return success\n } catch (err) {\n console.error('Failed to select audio device:', err)\n setError(\n err instanceof Error\n ? err\n : new Error('Failed to select audio device')\n )\n return false\n } finally {\n setLoading(false)\n }\n },\n []\n )\n\n /**\n * Reset to the default audio input device\n * @returns Promise resolving to a boolean indicating success\n */\n const resetToDefaultDevice = useCallback(async (): Promise<boolean> => {\n try {\n setLoading(true)\n setError(null)\n\n const success = await audioDeviceManager.resetToDefaultDevice()\n\n if (success) {\n // Get the updated current device after reset\n const device = await audioDeviceManager.getCurrentDevice()\n setCurrentDevice(device)\n }\n\n return success\n } catch (err) {\n console.error('Failed to reset to default audio device:', err)\n setError(\n err instanceof Error\n ? err\n : new Error('Failed to reset to default audio device')\n )\n return false\n } finally {\n setLoading(false)\n }\n }, [])\n\n /**\n * Refresh the list of available devices\n */\n const refreshDevices = useCallback(async (): Promise<AudioDevice[]> => {\n try {\n setLoading(true)\n setError(null)\n\n const updatedDevices = await audioDeviceManager.refreshDevices()\n setDevices(updatedDevices)\n\n // Also refresh the current device\n const device = await audioDeviceManager.getCurrentDevice()\n setCurrentDevice(device)\n\n return updatedDevices\n } catch (err) {\n console.error('Failed to refresh audio devices:', err)\n setError(\n err instanceof Error\n ? err\n : new Error('Failed to refresh audio devices')\n )\n return []\n } finally {\n setLoading(false)\n }\n }, [])\n\n return {\n devices,\n currentDevice,\n loading,\n error,\n selectDevice,\n resetToDefaultDevice,\n refreshDevices,\n }\n}\n"]}
1
+ {"version":3,"file":"useAudioDevices.js","sourceRoot":"","sources":["../../../src/hooks/useAudioDevices.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useState } from 'react'\n\nimport { audioDeviceManager } from '../AudioDeviceManager'\nimport { AudioDevice } from '../ExpoAudioStream.types'\n\n/**\n * React hook for managing audio input devices\n */\nexport function useAudioDevices() {\n const [devices, setDevices] = useState<AudioDevice[]>([])\n const [currentDevice, setCurrentDevice] = useState<AudioDevice | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n\n // Load devices on mount\n useEffect(() => {\n let isMounted = true\n\n const loadDevices = async () => {\n try {\n setLoading(true)\n setError(null)\n\n // Load available devices\n const availableDevices =\n await audioDeviceManager.getAvailableDevices()\n if (isMounted) setDevices(availableDevices)\n\n // Get current device\n const device = await audioDeviceManager.getCurrentDevice()\n if (isMounted) setCurrentDevice(device)\n } catch (err) {\n console.error('Failed to load audio devices:', err)\n if (isMounted)\n setError(\n err instanceof Error\n ? err\n : new Error('Failed to load audio devices')\n )\n } finally {\n if (isMounted) setLoading(false)\n }\n }\n\n loadDevices()\n\n // Set up device change listener\n const removeListener = audioDeviceManager.addDeviceChangeListener(\n (updatedDevices: AudioDevice[]) => {\n if (isMounted) {\n setDevices(updatedDevices)\n\n // If our current device is no longer available, update it\n if (\n currentDevice &&\n !updatedDevices.some(\n (d: AudioDevice) => d.id === currentDevice.id\n )\n ) {\n audioDeviceManager\n .getCurrentDevice()\n .then((newDevice: AudioDevice | null) => {\n if (isMounted) setCurrentDevice(newDevice)\n })\n }\n }\n }\n )\n\n return () => {\n isMounted = false\n removeListener()\n }\n }, [])\n\n /**\n * Select a specific audio input device\n * @param deviceId The ID of the device to select\n * @returns Promise resolving to a boolean indicating success\n */\n const selectDevice = useCallback(\n async (deviceId: string): Promise<boolean> => {\n try {\n setLoading(true)\n setError(null)\n\n const success = await audioDeviceManager.selectDevice(deviceId)\n\n if (success) {\n // Get the updated current device after selection\n const device = await audioDeviceManager.getCurrentDevice()\n setCurrentDevice(device)\n }\n\n return success\n } catch (err) {\n console.error('Failed to select audio device:', err)\n setError(\n err instanceof Error\n ? err\n : new Error('Failed to select audio device')\n )\n return false\n } finally {\n setLoading(false)\n }\n },\n []\n )\n\n /**\n * Reset to the default audio input device\n * @returns Promise resolving to a boolean indicating success\n */\n const resetToDefaultDevice = useCallback(async (): Promise<boolean> => {\n try {\n setLoading(true)\n setError(null)\n\n const success = await audioDeviceManager.resetToDefaultDevice()\n\n if (success) {\n // Get the updated current device after reset\n const device = await audioDeviceManager.getCurrentDevice()\n setCurrentDevice(device)\n }\n\n return success\n } catch (err) {\n console.error('Failed to reset to default audio device:', err)\n setError(\n err instanceof Error\n ? err\n : new Error('Failed to reset to default audio device')\n )\n return false\n } finally {\n setLoading(false)\n }\n }, [])\n\n /**\n * Refresh the list of available devices\n */\n const refreshDevices = useCallback(async (): Promise<AudioDevice[]> => {\n try {\n setLoading(true)\n setError(null)\n\n const updatedDevices = await audioDeviceManager.refreshDevices()\n setDevices(updatedDevices)\n\n // Also refresh the current device\n const device = await audioDeviceManager.getCurrentDevice()\n setCurrentDevice(device)\n\n return updatedDevices\n } catch (err) {\n console.error('Failed to refresh audio devices:', err)\n setError(\n err instanceof Error\n ? err\n : new Error('Failed to refresh audio devices')\n )\n return []\n } finally {\n setLoading(false)\n }\n }, [])\n\n return {\n devices,\n currentDevice,\n loading,\n error,\n selectDevice,\n resetToDefaultDevice,\n refreshDevices,\n }\n}\n"]}
@@ -3,7 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.trimAudioSimple = exports.trimAudio = void 0;
6
+ exports.trimAudio = trimAudio;
7
+ exports.trimAudioSimple = trimAudioSimple;
7
8
  const expo_modules_core_1 = require("expo-modules-core");
8
9
  const ExpoAudioStreamModule_1 = __importDefault(require("./ExpoAudioStreamModule"));
9
10
  // Create a single emitter instance
@@ -56,7 +57,6 @@ async function trimAudio(options, progressCallback) {
56
57
  }
57
58
  }
58
59
  }
59
- exports.trimAudio = trimAudio;
60
60
  /**
61
61
  * Simplified version of trimAudio that returns only the URI of the trimmed file.
62
62
  *
@@ -71,5 +71,4 @@ async function trimAudioSimple(options) {
71
71
  const result = await trimAudio(options);
72
72
  return result.uri;
73
73
  }
74
- exports.trimAudioSimple = trimAudioSimple;
75
74
  //# sourceMappingURL=trimAudio.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"trimAudio.js","sourceRoot":"","sources":["../../src/trimAudio.ts"],"names":[],"mappings":";;;;;;AAAA,yDAA8E;AAO9E,oFAA2D;AAE3D,mCAAmC;AACnC,MAAM,OAAO,GAAG,IAAI,sCAAkB,CAAC,+BAAqB,CAAC,CAAA;AAE7D;;;;;;;;;;GAUG;AACI,KAAK,UAAU,SAAS,CAC3B,OAAyB,EACzB,gBAAqD;IAErD,aAAa;IACb,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAA;IAC1C,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAA;IACrC,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpB,IACI,OAAO,CAAC,WAAW,KAAK,SAAS;YACjC,OAAO,CAAC,SAAS,KAAK,SAAS,EACjC,CAAC;YACC,MAAM,IAAI,KAAK,CACX,0EAA0E,CAC7E,CAAA;QACL,CAAC;IACL,CAAC;SAAM,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9C,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,CACX,gEAAgE,CACnE,CAAA;QACL,CAAC;IACL,CAAC;SAAM,CAAC;QACJ,MAAM,IAAI,KAAK,CACX,iBAAiB,IAAI,yCAAyC,CACjE,CAAA;IACL,CAAC;IAED,yDAAyD;IACzD,IAAI,YAA2C,CAAA;IAC/C,IAAI,gBAAgB,EAAE,CAAC;QACnB,YAAY,GAAG,OAAO,CAAC,WAAW,CAC9B,cAAc,EACd,CAAC,KAAwB,EAAE,EAAE;YACzB,gBAAgB,CAAC,KAAK,CAAC,CAAA;QAC3B,CAAC,CACJ,CAAA;IACL,CAAC;IAED,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,+BAAqB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;QAC7D,OAAO,MAAM,CAAA;IACjB,CAAC;YAAS,CAAC;QACP,IAAI,YAAY,EAAE,CAAC;YACf,YAAY,CAAC,MAAM,EAAE,CAAA;QACzB,CAAC;IACL,CAAC;AACL,CAAC;AAjDD,8BAiDC;AAED;;;;;;;;;GASG;AACI,KAAK,UAAU,eAAe,CACjC,OAAyB;IAEzB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAA;IACvC,OAAO,MAAM,CAAC,GAAG,CAAA;AACrB,CAAC;AALD,0CAKC","sourcesContent":["import { LegacyEventEmitter, type EventSubscription } from 'expo-modules-core'\n\nimport {\n TrimAudioOptions,\n TrimAudioResult,\n TrimProgressEvent,\n} from './ExpoAudioStream.types'\nimport ExpoAudioStreamModule from './ExpoAudioStreamModule'\n\n// Create a single emitter instance\nconst emitter = new LegacyEventEmitter(ExpoAudioStreamModule)\n\n/**\n * Trims an audio file based on the provided options.\n *\n * @experimental This API is experimental and not fully optimized for production use.\n * Performance may vary based on file size and device capabilities.\n * Future versions may include breaking changes.\n *\n * @param options Configuration options for the trimming operation\n * @param progressCallback Optional callback to receive progress updates\n * @returns Promise resolving to the trimmed audio file information, including processing time\n */\nexport async function trimAudio(\n options: TrimAudioOptions,\n progressCallback?: (event: TrimProgressEvent) => void\n): Promise<TrimAudioResult> {\n // Validation\n if (!options.fileUri) {\n throw new Error('fileUri is required')\n }\n const mode = options.mode ?? 'single'\n if (mode === 'single') {\n if (\n options.startTimeMs === undefined &&\n options.endTimeMs === undefined\n ) {\n throw new Error(\n 'At least one of startTimeMs or endTimeMs must be provided in single mode'\n )\n }\n } else if (mode === 'keep' || mode === 'remove') {\n if (!options.ranges || options.ranges.length === 0) {\n throw new Error(\n 'ranges must be provided and non-empty for keep or remove modes'\n )\n }\n } else {\n throw new Error(\n `Invalid mode: ${mode}. Must be 'single', 'keep', or 'remove'`\n )\n }\n\n // Set up progress event listener if callback is provided\n let subscription: EventSubscription | undefined\n if (progressCallback) {\n subscription = emitter.addListener(\n 'TrimProgress',\n (event: TrimProgressEvent) => {\n progressCallback(event)\n }\n )\n }\n\n try {\n const result = await ExpoAudioStreamModule.trimAudio(options)\n return result\n } finally {\n if (subscription) {\n subscription.remove()\n }\n }\n}\n\n/**\n * Simplified version of trimAudio that returns only the URI of the trimmed file.\n *\n * @experimental This API is experimental and not fully optimized for production use.\n * Performance may vary based on file size and device capabilities.\n * Future versions may include breaking changes.\n *\n * @param options Configuration options for the trimming operation\n * @returns Promise resolving to the URI of the trimmed audio file\n */\nexport async function trimAudioSimple(\n options: TrimAudioOptions\n): Promise<string> {\n const result = await trimAudio(options)\n return result.uri\n}\n"]}
1
+ {"version":3,"file":"trimAudio.js","sourceRoot":"","sources":["../../src/trimAudio.ts"],"names":[],"mappings":";;;;;AAuBA,8BAiDC;AAYD,0CAKC;AAzFD,yDAA8E;AAO9E,oFAA2D;AAE3D,mCAAmC;AACnC,MAAM,OAAO,GAAG,IAAI,sCAAkB,CAAC,+BAAqB,CAAC,CAAA;AAE7D;;;;;;;;;;GAUG;AACI,KAAK,UAAU,SAAS,CAC3B,OAAyB,EACzB,gBAAqD;IAErD,aAAa;IACb,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAA;IAC1C,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAA;IACrC,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpB,IACI,OAAO,CAAC,WAAW,KAAK,SAAS;YACjC,OAAO,CAAC,SAAS,KAAK,SAAS,EACjC,CAAC;YACC,MAAM,IAAI,KAAK,CACX,0EAA0E,CAC7E,CAAA;QACL,CAAC;IACL,CAAC;SAAM,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9C,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,CACX,gEAAgE,CACnE,CAAA;QACL,CAAC;IACL,CAAC;SAAM,CAAC;QACJ,MAAM,IAAI,KAAK,CACX,iBAAiB,IAAI,yCAAyC,CACjE,CAAA;IACL,CAAC;IAED,yDAAyD;IACzD,IAAI,YAA2C,CAAA;IAC/C,IAAI,gBAAgB,EAAE,CAAC;QACnB,YAAY,GAAG,OAAO,CAAC,WAAW,CAC9B,cAAc,EACd,CAAC,KAAwB,EAAE,EAAE;YACzB,gBAAgB,CAAC,KAAK,CAAC,CAAA;QAC3B,CAAC,CACJ,CAAA;IACL,CAAC;IAED,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,+BAAqB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;QAC7D,OAAO,MAAM,CAAA;IACjB,CAAC;YAAS,CAAC;QACP,IAAI,YAAY,EAAE,CAAC;YACf,YAAY,CAAC,MAAM,EAAE,CAAA;QACzB,CAAC;IACL,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACI,KAAK,UAAU,eAAe,CACjC,OAAyB;IAEzB,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAA;IACvC,OAAO,MAAM,CAAC,GAAG,CAAA;AACrB,CAAC","sourcesContent":["import { LegacyEventEmitter, type EventSubscription } from 'expo-modules-core'\n\nimport {\n TrimAudioOptions,\n TrimAudioResult,\n TrimProgressEvent,\n} from './ExpoAudioStream.types'\nimport ExpoAudioStreamModule from './ExpoAudioStreamModule'\n\n// Create a single emitter instance\nconst emitter = new LegacyEventEmitter(ExpoAudioStreamModule)\n\n/**\n * Trims an audio file based on the provided options.\n *\n * @experimental This API is experimental and not fully optimized for production use.\n * Performance may vary based on file size and device capabilities.\n * Future versions may include breaking changes.\n *\n * @param options Configuration options for the trimming operation\n * @param progressCallback Optional callback to receive progress updates\n * @returns Promise resolving to the trimmed audio file information, including processing time\n */\nexport async function trimAudio(\n options: TrimAudioOptions,\n progressCallback?: (event: TrimProgressEvent) => void\n): Promise<TrimAudioResult> {\n // Validation\n if (!options.fileUri) {\n throw new Error('fileUri is required')\n }\n const mode = options.mode ?? 'single'\n if (mode === 'single') {\n if (\n options.startTimeMs === undefined &&\n options.endTimeMs === undefined\n ) {\n throw new Error(\n 'At least one of startTimeMs or endTimeMs must be provided in single mode'\n )\n }\n } else if (mode === 'keep' || mode === 'remove') {\n if (!options.ranges || options.ranges.length === 0) {\n throw new Error(\n 'ranges must be provided and non-empty for keep or remove modes'\n )\n }\n } else {\n throw new Error(\n `Invalid mode: ${mode}. Must be 'single', 'keep', or 'remove'`\n )\n }\n\n // Set up progress event listener if callback is provided\n let subscription: EventSubscription | undefined\n if (progressCallback) {\n subscription = emitter.addListener(\n 'TrimProgress',\n (event: TrimProgressEvent) => {\n progressCallback(event)\n }\n )\n }\n\n try {\n const result = await ExpoAudioStreamModule.trimAudio(options)\n return result\n } finally {\n if (subscription) {\n subscription.remove()\n }\n }\n}\n\n/**\n * Simplified version of trimAudio that returns only the URI of the trimmed file.\n *\n * @experimental This API is experimental and not fully optimized for production use.\n * Performance may vary based on file size and device capabilities.\n * Future versions may include breaking changes.\n *\n * @param options Configuration options for the trimming operation\n * @returns Promise resolving to the URI of the trimmed audio file\n */\nexport async function trimAudioSimple(\n options: TrimAudioOptions\n): Promise<string> {\n const result = await trimAudio(options)\n return result.uri\n}\n"]}
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.useAudioRecorder = void 0;
6
+ exports.useAudioRecorder = useAudioRecorder;
7
7
  // src/useAudioRecorder.ts
8
8
  const expo_modules_core_1 = require("expo-modules-core");
9
9
  const react_1 = require("react");
@@ -449,5 +449,4 @@ function useAudioRecorder({ logger, audioWorkletUrl, featuresExtratorUrl, } = {}
449
449
  analysisData: state.analysisData,
450
450
  };
451
451
  }
452
- exports.useAudioRecorder = useAudioRecorder;
453
452
  //# sourceMappingURL=useAudioRecorder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useAudioRecorder.js","sourceRoot":"","sources":["../../src/useAudioRecorder.tsx"],"names":[],"mappings":"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","sourcesContent":["// src/useAudioRecorder.ts\nimport { EventSubscription, Platform } from 'expo-modules-core'\nimport { useCallback, useEffect, useReducer, useRef } from 'react'\n\nimport { AudioAnalysis } from './AudioAnalysis/AudioAnalysis.types'\nimport {\n AudioDataEvent,\n AudioRecording,\n AudioStreamStatus,\n CompressionInfo,\n ConsoleLike,\n RecordingConfig,\n StartRecordingResult,\n} from './ExpoAudioStream.types'\nimport ExpoAudioStreamModule from './ExpoAudioStreamModule'\nimport {\n addAudioAnalysisListener,\n addAudioEventListener,\n AudioEventPayload,\n addRecordingInterruptionListener,\n} from './events'\n\nexport interface UseAudioRecorderProps {\n logger?: ConsoleLike\n audioWorkletUrl?: string\n featuresExtratorUrl?: string\n}\n\nexport interface UseAudioRecorderState {\n prepareRecording: (_: RecordingConfig) => Promise<void>\n startRecording: (_: RecordingConfig) => Promise<StartRecordingResult>\n stopRecording: () => Promise<AudioRecording>\n pauseRecording: () => Promise<void>\n resumeRecording: () => Promise<void>\n isRecording: boolean\n isPaused: boolean\n durationMs: number\n size: number\n compression?: CompressionInfo\n analysisData?: AudioAnalysis\n}\n\ninterface RecorderReducerState {\n isRecording: boolean\n isPaused: boolean\n durationMs: number\n size: number\n compression?: CompressionInfo\n analysisData?: AudioAnalysis\n}\n\ntype RecorderAction =\n | { type: 'START' | 'STOP' | 'PAUSE' | 'RESUME' }\n | {\n type: 'UPDATE_RECORDING_STATE'\n payload: {\n isRecording: boolean\n isPaused: boolean\n }\n }\n | {\n type: 'UPDATE_STATUS'\n payload: {\n durationMs: number\n size: number\n compression?: CompressionInfo\n }\n }\n | { type: 'UPDATE_ANALYSIS'; payload: AudioAnalysis }\n\nconst defaultAnalysis: AudioAnalysis = {\n segmentDurationMs: 100,\n bitDepth: 32,\n numberOfChannels: 1,\n durationMs: 0,\n sampleRate: 44100,\n samples: 0,\n dataPoints: [],\n rmsRange: {\n min: Number.POSITIVE_INFINITY,\n max: Number.NEGATIVE_INFINITY,\n },\n amplitudeRange: {\n min: Number.POSITIVE_INFINITY,\n max: Number.NEGATIVE_INFINITY,\n },\n}\n\nfunction audioRecorderReducer(\n state: RecorderReducerState,\n action: RecorderAction\n): RecorderReducerState {\n switch (action.type) {\n case 'START':\n return {\n ...state,\n isRecording: true,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined,\n analysisData: defaultAnalysis,\n }\n case 'STOP':\n return {\n ...state,\n isRecording: false,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined,\n analysisData: undefined,\n }\n case 'PAUSE':\n return { ...state, isPaused: true, isRecording: false }\n case 'RESUME':\n return { ...state, isPaused: false, isRecording: true }\n case 'UPDATE_RECORDING_STATE':\n return {\n ...state,\n isPaused: action.payload.isPaused,\n isRecording: action.payload.isRecording,\n }\n case 'UPDATE_STATUS': {\n const newState = {\n ...state,\n durationMs: action.payload.durationMs,\n size: action.payload.size,\n compression: action.payload.compression\n ? {\n size: action.payload.compression.size,\n mimeType: action.payload.compression.mimeType,\n bitrate: action.payload.compression.bitrate,\n format: action.payload.compression.format,\n }\n : undefined,\n }\n return newState\n }\n case 'UPDATE_ANALYSIS':\n return {\n ...state,\n analysisData: action.payload,\n }\n default:\n return state\n }\n}\n\ninterface HandleAudioAnalysisProps {\n analysis: AudioAnalysis\n visualizationDuration: number\n}\n\nexport function useAudioRecorder({\n logger,\n audioWorkletUrl,\n featuresExtratorUrl,\n}: UseAudioRecorderProps = {}): UseAudioRecorderState {\n const [state, dispatch] = useReducer(audioRecorderReducer, {\n isRecording: false,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined,\n analysisData: undefined,\n })\n\n const startResultRef = useRef<StartRecordingResult | null>(null)\n\n const analysisListenerRef = useRef<EventSubscription | null>(null)\n // analysisRef is the current analysis data (last 10 seconds by default)\n const analysisRef = useRef<AudioAnalysis>({ ...defaultAnalysis })\n // fullAnalysisRef is the full analysis data (all data points)\n const fullAnalysisRef = useRef<AudioAnalysis>({\n ...defaultAnalysis,\n })\n\n // Instantiate the module for web with URLs\n const ExpoAudioStream =\n Platform.OS === 'web'\n ? ExpoAudioStreamModule({\n audioWorkletUrl,\n featuresExtratorUrl,\n logger,\n })\n : ExpoAudioStreamModule\n\n const onAudioStreamRef = useRef<\n ((_: AudioDataEvent) => Promise<void>) | null\n >(null)\n\n const stateRef = useRef({\n isRecording: false,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined as CompressionInfo | undefined,\n })\n\n const recordingConfigRef = useRef<RecordingConfig | null>(null)\n\n const handleAudioAnalysis = useCallback(\n async ({\n analysis,\n visualizationDuration,\n }: HandleAudioAnalysisProps) => {\n const savedAnalysisData = analysisRef.current || {\n ...defaultAnalysis,\n }\n\n const maxDuration = visualizationDuration\n\n logger?.debug(\n `[handleAudioAnalysis] Received audio analysis: maxDuration=${maxDuration} analysis.dataPoints=${analysis.dataPoints.length} analysisData.dataPoints=${savedAnalysisData.dataPoints.length}`\n )\n\n // Combine data points\n const combinedDataPoints = [\n ...savedAnalysisData.dataPoints,\n ...analysis.dataPoints,\n ]\n\n const fullCombinedDataPoints = [\n ...(fullAnalysisRef.current?.dataPoints ?? []),\n ...analysis.dataPoints,\n ]\n\n // Calculate the new duration\n // The number of segments is based on how many segments of segmentDurationMs can fit in visualizationDuration\n const numberOfSegments = Math.ceil(\n visualizationDuration / analysis.segmentDurationMs\n )\n // maxDataPoints should be the number of data points, not milliseconds\n const maxDataPoints = numberOfSegments\n\n logger?.debug(\n `[handleAudioAnalysis] Combined data points before trimming: numberOfSegments=${numberOfSegments} visualizationDuration=${visualizationDuration} combinedDataPointsLength=${combinedDataPoints.length} vs maxDataPoints=${maxDataPoints}`\n )\n\n // Trim data points to keep within the maximum number of data points\n if (combinedDataPoints.length > maxDataPoints) {\n combinedDataPoints.splice(\n 0,\n combinedDataPoints.length - maxDataPoints\n )\n }\n\n // Keep the full data points\n fullAnalysisRef.current = {\n ...fullAnalysisRef.current,\n dataPoints: fullCombinedDataPoints,\n }\n fullAnalysisRef.current.durationMs =\n fullCombinedDataPoints.length * analysis.segmentDurationMs\n savedAnalysisData.dataPoints = combinedDataPoints\n savedAnalysisData.bitDepth =\n analysis.bitDepth || savedAnalysisData.bitDepth\n savedAnalysisData.durationMs =\n combinedDataPoints.length * analysis.segmentDurationMs\n\n // Update amplitude range\n const newMin = Math.min(\n savedAnalysisData.amplitudeRange.min,\n analysis.amplitudeRange.min\n )\n const newMax = Math.max(\n savedAnalysisData.amplitudeRange.max,\n analysis.amplitudeRange.max\n )\n\n savedAnalysisData.amplitudeRange = {\n min: newMin,\n max: newMax,\n }\n fullAnalysisRef.current.amplitudeRange = {\n min: newMin,\n max: newMax,\n }\n\n logger?.debug(\n `[handleAudioAnalysis] Updated analysis data: durationMs=${savedAnalysisData.durationMs}`,\n { dataPoints: savedAnalysisData.dataPoints.length }\n )\n\n // Call the onAudioAnalysis callback if it exists in the recording config\n if (recordingConfigRef.current?.onAudioAnalysis) {\n recordingConfigRef.current\n .onAudioAnalysis(analysis)\n .catch((error) => {\n logger?.warn(`Error processing audio analysis:`, error)\n })\n }\n\n // Update the ref\n analysisRef.current = savedAnalysisData\n\n // Dispatch the updated analysis data to state to trigger re-render\n dispatch({\n type: 'UPDATE_ANALYSIS',\n payload: { ...savedAnalysisData },\n })\n },\n [dispatch]\n )\n\n const handleAudioEvent = useCallback(\n async (eventData: AudioEventPayload) => {\n const {\n fileUri,\n deltaSize,\n totalSize,\n lastEmittedSize,\n position,\n streamUuid,\n encoded,\n mimeType,\n buffer,\n compression,\n } = eventData\n logger?.debug(`[handleAudioEvent] Received audio event:`, {\n fileUri,\n deltaSize,\n totalSize,\n position,\n mimeType,\n lastEmittedSize,\n streamUuid,\n encodedLength: encoded?.length,\n compression,\n })\n if (deltaSize === 0) {\n // Ignore packet with no data\n return\n }\n try {\n // Coming from native ( ios / android ) otherwise buffer is set\n if (Platform.OS !== 'web') {\n // Read the audio file as a base64 string for comparison\n if (!encoded) {\n logger?.error(`Encoded audio data is missing`)\n throw new Error('Encoded audio data is missing')\n }\n onAudioStreamRef.current?.({\n data: encoded,\n position,\n fileUri,\n eventDataSize: deltaSize,\n totalSize,\n compression:\n compression && startResultRef.current?.compression\n ? {\n data: compression.data,\n size: compression.totalSize,\n mimeType:\n startResultRef.current.compression\n ?.mimeType,\n bitrate:\n startResultRef.current.compression\n ?.bitrate,\n format: startResultRef.current.compression\n ?.format,\n }\n : undefined,\n })\n } else if (buffer) {\n // Coming from web\n const webEvent: AudioDataEvent = {\n data: buffer,\n position,\n fileUri,\n eventDataSize: deltaSize,\n totalSize,\n compression:\n compression && startResultRef.current?.compression\n ? {\n data: compression.data,\n size: compression.totalSize,\n mimeType:\n startResultRef.current.compression\n ?.mimeType,\n bitrate:\n startResultRef.current.compression\n ?.bitrate,\n format: startResultRef.current.compression\n ?.format,\n }\n : undefined,\n }\n onAudioStreamRef.current?.(webEvent)\n logger?.debug(\n `[handleAudioEvent] Audio data sent to onAudioStream`,\n webEvent\n )\n }\n } catch (error) {\n logger?.error(`Error processing audio event:`, error)\n }\n },\n []\n )\n\n const checkStatus = useCallback(async () => {\n try {\n const status: AudioStreamStatus = ExpoAudioStream.status()\n logger?.debug(\n `Status: paused: ${status.isPaused} isRecording: ${status.isRecording} durationMs: ${status.durationMs} size: ${status.size}`,\n status.compression\n )\n\n // Only dispatch if values actually changed\n if (\n status.isRecording !== stateRef.current.isRecording ||\n status.isPaused !== stateRef.current.isPaused\n ) {\n stateRef.current.isRecording = status.isRecording\n stateRef.current.isPaused = status.isPaused\n dispatch({\n type: 'UPDATE_RECORDING_STATE',\n payload: {\n isRecording: status.isRecording,\n isPaused: status.isPaused,\n },\n })\n }\n\n if (\n status.durationMs !== stateRef.current.durationMs ||\n status.size !== stateRef.current.size\n ) {\n stateRef.current.durationMs = status.durationMs\n stateRef.current.size = status.size\n stateRef.current.compression = status.compression\n dispatch({\n type: 'UPDATE_STATUS',\n payload: {\n durationMs: status.durationMs,\n size: status.size,\n compression: status.compression,\n },\n })\n }\n } catch (error) {\n logger?.error(`Error getting status:`, error)\n }\n }, [ExpoAudioStream, logger]) // Only depend on ExpoAudioStream and logger\n\n // Update ref when state changes\n useEffect(() => {\n stateRef.current = {\n isRecording: state.isRecording,\n isPaused: state.isPaused,\n durationMs: state.durationMs,\n size: state.size,\n compression: state.compression,\n }\n }, [\n state.isRecording,\n state.isPaused,\n state.durationMs,\n state.size,\n state.compression,\n ])\n\n const startRecording = useCallback(\n async (recordingOptions: RecordingConfig) => {\n recordingConfigRef.current = recordingOptions\n logger?.debug(`start recoding`, recordingOptions)\n\n analysisRef.current = { ...defaultAnalysis } // Reset analysis data\n fullAnalysisRef.current = { ...defaultAnalysis }\n const { onAudioStream, ...options } = recordingOptions\n const { enableProcessing } = options\n\n const maxRecentDataDuration = 10000 // TODO compute maxRecentDataDuration based on screen dimensions\n if (typeof onAudioStream === 'function') {\n onAudioStreamRef.current = onAudioStream\n } else {\n logger?.warn(`onAudioStream is not a function`, onAudioStream)\n onAudioStreamRef.current = null\n }\n const startResult: StartRecordingResult =\n await ExpoAudioStream.startRecording(options)\n dispatch({ type: 'START' })\n\n startResultRef.current = startResult\n\n if (enableProcessing) {\n logger?.debug(`Enabling audio analysis listener`)\n const listener = addAudioAnalysisListener(\n async (analysisData) => {\n try {\n await handleAudioAnalysis({\n analysis: analysisData,\n visualizationDuration: maxRecentDataDuration,\n })\n } catch (error) {\n logger?.warn(\n `Error processing audio analysis:`,\n error\n )\n }\n }\n )\n\n analysisListenerRef.current = listener\n }\n\n return startResult\n },\n [handleAudioAnalysis, dispatch]\n )\n\n const prepareRecording = useCallback(\n async (recordingOptions: RecordingConfig) => {\n recordingConfigRef.current = recordingOptions\n logger?.debug(`preparing recording`, recordingOptions)\n\n analysisRef.current = { ...defaultAnalysis } // Reset analysis data\n fullAnalysisRef.current = { ...defaultAnalysis }\n const { onAudioStream, ...options } = recordingOptions\n\n // Store onAudioStream for later use when recording starts\n if (typeof onAudioStream === 'function') {\n onAudioStreamRef.current = onAudioStream\n } else {\n logger?.warn(`onAudioStream is not a function`, onAudioStream)\n onAudioStreamRef.current = null\n }\n\n // Call the native prepareRecording method\n await ExpoAudioStream.prepareRecording(options)\n logger?.debug(`recording prepared successfully`)\n },\n []\n )\n\n const stopRecording = useCallback(async () => {\n logger?.debug(`stoping recording`)\n\n const stopResult: AudioRecording = await ExpoAudioStream.stopRecording()\n stopResult.analysisData = fullAnalysisRef.current\n\n if (analysisListenerRef.current) {\n analysisListenerRef.current.remove()\n analysisListenerRef.current = null\n }\n onAudioStreamRef.current = null\n logger?.debug(`recording stopped`, stopResult)\n dispatch({ type: 'STOP' })\n return stopResult\n }, [dispatch])\n\n const pauseRecording = useCallback(async () => {\n logger?.debug(`pause recording`)\n const pauseResult = await ExpoAudioStream.pauseRecording()\n dispatch({ type: 'PAUSE' })\n return pauseResult\n }, [dispatch])\n\n const resumeRecording = useCallback(async () => {\n logger?.debug(`resume recording`)\n const resumeResult = await ExpoAudioStream.resumeRecording()\n dispatch({ type: 'RESUME' })\n return resumeResult\n }, [dispatch])\n\n useEffect(() => {\n let intervalId: NodeJS.Timeout | undefined\n\n if (state.isRecording || state.isPaused) {\n // Immediately check status when starting\n checkStatus()\n\n // Start interval\n intervalId = setInterval(checkStatus, 1000)\n }\n\n return () => {\n if (intervalId) {\n clearInterval(intervalId)\n intervalId = undefined\n }\n }\n }, [checkStatus, state.isRecording, state.isPaused])\n\n useEffect(() => {\n logger?.debug(`Registering audio event listener`)\n const subscribeAudio = addAudioEventListener(handleAudioEvent)\n\n logger?.debug(\n `Subscribed to audio event listener and analysis listener`,\n {\n subscribeAudio,\n }\n )\n\n return () => {\n logger?.debug(`Removing audio event listener`)\n subscribeAudio.remove()\n }\n }, [handleAudioEvent, handleAudioAnalysis])\n\n useEffect(() => {\n // Add event subscription for recording interruptions\n logger?.debug('Setting up recording interruption listener')\n\n const subscription = addRecordingInterruptionListener((event) => {\n logger?.debug('Received recording interruption event:', event)\n\n // Check if we have a callback configured\n if (recordingConfigRef.current?.onRecordingInterrupted) {\n try {\n recordingConfigRef.current.onRecordingInterrupted(event)\n } catch (error) {\n logger?.error(\n 'Error in recording interruption callback:',\n error\n )\n }\n } else {\n logger?.warn('No recording interruption callback configured')\n }\n })\n\n return () => {\n logger?.debug('Removing recording interruption listener')\n subscription.remove()\n }\n }, []) // Empty dependency array since we want this to run once\n\n return {\n prepareRecording,\n startRecording,\n stopRecording,\n pauseRecording,\n resumeRecording,\n isPaused: state.isPaused,\n isRecording: state.isRecording,\n durationMs: state.durationMs,\n size: state.size,\n compression: state.compression,\n analysisData: state.analysisData,\n }\n}\n"]}
1
+ {"version":3,"file":"useAudioRecorder.js","sourceRoot":"","sources":["../../src/useAudioRecorder.tsx"],"names":[],"mappings":"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","sourcesContent":["// src/useAudioRecorder.ts\nimport { EventSubscription, Platform } from 'expo-modules-core'\nimport { useCallback, useEffect, useReducer, useRef } from 'react'\n\nimport { AudioAnalysis } from './AudioAnalysis/AudioAnalysis.types'\nimport {\n AudioDataEvent,\n AudioRecording,\n AudioStreamStatus,\n CompressionInfo,\n ConsoleLike,\n RecordingConfig,\n StartRecordingResult,\n} from './ExpoAudioStream.types'\nimport ExpoAudioStreamModule from './ExpoAudioStreamModule'\nimport {\n addAudioAnalysisListener,\n addAudioEventListener,\n AudioEventPayload,\n addRecordingInterruptionListener,\n} from './events'\n\nexport interface UseAudioRecorderProps {\n logger?: ConsoleLike\n audioWorkletUrl?: string\n featuresExtratorUrl?: string\n}\n\nexport interface UseAudioRecorderState {\n prepareRecording: (_: RecordingConfig) => Promise<void>\n startRecording: (_: RecordingConfig) => Promise<StartRecordingResult>\n stopRecording: () => Promise<AudioRecording>\n pauseRecording: () => Promise<void>\n resumeRecording: () => Promise<void>\n isRecording: boolean\n isPaused: boolean\n durationMs: number\n size: number\n compression?: CompressionInfo\n analysisData?: AudioAnalysis\n}\n\ninterface RecorderReducerState {\n isRecording: boolean\n isPaused: boolean\n durationMs: number\n size: number\n compression?: CompressionInfo\n analysisData?: AudioAnalysis\n}\n\ntype RecorderAction =\n | { type: 'START' | 'STOP' | 'PAUSE' | 'RESUME' }\n | {\n type: 'UPDATE_RECORDING_STATE'\n payload: {\n isRecording: boolean\n isPaused: boolean\n }\n }\n | {\n type: 'UPDATE_STATUS'\n payload: {\n durationMs: number\n size: number\n compression?: CompressionInfo\n }\n }\n | { type: 'UPDATE_ANALYSIS'; payload: AudioAnalysis }\n\nconst defaultAnalysis: AudioAnalysis = {\n segmentDurationMs: 100,\n bitDepth: 32,\n numberOfChannels: 1,\n durationMs: 0,\n sampleRate: 44100,\n samples: 0,\n dataPoints: [],\n rmsRange: {\n min: Number.POSITIVE_INFINITY,\n max: Number.NEGATIVE_INFINITY,\n },\n amplitudeRange: {\n min: Number.POSITIVE_INFINITY,\n max: Number.NEGATIVE_INFINITY,\n },\n}\n\nfunction audioRecorderReducer(\n state: RecorderReducerState,\n action: RecorderAction\n): RecorderReducerState {\n switch (action.type) {\n case 'START':\n return {\n ...state,\n isRecording: true,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined,\n analysisData: defaultAnalysis,\n }\n case 'STOP':\n return {\n ...state,\n isRecording: false,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined,\n analysisData: undefined,\n }\n case 'PAUSE':\n return { ...state, isPaused: true, isRecording: false }\n case 'RESUME':\n return { ...state, isPaused: false, isRecording: true }\n case 'UPDATE_RECORDING_STATE':\n return {\n ...state,\n isPaused: action.payload.isPaused,\n isRecording: action.payload.isRecording,\n }\n case 'UPDATE_STATUS': {\n const newState = {\n ...state,\n durationMs: action.payload.durationMs,\n size: action.payload.size,\n compression: action.payload.compression\n ? {\n size: action.payload.compression.size,\n mimeType: action.payload.compression.mimeType,\n bitrate: action.payload.compression.bitrate,\n format: action.payload.compression.format,\n }\n : undefined,\n }\n return newState\n }\n case 'UPDATE_ANALYSIS':\n return {\n ...state,\n analysisData: action.payload,\n }\n default:\n return state\n }\n}\n\ninterface HandleAudioAnalysisProps {\n analysis: AudioAnalysis\n visualizationDuration: number\n}\n\nexport function useAudioRecorder({\n logger,\n audioWorkletUrl,\n featuresExtratorUrl,\n}: UseAudioRecorderProps = {}): UseAudioRecorderState {\n const [state, dispatch] = useReducer(audioRecorderReducer, {\n isRecording: false,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined,\n analysisData: undefined,\n })\n\n const startResultRef = useRef<StartRecordingResult | null>(null)\n\n const analysisListenerRef = useRef<EventSubscription | null>(null)\n // analysisRef is the current analysis data (last 10 seconds by default)\n const analysisRef = useRef<AudioAnalysis>({ ...defaultAnalysis })\n // fullAnalysisRef is the full analysis data (all data points)\n const fullAnalysisRef = useRef<AudioAnalysis>({\n ...defaultAnalysis,\n })\n\n // Instantiate the module for web with URLs\n const ExpoAudioStream =\n Platform.OS === 'web'\n ? ExpoAudioStreamModule({\n audioWorkletUrl,\n featuresExtratorUrl,\n logger,\n })\n : ExpoAudioStreamModule\n\n const onAudioStreamRef = useRef<\n ((_: AudioDataEvent) => Promise<void>) | null\n >(null)\n\n const stateRef = useRef({\n isRecording: false,\n isPaused: false,\n durationMs: 0,\n size: 0,\n compression: undefined as CompressionInfo | undefined,\n })\n\n const recordingConfigRef = useRef<RecordingConfig | null>(null)\n\n const handleAudioAnalysis = useCallback(\n async ({\n analysis,\n visualizationDuration,\n }: HandleAudioAnalysisProps) => {\n const savedAnalysisData = analysisRef.current || {\n ...defaultAnalysis,\n }\n\n const maxDuration = visualizationDuration\n\n logger?.debug(\n `[handleAudioAnalysis] Received audio analysis: maxDuration=${maxDuration} analysis.dataPoints=${analysis.dataPoints.length} analysisData.dataPoints=${savedAnalysisData.dataPoints.length}`\n )\n\n // Combine data points\n const combinedDataPoints = [\n ...savedAnalysisData.dataPoints,\n ...analysis.dataPoints,\n ]\n\n const fullCombinedDataPoints = [\n ...(fullAnalysisRef.current?.dataPoints ?? []),\n ...analysis.dataPoints,\n ]\n\n // Calculate the new duration\n // The number of segments is based on how many segments of segmentDurationMs can fit in visualizationDuration\n const numberOfSegments = Math.ceil(\n visualizationDuration / analysis.segmentDurationMs\n )\n // maxDataPoints should be the number of data points, not milliseconds\n const maxDataPoints = numberOfSegments\n\n logger?.debug(\n `[handleAudioAnalysis] Combined data points before trimming: numberOfSegments=${numberOfSegments} visualizationDuration=${visualizationDuration} combinedDataPointsLength=${combinedDataPoints.length} vs maxDataPoints=${maxDataPoints}`\n )\n\n // Trim data points to keep within the maximum number of data points\n if (combinedDataPoints.length > maxDataPoints) {\n combinedDataPoints.splice(\n 0,\n combinedDataPoints.length - maxDataPoints\n )\n }\n\n // Keep the full data points\n fullAnalysisRef.current = {\n ...fullAnalysisRef.current,\n dataPoints: fullCombinedDataPoints,\n }\n fullAnalysisRef.current.durationMs =\n fullCombinedDataPoints.length * analysis.segmentDurationMs\n savedAnalysisData.dataPoints = combinedDataPoints\n savedAnalysisData.bitDepth =\n analysis.bitDepth || savedAnalysisData.bitDepth\n savedAnalysisData.durationMs =\n combinedDataPoints.length * analysis.segmentDurationMs\n\n // Update amplitude range\n const newMin = Math.min(\n savedAnalysisData.amplitudeRange.min,\n analysis.amplitudeRange.min\n )\n const newMax = Math.max(\n savedAnalysisData.amplitudeRange.max,\n analysis.amplitudeRange.max\n )\n\n savedAnalysisData.amplitudeRange = {\n min: newMin,\n max: newMax,\n }\n fullAnalysisRef.current.amplitudeRange = {\n min: newMin,\n max: newMax,\n }\n\n logger?.debug(\n `[handleAudioAnalysis] Updated analysis data: durationMs=${savedAnalysisData.durationMs}`,\n { dataPoints: savedAnalysisData.dataPoints.length }\n )\n\n // Call the onAudioAnalysis callback if it exists in the recording config\n if (recordingConfigRef.current?.onAudioAnalysis) {\n recordingConfigRef.current\n .onAudioAnalysis(analysis)\n .catch((error) => {\n logger?.warn(`Error processing audio analysis:`, error)\n })\n }\n\n // Update the ref\n analysisRef.current = savedAnalysisData\n\n // Dispatch the updated analysis data to state to trigger re-render\n dispatch({\n type: 'UPDATE_ANALYSIS',\n payload: { ...savedAnalysisData },\n })\n },\n [dispatch]\n )\n\n const handleAudioEvent = useCallback(\n async (eventData: AudioEventPayload) => {\n const {\n fileUri,\n deltaSize,\n totalSize,\n lastEmittedSize,\n position,\n streamUuid,\n encoded,\n mimeType,\n buffer,\n compression,\n } = eventData\n logger?.debug(`[handleAudioEvent] Received audio event:`, {\n fileUri,\n deltaSize,\n totalSize,\n position,\n mimeType,\n lastEmittedSize,\n streamUuid,\n encodedLength: encoded?.length,\n compression,\n })\n if (deltaSize === 0) {\n // Ignore packet with no data\n return\n }\n try {\n // Coming from native ( ios / android ) otherwise buffer is set\n if (Platform.OS !== 'web') {\n // Read the audio file as a base64 string for comparison\n if (!encoded) {\n logger?.error(`Encoded audio data is missing`)\n throw new Error('Encoded audio data is missing')\n }\n onAudioStreamRef.current?.({\n data: encoded,\n position,\n fileUri,\n eventDataSize: deltaSize,\n totalSize,\n compression:\n compression && startResultRef.current?.compression\n ? {\n data: compression.data,\n size: compression.totalSize,\n mimeType:\n startResultRef.current.compression\n ?.mimeType,\n bitrate:\n startResultRef.current.compression\n ?.bitrate,\n format: startResultRef.current.compression\n ?.format,\n }\n : undefined,\n })\n } else if (buffer) {\n // Coming from web\n const webEvent: AudioDataEvent = {\n data: buffer,\n position,\n fileUri,\n eventDataSize: deltaSize,\n totalSize,\n compression:\n compression && startResultRef.current?.compression\n ? {\n data: compression.data,\n size: compression.totalSize,\n mimeType:\n startResultRef.current.compression\n ?.mimeType,\n bitrate:\n startResultRef.current.compression\n ?.bitrate,\n format: startResultRef.current.compression\n ?.format,\n }\n : undefined,\n }\n onAudioStreamRef.current?.(webEvent)\n logger?.debug(\n `[handleAudioEvent] Audio data sent to onAudioStream`,\n webEvent\n )\n }\n } catch (error) {\n logger?.error(`Error processing audio event:`, error)\n }\n },\n []\n )\n\n const checkStatus = useCallback(async () => {\n try {\n const status: AudioStreamStatus = ExpoAudioStream.status()\n logger?.debug(\n `Status: paused: ${status.isPaused} isRecording: ${status.isRecording} durationMs: ${status.durationMs} size: ${status.size}`,\n status.compression\n )\n\n // Only dispatch if values actually changed\n if (\n status.isRecording !== stateRef.current.isRecording ||\n status.isPaused !== stateRef.current.isPaused\n ) {\n stateRef.current.isRecording = status.isRecording\n stateRef.current.isPaused = status.isPaused\n dispatch({\n type: 'UPDATE_RECORDING_STATE',\n payload: {\n isRecording: status.isRecording,\n isPaused: status.isPaused,\n },\n })\n }\n\n if (\n status.durationMs !== stateRef.current.durationMs ||\n status.size !== stateRef.current.size\n ) {\n stateRef.current.durationMs = status.durationMs\n stateRef.current.size = status.size\n stateRef.current.compression = status.compression\n dispatch({\n type: 'UPDATE_STATUS',\n payload: {\n durationMs: status.durationMs,\n size: status.size,\n compression: status.compression,\n },\n })\n }\n } catch (error) {\n logger?.error(`Error getting status:`, error)\n }\n }, [ExpoAudioStream, logger]) // Only depend on ExpoAudioStream and logger\n\n // Update ref when state changes\n useEffect(() => {\n stateRef.current = {\n isRecording: state.isRecording,\n isPaused: state.isPaused,\n durationMs: state.durationMs,\n size: state.size,\n compression: state.compression,\n }\n }, [\n state.isRecording,\n state.isPaused,\n state.durationMs,\n state.size,\n state.compression,\n ])\n\n const startRecording = useCallback(\n async (recordingOptions: RecordingConfig) => {\n recordingConfigRef.current = recordingOptions\n logger?.debug(`start recoding`, recordingOptions)\n\n analysisRef.current = { ...defaultAnalysis } // Reset analysis data\n fullAnalysisRef.current = { ...defaultAnalysis }\n const { onAudioStream, ...options } = recordingOptions\n const { enableProcessing } = options\n\n const maxRecentDataDuration = 10000 // TODO compute maxRecentDataDuration based on screen dimensions\n if (typeof onAudioStream === 'function') {\n onAudioStreamRef.current = onAudioStream\n } else {\n logger?.warn(`onAudioStream is not a function`, onAudioStream)\n onAudioStreamRef.current = null\n }\n const startResult: StartRecordingResult =\n await ExpoAudioStream.startRecording(options)\n dispatch({ type: 'START' })\n\n startResultRef.current = startResult\n\n if (enableProcessing) {\n logger?.debug(`Enabling audio analysis listener`)\n const listener = addAudioAnalysisListener(\n async (analysisData) => {\n try {\n await handleAudioAnalysis({\n analysis: analysisData,\n visualizationDuration: maxRecentDataDuration,\n })\n } catch (error) {\n logger?.warn(\n `Error processing audio analysis:`,\n error\n )\n }\n }\n )\n\n analysisListenerRef.current = listener\n }\n\n return startResult\n },\n [handleAudioAnalysis, dispatch]\n )\n\n const prepareRecording = useCallback(\n async (recordingOptions: RecordingConfig) => {\n recordingConfigRef.current = recordingOptions\n logger?.debug(`preparing recording`, recordingOptions)\n\n analysisRef.current = { ...defaultAnalysis } // Reset analysis data\n fullAnalysisRef.current = { ...defaultAnalysis }\n const { onAudioStream, ...options } = recordingOptions\n\n // Store onAudioStream for later use when recording starts\n if (typeof onAudioStream === 'function') {\n onAudioStreamRef.current = onAudioStream\n } else {\n logger?.warn(`onAudioStream is not a function`, onAudioStream)\n onAudioStreamRef.current = null\n }\n\n // Call the native prepareRecording method\n await ExpoAudioStream.prepareRecording(options)\n logger?.debug(`recording prepared successfully`)\n },\n []\n )\n\n const stopRecording = useCallback(async () => {\n logger?.debug(`stoping recording`)\n\n const stopResult: AudioRecording = await ExpoAudioStream.stopRecording()\n stopResult.analysisData = fullAnalysisRef.current\n\n if (analysisListenerRef.current) {\n analysisListenerRef.current.remove()\n analysisListenerRef.current = null\n }\n onAudioStreamRef.current = null\n logger?.debug(`recording stopped`, stopResult)\n dispatch({ type: 'STOP' })\n return stopResult\n }, [dispatch])\n\n const pauseRecording = useCallback(async () => {\n logger?.debug(`pause recording`)\n const pauseResult = await ExpoAudioStream.pauseRecording()\n dispatch({ type: 'PAUSE' })\n return pauseResult\n }, [dispatch])\n\n const resumeRecording = useCallback(async () => {\n logger?.debug(`resume recording`)\n const resumeResult = await ExpoAudioStream.resumeRecording()\n dispatch({ type: 'RESUME' })\n return resumeResult\n }, [dispatch])\n\n useEffect(() => {\n let intervalId: NodeJS.Timeout | undefined\n\n if (state.isRecording || state.isPaused) {\n // Immediately check status when starting\n checkStatus()\n\n // Start interval\n intervalId = setInterval(checkStatus, 1000)\n }\n\n return () => {\n if (intervalId) {\n clearInterval(intervalId)\n intervalId = undefined\n }\n }\n }, [checkStatus, state.isRecording, state.isPaused])\n\n useEffect(() => {\n logger?.debug(`Registering audio event listener`)\n const subscribeAudio = addAudioEventListener(handleAudioEvent)\n\n logger?.debug(\n `Subscribed to audio event listener and analysis listener`,\n {\n subscribeAudio,\n }\n )\n\n return () => {\n logger?.debug(`Removing audio event listener`)\n subscribeAudio.remove()\n }\n }, [handleAudioEvent, handleAudioAnalysis])\n\n useEffect(() => {\n // Add event subscription for recording interruptions\n logger?.debug('Setting up recording interruption listener')\n\n const subscription = addRecordingInterruptionListener((event) => {\n logger?.debug('Received recording interruption event:', event)\n\n // Check if we have a callback configured\n if (recordingConfigRef.current?.onRecordingInterrupted) {\n try {\n recordingConfigRef.current.onRecordingInterrupted(event)\n } catch (error) {\n logger?.error(\n 'Error in recording interruption callback:',\n error\n )\n }\n } else {\n logger?.warn('No recording interruption callback configured')\n }\n })\n\n return () => {\n logger?.debug('Removing recording interruption listener')\n subscription.remove()\n }\n }, []) // Empty dependency array since we want this to run once\n\n return {\n prepareRecording,\n startRecording,\n stopRecording,\n pauseRecording,\n resumeRecording,\n isPaused: state.isPaused,\n isRecording: state.isRecording,\n durationMs: state.durationMs,\n size: state.size,\n compression: state.compression,\n analysisData: state.analysisData,\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.processAudioBuffer = void 0;
3
+ exports.processAudioBuffer = processAudioBuffer;
4
4
  // packages/expo-audio-stream/src/utils/audioProcessing.ts
5
5
  const react_native_1 = require("react-native");
6
6
  async function processAudioBuffer({ arrayBuffer, fileUri, targetSampleRate, targetChannels, normalizeAudio, startTimeMs, endTimeMs, position, length, audioContext, logger, }) {
@@ -133,5 +133,4 @@ async function processAudioBuffer({ arrayBuffer, fileUri, targetSampleRate, targ
133
133
  }
134
134
  }
135
135
  }
136
- exports.processAudioBuffer = processAudioBuffer;
137
136
  //# sourceMappingURL=audioProcessing.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"audioProcessing.js","sourceRoot":"","sources":["../../../src/utils/audioProcessing.ts"],"names":[],"mappings":"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","sourcesContent":["// packages/expo-audio-stream/src/utils/audioProcessing.ts\nimport { Platform } from 'react-native'\n\nimport { ConsoleLike } from '../ExpoAudioStream.types'\n\nexport interface ProcessAudioBufferOptions {\n arrayBuffer?: ArrayBuffer\n fileUri?: string\n targetSampleRate: number\n targetChannels: number\n normalizeAudio: boolean\n startTimeMs?: number\n endTimeMs?: number\n position?: number\n length?: number\n audioContext?: AudioContext\n logger?: ConsoleLike\n}\n\nexport interface ProcessedAudioData {\n channelData: Float32Array\n samples: number\n durationMs: number\n sampleRate: number\n channels: number\n buffer: AudioBuffer\n}\n\nexport async function processAudioBuffer({\n arrayBuffer,\n fileUri,\n targetSampleRate,\n targetChannels,\n normalizeAudio,\n startTimeMs,\n endTimeMs,\n position,\n length,\n audioContext,\n logger,\n}: ProcessAudioBufferOptions): Promise<ProcessedAudioData> {\n if (Platform.OS !== 'web') {\n throw new Error('processAudioBuffer is only supported on web')\n }\n\n let ctx: AudioContext | undefined\n let buffer: AudioBuffer | undefined\n\n try {\n // Log initial parameters\n logger?.debug('Process audio buffer - Initial params:', {\n hasArrayBuffer: !!arrayBuffer,\n fileUri,\n targetSampleRate,\n targetChannels,\n normalizeAudio,\n startTimeMs,\n endTimeMs,\n position,\n length,\n })\n\n // Get the audio data\n let audioData: ArrayBuffer\n if (arrayBuffer) {\n audioData = arrayBuffer\n } else if (fileUri) {\n const response = await fetch(fileUri)\n if (!response.ok) {\n throw new Error(\n `Failed to fetch fileUri: ${response.statusText}`\n )\n }\n audioData = await response.arrayBuffer()\n } else {\n throw new Error('Either arrayBuffer or fileUri must be provided')\n }\n\n logger?.debug('Audio data loaded:', {\n byteLength: audioData.byteLength,\n firstBytes: Array.from(new Uint8Array(audioData.slice(0, 16))),\n })\n\n // Create context at original sample rate first\n ctx =\n audioContext ||\n new (window.AudioContext || (window as any).webkitAudioContext)()\n buffer = await ctx.decodeAudioData(audioData)\n\n logger?.debug('Decoded audio buffer:', {\n originalChannels: buffer.numberOfChannels,\n originalSampleRate: buffer.sampleRate,\n originalDuration: buffer.duration,\n originalLength: buffer.length,\n })\n\n // Calculate time range\n const startSample =\n startTimeMs !== undefined\n ? Math.floor((startTimeMs / 1000) * buffer.sampleRate)\n : position !== undefined\n ? Math.floor(position / 2)\n : 0\n\n // Fix: Adjust position calculation based on original sample rate\n // When position is provided in bytes, we need to account for the original sample rate\n const bytesPerSample = 2 // 16-bit audio = 2 bytes per sample\n const adjustedStartSample =\n position !== undefined\n ? Math.floor(\n (position / bytesPerSample) *\n (buffer.sampleRate / targetSampleRate)\n )\n : startSample\n\n const samplesNeeded =\n length !== undefined\n ? Math.floor(\n (length / bytesPerSample) *\n (buffer.sampleRate / targetSampleRate)\n )\n : endTimeMs !== undefined && startTimeMs !== undefined\n ? Math.floor(\n ((endTimeMs - startTimeMs) / 1000) * buffer.sampleRate\n )\n : buffer.length - adjustedStartSample\n\n logger?.debug('Sample calculations (adjusted):', {\n originalStartSample: startSample,\n adjustedStartSample,\n samplesNeeded,\n originalSampleRate: buffer.sampleRate,\n targetSampleRate,\n conversionRatio: buffer.sampleRate / targetSampleRate,\n expectedDurationMs: (samplesNeeded / buffer.sampleRate) * 1000,\n })\n\n // Create temporary buffer for the segment\n const segmentBuffer = ctx.createBuffer(\n buffer.numberOfChannels,\n samplesNeeded,\n buffer.sampleRate\n )\n\n // Copy the segment\n for (let channel = 0; channel < buffer.numberOfChannels; channel++) {\n const channelData = buffer.getChannelData(channel)\n const segmentData = segmentBuffer.getChannelData(channel)\n for (let i = 0; i < samplesNeeded; i++) {\n segmentData[i] = channelData[adjustedStartSample + i]\n }\n }\n\n // Create offline context for resampling\n const offlineCtx = new OfflineAudioContext(\n targetChannels,\n Math.ceil((samplesNeeded * targetSampleRate) / buffer.sampleRate),\n targetSampleRate\n )\n\n // Create source and connect\n const source = offlineCtx.createBufferSource()\n source.buffer = segmentBuffer\n source.connect(offlineCtx.destination)\n\n // Render at new sample rate\n source.start()\n const processedBuffer = await offlineCtx.startRendering()\n\n // Get the final audio data\n const channelData = processedBuffer.getChannelData(0)\n const durationMs = Math.round(\n (samplesNeeded / buffer.sampleRate) * 1000\n )\n\n logger?.debug('Final processed audio:', {\n outputSamples: channelData.length,\n outputSampleRate: targetSampleRate,\n durationMs,\n })\n\n return {\n buffer: processedBuffer,\n channelData,\n samples: channelData.length,\n durationMs,\n sampleRate: targetSampleRate,\n channels: processedBuffer.numberOfChannels,\n }\n } catch (error) {\n logger?.error('Failed to process audio buffer:', {\n error,\n position,\n length,\n startTimeMs,\n endTimeMs,\n bufferLength: buffer?.length,\n })\n throw error\n } finally {\n if (!audioContext && ctx) {\n await ctx.close()\n }\n }\n}\n"]}
1
+ {"version":3,"file":"audioProcessing.js","sourceRoot":"","sources":["../../../src/utils/audioProcessing.ts"],"names":[],"mappings":";;AA4BA,gDAgLC;AA5MD,0DAA0D;AAC1D,+CAAuC;AA2BhC,KAAK,UAAU,kBAAkB,CAAC,EACrC,WAAW,EACX,OAAO,EACP,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,WAAW,EACX,SAAS,EACT,QAAQ,EACR,MAAM,EACN,YAAY,EACZ,MAAM,GACkB;IACxB,IAAI,uBAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;IAClE,CAAC;IAED,IAAI,GAA6B,CAAA;IACjC,IAAI,MAA+B,CAAA;IAEnC,IAAI,CAAC;QACD,yBAAyB;QACzB,MAAM,EAAE,KAAK,CAAC,wCAAwC,EAAE;YACpD,cAAc,EAAE,CAAC,CAAC,WAAW;YAC7B,OAAO;YACP,gBAAgB;YAChB,cAAc;YACd,cAAc;YACd,WAAW;YACX,SAAS;YACT,QAAQ;YACR,MAAM;SACT,CAAC,CAAA;QAEF,qBAAqB;QACrB,IAAI,SAAsB,CAAA;QAC1B,IAAI,WAAW,EAAE,CAAC;YACd,SAAS,GAAG,WAAW,CAAA;QAC3B,CAAC;aAAM,IAAI,OAAO,EAAE,CAAC;YACjB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,CAAA;YACrC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CACX,4BAA4B,QAAQ,CAAC,UAAU,EAAE,CACpD,CAAA;YACL,CAAC;YACD,SAAS,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAA;QAC5C,CAAC;aAAM,CAAC;YACJ,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAA;QACrE,CAAC;QAED,MAAM,EAAE,KAAK,CAAC,oBAAoB,EAAE;YAChC,UAAU,EAAE,SAAS,CAAC,UAAU;YAChC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;SACjE,CAAC,CAAA;QAEF,+CAA+C;QAC/C,GAAG;YACC,YAAY;gBACZ,IAAI,CAAC,MAAM,CAAC,YAAY,IAAK,MAAc,CAAC,kBAAkB,CAAC,EAAE,CAAA;QACrE,MAAM,GAAG,MAAM,GAAG,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;QAE7C,MAAM,EAAE,KAAK,CAAC,uBAAuB,EAAE;YACnC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;YACzC,kBAAkB,EAAE,MAAM,CAAC,UAAU;YACrC,gBAAgB,EAAE,MAAM,CAAC,QAAQ;YACjC,cAAc,EAAE,MAAM,CAAC,MAAM;SAChC,CAAC,CAAA;QAEF,uBAAuB;QACvB,MAAM,WAAW,GACb,WAAW,KAAK,SAAS;YACrB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC;YACtD,CAAC,CAAC,QAAQ,KAAK,SAAS;gBACtB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC;gBAC1B,CAAC,CAAC,CAAC,CAAA;QAEb,iEAAiE;QACjE,sFAAsF;QACtF,MAAM,cAAc,GAAG,CAAC,CAAA,CAAC,oCAAoC;QAC7D,MAAM,mBAAmB,GACrB,QAAQ,KAAK,SAAS;YAClB,CAAC,CAAC,IAAI,CAAC,KAAK,CACN,CAAC,QAAQ,GAAG,cAAc,CAAC;gBACvB,CAAC,MAAM,CAAC,UAAU,GAAG,gBAAgB,CAAC,CAC7C;YACH,CAAC,CAAC,WAAW,CAAA;QAErB,MAAM,aAAa,GACf,MAAM,KAAK,SAAS;YAChB,CAAC,CAAC,IAAI,CAAC,KAAK,CACN,CAAC,MAAM,GAAG,cAAc,CAAC;gBACrB,CAAC,MAAM,CAAC,UAAU,GAAG,gBAAgB,CAAC,CAC7C;YACH,CAAC,CAAC,SAAS,KAAK,SAAS,IAAI,WAAW,KAAK,SAAS;gBACpD,CAAC,CAAC,IAAI,CAAC,KAAK,CACN,CAAC,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,UAAU,CACzD;gBACH,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,mBAAmB,CAAA;QAE/C,MAAM,EAAE,KAAK,CAAC,iCAAiC,EAAE;YAC7C,mBAAmB,EAAE,WAAW;YAChC,mBAAmB;YACnB,aAAa;YACb,kBAAkB,EAAE,MAAM,CAAC,UAAU;YACrC,gBAAgB;YAChB,eAAe,EAAE,MAAM,CAAC,UAAU,GAAG,gBAAgB;YACrD,kBAAkB,EAAE,CAAC,aAAa,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,IAAI;SACjE,CAAC,CAAA;QAEF,0CAA0C;QAC1C,MAAM,aAAa,GAAG,GAAG,CAAC,YAAY,CAClC,MAAM,CAAC,gBAAgB,EACvB,aAAa,EACb,MAAM,CAAC,UAAU,CACpB,CAAA;QAED,mBAAmB;QACnB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,gBAAgB,EAAE,OAAO,EAAE,EAAE,CAAC;YACjE,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;YAClD,MAAM,WAAW,GAAG,aAAa,CAAC,cAAc,CAAC,OAAO,CAAC,CAAA;YACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,EAAE,CAAC,EAAE,EAAE,CAAC;gBACrC,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,mBAAmB,GAAG,CAAC,CAAC,CAAA;YACzD,CAAC;QACL,CAAC;QAED,wCAAwC;QACxC,MAAM,UAAU,GAAG,IAAI,mBAAmB,CACtC,cAAc,EACd,IAAI,CAAC,IAAI,CAAC,CAAC,aAAa,GAAG,gBAAgB,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,EACjE,gBAAgB,CACnB,CAAA;QAED,4BAA4B;QAC5B,MAAM,MAAM,GAAG,UAAU,CAAC,kBAAkB,EAAE,CAAA;QAC9C,MAAM,CAAC,MAAM,GAAG,aAAa,CAAA;QAC7B,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAA;QAEtC,4BAA4B;QAC5B,MAAM,CAAC,KAAK,EAAE,CAAA;QACd,MAAM,eAAe,GAAG,MAAM,UAAU,CAAC,cAAc,EAAE,CAAA;QAEzD,2BAA2B;QAC3B,MAAM,WAAW,GAAG,eAAe,CAAC,cAAc,CAAC,CAAC,CAAC,CAAA;QACrD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CACzB,CAAC,aAAa,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,IAAI,CAC7C,CAAA;QAED,MAAM,EAAE,KAAK,CAAC,wBAAwB,EAAE;YACpC,aAAa,EAAE,WAAW,CAAC,MAAM;YACjC,gBAAgB,EAAE,gBAAgB;YAClC,UAAU;SACb,CAAC,CAAA;QAEF,OAAO;YACH,MAAM,EAAE,eAAe;YACvB,WAAW;YACX,OAAO,EAAE,WAAW,CAAC,MAAM;YAC3B,UAAU;YACV,UAAU,EAAE,gBAAgB;YAC5B,QAAQ,EAAE,eAAe,CAAC,gBAAgB;SAC7C,CAAA;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,MAAM,EAAE,KAAK,CAAC,iCAAiC,EAAE;YAC7C,KAAK;YACL,QAAQ;YACR,MAAM;YACN,WAAW;YACX,SAAS;YACT,YAAY,EAAE,MAAM,EAAE,MAAM;SAC/B,CAAC,CAAA;QACF,MAAM,KAAK,CAAA;IACf,CAAC;YAAS,CAAC;QACP,IAAI,CAAC,YAAY,IAAI,GAAG,EAAE,CAAC;YACvB,MAAM,GAAG,CAAC,KAAK,EAAE,CAAA;QACrB,CAAC;IACL,CAAC;AACL,CAAC","sourcesContent":["// packages/expo-audio-stream/src/utils/audioProcessing.ts\nimport { Platform } from 'react-native'\n\nimport { ConsoleLike } from '../ExpoAudioStream.types'\n\nexport interface ProcessAudioBufferOptions {\n arrayBuffer?: ArrayBuffer\n fileUri?: string\n targetSampleRate: number\n targetChannels: number\n normalizeAudio: boolean\n startTimeMs?: number\n endTimeMs?: number\n position?: number\n length?: number\n audioContext?: AudioContext\n logger?: ConsoleLike\n}\n\nexport interface ProcessedAudioData {\n channelData: Float32Array\n samples: number\n durationMs: number\n sampleRate: number\n channels: number\n buffer: AudioBuffer\n}\n\nexport async function processAudioBuffer({\n arrayBuffer,\n fileUri,\n targetSampleRate,\n targetChannels,\n normalizeAudio,\n startTimeMs,\n endTimeMs,\n position,\n length,\n audioContext,\n logger,\n}: ProcessAudioBufferOptions): Promise<ProcessedAudioData> {\n if (Platform.OS !== 'web') {\n throw new Error('processAudioBuffer is only supported on web')\n }\n\n let ctx: AudioContext | undefined\n let buffer: AudioBuffer | undefined\n\n try {\n // Log initial parameters\n logger?.debug('Process audio buffer - Initial params:', {\n hasArrayBuffer: !!arrayBuffer,\n fileUri,\n targetSampleRate,\n targetChannels,\n normalizeAudio,\n startTimeMs,\n endTimeMs,\n position,\n length,\n })\n\n // Get the audio data\n let audioData: ArrayBuffer\n if (arrayBuffer) {\n audioData = arrayBuffer\n } else if (fileUri) {\n const response = await fetch(fileUri)\n if (!response.ok) {\n throw new Error(\n `Failed to fetch fileUri: ${response.statusText}`\n )\n }\n audioData = await response.arrayBuffer()\n } else {\n throw new Error('Either arrayBuffer or fileUri must be provided')\n }\n\n logger?.debug('Audio data loaded:', {\n byteLength: audioData.byteLength,\n firstBytes: Array.from(new Uint8Array(audioData.slice(0, 16))),\n })\n\n // Create context at original sample rate first\n ctx =\n audioContext ||\n new (window.AudioContext || (window as any).webkitAudioContext)()\n buffer = await ctx.decodeAudioData(audioData)\n\n logger?.debug('Decoded audio buffer:', {\n originalChannels: buffer.numberOfChannels,\n originalSampleRate: buffer.sampleRate,\n originalDuration: buffer.duration,\n originalLength: buffer.length,\n })\n\n // Calculate time range\n const startSample =\n startTimeMs !== undefined\n ? Math.floor((startTimeMs / 1000) * buffer.sampleRate)\n : position !== undefined\n ? Math.floor(position / 2)\n : 0\n\n // Fix: Adjust position calculation based on original sample rate\n // When position is provided in bytes, we need to account for the original sample rate\n const bytesPerSample = 2 // 16-bit audio = 2 bytes per sample\n const adjustedStartSample =\n position !== undefined\n ? Math.floor(\n (position / bytesPerSample) *\n (buffer.sampleRate / targetSampleRate)\n )\n : startSample\n\n const samplesNeeded =\n length !== undefined\n ? Math.floor(\n (length / bytesPerSample) *\n (buffer.sampleRate / targetSampleRate)\n )\n : endTimeMs !== undefined && startTimeMs !== undefined\n ? Math.floor(\n ((endTimeMs - startTimeMs) / 1000) * buffer.sampleRate\n )\n : buffer.length - adjustedStartSample\n\n logger?.debug('Sample calculations (adjusted):', {\n originalStartSample: startSample,\n adjustedStartSample,\n samplesNeeded,\n originalSampleRate: buffer.sampleRate,\n targetSampleRate,\n conversionRatio: buffer.sampleRate / targetSampleRate,\n expectedDurationMs: (samplesNeeded / buffer.sampleRate) * 1000,\n })\n\n // Create temporary buffer for the segment\n const segmentBuffer = ctx.createBuffer(\n buffer.numberOfChannels,\n samplesNeeded,\n buffer.sampleRate\n )\n\n // Copy the segment\n for (let channel = 0; channel < buffer.numberOfChannels; channel++) {\n const channelData = buffer.getChannelData(channel)\n const segmentData = segmentBuffer.getChannelData(channel)\n for (let i = 0; i < samplesNeeded; i++) {\n segmentData[i] = channelData[adjustedStartSample + i]\n }\n }\n\n // Create offline context for resampling\n const offlineCtx = new OfflineAudioContext(\n targetChannels,\n Math.ceil((samplesNeeded * targetSampleRate) / buffer.sampleRate),\n targetSampleRate\n )\n\n // Create source and connect\n const source = offlineCtx.createBufferSource()\n source.buffer = segmentBuffer\n source.connect(offlineCtx.destination)\n\n // Render at new sample rate\n source.start()\n const processedBuffer = await offlineCtx.startRendering()\n\n // Get the final audio data\n const channelData = processedBuffer.getChannelData(0)\n const durationMs = Math.round(\n (samplesNeeded / buffer.sampleRate) * 1000\n )\n\n logger?.debug('Final processed audio:', {\n outputSamples: channelData.length,\n outputSampleRate: targetSampleRate,\n durationMs,\n })\n\n return {\n buffer: processedBuffer,\n channelData,\n samples: channelData.length,\n durationMs,\n sampleRate: targetSampleRate,\n channels: processedBuffer.numberOfChannels,\n }\n } catch (error) {\n logger?.error('Failed to process audio buffer:', {\n error,\n position,\n length,\n startTimeMs,\n endTimeMs,\n bufferLength: buffer?.length,\n })\n throw error\n } finally {\n if (!audioContext && ctx) {\n await ctx.close()\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"extractAudioAnalysis.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractAudioAnalysis.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAGtD,OAAO,EACH,aAAa,EACb,oBAAoB,EAEpB,cAAc,EACjB,MAAM,uBAAuB,CAAA;AAI9B,OAAO,EAAkB,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAerE,MAAM,WAAW,4BAA4B;IACzC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,EAAE,oBAAoB,CAAA;IAC/B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,eAAe,CAAC,EAAE,cAAc,CAAA;CACnC;AAGD,UAAU,kBAAkB;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,EAAE,oBAAoB,CAAA;IAC/B,eAAe,CAAC,EAAE,cAAc,CAAA;IAChC,MAAM,CAAC,EAAE,WAAW,CAAA;CACvB;AAGD,UAAU,gBAAiB,SAAQ,kBAAkB;IACjD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAA;IAChB,MAAM,CAAC,EAAE,KAAK,CAAA;CACjB;AAGD,UAAU,gBAAiB,SAAQ,kBAAkB;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,KAAK,CAAA;IACnB,SAAS,CAAC,EAAE,KAAK,CAAA;CACpB;AAED;;;;;GAKG;AACH,MAAM,MAAM,yBAAyB,GAAG,gBAAgB,GAAG,gBAAgB,CAAA;AAE3E;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACtC,KAAK,EAAE,yBAAyB,GACjC,OAAO,CAAC,aAAa,CAAC,CAmHxB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,yIAY/B,4BAA4B,KAAG,QAAQ,aAAa,CAkGtD,CAAA"}
1
+ {"version":3,"file":"extractAudioAnalysis.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractAudioAnalysis.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAGtD,OAAO,EACH,aAAa,EACb,oBAAoB,EAEpB,cAAc,EACjB,MAAM,uBAAuB,CAAA;AAI9B,OAAO,EAAkB,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAerE,MAAM,WAAW,4BAA4B;IACzC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,EAAE,oBAAoB,CAAA;IAC/B,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,eAAe,CAAC,EAAE,cAAc,CAAA;CACnC;AAGD,UAAU,kBAAkB;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,EAAE,oBAAoB,CAAA;IAC/B,eAAe,CAAC,EAAE,cAAc,CAAA;IAChC,MAAM,CAAC,EAAE,WAAW,CAAA;CACvB;AAGD,UAAU,gBAAiB,SAAQ,kBAAkB;IACjD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAA;IAChB,MAAM,CAAC,EAAE,KAAK,CAAA;CACjB;AAGD,UAAU,gBAAiB,SAAQ,kBAAkB;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,KAAK,CAAA;IACnB,SAAS,CAAC,EAAE,KAAK,CAAA;CACpB;AAED;;;;;GAKG;AACH,MAAM,MAAM,yBAAyB,GAAG,gBAAgB,GAAG,gBAAgB,CAAA;AAE3E;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACtC,KAAK,EAAE,yBAAyB,GACjC,OAAO,CAAC,aAAa,CAAC,CAmHxB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,GAAU,sIAYzC,4BAA4B,KAAG,OAAO,CAAC,aAAa,CAkGtD,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"extractAudioData.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractAudioData.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAGlE,eAAO,MAAM,gBAAgB,UAAiB,uBAAuB,iBAEpE,CAAA"}
1
+ {"version":3,"file":"extractAudioData.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractAudioData.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAGlE,eAAO,MAAM,gBAAgB,GAAU,OAAO,uBAAuB,iBAEpE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"extractWaveform.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractWaveform.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,EAAE,MAAM,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAClB;AACD,eAAO,MAAM,eAAe,kDAKzB,oBAAoB,KAAG,QAAQ,OAAO,CAQxC,CAAA"}
1
+ {"version":3,"file":"extractWaveform.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractWaveform.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,EAAE,MAAM,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAClB;AACD,eAAO,MAAM,eAAe,GAAU,+CAKnC,oBAAoB,KAAG,OAAO,CAAC,OAAO,CAQxC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"useAudioDevices.d.ts","sourceRoot":"","sources":["../../../src/hooks/useAudioDevices.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAEtD;;GAEG;AACH,wBAAgB,eAAe;;;;;6BAyEN,MAAM,KAAG,QAAQ,OAAO,CAAC;gCAiCK,QAAQ,OAAO,CAAC;0BA8BtB,QAAQ,WAAW,EAAE,CAAC;EAmCtE"}
1
+ {"version":3,"file":"useAudioDevices.d.ts","sourceRoot":"","sources":["../../../src/hooks/useAudioDevices.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAEtD;;GAEG;AACH,wBAAgB,eAAe;;;;;6BAyEN,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;gCAiCK,OAAO,CAAC,OAAO,CAAC;0BA8BtB,OAAO,CAAC,WAAW,EAAE,CAAC;EAmCtE"}
@@ -1 +1 @@
1
- {"version":3,"file":"BlobFix.d.ts","sourceRoot":"","sources":["../../../src/utils/BlobFix.ts"],"names":[],"mappings":"AAygBA;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,SAClB,IAAI,YACA,MAAM,oBAEjB,QAAQ,IAAI,CA4Bd,CAAA"}
1
+ {"version":3,"file":"BlobFix.d.ts","sourceRoot":"","sources":["../../../src/utils/BlobFix.ts"],"names":[],"mappings":"AAygBA;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GACxB,MAAM,IAAI,EACV,UAAU,MAAM,EAChB,aAAmB,KACpB,OAAO,CAAC,IAAI,CA4Bd,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"concatenateBuffers.d.ts","sourceRoot":"","sources":["../../../src/utils/concatenateBuffers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,YAAa,WAAW,EAAE,KAAG,WAiB3D,CAAA"}
1
+ {"version":3,"file":"concatenateBuffers.d.ts","sourceRoot":"","sources":["../../../src/utils/concatenateBuffers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,WAAW,EAAE,KAAG,WAiB3D,CAAA"}
@@ -3,8 +3,8 @@ export declare const WAV_HEADER_SIZE = 44;
3
3
  export declare const convertPCMToFloat32: ({ bitDepth, buffer, skipWavHeader, logger, }: {
4
4
  buffer: ArrayBuffer;
5
5
  bitDepth: number;
6
- skipWavHeader?: boolean | undefined;
7
- logger?: ConsoleLike | undefined;
6
+ skipWavHeader?: boolean;
7
+ logger?: ConsoleLike;
8
8
  }) => Promise<{
9
9
  pcmValues: Float32Array;
10
10
  min: number;
@@ -1 +1 @@
1
- {"version":3,"file":"convertPCMToFloat32.d.ts","sourceRoot":"","sources":["../../../src/utils/convertPCMToFloat32.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAGtD,eAAO,MAAM,eAAe,KAAK,CAAA;AA+DjC,eAAO,MAAM,mBAAmB;YAMpB,WAAW;cACT,MAAM;;;MAGhB,QAAQ;IAAE,SAAS,EAAE,YAAY,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CA2FhE,CAAA"}
1
+ {"version":3,"file":"convertPCMToFloat32.d.ts","sourceRoot":"","sources":["../../../src/utils/convertPCMToFloat32.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAGtD,eAAO,MAAM,eAAe,KAAK,CAAA;AA+DjC,eAAO,MAAM,mBAAmB,GAAU,8CAKvC;IACC,MAAM,EAAE,WAAW,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,MAAM,CAAC,EAAE,WAAW,CAAA;CACvB,KAAG,OAAO,CAAC;IAAE,SAAS,EAAE,YAAY,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CA2FhE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"encodingToBitDepth.d.ts","sourceRoot":"","sources":["../../../src/utils/encodingToBitDepth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAEjE,eAAO,MAAM,kBAAkB;cAGjB,YAAY;MACtB,QAWH,CAAA"}
1
+ {"version":3,"file":"encodingToBitDepth.d.ts","sourceRoot":"","sources":["../../../src/utils/encodingToBitDepth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAEjE,eAAO,MAAM,kBAAkB,GAAI,eAEhC;IACC,QAAQ,EAAE,YAAY,CAAA;CACzB,KAAG,QAWH,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"getWavFileInfo.d.ts","sourceRoot":"","sources":["../../../src/utils/getWavFileInfo.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAoB/D;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,UAAU,EAAE,UAAU,CAAA;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,QAAQ,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,sBAAsB,EAAE,MAAM,CAAA;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,eAAe,EAAE,MAAM,CAAA;CAC1B;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,gBACV,WAAW,KACzB,QAAQ,WAAW,CAmFrB,CAAA"}
1
+ {"version":3,"file":"getWavFileInfo.d.ts","sourceRoot":"","sources":["../../../src/utils/getWavFileInfo.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAoB/D;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,UAAU,EAAE,UAAU,CAAA;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,QAAQ,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,sBAAsB,EAAE,MAAM,CAAA;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,eAAe,EAAE,MAAM,CAAA;CAC1B;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GACvB,aAAa,WAAW,KACzB,OAAO,CAAC,WAAW,CAmFrB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"writeWavHeader.d.ts","sourceRoot":"","sources":["../../../src/utils/writeWavHeader.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B,+FAA+F;IAC/F,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAA;IAClB,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAA;IACnB,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAA;IAChB,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAA;CACpB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,cAAc,4DAMxB,gBAAgB,KAAG,WAyErB,CAAA"}
1
+ {"version":3,"file":"writeWavHeader.d.ts","sourceRoot":"","sources":["../../../src/utils/writeWavHeader.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B,+FAA+F;IAC/F,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAA;IAClB,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAA;IACnB,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAA;IAChB,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAA;CACpB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,cAAc,GAAI,yDAM5B,gBAAgB,KAAG,WAyErB,CAAA"}
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Workspace
3
+ version = "1.0">
4
+ <FileRef
5
+ location = "self:">
6
+ </FileRef>
7
+ </Workspace>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>IDEDidComputeMac32BitWarning</key>
6
+ <true/>
7
+ </dict>
8
+ </plist>
package/package.json CHANGED
@@ -1,21 +1,12 @@
1
1
  {
2
2
  "name": "@siteed/expo-audio-studio",
3
- "version": "2.8.3",
3
+ "version": "2.8.5",
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",
7
7
  "main": "./build/cjs/index.js",
8
8
  "module": "./build/esm/index.js",
9
9
  "types": "./build/types/index.d.ts",
10
- "exports": {
11
- ".": {
12
- "types": "./build/types/index.d.ts",
13
- "import": "./build/esm/index.js",
14
- "require": "./build/cjs/index.js",
15
- "default": "./build/cjs/index.js"
16
- },
17
- "./package.json": "./package.json"
18
- },
19
10
  "expo": {
20
11
  "plugin": "./app.plugin.js"
21
12
  },
@@ -58,7 +49,6 @@
58
49
  "ios",
59
50
  "cpp",
60
51
  "plugin",
61
- "app.plugin.cjs",
62
52
  "app.plugin.js",
63
53
  "LICENSE",
64
54
  "CHANGELOG.md",
@@ -101,12 +91,12 @@
101
91
  "release": "./publish.sh"
102
92
  },
103
93
  "devDependencies": {
104
- "@expo/config-plugins": "~9.0.0",
94
+ "@expo/config-plugins": "~10.0.0",
105
95
  "@siteed/publisher": "^0.4.18",
106
96
  "@size-limit/preset-big-lib": "^11.1.4",
107
97
  "@types/jest": "^29.5.12",
108
98
  "@types/node": "^20.12.7",
109
- "@types/react": "~18.3.12",
99
+ "@types/react": "~19.0.10",
110
100
  "@typescript-eslint/eslint-plugin": "^7.7.0",
111
101
  "@typescript-eslint/parser": "^7.7.0",
112
102
  "bundle-size": "^1.1.5",
@@ -117,17 +107,17 @@
117
107
  "eslint-plugin-prettier": "^5.1.3",
118
108
  "eslint-plugin-promise": "^6.1.1",
119
109
  "eslint-plugin-react": "^7.34.1",
120
- "expo": "^53.0.6",
110
+ "expo": "^53.0.9",
121
111
  "expo-module-scripts": "^4.0.2",
122
112
  "jest": "^29.7.0",
123
113
  "prettier": "^3.2.5",
124
- "react-native": "0.76.6",
114
+ "react-native": "0.79.2",
125
115
  "rimraf": "^6.0.1",
126
116
  "size-limit": "^11.1.4",
127
117
  "ts-node": "^10.9.2",
128
118
  "typedoc": "^0.27.4",
129
119
  "typedoc-plugin-markdown": "~4.4.2",
130
- "typescript": "~5.3.3"
120
+ "typescript": "~5.8.3"
131
121
  },
132
122
  "peerDependencies": {
133
123
  "expo": "*",
@@ -139,6 +129,6 @@
139
129
  "registry": "https://registry.npmjs.org"
140
130
  },
141
131
  "dependencies": {
142
- "expo-modules-core": "~2.3.12"
132
+ "expo-modules-core": "~2.3.13"
143
133
  }
144
134
  }
@@ -0,0 +1 @@
1
+ {"root":["./src/index.ts"],"version":"5.8.3"}
package/app.plugin.cjs DELETED
@@ -1,15 +0,0 @@
1
- // only here for ts-node and projects using app.config.ts instead of app.json.
2
- try {
3
- // Export the plugin from its CommonJS build
4
- module.exports = require('./plugin/build/')
5
- } catch (error) {
6
- console.error(
7
- '[@siteed/expo-audio-studio] Plugin loading error:',
8
- error.message
9
- )
10
- // Fallback plugin that does nothing but logs error
11
- module.exports = (config) => {
12
- console.warn('[@siteed/expo-audio-studio] Using fallback plugin due to loading error. Run `yarn build` in the package directory.')
13
- return config
14
- }
15
- }