☰
ESP-ADF Audio Recorder 录音 API 详解:语音前端处理(AFE)与音频编码一体化
2026/10/14 2:10:51 网站建设 项目流程
  • 音视频
  • 音频处理
  • 嵌入式
  • 物联网
  • 语音

【免费下载链接】esp-adf

Espressif Advanced Development Framework for Multimedia Applications

项目地址:https://gitcode.com/gh_mirrors/es/esp-adf
点击查看免费下载

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: 9

3.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) Configuration
  • Feed 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)
G711A-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

项目地址:https://gitcode.com/gh_mirrors/es/esp-adf
点击查看免费下载
上一篇:Presto 0.100 版本解析:System Connector 架构重构与一批新 SQL 函数、配置变更详解
下一篇:如何快速实现create-react-native-app离线功能:打造可靠移动应用开发环境

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询