[Android Software/Hacking General [Developers Only]] ValdikSS:
How to test on Android device

In order to test from Android smartphone or tablet you need to use modified Bluetooth stack, which requires root privilege.

For regular users

Use PC method if possible.

Create backup before overwriting bluetooth library. Some patched libraries are attached to this post.

Unrestricted/unlimited versions negotiate Dual Channel mode and disable bitrate restriction (617-660 kbit/s will be used). Versions with 482 or 486 prefix negotiate 474-485 kbit/s.

For ROM developers (Android 5-7)

Patchset which increases maximum Bitpool value and adds Bluetooth Dual Channel option is available using the following link:

LineageOS 14.1 (Android 7.1.2)

The following information is outdated and is kept only for historical reasons:

[b]These modifications are designed only for test and should not be applied to the main ROM repository![/b]
[b]If you're a ROM developer, please provide flashable modified bluetooth library if possible![/b]
These modifications should be applied to stock Android bluetooth stacks Bluedroid (Android 5) and Fluoride (Android 6-7). Qualcomm-modified stack is not supported.
[b]1. Replace Joint Stereo with Dual Channel in standard SBC configuration[/b]
[url="https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/master/btif/co/bta_av_co.c#99"][i]android/platform/external/bluetooth/bluedroid/btif/co/bta_av_co.c:99[/i][/url]
[code]const tA2D_SBC_CIE btif_av_sbc_default_config =
{
BTIF_AV_SBC_DEFAULT_SAMP_FREQ, /* samp_freq */
A2D_SBC_IE_CH_MD_JOINT, /* ch_mode */
A2D_SBC_IE_BLOCKS_16, /* block_len */
A2D_SBC_IE_SUBBAND_8, /* num_subbands */
A2D_SBC_IE_ALLOC_MD_L, /* alloc_mthd */
BTA_AV_CO_SBC_MAX_BITPOOL, /* max_bitpool */
A2D_SBC_IE_MIN_BITPOOL /* min_bitpool */
};

Replace A2D_SBC_IE_CH_MD_JOINT with A2D_SBC_IE_CH_MD_DUAL.

2. Increase Dual Channel priority

android/platform/external/bluetooth/bluedroid/btif/co/bta_av_co.c:411

if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_JOINT)
pref_cap.ch_mode = A2D_SBC_IE_CH_MD_JOINT;
else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_STEREO)
pref_cap.ch_mode = A2D_SBC_IE_CH_MD_STEREO;
else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_DUAL)
pref_cap.ch_mode = A2D_SBC_IE_CH_MD_DUAL;
else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_MONO)
pref_cap.ch_mode = A2D_SBC_IE_CH_MD_MONO;

Move if with A2D_SBC_IE_CH_MD_DUAL to the top.

3. Disable or increase bitrate restriction

Android bluetooth stack has not only bitpool limit, but also bitrate limit, 328 kbit/s. If the headphones support, for example, bitpool 53 for 48 kHz, Android will decrease the bitpool down to fit into 328 kbit/s limit. This will happen AFTER codec negotiation, on the encoding stage, do not take into account bitpool value in Bluetooth SetCapabilities packet.

android/platform/external/bluetooth/bluedroid/btif/src/btif_media_task.c:172

#define DEFAULT_SBC_BITRATE 328

Replace with 512.

4. (for experiments only) Disable MTU limit.

This is required for bitrates higher than ~580 kbit/s.

btif/src/btif_media_task.c:174

/* 2DH5 payload size of 679 bytes - (4 bytes L2CAP Header + 12 bytes AVDTP Header) */
#define MAX_2MBPS_AVDTP_MTU 663

[/code]

For ROM developers (Android 8-9)

Patchset which increases maximum Bitpool value and adds Bluetooth Dual Channel option is available using the following links:

LineageOS 15.1 (Android 8.1)

LineageOS 16.0 (Android 9)

AOSP Master (what will eventually become Android 9.1/10)

If you're a ROM developer, please provide flashable modified bluetooth library if possible!

The following information is outdated and is kept only for historical reasons:

1. Add Dual Channel support into A2DP SBC Source

/platform/system/bt/stack/a2dp/a2dp_sbc.cc:55

/* SBC SRC codec capabilities */
static const tA2DP_SBC_CIE a2dp_sbc_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_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 */
A2DP_SBC_IE_ALLOC_MD_L, /* alloc_method */
A2DP_SBC_IE_MIN_BITPOOL, /* min_bitpool */
A2DP_SBC_MAX_BITPOOL, /* max_bitpool */
BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16 /* bits_per_sample */
};

add A2DP_SBC_IE_CH_MD_DUAL in ch_mode.

2. Replace Joint Stereo with Dual Channel in default config

/platform/system/bt/stack/a2dp/a2dp_sbc.cc:82

/* Default SBC codec configuration */
const tA2DP_SBC_CIE a2dp_sbc_default_config = {
A2DP_SBC_IE_SAMP_FREQ_44, /* samp_freq */
A2DP_SBC_IE_CH_MD_JOINT, /* ch_mode */
A2DP_SBC_IE_BLOCKS_16, /* block_len */
A2DP_SBC_IE_SUBBAND_8, /* num_subbands */
A2DP_SBC_IE_ALLOC_MD_L, /* alloc_method */
A2DP_SBC_IE_MIN_BITPOOL, /* min_bitpool */
A2DP_SBC_MAX_BITPOOL, /* max_bitpool */
BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16 /* bits_per_sample */
};

Replace A2DP_SBC_IE_CH_MD_JOINT with A2DP_SBC_IE_CH_MD_DUAL.

3. Increase Dual Channel priority

/platform/system/bt/stack/a2dp/a2dp_sbc.cc:1155

static bool select_best_channel_mode(uint8_t ch_mode, tA2DP_SBC_CIE* p_result,
btav_a2dp_codec_config_t* p_codec_config) {
if (ch_mode & A2DP_SBC_IE_CH_MD_JOINT) {
p_result->ch_mode = A2DP_SBC_IE_CH_MD_JOINT;
p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
return true;
}
if (ch_mode & A2DP_SBC_IE_CH_MD_STEREO) {
p_result->ch_mode = A2DP_SBC_IE_CH_MD_STEREO;
p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
return true;
}
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;
return true;
}
if (ch_mode & A2DP_SBC_IE_CH_MD_MONO) {
p_result->ch_mode = A2DP_SBC_IE_CH_MD_MONO;
p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
return true;
}
return false;
}

Move if with A2DP_SBC_IE_CH_MD_DUAL to the top.

4. Increase bitrate limit

/platform/system/bt/stack/a2dp/a2dp_sbc_encoder.cc:42

#define A2DP_SBC_DEFAULT_BITRATE 328

Replace with 512.

5. (for experiments only) Disable MTU limit

This is required for bitrates higher than ~580 kbit/s.

/platform/system/bt/stack/a2dp/a2dp_sbc_encoder.cc:47

#define MAX_2MBPS_AVDTP_MTU 663

[/code]

For advanced users and ROM developers (Android 5-7 binary patch)

Please refer to this post in Russian (use Google Translate): https://4pda.ru/forum/index.php?s=&showtopic=914135&view=findpost&p=76169677

How to capture Bluetooth data dump on Android

Turn off Bluetooth;

In Developer Settings, enable the "Enable Bluetooth HCI snoop log" switch;

Turn on Bluetooth, connect to your headset using Bluetooth menu (this is important! Do not allow auto connection!);

Play short audio sample;

Open developer settings, disable the "Enable Bluetooth HCI snoop log" switch;

There should be /storage/emulated/0/btsnoop_hci.log or /data/misc/bluetooth/logs/btsnoop_hci.log created. If it's missing, open /etc/bluetooth/bt_stack.conf with a text editor and see the path in BtSnoopFileName option.

Upload btsnoop_hci.log to https://btcodecs.valdikss.org.ru/;

Post in this topic your headphone model and test results.

There should be no cracklings, audio interruption or other sound distortion in the headphones. If you hear a good high-quality sound with the patched library, that means your headphones support audio with a bit rate of 512 kbps.

If you upload data to the server, please carefully follow the algorithm above. Especially, if you power off the headphones or disconnect after pairing, it's important to connect to the headphones manually from the bluetooth settings, do not allow auto connection!

Some of the files attached below have no MTU limit patched. Unlocked/unrestricted versions most probably will introduce cracklings.