@siteed/expo-audio-studio 2.18.5 → 3.0.0

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 (329) hide show
  1. package/README.md +13 -297
  2. package/index.d.ts +1 -0
  3. package/index.js +1 -0
  4. package/package.json +6 -135
  5. package/CHANGELOG.md +0 -493
  6. package/LICENSE +0 -21
  7. package/android/build.gradle +0 -129
  8. package/android/src/androidTest/assets/chorus.wav +0 -0
  9. package/android/src/androidTest/assets/jfk.wav +0 -0
  10. package/android/src/androidTest/assets/osr_us_000_0010_8k.wav +0 -0
  11. package/android/src/androidTest/assets/recorder_hello_world.wav +0 -0
  12. package/android/src/androidTest/java/net/siteed/audiostream/AudioProcessorInstrumentedTest.kt +0 -197
  13. package/android/src/androidTest/java/net/siteed/audiostream/AudioRecorderInstrumentedTest.kt +0 -541
  14. package/android/src/androidTest/java/net/siteed/audiostream/AudioRecorderPerformanceInstrumentedTest.kt +0 -234
  15. package/android/src/androidTest/java/net/siteed/audiostream/integration/AudioFocusStrategyIntegrationTest.kt +0 -332
  16. package/android/src/androidTest/java/net/siteed/audiostream/integration/BufferDurationIntegrationTest.kt +0 -324
  17. package/android/src/androidTest/java/net/siteed/audiostream/integration/CompressedOnlyOutputTest.kt +0 -253
  18. package/android/src/androidTest/java/net/siteed/audiostream/integration/DeviceDisconnectionFallbackTest.kt +0 -218
  19. package/android/src/androidTest/java/net/siteed/audiostream/integration/EventEmissionIntervalTest.kt +0 -120
  20. package/android/src/androidTest/java/net/siteed/audiostream/integration/M4aFormatTest.kt +0 -345
  21. package/android/src/androidTest/java/net/siteed/audiostream/integration/OutputControlIntegrationTest.kt +0 -340
  22. package/android/src/androidTest/java/net/siteed/audiostream/integration/PcmStreamingDurationTest.kt +0 -252
  23. package/android/src/androidTest/java/net/siteed/audiostream/integration/README.md +0 -95
  24. package/android/src/androidTest/java/net/siteed/audiostream/integration/run_integration_tests.sh +0 -43
  25. package/android/src/main/AndroidManifest.xml +0 -30
  26. package/android/src/main/java/net/siteed/audiostream/AudioAnalysisData.kt +0 -188
  27. package/android/src/main/java/net/siteed/audiostream/AudioDataEncoder.kt +0 -9
  28. package/android/src/main/java/net/siteed/audiostream/AudioDeviceManager.kt +0 -1741
  29. package/android/src/main/java/net/siteed/audiostream/AudioFileHandler.kt +0 -136
  30. package/android/src/main/java/net/siteed/audiostream/AudioFormatUtils.kt +0 -354
  31. package/android/src/main/java/net/siteed/audiostream/AudioNotificationsManager.kt +0 -439
  32. package/android/src/main/java/net/siteed/audiostream/AudioProcessor.kt +0 -2237
  33. package/android/src/main/java/net/siteed/audiostream/AudioRecorderManager.kt +0 -2141
  34. package/android/src/main/java/net/siteed/audiostream/AudioRecordingService.kt +0 -167
  35. package/android/src/main/java/net/siteed/audiostream/AudioTrimmer.kt +0 -1099
  36. package/android/src/main/java/net/siteed/audiostream/Constants.kt +0 -37
  37. package/android/src/main/java/net/siteed/audiostream/EventSender.kt +0 -7
  38. package/android/src/main/java/net/siteed/audiostream/ExpoAudioStreamModule.kt +0 -1113
  39. package/android/src/main/java/net/siteed/audiostream/FFT.kt +0 -99
  40. package/android/src/main/java/net/siteed/audiostream/Features.kt +0 -98
  41. package/android/src/main/java/net/siteed/audiostream/LogUtils.kt +0 -93
  42. package/android/src/main/java/net/siteed/audiostream/NotificationConfig.kt +0 -72
  43. package/android/src/main/java/net/siteed/audiostream/PermissionUtils.kt +0 -68
  44. package/android/src/main/java/net/siteed/audiostream/RecordingActionReceiver.kt +0 -59
  45. package/android/src/main/java/net/siteed/audiostream/RecordingConfig.kt +0 -257
  46. package/android/src/main/java/net/siteed/audiostream/WaveformConfig.kt +0 -19
  47. package/android/src/main/java/net/siteed/audiostream/WaveformRenderer.kt +0 -159
  48. package/android/src/main/res/drawable/ic_default_action_icon.xml +0 -16
  49. package/android/src/main/res/drawable/ic_microphone.xml +0 -13
  50. package/android/src/main/res/drawable/ic_pause.xml +0 -10
  51. package/android/src/main/res/drawable/ic_play.xml +0 -10
  52. package/android/src/main/res/drawable/ic_stop.xml +0 -10
  53. package/android/src/main/res/layout/notification_recording.xml +0 -37
  54. package/android/src/test/java/net/siteed/audiostream/AudioFileHandlerTest.kt +0 -279
  55. package/android/src/test/java/net/siteed/audiostream/AudioFocusStrategyTest.kt +0 -249
  56. package/android/src/test/java/net/siteed/audiostream/AudioFormatTest.kt +0 -151
  57. package/android/src/test/java/net/siteed/audiostream/AudioFormatUtilsTest.kt +0 -273
  58. package/android/src/test/java/net/siteed/audiostream/DeviceDisconnectionFallbackUnitTest.kt +0 -140
  59. package/android/src/test/resources/chorus.wav +0 -0
  60. package/android/src/test/resources/generate_test_audio.py +0 -94
  61. package/android/src/test/resources/jfk.wav +0 -0
  62. package/android/src/test/resources/osr_us_000_0010_8k.wav +0 -0
  63. package/android/src/test/resources/recorder_hello_world.wav +0 -0
  64. package/app.plugin.js +0 -3
  65. package/build/cjs/AudioAnalysis/AudioAnalysis.types.js +0 -4
  66. package/build/cjs/AudioAnalysis/AudioAnalysis.types.js.map +0 -1
  67. package/build/cjs/AudioAnalysis/extractAudioAnalysis.js +0 -210
  68. package/build/cjs/AudioAnalysis/extractAudioAnalysis.js.map +0 -1
  69. package/build/cjs/AudioAnalysis/extractAudioData.js +0 -21
  70. package/build/cjs/AudioAnalysis/extractAudioData.js.map +0 -1
  71. package/build/cjs/AudioAnalysis/extractMelSpectrogram.js +0 -92
  72. package/build/cjs/AudioAnalysis/extractMelSpectrogram.js.map +0 -1
  73. package/build/cjs/AudioAnalysis/extractPreview.js +0 -28
  74. package/build/cjs/AudioAnalysis/extractPreview.js.map +0 -1
  75. package/build/cjs/AudioAnalysis/extractWaveform.js +0 -18
  76. package/build/cjs/AudioAnalysis/extractWaveform.js.map +0 -1
  77. package/build/cjs/AudioDeviceManager.js +0 -689
  78. package/build/cjs/AudioDeviceManager.js.map +0 -1
  79. package/build/cjs/AudioRecorder.provider.js +0 -78
  80. package/build/cjs/AudioRecorder.provider.js.map +0 -1
  81. package/build/cjs/ExpoAudioStream.native.js +0 -8
  82. package/build/cjs/ExpoAudioStream.native.js.map +0 -1
  83. package/build/cjs/ExpoAudioStream.types.js +0 -11
  84. package/build/cjs/ExpoAudioStream.types.js.map +0 -1
  85. package/build/cjs/ExpoAudioStream.web.js +0 -708
  86. package/build/cjs/ExpoAudioStream.web.js.map +0 -1
  87. package/build/cjs/ExpoAudioStreamModule.js +0 -718
  88. package/build/cjs/ExpoAudioStreamModule.js.map +0 -1
  89. package/build/cjs/WebRecorder.web.js +0 -777
  90. package/build/cjs/WebRecorder.web.js.map +0 -1
  91. package/build/cjs/constants/platformLimitations.js +0 -99
  92. package/build/cjs/constants/platformLimitations.js.map +0 -1
  93. package/build/cjs/constants.js +0 -17
  94. package/build/cjs/constants.js.map +0 -1
  95. package/build/cjs/events.js +0 -29
  96. package/build/cjs/events.js.map +0 -1
  97. package/build/cjs/hooks/useAudioDevices.js +0 -179
  98. package/build/cjs/hooks/useAudioDevices.js.map +0 -1
  99. package/build/cjs/index.js +0 -58
  100. package/build/cjs/index.js.map +0 -1
  101. package/build/cjs/trimAudio.js +0 -76
  102. package/build/cjs/trimAudio.js.map +0 -1
  103. package/build/cjs/useAudioRecorder.js +0 -518
  104. package/build/cjs/useAudioRecorder.js.map +0 -1
  105. package/build/cjs/utils/BlobFix.js +0 -502
  106. package/build/cjs/utils/BlobFix.js.map +0 -1
  107. package/build/cjs/utils/audioProcessing.js +0 -136
  108. package/build/cjs/utils/audioProcessing.js.map +0 -1
  109. package/build/cjs/utils/cleanNativeOptions.js +0 -22
  110. package/build/cjs/utils/cleanNativeOptions.js.map +0 -1
  111. package/build/cjs/utils/concatenateBuffers.js +0 -25
  112. package/build/cjs/utils/concatenateBuffers.js.map +0 -1
  113. package/build/cjs/utils/convertPCMToFloat32.js +0 -124
  114. package/build/cjs/utils/convertPCMToFloat32.js.map +0 -1
  115. package/build/cjs/utils/crc32.js +0 -52
  116. package/build/cjs/utils/crc32.js.map +0 -1
  117. package/build/cjs/utils/encodingToBitDepth.js +0 -17
  118. package/build/cjs/utils/encodingToBitDepth.js.map +0 -1
  119. package/build/cjs/utils/getWavFileInfo.js +0 -96
  120. package/build/cjs/utils/getWavFileInfo.js.map +0 -1
  121. package/build/cjs/utils/writeWavHeader.js +0 -88
  122. package/build/cjs/utils/writeWavHeader.js.map +0 -1
  123. package/build/cjs/workers/InlineFeaturesExtractor.web.js +0 -859
  124. package/build/cjs/workers/InlineFeaturesExtractor.web.js.map +0 -1
  125. package/build/cjs/workers/inlineAudioWebWorker.web.js +0 -184
  126. package/build/cjs/workers/inlineAudioWebWorker.web.js.map +0 -1
  127. package/build/esm/AudioAnalysis/AudioAnalysis.types.js +0 -3
  128. package/build/esm/AudioAnalysis/AudioAnalysis.types.js.map +0 -1
  129. package/build/esm/AudioAnalysis/extractAudioAnalysis.js +0 -202
  130. package/build/esm/AudioAnalysis/extractAudioAnalysis.js.map +0 -1
  131. package/build/esm/AudioAnalysis/extractAudioData.js +0 -14
  132. package/build/esm/AudioAnalysis/extractAudioData.js.map +0 -1
  133. package/build/esm/AudioAnalysis/extractMelSpectrogram.js +0 -89
  134. package/build/esm/AudioAnalysis/extractMelSpectrogram.js.map +0 -1
  135. package/build/esm/AudioAnalysis/extractPreview.js +0 -25
  136. package/build/esm/AudioAnalysis/extractPreview.js.map +0 -1
  137. package/build/esm/AudioAnalysis/extractWaveform.js +0 -11
  138. package/build/esm/AudioAnalysis/extractWaveform.js.map +0 -1
  139. package/build/esm/AudioDeviceManager.js +0 -682
  140. package/build/esm/AudioDeviceManager.js.map +0 -1
  141. package/build/esm/AudioRecorder.provider.js +0 -40
  142. package/build/esm/AudioRecorder.provider.js.map +0 -1
  143. package/build/esm/ExpoAudioStream.native.js +0 -6
  144. package/build/esm/ExpoAudioStream.native.js.map +0 -1
  145. package/build/esm/ExpoAudioStream.types.js +0 -8
  146. package/build/esm/ExpoAudioStream.types.js.map +0 -1
  147. package/build/esm/ExpoAudioStream.web.js +0 -704
  148. package/build/esm/ExpoAudioStream.web.js.map +0 -1
  149. package/build/esm/ExpoAudioStreamModule.js +0 -713
  150. package/build/esm/ExpoAudioStreamModule.js.map +0 -1
  151. package/build/esm/WebRecorder.web.js +0 -773
  152. package/build/esm/WebRecorder.web.js.map +0 -1
  153. package/build/esm/constants/platformLimitations.js +0 -90
  154. package/build/esm/constants/platformLimitations.js.map +0 -1
  155. package/build/esm/constants.js +0 -14
  156. package/build/esm/constants.js.map +0 -1
  157. package/build/esm/events.js +0 -21
  158. package/build/esm/events.js.map +0 -1
  159. package/build/esm/hooks/useAudioDevices.js +0 -176
  160. package/build/esm/hooks/useAudioDevices.js.map +0 -1
  161. package/build/esm/index.js +0 -20
  162. package/build/esm/index.js.map +0 -1
  163. package/build/esm/trimAudio.js +0 -69
  164. package/build/esm/trimAudio.js.map +0 -1
  165. package/build/esm/useAudioRecorder.js +0 -512
  166. package/build/esm/useAudioRecorder.js.map +0 -1
  167. package/build/esm/utils/BlobFix.js +0 -498
  168. package/build/esm/utils/BlobFix.js.map +0 -1
  169. package/build/esm/utils/audioProcessing.js +0 -133
  170. package/build/esm/utils/audioProcessing.js.map +0 -1
  171. package/build/esm/utils/cleanNativeOptions.js +0 -19
  172. package/build/esm/utils/cleanNativeOptions.js.map +0 -1
  173. package/build/esm/utils/concatenateBuffers.js +0 -21
  174. package/build/esm/utils/concatenateBuffers.js.map +0 -1
  175. package/build/esm/utils/convertPCMToFloat32.js +0 -120
  176. package/build/esm/utils/convertPCMToFloat32.js.map +0 -1
  177. package/build/esm/utils/crc32.js +0 -50
  178. package/build/esm/utils/crc32.js.map +0 -1
  179. package/build/esm/utils/encodingToBitDepth.js +0 -13
  180. package/build/esm/utils/encodingToBitDepth.js.map +0 -1
  181. package/build/esm/utils/getWavFileInfo.js +0 -92
  182. package/build/esm/utils/getWavFileInfo.js.map +0 -1
  183. package/build/esm/utils/writeWavHeader.js +0 -84
  184. package/build/esm/utils/writeWavHeader.js.map +0 -1
  185. package/build/esm/workers/InlineFeaturesExtractor.web.js +0 -856
  186. package/build/esm/workers/InlineFeaturesExtractor.web.js.map +0 -1
  187. package/build/esm/workers/inlineAudioWebWorker.web.js +0 -181
  188. package/build/esm/workers/inlineAudioWebWorker.web.js.map +0 -1
  189. package/build/types/AudioAnalysis/AudioAnalysis.types.d.ts +0 -196
  190. package/build/types/AudioAnalysis/AudioAnalysis.types.d.ts.map +0 -1
  191. package/build/types/AudioAnalysis/extractAudioAnalysis.d.ts +0 -74
  192. package/build/types/AudioAnalysis/extractAudioAnalysis.d.ts.map +0 -1
  193. package/build/types/AudioAnalysis/extractAudioData.d.ts +0 -3
  194. package/build/types/AudioAnalysis/extractAudioData.d.ts.map +0 -1
  195. package/build/types/AudioAnalysis/extractMelSpectrogram.d.ts +0 -14
  196. package/build/types/AudioAnalysis/extractMelSpectrogram.d.ts.map +0 -1
  197. package/build/types/AudioAnalysis/extractPreview.d.ts +0 -11
  198. package/build/types/AudioAnalysis/extractPreview.d.ts.map +0 -1
  199. package/build/types/AudioAnalysis/extractWaveform.d.ts +0 -8
  200. package/build/types/AudioAnalysis/extractWaveform.d.ts.map +0 -1
  201. package/build/types/AudioDeviceManager.d.ts +0 -187
  202. package/build/types/AudioDeviceManager.d.ts.map +0 -1
  203. package/build/types/AudioRecorder.provider.d.ts +0 -11
  204. package/build/types/AudioRecorder.provider.d.ts.map +0 -1
  205. package/build/types/ExpoAudioStream.native.d.ts +0 -3
  206. package/build/types/ExpoAudioStream.native.d.ts.map +0 -1
  207. package/build/types/ExpoAudioStream.types.d.ts +0 -738
  208. package/build/types/ExpoAudioStream.types.d.ts.map +0 -1
  209. package/build/types/ExpoAudioStream.web.d.ts +0 -96
  210. package/build/types/ExpoAudioStream.web.d.ts.map +0 -1
  211. package/build/types/ExpoAudioStreamModule.d.ts +0 -3
  212. package/build/types/ExpoAudioStreamModule.d.ts.map +0 -1
  213. package/build/types/WebRecorder.web.d.ts +0 -198
  214. package/build/types/WebRecorder.web.d.ts.map +0 -1
  215. package/build/types/constants/platformLimitations.d.ts +0 -40
  216. package/build/types/constants/platformLimitations.d.ts.map +0 -1
  217. package/build/types/constants.d.ts +0 -11
  218. package/build/types/constants.d.ts.map +0 -1
  219. package/build/types/events.d.ts +0 -26
  220. package/build/types/events.d.ts.map +0 -1
  221. package/build/types/hooks/useAudioDevices.d.ts +0 -15
  222. package/build/types/hooks/useAudioDevices.d.ts.map +0 -1
  223. package/build/types/index.d.ts +0 -18
  224. package/build/types/index.d.ts.map +0 -1
  225. package/build/types/trimAudio.d.ts +0 -25
  226. package/build/types/trimAudio.d.ts.map +0 -1
  227. package/build/types/useAudioRecorder.d.ts +0 -22
  228. package/build/types/useAudioRecorder.d.ts.map +0 -1
  229. package/build/types/utils/BlobFix.d.ts +0 -9
  230. package/build/types/utils/BlobFix.d.ts.map +0 -1
  231. package/build/types/utils/audioProcessing.d.ts +0 -24
  232. package/build/types/utils/audioProcessing.d.ts.map +0 -1
  233. package/build/types/utils/cleanNativeOptions.d.ts +0 -15
  234. package/build/types/utils/cleanNativeOptions.d.ts.map +0 -1
  235. package/build/types/utils/concatenateBuffers.d.ts +0 -8
  236. package/build/types/utils/concatenateBuffers.d.ts.map +0 -1
  237. package/build/types/utils/convertPCMToFloat32.d.ts +0 -13
  238. package/build/types/utils/convertPCMToFloat32.d.ts.map +0 -1
  239. package/build/types/utils/crc32.d.ts +0 -7
  240. package/build/types/utils/crc32.d.ts.map +0 -1
  241. package/build/types/utils/encodingToBitDepth.d.ts +0 -5
  242. package/build/types/utils/encodingToBitDepth.d.ts.map +0 -1
  243. package/build/types/utils/getWavFileInfo.d.ts +0 -26
  244. package/build/types/utils/getWavFileInfo.d.ts.map +0 -1
  245. package/build/types/utils/writeWavHeader.d.ts +0 -34
  246. package/build/types/utils/writeWavHeader.d.ts.map +0 -1
  247. package/build/types/workers/InlineFeaturesExtractor.web.d.ts +0 -2
  248. package/build/types/workers/InlineFeaturesExtractor.web.d.ts.map +0 -1
  249. package/build/types/workers/inlineAudioWebWorker.web.d.ts +0 -2
  250. package/build/types/workers/inlineAudioWebWorker.web.d.ts.map +0 -1
  251. package/expo-module.config.json +0 -10
  252. package/ios/AudioAnalysisData.swift +0 -74
  253. package/ios/AudioDeviceManager.swift +0 -666
  254. package/ios/AudioNotificationManager.swift +0 -154
  255. package/ios/AudioProcessingHelpers.swift +0 -743
  256. package/ios/AudioProcessor.swift +0 -1151
  257. package/ios/AudioStreamError.swift +0 -7
  258. package/ios/AudioStreamManager.swift +0 -2352
  259. package/ios/AudioStreamManagerDelegate.swift +0 -16
  260. package/ios/DataPoint.swift +0 -54
  261. package/ios/DecodingConfig.swift +0 -59
  262. package/ios/ExpoAudioStream.podspec +0 -33
  263. package/ios/ExpoAudioStreamModule.swift +0 -1013
  264. package/ios/ExpoAudioStudioTests/AudioFileHandlerTests.swift +0 -338
  265. package/ios/ExpoAudioStudioTests/AudioFormatUtilsTests.swift +0 -331
  266. package/ios/ExpoAudioStudioTests/AudioTestHelpers.swift +0 -130
  267. package/ios/ExpoAudioStudioTests/CompressedOnlyOutputTests.swift +0 -294
  268. package/ios/ExpoAudioStudioTests/EventEmissionIntervalTests.swift +0 -105
  269. package/ios/ExpoAudioStudioTests/Info.plist +0 -22
  270. package/ios/ExpoAudioStudioTests/README.md +0 -39
  271. package/ios/ExpoAudioStudioTests/SimpleAudioTest.swift +0 -98
  272. package/ios/ExpoAudioStudioTests/TestAudioGenerator.swift +0 -75
  273. package/ios/FFT.swift +0 -62
  274. package/ios/Features.swift +0 -95
  275. package/ios/ISSUE_IOS.md +0 -68
  276. package/ios/Logger.swift +0 -39
  277. package/ios/NotificationExtension.swift +0 -15
  278. package/ios/RecordingResult.swift +0 -22
  279. package/ios/RecordingSettings.swift +0 -308
  280. package/ios/WaveformExtractor.swift +0 -105
  281. package/ios/tests/README.md +0 -41
  282. package/ios/tests/integration/buffer_and_fallback_test.swift +0 -178
  283. package/ios/tests/integration/buffer_duration_test.swift +0 -185
  284. package/ios/tests/integration/compressed_only_output_test.swift +0 -271
  285. package/ios/tests/integration/output_control_test.swift +0 -322
  286. package/ios/tests/integration/run_integration_tests.sh +0 -37
  287. package/ios/tests/opus_support_test_macos.swift +0 -154
  288. package/ios/tests/standalone/audio_processing_test.swift +0 -144
  289. package/ios/tests/standalone/audio_recording_test.swift +0 -277
  290. package/ios/tests/standalone/audio_streaming_test.swift +0 -249
  291. package/ios/tests/standalone/standalone_test.swift +0 -144
  292. package/plugin/build/index.cjs +0 -194
  293. package/plugin/build/index.d.cts +0 -22
  294. package/plugin/build/index.js +0 -194
  295. package/plugin/src/index.ts +0 -285
  296. package/plugin/tsconfig.json +0 -10
  297. package/plugin/tsconfig.tsbuildinfo +0 -1
  298. package/src/AudioAnalysis/AudioAnalysis.types.ts +0 -224
  299. package/src/AudioAnalysis/extractAudioAnalysis.ts +0 -344
  300. package/src/AudioAnalysis/extractAudioData.ts +0 -17
  301. package/src/AudioAnalysis/extractMelSpectrogram.ts +0 -154
  302. package/src/AudioAnalysis/extractPreview.ts +0 -34
  303. package/src/AudioAnalysis/extractWaveform.ts +0 -22
  304. package/src/AudioDeviceManager.ts +0 -803
  305. package/src/AudioRecorder.provider.tsx +0 -57
  306. package/src/ExpoAudioStream.native.ts +0 -6
  307. package/src/ExpoAudioStream.types.ts +0 -874
  308. package/src/ExpoAudioStream.web.ts +0 -905
  309. package/src/ExpoAudioStreamModule.ts +0 -990
  310. package/src/WebRecorder.web.ts +0 -1005
  311. package/src/constants/platformLimitations.ts +0 -118
  312. package/src/constants.ts +0 -18
  313. package/src/events.ts +0 -60
  314. package/src/hooks/useAudioDevices.ts +0 -213
  315. package/src/index.ts +0 -54
  316. package/src/trimAudio.ts +0 -94
  317. package/src/types/crc-32.d.ts +0 -9
  318. package/src/useAudioRecorder.tsx +0 -766
  319. package/src/utils/BlobFix.ts +0 -561
  320. package/src/utils/audioProcessing.ts +0 -205
  321. package/src/utils/cleanNativeOptions.ts +0 -18
  322. package/src/utils/concatenateBuffers.ts +0 -24
  323. package/src/utils/convertPCMToFloat32.ts +0 -170
  324. package/src/utils/crc32.ts +0 -59
  325. package/src/utils/encodingToBitDepth.ts +0 -18
  326. package/src/utils/getWavFileInfo.ts +0 -132
  327. package/src/utils/writeWavHeader.ts +0 -115
  328. package/src/workers/InlineFeaturesExtractor.web.tsx +0 -855
  329. package/src/workers/inlineAudioWebWorker.web.tsx +0 -180
@@ -1,338 +0,0 @@
1
- import XCTest
2
- import AVFoundation
3
- @testable import ExpoAudioStream
4
-
5
- class AudioFileHandlerTests: XCTestCase {
6
-
7
- var tempDir: URL!
8
- var audioProcessor: AudioProcessor!
9
-
10
- // Helper function to create WAV header for tests
11
- private func createWavHeader(sampleRate: Int, channels: Int, bitsPerSample: Int, dataSize: Int) -> Data {
12
- var header = Data()
13
-
14
- let blockAlign = channels * (bitsPerSample / 8)
15
- let byteRate = sampleRate * blockAlign
16
-
17
- // "RIFF" chunk descriptor
18
- header.append(contentsOf: "RIFF".utf8)
19
- header.append(contentsOf: UInt32(36 + dataSize).littleEndianBytes)
20
- header.append(contentsOf: "WAVE".utf8)
21
-
22
- // "fmt " sub-chunk
23
- header.append(contentsOf: "fmt ".utf8)
24
- header.append(contentsOf: UInt32(16).littleEndianBytes) // PCM format requires 16 bytes for the fmt sub-chunk
25
- header.append(contentsOf: UInt16(1).littleEndianBytes) // Audio format 1 for PCM
26
- header.append(contentsOf: UInt16(channels).littleEndianBytes)
27
- header.append(contentsOf: UInt32(sampleRate).littleEndianBytes)
28
- header.append(contentsOf: UInt32(byteRate).littleEndianBytes) // byteRate
29
- header.append(contentsOf: UInt16(blockAlign).littleEndianBytes) // blockAlign
30
- header.append(contentsOf: UInt16(bitsPerSample).littleEndianBytes) // bits per sample
31
-
32
- // "data" sub-chunk
33
- header.append(contentsOf: "data".utf8)
34
- header.append(contentsOf: UInt32(dataSize).littleEndianBytes) // Sub-chunk data size
35
-
36
- return header
37
- }
38
-
39
- // Helper function to update WAV header for tests
40
- private func updateWavHeader(fileURL: URL) {
41
- guard let fileHandle = try? FileHandle(forUpdating: fileURL) else { return }
42
- defer { fileHandle.closeFile() }
43
-
44
- // Get file size
45
- fileHandle.seekToEndOfFile()
46
- let fileSize = fileHandle.offsetInFile
47
-
48
- // Update file size in header (bytes 4-7)
49
- fileHandle.seek(toFileOffset: 4)
50
- var size = UInt32(fileSize - 8).littleEndian
51
- fileHandle.write(Data(bytes: &size, count: 4))
52
-
53
- // Update data chunk size (bytes 40-43)
54
- fileHandle.seek(toFileOffset: 40)
55
- var dataSize = UInt32(fileSize - 44).littleEndian
56
- fileHandle.write(Data(bytes: &dataSize, count: 4))
57
- }
58
- }
59
-
60
- override func setUp() {
61
- super.setUp()
62
-
63
- // Create temporary directory for tests
64
- tempDir = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
65
- try? FileManager.default.createDirectory(at: tempDir, withIntermediateDirectories: true)
66
-
67
- // Initialize AudioProcessor
68
- audioProcessor = AudioProcessor(filesDir: tempDir)
69
- }
70
-
71
- override func tearDown() {
72
- // Clean up temporary directory
73
- try? FileManager.default.removeItem(at: tempDir)
74
-
75
- super.tearDown()
76
- }
77
-
78
- // MARK: - WAV Header Tests
79
-
80
- func testWriteWavHeader_createsValidHeader() {
81
- // Given
82
- let sampleRate = 44100
83
- let channels = 2
84
- let bitsPerSample = 16
85
- let dataSize = 1000
86
-
87
- // When
88
- let header = createWavHeader(
89
- sampleRate: sampleRate,
90
- channels: channels,
91
- bitsPerSample: bitsPerSample,
92
- dataSize: dataSize
93
- )
94
-
95
- // Then
96
- XCTAssertEqual(header.count, 44, "WAV header should be 44 bytes")
97
-
98
- // Verify RIFF header
99
- let riffString = String(data: header[0..<4], encoding: .ascii)
100
- XCTAssertEqual(riffString, "RIFF")
101
-
102
- // Verify WAVE format
103
- let waveString = String(data: header[8..<12], encoding: .ascii)
104
- XCTAssertEqual(waveString, "WAVE")
105
-
106
- // Verify fmt chunk
107
- let fmtString = String(data: header[12..<16], encoding: .ascii)
108
- XCTAssertEqual(fmtString, "fmt ")
109
-
110
- // Verify data chunk
111
- let dataString = String(data: header[36..<40], encoding: .ascii)
112
- XCTAssertEqual(dataString, "data")
113
- }
114
-
115
- func testCreateAudioFile_createsFileWithCorrectSize() {
116
- // Given
117
- let fileName = "test_audio.wav"
118
- let sampleRate = 16000
119
- let channels = 1
120
- let durationMs = 1000
121
-
122
- // When
123
- let result = audioProcessor.createAudioFile(
124
- fileName: fileName,
125
- sampleRate: sampleRate,
126
- channels: channels,
127
- durationMs: durationMs
128
- )
129
-
130
- // Then
131
- XCTAssertTrue(result["success"] as? Bool ?? false)
132
-
133
- let fileUri = result["fileUri"] as? String
134
- XCTAssertNotNil(fileUri)
135
-
136
- if let fileUri = fileUri {
137
- let fileURL = URL(string: fileUri)!
138
- let fileExists = FileManager.default.fileExists(atPath: fileURL.path)
139
- XCTAssertTrue(fileExists)
140
-
141
- // Verify file size
142
- if let attributes = try? FileManager.default.attributesOfItem(atPath: fileURL.path),
143
- let fileSize = attributes[.size] as? Int64 {
144
- let expectedDataSize = sampleRate * channels * 2 * durationMs / 1000
145
- let expectedFileSize = 44 + expectedDataSize // WAV header + data
146
- XCTAssertEqual(fileSize, Int64(expectedFileSize))
147
- }
148
- }
149
- }
150
-
151
- func testDeleteAudioFile_removesExistingFile() {
152
- // Given - Create a file first
153
- let fileName = "test_to_delete.wav"
154
- _ = audioProcessor.createAudioFile(
155
- fileName: fileName,
156
- sampleRate: 16000,
157
- channels: 1,
158
- durationMs: 100
159
- )
160
-
161
- // When
162
- let result = audioProcessor.deleteAudioFile(fileName: fileName)
163
-
164
- // Then
165
- XCTAssertTrue(result["success"] as? Bool ?? false)
166
-
167
- let fileURL = tempDir.appendingPathComponent(fileName)
168
- XCTAssertFalse(FileManager.default.fileExists(atPath: fileURL.path))
169
- }
170
-
171
- func testDeleteAudioFile_handlesNonExistentFile() {
172
- // Given
173
- let fileName = "non_existent.wav"
174
-
175
- // When
176
- let result = audioProcessor.deleteAudioFile(fileName: fileName)
177
-
178
- // Then
179
- XCTAssertFalse(result["success"] as? Bool ?? true)
180
- XCTAssertNotNil(result["error"])
181
- }
182
-
183
- func testGetAudioFiles_returnsCorrectList() {
184
- // Given - Create multiple files
185
- let fileNames = ["file1.wav", "file2.wav", "file3.txt"]
186
-
187
- for fileName in fileNames {
188
- if fileName.hasSuffix(".wav") {
189
- _ = audioProcessor.createAudioFile(
190
- fileName: fileName,
191
- sampleRate: 16000,
192
- channels: 1,
193
- durationMs: 100
194
- )
195
- } else {
196
- // Create non-audio file
197
- let url = tempDir.appendingPathComponent(fileName)
198
- try? "test".write(to: url, atomically: true, encoding: .utf8)
199
- }
200
- }
201
-
202
- // When
203
- let files = audioProcessor.getAudioFiles()
204
-
205
- // Then
206
- XCTAssertEqual(files.count, 2, "Should only return WAV files")
207
- XCTAssertTrue(files.contains("file1.wav"))
208
- XCTAssertTrue(files.contains("file2.wav"))
209
- XCTAssertFalse(files.contains("file3.txt"))
210
- }
211
-
212
- func testClearAudioStorage_removesAllAudioFiles() {
213
- // Given - Create multiple files
214
- let audioFiles = ["audio1.wav", "audio2.wav"]
215
- let otherFiles = ["document.txt", "image.png"]
216
-
217
- for fileName in audioFiles {
218
- _ = audioProcessor.createAudioFile(
219
- fileName: fileName,
220
- sampleRate: 16000,
221
- channels: 1,
222
- durationMs: 100
223
- )
224
- }
225
-
226
- for fileName in otherFiles {
227
- let url = tempDir.appendingPathComponent(fileName)
228
- try? "test".write(to: url, atomically: true, encoding: .utf8)
229
- }
230
-
231
- // When
232
- let result = audioProcessor.clearAudioStorage()
233
-
234
- // Then
235
- XCTAssertTrue(result["success"] as? Bool ?? false)
236
-
237
- // Verify audio files are deleted
238
- for fileName in audioFiles {
239
- let url = tempDir.appendingPathComponent(fileName)
240
- XCTAssertFalse(FileManager.default.fileExists(atPath: url.path))
241
- }
242
-
243
- // Verify other files remain
244
- for fileName in otherFiles {
245
- let url = tempDir.appendingPathComponent(fileName)
246
- XCTAssertTrue(FileManager.default.fileExists(atPath: url.path))
247
- }
248
- }
249
-
250
- func testUpdateWavHeader_updatesFileSizeCorrectly() {
251
- // Given - Create a file
252
- let fileName = "test_update.wav"
253
- let createResult = audioProcessor.createAudioFile(
254
- fileName: fileName,
255
- sampleRate: 16000,
256
- channels: 1,
257
- durationMs: 1000
258
- )
259
-
260
- guard let fileUri = createResult["fileUri"] as? String,
261
- let fileURL = URL(string: fileUri) else {
262
- XCTFail("Failed to create test file")
263
- return
264
- }
265
-
266
- // Simulate appending more data
267
- if let fileHandle = try? FileHandle(forWritingTo: fileURL) {
268
- fileHandle.seekToEndOfFile()
269
- let additionalData = Data(count: 1000)
270
- fileHandle.write(additionalData)
271
- fileHandle.closeFile()
272
- }
273
-
274
- // When
275
- updateWavHeader(fileURL: fileURL)
276
-
277
- // Then - Verify header was updated
278
- if let data = try? Data(contentsOf: fileURL) {
279
- // Check file size in header (bytes 4-7)
280
- let fileSize = data.subdata(in: 4..<8).withUnsafeBytes { $0.load(as: UInt32.self) }
281
- XCTAssertEqual(fileSize, UInt32(data.count - 8))
282
-
283
- // Check data chunk size (bytes 40-43)
284
- let dataSize = data.subdata(in: 40..<44).withUnsafeBytes { $0.load(as: UInt32.self) }
285
- XCTAssertEqual(dataSize, UInt32(data.count - 44))
286
- }
287
- }
288
-
289
- // MARK: - Real File Tests
290
-
291
- func testLoadRealWavFile() {
292
- // Load test asset
293
- guard let testBundle = Bundle(for: type(of: self)).url(forResource: "jfk", withExtension: "wav") else {
294
- XCTFail("Test resource jfk.wav should exist")
295
- return
296
- }
297
-
298
- // Copy to temp directory
299
- let destURL = tempDir.appendingPathComponent("test_jfk.wav")
300
- try? FileManager.default.copyItem(at: testBundle, to: destURL)
301
-
302
- // Load and verify
303
- let audioData = audioProcessor.loadAudioFromAnyFormat(
304
- filePath: destURL.path,
305
- config: nil
306
- )
307
-
308
- XCTAssertNotNil(audioData)
309
-
310
- // JFK.wav is known to be mono, 16kHz, 16-bit
311
- XCTAssertEqual(audioData?.sampleRate, 16000)
312
- XCTAssertEqual(audioData?.channels, 1)
313
- XCTAssertEqual(audioData?.bitDepth, 16)
314
- XCTAssertGreaterThan(audioData?.data.count ?? 0, 0)
315
- }
316
-
317
- func testProcessMultipleRealFiles() {
318
- let testFiles = ["jfk.wav", "recorder_hello_world.wav", "osr_us_000_0010_8k.wav"]
319
-
320
- for fileName in testFiles {
321
- guard let testBundle = Bundle(for: type(of: self)).url(forResource: fileName.replacingOccurrences(of: ".wav", with: ""), withExtension: "wav") else {
322
- print("Skipping \(fileName) - not found in test bundle")
323
- continue
324
- }
325
-
326
- let destURL = tempDir.appendingPathComponent(fileName)
327
- try? FileManager.default.copyItem(at: testBundle, to: destURL)
328
-
329
- let audioData = audioProcessor.loadAudioFromAnyFormat(
330
- filePath: destURL.path,
331
- config: nil
332
- )
333
-
334
- XCTAssertNotNil(audioData, "Should load \(fileName)")
335
- XCTAssertGreaterThan(audioData?.data.count ?? 0, 0, "\(fileName) should have audio data")
336
- }
337
- }
338
- }
@@ -1,331 +0,0 @@
1
- import XCTest
2
- import AVFoundation
3
- import Accelerate
4
- @testable import ExpoAudioStream
5
-
6
- class AudioFormatUtilsTests: XCTestCase {
7
-
8
- // MARK: - Bit Depth Conversion Tests
9
-
10
- func testConvertBitDepth_8to16() {
11
- // Given
12
- let input8bit: [UInt8] = [0, 64, 128, 192, 255]
13
- let expected16bit: [Int16] = [-32768, -16384, 0, 16384, 32767]
14
-
15
- // When
16
- let result = AudioFormatUtils.convertBitDepth(
17
- data: Data(input8bit),
18
- fromBitDepth: 8,
19
- toBitDepth: 16
20
- )
21
-
22
- // Then
23
- let result16bit = result.withUnsafeBytes { Array($0.bindMemory(to: Int16.self)) }
24
- XCTAssertEqual(result16bit, expected16bit)
25
- }
26
-
27
- func testConvertBitDepth_16to8() {
28
- // Given
29
- let input16bit: [Int16] = [-32768, -16384, 0, 16384, 32767]
30
- let expected8bit: [UInt8] = [0, 64, 128, 192, 255]
31
-
32
- // When
33
- var data = Data()
34
- input16bit.forEach { data.append(contentsOf: withUnsafeBytes(of: $0) { Array($0) }) }
35
-
36
- let result = AudioFormatUtils.convertBitDepth(
37
- data: data,
38
- fromBitDepth: 16,
39
- toBitDepth: 8
40
- )
41
-
42
- // Then
43
- let result8bit = Array(result)
44
- XCTAssertEqual(result8bit, expected8bit)
45
- }
46
-
47
- func testConvertBitDepth_16to32() {
48
- // Given
49
- let input16bit: [Int16] = [-32768, 0, 32767]
50
- let expected32bit: [Int32] = [-2147483648, 0, 2147483647]
51
-
52
- // When
53
- var data = Data()
54
- input16bit.forEach { data.append(contentsOf: withUnsafeBytes(of: $0) { Array($0) }) }
55
-
56
- let result = AudioFormatUtils.convertBitDepth(
57
- data: data,
58
- fromBitDepth: 16,
59
- toBitDepth: 32
60
- )
61
-
62
- // Then
63
- let result32bit = result.withUnsafeBytes { Array($0.bindMemory(to: Int32.self)) }
64
- XCTAssertEqual(result32bit, expected32bit)
65
- }
66
-
67
- func testConvertBitDepth_32to16() {
68
- // Given
69
- let input32bit: [Int32] = [-2147483648, 0, 2147483647]
70
- let expected16bit: [Int16] = [-32768, 0, 32767]
71
-
72
- // When
73
- var data = Data()
74
- input32bit.forEach { data.append(contentsOf: withUnsafeBytes(of: $0) { Array($0) }) }
75
-
76
- let result = AudioFormatUtils.convertBitDepth(
77
- data: data,
78
- fromBitDepth: 32,
79
- toBitDepth: 16
80
- )
81
-
82
- // Then
83
- let result16bit = result.withUnsafeBytes { Array($0.bindMemory(to: Int16.self)) }
84
- XCTAssertEqual(result16bit, expected16bit)
85
- }
86
-
87
- func testConvertBitDepth_sameDepth() {
88
- // Given
89
- let input: [Int16] = [100, 200, 300]
90
- var data = Data()
91
- input.forEach { data.append(contentsOf: withUnsafeBytes(of: $0) { Array($0) }) }
92
-
93
- // When
94
- let result = AudioFormatUtils.convertBitDepth(
95
- data: data,
96
- fromBitDepth: 16,
97
- toBitDepth: 16
98
- )
99
-
100
- // Then
101
- XCTAssertEqual(result, data)
102
- }
103
-
104
- // MARK: - Channel Conversion Tests
105
-
106
- func testConvertChannels_monoToStereo() {
107
- // Given
108
- let monoData: [Int16] = [100, 200, 300]
109
- var data = Data()
110
- monoData.forEach { data.append(contentsOf: withUnsafeBytes(of: $0) { Array($0) }) }
111
-
112
- // When
113
- let result = AudioFormatUtils.convertChannels(
114
- data: data,
115
- fromChannels: 1,
116
- toChannels: 2,
117
- bitDepth: 16
118
- )
119
-
120
- // Then
121
- let stereoData = result.withUnsafeBytes { Array($0.bindMemory(to: Int16.self)) }
122
- let expected: [Int16] = [100, 100, 200, 200, 300, 300]
123
- XCTAssertEqual(stereoData, expected)
124
- }
125
-
126
- func testConvertChannels_stereoToMono() {
127
- // Given
128
- let stereoData: [Int16] = [100, 200, 300, 400, 500, 600]
129
- var data = Data()
130
- stereoData.forEach { data.append(contentsOf: withUnsafeBytes(of: $0) { Array($0) }) }
131
-
132
- // When
133
- let result = AudioFormatUtils.convertChannels(
134
- data: data,
135
- fromChannels: 2,
136
- toChannels: 1,
137
- bitDepth: 16
138
- )
139
-
140
- // Then
141
- let monoData = result.withUnsafeBytes { Array($0.bindMemory(to: Int16.self)) }
142
- let expected: [Int16] = [150, 350, 550] // Average of pairs
143
- XCTAssertEqual(monoData, expected)
144
- }
145
-
146
- func testConvertChannels_sameChannels() {
147
- // Given
148
- let input: [Int16] = [100, 200, 300, 400]
149
- var data = Data()
150
- input.forEach { data.append(contentsOf: withUnsafeBytes(of: $0) { Array($0) }) }
151
-
152
- // When
153
- let result = AudioFormatUtils.convertChannels(
154
- data: data,
155
- fromChannels: 2,
156
- toChannels: 2,
157
- bitDepth: 16
158
- )
159
-
160
- // Then
161
- XCTAssertEqual(result, data)
162
- }
163
-
164
- // MARK: - Audio Normalization Tests
165
-
166
- func testNormalizeAudio_quietAudio() {
167
- // Given - Very quiet audio
168
- let quietAudio: [Int16] = [10, -10, 20, -20, 30, -30]
169
- var data = Data()
170
- quietAudio.forEach { data.append(contentsOf: withUnsafeBytes(of: $0) { Array($0) }) }
171
-
172
- // When
173
- let result = AudioFormatUtils.normalizeAudio(
174
- data: data,
175
- bitDepth: 16,
176
- targetLevel: 0.9
177
- )
178
-
179
- // Then
180
- let normalized = result.withUnsafeBytes { Array($0.bindMemory(to: Int16.self)) }
181
-
182
- // Check that audio was amplified
183
- let maxOriginal = quietAudio.map { abs($0) }.max() ?? 0
184
- let maxNormalized = normalized.map { abs($0) }.max() ?? 0
185
-
186
- XCTAssertGreaterThan(maxNormalized, maxOriginal)
187
-
188
- // Check that max is close to target
189
- let targetMax = Int16(Float(Int16.max) * 0.9)
190
- XCTAssertGreaterThan(maxNormalized, Int16(Float(targetMax) * 0.8))
191
- XCTAssertLessThanOrEqual(maxNormalized, targetMax)
192
- }
193
-
194
- func testNormalizeAudio_loudAudio() {
195
- // Given - Already loud audio
196
- let loudAudio: [Int16] = [30000, -30000, 25000, -25000]
197
- var data = Data()
198
- loudAudio.forEach { data.append(contentsOf: withUnsafeBytes(of: $0) { Array($0) }) }
199
-
200
- // When
201
- let result = AudioFormatUtils.normalizeAudio(
202
- data: data,
203
- bitDepth: 16,
204
- targetLevel: 0.9
205
- )
206
-
207
- // Then
208
- let normalized = result.withUnsafeBytes { Array($0.bindMemory(to: Int16.self)) }
209
-
210
- // Check that audio was slightly reduced
211
- let maxOriginal = loudAudio.map { abs($0) }.max() ?? 0
212
- let maxNormalized = normalized.map { abs($0) }.max() ?? 0
213
-
214
- XCTAssertLessThanOrEqual(maxNormalized, maxOriginal)
215
-
216
- // Check that max is close to target
217
- let targetMax = Int16(Float(Int16.max) * 0.9)
218
- XCTAssertGreaterThan(maxNormalized, Int16(Float(targetMax) * 0.8))
219
- XCTAssertLessThanOrEqual(maxNormalized, targetMax)
220
- }
221
-
222
- func testNormalizeAudio_silentAudio() {
223
- // Given - Silent audio
224
- let silentAudio = [Int16](repeating: 0, count: 100)
225
- var data = Data()
226
- silentAudio.forEach { data.append(contentsOf: withUnsafeBytes(of: $0) { Array($0) }) }
227
-
228
- // When
229
- let result = AudioFormatUtils.normalizeAudio(
230
- data: data,
231
- bitDepth: 16,
232
- targetLevel: 0.9
233
- )
234
-
235
- // Then - Should remain silent
236
- let normalized = result.withUnsafeBytes { Array($0.bindMemory(to: Int16.self)) }
237
- XCTAssertTrue(normalized.allSatisfy { $0 == 0 })
238
- }
239
-
240
- // MARK: - Sample Rate Conversion Tests
241
-
242
- func testResampleAudio_upsample() {
243
- // Given
244
- let originalSampleRate = 16000
245
- let targetSampleRate = 44100
246
- let duration = 0.1 // 100ms
247
- let originalSamples = Int(Double(originalSampleRate) * duration)
248
-
249
- // Create a simple sine wave
250
- var sineWave = [Int16]()
251
- for i in 0..<originalSamples {
252
- let value = sin(2.0 * .pi * 440.0 * Double(i) / Double(originalSampleRate))
253
- sineWave.append(Int16(value * 10000))
254
- }
255
-
256
- var data = Data()
257
- sineWave.forEach { data.append(contentsOf: withUnsafeBytes(of: $0) { Array($0) }) }
258
-
259
- // When
260
- let result = AudioFormatUtils.resampleAudio(
261
- data: data,
262
- fromSampleRate: originalSampleRate,
263
- toSampleRate: targetSampleRate,
264
- channels: 1,
265
- bitDepth: 16
266
- )
267
-
268
- // Then
269
- let expectedSamples = Int(Double(targetSampleRate) * duration)
270
- let actualSamples = result.count / 2 // 16-bit = 2 bytes per sample
271
-
272
- // Allow some tolerance due to resampling
273
- XCTAssertGreaterThan(actualSamples, Int(Double(expectedSamples) * 0.95))
274
- XCTAssertLessThan(actualSamples, Int(Double(expectedSamples) * 1.05))
275
- }
276
-
277
- func testResampleAudio_downsample() {
278
- // Given
279
- let originalSampleRate = 44100
280
- let targetSampleRate = 16000
281
- let duration = 0.1 // 100ms
282
- let originalSamples = Int(Double(originalSampleRate) * duration)
283
-
284
- // Create a simple sine wave
285
- var sineWave = [Int16]()
286
- for i in 0..<originalSamples {
287
- let value = sin(2.0 * .pi * 440.0 * Double(i) / Double(originalSampleRate))
288
- sineWave.append(Int16(value * 10000))
289
- }
290
-
291
- var data = Data()
292
- sineWave.forEach { data.append(contentsOf: withUnsafeBytes(of: $0) { Array($0) }) }
293
-
294
- // When
295
- let result = AudioFormatUtils.resampleAudio(
296
- data: data,
297
- fromSampleRate: originalSampleRate,
298
- toSampleRate: targetSampleRate,
299
- channels: 1,
300
- bitDepth: 16
301
- )
302
-
303
- // Then
304
- let expectedSamples = Int(Double(targetSampleRate) * duration)
305
- let actualSamples = result.count / 2 // 16-bit = 2 bytes per sample
306
-
307
- // Allow some tolerance due to resampling
308
- XCTAssertGreaterThan(actualSamples, Int(Double(expectedSamples) * 0.95))
309
- XCTAssertLessThan(actualSamples, Int(Double(expectedSamples) * 1.05))
310
- }
311
-
312
- func testResampleAudio_sameSampleRate() {
313
- // Given
314
- let sampleRate = 44100
315
- let samples: [Int16] = [100, 200, 300, 400, 500]
316
- var data = Data()
317
- samples.forEach { data.append(contentsOf: withUnsafeBytes(of: $0) { Array($0) }) }
318
-
319
- // When
320
- let result = AudioFormatUtils.resampleAudio(
321
- data: data,
322
- fromSampleRate: sampleRate,
323
- toSampleRate: sampleRate,
324
- channels: 1,
325
- bitDepth: 16
326
- )
327
-
328
- // Then - Should return same data
329
- XCTAssertEqual(result, data)
330
- }
331
- }