From 6d61aabbec9efe5725f9bcb8ba7a5c2d0724adb0 Mon Sep 17 00:00:00 2001 From: Jakub Pyszczak Date: Mon, 31 May 2021 16:56:39 +0200 Subject: [PATCH] [EGD-6514] HSP volume control Bluetooth headset profile volume control introduced. Small refactor on A2DP volume control done. --- module-audio/Audio/VolumeScaler.cpp | 58 ++++++++++--- module-audio/Audio/VolumeScaler.hpp | 31 +++++-- module-audio/Audio/test/unittest_scaler.cpp | 84 ++++++++++++++++--- .../Bluetooth/audio/BluetoothAudioDevice.cpp | 36 +++++--- .../Bluetooth/audio/BluetoothAudioDevice.hpp | 5 +- .../interface/profiles/A2DP/AVRCP.cpp | 2 +- .../Bluetooth/interface/profiles/HSP/HSP.cpp | 14 +++- .../service-audio/AudioServiceAPI.cpp | 9 +- .../service-audio/ServiceAudio.cpp | 28 +++++-- .../service-audio/AudioMessage.hpp | 14 ++++ .../service-audio/AudioServiceAPI.hpp | 12 ++- .../service-audio/ServiceAudio.hpp | 4 +- .../service-bluetooth/ServiceBluetooth.cpp | 15 +++- .../service-bluetooth/ServiceBluetooth.hpp | 6 +- .../messages/AudioVolume.hpp | 13 +++ 15 files changed, 267 insertions(+), 64 deletions(-) diff --git a/module-audio/Audio/VolumeScaler.cpp b/module-audio/Audio/VolumeScaler.cpp index 2a152198760ab03c7c64e437ad5920b7640c06e7..2d30be512991f6a88c184d3b6aab152e5e9a61c3 100644 --- a/module-audio/Audio/VolumeScaler.cpp +++ b/module-audio/Audio/VolumeScaler.cpp @@ -5,20 +5,56 @@ namespace audio::volume::scaler { - Volume toSystemVolume(std::uint8_t avrcpVolume) noexcept + namespace { - constexpr auto avrcpMaxVolume = float{0x7F}; // from AVRCP documentation - const auto systemVolume = (avrcpVolume / avrcpMaxVolume) * audio::maxVolume; - // prevents conversion to 0 while in fact sound is not muted - if (systemVolume > 0.01f && systemVolume < 1.0f) { - return 1; + /// @brief Takes volume level from bluetooth profile and converts it to according one for the system. + /// @param profileVolume - Bluetooth profile volume level. + /// @param profileMaxVolume - Bluetooth profile max volume level. + /// @return Volume level scaled to satisfy system's range [audio::minVolume, audio::maxVolume]. + Volume btProfileToSystemVolume(std::uint8_t profileVolume, float profileMaxVolume) noexcept + { + const auto systemVolume = (profileVolume / profileMaxVolume) * audio::maxVolume; + // prevents conversion to 0 while in fact sound is not muted + if (systemVolume > 0.01f && systemVolume < 1.0f) { + return 1; + } + return systemVolume; } - return systemVolume; - } - std::uint8_t toAvrcpVolume(float systemVolume) noexcept + /// @brief Takes volume level and converts it to according one for the bluetooth profile. + /// @param systemVolume - system volume level. + /// @param profileMaxVolume - bluetooth profile max volume level. + /// @return Volume level scaled to satisfy bluetooth profile range [0, profileMaxVolume]. + std::uint8_t systemToBtProfileVolume(float systemVolume, std::uint8_t profileMaxVolume) noexcept + { + return std::round(systemVolume * profileMaxVolume / audio::maxVolume); + } + } // namespace + namespace a2dp { constexpr auto avrcpMaxVolume = std::uint8_t{0x7F}; // from AVRCP documentation - return std::round(systemVolume * avrcpMaxVolume / audio::maxVolume); - } + + Volume toSystemVolume(std::uint8_t avrcpVolume) noexcept + { + return btProfileToSystemVolume(avrcpVolume, static_cast(avrcpMaxVolume)); + } + + std::uint8_t toAvrcpVolume(float systemVolume) noexcept + { + return systemToBtProfileVolume(systemVolume, avrcpMaxVolume); + } + } // namespace a2dp + namespace hsp + { + constexpr auto hspMaxVolume = float{0x0F}; // from HSP documentation + + Volume toSystemVolume(std::uint8_t hspSpeakerGain) noexcept + { + return btProfileToSystemVolume(hspSpeakerGain, static_cast(hspMaxVolume)); + } + std::uint8_t toHSPGain(float systemVolume) noexcept + { + return systemToBtProfileVolume(systemVolume, hspMaxVolume); + } + } // namespace hsp } // namespace audio::volume::scaler diff --git a/module-audio/Audio/VolumeScaler.hpp b/module-audio/Audio/VolumeScaler.hpp index d658c4b15ca2de52dfdbeebfabe313183e0aa7ad..a2382daa7669a43ea513bf18e50849265dc8c99d 100644 --- a/module-audio/Audio/VolumeScaler.hpp +++ b/module-audio/Audio/VolumeScaler.hpp @@ -7,12 +7,27 @@ /// @brief Converts volume between system and bluetooth ranges. namespace audio::volume::scaler { - /// @brief Takes volume level and converts it to according one for the system. - /// @param avrcpVolume - AVRCP volume level. - /// @return Volume level scaled to satisfy system's range [audio::minVolume, audio::maxVolume]. - Volume toSystemVolume(std::uint8_t avrcpVolume) noexcept; - /// @brief Takes volume level and converts it to according one for the AVRCP. - /// @param systemVolume - system volume level. - /// @return Volume level scaled to satisfy AVRCP's range [0, 127]. - std::uint8_t toAvrcpVolume(float systemVolume) noexcept; + namespace a2dp + { + /// @brief Takes volume level and converts it to according one for the system. + /// @param avrcpVolume - AVRCP volume level. + /// @return Volume level scaled to satisfy system's range [audio::minVolume, audio::maxVolume]. + Volume toSystemVolume(std::uint8_t avrcpVolume) noexcept; + /// @brief Takes volume level and converts it to according one for the AVRCP. + /// @param systemVolume - system volume level. + /// @return Volume level scaled to satisfy AVRCP's range [0, 127]. + std::uint8_t toAvrcpVolume(float systemVolume) noexcept; + + } // namespace a2dp + namespace hsp + { + /// @brief Takes volume level and converts it to according one for the system. + /// @param hspSpeakerGain - HSP speaker gain. + /// @return Volume level scaled to satisfy system's range [audio::minVolume, audio::maxVolume]. + Volume toSystemVolume(std::uint8_t hspSpeakerGain) noexcept; + /// @brief Takes volume level and converts it to according one for the HSP speaker gain. + /// @param systemVolume - system volume level. + /// @return Volume level scaled to satisfy HSP's range [0, 15]. + std::uint8_t toHSPGain(float systemVolume) noexcept; + } // namespace hsp } // namespace audio::volume::scaler diff --git a/module-audio/Audio/test/unittest_scaler.cpp b/module-audio/Audio/test/unittest_scaler.cpp index 36d402084e541a392658b9fe3af0a0518f3f3413..c89e2ff5a56834daa1c96d993154cdfab06c59ad 100644 --- a/module-audio/Audio/test/unittest_scaler.cpp +++ b/module-audio/Audio/test/unittest_scaler.cpp @@ -15,49 +15,49 @@ SCENARIO("Scale volume levels between system and bluetooth") { THEN("System volume is set to 10") { - REQUIRE(audio::volume::scaler::toSystemVolume(127) == 10); + REQUIRE(audio::volume::scaler::a2dp::toSystemVolume(127) == 10); } } WHEN("Volume is 100") { THEN("System volume is set to 7") { - REQUIRE(audio::volume::scaler::toSystemVolume(100) == 7); + REQUIRE(audio::volume::scaler::a2dp::toSystemVolume(100) == 7); } } WHEN("Volume is 89") { THEN("System volume is set to 7") { - REQUIRE(audio::volume::scaler::toSystemVolume(89) == 7); + REQUIRE(audio::volume::scaler::a2dp::toSystemVolume(89) == 7); } } WHEN("Volume is 88") { THEN("System volume is set to 6") { - REQUIRE(audio::volume::scaler::toSystemVolume(88) == 6); + REQUIRE(audio::volume::scaler::a2dp::toSystemVolume(88) == 6); } } WHEN("Volume is 13") { THEN("System volume is set to 1") { - REQUIRE(audio::volume::scaler::toSystemVolume(13) == 1); + REQUIRE(audio::volume::scaler::a2dp::toSystemVolume(13) == 1); } } WHEN("Volume is 12") { THEN("System volume is set to 1") { - REQUIRE(audio::volume::scaler::toSystemVolume(12) == 1); + REQUIRE(audio::volume::scaler::a2dp::toSystemVolume(12) == 1); } } WHEN("Volume is 0") { THEN("System volume is set to 0") { - REQUIRE(audio::volume::scaler::toSystemVolume(0) == 0); + REQUIRE(audio::volume::scaler::a2dp::toSystemVolume(0) == 0); } } } @@ -68,21 +68,85 @@ SCENARIO("Scale volume levels between system and bluetooth") { THEN("AVRCP volume is 127") { - REQUIRE(audio::volume::scaler::toAvrcpVolume(10) == std::uint8_t{127}); + REQUIRE(audio::volume::scaler::a2dp::toAvrcpVolume(10) == std::uint8_t{127}); + } + THEN("HSP speaker gain is 15") + { + REQUIRE(audio::volume::scaler::hsp::toHSPGain(10) == std::uint8_t{15}); } } WHEN("System volume is set to 7") { THEN("AVRCP volume is 89") { - REQUIRE(audio::volume::scaler::toAvrcpVolume(7) == std::uint8_t{89}); + REQUIRE(audio::volume::scaler::a2dp::toAvrcpVolume(7) == std::uint8_t{89}); + } + THEN("HSP speaker gain is 7") + { + REQUIRE(audio::volume::scaler::hsp::toHSPGain(7) == std::uint8_t{11}); } } WHEN("System volume is set to 1") { THEN("AVRCP volume is 13") { - REQUIRE(audio::volume::scaler::toAvrcpVolume(1) == std::uint8_t{13}); + REQUIRE(audio::volume::scaler::a2dp::toAvrcpVolume(1) == std::uint8_t{13}); + } + THEN("HSP speaker gain is 2") + { + REQUIRE(audio::volume::scaler::hsp::toHSPGain(1) == std::uint8_t{2}); + } + } + } + GIVEN("HSP speaker gain") + { + WHEN("Gain is 15") + { + THEN("System volume is set to 10") + { + REQUIRE(audio::volume::scaler::hsp::toSystemVolume(15) == 10); + } + } + WHEN("Gain is 12") + { + THEN("System volume is set to 8") + { + REQUIRE(audio::volume::scaler::hsp::toSystemVolume(12) == 8); + } + } + WHEN("Gain is 10") + { + THEN("System volume is set to 6") + { + REQUIRE(audio::volume::scaler::hsp::toSystemVolume(10) == 6); + } + } + WHEN("Gain is 7") + { + THEN("System volume is set to 4") + { + REQUIRE(audio::volume::scaler::hsp::toSystemVolume(7) == 4); + } + } + WHEN("Gain is 3") + { + THEN("System volume is set to 2") + { + REQUIRE(audio::volume::scaler::hsp::toSystemVolume(3) == 2); + } + } + WHEN("Gain is 1") + { + THEN("System volume is set to 1") + { + REQUIRE(audio::volume::scaler::hsp::toSystemVolume(1) == 1); + } + } + WHEN("Volume is 0") + { + THEN("System volume is set to 0") + { + REQUIRE(audio::volume::scaler::hsp::toSystemVolume(0) == 0); } } } diff --git a/module-bluetooth/Bluetooth/audio/BluetoothAudioDevice.cpp b/module-bluetooth/Bluetooth/audio/BluetoothAudioDevice.cpp index e386a28ec071d0a584cec8bdaa7527ebf0497109..d74957cc95ebf202558db00882665ea7f449ba7a 100644 --- a/module-bluetooth/Bluetooth/audio/BluetoothAudioDevice.cpp +++ b/module-bluetooth/Bluetooth/audio/BluetoothAudioDevice.cpp @@ -34,19 +34,6 @@ auto BluetoothAudioDevice::getProfileType() const -> AudioProfile return profile; } -auto BluetoothAudioDevice::setOutputVolume(float vol) -> audio::AudioDevice::RetCode -{ - const auto volumeToSet = audio::volume::scaler::toAvrcpVolume(vol); - const auto status = avrcp_controller_set_absolute_volume(AVRCP::mediaTracker.avrcp_cid, volumeToSet); - if (status != ERROR_CODE_SUCCESS) { - LOG_ERROR("Can't set volume level. Status %x", status); - return audio::AudioDevice::RetCode::Failure; - } - - outputVolume = vol; - return audio::AudioDevice::RetCode::Success; -} - auto BluetoothAudioDevice::setInputGain(float gain) -> audio::AudioDevice::RetCode { return audio::AudioDevice::RetCode::Success; @@ -62,6 +49,19 @@ auto BluetoothAudioDevice::isOutputEnabled() const -> bool return outputEnabled; } +auto A2DPAudioDevice::setOutputVolume(float vol) -> audio::AudioDevice::RetCode +{ + const auto volumeToSet = audio::volume::scaler::a2dp::toAvrcpVolume(vol); + const auto status = avrcp_controller_set_absolute_volume(AVRCP::mediaTracker.avrcp_cid, volumeToSet); + if (status != ERROR_CODE_SUCCESS) { + LOG_ERROR("Can't set volume level. Status %x", status); + return audio::AudioDevice::RetCode::Failure; + } + + outputVolume = vol; + return audio::AudioDevice::RetCode::Success; +} + void A2DPAudioDevice::onDataSend() { if (isOutputEnabled()) { @@ -72,6 +72,16 @@ void A2DPAudioDevice::onDataSend() void A2DPAudioDevice::onDataReceive() {} +auto HSPAudioDevice::setOutputVolume(float vol) -> audio::AudioDevice::RetCode +{ + const auto volumeToSet = audio::volume::scaler::hsp::toHSPGain(vol); + hsp_ag_set_speaker_gain(volumeToSet); + + LOG_DEBUG("Volume to be set %d", volumeToSet); + outputVolume = vol; + return audio::AudioDevice::RetCode::Success; +} + void HSPAudioDevice::onDataSend() {} diff --git a/module-bluetooth/Bluetooth/audio/BluetoothAudioDevice.hpp b/module-bluetooth/Bluetooth/audio/BluetoothAudioDevice.hpp index 6284447089b1954de8f952d0c7d22b4d86f817a9..aa1224f0f2249720d9754f8e105320480ed72b85 100644 --- a/module-bluetooth/Bluetooth/audio/BluetoothAudioDevice.hpp +++ b/module-bluetooth/Bluetooth/audio/BluetoothAudioDevice.hpp @@ -25,7 +25,6 @@ namespace bluetooth virtual auto getProfileType() const -> AudioProfile; - auto setOutputVolume(float vol) -> audio::AudioDevice::RetCode override; auto setInputGain(float gain) -> audio::AudioDevice::RetCode override; // Endpoint control methods @@ -38,12 +37,12 @@ namespace bluetooth auto isInputEnabled() const -> bool; auto isOutputEnabled() const -> bool; auto fillSbcAudioBuffer() -> int; + float outputVolume; private: bool outputEnabled = false; bool inputEnabled = false; AudioProfile profile = AudioProfile::None; - float outputVolume; }; class A2DPAudioDevice : public BluetoothAudioDevice @@ -52,6 +51,7 @@ namespace bluetooth explicit A2DPAudioDevice() : BluetoothAudioDevice(AudioProfile::A2DP) {} + auto setOutputVolume(float vol) -> audio::AudioDevice::RetCode override; void onDataSend() override; void onDataReceive() override; auto getSupportedFormats() -> std::vector override; @@ -65,6 +65,7 @@ namespace bluetooth explicit HSPAudioDevice() : BluetoothAudioDevice(AudioProfile::HSP) {} + auto setOutputVolume(float vol) -> audio::AudioDevice::RetCode override; void onDataSend() override; void onDataSend(std::uint16_t scoHandle); void onDataReceive() override; diff --git a/module-bluetooth/Bluetooth/interface/profiles/A2DP/AVRCP.cpp b/module-bluetooth/Bluetooth/interface/profiles/A2DP/AVRCP.cpp index 043c836e261409f5693f1af9dc15b42fbde38220..26063b41705ff07077907baefcfe85198873eed9 100644 --- a/module-bluetooth/Bluetooth/interface/profiles/A2DP/AVRCP.cpp +++ b/module-bluetooth/Bluetooth/interface/profiles/A2DP/AVRCP.cpp @@ -166,7 +166,7 @@ namespace bluetooth case AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED: { const auto volume = avrcp_subevent_notification_volume_changed_get_absolute_volume(packet); auto &busProxy = AVRCP::ownerService->bus; - busProxy.sendUnicast(std::make_shared(volume), service::name::bluetooth); + busProxy.sendUnicast(std::make_shared(volume), service::name::bluetooth); LOG_INFO("AVRCP Controller: notification absolute volume changed %d %%\n", volume * 100 / 127); } break; case AVRCP_SUBEVENT_GET_CAPABILITY_EVENT_ID: diff --git a/module-bluetooth/Bluetooth/interface/profiles/HSP/HSP.cpp b/module-bluetooth/Bluetooth/interface/profiles/HSP/HSP.cpp index fe5b5fda14a47cbc4a7c77989b259d24d1c32309..ca2471147bc2abaf13753306f106eb1854ee524b 100644 --- a/module-bluetooth/Bluetooth/interface/profiles/HSP/HSP.cpp +++ b/module-bluetooth/Bluetooth/interface/profiles/HSP/HSP.cpp @@ -1,15 +1,18 @@ // Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md +#include #include "HSPImpl.hpp" #include "HSP.hpp" #include -#include #include +#include #include +#include +#include #include -#include +#include extern "C" { @@ -202,9 +205,12 @@ namespace bluetooth case HSP_SUBEVENT_MICROPHONE_GAIN_CHANGED: LOG_DEBUG("Received microphone gain change %d\n", hsp_subevent_microphone_gain_changed_get_gain(event)); break; - case HSP_SUBEVENT_SPEAKER_GAIN_CHANGED: + case HSP_SUBEVENT_SPEAKER_GAIN_CHANGED: { + const auto volume = hsp_subevent_speaker_gain_changed_get_gain(event); + auto &busProxy = const_cast(ownerService)->bus; + busProxy.sendUnicast(std::make_shared(volume), service::name::bluetooth); LOG_DEBUG("Received speaker gain change %d\n", hsp_subevent_speaker_gain_changed_get_gain(event)); - break; + } break; case HSP_SUBEVENT_HS_CALL_ANSWER: LOG_DEBUG("HSP CALL ANSWER"); cellularInterface->answerIncomingCall(const_cast(ownerService)); diff --git a/module-services/service-audio/AudioServiceAPI.cpp b/module-services/service-audio/AudioServiceAPI.cpp index 0982a40dcbeb14b512a12a02b1b5b13cb8ca5125..3144e67c0ddb395871a6e05a5c8091be7a9c49a9 100644 --- a/module-services/service-audio/AudioServiceAPI.cpp +++ b/module-services/service-audio/AudioServiceAPI.cpp @@ -219,8 +219,13 @@ namespace AudioServiceAPI return serv->bus.sendUnicast(msg, service::name::audio); } - bool BluetoothVolumeChanged(sys::Service *serv, const uint8_t volume) + bool BluetoothA2DPVolumeChanged(sys::Service *serv, const std::uint8_t volume) { - return serv->bus.sendUnicast(std::make_shared(volume), service::name::audio); + return serv->bus.sendUnicast(std::make_shared(volume), service::name::audio); + } + + bool BluetoothHSPVolumeChanged(sys::Service *serv, const std::uint8_t volume) + { + return serv->bus.sendUnicast(std::make_shared(volume), service::name::audio); } } // namespace AudioServiceAPI diff --git a/module-services/service-audio/ServiceAudio.cpp b/module-services/service-audio/ServiceAudio.cpp index 9f7e2fd70ff906d467edb7cb63a8e8a9c0f782b8..ee8c464d1ca5aeb04642f02f9e0c3b99446a9619 100644 --- a/module-services/service-audio/ServiceAudio.cpp +++ b/module-services/service-audio/ServiceAudio.cpp @@ -99,8 +99,10 @@ ServiceAudio::ServiceAudio() LOG_INFO("[ServiceAudio] Initializing"); bus.channels.push_back(sys::BusChannel::ServiceAudioNotifications); - connect(typeid(BluetoothDeviceVolumeChanged), - [this](sys::Message *msg) -> sys::MessagePointer { return handleVolumeChangedOnBluetoothDevice(msg); }); + connect(typeid(A2DPDeviceVolumeChanged), + [this](sys::Message *msg) -> sys::MessagePointer { return handleA2DPVolumeChangedOnBluetoothDevice(msg); }); + connect(typeid(HSPDeviceVolumeChanged), + [this](sys::Message *msg) -> sys::MessagePointer { return handleHSPVolumeChangedOnBluetoothDevice(msg); }); } ServiceAudio::~ServiceAudio() @@ -740,14 +742,30 @@ void ServiceAudio::settingsChanged(const std::string &name, std::string value) } LOG_ERROR("ServiceAudio::settingsChanged received notification about not registered setting: %s", name.c_str()); } -auto ServiceAudio::handleVolumeChangedOnBluetoothDevice(sys::Message *msgl) -> sys::MessagePointer + +void ServiceAudio::onVolumeChanged(Volume volume) { - auto *msg = static_cast(msgl); - const auto volume = volume::scaler::toSystemVolume(msg->getVolume()); const auto [profileType, playbackType] = getCurrentContext(); settingsProvider->setValue(dbPath(Setting::Volume, playbackType, profileType), std::to_string(volume)); settingsCache[dbPath(Setting::Volume, playbackType, profileType)] = std::to_string(volume); bus.sendMulticast(std::make_unique(volume, std::make_pair(profileType, playbackType)), sys::BusChannel::ServiceAudioNotifications); +} + +auto ServiceAudio::handleA2DPVolumeChangedOnBluetoothDevice(sys::Message *msgl) -> sys::MessagePointer +{ + auto *a2dpMsg = dynamic_cast(msgl); + assert(a2dpMsg != nullptr); + const auto volume = volume::scaler::a2dp::toSystemVolume(a2dpMsg->getVolume()); + onVolumeChanged(volume); + return sys::msgHandled(); +} + +auto ServiceAudio::handleHSPVolumeChangedOnBluetoothDevice(sys::Message *msgl) -> sys::MessagePointer +{ + auto *hspMsg = dynamic_cast(msgl); + assert(hspMsg != nullptr); + const auto volume = volume::scaler::hsp::toSystemVolume(hspMsg->getVolume()); + onVolumeChanged(volume); return sys::msgHandled(); } diff --git a/module-services/service-audio/service-audio/AudioMessage.hpp b/module-services/service-audio/service-audio/AudioMessage.hpp index 91110bdb4dbde83beeae3bd54fe1881d3dcd55c0..824a983f84965ad8d67477ca3676a515e88a79a4 100644 --- a/module-services/service-audio/service-audio/AudioMessage.hpp +++ b/module-services/service-audio/service-audio/AudioMessage.hpp @@ -287,3 +287,17 @@ class BluetoothDeviceVolumeChanged : public AudioMessage private: const std::uint8_t volume; }; + +class A2DPDeviceVolumeChanged : public BluetoothDeviceVolumeChanged +{ + public: + A2DPDeviceVolumeChanged(std::uint8_t volume) : BluetoothDeviceVolumeChanged{volume} + {} +}; + +class HSPDeviceVolumeChanged : public BluetoothDeviceVolumeChanged +{ + public: + HSPDeviceVolumeChanged(std::uint8_t volume) : BluetoothDeviceVolumeChanged{volume} + {} +}; diff --git a/module-services/service-audio/service-audio/AudioServiceAPI.hpp b/module-services/service-audio/service-audio/AudioServiceAPI.hpp index 9dc2e9242bf7cf516c856f9c47d29e80d160b37d..38a3184a516fe85ac1ac29fbba5e350513ce264e 100644 --- a/module-services/service-audio/service-audio/AudioServiceAPI.hpp +++ b/module-services/service-audio/service-audio/AudioServiceAPI.hpp @@ -212,11 +212,19 @@ namespace AudioServiceAPI */ bool KeyPressed(sys::Service *serv, const int step); - /** @brief Bluetooth volume changed handler. + /** @brief Bluetooth A2DP volume changed handler. * * @param serv - requesting service. * @param volume - volume level * @return True if request has been sent successfully, false otherwise */ - bool BluetoothVolumeChanged(sys::Service *serv, const uint8_t volume); + bool BluetoothA2DPVolumeChanged(sys::Service *serv, const std::uint8_t volume); + + /** @brief Bluetooth HSP volume changed handler. + * + * @param serv - requesting service. + * @param volume - volume level + * @return True if request has been sent successfully, false otherwise + */ + bool BluetoothHSPVolumeChanged(sys::Service *serv, const std::uint8_t volume); }; // namespace AudioServiceAPI diff --git a/module-services/service-audio/service-audio/ServiceAudio.hpp b/module-services/service-audio/service-audio/ServiceAudio.hpp index 8c66a55e62a61bf17e35237012cae697d0f36777..71847bf7ba75b3cbc10b8704c18667ee2d158d4d 100644 --- a/module-services/service-audio/service-audio/ServiceAudio.hpp +++ b/module-services/service-audio/service-audio/ServiceAudio.hpp @@ -109,7 +109,9 @@ class ServiceAudio : public sys::Service const audio::Context getCurrentContext(); void settingsChanged(const std::string &name, std::string value); - auto handleVolumeChangedOnBluetoothDevice(sys::Message *msgl) -> sys::MessagePointer; + void onVolumeChanged(audio::Volume volume); + auto handleA2DPVolumeChangedOnBluetoothDevice(sys::Message *msgl) -> sys::MessagePointer; + auto handleHSPVolumeChangedOnBluetoothDevice(sys::Message *msgl) -> sys::MessagePointer; }; namespace sys diff --git a/module-services/service-bluetooth/ServiceBluetooth.cpp b/module-services/service-bluetooth/ServiceBluetooth.cpp index adf82a621d2ee281775a2453191d8ff49bf9092a..274b33d2df0e1915aa6a43177c09b2d06f0534a0 100644 --- a/module-services/service-bluetooth/ServiceBluetooth.cpp +++ b/module-services/service-bluetooth/ServiceBluetooth.cpp @@ -82,7 +82,8 @@ sys::ReturnCodes ServiceBluetooth::InitHandler() connectHandler(); connectHandler(); connectHandler(); - connectHandler(); + connectHandler(); + connectHandler(); connectHandler(); connectHandler(); connectHandler(); @@ -343,9 +344,17 @@ auto ServiceBluetooth::handle(sdesktop::developerMode::DeveloperModeRequest *msg return sys::MessageNone{}; } -auto ServiceBluetooth::handle(message::bluetooth::AudioVolume *msg) -> std::shared_ptr +auto ServiceBluetooth::handle(message::bluetooth::A2DPVolume *msg) -> std::shared_ptr { - AudioServiceAPI::BluetoothVolumeChanged(this, msg->getVolume()); + using namespace message::bluetooth; + AudioServiceAPI::BluetoothA2DPVolumeChanged(this, msg->getVolume()); + return sys::MessageNone{}; +} + +auto ServiceBluetooth::handle(message::bluetooth::HSPVolume *msg) -> std::shared_ptr +{ + using namespace message::bluetooth; + AudioServiceAPI::BluetoothHSPVolumeChanged(this, msg->getVolume()); return sys::MessageNone{}; } diff --git a/module-services/service-bluetooth/service-bluetooth/ServiceBluetooth.hpp b/module-services/service-bluetooth/service-bluetooth/ServiceBluetooth.hpp index ce70ed387d22eba9d7315a02c2795f75aff912e4..b3d45f97680a128e8bce5ed35949f11da5ae17b9 100644 --- a/module-services/service-bluetooth/service-bluetooth/ServiceBluetooth.hpp +++ b/module-services/service-bluetooth/service-bluetooth/ServiceBluetooth.hpp @@ -48,7 +48,8 @@ namespace message::bluetooth class ConnectResult; class Disconnect; class DisconnectResult; - class AudioVolume; + class A2DPVolume; + class HSPVolume; class Ring; class StartAudioRouting; } // namespace message::bluetooth @@ -98,7 +99,8 @@ class ServiceBluetooth : public sys::Service [[nodiscard]] auto handle(BluetoothAddrMessage *msg) -> std::shared_ptr; [[nodiscard]] auto handle(sdesktop::developerMode::DeveloperModeRequest *msg) -> std::shared_ptr; [[nodiscard]] auto handle(BluetoothAudioStartMessage *msg) -> std::shared_ptr; - [[nodiscard]] auto handle(message::bluetooth::AudioVolume *msg) -> std::shared_ptr; + [[nodiscard]] auto handle(message::bluetooth::A2DPVolume *msg) -> std::shared_ptr; + [[nodiscard]] auto handle(message::bluetooth::HSPVolume *msg) -> std::shared_ptr; [[nodiscard]] auto handle(message::bluetooth::Ring *msg) -> std::shared_ptr; [[nodiscard]] auto handle(message::bluetooth::StartAudioRouting *msg) -> std::shared_ptr; [[nodiscard]] auto handle(message::bluetooth::ResponsePasskey *msg) -> std::shared_ptr; diff --git a/module-services/service-bluetooth/service-bluetooth/messages/AudioVolume.hpp b/module-services/service-bluetooth/service-bluetooth/messages/AudioVolume.hpp index fb6401f1069457d81f128a1228583ea1a4517011..18caaea1315883c98f48ef0c7dadd92ccab7737a 100644 --- a/module-services/service-bluetooth/service-bluetooth/messages/AudioVolume.hpp +++ b/module-services/service-bluetooth/service-bluetooth/messages/AudioVolume.hpp @@ -21,4 +21,17 @@ namespace message::bluetooth private: const std::uint8_t volume; }; + + class A2DPVolume : public AudioVolume + { + public: + explicit A2DPVolume(std::uint8_t volume) : AudioVolume{volume} + {} + }; + class HSPVolume : public AudioVolume + { + public: + explicit HSPVolume(std::uint8_t volume) : AudioVolume{volume} + {} + }; } // namespace message::bluetooth