From 2329a4d323b8b7fed095db7187a8adb3894facdf Mon Sep 17 00:00:00 2001 From: Pauli Virtanen Date: Sun, 7 Nov 2021 15:57:28 +0200 Subject: [PATCH] bluez5: quirks for headset without a2dp duplex codecs See #1756 (another headset with non-working, probably faststream duplex) --- spa/plugins/bluez5/bluez-hardware.conf | 3 +++ spa/plugins/bluez5/bluez5-dbus.c | 2 ++ spa/plugins/bluez5/defs.h | 1 + spa/plugins/bluez5/quirks.c | 6 ++++++ 4 files changed, 12 insertions(+) diff --git a/spa/plugins/bluez5/bluez-hardware.conf b/spa/plugins/bluez5/bluez-hardware.conf index 93539212a..c521af6e0 100644 --- a/spa/plugins/bluez5/bluez-hardware.conf +++ b/spa/plugins/bluez5/bluez-hardware.conf @@ -14,6 +14,7 @@ # hw-volume-mic Functional HSP/HFP microphone volume support # sbc-xq "nonstandard" SBC codec setting with better sound quality # faststream FastStream codec support +# a2dp-duplex A2DP duplex codec support # # Features are disabled with the key "no-features" whose value is an # array of strings in the match rule. @@ -42,6 +43,8 @@ bluez5.features.device = [ { name = "Tribit MAXSound Plus", no-features = [ hw-volume ] }, # #pipewire-1592 { name = "Urbanista Stockholm Plus", no-features = [ msbc-alt1, msbc-alt1-rtl ] }, + { address = "~^44:5e:cd:", no-features = [ faststream, a2dp-duplex ]}, # #pipewire-1756 + { address = "~^94:16:25:", no-features = [ hw-volume ]}, # AirPods 2 { address = "~^9c:64:8b:", no-features = [ hw-volume ]}, # AirPods 2 { address = "~^a0:e9:db:", no-features = [ hw-volume ]}, # Ausdom M05 diff --git a/spa/plugins/bluez5/bluez5-dbus.c b/spa/plugins/bluez5/bluez5-dbus.c index 934403b68..173afe2a8 100644 --- a/spa/plugins/bluez5/bluez5-dbus.c +++ b/spa/plugins/bluez5/bluez5-dbus.c @@ -1432,6 +1432,8 @@ bool spa_bt_device_supports_a2dp_codec(struct spa_bt_device *device, const struc { SPA_BLUETOOTH_AUDIO_CODEC_SBC_XQ, SPA_BT_FEATURE_SBC_XQ }, { SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM, SPA_BT_FEATURE_FASTSTREAM }, { SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM_DUPLEX, SPA_BT_FEATURE_FASTSTREAM }, + { SPA_BLUETOOTH_AUDIO_CODEC_APTX_LL_DUPLEX, SPA_BT_FEATURE_A2DP_DUPLEX }, + { SPA_BLUETOOTH_AUDIO_CODEC_FASTSTREAM_DUPLEX, SPA_BT_FEATURE_A2DP_DUPLEX }, }; size_t i; diff --git a/spa/plugins/bluez5/defs.h b/spa/plugins/bluez5/defs.h index b358f9890..8bbf3b408 100644 --- a/spa/plugins/bluez5/defs.h +++ b/spa/plugins/bluez5/defs.h @@ -682,6 +682,7 @@ enum spa_bt_feature { SPA_BT_FEATURE_HW_VOLUME_MIC = (1 << 4), SPA_BT_FEATURE_SBC_XQ = (1 << 5), SPA_BT_FEATURE_FASTSTREAM = (1 << 6), + SPA_BT_FEATURE_A2DP_DUPLEX = (1 << 7), }; struct spa_bt_quirks; diff --git a/spa/plugins/bluez5/quirks.c b/spa/plugins/bluez5/quirks.c index f3246ed8e..d2262cfa5 100644 --- a/spa/plugins/bluez5/quirks.c +++ b/spa/plugins/bluez5/quirks.c @@ -70,6 +70,7 @@ struct spa_bt_quirks { int force_hw_volume; int force_sbc_xq; int force_faststream; + int force_a2dp_duplex; char *device_rules; char *adapter_rules; @@ -86,6 +87,7 @@ static enum spa_bt_feature parse_feature(const char *str) { "hw-volume-mic", SPA_BT_FEATURE_HW_VOLUME_MIC }, { "sbc-xq", SPA_BT_FEATURE_SBC_XQ }, { "faststream", SPA_BT_FEATURE_FASTSTREAM }, + { "a2dp-duplex", SPA_BT_FEATURE_A2DP_DUPLEX }, }; size_t i; for (i = 0; i < SPA_N_ELEMENTS(feature_keys); ++i) { @@ -251,6 +253,7 @@ struct spa_bt_quirks *spa_bt_quirks_create(const struct spa_dict *info, struct s this->force_msbc = parse_force_flag(info, "bluez5.enable-msbc"); this->force_hw_volume = parse_force_flag(info, "bluez5.enable-hw-volume"); this->force_faststream = parse_force_flag(info, "bluez5.enable-faststream"); + this->force_a2dp_duplex = parse_force_flag(info, "bluez5.enable-a2dp-duplex"); if ((str = spa_dict_lookup(info, "bluez5.hardware-database")) != NULL) { spa_log_debug(this->log, "loading session manager provided data"); @@ -395,5 +398,8 @@ int spa_bt_quirks_get_features(const struct spa_bt_quirks *this, if (this->force_faststream != -1) SPA_FLAG_UPDATE(*features, SPA_BT_FEATURE_FASTSTREAM, this->force_faststream); + if (this->force_a2dp_duplex != -1) + SPA_FLAG_UPDATE(*features, SPA_BT_FEATURE_A2DP_DUPLEX, this->force_a2dp_duplex); + return 0; }