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

Before reading this article, it is recommended that you read the previous article: Audio via Bluetooth: as much detail as possible about profiles, codecs and devices

Some users of wireless headphones report poor sound quality and lack of high frequencies when using the standard Bluetooth SBC codec, which is supported by all audio devices. A common recommendation to improve sound is to buy devices and headphones that support aptX and LDAC codecs. These codecs require royalties, so devices that support them are more expensive.

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

SBC Codec

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

  • Number and type of channels: Joint Stereo, Stereo, Dual Channel, Mono;
  • Number of frequency bands: 4 or 8;
  • Number of blocks in a package: 4, 8, 12, 16;
  • Quantization bit allocation algorithm: Loudness, SNR;
  • The maximum and minimum value of the pool of bits used in quantization (bitpool): usually, from 2 to 53.

The decoder must support any combination of these parameters. The encoder may not implement everything.
Existing Bluetooth stacks typically agree on the following profile: Joint Stereo, 8 bands, 16 blocks, Loudness, bitpool 2..53. This profile encodes 44.1 kHz audio at a bit rate of 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 setting is not tied to a specific profile; other parameters also significantly affect the bitrate: the type of channels, the number of frequency bands, the number of blocks. You can raise the bitrate indirectly, by negotiating non-standard profiles, without changing the bitpool.

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

SBC Bitrate Formula

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

These fixed Bitpool and Bitrate values ​​originate from a table of recommended values ​​for high quality audio. But a recommendation is not a reason to limit yourself to these values.

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

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

The decoder of the SNK shall support all possible bitpool values ​​that do not result in excess of the maximum bit rate. This profile limits the available maximum bit rate to 320kb/s for mono, and 512kb/s for two-channel modes.

There is no bitrate limit in the new version of the specification. It is assumed that modern headphones released after 2015 and supporting EDR can support bit rates up to β‰ˆ730 kbps.

For some reason, the Linux (PulseAudio), Android, Blackberry, and macOS Bluetooth stacks I've tested have artificial limits 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 value to 53.
As I have already seen, 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 negotiated under normal conditions, on ordinary Bluetooth stacks.

Modifying the 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've made patches for Android 8.1 and Android 9 that add full Dual Channel support to the stack, add a mode to the mode switch menu in developer tools, and treat Dual Channel enabled SBCs as if they were an additional codec like aptX, AAC or LDAC ( Android calls it HD Audio) by adding a checkmark to the device's Bluetooth settings. Here's what it looks like:

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

Patch for Android 9
Patch for Android 8.1

When the checkbox is activated, Bluetooth audio starts to be transmitted with a bit rate 551 kbps, if the headphones support a 3 Mbps connection, or 452 kbpsif the headphones only support 2 Mbps.

This patch is included in the following alternative firmware:

  • LineageOS
  • Resurrection Remix
  • crDroid

Where did 551 and 452 kbps come from?

The air-splitting technology in Bluetooth is designed to efficiently transmit large, fixed-size packets. Data transfer occurs in slots, the largest number of slots sent in one transfer is 5. There are also transfer modes that use 1 or 3 slots, but not 2 or 4. Up to 5 bytes can be transferred in 679 slots 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.

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

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

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

SBC in Dual Channel mode, at 44100 Hz audio with Bitpool 38 parameters, 16 blocks per frame, 8 frequency bands, encodes audio into 164 byte frames, with a bit rate of 452 kbps.
Audio must be encapsulated in the L2CAP and AVDTP transfer protocols, which take 16 bytes from the audio payload.

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

Thus, in one Bluetooth transmission with 5 slots, it is possible to fit 4 audio frames:

679 (EDR 2 mbit/s DH5) - 4 (L2CAP) - 12 (AVDTP/RTP) - 1 (Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ SBC) - (164*4) = 6

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

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

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

Why is all this necessary?

Contrary to popular belief about the sound quality of the aptX codec, on some files it may give worse results than SBC with a standard bitrate of 328 kbps.

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

Let's consider a special case. Spectrogram of piano recording:
Modifying the Bluetooth stack to improve the sound on headphones without AAC, aptX and LDAC codecs

The main energy lies in frequencies from 0 to 4 kHz, and continues up to 10 kHz.
The spectrogram of a file compressed with aptX looks like this:
Modifying the Bluetooth stack to improve the sound on headphones without AAC, aptX and LDAC codecs

And this is what the SBC 328k looks like.
Modifying the Bluetooth stack to improve the sound on headphones without AAC, aptX and LDAC codecs

It can be seen that the SBC 328k periodically completely turned off the range above 16 kHz, and spent all the available bitrate on ranges below this value. However, aptX introduced more distortion into the frequency spectrum audible to the human ear, which can be seen in the subtracted original spectrogram from the aptX spectrogram (the brighter, the more distortion):
Modifying the Bluetooth stack to improve the sound on headphones without AAC, aptX and LDAC codecs

While the SBC 328k spoiled the signal less in the range from 0 to 10 kHz, and cut off the rest:
Modifying the Bluetooth stack to improve the sound on headphones without AAC, aptX and LDAC codecs

The bitrate of 485k SBC was enough to save the entire frequency range, without cutting off the bands.
Modifying the Bluetooth stack to improve the sound on headphones without AAC, aptX and LDAC codecs

SBC 485k on this composition is well 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):
Modifying the Bluetooth stack to improve the sound on headphones without AAC, aptX and LDAC codecs

Archive of original audio, SBC and aptX.

By switching to a high-bitrate SBC, you'll get audio that often outperforms aptX on any headphone. On headphones that support a 3 Mbps EDR connection, 551 kbps produces sound comparable to aptX HD.

And maybe even more?

The Android patch also has an option to further increase the bitrate for 2Mbps EDR devices. It is possible to increase the bit rate from 452 kbps to 595 kbps, at the cost of reduced transmission stability 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

The patch for extreme bitrate is only accepted 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 not surprising - 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.
For more information on compatible devices, see 4pda or xda-developers.

Comparison of 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, as well as change encoding parameters right during audio playback.
btcodecs.valdikss.org.ru/sbc-encoder

Contact Android Developers

I have written to many Bluetooth stack developers at Google, asking them to consider including patches in the Android main branch - AOSP, but have not received a single response. My patches are in Gerrit patching system for Android also remained without comment from anyone involved.
I would be happy if I could be helped in connection with the developers from Google and the implementation of the SBC HD in Android. The patch in gerrit is out of date (it's one of the early revisions), and I'll update it if the developers are interested in my changes (it's not easy for me to update it, I don't have devices compatible with Android Q).

Conclusion

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

Source: habr.com

Add a comment