doubao_chat/include_lib/driver/cpu/wl82/asm/eq.h

339 lines
13 KiB
C
Raw Permalink 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 _HW_EQ_H_
#define _HW_EQ_H_
#include "generic/typedef.h"
#include "generic/list.h"
#include "os/os_api.h"
#define EQ_SECTION_MAX 20
/**
* @brief EQ运行模式
*/
enum {
NORMAL = 0, /*!< 正常模式 */
MONO, /*!< 单声道模式 */
STEREO, /*!< 立体声模式 */
};
/**
* @brief 输出数据类型
*/
enum {
DATO_SHORT = 0, /*!< short短整型 */
DATO_INT, /*!< int整型 */
DATO_FLOAT, /*!< float浮点型 */
};
/**
* @brief 输入数据类型
*/
enum {
DATI_SHORT = 0, /*!< short短整型 */
DATI_INT, /*!< int整型 */
DATI_FLOAT, /*!< float浮点型 */
};
/**
* @brief 输入数据存放模式
*/
enum {
BLOCK_DAT_IN = 0, /*!< 块模式,例如输入数据是2通道,先存放完第1通道的所有数据,再存放第2通道的所有数据 */
SEQUENCE_DAT_IN, /*!< 序列模式,例如输入数据是2通道,先存放第1通道的第一个数据,再存放第2个通道的第一个数据,以此类推 */
};
/**
* @brief 输出数据存放模式
*/
enum {
BLOCK_DAT_OUT = 0, /*!< 块模式,例如输出数据是2通道,先存放完第1通道的所有数据,再存放第2通道的所有数据 */
SEQUENCE_DAT_OUT, /*!< 序列模式,例如输入数据是2通道,先存放第1通道的第一个数据,再存放第2个通道的第一个数据,以此类推 */
};
/**
* @brief eq IIR type滤波器类型
*/
typedef enum {
EQ_IIR_TYPE_HIGH_PASS = 0x00, /*!< 高通滤波器 */
EQ_IIR_TYPE_LOW_PASS, /*!< 低通滤波器 */
EQ_IIR_TYPE_BAND_PASS, /*!< 带通滤波器 */
EQ_IIR_TYPE_HIGH_SHELF, /*!< 高架滤波器 */
EQ_IIR_TYPE_LOW_SHELF, /*!< 低架滤波器 */
} EQ_IIR_TYPE;
/**
* @brief eq段信息
*/
struct eq_seg_info {
u16 index; /*!< eq段序号 */
u16 iir_type; /*!< 滤波器类型EQ_IIR_TYPE */
int freq; /*!< 中心截止频率 */
float gain; /*!< 增益(-12 ~12 db) */
float q; /*!< q值(0.3~30) */
};
/**
* @brief eq系数信息
*/
struct eq_coeff_info {
u16 nsection : 6; /*!< eq段数 */
u16 no_coeff : 1; /*!< 不是滤波系数 */
#ifdef CONFIG_EQ_NO_USE_COEFF_TABLE
u32 sr; /*!< 采样率 */
#endif
float *L_coeff; /*!< 左声道滤波器系数地址 */
float *R_coeff; /*!< 右声道滤波器系数地址 */
float L_gain; /*!< 左声道总增益(-20~20db) */
float R_gain; /*!< 右声道总增益(-20~20db)*/
float *N_coeff[8]; /*!< 滤波器系数 */
float N_gain[8]; /*!< 滤波器增益 */
};
/// \cond DO_NOT_DOCUMENT
struct hw_eq_ch;
/// \endcond
/**
* @brief 硬件eq
*/
struct hw_eq {
struct list_head head; /*!< 链表头 */
OS_MUTEX mutex; /*!< 互斥锁 */
struct hw_eq_ch *cur_ch; /*!< 当前需要处理的eq通道 */
};
/// \cond DO_NOT_DOCUMENT
enum {
HW_EQ_CMD_CLEAR_MEM = 0xffffff00,
HW_EQ_CMD_CLEAR_MEM_L,
HW_EQ_CMD_CLEAR_MEM_R,
};
/// \endcond
/**
* @brief 硬件eq句柄
*/
struct hw_eq_handler {
int (*eq_probe)(struct hw_eq_ch *); /*!< eq驱动内前处理 */
int (*eq_output)(struct hw_eq_ch *, s16 *, u16); /*!< eq驱动内输出处理回调 */
int (*eq_post)(struct hw_eq_ch *); /*!< eq驱动内处理后回调 */
int (*eq_input)(struct hw_eq_ch *, void **, void **); /*!< eq驱动内输入处理回调 */
};
// *INDENT-OFF*
/**
* @brief 硬件eq通道信息
*/
struct hw_eq_ch {
unsigned int updata_coeff_only : 1; /*!< 只更新参数,不更新中间数据 */
unsigned int no_wait : 1; /*!< 是否是异步eq处理 0:同步的eq 1:异步的eq */
unsigned int channels : 4; /*!< 输入通道数 */
unsigned int SHI : 4; /*!< eq运算输出数据左移位数控制,记录*/
unsigned int countL : 4; /*!< eq运算输出数据左移位数控制临时记录 */
unsigned int stage : 9; /*!< eq运算开始位置标识 */
unsigned int nsection : 6; /*!< eq段数 */
unsigned int no_coeff : 1; /*!< 非滤波系数 */
unsigned int reserve : 2;
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: 2; /*!< 0按照输入的数据排布方式 ,输出数据 1:单入多出, 2:立体声入多出 */
unsigned short in_mode : 2; /*!< 输入数据的位宽 0:short 1:int 2:float */
unsigned short out_32bit : 2; /*!< 输出数据的位宽 0:short 1:int 2:float */
unsigned short out_channels: 4; /*!< 输出通道数 */
unsigned short data_in_mode: 1; /*!< 输入数据存放模式 */
unsigned short data_out_mode: 1; /*!< 输出数据存放模式*/
#ifdef CONFIG_EQ_NO_USE_COEFF_TABLE
u32 sr; /*!< 采样率 */
#endif
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系数地址(包含运算的中间数据) */
int ram_inbuf_size; /*!< 内部ram输入buf大小 */
int ram_outbuf_size; /*!< 内部ram输出buf大小 */
s16 *ram_inbuf; /*!< 内部ram输入buf地址 */
s16 *ram_outbuf; /*!< 内部ram输出buf地址 */
s16 *out_buf; /*!< 输出buf地址 */
s16 *tmp_outbuf; //临时输出buf地址, 目的为了规避DMA读的慢导致越界问题
int tmp_outbuf_size; //临时输出buf地址大小
s16 *in_buf; /*!< 输入buf地址 */
int in_len; /*!< 输入数据长度 */
void *priv; /*!< 保存eq管理层的句柄 */
OS_SEM sem; /*!< 信号量,用于通知驱动,当前一次处理完成 */
struct list_head entry; /*!< 当前eq通道的节点 */
struct hw_eq *eq; /*!< 底层eq操作句柄 */
const struct hw_eq_handler *eq_handler; /*!< q操作的相关回调函数句柄 */
void *irq_priv; /*!< eq管理层传入的私有指针 */
void (*irq_callback)(void *priv); /*!< 需要eq中断执行的回调函数 */
};
//系数计算子函数
/*----------------------------------------------------------------------------*/
/**@brief 低通滤波器
@param fc:中心截止频率
@param fs:采样率
@param quality_factor:q值
@param coeff:计算后,系数输出地址
*/
/*----------------------------------------------------------------------------*/
void design_lp(int fc, int fs, float quality_factor, float *coeff);
/*----------------------------------------------------------------------------*/
/**@brief 高通滤波器
@param fc:中心截止频率
@param fs:采样率
@param quality_factor:q值
@param coeff:计算后,系数输出地址
*/
/*----------------------------------------------------------------------------*/
void design_hp(int fc, int fs, float quality_factor, float *coeff);
/*----------------------------------------------------------------------------*/
/**@brief 带通滤波器
@param fc:中心截止频率
@param fs:采样率
@param gain:增益
@param quality_factor:q值
@param coeff:计算后,系数输出地址
*/
/*----------------------------------------------------------------------------*/
void design_pe(int fc, int fs, float gain, float quality_factor, float *coeff);
/*----------------------------------------------------------------------------*/
/**@brief 低频搁架式滤波器
@param fc:中心截止频率
@param fs:采样率
@param gain:增益
@param quality_factor:q值
@param coeff:计算后,系数输出地址
*/
/*----------------------------------------------------------------------------*/
void design_ls(int fc, int fs, float gain, float quality_factor, float *coeff);
/*----------------------------------------------------------------------------*/
/**@brief 高频搁架式滤波器
@param fc:中心截止频率
@param fs:采样率
@param gain:增益
@param quality_factor:q值
@param coeff:计算后,系数输出地址
*/
/*----------------------------------------------------------------------------*/
void design_hs(int fc, int fs, float gain, float quality_factor, float *coeff);
/*----------------------------------------------------------------------------*/
/**@brief 滤波器系数检查
@param coeff:滤波器系数
@return 0:成功 -1:失败
*/
/*----------------------------------------------------------------------------*/
int eq_stable_check(float *coeff);
float eq_db2mag(float x);
/*----------------------------------------------------------------------------*/
/**@brief 获取直通的滤波器系数
@param coeff:滤波器系数
*/
/*----------------------------------------------------------------------------*/
void eq_get_AllpassCoeff(void *Coeff);
/*----------------------------------------------------------------------------*/
/**@brief 滤波器计算管理函数
@param seg:提供给滤波器的基本信息
@param sample_rate:采样率
@param coeff:计算后,系数输出地址
@return true:成功 false:失败
*/
/*----------------------------------------------------------------------------*/
int eq_seg_design(struct eq_seg_info *seg, int sample_rate, float *coeff);
/*----------------------------------------------------------------------------*/
/**@brief EQ初始化
@param eq:句柄
@return 0:成功 -1:失败
*/
/*----------------------------------------------------------------------------*/
int audio_hw_eq_init(struct hw_eq *eq, u32 eq_section_num);
/*----------------------------------------------------------------------------*/
/**@brief 打开一个通道
@param ch:通道句柄
@param eq:句柄
@return 0:成功 -1:失败
*/
/*----------------------------------------------------------------------------*/
int audio_hw_eq_ch_open(struct hw_eq_ch *ch, struct hw_eq *eq);
/*----------------------------------------------------------------------------*/
/**@brief 设置回调接口
@param ch:通道句柄
@param handler:回调的句柄
@return 0:成功 -1:失败
*/
/*----------------------------------------------------------------------------*/
int audio_hw_eq_ch_set_handler(struct hw_eq_ch *ch, struct hw_eq_handler *handler);
/*----------------------------------------------------------------------------*/
/**@brief 设置通道基础信息
@param ch:通道句柄
@param channels:通道数
@param out_32bit:是否输出32bit位宽数据 1:是 0:16bit位宽
@return 0:成功 -1:失败
*/
/*----------------------------------------------------------------------------*/
int audio_hw_eq_ch_set_info(struct hw_eq_ch *ch, u8 channels, u8 out_32bit);
/*----------------------------------------------------------------------------*/
/**@brief 设置硬件转换系数
@param ch:通道句柄
@param info:系数、增益等信息
@return 0:成功 -1:失败
*/
/*----------------------------------------------------------------------------*/
int audio_hw_eq_ch_set_coeff(struct hw_eq_ch *ch, struct eq_coeff_info *info);
/*----------------------------------------------------------------------------*/
/**@brief 启动一次转换
@param ch:eq句柄
@param input:输入数据地址
@param output:输出数据地址
@param len:输入数据长度
@return 输出数据的长度
*/
/*----------------------------------------------------------------------------*/
int audio_hw_eq_ch_start(struct hw_eq_ch *ch, void *input, void *output, int len);
/*----------------------------------------------------------------------------*/
/**@brief 关闭一个通道
@param ch:eq句柄
@return 0:成功 -1:失败
*/
/*----------------------------------------------------------------------------*/
int audio_hw_eq_ch_close(struct hw_eq_ch *ch);
/*----------------------------------------------------------------------------*/
/**@brief 挤出eq中的数据
@param eq:eq句柄
@return 0:成功 -1:失败
*/
/*----------------------------------------------------------------------------*/
int audio_hw_eq_flush_out(struct hw_eq *eq);
/*----------------------------------------------------------------------------*/
/**@brief 获取eq是否正在运行状态
@param eq:eq句柄
@return true or false
*/
/*----------------------------------------------------------------------------*/
int audio_hw_eq_is_running(struct hw_eq *eq);
#endif