Skip to main content


Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: ABXing A2DP (SBC) vs. lossless? (Read 12043 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

ABXing A2DP (SBC) vs. lossless?

I guess the main problem is that I can't seem to find an en-/decoder to create test file. I have found some references to an "A2DP test specification" which is supposed to include windows binaries, but was unable to locate it.

There is a workaround of level matching the A2DP streamed via bluetooth with a lossless file playing on pc, but I don't trust myself to be able to level the volumes so perfectly. Besides, it wouldn't be an ABX test because I would have to manually switch the stream playing.

Would recording the A2DP stream to wav -> level matching with replaygain -> feeding both versions to foobar2000's foo_abx plugin be acceptable? Personally, I'd appreciate if someone could provide me with those binaries instead...

ABXing A2DP (SBC) vs. lossless?

Reply #1
The problem with recording a bluetooth receiver, is that you won't be ABXing just SBC, but the receiver itself, with its own flaws added to the mix. If it rolls-off badly or if it's noisy or whatever, ABX results will be valid for the receiver, not for SBC.

ABXing A2DP (SBC) vs. lossless?

Reply #2
The setup I currently thought of testing with is my phone (xperia m2) streaming music to a bluetooth usb adapter in my pc, so the "receiver" in that case would be my sound card (realtek alc889).
The playback noise should be the same in that case, but I guess there can also be noise while recording. Is that what you mean?


ABXing A2DP (SBC) vs. lossless?

Reply #3
I wondered about doing the same however i have only an A2DP receiver in my car right now which makes ABX'ing impossible.

If you find a way to do is, it's very important to note however the bitrate the A2DP channel is using as well as the encoder. For example older Android phones used a low bitpool setting (~229kbps) with SBC which made  the highs noticeable distorted.  I think Jelly Bean was the first version where bitpool setting was increased (~328 kbps). My Galaxy S2 sounded awfully for example with ICS, but my Note 2 and my current Nexus 5 sounds indistinguishable for me, at least in the car while driving in noise. My headunit is a low priced JVC KD-X250BT after market stereo with the stock car speakers and a small Blaupunkt subwoofer. Nothing high end, still sounds okay for me in the car.

I don't know which SBC encoder is used in non Android phones. It's highly probably that every Linux based smartphone is using the default BlueZ SBC encoder though. Don't know what is the case with the iPhone or Windows Phone. Maybe it's possible to strip out the BlueZ SBC code and write a CLI encoder/decoder around it. I wonder why nobody done this already?

What also matters is the source. SBC makes highly compressed stuff sound worse. What worked the best for me is: lossless, lossywav, wavpack lossy, musepack, high bitrate AAC (QAAC iTunes+ setting for example). These all sound nice even after SBC transcoding.

ABXing A2DP (SBC) vs. lossless?

Reply #5
I feel stupid. There's a complete SBC tester app provided with the SBC implementation of BlueZ:
I'm trying to compile it right now  Seems like the only dependency is libsndfile which is probably used for opening source files.

Mod: this will not going to work on Cygwin since it's part of the util package. I'm trying instead with this separate SBC source release:

ABXing A2DP (SBC) vs. lossless?

Reply #6
I've tried to compile it using MinGW but no luck. I've got as far as correctly compiling libsndfile and had some problems with pkg-config but the real issues was compiling sbc_math where some strange macro issues showed up.  I'm not too good at compiling C/C++ code so others might spot the issue instantly.
However i've compiled it on my Ubuntu Atom box and could encode files with it  I think MinGW has a different GCC version which is incompatible with the SBC source. I'll get back to this later.

I've used the latest source release which is dated this January:

After issuing make install you get sbcenc, sbcdec and sbcinfo. It requires input files in AU format so you have to convert WAV files to AU first and back so you can listen to it with standard players. I've used SoX for this.
The "sbcenc" tool encodes with bitpool 32 setting by default which results in audio quality very similar to what i heard from the older Android phones (distorted highs). sbcinfo shows this:

Code: [Select]
Filename                out.sbc
mSBC                    0
Subbands                8
Block length            16
Sampling frequency      44.1 kHz
Channel mode            Stereo
Allocation method       Loudness
Bitpool                 32
Number of frames        69636
Frame length            76 Bytes
Bit rate                209.475 kbps

Bumping it to 52 (which i think is the default with newer Android phones and Cyanogenmod build) provides a much better quality. In this case sbcinfo shows this:
Code: [Select]
Filename                out.sbc
mSBC                    0
Subbands                8
Block length            16
Sampling frequency      44.1 kHz
Channel mode            Stereo
Allocation method       Loudness
Bitpool                 52
Number of frames        69636
Frame length            116 Bytes
Bit rate                319.725 kbps

Bitrate wise: 209kbps vs 320kbps.

sbcenc has some other interesting options though:

Code: [Select]
        sbcenc [options] file(s)

        -h, --help           Display help
        -v, --verbose        Verbose mode
        -m, --msbc           mSBC codec
        -s, --subbands       Number of subbands to use (4 or 8)
        -b, --bitpool        Bitpool value (default is 32)
        -j, --joint          Joint stereo
        -d, --dualchannel    Dual channel
        -S, --snr            Use SNR mode (default is loudness)
        -B, --blocks         Number of blocks (4, 8, 12 or 16)

For eg. i don't know what is that mSBC codec option there.
It would be interesting to extract the actual values the Android project using. There is an sbc_t structure initialized at the beginning of the encode method in sbcenc, Android should have a similar initialization somewhere.

ABXing A2DP (SBC) vs. lossless?

Reply #7
Although frequency spectrum alone doesn't say too much, i thought it would be interesting to show the effect on a source file. The source audio was a loud EDM music. I've choosen this to clearly see the subbands and other kind of lowpassing.


Encoded with default settings (bitpool 32):

Encoded with -b 52 (bitpool 52):

ABXing A2DP (SBC) vs. lossless?

Reply #8
I happen to have an arch VM, and it has the sbc library and binaries in a package already <3
Was able to encode to a2dp, but decoding gives me "Can't open output /dev/dsp: No such file or directory"
What am I supposed to pass for the -d option? Or rather, what command parameters have you used to decode it back to .au?

ABXing A2DP (SBC) vs. lossless?

Reply #9
What am I supposed to pass for the -d option? Or rather, what command parameters have you used to decode it back to .au?

You can use the --file switch of sbcdec to decode back to .au.
Code: [Select]
sbcdec --file out.sbc

Which version of SBC Tools your Arch build has? My compiled encoder says:
Code: [Select]
SBC encoder utility ver 1.2
Copyright (c) 2004-2010  Marcel Holtmann

ABXing A2DP (SBC) vs. lossless?

Reply #10
Ok, I messed up on the commandline, put the -f option after the input... 
Arch is a bleeding edge rolling release distro, so it gets the newest stuff ASAP. The version is 1.2, same as yours.

Will try to abx it tomorrow probably, a bit tired atm. Thanks for the pointer!

edit: actually, ABXing the default settings turned out to be effortless, way too much distortion:
Code: [Select]
foo_abx 1.3.4 report
foobar2000 v1.3.3
2014/07/17 23:42:08

File A: R:\lossless.wav
File B: R:\a2dpfromlossless.wav

23:42:08 : Test started.
23:42:33 : 01/01  50.0%
23:42:49 : 02/02  25.0%
23:44:59 : 03/03  12.5%
23:45:13 : 04/04  6.3%
23:45:23 : 05/05  3.1%
23:45:53 : 06/06  1.6%
23:46:04 : 07/07  0.8%
23:46:07 : Test finished.

Total: 7/7 (0.8%)

What we'd need, as darkbyte said, is to know which settings android uses... anyone has the AOSP repository setup or a link to an online viewable code?

ABXing A2DP (SBC) vs. lossless?

Reply #11
You are welcome, and curious about your test.

Tried to look up what settings Android is using. Haven't found the exact parameters (I'm especially curious about loudness/SNR and Joint Stereo) but looks like the newer version tries to negotiate with the receiver to use the maximum possible bitpool which is 53 by most hardware (not 52, so this makes that small bitrate difference). At least this is what I've found on XDA reported by other users.

The sbc_t initialization occurs in liba2dp.c, check the function bluetooth_a2dp_init. The whole configuration seems to start at a2dp_init which starts the a2dp handling thread which retreives the capabilities data in bluetooth_configure from an external service. This is where i got lost sadly.

ABXing A2DP (SBC) vs. lossless?

Reply #12
I assume the device capabilities are obtained on pairing, then depending on signal strength, the bitrate (and possibly other parameters) are varied.

ABXing A2DP (SBC) vs. lossless?

Reply #13
Maybe it's possible to obtain some info by attaching adb logcat on the phone and then pairing and playing something to the receiver. This should show up:
Code: [Select]
W/BTLD ( 1677): ### :: codec open ::
W/BTLD ( 1677): ### mtu 512, 660 bytes/frame, bitrate 229, nbr ch 0, freq 240
W/BTLD ( 1677): ### alloc : 3, blk len 240, chmode:15, bitpool 32:2, subbands 12

These lines are printed in: btif_media_task.c Not sure where those constant values are defined. The chmode (if it's encoding mono/stereo/jstereo/etc.) doesn't line up with the values defined in sbc.h.

ABXing A2DP (SBC) vs. lossless?

Reply #14
btif_media_task.c is the correct place. I have found a (now closed) google issue here and the last post says cyanogenmod fixed the issue by setting the default bitrate from 229 to 328. I guess google did, too: if you look here, you can see
Code: [Select]
140. /* Middle quality quality setting @ 44.1 khz */
141. #define DEFAULT_SBC_BITRATE 328
144. #define BTIF_A2DP_NON_EDR_MAX_RATE 229
145. #endif

It also seems that if the device does not support EDR, the rate will be reduced to 229kbps. (see lines 586-591)

Looking at files created with -b 53 gives the following output:
Code: [Select]
Filename    test.a2dp
mSBC    0
Subbands    8
Block length  16
Sampling frequency 44.1 kHz
Channel mode  Stereo
Allocation method  Loudness
Bitpool     53
Number of frames   83560
Frame length  118 Bytes
Bit rate    325.238 kbps

Not quite 328kbps, but increasing to -b54 gives 330.750 kbps, so I think we can safely assume current android sends data encoded with -b 53 at optimal conditions.

ABXing A2DP (SBC) vs. lossless?

Reply #15
Nice finding. I still interested if Android is using Joint-Stereo or not, also i think the Loudness vs. SNR bit allocation mode makes a noticable change in quality as well.

I would think that because SBC is actually a specialized MPEG Layer-I codec and even MPEG Layer-II's Joint-Stereo mode is more like MP3's Intensity Stereo (separation information for higher bands is dropped and replaced with more simple phase information) Android is using standard Stereo mode at this bitrate to achieve higher quality. But i'm just assuming this.

I've tried to compile sbc-1.2 on my Windows 8 box with MinGW-W64 which has GCC-4.8.2, the same as my Ubuntu box, but still getting strange compile errors. I don't know whats wrong. Here's the starting of the error log: The complete compile log has errors like this. Seems like it cannot find even standard headers, but i wonder how could i compile autoconf, pkgconfig-lite and libsndfile then.  Seems like ./configure generated by autoconf is wrong and miss detects things. Might someone has an idea to try.

ABXing A2DP (SBC) vs. lossless?

Reply #16

SBC ver 1.2 Win32 binaries. Parameter "-f" is mandatory for sbcdec, of course. AU files generated by sbcdec have a bunch of '0' after the header, hopefully SoX can deal with that problem (same behaviour under Linux).

Have a nice day,


ABXing A2DP (SBC) vs. lossless?

Reply #17
Thanks for the binaries! Damn Chrome is blocking the download, but the files are clean according to virustotal. I hate it when programs are trying to be smarter than the user.

SoX can deal with the zeroes, just warns you about header being too small or something. Foobar can't play those .au file directly though, so converting with SoX it is. Or maybe this plugin can be of use? (edit: no, it can't. probably because decoding a2dp results in the same .au unplayable by foobar)

That said, I can't seem to be able to ABX A2DP at -b 53. Haven't tried values in between yet. With windows binaries being available, maybe more people will be willing to test.

ABXing A2DP (SBC) vs. lossless?

Reply #18
Thanks AiZ for the Windows build! Can i ask you which tool did you use to compile it? I like to learn how to do these stuff.

I haven't done ABX'ing yet, just some casual listening on some samples i thought might reveal issues. Haven't detected anything wrong with -b53 with my headphones on. So I'm suspecting that i will be not able to ABX SBC@B53 which is actually very good, haven't expected this. I thought headphones will reveal artifacts very quickly.

Now that we have Windows binaries i would like to give classic MPEG killer samples a go though

ABXing A2DP (SBC) vs. lossless?

Reply #19

I've used MSYS2/gcc 4.9.1 environment. Libsndfile, which is available as a package in MSYS2 (like pkg-config), is only needed by the sbctester tool. Google a bit for pkg-config with MSYS and you can keep your MSYS setup if you only need sbcenc and sbcdec.
Of course, you'll have to slightly modify the source code to get rid of glibc, soundcard, whatever else stuff.

PM me if you need more information,


ABXing A2DP (SBC) vs. lossless?

Reply #20
I've made a batch script to ease encoding-decoding. It uses temp files, i don't know how to make SoX pipe to stdout. By writing "-" to the output filename it tries to create a file with that name.

Put SoX and sbcenc, sbcdec next to the batch file in a directory and then you can use it in Foobar as a passthrough encoder like this:

ABXing A2DP (SBC) vs. lossless?

Reply #21

SBC ver 1.2 Win32 binaries again.
Don't use stdin (-) as input for sbcenc as it seems to be broken (MSYS/MinGW problem?).
Modified sbcdec to output to stdout when not using -f or --file parameter.
Fixed .au files generated by sbcdec to be playable by foobar2000 and others (wrong default value in header).


ABXing A2DP (SBC) vs. lossless?

Reply #22
Thanks for that fix. Now we can both encode to .a2dp and play it directly from foobar! Just take the foobar decoder wrapper and use this template(save as .xml) to enable playing/ABXing .a2dp files.

ABXing A2DP (SBC) vs. lossless?

Reply #24
So I couldn't ABX SBC at 320kbps when playing it on my PC, but now that I got myself some BT headphones, I clearly hear artifacts on some songs. I thought it was supposed to be fixed with Android 4.0, but it isn't so.
My Xperia M2 runs 4.3, looking at google's repository, the first version with bitrate of 320kbps is android 4.4

Bummer. At least mine is getting an update to 4.4.2, so I will get the "full" quality in the future. Otherwise the only solution would be a custom ROM.

edit: before I get murdered: obligatory ABX of SBC@229 vs lossles:
Code: [Select]
foo_abx 1.3.4 report
foobar2000 v1.3.3
2014/08/19 14:53:00

File A: R:\01. TK from 凛として時雨 - unravel.tak
File B: R:\01. TK from 凛として時雨 - unravel_lq.a2dp

14:54:32 : Test started.
14:54:47 : 01/01  50.0%
14:55:45 : 02/02  25.0%
14:55:55 : 03/03  12.5%
14:56:06 : 04/04  6.3%
14:56:20 : 05/05  3.1%
14:56:56 : 06/06  1.6%
14:57:09 : 07/07  0.8%
14:57:12 : Test finished.

Total: 11/12 (0.3%)