123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- #include "include.h"
- #if ANC_EN
- #define TRACE_EN 1
- #if TRACE_EN
- #define TRACE(...) printf(__VA_ARGS__)
- #else
- #define TRACE(...)
- #endif
- typedef struct {
- u16 gain;
- u8 nos_band;
- u8 msc_band;
- u32 param_buf[8 * 5 + 2];
- u32 drc_buf[20];
- u8 drc_band;
- u8 drc_en;
- u8 rfu[1];
- u8 bypass :1;
- } anc_channel_t;
- struct anc_cfg_t {
- anc_channel_t *ch;
- u8 spr;
- u8 rfu[1];
- u16 mic_type :3; //mic输入类型
- };
- typedef struct {
- u32 *addr;
- u32 *len;
- } anc_param;
- anc_channel_t anc_ch AT(.anc_buf.ch);
- struct anc_cfg_t anc_cfg AT(.anc.cfg);
- #define ANC_FIX_BIT 23
- #define EQ_GAIN_MAX 0x07eca9cd //24dB
- #define EQ_GAIN_MIN 0x00081385 //-24dB
- #define EQ_GAIN_STEP 2 //0.2dB
- static const anc_param anc_ff_eq_tbl[8] = {
- //降噪模式参数
- {&RES_BUF_ANC_L0_NOS_EQ, &RES_LEN_ANC_L0_NOS_EQ},
- {&RES_BUF_ANC_L0_NOS_DRC, &RES_LEN_ANC_L0_NOS_DRC},
- {&RES_BUF_ANC_R0_NOS_EQ, &RES_LEN_ANC_R0_NOS_EQ},
- {&RES_BUF_ANC_R0_NOS_DRC, &RES_LEN_ANC_R0_NOS_DRC},
- //通透模式参数
- {&RES_BUF_ANC_TP_L0_NOS_EQ, &RES_LEN_ANC_TP_L0_NOS_EQ},
- {&RES_BUF_ANC_TP_L0_NOS_DRC, &RES_LEN_ANC_TP_L0_NOS_DRC},
- {&RES_BUF_ANC_TP_R0_NOS_EQ, &RES_LEN_ANC_TP_R0_NOS_EQ},
- {&RES_BUF_ANC_TP_R0_NOS_DRC, &RES_LEN_ANC_TP_R0_NOS_DRC},
- };
- u32 bsp_anc_gain_adjust_do(s8 value)
- {
- s32 gain, abs_gain, adjust_val = 0;
- gain = (s32)sys_cb.anc_mic_gain; //初始gain值
- if (value != 0) {
- adjust_val = (s32)anc_pow10_cal(value * EQ_GAIN_STEP);
- gain = ((s64)gain * adjust_val) >> ANC_FIX_BIT;
- abs_gain = gain > 0? gain : -gain;
- if (abs_gain > EQ_GAIN_MAX || abs_gain < EQ_GAIN_MIN) {
- return sys_cb.anc_mic_gain;
- }
- }
- return (u32)gain;
- }
- void bsp_anc_gain_adjust(s8 value)
- {
- if (anc_cfg.ch == NULL) {
- return;
- }
- sys_cb.anc_adjust_val = value;
- anc_cfg.ch->param_buf[0] = bsp_anc_gain_adjust_do(value);
- anc_set_param(); //更新参数
- }
- bool bsp_anc_res_check_crc(u32 addr, u32 len)
- {
- u8 *ptr = (u8 *)addr;
- u8 offset = 0;
- if (ptr[0] == 'E' && ptr[1] == 'q' && ptr[2] == 0x01) {
- offset = 4;
- }
- u8 band_cnt = ptr[3+offset];
- if (band_cnt > 8) {
- return false;
- }
- u32 res_crc = ptr[band_cnt*27+11+offset] << 8 | ptr[band_cnt*27+10+offset];
- u32 cal_crc = calc_crc(ptr, band_cnt*27+10+offset, 0xffff);
- if (res_crc == cal_crc) {
- return true;
- } else {
- return false;
- }
- }
- void bsp_anc_set_nos_param(u8 band_cnt, const u32 *param)
- {
- anc_cfg.ch->nos_band = band_cnt;
- if (band_cnt == 0 || param == NULL) {
- return;
- }
- memcpy(anc_cfg.ch->param_buf, param, (band_cnt * 5 + 1) * 4);
- }
- void bsp_anc_set_msc_param(u8 band_cnt, const u32 *param)
- {
- anc_cfg.ch->msc_band = band_cnt;
- if (band_cnt == 0 || param == NULL) {
- return;
- }
- anc_cfg.ch->param_buf[41] = param[0];
- memcpy(&anc_cfg.ch->param_buf[anc_cfg.ch->nos_band * 5 + 1], param + 1, band_cnt * 5 * 4);
- }
- void bsp_anc_set_drc_param(u8 band_cnt, const u32 *param)
- {
- if (band_cnt == 0 || param == NULL) {
- return;
- }
- anc_cfg.ch->drc_en = 1;
- anc_cfg.ch->drc_band = band_cnt;
- memcpy(&anc_cfg.ch->drc_buf[0], param, 4* 4);
- anc_cfg.ch->drc_buf[4] = 0; //in_level
- anc_cfg.ch->drc_buf[5] = 0; //out_gain
- anc_cfg.ch->drc_buf[6] = param[4]; //tav
- anc_cfg.ch->drc_buf[7] = 0x00800000; //in_rms = 0
- memcpy(&anc_cfg.ch->drc_buf[8], ¶m[5], 3*4*band_cnt);
- }
- //EQ V2
- int bsp_anc_set_nos_param_by_res(u32 addr, u32 len)
- {
- if (len == 0) {
- return -1;
- }
- if (!bsp_anc_res_check_crc(addr, len)) {
- return -2;
- }
- u8 *ptr = (u8 *)addr;
- u8 band_cnt = ptr[7];
- u32 *param = (u32 *)&ptr[8];
- bsp_anc_set_nos_param(band_cnt, param);
- sys_cb.anc_mic_gain = anc_cfg.ch->param_buf[0]; //保存资源文件中的gain值
- if (xcfg_cb.anc_gain_en) {
- if (!anc_cb.tp_flag && sys_cb.anc_adjust_val != 0) { //写入量产测试的Gain
- anc_cfg.ch->param_buf[0] = bsp_anc_gain_adjust_do(sys_cb.anc_adjust_val);
- } else if (anc_cb.tp_flag && sys_cb.tp_adjust_val != 0) { //写入量产测试的Gain
- anc_cfg.ch->param_buf[0] = bsp_anc_gain_adjust_do(sys_cb.tp_adjust_val);
- }
- }
- return 0;
- }
- //EQ V2
- int bsp_anc_set_msc_param_by_res(u32 addr, u32 len)
- {
- if (len == 0) {
- return -1;
- }
- if (!bsp_anc_res_check_crc(addr, len)) {
- return -2;
- }
- u8 *ptr = (u8 *)addr;
- u8 band_cnt = ptr[7];
- u32 *param = (u32 *)&ptr[8];
- bsp_anc_set_msc_param(band_cnt, param);
- return 0;
- }
- //DRC V3
- int bsp_anc_set_drc_param_by_res(u32 addr, u32 len)
- {
- u8 drc_cnt;
- u32 res_crc, cal_crc;
- if (len == 0) {
- return -1;
- }
- u8 *ptr = (u8 *)addr;
- if (ptr[2] != 0x02 || ptr[7] > 4 || !ptr[7]) { //DRC V3
- return -2;
- }
- drc_cnt = ptr[7];
- res_crc = ptr[drc_cnt * 17 + 41] << 8 | ptr[drc_cnt * 17 + 40];
- cal_crc = calc_crc(ptr, drc_cnt * 17 + 40, 0xffff);
- if (res_crc != cal_crc) {
- return -3;
- }
- bsp_anc_set_drc_param(drc_cnt, (const u32 *)&ptr[8]);
- return 0;
- }
- void bsp_anc_set_mic_gain(u8 anl, u8 gain)
- {
- TRACE("anc set mic gain:%d %d\n", anl, gain);
- anc_set_mic_gain(anl, gain);
- }
- void bsp_anc_mic_mute(u8 mute)
- {
- TRACE("anc mic mute:%x\n", mute);
- set_mic_mute(mute);
- }
- void bsp_anc_start(void)
- {
- dac_fade_in();
- if (sys_cb.anc_start == 0) {
- sys_cb.anc_start = 1;
- sys_cb.sleep_aupll_en = 1;
- anc_start();
- }
- }
- void bsp_anc_stop(void)
- {
- if (sys_cb.anc_start) {
- anc_stop();
- sys_cb.anc_start = 0;
- sys_cb.sleep_aupll_en = 0;
- }
- }
- //无线/uart调anc参数接口
- void bsp_anc_dbg_eq_param(u8 packet, u8 band_cnt, u32 *eq_buf)
- {
- if (packet > 2) {
- anc_set_tansparency_mode(1);
- packet -= 2;
- } else {
- anc_set_tansparency_mode(0);
- }
- if (packet == 1) {
- bsp_anc_set_nos_param(band_cnt, eq_buf);
- }
- anc_set_param(); //更新参数
- }
- void bsp_anc_set_param(u8 tp)
- {
- const anc_param *anc_tbl;
- anc_tbl = &anc_ff_eq_tbl[4 * tp];
- #if BT_TWS_EN
- if (xcfg_cb.bt_tws_en) {
- if (!(sys_cb.tws_force_channel - 1)) { //TWS下FF/FB模式右声道取R的曲线给MICL
- anc_tbl = &anc_ff_eq_tbl[4 * tp + 2];
- }
- }
- #endif
- anc_set_tansparency_mode(tp);
- bsp_anc_set_nos_param_by_res(*anc_tbl[0].addr, *anc_tbl[0].len);
- bsp_anc_set_drc_param_by_res(*anc_tbl[1].addr, *anc_tbl[1].len);
- anc_set_param(); //更新参数
- }
- void bsp_anc_parse_cmd_process(u8 *rx_buf)
- {
- // printf("anc rx:");
- // print_r(rx_buf, 16);
- u8 *ptr = rx_buf;
- u8 channel = ptr[5];
- u8 bit_ctl = ptr[6];
- s8 adjust0 = (s8)ptr[8];
- bool eq_tool = (bool)(bit_ctl & BIT(4));//判断是EQ工具还是量产工具
- bool tp_flag = (bool)(bit_ctl & BIT(5));//判断是anc模式测试,还是通透模式测试
- if(!tp_flag){
- if (!sys_cb.anc_start|| sys_cb.anc_user_mode != 1) {
- bsp_anc_set_mode(1);
- }
- }else{
- if (!sys_cb.anc_start|| sys_cb.anc_user_mode != 2) {
- bsp_anc_set_mode(2);
- }
- }
- eq_dbg_cb.eq_spp_cb.rx_size = 16;
- do {
- u8 ch = channel - 1;
- #if BT_TWS_EN
- if (xcfg_cb.bt_tws_en) {
- if (ch == 2 || (ch == func_bt_tws_get_channel())) { //声道不相等,转发
- if(bt_tws_is_connected()) {
- if (ch == 2) { //把这个声道去掉,重新算下CRC
- ptr[5] = (func_bt_tws_get_channel() == 1) ? 2 : 1;
- u16 crc = calc_crc(ptr, 14, 0xffff);
- ptr[14] = crc;
- ptr[15] = crc >> 8;
- }
- bt_tws_sync(TWS_SYNC_INFO_EQ);
- }
- if (ch != 2) { //如果收到单声道的命令,转发后跳出
- break;
- }
- }
- }
- #endif
- bool ch_mute = !((bit_ctl & BIT(0)) && (bit_ctl & BIT(2)) == 0);
- s8 old_ajust_val = sys_cb.anc_adjust_val;
- bsp_anc_mic_mute(ch_mute);
- if (!eq_tool) {
- bsp_anc_gain_adjust(adjust0);
- }
- if (bit_ctl & BIT(1)) {
- if (!tp_flag) {
- param_write((u8*)&sys_cb.anc_adjust_val, PARAM_ANC_MIC_VAL, 1);
- } else {
- sys_cb.tp_adjust_val = sys_cb.anc_adjust_val;
- sys_cb.anc_adjust_val = old_ajust_val;
- param_write((u8*)&sys_cb.tp_adjust_val, PARAM_ANC_TP_MIC_VAL, 1);
- }
- }
- //调整again,研发调试用
- if (bit_ctl & BIT(4)) {
- bsp_anc_set_mic_gain(1, ptr[10]);
- }
- if (bit_ctl & BIT(1)) {
- param_sync();
- }
- TRACE("## anc dbg mute:%d eq_tool:%d anl_vol:%d save:%d\n", ch_mute, eq_tool, ptr[10], (bool)(bit_ctl & BIT(1)));
- } while (0);
- }
- //mode: 0[off], 1[anc], 2[tansparency]
- void bsp_anc_set_mode(u8 mode)
- {
- if (!xcfg_cb.anc_en) {
- return;
- }
- sys_cb.anc_user_mode = mode;
- if (mode == 0) {
- bsp_anc_stop();
- } else {
- bsp_anc_set_param(mode - 1);
- bsp_anc_start();
- }
- TRACE("anc user mode:%d\n", mode);
- }
- void bsp_anc_init(void)
- {
- if (!xcfg_cb.anc_en) {
- TRACE("'xcfg_cb.anc_en' define 0\n");
- return;
- }
- memset(&anc_cfg, 0, sizeof(anc_cfg));
- memset(&anc_ch, 0, sizeof(anc_ch));
- anc_cfg.ch = &anc_ch;
- anc_cfg.spr = SPR_384000;
- anc_cfg.ch->drc_en = 0;
- anc_cfg.ch->gain = ((u16)BT_ANL_GAIN << 6) | 0;
- anc_cfg.ch->bypass = 0;
- param_read((u8*)&sys_cb.anc_adjust_val, PARAM_ANC_MIC_VAL, 1);
- param_read((u8*)&sys_cb.tp_adjust_val, PARAM_ANC_TP_MIC_VAL, 1);
- anc_init(&anc_cfg);
- bsp_anc_set_param(0);
- TRACE("anc init\n");
- TRACE("anc mic type:%d\n", anc_cfg.mic_type);
- TRACE("anc mic gain:%x\n", anc_cfg.ch->gain);
- TRACE("anc adjust mic gain: %d, %d\n", sys_cb.anc_adjust_val, sys_cb.tp_adjust_val);
- }
- void bsp_anc_exit(void)
- {
- anc_exit();
- sys_cb.anc_start = 0;
- }
- #endif //ANC_EN
|