- 音视频
- 音频处理
- 嵌入式
- 物联网
- 语音
【免费下载链接】esp-adf
Espressif Advanced Development Framework for Multimedia Applications
ESP-ADF 的 Audio Recorder 是面向语音录制场景的高层 API,将麦克风数据采集、语音前端处理(AFE)与音频编码封装进一条事件驱动的数据通路,开发者只需配置采样率、编码格式与 AFE 参数即可完成"唤醒词检测 → 命令词识别 → 录音编码"的完整流程。本文基于 audio_recorder.rst 的官方文档,结合仓库内 AI Agent 示例(coze_ws_app、baidu_rtc)与音频分析工具(esp_audio_analyzer_app)的源码实现,带你掌握 Audio Recorder 的数据通路、AFE 参数配置、编码格式选择与事件交互机制。
一、Audio Recorder 是什么
Audio Recorder API 是一组用于语音录制(voice recording)的函数集合。它的核心设计思想是把两条重要能力合二为一:
- 语音前端处理(Audio Front End,AFE):负责麦克风采集后的信号调理,包括回声消除(AEC)、自动增益控制(AGC)、语音活动检测(VAD)以及唤醒词/命令词识别(WakeNet / MultiNet);
- 音频编码(audio encoding):将处理后的语音数据编码为指定音频格式,供存储或上传。
这种"采集 + 前端处理 + 编码"的集成,让开发者无需手工串联多个 Element,即可获得一条开箱即用的录音流水线。文档明确指出:用户可以自定义 AFE 的 VAD、AGC、AEC 设置,从而根据真实硬件环境和场景(安静房间、嘈杂环境、免提通话等)灵活调整前端处理强度。
与此同时,Audio Recorder 通过audio_rec_evt_t事件机制对外暴露状态与结果(例如唤醒成功、命令词命中、VAD 端点等),使用户程序可以方便地与 Audio Recorder 软件进行交互,实现事件驱动的语音对话逻辑。
二、Audio Recorder 数据通路剖析
官方文档给出了 Audio Recorder 的完整数据通路(blockdiag 图),其节点与流向如下:
Mic ──▶ I2S stream ──▶ Resample element ──▶ RAW stream ──▶ AFE ──▶ WakeNet ──▶ MultiNet ──▶ Resample element ──▶ Encoder element │ └────────────▶(RAW stream 亦直接回采给 AFE,用于 AEC 参考信号)| 节点 | 作用 |
|---|---|
| Mic | 麦克风拾音起点 |
| I2S stream | 通过 I2S 总线从 Codec 芯片读取原始 PCM 数据 |
| Resample element | 重采样,将 I2S 流采样率转换为语音识别模型所需的采样率 |
| RAW stream | 原始 PCM 数据流,作为识别模型的输入,同时为 AFE 提供 AEC 回采参考 |
| AFE | 语音前端处理:AEC、AGC、VAD 等信号调理 |
| WakeNet | 唤醒词检测引擎 |
| MultiNet | 命令词(语音命令)识别引擎 |
| Encoder element | 将处理后的语音编码为目标格式(AAC、AMR、OPUS、G711 等) |
文档特别强调:数据通路中用平行四边形表示的区域是用户可配置的,开发者可以根据实际需求调整:
- 采样频率(sampling frequency):例如模型要求 16 kHz,而 Codec 输出 48 kHz,则通过 Resample element 做转换;
- 是否编码(whether to encode):可以只输出裸 PCM 供实时分析,也可以开启编码;
- 编码格式(encoding format):AAC、AMR-NB、AMR-WB、ADPCM、WAV、OPUS、G711 等。
与旧式 Element 管线的对比
在 esp_wn_iface.rst 中,官方展示了经典的语音识别管线:Mic → Codec chip → I2S stream → Filter → RAW stream → Speech recognition,其中Filter用于将 I2S 流采样率调整到与识别模型一致,RAW stream用于把音频输入喂给模型。文档明确给出建议:Audio Recorder 是比手工搭建 Element 管线更灵活、更方便的模块,强烈推荐使用。这也是 Audio Recorder 存在的意义——把上述手工步骤全部封装进一个高层 API。
三、AFE 前端处理:VAD / AGC / AEC / WakeNet / MultiNet
Audio Recorder 的价值核心在于可定制的 AFE。仓库中的coze_ws_app示例(audio_processor.c)给出了 AFE 配置的完整参考实现,其关键步骤如下。
3.1 模型加载与 AFE 配置初始化
srmodel_list_t *models = esp_srmodel_init("model"); // 从分区加载语音识别模型 const char *ch_format = INPUT_CH_ALLOCATION; // 麦克风通道分配,如 "MNRM" 表示 2 麦 + 1 回采 audio_recorder.afe_cfg = afe_config_init(ch_format, models, AFE_TYPE_SR, AFE_MODE_HIGH_PERF); if (!audio_recorder.afe_cfg) { ESP_LOGE(TAG, "Failed to initialize AFE config"); return ESP_FAIL; }esp_srmodel_init()从指定分区(如model、models)加载 SR(Speech Recognition)模型,该模型通常烧录在独立分区中;afe_config_init()返回afe_config_t结构体,是后续所有 AFE 参数的总入口;AFE_TYPE_SR与AFE_MODE_HIGH_PERF分别指定前端处理类型与性能模式。
在 baidu_rtc 示例(audio_processor.c)中可以看到同一模式的初始化写法,两者结构一致。
3.2 AEC 回声消除(Acoustic Echo Cancellation)
audio_recorder.afe_cfg->aec_init = true; // 开启回声消除开启 AEC 后,AFE 会消费播放链路(如扬声器输出)的回采参考信号,用于消除扬声器声音被麦克风拾取产生的回声,是免提对话和语音唤醒场景的必选项。在 esp_audio_analyzer_app 的启动日志中可以看到 AEC 生效时的 AFE 内部管线:
I (1459) AFE: AFE Pipeline: [input] -> |AEC(SR_HIGH_PERF)| -> |SE(BSS)| -> [output]3.3 VAD 语音活动检测(Voice Activity Detection)
audio_recorder.afe_cfg->vad_init = true; // 开启 VAD audio_recorder.afe_cfg->vad_mode = VAD_MODE_1; // VAD 模式(0 表示关闭/无模型,1 表示启用) audio_recorder.afe_cfg->vad_min_speech_ms = 64; // 最短语音时长(毫秒) audio_recorder.afe_cfg->vad_min_noise_ms = 1000; // 最短噪声时长(毫秒)VAD 用于区分"有人说话"与"环境噪声",是连续对话模式(无需唤醒词)的关键:ESP_GMF_AFE_EVT_VAD_START/ESP_GMF_AFE_EVT_VAD_END事件即由 VAD 触发。vad_min_speech_ms与vad_min_noise_ms分别控制语音端点检测的灵敏度,过小会误触发,过大则响应迟钝,需结合环境实测调优。
3.4 AGC 自动增益控制(Automatic Gain Control)
audio_recorder.afe_cfg->agc_init = true; // 开启自动增益AGC 自动调整麦克风增益,使远近距离说话时录音音量相对稳定,减少因距离变化导致的音量忽大忽小。在 esp_audio_analyzer_app 的 AFE 参数日志中可以看到 AGC 的完整可调参数:
/********** AGC (Automatic Gain Control) **********/ agc_init: false agc_mode: WAKENET agc_compression_gain_db: 9 agc_target_level_dbfs: 93.5 WakeNet 唤醒词与 MultiNet 命令词
audio_recorder.afe_cfg->wakenet_init = true; // 开启唤醒词检测(WakeNet)- WakeNet:检测用户设定的唤醒词(如
Hi 乐鑫),触发ESP_GMF_AFE_EVT_WAKEUP_START事件; - MultiNet:唤醒后持续识别命令词,命中后通过事件上报
phrase_id、prob与识别文本。
在 coze_ws_app 的事件回调(audio_processor.c)中可以看到完整的 AFE 事件分发逻辑:
case ESP_GMF_AFE_EVT_WAKEUP_START: { esp_gmf_afe_wakeup_info_t *info = event->event_data; ESP_LOGI(TAG, "WAKEUP_START [%d : %d]", info->wake_word_index, info->wakenet_model_index); break; } case ESP_GMF_AFE_EVT_VAD_START: { esp_gmf_afe_vcmd_detection_cancel(obj); // 取消上一次命令检测 esp_gmf_afe_vcmd_detection_begin(obj); // 开始命令词检测 break; } default: { esp_gmf_afe_vcmd_info_t *info = event->event_data; ESP_LOGI(TAG, "Command %d, phrase_id %d, prob %f, str: %s", event->type, info->phrase_id, info->prob, info->str); break; }工作模式与唤醒词的选择在menuconfig中完成。根据 coze_ws_app README_CN,系统支持三种模式:
- 普通模式:无需唤醒词,VAD 检测到说话即开始交互(连续对话);
- 唤醒对话模式:通过唤醒词(默认
Hi 乐鑫,可在menuconfig -> ESP Speech Recognition → use wakenet → Select wake words选择)唤醒; - 按键唤醒模式:通过按键(默认
REC)触发录音。
不同芯片对三种模式的支持度不同(ESP32-S3/P4/ESP32 全支持,ESP32-C3/C6/C5/S2 仅支持按键模式),选型时需对照 README_CN.md 的兼容表确认。
3.6 AFE 的工程化配置入口
对于不直接修改afe_config_t的场景,esp_audio_analyzer_app 提供了完整的 menuconfig 配置入口(Kconfig.projbuild):
menuconfig -> Audio Test Solution Configuration ├─ Enable AFE (总开关,select GMF_AI_AUDIO_INIT_AFE) ├─ Enable AEC (默认开启) ├─ Enable Wakeup (默认关闭) └─ Enable Voice Command (默认关闭)开启 AFE 后,进一步配置硬件相关参数(README_CN.md):
ESP GMF Loader -> GMF Audio Configurations -> GMF AI Audio -> Initialize GMF AI Audio AFE -> Audio Front-End (AFE) ConfigurationFeed Task Setting/Fetch Task Setting:AFE 前后台任务参数(核心、优先级、栈大小);AFE Channel Allocation:麦克风通道分配,使用M(麦克风)、R(回采参考)、N(未使用)字符描述硬件接法,例如2MIC方案的ch0/ch2 为麦克风、ch1 为回采(见下方案例日志)。
开启唤醒词与命令词识别时需要注意资源约束:至少需要 8MB Flash,且必须使用partitions_sr_model.csv分区表(默认partitions.csv不含模型分区),详见 esp_audio_analyzer_app 配置说明。
AFE 初始化完成后,启动日志会打印完整的参数清单与内部管线,可用于快速排查配置错误:
/********** General AFE (Audio Front End) Parameter **********/ pcm_config.total_ch_num: 4 pcm_config.mic_num: 2: [ ch0, ch2 ] pcm_config.ref_num: 1: [ ch1 ] pcm_config.sample_rate: 16000 afe_type: SR afe_mode: HIGH PERF /********** VAD (Voice Activity Detection) **********/ vad_init: false vad_mode: 0 vad_min_speech_ms: 128 vad_min_noise_ms: 1000 /********** WakeNet (Wake Word Engine) **********/ wakenet_init: false四、编码格式支持与编码配置
Audio Recorder 的编码功能用于建立编码音频 Element,官方文档列出支持的编码格式:
| 格式 | 说明 | 典型用途 |
|---|---|---|
| AAC | 高级音频编码 | 高质量语音/音乐存储 |
| AMR-NB | 窄带自适应多速率 | 电话语音(8 kHz) |
| AMR-WB | 宽带自适应多速率 | 高清语音(16 kHz) |
| ADPCM | 自适应差分脉冲编码调制 | 低码率嵌入式存储 |
| WAV | 未压缩 PCM 封装 | 测试、调试、音频分析 |
| OPUS | 现代低延迟有损编码 | 实时语音上传(WebSocket/RTP) |
| G711 | A-law / μ-law 电话语音编码 | 低带宽实时传输 |
编码格式与采样率、声道、位深共同构成了"可配置区域"。以 coze_ws_app 为例(audio_processor.c),录音管线会根据上传格式自动选择 Element 组合:
#if defined(CONFIG_UPLOAD_FORMAT_G711A) || defined(CONFIG_UPLOAD_FORMAT_G711U) static const char *pipeline[] = {"ai_afe", "aud_rate_cvt", "aud_enc"}; #elif defined(CONFIG_UPLOAD_FORMAT_OPUS) static const char *pipeline[] = {"ai_afe", "aud_enc"}; #else static const char *pipeline[] = {"ai_afe"}; #endif编码器参数通过esp_gmf_audio_enc_reconfig_by_sound_info()或esp_gmf_audio_enc_reconfig()下发。例如 G711 编码配置(8 kHz / 单声道 / 16 bit):
esp_gmf_info_sound_t info = { .sample_rates = 8000, .channels = 1, .bits = 16, #if defined CONFIG_UPLOAD_FORMAT_G711A .format_id = ESP_AUDIO_TYPE_G711A, #elif defined CONFIG_UPLOAD_FORMAT_G711U .format_id = ESP_AUDIO_TYPE_G711U, #endif }; esp_gmf_audio_enc_reconfig_by_sound_info(enc_handle, &info);OPUS 编码则给出更细的比特率控制(audio_processor.c):
esp_opus_enc_config_t opus_enc_cfg = ESP_OPUS_ENC_CONFIG_DEFAULT(); opus_enc_cfg.bitrate = 24000; // 24 kbps opus_enc_cfg.channel = 1; opus_enc_cfg.sample_rate = 16000; opus_enc_cfg.enable_vbr = false; // 固定码率coze_ws_app 实际支持的编解码格式为OPUS、G711A、G711U、PCM(默认 OPUS 一帧 60 ms),详见 README_CN.md。选择编码格式的核心权衡是带宽与音质:G711 码率低但音质一般,OPUS 在 16 kHz 下 24 kbps 即可获得良好可懂度,AAC/WAV 则适合本地高质量存储。
五、audio_rec_evt_t 事件交互
audio_rec_evt_t是 Audio Recorder 对外暴露的事件类型,使用户程序能够以事件驱动的方式响应录音状态变化。在仓库源码中,事件回调通过如下接口注册(audio_processor.h):
typedef void (*recorder_event_callback_t)(void *event, void *ctx); esp_err_t audio_recorder_open(recorder_event_callback_t cb, void *ctx);回调函数cb中收到的event即携带audio_rec_evt_t语义的事件数据。结合第三节的事件分发代码可以看到,事件覆盖了:
- 唤醒类:
ESP_GMF_AFE_EVT_WAKEUP_START(唤醒成功,携带wake_word_index与wakenet_model_index)、ESP_GMF_AFE_EVT_WAKEUP_END; - 端点类:
ESP_GMF_AFE_EVT_VAD_START/ESP_GMF_AFE_EVT_VAD_END(一次说话的开始/结束); - 识别类:命令词命中事件(携带
phrase_id、prob、str)与ESP_GMF_AFE_EVT_VCMD_DECT_TIMEOUT(命令检测超时)。
这种事件模型让上层应用(如 AI 对话 Agent)可以完全围绕"唤醒 → 检测 VAD 端点 → 识别命令 → 上传编码音频"的异步流程组织业务逻辑,无需轮询录音状态。
六、应用示例与实践
6.1 官方文档所述示例
官方文档提到speech_recognition/wwe/示例,它演示了:初始化语音识别模型、确定喂给模型的语音数据的样本数量与采样率、检测唤醒词与命令词、以及将语音编码为特定音频格式。该示例在旧版 ESP-ADF(Element 架构)仓库中提供,当前仓库的adf_examples下未包含该目录,可参考下文基于 esp_gmf 新架构的等价实现。
6.2 当前仓库中的实际应用
新架构下,Audio Recorder 的能力在多个 AI Agent 示例中得到完整落地,是理解文档所述 API 的最佳活教材:
- coze_ws_app(扣子智能语音对话):基于 WebSocket 与云端智能体实时语音交互,覆盖"普通模式 / 唤醒对话模式 / 按键模式"三种录音场景,完整实现了 AFE 配置、编码管线选择、事件回调与 FIFO 数据搬运;
- baidu_rtc(百度 RTC 语音对话):将录音管线输出经 FIFO 送入 RTC 通道,同时通过 Mixer 混入远端音频,展示 AFE 输出与多路音频汇流的配合;
- esp_audio_analyzer_app(ESP 音频分析工具):通过 menuconfig 开关 AFE/AEC/唤醒词,将录音流上传网页端做 THD、SNR 等标准化音频测试,并支持 AEC 调试数据落盘分析。
6.3 录音生命周期:open → read → close
从 audio_processor.c 可以归纳出 Audio Recorder 的典型使用流程:
1)打开录音(audio_recorder_open)
esp_err_t audio_recorder_open(recorder_event_callback_t cb, void *ctx);内部完成:创建 FIFO → 初始化 AFE 配置与 AFE Manager → 按上传格式创建编码管线(esp_gmf_pool_new_pipeline)→ 注册输入/输出端口 → 配置编码器 → 创建并运行录音任务。
2)读取编码后数据(audio_recorder_read_data)
esp_err_t audio_recorder_read_data(uint8_t *data, int data_size);应用从 FIFO 中阻塞读取编码后的语音块(esp_gmf_fifo_acquire_read),返回实际拷贝字节数;若data_size小于 FIFO 块有效长度,仅拷贝请求大小并打警告日志。
3)关闭录音(audio_recorder_close)
停止并销毁管线、任务与 FIFO,释放 AFE 配置与 AFE Manager,回调与上下文置空。
三个函数构成完整的生命周期管理,配合事件回调即可实现"常开监听 → 唤醒后录音上传 → 关闭释放"的完整语音交互链路。
6.4 调试手段
- AEC 调试数据落盘:在 coze_ws_app 中启用
CONFIG_ENABLE_RECORDER_DEBUG后,录音原始 PCM 会写入/sdcard/rec3.pcm(默认 30 秒),供离线分析回声消除效果; - 管线事件日志:
recorder_pipeline_event回调打印ESP_GMF_EVT_TYPE_CHANGE_STATE等事件,可观测录音管线的状态机流转; - AFE 参数日志:启动时打印的 AFE 参数清单可用于核对通道分配、VAD/WakeNet/AGC 配置是否按预期生效。
七、API 参考概览
官方文档末尾以include-build-file方式嵌入三份由文档构建系统自动生成的 API 参考:
inc/audio_recorder.inc:Audio Recorder 核心 API(打开、读取、关闭、事件等);inc/recorder_sr.inc:语音识别(SR)相关接口,对应 AFE / WakeNet / MultiNet 能力;inc/recorder_encoder.inc:编码器相关接口,对应各音频格式的编码配置。
这些.inc文件在编译文档时由 Doxygen 从源码注释自动生成(见 Doxyfile),因此源码注释即 API 的第一手权威说明。完整接口清单以构建后的 HTML 文档为准;本文第三、四、六节给出的afe_config_t字段、esp_gmf_audio_enc_reconfig_*()调用与生命周期函数,均与 esp_audio_analyzer_app 和 coze_ws_app 中的实际使用一一对应,可作为查阅 API 细节时的对照实现。
结语
Audio Recorder 是 ESP-ADF 语音识别体系中"最推荐使用"的高层录音模块:它以一条可配置的数据通路同时承载 AFE 前端处理与多格式音频编码,以audio_rec_evt_t事件机制解耦录音状态与业务逻辑。实际项目中,你只需依次完成AFE 参数配置(AEC/VAD/AGC/WakeNet)→ 编码格式选择(AAC/AMR/ADPCM/WAV/OPUS/G711)→ 生命周期管理(open/read/close)三步,即可获得稳定可靠的语音采集能力。仓库中的 coze_ws_app、baidu_rtc 与 esp_audio_analyzer_app 三个工程提供了从简单到复杂的完整参考,是快速上手与二次开发的首选范本。
- 音视频
- 音频处理
- 嵌入式
- 物联网
- 语音
【免费下载链接】esp-adf
Espressif Advanced Development Framework for Multimedia Applications
相关推荐
【免费下载】 Vue-Audio-Recorder:前端录音神器,轻松集成音频录制功能
Vue Audio Recorder:前端录音神器,轻松集成音频录制功能 在Web开发中,用户体验是至关重要的,而实时交互功能如语音记录,为用户提供更直观便捷的
ESP-ADF TCP客户端音频流播放实例详解
ESP ADF TCP客户端音频流播放实例详解 概述 本文将详细介绍ESP ADF(Espressif Audio Development Framework)
音视频音频处理嵌入式物联网语音Vue音频组件实战指南:用vue-audio-recorder打造专业前端录音功能
Vue音频组件实战指南:用vue audio recorder打造专业前端录音功能 你是否曾想过在网页上轻松实现录音功能?无论是语音笔记应用、在线客服系统还是语
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考