feat: Add rfid feature and .gitignore file

This commit is contained in:
lmx
2025-11-28 16:25:35 +08:00
parent 818e8c3778
commit ade4b0a1f8
1244 changed files with 342105 additions and 0 deletions

View File

@ -0,0 +1,457 @@
#ifndef _SD_ANC_LIB_H
#define _SD_ANC_LIB_H
#include "asm/anc.h"
#include "timer.h"
#include "math.h"
#if 0
#define _anc_printf printf //打开自适应ANC参数调试信息
#else
extern int anc_printf_off(const char *format, ...);
#define _anc_printf anc_printf_off
#endif
#if 0
#define icsd_printf printf
#else
#define icsd_printf(...)
#endif
#define ANC_TRAIN_TIMEOUT_S 5//10//秒
#define TWS_STA_SIBLING_CONNECTED 0x00000002//tws已连接
#define ANC_USER_TRAIN_DMA_LEN 16384
#define TEST_JT_OFF 0
#define ANC_DEBUG_OFF 0
#define ANC_DEBUG_TONEL_SZ_DATA 1
#define ANC_DEBUG_TONER_SZ_DATA 2
#define ANC_DEBUG_PZ_DATA 3
#define ANC_DEBUG_BYPASS_SIGN 4
extern const u8 ICSD_ANC_DEBUG;
#define ANC_FUN_TARGET_SYNC BIT(0)
extern const u16 ICSD_ANC_FUN;
//FF_FB_EN
#define ICSD_DFF_AFB_EN BIT(7)
#define ICSD_AFF_DFB_EN BIT(6)
#define ICSD_FB_TRAIN_OFF BIT(5)
#define ICSD_FB_TRAIN_NEW BIT(4)
//TEST_ANC_COMBINATION
#define TEST_ANC_COMBINATION_OFF 0x00
#define TEST_TFF_TFB_TONE 0x01 // bypassl强制失败
#define TEST_TFF_TFB_BYPASS 0x02 // tonel强制失败
#define TEST_TFF_DFB 0x03 // FB训练强制失败
#define TEST_DFF_TFB 0x04 // PZ强制失败
#define TEST_DFF_DFB 0x05 // tonel,bypassl,PZ强制失败
#define TEST_DFF_DFB_2 0x06 // tonel,PZ强制失败
//TEST_ANC_TRAIN
#define TEST_ANC_TRAIN_OFF 0x01
#define TEST_FF_TRAIN_PASS 0x02 // 强制每次训练都成功
#define TEST_TRAIN_FAIL 0x03 // 强制每次训练都失败
#define TWS_TONE_BYPASS_MODE 1
#define TWS_BYPASS_MODE 2
#define HEADSET_TONE_BYPASS_MODE 3
#define HEADSET_BYPASS_MODE 4
#define HEADSET_TONES_MODE 5
#define TWS_TONE_MODE 6
//user_train_state------------------------
#define ANC_USER_TRAIN_DMA_READY BIT(0)
#define ANC_USER_TRAIN_TOOL_DATA BIT(1)
#define ANC_DAC_MODE_H1_DIFF BIT(2)
#define ANC_USER_TRAIN_DMA_EN BIT(3)
#define ANC_USER_TRAIN_TONEMODE BIT(4)
#define ANC_TRAIN_TONE_PLAY BIT(5)
#define ANC_TRAIN_TONE_END BIT(6)
#define ANC_TRAIN_TONE_FIRST BIT(7)
#define ANC_TRAIN_IIR_READY BIT(8)
#define ANC_MASTER_RX_PZSYNC BIT(9)
#define ANC_FB_IIR_AB_DONE BIT(10)
#define ANC_FF_IIR_AB_DONE BIT(11)
#define ANC_PZOUT_INITED BIT(12)
#define ANC_SZOUT_INITED BIT(13)
#define ANC_USER_TRAIN_RUN BIT(14)
#define ANC_TRAIN_TIMEOUT BIT(15)
#define ANC_TRAIN_DMA_ON BIT(16)
#define ANC_TONE_DAC_ON BIT(17)
#define ANC_TONE_ANC_READY BIT(18)
#define ANC_TONESMODE_BYPASS_OFF BIT(19)
#define ANC_RX_TARGET BIT(20)
#define ANC_TARGET_DONE BIT(21)
//icsd_anc_contral
#define ICSD_ANC_FORCED_EXIT BIT(0)
#define ICSD_ANC_SUSPENDED BIT(1)
#define ICSD_ANC_FADE_GAIN_RESUME BIT(2)
#define ICSD_ANC_TONE_END BIT(3)
#define ICSD_ANC_INITED BIT(4)
#define ICSD_ANC_FORCED_BEFORE_INIT BIT(5)
//anctask cmd
enum {
ANC_CMD_FORCED_EXIT = 0,
ANC_CMD_TONE_MODE_START,
ANC_CMD_TONEL_START,
ANC_CMD_TONER_START,
ANC_CMD_PZL_START,
ANC_CMD_PZR_START,
ANC_CMD_TONE_DACON,
ANC_CMD_TRAIN_AFTER_TONE,
ANC_CMD_TARGET_END,
ANC_CMD_TARGET_HANDLE,
};
//SZPZ->anc_err---------------------------
#define ANC_ERR_LR_BALANCE BIT(0)//左右耳不平衡
#define ANC_ERR_SOUND_PRESSURE BIT(1)//低声压
#define ANC_ERR_SHAKE BIT(2)//抖动
//icsd_anc_function-----------------------
#define ANC_ADAPTIVE_CMP BIT(0)
#define ANC_EARPHONE_CHECK BIT(1)
#define TARLEN 120
#define TARLEN_L 40
#define DRPPNT 10
#define ANC_FBANC_OUT_SEL_L 13
#define ANC_FFANC_OUT_SEL_L 12
struct icsd_anc_tws_packet {
s8 *data;
u16 len;
};
struct icsd_anc_board_param {
u8 iir_mode;
void *anc_db;
void *anc_data_l;
void *anc_data_r;
void *anc_double_data_l;
void *anc_double_data_r;
u8 default_ff_gain;
u8 default_fb_gain;
s8 tool_ffgain_sign;
s8 tool_fbgain_sign;
s8 tool_target_sign;
s8 tfb_sign;
s8 tff_sign;
s8 bfb_sign;
s8 bff_sign;
s8 bypass_sign;
float m_value_l; //80 ~ 200 //135 最深点位置中心值
float sen_l; //12 ~ 22 //18 最深点深度
float in_q_l; //0.4 ~ 1.2 //0.6 最深点降噪宽度
float m_value_r; //80 ~ 200 //135 最深点位置中心值
float sen_r; //12 ~ 22 //18 最深点深度
float in_q_r; //0.4 ~ 1.2 //0.6 最深点降噪宽度
float *mse_tar;
int gold_curve_en;
float gain_a_param;
u8 gain_a_en;
u8 cmp_abs_en;
u8 jt_en;
int idx_begin;
int idx_end;
u8 FB_NFIX;
u16 fb_w2r;
float sen_offset_l;
float sen_offset_r;
u8 gain_min_offset;
u8 gain_max_offset;
u8 ff_target_fix_num_l;
u8 ff_target_fix_num_r;
u8 pz_max_times;
u8 bypass_max_times;
u8 ff_yorder;
u8 fb_yorder;
u8 cmp_yorder;
int cmp_type[8];
float cmp_thd_low;
float cmp_thd_high;
float bypass_volume;
float minvld;
//ctl
u8 mode;
u8 FF_FB_EN;
u8 dma_belong_to;
u32 tone_jiff;
int IIR_NUM;// 4 3
int IIR_NUM_FIX;// 4 8-IIR_NUM
int IIR_COEF; //(IIR_NUM * 3+1)
u8 JT_MODE;
float *anc_szl_out;
float *anc_szr_out;
float sz_priority_thr;
};
extern struct icsd_anc_board_param *ANC_BOARD_PARAM;
struct icsd_anc_backup {
int gains_alogm;
u8 gains_l_ffmic_gain;
u8 gains_l_fbmic_gain;
u8 gains_r_ffmic_gain;
u8 gains_r_fbmic_gain;
float gains_l_ffgain;
float gains_l_fbgain;
float gains_r_ffgain;
float gains_r_fbgain;
double *lff_coeff;
double *lfb_coeff;
double *rff_coeff;
double *rfb_coeff;
u8 lff_yorder;
u8 lfb_yorder;
u8 rff_yorder;
u8 rfb_yorder;
u8 ff_1st_dcc;
u8 fb_1st_dcc;
u8 ff_2nd_dcc;
u8 fb_2nd_dcc;
u8 gains_drc_en;
};
extern volatile struct icsd_anc_backup *CFG_BACKUP;
struct icsd_anc {
audio_anc_t *param;
u16 *anc_fade_gain;
u8 mode;
u8 train_index;
u8 adaptive_run_busy; //自适应训练中
int *gains_alogm;
u8 *gains_l_ffmic_gain;
u8 *gains_l_fbmic_gain;
u8 *gains_r_ffmic_gain;
u8 *gains_r_fbmic_gain;
float *gains_l_ffgain;
float *gains_l_fbgain;
float *gains_l_cmpgain;
float *gains_r_ffgain;
float *gains_r_fbgain;
float *gains_r_cmpgain;
double **lff_coeff;
double **lfb_coeff;
double **lcmp_coeff;
double **rff_coeff;
double **rfb_coeff;
double **rcmp_coeff;
u8 *lff_yorder;
u8 *lfb_yorder;
u8 *lcmp_yorder;
u8 *rff_yorder;
u8 *rfb_yorder;
u8 *rcmp_yorder;
u8 *ff_1st_dcc;
u8 *fb_1st_dcc;
u8 *ff_2nd_dcc;
u8 *fb_2nd_dcc;
u8 *gains_drc_en;
void *src_hdl;
u32 dac_on_jiff;
u32 dac_on_slience;
int tone_delay;
};
extern volatile struct icsd_anc ICSD_ANC;
struct icsd_anc_tool_data {
int h_len;
int yorderb;//int fb_yorder;
int yorderf;//int ff_yorder;
int yorderc;//int cmp_yorder;
float *h_freq;
float *data_out1;//float *hszpz_out_l;
float *data_out2;//float *hpz_out_l;
float *data_out3;//float *htarget_out_l;
float *data_out4;//float *fb_fgq_l;
float *data_out5;//float *ff_fgq_l;
float *data_out6;//float *hszpz_out_r;
float *data_out7;//float *hpz_out_r;
float *data_out8;//float *htarget_out_r;
float *data_out9;//float *fb_fgq_r;,
float *data_out10;//float *ff_fgq_r;
float *data_out11;//float *cmp_fgq_l;
float *data_out12;//float *cmp_fgq_r;
float *data_out13;//float *tool_target_out_l;
float *data_out14;//float *tool_target_out_r;
float *wz_temp;
u8 result;
u8 anc_err;
u8 save_idx;
u8 use_idx;
u8 tws_use_idx;
u8 anc_combination;
u8 cmp_result;
};
extern volatile struct icsd_anc_tool_data *TOOL_DATA;
enum {
TFF_TFB = 0,
TFF_DFB,
DFF_TFB,
DFF_DFB,
};
enum {
ICSD_FULL_INEAR = 0,
ICSD_HALF_INEAR,
ICSD_HEADSET,
};
extern const u8 ICSD_EP_TYPE;
extern int (*anc_printf)(const char *format, ...);
extern int icsd_anc_id;
extern volatile u8 icsd_anc_function;
extern volatile u8 icsd_anc_contral;
extern volatile int user_train_state;
extern u32 train_time;
extern u16 icsd_time_out_hdl;
extern u8 icsd_anc_combination_test;
extern u8 icsd_anc_train_test;
extern const u8 TWS_MODE;
extern const u8 HEADSET_MODE;
extern const u8 NEW_PRE_TREAT;
extern const u8 icsd_dcc[4];
extern const u8 FF_VERSION;
extern const u8 cmp_iir_type[];
extern const u8 ff_iir_type[];
extern const u8 fb_iir_type[];
//LIB调用的算术函数
extern float complex_abs_float(float x, float y);
extern float sin_float(float x);
extern float cos_float(float x);
extern float cos_hq(float x);
extern float sin_hq(float x);
extern float log10_float(float x);
extern float exp_float(float x);
extern float root_float(float x);
extern float anc_pow10(float n);
extern float angle_float(float x, float y);
extern void icsd_anc_save_with_idx(u8 save_idx);
extern void audio_adc_mic_demo_close(void);
extern void icsd_anc_board_config();
//SDK调用的SDANC APP函数
extern void icsd_anc_dma_done();
extern void icsd_anc_end(audio_anc_t *param);
extern void icsd_anc_run();
extern void icsd_anc_setparam();
extern void icsd_anc_timeout_handler();
extern void icsd_anc_init(audio_anc_t *param, u8 mode, u8 seq, int tone_delay, u8 tws_balance_en);
extern u16 sys_timeout_add(void *priv, void (*func)(void *priv), u32 msec);
extern void icsd_anc_tone_play_start();
extern void icsd_anctone_dacon(u32 slience_frames, u16 sample_rate);
extern u8 icsd_anc_train_result_get(struct icsd_anc_tool_data *TOOL_DATA);
//SDANC APP调用的库函数
extern void icsd_anc_cmd_packet(s8 *data, u8 cmd);
extern void icsd_anc_tws_sync_cmd(void *_data, u16 len, bool rx);
extern void icsd_anc_version();
extern void icsd_anc_lib_init();
extern void icsd_anc_htarget_data_send_end();
extern void icsd_anc_mode_init(int tone_delay);
extern void icsd_anc_train_after_tone();
extern void icsd_anc_m2s_packet(s8 *data, u8 cmd);
extern void icsd_anc_s2m_packet(s8 *data, u8 cmd);
extern void icsd_anc_msync_packet(struct icsd_anc_tws_packet *packet, u8 cmd);
extern void icsd_anc_ssync_packet(struct icsd_anc_tws_packet *packet, u8 cmd);
extern void icsd_anc_m2s_cb(void *_data, u16 len, bool rx);
extern void icsd_anc_s2m_cb(void *_data, u16 len, bool rx);
extern void icsd_anc_msync_cb(void *_data, u16 len, bool rx);
extern void icsd_anc_ssync_cb(void *_data, u16 len, bool rx);
extern void cal_wz(double *ab, float gain, int tap, float *freq, float fs, float *wz, int len);
extern void ff_fgq_2_aabb(double *iir_ab, float *ff_fgq);
extern float icsd_anc_vmdata_match(float *_vmdata, float gain);
extern void icsd_anc_tonemode_start();
extern float icsd_anc_default_match();
extern void icsd_anc_anctask_cmd_handle(u8 cmd);
extern void icsd_anc_board_param_init();
extern void icsd_anc_tool_data_init();
//SDANC APP调用的SDK函数
extern void icsd_biquad2ab_out(float gain, float f, float fs, float q, double *a0, double *a1, double *a2, double *b0, double *b1, double *b2, int type);
extern void biquad2ab_double(float gain, float f, float q, double *a0, double *a1, double *a2, double *b0, double *b1, double *b2, int type);
extern int tws_api_get_role(void);
extern int tws_api_get_tws_state();
extern void anc_dma_on(u8 out_sel, int *buf, int len);
extern void audio_anc_fade2(int gain, u8 en, u8 step, u8 slow);
extern void anc_user_train_process(audio_anc_t *param);
extern void audio_anc_post_msg_user_train_run(void);
extern void audio_anc_post_msg_user_train_setparam(void);
extern void audio_anc_post_msg_user_train_timeout(void);
extern unsigned int hw_fft_config(int N, int log2N, int is_same_addr, int is_ifft, int is_real);
extern void hw_fft_run(unsigned int fft_config, const int *in, int *out);
extern void anc_user_train_cb(u8 mode, u8 result, u8 forced_exit);
//库调用的SDANC APP函数
extern void icsd_anc_set_alogm(void *_param, int alogm);
extern void icsd_anc_set_micgain(void *_param, int lff_gain, int lfb_gain);
extern void icsd_anc_fade(void *_param);
extern void icsd_anc_long_fade(void *_param);
extern void icsd_anc_user_train_dma_on(u8 out_sel, u32 len, int *buf);
extern void icsd_anc_htarget_data_send();
extern void icsd_anc_fft(int *in, int *out);
extern u32 icsd_anc_get_role();
extern u32 icsd_anc_get_tws_state();
extern void icsd_anc_tws_m2s(u8 cmd);
extern void icsd_anc_tws_s2m(u8 cmd);
extern void icsd_anc_tws_msync(u8 cmd);
extern void icsd_anc_tws_ssync(u8 cmd);
extern void icsd_anc_train_timeout();
extern void icsd_anc_src_init(int in_rate, int out_rate, int (*handler)(void *, void *, int));
extern void icsd_anc_src_write(void *data, int len);
extern u8 icsd_anc_get_save_idx();
extern void icsd_anc_vmdata_num_reset();
extern u8 icsd_anc_get_vmdata_num();
extern u8 icsd_anc_min_diff_idx();
extern void icsd_anc_fgq_printf(float *ptr);
extern void icsd_anc_aabb_printf(double *iir_ab);
extern void icsd_anc_vmdata_by_idx(double *ff_ab, float *ff_gain, u8 idx);
extern void icsd_anc_vmdatar_by_idx(double *ff_ab, float *ff_gain, u8 idx);
extern void icsd_anc_config_inf();
extern void icsd_anc_ear_record_printf();
extern u8 icsd_anc_tooldata_select_vmdata(float *ff_fgq);
extern u8 icsd_anc_tooldata_select_vmdata_headset(float *ff_fgq_l, float *ff_fgq_r);
extern void icsd_audio_adc_mic_open(u8 mic_idx, u8 gain, u16 sr, u8 mic_2_dac);
extern void icsd_audio_adc_mic_close();
extern void sd_anc_exit();
extern void icsd_anc_tonel_start(void *priv);
extern void icsd_anc_toner_start(void *priv);
extern void icsd_anc_pzl_start(void *priv);
extern void icsd_anc_pzr_start(void *priv);
extern void anc_dmadata_debug();
extern void icsd_anc_fft256(int *in, int *out);
extern void icsd_anc_src_push();
extern void anc_core_dma_stop(void);
extern void anc_core_dma_ie(u8 en);
extern void icsd_anc_forced_exit();
extern void audio_anc_post_msg_icsd_anc_cmd(u8 cmd);
extern void icsd_anctone_dacon_handler();
extern void icsd_anc_forced_exit_end();
extern float anc_pow10(float n);
enum {
SD_ANC_TWS = 0,
SD_ANC_HEADSET,
};
struct icsd_anc_libfmt {
int lib_alloc_size; //算法ram需求大小
};
struct icsd_anc_infmt {
void *alloc_ptr; //外部申请的ram地址
};
extern void icsd_anc_set_infmt(struct icsd_anc_infmt *fmt);
extern void icsd_anc_get_libfmt(struct icsd_anc_libfmt *libfmt, u8 type);
extern const float THD_JT;
extern const float THD_JT_SAVE;
extern const float THD_JT2;
extern const float spl_tb [21];
extern const float spl_freq_tb [21];
extern const float target_cmp_dat[];
#endif

View File

@ -0,0 +1,756 @@
#include "icsd_anc_app.h"
#include "classic/tws_api.h"
#include "board_config.h"
#include "tone_player.h"
#include "adv_adaptive_noise_reduction.h"
#include "audio_anc.h"
#include "asm/audio_src.h"
#include "icsd_anc_user.h"
#if 1
#define icsd_anc_log printf
#else
#define icsd_anc_log(...)
#endif/*log_en*/
#if TCFG_AUDIO_ANC_EAR_ADAPTIVE_EN
#if (ICSD_ANC_MODE == TWS_TONE_BYPASS_MODE) || \
(ICSD_ANC_MODE == TWS_TONE_MODE) || \
(ICSD_ANC_MODE == TWS_BYPASS_MODE)
const u8 TWS_MODE = 1;
#else
const u8 TWS_MODE = 0;
#endif/**/
#if (ICSD_ANC_MODE == HEADSET_TONE_BYPASS_MODE) || \
(ICSD_ANC_MODE == HEADSET_BYPASS_MODE) || \
(ICSD_ANC_MODE == HEADSET_TONES_MODE)
const u8 HEADSET_MODE = 1;
#else
const u8 HEADSET_MODE = 0;
#endif/**/
const u8 ICSD_ANC_DEBUG = ICSD_ANC_DEBUG_TYPE;
u32 train_time;
struct icsd_anc_board_param *ANC_BOARD_PARAM = NULL;
volatile struct icsd_anc_tool_data *TOOL_DATA = NULL;
volatile struct icsd_anc_backup *CFG_BACKUP = NULL;
volatile struct icsd_anc ICSD_ANC;
volatile u8 icsd_anc_contral = 0;
volatile u8 icsd_anc_function = 0;
int *user_train_buf = 0;
volatile int user_train_state = 0;
u16 icsd_time_out_hdl = 0;
u8 icsd_anc_combination_test;
u8 icsd_anc_train_test;
int icsd_anc_id = 0;
u8 icsd_anc_tws_balance_en = 0;
int (*anc_printf)(const char *format, ...);
int anc_printf_off(const char *format, ...)
{
return 0;
}
#define TWS_FUNC_ID_SDANC_M2S TWS_FUNC_ID('I', 'C', 'M', 'S')
REGISTER_TWS_FUNC_STUB(icsd_anc_m2s) = {
.func_id = TWS_FUNC_ID_SDANC_M2S,
.func = icsd_anc_m2s_cb,
};
#define TWS_FUNC_ID_SDANC_S2M TWS_FUNC_ID('I', 'C', 'S', 'M')
REGISTER_TWS_FUNC_STUB(icsd_anc_s2m) = {
.func_id = TWS_FUNC_ID_SDANC_S2M,
.func = icsd_anc_s2m_cb,
};
#define TWS_FUNC_ID_SDANC_MSYNC TWS_FUNC_ID('I', 'C', 'M', 'N')
REGISTER_TWS_FUNC_STUB(icsd_anc_msync) = {
.func_id = TWS_FUNC_ID_SDANC_MSYNC,
.func = icsd_anc_msync_cb,
};
#define TWS_FUNC_ID_SDANC_SSYNC TWS_FUNC_ID('I', 'C', 'S', 'N')
REGISTER_TWS_FUNC_STUB(icsd_anc_ssync) = {
.func_id = TWS_FUNC_ID_SDANC_SSYNC,
.func = icsd_anc_ssync_cb,
};
void icsd_anc_tws_msync(u8 cmd)
{
struct icsd_anc_tws_packet packet;
icsd_anc_msync_packet(&packet, cmd);
anc_printf("msync:%d %d\n", packet.len, packet.data[0]);
int ret = tws_api_send_data_to_sibling(packet.data, packet.len, TWS_FUNC_ID_SDANC_MSYNC);
}
void icsd_anc_tws_ssync(u8 cmd)
{
struct icsd_anc_tws_packet packet;
icsd_anc_ssync_packet(&packet, cmd);
anc_printf("ssync:%d %d\n", packet.len, packet.data[0]);
int ret = tws_api_send_data_to_sibling(packet.data, packet.len, TWS_FUNC_ID_SDANC_SSYNC);
}
void icsd_anc_tws_m2s(u8 cmd)
{
s8 data[16];
icsd_anc_m2s_packet(data, cmd);
int ret = tws_api_send_data_to_sibling(data, 16, TWS_FUNC_ID_SDANC_M2S);
}
void icsd_anc_tws_s2m(u8 cmd)
{
s8 data[16];
icsd_anc_s2m_packet(data, cmd);
int ret = tws_api_send_data_to_sibling(data, 16, TWS_FUNC_ID_SDANC_S2M);
}
float anc_pow10(float n)
{
float pow10n = exp_float((float)n / log10_float(exp_float((float)1.0)));
return pow10n;
}
void icsd_anc_fgq_printf(float *ptr)
{
icsd_anc_log("icsd_anc_fgq\n");
for (int i = 0; i < ANC_VMDATA_FF_RECORD_SIZE; i++) {
icsd_anc_log("%d\n", (int)((*ptr++) * 1000));
}
}
void icsd_anc_aabb_printf(double *iir_ab)
{
icsd_anc_log("icsd_anc_aabb\n");
for (int i = 0; i < ANC_BOARD_PARAM->fb_yorder; i++) {
icsd_anc_log("AB:%d %d %d %d %d\n", (int)(iir_ab[i * 5] * 100000000),
(int)(iir_ab[i * 5 + 1] * 100000000),
(int)(iir_ab[i * 5 + 2] * 100000000),
(int)(iir_ab[i * 5 + 3] * 100000000),
(int)(iir_ab[i * 5 + 4] * 100000000));
}
//put_buf(iir_ab, 8 * 40);
}
void icsd_anc_forced_exit()
{
if (!(icsd_anc_contral & ICSD_ANC_FORCED_EXIT)) {
icsd_printf("icsd_anc_forced_exit----------------------------\n");
if (icsd_anc_contral & ICSD_ANC_INITED) {
icsd_anc_contral |= ICSD_ANC_FORCED_EXIT;
audio_anc_post_msg_icsd_anc_cmd(ANC_CMD_FORCED_EXIT);
} else {
icsd_anc_contral |= ICSD_ANC_FORCED_BEFORE_INIT;
}
}
}
void icsd_anc_train_timeout()
{
icsd_anc_log("icsd_anc_train_timeout\n");
user_train_state &= ~ANC_USER_TRAIN_RUN;
user_train_state |= ANC_TRAIN_TIMEOUT;
audio_anc_post_msg_user_train_timeout();
}
u32 icsd_anc_get_role()
{
return tws_api_get_role();
}
u32 icsd_anc_get_tws_state()
{
if (icsd_anc_tws_balance_en) {
return tws_api_get_tws_state();
}
return 0;
}
void icsd_anc_set_alogm(void *_param, int alogm)
{
audio_anc_t *param = _param;
param->gains.alogm = alogm;
}
void icsd_anc_set_micgain(void *_param, int lff_gain, int lfb_gain)
{
//0 ~ 15
audio_anc_t *param = _param;
icsd_anc_log("mic gain set:%d %d-->%d %d\n", param->gains.l_ffmic_gain, param->gains.l_fbmic_gain, lff_gain, lfb_gain);
param->gains.l_ffmic_gain = lff_gain;
param->gains.l_fbmic_gain = lfb_gain;
audio_anc_mic_management(param);
audio_anc_mic_gain(param->mic_param, 0);
}
void icsd_anc_fft(int *in, int *out)
{
u32 fft_config;
fft_config = hw_fft_config(1024, 10, 1, 0, 1);
hw_fft_run(fft_config, in, out);
}
void icsd_anc_fft256(int *in, int *out)
{
u32 fft_config;
fft_config = hw_fft_config(256, 8, 1, 0, 1);
hw_fft_run(fft_config, in, out);
}
void icsd_anc_fade(void *_param)
{
audio_anc_t *param = _param;
audio_anc_fade2(param->anc_fade_gain, param->anc_fade_en, 1, 0);
}
void icsd_anc_long_fade(void *_param)
{
audio_anc_t *param = _param;
audio_anc_fade2(0, param->anc_fade_en, 4, 0); //增益先淡出到0
os_time_dly(10);//10
}
void icsd_anc_user_train_dma_on(u8 out_sel, u32 len, int *buf)
{
user_train_state |= ANC_TRAIN_DMA_ON;
anc_dma_on(out_sel, buf, len);
}
void icsd_anc_dma_done()
{
if (ICSD_ANC.adaptive_run_busy) {
if (user_train_state & ANC_USER_TRAIN_DMA_EN) {
if (user_train_state & ANC_USER_TRAIN_DMA_READY) {
user_train_state &= ~ANC_USER_TRAIN_DMA_READY;
anc_core_dma_stop();
audio_anc_post_msg_user_train_run();
} else {
user_train_state |= ANC_USER_TRAIN_DMA_READY;
}
}
}
}
void *anc_ram_addr = 0;
void sd_anc_exit()
{
if (anc_ram_addr) {
free(anc_ram_addr);
anc_ram_addr = 0;
}
printf("sd_anc_exit");
mem_stats();
}
void sd_anc_init()
{
anc_printf = _anc_printf;
printf("sd anc init\n");
mem_stats();
struct icsd_anc_libfmt libfmt;
icsd_anc_get_libfmt(&libfmt, SD_ANC_TWS);
if (anc_ram_addr == 0) {
anc_ram_addr = zalloc(libfmt.lib_alloc_size);
}
struct icsd_anc_infmt infmt;
infmt.alloc_ptr = anc_ram_addr;
icsd_anc_set_infmt(&infmt);
printf("ram init:%d\n", libfmt.lib_alloc_size);
}
void icsd_anc_init(audio_anc_t *param, u8 mode, u8 seq, int tone_delay, u8 tws_balance_en)
{
sd_anc_init();
anc_printf = _anc_printf;
icsd_anc_contral |= ICSD_ANC_INITED;
if (icsd_anc_contral & ICSD_ANC_FORCED_BEFORE_INIT) {
icsd_anc_contral &= ~ICSD_ANC_FORCED_BEFORE_INIT;
icsd_anc_forced_exit();
}
if (icsd_anc_contral & ICSD_ANC_FORCED_EXIT) {
icsd_printf("icsd_anc_init FORCED EXIT\n");
return;
}
icsd_anc_id = seq;
icsd_anc_tws_balance_en = tws_balance_en;
icsd_anc_log("sd anc init:%d, seq %d, tone_delay %d, tws_balance %d ======================================\n", seq, tone_delay, icsd_anc_id, tws_balance_en);
mem_stats();
user_train_state = 0;
icsd_anc_function = 0;
if (mode == 1) {
user_train_state |= ANC_USER_TRAIN_TOOL_DATA;
icsd_anc_tool_data_init();
}
user_train_state |= ANC_TRAIN_TONE_PLAY;
icsd_anc_combination_test = TEST_ANC_COMBINATION;
icsd_anc_train_test = TEST_ANC_TRAIN;
#if ANC_USER_TRAIN_TONE_MODE
user_train_state |= ANC_USER_TRAIN_TONEMODE;
#endif
#if HEADSET_TONES_MODE_BYPASS_OFF
user_train_state |= ANC_TONESMODE_BYPASS_OFF;
#endif
#if ANC_ADAPTIVE_CMP_EN
icsd_anc_function |= ANC_ADAPTIVE_CMP;
#endif
#if ANC_EARPHONE_CHECK_EN
icsd_anc_function |= ANC_EARPHONE_CHECK;
#endif
ICSD_ANC.param = param;
ICSD_ANC.adaptive_run_busy = 1;
ICSD_ANC.anc_fade_gain = &param->anc_fade_gain;
ICSD_ANC.gains_l_ffgain = &param->gains.l_ffgain;
ICSD_ANC.gains_l_fbgain = &param->gains.l_fbgain;
ICSD_ANC.gains_l_cmpgain = &param->gains.l_cmpgain;
ICSD_ANC.gains_r_ffgain = &param->gains.r_ffgain;
ICSD_ANC.gains_r_fbgain = &param->gains.r_fbgain;
ICSD_ANC.gains_r_cmpgain = &param->gains.r_cmpgain;
ICSD_ANC.lff_yorder = &param->lff_yorder;
ICSD_ANC.lfb_yorder = &param->lfb_yorder;
ICSD_ANC.lcmp_yorder = &param->lcmp_yorder;
ICSD_ANC.rff_yorder = &param->rff_yorder;
ICSD_ANC.rfb_yorder = &param->rfb_yorder;
ICSD_ANC.rcmp_yorder = &param->rcmp_yorder;
ICSD_ANC.lff_coeff = &param->lff_coeff;
ICSD_ANC.lfb_coeff = &param->lfb_coeff;
ICSD_ANC.lcmp_coeff = &param->lcmp_coeff;
ICSD_ANC.rff_coeff = &param->rff_coeff;
ICSD_ANC.rfb_coeff = &param->rfb_coeff;
ICSD_ANC.rcmp_coeff = &param->rcmp_coeff;
ICSD_ANC.gains_l_ffmic_gain = &param->gains.l_ffmic_gain;
ICSD_ANC.gains_l_fbmic_gain = &param->gains.l_fbmic_gain;
ICSD_ANC.gains_r_ffmic_gain = &param->gains.r_ffmic_gain;
ICSD_ANC.gains_r_fbmic_gain = &param->gains.r_fbmic_gain;
ICSD_ANC.gains_alogm = (int *)(&param->gains.alogm);
ICSD_ANC.ff_1st_dcc = &param->gains.ff_1st_dcc;
ICSD_ANC.fb_1st_dcc = &param->gains.fb_1st_dcc;
ICSD_ANC.ff_2nd_dcc = &param->gains.ff_2nd_dcc;
ICSD_ANC.fb_2nd_dcc = &param->gains.fb_2nd_dcc;
ICSD_ANC.gains_drc_en = &param->gains.drc_en;
ICSD_ANC.mode = ANC_USER_TRAIN_MODE;
ICSD_ANC.train_index = 0;
ICSD_ANC.adaptive_run_busy = 1;
icsd_anc_board_config();
user_train_state |= ANC_USER_TRAIN_DMA_EN;
TOOL_DATA->save_idx = 0xff;
ANC_BOARD_PARAM->iir_mode = ANC_USER_TRAIN_MODE;
ANC_BOARD_PARAM->tool_ffgain_sign = 1;
ANC_BOARD_PARAM->tool_fbgain_sign = 1;
if (param->gains.gain_sign & ANCL_FF_SIGN) {
ANC_BOARD_PARAM->tool_ffgain_sign = -1;
}
if (param->gains.gain_sign & ANCL_FB_SIGN) {
ANC_BOARD_PARAM->tool_fbgain_sign = -1;
}
//金机曲线功能==================================
#if 1
icsd_anc_log("ref en:%d----------------------\n", param->gains.adaptive_ref_en);
struct icsd_fb_ref *fb_parm = NULL;
struct icsd_ff_ref *ff_parm = NULL;
if (param->gains.adaptive_ref_en) {
icsd_anc_log("get ref data\n");
anc_adaptive_fb_ref_data_get((u8 **)(&fb_parm));
anc_adaptive_ff_ref_data_get((u8 **)(&ff_parm));
ANC_BOARD_PARAM->m_value_l = fb_parm->m_value;
ANC_BOARD_PARAM->sen_l = fb_parm->sen;
ANC_BOARD_PARAM->in_q_l = fb_parm->in_q;
icsd_anc_log("fb_parm:%d %d %d\n", (int)(fb_parm->m_value * 1000), (int)(fb_parm->sen * 1000), (int)(fb_parm->in_q * 1000));
}
if (ff_parm) {
icsd_anc_log("use gold curve==========================================================\n");
ANC_BOARD_PARAM->gold_curve_en = param->gains.adaptive_ref_en;
ANC_BOARD_PARAM->mse_tar = ff_parm->db;
}
#endif
//==============================================
icsd_anc_config_inf();
icsd_anc_lib_init();
icsd_anc_set_alogm(param, ANC_USER_TRAIN_SR_SEL);
ICSD_ANC.tone_delay = tone_delay;
icsd_anc_mode_init(tone_delay);
}
void icsd_anc_init_cmd()
{
icsd_anc_log("icsd_anc_init_cmd\n");
extern void audio_anc_post_msg_user_train_init(u8 mode);
audio_anc_post_msg_user_train_init(ANC_ON);
}
u32 icsd_slience_frames;
u16 icsd_sample_rate;
void icsd_anctone_dacon_handler()
{
u32 slience_frames = icsd_slience_frames;
u16 sample_rate = icsd_sample_rate;
if (icsd_anc_contral & ICSD_ANC_FORCED_EXIT) {
icsd_printf("icsd_anctone_dacon FORCED EXIT\n");
return;
}
if (user_train_state & ANC_TRAIN_TONE_PLAY) {
icsd_anc_board_param_init();
ANC_BOARD_PARAM->mode = ICSD_ANC_MODE;
icsd_anc_log("icsd_anctone_dacon 1:%d %d %d\n", (int)jiffies, slience_frames, sample_rate);
user_train_state |= ANC_TONE_DAC_ON;
user_train_state &= ~ANC_TRAIN_TONE_PLAY;
u32 slience_ms = 0;
if ((slience_frames != 0) && (sample_rate != 0)) {
slience_ms = (slience_frames * 1000 / sample_rate) + 1;
icsd_anc_log("icsd_anctone_dacon 2:%d %d %d\n", slience_frames, sample_rate, slience_ms);
}
ANC_BOARD_PARAM->tone_jiff = jiffies + (slience_ms / 10) + 1;
ICSD_ANC.dac_on_jiff = jiffies;
ICSD_ANC.dac_on_slience = slience_ms;
if (user_train_state & ANC_TONE_ANC_READY) {
icsd_anc_log("dac on set tonemode start timeout:%d %d\n", slience_ms, ANC_BOARD_PARAM->tone_jiff);
switch (ANC_BOARD_PARAM->mode) {
case HEADSET_TONES_MODE:
sys_hi_timeout_add((void *)icsd_anc_id, icsd_anc_tonel_start, slience_ms + TONEL_DELAY);
sys_hi_timeout_add((void *)icsd_anc_id, icsd_anc_toner_start, slience_ms + TONER_DELAY);
sys_hi_timeout_add((void *)icsd_anc_id, icsd_anc_pzl_start, slience_ms + PZL_DELAY);
sys_hi_timeout_add((void *)icsd_anc_id, icsd_anc_pzr_start, slience_ms + PZR_DELAY);
break;
default:
sys_hi_timeout_add((void *)icsd_anc_id, icsd_anc_tonemode_start, slience_ms + ICSD_ANC.tone_delay);
break;
}
} else {
icsd_anc_log("dac on wait anc ready\n");
}
}
}
void icsd_anctone_dacon(u32 slience_frames, u16 sample_rate)
{
icsd_slience_frames = slience_frames;
icsd_sample_rate = sample_rate;
audio_anc_post_msg_icsd_anc_cmd(ANC_CMD_TONE_DACON);
}
void icsd_anc_tone_play_start()
{
#if ANC_USER_TRAIN_TONE_MODE
icsd_anc_log("icsd_anc_tone_play_start\n");
user_train_state |= ANC_TRAIN_TONE_PLAY;
icsd_anc_init_cmd();
os_time_dly(20);
#endif
}
u8 icsd_anc_adaptive_busy_flag_get(void)
{
return ICSD_ANC.adaptive_run_busy;
}
#if ANC_EAR_RECORD_EN
/* float vmdata_FL[EAR_RECORD_MAX][25]; */
/* float vmdata_FR[EAR_RECORD_MAX][25]; */
float (*vmdata_FL)[ANC_VMDATA_FF_RECORD_SIZE] = NULL;
float (*vmdata_FR)[ANC_VMDATA_FF_RECORD_SIZE] = NULL;
int *vmdata_num;
void icsd_anc_vmdata_init(float (*FL)[ANC_VMDATA_FF_RECORD_SIZE], float (*FR)[ANC_VMDATA_FF_RECORD_SIZE], int *num)
{
//读取耳道记忆 VM数据地址
vmdata_FL = FL;
vmdata_FR = FR;
vmdata_num = num;
/* icsd_anc_log("vmdata_num %d\n", *vmdata_num); */
/* put_buf((u8*)vmdata_FL, EAR_RECORD_MAX*ANC_VMDATA_FF_RECORD_SIZE*4); */
/* put_buf((u8*)vmdata_FR, EAR_RECORD_MAX*ANC_VMDATA_FF_RECORD_SIZE*4); */
}
void icsd_anc_vmdata_num_reset()
{
if ((!vmdata_FL) || (!vmdata_FR)) {
return;
}
*vmdata_num = 0;
memset(vmdata_FL, 0, EAR_RECORD_MAX * 4 * ANC_VMDATA_FF_RECORD_SIZE);
}
u8 icsd_anc_get_vmdata_num()
{
return *vmdata_num;
}
void icsd_anc_ear_record_printf()
{
int i;
if ((!vmdata_FL) || (!vmdata_FR)) {
return;
}
icsd_anc_log("vmdata_num:%d\n", *vmdata_num);
for (i = 0; i < EAR_RECORD_MAX; i++) {
icsd_anc_log("vmdata_FL[%d]\n", i);
icsd_anc_fgq_printf(&vmdata_FL[i][0]);
}
for (i = 0; i < EAR_RECORD_MAX; i++) {
icsd_anc_log("vmdata_FR[%d]\n", i);
icsd_anc_fgq_printf(&vmdata_FR[i][0]);
}
}
u8 icsd_anc_max_diff_idx()
{
u8 max_diff_idx = 0;
if ((!vmdata_FL) || (!vmdata_FR)) {
return max_diff_idx;
}
if (*vmdata_num > 0) {
float diff;
float max_diff = icsd_anc_vmdata_match(&vmdata_FL[0][0], vmdata_FL[0][0]);
max_diff_idx = 0;
for (int i = 1; i < *vmdata_num; i++) {
diff = icsd_anc_vmdata_match(&vmdata_FL[i][0], vmdata_FL[i][0]);
if (diff > max_diff) {
max_diff = diff;
max_diff_idx = i;
}
}
}
icsd_anc_log("max diff idx:%d\n", max_diff_idx);
return max_diff_idx;
}
u8 icsd_anc_min_diff_idx()
{
float diff;
float min_diff;
u8 min_diff_idx = 0xff;
if ((!vmdata_FL) || (!vmdata_FR)) {
return min_diff_idx;
}
if (*vmdata_num > 0) {
min_diff = icsd_anc_vmdata_match(&vmdata_FL[0][0], vmdata_FL[0][0]);
min_diff_idx = 0;
icsd_anc_log("DIFF[0]:%d\n", (int)(min_diff * 1000));
for (int i = 1; i < *vmdata_num; i++) {
diff = icsd_anc_vmdata_match(&vmdata_FL[i][0], vmdata_FL[i][0]);
if (diff < min_diff) {
min_diff = diff;
min_diff_idx = i;
}
icsd_anc_log("DIFF[%d]:%d %d %d\n", i, (int)(diff * 1000), min_diff_idx, (int)(min_diff * 1000));
}
diff = icsd_anc_default_match();
icsd_anc_log("default diff:%d vmmin diff:%d\n", (int)(diff * 100), (int)(min_diff * 100));
if (diff < min_diff) {
icsd_anc_log("use default\n");
min_diff_idx = 0xff;
} else {
icsd_anc_log("select vmdata_FL[%d]\n", min_diff_idx);
}
}
return min_diff_idx;
}
u8 icsd_anc_get_save_idx()
{
u8 save_idx = 0;
if (*vmdata_num < EAR_RECORD_MAX) {
save_idx = *vmdata_num;
} else {
save_idx = icsd_anc_max_diff_idx();
}
icsd_anc_log("icsd_anc_get_save_idx:%d\n", save_idx);
return save_idx;
}
void icsd_anc_save_with_idx(u8 save_idx)
{
anc_printf("save try:%d %d\n", save_idx, *vmdata_num);
if ((!vmdata_FL) || (!vmdata_FR)) {
return;
}
if (save_idx > *vmdata_num) {
return;
}
if ((save_idx >= 0) && (save_idx < EAR_RECORD_MAX)) {
if (*vmdata_num < EAR_RECORD_MAX) {
(*vmdata_num)++;
}
anc_printf("icsd_anc_save_with_idx:%d %d====================================================\n", save_idx, *vmdata_num);
switch (ANC_BOARD_PARAM->mode) {
case HEADSET_TONE_BYPASS_MODE:
case HEADSET_TONES_MODE:
case HEADSET_BYPASS_MODE:
memcpy(&vmdata_FL[save_idx][0], TOOL_DATA->data_out5, 4 * ANC_VMDATA_FF_RECORD_SIZE);
memcpy(&vmdata_FR[save_idx][0], TOOL_DATA->data_out10, 4 * ANC_VMDATA_FF_RECORD_SIZE);
break;
default:
memcpy(&vmdata_FL[save_idx][0], TOOL_DATA->data_out5, 4 * ANC_VMDATA_FF_RECORD_SIZE);
break;
}
#if TEST_EAR_RECORD_EN
icsd_anc_log("EAR RECORD SAVE:%d\n", save_idx);
icsd_anc_ear_record_printf();
#endif
}
}
void icsd_anc_vmdata_by_idx(double *ff_ab, float *ff_gain, u8 idx)
{
u8 num = icsd_anc_get_vmdata_num();
if ((!vmdata_FL) || (!vmdata_FR)) {
return;
}
if ((num == 0) || (idx == 0xff) || ((num - 1) < idx)) {
return;
}
#if TEST_EAR_RECORD_EN
icsd_anc_log("EAR RECORD USED RECORD L\n");
icsd_anc_fgq_printf(&vmdata_FL[idx][0]);
#endif
ff_fgq_2_aabb(ff_ab, &vmdata_FL[idx][0]);
*ff_gain = vmdata_FL[idx][0];
}
void icsd_anc_vmdatar_by_idx(double *ff_ab, float *ff_gain, u8 idx)
{
u8 num = icsd_anc_get_vmdata_num();
if ((!vmdata_FL) || (!vmdata_FR)) {
return;
}
if ((num == 0) || (idx == 0xff) || ((num - 1) < idx)) {
return;
}
#if TEST_EAR_RECORD_EN
icsd_anc_log("EAR RECORD USED RECORD R\n");
icsd_anc_fgq_printf(&vmdata_FR[idx][0]);
#endif
ff_fgq_2_aabb(ff_ab, &vmdata_FR[idx][0]);
*ff_gain = vmdata_FR[idx][0];
}
u8 icsd_anc_tooldata_select_vmdata_headset(float *ff_fgq_l, float *ff_fgq_r)
{
icsd_anc_log("headset train time vm select start:%d\n", (int)((jiffies - train_time) * 10));
u8 min_idx = icsd_anc_min_diff_idx();
extern void icsd_set_min_idx(u8 minidx);
icsd_set_min_idx(min_idx);
u8 num = icsd_anc_get_vmdata_num();
if ((!vmdata_FL) || (!vmdata_FR)) {
return 0;
}
//icsd_anc_log("icsd_anc_tooldata_select_vmdata:%d %d\n", num, min_idx);
if ((num == 0) || (min_idx == 0xff) || ((num - 1) < min_idx)) {
icsd_anc_log("use default\n");
return 0;
}
memcpy(ff_fgq_l, &vmdata_FL[min_idx][0], 4 * ANC_VMDATA_FF_RECORD_SIZE);
memcpy(ff_fgq_r, &vmdata_FR[min_idx][0], 4 * ANC_VMDATA_FF_RECORD_SIZE);
#if TEST_EAR_RECORD_EN
icsd_anc_log("EAR RECORD TOOL_DATA RECORD\n");
icsd_anc_fgq_printf(ff_fgq_l);
icsd_anc_fgq_printf(ff_fgq_r);
#endif
icsd_anc_log("train time vm select end:%d\n", (int)((jiffies - train_time) * 10));
icsd_anc_log("headset use record:%d\n", min_idx);
return 1;
}
u8 icsd_anc_tooldata_select_vmdata(float *ff_fgq)
{
icsd_anc_log("train time vm select start:%d\n", (int)((jiffies - train_time) * 10));
//u8 min_idx = icsd_anc_min_diff_idx();
u8 min_idx = TOOL_DATA->use_idx;
icsd_printf("use record idx:%d\n", TOOL_DATA->use_idx);
extern void icsd_set_min_idx(u8 minidx);
icsd_set_min_idx(min_idx);
u8 num = icsd_anc_get_vmdata_num();
if ((!vmdata_FL) || (!vmdata_FR)) {
return 0;
}
//icsd_anc_log("icsd_anc_tooldata_select_vmdata:%d %d\n", num, min_idx);
if ((num == 0) || (min_idx == 0xff) || ((num - 1) < min_idx)) {
icsd_anc_log("use default\n");
return 0;
}
memcpy(ff_fgq, &vmdata_FL[min_idx][0], 4 * ANC_VMDATA_FF_RECORD_SIZE);
#if TEST_EAR_RECORD_EN
icsd_anc_log("EAR RECORD TOOL_DATA RECORD\n");
icsd_anc_fgq_printf(ff_fgq);
#endif
icsd_anc_log("train time vm select end:%d\n", (int)((jiffies - train_time) * 10));
icsd_anc_log("use record:%d\n", min_idx);
return 1;
}
#else
u8 icsd_anc_min_diff_idx()
{
return 0xff;
}
u8 icsd_anc_get_save_idx()
{
return 0xff;
}
u8 icsd_anc_get_vmdata_num()
{
return 0;
}
void icsd_anc_vmdata_num_reset()
{}
void icsd_anc_save_with_idx(u8 save_idx)
{}
void icsd_anc_vmdata_by_idx(double *ff_ab, float *ff_gain, u8 idx)
{}
void icsd_anc_vmdatar_by_idx(double *ff_ab, float *ff_gain, u8 idx)
{}
void icsd_anc_ear_record_printf()
{}
u8 icsd_anc_tooldata_select_vmdata(float *ff_fgq)
{
return 0;
}
u8 icsd_anc_tooldata_select_vmdata_headset(float *ff_fgq_l, float *ff_fgq_r)
{
return 0;
}
#endif
#if ANC_SZ_OUT_EN
float icsd_anc_sz_data[TARLEN + TARLEN_L];
float icsd_anc_pz_data[TARLEN + TARLEN_L];
u8 sz_out_exist = 0;
void icsd_anc_sz_out(float *hz_in)
{
printf("icsd_anc_sz_out\n");
memcpy(icsd_anc_sz_data, hz_in, 4 * (TARLEN + TARLEN_L));
sz_out_exist = 1;
extern void icsd_aeq_demo();
icsd_aeq_demo();
icsd_printf("train time aeq end:%dms\n", (int)((jiffies - train_time) * 10));
}
void icsd_anc_pz_out(float *hz_in)
{
printf("icsd_anc_pz_out\n");
memcpy(icsd_anc_pz_data, hz_in, 4 * (TARLEN + TARLEN_L));
sz_out_exist = 1;
}
#endif
#endif/*TCFG_AUDIO_ANC_EAR_ADAPTIVE_EN*/

View File

@ -0,0 +1,151 @@
#ifndef _ICSD_ANC_APP_H
#define _ICSD_ANC_APP_H
/*===========接口说明=============================================
一. void sd_anc_init(audio_anc_t *param,u8 mode)
1.调用该函数启动sd anc训练
2.param为ANC ON模式下的audio_anc_t参数指针
3.mode0. 普通模式 1. htarget 数据上传模式
二. void sd_anc_htarget_data_send(float *h_freq,float *hszpz_out,float *hpz_out, float *htarget_out,int len)
1.htarget数据上传模式下当数据准备好后会自动调用该函数
三. void sd_anc_htarget_data_end()
1.htarget数据上传模式下当数据上传完成后需要调用该函数进入训练后的ANC ON模式
四. void anc_user_train_tone_play_cb()
1.当前ANC ON提示音结束时回调该函数进入 SD ANC 训练
2.SD ANC训练结束后会切换到ANC ON模式
1:rdout + lout 2:rdout + rerrmic
3:rdout + rrefmic 4:ldout + lerrmic
5:ldout + lrefmic 6:rerrmic + rrefmic
7:lerrmic + lrefmic
anc_sr, 0: 11.7k 1: 23.4k 2: 46.9k 3: 93.8k 4: 187.5k 5: 375k 6: 750k 7: 1.5M
================================================================*/
#include "asm/anc.h"
#include "asm/dac.h"
#include "app_config.h"
#include "icsd_anc.h"
#include "icsd_anc_client_board.h"
#ifndef ADAPTIVE_CLIENT_BOARD
#define ICSD_ANC_MODE TWS_TONE_BYPASS_MODE
#define ANC_ADAPTIVE_FF_ORDER 8 /*ANC自适应FF滤波器阶数, 原厂指定*/
#define ANC_ADAPTIVE_FB_ORDER 5 /*ANC自适应FB滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_CMP_ORDER 8 /*ANC自适应CMP滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_RECORD_FF_ORDER 8 /*ANC自适应耳道记忆FF滤波器阶数原厂指定*/
#define ANC_FB_TRAIN_OFF 1
#define ANC_FB_TRAIN_NEW 0
#define ANC_EARPHONE_CHECK_EN 0
#define ANC_ADAPTIVE_CMP_EN 1 //自适应CMP补偿
#define ANC_ADAPTIVE_TONE_DELAY 1570
#endif/*ADAPTIVE_CLIENT_BOARD*/
#define ANC_HEADSET_TONE_00 0
#define ANC_HEADSET_TONE_01 1
#define ANC_HEADSET_TONE ANC_HEADSET_TONE_00
#if ANC_HEADSET_TONE == ANC_HEADSET_TONE_00
#define TONEL_DELAY 50
#define TONER_DELAY 2400
#define PZL_DELAY 900
#define PZR_DELAY 3300
#else
#define TONEL_DELAY 50
#define TONER_DELAY 1000
#define PZL_DELAY 1900
#define PZR_DELAY 3200
#endif
#define TEST_EAR_RECORD_EN 0
#define TEST_ANC_COMBINATION TEST_ANC_COMBINATION_OFF
#define TEST_ANC_TRAIN TEST_ANC_TRAIN_OFF
#define ICSD_ANC_DEBUG_TYPE ANC_DEBUG_OFF
#define ANC_USER_TRAIN_EN 1
#if ICSD_ANC_MODE == HEADSET_BYPASS_MODE
#define ANC_USER_TRAIN_TONE_MODE 0
#define BYPASS_MAXTIME 4
#define PZ_MAXTIME 4
#elif ICSD_ANC_MODE == HEADSET_TONES_MODE
#define ANC_USER_TRAIN_TONE_MODE 1
#define BYPASS_MAXTIME 2
#define PZ_MAXTIME 3
#elif ICSD_ANC_MODE == TWS_BYPASS_MODE
#define ANC_USER_TRAIN_TONE_MODE 0
#define BYPASS_MAXTIME 4
#define PZ_MAXTIME 4
#elif ICSD_ANC_MODE == TWS_TONE_BYPASS_MODE
#define ANC_USER_TRAIN_TONE_MODE 1
#define BYPASS_MAXTIME 2
#define PZ_MAXTIME 3
#elif ICSD_ANC_MODE == TWS_TONE_MODE
#define ANC_USER_TRAIN_TONE_MODE 1
#define BYPASS_MAXTIME 2
#define PZ_MAXTIME 3
#elif ICSD_ANC_MODE == HEADSET_TONE_BYPASS_MODE
#define ANC_USER_TRAIN_TONE_MODE 1
#define BYPASS_MAXTIME 2
#define PZ_MAXTIME 3
#else
#define ANC_USER_TRAIN_TONE_MODE 0
#define BYPASS_MAXTIME 4
#define PZ_MAXTIME 4
#endif
#define ANC_USER_TRAIN_MODE 2//0:FF 1:FB 2:HY
#define ANC_USER_TRAIN_SR_SEL 2//46.9k
#define ANC_EAR_RECORD_EN 1 //耳道记忆
#define EAR_RECORD_MAX 5
#define ANC_DFF_AFB_EN 1//默认FF + 自适应FB 1:判断为自适应成功 0:判断为自适应失败
#define ANC_AFF_DFB_EN 1//默认FB + 自适应FF 1:判断为自适应成功 0:判断为自适应失败
#define ANC_SZ_OUT_EN 0//自适应SZ输出使能
#define HEADSET_TONES_MODE_BYPASS_OFF 0
//耳道记忆滤波器保存大小,滤波器组 * 3 + 总增益
#define ANC_VMDATA_FF_RECORD_SIZE (ANC_ADAPTIVE_RECORD_FF_ORDER * 3) + 1
extern float (*vmdata_FL)[ANC_VMDATA_FF_RECORD_SIZE];//ff fgq
extern float (*vmdata_FR)[ANC_VMDATA_FF_RECORD_SIZE];//ff fgq
extern int *vmdata_num;
#define ANC_USE_RECORD 1 //ANC自适应失败使用耳道记忆参数
#define ANC_SUCCESS 2 //ANC自适应成功
#define ANC_USE_DEFAULT 3 //ANC自适应使用ICSD内部默认参数目前不用;
//自适应训练结果 u8
#define ANC_ADAPTIVE_RESULT_LFF BIT(0) //使用LFF自适应or记忆参数
#define ANC_ADAPTIVE_RESULT_LFB BIT(1) //使用LFB自适应参数
#define ANC_ADAPTIVE_RESULT_LCMP BIT(2) //使用LCMP自适应参数
#define ANC_ADAPTIVE_RESULT_RFF BIT(3) //使用RFF自适应or记忆参数
#define ANC_ADAPTIVE_RESULT_RFB BIT(4) //使用RFB自适应参数
#define ANC_ADAPTIVE_RESULT_RCMP BIT(5) //使用RCMP自适应参数
struct icsd_fb_ref {
float m_value;
float sen;
float in_q;
};
struct icsd_ff_ref {
float fre[75];
float db[75];
};
extern void icsd_anc_vmdata_init(float (*FL)[ANC_VMDATA_FF_RECORD_SIZE], float (*FR)[ANC_VMDATA_FF_RECORD_SIZE], int *num);
#endif/*_ICSD_ANC_APP_H*/

View File

@ -0,0 +1,422 @@
#include "board_config.h"
#include "icsd_anc_app.h"
#include "tone_player.h"
#include "audio_anc.h"
#include "icsd_anc_user.h"
#if 1
#define icsd_board_log printf
#else
#define icsd_board_log(...)
#endif/*log_en*/
#if TCFG_AUDIO_ANC_EAR_ADAPTIVE_EN
u8 anc_train_result = 0; //ANC自适应训练结果返回值
u8 IIR_NUM;// 4 3
u8 IIR_NUM_FIX;// 4 8-IIR_NUM
u8 IIR_COEF; //(IIR_NUM * 3+1)
/*
typedef enum {
ANC_IIR_HIGH_PASS = 0,
ANC_IIR_LOW_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_HIGH_SHELF,
ANC_IIR_LOW_SHELF,
} ANC_iir_type;
*/
#ifndef ADAPTIVE_CLIENT_BOARD
const u8 cmp_iir_type[] = {
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_HIGH_SHELF,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
};
const u8 ff_iir_type[] = {
ANC_IIR_LOW_SHELF,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
};
const u8 fb_iir_type[] = {
ANC_IIR_HIGH_SHELF,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
ANC_IIR_BAND_PASS,
};
const u8 FF_VERSION = 1;
const u8 NEW_PRE_TREAT = 0;
const u8 ICSD_EP_TYPE = ICSD_FULL_INEAR;
const u8 icsd_dcc[4] = {1, 4, 1, 1}; //ff1st,ff2nd,fb12t,fb2nd
const u16 ICSD_ANC_FUN = 0;
void icsd_xtmp_handler(float *xtmp, float gain_min, float gain_max)
{
if (xtmp[1] < gain_min) {
xtmp[1] = (float)gain_min;
}
if (xtmp[1] > gain_max) {
xtmp[1] = (float)gain_max;
}
}
void icsd_anc_board_config()
{
icsd_anc_board_param_init();
ANC_BOARD_PARAM->ff_yorder = ANC_ADAPTIVE_FF_ORDER;
ANC_BOARD_PARAM->fb_yorder = ANC_ADAPTIVE_FB_ORDER;
ANC_BOARD_PARAM->cmp_yorder = ANC_ADAPTIVE_CMP_ORDER;
#define DEFAULT_FF_GAIN 3
#define DEFAULT_FB_GAIN 3
extern const float E108D_DATA[];
extern const s8 E108D_s8_DATA[];
extern const float E108D_DOUBLE_DATA[];
ANC_BOARD_PARAM->anc_data_l = (void *)E108D_DATA;
ANC_BOARD_PARAM->anc_data_r = (void *)E108D_DATA;
ANC_BOARD_PARAM->anc_db = (void *)E108D_s8_DATA;
ANC_BOARD_PARAM->anc_double_data_l = (void *)E108D_DOUBLE_DATA;
ANC_BOARD_PARAM->anc_double_data_r = (void *)E108D_DOUBLE_DATA;
ANC_BOARD_PARAM->m_value_l = 120.0; //80 ~ 200 最深点位置中心值
ANC_BOARD_PARAM->sen_l = 15.0; //12 ~ 22 最深点深度
ANC_BOARD_PARAM->in_q_l = 0.4; //0.4 ~ 1.2 最深点降噪宽度
ANC_BOARD_PARAM->m_value_r = 120.0; //80 ~ 200 最深点位置中心值
ANC_BOARD_PARAM->sen_r = 15.0; //12 ~ 22 最深点深度
ANC_BOARD_PARAM->in_q_r = 0.4; //0.4 ~ 1.2 最深点降噪宽度
ANC_BOARD_PARAM->sen_offset_l = 11.0 - 18.0;
ANC_BOARD_PARAM->sen_offset_r = 11.0 - 18.0;
ANC_BOARD_PARAM->ff_target_fix_num_l = 18;
ANC_BOARD_PARAM->ff_target_fix_num_r = 18;
ANC_BOARD_PARAM->gain_a_param = 25.0;
ANC_BOARD_PARAM->gain_a_en = 0;
ANC_BOARD_PARAM->cmp_abs_en = 0;
ANC_BOARD_PARAM->idx_begin = 18;
ANC_BOARD_PARAM->idx_end = 60;
ANC_BOARD_PARAM->fb_w2r = 1000;
ANC_BOARD_PARAM->FB_NFIX = 3;
ANC_BOARD_PARAM->gain_min_offset = 11;
ANC_BOARD_PARAM->gain_max_offset = 18;
ANC_BOARD_PARAM->minvld = -10.0;
ANC_BOARD_PARAM->bypass_max_times = BYPASS_MAXTIME;
ANC_BOARD_PARAM->pz_max_times = PZ_MAXTIME;
ANC_BOARD_PARAM->jt_en = 2;
ANC_BOARD_PARAM->tff_sign = 1;
ANC_BOARD_PARAM->tfb_sign = -1;
ANC_BOARD_PARAM->bff_sign = 1;
ANC_BOARD_PARAM->bfb_sign = 1;
ANC_BOARD_PARAM->bypass_sign = -1;
ANC_BOARD_PARAM->bypass_volume = 0.6; //0.6
ANC_BOARD_PARAM->tool_target_sign = -1;
ANC_BOARD_PARAM->cmp_type[0] = 1;
ANC_BOARD_PARAM->cmp_type[1] = 1;
ANC_BOARD_PARAM->cmp_type[2] = 0;
ANC_BOARD_PARAM->cmp_type[3] = 1;
ANC_BOARD_PARAM->cmp_type[4] = 1;
ANC_BOARD_PARAM->cmp_type[5] = 1;
ANC_BOARD_PARAM->cmp_type[6] = 1;
ANC_BOARD_PARAM->cmp_type[7] = 1;
ANC_BOARD_PARAM->cmp_thd_low = -40.0;
ANC_BOARD_PARAM->cmp_thd_high = 40.0;
ANC_BOARD_PARAM->IIR_NUM = 3;
ANC_BOARD_PARAM->IIR_NUM_FIX = 8 - ANC_BOARD_PARAM->IIR_NUM;
ANC_BOARD_PARAM->IIR_COEF = ANC_BOARD_PARAM->IIR_NUM * 3 + 1;
ANC_BOARD_PARAM->sz_priority_thr = 60;
ANC_BOARD_PARAM->JT_MODE = 0;
if (ANC_BOARD_PARAM->pz_max_times < 3) {
ANC_BOARD_PARAM->pz_max_times = 3;
}
if (ANC_BOARD_PARAM->bypass_max_times < 2) {
ANC_BOARD_PARAM->pz_max_times = 2;
}
ANC_BOARD_PARAM->mode = ICSD_ANC_MODE;
if (ANC_DFF_AFB_EN) {
icsd_board_log("ANC_DFF_AFB_EN ON\n");
ANC_BOARD_PARAM->FF_FB_EN |= ICSD_DFF_AFB_EN;//BIT(7);
}
if (ANC_AFF_DFB_EN) {
icsd_board_log("ANC_AFF_DFB_EN ON\n");
ANC_BOARD_PARAM->FF_FB_EN |= ICSD_AFF_DFB_EN;//BIT(6);
}
if (ANC_FB_TRAIN_OFF) {
ANC_BOARD_PARAM->FF_FB_EN |= ICSD_FB_TRAIN_OFF;//BIT(5);
}
if (ANC_FB_TRAIN_NEW) {
ANC_BOARD_PARAM->FF_FB_EN |= ICSD_FB_TRAIN_NEW;//BIT(4);
}
ANC_BOARD_PARAM->default_ff_gain = DEFAULT_FF_GAIN;
ANC_BOARD_PARAM->default_fb_gain = DEFAULT_FB_GAIN;
if (TCFG_AUDIO_DAC_MODE == DAC_MODE_H1_DIFF) {
user_train_state |= ANC_DAC_MODE_H1_DIFF;
} else {
user_train_state &= ~ANC_DAC_MODE_H1_DIFF;
}
}
#else
#include "icsd_anc_client_board.c"
#endif/*ADAPTIVE_CLIENT_BOARD*/
void icsd_anc_config_inf()
{
icsd_board_log("\n=============ANC COMFIG INF================\n");
icsd_anc_version();
switch (ICSD_ANC_MODE) {
case TWS_TONE_BYPASS_MODE:
icsd_board_log("TWS_TONE_BYPASS_MODE\n");
break;
case TWS_TONE_MODE:
icsd_board_log("TWS_TONE_MODE\n");
break;
case TWS_BYPASS_MODE:
icsd_board_log("TWS_BYPASS_MODE\n");
break;
case HEADSET_TONE_BYPASS_MODE:
icsd_board_log("HEADSET_TONE_BYPASS_MODE\n");
break;
case HEADSET_TONES_MODE:
icsd_board_log("HEADSET_TONES_MODE\n");
break;
case HEADSET_BYPASS_MODE:
icsd_board_log("HEADSET_BYPASS_MODE\n");
break;
default:
icsd_board_log("NEW MODE\n");
break;
}
icsd_board_log("TEST_ANC_COMBINATION:%d\n", TEST_ANC_COMBINATION);
icsd_board_log("ANC_ADAPTIVE_CMP_EN:%d\n", ANC_ADAPTIVE_CMP_EN);
icsd_board_log("ANC_EAR_RECORD_EN:%d\n", ANC_EAR_RECORD_EN);
icsd_board_log("TEST_EAR_RECORD_EN:%d\n", TEST_EAR_RECORD_EN);
icsd_board_log("BYPASS_TIMES MIN:2 MAX:%d\n", BYPASS_MAXTIME);
icsd_board_log("PZ_TIMES MIN:3 MAX:%d\n", PZ_MAXTIME);
icsd_board_log("\n");
#if TEST_EAR_RECORD_EN
icsd_board_log("EAR RECORD CURRENT RECORD\n");
//icsd_anc_ear_record_icsd_board_log();
#endif
}
//训练结果获取API用于通知应用层当前使用自适应参数还是默认参数
u8 icsd_anc_train_result_get(struct icsd_anc_tool_data *TOOL_DATA)
{
u8 result = 0;
if (TOOL_DATA) {
switch (TOOL_DATA->anc_combination) {
case TFF_TFB://使用自适应FF自适应FB
result = ANC_ADAPTIVE_RESULT_LFF | ANC_ADAPTIVE_RESULT_LFB | ANC_ADAPTIVE_RESULT_RFF | ANC_ADAPTIVE_RESULT_RFB;
break;
case TFF_DFB://使用自适应FF默认FB
result = ANC_ADAPTIVE_RESULT_LFF | ANC_ADAPTIVE_RESULT_RFF;
break;
case DFF_TFB://result:1 使用记忆FF自适应FB :3 使用默认FF自适应FB
result = ANC_ADAPTIVE_RESULT_LFB | ANC_ADAPTIVE_RESULT_RFB;
break;
case DFF_DFB://result:1 使用记忆FF默认FB :3 使用默认FF默认FB
default:
break;
}
//使用耳道记忆的FF参数
if (TOOL_DATA->result == ANC_USE_RECORD) {
result |= (ANC_ADAPTIVE_RESULT_LFF | ANC_ADAPTIVE_RESULT_RFF);
}
//CMP成功使用自适应CMP参数
if (TOOL_DATA->cmp_result) {
result |= (ANC_ADAPTIVE_RESULT_LCMP | ANC_ADAPTIVE_RESULT_RCMP);
}
}
return result;
}
extern int tone_play_index(u8 index, u8 preemption);
void icsd_anc_htarget_data_end(u8 result)
{
user_train_state &= ~ANC_USER_TRAIN_TOOL_DATA;
ICSD_ANC.adaptive_run_busy = 0;
/*
训练结果播放提示音
result = 1 训练成功
result = 0 训练失败
*/
anc_train_result = result;
printf("ICSD ANC RESULT:%d================\n", result);
switch (result) {
case 1:
anc_printf("FF USE RECORD\n");
break;
case 2:
anc_printf("FF USE TRAIN\n");
break;
case 3:
anc_printf("FF USE DEFAULT\n");
break;
default:
break;
}
switch (TOOL_DATA->anc_combination) {
case TFF_TFB://使用自适应FF自适应FB
anc_printf("TFF_TFB\n");
break;
case TFF_DFB://使用自适应FF默认FB
anc_printf("TFF_DFB\n");
#if ANC_DEVELOPER_MODE_EN
icsd_adt_tone_play(ICSD_ADT_TONE_NUM2);
#endif/*ANC_DEVELOPER_MODE_EN*/
break;
case DFF_TFB://result:1 使用记忆FF自适应FB :3 使用默认FF自适应FB
anc_printf("DFF_TFB\n");
#if ANC_DEVELOPER_MODE_EN
icsd_adt_tone_play(ICSD_ADT_TONE_NUM1);
#endif/*ANC_DEVELOPER_MODE_EN*/
break;
case DFF_DFB://result:1 使用记忆FF默认FB :3 使用默认FF默认FB
anc_printf("DFF_DFB\n");
#if ANC_DEVELOPER_MODE_EN
icsd_adt_tone_play(ICSD_ADT_TONE_NUM0);
#endif/*ANC_DEVELOPER_MODE_EN*/
break;
default:
break;
}
audio_anc_adaptive_fail_callback(TOOL_DATA->anc_err);
icsd_board_log("train time tool data end:%d\n", (int)((jiffies - train_time) * 10));
icsd_anc_htarget_data_send_end();
}
extern void audio_anc_adaptive_data_packet(struct icsd_anc_tool_data *TOOL_DATA);
void icsd_anc_htarget_data_send()
{
#if ANC_SZ_OUT_EN
extern void icsd_anc_sz_out(float * hz_in);
extern void icsd_anc_pz_out(float * hz_in);
if (HEADSET_MODE) {
if ((TOOL_DATA->result == 2) || (TOOL_DATA->anc_combination == TFF_DFB)) {
icsd_anc_sz_out(TOOL_DATA->data_out1);
icsd_anc_pz_out(TOOL_DATA->data_out2);
}
} else {
if (TOOL_DATA->result == 2) {
icsd_anc_sz_out(TOOL_DATA->data_out1);
icsd_anc_pz_out(TOOL_DATA->data_out2);
}
}
#endif
if (TOOL_DATA->cmp_result) {
anc_printf("CMP RESULT:success\n");
} else {
anc_printf("CMP RESULT:fail\n");
}
icsd_board_log("train time tool data start:%d\n", (int)((jiffies - train_time) * 10));
//TOOL_DATA->result 0:失败使用默认参数 1:耳道记忆参数 2:成功
printf("save check:%d %d----------------\n", TOOL_DATA->result, HEADSET_MODE);
if (HEADSET_MODE) {
if ((TOOL_DATA->result == 2) || (TOOL_DATA->anc_combination == TFF_DFB)) {
//成功时进行耳道记忆
icsd_anc_save_with_idx(TOOL_DATA->save_idx);
}
} else {
if (TOOL_DATA->result == 2) {
//成功时进行耳道记忆
icsd_anc_save_with_idx(TOOL_DATA->save_idx);
}
}
audio_anc_adaptive_data_packet((struct icsd_anc_tool_data *)TOOL_DATA);
icsd_anc_htarget_data_end(TOOL_DATA->result);
}
void icsd_anc_end(audio_anc_t *param)
{
icsd_board_log("train time finish:%dms\n", (int)((jiffies - train_time) * 10));
user_train_state &= ~ANC_USER_TRAIN_DMA_EN;
if (icsd_time_out_hdl) {
sys_timeout_del(icsd_time_out_hdl);
icsd_time_out_hdl = 0;
}
icsd_anc_contral = 0;
anc_user_train_cb(ANC_ON, anc_train_result, 0);
}
void icsd_anc_forced_exit_end()
{
if (icsd_anc_contral & ICSD_ANC_TONE_END) {
printf("icsd_anc_forced_exit_end cb-----------------------------\n");
icsd_anc_contral &= ~ICSD_ANC_FORCED_EXIT;
icsd_anc_contral &= ~ICSD_ANC_SUSPENDED;
icsd_anc_contral &= ~ICSD_ANC_TONE_END;
icsd_anc_contral &= ~ICSD_ANC_INITED;
icsd_anc_contral &= ~ICSD_ANC_FORCED_BEFORE_INIT;
if (icsd_time_out_hdl) {
sys_timeout_del(icsd_time_out_hdl);
icsd_time_out_hdl = 0;
}
anc_user_train_cb(ANC_ON, 0, 1);
}
}
void anc_user_train_tone_play_cb()
{
icsd_board_log("anc_user_train_tone_play_cb:%d========================================\n", (int)jiffies);
train_time = jiffies;
#if ANC_USER_TRAIN_EN
icsd_anc_contral |= ICSD_ANC_TONE_END;
if (icsd_anc_contral & ICSD_ANC_SUSPENDED) {
printf("FORCED EXIT END================================\n");
user_train_state |= ANC_TRAIN_TONE_END;
icsd_anc_forced_exit_end();
return;
}
#if ANC_USER_TRAIN_TONE_MODE
icsd_board_log("TONE MODE tone play cb~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
if (user_train_state & ANC_TRAIN_TONE_FIRST) {
user_train_state |= ANC_TRAIN_TONE_END;
} else {
icsd_board_log("second train at cb~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
user_train_state |= ANC_TRAIN_TONE_END;
audio_anc_post_msg_icsd_anc_cmd(ANC_CMD_TRAIN_AFTER_TONE);
}
#else
extern void audio_anc_post_msg_user_train_init(u8 mode);
audio_anc_post_msg_user_train_init(ANC_ON);
#endif/*ANC_USER_TRAIN_TONE_MODE*/
#else
anc_user_train_cb(ANC_ON, anc_train_result, 0);
#endif/*ANC_USER_TRAIN_EN*/
}
#endif/*TCFG_AUDIO_ANC_EAR_ADAPTIVE_EN*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
/*********************************************************************
ANC 耳道自适应配置文件
*********************************************************************/
#include "icsd_anc.h"
#define DEVE_BOARD 0x00 //开发板
#define HT03_HYBRID_6F 0x01 //CUSTOM1_CFG
#define HT03_HYBRID_6G 0x02 //CUSTOM2_CFG
#define A896_HYBRID_6G 0x03 //CUSTOM3_CFG
#define HT05_6G 0x04 //CUSTOM4_CFG
#define ANC05_HYBRID 0x05 //CUSTOM5_CFG
#define G02_HYBRID_6G 0x06 //CUSTOM6_CFG
#define AC098_HYBRID_6G 0x07 //CUSTOM7_CFG
#define G96_HYBRID 0x08 //CUSTOM8_CFG
#define H3_HYBRID 0x09 //CUSTOM9_CFG
#define P90_HYBRID 0x0a //CUSTOM10_CFG
#define JH4006_HYBRID 0x0d //CUSTOM10_CFG
#define D28_HYBRID 0x80
#define H3_TOZO_HYBIRD 0x81
//自适应板级配置,适配不同样机
//#define ADAPTIVE_CLIENT_BOARD HT03_HYBRID_6G
//#define ADAPTIVE_CLIENT_BOARD G96_HYBRID
//#define ADAPTIVE_CLIENT_BOARD P90_HYBRID
//#define ADAPTIVE_CLIENT_BOARD G02_HYBRID_6G
//#define ADAPTIVE_CLIENT_BOARD JH4006_HYBRID
#define ADAPTIVE_CLIENT_BOARD D28_HYBRID
//#define ADAPTIVE_CLIENT_BOARD H3_TOZO_HYBIRD
//#define ADAPTIVE_CLIENT_BOARD H3_HYBIRD
#if ADAPTIVE_CLIENT_BOARD == HT03_HYBRID_6G
#define ICSD_ANC_MODE TWS_TONE_BYPASS_MODE
#define ANC_ADAPTIVE_FF_ORDER 8 /*ANC自适应FF滤波器阶数, 原厂指定*/
#define ANC_ADAPTIVE_FB_ORDER 5 /*ANC自适应FB滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_CMP_ORDER 8 /*ANC自适应CMP滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_RECORD_FF_ORDER 8 /*ANC自适应耳道记忆FF滤波器阶数原厂指定*/
#define ANC_FB_TRAIN_OFF 0
#define ANC_FB_TRAIN_NEW 0
#define ANC_EARPHONE_CHECK_EN 1
#define ANC_ADAPTIVE_CMP_EN 1 //自适应CMP补偿
#define ANC_ADAPTIVE_TONE_DELAY 700
#elif ADAPTIVE_CLIENT_BOARD == G02_HYBRID_6G
#define ICSD_ANC_MODE TWS_TONE_BYPASS_MODE
#define ANC_ADAPTIVE_FF_ORDER 8 /*ANC自适应FF滤波器阶数, 原厂指定*/
#define ANC_ADAPTIVE_FB_ORDER 6 /*ANC自适应FB滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_CMP_ORDER 4 /*ANC自适应CMP滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_RECORD_FF_ORDER 8 /*ANC自适应耳道记忆FF滤波器阶数原厂指定*/
#define ANC_FB_TRAIN_OFF 0
#define ANC_FB_TRAIN_NEW 0
#define ANC_EARPHONE_CHECK_EN 0
#define ANC_ADAPTIVE_CMP_EN 0 //自适应CMP补偿
#define ANC_ADAPTIVE_TONE_DELAY 700
#elif ADAPTIVE_CLIENT_BOARD == ANC05_HYBRID
#define ICSD_ANC_MODE HEADSET_TONES_MODE //HEADSET_TONE_BYPASS_MODE
#define ANC_ADAPTIVE_FF_ORDER 8 /*ANC自适应FF滤波器阶数, 原厂指定*/
#define ANC_ADAPTIVE_FB_ORDER 5 /*ANC自适应FB滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_CMP_ORDER 8 /*ANC自适应CMP滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_RECORD_FF_ORDER 8 /*ANC自适应耳道记忆FF滤波器阶数原厂指定*/
#define ANC_FB_TRAIN_OFF 0
#define ANC_FB_TRAIN_NEW 0
#define ANC_EARPHONE_CHECK_EN 0
#define ANC_ADAPTIVE_CMP_EN 1 //自适应CMP补偿
#define ANC_ADAPTIVE_TONE_DELAY 700
#elif ADAPTIVE_CLIENT_BOARD == H3_HYBRID
#define ICSD_ANC_MODE HEADSET_TONES_MODE //HEADSET_TONE_BYPASS_MODE
#define ANC_ADAPTIVE_FF_ORDER 8 /*ANC自适应FF滤波器阶数, 原厂指定*/
#define ANC_ADAPTIVE_FB_ORDER 6 /*ANC自适应FB滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_CMP_ORDER 8 /*ANC自适应CMP滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_RECORD_FF_ORDER 8 /*ANC自适应耳道记忆FF滤波器阶数原厂指定*/
#define ANC_FB_TRAIN_OFF 0
#define ANC_FB_TRAIN_NEW 0
#define ANC_EARPHONE_CHECK_EN 1
#define ANC_ADAPTIVE_CMP_EN 1 //自适应CMP补偿
#define ANC_ADAPTIVE_TONE_DELAY 700
#elif ADAPTIVE_CLIENT_BOARD == H3_TOZO_HYBIRD
#define ICSD_ANC_MODE HEADSET_TONES_MODE //HEADSET_TONE_BYPASS_MODE
#define ANC_ADAPTIVE_FF_ORDER 8 /*ANC自适应FF滤波器阶数, 原厂指定*/
#define ANC_ADAPTIVE_FB_ORDER 6 /*ANC自适应FB滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_CMP_ORDER 8 /*ANC自适应CMP滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_RECORD_FF_ORDER 8 /*ANC自适应耳道记忆FF滤波器阶数原厂指定*/
#define ANC_FB_TRAIN_OFF 0
#define ANC_FB_TRAIN_NEW 0
#define ANC_EARPHONE_CHECK_EN 1
#define ANC_ADAPTIVE_CMP_EN 1 //自适应CMP补偿
#define ANC_ADAPTIVE_TONE_DELAY 700
#elif ADAPTIVE_CLIENT_BOARD == G96_HYBRID
#define ICSD_ANC_MODE TWS_TONE_BYPASS_MODE //HEADSET_TONE_BYPASS_MODE
#define ANC_ADAPTIVE_FF_ORDER 8 /*ANC自适应FF滤波器阶数, 原厂指定*/
#define ANC_ADAPTIVE_FB_ORDER 5 /*ANC自适应FB滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_CMP_ORDER 8 /*ANC自适应CMP滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_RECORD_FF_ORDER 8 /*ANC自适应耳道记忆FF滤波器阶数原厂指定*/
#define ANC_FB_TRAIN_OFF 0
#define ANC_FB_TRAIN_NEW 1
#define ANC_EARPHONE_CHECK_EN 1
#define ANC_ADAPTIVE_CMP_EN 0 //自适应CMP补偿
#define ANC_ADAPTIVE_TONE_DELAY 700
#elif ADAPTIVE_CLIENT_BOARD == P90_HYBRID
//#define ICSD_ANC_MODE TWS_TONE_BYPASS_MODE
#define ICSD_ANC_MODE TWS_TONE_MODE
#define ANC_ADAPTIVE_FF_ORDER 8 /*ANC自适应FF滤波器阶数, 原厂指定*/
#define ANC_ADAPTIVE_FB_ORDER 5 /*ANC自适应FB滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_CMP_ORDER 8 /*ANC自适应CMP滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_RECORD_FF_ORDER 8 /*ANC自适应耳道记忆FF滤波器阶数原厂指定*/
#define ANC_FB_TRAIN_OFF 1
#define ANC_FB_TRAIN_NEW 0
#define ANC_EARPHONE_CHECK_EN 0
#define ANC_ADAPTIVE_CMP_EN 1 //自适应CMP补偿
#define ANC_ADAPTIVE_TONE_DELAY 1600//700
#elif ADAPTIVE_CLIENT_BOARD == D28_HYBRID
#define ICSD_ANC_MODE TWS_TONE_MODE
#define ANC_ADAPTIVE_FF_ORDER 10 /*ANC自适应FF滤波器阶数, 原厂指定*/
#define ANC_ADAPTIVE_FB_ORDER 5 /*ANC自适应FB滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_CMP_ORDER 8 /*ANC自适应CMP滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_RECORD_FF_ORDER 10 /*ANC自适应耳道记忆FF滤波器阶数原厂指定*/
#define ANC_FB_TRAIN_OFF 1
#define ANC_FB_TRAIN_NEW 0
#define ANC_EARPHONE_CHECK_EN 0
#define ANC_ADAPTIVE_CMP_EN 1 //自适应CMP补偿
#define ANC_ADAPTIVE_TONE_DELAY 1600//700
#elif ADAPTIVE_CLIENT_BOARD == JH4006_HYBRID
#define ICSD_ANC_MODE HEADSET_TONES_MODE //HEADSET_TONE_BYPASS_MODE
#define ANC_ADAPTIVE_FF_ORDER 8 /*ANC自适应FF滤波器阶数, 原厂指定*/
#define ANC_ADAPTIVE_FB_ORDER 6 /*ANC自适应FB滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_CMP_ORDER 8 /*ANC自适应CMP滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_RECORD_FF_ORDER 8 /*ANC自适应耳道记忆FF滤波器阶数原厂指定*/
#define ANC_FB_TRAIN_OFF 0
#define ANC_FB_TRAIN_NEW 0
#define ANC_EARPHONE_CHECK_EN 0
#define ANC_ADAPTIVE_CMP_EN 0 //自适应CMP补偿
#define ANC_ADAPTIVE_TONE_DELAY 700
#else
#define ICSD_ANC_MODE TWS_TONE_BYPASS_MODE
#define ANC_ADAPTIVE_FF_ORDER 8 /*ANC自适应FF滤波器阶数, 原厂指定*/
#define ANC_ADAPTIVE_FB_ORDER 5 /*ANC自适应FB滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_CMP_ORDER 4 /*ANC自适应CMP滤波器阶数原厂指定*/
#define ANC_ADAPTIVE_RECORD_FF_ORDER 8 /*ANC自适应耳道记忆FF滤波器阶数原厂指定*/
#define ANC_FB_TRAIN_OFF 1
#define ANC_FB_TRAIN_NEW 0
#define ANC_EARPHONE_CHECK_EN 0
#define ANC_ADAPTIVE_CMP_EN 0 //自适应CMP补偿
#define ANC_ADAPTIVE_TONE_DELAY 700
#endif/*ADAPTIVE_CLIENT_BOARD*/

View File

@ -0,0 +1,266 @@
#include "audio_anc.h"
const float THD_JT = 6;
const float THD_JT_SAVE = 4;
const float THD_JT2 = 7;
const s8 ANC_s8_DATA[] = {
6,//P_PARAM_01
-12,//P_PARAM_02
4,//SP_PARAM_01
-12,//SP_PARAM_01
28,//ANC_ERRMIC_SPL_DB
12,//ANC_SZ_DB
-10,//EAR_CHECK_VLD1
-9,//EAR_CHECK_VLD2
40,//FSTOP_IDX
58,//FSTOP_IDX2
41,//_ANC_REFMIC_SPL_DB
-4,//B_PARM1_THR_L
4,//B_PARM1_THR_H
-6,//B_PARM2_THR_L
6,//B_PARM2_THR_H
-4,//B_PARM3_THR_L
4,//B_PARM3_THR_H
};
const double ICSD_ANC_DOUBLE_DATA[] = {
//double cmp_iir_ab[10] //
1.000496069900691509246826171875, -1.998426330275833606719970703125, 0.997930623590946197509765625, -1.998426330275833606719970703125, 0.9984266944229602813720703125,
0.9998088735155761241912841796875, -1.999607323668897151947021484375, 0.9997985516674816608428955078125, -1.999607323668897151947021484375, 0.9996074251830577850341796875,
};
const float spl_tb [21] = {
17, //134.765625000000
19, //179.687500000000
21, //224.609375000000
22, //269.531250000000
23, //314.453125000000
23, //359.375000000000
24, //404.296875000000
26, //449.218750000000
23, //494.140625000000
24, //539.062500000000
25, //583.984375000000
25, //628.906250000000
24, //673.828125000000
22, //718.750000000000
22, //763.671875000000
23, //808.593750000000
24, //853.515625000000
25, //898.437500000000
25, //943.359375000000
24, //988.281250000000
24, //1033.20312500000
};
const float spl_freq_tb [21] = {
134.765625000000,
179.687500000000,
224.609375000000,
269.531250000000,
314.453125000000,
359.375000000000,
404.296875000000,
449.218750000000,
494.140625000000,
539.062500000000,
583.984375000000,
628.906250000000,
673.828125000000,
718.750000000000,
763.671875000000,
808.593750000000,
853.515625000000,
898.437500000000,
943.359375000000,
988.281250000000,
1033.20312500000
};
const float ICSD_ANC_DATA[] = {
//float ff_fgq[25]
1,//gain
10000, 20.000, 1.000, //F G Q
1200, -3.500, 1.000,
2000, -4.000, 1.000,
6500, -6.000, 1.000,
10000, -30.000, 1.500,
75, 2.000, 2.000,
385, -4.260, 0.505,
620, 1.600, 1.500,
//float fb_fgq[25]
0.707945,//gain
3500.0, -6.000, 0.900, //F G Q
1510.0, -2, 0.800,
5289.0, -11, 0.800,
120.0, 18.000, 0.600,
45.0, 3.000, 1.000,
20.0, 0.0, 1.000,
20.0, 0.0, 1.000,
20.0, 0.0, 1.000,
//float ff_weight_HT03[75]
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 10.00, 10.00, 10.00,
10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
5.100, 5.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100,
0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100,
0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100, 0.100,
//float best_param_fix[13]
-3.00,
0.900, -6.000, 3500.0, // Q G F
0.800, -2, 1510.0,
0.800, -11, 5289.0,
1.000, 0.0, 20.0,
//float best_param_flex[6]
0.600, 18.000, 120.0,
1.000, 3.000, 45.0,
//float biquad_init_lcl[10]
-1, 150, 0.5,
-3, 500, 1,
-7, 1200, 0.8,
-1,
//float biquad_fix[15]
8, 60, 1.8,
-10, 15, 1.5,
4.5, 4500, 0.8,
-8, 7500, 2,
-25, 14000, 1.2,
//float Vrange[26]
-5.0, 5.0, 130, 400, 0.3, 1,
-5.0, 5.0, 400, 900, 0.3, 1,
-10.0, -5.0, 900, 1400, 0.7, 0.9,
-1.1, -0.9,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, //没有使用
//float biquad_init_data[7]
1.0,//highshlef_N
4.0,//peak_N
5.0,//N
1.0,//h_fix
2.0,//p_fix
3.0,//n_fix
2.0,//n_flex
//float fb_std[3]
1.414,
0.707,
20.0,
//float k_cmp[75*2]
0.355735, 0.000000,
0.406650, 0.009267,
0.540936, 0.013891,
0.677297, 0.006987,
0.661146, -0.122581,
0.762457, -0.082076,
0.845315, -0.032340,
0.922015, 0.001376,
0.983304, 0.017571,
1.003132, 0.021645,
1.013473, 0.016530,
1.014149, 0.007091,
1.005985, -0.001269,
0.992157, -0.002376,
0.982547, 0.008197,
0.987876, 0.019249,
0.993822, 0.015540,
0.984279, 0.010513,
0.969368, 0.020658,
0.970804, 0.034582,
0.996935, 0.025907,
0.985948, 0.031042,
0.935211, 0.022464,
0.953423, 0.025235,
0.961401, 0.012630,
0.929649, 0.025147,
0.916033, 0.070842,
0.908546, 0.113489,
0.890224, 0.146915,
0.880289, 0.170188,
0.897130, 0.177176,
0.899322, 0.215329,
0.902587, 0.219978,
0.901702, 0.301843,
0.930309, 0.364164,
0.958195, 0.421897,
1.015677, 0.431439,
1.046609, 0.453263,
1.089167, 0.435698,
1.112152, 0.445592,
1.149376, 0.458663,
1.143086, 0.467994,
1.178618, 0.494142,
1.178230, 0.490062,
1.202727, 0.519448,
1.264703, 0.538896,
1.300802, 0.571430,
1.309515, 0.629530,
1.383454, 0.672111,
1.433505, 0.684519,
1.510080, 0.676279,
1.680950, 0.720572,
1.649127, 0.726221,
1.787352, 0.769206,
1.911621, 0.671973,
1.936819, 0.780815,
2.111839, 0.570215,
2.236738, 0.596179,
2.329324, 0.556353,
2.423803, 0.479938,
2.548114, 0.379554,
2.495549, 0.279278,
2.675386, -0.007060,
2.512869, -0.084337,
2.723908, -0.190948,
2.353746, -0.626941,
2.550212, -0.385014,
2.369031, -0.435515,
2.333464, -0.795883,
1.912714, -0.841469,
1.844244, -1.095402,
1.741950, -1.333718,
1.919448, -1.361989,
1.672145, -1.309203,
1.559095, -0.326499,
//cmp_fix_biquad
-31.603, 19, 5,
4.247, 36, 0.3,
-12.149, 9046, 0.9,
11.905, 6464, 1.2,
//cmp_flex_vrange
-8, 8, 100, 300, 0.6, 1,
-8, 8, 400, 800, 0.5, 1,
-8, 8, 800, 1000, 0.5, 1,
-5, 5, 1000, 1500, 0.8, 1.5,
0.35481, 0.35481,
//cmp_flex_init
4.985, 193, 0.8,
0, 500, 1,
6.1, 900, 0.57,
0, 1200, 0.5,
//cmp_weight
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 10.00, 10.00, 10.00, 10.00,
10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00,
10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 10.00, 3.000, 3.000, 3.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000,
//cmp_iir_ab_idx
2,
//nmss_config
1,//flex_seq[0]
2,//flex_seq[1]
0,//flex_seq[2]
0,//flex_seq[3]
0,//flex_seq[4]
0,//flex_seq[5]
2,//n
1.0,//rho
2.0,//chi
0.5,//psi
0.5,//sigma
250,//maxnum
0.10,//usual_delta
5.0,//zero_term_delta
//lowshelf_config
0, //en
26, //f
-8.0,//g
1.0, //q
};