[pulseaudio-discuss] Timing interval for Bluetooth Wideband speech

Tanu Kaskinen tanuk at iki.fi
Sat Apr 7 14:26:59 UTC 2018

On Fri, 2018-04-06 at 19:05 +0530, Ajay Kv wrote:
> Hi,
> I am following this mail thread. Also trying to make the same in my setup.
> I have added msbc encoding/decoding in PA  (host) code . PA as BT  HF role
> connected to  phone  .
> Once the call is connected  PA  starts writing the audio (pcm data)  to SCO
> socket  via  msbc encoder/decoder module
> CVSD has sample rate of 8khz  (48bytes in every 3ms  ,mono )  and MSBC has
> sample rate of 16khz . So as per
> bluetooth Specification  msbc encoded data rate should be 60 bytes in every
> 7.5ms,   ( (60*8 )   *   (1/7.5)   * 10^3  =  64Kbps)
> Currently with msbc enabled , we receives  240 bytes of pcm on every
> polling (rendering )  which is decoded to
> 60 bytes  of msbc encoded frame  ,where 60 is  sco mtu and 240 is the
> write_block_size .
> Please find few of my queries regarding this
> 1: As microphone is writing sco audio as soon as it is available . Do we
> have any option  to configure
>     the  stream rate or the clock tick for getting more samples  in PA
> (timer based) or anywhere in rendering queue or
>     streaming buffer based on the codec selected (different sample spec)?

Since your use case is connecting to a phone, I guess the microphone is
an alsa source that module-loopback connects to the bluetooth sink. Is
that correct?

I don't really understand your question, but I'll try answering
nevertheless: You should configure the bluetooth sink (and source)
sample_spec with 16 kHz sample rate when using wideband and with 8 kHz
when using narrowband. PulseAudio will then resample the microphone
audio to the target rate automatically.

> 2: Is there a scope for implementing flow control (audio samples) mechanism
> between PA and BT driver  to achieve
>      the rate (7.5 msec interval)?

thread_func() in module-bluez5-device.c does the scheduling. As I said
earlier, currently the scheduling is based on the rate at which the
kernel provides audio to the source. If you need to change the
scheduling to use the system clock instead, that's possible by
modifying thread_func(), but I find it hard to believe that we can't
rely on the kernel to keep the data rate correct. My understanding of
the SCO protocol is that both ends of the link somehow agree on a
common clock, which probably is different than the system clock. I'm
pretty sure the kernel (or perhaps the hardware, I don't know) is
responsible for transmitting the data at the correct rate -
PulseAudio's job is then to just fill the write buffer fast enough so
that the kernel always has something available when the time comes to
write a packet. PulseAudio can't know the exact agreed clock rate,
except by observing at which rate the kernel is producing/consuming
data from the socket. Why can't PulseAudio do its writes whenever it
has read data from the kernel like it does now? The reads and writes
should have the same rate anyway.

> 3: If i add a delay of 7.5msec manually in polling thread (thread_func() -
> ), will it halt the process to drop the audio packets (RX/TX).
>     or  the rate and bytes at which PA writes to SCO socket is irrespective
> of the codec selected ?

If you decide to implement the sink scheduling with the system clock,
you should calculate the appropriate sleep time that is passed to
pa_rtpoll_run(). pa_rtpoll_run() may return before the configured
amount of time has passed (this happens when messages are sent to the
thread), so before writing anything you need to check if enough time
has passed since the last write, or if you need to sleep some more.



More information about the pulseaudio-discuss mailing list