ESP32
树莓派搭建espidf 开发环境
esp-matter 开发记录
WLED 笔记
esp32s3 作为 USB HOST UAC 读取 CM108A声卡
ESP-IDF USB Host UAC 支持情况
USB Host 与 Device 模式说明
ESP32-S3 UAC设备工作原理分析
espressif/usb_host_uac 组件完整使用指南
USB UAC Host 使用指南
本文档使用 MrDoc 发布
-
+
首页
USB UAC Host 使用指南
本文档基于 `usb_audio_player` 示例,详细说明 ESP-IDF 中 `usb_host_uac` (USB Audio Class Host) 组件的使用方法。 --- ## 1. 整体架构分层 ``` ┌─────────────────────────────────┐ │ 应用层 (usb_audio_player_main.c) │ │ - 事件处理 / 音频播放回调 / 用户逻辑 │ └─────────────────────────────────┘ ↓ 调用API ┌─────────────────────────────────┐ │ UAC Host类驱动 (usb_host_uac组件) │ │ - UAC协议解析 / 流传输 / 设备管理 │ └─────────────────────────────────┘ ↓ 调用API ┌─────────────────────────────────┐ │ USB Host核心栈 │ │ - USB底层传输 / 设备枚举 / 总线管理 │ └─────────────────────────────────┘ ``` --- ## 2. 完整使用流程 ### 2.1 初始化阶段 ```c // 1. 创建事件队列,用于传递UAC驱动和设备事件 s_event_queue = xQueueCreate(10, sizeof(s_event_queue_t)); // 2. 启动USB Host核心任务,安装USB Host驱动 xTaskCreatePinnedToCore(usb_lib_task, "usb_events", 4096, ...); // usb_lib_task中调用 usb_host_install(&host_config) 初始化USB Host栈 // 3. 安装UAC Host类驱动 uac_host_driver_config_t uac_config = { .create_background_task = true, .task_priority = UAC_TASK_PRIORITY, .stack_size = 4096, .core_id = 0, .callback = uac_host_lib_callback, // 注册驱动级回调 .callback_arg = NULL }; uac_host_install(&uac_config); ``` ### 2.2 设备连接检测与打开 当USB音频设备插入时: 1. UAC驱动触发 `UAC_HOST_DRIVER_EVENT_TX_CONNECTED` (扬声器) / `UAC_HOST_DRIVER_EVENT_RX_CONNECTED` (麦克风) 事件 2. 通过 `uac_host_lib_callback` 回调将事件发送到事件队列 3. 事件处理任务调用 `uac_host_device_open()` 打开设备: ```c const uac_host_device_config_t dev_config = { .addr = addr, // USB设备地址(从驱动事件回调获取) .iface_num = iface_num, // UAC接口号(从驱动事件回调获取) .buffer_size = 16000, // 音频环形缓冲区大小:16KB .buffer_threshold = 4000, // 缓冲区阈值:4KB,低于该值触发TX_DONE事件 .callback = uac_device_callback, // 注册设备级回调 .callback_arg = NULL, }; uac_host_device_open(&dev_config, &uac_device_handle); ``` 4. 调用 `uac_host_get_device_info()` 获取设备信息,`uac_host_printf_device_param()` 打印设备参数 ### 2.3 启动音频流 ```c const uac_host_stream_config_t stm_config = { .channels = 2, .bit_resolution = 16, .sample_freq = 48000, }; uac_host_device_start(uac_device_handle, &stm_config); ``` 配置音频流参数(通道数、位宽、采样率)并启动ISO传输。 ### 2.4 音频播放控制 - **写音频数据**: ```c esp_err_t ret = uac_host_device_write(s_spk_dev_handle, audio_buffer, len, timeout_ms); ``` 将PCM音频数据写入UAC内部环形缓冲区,后台任务自动通过USB ISO通道发送到设备。 - **参数调整**:当音频格式变化时,先调用 `uac_host_device_stop()` 停止流,重新配置参数后再启动 - **暂停/恢复**:调用 `uac_host_device_suspend()` / `uac_host_device_resume()` 控制流状态 - **音量/静音**:调用 `uac_host_device_set_volume()` / `uac_host_device_set_mute()` 控制音量和静音 ### 2.5 设备断开处理 当USB设备拔出时: 1. 触发 `UAC_HOST_DRIVER_EVENT_DISCONNECTED` 事件,通过 `uac_device_callback` 发送到事件队列 2. 停止音频播放器,调用 `uac_host_device_close(uac_device_handle)` 关闭设备,清理资源 --- ## 3. 事件回调机制 UAC驱动采用**两层异步回调**的事件驱动设计: | 回调层级 | 回调函数定义 | 触发时机 | | ---------- | ---------------------------- | ----------------------------- | | 驱动级回调 | `uac_host_driver_event_cb_t` | 全局UAC驱动事件(新设备连接) | | 设备级回调 | `uac_host_device_event_cb_t` | 单个UAC设备的专属事件 | ### 3.1 UAC_DRIVER_EVENT vs UAC_DEVICE_EVENT | 维度 | `UAC_DRIVER_EVENT` (驱动级事件) | `UAC_DEVICE_EVENT` (设备级事件) | | ------------ | ---------------------------------------------------- | ------------------------------------------------------------ | | **作用域** | 全局:属于整个UAC Host驱动,所有设备共享 | 实例级:属于**某一个已经打开的具体UAC设备**,独立触发 | | **触发时机** | 新UAC设备插入枚举完成时触发 | 已打开的UAC设备运行时触发(数据传输、错误、拔出) | | **携带信息** | 设备地址`addr`、接口号`iface_num`(用于打开设备) | 已打开的设备句柄`handle`(用于操作具体设备) | | **事件类型** | 仅设备连接相关:<br>- 扬声器连接<br>- 麦克风连接 | 设备运行时事件:<br>- 发送完成<br>- 接收完成<br>- 传输错误<br>- 当前设备拔出 | | **处理逻辑** | 用于发现新设备,调用`uac_host_device_open()`打开设备 | 用于操作已打开的设备:处理传输完成、断开清理、错误恢复等 | --- ## 4. 核心API说明 | API函数 | 作用 | | ------------------------------ | ---------------------------------- | | `uac_host_install()` | 安装UAC Host类驱动 | | `uac_host_uninstall()` | 卸载UAC Host类驱动 | | `uac_host_device_open()` | 打开连接的UAC设备,获取设备句柄 | | `uac_host_device_close()` | 关闭UAC设备,释放所有资源 | | `uac_host_device_start()` | 启动音频流传输 | | `uac_host_device_stop()` | 停止音频流传输,释放传输资源 | | `uac_host_device_suspend()` | 暂停流传输,保留缓冲区数据 | | `uac_host_device_resume()` | 恢复流传输,继续发送缓冲区剩余数据 | | `uac_host_device_write()` | 写入PCM音频数据到发送缓冲区 | | `uac_host_device_read()` | 从接收缓冲区读取麦克风数据 | | `uac_host_device_set_mute()` | 设置设备静音/取消静音 | | `uac_host_device_set_volume()` | 设置设备音量(0~100) | --- ## 5. 关键参数说明 1. **buffer_size**:UAC内部环形缓冲区大小,建议设置为至少2倍的最大音频帧大小,示例中为16KB 2. **buffer_threshold**:缓冲区阈值,当缓冲区剩余空间大于该值时触发`TX_DONE`事件,通知应用可以继续写入数据,示例中为4KB 3. **create_background_task**:是否创建UAC后台任务处理事件,建议设置为`true`,无需应用层手动处理事件 --- ## 6. 常见问题 ### 6.1 支持哪些音频参数? - 采样率:8kHz ~ 192kHz - 位宽:16bit / 24bit / 32bit - 通道数:1(单声道)/ 2(立体声) - 格式:仅支持PCM格式 ### 6.2 如何处理不同的音频格式? 当音频格式变化时,需要先调用 `uac_host_device_stop()` 停止当前流,重新配置 `uac_host_stream_config_t` 参数后再次调用 `uac_host_device_start()` 启动流。 ### 6.3 支持热插拔吗? 支持,设备拔出时会触发 `UAC_HOST_DRIVER_EVENT_DISCONNECTED` 事件,应用层需要在回调中清理资源,下次插入设备时会重新触发连接事件。
qingkai
2026年4月1日 00:14
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码