[pulseaudio-discuss] Bluetooth codec selection

Pali Rohár pali.rohar at gmail.com
Tue Jan 7 18:37:09 UTC 2020


My A2DP patch series which adds support for more A2DP codecs is still in
review state, but Tanu about year ago wrote that do not like my proposal
with usage of PA profiles for selecting A2DP codec. Because nobody for
last year come up with another option how to solve this problem and
because without it is not possible to add support for other codecs it
means that pulseaudio is stucked and has no way to improve A2DP support.

So here I'm adding another proposal how to handle multi-codec support
for bluetooth in pulseaudio. But first description of our problem:

Currently we have following profiles for bluetooth card:

* headset_audio_gateway
* headset_head_unit
* a2dp_source
* a2dp_sink

If we look at HW level of HSP/HFP profiles they may supports following
codecs: CVSD, mSBC, AuriStream. All are bidirectional, synchronous.
Moreover encoding from PCM stream to codec data may be done at HW level
(bluetooth adapter) or on SW level (pulseaudio). Currently encoding to
CVSD is done at HW level and encoding to mSBC at SW level. But e.g. new
Thinkpads has bluetooth adapters which can do mSBC-encoding at HW level
and theoretically pulseaudio could just pass PCM samples to BT without
need to use any software sbc encoding library (*).

And if we look at A2DP profiles it is quite a bit complicated. Every
"A2DP codec" is either one-way (source or sink) or is bi-directional
(but it is rare and most devices does not support them). Plus every
"A2DP codec" may support more "codec profiles", so e.g. we have SBC-MQ
or SBC-HQ. And bidirectional "A2DP codecs" may use different "audio
codec" for one directional and different for back directional (e.g.
A2DP codec aptX-LL uses aptX codec for playing and SBC codec for

Result is: "SBC" codec is supported in "headset_head_unit" PA profile
(as mSBC"), it is supported also in "a2dp_sink" PA profile when "A2DP
SBC" codec is used and also in "a2dp_source" PA profile when "aptX-LL"
codec is used.

So adding a new API which sets codec on PA bluetooth card is not enough.

I would propose following API:

Add support for pulseaudio "sub-profiles". For every pulseaudio profile
it would be possible to register sub-profile and applications via
pulseaudio API would be able to change sub-profile of some PA card (if
currently selected PA profile would support it).

Plus adds a two new profiles:
* a2dp_source_with_backchannel
* a2dp_sink_with_backchannel

For music playback in most cases is useful only profiles without
backchannel to maximize bandwidth. And because A2DP codecs with
bachannel does not fit into HSP profiles it make sense to have them in
separate profile. In most cases A2DP profile with backchannel is the
best way for VOIP (as it has microphone recording support), so bluetooth
policy plugin would be extended to use also this profile for VOIP.

Sub-profiles for bluetooth PA card would be following:

* headset_audio_gateway
  - CVSD (hardware)
  - mSBC (software)
  - mSBC (hardware)
* headset_head_unit
  - same as in headset_audio_gateway
* a2dp_source
  - SBC-LQ
  - SBC-MQ
  - SBC-HQ
  - faststream without backchannel
  - aptX
  - aptX-HD
  - aptX-LL without backannel
  - LDAC
* a2dp_sink
  - same as in a2dp_source
* a2dp_source_with_backchannel
  - faststream with backchannel
  - aptX-LL with backchannel
* a2dp_sink_with_backchannel
  - same as in a2dp_source_with_backchannel

So sub-profile would be one specific configuration of codec. In HSP/HFP
there would be two sub-profiles for every codec (one for software
encoding, one for hardware encoding). In A2DP it may be various. E.g.
for "SBC profiles" there would be one sub-profile for every SBC
configuration. For faststream codec there would be two, one with
backchannel, one without. Default sub-codec selection would be up to
the pulseaudio module. And applications (pactl / pavucontrol / ...)
would be able to change PA sub-profile in similar way how they can do it
for PA profiles.

Of course some sub-profiles does not have to be supported (e.g. mSBC in
hardware encoding) and in these cases pulseaudio would not announce
these unsupported sub-profiles.

What do you think about this my proposal?

Tanu, is this acceptable for you?

Basically it is needed only to add APIs for applications to:
* get current sub-profile of card
* get list of all sub-profiles for specific profile
* change sub-profile of card

I'm not saying how would API look like. I'm open for implementation
details... I can imagine that we can extend PA protocol or use messaging
API for it or anything else...

(*) - currently Linux kernel blocks this usage of mSBC HW encoding and
force userspace to do whole encoding at application level (in

Pali Rohár
pali.rohar at gmail.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/pulseaudio-discuss/attachments/20200107/387f2a3e/attachment.sig>

More information about the pulseaudio-discuss mailing list