Audio Engine 模块
模块简介
Audio Engine 是基于 bk_voice_service 基础设施构建的高级音频引擎模块,提供简化的音频启动/停止操作 API。该模块封装了复杂的音频处理流程,包括音频采集、编码、解码、AEC(回声消除)、NS(噪声抑制)等功能,为上层应用提供统一的音频处理接口。
核心特性
简化 API: 易于使用的
audio_engine_start()和audio_engine_stop()函数完整错误处理: 详细的错误代码,便于调试
灵活配置: 支持多种麦克风/扬声器类型和音频处理功能
线程安全: 正确的资源管理和状态跟踪
回调支持: 事件和数据读取回调,用于实时音频处理
音量控制: 支持音量调节和持久化存储
提示音支持: 支持提示音播放功能(可选)
模块架构
Audio Engine 模块架构如下:
应用层 (Application)
↓
Audio Engine API (audio_engine.h)
↓
Voice Service (bk_voice_service)
↓
Audio Pipeline (音频管道)
↓
硬件层 (ADC/DAC)
工作流程
初始化流程
Audio Engine 的初始化流程如下:
audio_engine_init()
↓
1. 音量初始化 (audio_engine_volume_init)
- 从配置读取音量等级
- 计算音量增益表
↓
2. 构建配置结构 (audio_engine_cfg_t)
- 采样率配置
- 编码/解码类型
- AEC/NS 配置
- PA 控制配置
- 回调函数设置
↓
3. 启动音频引擎 (audio_engine_start)
- 初始化 Voice Service
- 配置麦克风流
- 配置扬声器流
- 配置编码器/解码器
- 配置 AEC/NS 算法
- 启动音频服务
↓
4. 初始化提示音(可选)
- audio_engine_prompt_tone_init
↓
初始化完成
启动流程
audio_engine_start() 详细流程:
1. 参数验证
- 检查配置指针有效性
- 验证采样率(8000 或 16000)
- 检查是否已启动
↓
2. 配置 Voice Service
- 麦克风配置 (onboard_mic_stream_cfg_t)
* ADC 采样率
* 数字增益/模拟增益
* 帧大小(20ms)
* AEC 模式(硬件/软件)
- 编码器配置
* G.711A/U: 160/320 字节帧
* G.722: 80/160 字节帧
* OPUS: 默认配置
* PCM: 原始数据
- 解码器配置
* 对应编码器的解码配置
- 扬声器配置 (onboard_speaker_stream_cfg_t)
* DAC 采样率
* PA 控制(GPIO、延迟等)
* 数字增益/模拟增益
- AEC 配置(如果启用)
* AEC 模式选择
* 多路输出端口
- EQ 配置(如果启用)
↓
3. 初始化 Voice Service
- bk_voice_init(&voice_cfg)
↓
4. 初始化 Voice Read Service
- bk_voice_read_init()
- 注册读取回调
↓
5. 初始化 Voice Write Service
- bk_voice_write_init()
↓
6. 启动 Voice Service
- bk_voice_start()
- bk_voice_read_start()
- bk_voice_write_start()
↓
7. ASR 初始化(如果启用)
- 配置 ASR 服务
- 启动 ASR
↓
启动完成
音频数据流
上行音频流(麦克风 → 网络):
麦克风采集 (ADC)
↓
音频预处理 (AEC/NS)
↓
音频编码 (G.711/G.722/OPUS/PCM)
↓
读取回调 (audio_engine_read_callback_t)
↓
network_transfer
↓
网络发送
下行音频流(网络 → 扬声器):
网络接收
↓
audio_engine_write_data()
↓
音频解码 (G.711/G.722/OPUS/PCM)
↓
音频后处理 (EQ)
↓
扬声器播放 (DAC)
重要接口
初始化接口
/**
* @brief 初始化并启动音频引擎
*
* @param cfg 音频引擎配置结构指针
* @return int
* - 0 (AUDIO_ENGINE_SUCCESS): 成功
* - < 0: 错误代码(见 audio_engine_err_t)
*/
int audio_engine_start(audio_engine_cfg_t *cfg);
/**
* @brief 停止音频引擎并清理资源
*
* @return int
* - 0: 成功
* - < 0: 错误代码
*/
int audio_engine_stop(void);
/**
* @brief 初始化音频引擎(使用默认配置)
*
* 该函数使用 Kconfig 配置的默认参数自动初始化音频引擎
*
* @return int
* - 0: 成功
* - < 0: 错误代码
*/
int audio_engine_init(void);
/**
* @brief 反初始化音频引擎
*
* @return int
* - 0: 成功
*/
int audio_engine_deinit(void);
数据操作接口
/**
* @brief 向扬声器写入音频数据
*
* @param data 音频数据指针
* @param size 音频数据大小(字节)
* @param timeout_ms 超时时间(毫秒)
* @return int
* - 0: 成功
* - < 0: 错误代码
*/
int audio_engine_write_data(const uint8_t *data, uint32_t size, uint32_t timeout_ms);
/**
* @brief 检查音频引擎是否正在运行
*
* @return bool
* - true: 音频引擎正在运行
* - false: 音频引擎未运行
*/
bool audio_engine_is_running(void);
配置和查询接口
/**
* @brief 获取音频引擎编码器类型
*
* @return audio_enc_type_t 编码器类型
*/
audio_enc_type_t audio_engine_get_encoder_type(void);
/**
* @brief 获取音频引擎解码器类型
*
* @return audio_dec_type_t 解码器类型
*/
audio_dec_type_t audio_engine_get_decoder_type(void);
/**
* @brief 字符串转编码器类型
*
* @param enc_str 编码器类型字符串 ("PCM", "G711A", "G711U", "G722", "OPUS")
* @return audio_enc_type_t 编码器类型枚举值
*/
audio_enc_type_t audio_engine_str_to_enc_type(const char *enc_str);
/**
* @brief 字符串转解码器类型
*
* @param dec_str 解码器类型字符串 ("PCM", "G711A", "G711U", "G722", "OPUS")
* @return audio_dec_type_t 解码器类型枚举值
*/
audio_dec_type_t audio_engine_str_to_dec_type(const char *dec_str);
/**
* @brief 获取音频引擎错误字符串
*
* @param err 错误代码
* @return const char* 错误描述字符串
*/
const char *audio_engine_err_to_str(int err);
音量控制接口
/**
* @brief 增加音量
*/
void audio_engine_volume_increase(void);
/**
* @brief 减少音量
*/
void audio_engine_volume_decrease(void);
数据结构
audio_engine_cfg_t: 音频引擎配置结构
typedef struct {
uint32_t mic_sample_rate; // 麦克风采样率(8000 或 16000)
uint32_t spk_sample_rate; // 扬声器采样率(8000 或 16000)
/* 音频处理 */
uint8_t aec_enable; // 0: 禁用, 1: 启用 AEC
uint8_t eq_enable; // 0: 禁用, 1: 单声道 EQ, 2: 立体声 EQ
/* 编码/解码 */
audio_enc_type_t enc_type; // 编码类型
audio_dec_type_t dec_type; // 解码类型
/* 音频增益 */
uint8_t dig_gain; // DAC 数字增益
uint8_t ana_gain; // DAC 模拟增益
/* PA 控制 */
uint8_t pa_enable; // 0: 禁用, 1: 启用 PA 控制
uint8_t pa_gpio; // PA 控制 GPIO 编号
uint8_t pa_on_level; // PA 开启电平
uint32_t pa_on_delay; // PA 开启延迟(毫秒)
uint32_t pa_off_delay; // PA 关闭延迟(毫秒)
/* 回调函数 */
voice_event_callback_t event_cb; // 语音事件回调
audio_engine_read_callback_t read_cb; // 音频读取回调
void *user_data; // 用户数据
} audio_engine_cfg_t;
audio_engine_err_t: 错误代码枚举
typedef enum {
AUDIO_ENGINE_SUCCESS = 0, // 成功
AUDIO_ENGINE_ERR_INIT_FAILED = -1, // 初始化失败
AUDIO_ENGINE_ERR_INVALID_PARAM = -2, // 无效参数
AUDIO_ENGINE_ERR_NOT_STARTED = -3, // 音频引擎未启动
AUDIO_ENGINE_ERR_VOICE_INIT = -4, // Voice 初始化失败
AUDIO_ENGINE_ERR_READ_INIT = -5, // Voice Read 初始化失败
AUDIO_ENGINE_ERR_WRITE_INIT = -6, // Voice Write 初始化失败
AUDIO_ENGINE_ERR_VOICE_START = -7, // Voice 启动失败
AUDIO_ENGINE_ERR_READ_START = -8, // Voice Read 启动失败
AUDIO_ENGINE_ERR_WRITE_START = -9, // Voice Write 启动失败
AUDIO_ENGINE_ERR_VOICE_STOP = -10, // Voice 停止失败
AUDIO_ENGINE_ERR_READ_STOP = -11, // Voice Read 停止失败
AUDIO_ENGINE_ERR_WRITE_STOP = -12, // Voice Write 停止失败
AUDIO_ENGINE_ERR_ASR_INIT = -13, // ASR 初始化失败
AUDIO_ENGINE_ERR_ASR_START = -14, // ASR 启动失败
AUDIO_ENGINE_ERR_ASR_STOP = -15, // ASR 停止失败
} audio_engine_err_t;
主要宏定义
Kconfig 配置宏
基本配置:
// 启用音频引擎
CONFIG_BK_AUDIO_ENGINE=y
// 音频帧时长(毫秒)
CONFIG_AE_AUDIO_FRAME_DURATION_MS=20 // 范围: 20-60
// ADC 采样率
CONFIG_AE_AUDIO_ADC_SAMP_RATE=16000
// DAC 采样率
CONFIG_AE_AUDIO_DAC_SAMP_RATE=16000
编码器配置:
// 编码器类型选择(互斥)
CONFIG_AE_AUDIO_ENCODER_G722=y // G.722 编码
// 或
CONFIG_AE_AUDIO_ENCODER_G711A=y // G.711A 编码
// 或
CONFIG_AE_AUDIO_ENCODER_G711U=y // G.711U 编码
// 或
CONFIG_AE_AUDIO_ENCODER_OPUS=y // OPUS 编码
// 或
CONFIG_AE_AUDIO_ENCODER_PCM=y // PCM(无编码)
// 编码器类型字符串(自动生成)
CONFIG_AE_AUDIO_ENCODER_TYPE="G722" // 或 "G711A", "G711U", "OPUS", "PCM"
解码器配置:
// 解码器类型选择(互斥)
CONFIG_AE_AUDIO_DECODER_G722=y // G.722 解码
// 或
CONFIG_AE_AUDIO_DECODER_G711A=y // G.711A 解码
// 或
CONFIG_AE_AUDIO_DECODER_G711U=y // G.711U 解码
// 或
CONFIG_AE_AUDIO_DECODER_OPUS=y // OPUS 解码
// 或
CONFIG_AE_AUDIO_DECODER_PCM=y // PCM(无解码)
// 解码器类型字符串(自动生成)
CONFIG_AE_AUDIO_DECODER_TYPE="G722" // 或 "G711A", "G711U", "OPUS", "PCM"
提示音配置 (可选):
// 启用提示音支持
CONFIG_AE_SUPPORT_PROMPT_TONE=y
// 提示音源选择
CONFIG_AE_PROMPT_TONE_SOURCE_ARRAY=y // 数组存储
// 或
CONFIG_AE_PROMPT_TONE_SOURCE_VFS=y // 文件系统存储
// 提示音解码器类型
CONFIG_AE_PROMPT_TONE_DECODER_WAV=y // WAV 格式
// 或
CONFIG_AE_PROMPT_TONE_DECODER_MP3=y // MP3 格式
// 或
CONFIG_AE_PROMPT_TONE_DECODER_PCM=y // PCM 格式
注意事项
采样率限制: 麦克风和扬声器采样率必须为 8000 或 16000 Hz
帧大小: 帧大小根据采样率自动计算(20ms 一帧) - 8kHz: 160 样本/帧 - 16kHz: 320 样本/帧
AEC 模式: 硬件 AEC 模式需要双通道麦克风输入
编码器依赖: 选择编码器时,需要确保对应的 ADK 和 Voice Service 编码器已启用
线程安全: 音频引擎内部使用线程安全机制,但回调函数中应避免长时间阻塞
资源管理: 使用完毕后必须调用
audio_engine_stop()和audio_engine_deinit()释放资源音量持久化: 音量等级会保存到配置中,下次启动时自动恢复