杰理 SDK 文档中心
首页
首页
  • 概述

    • SDK 概览与产品定位
    • 支持芯片平台与蓝牙认证
    • SDK 架构与目录分层
  • 快速开始

    • 环境搭建与编译工具链
    • 编译构建系统
    • 板级工程与配置
    • 烧录与固件升级工具
  • 应用工程

    • 应用选择与工程总览
    • SPP + BLE 数传应用框架
    • 透传与 AT 指令示例
    • BLE 广播/中心与定位示例
    • 2.4G 私有协议与 Dongle 示例
    • 云平台接入示例
    • HID 人机交互应用框架
    • HID 示例工程(键盘/鼠标/遥控器/手柄)
    • Bluetooth Mesh 应用框架
    • Mesh 模型与 Mesh DFU 固件升级
    • Mesh 音频编解码演示
  • 芯片平台与硬件抽象

    • 芯片平台总览与差异
    • 音频编解码与时钟管理
    • 外设驱动接口(ADC/IIC/SPI/PWM/LED/充电)
    • 芯片配置工具与下载支持
  • 蓝牙协议栈

    • 蓝牙控制器层(btctrler)
    • 蓝牙协议栈与 Profile(btstack)
    • 蓝牙模块选择与配置
  • 媒体与音频框架

    • 音频流框架
    • 音频编解码与 A2DP 媒体
    • 音频效果处理(EQ/频谱/变调/环绕/超低音)
    • 本地 TWS 与音频同步
  • 系统服务与运行时

    • 实时操作系统与任务调度
    • 消息事件机制
    • 电源管理与低功耗
    • 存储与配置系统
    • 设备驱动框架(USB/RTC)
  • 应用公共组件

    • 音频应用组件
    • 设备外设抽象(按键/触摸/传感器/存储)
    • 蓝牙公共模块与消息联动
    • 调试与配置组件
    • 杰理关键词唤醒(jl_kws)
  • 第三方协议与云平台接入

    • 杰理 RCSP 私有协议
    • 低功耗蓝牙 Mesh 方案(llsync_mesh)
    • Sig Mesh 方案
    • 涂鸦协议接入
    • 腾讯连连接入
    • 华为 HiLink 接入
  • 固件升级与维护

    • OTA 升级机制
    • 升级补丁与版本维护
    • 升级工具链(BLE OTA / USB Dongle OTA)
  • 文档与开发资源

    • 数据手册与架构文档
    • 协议与云平台开发文档
    • 常见问题与技术支持

音频效果处理(EQ/频谱/变调/环绕/超低音)

本页介绍 AC63 系列蓝牙 SoC SDK 中的音频效果处理能力,重点覆盖以 audio_eq 为核心的 EQ 均衡(含高低音/超低音增强)、DRC 联动、频谱分析与在线调试等机制的实现原理、数据流、配置方式与使用示例。

Purpose and Scope

本页面向希望在 fw-AC63_BT_SDK 中接入、裁剪或调试音频效果的开发者,内容涵盖:

  • EQ 核心模块 audio_eq 的数据结构、工作模式(EQ_MODE)、系数来源(EQ_TYPE)与 API;
  • EQ/DRC 功能开关位(config_audio_eq_en / config_audio_drc_en)与编译期裁剪;
  • 高低音(high_bass,即超低音/高音增强)的接口设计;
  • EQ 节点如何挂载到音频流(audio_stream_entry)实现实时处理;
  • 频谱(spectrum_eq)等关联模块的入口位置;
  • 实际工程中的调用示例(audio_eq_drc_demo.c)。

不在本页范围内:解码/编码、DAC 驱动、蓝牙协议栈、UI 界面等属于其他目录的能力;变调(pitch)与环绕(surround)效果若由上层 DSP 算法库或 effects_adj 音效调节模块提供,其实现细节请参考对应模块文档。本页采集范围内未读取到变调/环绕算法的具体实现文件,因此仅给出模块定位与接入指引,不做未经验证的细节描述。

Overview

AC63 系列 SDK 采用「硬件 EQ 引擎 + 软件参数管理」的音效架构:实时 PCM 数据流经过挂在音频流节点链上的 audio_eq 节点,节点内部根据 struct audio_eq_param 提供的段数、采样率、系数表(struct eq_seg_info)等参数,通过系数回调(audio_eq_filter_cb)获取滤波器系数,再交给硬件 EQ 引擎(hw_eq)完成逐采样点运算。系数切换时支持淡入淡出(fade),避免增益突变产生"哒哒"杂音。

该设计把参数管理(软件)与数值运算(硬件)分离:软件层只负责维护效果模式、系数表和淡入过程,重负载的滤波运算下沉到硬件,从而在低主频 MCU 上也能实时处理多段 EQ。SDK 同时提供同步/异步两种运行方式(no_wait、CONFIG_EQ_SUPPORT_ASYNC),并可通过在线调试(EQ_ONLINE_EN)与文件解析(EQ_FILE_EN)动态更新效果。

Architecture

flowchart LR
    subgraph sg_Source["信号源"]
        Dec["解码器 Decoder"]
        Mic["MIC / Line-in"]
    end

    subgraph sg_Stream["音频流节点链 audio_stream"]
        Node["audio_stream_entry 节点"]
        EQ["audio_eq 节点<br/>(AEID_MUSIC_EQ)"]
        DRC["DRC 节点<br/>(限幅/压缩/多带)"]
    end

    subgraph sg_Core["EQ 参数管理层(软件)"]
        Param["audio_eq_param 参数"]
        Seg["eq_seg_info 系数表"]
        Cb["filter_cb 系数回调"]
        Fade["淡入淡出 audio_eq_fade"]
    end

    subgraph sg_HW["硬件/输出层"]
        HwEq["hw_eq 硬件EQ引擎"]
        DAC["DAC 输出"]
    end

    subgraph sg_Cfg["效果配置来源"]
        ModeTab["EQ_MODE_TAB 默认效果表"]
        FileCfg["EQ_TYPE_FILE eq_cfg_hw.bin"]
        Online["EQ_TYPE_ONLINE 在线调试"]
    end

    Dec --> Node
    Mic --> Node
    Node --> EQ
    EQ --> DRC
    DRC --> DAC

    Param --> EQ
    Seg --> Cb
    Cb --> HwEq
    Fade --> HwEq
    EQ --> HwEq

    ModeTab --> Param
    FileCfg --> Param
    Online --> Param

架构说明:

  • 音频流节点链(audio_stream):struct audio_eq 内嵌 struct audio_stream_entry entry(见 audio_eq.h),EQ 以节点形式挂入解码输出流,数据按帧流入流出,与 DRC 等节点级联。
  • 参数管理层:应用通过 audio_eq_param 声明段数(max_nsection/nsection)、采样率(sr)、通道数、总增益(global_gain)与左右声道独立系数表(seg/seg_r);cb 回调在需要更新系数时返回 audio_eq_filter_info(即 eq_coeff_info)。
  • 淡入淡出:audio_eq_fade 记录当前系数表与目标系数表,按 fade_step/q_fade_step/g_fade_step/f_fade_step 步进逐步逼近目标值,避免切换瞬间的增益跳变。
  • 配置来源:效果既可使用默认效果表(EQ_TYPE_MODE_TAB,对应 7 种 EQ_MODE 预设),也可解析 eq_cfg_hw.bin 文件(EQ_TYPE_FILE)或通过在线调试(EQ_TYPE_ONLINE)实时下发,在线调试结果可保存到 VM(EQ_ONLINE_FILE_SAVE)。

核心模块实现分析

EQ 工作模式与类型

EQ 的效果预设由 EQ_MODE 枚举定义,共 7 种可切换模式(EQ_MODE_MAX 为边界标记):

typedef enum {
    EQ_MODE_NORMAL = 0,
    EQ_MODE_ROCK,
    EQ_MODE_POP,
    EQ_MODE_CLASSIC,
    EQ_MODE_JAZZ,
    EQ_MODE_COUNTRY,
    EQ_MODE_CUSTOM,//自定义
    EQ_MODE_MAX,
} EQ_MODE;

Source: audio_eq.h

系数(效果)来源则由 EQ_TYPE 区分,EQ_TYPE_FILE(0x01)表示从文件解析、EQ_TYPE_ONLINE 表示在线调试下发、EQ_TYPE_MODE_TAB 表示使用内置默认效果表——三者对应不同的 audio_eq_param 装配路径:

typedef enum {
    EQ_TYPE_FILE = 0x01,
    EQ_TYPE_ONLINE,
    EQ_TYPE_MODE_TAB,
} EQ_TYPE;

Source: audio_eq.h

核心参数结构 audio_eq_param

audio_eq_open() 的输入完全由 struct audio_eq_param 驱动。该结构采用位域紧凑编码(u8 no_wait:1、u8 max_nsection:6 等),体现 SDK 对 RAM/代码体积的极致优化:

struct audio_eq_param {
    u8 no_wait : 1;     //是否使能异步eq, 1:使能  0:不使能
    u8 max_nsection : 6;//最大的eq段数,根据使用填写,要小于等于EQ_SECTION_MAX
    u8 nsection : 6;    //实际需要的eq段数,需小于等于max_nsection
    u8 out_32bit : 1;    //是否支持32bit eq输出,仅在 no_wait 写1时,out_32bit 才能写1
    u8 channels : 2;    //通道数
    u8 fade;            //系数更新是否使能淡入,0:不使能,1:使能淡入
    u8 f_fade_step;     //滤波器中心截止频率淡入步进(10~200Hz)
    float fade_step;    //滤波器增益淡入步进(0.01f~1.0f)
    float q_fade_step;  //滤波器q值淡入步进(0.01f~1.0f)
    float g_fade_step;  //总增益淡入步进(0.01f~1.0f)
    audio_eq_filter_cb cb;//获取eq系数的回调函数
    u32 eq_name;         //eq名字
    u32 sr;              //采样率,更根据当前数据实际采样率填写

    float global_gain;
    struct eq_seg_info *seg;
    float global_gain_r;
    struct eq_seg_info *seg_r;

    void *priv;          //私有指针
    int (*output)(void *priv, void *data, u32 len);//异步eq输出回调,节点方式使用时,output 配NULL
    void (*irq_callback)(void *priv);//总段回调函数,数据流激活
};

Source: audio_eq.h

设计要点:

  • no_wait(异步模式):置 1 时 EQ 以异步方式运行,数据不等待硬件处理完成即回调 output,需要额外的 run_buf/run_out_buf(见 struct audio_eq_async);置 0 时同步处理。异步模式才允许 out_32bit = 1。
  • seg/seg_r 左右声道分离:global_gain/seg 对应左(或主)声道,global_gain_r/seg_r 对应右声道,配合 EQ_HW_LR_ALONE 与 EQ_LR_DIVIDE_EN 可做四声道下左右效果拆分。
  • eq_name 唯一标识:如 AEID_MUSIC_EQ、AEID_MUSIC_RL_EQ,用于区分多个 EQ 实例(如音乐 EQ 与 RL/RR 声道 EQ 并存)。

运行时状态 struct audio_eq

struct audio_eq 是 EQ 实例的完整运行状态:既持有硬件句柄(eq_ch)、当前/最大段数(cur_nsection/max_nsection)、采样率(sr)、增益(global_gain/global_gain_r),也持有运算前后系数表(eq_seg_tab→eq_coeff_tab)、淡入结构(fade/fade_r)、音频流入口(entry)以及静音计数(mute_cnt_l/r/max)。mute_cnt_* 用于在长时间静音后清除 EQ 内部滤波器记忆(mem),防止恢复播放时产生异常瞬态。

struct audio_eq {
    void *eq_ch;                               //硬件eq句柄
    u8 updata;                            //系数是否需要更新
    u8 start;                             //eq start标识
    u8 max_nsection;                      //eq最大段数
    u8 cur_nsection;                      //当前eq段数
    u8 check_hw_running;                  //检测到硬件正在运行时不等待其完成1:设置检查  0:不检查
    u8 async_en;
    u8 out_32bit;
    u8 ch_num;
    u32 sr;                                    //采样率
    u32 eq_name;                               //eq标识
    u32 mask[2];
    float global_gain;
    float global_gain_r;
    s16 *eq_out_buf;//同步方式,32bit输出,当out为NULL时,内部申请eq_out_buf
    int out_buf_size;
    int eq_out_points;
    int eq_out_total;
    struct audio_stream_entry entry;	// 音频流入口
    ...
    u32 mute_cnt_l;                                  //左声道eq mem清除计数
    u32 mute_cnt_r;                                  //右声道eq mem清除计数
    u32 mute_cnt_max;                                //记录最大点数,超过该点数,清eq mem
    audio_eq_filter_cb cb;                           //系数回调
    void *output_priv;                               //私有指针
    int (*output)(void *priv, void *data, u32 len);  //输出回调
    struct eq_seg_info *eq_seg_tab;                 //运算前系数表
    struct eq_seg_info *seg;                        //运算前系数表,由audio_eq_param初始化时指定
    struct eq_seg_info *seg_r;                      //运算前系数表,由audio_eq_param初始化时指定
    int *eq_coeff_tab;                              //运算后系数表
    struct list_head hentry;                        //
    const char *event_owner;                        //记录data_handler所处的任务
    struct audio_eq_fade *fade;
    struct audio_eq_fade *fade_r;
    ...
};

Source: audio_eq.h

event_owner 记录 data_handler 所在任务,配合 hentry 链表头把 EQ 实例挂入系统管理链表,便于统一的事件回调与任务切换调度——这是嵌入式多任务环境中保证 EQ 系数更新与数据流处理线程安全的关键设计。

高低音 / 超低音增强(high_bass)

超低音(ultra bass)与高音增强在 SDK 中由 struct high_bass 描述,AUDIO_EQ_HIGH = 2、AUDIO_EQ_BASS = 3 两个宏分别对应高低音段索引:

struct high_bass {
    int freq;     //频率写0, 内部会用默认125hz  和12khz
    int gain;    //增益范围 -12~12
};

Source: audio_eq.h

freq 填 0 时内部使用默认值:低频段 125 Hz(超低音)、高频段 12 kHz;gain 取值范围 -12~+12 dB。该功能由 EQ_HIGH_BASS_EN(BIT(6))使能,并可选 EQ_HIGH_BASS_FADE_EN(BIT(7))让高低音增益变化也走淡入淡出路径,防止低频大增益切换时的"噗噗"声。

频谱分析与变调/环绕模块定位

  • 频谱(spectrum):SDK 提供 include_lib/media/spectrum/spectrum_eq.h,位于 include_lib/media/spectrum/ 目录,用于频谱显示相关的 EQ 数据处理(本页采集阶段未读取该文件实现,具体接口请直接查看该头文件)。
  • 变调(pitch)/ 环绕(surround):上层音效调节通常经由 effects_adj.h(audio_eq_drc_demo.c 已包含此头)或独立 DSP 算法库接入音频流节点链。本页源码采集范围内未找到这两个算法的实现文件,不做未经验证的描述;接入方式与 EQ 节点一致——通过 audio_stream_entry 挂入节点链,在 audio_eq 之后、DAC 之前按需插入。

Core Flow

EQ 从打开、运行到系数更新的完整时序如下:

sequenceDiagram
    participant App as 应用层(eq_sw_demo / music_eq_open)
    participant EQ as audio_eq 模块
    participant CB as filter_cb 系数回调
    participant HW as hw_eq 硬件引擎
    participant ST as audio_stream 节点链

    App->>EQ: audio_eq_open(eq, param)
    EQ->>EQ: 解析 param(段数/采样率/通道/淡入步进)
    EQ->>ST: 注册 audio_stream_entry 节点
    App->>EQ: audio_eq_start()
    loop 数据流运行
        ST->>EQ: 数据帧到达
        EQ->>EQ: 检查 updata 系数更新标志
        alt 需要更新系数
            EQ->>CB: 调用 cb(eq, sr, &info) 获取系数
            CB-->>EQ: eq_coeff_info 系数表
            EQ->>EQ: 按 fade_step 步进逼近目标增益/q/频率
        end
        EQ->>HW: 下发系数并处理 PCM 数据
        HW-->>EQ: 处理后数据
        EQ->>ST: 输出到下一节点(DRC/DAC)
    end
    App->>EQ: audio_eq_set_samplerate / audio_eq_set_channel
    App->>EQ: audio_dec_eq_close(eq)

关键控制流说明:

  1. 打开阶段:audio_eq_open() 根据 param 计算硬件段数与内存占用;若 no_wait=0 且未提供 eq_out_buf,内部自动申请输出缓冲(out_buf_size/eq_out_points 记录大小与点数)。
  2. 运行阶段:EQ 作为音频流节点被逐帧调用;updata 标志置位时触发系数刷新,刷新过程受 fade 控制,每帧只步进一小步,多帧后平滑到达目标值——这是消除"哒哒/爆破音"的核心机制。
  3. 模式切换:应用层 eq_mode_sw() 切换 7 种默认系数表,eq_mode_set(EQ_MODE_CUSTOM) 切换自定义表并更新总增益,切换全程由淡入淡出护航。
  4. 关闭阶段:audio_dec_eq_close(eq) 释放硬件句柄并从流节点链摘除,同时 clock_remove(EQ_CLK) 归还时钟资源(见下方使用示例)。

Usage Examples

以下示例全部取自 SDK 实际工程文件,展示 EQ 的典型接入方式。

打开音乐 EQ(同步模式 + 系数淡入)

music_eq_open() 演示了最常用的 EQ 装配方式:从 music_eq_tool 工具结构拷贝系数表,填充 audio_eq_param,使能淡入,然后通过 audio_dec_eq_open() 打开:

struct audio_eq *music_eq_open(u32 sample_rate, u8 ch_num)
{
#if defined(TCFG_EQ_ENABLE) && TCFG_EQ_ENABLE
    memcpy(&fl_eq_parm_tmp, &music_eq_parm, sizeof(fl_eq_parm_tmp));
    struct audio_eq_param parm = {0};
    parm.channels = ch_num;
    parm.no_wait = 0;
    parm.cb = eq_get_filter_info;
    parm.sr = sample_rate;
    parm.eq_name = AEID_MUSIC_EQ;
    parm.max_nsection = fl_eq_parm_tmp.seg_num;
    parm.nsection = fl_eq_parm_tmp.seg_num;
    parm.seg = fl_eq_parm_tmp.seg;
    parm.global_gain = fl_eq_parm_tmp.global_gain;

    parm.fade = 1;//使能系数淡入
    parm.fade_step = 0.2f;//淡入步进(0.1f~1.0f)
    parm.g_fade_step = 0.4f;//总增益步进
    parm.f_fade_step = 100;//中心截止频率步进Hz

    struct audio_eq *eq = audio_dec_eq_open(&parm);
    clock_add(EQ_CLK);
    return eq;
#endif //TCFG_EQ_ENABLE

    return NULL;
}

Source: audio_eq_drc_demo.c

对应关闭接口会释放 EQ 并归还时钟:

void music_eq_close(struct audio_eq *eq)
{
#if defined(TCFG_EQ_ENABLE) && TCFG_EQ_ENABLE
    if (eq) {
        audio_dec_eq_close(eq);
        clock_remove(EQ_CLK);
    }
#endif/*TCFG_EQ_ENABLE*/
}

Source: audio_eq_drc_demo.c

左右声道独立 EQ(四声道拆分)

当 TCFG_EQ_DIVIDE_ENABLE 打开时,可再开一路 RL/RR 声道 EQ,使用独立系数表 rl_eq_parm 与标识 AEID_MUSIC_RL_EQ,避免左右声道效果互相干扰:

struct audio_eq *music_eq_rl_rr_open(u32 sample_rate, u8 ch_num)
{
#if defined(TCFG_EQ_ENABLE) && TCFG_EQ_ENABLE
    memcpy(&rl_eq_parm_tmp, &rl_eq_parm, sizeof(rl_eq_parm_tmp));
    struct audio_eq_param parm = {0};
    parm.channels = ch_num;
    parm.no_wait = 0;
    parm.cb = eq_get_filter_info;
    parm.sr = sample_rate;
    parm.eq_name = AEID_MUSIC_RL_EQ;
    parm.max_nsection = rl_eq_parm_tmp.seg_num;
    parm.nsection = rl_eq_parm_tmp.seg_num;
    parm.seg = rl_eq_parm_tmp.seg;
    parm.global_gain = rl_eq_parm_tmp.global_gain;

    parm.fade = 1;//增益更新差异大,会引入哒哒音,此处使能系数淡入
    parm.fade_step = 0.2f;//淡入步进(0.1f~1.0f)
    parm.g_fade_step = 0.4f;//总增益步进

    struct audio_eq *eq = audio_dec_eq_open(&parm);
    clock_add(EQ_CLK);
    return eq;
#endif //TCFG_EQ_ENABLE
    return NULL;
}

Source: audio_eq_drc_demo.c

模式切换与自定义系数更新

模式切换与动态更新是 UI/按键最常见的调用路径:

//系数切换
void eq_sw_demo()
{
    eq_mode_sw();//7种默认系数切换
}

//获取当前eq系数表类型
void eq_mode_get_demo()
{
    u8 mode ;
    mode = eq_mode_get_cur();
}

//自定义系数表动态更新
void eq_update_demo()
{
    eq_mode_set_custom_info(0, 200, 2);//第0段,200Hz中心截止频率,2db
    eq_mode_set_custom_info(5, 2000, 2);//第5段,2000Hz中心截止频率,2db

    set_global_gain(EQ_MODE_CUSTOM, -1);//-1表示 -1dB
    eq_mode_set(EQ_MODE_CUSTOM);//设置系数、总增益更新
}

Source: audio_eq_drc_demo.c

eq_update_demo() 体现了自定义 EQ 的完整流程:先逐段设置中心频率与增益(eq_mode_set_custom_info(段号, 频率Hz, 增益dB)),再设置总增益(set_global_gain),最后调用 eq_mode_set(EQ_MODE_CUSTOM) 一次性提交——系数变化会经由 fade 机制平滑过渡。

Configuration Options

EQ/DRC 的编译期行为由 config_audio_eq_en 与 config_audio_drc_en 两个整型常量的位域控制,各 bit 定义见 eq_func_define.h:

config_audio_eq_en 功能位

位宏名说明
BIT(0)EQ_ENEQ 模式总使能
BIT(1)EQ_SUPPORT_OLD_VER_ENAC700N 兼容旧版本(0.7.1.0 / 0.7.1.1)
BIT(2)EQ_LITE_VER_EN精简版 EQ 驱动:不支持异步、不支持默认效果切换,仅文件解析
BIT(3)EQ_ONLINE_EN在线调试模块使能
BIT(4)EQ_FILE_EN支持文件解析 EQ;关闭则只能使用默认效果表
BIT(5)EQ_FILE_SWITCH_EN支持 eq_cfg_hw.bin 文件切换更新效果
BIT(6)EQ_HIGH_BASS_ENEQ 内部集成高低音(超低音/高音)接口使能
BIT(7)EQ_HIGH_BASS_FADE_EN高低音淡入淡出,配合 config_audio_eq_fade_step
BIT(8)EQ_FILTER_COEFF_FADE_EN默认系数表切换/在线调试更新使用淡入淡出,避免杂音
BIT(9)EQ_FILTER_COEFF_LIMITER_ZERO_EN滤波器系数限幅归零
BIT(10)EQ_HW_UPDATE_COEFF_ONLY_EN有空闲段时只更新系数、不切换
BIT(11)EQ_HW_LR_ALONE左右声道分开处理(与 BIT(10) 同时使能/关闭)
BIT(12)EQ_SUPPORT_32BIT_SYNC_EN支持同步方式 32bit EQ
BIT(13)EQ_SUPPORT_MULIT_CHANNEL_EN多声道(3~8)支持(AC699N/AC700N)
BIT(14)EQ_HW_CROSSOVER_TYPE0_EN硬件分频器,序列进序列出(需 BIT(13))
BIT(15)EQ_HW_CROSSOVER_TYPE1_EN分频器块出方式,仅单声道,增加内存
BIT(16)EQ_LR_DIVIDE_ENEQ 左右声道效果拆分(四声道场景)
BIT(17)EQ_ONLINE_FILE_SAVEEQ 在线调试结果保存到 VM
BIT(18)EQ_DRC_PROCESS_SPLITEQ/DRC 节点处理支持拆分
BIT(20)EQ_MDRC_V2_ENMDRC V2 使能

对应快捷宏(如 config_audio_eq_online_en、config_filter_coeff_fade_en、config_high_bass_en、hw_eq_support_multi_channels 等)在 eq_func_define.h 中定义,业务代码应使用这些宏而非直接读位。

config_audio_drc_en 功能位

位宏名说明
BIT(0)DRC_ENDRC 总使能
BIT(1)DRC_NBAND_MERGING_ASM_EN多带处理后多带合并使用汇编加速
BIT(2)DRC_NBAND_DIS关闭 DRC 多带
BIT(3)DRC_LIMITER_DIS关闭 DRC 限幅器
BIT(4)DRC_COMPRESSOF_DIS关闭 DRC 压缩器
BIT(5)WDRC_TYPE_ENWDRC 使能

由 DRC_LIMITER_DIS 等反推的使能宏(config_drc_limiter_en、config_drc_nband_en、config_wdrc_en 等)同样定义于 eq_func_define.h。

运行期参数(struct audio_eq_param)

字段类型默认/范围说明
no_waitu8:101=异步 EQ,0=同步
max_nsectionu8:6≤ EQ_SECTION_MAX最大 EQ 段数
nsectionu8:6≤ max_nsection实际 EQ 段数
out_32bitu8:1032bit 输出,仅异步模式下可为 1
channelsu8:21~2(多声道平台可到 8)通道数
fadeu80系数更新淡入使能
f_fade_stepu8—中心截止频率淡入步进(10~200Hz)
fade_stepfloat—滤波器增益淡入步进(0.01f~1.0f)
q_fade_stepfloat—Q 值淡入步进
g_fade_stepfloat—总增益淡入步进
cb回调必填获取 EQ 系数回调
eq_nameu32AEID_MUSIC_EQ 等EQ 实例标识
sru32实际采样率采样率
global_gain / global_gain_rfloat0左右声道总增益(dB)
seg / seg_rstruct eq_seg_info*—左右声道系数表
output回调NULL(节点方式)异步输出回调

API Reference

以下接口全部来自 audio_eq.h 的公开声明(头文件共 311 行,后续还有数据处理/关闭等接口,本页仅列出已读取并核实的部分)。

void audio_eq_init(void)

EQ 模块初始化,在系统启动阶段调用一次,建立 EQ 链表(hentry)与内部资源。

void audio_eq_init_new(int eq_section_num)

按指定段数初始化 EQ 模块,eq_section_num 为全局可用段数(受 EQ_SECTION_NUM / EQ_PRIV_SECTION_NUM 约束)。在需要动态分配段数的场景使用。

int audio_eq_open(struct audio_eq *eq, struct audio_eq_param *param)

打开一个 EQ 实例。

参数:

  • eq:调用方提供的 struct audio_eq 实例(可静态分配,也可通过 audio_dec_eq_open 内部申请)。
  • param:配置参数,见 struct audio_eq_param 表。

返回: 成功返回 EQ 句柄(int),失败返回错误码。工程中常通过包装函数 audio_dec_eq_open(&parm) 打开。

说明: 打开时会按 max_nsection 计算硬件段与内存;channels 与 sr 必须在数据流入前设置正确,否则滤波系数错误。

void audio_eq_set_output_handle(struct audio_eq *eq, int (*output)(void *priv, void *data, u32 len), void *output_priv)

设置异步模式下的输出回调:output 收到处理后数据,output_priv 为私有上下文。节点方式(挂入 audio_stream)使用时无需设置。

void audio_eq_set_output_buf(struct audio_eq *eq, s16 *buf, u32 len)

同步模式设置输出缓冲:buf 为用户提供的缓冲区,len 为字节长度;不设置时 EQ 内部自动申请(见 eq_out_buf/out_buf_size)。

void audio_eq_set_samplerate(struct audio_eq *eq, int sr)

设置 EQ 采样率。采样率变化必须调用此接口(如解码器切歌、蓝牙 SBC/AAC 切换采样率),内部会据此重算滤波器系数。

void audio_eq_set_channel(struct audio_eq *eq, u8 channel)

设置 EQ 输入输出通道数。

int audio_eq_set_check_running(struct audio_eq *eq, u8 check_hw_running)

设置是否检查硬件运行状态:check_hw_running=1 时检测到硬件正在运行则不等其完成直接返回(仅异步 EQ 有效),用于避免调用线程被阻塞。

int audio_eq_set_info(struct audio_eq *eq, u8 channels, u8 out_32bit)

设置 EQ 信息:channels 通道数,out_32bit 使能 32bit 输出(1=32bit,0=16bit)。

int audio_eq_set_info_new(struct audio_eq *eq, u8 channels, u8 in_mode, u8 out_mode, u8 run_mode, u8 data_in_mode, u8 data_out_mode)

扩展版设置接口,支持更精细的数据格式控制:

  • channels:通道数;
  • in_mode:输入格式,2=float,1=32bit,0=16bit;
  • out_mode:输出格式,2=float,1=32bit,0=16bit;
  • run_mode:运行模式,0=normal,1=mono,2=stereo;
  • data_in_mode / data_out_mode:数据存放方式,0=块模式,1=序列模式。

返回: int,成功为 0。

int audio_eq_start(struct audio_eq *eq)

启动 EQ 处理。启动后数据流经该节点即开始滤波;系数更新(updata)在运行中生效。

Failure Modes, Edge Cases & Concurrency

  • 系数突变导致的杂音:增益/Q 值/频率一次性大幅变化会产生"哒哒"或爆破音。源码级对策是 fade 淡入淡出机制(fade_step/q_fade_step/g_fade_step/f_fade_step 逐帧步进)以及 EQ_FILTER_COEFF_FADE_EN(BIT(8))将模式切换与在线调试更新都纳入淡入路径。audio_eq_drc_demo.c 中 RL/RR 声道 EQ 的注释明确说明"增益更新差异大,会引入哒哒音,此处使能系数淡入"。
  • 静音后的滤波器记忆残留:长时间静音后恢复播放,IIR 滤波器内部状态(mem)可能残留旧数据产生瞬态。struct audio_eq 的 mute_cnt_l/r 与 mute_cnt_max 记录静音点数,超过阈值即清空 EQ mem。
  • 异步模式下的等待阻塞:异步 EQ 若硬件忙,默认可能等待其完成,阻塞调用线程;audio_eq_set_check_running() 提供"检测到运行中即返回"的非阻塞选项,配合 irq_callback 在数据流激活时回调,适合低延迟场景。
  • 采样率/通道不匹配:sr 与 channels 必须在 audio_eq_open 时与实际数据一致,后续变化必须调用 audio_eq_set_samplerate/audio_eq_set_channel,否则滤波器系数按错误参数计算。
  • 多任务并发:event_owner 记录数据处理器所在任务,EQ 系数更新(应用任务)与数据处理(音频任务)分属不同上下文;系数表采用"运算前表(eq_seg_tab/seg)→ 运算后表(eq_coeff_tab)"双表设计,更新先写运算前表、硬件按需取用,降低并发竞争窗口。
  • 左右声道/四声道拆分:EQ_HW_LR_ALONE(BIT(11))与 EQ_LR_DIVIDE_EN(BIT(16))分别控制硬件左右独立处理与效果拆分;EQ_HW_UPDATE_COEFF_ONLY_EN(BIT(10))要求与 BIT(11) 同时使能/关闭,配置不一致会导致异常行为。
  • 精简版限制:EQ_LITE_VER_EN(BIT(2))下不支持异步与默认效果切换接口,仅支持文件解析——若业务代码误用 eq_mode_sw() 等接口将失效。

Performance & Operational Considerations

  • 硬件引擎承担运算:滤波数值运算由 hw_eq(如 asm/hw_eq.h)完成,软件只做参数管理与系数生成,CPU 占用低;多带 DRC 合并可开启 DRC_NBAND_MERGING_ASM_EN(BIT(1))用汇编加速。
  • 时钟管理:工程示例在打开 EQ 时 clock_add(EQ_CLK)、关闭时 clock_remove(EQ_CLK),表明 EQ 运行会占用系统时钟资源,关闭时必须归还,否则影响低功耗。
  • 内存权衡:out_32bit 输出、分频器块出方式(BIT(15))、多声道(BIT(13))都会显著增加内存占用,需按产品 RAM 预算裁剪。
  • 在线调试:EQ_ONLINE_EN + EQ_ONLINE_FILE_SAVE 支持运行时调参并保存到 VM,量产联调时按需开启,正式发布可关闭以省资源。

Extension Points

  1. 自定义效果模式:EQ_MODE_CUSTOM 配合 eq_mode_set_custom_info(段号, 频率Hz, 增益dB) 与 set_global_gain() 可动态构造任意均衡曲线,无需重新编译。
  2. 文件效果表:EQ_FILE_EN + EQ_FILE_SWITCH_EN 支持通过 eq_cfg_hw.bin 文件热更新效果,适合产线或用户自定义。
  3. 多 EQ 实例并存:eq_name(AEID_MUSIC_EQ / AEID_MUSIC_RL_EQ 等)标识不同实例,可在音乐、通话、录音等场景分别挂载不同 EQ。
  4. 节点链扩展:EQ 以 audio_stream_entry 节点形式存在,可在其前后插入自定义 DSP 节点(变调、环绕、声场等),复用同一套流式数据通路。
  5. 高低音独立调节:high_bass 结构(默认 125 Hz / 12 kHz,增益 ±12 dB)是超低音增强的标准入口,可替换为自定义频段实现。

Related Links

  • audio_eq.h(EQ 核心 API 与数据结构)
  • eq_func_define.h(EQ/DRC 功能开关位定义)
  • audio_eq_drc_demo.c(EQ/DRC 使用示例)
  • spectrum_eq.h(频谱分析模块入口)
  • audio_eq_drc_apply.h(EQ/DRC 应用层接口)
  • eq_config.h(EQ 配置与默认效果表)
  • 音频流节点机制请参阅本目录其他页面(如音频流与解码章节);变调/环绕 DSP 算法若独立提供,请参考对应算法模块文档。
Prev
音频编解码与 A2DP 媒体
Next
本地 TWS 与音频同步