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

Before reading this article, it is recommended to familiarize yourself with the previous article: Audio over Bluetooth: a detailed look at profiles, codecs, and devices

Some users of wireless headphones report low sound quality and a lack of high frequencies when using the standard SBC Bluetooth codec, which is supported by all audio devices. A common recommendation for improving sound is to purchase devices and headphones that support aptX and LDAC codecs. These codecs require licensing fees, which makes devices that support them more expensive.

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

SBC Codec

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

  • Number and type of channels: Joint Stereo, Stereo, Dual Channel, Mono;
  • Number of frequency bands: 4 or 8;
  • Number of blocks in a packet: 4, 8, 12, 16;
  • Bit distribution algorithm during quantization: Loudness, SNR;
  • Maximum and minimum value of the bit pool used during quantization (bitpool): typically, from 2 to 53.

The decoding device must support any combination of these parameters. The encoding device may not implement all of them.
Existing Bluetooth stacks typically negotiate the following profile: Joint Stereo, 8 bands, 16 blocks, Loudness, bitpool 2..53. This profile encodes 44.1 kHz audio at a bitrate of 328 kbps.
The bitpool parameter directly affects the bitrate within a profile: the higher it is, the higher the bitrate, and consequently the quality.
However, the bitpool parameter is not tied to a specific profile; other parameters such as channel type, number of frequency bands, and number of blocks also significantly influence the bitrate. The bitrate can be indirectly increased by negotiating non-standard profiles without changing the bitpool.

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

Formula for calculating SBC bitrate

For example, the Dual Channel mode encodes the channels separately, using the entire bitpool for each channel. Forcing the device to use Dual Channel instead of Joint Stereo, we will nearly double the bitrate at the same maximum bitpool value: 617 kbps.
In my opinion, using a non-profile-specific bitpool value at the negotiation stage is a shortcoming of the A2DP standard, which led to an artificial limitation on SBC quality. It would have been wiser to negotiate the bitrate instead of the bitpool.

These fixed values for Bitpool and Bitrate originate from a table of recommended values for high-quality audio. However, a recommendation is not a reason to confine ourselves to these values.

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

The A2DP v1.2 specification, which was in effect from 2007 to 2015, mandates that all decoding devices must correctly handle bitrates up to 512 kbps:

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

The new version of the specification has no bitrate limitation. It is assumed that modern headphones released after 2015 that support EDR can handle bitrates of up to ≈730 kbps.

For some reason, the Bluetooth stacks I have checked, such as Linux (PulseAudio), Android, Blackberry, and macOS, have artificial limitations on the maximum value of the bitpool parameter, which directly affects the maximum bitrate. However, this is not the biggest issue; almost all headphones also restrict the maximum bitpool value to 53.
As I have already confirmed, most devices work well on a modified Bluetooth stack with a bitrate of 551 kbps, without interruptions or crackling. However, such a bitrate will never be negotiated under normal conditions on standard Bluetooth stacks.

Modify the Bluetooth stack

Any Bluetooth stack that is compliant with the A2DP standard supports Dual Channel mode, but activating it through the interface is not feasible.

Let's add a switch to the interface! I created patches for Android 8.1 and Android 9 that provide full Dual Channel support in the stack, add a mode to the mode switching menu in developer tools, and handle SBC with Dual Channel support as if it's an additional codec, like aptX, AAC, or LDAC (Android refers to this as HD Audio), adding a checkbox in the Bluetooth device settings. Here's how it looks:

Modifying the Bluetooth stack to enhance sound quality 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 transmitting at a bitrate of 551 kbps, if the headphones support a connection speed of 3 Mbps, or 452 kbps, if the headphones only support 2 Mbps.

This patch is included in the following alternative firmware:

  • LineageOS
  • Resurrection Remix
  • crDroid

Where did the 551 and 452 kbps come from?

Bluetooth's air partitioning technology is designed for effective transmission of large fixed-size packets. Data is transmitted in slots, with the maximum number of slots sent in one transmission being 5. There are also transmission modes that use 1 or 3 slots, but not 2 or 4. In 5 slots, you can transmit up to 679 bytes at a connection speed of 2 Mbps and up to 1021 bytes at a speed of 3 Mbps, while in 3 slots, the limits are 367 and 552 bytes respectively.

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

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

Modifying the Bluetooth stack to enhance sound quality 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 ranges, encodes audio into frames of 164 bytes, with a bitrate of 452 kbps.
Audio must be encapsulated in L2CAP and AVDTP transmission protocols, which take away 16 bytes from the useful audio payload.

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

Thus, in one Bluetooth transmission with 5 slots, we can fit 4 audio frames:

679 (EDR 2 mbit/s DH5) - 4 (L2CAP) - 12 (AVDTP/RTP) - 1 (SBC header) - (164*4) = 6

We fit 11.7 ms of audio data into the transmitted packet, which will be sent in 3.75 ms, leaving us with 6 unused bytes in the packet.
If we slightly raise the bitpool, we won't be able to pack 4 audio frames into a single packet anymore. We'll have to send 3 frames at a time, which reduces transmission efficiency, decreases the amount of audio transmitted per packet, and will quickly lead to audio stuttering in poor radio conditions.

Similarly, a bitrate of 551 kbps was selected for EDR 3 Mbps: with Bitpool 47, 16 blocks in the frame, and 8 frequency bands, the frame size is 200 bytes at a bitrate of 551 kbps. One packet contains 5 frames or 14.6 ms of music.

The algorithm for calculating all SBC parameters is quite complex, and it's easy to get confused if calculating manually; that's why I created an interactive calculator to assist those interested: btcodecs.valdikss.org.ru/sbc-bitrate-calculator

Why is all this needed?

Contrary to the common belief about the sound quality of the aptX codec, in some files it can yield worse results than SBC with a standard bitrate of 328 kbps.

SBC dynamically allocates quantization bits for frequency bands, operating on the principle of 'from low to high.' If the entire bitrate is used on lower and mid frequencies, the upper frequencies will be 'cut off' (resulting in silence instead).
aptX quantizes frequency bands with the same number of bits continuously, which is why it has a constant bitrate: 352 kbps for 44.1 kHz, 384 kbps for 48 kHz, and it cannot 'transfer bits' to the frequencies that need them the most. Unlike SBC, aptX will not 'cut off' frequencies but will add quantization noise to them, reducing the audio dynamic range and sometimes introducing characteristic crackles. SBC, on the other hand, 'eats details' — discarding the quietest sections.
On average, compared to SBC 328k, aptX introduces fewer distortions in music with a wide frequency range, but in music with a narrow frequency range and wide dynamic range, SBC 328k sometimes performs better.

Let's consider a specific case. The spectrogram of a piano recording:
Modifying the Bluetooth stack to enhance sound quality on headphones without AAC, aptX, and LDAC codecs

The main energy lies in frequencies from 0 to 4 kHz and extends up to 10 kHz.
The spectrogram of the file compressed in aptX looks as follows:
Modifying the Bluetooth stack to enhance sound quality on headphones without AAC, aptX, and LDAC codecs

And this is how SBC 328k looks.
Modifying the Bluetooth stack to enhance sound quality on headphones without AAC, aptX, and LDAC codecs

It is evident that SBC 328k periodically completely cut off the range above 16 kHz, consuming all the available bitrate for ranges below this value. However, aptX introduced more distortions in 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 distortions):
Modifying the Bluetooth stack to enhance sound quality on headphones without AAC, aptX, and LDAC codecs

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

The 485k SBC bitrate was sufficient to preserve the entire frequency range without disabling bands.
Modifying the Bluetooth stack to enhance sound quality on headphones without AAC, aptX, and LDAC codecs

The 485k SBC on this track significantly outperforms aptX in the 0-15 kHz range, with a smaller but still noticeable difference in the 15-22 kHz range (the darker it gets, the fewer distortions):
Modifying the Bluetooth stack to enhance sound quality on headphones without AAC, aptX, and LDAC codecs

Archive of original audio, SBC, and aptX..

By switching to high-bitrate SBC, you’ll get sound that often exceeds aptX on any headphones. On headphones supporting EDR at 3 Mbps, a bitrate of 551 kbps delivers sound comparable to aptX HD.

Can you do even more?

The Android patch also includes an option for even greater bitrate increase for EDR 2 Mbps devices. You can increase the bitrate from 452 kbps to 595 kbps, at the cost of reduced transmission stability in complex radio conditions.
Simply set the persist.bluetooth.sbc_hd_higher_bitrate variable to 1:

# setprop persist.bluetooth.sbc_hd_higher_bitrate 1

The extreme bitrate patch has only been accepted in LineageOS 15.1, but not in 16.0.

Compatibility with devices

SBC Dual Channel is supported by almost all headphones, speakers, and car head units. It's no wonder, as the standard mandates support in any decoding devices. There are a few devices where this mode causes issues, but these are isolated cases.
For more details on compatible devices, check out 4pda or xda-developers.

Comparison of sound differences

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

Communication with Android developers

I have written to many Bluetooth stack developers at Google, asking them to consider integrating the patches into the main branch of Android — AOSP, but I haven't received a single response. My patches in the patch management system Gerrit for Android also went uncommented by anyone involved.
I would appreciate assistance regarding the developers at Google and the implementation of SBC HD in Android. The patch in Gerrit is already outdated (this is an early revision), and I will update it if the developers are interested in my changes (updating it is challenging for me, as I do not have devices compatible with Android Q).

Conclusion

Smartphone users with LineageOS, Resurrection Remix, and crDroid firmware can enjoy improved sound quality right now; they only need to activate the option in their Bluetooth device settings. Linux users can also achieve a higher SBC bitrate by installing the patch from Pali Rohár, which, among other things, adds support for aptX, aptX HD, and FastStream codecs.

Source: habr.com

Buy reliable website hosting with DDoS protection, VPS VDS servers 🔥 Buy reliable website hosting with DDoS protection, VPS VDS servers | ProHoster