bluetooth: Perform software attenuation until HF/HS reports gain control

HF/HS hardware attenuation is optional on HFP: the peer indicates
support with the AT+BRSF command, when bit 4 is set.  That does not
explicitly mandate speaker or microphone gain control; either is
dynamically detected as soon as `AT+VG[MS]=` is received.  Otherwise
software attenuation is performed.

It is also optional on HSP but nothing is mentioned about feature
detection, assume it is the same as HFP: perform software attenuation
until the HF/HS peer sends an `AT+VG[MS]=` command.

When PA is a HS/HF (and the peer the AG) we attenuate both channels in
software and unconditionally keep the peer up to date with
`AT+VGM/AT+VGS` commands.

Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/521>
This commit is contained in:
Marijn Suijten 2021-03-05 23:28:57 +01:00
parent 9c847b16a8
commit d510ddc7fb
2 changed files with 42 additions and 15 deletions

View file

@ -1041,10 +1041,8 @@ static int add_source(struct userdata *u) {
u->source->parent.process_msg = source_process_msg;
u->source->set_state_in_io_thread = source_set_state_in_io_thread_cb;
if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
|| u->profile == PA_BLUETOOTH_PROFILE_HSP_AG
|| u->profile == PA_BLUETOOTH_PROFILE_HFP_AG
|| u->profile == PA_BLUETOOTH_PROFILE_HFP_HF) {
if (u->transport->set_source_volume) {
pa_log_debug("Peer supports microphone gain control");
pa_source_set_set_volume_callback(u->source, source_set_volume_cb);
u->source->n_volume_steps = 16;
}
@ -1222,10 +1220,8 @@ static int add_sink(struct userdata *u) {
u->sink->parent.process_msg = sink_process_msg;
u->sink->set_state_in_io_thread = sink_set_state_in_io_thread_cb;
if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
|| u->profile == PA_BLUETOOTH_PROFILE_HSP_AG
|| u->profile == PA_BLUETOOTH_PROFILE_HFP_AG
|| u->profile == PA_BLUETOOTH_PROFILE_HFP_HF) {
if (u->transport->set_sink_volume) {
pa_log_debug("Peer supports speaker gain control");
pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
u->sink->n_volume_steps = 16;
}