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