Audio Engine 模块

[English]

模块简介

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 格式

注意事项

  1. 采样率限制: 麦克风和扬声器采样率必须为 8000 或 16000 Hz

  2. 帧大小: 帧大小根据采样率自动计算(20ms 一帧) - 8kHz: 160 样本/帧 - 16kHz: 320 样本/帧

  3. AEC 模式: 硬件 AEC 模式需要双通道麦克风输入

  4. 编码器依赖: 选择编码器时,需要确保对应的 ADK 和 Voice Service 编码器已启用

  5. 线程安全: 音频引擎内部使用线程安全机制,但回调函数中应避免长时间阻塞

  6. 资源管理: 使用完毕后必须调用 audio_engine_stop()audio_engine_deinit() 释放资源

  7. 音量持久化: 音量等级会保存到配置中,下次启动时自动恢复