@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,130 +0,0 @@
1
- import Foundation
2
- import AVFoundation
3
- import Accelerate
4
-
5
- extension AVAudioPCMBuffer {
6
-
7
- /// Convert buffer to Data
8
- func toData() -> Data {
9
- let audioFormat = self.format
10
- let channelCount = Int(audioFormat.channelCount)
11
- let frameLength = Int(self.frameLength)
12
-
13
- var data = Data()
14
-
15
- if let floatData = self.floatChannelData {
16
- // Convert float samples to 16-bit PCM
17
- for frame in 0..<frameLength {
18
- for channel in 0..<channelCount {
19
- let sample = floatData[channel][frame]
20
- let int16Sample = Int16(max(-32768, min(32767, sample * 32767)))
21
- data.append(contentsOf: withUnsafeBytes(of: int16Sample) { Array($0) })
22
- }
23
- }
24
- } else if let int16Data = self.int16ChannelData {
25
- // Already 16-bit, just copy
26
- for frame in 0..<frameLength {
27
- for channel in 0..<channelCount {
28
- let sample = int16Data[channel][frame]
29
- data.append(contentsOf: withUnsafeBytes(of: sample) { Array($0) })
30
- }
31
- }
32
- }
33
-
34
- return data
35
- }
36
-
37
- /// Calculate RMS (Root Mean Square) of the buffer
38
- func rms() -> Float {
39
- guard let channelData = self.floatChannelData else { return 0 }
40
-
41
- let channelCount = Int(self.format.channelCount)
42
- let frameLength = Int(self.frameLength)
43
-
44
- var sum: Float = 0
45
- var sampleCount = 0
46
-
47
- for channel in 0..<channelCount {
48
- for frame in 0..<frameLength {
49
- let sample = channelData[channel][frame]
50
- sum += sample * sample
51
- sampleCount += 1
52
- }
53
- }
54
-
55
- return sqrt(sum / Float(sampleCount))
56
- }
57
-
58
- /// Calculate energy of the buffer
59
- func energy() -> Float {
60
- guard let channelData = self.floatChannelData else { return 0 }
61
-
62
- let channelCount = Int(self.format.channelCount)
63
- let frameLength = Int(self.frameLength)
64
-
65
- var sum: Float = 0
66
-
67
- for channel in 0..<channelCount {
68
- for frame in 0..<frameLength {
69
- let sample = channelData[channel][frame]
70
- sum += sample * sample
71
- }
72
- }
73
-
74
- return sum
75
- }
76
- }
77
-
78
- extension Data {
79
-
80
- /// Convert PCM data to float array
81
- func toFloatArray(bitDepth: Int = 16) -> [Float] {
82
- var floats = [Float]()
83
-
84
- switch bitDepth {
85
- case 16:
86
- let samples = self.withUnsafeBytes { $0.bindMemory(to: Int16.self) }
87
- for sample in samples {
88
- floats.append(Float(sample) / Float(Int16.max))
89
- }
90
- case 32:
91
- let samples = self.withUnsafeBytes { $0.bindMemory(to: Int32.self) }
92
- for sample in samples {
93
- floats.append(Float(sample) / Float(Int32.max))
94
- }
95
- default:
96
- break
97
- }
98
-
99
- return floats
100
- }
101
-
102
- /// Calculate RMS from PCM data
103
- func rms(bitDepth: Int = 16) -> Float {
104
- let floats = toFloatArray(bitDepth: bitDepth)
105
- guard !floats.isEmpty else { return 0 }
106
-
107
- let sum = floats.reduce(0) { $0 + $1 * $1 }
108
- return sqrt(sum / Float(floats.count))
109
- }
110
-
111
- /// Calculate energy from PCM data
112
- func energy(bitDepth: Int = 16) -> Float {
113
- let floats = toFloatArray(bitDepth: bitDepth)
114
- return floats.reduce(0) { $0 + $1 * $1 }
115
- }
116
- }
117
-
118
- // Test assertion helpers
119
- extension XCTestCase {
120
-
121
- /// Assert two float values are approximately equal
122
- func XCTAssertApproximatelyEqual(_ value1: Float, _ value2: Float, tolerance: Float = 0.0001, _ message: String = "", file: StaticString = #file, line: UInt = #line) {
123
- XCTAssertLessThanOrEqual(abs(value1 - value2), tolerance, message, file: file, line: line)
124
- }
125
-
126
- /// Assert two double values are approximately equal
127
- func XCTAssertApproximatelyEqual(_ value1: Double, _ value2: Double, tolerance: Double = 0.0001, _ message: String = "", file: StaticString = #file, line: UInt = #line) {
128
- XCTAssertLessThanOrEqual(abs(value1 - value2), tolerance, message, file: file, line: line)
129
- }
130
- }
@@ -1,294 +0,0 @@
1
- import XCTest
2
- import AVFoundation
3
- @testable import ExpoAudioStream
4
-
5
- class CompressedOnlyOutputTests: XCTestCase {
6
-
7
- var audioManager: AudioStreamManager!
8
- var testDelegate: TestAudioStreamDelegate!
9
-
10
- override func setUp() {
11
- super.setUp()
12
- audioManager = AudioStreamManager()
13
- testDelegate = TestAudioStreamDelegate()
14
- audioManager.delegate = testDelegate
15
- }
16
-
17
- override func tearDown() {
18
- audioManager.stopRecording()
19
- audioManager = nil
20
- testDelegate = nil
21
- super.tearDown()
22
- }
23
-
24
- // MARK: - Test Compressed-Only Output (Issue #244)
25
-
26
- func testCompressedOnlyOutputWithAAC() {
27
- // Given: Recording settings with primary disabled and compressed enabled (AAC)
28
- var settings = RecordingSettings(
29
- sampleRate: 44100,
30
- desiredSampleRate: 44100,
31
- autoResumeAfterInterruption: false
32
- )
33
- settings.numberOfChannels = 1
34
- settings.bitDepth = 16
35
- settings.output.primary.enabled = false
36
- settings.output.compressed.enabled = true
37
- settings.output.compressed.format = "aac"
38
- settings.output.compressed.bitrate = 128000
39
-
40
- let expectation = self.expectation(description: "Recording should complete with compression info")
41
- var capturedCompressionInfo: [String: Any]?
42
- var capturedError: String?
43
-
44
- // When: Start and stop recording
45
- testDelegate.onAudioData = { data, recordingTime, totalDataSize, compressionInfo in
46
- capturedCompressionInfo = compressionInfo
47
- }
48
-
49
- testDelegate.onError = { error in
50
- capturedError = error
51
- }
52
-
53
- // Start recording returns a result that we can check
54
- let startResult = audioManager.startRecording(settings: settings)
55
- XCTAssertNotNil(startResult, "Start recording should return a result")
56
-
57
- // Generate and process some test audio to ensure compression happens
58
- let testBuffer = TestAudioGenerator.generateTone(frequency: 440, duration: 0.1, sampleRate: 44100)
59
- if let buffer = testBuffer {
60
- // Process multiple chunks to ensure we have enough data
61
- for _ in 0..<5 {
62
- audioManager.processAudioBuffer(buffer, time: AVAudioTime(hostTime: mach_absolute_time()))
63
- Thread.sleep(forTimeInterval: 0.1)
64
- }
65
- }
66
-
67
- // Stop recording and get the result
68
- let recordingResult = audioManager.stopRecording()
69
- expectation.fulfill()
70
-
71
- waitForExpectations(timeout: 2.0) { error in
72
- XCTAssertNil(error, "Recording should complete within timeout")
73
- }
74
-
75
- // Then: Verify compression info is returned
76
- XCTAssertNil(capturedError, "No errors should occur during recording")
77
- XCTAssertNotNil(recordingResult, "Recording result should not be nil")
78
- XCTAssertNotNil(recordingResult?.compression, "Compression info should be included")
79
-
80
- if let compression = recordingResult?.compression {
81
- XCTAssertEqual(compression.format, "aac", "Format should be AAC")
82
- XCTAssertEqual(compression.bitrate, 128000, "Bitrate should match settings")
83
- XCTAssertFalse(compression.compressedFileUri.isEmpty, "Compressed file URI should not be empty")
84
- XCTAssertGreaterThan(compression.size, 0, "Compressed file size should be greater than 0")
85
- XCTAssertEqual(compression.mimeType, "audio/aac", "MIME type should be audio/aac")
86
- }
87
-
88
- // Verify main result uses compressed info when primary is disabled
89
- XCTAssertEqual(recordingResult?.fileUri, recordingResult?.compression?.compressedFileUri,
90
- "Main fileUri should use compressed URI when primary is disabled")
91
- XCTAssertEqual(recordingResult?.mimeType, "audio/aac",
92
- "Main mimeType should reflect compressed format")
93
- }
94
-
95
- func testCompressedOnlyOutputWithOpusFallback() {
96
- // Given: Recording settings with primary disabled and compressed enabled (Opus)
97
- var settings = RecordingSettings(
98
- sampleRate: 48000,
99
- desiredSampleRate: 48000,
100
- autoResumeAfterInterruption: false
101
- )
102
- settings.numberOfChannels = 1
103
- settings.bitDepth = 16
104
- settings.output.primary.enabled = false
105
- settings.output.compressed.enabled = true
106
- settings.output.compressed.format = "opus" // Should fallback to AAC on iOS
107
- settings.output.compressed.bitrate = 64000
108
-
109
- let expectation = self.expectation(description: "Recording should complete with AAC fallback")
110
-
111
- // Start recording
112
- let startResult = audioManager.startRecording(settings: settings)
113
- XCTAssertNotNil(startResult, "Start recording should return a result")
114
-
115
- // Generate test audio
116
- if let buffer = TestAudioGenerator.generateTone(frequency: 440, duration: 0.1, sampleRate: 48000) {
117
- for _ in 0..<3 {
118
- audioManager.processAudioBuffer(buffer, time: AVAudioTime(hostTime: mach_absolute_time()))
119
- Thread.sleep(forTimeInterval: 0.1)
120
- }
121
- }
122
-
123
- // Stop recording
124
- let recordingResult = audioManager.stopRecording()
125
- expectation.fulfill()
126
-
127
- waitForExpectations(timeout: 2.0) { error in
128
- XCTAssertNil(error, "Recording should complete within timeout")
129
- }
130
-
131
- // Then: Verify Opus falls back to AAC on iOS
132
- XCTAssertNotNil(recordingResult?.compression, "Compression info should be included")
133
- XCTAssertEqual(recordingResult?.compression?.format, "aac",
134
- "Opus should fallback to AAC on iOS")
135
- XCTAssertEqual(recordingResult?.compression?.bitrate, 64000,
136
- "Bitrate should be preserved from original settings")
137
- }
138
-
139
- func testCompressedFileAccessibility() {
140
- // Given: Recording with compressed output
141
- var settings = RecordingSettings(
142
- sampleRate: 44100,
143
- desiredSampleRate: 44100,
144
- autoResumeAfterInterruption: false
145
- )
146
- settings.numberOfChannels = 1
147
- settings.bitDepth = 16
148
- settings.output.primary.enabled = false
149
- settings.output.compressed.enabled = true
150
- settings.output.compressed.format = "aac"
151
- settings.output.compressed.bitrate = 96000
152
-
153
- let expectation = self.expectation(description: "Compressed file should be accessible")
154
-
155
- // Start recording
156
- let startResult = audioManager.startRecording(settings: settings)
157
- XCTAssertNotNil(startResult, "Start recording should return a result")
158
-
159
- // Generate substantial audio data to ensure file is created
160
- if let buffer = TestAudioGenerator.generateTone(frequency: 440, duration: 0.2, sampleRate: 44100) {
161
- for _ in 0..<5 {
162
- audioManager.processAudioBuffer(buffer, time: AVAudioTime(hostTime: mach_absolute_time()))
163
- Thread.sleep(forTimeInterval: 0.1)
164
- }
165
- }
166
-
167
- // Stop recording
168
- let recordingResult = audioManager.stopRecording()
169
- expectation.fulfill()
170
-
171
- waitForExpectations(timeout: 2.0) { error in
172
- XCTAssertNil(error, "Recording should complete within timeout")
173
- }
174
-
175
- // Then: Verify compressed file is accessible
176
- if let compression = recordingResult?.compression {
177
- let fileURL = URL(string: compression.compressedFileUri)
178
- XCTAssertNotNil(fileURL, "Compressed file URL should be valid")
179
-
180
- if let url = fileURL {
181
- let fileExists = FileManager.default.fileExists(atPath: url.path)
182
- XCTAssertTrue(fileExists, "Compressed file should exist at the specified path")
183
-
184
- // Verify file size matches reported size
185
- if fileExists {
186
- do {
187
- let attributes = try FileManager.default.attributesOfItem(atPath: url.path)
188
- let actualSize = attributes[.size] as? Int64 ?? 0
189
- XCTAssertEqual(actualSize, compression.size,
190
- "Reported size should match actual file size")
191
- } catch {
192
- XCTFail("Failed to get file attributes: \(error)")
193
- }
194
- }
195
- }
196
- } else {
197
- XCTFail("Compression info should not be nil")
198
- }
199
- }
200
-
201
- func testStreamingOnlyWithCompression() {
202
- // Given: Streaming configuration with compression
203
- var settings = RecordingSettings(
204
- sampleRate: 44100,
205
- desiredSampleRate: 44100,
206
- autoResumeAfterInterruption: false
207
- )
208
- settings.numberOfChannels = 1
209
- settings.bitDepth = 16
210
- settings.output.primary.enabled = false
211
- settings.output.compressed.enabled = true
212
- settings.output.compressed.format = "aac"
213
- settings.output.compressed.bitrate = 128000
214
- settings.interval = 100 // Enable streaming with 100ms intervals
215
-
216
- let expectation = self.expectation(description: "Streaming should work with compressed output")
217
- var dataEventCount = 0
218
- var hasCompressionInfo = false
219
-
220
- testDelegate.onAudioData = { data, recordingTime, totalDataSize, compressionInfo in
221
- dataEventCount += 1
222
- if compressionInfo != nil {
223
- hasCompressionInfo = true
224
- }
225
- }
226
-
227
- // Start recording
228
- let startResult = audioManager.startRecording(settings: settings)
229
- XCTAssertNotNil(startResult, "Start recording should return a result")
230
-
231
- // Generate audio data
232
- if let buffer = TestAudioGenerator.generateTone(frequency: 440, duration: 0.1, sampleRate: 44100) {
233
- for _ in 0..<5 {
234
- audioManager.processAudioBuffer(buffer, time: AVAudioTime(hostTime: mach_absolute_time()))
235
- Thread.sleep(forTimeInterval: 0.1)
236
- }
237
- }
238
-
239
- // Stop recording
240
- let recordingResult = audioManager.stopRecording()
241
- expectation.fulfill()
242
-
243
- waitForExpectations(timeout: 2.0) { error in
244
- XCTAssertNil(error, "Recording should complete within timeout")
245
- }
246
-
247
- // Then: Verify streaming worked and compression info is available
248
- XCTAssertGreaterThan(dataEventCount, 0, "Should have received audio data events")
249
- XCTAssertTrue(hasCompressionInfo, "Should have received compression info in data events")
250
- XCTAssertNotNil(recordingResult?.compression, "Compression info should be available in final result")
251
- }
252
- }
253
-
254
- // MARK: - Test Delegate
255
-
256
- class TestAudioStreamDelegate: AudioStreamManagerDelegate {
257
- var onAudioData: ((Data, TimeInterval, Int64, [String: Any]?) -> Void)?
258
- var onError: ((String) -> Void)?
259
- var onAnalysis: ((AudioAnalysisData?) -> Void)?
260
-
261
- func audioStreamManager(
262
- _ manager: AudioStreamManager,
263
- didReceiveAudioData data: Data,
264
- recordingTime: TimeInterval,
265
- totalDataSize: Int64,
266
- compressionInfo: [String: Any]?
267
- ) {
268
- onAudioData?(data, recordingTime, totalDataSize, compressionInfo)
269
- }
270
-
271
- func audioStreamManager(_ manager: AudioStreamManager, didReceiveProcessingResult result: AudioAnalysisData?) {
272
- onAnalysis?(result)
273
- }
274
-
275
- func audioStreamManager(_ manager: AudioStreamManager, didPauseRecording pauseTime: Date) {
276
- // Optional: Handle pause
277
- }
278
-
279
- func audioStreamManager(_ manager: AudioStreamManager, didResumeRecording resumeTime: Date) {
280
- // Optional: Handle resume
281
- }
282
-
283
- func audioStreamManager(_ manager: AudioStreamManager, didUpdateNotificationState isPaused: Bool) {
284
- // Optional: Handle notification state
285
- }
286
-
287
- func audioStreamManager(_ manager: AudioStreamManager, didReceiveInterruption info: [String: Any]) {
288
- // Optional: Handle interruption
289
- }
290
-
291
- func audioStreamManager(_ manager: AudioStreamManager, didFailWithError error: String) {
292
- onError?(error)
293
- }
294
- }
@@ -1,105 +0,0 @@
1
- import XCTest
2
- @testable import ExpoAudioStudio
3
-
4
- class EventEmissionIntervalTests: XCTestCase {
5
-
6
- var audioStreamManager: AudioStreamManager!
7
-
8
- override func setUp() {
9
- super.setUp()
10
- audioStreamManager = AudioStreamManager()
11
- }
12
-
13
- override func tearDown() {
14
- audioStreamManager = nil
15
- super.tearDown()
16
- }
17
-
18
- func testIntervalClamping() {
19
- // Test case 1: Interval below minimum (10ms)
20
- let config1 = RecordingConfig()
21
- config1.interval = 10
22
- config1.intervalAnalysis = 10
23
-
24
- audioStreamManager.prepareRecording(with: config1) { error in
25
- XCTAssertNil(error, "Should prepare successfully")
26
- }
27
-
28
- // After our fix, this should be 10ms (0.01s), not 100ms (0.1s)
29
- XCTAssertEqual(audioStreamManager.emissionInterval, 0.01, accuracy: 0.001)
30
- XCTAssertEqual(audioStreamManager.emissionIntervalAnalysis, 0.01, accuracy: 0.001)
31
-
32
- // Test case 2: Interval at old minimum (100ms)
33
- let config2 = RecordingConfig()
34
- config2.interval = 100
35
- config2.intervalAnalysis = 100
36
-
37
- audioStreamManager.prepareRecording(with: config2) { error in
38
- XCTAssertNil(error, "Should prepare successfully")
39
- }
40
-
41
- XCTAssertEqual(audioStreamManager.emissionInterval, 0.1, accuracy: 0.001)
42
- XCTAssertEqual(audioStreamManager.emissionIntervalAnalysis, 0.1, accuracy: 0.001)
43
-
44
- // Test case 3: Interval above minimum (200ms)
45
- let config3 = RecordingConfig()
46
- config3.interval = 200
47
- config3.intervalAnalysis = 200
48
-
49
- audioStreamManager.prepareRecording(with: config3) { error in
50
- XCTAssertNil(error, "Should prepare successfully")
51
- }
52
-
53
- XCTAssertEqual(audioStreamManager.emissionInterval, 0.2, accuracy: 0.001)
54
- XCTAssertEqual(audioStreamManager.emissionIntervalAnalysis, 0.2, accuracy: 0.001)
55
- }
56
-
57
- func testEventEmissionTiming() {
58
- let expectation = self.expectation(description: "Should emit events at correct intervals")
59
- var eventTimestamps: [TimeInterval] = []
60
- let testDuration: TimeInterval = 0.5 // 500ms
61
-
62
- // Configure for 10ms intervals
63
- let config = RecordingConfig()
64
- config.interval = 10
65
- config.intervalAnalysis = 10
66
- config.enableProcessing = true
67
- config.features = ["fft": true]
68
-
69
- // Mock event handler to capture timestamps
70
- audioStreamManager.onAudioData = { _ in
71
- eventTimestamps.append(Date().timeIntervalSince1970)
72
- }
73
-
74
- audioStreamManager.startRecording(with: config) { error in
75
- XCTAssertNil(error, "Should start recording successfully")
76
-
77
- // Record for test duration
78
- DispatchQueue.main.asyncAfter(deadline: .now() + testDuration) {
79
- self.audioStreamManager.stopRecording()
80
-
81
- // Analyze intervals
82
- if eventTimestamps.count > 1 {
83
- var intervals: [TimeInterval] = []
84
- for i in 1..<eventTimestamps.count {
85
- intervals.append((eventTimestamps[i] - eventTimestamps[i-1]) * 1000) // Convert to ms
86
- }
87
-
88
- let avgInterval = intervals.reduce(0, +) / Double(intervals.count)
89
- let minInterval = intervals.min() ?? 0
90
- let maxInterval = intervals.max() ?? 0
91
-
92
- print("Event emission intervals - Avg: \(avgInterval)ms, Min: \(minInterval)ms, Max: \(maxInterval)ms")
93
-
94
- // With the fix, average should be close to 10ms
95
- XCTAssertLessThan(abs(avgInterval - 10), 5, "Average interval should be close to 10ms")
96
- XCTAssertGreaterThan(minInterval, 5, "Minimum interval should be at least 5ms")
97
- }
98
-
99
- expectation.fulfill()
100
- }
101
- }
102
-
103
- waitForExpectations(timeout: testDuration + 1.0)
104
- }
105
- }
@@ -1,22 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>CFBundleDevelopmentRegion</key>
6
- <string>$(DEVELOPMENT_LANGUAGE)</string>
7
- <key>CFBundleExecutable</key>
8
- <string>$(EXECUTABLE_NAME)</string>
9
- <key>CFBundleIdentifier</key>
10
- <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11
- <key>CFBundleInfoDictionaryVersion</key>
12
- <string>6.0</string>
13
- <key>CFBundleName</key>
14
- <string>$(PRODUCT_NAME)</string>
15
- <key>CFBundlePackageType</key>
16
- <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
17
- <key>CFBundleShortVersionString</key>
18
- <string>1.0</string>
19
- <key>CFBundleVersion</key>
20
- <string>1</string>
21
- </dict>
22
- </plist>
@@ -1,39 +0,0 @@
1
- # ExpoAudioStudio iOS Unit Tests
2
-
3
- This directory contains unit tests for the ExpoAudioStudio iOS module.
4
-
5
- ## Test Files
6
-
7
- - `AudioTestHelpers.swift` - Common test utilities and extensions
8
- - `AudioFormatUtilsTests.swift` - Tests for audio format utilities
9
- - `AudioFileHandlerTests.swift` - Tests for file handling
10
- - `SimpleAudioTest.swift` - Basic audio functionality tests
11
- - `TestAudioGenerator.swift` - Audio generation utilities for testing
12
- - `CompressedOnlyOutputTests.swift` - Tests for compressed-only output feature (Issue #244)
13
-
14
- ## Running Tests
15
-
16
- ### In Xcode
17
- 1. Open the workspace/project containing ExpoAudioStudio
18
- 2. Select the test target
19
- 3. Press `Cmd+U` to run all tests or click on individual test methods
20
-
21
- ### From Command Line
22
- ```bash
23
- # Run all tests
24
- xcodebuild test -scheme ExpoAudioStudioTests -destination 'platform=iOS Simulator,name=iPhone 15'
25
-
26
- # Run specific test class
27
- xcodebuild test -scheme ExpoAudioStudioTests -destination 'platform=iOS Simulator,name=iPhone 15' -only-testing:ExpoAudioStudioTests/CompressedOnlyOutputTests
28
- ```
29
-
30
- ## Compressed-Only Output Tests
31
-
32
- The `CompressedOnlyOutputTests.swift` file tests the fix for Issue #244, ensuring that:
33
- - Compression info is properly returned when primary output is disabled
34
- - AAC format works correctly
35
- - Opus format falls back to AAC on iOS
36
- - Compressed file URIs are accessible
37
- - File sizes and metadata are correctly reported
38
-
39
- These tests verify that users can access compressed audio files even when primary WAV output is disabled.
@@ -1,98 +0,0 @@
1
- import XCTest
2
- import AVFoundation
3
-
4
- class SimpleAudioTest: XCTestCase {
5
-
6
- func testCreateWAVHeader() {
7
- // Test creating a basic WAV header
8
- let sampleRate = 44100
9
- let channels = 2
10
- let bitsPerSample = 16
11
- let dataSize = 1024
12
-
13
- // Calculate expected values
14
- let byteRate = sampleRate * channels * (bitsPerSample / 8)
15
- let blockAlign = channels * (bitsPerSample / 8)
16
-
17
- // Create header data manually (44 bytes)
18
- var header = Data()
19
-
20
- // RIFF chunk
21
- header.append("RIFF".data(using: .ascii)!)
22
- var fileSize = UInt32(dataSize + 36).littleEndian
23
- header.append(Data(bytes: &fileSize, count: 4))
24
- header.append("WAVE".data(using: .ascii)!)
25
-
26
- // fmt chunk
27
- header.append("fmt ".data(using: .ascii)!)
28
- var fmtSize = UInt32(16).littleEndian
29
- header.append(Data(bytes: &fmtSize, count: 4))
30
- var audioFormat = UInt16(1).littleEndian // PCM
31
- header.append(Data(bytes: &audioFormat, count: 2))
32
- var numChannels = UInt16(channels).littleEndian
33
- header.append(Data(bytes: &numChannels, count: 2))
34
- var sampleRateValue = UInt32(sampleRate).littleEndian
35
- header.append(Data(bytes: &sampleRateValue, count: 4))
36
- var byteRateValue = UInt32(byteRate).littleEndian
37
- header.append(Data(bytes: &byteRateValue, count: 4))
38
- var blockAlignValue = UInt16(blockAlign).littleEndian
39
- header.append(Data(bytes: &blockAlignValue, count: 2))
40
- var bitsPerSampleValue = UInt16(bitsPerSample).littleEndian
41
- header.append(Data(bytes: &bitsPerSampleValue, count: 2))
42
-
43
- // data chunk
44
- header.append("data".data(using: .ascii)!)
45
- var dataSizeValue = UInt32(dataSize).littleEndian
46
- header.append(Data(bytes: &dataSizeValue, count: 4))
47
-
48
- // Verify header size
49
- XCTAssertEqual(header.count, 44, "WAV header should be 44 bytes")
50
-
51
- // Verify RIFF header
52
- let riffHeader = String(data: header[0..<4], encoding: .ascii)
53
- XCTAssertEqual(riffHeader, "RIFF")
54
-
55
- // Verify WAVE format
56
- let waveFormat = String(data: header[8..<12], encoding: .ascii)
57
- XCTAssertEqual(waveFormat, "WAVE")
58
-
59
- print("✅ Basic WAV header test passed!")
60
- }
61
-
62
- func testSimpleAudioBuffer() {
63
- // Test creating a simple audio buffer
64
- let sampleRate = 44100.0
65
- let duration = 0.1 // 100ms
66
- let frequency = 440.0 // A4 note
67
-
68
- let frameCount = Int(sampleRate * duration)
69
- let format = AVAudioFormat(standardFormatWithSampleRate: sampleRate, channels: 1)!
70
-
71
- guard let buffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: AVAudioFrameCount(frameCount)) else {
72
- XCTFail("Failed to create audio buffer")
73
- return
74
- }
75
-
76
- buffer.frameLength = AVAudioFrameCount(frameCount)
77
-
78
- // Generate a simple sine wave
79
- let channelData = buffer.floatChannelData![0]
80
- for frame in 0..<frameCount {
81
- let phase = 2.0 * Double.pi * frequency * Double(frame) / sampleRate
82
- channelData[frame] = Float(sin(phase) * 0.5)
83
- }
84
-
85
- // Verify buffer properties
86
- XCTAssertEqual(buffer.frameLength, AVAudioFrameCount(frameCount))
87
- XCTAssertEqual(buffer.format.sampleRate, sampleRate)
88
- XCTAssertEqual(buffer.format.channelCount, 1)
89
-
90
- // Verify we have audio data
91
- let firstSample = channelData[0]
92
- let lastSample = channelData[frameCount - 1]
93
- XCTAssertNotEqual(firstSample, 0.0, accuracy: 0.001)
94
- XCTAssertNotEqual(lastSample, firstSample, accuracy: 0.001)
95
-
96
- print("✅ Simple audio buffer test passed!")
97
- }
98
- }