Android

Как изменить стеки Bluetooth на Android для значительного улучшения качества звука Bluetooth

Предупреждение: Это очень продвинутое руководство, которое включает в себя изменение стека Bluetooth на Android — прочитайте это руководство полностью и следуйте всем инструкциям в точности, как они даны.

Несмотря на то, что Bluetooth-гарнитуры и Bluetooth-аудио стали довольно популярными, для меломанов это является некоторой проблемой, поскольку доказано, что Bluetooth снижает качество звука, поскольку биты аудиоинформации и частоты теряются в воздухе при передаче по Bluetooth.

Именно поэтому некоторые производители выпускают кодеки aptX и LDAC, чтобы улучшить качество звука по сравнению со стандартным кодеком SBC Bluetooth, который поддерживается всеми наушниками и большинством устройств Bluetooth — однако устройства с кодеками aptX и LDAC стоят намного дороже, поскольку эти кодеки требуют лицензионных отчислений, которые в конечном итоге оплачивает потребитель.

Низкое качество звука Bluetooth-кодека SBC вызвано искусственными ограничениями всех существующих Bluetooth-стеков и наушников’ конфигурации, и это ограничение можно обойти на любых существующих устройствах.

Если вы интересуетесь Bluetooth-аудио, в конце этого руководства мы покажем вам, как взять дамп журнала Bluetooth-аудио и проанализировать его, чтобы узнать, какое качество и частоту звука вы получаете от Bluetooth-приемника вашего Android.

Большая часть этого руководства будет посвящена нескольким простым настройкам и способам чтения аудиовыхода Bluetooth для значительного улучшения качества вывода стандартных кодеков SBC Bluetooth — пожалуйста, внимательно прочитайте все руководство, так как оно довольно познавательно и в нем есть много разных вещей, которые нужно прошить или настроить, в зависимости от модели вашего устройства.

В конце этого руководства находится список предварительно пропатченных стеков Bluetooth для многих популярных устройств Android — их можно прошить в recovery, как и любые другие прошиваемые устройства .zip — если ни одно из устройств не принадлежит вам, вам придется следовать руководству по изменению стеков Bluetooth на Android.

Краткая техническая информация о кодеке SBC

SBC имеет множество различных параметров, которые согласовываются на этапе установки соединения:

  • Тип и номер аудиоканала: Совместный Стерео, Стерео, двухканальный, моно;
  • Количество частотных диапазонов: 4 или 8;
  • Количество звуковых блоков в одном пакете: 4, 8, 12, 16;
  • Алгоритм распределения битов квантования: Loudness, SNR;
  • Максимальный и минимальный битовый пул, используемый в процессе квантования: обычно 2-53.

Декодер должен поддерживать любую комбинацию этих параметров. Кодер может реализовать только часть из них.

Существующие стеки Bluetooth обычно используют следующий профиль: Joint Stereo, 8 полос, 16 блоков, Loudness, bitpool 2..53. Этот профиль кодирует 44.Аудио 1 кГц с битрейтом 328 кбит/с.

Параметр Bitpool напрямую влияет на битрейт внутри одного профиля: чем он выше, тем выше битрейт, а значит и качество.

Однако параметр bitpool не привязан к определенному профилю. На битрейт также существенно влияют другие параметры: тип аудиоканала, количество частотных полос, количество аудиоблоков. Вы можете увеличить битрейт косвенно, согласовав нестандартные профили, без изменения битпула.

Например, Dual Channel кодирует каналы отдельно, используя весь битпул для каждого канала. Заставив устройство использовать Dual Channel вместо Joint Stereo, мы получим почти удвоенный битрейт при том же максимальном битпуле — 617 кбит/с.

Мне кажется, что битпул должен быть внутренней переменной. Это ошибка проектирования спецификации A2DP, что значение bitpool не привязано к другим параметрам кодека и определяется только как глобальное значение.

Эти фиксированные значения Bitpool и Bitrate происходят от рекомендуемых значений для высококачественного аудио. Но эта рекомендация не является поводом ограничивать профиль этими значениями.

Спецификация A2DP v1.2, который был активен с 2007 по 2015 год, требует от всех декодеров корректной работы с битрейтом до 512 кбит/с:

Декодер SNK должен поддерживать все возможные значения битпула, которые не приводят к превышению максимального битрейта. Этот профиль ограничивает доступный максимальный битрейт до 320 кб/с для монофонического и 512 кб/с для двухканального режимов.

В новой версии спецификации нет ограничения битрейта. Предполагается, что современные наушники, выпущенные после 2015 года, могут поддерживать битрейт до 1000 кбит/с.

По какой-то причине все протестированные в настоящее время Bluetooth стеки (Linux (PulseAudio), Android, Blackberry и macOS) имеют искусственные ограничения максимального параметра bitpool, что напрямую влияет на максимальный битрейт. Но это не самая большая проблема, почти все наушники также ограничивают максимальное значение bitpool до 53.

Большинство устройств прекрасно работают на модифицированном Bluetooth-стеке с битрейтом 507 кбит/с, без прерываний и треска. Но такой битрейт никогда не будет согласован в нормальных условиях, со стоковыми стеками Bluetooth.

***Требуется для тестирования с помощью руководств ниже: bluetooth-dualchannel-test-ubuntu-18.04.1-desktop-amd64.iso.торрент

Как проверить на ПК

Тест на совместимость с наушниками SBC с высоким битрейтом проще всего выполнить на компьютере с Bluetooth-адаптером. Я’подготовил образ Ubuntu с модифицированным Bluetooth стеком, который можно запустить как в виртуальной машине (подключив Bluetooth адаптер как USB устройство внутри виртуальной машины, он также работает с адаптерами, встроенными в ноутбуки), так и загрузившись с USB флешки. В данном изображении используется следующий профиль: Dual Channel, 8 полос, 16 блоков, Loudness, bitpool 2..41, 44.1 кГц, что обеспечивает битрейт 485 кбит/с.

Запуск на виртуальной машине

  • Скачать Virtualbox и Virtualbox Extension Pack: https://www.virtualbox.org/wiki/Загрузки;
  • Установите Virtualbox, запустите его;
  • Установите Extension Pack с помощью File → Preferences → Extensions;
  • Создайте новую виртуальную машину: Linux, Ubuntu (64-бит), 1024 RAM. Не создавайте жесткий диск.
  • Перейдите к настройкам виртуальной машины, в Storage выберите Controller: IDE, Empty, нажмите значок CD → Выберите файл виртуального оптического диска;
  • Выберите загруженный файл bluetooth-dualchannel-test-ubuntu-18.04.1-desktop-amd64.iso;
  • Сохраните и закройте окно настроек, запустите виртуальную машину;
  • Щелкните правой кнопкой мыши значок USB-кабеля в правом нижнем углу, выберите ваш Bluetooth-адаптер;

Запуск на ПК

Образ поддерживает загрузку BIOS/CSM и UEFI.

  • Запишите образ на USB-накопитель с помощью Etcher: https://www.balena.io/etcher/. Эта операция приведет к удалению всех существующих файлов на USB-накопителе.
  • Выключите компьютер;
  • Вставьте USB-накопитель, включите ПК и нажмите кнопку порядка загрузки (обычно Esc или F12);
  • Выберите ваш USB-накопитель.

Выполнение теста

  • (необязательно, но рекомендуется) Дважды щелкните по “Btsnoop Dump” скрипту на рабочем столе. Это запустит захват данных Bluetooth для последующего анализа. Не закрывайте окно терминала.
  • Переключите наушники в режим сопряжения;
  • Нажмите на стрелку в правом верхнем углу, выберите значок Bluetooth → Настройки Bluetooth;
  • Выберите наушники, дождитесь завершения сопряжения и закройте окно;
  • Установите громкость Ubuntu примерно на 2/3. Также уменьшите громкость с помощью кнопок гарнитуры, так как после сопряжения она может быть очень громкой.
  • Откройте папку “music”, воспроизведите “testrecord1.flac”;
  • (необязательно, но рекомендуется) Закройте плеер, закройте окно терминала. Это остановит захват данных.
  • (необязательно, но рекомендуется) Откройте браузер Firefox, загрузите дамп данных (btsnoop_hci.btsnoop на рабочем столе) на https://btcodecs.valdikss.org.ru/

Вы можете слушать другую музыку в папке «Музыка» или загрузить свою собственную;

В наушниках не должно быть тресков, прерываний звука или других искажений звука. Если вы слышите качественный звук, значит, ваши наушники поддерживают аудио со скоростью передачи 485 кбит/с.

Как проверить на устройстве Android

Для тестирования с Android смартфона или планшета необходимо использовать модифицированный Bluetooth стек, что требует root привилегий.

Как перехватить дамп данных Bluetooth на Android

  1. Выключите Bluetooth;
  2. В Developer Settings включите переключатель “Enable Bluetooth HCI snoop log”;
  3. Включите Bluetooth, подключитесь к гарнитуре с помощью меню Bluetooth (это важно)! Не разрешайте автоматическое подключение!);
  4. Воспроизведите короткий образец аудио;
  5. Откройте настройки разработчика, отключите переключатель “Enable Bluetooth HCI snoop log”;
  6. Там должно быть /storage/emulated/0/btsnoop_hci.log или /data/misc/bluetooth/logs/btsnoop_hci.журнал создан. Если она отсутствует, откройте /etc/bluetooth/bt_stack.conf с помощью текстового редактора и посмотрите путь в параметре BtSnoopFileName.

В наушниках не должно быть тресков, прерывания звука или других искажений звука. Если вы слышите качественный звук с пропатченной библиотекой, это означает, что ваши наушники поддерживают звук с битрейтом 512 кбит/с.

Пожалуйста, внимательно следуйте приведенному выше алгоритму. Особенно, если вы выключили наушники или отсоединились после сопряжения, то’важно подключиться к наушникам вручную из настроек Bluetooth, не допускайте автоматического подключения!

Устройства, поддерживающие SBC не менее 512 кбит/с

  • 1MORE iBFree
  • JBL Everest 310
  • JBL Everest 700
  • Skullcandy HESH 3
  • Sony WI-C400
  • Sony MDR-1ABT
  • Sony MDR-ZX770BT
  • Sony MDR-XB650BT
  • Sony MDR-XB950B1
  • Sony SBH50
  • Bluedio T4s (Bitpool max 39. Отвечает, что не поддерживает Dual Channel, но работает, если его заставить, 462 кбит/с. Не соответствует спецификации A2DP.)
  • Bluedio T5 (Отвечает, что не поддерживает Dual Channel, но работает, если его заставить. Не соответствует спецификации A2DP.)
  • Bluedio T6 (Отвечает, что не поддерживает Dual Channel, но работает, если заставить. Не соответствует спецификации A2DP. Применяется чип Max 97220.)
  • Marshall Major II Bluetooth
  • Overdrive RealForce D1
  • Edifier W830BT
  • DEXP BT-250
  • Logitech BT Adapter
  • Автомобильное головное устройство Noname (чип CSR8645)
  • Автомобильное головное устройство Sony DSX-A400BT

Устройства, поддерживающие SBC выше 512 кбит/с

  • JBL Everest 310 (617-660 кбит/с)
  • Sony WI-C400 (576 кбит/с)
  • Sony MDR-ZX770BT (617-660 кбит/с)
  • Marshall Major II Bluetooth (617-660 кбит/с)
  • Overdrive RealForce D1 (730 кбит/с, двухканальный, 4 субдиапазона)

Устройства, которые не работают с более высокими битрейтами или Dual Channel

  1. Harper HB-202 (треск; чип Beken BK3256)
  2. Sony Ericsson MW600 (высокочастотные искажения, треск; устройство 2009 года)

Почему это важно: SBC 328k и 485k против aptX

Вопреки распространенному мнению о качестве звука aptX, в некоторых случаях он может давать худшее качество звука, чем SBC со стандартным битрейтом 328k.

SBC динамически распределяет биты квантования для частотных диапазонов, действуя по принципу “снизу вверх”. Если весь битрейт был использован для нижних и средних частот, то верхние частоты “обрезаются” (заглушаются).

aptX квантует частотные полосы с одинаковым количеством битов постоянно, что делает его кодеком с постоянным битрейтом: 352 кбит/с для 44.1 кГц, 384 кбит/с для 48 кГц. Он не может ’передавать биты” на частотах, которые в них в основном нужны. В отличие от SBC, aptX не “обрезает” частоты, но добавляет к ним шум квантования, уменьшая динамический диапазон звука и иногда внося треск. SBC, наоборот, “съедает детали” – отбрасывает самые тихие участки.

В среднем, по сравнению с SBC 328k, aptX вносит меньше искажений в музыку с широким частотным диапазоном, но в музыке с узким частотным диапазоном и широким динамическим диапазоном SBC 328k иногда выигрывает.

Рассмотрим особый случай, запись фортепиано. Вот’ спектрограмма:


Наибольшая энергия приходится на частоты 0-4 кГц и сохраняется до 10 кГц.
Спектрограмма файла aptX выглядит следующим образом:

Вот SBC 328k:

Видно, что SBC 328k периодически полностью отсекает диапазон выше 16 кГц, и использует все доступные битрейты для диапазонов ниже этого значения. Однако aptX вносит больше искажений в слышимый человеческим ухом частотный спектр, что видно на вычитании оригинальной спектрограммы из спектрограммы aptX (чем ярче, тем больше искажений):


В то время как SBC 328k внес меньше искажений в сигнал в диапазоне от 0 до 10 кГц, а остальное вырезано:

Битрейта 485k для SBC было достаточно, чтобы сохранить весь частотный диапазон, не отсекая полосы.

SBC 485k на этом аудио образце намного лучше aptX в диапазоне 0-15 кГц, и с меньшей, но все же заметной разницей – на 15-22 кГц (чем темнее, тем меньше искажений):

Переключившись на SBC с высоким битрейтом, вы получите звук, превосходящий aptX в большинстве случаев, на любых наушниках.

Как изменить стеки Bluetooth на Android 5 – 7

Эти модификации должны быть применены к стоковым блютуз-стекам Android Bluedroid (Android 5) и Fluoride (Android 6-7). Модифицированный Qualcomm стек не поддерживается.

Замените совместное стерео на двухканальное в стандартной конфигурации SBC

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

Код:

                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 */

};

Заменить A2D_SBC_IE_CH_MD_JOINT на A2D_SBC_IE_CH_MD_DUAL.

Увеличение приоритета двухканального соединения

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

Код:

    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;




Переместите if с A2D_SBC_IE_CH_MD_DUAL на самый верх.

  1. Отключите или увеличьте ограничение битрейта

Стек bluetooth для Android имеет не только ограничение битпула, но и ограничение битрейта, 328 кбит/с. Если наушники поддерживают, например, битпул 53 для 48 кГц, Android уменьшит битпул, чтобы уложиться в лимит 328 кбит/с. Это произойдет ПОСЛЕ согласования кодека, на этапе кодирования, не учитывайте значение битпула в пакете Bluetooth SetCapabilities.

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

Код:

#define DEFAULT_SBC_BITRATE 328

Замените на 512.

  1. (только для экспериментов) Отключить ограничение MTU.

Это необходимо для битрейтов выше ~580 кбит/с.

btif/src/btif_media_task.c:174

Код:

/* Размер полезной нагрузки 2DH5 составляет 679 байт - (4 байта L2CAP Header + 12 байт AVDTP Header) */

#define MAX_2MBPS_AVDTP_MTU 663

Как изменить стек Bluetooth на Android 8 — 9

Эти модификации не были протестированы, но должны работать.

Добавьте поддержку двухканального режима в A2DP SBC Source

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

Код:

/* Возможности кодека SBC SRC */

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 */

};


добавить A2DP_SBC_IE_CH_MD_DUAL в ch_mode.

Замените совместное стерео на двухканальное в конфигурации по умолчанию

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

Код:

/* Конфигурация кодека SBC по умолчанию */

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 */

};


Замените A2DP_SBC_IE_CH_MD_JOINT на A2DP_SBC_IE_CH_MD_DUAL.

Повышение приоритета двухканального режима

/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;

вернуть 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;

возвращает 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;

возвращать 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;

}

возвращать false;

}

Переместите на самый верх значение if с A2DP_SBC_IE_CH_MD_DUAL.

Увеличение лимита битрейта

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

Код:

#define A2DP_SBC_DEFAULT_BITRATE 328

Замените на 512.

  1. (только для экспериментов) Отключить ограничение MTU

Это необходимо для битрейтов выше ~580 кбит/с.

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

Код:

#define MAX_2MBPS_AVDTP_MTU 663

Добавить комментарий