bluetooth: add support for mSBC codec

Adding processing support for the mSBC codec is somewhat problematic,
because, although it is a SBC codec, the a2dp handling can't simply be
reused because the codec is used on an eSCO link with transparent
data, meaning the transmission unit has to be 48 bytes (fragmenting
the codec packets) and reassembly and boundary detection is required
to be done by the implementation.  Therefore we have to implement
separate render and push routines for msbc that do this fragmentation.

Fragmentation is done by emulating circular buffers.  The receive
(push) buffer is easy, since the mSBC packet size is 60, simply have a
buffer of this size in the sbc_info area where the fragments are
reassembled.  Once we have a full 60 bytes, decode and restart from
zero.  The send (render) buffer is more problematic, since the
transmit must be done from contiguous memory.  This means that the
buffer must be the lowest common multiple of the transmission unit and
the packet size.  This value is 240 since 240/48 == 5 and 240/60 == 4.
So the buffer pointers are reset at 240 which is a whole number of
both rendered packets and eSCO transmission units.

Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/507>
This commit is contained in:
James Bottomley 2021-02-17 09:44:34 +03:00 committed by PulseAudio Marge Bot
parent a7b21fb555
commit f22cfa8f81
5 changed files with 329 additions and 0 deletions

View file

@ -0,0 +1,35 @@
#pragma once
/*
* Parameters for use with mSBC over eSCO link
*/
#define MSBC_H2_ID0 0x01
#define MSBC_H2_ID1 0x08
#define MSBC_FRAME_SIZE 57
#define MSBC_SYNC_BYTE 0xad
struct msbc_h2_id1_s {
uint8_t id1:4;
uint8_t sn0:2;
uint8_t sn1:2;
} __attribute__ ((packed));
union msbc_h2_id1 {
struct msbc_h2_id1_s s;
uint8_t b;
};
struct msbc_h2_header {
uint8_t id0;
union msbc_h2_id1 id1;
} __attribute__ ((packed));
struct msbc_frame {
struct msbc_h2_header hdr;
uint8_t payload[MSBC_FRAME_SIZE];
uint8_t padding; /* must be zero */
} __attribute__ ((packed));
#define MSBC_PACKET_SIZE sizeof(struct msbc_frame)