mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
bluetooth: Update source software volume on AVRCP SetAbsoluteVolume
The A2DP spec mandates that the audio rendering device - the device
receiving audio, in our case a `pa_source` - is responsible for
performing attenuation:
AVRCP v1.6.2, §5.8:
The SetAbsoluteVolume command is used to set an absolute volume to be used by the rendering device.
BlueZ models this call as a change of the `Volume` property on the
`org.bluez.MediaTransport1` interface. Supporting Absolute Volume is
optional but BlueZ unconditionally reports feature category 2 in its
profile, mandating support. Hence remote devices (ie. a phone) playing
back audio to a machine running PulseAudio assume volume is to be
changed through SetAbsoluteVolume, without performing any local
attenuation.
Future changes will implement this feature the other way around: setting
an initial value for the `Volume` property as well as propagating
`pa_source` volume changes back to the peer.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/239>
This commit is contained in:
parent
c098a75d10
commit
710a35cdc3
2 changed files with 45 additions and 0 deletions
|
|
@ -101,6 +101,19 @@
|
||||||
" </interface>" \
|
" </interface>" \
|
||||||
"</node>"
|
"</node>"
|
||||||
|
|
||||||
|
static pa_volume_t a2dp_gain_to_volume(uint16_t gain) {
|
||||||
|
pa_volume_t volume = (pa_volume_t) ((
|
||||||
|
gain * PA_VOLUME_NORM
|
||||||
|
/* Round to closest by adding half the denominator */
|
||||||
|
+ A2DP_MAX_GAIN / 2
|
||||||
|
) / A2DP_MAX_GAIN);
|
||||||
|
|
||||||
|
if (volume > PA_VOLUME_NORM)
|
||||||
|
volume = PA_VOLUME_NORM;
|
||||||
|
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
struct pa_bluetooth_discovery {
|
struct pa_bluetooth_discovery {
|
||||||
PA_REFCNT_DECLARE;
|
PA_REFCNT_DECLARE;
|
||||||
|
|
||||||
|
|
@ -496,6 +509,24 @@ void pa_bluetooth_transport_set_state(pa_bluetooth_transport *t, pa_bluetooth_tr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pa_bluetooth_transport_remote_volume_changed(pa_bluetooth_transport *t, uint16_t gain) {
|
||||||
|
pa_volume_t volume;
|
||||||
|
|
||||||
|
pa_assert(t);
|
||||||
|
|
||||||
|
volume = a2dp_gain_to_volume(gain);
|
||||||
|
|
||||||
|
/* increment volume by one to correct rounding errors */
|
||||||
|
if (volume < PA_VOLUME_NORM)
|
||||||
|
volume++;
|
||||||
|
|
||||||
|
if (t->source_volume == volume)
|
||||||
|
return;
|
||||||
|
|
||||||
|
t->source_volume = volume;
|
||||||
|
pa_hook_fire(pa_bluetooth_discovery_hook(t->device->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_SOURCE_VOLUME_CHANGED), t);
|
||||||
|
}
|
||||||
|
|
||||||
void pa_bluetooth_transport_put(pa_bluetooth_transport *t) {
|
void pa_bluetooth_transport_put(pa_bluetooth_transport *t) {
|
||||||
pa_assert(t);
|
pa_assert(t);
|
||||||
|
|
||||||
|
|
@ -679,6 +710,8 @@ static void parse_transport_property(pa_bluetooth_transport *t, DBusMessageIter
|
||||||
if (key == NULL)
|
if (key == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
pa_log_debug("Transport property %s changed", key);
|
||||||
|
|
||||||
dbus_message_iter_recurse(i, &variant_i);
|
dbus_message_iter_recurse(i, &variant_i);
|
||||||
|
|
||||||
switch (dbus_message_iter_get_arg_type(&variant_i)) {
|
switch (dbus_message_iter_get_arg_type(&variant_i)) {
|
||||||
|
|
@ -701,6 +734,17 @@ static void parse_transport_property(pa_bluetooth_transport *t, DBusMessageIter
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case DBUS_TYPE_UINT16: {
|
||||||
|
uint16_t value;
|
||||||
|
dbus_message_iter_get_basic(&variant_i, &value);
|
||||||
|
|
||||||
|
if (pa_streq(key, "Volume")) {
|
||||||
|
if (t->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE)
|
||||||
|
pa_bluetooth_transport_remote_volume_changed(t, value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@
|
||||||
#define PA_BLUETOOTH_UUID_HFP_HF "0000111e-0000-1000-8000-00805f9b34fb"
|
#define PA_BLUETOOTH_UUID_HFP_HF "0000111e-0000-1000-8000-00805f9b34fb"
|
||||||
#define PA_BLUETOOTH_UUID_HFP_AG "0000111f-0000-1000-8000-00805f9b34fb"
|
#define PA_BLUETOOTH_UUID_HFP_AG "0000111f-0000-1000-8000-00805f9b34fb"
|
||||||
|
|
||||||
|
#define A2DP_MAX_GAIN 127
|
||||||
#define HSP_MAX_GAIN 15
|
#define HSP_MAX_GAIN 15
|
||||||
|
|
||||||
typedef struct pa_bluetooth_transport pa_bluetooth_transport;
|
typedef struct pa_bluetooth_transport pa_bluetooth_transport;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue