[pulseaudio-discuss] [PATCH v8 08/12] bluetooth: Add A2DP FastStream codec support

Pali Rohár pali.rohar at gmail.com
Mon Apr 22 09:14:23 UTC 2019


On Monday 22 April 2019 11:01:01 Tanu Kaskinen wrote:
> On Sat, 2019-04-20 at 11:24 +0200, Pali Rohár wrote:
> > On Saturday 20 April 2019 11:37:56 Tanu Kaskinen wrote:
> > > On Sat, 2019-04-06 at 11:16 +0200, Pali Rohár wrote:
> > > > This patch provides support for FastStream codec in bluetooth A2DP profile.
> > > > FastStream codec is bi-directional, which means that support both music
> > > > playback and microphone voice at the same time.
> > > > 
> > > > FastStream codec is just SBC codec with fixed parameters. For playback are
> > > > used following parameters: 48.0kHz or 44.1kHz, Blocks 16, Sub-bands 8,
> > > > Joint Stereo, Loudness, Bitpool = 29 (data rate = 212kbps, packet size =
> > > > (71+1)*3+4 = 220 = DM5). SBC frame size is 71 bytes, but padded with one
> > > > zero byte due to rounding to 72 bytes. For microphone are used following
> > > > SBC parameters: 16kHz, Mono, Blocks 16, Sub-bands 8, Loudness, Bitpool = 32
> > > > (data rate = 72kbps, packet size = 3*72 + 4 = 220 <= DM5).
> > > > 
> > > > So FastStream codec is slightly equivalent to SBC Low Quality settings
> > > > (which uses bitpool value 30). But the main benefit of FastStream codec is
> > > > support for microphone voice channel for audio calls. Compared to bluetooth
> > > > HSP profile (with CVSD codec), it provides better audio quality for both
> > > > playback and recording.
> > > > ---
> > > >  src/Makefile.am                               |   2 +
> > > >  src/modules/bluetooth/a2dp-codec-faststream.c | 436 ++++++++++++++++++++++++++
> > > >  src/modules/bluetooth/a2dp-codec-util.c       |   2 +
> > > >  3 files changed, 440 insertions(+)
> > > >  create mode 100644 src/modules/bluetooth/a2dp-codec-faststream.c
> > > > +static bool is_configuration_valid(const uint8_t *config_buffer, uint8_t config_size) {
> > > > +    const a2dp_faststream_t *config = (const a2dp_faststream_t *) config_buffer;
> > > > +
> > > > +    if (config_size != sizeof(*config)) {
> > > > +        pa_log_error("Invalid size of config buffer");
> > > > +        return false;
> > > > +    }
> > > > +
> > > > +    if (A2DP_GET_VENDOR_ID(config->info) != FASTSTREAM_VENDOR_ID || A2DP_GET_CODEC_ID(config->info) != FASTSTREAM_CODEC_ID) {
> > > > +        pa_log_error("Invalid vendor codec information in configuration");
> > > > +        return false;
> > > > +    }
> > > > +
> > > > +    if (!(config->direction & FASTSTREAM_DIRECTION_SINK) || !(config->direction & FASTSTREAM_DIRECTION_SOURCE)) {
> > > > +        pa_log_error("Invalid direction in configuration");
> > > > +        return false;
> > > > +    }
> > > > +
> > > > +    /* Remote endpoint indicates list of frequences, not just one frequency */
> > > 
> > > Typo: "frequences" -> "frequencies".
> > 
> > Ok, I will fix all occurrences.
> > 
> > > > +    if ((config->sink_frequency & ~(FASTSTREAM_SINK_SAMPLING_FREQ_44100|FASTSTREAM_SINK_SAMPLING_FREQ_48000)) ||
> > > > +       (!(config->sink_frequency & (FASTSTREAM_SINK_SAMPLING_FREQ_44100|FASTSTREAM_SINK_SAMPLING_FREQ_48000)))) {
> > > 
> > > Do we really need to be this strict?
> > 
> > Yes.
> > 
> > > The final sample rate is decided
> > > by us, so isn't it enough if the config contains just one of the rates
> > > that we support? If the sink supports some other rates, we don't need
> > > to care about that.
> > 
> > Normally in A2DP capabilities buffer device announces combination (list)
> > of supported features and configurations. In A2DP config buffer device
> > usually says one exact configuration which should be used.
> > 
> > But my testing headphones in A2DP FastStream config buffer sometimes
> > says that sink frequency is both 44100|48000 -- which does not make
> > sense. When pulseaudio started sending SBC data with 44.1kHz then sound
> > was obviously bad, there was periodically quiet period (should be for
> > 1.8 us). When pulseaudio started sending SBC data with 48kHz everything
> > was OK. So conclusion is that when headphones says that sampling
> > frequency is both 44100|48000 in config buffer they means it is 48kHz.
> > 
> > In function is_configuration_valid we need to ensure that pulseaudio and
> > remove device negotiate correctly all parameters, including sampling
> > frequency and both sides know how to interpret config buffer.
> > 
> > So strictness is needed to ensure that audio is correctly encoded to SBC
> > codec and then correctly decoded from SBC codec to RAW.
> 
> Ok, so this is a firmware bug. That should be documented as such, and I
> think it would be best to do the firmware bug fixup as a separate step,
> like this:
> 
> static bool is_configuration_valid(...) {
>     uint8_t sink_frequency;
> 
>     ...
> 
>     sink_frequency = config->sink_frequency;
> 
>     /* Some headsets are buggy and set both 48 kHz and 44.1 kHz in
>      * the config. In such situation trying to send audio at 44.1 kHz
>      * results in choppy audio, so we have to assume that the headset
>      * actually wants 48 kHz audio. */
>     if (sink_frequency == (FASTSTREAM_SINK_SAMPLING_FREQ_44100 | FASTSTREAM_SINK_SAMPLING_FREQ_48000))
>         sink_frequency = FASTSTREAM_SINK_SAMPLING_FREQ_48000;
> 
>     if (sink_frequency != FASTSTREAM_SINK_SAMPLING_FREQ_44100 && sink_frequency != FASTSTREAM_SINK_SAMPLING_FREQ_48000) {
>         pa_log_error("Invalid sink sampling frequency in configuration");
>         return false;
>     }
> 
>     ...
> }
> 
> By the way, your original error message is "Invalid sampling sink
> frequency in configuration" and the same for source. The word ordering
> needs changing: it's "sink sampling frequency", not "sampling sink
> frequency".

Ok, I will adjust code according to your suggestion.

> > > > +        
> > > > +        return false;
> > > > +    }
> > > > +
> > > > +    /* Remote endpoint indicates list of frequences, not just one frequency */
> > > 
> > > Typo: "frequences" -> "frequencies".
> > > 
> > > Is this comment really true for sources?
> > 
> > Based on above observation about sinks I can deduce that it may be truth
> > also for sources... Currently we support only one frequency (because my
> > testing faststream headphones does not support more) but in future
> > somebody may extend support... and should be aware of this "bug".
> > 
> > I think that having more frequencies in config buffer is error and bug
> > in headphones firmware. But we need to deal with it.
> 
> We only need to deal with known firmware bugs, we shouldn't deviate
> from the specification (or the assumed specification - if I've
> understood correctly, the FastStream spec isn't available) due to
> speculation that other bugs might exist in some implementations. Even
> if similar bugs exist also with the backchannel frequencies, we can't
> assume without testing that the device wants 16 kHz audio rather than
> whatever other frequency it ended up putting in the config.

Ok, no problem. I will remove that part for source frequency. Currently
only 16kHz is supported...

-- 
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/20190422/0aef19ec/attachment.sig>


More information about the pulseaudio-discuss mailing list