9.6. EQ
概述
本工程展示了 AC790N
与 AC791N
的EQ工具使用示例:
如何使用EQ工具在线调试;
如何使用EQ导入/导出EQ配置文件;
如何使用动态DRC调试;
9.6.1. AC790N配置
9.6.1.1. 配置说明
在app_config.h中,若使用在线EQ调试,配置如下
#define TCFG_EQ_ENABLE 1 //支持EQ功能
#define TCFG_EQ_ONLINE_ENABLE 1 //支持在线EQ调试
#define TCFG_LIMITER_ENABLE 1 //限幅器
9.6.1.2. 操作说明
example: 以故事机工程作为例子说明。
打开EQ调试工具 AC790N_配置工具入口:
cpu/wl80/tools/AC791N_config_tool/AC790N_配置工具入口(Config Tools Entry).jlxproj
,选择“打开EQ工具”。
- 1.在线模式
在线调试通过串口进行与上位机通讯,选择好固件(AC790N), 配置好串口端口(默认使用uart1, 配置在相关板级里,默认波特率1000000,USBA的DMDP作为TX,RX),点击打开串口,工具最下面有信息栏提示
串口打开成功
,之后勾选在线EQ
, 这个时候一边播歌一边调节EQ等参数。(注意: 只支持均衡器与限幅器, 如操作了其他地方导致通讯失败, 需重新勾选在线EQ
)
UART1_PLATFORM_DATA_BEGIN(uart1_data)
.baudrate = 1000000,
.port = PORTUSB_A,
.tx_pin = IO_PORT_USB_DPA,
.rx_pin = IO_PORT_USB_DMA,
.max_continue_recv_cnt = 1024,
.idle_sys_clk_cnt = 500000,
.clk_src = PLL_48M,
.flags = UART_DEBUG,
UART1_PLATFORM_DATA_END();
- 2.读取文件模式
读取存放在flash里面的bin文件, 以文件中的数据调整eq参数, 该文件存放在
tools\cfg\eq_cfg_hw.bin
, 由在线调试EQ工具生成, 如图, 使用该模式, 需要改动如下:
#define TCFG_EQ_ONLINE_ENABLE 0 //支持在线EQ调试
#define TCFG_EQ_FILE_ENABLE 1 //从bin文件读取eq配置数据
注: 请注意导出的bin不一定直接存放到 tools\cfg\
目录, 请多留意,有必要自行挪到对应地方。
- 3.读取TABLE模式
读取存放在代码段中的数据, 以该TABLE的数据为准, 该TABLE存放在
apps/common/config/include/eq_tab.h
, 使用该模式, 需要改动如下:
#define TCFG_EQ_ONLINE_ENABLE 0 //支持在线EQ调试
#define TCFG_EQ_FILE_ENABLE 0 //从bin文件读取eq配置数据
- 三个模式的优先级:
在线模式 > 读取文件模式 > 读取TABLE模式
9.6.2. AC791N配置
9.6.2.1. 配置说明
example: 进入
demo_DevKitBoard/include/demo_config.h
,开启宏USE_AUDIO_DEMO
在app_config.h中,保证配置如下
#define TCFG_EQ_ENABLE 1 //支持EQ功能
#define TCFG_EQ_ONLINE_ENABLE 1 //支持在线EQ调试
#define TCFG_LIMITER_ENABLE 1 //限幅器
#define TCFG_DRC_ENABLE TCFG_LIMITER_ENABLE //DRC使能
#define TCFG_COMM_TYPE TCFG_USB_COMM
#define USB_DEVICE_CLASS_CONFIG (CDC_CLASS)
外部库依赖
libcompressor.a
、lib_crossover_coff.a
、media_app.a
、libdrc.a
,以DEMO_EDR工程为例,工程需要添加文件
apps/common/audio_music/audio_eff_default_parm.c
、apps/common/audio_music/audio_config.c
、apps/common/audio_music/effects_adj.c
、apps/common/audio_music/eq_config_new.c
、apps/common/config/new_cfg_tool.c
由于需要用到USB功能,则需继续添加
apps/common/system/device_mount.c
、apps/common/usb
目录下所有文件,添加搜索目录apps/common/usb
、apps/common/usb/device
、apps/common/usb/host
、apps/common/usb/include/host
、apps/common/usb/include
、include_lib/driver/device/usb
、include_lib/driver/device/usb/device
、include_lib/driver/device/usb/host
9.6.2.2. 操作说明
打开EQ调试工具 AC791N_配置工具入口:
cpu/wl82/tools/AC791N_config_tool/AC791N_配置工具入口(Config Tools Entry).jlxproj
,选择“打开音效配置工具(新EQ工具)”, 然后选择“ATK”后点击确定。
- 1.在线模式
1.1 在线调试通过串口进行与上位机通讯,配置好串口端口(USB串行设备),波特率后(波特率可自行选择,SDK会自动适配,默认115200,类型为异步),点击打开(暂时不支持蓝牙串口模式),进行通讯,通讯成功以后会跳转到【音效调节】界面,进行EQ、DRC各模块参数配置。
1.2 选择对应的音效(目前仅支持音乐音效中的musicEQ、CrossOver、LowBandDRC、HighBandDRC、DRC,后续会继续添加支持),然后右键点击编辑(或者双击),若当前设备在播放音乐,能直接听到修改前后的差别,根据需要进行调节。
1.3 进入
musicEQ
界面, 可以通过调节段点,或修改对应段点数据,进行频率、增益和高/中/低带通等的设置。
1.4 进入
CrossOver
界面:可以设置低中分频点,也可调节分频器阶数。
分频点处问题:由于分频点是低中DRC处理器的界限,所以在该频点处两个DRC的调节叠加会比较明显。
1.5 进入
LowBandDRC
HighBandDRC
DRC
界面:可以使用限幅器、多带限幅器、压缩器和多带压缩器,例子可以查看快照。曲线可以通过双击增加节点,右键可以编辑节点位置信息。在include_lib/media/effects_adj.h中, 如下宏控制DRC使能与否
#define TCFG_AUDIO_MDRC_ENABLE 2 //0:不使能低中DRC,LowBandDRC,HighBandDRC不起作用
1: 多带分频器使能,LowBandDRC,HighBandDRC使能 2: 多带分频后,再做一次全带平滑处理使能(仅打开驱动支持,无在线调试,效果与LowBandDRC,HighBandDRC设置的参数相关联)
#define TCFG_LAST_WHOLE_DRC_ENABLE 1 //0: 不使能最后的全带DRC,DRC不起作用 1: 使能最后的全带DRC
bypass:勾选后该DRC不起作用。
启动时间:输入幅值在曲线以上时,启动DRC到声音幅值稳定所需时间。
释放时间:输入幅值在曲线以下时,关闭DRC到声音幅值稳定所需时间。
RMS时间:detect mode在RMS模式下有效,算法一小段数据的采样范围(包含多个采样点),用于求平均值,以一个数据代表这段时间的数据。
输入增益:进入该DRC前的一个数字gain增益。
输出增益:退出该DRC后的一个数字gain增益。
detect mode:
RMS算法:取多个采样点的平均声音幅值作为当前RMS时间的平均幅值,低频有效减少声音抖动,高频效果不明显(占用算力大)
PEAK算法:取多个采样点,取到的采样点都加入算法运算。
precision和precision+:precision精度比precision+差点,但是运算速度是precision+的一倍。
1.6 修改完后,点击”保存配置“,生成“eq_cfg_hw.bin”配置文件,将该文件放置
cpu/wl82/tools/cfg
目录下,重新烧录的时候会将该文件烧写进设备,也可以点击加载配置文件
加载文件里的配置。设备开机时,首先会读取加载烧录进设备的EQ文件,当打开在线EQ调试,会加载当前工具的配置,可以点击左上角将配置写入设备
覆盖设备里旧的配置,也可以点击从设备中读取
按钮读取设备配置。
SDK代码需要在请求打开解码器时需要加上以下参数才会有EQ效果
#if TCFG_EQ_ENABLE
#if defined EQ_CORE_V1
req.dec.attr |= AUDIO_ATTR_EQ_EN;
#if TCFG_LIMITER_ENABLE
req.dec.attr |= AUDIO_ATTR_EQ32BIT_EN;
#endif
#if TCFG_DRC_ENABLE
req.dec.attr |= AUDIO_ATTR_DRC_EN;
#endif
#else
struct eq_s_attr eq_attr = {0};
extern void set_eq_req_attr_parm(struct eq_s_attr * eq_attr);
set_eq_req_attr_parm(&eq_attr);
req.dec.eq_attr = &eq_attr;
req.dec.eq_hdl = __this->eq_hdl;
#endif
#endif
9.6.2.3. 常见问题
Note
在线调试发送命令一直提示超时,请检查USB/串口 IO是否被其他模块占用,检查杜邦线连接是否正常
9.6.2.4. API参考
Enums
-
enum [anonymous]
EQ运行模式
Values:
-
enumerator NORMAL
正常模式
-
enumerator MONO
单声道模式
-
enumerator STEREO
立体声模式
-
enumerator NORMAL
-
enum [anonymous]
输出数据类型
Values:
-
enumerator DATO_SHORT
short短整型
-
enumerator DATO_INT
int整型
-
enumerator DATO_FLOAT
float浮点型
-
enumerator DATO_SHORT
-
enum [anonymous]
输入数据类型
Values:
-
enumerator DATI_SHORT
short短整型
-
enumerator DATI_INT
int整型
-
enumerator DATI_FLOAT
float浮点型
-
enumerator DATI_SHORT
-
enum [anonymous]
输入数据存放模式
Values:
-
enumerator BLOCK_DAT_IN
块模式,例如输入数据是2通道,先存放完第1通道的所有数据,再存放第2通道的所有数据
-
enumerator SEQUENCE_DAT_IN
序列模式,例如输入数据是2通道,先存放第1通道的第一个数据,再存放第2个通道的第一个数据,以此类推
-
enumerator BLOCK_DAT_IN
-
enum [anonymous]
输出数据存放模式
Values:
-
enumerator BLOCK_DAT_OUT
块模式,例如输出数据是2通道,先存放完第1通道的所有数据,再存放第2通道的所有数据
-
enumerator SEQUENCE_DAT_OUT
序列模式,例如输入数据是2通道,先存放第1通道的第一个数据,再存放第2个通道的第一个数据,以此类推
-
enumerator BLOCK_DAT_OUT
-
enum EQ_IIR_TYPE
eq IIR type滤波器类型
Values:
-
enumerator EQ_IIR_TYPE_HIGH_PASS
高通滤波器
-
enumerator EQ_IIR_TYPE_LOW_PASS
低通滤波器
-
enumerator EQ_IIR_TYPE_BAND_PASS
带通滤波器
-
enumerator EQ_IIR_TYPE_HIGH_SHELF
高架滤波器
-
enumerator EQ_IIR_TYPE_LOW_SHELF
低架滤波器
-
enumerator EQ_IIR_TYPE_HIGH_PASS
-
enumerator EQ_IIR_TYPE_LOW_PASS
-
enumerator EQ_IIR_TYPE_BAND_PASS
-
enumerator EQ_IIR_TYPE_HIGH_SHELF
-
enumerator EQ_IIR_TYPE_LOW_SHELF
-
enumerator EQ_IIR_TYPE_HIGH_PASS
Functions
-
void design_lp(int fc, int fs, float quality_factor, float *coeff)
低通滤波器
- Parameters
fc:中心截止频率 –
fs:采样率 –
quality_factor:q值 –
coeff:计算后,系数输出地址 –
-
void design_hp(int fc, int fs, float quality_factor, float *coeff)
高通滤波器
- Parameters
fc:中心截止频率 –
fs:采样率 –
quality_factor:q值 –
coeff:计算后,系数输出地址 –
-
void design_pe(int fc, int fs, float gain, float quality_factor, float *coeff)
带通滤波器
- Parameters
fc:中心截止频率 –
fs:采样率 –
gain:增益 –
quality_factor:q值 –
coeff:计算后,系数输出地址 –
-
void design_ls(int fc, int fs, float gain, float quality_factor, float *coeff)
低频搁架式滤波器
- Parameters
fc:中心截止频率 –
fs:采样率 –
gain:增益 –
quality_factor:q值 –
coeff:计算后,系数输出地址 –
-
void design_hs(int fc, int fs, float gain, float quality_factor, float *coeff)
高频搁架式滤波器
- Parameters
fc:中心截止频率 –
fs:采样率 –
gain:增益 –
quality_factor:q值 –
coeff:计算后,系数输出地址 –
-
int eq_stable_check(float *coeff)
滤波器系数检查
- Parameters
coeff:滤波器系数 –
- Returns
0:成功 -1:失败
-
float eq_db2mag(float x)
-
void eq_get_AllpassCoeff(void *Coeff)
获取直通的滤波器系数
- Parameters
coeff:滤波器系数 –
-
int eq_seg_design(struct eq_seg_info *seg, int sample_rate, float *coeff)
滤波器计算管理函数
- Parameters
seg:提供给滤波器的基本信息 –
sample_rate:采样率 –
coeff:计算后,系数输出地址 –
- Returns
true:成功 false:失败
-
int audio_hw_eq_init(struct hw_eq *eq, u32 eq_section_num)
EQ初始化
- Parameters
eq:句柄 –
- Returns
0:成功 -1:失败
-
int audio_hw_eq_ch_open(struct hw_eq_ch *ch, struct hw_eq *eq)
打开一个通道
- Parameters
ch:通道句柄 –
eq:句柄 –
- Returns
0:成功 -1:失败
-
int audio_hw_eq_ch_set_handler(struct hw_eq_ch *ch, struct hw_eq_handler *handler)
设置回调接口
- Parameters
ch:通道句柄 –
handler:回调的句柄 –
- Returns
0:成功 -1:失败
-
int audio_hw_eq_ch_set_info(struct hw_eq_ch *ch, u8 channels, u8 out_32bit)
设置通道基础信息
- Parameters
ch:通道句柄 –
channels:通道数 –
out_32bit:是否输出32bit位宽数据 – 1:是 0:16bit位宽
- Returns
0:成功 -1:失败
-
int audio_hw_eq_ch_set_coeff(struct hw_eq_ch *ch, struct eq_coeff_info *info)
设置硬件转换系数
- Parameters
ch:通道句柄 –
info:系数、增益等信息 –
- Returns
0:成功 -1:失败
-
struct eq_seg_info
- #include <eq.h>
eq段信息
-
struct eq_coeff_info
- #include <eq.h>
eq系数信息
-
struct hw_eq
- #include <eq.h>
硬件eq
-
struct hw_eq_handler
- #include <eq.h>
硬件eq句柄
-
struct hw_eq_ch
- #include <eq.h>
硬件eq通道信息
Public Members
-
unsigned int updata_coeff_only
只更新参数,不更新中间数据
-
unsigned int no_wait
是否是异步eq处理 0:同步的eq 1:异步的eq
-
unsigned int channels
输入通道数
-
unsigned int SHI
eq运算输出数据左移位数控制,记录
-
unsigned int countL
eq运算输出数据左移位数控制临时记录
-
unsigned int stage
eq运算开始位置标识
-
unsigned int nsection
eq段数
-
unsigned int no_coeff
非滤波系数
-
unsigned int reserve
-
volatile unsigned char updata
更新参数以及中间数据
-
volatile unsigned char active
已启动eq处理 1:busy 0:处理结束
-
volatile unsigned char need_run
多eq同时使用时,未启动成功的eq,是否需要重新唤醒处理 1:需要 0:否
-
unsigned short run_mode
0按照输入的数据排布方式 ,输出数据 1:单入多出, 2:立体声入多出
-
unsigned short in_mode
输入数据的位宽 0:short 1:int 2:float
-
unsigned short out_32bit
输出数据的位宽 0:short 1:int 2:float
-
unsigned short out_channels
输出通道数
-
unsigned short data_in_mode
输入数据存放模式
-
unsigned short data_out_mode
输出数据存放模式
-
float *L_coeff
输入给左声道系数地址
-
float *R_coeff
输入给右声道系数地址
-
float L_gain
输入给左声道总增益(-20~20)
-
float R_gain
输入给右声道总增益(-20~20)
-
float *N_coeff[8]
-
float N_gain[8]
-
float *eq_LRmem
eq系数地址(包含运算的中间数据)
-
s16 *out_buf
输出buf地址
-
s16 *in_buf
输入buf地址
-
int in_len
输入数据长度
-
void *priv
保存eq管理层的句柄
-
OS_SEM sem
信号量,用于通知驱动,当前一次处理完成
-
struct list_head entry
当前eq通道的节点
-
const struct hw_eq_handler *eq_handler
q操作的相关回调函数句柄
-
void *irq_priv
eq管理层传入的私有指针
-
void (*irq_callback)(void *priv)
需要eq中断执行的回调函数
-
unsigned int updata_coeff_only