USB UAC 设备示例

功能说明

演示如何使用 USB UAC(USB Audio Class)设备功能将开发板作为标准 USB 声卡接入 PC,实现 PC 端录音和播放。

本示例基于 TinyUSB 协议栈实现 UAC2.0 设备功能,并通过 lisa_audio 对接板端真实音频链路。PC 端可枚举出标准 USB Audio 设备,无需安装私有驱动即可使用系统录音、播放工具或 Audacity 等音频软件。

默认音频格式如下:

方向

功能

默认配置

数据来源/去向

MIC

USB IN,设备到 PC

16 kHz, 2 ch, 16 bit

lisa_audio_record 采集真实 MIC 数据

Speaker

USB OUT,PC 到设备

16 kHz, 1 ch, 16 bit

lisa_audio_play 播放 PC 下发的数据

MIC/Speaker 的采样率、通道数、采样深度、录音增益、播放增益、播放缓冲等参数可通过 Kconfig 调整。

硬件连接

开发板

  • Arcs-EVB 开发板

  • Arcs-Mini 开发板

  • Venusa RD EVB 开发板

音频连接

  • MIC 输入:使用开发板板载或外接麦克风,具体硬件连接由对应开发板和 lisa_audio 驱动配置决定。

  • Speaker 输出:使用开发板板载或外接喇叭,具体硬件连接由对应开发板和 lisa_audio 驱动配置决定。

  • Venusa RD EVB:喇叭功放 PA_EN 接在 GPIOA0,本示例提供 venusa_rd_evb_overlay.conf 用于显式使能 PA 控制。

USB 连接

  • 使用开发板 USB device 口通过 USB 线缆连接到 PC。

  • 当前默认音频带宽较低,USB Full-Speed 即可满足 16 kHz 语音录放需求。

示例内容

  1. 初始化 LISA Audio 驱动,配置真实 MIC 录音和 speaker 播放参数。

  2. 初始化 TinyUSB device,配置 UAC2.0 描述符、AudioControl 和 AudioStreaming 接口。

  3. lisa_audio_record 采集到的 MIC 数据缓存后通过 USB IN endpoint 发送给 PC。

  4. 将 PC 通过 USB OUT endpoint 下发的 speaker 数据缓存后写入 lisa_audio_play 播放。

  5. 处理 UAC mute、volume、sampling frequency 等 class control 请求。

  6. PC 端识别为标准 USB Audio 录音和播放设备。

编译

重要提示:在编译前,请先确认您使用的开发板型号。SDK 目前支持以下开发板:

  • arcs_evb - ARCS EVB 评估板

  • arcs_mini - ARCS Mini 开发板

根据您的开发板型号,选择对应的编译命令:

在 SDK 根目录执行编译。Linux 使用 build.sh

# 使用 arcs_evb 开发板
./build.sh -C -S samples/<示例路径> -DBOARD=arcs_evb

# 或使用 arcs_mini 开发板
./build.sh -C -S samples/<示例路径> -DBOARD=arcs_mini

Windows PowerShell 使用 build.ps1

# 使用 arcs_evb 开发板
.\build.ps1 -C -S samples/<示例路径> -DBOARD=arcs_evb

# 或使用 arcs_mini 开发板
.\build.ps1 -C -S samples/<示例路径> -DBOARD=arcs_mini

Note

确保已安装对应平台的工具链和 ListenAI 开发工具包。Windows 环境请先执行 .\env.ps1 或直接使用 .\build.ps1 自动加载环境。

Arcs-EVB

./build.sh -S samples/subsys/usb/device/uac -DBOARD=arcs_evb

Arcs-Mini

./build.sh -S samples/subsys/usb/device/uac -DBOARD=arcs_mini

Venusa RD EVB

Venusa RD EVB 建议叠加 PA_EN overlay:

./build.sh -S samples/subsys/usb/device/uac \
  -DBOARD=venusa_rd_evb \
  -DCONFIG_FILES=venusa_rd_evb_overlay.conf

烧录

编译完成后,使用 SDK tools 目录下的 cskburn 工具烧录固件。

Linux:

./tools/burn/cskburn -s /dev/ttyUSB0 -b 3000000 0x0 build/arcs.bin -C arcs

Windows PowerShell:

.\tools\burn\cskburn.exe -C arcs -s COM7 -b 3000000 0x0 .\build\arcs.bin

Note

烧录参数说明

  • -s /dev/ttyUSB0 / -s COM7:串口设备路径,需要根据实际情况修改 - Linux 系统:通常是 /dev/ttyUSB0/dev/ttyACM0 - 可通过 ls /dev/tty* 命令查看可用串口设备 - Windows 系统:通常是 COM7COM8 等,可在“设备管理器”的“端口”中查看 - 不同开发板或 USB 转串口芯片可能使用不同的设备名

  • -b 3000000:烧录波特率(3Mbps)

  • 0x0:烧录起始地址

  • build/arcs.bin / .\build\arcs.bin:编译生成的固件路径

  • -C arcs:芯片类型

注意事项

  • 确保开发板已正确连接到电脑

  • 如果无法识别串口设备,请检查 USB 连接线是否正常,或尝试其他 USB 端口

Venusa RD EVB 示例烧录命令:

./tools/burn/cskburn -C venusa -s /dev/ttyACM0 -b 3000000 0x0 build/arcs.bin

Arcs-EVB 示例烧录命令:

./tools/burn/cskburn -C arcs -s /dev/ttyACM0 -b 3000000 0x0 build/arcs.bin

预期输出

设备端日志:

********SDK 0.1.7 @ v0.0.1-1810-g555f61e57ca1********
Running on cpu-id: 1
I/elog            [00:00:00.009 1 elog_async] EasyLogger V2.2.99 is initialize success.
I/main            [00:00:00.010 1 main] TinyUSB UAC2 lisa_audio sample starting
I/uac             [00:00:00.013 1 main] TinyUSB UAC2 ready: mic 16000Hz/16bit/2ch, speaker 16000Hz/16bit/1ch
I/main            [00:00:00.013 1 main] TinyUSB UAC2 lisa_audio sample ready
I/uac             [00:00:01.100 1 tinyusb] USB mounted
I/uac             [00:00:02.000 1 tinyusb] mic opened
I/uac             [00:00:03.000 1 tinyusb] speaker opened
I/main            [00:00:05.013 1 main] UAC sample running

PC 端测试方法

Windows

正常情况下设备管理器中可看到 USB Audio 设备,系统声音设置或 Audacity 中可选择对应的录音和播放设备。

  1. 在“声音设置”中选择 ListenAI TinyUSB UAC2 对应的输入设备进行录音。

  2. 在“声音设置”中选择 ListenAI TinyUSB UAC2 对应的输出设备进行播放。

  3. 也可以使用 Audacity 选择该设备进行录音、播放和波形检查。

Linux

# 查看 USB 枚举信息
lsusb
lsusb -t

# 查看 ALSA 声卡列表
arecord -l
aplay -l

录制 MIC 原始 PCM 数据:

# <card> 替换为 arecord -l 中枚举出的声卡编号
arecord -D hw:<card>,0 -f S16_LE -c 2 -r 16000 -d 5 mic_16k_2ch.raw

录制 WAV 文件:

arecord -D hw:<card>,0 -f S16_LE -c 2 -r 16000 -d 5 mic_16k_2ch.wav

播放 WAV 文件到开发板 speaker:

aplay -D hw:<card>,0 -f S16_LE -c 1 -r 16000 test_16k_mono.wav

也可以使用 Audacity 选择 ListenAI TinyUSB UAC2 进行录音和播放验证。

核心 API

UAC Device API

API

说明

uac_device_start()

初始化 TinyUSB UAC2 设备,注册 capture/playback stream 并启动 USB task

uac_stream_t

UAC 数据流抽象,用于对接 MIC capture 和 speaker playback

uac_stream_ops_t::read()

从 capture stream 读取 MIC 数据并发送给 USB host

uac_stream_ops_t::write()

将 USB host 下发的 speaker 数据写入 playback stream

uac_stream_ops_t::set_mute()

响应 host mute 控制

uac_stream_ops_t::set_volume()

响应 host volume 控制

MIC API

API

说明

mic_init()

初始化 lisa_audio_record 并注册录音回调

mic_stream()

获取 MIC capture stream,用于注册到 UAC device

Speaker API

API

说明

speaker_init()

初始化 lisa_audio_play 并配置播放参数

speaker_stream()

获取 speaker playback stream,用于注册到 UAC device

关键代码

UAC 设备组装

ret = mic_init(audio_dev);
ret = speaker_init();

const uac_device_config_t uac_config = {
    .capture = mic_stream(),
    .playback = speaker_stream(),
};

ret = uac_device_start(&uac_config);

MIC 数据流

static uint32_t mic_read(uac_stream_t *stream, uint8_t *buffer, uint32_t bytes)
{
    mic_priv_t *priv = (mic_priv_t *)stream->priv;
    uint32_t copied;

    taskENTER_CRITICAL();
    copied = ring_buf_get(&priv->ring, buffer, bytes);
    taskEXIT_CRITICAL();

    return copied;
}

Speaker 数据流

static uint32_t speaker_write(uac_stream_t *stream, const uint8_t *data, uint32_t bytes)
{
    speaker_priv_t *priv = (speaker_priv_t *)stream->priv;
    uint32_t sample_bytes = priv->sample_bits / 8U;
    uint32_t samples = bytes / sample_bytes;

    int ret = lisa_audio_play_write(priv->audio_dev, data, samples);
    return (ret > 0) ? (uint32_t)ret * sample_bytes : 0U;
}

TinyUSB 与音频任务

/* USB task 只负责 TinyUSB device poll */
while (1) {
    tud_task();
}

/* MIC USB task 负责 tud_audio_n_write() */
/* Speaker USB task 负责 tud_audio_n_read() 和 feedback */
/* Speaker playback task 负责 lisa_audio_play_write() */

配置说明

常用 Kconfig 配置项:

配置项

默认值

说明

CONFIG_UAC_MIC_SAMPLE_RATE

16000

MIC 采样率

CONFIG_UAC_MIC_CHANNELS

2

MIC 通道数

CONFIG_UAC_MIC_SAMPLE_BITS

16

MIC 采样深度

CONFIG_UAC_SPK_SAMPLE_RATE

16000

Speaker 采样率

CONFIG_UAC_SPK_CHANNELS

1

Speaker 通道数

CONFIG_UAC_SPK_SAMPLE_BITS

16

Speaker 采样深度

CONFIG_UAC_PLAY_BUFFER_MS

16

lisa_audio_play 单个播放缓冲时长

CONFIG_UAC_PLAY_BUFFER_COUNT

12

lisa_audio_play 播放缓冲数量

CONFIG_UAC_ENABLE_BOARD_PA

板级默认

是否启用板级 speaker PA 控制

注意事项

  1. 协议版本:本示例使用 TinyUSB UAC2.0;如需要 UAC1.0,可参考 CherryUSB 相关 audio sample。

  2. USB 速度:当前默认格式为 16 kHz 语音录放,USB Full-Speed 可以满足带宽要求。

  3. 真实音频链路:MIC 和 speaker 均对接真实 lisa_audio,因此录放效果受开发板硬件、麦克风、功放、喇叭和增益配置影响。

  4. Venusa PA_EN:Venusa RD EVB 需要控制 GPIOA0 上的 PA_EN,建议使用 -DCONFIG_FILES=venusa_rd_evb_overlay.conf 编译。

  5. 音量控制:Host 下发的 UAC volume 会映射到 lisa_audio_play_set_gain(),实际音量曲线由 CONFIG_UAC_PLAY_VOLUME_DIVISOR 和底层 codec/PA 决定。

  6. 任务模型:本示例将 TinyUSB poll、MIC USB 写、speaker USB 读、speaker 播放拆分为多个任务;TinyUSB audio API 使用 mutex 串行化,避免多任务并发访问 TinyUSB audio 内部状态。

  7. 反馈端点:Speaker 使用 asynchronous OUT + feedback endpoint,feedback 当前按固定采样率返回,用于让 host 按设备速率发送播放数据。

  8. 驱动支持:Windows 10/11、Linux 均原生支持 USB Audio,无需额外私有驱动;不同桌面环境可能不会在系统设置中显示所有多媒体设备,可使用 Audacity 或 ALSA 工具验证。

  9. 实机验证:USB Audio 需要 PC 枚举和实际录放验证,sample.yaml 标记为 build_only: true