杰理 SDK 文档中心
首页
首页
  • SDK 概述与快速开始

    • SDK 概览与 AC791N 芯片平台
    • 环境搭建与编译指南
    • 烧录与固件升级
    • 工程结构导览
  • 产品方案应用

    • WiFi 摄像头方案
    • WiFi IPC 可视对讲方案
    • WiFi 故事机方案
    • 扫码枪 HID 方案
    • 开发板示例工程
  • 公共应用组件

    • 语音识别 ASR 引擎
    • LLM 与 AI 语音助手接入
    • 摄像头传感器驱动
    • UI 显示框架与驱动
    • USB 主机与设备栈
    • 文件系统与存储管理
    • 系统服务与外设管理
    • 生产测试与射频工具
  • 蓝牙协议栈

    • 经典蓝牙 BR/EDR
    • BLE 低功耗蓝牙
    • 蓝牙 Mesh 网络
    • 蓝牙扩展协议(RCSP/广播/无线麦克风)
  • WiFi 与网络协议栈

    • WiFi 驱动与网络模式
    • lwIP TCP/IP 协议栈
    • 网络安全与加密库
    • 应用层网络协议
    • 流媒体与音视频传输
    • 云平台接入 SDK
    • P2P 远程访问与设备互联
  • 芯片平台与驱动

    • wl82 平台与硬件加速
    • 外设驱动框架
    • 平台配置与固件打包工具
  • 媒体与音频引擎

    • 音频编解码与音源
    • 音效处理引擎
    • 视频与图像处理
  • 操作系统与运行时

    • 实时操作系统与 POSIX 层
    • C/C++ 运行时库
  • 开发资源与文档

    • 文档与规格书
    • 公共示例工程
    • UI 资源工程与打包
    • SDK 辅助工具与脚本

音效处理引擎

本文档介绍 AC79NN SDK 中的音效处理引擎:一个以 EQ(均衡器)与 DRC(动态范围压缩)为核心的、可在线调音的音频效果框架,涵盖模块注册、参数管理、默认参数、引擎打开流程与配置持久化。

Purpose and Scope

本页面聚焦 apps/common/audio_music/ 下的音效处理引擎实现,即 effects_adj.c(在线调音/模块注册)与 audio_eff_default_parm.c(默认参数与引擎打开)所构成的完整音效能力,包括:

  • 音效模块注册表(mlist / aux_list)与 AEID_*/EFF_* 标识体系
  • 各 EQ / DRC 引擎的打开流程(music_eq_front_open、music_drc_fl_open 等)
  • 默认 EQ 系数表与模式参数(music_mode、phone_mode 等)
  • 配置文件 eq_cfg_hw.bin 的持久化机制

以下主题属于兄弟页面,不在本文展开:数字音量控制(audio_digital_vol.c)、EQ 配置加载与扇区工具(eq_config.c / eq_config_new.c)、音乐解码播放流程(pcm_play_api.c / usb_audio_api.c)。本文只描述音效引擎本身的架构与行为。

Overview

音效处理引擎是 AC79NN 音频链路中位于解码器之后、喇叭输出之前的一段可编程 DSP 处理链。它由两个层面组成:

  1. 底层 DSP 引擎:audio_eq(IIR 均衡器,支持多段带通/高通/低通/峰值滤波)与 audio_drc(多频段动态范围压缩,含分频器 crossover),由 audio_dec_eq_open() / audio_dec_drc_open() 创建。
  2. 应用层参数框架:effects_adj.c 维护一张"模块 ID → 功能 group_id 数组"的注册表,把每个可调音效模块(音乐 EQ、动态 EQ、DRC 后扩展 EQ、麦克风 EQ、通话上下行 EQ/DRC、高低音 EQ、整机 DRC 等)映射到一组持久化的参数句柄;audio_eff_default_parm.c 则提供各模式的默认系数与引擎打开函数。

设计意图:把"DSP 算法"与"用户参数"解耦。底层算法引擎是封闭的 DSP 核,应用层通过 struct mode_list 把编译期条件宏(TCFG_*)展开成实际可用的模块集合,再通过 eq_get_filter_info / drc_get_filter_info 回调把参数注入引擎。这样新增一种音效只需在注册表中加一项,并补充默认参数即可,无需改动 DSP 内核。

Architecture

flowchart TD
    subgraph sg_App["应用层 (apps/common/audio_music)"]
        Adj["effects_adj.c<br/>模块注册表 mlist/aux_list<br/>AEID->EFF group_id 映射"]
        DefParm["audio_eff_default_parm.c<br/>默认EQ系数表/模式参数<br/>引擎打开函数"]
        CfgTool["cfg_tool.h / eq_cfg_hw.bin<br/>参数持久化"]
    end

    subgraph sg_Engine["DSP引擎层 (media/audio)"]
        EQ["audio_eq (IIR均衡器)<br/>audio_dec_eq_open()"]
        DRC["audio_drc (动态范围压缩)<br/>audio_dec_drc_open()"]
    end

    subgraph sg_Media["音频链路"]
        Decoder["解码器/音源"] --> EQ
        EQ --> DRC
        DRC --> Out["功放/喇叭输出"]
    end

    Adj -->|"get_group_list / get_index_by_group_id"| DefParm
    DefParm -->|"eq_get_filter_info 回调"| EQ
    DefParm -->|"drc_get_filter_info 回调"| DRC
    CfgTool -->|"读写模式参数"| Adj
    CfgTool -->|"更新默认参数"| DefParm

架构要点:

  • 注册表(effects_adj.c) 是引擎的"目录":struct mode_list mlist[] 中每一项把 AEID_*(模块 ID,如 AEID_MUSIC_EQ)与一组 EFF_*(功能 ID,如 EFF_MUSIC_EQ、EFF_MUSIC_FR_EQ)绑定,同时声明该模块的 EQ 段数(nsection)与 group 数量。这是编译期条件宏展开的结果——每个 TCFG_* 开关决定注册表中是否出现对应模块,因此同一份源码在不同产品配置下自动裁剪音效集合。
  • 默认参数层(audio_eff_default_parm.c) 是引擎的"配方":music_mode[mode_add]、phone_mode[4]、fr_eq_parm、rl_eq_parm、fr_drc_parm 等全局数组保存每个模式的 EQ/DRC 系数;打开函数从这些数组取参并调用底层引擎 API。
  • 参数持久化(eq_cfg_hw.bin):effects_adj.c 中声明配置文件名 mnt/sdfile/res/cfg/eq_cfg_hw.bin,配合 cfg_tool.h 实现设备掉电后仍保留用户调音结果。
  • DSP 引擎(media/audio 库) 为封闭实现,应用层只通过 struct audio_eq_param / struct audio_drc_param 与其交互,param.cb = eq_get_filter_info 回调使引擎能按需拉取当前滤波器系数,支持在线调音(运行时改参)。

模块注册表:mlist 与 aux_list

音效引擎的核心数据结构是 struct mode_list,effects_adj.c 用它声明了两张表:

  • mlist[]:主音效模式(音乐、通话、麦克风、高低音等),覆盖全部音效模块。
  • aux_list[]:当 LINEIN_MODE_SOLE_EQ_EN 开启时,LINEIN(线路输入)场景拥有独立的 EQ/DRC 组合(AEID_AUX_EQ、AEID_AUX_DRC 等),避免与音乐模式互相干扰。
static struct mode_list mlist[] = {

//EQ
#if defined(TCFG_EQ_ENABLE) && TCFG_EQ_ENABLE
    //music fl & fr eq
    {AEID_MUSIC_EQ,      MUSIC_EQ_NSECTION_SPC,    2,    {EFF_MUSIC_EQ, EFF_MUSIC_FR_EQ}},
    ...
//DRC
#if defined(TCFG_DRC_ENABLE) && TCFG_DRC_ENABLE
    //music fl drc
    {AEID_MUSIC_DRC,     0, 5,    {EFF_MUSIC_LOW_DRC, EFF_MUSIC_MID_DRC, EFF_MUSIC_HIGH_DRC, EFF_MUSIC_WHOLE_DRC, EFF_MUSIC_CROSSOVER }},  //最后一个group_id存放分频器

Source: effects_adj.c

字段语义:

字段含义
AEID_*模块 ID(Audio Effect ID),引擎按此 ID 区分实例,如 AEID_MUSIC_EQ、AEID_MIC_DRC0
nsection该模块支持的 EQ 段数;0 表示非 EQ 模块(如 DRC)。段数可以是编译期常量(如 EXT_EQ_NSECTION 5)或运行期变量(如 music_eq_nsection)
group_num该模块包含的 group(功能)数量
group_id[]功能 ID 数组(EFF_*),即参数存储/导出时使用的键;同一模块可含多个声道/频段的 group,如音乐 EQ 的 FL/FR、音乐 DRC 的低/中/高/整机/分频器

设计意图:DRC 模块的 nsection 为 0 且 group 数达 5 个,是因为 DRC 参数按"低/中/高频段 + 整机 + 分频器"组织,最后一个 group_id 专门存放分频器(crossover)系数——这使多频段 DRC 的分频点也能被在线调音工具统一读写。

模块 → 索引查找

get_index_by_group_id(u16 group_id, u8 tar) 遍历 mlist(tar=0)或 aux_list(tar=1),在 group_id[j] 数组中匹配目标功能 ID,返回所在模式项的下标:

int get_index_by_group_id(u16 group_id, u8 tar)
{
    if (!tar) {
        for (int i = 0; i < ARRAY_SIZE(mlist); i++) {
            struct mode_list *list = (struct mode_list *)&mlist[i];
            for (int j = 0; j < list->group_num; j++) {
                if (list->group_id[j] == group_id) {
                    return i;
                }
            }
        }
    }
    ...
}

Source: effects_adj.c

配套的 get_group_list(u16 module_name) 由默认参数文件 extern 引用,用于按模块 ID 取回注册表项——这是"打开引擎前先查注册表"的标准入口。

EQ / DRC 引擎打开流程

audio_eff_default_parm.c 提供一组 *_open() 工厂函数,负责把全局模式参数翻译成 struct audio_eq_param / struct audio_drc_param 并调用底层引擎。以音乐前置 EQ 为例:

struct audio_eq *music_eq_front_open(u32 sample_rate, u8 out_32bit_enable)
{
    struct audio_eq_param param = {0};
    param.channels   = 2;
    param.sr         = sample_rate;
    param.cb         = eq_get_filter_info;
    param.eq_name    = AEID_MUSIC_EQ;
    u8 tar = nor_label;
    param.seg            = music_mode[tar].eq_parm.seg;
    param.global_gain    = music_mode[tar].eq_parm.global_gain;
    ...
    param.max_nsection   = music_mode[tar].eq_parm.seg_num;
    param.nsection       = music_mode[tar].eq_parm.seg_num;
    param.out_32bit      = out_32bit_enable;

    struct audio_eq *eq = audio_dec_eq_open(&param);
    ASSERT(eq);
    return eq;
}

Source: audio_eff_default_parm.c

要点:

  • param.cb = eq_get_filter_info:引擎在需要系数时回调此函数,实现在线调音——改参后引擎可重新拉取滤波器系数而无需重建实例。
  • param.eq_name = AEID_MUSIC_EQ:与注册表模块 ID 对应,使回调能按 ID 定位到正确的参数缓存。
  • param.max_nsection / nsection:来自 music_mode[tar].eq_parm.seg_num,实际段数由用户调音结果决定。
  • tar = nor_label:模式标签(normal label),表明默认使用"普通"模式参数;多模式产品可切换 tar 获得不同音色。
  • 支持 TCFG_EQ_SPLIT_ENABLE 左右声道分离参数(seg_r / global_gain_r),并自动同步 FL/FR 段数以保持双声道一致。

DRC 打开同理,但多出分频器参数注入:

struct audio_drc *music_drc_fl_open(u32 sample_rate, u8 out_32bit_enable)
{
    struct audio_drc_param drc_param = {0};
    drc_param.sr         = sample_rate;
    drc_param.channels   = 2;
    drc_param.drc_name   = AEID_MUSIC_DRC;
    drc_param.cb         = drc_get_filter_info;
    u8 tar = nor_label;
#if (defined(TCFG_AUDIO_MDRC_ENABLE) && TCFG_AUDIO_MDRC_ENABLE != 0)
    drc_param.crossover  = &music_mode[tar].drc_parm.crossover;
    drc_param.nband      = CROSSOVER_EN
#if (TCFG_AUDIO_MDRC_ENABLE == 2)
                          | MORE_BAND_EN
#endif
                          | 0;
#endif
    drc_param.wdrc       = music_mode[tar].drc_parm.wdrc_parm;  //drc
    drc_param.out_32bit  = out_32bit_enable;
#if (defined(TCFG_DRC_SPILT_ENABLE) && TCFG_DRC_SPILT_ENABLE)
    drc_param.spilt          = 1;
    drc_param.start_point    = 0;
#endif
    struct audio_drc *drc = audio_dec_drc_open(&drc_param);
    ASSERT(drc);
    return drc;
}

Source: audio_eff_default_parm.c

关键设计:

  • CROSSOVER_EN / MORE_BAND_EN 位标志组合成 nband,由 TCFG_AUDIO_MDRC_ENABLE 决定 DRC 是单频段、多频段(=1)还是更多频段(=2)。
  • drc_param.spilt = 1; start_point = 0/1:当 TCFG_DRC_SPILT_ENABLE 开启时,FL 声道 DRC 与 FR 声道 DRC(music_drc_fr_open)分开实例化,各自独立参数,实现左右声道独立压缩。
  • 通话场景由 enc_ul_eq_open() 处理,采样率为 8 kHz 时自动切换到窄带模式(mode = 3),否则用宽带模式(mode = 2),对应 phone_mode[4] 的四组参数:0=下行宽带、1=下行窄带、2=上行宽带、3=上行窄带。

默认参数体系

默认参数文件以编译期常量表 + 全局运行期数组两层组织。

EQ 系数常量表

每种音效场景都有一张 struct eq_seg_info 常量表,例如混响音效(麦克风效果)默认 EQ:

const struct eq_seg_info mic_eff_eq_tab[5] = {
    {0, EQ_IIR_TYPE_BAND_PASS, 200,   0, 0.7f},
    {1, EQ_IIR_TYPE_BAND_PASS, 300,   0, 0.7f},
    {2, EQ_IIR_TYPE_BAND_PASS, 400,   0, 0.7f},
    {3, EQ_IIR_TYPE_BAND_PASS, 400,   0, 0.7f},
    {4, EQ_IIR_TYPE_BAND_PASS, 500,   0, 0.7f},
};

Source: audio_eff_default_parm.c

struct eq_seg_info 字段依次为:段序号、滤波器类型(EQ_IIR_TYPE_BAND_PASS 等)、中心频率(Hz)、增益、Q 值。类似的常量表还有:

表名用途段数/频率范围
mic_eff_eq_tab[5]混响/麦克风音效默认 EQ200–500 Hz 带通
phone_eq_tab_normal[]通话下行 EQ200/300/400 Hz
ul_eq_tab_normal[]通话上行(AEC)EQ25 Hz–22 kHz 十段
music_eq2_tab[]动态 EQ 前级 EQ31 Hz–16 kHz 十段
eq_tab_bass_treb[]高低音 EQ(2.1 声道特殊配置)31 Hz–16 kHz 十段

这些表的设计意图:提供一套"听得过去"的出厂音色,同时在 TWO_POINT_X_SPECIAL_CONFIG、TCFG_DYNAMIC_EQ_ENABLE 等宏关闭时整表被裁剪,避免 ROM 浪费。

全局模式参数

struct music_parm_tool_set music_mode[mode_add];   //fl eq & drc
struct phone_parm_tool_set phone_mode[4];          //通话上下行模式
struct music_eq_tool fr_eq_parm[mode_add];         //fr eq
struct music_eq_tool rl_eq_parm[mode_add];         //rl eq
struct nband_drc fr_drc_parm[mode_add];            //fr drc
struct nband_drc rl_drc_parm[mode_add];            //rl drc

Source: audio_eff_default_parm.c

  • music_mode 是核心:每个模式(mode_add 个)携带 eq_parm(段表、段数、总增益)与 drc_parm(wdrc_parm 宽频 DRC + crossover 分频器)。
  • 这些数组在运行时由 audio_eff_default_parm.c 的初始化函数填充(默认值 + 从 eq_cfg_hw.bin 读回的调音值),*_open() 工厂函数再从中取参。
  • 当 TCFG_MIC_EFFECT_ENABLE 开启时,麦克风效果参数(mic_eff->voicechanger_parm 等)在初始化中被赋值默认值,例如 voicechanger_parm.parm.effect_v = 0; shiftv = 56(变声强度/音高偏移),并支持 EFFECT_REVERB_PARM_MAX 组混响参数循环初始化。

核心流程

sequenceDiagram
    participant App as 应用层 (播放/通话)
    participant Adj as effects_adj.c 注册表
    participant Def as audio_eff_default_parm.c
    participant Eng as audio_eq / audio_drc 引擎
    participant Cfg as eq_cfg_hw.bin (cfg_tool)

    App->>Adj: get_group_list(AEID_MUSIC_EQ)
    Adj-->>App: mode_list 项 (nsection/group_id)
    App->>Def: music_eq_front_open(sample_rate, out_32bit)
    Def->>Def: 取 music_mode[nor_label].eq_parm 填充 audio_eq_param
    Def->>Eng: audio_dec_eq_open(&param)
    Eng-->>Def: audio_eq* 句柄
    Def-->>App: 返回 EQ 实例
    loop 播放过程中在线调音
        App->>Cfg: 写入新 EQ 系数
        Cfg-->>Def: 更新 music_mode 参数
        Eng->>Def: eq_get_filter_info() 回调
        Def-->>Eng: 返回最新滤波器系数
    end
    App->>Def: music_drc_fl_open(...) 同理打开 DRC
    Def-->>App: 返回 DRC 实例

端到端数据流:

  1. 播放/通话应用先通过 get_group_list() 向注册表查询模块能力(段数、声道 group)。
  2. 应用调用对应 *_open() 工厂函数;工厂从全局参数(含 eq_cfg_hw.bin 回读的用户调音值)构建 audio_eq_param / audio_drc_param。
  3. 底层引擎打开后,解码音频依次经过 EQ → DRC(多频段)→ 输出功放;EQ/DRC 通过 eq_get_filter_info / drc_get_filter_info 回调随时获取最新系数,实现不中断播放的在线调音。
  4. 用户调音结果经 cfg_tool 写回 mnt/sdfile/res/cfg/eq_cfg_hw.bin,掉电后由初始化流程再次读入。

Configuration Options

音效引擎的可用模块完全由编译期宏裁剪,运行时行为由 eq_cfg_hw.bin 决定。下表整理 effects_adj.c / audio_eff_default_parm.c 中出现的核心配置项:

配置宏类型默认/取值作用
TCFG_EQ_ENABLE编译期宏0/1总开关,控制整个音效引擎文件是否编译(#if defined(TCFG_EQ_ENABLE) && TCFG_EQ_ENABLE)
TCFG_EQ_DIVIDE_ENABLE编译期宏0/1前后声道分离(RL/RR EQ、DRC),用于多声道输出
TCFG_EQ_SPILT_ENABLE编译期宏0/1左右声道(FL/FR)独立 EQ 参数
TCFG_PHONE_EQ_ENABLE编译期宏0/1通话下行(ESCO DL)EQ:AEID_ESCO_DL_EQ
TCFG_AEC_UL_EQ_ENABLE编译期宏0/1通话上行(AEC UL)EQ:AEID_ESCO_UL_EQ
TCFG_DYNAMIC_EQ_ENABLE编译期宏0/1动态 EQ 前级 EQ:AEID_MUSIC_EQ2(10 段)
TCFG_MIC_EFFECT_ENABLE编译期宏0/1麦克风音效(混响/变声),开启后注册 AEID_MIC_EQ0-4、AEID_MIC_DRC0-4
TCFG_AUDIO_OUT_EQ_ENABLE编译期宏0/1高低音 EQ(AEID_HIGH_BASS_EQ,10 段)
TCFG_DRC_ENABLE编译期宏0/1DRC 总开关
TCFG_DRC_SPILT_ENABLE编译期宏0/1DRC 左右声道分离实例化
TCFG_AUDIO_MDRC_ENABLE编译期宏0/1/2多频段 DRC:=1 开分频器(CROSSOVER_EN),=2 再加 MORE_BAND_EN
TCFG_PHONE_DRC_ENABLE编译期宏0/1通话上下行 DRC:AEID_ESCO_DL_DRC / AEID_ESCO_UL_DRC
TCFG_AUDIO_OUT_DRC_ENABLE编译期宏0/1高低音 DRC:AEID_HIGH_BASS_DRC
TCFG_LAST_WHOLE_DRC_ENABLE编译期宏0/1整机末级 DRC:AEID_LAST_WHOLE_DRC
MUSIC_EXT_EQ_AFTER_DRC编译期宏0/1DRC 后扩展 EQ(AEID_MUSIC_EXTEQ,5 段)
MUSIC_EXT_EQ2_AFTER_DRC编译期宏0/1DRC 后第二扩展 EQ(AEID_MUSIC_EXTEQ2,5 段)
LINEIN_MODE_SOLE_EQ_EN编译期宏0/1LINEIN 独立音效(aux_list),与音乐模式隔离
SOUND_TRACK_2_P_X_CH_CONFIG编译期宏0/12.1 声道配置,配合 EQ_SECTION_MAX==32 时 MUSIC_EQ_NSECTION_SPC 取 mSECTION_MAX
EQ_SECTION_MAX编译期宏数值EQ 最大段数上限
EFF_CFG_FILE_NAME字符串"mnt/sdfile/res/cfg/eq_cfg_hw.bin"调音参数持久化文件路径
eff_sdk_name / eff_eq_ver常量数组"AC791N" / {1,0,0,0}配置文件的 SDK 标识与 EQ 版本,用于兼容性校验

所有宏均在 app_config.h / 板级配置中定义;引擎内通过 #if defined(...) 逐项展开注册表,未定义的模块不会出现在 mlist 中,也不会被打开。

API Reference

以下接口为音效引擎对外暴露的核心 API(位于 media/effects_adj.h 声明,effects_adj.c / audio_eff_default_parm.c 实现)。

int get_index_by_group_id(u16 group_id, u8 tar)

在注册表中按功能 ID 查找模块下标。

Parameters:

  • group_id (u16):EFF_* 功能 ID,如 EFF_MUSIC_EQ、EFF_MUSIC_CROSSOVER
  • tar (u8):0 = 查 mlist(主模式),1 = 查 aux_list(LINEIN 模式)

Returns: 命中时返回 mlist/aux_list 下标;未命中返回 -1(由实现尾部 return -1 决定)。

设计意图: 供在线调音工具把"用户看到的音效项"(group_id)翻译成"注册表中的模块",是参数读写的中枢索引。

struct mode_list *get_group_list(u16 module_name)

按模块 ID(AEID_*)返回注册表项指针。

Parameters:

  • module_name (u16):模块 ID,如 AEID_MUSIC_EQ

Returns: struct mode_list *,包含该模块的 nsection、group_num 与 group_id[]。

Throws: 无(返回 NULL 表示模块未注册/宏未开启,调用方需判空)。

struct audio_eq *music_eq_front_open(u32 sample_rate, u8 out_32bit_enable)

打开音乐前置(FL/FR)EQ 引擎实例。

Parameters:

  • sample_rate (u32):采样率(如 48000)
  • out_32bit_enable (u8):输出是否 32 bit 宽位宽

Returns: struct audio_eq * 引擎句柄;内部 ASSERT(eq) 失败即断言停机。

struct audio_eq *enc_ul_eq_open(u32 sample_rate, u8 ch_num)

打开通话上行(AEC 方向)EQ;8 kHz 采样率自动选窄带模式,其余选宽带模式。

Parameters:

  • sample_rate (u32):采样率(8000 → 窄带)
  • ch_num (u8):通道数

Returns: struct audio_eq * 句柄。

struct audio_drc *music_drc_fl_open(u32 sample_rate, u8 out_32bit_enable)

打开音乐 FL 声道 DRC;当 TCFG_AUDIO_MDRC_ENABLE 开启时注入分频器(crossover)与频段标志(CROSSOVER_EN / MORE_BAND_EN)。

Parameters:

  • sample_rate (u32):采样率
  • out_32bit_enable (u8):32 bit 输出使能

Returns: struct audio_drc * 句柄。

struct audio_drc *music_drc_fr_open(u32 sample_rate, u8 out_32bit_enable)

打开音乐 FR 声道 DRC(需 TCFG_DRC_SPILT_ENABLE),参数来自独立数组 fr_drc_parm[tar].wdrc_parm[0],start_point = 1 标识右声道处理起点。

Failure Modes, Edge Cases & Concurrency

  • 配置宏不一致导致引擎缺失:若某 TCFG_* 宏在 effects_adj.c 中被引用但未在工程配置中定义,该模块不会注册;上层若仍按固定 ID 调用 get_group_list 会得到 NULL。设计上用 ASSERT(eq) 在打开失败时立即暴露问题,避免空指针在音频中断中蔓延。
  • EQ 段数边界:music_eq_front_open 中 max_nsection = nsection = seg_num,若持久化文件中的段数超出 EQ_SECTION_MAX 或注册表 nsection,可能导致滤波系数越界。SOUND_TRACK_2_P_X_CH_CONFIG 场景下段数上限提升到 mSECTION_MAX 即是为此类 2.1 声道配置预留。
  • FL/FR 段数同步:TCFG_EQ_SPILT_ENABLE 时取 music_mode 与 fr_eq_parm 段数的较大值回写双方,防止左右声道滤波器段数不一致导致声像偏移。
  • 窄带/宽带切换:enc_ul_eq_open 按采样率 8000 判定窄带,若通话编解码协商出非 8000 的低采样率(如 16 kHz 折中),仍会走宽带参数,属于已知边界。
  • 在线调音并发:EQ/DRC 系数由 eq_get_filter_info / drc_get_filter_info 回调在 DSP 处理线程中拉取,而参数写入来自控制线程;audio_dec_*_open 内部需保证回调读与工具写的原子性(单段结构体赋值 + 段数同步),应用层不应在回调执行中直接改写参数数组。
  • 文件系统不可用:eq_cfg_hw.bin 位于 mnt/sdfile(TF 卡/文件系统挂载点),若设备未挂载文件系统则读取失败,引擎回退到代码内默认参数(*_tab 常量表),保证基本音效可用。

Performance & Operational Notes

  • 代码/常量分区:effects_adj.c 通过 #pragma const_seg(".audio_effect_adj_const") 与 #pragma code_seg(".audio_effect_adj_code") 将音效代码与常量放入独立内存段,便于链接器按需加载/排除,降低常驻 RAM 占用(配合 MEDIA_SUPPORT_MS_EXTENSIONS)。
  • 在线调音热路径:DSP 引擎每帧经回调取系数,因此回调应只做查表返回,不做浮点重算;滤波器系数更新应在打开时或工具写入时预计算。
  • 双声道/多声道成本:TCFG_DRC_SPILT_ENABLE 会为 FL/FR 各开一个 DRC 实例(start_point 0/1 分工),TCFG_EQ_DIVIDE_ENABLE 再为 RL/RR 增加一组,MIPS 消耗随声道数线性增长,量产时需按产品声道配置裁剪宏。
  • 版本兼容:配置文件带 eff_sdk_name("AC791N")与 eff_eq_ver(1.0.0.0),升级固件后若版本不匹配应重新生成配置,防止旧文件字段错位。

Extension Points

  • 新增音效模块:三步走——① 在 media/effects_adj.h 增加 AEID_* 模块 ID 与 EFF_* group ID;② 在 mlist[](或 aux_list[])按 TCFG_* 宏条件注册条目,指定段数与 group 数组;③ 在 audio_eff_default_parm.c 增加默认系数表与 *_open() 工厂函数。底层 DSP 引擎无需改动。
  • 新增模式(mode_add):扩大 music_mode / fr_eq_parm 等数组的模式维,tar 标签即新模式下标,可在打开函数中按 tar 切换参数。
  • 新增音效类型(如环绕声、噪声门、虚拟低音):effects_adj.c 头部注释列出了可选的 demo 头文件(audio_surround_demo.h、audio_noise_gate_demo.h、audio_vbass_demo.h、audio_voice_changer_demo.h、audio_gain_process_demo.h),表明 SDK 预留了将更多 DSP 效果挂入本框架的接口路径。
  • 自定义持久化:EFF_CFG_FILE_NAME 可在板级配置中重定义,将调音文件迁移到其他存储介质。

Related Links

  • effects_adj.c(模块注册表与在线调音)
  • audio_eff_default_parm.c(默认参数与引擎打开)
  • audio_digital_vol.c(数字音量控制,兄弟模块)
  • eq_config.c / eq_config_new.c(EQ 配置加载)
  • pcm_play_api.c(PCM 播放链路)
  • 媒体/音频目录文档:音频链路总体架构(7.1 音频播放)、EQ 配置工具(7.2 相关子页)
Prev
音频编解码与音源
Next
视频与图像处理