diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 42742798900..a7d248026a1 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -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, diff --git a/samples/bluetooth/broadcast_audio_sink/src/main.c b/samples/bluetooth/broadcast_audio_sink/src/main.c index 38f9f546078..b08c4f96c9a 100644 --- a/samples/bluetooth/broadcast_audio_sink/src/main.c +++ b/samples/bluetooth/broadcast_audio_sink/src/main.c @@ -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; diff --git a/subsys/bluetooth/audio/audio.c b/subsys/bluetooth/audio/audio.c index 164a52afa5e..619f52c7abc 100644 --- a/subsys/bluetooth/audio/audio.c +++ b/subsys/bluetooth/audio/audio.c @@ -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) diff --git a/subsys/bluetooth/audio/shell/audio.h b/subsys/bluetooth/audio/shell/audio.h index 8d537557dae..1a73258d2e8 100644 --- a/subsys/bluetooth/audio/shell/audio.h +++ b/subsys/bluetooth/audio/shell/audio.h @@ -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) diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index 4ffa9539940..b045ecbcda4 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -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; diff --git a/subsys/bluetooth/audio/shell/bap_usb.c b/subsys/bluetooth/audio/shell/bap_usb.c index 30afd5ae093..cd597c65de1 100644 --- a/subsys/bluetooth/audio/shell/bap_usb.c +++ b/subsys/bluetooth/audio/shell/bap_usb.c @@ -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; diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c index cabd365ab5d..04fe1ce07a6 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c @@ -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);