@siteed/audio-studio 3.1.0 → 3.2.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/CHANGELOG.md +30 -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/AudioStreamDecoder.kt +640 -0
  9. package/android/src/main/java/net/siteed/audiostudio/AudioStudioModule.kt +187 -13
  10. package/android/src/main/java/net/siteed/audiostudio/AudioTrimmer.kt +174 -212
  11. package/android/src/main/java/net/siteed/audiostudio/Constants.kt +4 -0
  12. package/build/cjs/AudioAnalysis/AudioAnalysis.types.js.map +1 -1
  13. package/build/cjs/AudioAnalysis/extractPreview.js +92 -15
  14. package/build/cjs/AudioAnalysis/extractPreview.js.map +1 -1
  15. package/build/cjs/AudioAnalysis/extractPreviewBars.js +134 -0
  16. package/build/cjs/AudioAnalysis/extractPreviewBars.js.map +1 -0
  17. package/build/cjs/errors/AudioExtractionError.js +127 -0
  18. package/build/cjs/errors/AudioExtractionError.js.map +1 -0
  19. package/build/cjs/errors/AudioStreamError.js +152 -0
  20. package/build/cjs/errors/AudioStreamError.js.map +1 -0
  21. package/build/cjs/errors/AudioStreamError.test.js +61 -0
  22. package/build/cjs/errors/AudioStreamError.test.js.map +1 -0
  23. package/build/cjs/index.js +12 -1
  24. package/build/cjs/index.js.map +1 -1
  25. package/build/cjs/streamAudioData.js +467 -0
  26. package/build/cjs/streamAudioData.js.map +1 -0
  27. package/build/esm/AudioAnalysis/AudioAnalysis.types.js.map +1 -1
  28. package/build/esm/AudioAnalysis/extractPreview.js +92 -15
  29. package/build/esm/AudioAnalysis/extractPreview.js.map +1 -1
  30. package/build/esm/AudioAnalysis/extractPreviewBars.js +128 -0
  31. package/build/esm/AudioAnalysis/extractPreviewBars.js.map +1 -0
  32. package/build/esm/errors/AudioExtractionError.js +122 -0
  33. package/build/esm/errors/AudioExtractionError.js.map +1 -0
  34. package/build/esm/errors/AudioStreamError.js +147 -0
  35. package/build/esm/errors/AudioStreamError.js.map +1 -0
  36. package/build/esm/errors/AudioStreamError.test.js +59 -0
  37. package/build/esm/errors/AudioStreamError.test.js.map +1 -0
  38. package/build/esm/index.js +5 -1
  39. package/build/esm/index.js.map +1 -1
  40. package/build/esm/streamAudioData.js +460 -0
  41. package/build/esm/streamAudioData.js.map +1 -0
  42. package/build/types/AudioAnalysis/AudioAnalysis.types.d.ts +79 -0
  43. package/build/types/AudioAnalysis/AudioAnalysis.types.d.ts.map +1 -1
  44. package/build/types/AudioAnalysis/extractPreview.d.ts +2 -2
  45. package/build/types/AudioAnalysis/extractPreview.d.ts.map +1 -1
  46. package/build/types/AudioAnalysis/extractPreviewBars.d.ts +12 -0
  47. package/build/types/AudioAnalysis/extractPreviewBars.d.ts.map +1 -0
  48. package/build/types/errors/AudioExtractionError.d.ts +24 -0
  49. package/build/types/errors/AudioExtractionError.d.ts.map +1 -0
  50. package/build/types/errors/AudioStreamError.d.ts +25 -0
  51. package/build/types/errors/AudioStreamError.d.ts.map +1 -0
  52. package/build/types/errors/AudioStreamError.test.d.ts +2 -0
  53. package/build/types/errors/AudioStreamError.test.d.ts.map +1 -0
  54. package/build/types/index.d.ts +8 -1
  55. package/build/types/index.d.ts.map +1 -1
  56. package/build/types/streamAudioData.d.ts +114 -0
  57. package/build/types/streamAudioData.d.ts.map +1 -0
  58. package/ios/AudioProcessingHelpers.swift +10 -5
  59. package/ios/AudioProcessor.swift +99 -0
  60. package/ios/AudioStreamDecoder.swift +523 -0
  61. package/ios/AudioStudioModule.swift +210 -3
  62. package/ios/AudioStudioTests/AudioStreamDecoderTests.swift +128 -0
  63. package/package.json +7 -7
  64. package/src/AudioAnalysis/AudioAnalysis.types.ts +82 -0
  65. package/src/AudioAnalysis/extractPreview.ts +118 -17
  66. package/src/AudioAnalysis/extractPreviewBars.ts +193 -0
  67. package/src/errors/AudioExtractionError.ts +167 -0
  68. package/src/errors/AudioStreamError.test.ts +65 -0
  69. package/src/errors/AudioStreamError.ts +185 -0
  70. package/src/index.ts +34 -0
  71. package/src/streamAudioData.ts +654 -0
@@ -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":"AAEA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAE5D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,yCAAyC;IACzC,cAAc,CAAC,EAAE,QAAQ,CAAA;IACzB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,QAAQ,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;CAMrB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IAEjC,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,GAAG,CAAC,EAAE,OAAO,CAAA;IAGb,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,OAAO,CAAA;IAGf,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,OAAO,CAAA;IACf,QAAQ,CAAC,EAAE,aAAa,CAAA;IACxB,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,OAAO,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,iBAAiB,EAAE,MAAM,CAAA;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB;;;;;;;;;;;;;OAaG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,gBAAgB,EAAE,MAAM,CAAA;IACxB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,SAAS,EAAE,CAAA;IACvB,cAAc,EAAE;QACZ,GAAG,EAAE,MAAM,CAAA;QACX,GAAG,EAAE,MAAM,CAAA;KACd,CAAA;IACD,QAAQ,EAAE;QACN,GAAG,EAAE,MAAM,CAAA;QACX,GAAG,EAAE,MAAM,CAAA;KACd,CAAA;IACD,gBAAgB,EAAE,MAAM,CAAA;IAExB,cAAc,CAAC,EAAE;QACb,cAAc,EAAE;YACZ,SAAS,EAAE,MAAM,CAAA;YACjB,SAAS,EAAE,MAAM,CAAA;SACpB,EAAE,CAAA;KAKN,CAAA;CACJ;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAC9B,iCAAiC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACvB,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAA;IACV,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAA;IACjB,mEAAmE;IACnE,GAAG,EAAE,MAAM,CAAA;IACX,sEAAsE;IACtE,MAAM,EAAE,OAAO,CAAA;IACf,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAA;IACnB,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAA;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,UAAU,EAAE,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,MAAM,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,2DAA2D;IAC3D,qBAAqB,EAAE,MAAM,CAAA;IAC7B,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAA;IACrB,cAAc,EAAE;QACZ,GAAG,EAAE,MAAM,CAAA;QACX,GAAG,EAAE,MAAM,CAAA;KACd,CAAA;IACD,QAAQ,EAAE;QACN,GAAG,EAAE,MAAM,CAAA;QACX,GAAG,EAAE,MAAM,CAAA;KACd,CAAA;IACD,gBAAgB,EAAE,MAAM,CAAA;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IACzD,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,qCAAqC;IACrC,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,0DAA0D;IAC1D,eAAe,CAAC,EAAE,cAAc,CAAA;IAChC;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACvE;AAED,MAAM,WAAW,cAAe,SAAQ,iBAAiB;IACrD,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,cAAc,CAAA;IAChC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvE;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAA;CACvB;AAED;;;;;GAKG;AACH,MAAM,WAAW,4BAA4B;IACzC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,eAAe,CAAC,EAAE,cAAc,CAAA;IAChC,6FAA6F;IAC7F,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iGAAiG;IACjG,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,WAAW,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACpC,gBAAgB,EAAE,MAAM,CAAA;IACxB,gBAAgB,EAAE,MAAM,CAAA;IACxB,eAAe,EAAE,MAAM,CAAA;IACvB,iBAAiB,EAAE,MAAM,CAAA;IACzB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,UAAU,EAAE,MAAM,EAAE,CAAA;CACvB;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC3B,WAAW,EAAE,MAAM,EAAE,EAAE,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACrB"}
@@ -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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Typed error class for audio extraction failures.
3
+ * Wraps native module errors with stable codes consumers can switch on.
4
+ */
5
+ export type AudioExtractionErrorCode = 'unsupported_codec' | 'malformed_file' | 'decode_failed' | 'permission_denied' | 'file_not_found' | 'unknown';
6
+ export interface AudioExtractionErrorPayload {
7
+ code: AudioExtractionErrorCode;
8
+ message: string;
9
+ nativeMessage?: string;
10
+ fileUri?: string;
11
+ }
12
+ export declare class AudioExtractionError extends Error {
13
+ readonly code: AudioExtractionErrorCode;
14
+ readonly nativeMessage?: string;
15
+ readonly fileUri?: string;
16
+ constructor(payload: AudioExtractionErrorPayload);
17
+ toJSON(): AudioExtractionErrorPayload;
18
+ }
19
+ /**
20
+ * Map a thrown native/JS value into an AudioExtractionError with a stable code.
21
+ * Heuristics inspect message text and known native error codes.
22
+ */
23
+ export declare function mapExtractionError(err: unknown, fileUri?: string): AudioExtractionError;
24
+ //# sourceMappingURL=AudioExtractionError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AudioExtractionError.d.ts","sourceRoot":"","sources":["../../../src/errors/AudioExtractionError.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAC9B,mBAAmB,GACnB,gBAAgB,GAChB,eAAe,GACf,mBAAmB,GACnB,gBAAgB,GAChB,SAAS,CAAA;AAEf,MAAM,WAAW,2BAA2B;IACxC,IAAI,EAAE,wBAAwB,CAAA;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,qBAAa,oBAAqB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAA;IACvC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;gBAEb,OAAO,EAAE,2BAA2B;IAQhD,MAAM,IAAI,2BAA2B;CAQxC;AAkED;;;GAGG;AACH,wBAAgB,kBAAkB,CAC9B,GAAG,EAAE,OAAO,EACZ,OAAO,CAAC,EAAE,MAAM,GACjB,oBAAoB,CAqDtB"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Stable typed errors for `streamAudioData`. Callers can switch on `code`.
3
+ */
4
+ export type AudioStreamErrorCode = 'ERR_AUDIO_STREAM_UNSUPPORTED_FORMAT' | 'ERR_AUDIO_STREAM_INVALID_RANGE' | 'ERR_AUDIO_STREAM_DECODE_FAILED' | 'ERR_AUDIO_STREAM_CANCELLED' | 'ERR_AUDIO_STREAM_PERMISSION_DENIED' | 'ERR_AUDIO_STREAM_FILE_NOT_FOUND' | 'ERR_AUDIO_STREAM_BACKPRESSURE_TIMEOUT' | 'ERR_AUDIO_STREAM_NATIVE_UNAVAILABLE' | 'ERR_AUDIO_STREAM_BUSY' | 'ERR_AUDIO_STREAM_UNKNOWN';
5
+ export interface AudioStreamErrorPayload {
6
+ code: AudioStreamErrorCode;
7
+ message: string;
8
+ recoverable: boolean;
9
+ fileUri?: string;
10
+ platform?: string;
11
+ nativeCode?: string;
12
+ nativeMessage?: string;
13
+ }
14
+ export declare class AudioStreamError extends Error {
15
+ readonly code: AudioStreamErrorCode;
16
+ readonly recoverable: boolean;
17
+ readonly fileUri?: string;
18
+ readonly platform?: string;
19
+ readonly nativeCode?: string;
20
+ readonly nativeMessage?: string;
21
+ constructor(payload: AudioStreamErrorPayload);
22
+ toJSON(): AudioStreamErrorPayload;
23
+ }
24
+ export declare function mapStreamError(err: unknown, fileUri?: string, platform?: string): AudioStreamError;
25
+ //# sourceMappingURL=AudioStreamError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AudioStreamError.d.ts","sourceRoot":"","sources":["../../../src/errors/AudioStreamError.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAC1B,qCAAqC,GACrC,gCAAgC,GAChC,gCAAgC,GAChC,4BAA4B,GAC5B,oCAAoC,GACpC,iCAAiC,GACjC,uCAAuC,GACvC,qCAAqC,GACrC,uBAAuB,GACvB,0BAA0B,CAAA;AAEhC,MAAM,WAAW,uBAAuB;IACpC,IAAI,EAAE,oBAAoB,CAAA;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,MAAM,CAAA;CACzB;AASD,qBAAa,gBAAiB,SAAQ,KAAK;IACvC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAA;IACnC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;gBAEnB,OAAO,EAAE,uBAAuB;IAW5C,MAAM,IAAI,uBAAuB;CAWpC;AAgFD,wBAAgB,cAAc,CAC1B,GAAG,EAAE,OAAO,EACZ,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,GAClB,gBAAgB,CAsClB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=AudioStreamError.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AudioStreamError.test.d.ts","sourceRoot":"","sources":["../../../src/errors/AudioStreamError.test.ts"],"names":[],"mappings":""}
@@ -5,6 +5,7 @@ import { extractPreview } from './AudioAnalysis/extractPreview';
5
5
  import { initMelStreamingWasm, computeMelFrameWasm } from './AudioAnalysis/melSpectrogramWasm';
6
6
  import { AudioRecorderProvider, useSharedAudioRecorder } from './AudioRecorder.provider';
7
7
  import AudioStudioModule from './AudioStudioModule';
8
+ import { getAudioDecodeCapabilities, streamAudioData } from './streamAudioData';
8
9
  import { trimAudio } from './trimAudio';
9
10
  import { useAudioRecorder } from './useAudioRecorder';
10
11
  export * from './utils/convertPCMToFloat32';
@@ -14,7 +15,13 @@ export { getPlatformCapabilities, isEncodingSupported, isBitDepthSupported, getF
14
15
  export { AudioDeviceManager, audioDeviceManager } from './AudioDeviceManager';
15
16
  export { useAudioDevices } from './hooks/useAudioDevices';
16
17
  export { setMelSpectrogramWasmUrl } from './AudioAnalysis/wasmConfig';
17
- export { AudioRecorderProvider, AudioStudioModule, extractRawWavAnalysis, extractAudioAnalysis, extractPreview, trimAudio, extractAudioData, extractMelSpectrogram, initMelStreamingWasm, computeMelFrameWasm, MAX_DURATION_MS, useAudioRecorder, useSharedAudioRecorder, };
18
+ export { extractPreviewBars } from './AudioAnalysis/extractPreviewBars';
19
+ export { AudioRecorderProvider, AudioStudioModule, extractRawWavAnalysis, extractAudioAnalysis, extractPreview, trimAudio, extractAudioData, streamAudioData, getAudioDecodeCapabilities, extractMelSpectrogram, initMelStreamingWasm, computeMelFrameWasm, MAX_DURATION_MS, useAudioRecorder, useSharedAudioRecorder, };
20
+ export { AudioExtractionError, mapExtractionError, } from './errors/AudioExtractionError';
21
+ export type { AudioExtractionErrorCode, AudioExtractionErrorPayload, } from './errors/AudioExtractionError';
22
+ export { AudioStreamError, mapStreamError, } from './errors/AudioStreamError';
23
+ export type { AudioStreamErrorCode, AudioStreamErrorPayload, } from './errors/AudioStreamError';
24
+ export type { StreamAudioDataOptions, StreamAudioDataChunk, StreamAudioDataProgress, StreamAudioDataResult, StreamAudioDataCallbacks, AudioDecodeCapabilities, } from './streamAudioData';
18
25
  export type * from './AudioAnalysis/AudioAnalysis.types';
19
26
  export type * from './AudioStudio.types';
20
27
  /** @deprecated Use AudioStudioModule instead */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,qBAAqB,EACrB,oBAAoB,EACvB,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,EACH,qBAAqB,EACrB,eAAe,EAClB,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EACH,oBAAoB,EACpB,mBAAmB,EACtB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EACH,qBAAqB,EACrB,sBAAsB,EACzB,MAAM,0BAA0B,CAAA;AACjC,OAAO,iBAAiB,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAErD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AAGtC,OAAO,EACH,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,EACvB,KAAK,oBAAoB,GAC5B,MAAM,iCAAiC,CAAA;AAGxC,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAG7E,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAEzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AAErE,OAAO,EACH,qBAAqB,EACrB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,cAAc,EACd,SAAS,EACT,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,sBAAsB,GACzB,CAAA;AAGD,mBAAmB,qCAAqC,CAAA;AACxD,mBAAmB,qBAAqB,CAAA;AAExC,gDAAgD;AAChD,eAAO,MAAM,qBAAqB,KAAoB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,qBAAqB,EACrB,oBAAoB,EACvB,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,EACH,qBAAqB,EACrB,eAAe,EAClB,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EACH,oBAAoB,EACpB,mBAAmB,EACtB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EACH,qBAAqB,EACrB,sBAAsB,EACzB,MAAM,0BAA0B,CAAA;AACjC,OAAO,iBAAiB,MAAM,qBAAqB,CAAA;AACnD,OAAO,EACH,0BAA0B,EAC1B,eAAe,EAClB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAErD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AAGtC,OAAO,EACH,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,EACvB,KAAK,oBAAoB,GAC5B,MAAM,iCAAiC,CAAA;AAGxC,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAG7E,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAEzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;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,eAAe,EACf,0BAA0B,EAC1B,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,sBAAsB,GACzB,CAAA;AAED,OAAO,EACH,oBAAoB,EACpB,kBAAkB,GACrB,MAAM,+BAA+B,CAAA;AACtC,YAAY,EACR,wBAAwB,EACxB,2BAA2B,GAC9B,MAAM,+BAA+B,CAAA;AAEtC,OAAO,EACH,gBAAgB,EAChB,cAAc,GACjB,MAAM,2BAA2B,CAAA;AAClC,YAAY,EACR,oBAAoB,EACpB,uBAAuB,GAC1B,MAAM,2BAA2B,CAAA;AAElC,YAAY,EACR,sBAAsB,EACtB,oBAAoB,EACpB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,GAC1B,MAAM,mBAAmB,CAAA;AAG1B,mBAAmB,qCAAqC,CAAA;AACxD,mBAAmB,qBAAqB,CAAA;AAExC,gDAAgD;AAChD,eAAO,MAAM,qBAAqB,KAAoB,CAAA"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * High-level API: stream decoded audio from a stored file as bounded Float32
3
+ * chunks without materializing the full PCM range in memory.
4
+ *
5
+ * See `docs/STREAM_AUDIO_DATA.md` for the full contract and rollout notes.
6
+ */
7
+ export interface StreamAudioDataOptions {
8
+ /** URI of the audio file to decode. */
9
+ fileUri: string;
10
+ /** Start time in milliseconds (default: 0). */
11
+ startTimeMs?: number;
12
+ /** End time in milliseconds (default: end-of-file). */
13
+ endTimeMs?: number;
14
+ /**
15
+ * Source sample rate hint. Ignored if `targetSampleRate` is set; native
16
+ * decoders read the actual rate from the file.
17
+ */
18
+ sampleRate?: number;
19
+ /** Output sample rate. Native resamples when this differs from the file. */
20
+ targetSampleRate?: number;
21
+ /** Output channel count (1 = mono downmix, 2 = stereo passthrough). */
22
+ channels?: number;
23
+ /** Clamp samples to [-1, 1] and replace non-finite values with 0. */
24
+ normalizeAudio?: boolean;
25
+ /** Target chunk duration in ms (default: 1000, min: 10, max: 60000). */
26
+ chunkDurationMs?: number;
27
+ /** Soft cap on chunk size in bytes (Float32 = 4 bytes/sample). */
28
+ maxChunkBytes?: number;
29
+ /** Max chunks queued in native before JS ack pauses decode (default: 4). */
30
+ maxBufferedChunks?: number;
31
+ /** Output PCM format; only `'float32'` supported today. */
32
+ streamFormat?: 'float32';
33
+ /** Abort the in-flight request. Resolves promise with `cancelled: true`. */
34
+ signal?: AbortSignal;
35
+ }
36
+ export interface StreamAudioDataChunk {
37
+ /** Native request id; constant across all chunks of one call. */
38
+ requestId: string;
39
+ /** Zero-based monotonic chunk index. */
40
+ chunkIndex: number;
41
+ /** Start time in output-rate ms (rounded to nearest sample). */
42
+ startTimeMs: number;
43
+ /** End time in output-rate ms. */
44
+ endTimeMs: number;
45
+ /** Duration in ms (`endTimeMs - startTimeMs`). */
46
+ durationMs: number;
47
+ /** First sample index in the output timeline. */
48
+ startSample: number;
49
+ /** Sample count in `samples` (interleaved if channels > 1). */
50
+ sampleCount: number;
51
+ /** Output sample rate. */
52
+ sampleRate: number;
53
+ /** Output channel count. */
54
+ channels: number;
55
+ /** Interleaved Float32 samples in [-1, 1]. */
56
+ samples: Float32Array;
57
+ /** True for the last chunk of a non-cancelled run. */
58
+ isFinal: boolean;
59
+ }
60
+ export interface StreamAudioDataProgress {
61
+ requestId: string;
62
+ processedMs: number;
63
+ durationMs: number;
64
+ progress: number;
65
+ emittedChunks: number;
66
+ bufferedChunks?: number;
67
+ }
68
+ export interface StreamAudioDataResult {
69
+ requestId: string;
70
+ durationMs: number;
71
+ sampleRate: number;
72
+ channels: number;
73
+ chunks: number;
74
+ samples: number;
75
+ cancelled: boolean;
76
+ }
77
+ export interface StreamAudioDataCallbacks {
78
+ /**
79
+ * Called with each decoded chunk. If this returns a Promise, native decode
80
+ * pauses until it resolves (backpressure). Throwing aborts the stream with
81
+ * `ERR_AUDIO_STREAM_DECODE_FAILED`.
82
+ */
83
+ onChunk: (chunk: StreamAudioDataChunk) => void | Promise<void>;
84
+ /** Called whenever native reports progress. */
85
+ onProgress?: (progress: StreamAudioDataProgress) => void;
86
+ }
87
+ export interface AudioDecodeCapabilities {
88
+ platform: 'ios' | 'android' | 'web';
89
+ supportedInputFormats: string[];
90
+ supportedOutputFormats: Array<'float32'>;
91
+ supportsCancellation: boolean;
92
+ supportsBackpressure: boolean;
93
+ supportsTimeRange: boolean;
94
+ supportsTargetSampleRate: boolean;
95
+ supportsChannelMixing: boolean;
96
+ knownLimitations?: string[];
97
+ }
98
+ /**
99
+ * Stream decoded audio from a stored file as bounded Float32 PCM chunks.
100
+ *
101
+ * Memory bound:
102
+ * `chunkDurationMs * sampleRate * channels * 4 * maxBufferedChunks` +
103
+ * native decoder buffers.
104
+ *
105
+ * Cancellation: pass `options.signal` and call `abort()`. The returned promise
106
+ * resolves with `cancelled: true` (it does not reject) when cancellation wins.
107
+ *
108
+ * Backpressure: if `onChunk` returns a Promise, native decode is paused until
109
+ * it resolves; if it throws, the stream is aborted with a `decode_failed` error.
110
+ */
111
+ export declare function streamAudioData(options: StreamAudioDataOptions, callbacks: StreamAudioDataCallbacks): Promise<StreamAudioDataResult>;
112
+ /** Discover what the running platform supports. */
113
+ export declare function getAudioDecodeCapabilities(): Promise<AudioDecodeCapabilities>;
114
+ //# sourceMappingURL=streamAudioData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streamAudioData.d.ts","sourceRoot":"","sources":["../../src/streamAudioData.ts"],"names":[],"mappings":"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"}
@@ -681,15 +681,20 @@ func extractRawAudioData(
681
681
  for channel in 0..<channels {
682
682
  let sample = floatData[channel][frame]
683
683
 
684
- let normalizedSample = decodingConfig.normalizeAudio ?
685
- max(-1.0, min(1.0, sample)) : sample
686
-
684
+ // Sanitize: replace NaN/Inf with 0 then clamp. Skip clamp when
685
+ // normalizeAudio=false so callers see the raw decoded magnitude,
686
+ // but always finite-check to avoid Swift's `Int16(_:)` /
687
+ // `Int32(_:)` trap on non-finite values.
688
+ let safeSample: Float = sample.isFinite ? sample : 0
689
+ let normalizedSample = decodingConfig.normalizeAudio ?
690
+ max(-1.0, min(1.0, safeSample)) : safeSample
691
+
687
692
  switch targetBitDepth {
688
693
  case 16:
689
- let intValue = Int16(normalizedSample * Float(Int16.max))
694
+ let intValue = safeFloatToInt16(normalizedSample)
690
695
  pcmData.append(contentsOf: withUnsafeBytes(of: intValue) { Array($0) })
691
696
  case 32:
692
- let intValue = Int32(normalizedSample * Float(Int32.max))
697
+ let intValue = safeFloatToInt32(normalizedSample)
693
698
  pcmData.append(contentsOf: withUnsafeBytes(of: intValue) { Array($0) })
694
699
  default:
695
700
  throw NSError(domain: "AudioProcessing", code: -1, userInfo: [NSLocalizedDescriptionKey: "Unsupported bit depth \(targetBitDepth)"])
@@ -1022,6 +1022,105 @@ public class AudioProcessor {
1022
1022
  /// - endTimeMs: Optional end time in milliseconds
1023
1023
  /// - featureOptions: The features to extract
1024
1024
  /// - Returns: An `AudioAnalysisData` object containing the extracted features
1025
+ public func extractPreviewBars(
1026
+ numberOfBars: Int,
1027
+ startTimeMs: Double? = nil,
1028
+ endTimeMs: Double? = nil,
1029
+ silenceRmsThreshold: Float = 0.01
1030
+ ) -> [String: Any]? {
1031
+ guard let audioFile = audioFile else {
1032
+ reject("FILE_NOT_INITIALIZED", "Audio file is not initialized.")
1033
+ return nil
1034
+ }
1035
+
1036
+ let requestedBars = max(1, numberOfBars)
1037
+ let sampleRate = audioFile.fileFormat.sampleRate
1038
+ let totalDurationMs = Double(audioFile.length) / sampleRate * 1000
1039
+ let effectiveStartMs = max(0, startTimeMs ?? 0)
1040
+ let effectiveEndMs = min(endTimeMs ?? totalDurationMs, totalDurationMs)
1041
+ let durationMs = max(1, effectiveEndMs - effectiveStartMs)
1042
+ let startFrame = AVAudioFramePosition(effectiveStartMs * sampleRate / 1000.0)
1043
+ let endFrame = AVAudioFramePosition(effectiveEndMs * sampleRate / 1000.0)
1044
+ let samplesInRange = Int(endFrame - startFrame)
1045
+
1046
+ guard samplesInRange > 0 else {
1047
+ reject("INVALID_RANGE", "Invalid sample range: contains no samples")
1048
+ return nil
1049
+ }
1050
+
1051
+ let framesPerBar = max(1, samplesInRange / requestedBars)
1052
+ let startTime = CACurrentMediaTime()
1053
+ var bars: [[String: Any]] = []
1054
+ bars.reserveCapacity(requestedBars)
1055
+ var minAmplitude: Float = .greatestFiniteMagnitude
1056
+ var maxAmplitude: Float = -.greatestFiniteMagnitude
1057
+ var minRms: Float = .greatestFiniteMagnitude
1058
+ var maxRms: Float = -.greatestFiniteMagnitude
1059
+
1060
+ for index in 0..<requestedBars {
1061
+ let barStartFrame = startFrame + AVAudioFramePosition(index * framesPerBar)
1062
+ let barEndFrame = min(startFrame + AVAudioFramePosition((index + 1) * framesPerBar), endFrame)
1063
+ let framesToRead = AVAudioFrameCount(barEndFrame - barStartFrame)
1064
+ if framesToRead == 0 { break }
1065
+
1066
+ do {
1067
+ audioFile.framePosition = barStartFrame
1068
+ guard let buffer = AVAudioPCMBuffer(pcmFormat: audioFile.processingFormat, frameCapacity: framesToRead) else { continue }
1069
+ try audioFile.read(into: buffer, frameCount: framesToRead)
1070
+ guard let floatData = buffer.floatChannelData else { continue }
1071
+
1072
+ var sumSquares: Float = 0
1073
+ var amplitude: Float = 0
1074
+ for frame in 0..<Int(buffer.frameLength) {
1075
+ let value = floatData[0][frame]
1076
+ sumSquares += value * value
1077
+ amplitude = max(amplitude, abs(value))
1078
+ }
1079
+ let frameLength = max(1, Int(buffer.frameLength))
1080
+ let rms = sqrt(sumSquares / Float(frameLength))
1081
+ minAmplitude = min(minAmplitude, amplitude)
1082
+ maxAmplitude = max(maxAmplitude, amplitude)
1083
+ minRms = min(minRms, rms)
1084
+ maxRms = max(maxRms, rms)
1085
+
1086
+ let startBarTimeMs = Double(barStartFrame - startFrame) / Double(samplesInRange) * durationMs
1087
+ let endBarTimeMs = Double(barEndFrame - startFrame) / Double(samplesInRange) * durationMs
1088
+ bars.append([
1089
+ "id": index,
1090
+ "amplitude": min(max(amplitude, 0), 1),
1091
+ "rms": min(max(rms, 0), 1),
1092
+ "silent": rms < silenceRmsThreshold,
1093
+ "startTimeMs": startBarTimeMs,
1094
+ "endTimeMs": max(startBarTimeMs, endBarTimeMs)
1095
+ ])
1096
+ } catch {
1097
+ reject("AUDIO_READ_ERROR", "Error reading audio data: \(error.localizedDescription)")
1098
+ return nil
1099
+ }
1100
+ }
1101
+
1102
+ guard !bars.isEmpty else {
1103
+ reject("PROCESSING_ERROR", "No preview bars were generated")
1104
+ return nil
1105
+ }
1106
+
1107
+ let bitDepth = audioFile.fileFormat.settings[AVLinearPCMBitDepthKey] as? Int ?? 16
1108
+ let extractionTimeMs = Float((CACurrentMediaTime() - startTime) * 1000)
1109
+ return [
1110
+ "bars": bars,
1111
+ "durationMs": durationMs,
1112
+ "sampleRate": Int(sampleRate),
1113
+ "numberOfChannels": Int(audioFile.processingFormat.channelCount),
1114
+ "bitDepth": bitDepth,
1115
+ "samples": samplesInRange,
1116
+ "requestedNumberOfBars": requestedBars,
1117
+ "barDurationMs": durationMs / Double(bars.count),
1118
+ "amplitudeRange": ["min": minAmplitude, "max": maxAmplitude],
1119
+ "rmsRange": ["min": minRms, "max": maxRms],
1120
+ "extractionTimeMs": extractionTimeMs
1121
+ ]
1122
+ }
1123
+
1025
1124
  public func extractPreview(
1026
1125
  numberOfPoints: Int,
1027
1126
  startTimeMs: Double? = nil,