diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ed0c23..9b33c9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.4.1 + +* fixed microphone gain capability detection so it is only registered when the device exposes the required characteristic. + ## 2.4.0 * added audio response capability support for OpenEarable V2 devices. diff --git a/example/pubspec.lock b/example/pubspec.lock index 4c3f371..4539e62 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -414,7 +414,7 @@ packages: path: ".." relative: true source: path - version: "2.4.0" + version: "2.4.1" open_earable_protocols: dependency: transitive description: diff --git a/lib/src/models/devices/open_earable_factory.dart b/lib/src/models/devices/open_earable_factory.dart index a5ca10f..a1d82b0 100644 --- a/lib/src/models/devices/open_earable_factory.dart +++ b/lib/src/models/devices/open_earable_factory.dart @@ -16,6 +16,7 @@ import '../capabilities/audio_mode_manager.dart'; import '../capabilities/audio_response_manager.dart'; import '../capabilities/fota_capability.dart'; import '../capabilities/fota_slot_info_capability.dart'; +import '../capabilities/microphone_gain_manager.dart'; import '../capabilities/power_saving_mode_manager.dart'; import '../capabilities/sensor.dart'; import '../capabilities/sensor_configuration.dart'; @@ -28,6 +29,7 @@ import 'discovered_device.dart'; import 'open_earable_v1.dart'; import 'open_earable_v2.dart'; import 'open_earable_v2_audio_response_manager.dart'; +import 'open_earable_v2_microphone_gain_manager.dart'; import 'wearable.dart'; import '../../fota/firmware_slot_manager_impl.dart'; @@ -130,6 +132,18 @@ class OpenEarableFactory extends WearableFactory { ), ); } + if (await bleManager!.hasCharacteristic( + deviceId: device.id, + serviceId: OpenEarableV2MicrophoneGainManager.serviceUuid, + characteristicId: OpenEarableV2MicrophoneGainManager.characteristicUuid, + )) { + wearable.registerCapability( + OpenEarableV2MicrophoneGainManager( + bleManager: bleManager!, + deviceId: device.id, + ), + ); + } if (await bleManager!.hasService( deviceId: device.id, serviceId: mcuMgrSmpServiceUuid, diff --git a/lib/src/models/devices/open_earable_v2.dart b/lib/src/models/devices/open_earable_v2.dart index bde6e57..ad3a250 100644 --- a/lib/src/models/devices/open_earable_v2.dart +++ b/lib/src/models/devices/open_earable_v2.dart @@ -33,9 +33,6 @@ const String _micSelectCharacteristicUuid = "0x1410df97-5f68-4ebb-a7c7-5e0fb9ae7557"; const String _audioModeCharacteristicUuid = "0x1410df96-5f68-4ebb-a7c7-5e0fb9ae7557"; -const String _dmicGainCharacteristicUuid = - "1410df99-5f68-4ebb-a7c7-5e0fb9ae7557"; - const String _buttonServiceUuid = "29c10bdc-4773-11ee-be56-0242ac120002"; const String _buttonCharacteristicUuid = "29c10f38-4773-11ee-be56-0242ac120002"; @@ -78,7 +75,6 @@ class OpenEarableV2 extends BluetoothWearable DeviceFirmwareVersion, DeviceHardwareVersion, MicrophoneManager, - MicrophoneGainManager, AudioModeManager, EdgeRecorderManager, ButtonManager, @@ -489,38 +485,6 @@ class OpenEarableV2 extends BluetoothWearable return availableMicrophones.firstWhere((mic) => mic.id == microphoneId); } - // MARK: MicrophoneGainManager - - @override - Future getMicrophoneGain() async { - final gainBytes = await bleManager.read( - deviceId: deviceId, - serviceId: _audioConfigServiceUuid, - characteristicId: _dmicGainCharacteristicUuid, - ); - - if (gainBytes.length != 2) { - throw StateError( - 'Microphone gain characteristic expected 2 values, but got ${gainBytes.length}', - ); - } - - return MicrophoneGain( - outerRegister: gainBytes[0], - innerRegister: gainBytes[1], - ); - } - - @override - Future setMicrophoneGain(MicrophoneGain gain) { - return bleManager.write( - deviceId: deviceId, - serviceId: _audioConfigServiceUuid, - characteristicId: _dmicGainCharacteristicUuid, - byteData: [gain.outerRegister, gain.innerRegister], - ); - } - // MARK: AudioModeManager @override diff --git a/lib/src/models/devices/open_earable_v2_microphone_gain_manager.dart b/lib/src/models/devices/open_earable_v2_microphone_gain_manager.dart new file mode 100644 index 0000000..085bc40 --- /dev/null +++ b/lib/src/models/devices/open_earable_v2_microphone_gain_manager.dart @@ -0,0 +1,55 @@ +import '../../managers/ble_gatt_manager.dart'; +import '../capabilities/microphone_gain_manager.dart'; + +/// Microphone gain implementation for OpenEarable V2 devices that expose the +/// optional DMIC gain characteristic. +class OpenEarableV2MicrophoneGainManager implements MicrophoneGainManager { + /// UUID of the OpenEarable V2 audio configuration service. + static const String serviceUuid = '1410df95-5f68-4ebb-a7c7-5e0fb9ae7557'; + + /// UUID of the optional DMIC gain characteristic. + static const String characteristicUuid = + '1410df99-5f68-4ebb-a7c7-5e0fb9ae7557'; + + /// Creates a microphone gain manager backed by [bleManager]. + const OpenEarableV2MicrophoneGainManager({ + required this.bleManager, + required this.deviceId, + }); + + /// BLE manager used to communicate with the device. + final BleGattManager bleManager; + + /// Identifier of the OpenEarable device. + final String deviceId; + + @override + Future getMicrophoneGain() async { + final gainBytes = await bleManager.read( + deviceId: deviceId, + serviceId: serviceUuid, + characteristicId: characteristicUuid, + ); + + if (gainBytes.length != 2) { + throw StateError( + 'Microphone gain characteristic expected 2 values, but got ${gainBytes.length}', + ); + } + + return MicrophoneGain( + outerRegister: gainBytes[0], + innerRegister: gainBytes[1], + ); + } + + @override + Future setMicrophoneGain(MicrophoneGain gain) { + return bleManager.write( + deviceId: deviceId, + serviceId: serviceUuid, + characteristicId: characteristicUuid, + byteData: [gain.outerRegister, gain.innerRegister], + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index ffac47f..b81f405 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: open_earable_flutter description: This package provides functionality for interacting with OpenEarable devices. Control LED colors, control audio, and access raw sensor data. -version: 2.4.0 +version: 2.4.1 repository: https://github.com/OpenEarable/open_earable_flutter/tree/main platforms: