samples: Bluetooth: BAP: Broadcast sink use new USB stack
Refactor the USB of the BAP broadcast sink to use the new USB stack. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
parent
e420b21834
commit
7f379fb963
17 changed files with 192 additions and 122 deletions
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
@ -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"
|
||||
|
|
57
samples/bluetooth/bap_broadcast_sink/app.overlay
Normal file
57
samples/bluetooth/bap_broadcast_sink/app.overlay
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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>;
|
||||
/* Falsely claim synchronous audio because we
|
||||
* currently don't calculate feedback value
|
||||
*/
|
||||
sof-synchronized;
|
||||
};
|
||||
|
||||
/* 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>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# Use USB Audio as audio sink
|
||||
CONFIG_USE_USB_AUDIO_OUTPUT=y
|
||||
CONFIG_SAMPLE_USBD_PRODUCT="USB Broadcast Sink sample"
|
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "../app.overlay"
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "../app.overlay"
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
@ -92,7 +91,7 @@ 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");
|
||||
|
@ -100,7 +99,6 @@ static int init_lc3_decoder(struct stream_rx *stream, uint32_t lc3_frame_duratio
|
|||
}
|
||||
|
||||
LOG_INF("Initialized LC3 decoder for %p", stream);
|
||||
rx_streaming_cnt++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -488,8 +485,3 @@ int lc3_init(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t lc3_get_rx_streaming_cnt(void)
|
||||
{
|
||||
return rx_streaming_cnt;
|
||||
}
|
||||
|
|
|
@ -41,13 +41,6 @@
|
|||
((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
|
||||
*
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <zephyr/bluetooth/audio/audio.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
#include <zephyr/drivers/usb/udc_buf.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/net_buf.h>
|
||||
|
@ -28,11 +29,12 @@
|
|||
#include <zephyr/sys/util_macro.h>
|
||||
#include <zephyr/sys_clock.h>
|
||||
#include <zephyr/toolchain.h>
|
||||
#include <zephyr/usb/usb_device.h>
|
||||
#include <zephyr/usb/class/usb_audio.h>
|
||||
#include <zephyr/usb/class/usbd_uac2.h>
|
||||
#include <zephyr/usb/usbd.h>
|
||||
|
||||
#include <sample_usbd.h>
|
||||
|
||||
#include "lc3.h"
|
||||
#include "stream_rx.h"
|
||||
#include "usb.h"
|
||||
|
||||
LOG_MODULE_REGISTER(usb, CONFIG_LOG_DEFAULT_LEVEL);
|
||||
|
@ -47,6 +49,8 @@ LOG_MODULE_REGISTER(usb, CONFIG_LOG_DEFAULT_LEVEL);
|
|||
#define USB_OUT_RING_BUF_SIZE (CONFIG_BT_ISO_RX_BUF_COUNT * LC3_MAX_NUM_SAMPLES_STEREO)
|
||||
#define USB_IN_RING_BUF_SIZE (USB_MONO_FRAME_SIZE * USB_ENQUEUE_COUNT)
|
||||
|
||||
#define IN_TERMINAL_ID UAC2_ENTITY_ID(DT_NODELABEL(in_terminal))
|
||||
|
||||
struct decoded_sdu {
|
||||
int16_t right_frames[CONFIG_MAX_CODEC_FRAMES_PER_SDU][LC3_MAX_NUM_SAMPLES_MONO];
|
||||
int16_t left_frames[CONFIG_MAX_CODEC_FRAMES_PER_SDU][LC3_MAX_NUM_SAMPLES_MONO];
|
||||
|
@ -57,66 +61,75 @@ struct decoded_sdu {
|
|||
} decoded_sdu;
|
||||
|
||||
RING_BUF_DECLARE(usb_out_ring_buf, USB_OUT_RING_BUF_SIZE);
|
||||
NET_BUF_POOL_DEFINE(usb_out_buf_pool, USB_ENQUEUE_COUNT, USB_STEREO_FRAME_SIZE, 0, net_buf_destroy);
|
||||
K_MEM_SLAB_DEFINE_STATIC(usb_out_buf_pool, ROUND_UP(USB_STEREO_FRAME_SIZE, UDC_BUF_GRANULARITY),
|
||||
USB_ENQUEUE_COUNT, UDC_BUF_ALIGN);
|
||||
static volatile bool terminal_enabled;
|
||||
|
||||
/* USB consumer callback, called every 1ms, consumes data from ring-buffer */
|
||||
static void usb_data_request_cb(const struct device *dev)
|
||||
static void uac2_sof_cb(const struct device *dev, void *user_data)
|
||||
{
|
||||
uint8_t usb_audio_data[USB_STEREO_FRAME_SIZE] = {0};
|
||||
struct net_buf *pcm_buf;
|
||||
void *pcm_buf;
|
||||
uint32_t size;
|
||||
int err;
|
||||
|
||||
if (lc3_get_rx_streaming_cnt() == 0) {
|
||||
/* no-op as we have no streams that receive data */
|
||||
if (!terminal_enabled) {
|
||||
/* Simply discard the data then */
|
||||
(void)ring_buf_get(&usb_out_ring_buf, NULL, USB_STEREO_FRAME_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
pcm_buf = net_buf_alloc(&usb_out_buf_pool, K_NO_WAIT);
|
||||
if (pcm_buf == NULL) {
|
||||
err = k_mem_slab_alloc(&usb_out_buf_pool, &pcm_buf, K_NO_WAIT);
|
||||
if (err != 0) {
|
||||
LOG_WRN("Could not allocate pcm_buf");
|
||||
return;
|
||||
}
|
||||
|
||||
/* This may fail without causing issues since usb_audio_data is 0-initialized */
|
||||
size = ring_buf_get(&usb_out_ring_buf, usb_audio_data, sizeof(usb_audio_data));
|
||||
|
||||
net_buf_add_mem(pcm_buf, usb_audio_data, sizeof(usb_audio_data));
|
||||
size = ring_buf_get(&usb_out_ring_buf, pcm_buf, USB_STEREO_FRAME_SIZE);
|
||||
if (size != USB_STEREO_FRAME_SIZE) {
|
||||
/* If we could not fill the buffer, zero-fill the rest (possibly all) */
|
||||
memset(((uint8_t *)pcm_buf) + size, 0, USB_STEREO_FRAME_SIZE - size);
|
||||
}
|
||||
|
||||
if (CONFIG_INFO_REPORTING_INTERVAL > 0) {
|
||||
if (size != 0) {
|
||||
static size_t cnt;
|
||||
|
||||
if (CONFIG_INFO_REPORTING_INTERVAL > 0 &&
|
||||
(++cnt % (CONFIG_INFO_REPORTING_INTERVAL * 10)) == 0U) {
|
||||
if (++cnt % (CONFIG_INFO_REPORTING_INTERVAL * 10) == 0U) {
|
||||
LOG_INF("[%zu]: Sending USB audio", cnt);
|
||||
}
|
||||
} else {
|
||||
static size_t cnt;
|
||||
|
||||
if (CONFIG_INFO_REPORTING_INTERVAL > 0 &&
|
||||
(++cnt % (CONFIG_INFO_REPORTING_INTERVAL * 10)) == 0U) {
|
||||
if (++cnt % (CONFIG_INFO_REPORTING_INTERVAL * 10) == 0U) {
|
||||
LOG_INF("[%zu]: Sending empty USB audio", cnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = usb_audio_send(dev, pcm_buf, sizeof(usb_audio_data));
|
||||
err = usbd_uac2_send(dev, IN_TERMINAL_ID, pcm_buf, USB_STEREO_FRAME_SIZE);
|
||||
if (err != 0) {
|
||||
if (CONFIG_INFO_REPORTING_INTERVAL > 0) {
|
||||
static size_t cnt;
|
||||
|
||||
cnt++;
|
||||
if (CONFIG_INFO_REPORTING_INTERVAL > 0 &&
|
||||
(cnt % (CONFIG_INFO_REPORTING_INTERVAL * 10)) == 0) {
|
||||
LOG_ERR("Failed to send USB audio: %d (%zu)", err, cnt);
|
||||
}
|
||||
|
||||
net_buf_unref(pcm_buf);
|
||||
if (cnt++ % (CONFIG_INFO_REPORTING_INTERVAL * 10) == 0) {
|
||||
LOG_ERR("[%zu]: Failed to send USB audio: %d", cnt, err);
|
||||
}
|
||||
}
|
||||
|
||||
static void usb_data_written_cb(const struct device *dev, struct net_buf *buf, size_t size)
|
||||
k_mem_slab_free(&usb_out_buf_pool, pcm_buf);
|
||||
} /* USB owns the buffer which will be released in uac2_buf_release_cb */
|
||||
}
|
||||
|
||||
static void uac2_buf_release_cb(const struct device *dev, uint8_t terminal, void *buf,
|
||||
void *user_data)
|
||||
{
|
||||
/* Unreference the buffer now that the USB is done with it */
|
||||
net_buf_unref(buf);
|
||||
k_mem_slab_free(&usb_out_buf_pool, buf);
|
||||
}
|
||||
|
||||
static void terminal_update_cb(const struct device *dev, uint8_t terminal, bool enabled,
|
||||
bool microframes, void *user_data)
|
||||
{
|
||||
terminal_enabled = enabled;
|
||||
}
|
||||
|
||||
static void usb_send_frames_to_usb(void)
|
||||
|
@ -215,6 +228,12 @@ int usb_add_frame_to_usb(enum bt_audio_location chan_allocation, const int16_t *
|
|||
const uint8_t ts_jitter_us = 100; /* timestamps may have jitter */
|
||||
static size_t cnt;
|
||||
|
||||
if (!terminal_enabled) {
|
||||
/* Simply discard the data then */
|
||||
/* TODO: Consider if we still want to decode the incoming audio */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (CONFIG_INFO_REPORTING_INTERVAL > 0 && (++cnt % CONFIG_INFO_REPORTING_INTERVAL) == 0U) {
|
||||
LOG_INF("[%zu]: Adding USB audio frame", cnt);
|
||||
}
|
||||
|
@ -319,11 +338,13 @@ void usb_clear_frames_to_usb(void)
|
|||
|
||||
int usb_init(void)
|
||||
{
|
||||
const struct device *hs_dev = DEVICE_DT_GET(DT_NODELABEL(hs_0));
|
||||
static const struct usb_audio_ops usb_ops = {
|
||||
.data_request_cb = usb_data_request_cb,
|
||||
.data_written_cb = usb_data_written_cb,
|
||||
const struct device *mic_dev = DEVICE_DT_GET(DT_NODELABEL(uac2_microphone));
|
||||
static struct uac2_ops usb_audio_ops = {
|
||||
.sof_cb = uac2_sof_cb,
|
||||
.buf_release_cb = uac2_buf_release_cb,
|
||||
.terminal_update_cb = terminal_update_cb,
|
||||
};
|
||||
struct usbd_context *sample_usbd;
|
||||
static bool initialized;
|
||||
int err;
|
||||
|
||||
|
@ -331,15 +352,20 @@ int usb_init(void)
|
|||
return -EALREADY;
|
||||
}
|
||||
|
||||
if (!device_is_ready(hs_dev)) {
|
||||
LOG_ERR("Cannot get USB Headset Device");
|
||||
if (!device_is_ready(mic_dev)) {
|
||||
LOG_ERR("Cannot get USB Microphone Device");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
usb_audio_register(hs_dev, &usb_ops);
|
||||
err = usb_enable(NULL);
|
||||
usbd_uac2_set_ops(mic_dev, &usb_audio_ops, NULL);
|
||||
|
||||
sample_usbd = sample_usbd_init_device(NULL);
|
||||
if (sample_usbd == NULL) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = usbd_enable(sample_usbd);
|
||||
if (err != 0) {
|
||||
LOG_ERR("Failed to enable USB");
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue