#!/bin/bash

# Copyright 2004, ..., 2017  Jean-Philippe Guillemin <h1p8r10n@yandex.com>
# All rights reserved.
#
#   Permission to use, copy, modify, and distribute this patch for
#   any purpose with or without fee is hereby granted, provided that
#   the above copyright notice and this permission notice appear in all
#   copies.
#
#   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
#   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
#   IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#   SUCH DAMAGE.

here are the features of this patch : 
- allow to use bitpool 94 on devices that support it, aka SBC XQ
- harmless for devices limited to bitpool 53
- deprecates the need for APTX & APTX HD support, which are not better than SBC XQ, are not Open Source, and less supported by devices

Reference : http://soundexpert.org/articles/-/blogs/audio-quality-of-sbc-xq-bluetooth-audio-codec 

diff -rNaud pulseaudio-13.0-orig/src/modules/bluetooth/a2dp-codec-sbc.c pulseaudio-13.0/src/modules/bluetooth/a2dp-codec-sbc.c
--- pulseaudio-13.0-orig/src/modules/bluetooth/a2dp-codec-sbc.c	2019-09-13 15:20:03.000000000 +0200
+++ pulseaudio-13.0/src/modules/bluetooth/a2dp-codec-sbc.c	2019-09-18 12:52:07.385514911 +0200
@@ -156,17 +156,17 @@
 static uint8_t default_bitpool(uint8_t freq, uint8_t mode) {
     /* These bitpool values were chosen based on the A2DP spec recommendation */
     switch (freq) {
-        case SBC_SAMPLING_FREQ_16000:
-        case SBC_SAMPLING_FREQ_32000:
+        case SBC_SAMPLING_FREQ_48000:
             switch (mode) {
                 case SBC_CHANNEL_MODE_MONO:
                 case SBC_CHANNEL_MODE_DUAL_CHANNEL:
+                    return SBC_BITPOOL_HQ_MONO_48000;
+
                 case SBC_CHANNEL_MODE_STEREO:
                 case SBC_CHANNEL_MODE_JOINT_STEREO:
-                    return SBC_BITPOOL_HQ_JOINT_STEREO_44100;
+                    return SBC_BITPOOL_HQ_JOINT_STEREO_48000;
             }
             break;
-
         case SBC_SAMPLING_FREQ_44100:
             switch (mode) {
                 case SBC_CHANNEL_MODE_MONO:
@@ -178,16 +178,14 @@
                     return SBC_BITPOOL_HQ_JOINT_STEREO_44100;
             }
             break;
-
-        case SBC_SAMPLING_FREQ_48000:
+        case SBC_SAMPLING_FREQ_16000:
+        case SBC_SAMPLING_FREQ_32000:
             switch (mode) {
                 case SBC_CHANNEL_MODE_MONO:
                 case SBC_CHANNEL_MODE_DUAL_CHANNEL:
-                    return SBC_BITPOOL_HQ_MONO_48000;
-
                 case SBC_CHANNEL_MODE_STEREO:
                 case SBC_CHANNEL_MODE_JOINT_STEREO:
-                    return SBC_BITPOOL_HQ_JOINT_STEREO_48000;
+                    return SBC_BITPOOL_HQ_JOINT_STEREO_44100;
             }
             break;
     }
@@ -254,12 +252,12 @@
             return 0;
         }
     } else {
-        if (capabilities->channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO)
-            config->channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
+        if (capabilities->channel_mode & SBC_CHANNEL_MODE_DUAL_CHANNEL)
+            config->channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
         else if (capabilities->channel_mode & SBC_CHANNEL_MODE_STEREO)
             config->channel_mode = SBC_CHANNEL_MODE_STEREO;
-        else if (capabilities->channel_mode & SBC_CHANNEL_MODE_DUAL_CHANNEL)
-            config->channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
+        else if (capabilities->channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO)
+            config->channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
         else if (capabilities->channel_mode & SBC_CHANNEL_MODE_MONO)
             config->channel_mode = SBC_CHANNEL_MODE_MONO;
         else {
@@ -343,31 +341,27 @@
     sample_spec->format = PA_SAMPLE_S16LE;
 
     switch (config->frequency) {
-        case SBC_SAMPLING_FREQ_16000:
-            sbc_info->frequency = SBC_FREQ_16000;
-            sample_spec->rate = 16000U;
-            break;
-        case SBC_SAMPLING_FREQ_32000:
-            sbc_info->frequency = SBC_FREQ_32000;
-            sample_spec->rate = 32000U;
+        case SBC_SAMPLING_FREQ_48000:
+            sbc_info->frequency = SBC_FREQ_48000;
+            sample_spec->rate = 48000U;
             break;
         case SBC_SAMPLING_FREQ_44100:
             sbc_info->frequency = SBC_FREQ_44100;
             sample_spec->rate = 44100U;
             break;
-        case SBC_SAMPLING_FREQ_48000:
-            sbc_info->frequency = SBC_FREQ_48000;
-            sample_spec->rate = 48000U;
+        case SBC_SAMPLING_FREQ_32000:
+            sbc_info->frequency = SBC_FREQ_32000;
+            sample_spec->rate = 32000U;
+            break;
+        case SBC_SAMPLING_FREQ_16000:
+            sbc_info->frequency = SBC_FREQ_16000;
+            sample_spec->rate = 16000U;
             break;
         default:
             pa_assert_not_reached();
     }
 
     switch (config->channel_mode) {
-        case SBC_CHANNEL_MODE_MONO:
-            sbc_info->mode = SBC_MODE_MONO;
-            sample_spec->channels = 1;
-            break;
         case SBC_CHANNEL_MODE_DUAL_CHANNEL:
             sbc_info->mode = SBC_MODE_DUAL_CHANNEL;
             sample_spec->channels = 2;
@@ -380,17 +374,21 @@
             sbc_info->mode = SBC_MODE_JOINT_STEREO;
             sample_spec->channels = 2;
             break;
+        case SBC_CHANNEL_MODE_MONO:
+            sbc_info->mode = SBC_MODE_MONO;
+            sample_spec->channels = 1;
+            break;
         default:
             pa_assert_not_reached();
     }
 
     switch (config->allocation_method) {
-        case SBC_ALLOCATION_SNR:
-            sbc_info->allocation = SBC_AM_SNR;
-            break;
         case SBC_ALLOCATION_LOUDNESS:
             sbc_info->allocation = SBC_AM_LOUDNESS;
             break;
+        case SBC_ALLOCATION_SNR:
+            sbc_info->allocation = SBC_AM_SNR;
+            break;
         default:
             pa_assert_not_reached();
     }
diff -rNaud pulseaudio-13.0-orig/src/modules/bluetooth/a2dp-codecs.h pulseaudio-13.0/src/modules/bluetooth/a2dp-codecs.h
--- pulseaudio-13.0-orig/src/modules/bluetooth/a2dp-codecs.h	2019-09-13 15:20:03.000000000 +0200
+++ pulseaudio-13.0/src/modules/bluetooth/a2dp-codecs.h	2019-09-18 12:50:40.543522257 +0200
@@ -61,14 +61,10 @@
  * Allocation method = Loudness
  * Subbands = 8
  */
-#define SBC_BITPOOL_MQ_MONO_44100		19
-#define SBC_BITPOOL_MQ_MONO_48000		18
-#define SBC_BITPOOL_MQ_JOINT_STEREO_44100	35
-#define SBC_BITPOOL_MQ_JOINT_STEREO_48000	33
-#define SBC_BITPOOL_HQ_MONO_44100		31
-#define SBC_BITPOOL_HQ_MONO_48000		29
-#define SBC_BITPOOL_HQ_JOINT_STEREO_44100	53
-#define SBC_BITPOOL_HQ_JOINT_STEREO_48000	51
+#define SBC_BITPOOL_HQ_MONO_44100		38
+#define SBC_BITPOOL_HQ_MONO_48000		38
+#define SBC_BITPOOL_HQ_JOINT_STEREO_44100	76
+#define SBC_BITPOOL_HQ_JOINT_STEREO_48000	76
 
 #define MPEG_CHANNEL_MODE_MONO		(1 << 3)
 #define MPEG_CHANNEL_MODE_DUAL_CHANNEL	(1 << 2)
