Re: [pulseaudio-discuss] [PATCH v15 10/10] bluetooth: Add more variants of SBC codec

2020-04-16 Thread Hyperion
Hi, v15 works, as expected : 90% of the time. As already discussed (for too long) : forcing bitpools for XQ modes is not a good idea, and doesn't work with all speakers. bitpool must always be negotiated : for standard "high quality" mode AND for xq MODES. My patch, available since months : already implement XQ this way (many too simple ?), and it never failed with any BT speaker or headphone : it provides XQ when negocieted bitpools are possible for the receiver : mostly always. JP 15.04.2020, 21:07, "Pali Rohár" :Specify configuration for Low, Middle, High and eXtreme Quality of SBCcodec. SBC codec in eXtreme Quality has higher quality than aptX.Automatic Quality mode matches configuration of SBC codec which was usedbefore this change. Which means that it accept configuration between Lowand High quality.Current SBC code was extended to allow definitions of arbitraryconfiguration variants of SBC codec parameters.SBC XQ testing is in following article:http://soundexpert.org/articles/-/blogs/audio-quality-of-sbc-xq-bluetooth-audio-codec--- src/modules/bluetooth/a2dp-codec-sbc.c  | 655 +++- src/modules/bluetooth/a2dp-codec-util.c |  18 +- 2 files changed, 534 insertions(+), 139 deletions(-)diff --git a/src/modules/bluetooth/a2dp-codec-sbc.c b/src/modules/bluetooth/a2dp-codec-sbc.cindex ba47fa066..f275586ef 100644--- a/src/modules/bluetooth/a2dp-codec-sbc.c+++ b/src/modules/bluetooth/a2dp-codec-sbc.c@@ -36,8 +36,71 @@ #include "a2dp-codec-api.h" #include "rtp.h"-#define SBC_BITPOOL_DEC_LIMIT 32-#define SBC_BITPOOL_DEC_STEP 5+/* Below are capabilities tables for different qualities. Order of capabilities in tables are from the most preferred to the least preferred. */++#define FIXED_SBC_CAPS(mode, freq, bitpool) { .channel_mode = (mode), .frequency = (freq), .min_bitpool = (bitpool), .max_bitpool = (bitpool), .allocation_method = SBC_ALLOCATION_LOUDNESS, .subbands = SBC_SUBBANDS_8, .block_length = SBC_BLOCK_LENGTH_16 }++/* SBC Low Quality, Joint Stereo is same as FastStream's SBC codec configuration, Mono was calculated to match Joint Stereo */+static const a2dp_sbc_t sbc_lq_caps_table[] = {+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_44100, 29), /* 195.7 kbps */+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_48000, 29), /* 213   kbps */+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_44100, 15), /* 104.7 kbps */+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_48000, 15), /* 114   kbps */+};++/* SBC Middle Quality, based on A2DP spec: Recommended sets of SBC parameters */+static const a2dp_sbc_t sbc_mq_caps_table[] = {+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_44100, SBC_BITPOOL_MQ_JOINT_STEREO_44100), /* bitpool = 35, 228.8 kbps */+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_48000, SBC_BITPOOL_MQ_JOINT_STEREO_48000), /* bitpool = 33, 237   kbps */+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_44100, SBC_BITPOOL_MQ_MONO_44100), /* bitpool = 19, 126.8 kbps */+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_48000, SBC_BITPOOL_MQ_MONO_48000), /* bitpool = 18, 132   kbps */+};++/* SBC High Quality, based on A2DP spec: Recommended sets of SBC parameters */+static const a2dp_sbc_t sbc_hq_caps_table[] = {+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_44100, SBC_BITPOOL_HQ_JOINT_STEREO_44100), /* bitpool = 53, 328   kbps */+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_48000, SBC_BITPOOL_HQ_JOINT_STEREO_48000), /* bitpool = 51, 345   kbps */+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_44100, SBC_BITPOOL_HQ_MONO_44100), /* bitpool = 31, 192.9 kbps */+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_48000, SBC_BITPOOL_HQ_MONO_48000), /* bitpool = 29, 210   kbps */+};++/* SBC eXtreme Quality, calculated to minimize wasted bytes for EDR-2 and to+ * be below max possible 512 kbps. In most cases bluetooth headsets would+ * support only sbc dual channel mode for 2 channels as they have limited+ * maximal bitpool value to 53. We need to define it in two tables to disallow+ * invalid combination of joint stereo with bitpool 38 which is not XQ. */+static const a2dp_sbc_t sbc_xq1_caps_table[] = {+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_44100, 76), /* 454.8 kbps */+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_48000, 76), /* 495   kbps */+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_STEREO,   SBC_SAMPLING_FREQ_44100, 76), /* 452   kbps */+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_STEREO,   SBC_SAMPLING_FREQ_48000, 76), /* 492   kbps */+};+static const a2dp_sbc_t sbc_xq2_caps_table[] = {+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_DUAL_CHANNEL, SBC_SAMPLING_FREQ_44100, 38), /* 452   kbps */+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_DUAL_CHANNEL, SBC_SAMPLING_FREQ_48000, 38), /* 492   kbps 

[pulseaudio-discuss] [PATCH v15 10/10] bluetooth: Add more variants of SBC codec

2020-04-15 Thread Pali Rohár
Specify configuration for Low, Middle, High and eXtreme Quality of SBC
codec. SBC codec in eXtreme Quality has higher quality than aptX.

Automatic Quality mode matches configuration of SBC codec which was used
before this change. Which means that it accept configuration between Low
and High quality.

Current SBC code was extended to allow definitions of arbitrary
configuration variants of SBC codec parameters.

SBC XQ testing is in following article:
http://soundexpert.org/articles/-/blogs/audio-quality-of-sbc-xq-bluetooth-audio-codec
---
 src/modules/bluetooth/a2dp-codec-sbc.c  | 655 +++-
 src/modules/bluetooth/a2dp-codec-util.c |  18 +-
 2 files changed, 534 insertions(+), 139 deletions(-)

diff --git a/src/modules/bluetooth/a2dp-codec-sbc.c 
b/src/modules/bluetooth/a2dp-codec-sbc.c
index ba47fa066..f275586ef 100644
--- a/src/modules/bluetooth/a2dp-codec-sbc.c
+++ b/src/modules/bluetooth/a2dp-codec-sbc.c
@@ -36,8 +36,71 @@
 #include "a2dp-codec-api.h"
 #include "rtp.h"
 
-#define SBC_BITPOOL_DEC_LIMIT 32
-#define SBC_BITPOOL_DEC_STEP 5
+/* Below are capabilities tables for different qualities. Order of 
capabilities in tables are from the most preferred to the least preferred. */
+
+#define FIXED_SBC_CAPS(mode, freq, bitpool) { .channel_mode = (mode), 
.frequency = (freq), .min_bitpool = (bitpool), .max_bitpool = (bitpool), 
.allocation_method = SBC_ALLOCATION_LOUDNESS, .subbands = SBC_SUBBANDS_8, 
.block_length = SBC_BLOCK_LENGTH_16 }
+
+/* SBC Low Quality, Joint Stereo is same as FastStream's SBC codec 
configuration, Mono was calculated to match Joint Stereo */
+static const a2dp_sbc_t sbc_lq_caps_table[] = {
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_44100, 
29), /* 195.7 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_48000, 
29), /* 213   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_44100, 
15), /* 104.7 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_48000, 
15), /* 114   kbps */
+};
+
+/* SBC Middle Quality, based on A2DP spec: Recommended sets of SBC parameters 
*/
+static const a2dp_sbc_t sbc_mq_caps_table[] = {
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_44100, 
SBC_BITPOOL_MQ_JOINT_STEREO_44100), /* bitpool = 35, 228.8 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_48000, 
SBC_BITPOOL_MQ_JOINT_STEREO_48000), /* bitpool = 33, 237   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_44100, 
SBC_BITPOOL_MQ_MONO_44100), /* bitpool = 19, 126.8 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_48000, 
SBC_BITPOOL_MQ_MONO_48000), /* bitpool = 18, 132   kbps */
+};
+
+/* SBC High Quality, based on A2DP spec: Recommended sets of SBC parameters */
+static const a2dp_sbc_t sbc_hq_caps_table[] = {
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_44100, 
SBC_BITPOOL_HQ_JOINT_STEREO_44100), /* bitpool = 53, 328   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_48000, 
SBC_BITPOOL_HQ_JOINT_STEREO_48000), /* bitpool = 51, 345   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_44100, 
SBC_BITPOOL_HQ_MONO_44100), /* bitpool = 31, 192.9 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_48000, 
SBC_BITPOOL_HQ_MONO_48000), /* bitpool = 29, 210   kbps */
+};
+
+/* SBC eXtreme Quality, calculated to minimize wasted bytes for EDR-2 and to
+ * be below max possible 512 kbps. In most cases bluetooth headsets would
+ * support only sbc dual channel mode for 2 channels as they have limited
+ * maximal bitpool value to 53. We need to define it in two tables to disallow
+ * invalid combination of joint stereo with bitpool 38 which is not XQ. */
+static const a2dp_sbc_t sbc_xq1_caps_table[] = {
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_44100, 
76), /* 454.8 kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_JOINT_STEREO, SBC_SAMPLING_FREQ_48000, 
76), /* 495   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_STEREO,   SBC_SAMPLING_FREQ_44100, 
76), /* 452   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_STEREO,   SBC_SAMPLING_FREQ_48000, 
76), /* 492   kbps */
+};
+static const a2dp_sbc_t sbc_xq2_caps_table[] = {
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_DUAL_CHANNEL, SBC_SAMPLING_FREQ_44100, 
38), /* 452   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_DUAL_CHANNEL, SBC_SAMPLING_FREQ_48000, 
38), /* 492   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_44100, 
37), /* 226   kbps */
+FIXED_SBC_CAPS(SBC_CHANNEL_MODE_MONO, SBC_SAMPLING_FREQ_48000, 
37), /* 246   kbps */
+};
+
+#undef FIXED_SBC_CAPS
+
+/* SBC Auto Quality, only one row which allow any possible configuration up to 
common High Quality */
+/* We need to ensure that bitrate is below max possible 512 kbps, therefore 
limit