mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-12-25 15:39:26 -05:00
SBC dualchannel picks
Signed-off-by: Tad <tad@spotco.us>
This commit is contained in:
parent
7277291dd7
commit
b5bc269743
22
Patches/LineageOS-17.1/android_frameworks_base/272645.patch
Normal file
22
Patches/LineageOS-17.1/android_frameworks_base/272645.patch
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: ValdikSS <iam@valdikss.org.ru>
|
||||||
|
Date: Mon, 10 Sep 2018 13:07:13 +0300
|
||||||
|
Subject: [PATCH] Add CHANNEL_MODE_DUAL_CHANNEL constant
|
||||||
|
|
||||||
|
Change-Id: Id8601789879f9ded097aebb883fa3456bf74988e
|
||||||
|
---
|
||||||
|
core/java/android/bluetooth/BluetoothCodecConfig.java | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java
|
||||||
|
index c449c32fe4be..859d1633af78 100644
|
||||||
|
--- a/core/java/android/bluetooth/BluetoothCodecConfig.java
|
||||||
|
+++ b/core/java/android/bluetooth/BluetoothCodecConfig.java
|
||||||
|
@@ -95,6 +95,7 @@ public final class BluetoothCodecConfig implements Parcelable {
|
||||||
|
public static final int CHANNEL_MODE_MONO = 0x1 << 0;
|
||||||
|
@UnsupportedAppUsage
|
||||||
|
public static final int CHANNEL_MODE_STEREO = 0x1 << 1;
|
||||||
|
+ public static final int CHANNEL_MODE_DUAL_CHANNEL = 0x1 << 2;
|
||||||
|
|
||||||
|
private final int mCodecType;
|
||||||
|
private int mCodecPriority;
|
@ -0,0 +1,44 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: ValdikSS <iam@valdikss.org.ru>
|
||||||
|
Date: Mon, 10 Sep 2018 14:07:40 +0300
|
||||||
|
Subject: [PATCH] Add Dual Channel into Bluetooth Audio Channel Mode developer
|
||||||
|
options menu
|
||||||
|
|
||||||
|
Change-Id: I9360b91c9b3d28e0cb9d8adebb5131c38b3082f0
|
||||||
|
---
|
||||||
|
packages/SettingsLib/res/values/cm_arrays.xml | 24 +++++++++++++++++++
|
||||||
|
1 file changed, 24 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/packages/SettingsLib/res/values/cm_arrays.xml b/packages/SettingsLib/res/values/cm_arrays.xml
|
||||||
|
index beff6a47dc24..e15f4dd23cef 100644
|
||||||
|
--- a/packages/SettingsLib/res/values/cm_arrays.xml
|
||||||
|
+++ b/packages/SettingsLib/res/values/cm_arrays.xml
|
||||||
|
@@ -45,4 +45,28 @@
|
||||||
|
<item>Enable Optional Codecs</item>
|
||||||
|
<item>Disable Optional Codecs</item>
|
||||||
|
</string-array>
|
||||||
|
+
|
||||||
|
+ <!-- Summaries for Bluetooth Audio Codec Channel Mode selection preference. [CHAR LIMIT=50]-->
|
||||||
|
+ <string-array name="lineage_bluetooth_a2dp_codec_channel_mode_summaries" >
|
||||||
|
+ <item>Use System Selection (Default)</item>
|
||||||
|
+ <item>Mono</item>
|
||||||
|
+ <item>Stereo</item>
|
||||||
|
+ <item>Dual Channel</item>
|
||||||
|
+ </string-array>
|
||||||
|
+
|
||||||
|
+ <!-- Titles for Bluetooth Audio Codec Channel Mode selection preference. [CHAR LIMIT=50] -->
|
||||||
|
+ <string-array name="lineage_bluetooth_a2dp_codec_channel_mode_titles">
|
||||||
|
+ <item>Use System Selection (Default)</item>
|
||||||
|
+ <item>Mono</item>
|
||||||
|
+ <item>Stereo</item>
|
||||||
|
+ <item>Dual Channel</item>
|
||||||
|
+ </string-array>
|
||||||
|
+
|
||||||
|
+ <!-- Values for Bluetooth Audio Codec Channel Mode selection preference. -->
|
||||||
|
+ <string-array name="lineage_bluetooth_a2dp_codec_channel_mode_values" translatable="false" >
|
||||||
|
+ <item>0</item>
|
||||||
|
+ <item>1</item>
|
||||||
|
+ <item>2</item>
|
||||||
|
+ <item>3</item>
|
||||||
|
+ </string-array>
|
||||||
|
</resources>
|
39
Patches/LineageOS-17.1/android_frameworks_base/272647.patch
Normal file
39
Patches/LineageOS-17.1/android_frameworks_base/272647.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: ValdikSS <iam@valdikss.org.ru>
|
||||||
|
Date: Mon, 10 Sep 2018 02:16:50 +0300
|
||||||
|
Subject: [PATCH] Allow SBC as HD audio codec in Bluetooth device configuration
|
||||||
|
|
||||||
|
Change-Id: I4d149e87e27e16d571f53d0521f12a8ab9d0fc94
|
||||||
|
---
|
||||||
|
.../src/com/android/settingslib/bluetooth/A2dpProfile.java | 2 +-
|
||||||
|
.../com/android/settingslib/bluetooth/A2dpProfileTest.java | 4 +++-
|
||||||
|
2 files changed, 4 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
|
||||||
|
index 31624a5cc95e..0d64c2bba991 100644
|
||||||
|
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
|
||||||
|
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
|
||||||
|
@@ -288,7 +288,7 @@ public class A2dpProfile implements LocalBluetoothProfile {
|
||||||
|
|
||||||
|
final BluetoothCodecConfig codecConfig = (selectable == null || selectable.length < 1)
|
||||||
|
? null : selectable[0];
|
||||||
|
- final int codecType = (codecConfig == null || codecConfig.isMandatoryCodec())
|
||||||
|
+ final int codecType = (codecConfig == null)
|
||||||
|
? BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID : codecConfig.getCodecType();
|
||||||
|
|
||||||
|
int index = -1;
|
||||||
|
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
|
||||||
|
index 9fb11813f245..03d2fa86c42b 100644
|
||||||
|
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
|
||||||
|
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
|
||||||
|
@@ -183,7 +183,9 @@ public class A2dpProfileTest {
|
||||||
|
when(status.getCodecsSelectableCapabilities()).thenReturn(configs);
|
||||||
|
|
||||||
|
when(config.isMandatoryCodec()).thenReturn(true);
|
||||||
|
- assertThat(mProfile.getHighQualityAudioOptionLabel(mDevice)).isEqualTo(UNKNOWN_CODEC_LABEL);
|
||||||
|
+ when(config.getCodecName()).thenReturn("SBC");
|
||||||
|
+ assertThat(mProfile.getHighQualityAudioOptionLabel(mDevice)).isEqualTo(
|
||||||
|
+ String.format(KNOWN_CODEC_LABEL, config.getCodecName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
@ -0,0 +1,48 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: ValdikSS <iam@valdikss.org.ru>
|
||||||
|
Date: Mon, 10 Sep 2018 02:02:50 +0300
|
||||||
|
Subject: [PATCH] SBC Dual Channel (SBC HD Audio) support
|
||||||
|
|
||||||
|
"HD Audio" checkbox is not checked for SBC by default.
|
||||||
|
|
||||||
|
Change-Id: Id45c48aeaa2eb86f3dffa0cc825d1e09f1c00187
|
||||||
|
---
|
||||||
|
src/com/android/bluetooth/a2dp/A2dpCodecConfig.java | 8 ++++++++
|
||||||
|
src/com/android/bluetooth/a2dp/A2dpService.java | 5 ++++-
|
||||||
|
2 files changed, 12 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java b/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java
|
||||||
|
index 8127e766b..890f4c188 100644
|
||||||
|
--- a/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java
|
||||||
|
+++ b/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java
|
||||||
|
@@ -109,6 +109,14 @@ class A2dpCodecConfig {
|
||||||
|
BluetoothCodecConfig codecConfig = codecConfigArray[i];
|
||||||
|
if (!codecConfig.isMandatoryCodec()) {
|
||||||
|
codecConfigArray[i] = null;
|
||||||
|
+ } else {
|
||||||
|
+ // Rebuild SBC selectable codec with Dual Channel (SBC HD audio)
|
||||||
|
+ codecConfigArray[i] = new BluetoothCodecConfig(
|
||||||
|
+ BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, mA2dpSourceCodecPrioritySbc,
|
||||||
|
+ BluetoothCodecConfig.SAMPLE_RATE_NONE,
|
||||||
|
+ BluetoothCodecConfig.BITS_PER_SAMPLE_NONE,
|
||||||
|
+ BluetoothCodecConfig.CHANNEL_MODE_DUAL_CHANNEL, 0 /* codecSpecific1 */,
|
||||||
|
+ 0 /* codecSpecific2 */, 0 /* codecSpecific3 */, 0 /* codecSpecific4 */);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/com/android/bluetooth/a2dp/A2dpService.java b/src/com/android/bluetooth/a2dp/A2dpService.java
|
||||||
|
index f9d0501c2..18a00646a 100644
|
||||||
|
--- a/src/com/android/bluetooth/a2dp/A2dpService.java
|
||||||
|
+++ b/src/com/android/bluetooth/a2dp/A2dpService.java
|
||||||
|
@@ -1039,7 +1039,10 @@ public class A2dpService extends ProfileService {
|
||||||
|
BluetoothCodecStatus codecStatus = sm.getCodecStatus();
|
||||||
|
if (codecStatus != null) {
|
||||||
|
for (BluetoothCodecConfig config : codecStatus.getCodecsSelectableCapabilities()) {
|
||||||
|
- if (config.isMandatoryCodec()) {
|
||||||
|
+ boolean isMandatoryCodecWithDualChannel = (config.isMandatoryCodec()
|
||||||
|
+ && (config.getChannelMode() & config.CHANNEL_MODE_DUAL_CHANNEL)
|
||||||
|
+ == config.CHANNEL_MODE_DUAL_CHANNEL);
|
||||||
|
+ if (config.isMandatoryCodec() || !isMandatoryCodecWithDualChannel) {
|
||||||
|
hasMandatoryCodec = true;
|
||||||
|
} else {
|
||||||
|
supportsOptional = true;
|
@ -0,0 +1,33 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: ValdikSS <iam@valdikss.org.ru>
|
||||||
|
Date: Mon, 17 Sep 2018 19:04:27 +0300
|
||||||
|
Subject: [PATCH] Assume optional codecs are supported if were supported
|
||||||
|
previously
|
||||||
|
|
||||||
|
This fix is required to properly follow codec reconfiguration for SBC HD
|
||||||
|
(SBC Dual Channel) in case of incoming Bluetooth connection.
|
||||||
|
|
||||||
|
Change-Id: Idb8fce75b4f628ae865fc1d3a787e34b6a29e31e
|
||||||
|
---
|
||||||
|
src/com/android/bluetooth/a2dp/A2dpService.java | 6 +++---
|
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/com/android/bluetooth/a2dp/A2dpService.java b/src/com/android/bluetooth/a2dp/A2dpService.java
|
||||||
|
index 18a00646a..11b283d72 100644
|
||||||
|
--- a/src/com/android/bluetooth/a2dp/A2dpService.java
|
||||||
|
+++ b/src/com/android/bluetooth/a2dp/A2dpService.java
|
||||||
|
@@ -1059,11 +1059,11 @@ public class A2dpService extends ProfileService {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (previousSupport == BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN
|
||||||
|
- || supportsOptional != (previousSupport
|
||||||
|
- == BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED)) {
|
||||||
|
+ || previousSupport == BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED) {
|
||||||
|
setSupportsOptionalCodecs(device, supportsOptional);
|
||||||
|
}
|
||||||
|
- if (supportsOptional) {
|
||||||
|
+ if (supportsOptional
|
||||||
|
+ || previousSupport == BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED) {
|
||||||
|
int enabled = getOptionalCodecsEnabled(device);
|
||||||
|
switch (enabled) {
|
||||||
|
case BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN:
|
@ -0,0 +1,67 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: ValdikSS <iam@valdikss.org.ru>
|
||||||
|
Date: Mon, 10 Sep 2018 14:01:25 +0300
|
||||||
|
Subject: [PATCH] Add Dual Channel into Bluetooth Audio Channel Mode developer
|
||||||
|
options menu
|
||||||
|
|
||||||
|
Change-Id: Icd3179ac63310355547fd58060e75f25b4a8210d
|
||||||
|
---
|
||||||
|
res/xml/development_settings.xml | 4 ++--
|
||||||
|
.../BluetoothAudioChannelModePreferenceController.java | 10 ++++++++--
|
||||||
|
2 files changed, 10 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
|
||||||
|
index 0262556d09..f02301d51b 100644
|
||||||
|
--- a/res/xml/development_settings.xml
|
||||||
|
+++ b/res/xml/development_settings.xml
|
||||||
|
@@ -356,8 +356,8 @@
|
||||||
|
android:key="bluetooth_select_a2dp_channel_mode"
|
||||||
|
android:title="@string/bluetooth_select_a2dp_codec_channel_mode"
|
||||||
|
android:dialogTitle="@string/bluetooth_select_a2dp_codec_channel_mode_dialog_title"
|
||||||
|
- android:entries="@array/bluetooth_a2dp_codec_channel_mode_titles"
|
||||||
|
- android:entryValues="@array/bluetooth_a2dp_codec_channel_mode_values" />
|
||||||
|
+ android:entries="@array/lineage_bluetooth_a2dp_codec_channel_mode_titles"
|
||||||
|
+ android:entryValues="@array/lineage_bluetooth_a2dp_codec_channel_mode_values" />
|
||||||
|
|
||||||
|
<ListPreference
|
||||||
|
android:key="bluetooth_select_a2dp_ldac_playback_quality"
|
||||||
|
diff --git a/src/com/android/settings/development/BluetoothAudioChannelModePreferenceController.java b/src/com/android/settings/development/BluetoothAudioChannelModePreferenceController.java
|
||||||
|
index a58c675516..50fcdd42af 100644
|
||||||
|
--- a/src/com/android/settings/development/BluetoothAudioChannelModePreferenceController.java
|
||||||
|
+++ b/src/com/android/settings/development/BluetoothAudioChannelModePreferenceController.java
|
||||||
|
@@ -42,13 +42,13 @@ public class BluetoothAudioChannelModePreferenceController extends
|
||||||
|
@Override
|
||||||
|
protected String[] getListValues() {
|
||||||
|
return mContext.getResources().getStringArray(
|
||||||
|
- R.array.bluetooth_a2dp_codec_channel_mode_values);
|
||||||
|
+ R.array.lineage_bluetooth_a2dp_codec_channel_mode_values);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] getListSummaries() {
|
||||||
|
return mContext.getResources().getStringArray(
|
||||||
|
- R.array.bluetooth_a2dp_codec_channel_mode_summaries);
|
||||||
|
+ R.array.lineage_bluetooth_a2dp_codec_channel_mode_summaries);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@@ -70,6 +70,9 @@ public class BluetoothAudioChannelModePreferenceController extends
|
||||||
|
case 2:
|
||||||
|
channelModeValue = BluetoothCodecConfig.CHANNEL_MODE_STEREO;
|
||||||
|
break;
|
||||||
|
+ case 3:
|
||||||
|
+ channelModeValue = BluetoothCodecConfig.CHANNEL_MODE_DUAL_CHANNEL;
|
||||||
|
+ break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -87,6 +90,9 @@ public class BluetoothAudioChannelModePreferenceController extends
|
||||||
|
case BluetoothCodecConfig.CHANNEL_MODE_STEREO:
|
||||||
|
index = 2;
|
||||||
|
break;
|
||||||
|
+ case BluetoothCodecConfig.CHANNEL_MODE_DUAL_CHANNEL:
|
||||||
|
+ index = 3;
|
||||||
|
+ break;
|
||||||
|
case BluetoothCodecConfig.CHANNEL_MODE_NONE:
|
||||||
|
default:
|
||||||
|
break;
|
57
Patches/LineageOS-17.1/android_system_bt/272648.patch
Normal file
57
Patches/LineageOS-17.1/android_system_bt/272648.patch
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: ValdikSS <iam@valdikss.org.ru>
|
||||||
|
Date: Sun, 9 Sep 2018 01:50:42 +0300
|
||||||
|
Subject: [PATCH] Increase maximum Bluetooth SBC codec bitrate for SBC HD
|
||||||
|
|
||||||
|
This commit increases maximum possible bitrate to 452 kbit/s for 44.1 kHz,
|
||||||
|
492 kbit/s for 48 kHz, which is optimal for both
|
||||||
|
EDR 2 mbit/s (4 audio frames, 11.7 ms, 6 wasted bytes) and
|
||||||
|
EDR 3 mbit/s (6 audio frames, 17.5 ms, 20 wasted bytes).
|
||||||
|
|
||||||
|
It does not increase bitpool value and won't introduce higher bitrates for
|
||||||
|
modes other than SBC Dual Channel.
|
||||||
|
|
||||||
|
Change-Id: I43f0b48f8b99bfb296c6b5a0b7fdb4d0592f5f82
|
||||||
|
---
|
||||||
|
stack/a2dp/a2dp_sbc_encoder.cc | 16 ++++++++++++----
|
||||||
|
1 file changed, 12 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/stack/a2dp/a2dp_sbc_encoder.cc b/stack/a2dp/a2dp_sbc_encoder.cc
|
||||||
|
index aac7e6d18..16d28e808 100644
|
||||||
|
--- a/stack/a2dp/a2dp_sbc_encoder.cc
|
||||||
|
+++ b/stack/a2dp/a2dp_sbc_encoder.cc
|
||||||
|
@@ -39,15 +39,19 @@
|
||||||
|
// A2DP SBC encoder interval in milliseconds.
|
||||||
|
#define A2DP_SBC_ENCODER_INTERVAL_MS 20
|
||||||
|
|
||||||
|
-/* High quality quality setting @ 44.1 khz */
|
||||||
|
-#define A2DP_SBC_DEFAULT_BITRATE 328
|
||||||
|
+/*
|
||||||
|
+ * Higher quality setting. 492 kbps @ 48 khz, 452 kbps @ 44.1 khz.
|
||||||
|
+ * Up to 4 frames for 2DH5, 6 frames for 3DH5.
|
||||||
|
+ */
|
||||||
|
+#define A2DP_SBC_DEFAULT_BITRATE 454
|
||||||
|
+#define A2DP_SBC_48KHZ_BITRATE 494
|
||||||
|
|
||||||
|
#define A2DP_SBC_NON_EDR_MAX_RATE 229
|
||||||
|
|
||||||
|
#define A2DP_SBC_MAX_PCM_ITER_NUM_PER_TICK 3
|
||||||
|
|
||||||
|
-#define A2DP_SBC_MAX_HQ_FRAME_SIZE_44_1 119
|
||||||
|
-#define A2DP_SBC_MAX_HQ_FRAME_SIZE_48 115
|
||||||
|
+#define A2DP_SBC_MAX_HQ_FRAME_SIZE_44_1 165
|
||||||
|
+#define A2DP_SBC_MAX_HQ_FRAME_SIZE_48 165
|
||||||
|
|
||||||
|
/* Define the bitrate step when trying to match bitpool value */
|
||||||
|
#define A2DP_SBC_BITRATE_STEP 5
|
||||||
|
@@ -832,6 +836,10 @@ static uint8_t calculate_max_frames_per_packet(void) {
|
||||||
|
static uint16_t a2dp_sbc_source_rate() {
|
||||||
|
uint16_t rate = A2DP_SBC_DEFAULT_BITRATE;
|
||||||
|
|
||||||
|
+ if (a2dp_sbc_encoder_cb.sbc_encoder_params.s16SamplingFreq == SBC_sf48000) {
|
||||||
|
+ rate = A2DP_SBC_48KHZ_BITRATE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* restrict bitrate if a2dp link is non-edr */
|
||||||
|
if (!a2dp_sbc_encoder_cb.is_peer_edr) {
|
||||||
|
rate = A2DP_SBC_NON_EDR_MAX_RATE;
|
418
Patches/LineageOS-17.1/android_system_bt/272649.patch
Normal file
418
Patches/LineageOS-17.1/android_system_bt/272649.patch
Normal file
@ -0,0 +1,418 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: ValdikSS <iam@valdikss.org.ru>
|
||||||
|
Date: Mon, 17 Sep 2018 18:48:42 +0300
|
||||||
|
Subject: [PATCH] Explicit SBC Dual Channel (SBC HD) support
|
||||||
|
|
||||||
|
Overwhelming majority of Bluetooth audio devices have SBC maximum bitpool value
|
||||||
|
limited to 53, which prevents bitrates higher than 328 kbit/s to be used with
|
||||||
|
the most common 44.1 kHz Joint Stereo, 8 subbands, 16 blocks profile. This
|
||||||
|
limitation could be circumvented on any existing device to achieve higher audio
|
||||||
|
quality, by using Dual Channel mode.
|
||||||
|
Dual Channel encodes channels separately, using the entire bitpool for each
|
||||||
|
channel. Forcing the device to use Dual Channel instead of Joint Stereo almost
|
||||||
|
doubles maximum possible bitrate for the same bitpool value.
|
||||||
|
|
||||||
|
A2DP specification v1.2, which was active from 2007 to 2015, requires all
|
||||||
|
decoders to work correctly with bitrates up to 512 kbps. Newer specification
|
||||||
|
does not have the limit at all. It is assumed that most modern headphones with
|
||||||
|
EDR support can handle any SBC profile with maximum bitpool value, regardless
|
||||||
|
of resulting bitrate.
|
||||||
|
|
||||||
|
This commit defines optimal Dual Channel bitrate profiles:
|
||||||
|
EDR 2mbit/s - 452 kbit/s for 44.1 kHz, 492 kbit/s for 48 kHz (bitpool 38,
|
||||||
|
4 audio frames, 10.7 ms, 6 wasted bytes per packet)
|
||||||
|
EDR 3mbit/s - 551.3 kbit/s for 44.1 kHz, 600 kbit/s for 48 kHz (bitpool 47,
|
||||||
|
5 audio frames, 13.4 ms, 4 wasted bytes per packet)
|
||||||
|
|
||||||
|
With 452 kbit/s, SBC outperforms aptX, with 551.3 kbit/s, on par or close to
|
||||||
|
aptX HD.
|
||||||
|
|
||||||
|
53 out of 57 tested headphones, receivers and automotive head units were able
|
||||||
|
to correctly receive and decode high bitrate Dual Channel audio.
|
||||||
|
SBC HD is disabled by default and could be activated in Bluetooth device menu,
|
||||||
|
per device.
|
||||||
|
|
||||||
|
Change-Id: Ic002851882900476019d70a9e3cb0c0bab3de290
|
||||||
|
---
|
||||||
|
audio_a2dp_hw/src/audio_a2dp_hw.cc | 6 ++-
|
||||||
|
audio_a2dp_hw/test/audio_a2dp_hw_test.cc | 1 +
|
||||||
|
.../test/audio_hearing_aid_hw_test.cc | 1 +
|
||||||
|
include/hardware/bt_av.h | 6 ++-
|
||||||
|
stack/a2dp/a2dp_aac.cc | 2 +
|
||||||
|
stack/a2dp/a2dp_codec_config.cc | 11 ++++-
|
||||||
|
stack/a2dp/a2dp_sbc.cc | 48 +++++++++----------
|
||||||
|
stack/a2dp/a2dp_sbc_encoder.cc | 22 ++++++++-
|
||||||
|
stack/a2dp/a2dp_vendor_aptx.cc | 2 +
|
||||||
|
stack/a2dp/a2dp_vendor_aptx_hd.cc | 2 +
|
||||||
|
stack/a2dp/a2dp_vendor_ldac.cc | 2 +
|
||||||
|
11 files changed, 75 insertions(+), 28 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/audio_a2dp_hw/src/audio_a2dp_hw.cc b/audio_a2dp_hw/src/audio_a2dp_hw.cc
|
||||||
|
index 2fb139f89..0b0d312b4 100644
|
||||||
|
--- a/audio_a2dp_hw/src/audio_a2dp_hw.cc
|
||||||
|
+++ b/audio_a2dp_hw/src/audio_a2dp_hw.cc
|
||||||
|
@@ -611,6 +611,7 @@ static int a2dp_read_output_audio_config(
|
||||||
|
stream_config.is_stereo_to_mono = true;
|
||||||
|
break;
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
|
||||||
|
+ case BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL:
|
||||||
|
stream_config.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
|
||||||
|
stream_config.is_stereo_to_mono = false;
|
||||||
|
break;
|
||||||
|
@@ -1075,6 +1076,7 @@ size_t audio_a2dp_hw_stream_compute_buffer_size(
|
||||||
|
number_of_channels = 1;
|
||||||
|
break;
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
|
||||||
|
+ case BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL:
|
||||||
|
number_of_channels = 2;
|
||||||
|
break;
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
|
||||||
|
@@ -1285,7 +1287,9 @@ static char* out_get_parameters(const struct audio_stream* stream,
|
||||||
|
if (!param.empty()) param += "|";
|
||||||
|
param += "AUDIO_CHANNEL_OUT_MONO";
|
||||||
|
}
|
||||||
|
- if (codec_capability.channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO) {
|
||||||
|
+ if (codec_capability.channel_mode &
|
||||||
|
+ (BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO |
|
||||||
|
+ BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL)) {
|
||||||
|
if (!param.empty()) param += "|";
|
||||||
|
param += "AUDIO_CHANNEL_OUT_STEREO";
|
||||||
|
}
|
||||||
|
diff --git a/audio_a2dp_hw/test/audio_a2dp_hw_test.cc b/audio_a2dp_hw/test/audio_a2dp_hw_test.cc
|
||||||
|
index 8fcbae515..ce64e6e3a 100644
|
||||||
|
--- a/audio_a2dp_hw/test/audio_a2dp_hw_test.cc
|
||||||
|
+++ b/audio_a2dp_hw/test/audio_a2dp_hw_test.cc
|
||||||
|
@@ -67,6 +67,7 @@ static uint32_t codec_channel_mode2value(
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
|
||||||
|
return 1;
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
|
||||||
|
+ case BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL:
|
||||||
|
return 2;
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
|
||||||
|
break;
|
||||||
|
diff --git a/audio_hearing_aid_hw/test/audio_hearing_aid_hw_test.cc b/audio_hearing_aid_hw/test/audio_hearing_aid_hw_test.cc
|
||||||
|
index c5d0e2b4e..55b0515d6 100644
|
||||||
|
--- a/audio_hearing_aid_hw/test/audio_hearing_aid_hw_test.cc
|
||||||
|
+++ b/audio_hearing_aid_hw/test/audio_hearing_aid_hw_test.cc
|
||||||
|
@@ -67,6 +67,7 @@ static uint32_t codec_channel_mode2value(
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
|
||||||
|
return 1;
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
|
||||||
|
+ case BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL:
|
||||||
|
return 2;
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
|
||||||
|
break;
|
||||||
|
diff --git a/include/hardware/bt_av.h b/include/hardware/bt_av.h
|
||||||
|
index 59827e2d5..1b0ed42de 100644
|
||||||
|
--- a/include/hardware/bt_av.h
|
||||||
|
+++ b/include/hardware/bt_av.h
|
||||||
|
@@ -107,7 +107,8 @@ typedef enum {
|
||||||
|
typedef enum {
|
||||||
|
BTAV_A2DP_CODEC_CHANNEL_MODE_NONE = 0x0,
|
||||||
|
BTAV_A2DP_CODEC_CHANNEL_MODE_MONO = 0x1 << 0,
|
||||||
|
- BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO = 0x1 << 1
|
||||||
|
+ BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO = 0x1 << 1,
|
||||||
|
+ BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL = 0x1 << 2
|
||||||
|
} btav_a2dp_codec_channel_mode_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -223,6 +224,9 @@ typedef struct {
|
||||||
|
AppendCapability(channel_mode_str,
|
||||||
|
(channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO),
|
||||||
|
"STEREO");
|
||||||
|
+ AppendCapability(channel_mode_str,
|
||||||
|
+ (channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL),
|
||||||
|
+ "DUAL_CHANNEL");
|
||||||
|
|
||||||
|
return "codec: " + codec_name_str +
|
||||||
|
" priority: " + std::to_string(codec_priority) +
|
||||||
|
diff --git a/stack/a2dp/a2dp_aac.cc b/stack/a2dp/a2dp_aac.cc
|
||||||
|
index df641be8f..7c9d7afdd 100644
|
||||||
|
--- a/stack/a2dp/a2dp_aac.cc
|
||||||
|
+++ b/stack/a2dp/a2dp_aac.cc
|
||||||
|
@@ -978,6 +978,7 @@ static bool select_audio_channel_mode(
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
+ case BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL:
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -1249,6 +1250,7 @@ bool A2dpCodecConfigAacBase::setCodecConfig(const uint8_t* p_peer_codec_info,
|
||||||
|
codec_config_.channel_mode = codec_user_config_.channel_mode;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
+ case BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL:
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
|
||||||
|
codec_capability_.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
|
||||||
|
codec_config_.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
|
||||||
|
diff --git a/stack/a2dp/a2dp_codec_config.cc b/stack/a2dp/a2dp_codec_config.cc
|
||||||
|
index 2480cdc66..5f4371fbc 100644
|
||||||
|
--- a/stack/a2dp/a2dp_codec_config.cc
|
||||||
|
+++ b/stack/a2dp/a2dp_codec_config.cc
|
||||||
|
@@ -340,6 +340,9 @@ bool A2dpCodecConfig::setCodecUserConfig(
|
||||||
|
uint8_t* p_result_codec_config, bool* p_restart_input,
|
||||||
|
bool* p_restart_output, bool* p_config_updated) {
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
|
||||||
|
+ auto stereo_dualchannel_inv_mask =
|
||||||
|
+ ~(BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL |
|
||||||
|
+ BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO);
|
||||||
|
*p_restart_input = false;
|
||||||
|
*p_restart_output = false;
|
||||||
|
*p_config_updated = false;
|
||||||
|
@@ -370,7 +373,9 @@ bool A2dpCodecConfig::setCodecUserConfig(
|
||||||
|
if ((saved_codec_config.sample_rate != new_codec_config.sample_rate) ||
|
||||||
|
(saved_codec_config.bits_per_sample !=
|
||||||
|
new_codec_config.bits_per_sample) ||
|
||||||
|
- (saved_codec_config.channel_mode != new_codec_config.channel_mode)) {
|
||||||
|
+ ((saved_codec_config.channel_mode != new_codec_config.channel_mode) &&
|
||||||
|
+ (saved_codec_config.channel_mode & stereo_dualchannel_inv_mask) !=
|
||||||
|
+ (new_codec_config.channel_mode & stereo_dualchannel_inv_mask))) {
|
||||||
|
*p_restart_input = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -499,6 +504,10 @@ std::string A2dpCodecConfig::codecChannelMode2Str(
|
||||||
|
if (!result.empty()) result += "|";
|
||||||
|
result += "STEREO";
|
||||||
|
}
|
||||||
|
+ if (codec_channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL) {
|
||||||
|
+ if (!result.empty()) result += "|";
|
||||||
|
+ result += "DUAL_CHANNEL";
|
||||||
|
+ }
|
||||||
|
if (result.empty()) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "UnknownChannelMode(0x" << std::hex << codec_channel_mode << ")";
|
||||||
|
diff --git a/stack/a2dp/a2dp_sbc.cc b/stack/a2dp/a2dp_sbc.cc
|
||||||
|
index 4c48993c4..e0039d95c 100644
|
||||||
|
--- a/stack/a2dp/a2dp_sbc.cc
|
||||||
|
+++ b/stack/a2dp/a2dp_sbc.cc
|
||||||
|
@@ -55,8 +55,9 @@ typedef struct {
|
||||||
|
|
||||||
|
/* SBC Source codec capabilities */
|
||||||
|
static const tA2DP_SBC_CIE a2dp_sbc_source_caps = {
|
||||||
|
- (A2DP_SBC_IE_SAMP_FREQ_44), /* samp_freq */
|
||||||
|
- (A2DP_SBC_IE_CH_MD_MONO | A2DP_SBC_IE_CH_MD_JOINT), /* ch_mode */
|
||||||
|
+ (A2DP_SBC_IE_SAMP_FREQ_44), /* samp_freq */
|
||||||
|
+ (A2DP_SBC_IE_CH_MD_MONO | A2DP_SBC_IE_CH_MD_JOINT |
|
||||||
|
+ A2DP_SBC_IE_CH_MD_DUAL), /* ch_mode */
|
||||||
|
(A2DP_SBC_IE_BLOCKS_16 | A2DP_SBC_IE_BLOCKS_12 | A2DP_SBC_IE_BLOCKS_8 |
|
||||||
|
A2DP_SBC_IE_BLOCKS_4), /* block_len */
|
||||||
|
A2DP_SBC_IE_SUBBAND_8, /* num_subbands */
|
||||||
|
@@ -861,10 +862,11 @@ UNUSED_ATTR static void build_codec_config(const tA2DP_SBC_CIE& config_cie,
|
||||||
|
if (config_cie.ch_mode & A2DP_SBC_IE_CH_MD_MONO)
|
||||||
|
result->channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
|
||||||
|
|
||||||
|
- if (config_cie.ch_mode & (A2DP_SBC_IE_CH_MD_STEREO | A2DP_SBC_IE_CH_MD_JOINT |
|
||||||
|
- A2DP_SBC_IE_CH_MD_DUAL)) {
|
||||||
|
+ if (config_cie.ch_mode & (A2DP_SBC_IE_CH_MD_STEREO | A2DP_SBC_IE_CH_MD_JOINT))
|
||||||
|
result->channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
|
||||||
|
- }
|
||||||
|
+
|
||||||
|
+ if (config_cie.ch_mode & A2DP_SBC_IE_CH_MD_DUAL)
|
||||||
|
+ result->channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
A2dpCodecConfigSbcSource::A2dpCodecConfigSbcSource(
|
||||||
|
@@ -890,7 +892,8 @@ A2dpCodecConfigSbcSource::A2dpCodecConfigSbcSource(
|
||||||
|
codec_local_capability_.channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
|
||||||
|
}
|
||||||
|
if (a2dp_sbc_source_caps.ch_mode & A2DP_SBC_IE_CH_MD_DUAL) {
|
||||||
|
- codec_local_capability_.channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
|
||||||
|
+ codec_local_capability_.channel_mode |=
|
||||||
|
+ BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1017,7 +1020,7 @@ static bool select_best_channel_mode(uint8_t ch_mode, tA2DP_SBC_CIE* p_result,
|
||||||
|
}
|
||||||
|
if (ch_mode & A2DP_SBC_IE_CH_MD_DUAL) {
|
||||||
|
p_result->ch_mode = A2DP_SBC_IE_CH_MD_DUAL;
|
||||||
|
- p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
|
||||||
|
+ p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ch_mode & A2DP_SBC_IE_CH_MD_MONO) {
|
||||||
|
@@ -1056,9 +1059,12 @@ static bool select_audio_channel_mode(
|
||||||
|
p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
+ break;
|
||||||
|
+ case BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL:
|
||||||
|
if (ch_mode & A2DP_SBC_IE_CH_MD_DUAL) {
|
||||||
|
p_result->ch_mode = A2DP_SBC_IE_CH_MD_DUAL;
|
||||||
|
- p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
|
||||||
|
+ p_codec_config->channel_mode =
|
||||||
|
+ BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
@@ -1108,17 +1114,9 @@ bool A2dpCodecConfigSbcBase::setCodecConfig(const uint8_t* p_peer_codec_info,
|
||||||
|
}
|
||||||
|
// Try using the prefered peer codec config (if valid), instead of the peer
|
||||||
|
// capability.
|
||||||
|
- if (is_capability) {
|
||||||
|
- if (is_source_) {
|
||||||
|
- if (A2DP_IsPeerSinkCodecValidSbc(ota_codec_peer_config_)) {
|
||||||
|
- status =
|
||||||
|
- A2DP_ParseInfoSbc(&peer_info_cie, ota_codec_peer_config_, false);
|
||||||
|
- }
|
||||||
|
- } else {
|
||||||
|
- if (A2DP_IsPeerSourceCodecValidSbc(ota_codec_peer_config_)) {
|
||||||
|
- status =
|
||||||
|
- A2DP_ParseInfoSbc(&peer_info_cie, ota_codec_peer_config_, false);
|
||||||
|
- }
|
||||||
|
+ if (is_capability && !is_source_) {
|
||||||
|
+ if (A2DP_IsPeerSourceCodecValidSbc(ota_codec_peer_config_)) {
|
||||||
|
+ status = A2DP_ParseInfoSbc(&peer_info_cie, ota_codec_peer_config_, false);
|
||||||
|
}
|
||||||
|
if (status != A2DP_SUCCESS) {
|
||||||
|
// Use the peer codec capability
|
||||||
|
@@ -1292,11 +1290,12 @@ bool A2dpCodecConfigSbcBase::setCodecConfig(const uint8_t* p_peer_codec_info,
|
||||||
|
codec_config_.channel_mode = codec_user_config_.channel_mode;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+ break;
|
||||||
|
+ case BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL:
|
||||||
|
if (ch_mode & A2DP_SBC_IE_CH_MD_DUAL) {
|
||||||
|
result_config_cie.ch_mode = A2DP_SBC_IE_CH_MD_DUAL;
|
||||||
|
codec_capability_.channel_mode = codec_user_config_.channel_mode;
|
||||||
|
codec_config_.channel_mode = codec_user_config_.channel_mode;
|
||||||
|
- break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
|
||||||
|
@@ -1322,7 +1321,7 @@ bool A2dpCodecConfigSbcBase::setCodecConfig(const uint8_t* p_peer_codec_info,
|
||||||
|
}
|
||||||
|
if (ch_mode & A2DP_SBC_IE_CH_MD_DUAL) {
|
||||||
|
codec_selectable_capability_.channel_mode |=
|
||||||
|
- BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
|
||||||
|
+ BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codec_config_.channel_mode != BTAV_A2DP_CODEC_CHANNEL_MODE_NONE) break;
|
||||||
|
@@ -1330,10 +1329,11 @@ bool A2dpCodecConfigSbcBase::setCodecConfig(const uint8_t* p_peer_codec_info,
|
||||||
|
// Compute the common capability
|
||||||
|
if (ch_mode & A2DP_SBC_IE_CH_MD_MONO)
|
||||||
|
codec_capability_.channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
|
||||||
|
- if (ch_mode & (A2DP_SBC_IE_CH_MD_JOINT | A2DP_SBC_IE_CH_MD_STEREO |
|
||||||
|
- A2DP_SBC_IE_CH_MD_DUAL)) {
|
||||||
|
+ if (ch_mode & (A2DP_SBC_IE_CH_MD_JOINT | A2DP_SBC_IE_CH_MD_STEREO)) {
|
||||||
|
codec_capability_.channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
|
||||||
|
}
|
||||||
|
+ if (ch_mode & A2DP_SBC_IE_CH_MD_DUAL)
|
||||||
|
+ codec_capability_.channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL;
|
||||||
|
|
||||||
|
// No user preference - use the codec audio config
|
||||||
|
if (select_audio_channel_mode(&codec_audio_config_, ch_mode,
|
||||||
|
@@ -1536,7 +1536,7 @@ bool A2dpCodecConfigSbcBase::setPeerCodecCapabilities(
|
||||||
|
}
|
||||||
|
if (ch_mode & A2DP_SBC_IE_CH_MD_DUAL) {
|
||||||
|
codec_selectable_capability_.channel_mode |=
|
||||||
|
- BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
|
||||||
|
+ BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = A2DP_BuildInfoSbc(AVDT_MEDIA_TYPE_AUDIO, &peer_info_cie,
|
||||||
|
diff --git a/stack/a2dp/a2dp_sbc_encoder.cc b/stack/a2dp/a2dp_sbc_encoder.cc
|
||||||
|
index 16d28e808..d80f1b680 100644
|
||||||
|
--- a/stack/a2dp/a2dp_sbc_encoder.cc
|
||||||
|
+++ b/stack/a2dp/a2dp_sbc_encoder.cc
|
||||||
|
@@ -46,8 +46,22 @@
|
||||||
|
#define A2DP_SBC_DEFAULT_BITRATE 454
|
||||||
|
#define A2DP_SBC_48KHZ_BITRATE 494
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * SBC Dual Channel (SBC HD) 3DH5 bitrates.
|
||||||
|
+ * 600 kbps @ 48 khz, 551.3 kbps @ 44.1 khz.
|
||||||
|
+ * Up to 5 frames for 3DH5.
|
||||||
|
+ */
|
||||||
|
+#define A2DP_SBC_3DH5_DEFAULT_BITRATE 552
|
||||||
|
+#define A2DP_SBC_3DH5_48KHZ_BITRATE 601
|
||||||
|
+
|
||||||
|
#define A2DP_SBC_NON_EDR_MAX_RATE 229
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * 3DH5 minimum safe payload size for 4 audio frames of:
|
||||||
|
+ * 817 bytes - (4 bytes L2CAP Header + 12 bytes AVDTP Header)
|
||||||
|
+ */
|
||||||
|
+#define MIN_3MBPS_AVDTP_SAFE_MTU 801
|
||||||
|
+
|
||||||
|
#define A2DP_SBC_MAX_PCM_ITER_NUM_PER_TICK 3
|
||||||
|
|
||||||
|
#define A2DP_SBC_MAX_HQ_FRAME_SIZE_44_1 165
|
||||||
|
@@ -836,8 +850,14 @@ static uint8_t calculate_max_frames_per_packet(void) {
|
||||||
|
static uint16_t a2dp_sbc_source_rate() {
|
||||||
|
uint16_t rate = A2DP_SBC_DEFAULT_BITRATE;
|
||||||
|
|
||||||
|
- if (a2dp_sbc_encoder_cb.sbc_encoder_params.s16SamplingFreq == SBC_sf48000) {
|
||||||
|
+ if (a2dp_sbc_encoder_cb.sbc_encoder_params.s16SamplingFreq == SBC_sf48000)
|
||||||
|
rate = A2DP_SBC_48KHZ_BITRATE;
|
||||||
|
+
|
||||||
|
+ if (a2dp_sbc_encoder_cb.peer_supports_3mbps &&
|
||||||
|
+ a2dp_sbc_encoder_cb.TxAaMtuSize >= MIN_3MBPS_AVDTP_SAFE_MTU) {
|
||||||
|
+ rate = A2DP_SBC_3DH5_DEFAULT_BITRATE;
|
||||||
|
+ if (a2dp_sbc_encoder_cb.sbc_encoder_params.s16SamplingFreq == SBC_sf48000)
|
||||||
|
+ rate = A2DP_SBC_3DH5_48KHZ_BITRATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* restrict bitrate if a2dp link is non-edr */
|
||||||
|
diff --git a/stack/a2dp/a2dp_vendor_aptx.cc b/stack/a2dp/a2dp_vendor_aptx.cc
|
||||||
|
index e3e844d73..62c1da9f2 100644
|
||||||
|
--- a/stack/a2dp/a2dp_vendor_aptx.cc
|
||||||
|
+++ b/stack/a2dp/a2dp_vendor_aptx.cc
|
||||||
|
@@ -611,6 +611,7 @@ static bool select_audio_channel_mode(
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
+ case BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL:
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -812,6 +813,7 @@ bool A2dpCodecConfigAptx::setCodecConfig(const uint8_t* p_peer_codec_info,
|
||||||
|
codec_config_.channel_mode = codec_user_config_.channel_mode;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
+ case BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL:
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
|
||||||
|
codec_capability_.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
|
||||||
|
codec_config_.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
|
||||||
|
diff --git a/stack/a2dp/a2dp_vendor_aptx_hd.cc b/stack/a2dp/a2dp_vendor_aptx_hd.cc
|
||||||
|
index 9e19d5fee..36e3530eb 100644
|
||||||
|
--- a/stack/a2dp/a2dp_vendor_aptx_hd.cc
|
||||||
|
+++ b/stack/a2dp/a2dp_vendor_aptx_hd.cc
|
||||||
|
@@ -629,6 +629,7 @@ static bool select_audio_channel_mode(
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
+ case BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL:
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -831,6 +832,7 @@ bool A2dpCodecConfigAptxHd::setCodecConfig(const uint8_t* p_peer_codec_info,
|
||||||
|
codec_config_.channel_mode = codec_user_config_.channel_mode;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
+ case BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL:
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
|
||||||
|
codec_capability_.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
|
||||||
|
codec_config_.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
|
||||||
|
diff --git a/stack/a2dp/a2dp_vendor_ldac.cc b/stack/a2dp/a2dp_vendor_ldac.cc
|
||||||
|
index 4949e74e9..aae79c1d8 100644
|
||||||
|
--- a/stack/a2dp/a2dp_vendor_ldac.cc
|
||||||
|
+++ b/stack/a2dp/a2dp_vendor_ldac.cc
|
||||||
|
@@ -941,6 +941,7 @@ static bool select_audio_channel_mode(
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
+ case BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL:
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -1221,6 +1222,7 @@ bool A2dpCodecConfigLdacBase::setCodecConfig(const uint8_t* p_peer_codec_info,
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
+ case BTAV_A2DP_CODEC_CHANNEL_MODE_DUAL_CHANNEL:
|
||||||
|
case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
|
||||||
|
codec_capability_.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
|
||||||
|
codec_config_.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
|
64
Patches/LineageOS-17.1/android_system_bt/272650.patch
Normal file
64
Patches/LineageOS-17.1/android_system_bt/272650.patch
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: ValdikSS <iam@valdikss.org.ru>
|
||||||
|
Date: Thu, 13 Sep 2018 23:14:10 +0300
|
||||||
|
Subject: [PATCH] Allow using alternative (higher) SBC HD bitrates with a
|
||||||
|
property
|
||||||
|
|
||||||
|
Change-Id: Ic85e5c8a8c70233de2125e69c01d74e5501a2da8
|
||||||
|
---
|
||||||
|
stack/a2dp/a2dp_sbc_encoder.cc | 21 +++++++++++++++++++++
|
||||||
|
1 file changed, 21 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/stack/a2dp/a2dp_sbc_encoder.cc b/stack/a2dp/a2dp_sbc_encoder.cc
|
||||||
|
index d80f1b680..5cf1ac104 100644
|
||||||
|
--- a/stack/a2dp/a2dp_sbc_encoder.cc
|
||||||
|
+++ b/stack/a2dp/a2dp_sbc_encoder.cc
|
||||||
|
@@ -32,6 +32,7 @@
|
||||||
|
#include "embdrv/sbc/encoder/include/sbc_encoder.h"
|
||||||
|
#include "osi/include/log.h"
|
||||||
|
#include "osi/include/osi.h"
|
||||||
|
+#include "osi/include/properties.h"
|
||||||
|
|
||||||
|
/* Buffer pool */
|
||||||
|
#define A2DP_SBC_BUFFER_SIZE BT_DEFAULT_BUFFER_SIZE
|
||||||
|
@@ -54,6 +55,17 @@
|
||||||
|
#define A2DP_SBC_3DH5_DEFAULT_BITRATE 552
|
||||||
|
#define A2DP_SBC_3DH5_48KHZ_BITRATE 601
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * SBC Dual Channel (SBC HD) 2DH5 alternative bitrates.
|
||||||
|
+ * 648 kbps @ 48 khz, 595.4 kbps @ 44.1 khz.
|
||||||
|
+ * Up to 3 frames for 2DH5.
|
||||||
|
+ */
|
||||||
|
+#define A2DP_SBC_2DH5_ALT_BITRATE 596
|
||||||
|
+#define A2DP_SBC_2DH5_ALT_48KHZ_BITRATE 649
|
||||||
|
+
|
||||||
|
+// SBC HD alternative bitrate property
|
||||||
|
+#define A2DP_SBC_HD_PROP "persist.bluetooth.sbc_hd_higher_bitrate"
|
||||||
|
+
|
||||||
|
#define A2DP_SBC_NON_EDR_MAX_RATE 229
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -853,6 +865,7 @@ static uint16_t a2dp_sbc_source_rate() {
|
||||||
|
if (a2dp_sbc_encoder_cb.sbc_encoder_params.s16SamplingFreq == SBC_sf48000)
|
||||||
|
rate = A2DP_SBC_48KHZ_BITRATE;
|
||||||
|
|
||||||
|
+ /* 3DH5 maximum bitrates */
|
||||||
|
if (a2dp_sbc_encoder_cb.peer_supports_3mbps &&
|
||||||
|
a2dp_sbc_encoder_cb.TxAaMtuSize >= MIN_3MBPS_AVDTP_SAFE_MTU) {
|
||||||
|
rate = A2DP_SBC_3DH5_DEFAULT_BITRATE;
|
||||||
|
@@ -860,6 +873,14 @@ static uint16_t a2dp_sbc_source_rate() {
|
||||||
|
rate = A2DP_SBC_3DH5_48KHZ_BITRATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* 2DH5 alternative bitrates */
|
||||||
|
+ if (!a2dp_sbc_encoder_cb.peer_supports_3mbps &&
|
||||||
|
+ osi_property_get_int32(A2DP_SBC_HD_PROP, 0)) {
|
||||||
|
+ rate = A2DP_SBC_2DH5_ALT_BITRATE;
|
||||||
|
+ if (a2dp_sbc_encoder_cb.sbc_encoder_params.s16SamplingFreq == SBC_sf48000)
|
||||||
|
+ rate = A2DP_SBC_2DH5_ALT_48KHZ_BITRATE;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* restrict bitrate if a2dp link is non-edr */
|
||||||
|
if (!a2dp_sbc_encoder_cb.is_peer_edr) {
|
||||||
|
rate = A2DP_SBC_NON_EDR_MAX_RATE;
|
@ -415,8 +415,8 @@ applyPatch "$DOS_PATCHES/android_system_bt/345528.patch"; #n-asb-2022-12 Added m
|
|||||||
applyPatch "$DOS_PATCHES/android_system_bt/345529.patch"; #n-asb-2022-12 Add missing increment in bnep_api.cc
|
applyPatch "$DOS_PATCHES/android_system_bt/345529.patch"; #n-asb-2022-12 Add missing increment in bnep_api.cc
|
||||||
applyPatch "$DOS_PATCHES/android_system_bt/345530.patch"; #n-asb-2022-12 Add length check when copy AVDT and AVCT packet
|
applyPatch "$DOS_PATCHES/android_system_bt/345530.patch"; #n-asb-2022-12 Add length check when copy AVDT and AVCT packet
|
||||||
applyPatch "$DOS_PATCHES/android_system_bt/345531.patch"; #n-asb-2022-12 Fix integer overflow when parsing avrc response
|
applyPatch "$DOS_PATCHES/android_system_bt/345531.patch"; #n-asb-2022-12 Fix integer overflow when parsing avrc response
|
||||||
applyPatch "$DOS_PATCHES/android_system_bt/229574.patch"; #Increase maximum Bluetooth SBC codec bitrate for SBC HD (ValdikSS)
|
applyPatch "$DOS_PATCHES/android_system_bt/229574.patch"; #bt-sbc-hd-dualchannel-nougat: Increase maximum Bluetooth SBC codec bitrate for SBC HD (ValdikSS)
|
||||||
applyPatch "$DOS_PATCHES/android_system_bt/229575.patch"; #Explicit SBC Dual Channel (SBC HD) support (ValdikSS)
|
applyPatch "$DOS_PATCHES/android_system_bt/229575.patch"; #bt-sbc-hd-dualchannel-nougat: Explicit SBC Dual Channel (SBC HD) support (ValdikSS)
|
||||||
applyPatch "$DOS_PATCHES/android_system_bt/242134.patch"; #avrc_bld_get_attrs_rsp - fix attribute length position off by one (cprhokie)
|
applyPatch "$DOS_PATCHES/android_system_bt/242134.patch"; #avrc_bld_get_attrs_rsp - fix attribute length position off by one (cprhokie)
|
||||||
applyPatch "$DOS_PATCHES/android_system_bt/0001-NO_READENCRKEYSIZE.patch"; #Add an option to let devices opt-out of the HCI_READ_ENCR_KEY_SIZE_SUPPORTED assert (DivestOS)
|
applyPatch "$DOS_PATCHES/android_system_bt/0001-NO_READENCRKEYSIZE.patch"; #Add an option to let devices opt-out of the HCI_READ_ENCR_KEY_SIZE_SUPPORTED assert (DivestOS)
|
||||||
fi;
|
fi;
|
||||||
|
@ -131,6 +131,9 @@ awk -i inplace '!/deletePackage/' pico/src/com/svox/pico/LangPackUninstaller.jav
|
|||||||
fi;
|
fi;
|
||||||
|
|
||||||
if enterAndClear "frameworks/base"; then
|
if enterAndClear "frameworks/base"; then
|
||||||
|
#applyPatch "$DOS_PATCHES/android_frameworks_base/272645.patch"; #ten-bt-sbc-hd-dualchannel: Add CHANNEL_MODE_DUAL_CHANNEL constant (ValdikSS)
|
||||||
|
#applyPatch "$DOS_PATCHES/android_frameworks_base/272646-forwardport.patch"; #ten-bt-sbc-hd-dualchannel: Add Dual Channel into Bluetooth Audio Channel Mode developer options menu (ValdikSS)
|
||||||
|
#applyPatch "$DOS_PATCHES/android_frameworks_base/272647.patch"; #ten-bt-sbc-hd-dualchannel: Allow SBC as HD audio codec in Bluetooth device configuration (ValdikSS)
|
||||||
applyPatch "$DOS_PATCHES/android_frameworks_base/0007-Always_Restict_Serial.patch"; #Always restrict access to Build.SERIAL (GrapheneOS)
|
applyPatch "$DOS_PATCHES/android_frameworks_base/0007-Always_Restict_Serial.patch"; #Always restrict access to Build.SERIAL (GrapheneOS)
|
||||||
applyPatch "$DOS_PATCHES/android_frameworks_base/0008-Browser_No_Location.patch"; #Don't grant location permission to system browsers (GrapheneOS)
|
applyPatch "$DOS_PATCHES/android_frameworks_base/0008-Browser_No_Location.patch"; #Don't grant location permission to system browsers (GrapheneOS)
|
||||||
applyPatch "$DOS_PATCHES/android_frameworks_base/0009-SystemUI_No_Permission_Review.patch"; #Allow SystemUI to directly manage Bluetooth/WiFi (GrapheneOS)
|
applyPatch "$DOS_PATCHES/android_frameworks_base/0009-SystemUI_No_Permission_Review.patch"; #Allow SystemUI to directly manage Bluetooth/WiFi (GrapheneOS)
|
||||||
@ -256,6 +259,8 @@ if [ "$DOS_DEBLOBBER_REMOVE_AUDIOFX" = true ]; then awk -i inplace '!/LineageAud
|
|||||||
fi;
|
fi;
|
||||||
|
|
||||||
if enterAndClear "packages/apps/Bluetooth"; then
|
if enterAndClear "packages/apps/Bluetooth"; then
|
||||||
|
#applyPatch "$DOS_PATCHES/android_packages_apps_Bluetooth/272652.patch"; #ten-bt-sbc-hd-dualchannel: SBC Dual Channel (SBC HD Audio) support (ValdikSS)
|
||||||
|
#applyPatch "$DOS_PATCHES/android_packages_apps_Bluetooth/272653.patch"; #ten-bt-sbc-hd-dualchannel: Assume optional codecs are supported if were supported previously (ValdikSS)
|
||||||
if [ "$DOS_GRAPHENE_CONSTIFY" = true ]; then applyPatch "$DOS_PATCHES/android_packages_apps_Bluetooth/0001-constify_JNINativeMethod.patch"; fi; #Constify JNINativeMethod tables (GrapheneOS)
|
if [ "$DOS_GRAPHENE_CONSTIFY" = true ]; then applyPatch "$DOS_PATCHES/android_packages_apps_Bluetooth/0001-constify_JNINativeMethod.patch"; fi; #Constify JNINativeMethod tables (GrapheneOS)
|
||||||
fi;
|
fi;
|
||||||
|
|
||||||
@ -294,6 +299,7 @@ fi;
|
|||||||
|
|
||||||
if enterAndClear "packages/apps/Settings"; then
|
if enterAndClear "packages/apps/Settings"; then
|
||||||
git revert --no-edit 486980cfecce2ca64267f41462f9371486308e9d; #Don't hide OEM unlock
|
git revert --no-edit 486980cfecce2ca64267f41462f9371486308e9d; #Don't hide OEM unlock
|
||||||
|
#applyPatch "$DOS_PATCHES/android_packages_apps_Settings/272651.patch"; #ten-bt-sbc-hd-dualchannel: Add Dual Channel into Bluetooth Audio Channel Mode developer options menu (ValdikSS)
|
||||||
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0001-Captive_Portal_Toggle.patch"; #Add option to disable captive portal checks (MSe1969)
|
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0001-Captive_Portal_Toggle.patch"; #Add option to disable captive portal checks (MSe1969)
|
||||||
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0003-Remove_SensorsOff_Tile.patch"; #Remove the Sensors Off development tile (DivestOS)
|
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0003-Remove_SensorsOff_Tile.patch"; #Remove the Sensors Off development tile (DivestOS)
|
||||||
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0004-Private_DNS.patch"; #More 'Private DNS' options (heavily based off of a CalyxOS patch)
|
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0004-Private_DNS.patch"; #More 'Private DNS' options (heavily based off of a CalyxOS patch)
|
||||||
@ -351,6 +357,9 @@ fi;
|
|||||||
|
|
||||||
if enterAndClear "system/bt"; then
|
if enterAndClear "system/bt"; then
|
||||||
applyPatch "$DOS_PATCHES_COMMON/android_system_bt/0001-alloc_size.patch"; #Add alloc_size attributes to the allocator (GrapheneOS)
|
applyPatch "$DOS_PATCHES_COMMON/android_system_bt/0001-alloc_size.patch"; #Add alloc_size attributes to the allocator (GrapheneOS)
|
||||||
|
#applyPatch "$DOS_PATCHES/android_system_bt/272648.patch"; #ten-bt-sbc-hd-dualchannel: Increase maximum Bluetooth SBC codec bitrate for SBC HD (ValdikSS)
|
||||||
|
#applyPatch "$DOS_PATCHES/android_system_bt/272649.patch"; #ten-bt-sbc-hd-dualchannel: Explicit SBC Dual Channel (SBC HD) support (ValdikSS)
|
||||||
|
#applyPatch "$DOS_PATCHES/android_system_bt/272650.patch"; #ten-bt-sbc-hd-dualchannel: Allow using alternative (higher) SBC HD bitrates with a property (ValdikSS)
|
||||||
fi;
|
fi;
|
||||||
|
|
||||||
if enterAndClear "system/core"; then
|
if enterAndClear "system/core"; then
|
||||||
|
@ -101,6 +101,7 @@ patchWorkspace() {
|
|||||||
gpgVerifyGitHead "$DOS_BUILD_BASE/external/chromium-webview";
|
gpgVerifyGitHead "$DOS_BUILD_BASE/external/chromium-webview";
|
||||||
|
|
||||||
source build/envsetup.sh;
|
source build/envsetup.sh;
|
||||||
|
#repopick -ift twelve-bt-sbc-hd-dualchannel;
|
||||||
#repopick -it twelve-colors;
|
#repopick -it twelve-colors;
|
||||||
repopick -it S_tzdb2022f;
|
repopick -it S_tzdb2022f;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user