Files
AC707N/SDK/interface/media/effects/audio_eq.h
T
2025-12-03 11:12:34 +08:00

443 lines
15 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef _EQ_API_H_
#define _EQ_API_H_
#include "typedef.h"
#include "asm/hw_eq.h"
#include "media/audio_stream.h"
#include "system/timer.h"
#include "system/init.h"
#include "effects/effects_adj.h"
#define EQ_COEFF_NUM_PER_SECTION 5
/*eq type*/
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;
/*eq type*/
typedef enum {
EQ_TYPE_FILE = 0x01,
EQ_TYPE_ONLINE,
EQ_TYPE_MODE_TAB,
} EQ_TYPE;
typedef enum {
HW_EQ_CORE_AUTO_SEL = 0,
HW_EQ_CORE_0 = 1,
HW_EQ_CORE_1 = 2,
} HW_EQ_CORE_SEL;
#define audio_eq_filter_info eq_coeff_info
typedef int (*audio_eq_filter_cb)(void *eq, int sr, struct audio_eq_filter_info *info);
//64位的位或处理
#define MASK_BIT(n) (u64)((u64)1 << (n))
struct audio_eq;
struct eq_parm {
u8 in_mode; //输入数据位宽 0:short 1:int 2:float
u8 out_mode; //输出数据位宽 0:short 1:int 2:float
u8 run_mode; //运行模式 0:normal 1:mono 2:stereo
u8 data_in_mode; //输入数据排放模式 0:block_in 1:sequence_in
u8 data_out_mode; //输出数据排放模式 0:block_out 1:sequenceo_out
};
struct audio_eq_param {
u8 no_wait; //异步eq处理使能, 1:使能异步eq(非阻塞) 0:使用同步阻塞方式eq处理
u8 max_nsection; //最大的eq段数,根据使用填写,要小于等于EQ_SECTION_MAX
u8 nsection; //实际需要的eq段数,需小于等于max_nsection
u8 out_32bit; //输入16bit时,输出位宽控制 0:16bit 1:32bit(如需输入其他位宽,请看结构体 struct eq_parm)
u8 channels; //通道数,1:单声道 2:立体声
u8 core; //多硬件支持选配,需芯片支持 0:自动选配, 1:使用eq core1 2:使用eq core2 (HW_EQ_CORE_SEL)
audio_eq_filter_cb cb;//获取eq系数的回调函数
u32 sr; //采样率,更根据当前数据实际采样率填写
float global_gain;
struct eq_seg_info *seg;
float global_gain_r;
struct eq_seg_info *seg_r;
void *parm; //struct eq_parm
void *priv; //私有指针
int (*output)(void *priv, void *data, u32 len);//异步eq输出回调
};
struct eq_fade_parm {
u8 fade_time; //系数更新是否需要淡入,淡入timer循环时间建议值(10~100ms)
u8 f_fade_step; //滤波器中心截止频率淡入步进(10~100Hz)
float fade_step; //滤波器增益淡入步进(0.01f~1.0f)
float q_fade_step; //滤波器q值淡入步进(0.01f~1.0f
float g_fade_step; //总增益淡入步进(0.01f~1.0f
void *priv;
int (*callback)(struct audio_eq *eq, void *priv);//淡出结束时的回调函数
};
struct audio_eq_fade {
u8 type_en;
u8 nsection;
u16 timer;
u32 cur_seg_size;
float cur_global_gain;
float use_global_gain;
struct eq_seg_info *cur_seg;
struct eq_seg_info *use_seg;
u8 *gain_flag;
void *priv;
int (*callback)(struct audio_eq *eq, void *priv);
} ;
#ifdef CONFIG_EQ_SUPPORT_ASYNC
struct audio_eq_async {
u16 ptr;
u16 len;
u16 buf_len;
u8 clear;
u8 out_stu;
char *buf;
};
#endif
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;
u8 core; //多硬件支持选配,需芯片支持
u8 run_status;
u8 dma_ram; //是否使用外部配置的dma_ram 0:否, 1:是
u8 ext_seg_num[2];
u8 ext_coeff_lp_num[2];
u8 ext_coeff_hp_num[2];
u32 sr; //采样率
u64 mask[2];
float global_gain;
float global_gain_r;
s16 *eq_out_buf;//同步方式,32bit输出,当out为NULL时,内部申请eq_out_buf
int out_buf_size;
#ifdef CONFIG_EQ_SUPPORT_ASYNC
void *run_buf;
void *run_out_buf;
int run_len;
struct audio_eq_async async; //异步eq 输出管理
#endif
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 audio_eq_fade *fade;
struct audio_eq_fade *fade_r;
struct eq_fade_parm fade_parm;
void (*resume)(void *priv); //非数据流节点方式,激活解码
void *resume_priv;
spinlock_t lock;
};
/*获取默认系数表EQ_MODE*/
struct eq_default_seg_tab {
float global_gain;
int seg_num;
struct eq_seg_info *seg;
};
struct eq_default_parm { //eq默认参数配置
char name[16]; //节点名字
char mode_index;//节点与多模式关联时,该变量用于获取相应模式下的节点参数.模式序号(如,蓝牙模式下,无多子模式,mode_index 是0
char cfg_index;//默认配置项序号(指定配置文件内的目标配置项)
char core;
struct eq_default_seg_tab default_tab;//发生过调用默认系数表切换(eq_mode_set, eq_mode_sw)的动作时,此处的获取才会有效,否则使用文件内cfg_name对应的参数
};
struct eq_tool {//配置项存储结构
float global_gain; //总增益
int is_bypass: 8; //0 关闭, 1:打开bypass
int seg_num: 8; //eq效果文件存储的段数 +2
int reserve: 16;
struct eq_seg_info seg[0]; //eq系数存储地址,高阶高通低通滤波器追加存储在尾部
};
struct eq_online { //在线调试临时存储的系数结构
int uuid;
char name[16];
int is_bypass; //1: 直通
float global_gain; //总增益
int seg_num; //eq效果文件存储的段数
struct eq_seg_info seg[0]; //eq系数存储地址
};
#define EQ_NAME_CMD 0x1
#define EQ_IS_BYPASS_CMD 0x2
#define EQ_SEG_NUM_CMD 0x3
#define EQ_SEG_CMD 0x7
#define EQ_GLOBAL_GAIN_CMD 0x8
/*
*特殊类型,用于工具同步所有节点参数下来时,提速使用
* */
#define EQ_SPECIAL_CMD 0x9//bypass 总增益 段数
#define EQ_SPECIAL_SEG_CMD 0xa//多滤波器同时更新
/*调音结构、eq节点参数更新结构*/
struct eq_adj {
/*****************************/
/*工具调音结构*/
int type;
union {
int is_bypass;//1: 直通
float global_gain;
int seg_num; //eq效果文件存储的段数
struct eq_seg_info seg;
} param;
/*****************************/
/*参数更新附带淡入配置结构*/
struct eq_fade_parm fade_parm;
};
struct eq_core_check {
struct list_head entry;
void *stream;
int core;
};
/*
*eq core自动选配,并添加到eq core链表
* */
int eq_core_auto_sel(struct eq_core_check *check, void *stream);
/*
* 从eq core链表内删除
* */
void eq_core_auto_del(struct eq_core_check *check);
/*----------------------------------------------------------------------------*/
/**@brief eq模块初始化
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void audio_eq_init(int eq_section_num);
/*----------------------------------------------------------------------------*/
/**@brief eq 打开
@param *param: eq参数句柄,参数详见结构体struct audio_eq_param
@return eq句柄
@note
*/
/*----------------------------------------------------------------------------*/
int audio_eq_open(struct audio_eq *eq, struct audio_eq_param *param);
/*----------------------------------------------------------------------------*/
/**@brief 异步eq设置输出回调
@param eq:句柄
@param *output:回调函数
@return
@note
*/
/*----------------------------------------------------------------------------*/
void audio_eq_set_output_handle(struct audio_eq *eq, int (*output)(void *priv, void *data, u32 len), void *output_priv);
/*----------------------------------------------------------------------------*/
/**@brief 同步eq设置输出buf
@param eq:句柄
@param *output:回调函数
@return
@note
*/
/*----------------------------------------------------------------------------*/
void audio_eq_set_output_buf(struct audio_eq *eq, s16 *buf, u32 len);
/*----------------------------------------------------------------------------*/
/**@brief eq设置采样率
@param eq:句柄
@param sr:采样率
@return
@note
*/
/*----------------------------------------------------------------------------*/
void audio_eq_set_samplerate(struct audio_eq *eq, int sr);
/*----------------------------------------------------------------------------*/
/**@brief eq设置输入输出通道数
@param eq:句柄
@param channel:通道数
@return
@note
*/
/*----------------------------------------------------------------------------*/
void audio_eq_set_channel(struct audio_eq *eq, u8 channel);
/*----------------------------------------------------------------------------*/
/**@brief 设置检查eq是否正在运行
@param eq:句柄
@param check_hw_running: 1:设置检查 0:不检查
@return
@note 检测到硬件正在运行时不等待其完成,直接返回, 仅异步EQ有效
*/
/*----------------------------------------------------------------------------*/
int audio_eq_set_check_running(struct audio_eq *eq, u8 check_hw_running);
/*----------------------------------------------------------------------------*/
/**@brief 设置eq信息
@param eq:句柄
@param channels:设置输入输出通道数
@param out_32bit:使能eq输出32bit数据,1:输出32bit数据, 0:输出16bit是数据
@return
@note
*/
/*----------------------------------------------------------------------------*/
int audio_eq_set_info(struct audio_eq *eq, u8 channels, u8 out_32bit);
/*----------------------------------------------------------------------------*/
/**@brief 设置eq信息
@param eq:句柄
@param channels:设置输出通道数
@param in_mode:使能eq输入32bit数据,2:float, 1:输入32bit数据, 0:输入16bit是数据
@param out_mode:使能eq输出32bit数据,2:float, 1:输出32bit数据, 0:输出16bit是数据
@param run_mode:运行模式,0normal, 1:mono, 2:stero
@param data_in_mode:输入数据存放方式 0:块模式 1:序列模式
@param data_out_mode:输入数据存放方式 0:块模式 1:序列模式
@return
@note
*/
/*----------------------------------------------------------------------------*/
int audio_eq_set_info_new(struct audio_eq *eq, struct hw_eq_info *info);
/*----------------------------------------------------------------------------*/
/**@brief eq启动
@param eq:句柄
@return
@note
*/
/*----------------------------------------------------------------------------*/
int audio_eq_start(struct audio_eq *eq);
/*----------------------------------------------------------------------------*/
/**@brief eq的数据处理
@param eq:句柄
@param *data:输入数据地址
@param len:输入数据长度
@return
@note
*/
/*----------------------------------------------------------------------------*/
int audio_eq_run(struct audio_eq *eq, s16 *data, u32 len);
/*----------------------------------------------------------------------------*/
/**@brief eq关闭
@param eq:句柄
@return
@note
*/
/*----------------------------------------------------------------------------*/
int audio_eq_close(struct audio_eq *eq);
#ifdef CONFIG_EQ_SUPPORT_ASYNC
/*----------------------------------------------------------------------------*/
/**@brief 清除异步eq剩余的数据
@param eq:句柄
@return
@note
*/
/*----------------------------------------------------------------------------*/
void audio_eq_async_data_clear(struct audio_eq *eq);
#endif
/*----------------------------------------------------------------------------*/
/**@brief 获取异步eq剩余的数据
@param eq:句柄
@return
@note
*/
/*----------------------------------------------------------------------------*/
int audio_eq_data_len(struct audio_eq *eq);
/*
* audio_eq_open重新封装,简化使用
**/
/*----------------------------------------------------------------------------*/
struct audio_eq *audio_dec_eq_open(struct audio_eq_param *parm);
/*
*audio_eq_close重新封装,简化使用
* */
void audio_dec_eq_close(struct audio_eq *eq);
/*
*audio_eq_run重新疯转,支持输入输出不同地址,如使用异步处理,out配NULL
* */
int audio_dec_eq_run(struct audio_eq *eq, s16 *in, s16 *out, u16 len);
int audio_eq_flush_out(struct audio_eq *eq);
int check_eq_core(struct eq_core_check *check);
/*
*更新左声道总增益
* */
void audio_eq_update_global_gain(struct audio_eq *eq, struct eq_fade_parm fade_parm, float g_Gain);
/*
*更新右声道总增益
* */
void audio_eq_update_right_ch_global_gain(struct audio_eq *eq, struct eq_fade_parm fade_parm, float g_Gain);
/*
*更新左声某一段eq系数seg
*nsection:总的段数
* */
void audio_eq_update_seg_info(struct audio_eq *eq, struct eq_fade_parm fade_parm, struct eq_seg_info *seg, u32 nsection);
/*
*更新右声道某一段eq系数
*nsection:总的段数
* */
void audio_eq_update_right_ch_seg_info(struct audio_eq *eq, struct eq_fade_parm fade_parm, struct eq_seg_info *seg, u32 nsection);
/*
*段数发生改变,更新系数表地址
* */
void audio_eq_update_seg_ptr(struct audio_eq *eq, struct eq_seg_info *seg);
/*
*eq滤波器系数回调
* */
int eq_get_filter_info(void *_eq, int sr, struct audio_eq_filter_info *info);
/*
*初始化为直通系数
*nsection:总的段数
*coeff:目标系数首地址
* */
void eq_coeff_default_init(u32 nsection, void *coeff);
/*----------------------------------------------------------------------------*/
/**@brief 滤波器计算管理函数
@param *seg:提供给滤波器的基本信息
@param sample_rate:采样率
@param *coeff:计算后,系数输出地址
@return
@note
*/
/*----------------------------------------------------------------------------*/
int eq_seg_design(struct eq_seg_info *seg, int sample_rate, void *coeff);
int audio_eq_tab_check(struct eq_seg_info *seg, u16 seg_num);
int audio_eq_cal_hp_lp_filter_addr(struct audio_eq *eq, struct eq_seg_info *seg_tab, u8 i);
#endif