📜 ⬆️ ⬇️

We modify the Bluetooth stack to improve the sound on headphones without AAC, aptX and LDAC codecs

Before reading this article, it is recommended to familiarize yourself with the previous article: Audio via Bluetooth: as detailed as possible about profiles, codecs and devices

Some users of wireless headphones note poor sound quality and lack of high frequencies when using the standard Bluetooth SBC codec, which is supported by all audio devices. A frequent recommendation to improve the sound is to purchase devices and headphones with support for aptX and LDAC codecs. These codecs require license fees, so devices with their support are more expensive.

It turns out that the low quality of the SBC is due to the artificial limitations of the Bluetooth stacks and the settings of the headphones, and this restriction can be circumvented on any existing devices by programmatic changes of the smartphone or computer.
')

SBC Codec

The SBC codec has many different parameters that are consistent during the connection setup phase. Among them:



The decoder is required to support any combination of these parameters. The encoder may not implement everything.
Existing Bluetooth stacks usually agree on the following profile: Joint Stereo, 8 lanes, 16 blocks, Loudness, bitpool 2..53. This profile encodes 44.1 kHz audio at 328 kbps.
The bitpool parameter directly affects the bitrate within one profile: the higher it is, the higher the bitrate, and hence the quality.
However, the bitpool parameter is not tied to a specific profile; Other parameters also have a significant effect on the bitrate: type of channels, number of frequency bands, number of blocks. You can increase the bitrate indirectly, by agreeing on non-standard profiles, without changing the bitpool.

bitrate= frac8 timesframe length timessample ratesubbands timesblocks


SBC bit rate formula


For example, Dual Channel mode encodes channels separately, using the entire bitpool for each channel. By causing the device to use the Dual Channel instead of the Joint Stereo, we get an almost doubled bitrate at the same maximum bitpool value: 617 kbps.
In my opinion, the use of non-profile bitpool values ​​at the negotiation stage is a flaw in the A2DP standard, which led to an artificial limitation of the quality of the SBC. It would be wiser to negotiate bitrate, not bitpool.

These fixed Bitpool and Bitrate values ​​originate from a table with recommended values ​​for high-quality audio. But the recommendation is not a reason to be limited to these values.

Bluetooth SBC Profile Table

The A2DP v1.2 specification, which was active from 2007 to 2015, requires all decoders to work correctly with bitrates up to 512 kbps:

It is not necessary to ensure that it is possible to achieve the maximum bit rate. The maximum bit rate is up to 320kb / s for mono, and 512kb / s for two-channel modes.


In the new version of the specification there is no limit on bitrate. It is assumed that modern headphones, released after 2015 and supporting EDR, can support bit rates up to ≈ 730 kbit / s.

For some reason, the Linux stack of Linux (PulseAudio), Android, Blackberry, and macOS I tested have artificial limitations on the maximum value of the bitpool parameter, which directly affects the maximum bitrate. But this is not the biggest problem, almost all headphones also limit the maximum bitpool number to 53.
As I have already managed to make sure, most devices work fine on a modified Bluetooth stack with a bit rate of 551 kbps, without interruptions and cod. But such a bitrate will never be matched under normal conditions, on conventional Bluetooth stacks.

Modifying Bluetooth Stack

In any Bluetooth-stack that is compatible with the A2DP standard, there is support for Dual Channel mode, but it is not possible to activate it from the interface.

Let's add a switch to the interface! I made patches for Android 8.1 and Android 9, which add full support for Dual Channel to the stack, add mode to the mode switch menu in the developer tools, and process SBC with Dual Channel support as if it were an additional codec, like aptX, AAC or LDAC ( Android calls this HD Audio) by adding a checkmark to the settings of a Bluetooth device. Here's what it looks like:

image

Patch for Android 9
Patch for Android 8.1

When you activate the checkbox, Bluetooth audio starts to be transmitted with a bit rate of 551 kbps , if the headphones support the connection at a speed of 3 Mbps, or 452 kbps , if the headphones support only 2 Mbps.

This patch is included in the following alternative firmware:


Where did 551 and 452 kbps come from?

Bluetooth dividing technology is designed to efficiently transmit large fixed-size packets. Data transfer occurs by slots, the largest number of slots sent in one transmission is 5. There are also transfer modes using 1 or 3 slots, but not 2 or 4. In 5 slots, you can transfer up to 679 bytes at a connection speed of 2 Mbps and up to 1021 bytes at a speed of 3 Mbps, and in 3 - 367 and 552 bytes, respectively.

image

If we want to transfer less data than 679 or 1021 bytes, but more than 367 or 552 bytes, the transfer will still take 5 slots, and the data will be transmitted in the same time, which reduces the transmission efficiency.

image

SBC in Dual Channel mode, on 44100 Hz audio with Bitpool parameters 38, 16 blocks in a frame, 8 frequency bands, encodes audio into frames of 164 bytes, with a bitrate of 452 kbit / s.
Audio must be encapsulated in L2CAP and AVDTP transmission protocols, which take 16 bytes from the audio payload.

\ begin {align *} framelength & = 4 + \ frac {subbands \ times channels} {2} + \\ & \ begin {cases} \ frac {blocks \ times channels \ times bitpool} {8} & \ text { if mono or dual channel mode} \\ \ frac {subbands + blocks \ times bitpool} {8} & \ text {if joint stereo mode} \\ \ frac {blocks \ times bitpool} {8} & \ text {if stereo mode} \\ \ end {cases} \ end {align *}





Thus, one audio transmission with 5 slots can accommodate 4 audio frames:
679 (EDR 2 mbit/s DH5) - 4 (L2CAP) - 12 (AVDTP/RTP) - 1 ( SBC) - (164*4) = 6 

We contained 11.7 ms of audio data in the sent packet, which will be transmitted in 3.75 ms, and we have 6 unused bytes left in the package.
If you slightly raise the bitpool, 4 audio frames can no longer be packaged in one package. You'll have to send 3 frames at a time, which reduces transmission efficiency, reduces the amount of audio transmitted in one package, and will quickly lead to stuttering audio under poor radio conditions.

In the same way, the 551 kbps bitrate for EDR 3 Mbps was selected: with Bitpool 47, 16 blocks per frame, 8 frequency bands, the frame size is 200 bytes, with a bit rate of 551 kbps. In one package can hold 5 frames or 14.6 ms of music.

The algorithm for calculating all the SBC parameters is quite complicated, you can easily get confused if you count it manually, so I made an interactive calculator to help those interested in: btcodecs.valdikss.org.ru/sbc-bitrate-calculator

Why is all this necessary?

Contrary to popular opinion about the sound quality of the aptX codec, on some files it may produce worse results than SBC with a standard bit rate of 328 kbps.

The SBC dynamically allocates quantization bits for frequency bands, acting on the “from bottom to top” principle. If the entire bit rate was used on the lower and middle frequencies, the upper frequencies will be cut off (instead of them there will be silence).
aptX quantizes frequency bands with the same number of bits all the time, which is why it has a constant bitrate: 352 kbit / s for 44.1 kHz, 384 kbit / s for 48 kHz, and it cannot "transfer bits" to those frequencies that most need them. Unlike SBC, aptX will not “cut off” frequencies, but will add quantization noise to them, reducing the dynamic range of the audio, and sometimes introduce characteristic crackles. SBC "eats the details" - discards the quietest areas.
On average, compared to the SBC 328k, aptX introduces less distortion in music with a wide frequency range, but on music with a narrow frequency range and wide dynamic range, the SBC 328k sometimes wins.

Consider a special case. Spectrogram recording of the piano:
image

The main energy lies in frequencies from 0 to 4 kHz, and lasts up to 10 kHz.
The spectrogram of a file compressed with aptX looks like this:
image

And this is what SBC 328k looks like.
image

It can be seen that the SBC 328k periodically completely turned off the range above 16 kHz, and consumed all the available bitrate for the bands below this value. However, aptX introduced more distortions into the frequency spectrum heard by the human ear, as can be seen on the aptX spectrogram subtracted from the original spectrogram (the brighter, the more distortions):
image

While the SBC 328k less spoiled the signal in the range from 0 to 10 kHz, and the rest - cut:
image

The 485k SBC bit rate was enough to save the entire frequency range, without turning off the bands.
image

SBC 485k on this composition is significantly ahead of aptX in the range of 0-15 kHz, and with a smaller, but still noticeable difference - in 15-22 kHz (the darker, the less distortion):
image

Archive of original audio, SBC and aptX .

Switching to high-bit SBC, you get a sound, often superior to aptX, on any headphones. On headphones that support an EDR connection of 3 Mbps, a 551 kbit / s bitrate gives a sound comparable to aptX HD.

And you can even more?

The patch for Android also has an option to further increase the bit rate for EDR devices 2 Mbps. You can increase the bitrate from 452 kbps to 595 kbps, at the cost of reducing the stability of the transmission in difficult radio conditions.
It is enough to set the variable persist.bluetooth.sbc_hd_higher_bitrate to 1:
 # setprop persist.bluetooth.sbc_hd_higher_bitrate 1 

Extreme bit rate patch is currently accepted only in LineageOS 15.1, but not in 16.0.

Device Compatibility

SBC Dual Channel is supported by almost all headphones, speakers and car head units. This is no wonder - the standard prescribes its support in any decoding devices. There are a small number of devices on which this mode causes problems, but these are single instances.
More details on compatible devices can be found at w3bsit3-dns.com or xda-developers .

Comparing Sound Differences

I made a web service that encodes audio in SBC (as well as aptX and aptX HD) in real time, right in the browser. With it, you can compare the sound of different SBC profiles and other codecs, without actually transmitting audio via Bluetooth, on any wired headphones, speakers, and your favorite music, and also change the encoding parameters directly during audio playback.
btcodecs.valdikss.org.ru/sbc-encoder

Communication with Android developers

I wrote to many Bluetooth stack developers from Google, asking them to consider including patches in the main Android branch - AOSP, but did not receive a single answer. My patches in the Gerrit patches for Android system were also left without comments from anyone involved.
I would be glad if they could help me in connection with the developers from Google and the implementation of SBC HD in Android. The gerrit patch is already out of date (this is one of the earliest revisions), and I will update it if developers are interested in my changes (it's not easy for me to update it, I don't have Android Q compatible devices).

Conclusion

Users of smartphones with LineageOS, Resurrection Remix and crDroid firmware can be content with improved sound quality right now, just activate the option in the Bluetooth device settings. Linux users can also get a higher SBC bitrate by installing a patch from Pali Rohár , which, among other things, adds support for aptX, aptX HD and FastStream codecs.

Source: https://habr.com/ru/post/455316/


All Articles