bluez5: further HFP cleanups

Fix naming issues.
This commit is contained in:
Pauli Virtanen 2024-01-23 22:56:03 +02:00 committed by Wim Taymans
parent ebde25fe58
commit 65f594c6a1
5 changed files with 50 additions and 56 deletions

View file

@ -638,7 +638,7 @@ static bool device_supports_codec(struct impl *backend, struct spa_bt_device *de
alt1_ok = msbc_alt1_ok; alt1_ok = msbc_alt1_ok;
alt6_ok = msbc_alt6_ok; alt6_ok = msbc_alt6_ok;
break; break;
case HFP_AUDIO_CODEC_LC3: case HFP_AUDIO_CODEC_LC3_SWB:
#ifdef HAVE_LC3 #ifdef HAVE_LC3
/* LC3-SWB has same transport requirements as msbc. /* LC3-SWB has same transport requirements as msbc.
* However, ALT1/ALT5 modes don't appear to work, seem * However, ALT1/ALT5 modes don't appear to work, seem
@ -801,7 +801,7 @@ static bool rfcomm_hfp_ag(struct rfcomm *rfcomm, char* buf)
if (sscanf(buf, "AT+BRSF=%u", &features) == 1) { if (sscanf(buf, "AT+BRSF=%u", &features) == 1) {
unsigned int ag_features = SPA_BT_HFP_AG_FEATURE_NONE; unsigned int ag_features = SPA_BT_HFP_AG_FEATURE_NONE;
bool codecs = device_supports_codec(backend, rfcomm->device, HFP_AUDIO_CODEC_MSBC) || bool codecs = device_supports_codec(backend, rfcomm->device, HFP_AUDIO_CODEC_MSBC) ||
device_supports_codec(backend, rfcomm->device, HFP_AUDIO_CODEC_LC3); device_supports_codec(backend, rfcomm->device, HFP_AUDIO_CODEC_LC3_SWB);
/* /*
* Determine device volume control. Some headsets only support control of * Determine device volume control. Some headsets only support control of
@ -860,9 +860,9 @@ static bool rfcomm_hfp_ag(struct rfcomm *rfcomm, char* buf)
if (codec_id == HFP_AUDIO_CODEC_MSBC) if (codec_id == HFP_AUDIO_CODEC_MSBC)
rfcomm->msbc_supported_by_hfp = rfcomm->msbc_supported_by_hfp =
device_supports_codec(backend, rfcomm->device, HFP_AUDIO_CODEC_MSBC); device_supports_codec(backend, rfcomm->device, HFP_AUDIO_CODEC_MSBC);
else if (codec_id == HFP_AUDIO_CODEC_LC3) else if (codec_id == HFP_AUDIO_CODEC_LC3_SWB)
rfcomm->lc3_supported_by_hfp = rfcomm->lc3_supported_by_hfp =
device_supports_codec(backend, rfcomm->device, HFP_AUDIO_CODEC_LC3); device_supports_codec(backend, rfcomm->device, HFP_AUDIO_CODEC_LC3_SWB);
} }
cntr++; cntr++;
} }
@ -935,7 +935,7 @@ static bool rfcomm_hfp_ag(struct rfcomm *rfcomm, char* buf)
volume_sync_stop_timer(rfcomm); volume_sync_stop_timer(rfcomm);
if (selected_codec != HFP_AUDIO_CODEC_CVSD && selected_codec != HFP_AUDIO_CODEC_MSBC && if (selected_codec != HFP_AUDIO_CODEC_CVSD && selected_codec != HFP_AUDIO_CODEC_MSBC &&
selected_codec != HFP_AUDIO_CODEC_LC3) { selected_codec != HFP_AUDIO_CODEC_LC3_SWB) {
spa_log_warn(backend->log, "unsupported codec negotiation: %d", selected_codec); spa_log_warn(backend->log, "unsupported codec negotiation: %d", selected_codec);
rfcomm_send_error(rfcomm, CMEE_AG_FAILURE); rfcomm_send_error(rfcomm, CMEE_AG_FAILURE);
if (was_switching_codec) if (was_switching_codec)
@ -1220,7 +1220,7 @@ static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* token)
rfcomm->codec_negotiation_supported = true; rfcomm->codec_negotiation_supported = true;
} else if (sscanf(token, "+BCS:%u", &selected_codec) == 1 && rfcomm->codec_negotiation_supported) { } else if (sscanf(token, "+BCS:%u", &selected_codec) == 1 && rfcomm->codec_negotiation_supported) {
if (selected_codec != HFP_AUDIO_CODEC_CVSD && selected_codec != HFP_AUDIO_CODEC_MSBC && if (selected_codec != HFP_AUDIO_CODEC_CVSD && selected_codec != HFP_AUDIO_CODEC_MSBC &&
selected_codec != HFP_AUDIO_CODEC_LC3) { selected_codec != HFP_AUDIO_CODEC_LC3_SWB) {
spa_log_warn(backend->log, "unsupported codec negotiation: %d", selected_codec); spa_log_warn(backend->log, "unsupported codec negotiation: %d", selected_codec);
} else { } else {
spa_log_debug(backend->log, "RFCOMM selected_codec = %i", selected_codec); spa_log_debug(backend->log, "RFCOMM selected_codec = %i", selected_codec);
@ -1503,7 +1503,7 @@ static int sco_do_connect(struct spa_bt_transport *t)
str2ba(d->address, &addr.sco_bdaddr); str2ba(d->address, &addr.sco_bdaddr);
for (int retry = 2;;) { for (int retry = 2;;) {
bool transparent = (t->codec == HFP_AUDIO_CODEC_MSBC || t->codec == HFP_AUDIO_CODEC_LC3); bool transparent = (t->codec == HFP_AUDIO_CODEC_MSBC || t->codec == HFP_AUDIO_CODEC_LC3_SWB);
spa_autoclose int sock = sco_create_socket(backend, d->adapter, transparent); spa_autoclose int sock = sco_create_socket(backend, d->adapter, transparent);
if (sock < 0) if (sock < 0)
return -1; return -1;
@ -1834,7 +1834,7 @@ static void sco_listen_event(struct spa_source *source)
* accepted socket. */ * accepted socket. */
char buff; char buff;
if (t->codec == HFP_AUDIO_CODEC_MSBC || t->codec == HFP_AUDIO_CODEC_LC3) { if (t->codec == HFP_AUDIO_CODEC_MSBC || t->codec == HFP_AUDIO_CODEC_LC3_SWB) {
/* set correct socket options for mSBC/LC3 */ /* set correct socket options for mSBC/LC3 */
struct bt_voice voice_config; struct bt_voice voice_config;
memset(&voice_config, 0, sizeof(voice_config)); memset(&voice_config, 0, sizeof(voice_config));
@ -2015,7 +2015,7 @@ static int backend_native_supports_codec(void *data, struct spa_bt_device *devic
if (codec == HFP_AUDIO_CODEC_MSBC) if (codec == HFP_AUDIO_CODEC_MSBC)
return rfcomm->msbc_supported_by_hfp; return rfcomm->msbc_supported_by_hfp;
else if (codec == HFP_AUDIO_CODEC_LC3) else if (codec == HFP_AUDIO_CODEC_LC3_SWB)
return rfcomm->lc3_supported_by_hfp; return rfcomm->lc3_supported_by_hfp;
return 0; return 0;
@ -2320,7 +2320,7 @@ static DBusHandlerResult profile_new_connection(DBusConnection *conn, DBusMessag
/* Start SLC connection */ /* Start SLC connection */
unsigned int hf_features = SPA_BT_HFP_HF_FEATURE_NONE; unsigned int hf_features = SPA_BT_HFP_HF_FEATURE_NONE;
bool has_msbc = device_supports_codec(backend, rfcomm->device, HFP_AUDIO_CODEC_MSBC); bool has_msbc = device_supports_codec(backend, rfcomm->device, HFP_AUDIO_CODEC_MSBC);
bool has_lc3 = device_supports_codec(backend, rfcomm->device, HFP_AUDIO_CODEC_LC3); bool has_lc3 = device_supports_codec(backend, rfcomm->device, HFP_AUDIO_CODEC_LC3_SWB);
/* Decide if we want to signal that the HF supports mSBC/LC3 negotiation /* Decide if we want to signal that the HF supports mSBC/LC3 negotiation
This should be done when the bluetooth adapter supports the necessary transport mode */ This should be done when the bluetooth adapter supports the necessary transport mode */

View file

@ -248,7 +248,7 @@ static unsigned int get_hfp_codec(enum spa_bluetooth_audio_codec id)
case SPA_BLUETOOTH_AUDIO_CODEC_MSBC: case SPA_BLUETOOTH_AUDIO_CODEC_MSBC:
return HFP_AUDIO_CODEC_MSBC; return HFP_AUDIO_CODEC_MSBC;
case SPA_BLUETOOTH_AUDIO_CODEC_LC3_SWB: case SPA_BLUETOOTH_AUDIO_CODEC_LC3_SWB:
return HFP_AUDIO_CODEC_LC3; return HFP_AUDIO_CODEC_LC3_SWB;
default: default:
return 0; return 0;
} }
@ -259,7 +259,7 @@ static enum spa_bluetooth_audio_codec get_hfp_codec_id(unsigned int codec)
switch (codec) { switch (codec) {
case HFP_AUDIO_CODEC_MSBC: case HFP_AUDIO_CODEC_MSBC:
return SPA_BLUETOOTH_AUDIO_CODEC_MSBC; return SPA_BLUETOOTH_AUDIO_CODEC_MSBC;
case HFP_AUDIO_CODEC_LC3: case HFP_AUDIO_CODEC_LC3_SWB:
return SPA_BLUETOOTH_AUDIO_CODEC_LC3_SWB; return SPA_BLUETOOTH_AUDIO_CODEC_LC3_SWB;
case HFP_AUDIO_CODEC_CVSD: case HFP_AUDIO_CODEC_CVSD:
return SPA_BLUETOOTH_AUDIO_CODEC_CVSD; return SPA_BLUETOOTH_AUDIO_CODEC_CVSD;
@ -272,7 +272,7 @@ static const char *get_hfp_codec_description(unsigned int codec)
switch (codec) { switch (codec) {
case HFP_AUDIO_CODEC_MSBC: case HFP_AUDIO_CODEC_MSBC:
return "mSBC"; return "mSBC";
case HFP_AUDIO_CODEC_LC3: case HFP_AUDIO_CODEC_LC3_SWB:
return "LC3-SWB"; return "LC3-SWB";
case HFP_AUDIO_CODEC_CVSD: case HFP_AUDIO_CODEC_CVSD:
return "CVSD"; return "CVSD";
@ -285,7 +285,7 @@ static const char *get_hfp_codec_name(unsigned int codec)
switch (codec) { switch (codec) {
case HFP_AUDIO_CODEC_MSBC: case HFP_AUDIO_CODEC_MSBC:
return "msbc"; return "msbc";
case HFP_AUDIO_CODEC_LC3: case HFP_AUDIO_CODEC_LC3_SWB:
return "lc3_swb"; return "lc3_swb";
case HFP_AUDIO_CODEC_CVSD: case HFP_AUDIO_CODEC_CVSD:
return "cvsd"; return "cvsd";
@ -2264,7 +2264,7 @@ static struct spa_pod *build_prop_info_codec(struct impl *this, struct spa_pod_b
#define FOR_EACH_MEDIA_CODEC(j, codec) \ #define FOR_EACH_MEDIA_CODEC(j, codec) \
for (j = -1; iterate_supported_media_codecs(this, &j, &codec);) for (j = -1; iterate_supported_media_codecs(this, &j, &codec);)
#define FOR_EACH_HFP_CODEC(j) \ #define FOR_EACH_HFP_CODEC(j) \
for (j = HFP_AUDIO_CODEC_LC3; j >= HFP_AUDIO_CODEC_CVSD; --j) \ for (j = HFP_AUDIO_CODEC_LC3_SWB; j >= HFP_AUDIO_CODEC_CVSD; --j) \
if (spa_bt_device_supports_hfp_codec(this->bt_dev, j) == 1) if (spa_bt_device_supports_hfp_codec(this->bt_dev, j) == 1)
spa_pod_builder_push_object(b, &f[0], SPA_TYPE_OBJECT_PropInfo, id); spa_pod_builder_push_object(b, &f[0], SPA_TYPE_OBJECT_PropInfo, id);
@ -2748,7 +2748,7 @@ static int impl_set_param(void *object,
spa_bt_device_supports_hfp_codec(this->bt_dev, HFP_AUDIO_CODEC_MSBC) == 1) { spa_bt_device_supports_hfp_codec(this->bt_dev, HFP_AUDIO_CODEC_MSBC) == 1) {
return set_profile(this, this->profile, codec_id, true); return set_profile(this, this->profile, codec_id, true);
} else if (codec_id == SPA_BLUETOOTH_AUDIO_CODEC_LC3_SWB && } else if (codec_id == SPA_BLUETOOTH_AUDIO_CODEC_LC3_SWB &&
spa_bt_device_supports_hfp_codec(this->bt_dev, HFP_AUDIO_CODEC_LC3) == 1) { spa_bt_device_supports_hfp_codec(this->bt_dev, HFP_AUDIO_CODEC_LC3_SWB) == 1) {
return set_profile(this, this->profile, codec_id, true); return set_profile(this, this->profile, codec_id, true);
} }
} }

View file

@ -143,7 +143,7 @@ extern "C" {
#define HFP_AUDIO_CODEC_CVSD 0x01 #define HFP_AUDIO_CODEC_CVSD 0x01
#define HFP_AUDIO_CODEC_MSBC 0x02 #define HFP_AUDIO_CODEC_MSBC 0x02
#define HFP_AUDIO_CODEC_LC3 0x03 #define HFP_AUDIO_CODEC_LC3_SWB 0x03
#define A2DP_OBJECT_MANAGER_PATH "/MediaEndpoint" #define A2DP_OBJECT_MANAGER_PATH "/MediaEndpoint"
#define A2DP_SINK_ENDPOINT A2DP_OBJECT_MANAGER_PATH "/A2DPSink" #define A2DP_SINK_ENDPOINT A2DP_OBJECT_MANAGER_PATH "/A2DPSink"
@ -161,13 +161,11 @@ extern "C" {
/* HFP uses SBC encoding with precisely defined parameters. Hence, the size /* HFP uses SBC encoding with precisely defined parameters. Hence, the size
* of the input (number of PCM samples) and output is known up front. */ * of the input (number of PCM samples) and output is known up front. */
#define MSBC_DECODED_SIZE 240 #define MSBC_DECODED_SIZE 240
#define MSBC_ENCODED_SIZE 60 /* 2 bytes header + 57 mSBC payload + 1 byte padding */ #define MSBC_PAYLOAD_SIZE 57 /* 1 byte padding follows payload */
#define MSBC_PAYLOAD_SIZE 57 #define LC3_SWB_DECODED_SIZE 960 /* 32 kHz mono S24_32 @ 7.5 ms */
#define LC3_SWB_PAYLOAD_SIZE 58
#define LC3_SWB_DECODED_SIZE 960 /* 32 kHz mono S24_32 @ 7.5 ms */ #define HFP_CODEC_PACKET_SIZE 60 /* 2 bytes header + payload */
#define LC3_SWB_ENCODED_SIZE 60 /* 2 bytes header + 58 LC3 payload */
#define LC3_SWB_PAYLOAD_SIZE 58
enum spa_bt_media_direction { enum spa_bt_media_direction {
SPA_BT_MEDIA_SOURCE, SPA_BT_MEDIA_SOURCE,

View file

@ -49,6 +49,9 @@ struct props {
#define MAX_BUFFERS 32 #define MAX_BUFFERS 32
#define ALT1_PACKET_SIZE 24
#define ALT6_PACKET_SIZE 60
struct buffer { struct buffer {
uint32_t id; uint32_t id;
unsigned int outstanding:1; unsigned int outstanding:1;
@ -409,7 +412,7 @@ static int flush_data(struct impl *this)
return -EIO; return -EIO;
const uint32_t min_in_size = (this->transport->codec == HFP_AUDIO_CODEC_MSBC) ? MSBC_DECODED_SIZE : const uint32_t min_in_size = (this->transport->codec == HFP_AUDIO_CODEC_MSBC) ? MSBC_DECODED_SIZE :
(this->transport->codec == HFP_AUDIO_CODEC_LC3) ? LC3_SWB_DECODED_SIZE : (this->transport->codec == HFP_AUDIO_CODEC_LC3_SWB) ? LC3_SWB_DECODED_SIZE :
this->transport->write_mtu; this->transport->write_mtu;
const uint32_t packet_samples = min_in_size / port->frame_size; const uint32_t packet_samples = min_in_size / port->frame_size;
const uint64_t packet_time = (uint64_t)packet_samples * SPA_NSEC_PER_SEC const uint64_t packet_time = (uint64_t)packet_samples * SPA_NSEC_PER_SEC
@ -466,13 +469,11 @@ static int flush_data(struct impl *this)
} }
if (this->transport->codec == HFP_AUDIO_CODEC_MSBC || if (this->transport->codec == HFP_AUDIO_CODEC_MSBC ||
this->transport->codec == HFP_AUDIO_CODEC_LC3) { this->transport->codec == HFP_AUDIO_CODEC_LC3_SWB) {
uint32_t encoded_size = (this->transport->codec == HFP_AUDIO_CODEC_MSBC) ? MSBC_ENCODED_SIZE :
LC3_SWB_ENCODED_SIZE;
ssize_t out_encoded; ssize_t out_encoded;
/* Encode */ /* Encode */
if (this->buffer_next + encoded_size > this->buffer + this->buffer_size) { if (this->buffer_next + HFP_CODEC_PACKET_SIZE > this->buffer + this->buffer_size) {
/* Buffer overrun; shouldn't usually happen. Drop data and reset. */ /* Buffer overrun; shouldn't usually happen. Drop data and reset. */
this->buffer_head = this->buffer_next = this->buffer; this->buffer_head = this->buffer_next = this->buffer;
spa_log_warn(this->log, "sco-sink: mSBC/LC3 buffer overrun, dropping data"); spa_log_warn(this->log, "sco-sink: mSBC/LC3 buffer overrun, dropping data");
@ -486,11 +487,11 @@ static int flush_data(struct impl *this)
if (this->transport->codec == HFP_AUDIO_CODEC_MSBC) { if (this->transport->codec == HFP_AUDIO_CODEC_MSBC) {
processed = sbc_encode(&this->msbc, port->write_buffer, port->write_buffer_size, processed = sbc_encode(&this->msbc, port->write_buffer, port->write_buffer_size,
this->buffer_next + 2, encoded_size - 3, &out_encoded); this->buffer_next + 2, HFP_CODEC_PACKET_SIZE - 3, &out_encoded);
out_encoded += 1; /* pad */ out_encoded += 1; /* pad */
} else { } else {
processed = lc3_encode_frame(this, port->write_buffer, port->write_buffer_size, processed = lc3_encode_frame(this, port->write_buffer, port->write_buffer_size,
this->buffer_next + 2, encoded_size - 2, &out_encoded); this->buffer_next + 2, HFP_CODEC_PACKET_SIZE - 2, &out_encoded);
} }
if (processed < 0) { if (processed < 0) {
@ -513,9 +514,9 @@ static int flush_data(struct impl *this)
if (this->buffer_head == this->buffer_next) if (this->buffer_head == this->buffer_next)
this->buffer_head = this->buffer_next = this->buffer; this->buffer_head = this->buffer_next = this->buffer;
else if (this->buffer_next + encoded_size > this->buffer + this->buffer_size) { else if (this->buffer_next + HFP_CODEC_PACKET_SIZE > this->buffer + this->buffer_size) {
/* Written bytes is not necessarily commensurate /* Written bytes is not necessarily commensurate
* with encoded_size. If this occurs, copy data. * with HFP_CODEC_PACKET_SIZE. If this occurs, copy data.
*/ */
int size = this->buffer_next - this->buffer_head; int size = this->buffer_next - this->buffer_head;
spa_memmove(this->buffer, this->buffer_head, size); spa_memmove(this->buffer, this->buffer_head, size);
@ -722,8 +723,8 @@ static int transport_start(struct impl *this)
* commensurate, we may end up doing memmoves, but nothing worse * commensurate, we may end up doing memmoves, but nothing worse
* is going to happen. * is going to happen.
*/ */
this->buffer_size = lcm(24, lcm(60, lcm(this->transport->write_mtu, 2 * MSBC_ENCODED_SIZE))); this->buffer_size = lcm(ALT1_PACKET_SIZE, lcm(ALT6_PACKET_SIZE, lcm(this->transport->write_mtu, 2 * HFP_CODEC_PACKET_SIZE)));
} else if (this->transport->codec == HFP_AUDIO_CODEC_LC3) { } else if (this->transport->codec == HFP_AUDIO_CODEC_LC3_SWB) {
#ifdef HAVE_LC3 #ifdef HAVE_LC3
this->lc3 = lc3_setup_encoder(7500, 32000, 0, this->lc3 = lc3_setup_encoder(7500, 32000, 0,
calloc(1, lc3_encoder_size(7500, 32000))); calloc(1, lc3_encoder_size(7500, 32000)));
@ -732,7 +733,7 @@ static int transport_start(struct impl *this)
spa_assert(lc3_frame_samples(7500, 32000) * this->port.frame_size == LC3_SWB_DECODED_SIZE); spa_assert(lc3_frame_samples(7500, 32000) * this->port.frame_size == LC3_SWB_DECODED_SIZE);
this->buffer_size = lcm(24, lcm(60, lcm(this->transport->write_mtu, 2 * LC3_SWB_ENCODED_SIZE))); this->buffer_size = lcm(ALT1_PACKET_SIZE, lcm(ALT6_PACKET_SIZE, lcm(this->transport->write_mtu, 2 * HFP_CODEC_PACKET_SIZE)));
#else #else
res = -EOPNOTSUPP; res = -EOPNOTSUPP;
goto fail; goto fail;
@ -1090,7 +1091,7 @@ impl_node_port_enum_params(void *object, int seq,
/* set the info structure */ /* set the info structure */
struct spa_audio_info_raw info = { 0, }; struct spa_audio_info_raw info = { 0, };
if (this->transport->codec == HFP_AUDIO_CODEC_LC3) if (this->transport->codec == HFP_AUDIO_CODEC_LC3_SWB)
info.format = SPA_AUDIO_FORMAT_S24_32_LE; info.format = SPA_AUDIO_FORMAT_S24_32_LE;
else else
info.format = SPA_AUDIO_FORMAT_S16_LE; info.format = SPA_AUDIO_FORMAT_S16_LE;
@ -1101,7 +1102,7 @@ impl_node_port_enum_params(void *object, int seq,
* MSBC format has a rate of 16kHz * MSBC format has a rate of 16kHz
* LC3-SWB format has a rate of 32kHz * LC3-SWB format has a rate of 32kHz
*/ */
if (this->transport->codec == HFP_AUDIO_CODEC_LC3) if (this->transport->codec == HFP_AUDIO_CODEC_LC3_SWB)
info.rate = 32000; info.rate = 32000;
else if (this->transport->codec == HFP_AUDIO_CODEC_MSBC) else if (this->transport->codec == HFP_AUDIO_CODEC_MSBC)
info.rate = 16000; info.rate = 16000;
@ -1238,12 +1239,12 @@ static int port_set_format(struct impl *this, struct port *port,
switch (info.info.raw.format) { switch (info.info.raw.format) {
case SPA_AUDIO_FORMAT_S16_LE: case SPA_AUDIO_FORMAT_S16_LE:
if (this->transport->codec == HFP_AUDIO_CODEC_LC3) if (this->transport->codec == HFP_AUDIO_CODEC_LC3_SWB)
return -EINVAL; return -EINVAL;
port->frame_size = info.info.raw.channels * 2; port->frame_size = info.info.raw.channels * 2;
break; break;
case SPA_AUDIO_FORMAT_S24_32_LE: case SPA_AUDIO_FORMAT_S24_32_LE:
if (this->transport->codec != HFP_AUDIO_CODEC_LC3) if (this->transport->codec != HFP_AUDIO_CODEC_LC3_SWB)
return -EINVAL; return -EINVAL;
port->frame_size = info.info.raw.channels * 4; port->frame_size = info.info.raw.channels * 4;
break; break;

View file

@ -138,7 +138,7 @@ struct impl {
uint8_t h2_seq; uint8_t h2_seq;
/* mSBC/LC3 frame parsing */ /* mSBC/LC3 frame parsing */
uint8_t recv_buffer[MSBC_ENCODED_SIZE + LC3_SWB_ENCODED_SIZE]; uint8_t recv_buffer[HFP_CODEC_PACKET_SIZE];
uint8_t recv_buffer_pos; uint8_t recv_buffer_pos;
/* mSBC */ /* mSBC */
@ -359,9 +359,6 @@ static void recycle_buffer(struct impl *this, struct port *port, uint32_t buffer
/* Append data to recv buffer, syncing buffer start to headers */ /* Append data to recv buffer, syncing buffer start to headers */
static void recv_buffer_append_byte(struct impl *this, uint8_t byte) static void recv_buffer_append_byte(struct impl *this, uint8_t byte)
{ {
unsigned int encoded_size = (this->transport->codec == HFP_AUDIO_CODEC_MSBC) ? MSBC_ENCODED_SIZE :
LC3_SWB_ENCODED_SIZE;
/* Parse H2 sync header */ /* Parse H2 sync header */
if (this->recv_buffer_pos == 0) { if (this->recv_buffer_pos == 0) {
if (byte != 0x01) { if (byte != 0x01) {
@ -397,7 +394,7 @@ static void recv_buffer_append_byte(struct impl *this, uint8_t byte)
} }
} }
if (this->recv_buffer_pos >= encoded_size) { if (this->recv_buffer_pos >= HFP_CODEC_PACKET_SIZE) {
/* Packet completed. Reset. */ /* Packet completed. Reset. */
this->recv_buffer_pos = 0; this->recv_buffer_pos = 0;
recv_buffer_append_byte(this, byte); recv_buffer_append_byte(this, byte);
@ -465,8 +462,6 @@ static uint32_t preprocess_and_decode_codec_data(void *userdata, uint8_t *read_d
struct port *port = &this->port; struct port *port = &this->port;
uint32_t decoded = 0; uint32_t decoded = 0;
int i; int i;
uint32_t encoded_size = (this->transport->codec == HFP_AUDIO_CODEC_MSBC) ? MSBC_ENCODED_SIZE :
LC3_SWB_ENCODED_SIZE;
uint32_t decoded_size = (this->transport->codec == HFP_AUDIO_CODEC_MSBC) ? MSBC_DECODED_SIZE : uint32_t decoded_size = (this->transport->codec == HFP_AUDIO_CODEC_MSBC) ? MSBC_DECODED_SIZE :
LC3_SWB_DECODED_SIZE; LC3_SWB_DECODED_SIZE;
@ -489,7 +484,7 @@ static uint32_t preprocess_and_decode_codec_data(void *userdata, uint8_t *read_d
recv_buffer_append_byte(this, read_data[i]); recv_buffer_append_byte(this, read_data[i]);
if (this->recv_buffer_pos != encoded_size) if (this->recv_buffer_pos != HFP_CODEC_PACKET_SIZE)
continue; continue;
/* /*
@ -521,10 +516,10 @@ static uint32_t preprocess_and_decode_codec_data(void *userdata, uint8_t *read_d
/* decode frame */ /* decode frame */
processed = sbc_decode( processed = sbc_decode(
&this->msbc, this->recv_buffer + 2, encoded_size - 3, &this->msbc, this->recv_buffer + 2, HFP_CODEC_PACKET_SIZE - 3,
buf, avail, &written); buf, avail, &written);
} else { } else {
processed = lc3_decode_frame(this, this->recv_buffer + 2, encoded_size - 2, processed = lc3_decode_frame(this, this->recv_buffer + 2, HFP_CODEC_PACKET_SIZE - 2,
buf, avail, &written); buf, avail, &written);
} }
@ -568,7 +563,7 @@ static int sco_source_cb(void *userdata, uint8_t *read_data, int size_read)
#endif #endif
if (this->transport->codec == HFP_AUDIO_CODEC_MSBC || if (this->transport->codec == HFP_AUDIO_CODEC_MSBC ||
this->transport->codec == HFP_AUDIO_CODEC_LC3) { this->transport->codec == HFP_AUDIO_CODEC_LC3_SWB) {
decoded = preprocess_and_decode_codec_data(userdata, read_data, size_read); decoded = preprocess_and_decode_codec_data(userdata, read_data, size_read);
} else { } else {
uint32_t avail; uint32_t avail;
@ -746,7 +741,7 @@ static int transport_start(struct impl *this)
this->h2_seq_initialized = false; this->h2_seq_initialized = false;
this->recv_buffer_pos = 0; this->recv_buffer_pos = 0;
} else if (this->transport->codec == HFP_AUDIO_CODEC_LC3) { } else if (this->transport->codec == HFP_AUDIO_CODEC_LC3_SWB) {
#ifdef HAVE_LC3 #ifdef HAVE_LC3
this->lc3 = lc3_setup_decoder(7500, 32000, 0, this->lc3 = lc3_setup_decoder(7500, 32000, 0,
calloc(1, lc3_decoder_size(7500, 32000))); calloc(1, lc3_decoder_size(7500, 32000)));
@ -1066,7 +1061,7 @@ impl_node_port_enum_params(void *object, int seq,
/* set the info structure */ /* set the info structure */
struct spa_audio_info_raw info = { 0, }; struct spa_audio_info_raw info = { 0, };
if (this->transport->codec == HFP_AUDIO_CODEC_LC3) if (this->transport->codec == HFP_AUDIO_CODEC_LC3_SWB)
info.format = SPA_AUDIO_FORMAT_S24_32_LE; info.format = SPA_AUDIO_FORMAT_S24_32_LE;
else else
info.format = SPA_AUDIO_FORMAT_S16_LE; info.format = SPA_AUDIO_FORMAT_S16_LE;
@ -1077,7 +1072,7 @@ impl_node_port_enum_params(void *object, int seq,
* MSBC format has a rate of 16kHz * MSBC format has a rate of 16kHz
* LC3-SWB format has a rate of 32kHz * LC3-SWB format has a rate of 32kHz
*/ */
if (this->transport->codec == HFP_AUDIO_CODEC_LC3) if (this->transport->codec == HFP_AUDIO_CODEC_LC3_SWB)
info.rate = 32000; info.rate = 32000;
else if (this->transport->codec == HFP_AUDIO_CODEC_MSBC) else if (this->transport->codec == HFP_AUDIO_CODEC_MSBC)
info.rate = 16000; info.rate = 16000;
@ -1214,12 +1209,12 @@ static int port_set_format(struct impl *this, struct port *port,
switch (info.info.raw.format) { switch (info.info.raw.format) {
case SPA_AUDIO_FORMAT_S16_LE: case SPA_AUDIO_FORMAT_S16_LE:
if (this->transport->codec == HFP_AUDIO_CODEC_LC3) if (this->transport->codec == HFP_AUDIO_CODEC_LC3_SWB)
return -EINVAL; return -EINVAL;
port->frame_size = info.info.raw.channels * 2; port->frame_size = info.info.raw.channels * 2;
break; break;
case SPA_AUDIO_FORMAT_S24_32_LE: case SPA_AUDIO_FORMAT_S24_32_LE:
if (this->transport->codec != HFP_AUDIO_CODEC_LC3) if (this->transport->codec != HFP_AUDIO_CODEC_LC3_SWB)
return -EINVAL; return -EINVAL;
port->frame_size = info.info.raw.channels * 4; port->frame_size = info.info.raw.channels * 4;
break; break;