Skip to content

Commit

Permalink
samples: Bluetooth: BAP: Broadcast sink use new USB stack
Browse files Browse the repository at this point in the history
Refactor the USB of the BAP broadcast sink to use the new
USB stack.

Signed-off-by: Emil Gydesen <[email protected]>
  • Loading branch information
Thalley committed Jan 30, 2025
1 parent 604bc35 commit 98a937c
Show file tree
Hide file tree
Showing 17 changed files with 196 additions and 122 deletions.
10 changes: 6 additions & 4 deletions samples/bluetooth/bap_broadcast_sink/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(bap_unicast_server)
project(bap_unicast_sink)

target_sources(app PRIVATE
src/main.c
src/stream_rx.c
)

zephyr_sources_ifdef(CONFIG_LIBLC3 src/lc3.c)
zephyr_sources_ifdef(CONFIG_USB_DEVICE_AUDIO src/usb.c)
target_sources_ifdef(CONFIG_ENABLE_LC3 app PRIVATE src/lc3.c)

zephyr_library_include_directories(${ZEPHYR_BASE}/samples/bluetooth)
if (CONFIG_USE_USB_AUDIO_OUTPUT)
include(${ZEPHYR_BASE}/samples/subsys/usb/common/common.cmake)
target_sources(app PRIVATE src/usb.c)
endif()
9 changes: 7 additions & 2 deletions samples/bluetooth/bap_broadcast_sink/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ config ENABLE_LC3
config USE_USB_AUDIO_OUTPUT
bool "Use USB Audio as output"
depends on ENABLE_LC3
select USB_DEVICE_STACK
select USB_DEVICE_AUDIO
select USB_DEVICE_STACK_NEXT
select USBD_AUDIO2_CLASS
select RING_BUFFER
help
Enables USB audio as output as a USB peripheral. This does not support providing USB
Expand Down Expand Up @@ -87,4 +87,9 @@ config INFO_REPORTING_INTERVAL
Determines how often information about received data is logged.
Set to 0 to disable reporting.

# Source common USB sample options used to initialize new experimental USB device stack.
# The scope of these options is limited to USB samples in project tree,
# you cannot use them in your own application.
source "samples/subsys/usb/common/Kconfig.sample_usbd"

source "Kconfig.zephyr"
53 changes: 53 additions & 0 deletions samples/bluetooth/bap_broadcast_sink/app.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <dt-bindings/usb/audio.h>

/ {
uac2_microphone: usb_audio2 {
compatible = "zephyr,uac2";
status = "okay";
full-speed;
audio-function = <AUDIO_FUNCTION_MICROPHONE>;

/* Clock supporting 48KHz
*
* Since the incoming audio may be between 8 and 48 KHz, we always upsample to 48KHz
*/
uac_aclk: aclk {
compatible = "zephyr,uac2-clock-source";
clock-type = "internal-programmable";
frequency-control = "read-only";
sampling-frequencies = <48000>;
};

/* The out_terminal supports the incoming Bluetooth LE Audio over ISO
* and treats it as a microphone towards the USB host
*/
out_terminal: out_terminal {
compatible = "zephyr,uac2-input-terminal";
clock-source = <&uac_aclk>;
terminal-type = <INPUT_TERMINAL_MICROPHONE>;
front-left;
front-right;
};

/* USB Audio terminal from USB device to USB host */
in_terminal: in_terminal {
compatible = "zephyr,uac2-output-terminal";
data-source = <&out_terminal>;
clock-source = <&uac_aclk>;
terminal-type = <USB_TERMINAL_STREAMING>;
};

as_iso_in: in_interface {
compatible = "zephyr,uac2-audio-streaming";
linked-terminal = <&in_terminal>;
subslot-size = <2>;
bit-resolution = <16>;
};
};
};
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Use USB Audio as audio sink
CONFIG_USE_USB_AUDIO_OUTPUT=y
CONFIG_USB_DEVICE_PRODUCT="USB Broadcast Sink"
CONFIG_SAMPLE_USBD_PRODUCT="USB Broadcast Sink sample"
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
zephyr_udc0: &usbd {
compatible = "nordic,nrf-usbd";
status = "okay";
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

hs_0: hs_0 {
compatible = "usb-audio-hs";
mic-feature-mute;
mic-channel-l;
mic-channel-r;

hp-feature-mute;
hp-channel-l;
hp-channel-r;
};
};
#include "../app.overlay"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Use USB Audio as audio sink
CONFIG_USE_USB_AUDIO_OUTPUT=y
CONFIG_SAMPLE_USBD_PRODUCT="USB Broadcast Sink sample"
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "../app.overlay"
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Use USB Audio as audio sink
CONFIG_USE_USB_AUDIO_OUTPUT=y
CONFIG_USB_DEVICE_PRODUCT="USB Broadcast Sink"
CONFIG_SAMPLE_USBD_PRODUCT="USB Broadcast Sink sample"

CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM=n
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
zephyr_udc0: &usbd {
compatible = "nordic,nrf-usbd";
status = "okay";
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

hs_0: hs_0 {
compatible = "usb-audio-hs";
mic-feature-mute;
mic-channel-l;
mic-channel-r;

hp-feature-mute;
hp-channel-l;
hp-channel-r;
};
};
#include "../app.overlay"
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Use USB Audio as audio sink
CONFIG_USE_USB_AUDIO_OUTPUT=y
CONFIG_USB_DEVICE_PRODUCT="USB Broadcast Sink"
CONFIG_SAMPLE_USBD_PRODUCT="USB Broadcast Sink sample"
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "../app.overlay"
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Use USB Audio as audio sink
CONFIG_USE_USB_AUDIO_OUTPUT=y
CONFIG_USB_DEVICE_PRODUCT="USB Broadcast Sink"
CONFIG_SAMPLE_USBD_PRODUCT="USB Broadcast Sink sample"
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
zephyr_udc0: &usbd {
compatible = "nordic,nrf-usbd";
status = "okay";
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

hs_0: hs_0 {
compatible = "usb-audio-hs";
mic-feature-mute;
mic-channel-l;
mic-channel-r;

hp-feature-mute;
hp-channel-l;
hp-channel-r;
};
};
#include "../app.overlay"
24 changes: 8 additions & 16 deletions samples/bluetooth/bap_broadcast_sink/src/lc3.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ static K_FIFO_DEFINE(lc3_in_fifo);
*/
static struct stream_rx *usb_left_stream;
static struct stream_rx *usb_right_stream;
static size_t rx_streaming_cnt;

static int init_lc3_decoder(struct stream_rx *stream, uint32_t lc3_frame_duration_us,
uint32_t lc3_freq_hz)
Expand All @@ -92,15 +91,14 @@ static int init_lc3_decoder(struct stream_rx *stream, uint32_t lc3_frame_duratio
/* Create the decoder instance. This shall complete before stream_started() is called. */
stream->lc3_decoder =
lc3_setup_decoder(lc3_frame_duration_us, lc3_freq_hz,
IS_ENABLED(CONFIG_USB_DEVICE_AUDIO) ? USB_SAMPLE_RATE_HZ : 0,
IS_ENABLED(CONFIG_USE_USB_AUDIO_OUTPUT) ? USB_SAMPLE_RATE_HZ : 0,
&stream->lc3_decoder_mem);
if (stream->lc3_decoder == NULL) {
LOG_ERR("Failed to setup LC3 decoder - wrong parameters?\n");
return -EINVAL;
}

LOG_INF("Initialized LC3 decoder for %p", stream);
rx_streaming_cnt++;

return 0;
}
Expand Down Expand Up @@ -152,7 +150,7 @@ static bool decode_frame(struct lc3_data *data, size_t frame_cnt)
static int get_lc3_chan_alloc_from_index(const struct stream_rx *stream, uint8_t index,
enum bt_audio_location *chan_alloc)
{
#if defined(CONFIG_USB_DEVICE_AUDIO)
#if defined(CONFIG_USE_USB_AUDIO_OUTPUT)
const bool has_left = (stream->lc3_chan_allocation & BT_AUDIO_LOCATION_FRONT_LEFT) != 0;
const bool has_right = (stream->lc3_chan_allocation & BT_AUDIO_LOCATION_FRONT_RIGHT) != 0;
const bool is_mono = stream->lc3_chan_allocation == BT_AUDIO_LOCATION_MONO_AUDIO;
Expand All @@ -174,9 +172,9 @@ static int get_lc3_chan_alloc_from_index(const struct stream_rx *stream, uint8_t
}

return 0;
#else /* !CONFIG_USB_DEVICE_AUDIO */
#else /* !CONFIG_USE_USB_AUDIO_OUTPUT */
return -EINVAL;
#endif /* CONFIG_USB_DEVICE_AUDIO */
#endif /* CONFIG_USE_USB_AUDIO_OUTPUT */
}

static size_t decode_frame_block(struct lc3_data *data, size_t frame_cnt)
Expand All @@ -192,7 +190,7 @@ static size_t decode_frame_block(struct lc3_data *data, size_t frame_cnt)
if (decode_frame(data, frame_cnt + decoded_frames)) {
decoded_frames++;

if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO)) {
if (IS_ENABLED(CONFIG_USE_USB_AUDIO_OUTPUT)) {
enum bt_audio_location chan_alloc;
int err;

Expand Down Expand Up @@ -223,7 +221,7 @@ static size_t decode_frame_block(struct lc3_data *data, size_t frame_cnt)
/* If decoding failed, we clear the data to USB as it would contain
* invalid data
*/
if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO)) {
if (IS_ENABLED(CONFIG_USE_USB_AUDIO_OUTPUT)) {
usb_clear_frames_to_usb();
}

Expand Down Expand Up @@ -379,7 +377,7 @@ int lc3_enable(struct stream_rx *stream)
}
}

if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO)) {
if (IS_ENABLED(CONFIG_USE_USB_AUDIO_OUTPUT)) {
if ((stream->lc3_chan_allocation & BT_AUDIO_LOCATION_FRONT_LEFT) != 0) {
if (usb_left_stream == NULL) {
LOG_INF("Setting USB left stream to %p", stream);
Expand All @@ -404,12 +402,11 @@ int lc3_enable(struct stream_rx *stream)

int lc3_disable(struct stream_rx *stream)
{
if (rx_streaming_cnt == 0 || stream->lc3_decoder == NULL) {
if (stream->lc3_decoder == NULL) {
return -EINVAL;
}

stream->lc3_decoder = NULL;
rx_streaming_cnt--;

if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO)) {
if (usb_left_stream == stream) {
Expand Down Expand Up @@ -488,8 +485,3 @@ int lc3_init(void)

return 0;
}

size_t lc3_get_rx_streaming_cnt(void)
{
return rx_streaming_cnt;
}
9 changes: 1 addition & 8 deletions samples/bluetooth/bap_broadcast_sink/src/lc3.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,12 @@

#include "stream_rx.h"

#define LC3_MAX_SAMPLE_RATE_HZ 48000U
#define LC3_MAX_SAMPLE_RATE_HZ 48000U /* Limit to 16KHz for now */
#define LC3_MAX_FRAME_DURATION_US 10000U
#define LC3_MAX_NUM_SAMPLES_MONO \
((LC3_MAX_FRAME_DURATION_US * LC3_MAX_SAMPLE_RATE_HZ) / USEC_PER_SEC)
#define LC3_MAX_NUM_SAMPLES_STEREO (LC3_MAX_NUM_SAMPLES_MONO * 2U)

/**
* @brief Returns the number of active streams using an LC3 codec
*
* @return the number of active streams using an LC3 codec
*/
size_t lc3_get_rx_streaming_cnt(void);

/**
* @brief Enables LC3 for a stream
*
Expand Down
2 changes: 1 addition & 1 deletion samples/bluetooth/bap_broadcast_sink/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,7 @@ static int init(void)
lc3_init();
}

if (IS_ENABLED(CONFIG_USB_DEVICE_AUDIO)) {
if (IS_ENABLED(CONFIG_USE_USB_AUDIO_OUTPUT)) {
usb_init();
}

Expand Down
Loading

0 comments on commit 98a937c

Please sign in to comment.