mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
bluez5: add and use quirk for broken mic HW volume
Some headsets emit AT+VGM even though +VGM commands do not actually adjust the recording volume.
This commit is contained in:
parent
4899b75410
commit
9d38d375d2
4 changed files with 21 additions and 6 deletions
|
|
@ -129,6 +129,7 @@ struct rfcomm {
|
||||||
char* path;
|
char* path;
|
||||||
bool has_volume;
|
bool has_volume;
|
||||||
struct rfcomm_volume volumes[SPA_BT_VOLUME_ID_TERM];
|
struct rfcomm_volume volumes[SPA_BT_VOLUME_ID_TERM];
|
||||||
|
unsigned int broken_mic_hw_volume:1;
|
||||||
#ifdef HAVE_BLUEZ_5_BACKEND_HFP_NATIVE
|
#ifdef HAVE_BLUEZ_5_BACKEND_HFP_NATIVE
|
||||||
unsigned int slc_configured:1;
|
unsigned int slc_configured:1;
|
||||||
unsigned int codec_negotiation_supported:1;
|
unsigned int codec_negotiation_supported:1;
|
||||||
|
|
@ -331,7 +332,8 @@ static bool rfcomm_hsp_ag(struct spa_source *source, char* buf)
|
||||||
}
|
}
|
||||||
} else if (sscanf(buf, "AT+VGM=%d", &gain) == 1) {
|
} else if (sscanf(buf, "AT+VGM=%d", &gain) == 1) {
|
||||||
if (gain <= SPA_BT_VOLUME_HS_MAX) {
|
if (gain <= SPA_BT_VOLUME_HS_MAX) {
|
||||||
rfcomm_emit_volume_changed(rfcomm, SPA_BT_VOLUME_ID_RX, gain);
|
if (!rfcomm->broken_mic_hw_volume)
|
||||||
|
rfcomm_emit_volume_changed(rfcomm, SPA_BT_VOLUME_ID_RX, gain);
|
||||||
rfcomm_send_reply(source, "OK");
|
rfcomm_send_reply(source, "OK");
|
||||||
} else {
|
} else {
|
||||||
rfcomm_send_reply(source, "ERROR");
|
rfcomm_send_reply(source, "ERROR");
|
||||||
|
|
@ -619,7 +621,7 @@ static bool rfcomm_hfp_ag(struct spa_source *source, char* buf)
|
||||||
/*
|
/*
|
||||||
* Determine device volume control. Some headsets only support control of
|
* Determine device volume control. Some headsets only support control of
|
||||||
* TX volume, but not RX, even if they have a microphone. Determine this
|
* TX volume, but not RX, even if they have a microphone. Determine this
|
||||||
* separately based on whether we also get AT+VGS/AT+VGM.
|
* separately based on whether we also get AT+VGS/AT+VGM, and quirks.
|
||||||
*/
|
*/
|
||||||
rfcomm->has_volume = (features & SPA_BT_HFP_HF_FEATURE_REMOTE_VOLUME_CONTROL);
|
rfcomm->has_volume = (features & SPA_BT_HFP_HF_FEATURE_REMOTE_VOLUME_CONTROL);
|
||||||
|
|
||||||
|
|
@ -753,7 +755,8 @@ static bool rfcomm_hfp_ag(struct spa_source *source, char* buf)
|
||||||
spa_bt_device_emit_codec_switched(rfcomm->device, 0);
|
spa_bt_device_emit_codec_switched(rfcomm->device, 0);
|
||||||
} else if (sscanf(buf, "AT+VGM=%u", &gain) == 1) {
|
} else if (sscanf(buf, "AT+VGM=%u", &gain) == 1) {
|
||||||
if (gain <= SPA_BT_VOLUME_HS_MAX) {
|
if (gain <= SPA_BT_VOLUME_HS_MAX) {
|
||||||
rfcomm_emit_volume_changed(rfcomm, SPA_BT_VOLUME_ID_RX, gain);
|
if (!rfcomm->broken_mic_hw_volume)
|
||||||
|
rfcomm_emit_volume_changed(rfcomm, SPA_BT_VOLUME_ID_RX, gain);
|
||||||
rfcomm_send_reply(source, "OK");
|
rfcomm_send_reply(source, "OK");
|
||||||
} else {
|
} else {
|
||||||
spa_log_debug(backend->log, NAME": RFCOMM receive unsupported VGM gain: %s", buf);
|
spa_log_debug(backend->log, NAME": RFCOMM receive unsupported VGM gain: %s", buf);
|
||||||
|
|
@ -1659,6 +1662,15 @@ static DBusHandlerResult profile_new_connection(DBusConnection *conn, DBusMessag
|
||||||
rfcomm->hf_state = hfp_hf_brsf;
|
rfcomm->hf_state = hfp_hf_brsf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rfcomm_volume_enabled(rfcomm) && (profile == SPA_BT_PROFILE_HFP_HF || profile == SPA_BT_PROFILE_HSP_HS)) {
|
||||||
|
uint32_t device_features;
|
||||||
|
if (spa_bt_quirks_get_features(backend->quirks, d->adapter, d, &device_features) == 0) {
|
||||||
|
rfcomm->broken_mic_hw_volume = !(device_features & SPA_BT_FEATURE_HW_VOLUME_MIC);
|
||||||
|
if (rfcomm->broken_mic_hw_volume)
|
||||||
|
spa_log_debug(backend->log, NAME": microphone HW volume disabled by quirk");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((r = dbus_message_new_method_return(m)) == NULL)
|
if ((r = dbus_message_new_method_return(m)) == NULL)
|
||||||
goto fail_need_memory;
|
goto fail_need_memory;
|
||||||
if (!dbus_connection_send(conn, r, NULL))
|
if (!dbus_connection_send(conn, r, NULL))
|
||||||
|
|
|
||||||
|
|
@ -671,7 +671,8 @@ enum spa_bt_feature {
|
||||||
SPA_BT_FEATURE_MSBC_ALT1 = (1 << 1),
|
SPA_BT_FEATURE_MSBC_ALT1 = (1 << 1),
|
||||||
SPA_BT_FEATURE_MSBC_ALT1_RTL = (1 << 2),
|
SPA_BT_FEATURE_MSBC_ALT1_RTL = (1 << 2),
|
||||||
SPA_BT_FEATURE_HW_VOLUME = (1 << 3),
|
SPA_BT_FEATURE_HW_VOLUME = (1 << 3),
|
||||||
SPA_BT_FEATURE_SBC_XQ = (1 << 4),
|
SPA_BT_FEATURE_HW_VOLUME_MIC = (1 << 4),
|
||||||
|
SPA_BT_FEATURE_SBC_XQ = (1 << 5),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct spa_bt_quirks;
|
struct spa_bt_quirks;
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ static enum spa_bt_feature parse_feature(const char *str)
|
||||||
{ "msbc-alt1", SPA_BT_FEATURE_MSBC_ALT1 },
|
{ "msbc-alt1", SPA_BT_FEATURE_MSBC_ALT1 },
|
||||||
{ "msbc-alt1-rtl", SPA_BT_FEATURE_MSBC_ALT1_RTL },
|
{ "msbc-alt1-rtl", SPA_BT_FEATURE_MSBC_ALT1_RTL },
|
||||||
{ "hw-volume", SPA_BT_FEATURE_HW_VOLUME },
|
{ "hw-volume", SPA_BT_FEATURE_HW_VOLUME },
|
||||||
|
{ "hw-volume-mic", SPA_BT_FEATURE_HW_VOLUME_MIC },
|
||||||
{ "sbc-xq", SPA_BT_FEATURE_SBC_XQ },
|
{ "sbc-xq", SPA_BT_FEATURE_SBC_XQ },
|
||||||
};
|
};
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@
|
||||||
# msbc "standard" mSBC (60 byte tx packet)
|
# msbc "standard" mSBC (60 byte tx packet)
|
||||||
# msbc-alt1 USB adapters with mSBC in ALT1 setting (24 byte tx packet)
|
# msbc-alt1 USB adapters with mSBC in ALT1 setting (24 byte tx packet)
|
||||||
# msbc-alt1-rtl Realtek USB adapters with mSBC in ALT1 setting (24 byte tx packet)
|
# msbc-alt1-rtl Realtek USB adapters with mSBC in ALT1 setting (24 byte tx packet)
|
||||||
# hw-volume AVRCP absolute volume support
|
# hw-volume AVRCP and HSP/HFP hardware volume support
|
||||||
|
# hw-volume-mic Functional HSP/HFP microphone volume support
|
||||||
# sbc-xq "nonstandard" SBC codec setting with better sound quality
|
# sbc-xq "nonstandard" SBC codec setting with better sound quality
|
||||||
# (XXX: the SBC-XQ per-device setting doesn't have effect yet)
|
# (XXX: the SBC-XQ per-device setting doesn't have effect yet)
|
||||||
#
|
#
|
||||||
|
|
@ -25,7 +26,7 @@ bluez5.features.device = [
|
||||||
# - product-id
|
# - product-id
|
||||||
# - version-id
|
# - version-id
|
||||||
|
|
||||||
{ name = "Air 1 Plus" },
|
{ name = "Air 1 Plus", no-features = [ hw-volume-mic ] },
|
||||||
{ name = "AirPods", no-features = [ msbc-alt1, msbc-alt1-rtl ] },
|
{ name = "AirPods", no-features = [ msbc-alt1, msbc-alt1-rtl ] },
|
||||||
{ name = "AirPods Pro", no-features = [ msbc-alt1, msbc-alt1-rtl ] },
|
{ name = "AirPods Pro", no-features = [ msbc-alt1, msbc-alt1-rtl ] },
|
||||||
{ name = "AXLOIE Goin", no-features = [ msbc-alt1, msbc-alt1-rtl ] },
|
{ name = "AXLOIE Goin", no-features = [ msbc-alt1, msbc-alt1-rtl ] },
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue