@mentra/bluetooth-sdk 0.1.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.
- package/README.md +278 -0
- package/android/build.gradle +167 -0
- package/android/lc3Lib/CMakeLists.txt +6 -0
- package/android/lc3Lib/build.gradle +109 -0
- package/android/lc3Lib/proguard-rules.pro +33 -0
- package/android/lc3Lib/src/main/AndroidManifest.xml +2 -0
- package/android/lc3Lib/src/main/cpp/CMakeLists.txt +8 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/CMakeLists.txt +30 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/CMakeLists.txt +7 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/ogg_opus_encoder.cc +96 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/ogg_opus_encoder.h +53 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/Makefile.am +6 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/config_types.h +26 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/config_types.h.in +26 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/ogg.h +209 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/os_types.h +158 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus.h +981 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_custom.h +342 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_defines.h +799 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_multistream.h +660 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_projection.h +568 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_types.h +166 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/ogg_opus_encoder.cc +268 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/ogg_opus_encoder.h +115 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/opus_tools/opus_header.h +59 -0
- package/android/lc3Lib/src/main/cpp/liblc3/CMakeLists.txt +38 -0
- package/android/lc3Lib/src/main/cpp/liblc3/include/lc3.h +309 -0
- package/android/lc3Lib/src/main/cpp/liblc3/include/lc3_private.h +162 -0
- package/android/lc3Lib/src/main/cpp/liblc3/include/rnnoise.h +114 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/CMakeLists.txt +19 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/attdet.c +92 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/attdet.h +44 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bits.c +375 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bits.h +315 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bwdet.c +129 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bwdet.h +69 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/common.h +148 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/energy.c +70 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/energy.h +43 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/fastmath.h +158 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/lc3.c +702 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf.c +893 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf.h +111 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf_arm.h +506 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf_neon.h +281 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/makefile.mk +35 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct.c +452 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct.h +57 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct_neon.h +296 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/meson.build +46 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/plc.c +61 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/plc.h +57 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/sns.c +880 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/sns.h +103 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/spec.c +904 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/spec.h +119 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tables.c +3457 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tables.h +94 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tns.c +457 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tns.h +99 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3.cpp +159 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/_kiss_fft_guts.h +182 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/arch.h +261 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/celt_lpc.c +279 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/celt_lpc.h +59 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/common.h +48 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/compile.sh +3 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/denoise.c +646 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/kiss_fft.c +601 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/kiss_fft.h +203 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/opus_types.h +159 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/pitch.c +526 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/pitch.h +149 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn.c +178 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn.h +69 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_data.c +11051 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_data.h +34 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_reader.c +168 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_train.py +66 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/tansig_table.h +45 -0
- package/android/lc3Lib/src/main/java/com/mentra/lc3Lib/Lc3Cpp.java +38 -0
- package/android/lc3Lib/third_party/CMakeLists.txt +23 -0
- package/android/lc3Lib/third_party/CMakeLists_libogg.txt +18 -0
- package/android/lc3Lib/third_party/CMakeLists_libopus.txt +18 -0
- package/android/lc3Lib/third_party/CMakeLists_opus-tools.txt +23 -0
- package/android/lc3Lib/third_party/opus_tools/src/AUTHORS +5 -0
- package/android/lc3Lib/third_party/opus_tools/src/CMakeLists.txt +4 -0
- package/android/lc3Lib/third_party/opus_tools/src/COPYING +371 -0
- package/android/lc3Lib/third_party/opus_tools/src/ChangeLog +3 -0
- package/android/lc3Lib/third_party/opus_tools/src/Makefile.am +42 -0
- package/android/lc3Lib/third_party/opus_tools/src/Makefile.unix +23 -0
- package/android/lc3Lib/third_party/opus_tools/src/NEWS +0 -0
- package/android/lc3Lib/third_party/opus_tools/src/README +0 -0
- package/android/lc3Lib/third_party/opus_tools/src/autogen.sh +115 -0
- package/android/lc3Lib/third_party/opus_tools/src/configure.ac +293 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/arch.h +239 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/audio-in.c +1046 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/diag_range.c +245 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/diag_range.h +28 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/info_opus.c +320 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/info_opus.h +51 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/lpc.c +157 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/lpc.h +27 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opus_header.c +286 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opus_header.h +59 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opusdec.c +884 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opusenc.c +1021 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opusenc.h +101 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opusinfo.c +639 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opusinfo.h +51 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/os_support.h +167 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/resample.c +1137 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/speex_resampler.h +344 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/stack_alloc.h +115 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/wav_io.c +125 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/wav_io.h +62 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/wave_out.c +223 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/wave_out.h +60 -0
- package/android/settings.gradle +1 -0
- package/android/src/main/AndroidManifest.xml +40 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +528 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +610 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +1616 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +314 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothModels.kt +1710 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +554 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/ObservableStore.kt +68 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/ControllerManager.kt +158 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/R1.kt +934 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/services/Foreground.kt +175 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/services/PhoneMic.kt +1109 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.java +3974 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +3551 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Mach1.java +1327 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.java +6959 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +1655 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraosBle.java +53675 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +202 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +224 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/stt/STTTools.kt +340 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/stt/SherpaOnnxTranscriber.kt +465 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/stt/VadGateSpeechPolicy.kt +221 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/AES.java +106 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/AudioSessionMonitor.kt +189 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/BitmapJavaUtils.java +169 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/BlePhotoUploadService.java +179 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/Constants.kt +44 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/G1Text.kt +436 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/IncidentLogBleRelayNaming.java +29 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/IncidentLogBleUploadService.java +76 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/K900ProtocolUtils.java +791 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/MessageChunker.java +186 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/NexSGCUtils.kt +589 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/PhoneAudioMonitor.kt +303 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/SmartGlassesConnectionState.java +9 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/ByteUtilAudioPlayer.java +655 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/Lc3Player.java +441 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/PCMAudioPlayer.java +431 -0
- package/android/src/main/res/values/strings.xml +4 -0
- package/app.plugin.js +1 -0
- package/build/BluetoothSdk.types.d.ts +498 -0
- package/build/BluetoothSdk.types.d.ts.map +1 -0
- package/build/BluetoothSdk.types.js +23 -0
- package/build/BluetoothSdk.types.js.map +1 -0
- package/build/BluetoothSdkModule.d.ts +71 -0
- package/build/BluetoothSdkModule.d.ts.map +1 -0
- package/build/BluetoothSdkModule.js +106 -0
- package/build/BluetoothSdkModule.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +5 -0
- package/build/index.js.map +1 -0
- package/expo-module.config.json +9 -0
- package/ios/BluetoothSdkModule.swift +665 -0
- package/ios/MentraBluetoothSDK.podspec +77 -0
- package/ios/Packages/CoreObjC/CoreObjC.xcodeproj/project.pbxproj +213 -0
- package/ios/Packages/CoreObjC/PcmConverter.h +22 -0
- package/ios/Packages/CoreObjC/PcmConverter.m +266 -0
- package/ios/Packages/CoreObjC/attdet.c +92 -0
- package/ios/Packages/CoreObjC/attdet.h +44 -0
- package/ios/Packages/CoreObjC/bits.c +375 -0
- package/ios/Packages/CoreObjC/bits.h +315 -0
- package/ios/Packages/CoreObjC/bwdet.c +129 -0
- package/ios/Packages/CoreObjC/bwdet.h +69 -0
- package/ios/Packages/CoreObjC/common.h +151 -0
- package/ios/Packages/CoreObjC/energy.c +70 -0
- package/ios/Packages/CoreObjC/energy.h +43 -0
- package/ios/Packages/CoreObjC/fastmath.h +158 -0
- package/ios/Packages/CoreObjC/lc3.c +704 -0
- package/ios/Packages/CoreObjC/lc3.h +313 -0
- package/ios/Packages/CoreObjC/lc3_cpp.h +283 -0
- package/ios/Packages/CoreObjC/lc3_private.h +163 -0
- package/ios/Packages/CoreObjC/ltpf.c +905 -0
- package/ios/Packages/CoreObjC/ltpf.h +111 -0
- package/ios/Packages/CoreObjC/ltpf_arm.h +506 -0
- package/ios/Packages/CoreObjC/ltpf_neon.h +281 -0
- package/ios/Packages/CoreObjC/makefile.mk +35 -0
- package/ios/Packages/CoreObjC/mdct.c +469 -0
- package/ios/Packages/CoreObjC/mdct.h +57 -0
- package/ios/Packages/CoreObjC/mdct_neon.h +296 -0
- package/ios/Packages/CoreObjC/meson.build +61 -0
- package/ios/Packages/CoreObjC/plc.c +61 -0
- package/ios/Packages/CoreObjC/plc.h +57 -0
- package/ios/Packages/CoreObjC/rnnoise.h +114 -0
- package/ios/Packages/CoreObjC/sns.c +880 -0
- package/ios/Packages/CoreObjC/sns.h +103 -0
- package/ios/Packages/CoreObjC/spec.c +907 -0
- package/ios/Packages/CoreObjC/spec.h +119 -0
- package/ios/Packages/CoreObjC/tables.c +3457 -0
- package/ios/Packages/CoreObjC/tables.h +94 -0
- package/ios/Packages/CoreObjC/tns.c +457 -0
- package/ios/Packages/CoreObjC/tns.h +99 -0
- package/ios/Packages/SherpaOnnx/Model/joiner.onnx +0 -0
- package/ios/Packages/SherpaOnnx/Model/tokens.txt +502 -0
- package/ios/Packages/SherpaOnnx/SherpaOnnx.swift +1659 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/cargs.h +162 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/sherpa-onnx/c-api/c-api.h +1852 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/sherpa-onnx/c-api/cxx-api.h +674 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Info.plist +44 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/libsherpa-onnx.a +0 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/sherpa-onnx.a +0 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/libsherpa-onnx.a +0 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/sherpa-onnx.a +0 -0
- package/ios/Packages/VAD/Common/VAD/VADQuality.swift +41 -0
- package/ios/Packages/VAD/Common/VAD/VADState.swift +26 -0
- package/ios/Packages/VAD/Common/VAD/VADStrategy.swift +29 -0
- package/ios/Packages/VAD/Common/VAD/VADType.swift +14 -0
- package/ios/Packages/VAD/Data/Configuration.swift +68 -0
- package/ios/Packages/VAD/Data/FrameSize.swift +39 -0
- package/ios/Packages/VAD/Data/Record.swift +13 -0
- package/ios/Packages/VAD/Data/Result.swift +22 -0
- package/ios/Packages/VAD/Data/SampleRate.swift +48 -0
- package/ios/Packages/VAD/Silero/Model/silero_vad.onnx +0 -0
- package/ios/Packages/VAD/Silero/SileroVAD.swift +284 -0
- package/ios/Packages/VAD/Silero/SileroVADStrategy.swift +64 -0
- package/ios/Packages/libbz2/module.modulemap +5 -0
- package/ios/Packages/libbz2/shim.h +1 -0
- package/ios/Source/Bridge.swift +353 -0
- package/ios/Source/Bridging-Header.h +16 -0
- package/ios/Source/DeviceManager.swift +1478 -0
- package/ios/Source/DeviceStore.swift +295 -0
- package/ios/Source/MentraBluetoothSDK.swift +2439 -0
- package/ios/Source/ObservableStore.swift +88 -0
- package/ios/Source/PrivacyInfo.xcprivacy +23 -0
- package/ios/Source/controllers/ControllerManager.swift +187 -0
- package/ios/Source/controllers/R1.swift +827 -0
- package/ios/Source/services/PhoneMic.swift +662 -0
- package/ios/Source/sgcs/Frame.swift +651 -0
- package/ios/Source/sgcs/G1.swift +2505 -0
- package/ios/Source/sgcs/G2.swift +3730 -0
- package/ios/Source/sgcs/Mach1.swift +543 -0
- package/ios/Source/sgcs/MentraLive.swift +4708 -0
- package/ios/Source/sgcs/MentraNex.swift +2479 -0
- package/ios/Source/sgcs/SGCManager.swift +243 -0
- package/ios/Source/sgcs/Simulated.swift +270 -0
- package/ios/Source/sgcs/mentraos_ble.pb.swift +3811 -0
- package/ios/Source/stt/STTTools.swift +154 -0
- package/ios/Source/stt/SherpaOnnxTranscriber.swift +401 -0
- package/ios/Source/utils/AudioSessionMonitor.swift +283 -0
- package/ios/Source/utils/Constants.swift +74 -0
- package/ios/Source/utils/Enums.swift +95 -0
- package/ios/Source/utils/G1Text.swift +2067 -0
- package/ios/Source/utils/JSCExperiment.swift +241 -0
- package/ios/Source/utils/MemoryMonitor.swift +44 -0
- package/ios/Source/utils/MessageChunker.swift +164 -0
- package/ios/Source/utils/Models.swift +135 -0
- package/ios/Source/utils/PhoneAudioMonitor.swift +226 -0
- package/ios/Source/utils/TarBz2Extractor.swift +206 -0
- package/package.json +78 -0
- package/plugin/build/index.d.ts +6 -0
- package/plugin/build/index.js +12 -0
- package/plugin/build/withAndroid.d.ts +4 -0
- package/plugin/build/withAndroid.js +80 -0
- package/plugin/build/withIos.d.ts +4 -0
- package/plugin/build/withIos.js +64 -0
- package/src/BluetoothSdk.types.ts +581 -0
- package/src/BluetoothSdkModule.ts +259 -0
- package/src/index.ts +4 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
//
|
|
2
|
+
// AudioSessionMonitor.swift
|
|
3
|
+
// AOS
|
|
4
|
+
//
|
|
5
|
+
// Monitors iOS AVAudioSession for Bluetooth audio device connections
|
|
6
|
+
// Used to detect when Mentra Live glasses are paired/connected for audio
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import AVFoundation
|
|
10
|
+
import Foundation
|
|
11
|
+
import UIKit
|
|
12
|
+
|
|
13
|
+
class AudioSessionMonitor {
|
|
14
|
+
/// Singleton instance
|
|
15
|
+
private static var instance: AudioSessionMonitor?
|
|
16
|
+
|
|
17
|
+
// Current monitoring state
|
|
18
|
+
static var isMonitoring = false
|
|
19
|
+
static var devicePattern: String?
|
|
20
|
+
static var callback: ((Bool, String?) -> Void)?
|
|
21
|
+
|
|
22
|
+
private init() {
|
|
23
|
+
Bridge.log("AudioMonitor: Initialized")
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static func getInstance() -> AudioSessionMonitor {
|
|
27
|
+
if instance == nil {
|
|
28
|
+
instance = AudioSessionMonitor()
|
|
29
|
+
}
|
|
30
|
+
return instance!
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/// Check if AVAudioSession is configured for Bluetooth
|
|
34
|
+
/// Returns true if session allows Bluetooth audio
|
|
35
|
+
/// NOTE: We don't configure the session - PhoneMic.swift handles that when recording
|
|
36
|
+
static func isAudioSessionConfigured() -> Bool {
|
|
37
|
+
let session = AVAudioSession.sharedInstance()
|
|
38
|
+
|
|
39
|
+
// Check if category supports Bluetooth
|
|
40
|
+
let category = session.category
|
|
41
|
+
let supportsBluetooth =
|
|
42
|
+
category == .playAndRecord || category == .record || category == .multiRoute
|
|
43
|
+
|
|
44
|
+
Bridge.log(
|
|
45
|
+
"AudioMonitor: Audio session category: \(category.rawValue), supports BT: \(supportsBluetooth)"
|
|
46
|
+
)
|
|
47
|
+
return supportsBluetooth
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/// Check if a Bluetooth audio device matching the pattern is currently the active audio route
|
|
51
|
+
/// Returns true if device is actively routing audio
|
|
52
|
+
static func isAudioDeviceConnected(devicePattern: String) -> Bool {
|
|
53
|
+
let session = AVAudioSession.sharedInstance()
|
|
54
|
+
let outputs = session.currentRoute.outputs
|
|
55
|
+
|
|
56
|
+
Bridge.log("AudioMonitor: Checking active route, output count: \(outputs.count)")
|
|
57
|
+
for output in outputs {
|
|
58
|
+
Bridge.log("AudioMonitor: - \(output.portName) (type: \(output.portType.rawValue))")
|
|
59
|
+
if output.portType == .bluetoothHFP || output.portType == .bluetoothA2DP {
|
|
60
|
+
if output.portName.localizedCaseInsensitiveContains(devicePattern) {
|
|
61
|
+
Bridge.log("AudioMonitor: ✅ Found active audio device: \(output.portName)")
|
|
62
|
+
return true
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
Bridge.log("AudioMonitor: No active audio device matching '\(devicePattern)'")
|
|
68
|
+
return false
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static func isOtherAudioDeviceConnected(devicePattern: String) -> Bool {
|
|
72
|
+
let connected = isAudioDeviceConnected(devicePattern: devicePattern)
|
|
73
|
+
if connected {
|
|
74
|
+
return false
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// do we have multiple devices connected?
|
|
78
|
+
let session = AVAudioSession.sharedInstance()
|
|
79
|
+
let outputs = session.currentRoute.outputs
|
|
80
|
+
|
|
81
|
+
Bridge.log("AudioMonitor: Checking active route, output count: \(outputs.count)")
|
|
82
|
+
if outputs.count > 1 {
|
|
83
|
+
return true
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return false
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/// Check if a Bluetooth device matching the pattern is paired (appears in availableInputs)
|
|
90
|
+
/// Returns true if device is found (paired), WITHOUT activating it
|
|
91
|
+
/// This avoids switching A2DP music playback to HFP microphone mode
|
|
92
|
+
static func isDevicePaired(devicePattern: String) -> Bool {
|
|
93
|
+
let session = AVAudioSession.sharedInstance()
|
|
94
|
+
|
|
95
|
+
// Check if already active (using A2DP for music or HFP for calls)
|
|
96
|
+
if isAudioDeviceConnected(devicePattern: devicePattern) {
|
|
97
|
+
Bridge.log("AudioMonitor: Device '\(devicePattern)' already active")
|
|
98
|
+
return true
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Try to find in availableInputs (includes paired devices)
|
|
102
|
+
guard let availableInputs = session.availableInputs else {
|
|
103
|
+
Bridge.log("AudioMonitor: ❌ availableInputs is nil")
|
|
104
|
+
return false
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
Bridge.log("AudioMonitor: availableInputs count: \(availableInputs.count)")
|
|
108
|
+
for input in availableInputs {
|
|
109
|
+
Bridge.log("AudioMonitor: - \(input.portName) (type: \(input.portType.rawValue))")
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
let bluetoothInput = availableInputs.first { input in
|
|
113
|
+
input.portType == .bluetoothHFP
|
|
114
|
+
&& input.portName.localizedCaseInsensitiveContains(devicePattern)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if let btInput = bluetoothInput {
|
|
118
|
+
Bridge.log(
|
|
119
|
+
"AudioMonitor: ✅ Found paired device '\(btInput.portName)' (not activating to preserve A2DP)"
|
|
120
|
+
)
|
|
121
|
+
return true
|
|
122
|
+
} else {
|
|
123
|
+
Bridge.log(
|
|
124
|
+
"AudioMonitor: ❌ Bluetooth HFP device '\(devicePattern)' not found in availableInputs"
|
|
125
|
+
)
|
|
126
|
+
return false
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/// Start monitoring for audio route changes
|
|
131
|
+
/// Callback will be called when device matching pattern connects/disconnects
|
|
132
|
+
static func startMonitoring(devicePattern: String, callback: @escaping (Bool, String?) -> Void) {
|
|
133
|
+
guard !isMonitoring else {
|
|
134
|
+
Bridge.log("AudioMonitor: Already monitoring")
|
|
135
|
+
return
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
self.devicePattern = devicePattern
|
|
139
|
+
self.callback = callback
|
|
140
|
+
|
|
141
|
+
// Register for route change notifications
|
|
142
|
+
NotificationCenter.default.addObserver(
|
|
143
|
+
self,
|
|
144
|
+
selector: #selector(handleRouteChange),
|
|
145
|
+
name: AVAudioSession.routeChangeNotification,
|
|
146
|
+
object: nil
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
// Register for app foreground notifications
|
|
150
|
+
// This handles the case where user pairs in Settings and returns to app
|
|
151
|
+
NotificationCenter.default.addObserver(
|
|
152
|
+
self,
|
|
153
|
+
selector: #selector(handleAppBecameActive),
|
|
154
|
+
name: UIApplication.didBecomeActiveNotification,
|
|
155
|
+
object: nil
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
isMonitoring = true
|
|
159
|
+
Bridge.log("AudioMonitor: Started monitoring for '\(devicePattern)'")
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/// Stop monitoring for audio route changes
|
|
163
|
+
static func stopMonitoring() {
|
|
164
|
+
guard isMonitoring else {
|
|
165
|
+
Bridge.log("AudioMonitor: Not currently monitoring")
|
|
166
|
+
return
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
NotificationCenter.default.removeObserver(
|
|
170
|
+
self,
|
|
171
|
+
name: AVAudioSession.routeChangeNotification,
|
|
172
|
+
object: nil
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
NotificationCenter.default.removeObserver(
|
|
176
|
+
self,
|
|
177
|
+
name: UIApplication.didBecomeActiveNotification,
|
|
178
|
+
object: nil
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
AudioSessionMonitor.isMonitoring = false
|
|
182
|
+
AudioSessionMonitor.devicePattern = nil
|
|
183
|
+
AudioSessionMonitor.callback = nil
|
|
184
|
+
|
|
185
|
+
Bridge.log("AudioMonitor: Stopped monitoring")
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
@objc private func handleRouteChange(notification: Notification) {
|
|
189
|
+
guard let userInfo = notification.userInfo,
|
|
190
|
+
let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt,
|
|
191
|
+
let reason = AVAudioSession.RouteChangeReason(rawValue: reasonValue),
|
|
192
|
+
let pattern = AudioSessionMonitor.devicePattern
|
|
193
|
+
else {
|
|
194
|
+
return
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
Bridge.log("AudioMonitor: Route change detected: \(reason.rawValue)")
|
|
198
|
+
|
|
199
|
+
switch reason {
|
|
200
|
+
case .newDeviceAvailable:
|
|
201
|
+
// When a new device becomes available, try to set it as preferred
|
|
202
|
+
// This handles the case where user pairs in Settings and returns to app
|
|
203
|
+
Bridge.log("AudioMonitor: New device available, attempting to activate '\(pattern)'")
|
|
204
|
+
|
|
205
|
+
// Add small delay to let iOS populate availableInputs
|
|
206
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
|
|
207
|
+
if AudioSessionMonitor.isDevicePaired(devicePattern: pattern) {
|
|
208
|
+
let session = AVAudioSession.sharedInstance()
|
|
209
|
+
let deviceName = session.availableInputs?.first(where: {
|
|
210
|
+
$0.portName.localizedCaseInsensitiveContains(pattern)
|
|
211
|
+
})?.portName
|
|
212
|
+
Bridge.log(
|
|
213
|
+
"AudioMonitor: ✅ Successfully detected newly paired device '\(pattern)'"
|
|
214
|
+
)
|
|
215
|
+
AudioSessionMonitor.callback?(true, deviceName)
|
|
216
|
+
} else {
|
|
217
|
+
Bridge.log("AudioMonitor: New device available but not matching '\(pattern)'")
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
case .oldDeviceUnavailable:
|
|
222
|
+
// Check if our device disconnected
|
|
223
|
+
if !AudioSessionMonitor.isAudioDeviceConnected(devicePattern: pattern) {
|
|
224
|
+
Bridge.log("AudioMonitor: Device '\(pattern)' disconnected")
|
|
225
|
+
AudioSessionMonitor.callback?(false, nil)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
default:
|
|
229
|
+
break
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
@objc private static func handleAppBecameActive() {
|
|
234
|
+
guard let pattern = AudioSessionMonitor.devicePattern else { return }
|
|
235
|
+
|
|
236
|
+
Bridge.log("AudioMonitor: App became active, checking for paired device '\(pattern)'")
|
|
237
|
+
|
|
238
|
+
// Don't reconfigure session - it's already configured from when monitoring started
|
|
239
|
+
// Just wait a bit for iOS to update availableInputs after returning from background
|
|
240
|
+
// iOS needs time to populate availableInputs after app foreground
|
|
241
|
+
// Use retry with progressive delays: 100ms, 400ms, 500ms = 1s total
|
|
242
|
+
AudioSessionMonitor.attemptActivateDevice(pattern: pattern, attempt: 0, maxAttempts: 3)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/// Try to detect if the audio device is paired with retry logic
|
|
246
|
+
/// Delays: [100ms, 400ms, 500ms] = 1 second total
|
|
247
|
+
static func attemptActivateDevice(pattern: String, attempt: Int, maxAttempts: Int) {
|
|
248
|
+
// Progressive delays in seconds (total: 1 second)
|
|
249
|
+
let delays: [TimeInterval] = [0.1, 0.4, 0.5]
|
|
250
|
+
|
|
251
|
+
if attempt >= maxAttempts {
|
|
252
|
+
Bridge.log(
|
|
253
|
+
"AudioMonitor: ❌ Failed to find paired device '\(pattern)' after \(maxAttempts) attempts"
|
|
254
|
+
)
|
|
255
|
+
return
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
let delay = attempt < delays.count ? delays[attempt] : 0.5
|
|
259
|
+
|
|
260
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
|
|
261
|
+
Bridge.log(
|
|
262
|
+
"AudioMonitor: Attempt \(attempt + 1)/\(maxAttempts) to detect '\(pattern)'..."
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
if AudioSessionMonitor.isDevicePaired(devicePattern: pattern) {
|
|
266
|
+
let session = AVAudioSession.sharedInstance()
|
|
267
|
+
// Try to get device name from availableInputs
|
|
268
|
+
let deviceName = session.availableInputs?.first(where: {
|
|
269
|
+
$0.portName.localizedCaseInsensitiveContains(pattern)
|
|
270
|
+
})?.portName
|
|
271
|
+
Bridge.log("AudioMonitor: ✅ Found paired device on attempt \(attempt + 1)")
|
|
272
|
+
AudioSessionMonitor.callback?(true, deviceName)
|
|
273
|
+
} else {
|
|
274
|
+
Bridge.log(
|
|
275
|
+
"AudioMonitor: Attempt \(attempt + 1) failed, retrying in \(delays[min(attempt + 1, delays.count - 1)])s..."
|
|
276
|
+
)
|
|
277
|
+
AudioSessionMonitor.attemptActivateDevice(
|
|
278
|
+
pattern: pattern, attempt: attempt + 1, maxAttempts: maxAttempts
|
|
279
|
+
)
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
struct DeviceTypes {
|
|
2
|
+
static let SIMULATED = "Simulated Glasses"
|
|
3
|
+
static let G1 = "Even Realities G1"
|
|
4
|
+
static let G2 = "Even Realities G2"
|
|
5
|
+
static let LIVE = "Mentra Live"
|
|
6
|
+
static let MACH1 = "Mentra Mach1"
|
|
7
|
+
static let Z100 = "Vuzix Z100"
|
|
8
|
+
static let NEX = "Mentra Display"
|
|
9
|
+
static let FRAME = "Brilliant Frame"
|
|
10
|
+
|
|
11
|
+
static let ALL = [
|
|
12
|
+
SIMULATED,
|
|
13
|
+
G1,
|
|
14
|
+
G2,
|
|
15
|
+
MACH1,
|
|
16
|
+
LIVE,
|
|
17
|
+
Z100,
|
|
18
|
+
NEX,
|
|
19
|
+
FRAME,
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
/// Private init to prevent instantiation
|
|
23
|
+
private init() {}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
struct ControllerTypes {
|
|
27
|
+
static let R1 = "Even Realities R1"
|
|
28
|
+
|
|
29
|
+
static let ALL = [
|
|
30
|
+
R1,
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
/// Private init to prevent instantiation
|
|
34
|
+
private init() {}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
struct ConnTypes {
|
|
38
|
+
static let CONNECTING = "CONNECTING"
|
|
39
|
+
static let CONNECTED = "CONNECTED"
|
|
40
|
+
static let DISCONNECTED = "DISCONNECTED"
|
|
41
|
+
static let SCANNING = "SCANNING"
|
|
42
|
+
static let BONDING = "BONDING"
|
|
43
|
+
|
|
44
|
+
/// Private init to prevent instantiation
|
|
45
|
+
private init() {}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
struct MicTypes {
|
|
49
|
+
static let PHONE_INTERNAL = "phone"
|
|
50
|
+
static let GLASSES_CUSTOM = "glasses"
|
|
51
|
+
static let BT_CLASSIC = "btclassic"
|
|
52
|
+
static let BT = "bt"
|
|
53
|
+
|
|
54
|
+
static let ALL = [
|
|
55
|
+
PHONE_INTERNAL,
|
|
56
|
+
GLASSES_CUSTOM,
|
|
57
|
+
BT_CLASSIC,
|
|
58
|
+
BT,
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
/// Private init to prevent instantiation
|
|
62
|
+
private init() {}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
enum MicMap {
|
|
66
|
+
static var map: [String: [String]] = [
|
|
67
|
+
"auto": [
|
|
68
|
+
MicTypes.GLASSES_CUSTOM, MicTypes.PHONE_INTERNAL, MicTypes.BT, MicTypes.BT_CLASSIC,
|
|
69
|
+
],
|
|
70
|
+
"glasses": [MicTypes.GLASSES_CUSTOM],
|
|
71
|
+
"phone": [MicTypes.PHONE_INTERNAL, MicTypes.GLASSES_CUSTOM],
|
|
72
|
+
"bluetooth": [MicTypes.BT, MicTypes.PHONE_INTERNAL, MicTypes.GLASSES_CUSTOM],
|
|
73
|
+
]
|
|
74
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Enums.swift
|
|
3
|
+
// MentraOS_Manager
|
|
4
|
+
//
|
|
5
|
+
// Created by Matthew Fosse on 3/3/25.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
enum CommandResponse: UInt8 {
|
|
11
|
+
case ACK = 0xC9
|
|
12
|
+
case CONTINUE = 0xCB
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
enum Commands: UInt8 {
|
|
16
|
+
case BLE_EXIT_ALL_FUNCTIONS = 0x18
|
|
17
|
+
case BLE_REQ_INIT = 0x4D
|
|
18
|
+
case BLE_REQ_BATTERY = 0x2C
|
|
19
|
+
case BLE_REQ_HEARTBEAT = 0x25
|
|
20
|
+
case BLE_REQ_EVENAI = 0x4E
|
|
21
|
+
case BLE_REQ_TRANSFER_MIC_DATA = 0xF1
|
|
22
|
+
case BLE_REQ_DEVICE_ORDER = 0xF5
|
|
23
|
+
case BLE_REQ_MIC_ON = 0x0E
|
|
24
|
+
case QUICK_NOTE_ADD = 0x1E
|
|
25
|
+
case CRC_CHECK = 0x16
|
|
26
|
+
case BMP_END = 0x20
|
|
27
|
+
case BRIGHTNESS = 0x01
|
|
28
|
+
case WHITELIST = 0x04
|
|
29
|
+
case SILENT_MODE = 0x03
|
|
30
|
+
case DASHBOARD_LAYOUT_COMMAND = 0x26
|
|
31
|
+
case DASHBOARD_SHOW = 0x06
|
|
32
|
+
case HEAD_UP_ANGLE = 0x0B
|
|
33
|
+
case UNK_2 = 0x39
|
|
34
|
+
case UNK_1 = 0x50
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
enum DeviceOrders: UInt8 {
|
|
38
|
+
case DISPLAY_READY = 0x00
|
|
39
|
+
case TRIGGER_CHANGE_PAGE = 0x01
|
|
40
|
+
case TRIGGER_FOR_AI = 0x17
|
|
41
|
+
case TRIGGER_FOR_STOP_RECORDING = 0x18
|
|
42
|
+
case G1_IS_READY = 0x09
|
|
43
|
+
case HEAD_UP = 0x1E
|
|
44
|
+
case HEAD_DOWN = 0x1F
|
|
45
|
+
case SILENCED = 0x04
|
|
46
|
+
case ACTIVATED = 0x05
|
|
47
|
+
case HEAD_UP2 = 0x02
|
|
48
|
+
case HEAD_DOWN2 = 0x03
|
|
49
|
+
case CASE_REMOVED = 0x07
|
|
50
|
+
case CASE_REMOVED2 = 0x06
|
|
51
|
+
case CASE_OPEN = 0x08
|
|
52
|
+
case CASE_CLOSED = 0x0B
|
|
53
|
+
case CASE_CHARGING_STATUS = 0x0E
|
|
54
|
+
case CASE_CHARGE_INFO = 0x0F
|
|
55
|
+
case DOUBLE_TAP = 0x20
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
enum DisplayStatus: UInt8 {
|
|
59
|
+
case NORMAL_TEXT = 0x30
|
|
60
|
+
case FINAL_TEXT = 0x40
|
|
61
|
+
case MANUAL_PAGE = 0x50
|
|
62
|
+
case ERROR_TEXT = 0x60
|
|
63
|
+
case SIMPLE_TEXT = 0x70
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public enum DashboardHeight: UInt8 {
|
|
67
|
+
case position0 = 0x00 // Bottom
|
|
68
|
+
case position1 = 0x01
|
|
69
|
+
case position2 = 0x02
|
|
70
|
+
case position3 = 0x03
|
|
71
|
+
case position4 = 0x04
|
|
72
|
+
case position5 = 0x05
|
|
73
|
+
case position6 = 0x06
|
|
74
|
+
case position7 = 0x07
|
|
75
|
+
case position8 = 0x08 // Top
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public enum DashboardDepth: UInt8 {
|
|
79
|
+
case position0 = 0x00 // Bottom
|
|
80
|
+
case position1 = 0x01
|
|
81
|
+
case position2 = 0x02
|
|
82
|
+
case position3 = 0x03
|
|
83
|
+
case position4 = 0x04
|
|
84
|
+
case position5 = 0x05
|
|
85
|
+
case position6 = 0x06
|
|
86
|
+
case position7 = 0x07
|
|
87
|
+
case position8 = 0x08
|
|
88
|
+
case position9 = 0x09
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public enum DashboardMode: UInt8 {
|
|
92
|
+
case full = 0x00
|
|
93
|
+
case dual = 0x01
|
|
94
|
+
case minimal = 0x02
|
|
95
|
+
}
|