@siteed/audio-studio 3.1.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/README.md +97 -50
  3. package/android/src/androidTest/java/net/siteed/audiostudio/AudioFinalMetadataContractInstrumentedTest.kt +190 -0
  4. package/android/src/androidTest/java/net/siteed/audiostudio/AudioRecorderInstrumentedTest.kt +29 -83
  5. package/android/src/androidTest/java/net/siteed/audiostudio/AudioRecorderPerformanceInstrumentedTest.kt +17 -1
  6. package/android/src/androidTest/java/net/siteed/audiostudio/OpusRangeDecodeRegressionInstrumentedTest.kt +186 -0
  7. package/android/src/main/java/net/siteed/audiostudio/AudioProcessor.kt +473 -380
  8. package/android/src/main/java/net/siteed/audiostudio/AudioStudioModule.kt +53 -10
  9. package/android/src/main/java/net/siteed/audiostudio/AudioTrimmer.kt +174 -212
  10. package/build/cjs/AudioAnalysis/AudioAnalysis.types.js.map +1 -1
  11. package/build/cjs/AudioAnalysis/extractPreview.js +92 -15
  12. package/build/cjs/AudioAnalysis/extractPreview.js.map +1 -1
  13. package/build/cjs/AudioAnalysis/extractPreviewBars.js +134 -0
  14. package/build/cjs/AudioAnalysis/extractPreviewBars.js.map +1 -0
  15. package/build/cjs/errors/AudioExtractionError.js +127 -0
  16. package/build/cjs/errors/AudioExtractionError.js.map +1 -0
  17. package/build/cjs/index.js +6 -1
  18. package/build/cjs/index.js.map +1 -1
  19. package/build/esm/AudioAnalysis/AudioAnalysis.types.js.map +1 -1
  20. package/build/esm/AudioAnalysis/extractPreview.js +92 -15
  21. package/build/esm/AudioAnalysis/extractPreview.js.map +1 -1
  22. package/build/esm/AudioAnalysis/extractPreviewBars.js +128 -0
  23. package/build/esm/AudioAnalysis/extractPreviewBars.js.map +1 -0
  24. package/build/esm/errors/AudioExtractionError.js +122 -0
  25. package/build/esm/errors/AudioExtractionError.js.map +1 -0
  26. package/build/esm/index.js +2 -0
  27. package/build/esm/index.js.map +1 -1
  28. package/build/types/AudioAnalysis/AudioAnalysis.types.d.ts +79 -0
  29. package/build/types/AudioAnalysis/AudioAnalysis.types.d.ts.map +1 -1
  30. package/build/types/AudioAnalysis/extractPreview.d.ts +2 -2
  31. package/build/types/AudioAnalysis/extractPreview.d.ts.map +1 -1
  32. package/build/types/AudioAnalysis/extractPreviewBars.d.ts +12 -0
  33. package/build/types/AudioAnalysis/extractPreviewBars.d.ts.map +1 -0
  34. package/build/types/errors/AudioExtractionError.d.ts +24 -0
  35. package/build/types/errors/AudioExtractionError.d.ts.map +1 -0
  36. package/build/types/index.d.ts +3 -0
  37. package/build/types/index.d.ts.map +1 -1
  38. package/ios/AudioProcessor.swift +99 -0
  39. package/ios/AudioStudioModule.swift +63 -0
  40. package/package.json +7 -7
  41. package/src/AudioAnalysis/AudioAnalysis.types.ts +82 -0
  42. package/src/AudioAnalysis/extractPreview.ts +118 -17
  43. package/src/AudioAnalysis/extractPreviewBars.ts +193 -0
  44. package/src/errors/AudioExtractionError.ts +167 -0
  45. package/src/index.ts +10 -0
@@ -1,25 +1,102 @@
1
+ import { mapExtractionError } from '../errors/AudioExtractionError';
1
2
  import { extractAudioAnalysis } from './extractAudioAnalysis';
3
+ const DEFAULT_SILENCE_THRESHOLD = 0.01;
4
+ /**
5
+ * Apply a silence threshold to the data points by recomputing the `silent` flag from rms.
6
+ * Returns a new array (does not mutate the source).
7
+ */
8
+ function applySilenceThreshold(dataPoints, threshold) {
9
+ return dataPoints.map((p) => ({
10
+ ...p,
11
+ silent: p.rms < threshold,
12
+ }));
13
+ }
14
+ const SMALL_TOTAL_INSTANT_THRESHOLD = 50;
15
+ const PROGRESSIVE_BATCH_DELAY_MS = 30;
16
+ const PROGRESSIVE_BATCH_COUNT = 8;
17
+ /**
18
+ * Schedule progressive emission of points after the native one-shot resolve.
19
+ * Native progressive streaming is a future enhancement; today the points are
20
+ * micro-batched on the JS side so consumers (and the agentic recipe runner)
21
+ * can observe an in-flight `pointsReceived < totalPoints` window.
22
+ */
23
+ function emitPointsProgressively(dataPoints, onPointReady, signal, logger) {
24
+ const total = dataPoints.length;
25
+ if (total === 0)
26
+ return;
27
+ const safeEmit = (point, index) => {
28
+ if (signal?.aborted)
29
+ return;
30
+ try {
31
+ onPointReady(point, index, total);
32
+ }
33
+ catch (err) {
34
+ // Swallow callback errors so a buggy consumer cannot break extraction.
35
+ logger?.warn?.('extractPreview onPointReady callback failed', err);
36
+ }
37
+ };
38
+ if (signal?.aborted)
39
+ return;
40
+ if (total <= SMALL_TOTAL_INSTANT_THRESHOLD) {
41
+ for (let i = 0; i < total; i++)
42
+ safeEmit(dataPoints[i], i);
43
+ return;
44
+ }
45
+ // First quarter flushes immediately so the UI shows something within a frame.
46
+ const firstFlushCount = Math.max(1, Math.floor(total / 4));
47
+ for (let i = 0; i < firstFlushCount; i++)
48
+ safeEmit(dataPoints[i], i);
49
+ if (firstFlushCount >= total)
50
+ return;
51
+ const remaining = total - firstFlushCount;
52
+ const batchSize = Math.max(1, Math.ceil(remaining / PROGRESSIVE_BATCH_COUNT));
53
+ let cursor = firstFlushCount;
54
+ const pump = () => {
55
+ if (signal?.aborted)
56
+ return;
57
+ const end = Math.min(total, cursor + batchSize);
58
+ for (let i = cursor; i < end; i++)
59
+ safeEmit(dataPoints[i], i);
60
+ cursor = end;
61
+ if (cursor < total) {
62
+ setTimeout(pump, PROGRESSIVE_BATCH_DELAY_MS);
63
+ }
64
+ };
65
+ setTimeout(pump, PROGRESSIVE_BATCH_DELAY_MS);
66
+ }
2
67
  /**
3
68
  * Generates a simplified preview of the audio waveform for quick visualization.
4
69
  * Ideal for UI rendering with a specified number of points.
5
70
  *
6
71
  * @param options - The options for the preview, including file URI and time range.
7
72
  * @returns A promise that resolves to the audio preview data.
73
+ * @throws {AudioExtractionError} when the underlying extraction fails.
8
74
  */
9
- export async function extractPreview({ fileUri, numberOfPoints = 100, startTimeMs = 0, endTimeMs = 30000, // First 30 seconds
10
- decodingOptions, logger, }) {
11
- const durationMs = endTimeMs - startTimeMs;
12
- const segmentDurationMs = Math.floor(durationMs / numberOfPoints);
13
- // Call extractAudioAnalysis with calculated parameters
14
- const analysis = await extractAudioAnalysis({
15
- fileUri,
16
- startTimeMs,
17
- endTimeMs,
18
- logger,
19
- segmentDurationMs,
20
- decodingOptions,
21
- });
22
- // Transform the result into AudioPreview format
23
- return analysis;
75
+ export async function extractPreview({ fileUri, numberOfPoints = 100, startTimeMs = 0, endTimeMs = 30000, decodingOptions, logger, onPointReady, signal, }) {
76
+ const durationMs = Math.max(1, endTimeMs - startTimeMs);
77
+ const segmentDurationMs = Math.max(1, Math.floor(durationMs / numberOfPoints));
78
+ let analysis;
79
+ try {
80
+ analysis = await extractAudioAnalysis({
81
+ fileUri,
82
+ startTimeMs,
83
+ endTimeMs,
84
+ logger,
85
+ segmentDurationMs,
86
+ decodingOptions,
87
+ });
88
+ }
89
+ catch (err) {
90
+ throw mapExtractionError(err, fileUri);
91
+ }
92
+ const threshold = decodingOptions?.silenceRmsThreshold ?? DEFAULT_SILENCE_THRESHOLD;
93
+ const adjusted = {
94
+ ...analysis,
95
+ dataPoints: applySilenceThreshold(analysis.dataPoints, threshold),
96
+ };
97
+ if (onPointReady) {
98
+ emitPointsProgressively(adjusted.dataPoints, onPointReady, signal, logger);
99
+ }
100
+ return adjusted;
24
101
  }
25
102
  //# sourceMappingURL=extractPreview.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"extractPreview.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractPreview.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAE7D;;;;;;GAMG;AACH,MAAM,CAAC,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,oBAAoB,CAAC;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"]}
1
+ {"version":3,"file":"extractPreview.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractPreview.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapExtractionError } from '../errors/AudioExtractionError'\nimport { PreviewOptions, AudioAnalysis, DataPoint } from './AudioAnalysis.types'\nimport { extractAudioAnalysis } from './extractAudioAnalysis'\n\nconst DEFAULT_SILENCE_THRESHOLD = 0.01\n\n/**\n * Apply a silence threshold to the data points by recomputing the `silent` flag from rms.\n * Returns a new array (does not mutate the source).\n */\nfunction applySilenceThreshold(\n dataPoints: DataPoint[],\n threshold: number\n): DataPoint[] {\n return dataPoints.map((p) => ({\n ...p,\n silent: p.rms < threshold,\n }))\n}\n\nconst SMALL_TOTAL_INSTANT_THRESHOLD = 50\nconst PROGRESSIVE_BATCH_DELAY_MS = 30\nconst PROGRESSIVE_BATCH_COUNT = 8\n\n/**\n * Schedule progressive emission of points after the native one-shot resolve.\n * Native progressive streaming is a future enhancement; today the points are\n * micro-batched on the JS side so consumers (and the agentic recipe runner)\n * can observe an in-flight `pointsReceived < totalPoints` window.\n */\nfunction emitPointsProgressively(\n dataPoints: DataPoint[],\n onPointReady: NonNullable<PreviewOptions['onPointReady']>,\n signal?: PreviewOptions['signal'],\n logger?: PreviewOptions['logger']\n): void {\n const total = dataPoints.length\n if (total === 0) return\n\n const safeEmit = (point: DataPoint, index: number) => {\n if (signal?.aborted) return\n try {\n onPointReady(point, index, total)\n } catch (err) {\n // Swallow callback errors so a buggy consumer cannot break extraction.\n logger?.warn?.('extractPreview onPointReady callback failed', err)\n }\n }\n\n if (signal?.aborted) return\n if (total <= SMALL_TOTAL_INSTANT_THRESHOLD) {\n for (let i = 0; i < total; i++) safeEmit(dataPoints[i], i)\n return\n }\n\n // First quarter flushes immediately so the UI shows something within a frame.\n const firstFlushCount = Math.max(1, Math.floor(total / 4))\n for (let i = 0; i < firstFlushCount; i++) safeEmit(dataPoints[i], i)\n\n if (firstFlushCount >= total) return\n\n const remaining = total - firstFlushCount\n const batchSize = Math.max(\n 1,\n Math.ceil(remaining / PROGRESSIVE_BATCH_COUNT)\n )\n let cursor = firstFlushCount\n const pump = () => {\n if (signal?.aborted) return\n const end = Math.min(total, cursor + batchSize)\n for (let i = cursor; i < end; i++) safeEmit(dataPoints[i], i)\n cursor = end\n if (cursor < total) {\n setTimeout(pump, PROGRESSIVE_BATCH_DELAY_MS)\n }\n }\n setTimeout(pump, PROGRESSIVE_BATCH_DELAY_MS)\n}\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 * @throws {AudioExtractionError} when the underlying extraction fails.\n */\nexport async function extractPreview({\n fileUri,\n numberOfPoints = 100,\n startTimeMs = 0,\n endTimeMs = 30000,\n decodingOptions,\n logger,\n onPointReady,\n signal,\n}: PreviewOptions): Promise<AudioAnalysis> {\n const durationMs = Math.max(1, endTimeMs - startTimeMs)\n const segmentDurationMs = Math.max(\n 1,\n Math.floor(durationMs / numberOfPoints)\n )\n\n let analysis: AudioAnalysis\n try {\n analysis = await extractAudioAnalysis({\n fileUri,\n startTimeMs,\n endTimeMs,\n logger,\n segmentDurationMs,\n decodingOptions,\n })\n } catch (err) {\n throw mapExtractionError(err, fileUri)\n }\n\n const threshold =\n decodingOptions?.silenceRmsThreshold ?? DEFAULT_SILENCE_THRESHOLD\n const adjusted: AudioAnalysis = {\n ...analysis,\n dataPoints: applySilenceThreshold(analysis.dataPoints, threshold),\n }\n\n if (onPointReady) {\n emitPointsProgressively(\n adjusted.dataPoints,\n onPointReady,\n signal,\n logger\n )\n }\n\n return adjusted\n}\n"]}
@@ -0,0 +1,128 @@
1
+ import { extractPreview } from './extractPreview';
2
+ import AudioStudioModule from '../AudioStudioModule';
3
+ import { mapExtractionError } from '../errors/AudioExtractionError';
4
+ import { cleanNativeOptions } from '../utils/cleanNativeOptions';
5
+ const DEFAULT_PREVIEW_BARS = 100;
6
+ const DEFAULT_PREVIEW_END_TIME_MS = 30000;
7
+ const DEFAULT_SILENCE_THRESHOLD = 0.01;
8
+ function hasNativePreviewBars(module) {
9
+ return (module !== null &&
10
+ (typeof module === 'object' || typeof module === 'function') &&
11
+ typeof module.extractPreviewBars ===
12
+ 'function');
13
+ }
14
+ function clamp01(value) {
15
+ if (!Number.isFinite(value))
16
+ return 0;
17
+ return Math.max(0, Math.min(1, value));
18
+ }
19
+ function getPointTimeMs(value, fallbackMs) {
20
+ return typeof value === 'number' && Number.isFinite(value)
21
+ ? Math.round(value)
22
+ : fallbackMs;
23
+ }
24
+ function pointToPreviewBar(point, index, fallbackBarDurationMs, silenceRmsThreshold) {
25
+ const fallbackStartTimeMs = Math.round(index * fallbackBarDurationMs);
26
+ const fallbackEndTimeMs = Math.round((index + 1) * fallbackBarDurationMs);
27
+ const startTimeMs = getPointTimeMs(point.startTime, fallbackStartTimeMs);
28
+ const endTimeMs = getPointTimeMs(point.endTime, fallbackEndTimeMs);
29
+ const rms = clamp01(point.rms);
30
+ return {
31
+ id: point.id ?? index,
32
+ amplitude: clamp01(point.amplitude),
33
+ rms,
34
+ silent: point.silent ?? rms < silenceRmsThreshold,
35
+ startTimeMs,
36
+ endTimeMs: Math.max(startTimeMs, endTimeMs),
37
+ };
38
+ }
39
+ function calculateRange(values) {
40
+ if (values.length === 0) {
41
+ return { min: 0, max: 0 };
42
+ }
43
+ let min = Number.POSITIVE_INFINITY;
44
+ let max = Number.NEGATIVE_INFINITY;
45
+ for (const value of values) {
46
+ const safeValue = clamp01(value);
47
+ min = Math.min(min, safeValue);
48
+ max = Math.max(max, safeValue);
49
+ }
50
+ return { min, max };
51
+ }
52
+ function fromAudioAnalysis(analysis, requestedNumberOfBars, silenceRmsThreshold) {
53
+ const barDurationMs = analysis.segmentDurationMs ||
54
+ Math.max(1, analysis.durationMs / Math.max(1, analysis.dataPoints.length));
55
+ const bars = analysis.dataPoints.map((point, index) => pointToPreviewBar(point, index, barDurationMs, silenceRmsThreshold));
56
+ return {
57
+ bars,
58
+ durationMs: analysis.durationMs,
59
+ sampleRate: analysis.sampleRate,
60
+ numberOfChannels: analysis.numberOfChannels,
61
+ bitDepth: analysis.bitDepth,
62
+ samples: analysis.samples,
63
+ requestedNumberOfBars,
64
+ barDurationMs,
65
+ amplitudeRange: calculateRange(bars.map((bar) => bar.amplitude)),
66
+ rmsRange: calculateRange(bars.map((bar) => bar.rms)),
67
+ extractionTimeMs: analysis.extractionTimeMs,
68
+ };
69
+ }
70
+ function emitBarsProgressively(bars, onBarReady) {
71
+ const total = bars.length;
72
+ for (let index = 0; index < total; index++) {
73
+ onBarReady(bars[index], index, total);
74
+ }
75
+ }
76
+ /**
77
+ * Extracts compact waveform preview bars for UI rendering.
78
+ *
79
+ * Native platforms may provide a compact `extractPreviewBars` bridge. Until that
80
+ * bridge is available, this safely falls back to the existing `extractPreview`
81
+ * compatibility path and adapts `DataPoint` objects into compact bars.
82
+ *
83
+ * @throws {AudioExtractionError} when the underlying extraction fails.
84
+ */
85
+ export async function extractPreviewBars({ fileUri, numberOfBars = DEFAULT_PREVIEW_BARS, startTimeMs = 0, endTimeMs = DEFAULT_PREVIEW_END_TIME_MS, decodingOptions, logger, onBarReady, }) {
86
+ const requestedNumberOfBars = Math.max(1, Math.floor(numberOfBars));
87
+ const nativeOptions = {
88
+ fileUri,
89
+ numberOfBars: requestedNumberOfBars,
90
+ startTimeMs,
91
+ endTimeMs,
92
+ decodingOptions,
93
+ };
94
+ const nativeModule = AudioStudioModule;
95
+ if (hasNativePreviewBars(nativeModule)) {
96
+ let result;
97
+ try {
98
+ result = await nativeModule.extractPreviewBars(cleanNativeOptions(nativeOptions));
99
+ }
100
+ catch (err) {
101
+ throw mapExtractionError(err, fileUri);
102
+ }
103
+ if (onBarReady) {
104
+ emitBarsProgressively(result.bars, onBarReady);
105
+ }
106
+ return result;
107
+ }
108
+ let analysis;
109
+ try {
110
+ analysis = await extractPreview({
111
+ fileUri,
112
+ numberOfPoints: requestedNumberOfBars,
113
+ startTimeMs,
114
+ endTimeMs,
115
+ decodingOptions,
116
+ logger,
117
+ });
118
+ }
119
+ catch (err) {
120
+ throw mapExtractionError(err, fileUri);
121
+ }
122
+ const result = fromAudioAnalysis(analysis, requestedNumberOfBars, decodingOptions?.silenceRmsThreshold ?? DEFAULT_SILENCE_THRESHOLD);
123
+ if (onBarReady) {
124
+ emitBarsProgressively(result.bars, onBarReady);
125
+ }
126
+ return result;
127
+ }
128
+ //# sourceMappingURL=extractPreviewBars.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractPreviewBars.js","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractPreviewBars.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AudioAnalysis,\n DataPoint,\n PreviewBar,\n PreviewBarsOptions,\n PreviewBarsResult,\n} from './AudioAnalysis.types'\nimport { extractPreview } from './extractPreview'\nimport AudioStudioModule from '../AudioStudioModule'\nimport { mapExtractionError } from '../errors/AudioExtractionError'\nimport { cleanNativeOptions } from '../utils/cleanNativeOptions'\n\nconst DEFAULT_PREVIEW_BARS = 100\nconst DEFAULT_PREVIEW_END_TIME_MS = 30000\nconst DEFAULT_SILENCE_THRESHOLD = 0.01\n\ninterface NativePreviewBarsModule {\n extractPreviewBars: (\n options: Record<string, unknown>\n ) => Promise<PreviewBarsResult>\n}\n\nfunction hasNativePreviewBars(\n module: unknown\n): module is NativePreviewBarsModule {\n return (\n module !== null &&\n (typeof module === 'object' || typeof module === 'function') &&\n typeof (module as NativePreviewBarsModule).extractPreviewBars ===\n 'function'\n )\n}\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.min(1, value))\n}\n\nfunction getPointTimeMs(value: number | undefined, fallbackMs: number): number {\n return typeof value === 'number' && Number.isFinite(value)\n ? Math.round(value)\n : fallbackMs\n}\n\nfunction pointToPreviewBar(\n point: DataPoint,\n index: number,\n fallbackBarDurationMs: number,\n silenceRmsThreshold: number\n): PreviewBar {\n const fallbackStartTimeMs = Math.round(index * fallbackBarDurationMs)\n const fallbackEndTimeMs = Math.round((index + 1) * fallbackBarDurationMs)\n const startTimeMs = getPointTimeMs(point.startTime, fallbackStartTimeMs)\n const endTimeMs = getPointTimeMs(point.endTime, fallbackEndTimeMs)\n const rms = clamp01(point.rms)\n\n return {\n id: point.id ?? index,\n amplitude: clamp01(point.amplitude),\n rms,\n silent: point.silent ?? rms < silenceRmsThreshold,\n startTimeMs,\n endTimeMs: Math.max(startTimeMs, endTimeMs),\n }\n}\n\nfunction calculateRange(values: number[]): { min: number; max: number } {\n if (values.length === 0) {\n return { min: 0, max: 0 }\n }\n\n let min = Number.POSITIVE_INFINITY\n let max = Number.NEGATIVE_INFINITY\n\n for (const value of values) {\n const safeValue = clamp01(value)\n min = Math.min(min, safeValue)\n max = Math.max(max, safeValue)\n }\n\n return { min, max }\n}\n\nfunction fromAudioAnalysis(\n analysis: AudioAnalysis,\n requestedNumberOfBars: number,\n silenceRmsThreshold: number\n): PreviewBarsResult {\n const barDurationMs =\n analysis.segmentDurationMs ||\n Math.max(\n 1,\n analysis.durationMs / Math.max(1, analysis.dataPoints.length)\n )\n const bars = analysis.dataPoints.map((point, index) =>\n pointToPreviewBar(point, index, barDurationMs, silenceRmsThreshold)\n )\n\n return {\n bars,\n durationMs: analysis.durationMs,\n sampleRate: analysis.sampleRate,\n numberOfChannels: analysis.numberOfChannels,\n bitDepth: analysis.bitDepth,\n samples: analysis.samples,\n requestedNumberOfBars,\n barDurationMs,\n amplitudeRange: calculateRange(bars.map((bar) => bar.amplitude)),\n rmsRange: calculateRange(bars.map((bar) => bar.rms)),\n extractionTimeMs: analysis.extractionTimeMs,\n }\n}\n\nfunction emitBarsProgressively(\n bars: PreviewBar[],\n onBarReady: NonNullable<PreviewBarsOptions['onBarReady']>\n): void {\n const total = bars.length\n for (let index = 0; index < total; index++) {\n onBarReady(bars[index], index, total)\n }\n}\n\n/**\n * Extracts compact waveform preview bars for UI rendering.\n *\n * Native platforms may provide a compact `extractPreviewBars` bridge. Until that\n * bridge is available, this safely falls back to the existing `extractPreview`\n * compatibility path and adapts `DataPoint` objects into compact bars.\n *\n * @throws {AudioExtractionError} when the underlying extraction fails.\n */\nexport async function extractPreviewBars({\n fileUri,\n numberOfBars = DEFAULT_PREVIEW_BARS,\n startTimeMs = 0,\n endTimeMs = DEFAULT_PREVIEW_END_TIME_MS,\n decodingOptions,\n logger,\n onBarReady,\n}: PreviewBarsOptions): Promise<PreviewBarsResult> {\n const requestedNumberOfBars = Math.max(1, Math.floor(numberOfBars))\n const nativeOptions = {\n fileUri,\n numberOfBars: requestedNumberOfBars,\n startTimeMs,\n endTimeMs,\n decodingOptions,\n }\n\n const nativeModule = AudioStudioModule as unknown\n if (hasNativePreviewBars(nativeModule)) {\n let result: PreviewBarsResult\n try {\n result = await nativeModule.extractPreviewBars(\n cleanNativeOptions(nativeOptions)\n )\n } catch (err) {\n throw mapExtractionError(err, fileUri)\n }\n\n if (onBarReady) {\n emitBarsProgressively(result.bars, onBarReady)\n }\n return result\n }\n\n let analysis: AudioAnalysis\n try {\n analysis = await extractPreview({\n fileUri,\n numberOfPoints: requestedNumberOfBars,\n startTimeMs,\n endTimeMs,\n decodingOptions,\n logger,\n })\n } catch (err) {\n throw mapExtractionError(err, fileUri)\n }\n\n const result = fromAudioAnalysis(\n analysis,\n requestedNumberOfBars,\n decodingOptions?.silenceRmsThreshold ?? DEFAULT_SILENCE_THRESHOLD\n )\n\n if (onBarReady) {\n emitBarsProgressively(result.bars, onBarReady)\n }\n\n return result\n}\n"]}
@@ -0,0 +1,122 @@
1
+ export class AudioExtractionError extends Error {
2
+ code;
3
+ nativeMessage;
4
+ fileUri;
5
+ constructor(payload) {
6
+ super(payload.message);
7
+ this.name = 'AudioExtractionError';
8
+ this.code = payload.code;
9
+ this.nativeMessage = payload.nativeMessage;
10
+ this.fileUri = payload.fileUri;
11
+ }
12
+ toJSON() {
13
+ return {
14
+ code: this.code,
15
+ message: this.message,
16
+ nativeMessage: this.nativeMessage,
17
+ fileUri: this.fileUri,
18
+ };
19
+ }
20
+ }
21
+ function getNativeMessage(err) {
22
+ if (err instanceof Error)
23
+ return err.message;
24
+ if (typeof err === 'string')
25
+ return err;
26
+ try {
27
+ return JSON.stringify(err) ?? String(err);
28
+ }
29
+ catch {
30
+ return String(err);
31
+ }
32
+ }
33
+ function getNativeCode(err) {
34
+ if (err && typeof err === 'object' && 'code' in err) {
35
+ const code = err.code;
36
+ if (typeof code === 'string')
37
+ return code;
38
+ }
39
+ return undefined;
40
+ }
41
+ function mapNativeCode(code) {
42
+ if (!code)
43
+ return null;
44
+ const normalized = code.toUpperCase();
45
+ if (normalized.includes('FILE_NOT_FOUND') ||
46
+ normalized === 'ENOENT' ||
47
+ normalized.includes('NO_SUCH_FILE')) {
48
+ return 'file_not_found';
49
+ }
50
+ if (normalized.includes('PERMISSION') ||
51
+ normalized === 'EACCES' ||
52
+ normalized.includes('NOT_AUTHORIZED')) {
53
+ return 'permission_denied';
54
+ }
55
+ if (normalized.includes('UNSUPPORTED') ||
56
+ normalized.includes('NO_SUITABLE_CODEC')) {
57
+ return 'unsupported_codec';
58
+ }
59
+ if (normalized.includes('INVALID_RANGE') ||
60
+ normalized.includes('INVALID_HEADER') ||
61
+ normalized.includes('MALFORMED') ||
62
+ normalized.includes('CORRUPT')) {
63
+ return 'malformed_file';
64
+ }
65
+ if (normalized.includes('PROCESSING_ERROR') ||
66
+ normalized.includes('AUDIO_READ_ERROR') ||
67
+ normalized.includes('DECODE')) {
68
+ return 'decode_failed';
69
+ }
70
+ return null;
71
+ }
72
+ /**
73
+ * Map a thrown native/JS value into an AudioExtractionError with a stable code.
74
+ * Heuristics inspect message text and known native error codes.
75
+ */
76
+ export function mapExtractionError(err, fileUri) {
77
+ if (err instanceof AudioExtractionError)
78
+ return err;
79
+ const nativeMessage = getNativeMessage(err);
80
+ const lower = nativeMessage.toLowerCase();
81
+ let code = mapNativeCode(getNativeCode(err)) ?? 'unknown';
82
+ if (code === 'unknown' &&
83
+ (lower.includes('unsupported') ||
84
+ lower.includes('not supported') ||
85
+ lower.includes('no suitable codec') ||
86
+ lower.includes('no track'))) {
87
+ code = 'unsupported_codec';
88
+ }
89
+ else if (code === 'unknown' &&
90
+ (lower.includes('not found') ||
91
+ lower.includes('no such file') ||
92
+ lower.includes('does not exist'))) {
93
+ code = 'file_not_found';
94
+ }
95
+ else if (code === 'unknown' &&
96
+ (lower.includes('permission') ||
97
+ lower.includes('denied') ||
98
+ lower.includes('not authorized'))) {
99
+ code = 'permission_denied';
100
+ }
101
+ else if (code === 'unknown' &&
102
+ (lower.includes('malformed') ||
103
+ lower.includes('corrupt') ||
104
+ lower.includes('invalid header') ||
105
+ lower.includes('invalid wav'))) {
106
+ code = 'malformed_file';
107
+ }
108
+ else if (code === 'unknown' &&
109
+ (lower.includes('decode') ||
110
+ lower.includes('codec') ||
111
+ lower.includes('mediaextractor') ||
112
+ lower.includes('avaudio'))) {
113
+ code = 'decode_failed';
114
+ }
115
+ return new AudioExtractionError({
116
+ code,
117
+ message: `Audio extraction failed (${code}): ${nativeMessage}`,
118
+ nativeMessage,
119
+ fileUri,
120
+ });
121
+ }
122
+ //# sourceMappingURL=AudioExtractionError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AudioExtractionError.js","sourceRoot":"","sources":["../../../src/errors/AudioExtractionError.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Typed error class for audio extraction failures.\n * Wraps native module errors with stable codes consumers can switch on.\n */\nexport type AudioExtractionErrorCode =\n | 'unsupported_codec'\n | 'malformed_file'\n | 'decode_failed'\n | 'permission_denied'\n | 'file_not_found'\n | 'unknown'\n\nexport interface AudioExtractionErrorPayload {\n code: AudioExtractionErrorCode\n message: string\n nativeMessage?: string\n fileUri?: string\n}\n\nexport class AudioExtractionError extends Error {\n readonly code: AudioExtractionErrorCode\n readonly nativeMessage?: string\n readonly fileUri?: string\n\n constructor(payload: AudioExtractionErrorPayload) {\n super(payload.message)\n this.name = 'AudioExtractionError'\n this.code = payload.code\n this.nativeMessage = payload.nativeMessage\n this.fileUri = payload.fileUri\n }\n\n toJSON(): AudioExtractionErrorPayload {\n return {\n code: this.code,\n message: this.message,\n nativeMessage: this.nativeMessage,\n fileUri: this.fileUri,\n }\n }\n}\n\nfunction getNativeMessage(err: unknown): string {\n if (err instanceof Error) return err.message\n if (typeof err === 'string') return err\n\n try {\n return JSON.stringify(err) ?? String(err)\n } catch {\n return String(err)\n }\n}\n\nfunction getNativeCode(err: unknown): string | undefined {\n if (err && typeof err === 'object' && 'code' in err) {\n const code = (err as { code?: unknown }).code\n if (typeof code === 'string') return code\n }\n return undefined\n}\n\nfunction mapNativeCode(\n code: string | undefined\n): AudioExtractionErrorCode | null {\n if (!code) return null\n\n const normalized = code.toUpperCase()\n if (\n normalized.includes('FILE_NOT_FOUND') ||\n normalized === 'ENOENT' ||\n normalized.includes('NO_SUCH_FILE')\n ) {\n return 'file_not_found'\n }\n if (\n normalized.includes('PERMISSION') ||\n normalized === 'EACCES' ||\n normalized.includes('NOT_AUTHORIZED')\n ) {\n return 'permission_denied'\n }\n if (\n normalized.includes('UNSUPPORTED') ||\n normalized.includes('NO_SUITABLE_CODEC')\n ) {\n return 'unsupported_codec'\n }\n if (\n normalized.includes('INVALID_RANGE') ||\n normalized.includes('INVALID_HEADER') ||\n normalized.includes('MALFORMED') ||\n normalized.includes('CORRUPT')\n ) {\n return 'malformed_file'\n }\n if (\n normalized.includes('PROCESSING_ERROR') ||\n normalized.includes('AUDIO_READ_ERROR') ||\n normalized.includes('DECODE')\n ) {\n return 'decode_failed'\n }\n\n return null\n}\n\n/**\n * Map a thrown native/JS value into an AudioExtractionError with a stable code.\n * Heuristics inspect message text and known native error codes.\n */\nexport function mapExtractionError(\n err: unknown,\n fileUri?: string\n): AudioExtractionError {\n if (err instanceof AudioExtractionError) return err\n\n const nativeMessage = getNativeMessage(err)\n const lower = nativeMessage.toLowerCase()\n\n let code = mapNativeCode(getNativeCode(err)) ?? 'unknown'\n if (\n code === 'unknown' &&\n (lower.includes('unsupported') ||\n lower.includes('not supported') ||\n lower.includes('no suitable codec') ||\n lower.includes('no track'))\n ) {\n code = 'unsupported_codec'\n } else if (\n code === 'unknown' &&\n (lower.includes('not found') ||\n lower.includes('no such file') ||\n lower.includes('does not exist'))\n ) {\n code = 'file_not_found'\n } else if (\n code === 'unknown' &&\n (lower.includes('permission') ||\n lower.includes('denied') ||\n lower.includes('not authorized'))\n ) {\n code = 'permission_denied'\n } else if (\n code === 'unknown' &&\n (lower.includes('malformed') ||\n lower.includes('corrupt') ||\n lower.includes('invalid header') ||\n lower.includes('invalid wav'))\n ) {\n code = 'malformed_file'\n } else if (\n code === 'unknown' &&\n (lower.includes('decode') ||\n lower.includes('codec') ||\n lower.includes('mediaextractor') ||\n lower.includes('avaudio'))\n ) {\n code = 'decode_failed'\n }\n\n return new AudioExtractionError({\n code,\n message: `Audio extraction failed (${code}): ${nativeMessage}`,\n nativeMessage,\n fileUri,\n })\n}\n"]}
@@ -18,7 +18,9 @@ export { AudioDeviceManager, audioDeviceManager } from './AudioDeviceManager';
18
18
  // Export useAudioDevices hook
19
19
  export { useAudioDevices } from './hooks/useAudioDevices';
20
20
  export { setMelSpectrogramWasmUrl } from './AudioAnalysis/wasmConfig';
21
+ export { extractPreviewBars } from './AudioAnalysis/extractPreviewBars';
21
22
  export { AudioRecorderProvider, AudioStudioModule, extractRawWavAnalysis, extractAudioAnalysis, extractPreview, trimAudio, extractAudioData, extractMelSpectrogram, initMelStreamingWasm, computeMelFrameWasm, MAX_DURATION_MS, useAudioRecorder, useSharedAudioRecorder, };
23
+ export { AudioExtractionError, mapExtractionError, } from './errors/AudioExtractionError';
22
24
  /** @deprecated Use AudioStudioModule instead */
23
25
  export const ExpoAudioStreamModule = AudioStudioModule;
24
26
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AAEf,OAAO,EACH,qBAAqB,EACrB,oBAAoB,GACvB,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,EACH,qBAAqB,EACrB,eAAe,GAClB,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EACH,oBAAoB,EACpB,mBAAmB,GACtB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EACH,qBAAqB,EACrB,sBAAsB,GACzB,MAAM,0BAA0B,CAAA;AACjC,OAAO,iBAAiB,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAErD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AAEtC,+BAA+B;AAC/B,OAAO,EACH,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,GAE1B,MAAM,iCAAiC,CAAA;AAExC,4BAA4B;AAC5B,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAE7E,8BAA8B;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAEzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AAErE,OAAO,EACH,qBAAqB,EACrB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,sBAAsB,GACzB,CAAA;AAMD,gDAAgD;AAChD,MAAM,CAAC,MAAM,qBAAqB,GAAG,iBAAiB,CAAA","sourcesContent":["// src/index.ts\n\nimport {\n extractRawWavAnalysis,\n extractAudioAnalysis,\n} from './AudioAnalysis/extractAudioAnalysis'\nimport { extractAudioData } from './AudioAnalysis/extractAudioData'\nimport {\n extractMelSpectrogram,\n MAX_DURATION_MS,\n} from './AudioAnalysis/extractMelSpectrogram'\nimport { extractPreview } from './AudioAnalysis/extractPreview'\nimport {\n initMelStreamingWasm,\n computeMelFrameWasm,\n} from './AudioAnalysis/melSpectrogramWasm'\nimport {\n AudioRecorderProvider,\n useSharedAudioRecorder,\n} from './AudioRecorder.provider'\nimport AudioStudioModule from './AudioStudioModule'\nimport { trimAudio } from './trimAudio'\nimport { useAudioRecorder } from './useAudioRecorder'\n\nexport * from './utils/convertPCMToFloat32'\nexport * from './utils/getWavFileInfo'\nexport * from './utils/writeWavHeader'\n\n// Export platform capabilities\nexport {\n getPlatformCapabilities,\n isEncodingSupported,\n isBitDepthSupported,\n getFallbackEncoding,\n getFallbackBitDepth,\n validateRecordingConfig,\n type PlatformCapabilities,\n} from './constants/platformLimitations'\n\n// Export AudioDeviceManager\nexport { AudioDeviceManager, audioDeviceManager } from './AudioDeviceManager'\n\n// Export useAudioDevices hook\nexport { useAudioDevices } from './hooks/useAudioDevices'\n\nexport { setMelSpectrogramWasmUrl } from './AudioAnalysis/wasmConfig'\n\nexport {\n AudioRecorderProvider,\n AudioStudioModule,\n extractRawWavAnalysis,\n extractAudioAnalysis,\n extractPreview,\n trimAudio,\n extractAudioData,\n extractMelSpectrogram,\n initMelStreamingWasm,\n computeMelFrameWasm,\n MAX_DURATION_MS,\n useAudioRecorder,\n useSharedAudioRecorder,\n}\n\n// Export all types\nexport type * from './AudioAnalysis/AudioAnalysis.types'\nexport type * from './AudioStudio.types'\n\n/** @deprecated Use AudioStudioModule instead */\nexport const ExpoAudioStreamModule = AudioStudioModule\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AAEf,OAAO,EACH,qBAAqB,EACrB,oBAAoB,GACvB,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,EACH,qBAAqB,EACrB,eAAe,GAClB,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EACH,oBAAoB,EACpB,mBAAmB,GACtB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EACH,qBAAqB,EACrB,sBAAsB,GACzB,MAAM,0BAA0B,CAAA;AACjC,OAAO,iBAAiB,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAErD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AAEtC,+BAA+B;AAC/B,OAAO,EACH,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,GAE1B,MAAM,iCAAiC,CAAA;AAExC,4BAA4B;AAC5B,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAE7E,8BAA8B;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAEzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAA;AAEvE,OAAO,EACH,qBAAqB,EACrB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,sBAAsB,GACzB,CAAA;AAED,OAAO,EACH,oBAAoB,EACpB,kBAAkB,GACrB,MAAM,+BAA+B,CAAA;AAUtC,gDAAgD;AAChD,MAAM,CAAC,MAAM,qBAAqB,GAAG,iBAAiB,CAAA","sourcesContent":["// src/index.ts\n\nimport {\n extractRawWavAnalysis,\n extractAudioAnalysis,\n} from './AudioAnalysis/extractAudioAnalysis'\nimport { extractAudioData } from './AudioAnalysis/extractAudioData'\nimport {\n extractMelSpectrogram,\n MAX_DURATION_MS,\n} from './AudioAnalysis/extractMelSpectrogram'\nimport { extractPreview } from './AudioAnalysis/extractPreview'\nimport {\n initMelStreamingWasm,\n computeMelFrameWasm,\n} from './AudioAnalysis/melSpectrogramWasm'\nimport {\n AudioRecorderProvider,\n useSharedAudioRecorder,\n} from './AudioRecorder.provider'\nimport AudioStudioModule from './AudioStudioModule'\nimport { trimAudio } from './trimAudio'\nimport { useAudioRecorder } from './useAudioRecorder'\n\nexport * from './utils/convertPCMToFloat32'\nexport * from './utils/getWavFileInfo'\nexport * from './utils/writeWavHeader'\n\n// Export platform capabilities\nexport {\n getPlatformCapabilities,\n isEncodingSupported,\n isBitDepthSupported,\n getFallbackEncoding,\n getFallbackBitDepth,\n validateRecordingConfig,\n type PlatformCapabilities,\n} from './constants/platformLimitations'\n\n// Export AudioDeviceManager\nexport { AudioDeviceManager, audioDeviceManager } from './AudioDeviceManager'\n\n// Export useAudioDevices hook\nexport { useAudioDevices } from './hooks/useAudioDevices'\n\nexport { setMelSpectrogramWasmUrl } from './AudioAnalysis/wasmConfig'\nexport { extractPreviewBars } from './AudioAnalysis/extractPreviewBars'\n\nexport {\n AudioRecorderProvider,\n AudioStudioModule,\n extractRawWavAnalysis,\n extractAudioAnalysis,\n extractPreview,\n trimAudio,\n extractAudioData,\n extractMelSpectrogram,\n initMelStreamingWasm,\n computeMelFrameWasm,\n MAX_DURATION_MS,\n useAudioRecorder,\n useSharedAudioRecorder,\n}\n\nexport {\n AudioExtractionError,\n mapExtractionError,\n} from './errors/AudioExtractionError'\nexport type {\n AudioExtractionErrorCode,\n AudioExtractionErrorPayload,\n} from './errors/AudioExtractionError'\n\n// Export all types\nexport type * from './AudioAnalysis/AudioAnalysis.types'\nexport type * from './AudioStudio.types'\n\n/** @deprecated Use AudioStudioModule instead */\nexport const ExpoAudioStreamModule = AudioStudioModule\n"]}
@@ -11,6 +11,12 @@ export interface DecodingConfig {
11
11
  targetBitDepth?: BitDepth;
12
12
  /** Whether to normalize audio levels (Android and Web) */
13
13
  normalizeAudio?: boolean;
14
+ /**
15
+ * RMS threshold below which a segment is flagged silent.
16
+ * Range 0..1. Default 0.01.
17
+ * Currently applied as a JS post-process so the same behavior holds across iOS/Android/Web.
18
+ */
19
+ silenceRmsThreshold?: number;
14
20
  }
15
21
  /**
16
22
  * Represents speech-related features extracted from audio.
@@ -136,6 +142,66 @@ export interface AudioRangeOptions {
136
142
  * Options for generating a quick preview of audio waveform.
137
143
  * This is optimized for UI rendering with a specified number of points.
138
144
  */
145
+ export interface PreviewBar {
146
+ /** Stable zero-based bar identifier. */
147
+ id: number;
148
+ /** Peak amplitude for this bar, normalized to 0..1. */
149
+ amplitude: number;
150
+ /** Root mean square amplitude for this bar, normalized to 0..1. */
151
+ rms: number;
152
+ /** Whether this bar is below the configured silence RMS threshold. */
153
+ silent: boolean;
154
+ /** Bar start time in milliseconds from the extracted range start. */
155
+ startTimeMs: number;
156
+ /** Bar end time in milliseconds from the extracted range start. */
157
+ endTimeMs: number;
158
+ }
159
+ /**
160
+ * Compact preview-bars result for UI waveform rendering.
161
+ * Unlike `AudioAnalysis`, this intentionally omits full `DataPoint` feature data.
162
+ */
163
+ export interface PreviewBarsResult {
164
+ bars: PreviewBar[];
165
+ durationMs: number;
166
+ sampleRate: number;
167
+ numberOfChannels: number;
168
+ bitDepth: number;
169
+ samples: number;
170
+ /** Requested bar count before native/platform clamping. */
171
+ requestedNumberOfBars: number;
172
+ /** Approximate duration represented by each bar. */
173
+ barDurationMs: number;
174
+ amplitudeRange: {
175
+ min: number;
176
+ max: number;
177
+ };
178
+ rmsRange: {
179
+ min: number;
180
+ max: number;
181
+ };
182
+ extractionTimeMs: number;
183
+ }
184
+ /**
185
+ * Options for extracting compact waveform preview bars for UI rendering.
186
+ */
187
+ export interface PreviewBarsOptions extends AudioRangeOptions {
188
+ /** URI of the audio file to analyze */
189
+ fileUri: string;
190
+ /**
191
+ * Total number of bars to generate for the preview.
192
+ * @default 100
193
+ */
194
+ numberOfBars?: number;
195
+ /** Optional logger for debugging. */
196
+ logger?: ConsoleLike;
197
+ /** Optional configuration for decoding the audio file. */
198
+ decodingOptions?: DecodingConfig;
199
+ /**
200
+ * Optional callback fired once per compact bar after extraction resolves.
201
+ * Native progressive streaming is not implied by this callback.
202
+ */
203
+ onBarReady?: (bar: PreviewBar, index: number, total: number) => void;
204
+ }
139
205
  export interface PreviewOptions extends AudioRangeOptions {
140
206
  /** URI of the audio file to analyze */
141
207
  fileUri: string;
@@ -157,6 +223,19 @@ export interface PreviewOptions extends AudioRangeOptions {
157
223
  * - normalizeAudio: false
158
224
  */
159
225
  decodingOptions?: DecodingConfig;
226
+ /**
227
+ * Optional callback fired once per data point as the preview becomes available.
228
+ * Today the native module returns the full analysis in one shot; the points are then
229
+ * micro-batched on the JS side so consumers can render bars incrementally.
230
+ * Native progressive streaming is a future enhancement.
231
+ */
232
+ onPointReady?: (point: DataPoint, index: number, total: number) => void;
233
+ /**
234
+ * Optional cancellation signal for JS-side progressive point emission.
235
+ * Aborting does not cancel native extraction after it has started, but it
236
+ * stops any queued `onPointReady` callbacks from an older request.
237
+ */
238
+ signal?: AbortSignal;
160
239
  }
161
240
  /**
162
241
  * Options for mel-spectrogram extraction
@@ -1 +1 @@
1
- {"version":3,"file":"AudioAnalysis.types.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/AudioAnalysis.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AudioAnalysis.types.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/AudioAnalysis.types.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ import { PreviewOptions, AudioAnalysis } from './AudioAnalysis.types';
5
5
  *
6
6
  * @param options - The options for the preview, including file URI and time range.
7
7
  * @returns A promise that resolves to the audio preview data.
8
+ * @throws {AudioExtractionError} when the underlying extraction fails.
8
9
  */
9
- export declare function extractPreview({ fileUri, numberOfPoints, startTimeMs, endTimeMs, // First 30 seconds
10
- decodingOptions, logger, }: PreviewOptions): Promise<AudioAnalysis>;
10
+ export declare function extractPreview({ fileUri, numberOfPoints, startTimeMs, endTimeMs, decodingOptions, logger, onPointReady, signal, }: PreviewOptions): Promise<AudioAnalysis>;
11
11
  //# sourceMappingURL=extractPreview.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extractPreview.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractPreview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAGrE;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,EACjC,OAAO,EACP,cAAoB,EACpB,WAAe,EACf,SAAiB,EAAE,mBAAmB;AACtC,eAAe,EACf,MAAM,GACT,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAgBzC"}
1
+ {"version":3,"file":"extractPreview.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractPreview.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAa,MAAM,uBAAuB,CAAA;AA8EhF;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,EACjC,OAAO,EACP,cAAoB,EACpB,WAAe,EACf,SAAiB,EACjB,eAAe,EACf,MAAM,EACN,YAAY,EACZ,MAAM,GACT,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAsCzC"}
@@ -0,0 +1,12 @@
1
+ import { PreviewBarsOptions, PreviewBarsResult } from './AudioAnalysis.types';
2
+ /**
3
+ * Extracts compact waveform preview bars for UI rendering.
4
+ *
5
+ * Native platforms may provide a compact `extractPreviewBars` bridge. Until that
6
+ * bridge is available, this safely falls back to the existing `extractPreview`
7
+ * compatibility path and adapts `DataPoint` objects into compact bars.
8
+ *
9
+ * @throws {AudioExtractionError} when the underlying extraction fails.
10
+ */
11
+ export declare function extractPreviewBars({ fileUri, numberOfBars, startTimeMs, endTimeMs, decodingOptions, logger, onBarReady, }: PreviewBarsOptions): Promise<PreviewBarsResult>;
12
+ //# sourceMappingURL=extractPreviewBars.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractPreviewBars.d.ts","sourceRoot":"","sources":["../../../src/AudioAnalysis/extractPreviewBars.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,kBAAkB,EAClB,iBAAiB,EACpB,MAAM,uBAAuB,CAAA;AAqH9B;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CAAC,EACrC,OAAO,EACP,YAAmC,EACnC,WAAe,EACf,SAAuC,EACvC,eAAe,EACf,MAAM,EACN,UAAU,GACb,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAoDjD"}