Skip to content

Additional Sample Format for USB Audio Streaming in usb_device_uac (AEGHB-1139) #541

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions components/usb/usb_device_uac/Kconfig.uac
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,42 @@ menu "USB Device UAC"
config UAC_SAMPLE_RATE
int "UAC sample rate"
default 48000

choice UAC_SPK_SAMPLE_FORMAT
prompt "UAC SPK sample format"
default UAC_SPK_SAMPLE_FORMAT_PCM
help
SPK: Select in which data type samples shall be expected from USB host.
Currently supports PCM (16-bit signed integer) or IEEE Floating Point (32-bit).

config UAC_SPK_SAMPLE_FORMAT_PCM
bool "PCM (16-bit)"

config UAC_SPK_SAMPLE_FORMAT_FLOAT
bool "IEEE Floating Point (32-bit)"
endchoice

config UAC_SPK_INTERVAL_MS
int "UAC SPK interval(ms)"
default 10
help
SPK: The first interval of reading data from UAC device, in ms. And make SPK FIFO to accommodate data of size n milliseconds.

choice UAC_MIC_SAMPLE_FORMAT
prompt "UAC MIC sample format"
default UAC_MIC_SAMPLE_FORMAT_PCM
help
MIC: Select in which data type samples are sent to USB host.
Currently supports PCM (16-bit signed integer) or IEEE Floating Point (32-bit).
Only affects data rate calculation and USB descriptor! Library user must ensure correct data format.

config UAC_MIC_SAMPLE_FORMAT_PCM
bool "PCM (16-bit)"

config UAC_MIC_SAMPLE_FORMAT_FLOAT
bool "IEEE Floating Point (32-bit)"
endchoice

config UAC_MIC_INTERVAL_MS
int "UAC MIC interval(ms)"
default 10
Expand Down
38 changes: 30 additions & 8 deletions components/usb/usb_device_uac/tusb_uac/tusb_config_uac.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ extern "C" {
// AUDIO CLASS DRIVER CONFIGURATION
//--------------------------------------------------------------------

// Beware of confusion!

// When using RX and TX it is out of the perspective of the device (us),
// so RX is the data received from the host (SPK) and TX is the data sent to the host (MIC).

// But IN and OUT are the perspective of the host,
// so OUT is the data received from the host (SPK) and IN is the data sent to the host (MIC).

// Enable feedback EP
#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 1

Expand All @@ -33,29 +41,43 @@ extern "C" {
#define CFG_TUD_AUDIO_FUNC_1_N_FORMATS 1

#define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE DEFAULT_SAMPLE_RATE
#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX SPEAK_CHANNEL_NUM
#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX MIC_CHANNEL_NUM
#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX SPEAK_CHANNEL_NUM
#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX MIC_CHANNEL_NUM

// Sample type
#if SPK_FORMAT_PCM
Copy link
Preview

Copilot AI Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing #else clause for SPK format configuration. If neither SPK_FORMAT_PCM nor SPK_FORMAT_FLOAT is defined, the RX sample configuration will be undefined, leading to compilation errors.

Copilot uses AI. Check for mistakes.

// 16bit in 16bit slots
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX 2
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_TX 16
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX 2
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX 16
#elif SPK_FORMAT_FLOAT
// 32bit in 32bit slots
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX 4
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX 32
#endif

#if MIC_FORMAT_PCM
Copy link
Preview

Copilot AI Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing #else clause for MIC format configuration. If neither MIC_FORMAT_PCM nor MIC_FORMAT_FLOAT is defined, the TX sample configuration will be undefined, leading to compilation errors.

Copilot uses AI. Check for mistakes.

#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX 2
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_TX 16
#elif MIC_FORMAT_FLOAT
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX 4
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_TX 32
#endif

// EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense)
#define CFG_TUD_AUDIO_ENABLE_EP_IN 1

// MIC
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN ((CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE / 1000 * CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) + 4)
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN ((CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE / 1000 * CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) + 4)

#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN * (MIC_INTERVAL_MS + 1)
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN // Maximum EP IN size for all AS alternate settings used

//------------ SPK (RX / OUT) -------------//

// EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense)
#define CFG_TUD_AUDIO_ENABLE_EP_OUT 1

// SPK +4 for audio feedback
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT ((CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE / 1000 * CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX) + 4)
// +4 for audio feedback
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT ((CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE / 1000 * CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX) + 4)

#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT * (SPK_INTERVAL_MS + 1)
#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT // Maximum EP IN size for all AS alternate settings used
Expand Down
12 changes: 12 additions & 0 deletions components/usb/usb_device_uac/tusb_uac/uac_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ extern "C" {
#define SPK_INTERVAL_MS CONFIG_UAC_SPK_INTERVAL_MS /*!< READ INTERVAL in ms*/
#define MIC_INTERVAL_MS CONFIG_UAC_MIC_INTERVAL_MS /*!< WRITE INTERVAL in ms*/

#if CONFIG_UAC_SPK_SAMPLE_FORMAT_PCM
#define SPK_FORMAT_PCM 1
#elif CONFIG_UAC_SPK_SAMPLE_FORMAT_FLOAT
#define SPK_FORMAT_FLOAT 1
#endif

#if CONFIG_UAC_MIC_SAMPLE_FORMAT_PCM
#define MIC_FORMAT_PCM 1
#elif CONFIG_UAC_MIC_SAMPLE_FORMAT_FLOAT
#define MIC_FORMAT_FLOAT 1
#endif

#define IN_CTRL_CH_VALUE U32_TO_U8S_LE(AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO_CTRL_RW << AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS)

#if SPEAK_CHANNEL_NUM == 1
Expand Down
20 changes: 16 additions & 4 deletions components/usb/usb_device_uac/tusb_uac/uac_descriptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@ enum {
#define UAC2_ENTITY_MIC_FEATURE_TERMINAL 0x12
#define UAC2_ENTITY_MIC_OUTPUT_TERMINAL 0x13

#if SPK_FORMAT_PCM
Copy link
Preview

Copilot AI Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The macro SPK_FORMAT_PCM may be undefined when neither PCM nor FLOAT is selected, leading to undefined behavior. Consider adding an #else clause with a default format or an #error directive to catch invalid configurations.

Copilot uses AI. Check for mistakes.

#define SPK_SAMPLE_FORMAT AUDIO_DATA_FORMAT_TYPE_I_PCM
#elif SPK_FORMAT_FLOAT
#define SPK_SAMPLE_FORMAT AUDIO_DATA_FORMAT_TYPE_I_IEEE_FLOAT
#endif

#if MIC_FORMAT_PCM
Copy link
Preview

Copilot AI Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The macro MIC_FORMAT_PCM may be undefined when neither PCM nor FLOAT is selected, leading to undefined behavior. Consider adding an #else clause with a default format or an #error directive to catch invalid configurations.

Copilot uses AI. Check for mistakes.

#define MIC_SAMPLE_FORMAT AUDIO_DATA_FORMAT_TYPE_I_PCM
#elif MIC_FORMAT_FLOAT
#define MIC_SAMPLE_FORMAT AUDIO_DATA_FORMAT_TYPE_I_IEEE_FLOAT
#endif

#if SPEAK_CHANNEL_NUM && MIC_CHANNEL_NUM
#define NUM_INTERFACES 3
#elif SPEAK_CHANNEL_NUM || MIC_CHANNEL_NUM
Expand Down Expand Up @@ -175,7 +187,7 @@ enum {
/* Interface 1, Alternate 1 - alternate interface for data streaming */\
TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ _itfnum + 1, /*_altset*/ 0x01, /*_nEPs*/ 0x02, /*_stridx*/ _stridx + 1),\
/* Class-Specific AS Interface Descriptor(4.9.2) */\
TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ SPEAK_CHANNEL_NUM, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\
TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ SPK_SAMPLE_FORMAT, /*_nchannelsphysical*/ SPEAK_CHANNEL_NUM, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\
/* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\
TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX),\
/* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\
Expand All @@ -191,7 +203,7 @@ enum {
/* Interface 2, Alternate 1 - alternate interface for data streaming */\
TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ _itfnum + 2, /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ _stridx + 2),\
/* Class-Specific AS Interface Descriptor(4.9.2) */\
TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ MIC_CHANNEL_NUM, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_FRONT_CENTER, /*_stridx*/ 0x00),\
TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ MIC_SAMPLE_FORMAT, /*_nchannelsphysical*/ MIC_CHANNEL_NUM, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_FRONT_CENTER, /*_stridx*/ 0x00),\
/* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\
TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_TX),\
/* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\
Expand Down Expand Up @@ -226,7 +238,7 @@ enum {
/* Interface 1, Alternate 1 - alternate interface for data streaming */\
TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ _itfnum + 1, /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ _stridx + 1),\
/* Class-Specific AS Interface Descriptor(4.9.2) */\
TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ MIC_CHANNEL_NUM, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_FRONT_CENTER, /*_stridx*/ 0x00),\
TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ MIC_SAMPLE_FORMAT, /*_nchannelsphysical*/ MIC_CHANNEL_NUM, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_FRONT_CENTER, /*_stridx*/ 0x00),\
/* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\
TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_TX),\
/* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\
Expand Down Expand Up @@ -261,7 +273,7 @@ enum {
/* Interface 1, Alternate 1 - alternate interface for data streaming */\
TUD_AUDIO_DESC_STD_AS_INT(/*_itfnum*/ _itfnum + 1, /*_altset*/ 0x01, /*_nEPs*/ 0x02, /*_stridx*/ _stridx + 1),\
/* Class-Specific AS Interface Descriptor(4.9.2) */\
TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ AUDIO_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ SPEAK_CHANNEL_NUM, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\
TUD_AUDIO_DESC_CS_AS_INT(/*_termid*/ UAC2_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO_CTRL_NONE, /*_formattype*/ AUDIO_FORMAT_TYPE_I, /*_formats*/ SPK_SAMPLE_FORMAT, /*_nchannelsphysical*/ SPEAK_CHANNEL_NUM, /*_channelcfg*/ AUDIO_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00),\
/* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\
TUD_AUDIO_DESC_TYPE_I_FORMAT(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX),\
/* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\
Expand Down
20 changes: 12 additions & 8 deletions components/usb/usb_device_uac/usb_device_uac.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,15 +312,15 @@ bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const
uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex));
uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue));

#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX
#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX
if (s_uac_device->spk_itf_num == itf && alt == 0) {
TU_LOG2("Speaker interface closed");
s_uac_device->spk_data_size = 0;
s_uac_device->spk_active = false;
}
#endif

#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX
#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX
if (s_uac_device->mic_itf_num == itf && alt == 0) {
TU_LOG2("Microphone interface closed");
s_uac_device->mic_data_size = 0;
Expand All @@ -339,7 +339,7 @@ bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const *p_reques

TU_LOG2("Set interface %d alt %d\r\n", itf, alt);

#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX
#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX
if (s_uac_device->spk_itf_num == itf && alt != 0) {
s_uac_device->spk_data_size = 0;
s_uac_device->spk_resolution = spk_resolutions_per_format[alt - 1];
Expand All @@ -351,7 +351,7 @@ bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const *p_reques
}
#endif

#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX
#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX
if (s_uac_device->mic_itf_num == itf && alt != 0) {
s_uac_device->mic_data_size = 0;
s_uac_device->mic_resolution = mic_resolutions_per_format[alt - 1];
Expand Down Expand Up @@ -431,7 +431,7 @@ bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, u
return true;
}

#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX
#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX
static void usb_spk_task(void *pvParam)
{
while (1) {
Expand All @@ -453,7 +453,7 @@ static void usb_spk_task(void *pvParam)
}
#endif

#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX
#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX
static void usb_mic_task(void *pvParam)
{
while (1) {
Expand Down Expand Up @@ -505,8 +505,12 @@ esp_err_t uac_device_init(uac_device_config_t *config)
s_uac_device->spk_itf_num = config->spk_itf_num;
s_uac_device->mic_itf_num = config->mic_itf_num;
#else
#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX
s_uac_device->spk_itf_num = ITF_NUM_AUDIO_STREAMING_SPK;
#endif
#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX
s_uac_device->mic_itf_num = ITF_NUM_AUDIO_STREAMING_MIC;
#endif
#endif

BaseType_t ret_val;
Expand All @@ -522,13 +526,13 @@ esp_err_t uac_device_init(uac_device_config_t *config)
ESP_RETURN_ON_FALSE(ret_val == pdPASS, ESP_FAIL, TAG, "Failed to create TinyUSB task");
}

#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX
#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX
ret_val = xTaskCreatePinnedToCore(usb_mic_task, "usb_mic_task", 4096, NULL, CONFIG_UAC_MIC_TASK_PRIORITY,
&s_uac_device->mic_task_handle, CONFIG_UAC_MIC_TASK_CORE == -1 ? tskNO_AFFINITY : CONFIG_UAC_MIC_TASK_CORE);
ESP_RETURN_ON_FALSE(ret_val == pdPASS, ESP_FAIL, TAG, "Failed to create usb_mic task");
#endif

#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX
#if CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX
ret_val = xTaskCreatePinnedToCore(usb_spk_task, "usb_spk_task", 4096, NULL, CONFIG_UAC_SPK_TASK_PRIORITY,
&s_uac_device->spk_task_handle, CONFIG_UAC_SPK_TASK_CORE == -1 ? tskNO_AFFINITY : CONFIG_UAC_SPK_TASK_CORE);
ESP_RETURN_ON_FALSE(ret_val == pdPASS, ESP_FAIL, TAG, "Failed to create usb_spk task");
Expand Down