From de0f54c32445fe1047db951227f3026e74824e38 Mon Sep 17 00:00:00 2001 From: Pauli Virtanen Date: Sat, 25 Jan 2025 17:08:40 +0200 Subject: [PATCH] bluez5: support BAP hardware volume on device sets Enable hardware volume for device sets, when all devices in the set support HW volume. --- spa/plugins/bluez5/bluez5-device.c | 37 ++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/spa/plugins/bluez5/bluez5-device.c b/spa/plugins/bluez5/bluez5-device.c index f615d0a90..2462e18e3 100644 --- a/spa/plugins/bluez5/bluez5-device.c +++ b/spa/plugins/bluez5/bluez5-device.c @@ -2555,6 +2555,41 @@ static int impl_enum_params(void *object, int seq, return 0; } +static void device_set_update_volumes(struct node *node) +{ + struct impl *impl = node->impl; + struct device_set *dset = &impl->device_set; + float hw_volume = node_get_hw_volume(node); + bool sink = (node->id == DEVICE_ID_SINK_SET); + struct device_set_member *members = sink ? dset->sink : dset->source; + uint32_t n_members = sink ? dset->sinks : dset->sources; + uint32_t i; + + /* Check if all sub-devices have HW volume */ + if ((sink && !dset->sink_enabled) || (!sink && !dset->source_enabled)) + goto soft_volume; + + for (i = 0; i < n_members; ++i) { + struct spa_bt_transport *t = members[i].transport; + struct spa_bt_transport_volume *t_volume = t ? &t->volumes[members[i].id] : NULL; + + if (!t_volume || !t_volume->active) + goto soft_volume; + } + + node_update_soft_volumes(node, hw_volume); + for (i = 0; i < n_members; ++i) + spa_bt_transport_set_volume(members[i].transport, members[i].id, hw_volume); + return; + +soft_volume: + /* Soft volume fallback */ + for (i = 0; i < n_members; ++i) + spa_bt_transport_set_volume(members[i].transport, members[i].id, 1.0f); + node_update_soft_volumes(node, 1.0f); + return; +} + static int node_set_volume(struct impl *this, struct node *node, float volumes[], uint32_t n_volumes) { uint32_t i; @@ -2582,6 +2617,8 @@ static int node_set_volume(struct impl *this, struct node *node, float volumes[] node_update_soft_volumes(node, hw_volume); spa_bt_transport_set_volume(node->transport, node->id, hw_volume); + } else if (node->id == DEVICE_ID_SOURCE_SET || node->id == DEVICE_ID_SINK_SET) { + device_set_update_volumes(node); } else { float boost = get_soft_volume_boost(node); for (uint32_t i = 0; i < node->n_channels; ++i)