From 8a7c71694dc70517763ca40733ac0f226f5ac0c6 Mon Sep 17 00:00:00 2001 From: Pauli Virtanen Date: Wed, 31 Dec 2025 12:54:26 +0200 Subject: [PATCH] bluez5: handle BAP initial HW volumes Setup initial HW volumes for BAP profiles similarly as done for A2DP. As Client, retain the remote volumes as initial values, and as Server use our own default volumes. Also as A2DP Source, use the remote HW volume as initial value, if available. In the Client / A2DP Source modes session manager usually restores its own volumes overriding what we set here. --- spa/plugins/bluez5/bluez5-dbus.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/spa/plugins/bluez5/bluez5-dbus.c b/spa/plugins/bluez5/bluez5-dbus.c index 95a235f5e..01291f6cf 100644 --- a/spa/plugins/bluez5/bluez5-dbus.c +++ b/spa/plugins/bluez5/bluez5-dbus.c @@ -3557,6 +3557,9 @@ static void spa_bt_transport_volume_changed(struct spa_bt_transport *transport) t_volume = &transport->volumes[volume_id]; + if (!t_volume->active) + return; + if (t_volume->hw_volume != t_volume->new_hw_volume) { t_volume->hw_volume = t_volume->new_hw_volume; t_volume->volume = (float)spa_bt_volume_hw_to_linear(t_volume->hw_volume, @@ -5276,8 +5279,25 @@ static DBusHandlerResult endpoint_set_configuration(DBusConnection *conn, /* PW is the rendering device so it's responsible for reporting hardware volume. */ transport->volumes[SPA_BT_VOLUME_ID_RX].active = true; } else if (profile & SPA_BT_PROFILE_A2DP_SINK) { + /* Retain remote volume (if present) */ + spa_bt_transport_volume_changed(transport); + transport->volumes[SPA_BT_VOLUME_ID_TX].active |= transport->device->a2dp_volume_active[SPA_BT_VOLUME_ID_TX]; + } else if (profile & (SPA_BT_PROFILE_BAP_SINK | SPA_BT_PROFILE_BAP_SOURCE)) { + if (transport->bap_initiator) { + /* BAP Client: Retain remote volume (if present) */ + spa_bt_transport_volume_changed(transport); + } else { + /* BAP Server: rendering/capture device */ + if (profile & SPA_BT_PROFILE_BAP_SOURCE) + transport->volumes[SPA_BT_VOLUME_ID_RX].active = true; + if (profile & SPA_BT_PROFILE_BAP_SINK) + transport->volumes[SPA_BT_VOLUME_ID_TX].active = true; + } + } else if (profile & SPA_BT_PROFILE_BAP_BROADCAST_SOURCE) { + /* PW is the rendering device */ + transport->volumes[SPA_BT_VOLUME_ID_RX].active = true; } if (codec->validate_config) {