EQ/DRC 与音效处理
EQ/DRC 与音效处理是 AD16N 音频子系统中负责对音频信号进行频响修正、动态范围压缩及人声/音乐美化效果处理的核心能力层。本文档基于 audio_eq.h、audio_eq_api.c、effects_adj.h 等实际源码,完整阐述 EQ/DRC 的效果 ID 体系、EQ 处理链路、参数切换机制与在线调试流程。
Purpose and Scope
本文档覆盖 AD16N 音频子系统中与 EQ(均衡器)、DRC(动态范围压缩)及其他音效处理相关的完整能力,包括:
- 效果 ID 体系(
effects_adj.h):MIC、PHONE/AEC、MUSIC、AUX 各通路的 EQ、DRC、混响、变声、噪声门等效果枚举; - EQ 处理链路(
audio_eq.h/audio_eq_api.c):EQ 运行结构、EQ API 操作集、EQ 的初始化/运行/释放流程; - EQ 参数模式切换(
eq_mode_sw)与在线 EQ 助手参数更新(eq_online_sw); - EQ 配置产物(
eq_cfg.bin、dir_eq目录、eqbin2dir.bat转换脚本)。
以下内容属于兄弟页面,不在本文档展开:音频解码器(Decoder)、DAC/ADC 硬件通路、音频流管理(sound_mge)、降噪/AEC 算法本体。DRC 与 EQ 共享同一套效果框架,故 DRC 的 ID 定义与挂载方式在此一并说明,但其算法库(audio_eq_lib.a 预编译库)内部实现不在此展开。
Overview
在嵌入式音频系统中,扬声器/麦克风/功放的频响曲线不平直、音量过大导致削波、人声与伴奏比例失衡等问题都需要在数字域进行补偿与美化。AD16N 通过一套统一的"效果对象"(EFFECT_OBJ)框架,把 EQ、DRC、混响、变声、噪声门等效果串联进音频数据流中:每个效果都是一个可插入 sound_out_obj 链表的节点,输入 PCM 短整型数据、输出处理后的 PCM 数据。
EQ/DRC 处理的几个关键设计点:
- 统一效果 ID 体系:每个效果(EQ 段、DRC、混响等)都有唯一的 16 位 ID(如
EFF_MUSIC_EQ = 0x2001),按通路(MIC/PHONE/AEC/MUSIC/AUX)分组,便于调音工具与固件按 ID 定位参数。 - EQ 段(segment)模型:EQ 由最多
EQ_SECTION_MAX(10)个 IIR 滤波段组成,每段指定滤波器类型(如带通)、中心频率、增益与 Q 值;music_eq_tool结构体承载整组 EQ 参数。 - 参数在线热切换:
EQ_CMD_SWITCH_TAB命令允许在运行中替换系数表(切模式/调音),配合 fade-in/fade-out 防爆音。 - 预编译库 + 薄封装:EQ 算法本体以
audio_eq_lib.a预编译库提供(get_eq_context()返回操作集),SDK 侧仅提供挂载、参数管理与在线调试封装,兼顾性能与灵活性。
flowchart TD
subgraph sg_App["应用层"]
APP["应用/调音工具"]
MUSIC_TOOL["music_eq_tool_online<br/>(在线EQ参数)"]
end
subgraph sg_Api["EQ 封装层 (audio_eq_api.c)"]
LINK["link_eq_sound()"]
EQMODE["eq_mode_sw()"]
EQONLINE["eq_online_sw()"]
EQAPI["eq_api() 创建EQ句柄"]
end
subgraph sg_Framework["效果框架 (audio_eq.h)"]
EHDL["EQ_HDL"]
EOBJ["EFFECT_OBJ + sound_in_obj"]
EIO["EQ_IO_CONTEXT"]
EBUFF["EQ_BUFF (含fade)"]
end
subgraph sg_Lib["预编译库 (audio_eq_lib.a)"]
OPS["EQ_STUCT_API<br/>need_buf/open/run/config"]
HW["hw_eq 硬件EQ"]
end
subgraph sg_Cfg["参数存储"]
CFGBIN["eq_cfg.bin"]
DIR["dir_eq 目录"]
BATCH["eqbin2dir.bat"]
end
APP --> LINK
APP --> EQMODE
APP --> EQONLINE
MUSIC_TOOL --> LINK
MUSIC_TOOL --> EQMODE
LINK --> EQAPI
EQAPI --> EHDL
EHDL --> EOBJ
EHDL --> EIO
EOBJ --> EBUFF
EQAPI --> OPS
OPS --> HW
EQMODE --> CFGBIN
CFGBIN --> DIR
BATCH --> DIR
EQONLINE --> OPS
说明:EQ 封装层负责把
music_eq_tool_online中的参数通过eq_api()创建为EQ_HDL句柄并挂入音效链表;运行时EQ_STUCT_API操作集指向预编译库中的算法实现;模式切换时从eq_cfg.bin读取参数组并下发EQ_CMD_SWITCH_TAB。
效果 ID 体系(effects_adj.h)
所有音效的枚举 ID 定义在 effects_adj.h,按"通路 + 效果类型"编码:
| ID 区间 | 通路 | 典型效果 |
|---|---|---|
| 0x1001 ~ 0x101a | MIC(麦克风) | EQ0~EQ4、DRC0~DRC4、板混响、回声、噪声门、啸叫抑制、变声 |
| 0x1101 ~ 0x1108 | PHONE / AEC | 宽带/窄带 EQ 与 DRC(通话场景) |
| 0x2001 ~ 0x2069 | MUSIC(音乐) | 主 EQ、低/中/高/整段 DRC、分频器、动态 EQ、虚拟低音、环绕、声道交换 |
| 0x2030 ~ 0x2032 | AUX(Line-in) | 独立 EQ、DRC、增益 |
示例(节选自 effects_adj.h#L55-L65):
EFF_MUSIC_EQ = 0x2001,
EFF_MUSIC_LOW_DRC = 0x2002,
EFF_MUSIC_FR_EQ = 0x2003,
EFF_MUSIC_MID_DRC = 0x2011,
EFF_MUSIC_HIGH_DRC = 0x2012,
EFF_MUSIC_WHOLE_DRC = 0x2013,
EFF_MUSIC_CROSSOVER = 0x2014,
EFF_MUSIC_DYNAMIC_EQ = 0x2015,
EFF_MUSIC_EQ2 = 0x2016,
EFF_MUSIC_GAIN = 0x2017,
设计意图:ID 前缀(0x10xx 麦克风 / 0x11xx 通话 / 0x20xx 音乐)让调音工具(EQ 在线调试助手)无需理解内部实现即可按场景定位效果;2.1/2.2 声道场景中
EFF_MUSIC_RL_*、EFF_MUSIC_RR_*、EFF_MUSIC_FR_*系列(0x2005~0x2069)为每个物理声道单独挂 EQ/DRC/分频器,体现多声道独立调音能力。
除效果 ID 外,该头文件还定义了在线调试协议相关常量:
EFF_ONLINE_PACKET:{cmd, data[64]}结构,承载在线调音命令与 64 个 int 参数;EFF_CFG_FILE_ID = 0x3:音效配置项源文件 ID;- 命令字:
EFF_CMD_INQUIRE(0x4)查询、EFF_CMD_GETVER(0x5)版本、EFF_CMD_FILE_SIZE(0xB)文件大小、EFF_CMD_FILE(0xC)文件内容、EFF_CMD_CHANGE_MODE(0xE)切模式、EFF_CMD_RESYNC_PARM_BEGIN/END(0x30/0x28)参数重同步边界。
EQ 数据模型与 API 结构
EQ 的核心数据结构定义在 audio_eq.h,其设计围绕"参数表可热替换"展开:
| 结构体 | 职责 |
|---|---|
EQ_PARA_STRUCT | 运行参数:段表指针(seg/next_seg)、全局增益(global_gain)、采样率、最大段数、声道数 |
EQ_STUCT_API | 算法操作集:need_buf 计算内存、open 打开实例、run 处理 PCM、config 动态配置 |
EQ_BUFF | 运行缓冲:IO 上下文、操作集、参数、fade 对象、系数缓存表 |
EQ_UPDATE | 更新命令载荷:新段表指针 + 全局增益 + EQ 模式 |
EQ_HDL | 效果句柄:内嵌 EFFECT_OBJ、sound_in_obj、EQ_IO_CONTEXT、EQ_BUFF |
music_eq_tool | 调音参数载体:全局增益 + 段数 + 使能段 + 段表(最多 10 段) |
关键常量(audio_eq.h#L7-L19):
#define EQ_MAX_POINT (128)
#define EQ_SECTION_MAX 10
#define EQ_COEFF_BASE (0x2F0000)
#define EQ_RUN_MODE NORMAL
#define EQ_IN_FORMAT DATI_SHORT
#define EQ_OUT_FORMAT DATO_SHORT
#define EQ_DATA_IN_MODE SEQUENCE_DAT_IN
#define EQ_DATA_OUT_MODE SEQUENCE_DAT_OUT
#define B_EQ_START BIT(0)
#define B_EQ_FADE_IN BIT(1)
#define B_EQ_FADE_OUT BIT(2)
设计意图:EQ 输入/输出格式固定为
DATI_SHORT/DATO_SHORT(16 位 PCM),运行模式为NORMAL,数据按SEQUENCE_DAT_IN/OUT顺序组织——这意味着 EQ 直接内嵌在标准音频链路中,不改变前后级的数据格式约定。B_EQ_FADE_IN/OUT标志配合EQ_BUFF内的sound_fade_obj实现参数切换时的渐变,避免系数跳变产生爆音。
EQ 操作集 EQ_STUCT_API 的四个函数指针(audio_eq.h#L36-L41)是整个 EQ 的抽象边界:
typedef struct _EQ_STUCT_API_ {
unsigned int(*need_buf)(int max_eq_seg, int ch);
int *(*open)(unsigned int *ptr, EQ_PARA_STRUCT *para, EQ_IO_CONTEXT *rsio);
int (*run)(unsigned int *ptr, short *inbuf, int len);
u32(*config)(void *work_buf, u32 cmd, void *parm);
} EQ_STUCT_API;
need_buf:按最大段数与声道数返回所需 RAM(源码注释:单路 EQ 需 344 字节;多路每路需 344 + 64×最大段数 字节);open:初始化实例,返回工作缓冲;run:处理一段shortPCM 数据;config:执行EQ_CMD_SWITCH_TAB(切换系数表)或EQ_GET_CURR_MODE(查询当前模式)。
EQ 处理链路实现(audio_eq_api.c)
audio_eq_api.c 在 AUDIO_HW_EQ_EN 宏开启时编译,是 EQ 在 SDK 中的唯一封装层。它同时定义了两个编译期常量(audio_eq_api.c#L16-L18):
const int config_hw_single_eq = 1; // 仅使用一路EQ,省RAM
const int config_eq_fade_enbale = 1; // 使能EQ淡入淡出
const int config_eq_fade_step = 128; // 淡入淡出步长
默认在线调音参数 music_eq_tool_online(audio_eq_api.c#L20-L36)预置了 10 个 1/3 倍频程带通滤波器段(31Hz~16kHz,Q=0.7),增益全为 0——即默认平直响应:
struct music_eq_tool music_eq_tool_online = {
.global_gain = 0x0,
.seg_num = EQ_SECTION_MAX,
.enable_section = 0x0,
.seg = {
{0, EQ_IIR_TYPE_BAND_PASS, 31, 0, 0.7f},
{1, EQ_IIR_TYPE_BAND_PASS, 62, 0, 0.7f},
{2, EQ_IIR_TYPE_BAND_PASS, 125, 0, 0.7f},
{3, EQ_IIR_TYPE_BAND_PASS, 250, 0, 0.7f},
{4, EQ_IIR_TYPE_BAND_PASS, 500, 0, 0.7f},
{5, EQ_IIR_TYPE_BAND_PASS, 1000, 0, 0.7f},
{6, EQ_IIR_TYPE_BAND_PASS, 2000, 0, 0.7f},
{7, EQ_IIR_TYPE_BAND_PASS, 4000, 0, 0.7f},
{8, EQ_IIR_TYPE_BAND_PASS, 8000, 0, 0.7f},
{9, EQ_IIR_TYPE_BAND_PASS, 16000, 0, 0.7f},
},
};
设计意图:段表条目为
{段序号, 滤波器类型, 中心频率, 增益, Q值}。预置 10 段等间隔倍频程带通 + 0 增益,保证"出厂默认无音染";enable_section=0配合段级使能位可在不重建段表的情况下关闭部分滤波段,节省算力。
链路挂载:link_eq_sound()
link_eq_sound()(audio_eq_api.c#L40-L68)把 EQ 实例插入 sound_out_obj 输出链表:
void *link_eq_sound(void *p_sound_out, void *p_dac_cbuf, void **pp_effect, u32 sr, u8 ch)
{
sound_out_obj *p_next_sound = 0;
sound_out_obj *p_curr_sound = p_sound_out;
if (NULL == pp_effect) {
log_info("eq init err\n");
return p_curr_sound;
}
/* EQ参数配置 */
EQ_PARA_STRUCT para;
para.sample_rate = sr;
para.ch = ch;
para.seg = music_eq_tool_online.seg;
para.global_gain = music_eq_tool_online.global_gain;
para.max_nsection = music_eq_tool_online.seg_num;
p_curr_sound->effect = eq_api(p_curr_sound->p_obuf, ¶, (void **)&p_next_sound);
if (NULL != p_curr_sound->effect) {
*pp_effect = p_curr_sound->effect;
p_curr_sound->enable |= B_DEC_EFFECT;
p_curr_sound = p_next_sound;
p_curr_sound->p_obuf = p_dac_cbuf;
log_info("audio eq init succ\n");
} else {
log_info("audio eq init fail\n");
}
return p_curr_sound;
}
执行流程:用当前采样率/声道数/在线参数构造 EQ_PARA_STRUCT → 调用 eq_api() 创建效果对象 → 把 p_curr_sound->effect 指向新 EQ 对象并置 B_DEC_EFFECT 位 → 将下一级输出缓冲指向 DAC 环形缓冲,形成"解码器 → EQ → DAC"的串接。EQ 初始化失败时返回原节点,系统仍可无 EQ 出声(容错设计)。
实例创建:eq_api()
eq_api()(audio_eq_api.c#L146-L172)是 EQ 实例的构造函数,展示了一个效果对象如何被组织:
static void *eq_api(void *obuf, EQ_PARA_STRUCT *p_para, void **ppsound)
{
u32 buff_len, i;
EQ_STUCT_API *ops = (EQ_STUCT_API *)get_eq_context();
buff_len = ops->need_buf(p_para->max_nsection, p_para->ch);
EQ_HDL *p_eq_hdl = eq_hld_malloc(buff_len);
if (NULL == p_eq_hdl) {
log_error("eq malloc fail, need buff_len:%d\n", buff_len);
return 0;
}
memset((void *)p_eq_hdl, 0, buff_len);
ops->open((unsigned int *)&p_eq_hdl->buff, p_para, (void *)&p_eq_hdl->io);
EFFECT_OBJ *p_eq_obj = &p_eq_hdl->obj;
p_eq_hdl->io.priv = &p_eq_obj->sound;
p_eq_hdl->io.output = sound_output;
p_eq_hdl->si.ops = ops;
p_eq_hdl->si.p_dbuf = &p_eq_hdl->buff;
p_eq_hdl->obj.p_si = &p_eq_hdl->si;
p_eq_hdl->obj.run = eq_run_api;
p_eq_hdl->obj.sound.p_obuf = obuf;
*ppsound = &p_eq_obj->sound;
return p_eq_obj;
}
关键点:
get_eq_context()返回预编译库中的EQ_STUCT_API操作集(need_buf/open/run/config);need_buf计算所需内存,eq_hld_malloc()(内部走my_malloc(malloc_size, MM_EQ))从 EQ 内存池分配——MM_EQ说明 EQ 有独立内存分区管理;ops->open()完成算法实例初始化,EQ_IO_CONTEXT.output指向sound_output,使 EQ 处理完的数据能继续向后级输出;EQ_HDL把"算法缓冲(p_dbuf)+ 操作集(ops)+ 运行回调(run)+ 输出对象(sound)"统一封装为EFFECT_OBJ,从而可以被标准音频框架调度。
运行时回调:eq_run_api()
static int eq_run_api(void *hld, short *inbuf, int len)
{
sound_in_obj *p_si = (sound_in_obj *)hld;
EQ_STUCT_API *ops = (EQ_STUCT_API *)p_si->ops;
return ops->run(p_si->p_dbuf, inbuf, len);
}
每次音频帧到来,框架调用 EFFECT_OBJ.run,即 eq_run_api:取出句柄内的操作集与算法缓冲,转调库中的 run 处理 len 个 short 采样。这是整个 EQ 处理的热路径,不涉及锁与动态分配,保证实时性。
参数切换与在线调音
EQ 参数支持两种运行时更新途径,都通过 EQ_STUCT_API.config(..., EQ_CMD_SWITCH_TAB, &update_parm) 下发新段表。
模式切换:eq_mode_sw()
eq_mode_sw()(audio_eq_api.c#L89-L124)用于切换预置 EQ 模式(例如"流行/摇滚/古典"):
void eq_mode_sw(void *parm)
{
EFFECT_OBJ *e_obj = (EFFECT_OBJ *)parm;
if (NULL == e_obj) {
return ;
}
/* 切换eq参数组 */
eq_mode++;
if (eq_mode >= get_eq_mode_total_num()) {
eq_mode = 0;
}
/* 获取名字 */
void *ret_name = NULL;
ret_name = get_eq_mode_name_api(eq_mode);
log_info("now eq_mode is %d , eq_mode_name is %s ", eq_mode, ret_name);
/* 读取eq_cfg.bin文件,获取对应eq参数组参数 */
u32 ret = ext_eff_file_analyze_api(eq_mode, &music_eq_tool_online, sizeof(struct music_eq_tool));
if (ret != 0) {
log_info("ext_eff_file_analyze ret %d ", ret);
return ;
}
/* 配置eq */
EQ_UPDATE update_parm;
memset(&update_parm, 0, sizeof(update_parm));
update_parm.seg = music_eq_tool_online.seg;
update_parm.global_gain = music_eq_tool_online.global_gain;
sound_in_obj *p_src_si = e_obj->p_si;
EQ_STUCT_API *p_ops = p_src_si->ops;
p_ops->config(p_src_si->p_dbuf, EQ_CMD_SWITCH_TAB, (void *)&update_parm);
}
流程:模式号 eq_mode 循环递增 → 通过 get_eq_mode_name_api() 获取模式名(用于日志/UI)→ ext_eff_file_analyze_api() 从 eq_cfg.bin 解析对应参数组写入 music_eq_tool_online → 构造 EQ_UPDATE 下发 EQ_CMD_SWITCH_TAB。eq_mode 是全局变量,注释明确指出"EQ 模式参数由应用层管理",即 SDK 只提供机制,模式数量与参数内容由应用侧的 eq_cfg.bin 决定。
在线 EQ 助手:eq_online_sw()
eq_online_sw()(audio_eq_api.c#L71-L85)是"AD16N 在线 EQ 调试助手"(仓库 post_build/uc03/eq_tool/AD16N在线EQ调试助手.jlxproj)拖拽曲线时的回调:调音工具改写 music_eq_tool_online 后调用本函数,将新段表/增益通过 EQ_CMD_SWITCH_TAB 热更新到运行中的 EQ,实现听感即时反馈,无需重新编译固件。
资源释放:eq_reless()
void eq_reless(void **ppeffect)
{
EFFECT_OBJ *p_eobj = *ppeffect;
log_info("eq free : 0x%x", (u32) p_eobj);
if (NULL != p_eobj) {
*ppeffect = my_free(p_eobj);
}
}
停止播放/关闭 EQ 时调用,释放 EQ 句柄内存(归还 MM_EQ 池)。释放后 *ppeffect 置 NULL 防止悬垂指针。
核心流程
sequenceDiagram
participant APP as 应用/调音工具
participant LINK as link_eq_sound()
participant API as eq_api()/EQ_HDL
participant OPS as EQ_STUCT_API (audio_eq_lib.a)
participant CFG as eq_cfg.bin
APP->>LINK: 初始化链路 (sr, ch, music_eq_tool_online)
LINK->>API: 构造 EQ_PARA_STRUCT
API->>OPS: need_buf(max_nsection, ch)
OPS-->>API: 所需RAM大小
API->>API: eq_hld_malloc() 分配 MM_EQ 内存
API->>OPS: open(buff, para, io)
API->>API: 组装 EFFECT_OBJ / sound_in_obj / EQ_IO_CONTEXT
LINK-->>APP: 返回新 sound_out_obj 节点
loop 每帧音频
APP->>API: eq_run_api() 回调
API->>OPS: run(p_dbuf, inbuf, len)
OPS-->>API: 处理后PCM
API->>API: io.output() 向后级输出
end
APP->>CFG: eq_mode_sw() → ext_eff_file_analyze_api(eq_mode)
CFG-->>APP: 参数组写入 music_eq_tool_online
APP->>OPS: config(EQ_CMD_SWITCH_TAB, EQ_UPDATE)
Note over OPS: 系数表热替换 + fade 渐变防爆音
配置选项
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
AUDIO_HW_EQ_EN | 编译宏 | — | EQ 功能总开关,关闭时整个 audio_eq_api.c 不参与编译 |
config_hw_single_eq | const int | 1 | 仅使用一路 EQ(省 RAM);多路时每路需额外 64×段数字节 |
config_eq_fade_enbale | const int | 1 | 使能 EQ 淡入淡出(防爆音) |
config_eq_fade_step | const int | 128 | 淡入淡出步长 |
EQ_SECTION_MAX | 宏 | 10 | 最大 EQ 段数 |
EQ_MAX_POINT | 宏 | 128 | 单次处理最大采样点数 |
EQ_COEFF_BASE | 宏 | 0x2F0000 | 系数表存储基地址 |
EFF_CFG_FILE_ID | 宏 | 0x3 | 音效配置项源文件 ID(eq_cfg.bin) |
API Reference
link_eq_sound(void *p_sound_out, void *p_dac_cbuf, void **pp_effect, u32 sr, u8 ch): void *
将 EQ 实例挂入输出音效链。参数:p_sound_out 当前输出对象、p_dac_cbuf DAC 环形缓冲、pp_effect 返回效果对象指针、sr 采样率、ch 声道数。返回:下一个 sound_out_obj(失败时返回原节点,系统降级为无 EQ 输出)。位置:audio_eq_api.c#L40
eq_mode_sw(void *parm): void
切换到下一个 EQ 参数组(模式号循环)。参数:parm 为 EFFECT_OBJ *。副作用:从 eq_cfg.bin 解析新参数并热更新运行中的 EQ;eq_cfg.bin 解析失败时仅打日志并返回,保持原参数不变。位置:audio_eq_api.c#L89
eq_online_sw(void *parm): void
在线调音工具改参后的热更新入口。参数:parm 为 EFFECT_OBJ *。位置:audio_eq_api.c#L71
eq_api(void *obuf, EQ_PARA_STRUCT *p_para, void **ppsound): void *
创建 EQ 效果对象(内部函数,经 link_eq_sound 调用)。返回:EFFECT_OBJ *;内存分配失败返回 0。位置:audio_eq_api.c#L146
eq_hld_malloc(u32 malloc_size): void * / eq_reless(void **ppeffect): void
EQ 内存的分配/释放钩子,使用 my_malloc(..., MM_EQ) 与 my_free()。位置:audio_eq_api.c#L127、audio_eq_api.c#L131
EQ_STUCT_API 操作集(由 get_eq_context() 提供,预编译库实现)
need_buf(max_eq_seg, ch):返回所需 RAM 字节数;open(ptr, para, rsio):初始化 EQ 实例,返回工作缓冲指针;run(ptr, inbuf, len):处理len个shortPCM 采样,返回处理结果;config(work_buf, cmd, parm):支持EQ_CMD_SWITCH_TAB(切换系数表)与EQ_GET_CURR_MODE(查询当前模式)。
失败模式与边界情况
- EQ 内存不足:
eq_api()中need_buf计算后eq_hld_malloc失败会log_error并返回0,link_eq_sound判定effect==NULL走 "init fail" 分支——音频链路保持无 EQ 直通,系统不崩溃(降级容错)。 - 空句柄:
eq_online_sw/eq_mode_sw入口对NULL效果对象直接return,避免对未初始化链路下发参数。 - eq_cfg.bin 解析失败:
ext_eff_file_analyze_api()返回非 0 时eq_mode_sw提前返回,运行中的 EQ 参数不受影响(上次成功参数继续生效),但模式号已递增,下次调用将尝试下一组。 - 参数热切换爆音:系数表跳变会引起输出突变,因此
EQ_BUFF内嵌sound_fade_obj,B_EQ_FADE_IN/OUT标志 +config_eq_fade_step步长实现渐变;config_eq_fade_enbale可整体关闭。 - 并发/重入:EQ 的
run在音频中断/音频任务上下文中被逐帧调用,参数切换(config)由应用层发起。二者共享music_eq_tool_online全局参数,SDK 未在源码层加锁——参数切换应避免在音频帧处理中途执行,或由应用层保证时序(注释明确"EQ 模式参数由应用层管理")。
性能与运维
- RAM 预算:单路 EQ 固定 344 字节;多路每路增加
64 × 最大段数字节,config_hw_single_eq=1即面向省 RAM 场景(源码注释给出明确公式)。 - 热路径:
eq_run_api → ops->run每帧调用,无锁、无动态分配,算法为定点/浮点 IIR 段级联,段数(seg_num)与使能段(enable_section)决定实际算力消耗。 - 调音产物:EQ 参数固化于
eq_cfg.bin,发布前用eqbin2dir.bat转成dir_eq目录格式烧录(仓库post_build/uc03/下可见eq_tool/eq_cfg.bin与dir_eq);运行期eq_mode_sw按EFF_CFG_FILE_ID(0x3)读取。 - 在线调音:配合
AD16N在线EQ调试助手.jlxproj工程与EFF_ONLINE_PACKET协议(EFF_CMD_INQUIRE/GETVER/FILE/CHANGE_MODE/RESYNC_PARM_*)可在不重刷固件的前提下改曲线、切模式。
扩展点
- 新增 EQ 模式:在
eq_cfg.bin中追加参数组,模式总数由get_eq_mode_total_num()返回,eq_mode_sw自动循环,无需改 SDK 代码。 - 多声道独立调音:
EFF_MUSIC_RL_EQ/RR_EQ/FR_EQ、EFF_MUSIC_*_DRC、EFF_MUSIC_*_CROSSOVER系列 ID 表明 2.1/2.2 声道方案已预留每声道独立 EQ/DRC/分频器挂载点。 - 更换算法库:EQ 算法全部走
EQ_STUCT_API抽象(get_eq_context()返回),替换audio_eq_lib.a即可换算法而不动封装层。 - 新增效果类型:在
effects_adj.h枚举中分配新 ID,并在效果框架中按EFFECT_OBJ约定实现 run/init/release 即可接入链路(如EFF_MIC_VOICE_CHANGER、EFF_MUSIC_VBASS、EFF_MUSIC_SURRROUND_EFF等已有先例)。
Related Links
- audio_eq.h(EQ API 结构定义)
- audio_eq_api.c(EQ 封装层实现)
- effects_adj.h(效果 ID 体系)
- hw_eq.h(硬件 EQ 定义)
- pcm_eq_api.h(PCM 域 EQ API)
- audio_eq_lib.a(EQ 预编译算法库)
- AD16N 在线 EQ 调试助手工程
- eqbin2dir.bat(EQ 配置转换脚本)
兄弟页面指引:音频解码与播放链路、DAC/ADC 通路、AEC/降噪算法本体请参见音频子系统下对应目录页。