Skip to content

Commit

Permalink
Bluetooth samples: Add USB Audio to Broadcast Sink sample
Browse files Browse the repository at this point in the history
wip

Signed-off-by: Fredrik Danebjer <[email protected]>
  • Loading branch information
fredrikdanebjer committed Jan 24, 2024
1 parent 954f2c1 commit 3f8c0bc
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 50 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
# The LC3 codec uses a large amount of stack. This app runs the codec in the work-queue, hence
# inctease stack size for that thread.
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
# Enable encryption.
CONFIG_BT_TINYCRYPT_ECC=y
# LC3 Needs these
CONFIG_BT_ISO_RX_BUF_COUNT=20
CONFIG_BT_ISO_SYNC_RECEIVER=y
CONFIG_BT_ISO_MAX_CHAN=5
CONFIG_BT_ISO_RX_MTU=60
#Enable USB
CONFIG_USE_USB_AUDIO_OUTPUT=y
CONFIG_USB_DEVICE_PRODUCT="USB Broadcast Sink"
# Enabling the USB causes the HCI to sometimes overflow
CONFIG_BT_HCI_TX_STACK_SIZE_WITH_PROMPT=y
CONFIG_BT_HCI_TX_STACK_SIZE=2048
6 changes: 0 additions & 6 deletions samples/bluetooth/broadcast_audio_sink/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,4 @@ CONFIG_BT_BUF_ACL_TX_SIZE=251

CONFIG_BT_DEVICE_NAME="Broadcast Audio Sink"

# LC3 Needs these
CONFIG_BT_ISO_RX_BUF_COUNT=20
CONFIG_BT_ISO_SYNC_RECEIVER=y
CONFIG_BT_ISO_MAX_CHAN=5
CONFIG_BT_ISO_RX_MTU=60

CONFIG_BT_TINYCRYPT_ECC=y
53 changes: 19 additions & 34 deletions samples/bluetooth/broadcast_audio_sink/src/main.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2022-2023 Nordic Semiconductor ASA
* Copyright (c) 2024 Demant A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -19,7 +20,6 @@
#include <zephyr/usb/usb_device.h>
#include <zephyr/usb/class/usb_audio.h>
#include <zephyr/sys/ring_buffer.h>
#include "nrfx_clock.h"
#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */


Expand All @@ -40,8 +40,6 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_SCAN_SELF) || IS_ENABLED(CONFIG_SCAN_OFFLOAD),
#define PA_SYNC_SKIP 5
#define NAME_LEN sizeof(CONFIG_TARGET_BROADCAST_NAME) + 1



#if defined(CONFIG_LIBLC3)
#define MAX_SAMPLE_RATE 48000U
#define MAX_FRAME_DURATION_US 10000U
Expand All @@ -56,14 +54,14 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_SCAN_SELF) || IS_ENABLED(CONFIG_SCAN_OFFLOAD),
#define USB_SAMPLE_RATE 48000U
#define USB_FRAME_DURATION_US 1000U
#define USB_TX_BUF_NUM 10U
#define BROADCAST_MONO_SAMPLE_SIZE (MAX_NUM_SAMPLES_MONO * sizeof(int16_t))
#define BROADCAST_STEREO_SAMPLE_SIZE (BROADCAST_MONO_SAMPLE_SIZE * sizeof(int16_t))
#define USB_STEREO_SAMPLE_SIZE ((USB_FRAME_DURATION_US * USB_SAMPLE_RATE * sizeof(int16_t) \
* 2) / USEC_PER_SEC)
#define BROADCAST_DATA_ELEMENT_SIZE sizeof(int16_t)
#define BROADCAST_MONO_SAMPLE_SIZE (MAX_NUM_SAMPLES_MONO * BROADCAST_DATA_ELEMENT_SIZE)
#define BROADCAST_STEREO_SAMPLE_SIZE (BROADCAST_MONO_SAMPLE_SIZE * BROADCAST_DATA_ELEMENT_SIZE)
#define USB_STEREO_SAMPLE_SIZE ((USB_FRAME_DURATION_US * USB_SAMPLE_RATE * \
BROADCAST_DATA_ELEMENT_SIZE * 2) / USEC_PER_SEC)
#define AUDIO_RING_BUF_SIZE 10000U
#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */


static K_SEM_DEFINE(sem_connected, 0U, 1U);
static K_SEM_DEFINE(sem_disconnected, 0U, 1U);
static K_SEM_DEFINE(sem_broadcaster_found, 0U, 1U);
Expand Down Expand Up @@ -125,11 +123,14 @@ static uint8_t sink_broadcast_code[BT_AUDIO_BROADCAST_CODE_SIZE];
uint64_t total_rx_iso_packet_count; /* This value is exposed to test code */

#if defined(CONFIG_USB_DEVICE_AUDIO)
int16_t usb_audio_data[MAX_NUM_SAMPLES_MONO] = {0};
int16_t usb_audio_data_stereo[MAX_NUM_SAMPLES_STEREO] = {0};

RING_BUF_DECLARE(ring_buf_usb, AUDIO_RING_BUF_SIZE);
NET_BUF_POOL_DEFINE(usb_tx_buf_pool, USB_TX_BUF_NUM, BROADCAST_STEREO_SAMPLE_SIZE, 0,
net_buf_destroy);

void mix_mono_to_stereo(void);
static void mix_mono_to_stereo(void);
#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */

#if defined(CONFIG_LIBLC3)
Expand Down Expand Up @@ -184,7 +185,7 @@ static void do_lc3_decode(struct broadcast_sink_stream *sink_stream)

for (int i = 0; i < frames_per_sdu; i++) {
err = lc3_decode(sink_stream->lc3_decoder, buf_data + offset, octets_per_frame,
LC3_PCM_FORMAT_S16, audio_buf, 1);
LC3_PCM_FORMAT_S16, audio_buf, 1);

if (err == 1) {
printk(" decoder performed PLC\n");
Expand All @@ -198,12 +199,14 @@ static void do_lc3_decode(struct broadcast_sink_stream *sink_stream)
net_buf_unref(ptr_net_buf);

#if defined(CONFIG_USB_DEVICE_AUDIO)
uint32_t rbret;

if (ring_buf_space_get(&sink_stream->audio_ring_buf) == 0) {
ring_buf_reset(&sink_stream->audio_ring_buf);
}

/* Put in ring-buffer to be consumed */
uint32_t rbret = ring_buf_put(&sink_stream->audio_ring_buf, (uint8_t *)audio_buf,
rbret = ring_buf_put(&sink_stream->audio_ring_buf, (uint8_t *)audio_buf,
BROADCAST_MONO_SAMPLE_SIZE);
if (rbret != BROADCAST_MONO_SAMPLE_SIZE) {
static int rb_add_failures;
Expand Down Expand Up @@ -241,7 +244,8 @@ static int lc3_enable(struct broadcast_sink_stream *sink_stream)
return ret;
}

frames_per_sdu = bt_audio_codec_cfg_get_frame_blocks_per_sdu(sink_stream->stream.codec_cfg, true);
frames_per_sdu = bt_audio_codec_cfg_get_frame_blocks_per_sdu(sink_stream->stream.codec_cfg,
true);

#if defined(CONFIG_USB_DEVICE_AUDIO)
sink_stream->lc3_decoder = lc3_setup_decoder(frame_duration_us, freq_hz, USB_SAMPLE_RATE,
Expand All @@ -264,16 +268,14 @@ static int lc3_enable(struct broadcast_sink_stream *sink_stream)

#if defined(CONFIG_USB_DEVICE_AUDIO)
/* Duplicate the audio from one channel and put it in both channels */
void mix_mono_to_stereo(void)
static void mix_mono_to_stereo(void)
{
int16_t usb_audio_data[MAX_NUM_SAMPLES_MONO] = {0};
int16_t usb_audio_data_stereo[MAX_NUM_SAMPLES_STEREO] = {0};
uint32_t size;

size = ring_buf_get(&streams[0].audio_ring_buf, (uint8_t *)usb_audio_data,
MAX_NUM_SAMPLES_STEREO);
if (size != MAX_NUM_SAMPLES_STEREO) {
memset(&((uint8_t *)usb_audio_data)[size], 0, MAX_NUM_SAMPLES_STEREO - size);
memset(&((uint8_t *)usb_audio_data)[size], 0, sizeof(usb_audio_data) - size);
}

/* Interleave the channel sample */
Expand All @@ -299,14 +301,11 @@ void mix_mono_to_stereo(void)
static void data_request(const struct device *dev)
{
static struct net_buf *pcm_buf;
size_t in_frame_size;
int err;
uint32_t size;
void *out;
int16_t usb_audio_data[USB_STEREO_SAMPLE_SIZE] = {0};

in_frame_size = usb_audio_get_in_frame_size(dev);

size = ring_buf_get(&ring_buf_usb, (uint8_t *)usb_audio_data, USB_STEREO_SAMPLE_SIZE);
if (size != USB_STEREO_SAMPLE_SIZE) {
memset(&((uint8_t *)usb_audio_data)[size], 0, USB_STEREO_SAMPLE_SIZE);
Expand Down Expand Up @@ -854,7 +853,7 @@ static int init(void)
int ret;
const struct device *hs_dev = DEVICE_DT_GET(DT_NODELABEL(hs_0));

for (size_t i = 0U; i < CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT; i++) {
for (int i = 0U; i < CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT; i++) {
ring_buf_init(&streams[i].audio_ring_buf, AUDIO_RING_BUF_SIZE,
streams[i]._ring_buffer);
}
Expand Down Expand Up @@ -1038,20 +1037,6 @@ int main(void)
{
int err;

#if defined(CONFIG_USB_DEVICE_AUDIO)
/* Use this to turn on 128 MHz clock for cpu_app, this improves the */
err = nrfx_clock_divider_set(NRF_CLOCK_DOMAIN_HFCLK, NRF_CLOCK_HFCLK_DIV_1);

err -= NRFX_ERROR_BASE_NUM;
if (err) {
return err;
}

nrfx_clock_hfclk_start();
while (!nrfx_clock_hfclk_is_running()) {
}
#endif /* defined(CONFIG_USB_DEVICE_AUDIO) */

err = init();
if (err) {
printk("Init failed (err %d)\n", err);
Expand Down

0 comments on commit 3f8c0bc

Please sign in to comment.