Commit 750dca61 authored by Marijn Suijten's avatar Marijn Suijten 🦀

bluetooth: Implement event Volume has changed (org.bluez.MediaTransport1) in...

bluetooth: Implement event Volume has changed (org.bluez.MediaTransport1) in order to take into account volume changes of A2DP sources.

Using A2DP and a bluetooth audio source, Pulseaudio doesn't take into account the volume modification (for device sending the event via AVRCP (ex:Apple devices))
This work aims to integrate bluez event Volume (org.bluez.MediaTransport1) for A2DP source in pulseaudio.
This permits to take into account A2DP source volume changes (sent using AVRCP protocol).

Change has been tested with an iphone and an ipad and is fully working.

Originally written by Mathieu Tournier <> this
commit has been altered to account for generalized volume callbacks and
includes various logic changes/fixes, and as such has its author reset
due to the vast number of changes I do not feel comfortable holding a
different author responsible for. The orignal commit message and title
have been preserved though.
parent 89b5ce87
......@@ -83,6 +83,8 @@
" <node name=\"A2DPSource\"/>\n" \
#define A2DP_MAX_VOLUME 127
"<node>\n" \
......@@ -414,6 +416,21 @@ pa_hashmap *pa_bluetooth_transport_get_all(pa_bluetooth_discovery *y) {
return y->transports;
static void pa_bluetooth_transport_set_source_volume(pa_bluetooth_transport *t, uint16_t gain) {
pa_volume_t volume;
volume = (pa_volume_t) (gain * PA_VOLUME_NORM / A2DP_MAX_VOLUME);
/* increment volume by one to correct rounding errors */
if (volume < PA_VOLUME_NORM)
t->rx_volume_gain = volume;
pa_hook_fire(pa_bluetooth_discovery_hook(t->device->discovery, /* PA_BLUETOOTH_HOOK_TRANSPORT_SOURCE_VOLUME_CHANGED */PA_BLUETOOTH_HOOK_TRANSPORT_RX_VOLUME_GAIN_CHANGED), t);
void pa_bluetooth_transport_put(pa_bluetooth_transport *t) {
......@@ -669,6 +686,18 @@ static void parse_transport_property(pa_bluetooth_transport *t, DBusMessageIter
case DBUS_TYPE_UINT16: {
uint16_t uintValue;
dbus_message_iter_get_basic(&variant_i, &uintValue);
if (pa_streq(key, "Volume")) {
if (pa_bluetooth_profile_is_a2dp_source(t->profile))
pa_bluetooth_transport_set_source_volume(t, uintValue);
......@@ -2260,11 +2289,12 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage
t = pa_bluetooth_transport_new(d, sender, path, p, config, size);
/* We do not support AVRCP Absolute Volume yet, so use softvol */
/* AVRCP Absolute Volume is dynamically detected and enabled as soon as the
* Volume property becomes available */
t->rx_soft_volume = true;
t->tx_soft_volume = true;
t->max_rx_volume_gain = PA_VOLUME_NORM;
t->max_tx_volume_gain = PA_VOLUME_NORM;
t->max_rx_volume_gain = A2DP_MAX_VOLUME;
t->max_tx_volume_gain = A2DP_MAX_VOLUME;
t->acquire = bluez5_transport_acquire_cb;
t->release = bluez5_transport_release_cb;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment