Bluetooth: Audio: add bt_audio_get_chan_count

Implement a function bt_audio_get_chan_count that takes an enum
bt_audio_location and returns the number of channels in that value.

This PR fixes #69617
(https://github.com/zephyrproject-rtos/zephyr/issues/69617)

Signed-off-by: Babak Arisian <bbaa@demant.com>
This commit is contained in:
Babak Arisian 2024-05-15 15:11:11 +02:00 committed by Maureen Helm
commit b0dceffacc
7 changed files with 37 additions and 51 deletions

View file

@ -631,6 +631,15 @@ struct bt_audio_codec_cfg {
int bt_audio_data_parse(const uint8_t ltv[], size_t size,
bool (*func)(struct bt_data *data, void *user_data), void *user_data);
/**
* @brief Function to get the number of channels from the channel allocation
*
* @param chan_allocation The channel allocation
*
* @return The number of channels
*/
uint8_t bt_audio_get_chan_count(enum bt_audio_location chan_allocation);
/** @brief Audio Capability type */
enum bt_audio_dir {
BT_AUDIO_DIR_SINK = 0x01,

View file

@ -151,22 +151,6 @@ static void lc3_decoder_thread(void *arg1, void *arg2, void *arg3);
K_THREAD_DEFINE(decoder_tid, LC3_ENCODER_STACK_SIZE, lc3_decoder_thread,
NULL, NULL, NULL, LC3_ENCODER_PRIORITY, 0, -1);
static size_t get_chan_cnt(enum bt_audio_location chan_allocation)
{
size_t cnt = 0U;
if (chan_allocation == BT_AUDIO_LOCATION_MONO_AUDIO) {
return 1;
}
while (chan_allocation != 0) {
cnt += chan_allocation & 1U;
chan_allocation >>= 1;
}
return cnt;
}
/* Consumer thread of the decoded stream data */
static void lc3_decoder_thread(void *arg1, void *arg2, void *arg3)
{
@ -207,7 +191,7 @@ static void lc3_decoder_thread(void *arg1, void *arg2, void *arg3)
stream->in_buf = NULL;
k_mutex_unlock(&stream->lc3_decoder_mutex);
frames_per_block = get_chan_cnt(stream->chan_allocation);
frames_per_block = bt_audio_get_chan_count(stream->chan_allocation);
if (buf->len !=
(frames_per_block * octets_per_frame * frames_blocks_per_sdu)) {
printk("Expected %u frame blocks with %u frames of size %u, but "
@ -386,7 +370,7 @@ static int lc3_enable(struct broadcast_sink_stream *sink_stream)
/* An SDU can consist of X frame blocks, each with Y frames (one per channel) of size Z in
* them. The minimum SDU size required for this is X * Y * Z.
*/
chan_alloc_bit_cnt = get_chan_cnt(sink_stream->chan_allocation);
chan_alloc_bit_cnt = bt_audio_get_chan_count(sink_stream->chan_allocation);
sdu_size_required = chan_alloc_bit_cnt * sink_stream->lc3_octets_per_frame *
sink_stream->lc3_frames_blocks_per_sdu;
if (sdu_size_required < sink_stream->stream.qos->sdu) {
@ -771,7 +755,7 @@ static bool find_valid_bis_in_subgroup_cb(const struct bt_bap_base_subgroup *sub
} else {
/* If the subgroup contains a single channel, then we just grab the first BIS index
*/
if (get_chan_cnt(chan_allocation) == 1 &&
if (bt_audio_get_chan_count(chan_allocation) == 1 &&
chan_allocation == CONFIG_TARGET_BROADCAST_CHANNEL) {
uint32_t subgroup_bis_indexes;

View file

@ -67,6 +67,26 @@ int bt_audio_data_parse(const uint8_t ltv[], size_t size,
return 0;
}
uint8_t bt_audio_get_chan_count(enum bt_audio_location chan_allocation)
{
if (chan_allocation == BT_AUDIO_LOCATION_MONO_AUDIO) {
return 1;
}
#ifdef POPCOUNT
return POPCOUNT(chan_allocation);
#else
uint8_t cnt = 0U;
while (chan_allocation != 0U) {
cnt += chan_allocation & 1U;
chan_allocation >>= 1U;
}
return cnt;
#endif
}
#if defined(CONFIG_BT_CONN)
static uint8_t bt_audio_security_check(const struct bt_conn *conn)

View file

@ -220,22 +220,6 @@ int cap_ac_unicast(const struct shell *sh, const struct bap_unicast_ac_param *pa
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT */
#endif /* CONFIG_BT_BAP_UNICAST */
static inline uint8_t get_chan_cnt(enum bt_audio_location chan_allocation)
{
uint8_t cnt = 0U;
if (chan_allocation == BT_AUDIO_LOCATION_MONO_AUDIO) {
return 1;
}
while (chan_allocation != 0) {
cnt += chan_allocation & 1U;
chan_allocation >>= 1;
}
return cnt;
}
static inline void print_qos(const struct shell *sh, const struct bt_audio_codec_qos *qos)
{
#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_UNICAST)

View file

@ -2855,7 +2855,8 @@ static void stream_started_cb(struct bt_bap_stream *bap_stream)
ret = bt_audio_codec_cfg_get_chan_allocation(codec_cfg,
&sh_stream->lc3_chan_allocation);
if (ret == 0) {
sh_stream->lc3_chan_cnt = get_chan_cnt(sh_stream->lc3_chan_allocation);
sh_stream->lc3_chan_cnt =
bt_audio_get_chan_count(sh_stream->lc3_chan_allocation);
} else {
shell_error(ctx_shell, "Could not get channel allocation: %d", ret);
sh_stream->lc3_chan_allocation = BT_AUDIO_LOCATION_MONO_AUDIO;

View file

@ -214,7 +214,7 @@ int bap_usb_add_frame_to_usb(enum bt_audio_location chan_allocation, const int16
return -EINVAL;
}
if (get_chan_cnt(chan_allocation) != 1) {
if (bt_audio_get_chan_count(chan_allocation) != 1) {
LOG_DBG("Invalid channel allocation %d", chan_allocation);
return -EINVAL;

View file

@ -66,18 +66,6 @@ static K_SEM_DEFINE(sem_stopped, 0U, ARRAY_SIZE(streams));
static const uint32_t bis_index_mask = BIT_MASK(ARRAY_SIZE(streams) + 1U);
static uint32_t bis_index_bitfield;
static uint8_t count_bits(enum bt_audio_location chan_allocation)
{
uint8_t cnt = 0U;
while (chan_allocation != 0) {
cnt += chan_allocation & 1U;
chan_allocation >>= 1;
}
return cnt;
}
static bool valid_base_subgroup(const struct bt_bap_base_subgroup *subgroup)
{
struct bt_audio_codec_cfg codec_cfg = {0};
@ -128,7 +116,7 @@ static bool valid_base_subgroup(const struct bt_bap_base_subgroup *subgroup)
ret = bt_audio_codec_cfg_get_chan_allocation(&codec_cfg, &chan_allocation);
if (ret == 0) {
chan_cnt = count_bits(chan_allocation);
chan_cnt = bt_audio_get_chan_count(chan_allocation);
} else {
printk("Could not get subgroup channel allocation: %d\n", ret);
/* Channel allocation is an optional field, and omitting it implicitly means mono */
@ -444,7 +432,7 @@ static void validate_stream_codec_cfg(const struct bt_bap_stream *stream)
return;
}
chan_cnt = count_bits(chan_allocation);
chan_cnt = bt_audio_get_chan_count(chan_allocation);
} else {
FAIL("Could not get subgroup channel allocation: %d\n", ret);