[pulseaudio-discuss] [PATCH v3] bluetooth: Wide Band Speech implementaion for backend ofono

James Bottomley James.Bottomley at HansenPartnership.com
Mon Aug 20 14:41:14 UTC 2018


On Mon, 2018-08-20 at 19:19 +0530, Sathish Narasimman wrote:
> From: Sathish Narasimman <sathish.narasimman at intel.com>
> 
> mSBC-encoded streams for HFP. The Wide Band Speech(WBS) encoding and
> decoding
> is implemeted with this patch. This patch was refered from original
> patch of Joao Paula Rechi Vita and was verified with the supported
> bluetooth controller.

Which headset did you test this with?  When I try it with an LG 900 I
get a huge amount of chop which shreds the audio quality.  For this
headset the packet size (MTU) still needs to be set at 48 on both the
send and receive side otherwise the audio doesn't work at all.

What seems to be happening is that the LG insists on running the eSCO
links at full speed but the encoded packets only take about half the
bandwidth, so on the headset receiving side, we get about half as many
mSBC encoded packets with the rest being zero padded.

The problem occurs because on the receive side you count mSBC packets,
so the reader/writer thread you try to send 1 mSBC encoded packet for
every 1 mSBC packet you receive.

But in this send loop:

> +        /* Send MTU bytes of it, if there is more it will send later
> */
> +        while (u->msbc_info.ebuffer_start + u->write_link_mtu <= u-
> >msbc_info.ebuffer_end) {
> +            l = pa_write(u->stream_fd,
> +                         u->msbc_info.ebuffer + u-
> >msbc_info.ebuffer_start,
> +                         u->write_link_mtu,
> +                         &u->stream_write_type);
> +
> +            wrote = true;
> +            if (l <= 0) {
> +                pa_log_debug("Error while writing: l %d, errno %d",
> l, errno);
> +                break;
> +            }
> +
> +            u->msbc_info.ebuffer_start += l;
> +            if (u->msbc_info.ebuffer_start >= u-
> >msbc_info.ebuffer_end)
> +                u->msbc_info.ebuffer_start = u-
> >msbc_info.ebuffer_end = 0;
> +        }
> +
> +        pa_memblock_release(u->write_memchunk.memblock);
> +
> +        if (wrote && l < 0) {
> +
> +            if (errno == EINTR)
> +                /* Retry right away if we got interrupted */
> +                continue;
> +
> +            else if (errno == EAGAIN)
> +                /* Hmm, apparently the socket was not writable, give
> up for now */
> +                break;
> +
> +            pa_log_error("Failed to write data to SCO socket: %s",
> pa_cstrerror(errno));
> +            ret = -1;
> +            break;
> +        }
> +
> +        if ((size_t) l != (size_t)u->write_link_mtu) {
> +            pa_log_error("Wrote memory block to socket only
> partially! %llu written, wanted to write %llu.",
> +                        (unsigned long long) l,
> +                        (unsigned long long) u->write_link_mtu);
> +            ret = -1;
> +            break;
> +        }
> +
> +        u->write_index += (uint64_t) u->write_memchunk.length;
> +
> +        pa_memblock_unref(u->write_memchunk.memblock);
> +        pa_memchunk_reset(&u->write_memchunk);
> +
> +        ret = 1;
> +        break;
> +    }

Because the mtu is 48 and the mSBC encode size is 60, the transmission
stops after 48 bytes, we now wait for a new mSBC packet to be received,
so we miss the next eSCO transmission window and the headset fills in
with zeros causing the packet to be chopped and the next one to be
discarded as invalid.

I suspect the only way to get mSBC to work for this type of headset is
to count actual received packets, always to transmit full 60 byte mSBC
packets in adjacent frames and to pad with zeros if we're not ready.

James



More information about the pulseaudio-discuss mailing list