@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,689 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.DeviceDisconnectionBehavior = exports.audioDeviceManager = exports.AudioDeviceManager = void 0;
7
- const expo_modules_core_1 = require("expo-modules-core");
8
- const react_native_1 = require("react-native");
9
- const ExpoAudioStream_types_1 = require("./ExpoAudioStream.types");
10
- Object.defineProperty(exports, "DeviceDisconnectionBehavior", { enumerable: true, get: function () { return ExpoAudioStream_types_1.DeviceDisconnectionBehavior; } });
11
- const ExpoAudioStreamModule_1 = __importDefault(require("./ExpoAudioStreamModule"));
12
- // Default device fallback for web and unsupported platforms
13
- const DEFAULT_DEVICE = {
14
- id: 'default',
15
- name: 'Default Microphone',
16
- type: 'builtin_mic',
17
- isDefault: true,
18
- isAvailable: true,
19
- capabilities: {
20
- sampleRates: [16000, 44100, 48000],
21
- channelCounts: [1, 2],
22
- bitDepths: [16, 24, 32],
23
- hasEchoCancellation: true,
24
- hasNoiseSuppression: true,
25
- hasAutomaticGainControl: true,
26
- },
27
- };
28
- // Helper function to map raw object to AudioDevice interface
29
- // This handles potential inconsistencies from the native module
30
- function mapRawDeviceToAudioDevice(rawDevice) {
31
- const capabilities = rawDevice.capabilities || {};
32
- return {
33
- id: rawDevice.id || 'unknown',
34
- name: rawDevice.name || 'Unknown Device',
35
- type: rawDevice.type || 'unknown',
36
- isDefault: rawDevice.isDefault || false,
37
- isAvailable: rawDevice.isAvailable !== undefined ? rawDevice.isAvailable : true, // Default to true if undefined
38
- capabilities: {
39
- sampleRates: capabilities.sampleRates || [16000, 44100, 48000], // Provide defaults
40
- channelCounts: capabilities.channelCounts || [1, 2],
41
- bitDepths: capabilities.bitDepths || [16, 24, 32],
42
- hasEchoCancellation: capabilities.hasEchoCancellation,
43
- hasNoiseSuppression: capabilities.hasNoiseSuppression,
44
- hasAutomaticGainControl: capabilities.hasAutomaticGainControl,
45
- },
46
- };
47
- }
48
- /**
49
- * Class that provides a cross-platform API for managing audio input devices
50
- *
51
- * EVENT API SPECIFICATION:
52
- * ========================
53
- *
54
- * Device Events (deviceChangedEvent):
55
- * ```
56
- * {
57
- * type: "deviceConnected" | "deviceDisconnected",
58
- * deviceId: string
59
- * }
60
- * ```
61
- *
62
- * Recording Interruption Events (recordingInterruptedEvent):
63
- * ```
64
- * {
65
- * reason: "userPaused" | "userResumed" | "audioFocusLoss" | "audioFocusGain" |
66
- * "deviceFallback" | "deviceSwitchFailed" | "phoneCall" | "phoneCallEnded",
67
- * isPaused: boolean,
68
- * timestamp: number
69
- * }
70
- * ```
71
- *
72
- * NOTE: Device events use "type" field, interruption events use "reason" field.
73
- * This is intentional to distinguish between different event categories.
74
- */
75
- class AudioDeviceManager {
76
- eventEmitter;
77
- currentDeviceId = null;
78
- availableDevices = [];
79
- deviceChangeListeners = new Set();
80
- webDeviceChangeHandler;
81
- lastRefreshTime = 0;
82
- refreshInProgress = false;
83
- refreshDebounceMs = 500; // Minimum 500ms between refreshes
84
- logger;
85
- // Track temporarily disconnected devices
86
- temporarilyDisconnectedDevices = new Set();
87
- disconnectionTimeouts = new Map();
88
- DISCONNECTION_TIMEOUT_MS = 5000; // 5 seconds
89
- constructor(options) {
90
- this.eventEmitter = new expo_modules_core_1.EventEmitter(ExpoAudioStreamModule_1.default);
91
- this.logger = options?.logger;
92
- // Set up device event listeners for all platforms immediately
93
- this.setupDeviceEventListeners();
94
- }
95
- /**
96
- * Set up device event listeners for the current platform
97
- */
98
- setupDeviceEventListeners() {
99
- if (react_native_1.Platform.OS === 'web') {
100
- this.setupWebDeviceChangeListener();
101
- }
102
- else {
103
- this.setupNativeDeviceEventListener();
104
- }
105
- }
106
- /**
107
- * Set up native device event listener for iOS/Android
108
- */
109
- setupNativeDeviceEventListener() {
110
- // Store the last event type to avoid duplicates
111
- let lastEventType = null;
112
- let lastEventTime = 0;
113
- this.eventEmitter.addListener('deviceChangedEvent', (event) => {
114
- // Skip processing duplicate events that occur too close together
115
- const now = Date.now();
116
- const isSimilarEvent = lastEventType === event.type &&
117
- now - lastEventTime < this.refreshDebounceMs;
118
- if (isSimilarEvent) {
119
- this.logger?.debug(`Skipping similar device event (${event.type}) received too soon`);
120
- return;
121
- }
122
- // Update the last event tracking
123
- lastEventType = event.type;
124
- lastEventTime = now;
125
- // Only refresh on meaningful events
126
- if (event.type === 'deviceConnected' ||
127
- event.type === 'deviceDisconnected' ||
128
- event.type === 'routeChanged') {
129
- this.logger?.debug(`Processing device event: ${event.type}`);
130
- // Force refresh for device events to ensure fresh data
131
- this.forceRefreshDevices();
132
- }
133
- });
134
- this.logger?.debug('Native device event listener set up');
135
- }
136
- /**
137
- * Initialize the device manager with a logger
138
- * @param logger A logger instance that implements the ConsoleLike interface
139
- * @returns The manager instance for chaining
140
- */
141
- initWithLogger(logger) {
142
- this.setLogger(logger);
143
- return this;
144
- }
145
- /**
146
- * Set the logger instance
147
- * @param logger A logger instance that implements the ConsoleLike interface
148
- */
149
- setLogger(logger) {
150
- this.logger = logger;
151
- }
152
- /**
153
- * Initialize or reinitialize device detection
154
- * Useful for restarting device detection if initial setup failed
155
- */
156
- initializeDeviceDetection() {
157
- this.logger?.debug('Initializing device detection...');
158
- // Clean up existing listeners first
159
- if (react_native_1.Platform.OS === 'web' && this.webDeviceChangeHandler) {
160
- if (typeof navigator !== 'undefined' && navigator.mediaDevices) {
161
- navigator.mediaDevices.removeEventListener('devicechange', this.webDeviceChangeHandler);
162
- }
163
- this.webDeviceChangeHandler = undefined;
164
- }
165
- // Re-setup device event listeners
166
- this.setupDeviceEventListeners();
167
- }
168
- /**
169
- * Get the current logger instance
170
- * @returns The logger instance or undefined if not set
171
- */
172
- getLogger() {
173
- return this.logger;
174
- }
175
- /**
176
- * Get all available audio input devices
177
- * @param options Optional settings to force refresh the device list. Can include a refresh flag.
178
- * @returns Promise resolving to an array of audio devices conforming to AudioDevice interface
179
- */
180
- async getAvailableDevices(options) {
181
- try {
182
- if (react_native_1.Platform.OS === 'web') {
183
- this.availableDevices = await this.getWebAudioDevices();
184
- }
185
- else if (ExpoAudioStreamModule_1.default.getAvailableInputDevices) {
186
- // Expecting an array of raw device objects from native
187
- const rawDevices = await ExpoAudioStreamModule_1.default.getAvailableInputDevices(options);
188
- // Map raw objects to the AudioDevice interface
189
- this.availableDevices = rawDevices.map(mapRawDeviceToAudioDevice);
190
- }
191
- else {
192
- // Fallback for unsupported platforms
193
- this.availableDevices = [DEFAULT_DEVICE];
194
- }
195
- return this.availableDevices;
196
- }
197
- catch (error) {
198
- this.logger?.error('Failed to get available devices:', error);
199
- this.availableDevices = [DEFAULT_DEVICE]; // Ensure state is updated on error
200
- return this.availableDevices;
201
- }
202
- }
203
- /**
204
- * Get the currently selected audio input device
205
- * @returns Promise resolving to the current device (conforming to AudioDevice) or null
206
- */
207
- async getCurrentDevice() {
208
- try {
209
- if (react_native_1.Platform.OS === 'web') {
210
- if (!this.currentDeviceId) {
211
- // On web, return the typed default device if nothing is selected
212
- return DEFAULT_DEVICE;
213
- }
214
- // Refresh web devices to ensure the current one is up-to-date
215
- const webDevices = await this.getWebAudioDevices();
216
- return (webDevices.find((d) => d.id === this.currentDeviceId) ||
217
- DEFAULT_DEVICE // Fallback to default if current ID not found
218
- );
219
- }
220
- else if (ExpoAudioStreamModule_1.default.getCurrentInputDevice) {
221
- // Expecting a single raw device object or null from native
222
- const rawDevice = await ExpoAudioStreamModule_1.default.getCurrentInputDevice();
223
- // Map to AudioDevice interface if not null
224
- return rawDevice ? mapRawDeviceToAudioDevice(rawDevice) : null;
225
- }
226
- else {
227
- // Fallback for unsupported platforms
228
- return DEFAULT_DEVICE;
229
- }
230
- }
231
- catch (error) {
232
- this.logger?.error('Failed to get current device:', error);
233
- return DEFAULT_DEVICE; // Return default on error
234
- }
235
- }
236
- /**
237
- * Select a specific audio input device for recording
238
- * @param deviceId The ID of the device to select
239
- * @returns Promise resolving to a boolean indicating success
240
- */
241
- async selectDevice(deviceId) {
242
- try {
243
- let success = false;
244
- if (react_native_1.Platform.OS === 'web') {
245
- // Check if the device exists before setting it
246
- const devices = await this.getWebAudioDevices();
247
- if (devices.some((d) => d.id === deviceId)) {
248
- this.currentDeviceId = deviceId;
249
- success = true;
250
- }
251
- else {
252
- this.logger?.warn(`Web: Device with ID ${deviceId} not found.`);
253
- success = false;
254
- }
255
- }
256
- else if (ExpoAudioStreamModule_1.default.selectInputDevice) {
257
- success =
258
- await ExpoAudioStreamModule_1.default.selectInputDevice(deviceId);
259
- if (success) {
260
- this.currentDeviceId = deviceId;
261
- }
262
- }
263
- // Refresh devices after selection attempt to update state
264
- await this.refreshDevices();
265
- return success;
266
- }
267
- catch (error) {
268
- this.logger?.error('Failed to select device:', error);
269
- await this.refreshDevices(); // Refresh even on error
270
- return false;
271
- }
272
- }
273
- /**
274
- * Reset to the default audio input device
275
- * @returns Promise resolving to a boolean indicating success
276
- */
277
- async resetToDefaultDevice() {
278
- try {
279
- let success = false;
280
- if (react_native_1.Platform.OS === 'web') {
281
- this.currentDeviceId = 'default';
282
- success = true;
283
- }
284
- else if (ExpoAudioStreamModule_1.default.resetToDefaultDevice) {
285
- success = await ExpoAudioStreamModule_1.default.resetToDefaultDevice();
286
- if (success) {
287
- this.currentDeviceId = null;
288
- }
289
- }
290
- // Refresh devices after reset attempt
291
- await this.refreshDevices();
292
- return success;
293
- }
294
- catch (error) {
295
- this.logger?.error('Failed to reset to default device:', error);
296
- await this.refreshDevices(); // Refresh even on error
297
- return false;
298
- }
299
- }
300
- /**
301
- * Register a listener for device changes
302
- * @param listener Function to call when devices change (receives AudioDevice[])
303
- * @returns Function to remove the listener
304
- */
305
- addDeviceChangeListener(listener) {
306
- this.deviceChangeListeners.add(listener);
307
- // Immediately call listener with current devices if available
308
- if (this.availableDevices.length > 0) {
309
- listener([...this.availableDevices]);
310
- }
311
- // Return a function to remove the listener
312
- return () => {
313
- this.deviceChangeListeners.delete(listener);
314
- };
315
- }
316
- /**
317
- * Mark a device as temporarily disconnected (for UI filtering)
318
- * @param deviceId The ID of the device that was disconnected
319
- * @param notify Whether to notify listeners immediately (default: true)
320
- */
321
- markDeviceAsDisconnected(deviceId, notify = true) {
322
- this.logger?.debug(`Marking device ${deviceId} as temporarily disconnected`);
323
- // Clear any existing timeout for this device
324
- const existingTimeout = this.disconnectionTimeouts.get(deviceId);
325
- if (existingTimeout) {
326
- clearTimeout(existingTimeout);
327
- }
328
- // Add to disconnected set
329
- this.temporarilyDisconnectedDevices.add(deviceId);
330
- // Set timeout to remove from disconnected set
331
- const timeout = setTimeout(() => {
332
- this.logger?.debug(`Reconnection timeout expired for device ${deviceId}`);
333
- this.temporarilyDisconnectedDevices.delete(deviceId);
334
- this.disconnectionTimeouts.delete(deviceId);
335
- // Refresh devices to show the device again if it's still available
336
- this.forceRefreshDevices();
337
- }, this.DISCONNECTION_TIMEOUT_MS);
338
- this.disconnectionTimeouts.set(deviceId, timeout);
339
- // Only notify listeners if requested
340
- if (notify) {
341
- this.notifyListeners();
342
- }
343
- }
344
- /**
345
- * Mark a device as reconnected (remove from disconnected set)
346
- * @param deviceId The ID of the device that was reconnected
347
- */
348
- markDeviceAsReconnected(deviceId) {
349
- this.logger?.debug(`Marking device ${deviceId} as reconnected`);
350
- // Clear timeout and remove from disconnected set
351
- const timeout = this.disconnectionTimeouts.get(deviceId);
352
- if (timeout) {
353
- clearTimeout(timeout);
354
- this.disconnectionTimeouts.delete(deviceId);
355
- }
356
- this.temporarilyDisconnectedDevices.delete(deviceId);
357
- // Notify listeners with updated device list
358
- this.notifyListeners();
359
- }
360
- /**
361
- * Get filtered device list (excluding temporarily disconnected devices)
362
- * @returns Array of available devices excluding temporarily disconnected ones
363
- */
364
- getFilteredDevices() {
365
- if (this.temporarilyDisconnectedDevices.size === 0) {
366
- return [...this.availableDevices];
367
- }
368
- const filtered = this.availableDevices.filter((device) => !this.temporarilyDisconnectedDevices.has(device.id));
369
- this.logger?.debug(`Filtered ${this.availableDevices.length - filtered.length} temporarily disconnected devices. ` +
370
- `Showing ${filtered.length} devices.`);
371
- return filtered;
372
- }
373
- /**
374
- * Get the raw device list (including temporarily disconnected devices)
375
- * @returns Array of all available devices from native layer
376
- */
377
- getRawDevices() {
378
- return [...this.availableDevices];
379
- }
380
- /**
381
- * Get the IDs of temporarily disconnected devices
382
- * @returns Set of device IDs that are temporarily hidden from UI
383
- */
384
- getTemporarilyDisconnectedDeviceIds() {
385
- return new Set(this.temporarilyDisconnectedDevices);
386
- }
387
- /**
388
- * Clean up timeouts and listeners (useful for testing or cleanup)
389
- */
390
- cleanup() {
391
- // Clear all disconnection timeouts
392
- this.disconnectionTimeouts.forEach((timeout) => clearTimeout(timeout));
393
- this.disconnectionTimeouts.clear();
394
- this.temporarilyDisconnectedDevices.clear();
395
- // Clear device change listeners
396
- this.deviceChangeListeners.clear();
397
- // Clean up web device listener
398
- if (react_native_1.Platform.OS === 'web' && this.webDeviceChangeHandler) {
399
- if (typeof navigator !== 'undefined' && navigator.mediaDevices) {
400
- navigator.mediaDevices.removeEventListener('devicechange', this.webDeviceChangeHandler);
401
- }
402
- this.webDeviceChangeHandler = undefined;
403
- }
404
- this.logger?.debug('AudioDeviceManager cleanup completed');
405
- }
406
- /**
407
- * Force refresh devices without debouncing (for device events)
408
- * @returns Promise resolving to the updated device list (AudioDevice[])
409
- */
410
- async forceRefreshDevices() {
411
- this.logger?.debug('Force refreshing devices (bypassing debounce)...');
412
- this.refreshInProgress = true;
413
- try {
414
- // Force fetch the latest devices from native layer
415
- const devices = await this.getAvailableDevices({ refresh: true });
416
- // Update internal state
417
- this.availableDevices = devices;
418
- // Notify listeners with fresh data
419
- this.notifyListeners();
420
- this.lastRefreshTime = Date.now();
421
- return devices;
422
- }
423
- catch (error) {
424
- this.logger?.error('Error during forceRefreshDevices:', error);
425
- return this.availableDevices;
426
- }
427
- finally {
428
- this.refreshInProgress = false;
429
- this.logger?.debug('Force refresh finished.');
430
- }
431
- }
432
- /**
433
- * Refresh the list of available devices with debouncing and notify listeners.
434
- * @returns Promise resolving to the updated device list (AudioDevice[])
435
- */
436
- async refreshDevices() {
437
- const now = Date.now();
438
- if (this.refreshInProgress) {
439
- this.logger?.debug('Refresh already in progress, skipping');
440
- return this.availableDevices;
441
- }
442
- // Always allow refresh if forced by native event or longer than 2s debounce
443
- const timeSinceLastRefresh = now - this.lastRefreshTime;
444
- const shouldDebounce = timeSinceLastRefresh < this.refreshDebounceMs &&
445
- timeSinceLastRefresh < 2000;
446
- if (shouldDebounce) {
447
- this.logger?.debug(`Refresh debounced, skipping (last refresh was ${timeSinceLastRefresh}ms ago)`);
448
- return this.availableDevices;
449
- }
450
- this.logger?.debug('Refreshing devices...');
451
- this.refreshInProgress = true;
452
- try {
453
- // Fetch the latest devices; getAvailableDevices handles mapping now
454
- const devices = await this.getAvailableDevices({ refresh: true });
455
- // availableDevices state is updated within getAvailableDevices
456
- this.notifyListeners(); // Notify listeners with the updated list
457
- this.lastRefreshTime = Date.now();
458
- return devices; // Return the fetched & mapped list
459
- }
460
- catch (error) {
461
- this.logger?.error('Error during refreshDevices:', error);
462
- return this.availableDevices; // Return potentially stale list on error
463
- }
464
- finally {
465
- this.refreshInProgress = false;
466
- this.logger?.debug('Refresh finished.');
467
- }
468
- }
469
- /**
470
- * Get audio input devices using the Web Audio API
471
- * @returns Promise resolving to an array of AudioDevice objects
472
- */
473
- async getWebAudioDevices() {
474
- if (typeof navigator === 'undefined' ||
475
- !navigator.mediaDevices ||
476
- !navigator.mediaDevices.enumerateDevices) {
477
- return [DEFAULT_DEVICE];
478
- }
479
- try {
480
- const permissionStatus = await this.checkMicrophonePermission();
481
- if (permissionStatus === 'denied') {
482
- return [
483
- {
484
- ...DEFAULT_DEVICE,
485
- name: 'Microphone Access Denied',
486
- isAvailable: false,
487
- },
488
- ];
489
- }
490
- if (permissionStatus !== 'granted') {
491
- try {
492
- // Requesting stream often reveals device labels
493
- await navigator.mediaDevices.getUserMedia({ audio: true });
494
- }
495
- catch (error) {
496
- this.logger?.warn('Microphone permission request failed:', error);
497
- return [
498
- {
499
- ...DEFAULT_DEVICE,
500
- name: 'Microphone Access Required',
501
- isAvailable: false,
502
- },
503
- ];
504
- }
505
- }
506
- const devices = await navigator.mediaDevices.enumerateDevices();
507
- const audioInputDevices = devices
508
- .filter((device) => device.kind === 'audioinput')
509
- .map((device) => this.mapWebDeviceToAudioDevice(device));
510
- const hasUnlabeledDevices = audioInputDevices.some((device) => !device.name || device.name.startsWith('Microphone '));
511
- let finalDevices = audioInputDevices;
512
- if (hasUnlabeledDevices && this.isSafariOrIOS()) {
513
- finalDevices = this.enhanceDevicesForSafari(audioInputDevices);
514
- }
515
- if (finalDevices.length === 0) {
516
- finalDevices = [DEFAULT_DEVICE];
517
- }
518
- this.availableDevices = finalDevices; // Update internal state
519
- return finalDevices;
520
- }
521
- catch (error) {
522
- this.logger?.error('Failed to enumerate web audio devices:', error);
523
- this.availableDevices = [DEFAULT_DEVICE]; // Update state on error
524
- return this.availableDevices;
525
- }
526
- }
527
- /**
528
- * Check the current microphone permission status
529
- * @returns Permission state ('prompt', 'granted', or 'denied')
530
- */
531
- async checkMicrophonePermission() {
532
- if (!navigator.permissions || !navigator.permissions.query) {
533
- return 'prompt';
534
- }
535
- try {
536
- const permissionStatus = await navigator.permissions.query({
537
- name: 'microphone',
538
- });
539
- permissionStatus.onchange = () => {
540
- // Refresh devices when permission changes
541
- this.refreshDevices();
542
- };
543
- return permissionStatus.state;
544
- }
545
- catch (error) {
546
- this.logger?.warn('Permission query not supported:', error);
547
- return 'prompt';
548
- }
549
- }
550
- /**
551
- * Setup listener for device changes in web environment
552
- */
553
- setupWebDeviceChangeListener() {
554
- if (typeof navigator === 'undefined' ||
555
- !navigator.mediaDevices ||
556
- this.webDeviceChangeHandler // Avoid adding multiple listeners
557
- ) {
558
- this.logger?.debug('Web device change listener not available or already set up');
559
- return;
560
- }
561
- try {
562
- this.webDeviceChangeHandler = () => {
563
- this.logger?.debug('Web device change detected, refreshing device list');
564
- // Force refresh to get immediate updates
565
- this.forceRefreshDevices();
566
- };
567
- navigator.mediaDevices.addEventListener('devicechange', this.webDeviceChangeHandler);
568
- this.logger?.debug('Web device change listener successfully set up');
569
- }
570
- catch (error) {
571
- this.logger?.warn('Failed to set up web device change listener:', error);
572
- this.webDeviceChangeHandler = undefined;
573
- }
574
- }
575
- /**
576
- * Check if the current browser is Safari or iOS WebKit
577
- */
578
- isSafariOrIOS() {
579
- if (typeof navigator === 'undefined')
580
- return false;
581
- const ua = navigator.userAgent;
582
- return (/^((?!chrome|android).)*safari/i.test(ua) ||
583
- /iPad|iPhone|iPod/.test(ua) ||
584
- (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1));
585
- }
586
- /**
587
- * Create enhanced device information for Safari and privacy-restricted browsers
588
- * @param devices Array of AudioDevice objects, potentially unlabeled
589
- * @returns Array of enhanced AudioDevice objects
590
- */
591
- enhanceDevicesForSafari(devices) {
592
- const defaultDevice = devices.find((d) => d.isDefault);
593
- if (devices.length <= 1) {
594
- // Return a typed default device
595
- return [
596
- {
597
- id: defaultDevice?.id || 'default',
598
- name: 'Microphone (Browser Managed)',
599
- type: 'builtin_mic',
600
- isDefault: true,
601
- isAvailable: true,
602
- capabilities: defaultDevice?.capabilities ||
603
- DEFAULT_DEVICE.capabilities,
604
- },
605
- ];
606
- }
607
- // Provide more descriptive names for unlabeled devices
608
- return devices.map((device, index) => {
609
- if (!device.name || device.name.startsWith('Microphone ')) {
610
- const deviceTypes = [
611
- 'Built-in Microphone',
612
- 'External Microphone',
613
- 'Headset Microphone',
614
- ];
615
- const typeName = deviceTypes[index % deviceTypes.length];
616
- return {
617
- ...device,
618
- name: device.isDefault ? `${typeName} (Default)` : typeName,
619
- };
620
- }
621
- return device;
622
- });
623
- }
624
- /**
625
- * Map a Web MediaDeviceInfo to our AudioDevice format
626
- * @param device The MediaDeviceInfo object from the browser
627
- * @returns An object conforming to the AudioDevice interface
628
- */
629
- mapWebDeviceToAudioDevice(device) {
630
- const isDefault = device.deviceId === 'default';
631
- const deviceType = this.inferDeviceType(device.label || '');
632
- // Provide reasonable default capabilities for web devices
633
- const defaultWebCapabilities = {
634
- sampleRates: [16000, 44100, 48000],
635
- channelCounts: [1, 2],
636
- bitDepths: [16, 32], // Web Audio uses float32, common PCM might be 16/32
637
- hasEchoCancellation: true, // Often handled by browser
638
- hasNoiseSuppression: true, // Often handled by browser
639
- hasAutomaticGainControl: true, // Often handled by browser
640
- };
641
- return {
642
- id: device.deviceId,
643
- name: device.label || `Microphone ${device.deviceId.substring(0, 8)}`,
644
- type: deviceType,
645
- isDefault,
646
- isAvailable: true, // Assume available if enumerated
647
- capabilities: defaultWebCapabilities,
648
- };
649
- }
650
- /**
651
- * Try to infer the device type from its name
652
- * @param deviceName The label of the device
653
- * @returns A string representing the inferred device type
654
- */
655
- inferDeviceType(deviceName) {
656
- const name = deviceName.toLowerCase();
657
- if (name.includes('bluetooth') || name.includes('airpods'))
658
- return 'bluetooth';
659
- if (name.includes('usb'))
660
- return 'usb';
661
- if (name.includes('headphone') || name.includes('headset')) {
662
- return name.includes('wired') ? 'wired_headset' : 'wired_headphones';
663
- }
664
- if (name.includes('speaker'))
665
- return 'speaker';
666
- return 'builtin_mic'; // Default assumption
667
- }
668
- /**
669
- * Notify all registered listeners about device changes.
670
- */
671
- notifyListeners() {
672
- // Pass a copy of the filtered devices array to listeners
673
- const devicesCopy = this.getFilteredDevices();
674
- this.logger?.debug(`Notifying ${this.deviceChangeListeners.size} listeners with ${devicesCopy.length} devices ` +
675
- `(${this.temporarilyDisconnectedDevices.size} temporarily hidden)`);
676
- this.deviceChangeListeners.forEach((listener) => {
677
- try {
678
- listener(devicesCopy);
679
- }
680
- catch (error) {
681
- this.logger?.error('Error in device change listener:', error);
682
- }
683
- });
684
- }
685
- }
686
- exports.AudioDeviceManager = AudioDeviceManager;
687
- // Create and export the singleton instance
688
- exports.audioDeviceManager = new AudioDeviceManager();
689
- //# sourceMappingURL=AudioDeviceManager.js.map