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>
diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h
index 4274279..a7d2480 100644
--- a/include/zephyr/bluetooth/audio/audio.h
+++ b/include/zephyr/bluetooth/audio/audio.h
@@ -631,6 +631,15 @@
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 38f9f54..b08c4f9 100644
--- a/samples/bluetooth/broadcast_audio_sink/src/main.c
+++ b/samples/bluetooth/broadcast_audio_sink/src/main.c
@@ -151,22 +151,6 @@
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 @@
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 @@
/* 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 @@
} 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 164a52a..619f52c 100644
--- a/subsys/bluetooth/audio/audio.c
+++ b/subsys/bluetooth/audio/audio.c
@@ -67,6 +67,26 @@
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 8d53755..1a73258 100644
--- a/subsys/bluetooth/audio/shell/audio.h
+++ b/subsys/bluetooth/audio/shell/audio.h
@@ -220,22 +220,6 @@
#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 4ffa953..b045ecb 100644
--- a/subsys/bluetooth/audio/shell/bap.c
+++ b/subsys/bluetooth/audio/shell/bap.c
@@ -2855,7 +2855,8 @@
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 30afd5a..cd597c6 100644
--- a/subsys/bluetooth/audio/shell/bap_usb.c
+++ b/subsys/bluetooth/audio/shell/bap_usb.c
@@ -214,7 +214,7 @@
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 cabd365..04fe1ce 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 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 @@
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 @@
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);