Bluetooth: Audio: Refactor codec_cfg_get_frame_duration_us

Refactor the codec_cfg_get_frame_duration function to return the
assigned numbers value, instead of a converted value, but with
support for converting the value.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2023-09-27 11:27:01 +02:00 committed by Carles Cufí
parent 0bb77191c0
commit 9c47eb924f
10 changed files with 185 additions and 40 deletions

View file

@ -635,16 +635,49 @@ int bt_audio_codec_cfg_get_freq(const struct bt_audio_codec_cfg *codec_cfg);
int bt_audio_codec_cfg_set_freq(struct bt_audio_codec_cfg *codec_cfg,
enum bt_audio_codec_config_freq freq);
/**
* @brief Convert assigned numbers frame duration to duration in microseconds.
*
* @param frame_dur The assigned numbers frame duration to convert.
*
* @retval -EINVAL if arguments are invalid.
* @retval The converted frame duration value in microseconds.
*/
int bt_audio_codec_cfg_frame_dur_to_frame_dur_us(enum bt_audio_codec_config_frame_dur frame_dur);
/**
* @brief Convert frame duration in microseconds to assigned numbers frame duration.
*
* @param frame_dur_us The frame duration in microseconds to convert.
*
* @retval -EINVAL if arguments are invalid.
* @retval The assigned numbers frame duration (@ref bt_audio_codec_config_frame_dur).
*/
int bt_audio_codec_cfg_frame_dur_us_to_frame_dur(uint32_t frame_dur_us);
/** @brief Extract frame duration from BT codec config
*
* @param codec_cfg The codec configuration to extract data from.
*
* @retval Frame duration in microseconds
* @retval A @ref bt_audio_codec_config_frame_dur value
* @retval -EINVAL if arguments are invalid
* @retval -ENODATA if not found
* @retval -EBADMSG if found value has invalid size or value
*/
int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *codec_cfg);
int bt_audio_codec_cfg_get_frame_dur(const struct bt_audio_codec_cfg *codec_cfg);
/**
* @brief Set the frame duration of a codec configuration.
*
* @param codec_cfg The codec configuration to set data for.
* @param frame_dur The assigned numbers frame duration to set.
*
* @retval The data_len of @p codec_cfg on success
* @retval -EINVAL if arguments are invalid
* @retval -ENOMEM if the new value could not set or added due to memory
*/
int bt_audio_codec_cfg_set_frame_dur(struct bt_audio_codec_cfg *codec_cfg,
enum bt_audio_codec_config_frame_dur frame_dur);
/** @brief Extract channel allocation from BT codec config
*

View file

@ -243,14 +243,16 @@ enum bt_audio_codec_config_freq {
BT_AUDIO_CODEC_CONFIG_LC3_FREQ_384KHZ = 0x0d,
};
/**
* @brief LC3 7.5 msec Frame Duration configuration
*/
#define BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5 0x00
/**
* @brief LC3 10 msec Frame Duration configuration
*/
#define BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10 0x01
enum bt_audio_codec_config_frame_dur {
/**
* @brief LC3 7.5 msec Frame Duration configuration
*/
BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5 = 0x00,
/**
* @brief LC3 10 msec Frame Duration configuration
*/
BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10 = 0x01,
};
/**
* @brief Helper to declare LC3 codec capability

View file

@ -87,8 +87,12 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg)
printk(" Frequency: %d Hz\n", bt_audio_codec_cfg_freq_to_freq_hz(ret));
}
printk(" Frame Duration: %d us\n",
bt_audio_codec_cfg_get_frame_duration_us(codec_cfg));
ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg);
if (ret > 0) {
printk(" Frame Duration: %d us\n",
bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret));
}
if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) {
printk(" Channel allocation: 0x%x\n", chan_allocation);
}

View file

@ -76,8 +76,12 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg)
printk(" Frequency: %d Hz\n", bt_audio_codec_cfg_freq_to_freq_hz(ret));
}
printk(" Frame Duration: %d us\n",
bt_audio_codec_cfg_get_frame_duration_us(codec_cfg));
ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg);
if (ret > 0) {
printk(" Frame Duration: %d us\n",
bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret));
}
if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) {
printk(" Channel allocation: 0x%x\n", chan_allocation);
}

View file

@ -234,7 +234,11 @@ static int init_lc3(void)
return ret;
}
frame_duration_us = bt_audio_codec_cfg_get_frame_duration_us(codec_cfg);
ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg);
if (ret > 0) {
frame_duration_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret);
}
octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg);
frames_per_sdu = bt_audio_codec_cfg_get_frame_blocks_per_sdu(codec_cfg, true);
octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg);

View file

@ -147,8 +147,12 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg)
printk(" Frequency: %d Hz\n", bt_audio_codec_cfg_freq_to_freq_hz(ret));
}
printk(" Frame Duration: %d us\n",
bt_audio_codec_cfg_get_frame_duration_us(codec_cfg));
ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg);
if (ret > 0) {
printk(" Frame Duration: %d us\n",
bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret));
}
if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) {
printk(" Channel allocation: 0x%x\n", chan_allocation);
}
@ -354,8 +358,7 @@ static int lc3_enable(struct bt_bap_stream *stream, const uint8_t meta[], size_t
#if defined(CONFIG_LIBLC3)
{
const int frame_duration_us =
bt_audio_codec_cfg_get_frame_duration_us(stream->codec_cfg);
int frame_duration_us;
int freq;
int ret;
@ -369,11 +372,14 @@ static int lc3_enable(struct bt_bap_stream *stream, const uint8_t meta[], size_t
return ret;
}
if (frame_duration_us < 0) {
ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg);
if (ret > 0) {
frame_duration_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret);
} else {
printk("Error: Frame duration not set, cannot start codec.");
*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_CONF_INVALID,
BT_BAP_ASCS_REASON_CODEC_DATA);
return -1;
return ret;
}
frames_per_sdu =

View file

@ -88,6 +88,30 @@ int bt_audio_codec_cfg_freq_hz_to_freq(uint32_t freq_hz)
}
}
int bt_audio_codec_cfg_frame_dur_to_frame_dur_us(enum bt_audio_codec_config_frame_dur frame_dur)
{
switch (frame_dur) {
case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5:
return 7500;
case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10:
return 10000;
default:
return -EINVAL;
}
}
int bt_audio_codec_cfg_frame_dur_us_to_frame_dur(uint32_t frame_dur_us)
{
switch (frame_dur_us) {
case 7500U:
return BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5;
case 10000U:
return BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10;
default:
return -EINVAL;
}
}
struct search_type_param {
bool found;
uint8_t type;
@ -309,8 +333,9 @@ int bt_audio_codec_cfg_set_freq(struct bt_audio_codec_cfg *codec_cfg,
sizeof(freq_u8));
}
int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *codec_cfg)
int bt_audio_codec_cfg_get_frame_dur(const struct bt_audio_codec_cfg *codec_cfg)
{
enum bt_audio_codec_config_frame_dur frame_dur;
const uint8_t *data;
uint8_t data_len;
@ -328,14 +353,29 @@ int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *co
return -EBADMSG;
}
switch (data[0]) {
case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5:
return 7500;
case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10:
return 10000;
default:
frame_dur = data[0];
if (bt_audio_codec_cfg_frame_dur_to_frame_dur_us(frame_dur) < 0) {
LOG_DBG("Invalid frame_dur value: 0x%02X", frame_dur);
return -EBADMSG;
}
return frame_dur;
}
int bt_audio_codec_cfg_set_frame_dur(struct bt_audio_codec_cfg *codec_cfg,
enum bt_audio_codec_config_frame_dur frame_dur)
{
uint8_t frame_dur_u8;
if (bt_audio_codec_cfg_frame_dur_to_frame_dur_us(frame_dur) < 0) {
LOG_DBG("Invalid freq value: %d", frame_dur);
return -EINVAL;
}
frame_dur_u8 = (uint8_t)frame_dur;
return bt_audio_codec_cfg_set_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_DURATION,
&frame_dur_u8, sizeof(frame_dur_u8));
}
int bt_audio_codec_cfg_get_chan_allocation(const struct bt_audio_codec_cfg *codec_cfg,

View file

@ -245,7 +245,13 @@ static int init_lc3(const struct bt_bap_stream *stream)
return ret;
}
lc3_frame_duration_us = bt_audio_codec_cfg_get_frame_duration_us(stream->codec_cfg);
ret = bt_audio_codec_cfg_get_frame_dur(stream->codec_cfg);
if (ret > 0) {
lc3_frame_duration_us = bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret);
} else {
return ret;
}
lc3_octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(stream->codec_cfg);
lc3_frames_per_sdu = bt_audio_codec_cfg_get_frame_blocks_per_sdu(stream->codec_cfg, true);
lc3_octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(stream->codec_cfg);
@ -2637,8 +2643,12 @@ static bool stream_start_sine_verify(const struct bt_bap_stream *bap_stream)
return false;
}
stream_frame_duration_us = bt_audio_codec_cfg_get_frame_duration_us(bap_stream->codec_cfg);
if (stream_frame_duration_us != lc3_frame_duration_us) {
err = bt_audio_codec_cfg_get_frame_dur(bap_stream->codec_cfg);
if (err > 0) {
if (bt_audio_codec_cfg_frame_dur_to_frame_dur_us(err) != lc3_frame_duration_us) {
return false;
}
} else {
return false;
}

View file

@ -73,15 +73,54 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_set_freq)
zassert_equal(ret, 0x06, "Unexpected return value %d", ret);
}
ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_frame_duration_us)
ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_frame_dur_to_frame_dur_us)
{
const struct frame_dur_test_input {
enum bt_audio_codec_config_frame_dur frame_dur;
uint32_t frame_dur_us;
} frame_dur_test_inputs[] = {
{.frame_dur = BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5, .frame_dur_us = 7500U},
{.frame_dur = BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10, .frame_dur_us = 10000U},
};
for (size_t i = 0U; i < ARRAY_SIZE(frame_dur_test_inputs); i++) {
const struct frame_dur_test_input *fdti = &frame_dur_test_inputs[i];
zassert_equal(bt_audio_codec_cfg_frame_dur_to_frame_dur_us(fdti->frame_dur),
fdti->frame_dur_us, "frame_dur %d was not coverted to %u",
fdti->frame_dur, fdti->frame_dur_us);
zassert_equal(bt_audio_codec_cfg_frame_dur_us_to_frame_dur(fdti->frame_dur_us),
fdti->frame_dur, "frame_dur_us %u was not coverted to %d",
fdti->frame_dur_us, fdti->frame_dur);
}
}
ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_frame_dur)
{
const struct bt_bap_lc3_preset preset =
BT_BAP_LC3_UNICAST_PRESET_48_2_2(BT_AUDIO_LOCATION_FRONT_LEFT,
BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED);
int ret;
ret = bt_audio_codec_cfg_get_frame_duration_us(&preset.codec_cfg);
zassert_equal(ret, 10000u, "unexpected return value %d", ret);
ret = bt_audio_codec_cfg_get_frame_dur(&preset.codec_cfg);
zassert_equal(ret, 0x01, "unexpected return value %d", ret);
}
ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_set_frame_dur)
{
struct bt_bap_lc3_preset preset = BT_BAP_LC3_UNICAST_PRESET_16_2_1(
BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED);
int ret;
ret = bt_audio_codec_cfg_get_frame_dur(&preset.codec_cfg);
zassert_equal(ret, 0x01, "Unexpected return value %d", ret);
ret = bt_audio_codec_cfg_set_frame_dur(&preset.codec_cfg,
BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5);
zassert_true(ret > 0, "Unexpected return value %d", ret);
ret = bt_audio_codec_cfg_get_frame_dur(&preset.codec_cfg);
zassert_equal(ret, 0x00, "Unexpected return value %d", ret);
}
ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_chan_allocation)

View file

@ -148,8 +148,12 @@ static void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg)
LOG_DBG(" Frequency: %d Hz", bt_audio_codec_cfg_freq_to_freq_hz(ret));
}
LOG_DBG(" Frame Duration: %d us",
bt_audio_codec_cfg_get_frame_duration_us(codec_cfg));
ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg);
if (ret > 0) {
LOG_DBG(" Frame Duration: %d us",
bt_audio_codec_cfg_frame_dur_to_frame_dur_us(ret));
}
if (bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation) == 0) {
LOG_DBG(" Channel allocation: 0x%x", chan_allocation);
}
@ -260,14 +264,12 @@ static void btp_send_ascs_ase_state_changed_ev(struct bt_conn *conn, uint8_t ase
static int validate_codec_parameters(const struct bt_audio_codec_cfg *codec_cfg)
{
int frame_duration_us;
int frames_per_sdu;
int octets_per_frame;
int chan_allocation_err;
enum bt_audio_location chan_allocation;
int ret;
frame_duration_us = bt_audio_codec_cfg_get_frame_duration_us(codec_cfg);
chan_allocation_err =
bt_audio_codec_cfg_get_chan_allocation(codec_cfg, &chan_allocation);
octets_per_frame = bt_audio_codec_cfg_get_octets_per_frame(codec_cfg);
@ -279,8 +281,9 @@ static int validate_codec_parameters(const struct bt_audio_codec_cfg *codec_cfg)
return -EINVAL;
}
if (frame_duration_us < 0) {
LOG_DBG("Error: Invalid frame duration.");
ret = bt_audio_codec_cfg_get_frame_dur(codec_cfg);
if (ret < 0) {
LOG_DBG("Error: Invalid frame duration: %d", ret);
return -EINVAL;
}