3529 lines
129 KiB
C
3529 lines
129 KiB
C
/*
|
||
****************************************************************
|
||
* AUDIO ANC
|
||
* File : audio_anc.c
|
||
* By :
|
||
* Notes : ref_mic = 参考mic
|
||
* err_mic = 误差mic
|
||
*
|
||
****************************************************************
|
||
*/
|
||
#include "system/includes.h"
|
||
#include "audio_anc.h"
|
||
#include "system/task.h"
|
||
#include "timer.h"
|
||
#include "asm/clock.h"
|
||
#include "asm/power/p33.h"
|
||
#include "online_db_deal.h"
|
||
#include "app_config.h"
|
||
#include "tone_player.h"
|
||
#include "audio_adc.h"
|
||
#include "audio_enc.h"
|
||
#include "asm/dac.h"
|
||
#include "audio_anc_coeff.h"
|
||
#include "btstack/avctp_user.h"
|
||
#include "app_main.h"
|
||
#include "audio_decoder.h"
|
||
#include "adv_adaptive_noise_reduction.h"
|
||
#include "audio_codec_clock.h"
|
||
#if ANC_MUSIC_DYNAMIC_GAIN_EN
|
||
#include "amplitude_statistic.h"
|
||
#endif/*ANC_MUSIC_DYNAMIC_GAIN_EN*/
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
#include "icsd_adt.h"
|
||
#include "icsd_adt_app.h"
|
||
#endif /*TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN*/
|
||
|
||
#if TCFG_USER_TWS_ENABLE
|
||
#include "bt_tws.h"
|
||
#endif/*TCFG_USER_TWS_ENABLE*/
|
||
#ifdef SUPPORT_MS_EXTENSIONS
|
||
#pragma bss_seg(".anc_user_bss")
|
||
#pragma data_seg(".anc_user_data")
|
||
#pragma const_seg(".anc_user_const")
|
||
#pragma code_seg(".anc_user_code")
|
||
#endif/*SUPPORT_MS_EXTENSIONS*/
|
||
|
||
#define AT_VOLATILE_RAM_CODE AT(.volatile_ram_code)
|
||
|
||
#if INEAR_ANC_UI
|
||
extern u8 inear_tws_ancmode;
|
||
#endif/*INEAR_ANC_UI*/
|
||
|
||
#if TCFG_AUDIO_ANC_ENABLE
|
||
|
||
#if 1
|
||
#define user_anc_log printf
|
||
#else
|
||
#define user_anc_log(...)
|
||
#endif/*log_en*/
|
||
|
||
/*************************ANC增益配置******************************/
|
||
#define ANC_DAC_GAIN 13 //ANC Speaker增益
|
||
#define ANC_REF_MIC_GAIN 8 //ANC参考Mic增益
|
||
#define ANC_ERR_MIC_GAIN 8 //ANC误差Mic增益
|
||
#define ANC_FADE_GAIN_DEFAULT 16384 //ANC默认淡入淡出增益,16384 = 0dB
|
||
/*****************************************************************/
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
const u8 CONST_ANC_ADT_EN = 1;
|
||
#else
|
||
const u8 CONST_ANC_ADT_EN = 0;
|
||
#endif /*TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN*/
|
||
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
const u8 CONST_ANC_EAR_ADAPTIVE_EN = 1;
|
||
#else
|
||
const u8 CONST_ANC_EAR_ADAPTIVE_EN = 0;
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
|
||
#if TCFG_ANC_SELF_DUT_GET_SZ
|
||
const u8 CONST_ANC_DUT_SZ_EN = 1;
|
||
#else
|
||
const u8 CONST_ANC_DUT_SZ_EN = 0;
|
||
#endif/*TCFG_ANC_SELF_DUT_GET_SZ*/
|
||
|
||
#if ANC_ADAPTIVE_EN
|
||
/*自适应增益等级系数表*/
|
||
anc_adap_param_t anc_adap_param[] = {
|
||
{
|
||
.pow_thr = 0XFFFFFFFF, //当前等级能量高阈值
|
||
.default_flag = 1, //默认等级标志
|
||
.trigger_cnt = 20, //当前等级检测时间*500ms */
|
||
.gain = 1024, //当前等级对应增益 */
|
||
.fade_lvl = 10, //当前等级增益淡入时间*100ms */
|
||
/*
|
||
此阈值对应MIC模拟增益为4, 对应差值倍数为1.259,
|
||
如MIC模拟增益为3, 该阈值 = 500*(1.259^(3-4)) = 397
|
||
如MIC模拟增益为6, 该阈值 = 500*(1.259^(6-4)) = 792
|
||
*/
|
||
.pow_lthr = 700, //当前等级能量低阈值
|
||
},
|
||
{
|
||
.pow_thr = 200, //此阈值对应模拟增益为4,计算方法如上
|
||
.trigger_cnt = 20,
|
||
.gain = 350,
|
||
.fade_lvl = 10,
|
||
.pow_lthr = 0,
|
||
},
|
||
};
|
||
|
||
void audio_anc_pow_adap_fade(u16 gain);
|
||
#endif/*ANC_ADAPTIVE_EN*/
|
||
|
||
|
||
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
float anc_trans_lfb_gain = 0.0625f;
|
||
|
||
float anc_trans_rfb_gain = 0.0625f;
|
||
|
||
const double anc_trans_lfb_coeff[] = {
|
||
0.195234751212410628795623779296875,
|
||
0.1007948522455990314483642578125,
|
||
0.0427739980514161288738250732421875,
|
||
-1.02504855208098888397216796875,
|
||
0.36385215423069894313812255859375,
|
||
/*
|
||
0.0508266850956715643405914306640625,
|
||
-0.1013386586564593017101287841796875,
|
||
0.0505129448720254004001617431640625,
|
||
-1.99860572628676891326904296875,
|
||
0.9986066981218755245208740234375,
|
||
*/
|
||
};
|
||
|
||
const double anc_trans_rfb_coeff[] = {
|
||
0.195234751212410628795623779296875,
|
||
0.1007948522455990314483642578125,
|
||
0.0427739980514161288738250732421875,
|
||
-1.02504855208098888397216796875,
|
||
0.36385215423069894313812255859375,
|
||
};
|
||
#endif /*TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN*/
|
||
|
||
|
||
static void anc_mix_out_audio_drc_thr(float thr);
|
||
static void anc_fade_in_timeout(void *arg);
|
||
static void anc_mode_switch_deal(u8 mode);
|
||
static void anc_timer_deal(void *priv);
|
||
static int anc_app_online_parse(u8 *packet, u8 size, u8 *ext_data, u16 ext_size);
|
||
static anc_coeff_t *anc_cfg_test(u8 coeff_en, u8 gains_en);
|
||
static void anc_fade_in_timer_add(audio_anc_t *param);
|
||
static void audio_anc_adap_tone_play(int ref_lvl, int err_lvl);
|
||
void anc_dmic_io_init(audio_anc_t *param, u8 en);
|
||
u8 anc_btspp_train_again(u8 mode, u32 dat);
|
||
static void anc_tone_play_and_mode_switch(u8 index, u8 preemption, u8 cb_sel);
|
||
void anc_mode_enable_set(u8 mode_enable);
|
||
void audio_anc_post_msg_drc(void);
|
||
void audio_anc_post_msg_debug(void);
|
||
void audio_anc_post_msg_user_train_run(void);
|
||
void audio_anc_adc_ch_set(void);
|
||
void audio_anc_music_dynamic_gain_process(void);
|
||
|
||
static void audio_anc_sz_fft_dac_check_slience_cb(void *buf, int len);
|
||
void audio_anc_post_msg_sz_fft_run(void);
|
||
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
int audio_anc_adaptive_data_save(anc_adaptive_iir_t *iir);
|
||
int audio_anc_adaptive_data_read(anc_adaptive_iir_t *iir);
|
||
void audio_anc_ear_adaptive_param_init(audio_anc_t *param);
|
||
|
||
void audio_anc_param_map(u8 coeff_en, u8 gain_en);
|
||
void audio_anc_adaptive_poweron_catch_data(anc_adaptive_iir_t *iir);
|
||
void audio_anc_adaptive_data_format(anc_adaptive_iir_t *iir);
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
|
||
|
||
extern u8 bt_phone_dec_is_running();
|
||
extern u8 bt_media_is_running(void);
|
||
extern void anc_user_train_tone_play_cb();
|
||
extern void esco_adc_mic_set_buffs(void);
|
||
|
||
#define ESCO_MIC_DUMP_CNT 10
|
||
extern void esco_mic_dump_set(u16 dump_cnt);
|
||
extern struct audio_dac_hdl dac_hdl;
|
||
|
||
|
||
typedef struct {
|
||
u8 mode_num; /*模式总数*/
|
||
u8 mode_enable; /*使能的模式*/
|
||
u8 anc_parse_seq;
|
||
u8 suspend; /*挂起*/
|
||
u8 ui_mode_sel; /*ui菜单降噪模式选择*/
|
||
u8 new_mode; /*记录模式切换最新的目标模式*/
|
||
u8 last_mode; /*记录模式切换的上一个模式*/
|
||
u8 mic_dy_state; /*动态MIC增益状态*/
|
||
char mic_diff_gain; /*动态MIC增益差值*/
|
||
u16 scene_id; /*多场景滤波器-场景ID*/
|
||
u8 scene_max; /*多场景滤波器-最大场景个数*/
|
||
u16 ui_mode_sel_timer;
|
||
u16 fade_in_timer;
|
||
u16 fade_gain;
|
||
u16 mic_resume_timer; /*动态MIC增益恢复定时器id*/
|
||
float drc_ratio; /*动态MIC增益,对应DRC增益比例*/
|
||
volatile u8 state; /*ANC状态*/
|
||
volatile u8 mode_switch_lock; /*切模式锁存,1表示正在切ANC模式*/
|
||
volatile u8 sync_busy;
|
||
audio_anc_t param; /*ANC lib句柄*/
|
||
audio_adc_mic_mana_t dy_mic_param[4]; /*MIC动态增益参数管理*/
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
u8 ear_adaptive_tws_sync; /*耳道自适应-左右耳平衡使能*/
|
||
u8 ear_adaptive_seq;
|
||
u8 dac_check_slience_flag; /*耳道自适应-DAC静音检测标志*/
|
||
u8 ear_adaptive_data_from; /*耳道自适应-滤波器数据来源*/
|
||
u8 ear_adaptive; /*耳道自适应-模式标志*/
|
||
u8 ear_adaptive_busy; /*耳道自适应-检测繁忙标记*/
|
||
u8 ear_adaptive_dec_wait; /*耳道自适应-音乐播放打断标志*/
|
||
int last_sys_clk; /*上一次系统时钟*/
|
||
anc_adaptive_iir_t adaptive_iir;/*耳道自适应*/
|
||
struct audio_res_wait adaptive_wait; /*耳道自适应,解码任务hdl*/
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
|
||
#if ANC_MUSIC_DYNAMIC_GAIN_EN
|
||
char loud_dB; /*音乐动态增益-当前音乐幅值*/
|
||
s16 loud_nowgain; /*音乐动态增益-当前增益*/
|
||
s16 loud_targetgain; /*音乐动态增益-目标增益*/
|
||
u16 loud_timeid; /*音乐动态增益-定时器ID*/
|
||
LOUDNESS_M_STRUCT loud_hdl; /*音乐动态增益-操作句柄*/
|
||
#endif/*ANC_MUSIC_DYNAMIC_GAIN_EN*/
|
||
|
||
} anc_t;
|
||
static anc_t *anc_hdl = NULL;
|
||
anc_packet_data_t *anc_adaptive_data = NULL;
|
||
|
||
const u8 anc_tone_tab[3] = {IDEX_TONE_ANC_OFF, IDEX_TONE_ANC_ON, IDEX_TONE_TRANSPARCNCY};
|
||
|
||
u32 get_anc_gains_sign()
|
||
{
|
||
if (anc_hdl) {
|
||
return anc_hdl->param.gains.gain_sign;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
u32 get_anc_gains_alogm()
|
||
{
|
||
if (anc_hdl) {
|
||
return anc_hdl->param.gains.alogm;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
u32 get_anc_gains_trans_alogm()
|
||
{
|
||
if (anc_hdl) {
|
||
return anc_hdl->param.gains.trans_alogm;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
void *get_anc_lfb_coeff()
|
||
{
|
||
if (anc_hdl) {
|
||
return anc_hdl->param.lfb_coeff;
|
||
} else {
|
||
return NULL;
|
||
}
|
||
}
|
||
|
||
float get_anc_gains_l_fbgain()
|
||
{
|
||
if (anc_hdl) {
|
||
return anc_hdl->param.gains.l_fbgain;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
u8 get_anc_l_fbyorder()
|
||
{
|
||
if (anc_hdl) {
|
||
return anc_hdl->param.lfb_yorder;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
void *get_anc_lff_coeff()
|
||
{
|
||
if (anc_hdl) {
|
||
printf("anc hdl lff coeff:%x\n", (int)anc_hdl->param.lff_coeff);
|
||
return anc_hdl->param.lff_coeff;
|
||
} else {
|
||
printf("anc hdl NULL~~~~~~~~\n");
|
||
return NULL;
|
||
}
|
||
}
|
||
|
||
float get_anc_gains_l_ffgain()
|
||
{
|
||
if (anc_hdl) {
|
||
return anc_hdl->param.gains.l_ffgain;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
u8 get_anc_l_ffyorder()
|
||
{
|
||
if (anc_hdl) {
|
||
return anc_hdl->param.lff_yorder;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
void *get_anc_ltrans_coeff()
|
||
{
|
||
if (anc_hdl) {
|
||
return anc_hdl->param.ltrans_coeff;
|
||
} else {
|
||
return NULL;
|
||
}
|
||
}
|
||
|
||
float get_anc_gains_l_transgain()
|
||
{
|
||
if (anc_hdl) {
|
||
return anc_hdl->param.gains.l_transgain;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
u8 get_anc_l_transyorder()
|
||
{
|
||
if (anc_hdl) {
|
||
return anc_hdl->param.ltrans_yorder;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
void *get_anc_ltrans_fb_coeff()
|
||
{
|
||
if (anc_hdl) {
|
||
return anc_hdl->param.ltrans_fb_coeff;
|
||
} else {
|
||
return NULL;
|
||
}
|
||
}
|
||
|
||
float get_anc_gains_lfb_transgain()
|
||
{
|
||
if (anc_hdl) {
|
||
return anc_hdl->param.ltrans_fbgain;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
u8 get_anc_lfb_transyorder()
|
||
{
|
||
if (anc_hdl) {
|
||
return anc_hdl->param.ltrans_fb_yorder;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
void set_anc_adt_state(u8 state)
|
||
{
|
||
if (anc_hdl) {
|
||
anc_hdl->param.adt_state = state;
|
||
}
|
||
}
|
||
|
||
static void anc_task(void *p)
|
||
{
|
||
int res;
|
||
int anc_ret = 0;
|
||
int msg[16];
|
||
u8 speak_to_chat_flag = 0;
|
||
u8 adt_flag = 0;
|
||
u8 cur_anc_mode;
|
||
u32 pend_timeout = portMAX_DELAY;
|
||
user_anc_log(">>>ANC TASK<<<\n");
|
||
while (1) {
|
||
res = os_taskq_pend(NULL, msg, ARRAY_SIZE(msg));
|
||
if (res == OS_TASKQ) {
|
||
switch (msg[1]) {
|
||
case ANC_MSG_TRAIN_OPEN:/*启动训练模式*/
|
||
audio_mic_pwr_ctl(MIC_PWR_ON);
|
||
anc_dmic_io_init(&anc_hdl->param, 1);
|
||
user_anc_log("ANC_MSG_TRAIN_OPEN");
|
||
audio_anc_train(&anc_hdl->param, 1);
|
||
os_time_dly(1);
|
||
anc_train_close();
|
||
audio_mic_pwr_ctl(MIC_PWR_OFF);
|
||
break;
|
||
case ANC_MSG_TRAIN_CLOSE:/*训练关闭模式*/
|
||
user_anc_log("ANC_MSG_TRAIN_CLOSE");
|
||
anc_train_close();
|
||
break;
|
||
case ANC_MSG_RUN:
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
if (anc_hdl->param.gains.trans_alogm != 5) {
|
||
ASSERT(0, "ERR!!ANC ADT trans_alogm %d != 5\n", anc_hdl->param.gains.trans_alogm);
|
||
}
|
||
audio_anc_mode_switch_in_adt(anc_hdl->param.mode);
|
||
if (get_adt_open_in_anc_state() && anc_hdl->param.mode == ANC_OFF) {
|
||
user_anc_log("[ADT] ANC_MSG_RUN:%s \n", anc_mode_str[anc_hdl->param.mode]);
|
||
anc_hdl->param.anc_fade_gain = 0;
|
||
anc_hdl->param.mode = ANC_ON;
|
||
speak_to_chat_flag = 1;
|
||
} else {
|
||
anc_hdl->param.anc_fade_gain = 16384;
|
||
speak_to_chat_flag = 0;
|
||
}
|
||
#endif /*TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN*/
|
||
|
||
cur_anc_mode = anc_hdl->param.mode;/*保存当前anc模式,防止切换过程anc_hdl->param.mode发生切换改变*/
|
||
|
||
#if ANC_MULT_ORDER_ENABLE
|
||
if (cur_anc_mode != ANC_OFF) {
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
if (anc_hdl->param.anc_coeff_mode == ANC_COEFF_MODE_ADAPTIVE) {
|
||
audio_anc_coeff_adaptive_set(ANC_COEFF_MODE_ADAPTIVE, 0, 0);
|
||
} else {
|
||
anc_mult_scene_set(anc_hdl->scene_id);
|
||
}
|
||
#else
|
||
anc_mult_scene_set(anc_hdl->scene_id);
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
}
|
||
#endif/*ANC_MULT_ORDER_ENABLE*/
|
||
|
||
user_anc_log("ANC_MSG_RUN:%s \n", anc_mode_str[cur_anc_mode]);
|
||
#if ANC_MUSIC_DYNAMIC_GAIN_EN
|
||
audio_anc_music_dynamic_gain_reset(0); /*音乐动态增益,切模式复位状态*/
|
||
#endif/*ANC_MUSIC_DYNAMIC_GAIN_EN*/
|
||
|
||
#if TCFG_AUDIO_DYNAMIC_ADC_GAIN
|
||
if (anc_hdl->mic_resume_timer) {
|
||
sys_timer_del(anc_hdl->mic_resume_timer);
|
||
anc_hdl->mic_resume_timer = 0;
|
||
}
|
||
#endif/*TCFG_AUDIO_DYNAMIC_ADC_GAIN*/
|
||
#if (TCFG_AUDIO_ADC_MIC_CHA == LADC_CH_PLNK)
|
||
esco_mic_dump_set(ESCO_MIC_DUMP_CNT);
|
||
#endif/*LADC_CH_PLNK*/
|
||
if (anc_hdl->state == ANC_STA_INIT) {
|
||
audio_mic_pwr_ctl(MIC_PWR_ON);
|
||
anc_dmic_io_init(&anc_hdl->param, 1);
|
||
#if ANC_MODE_SYSVDD_EN
|
||
clock_set_lowest_voltage(SYSVDD_VOL_SEL_105V); //进入ANC时提高SYSVDD电压
|
||
#endif/*ANC_MODE_SYSVDD_EN*/
|
||
anc_ret = audio_anc_run(&anc_hdl->param);
|
||
if (anc_ret == 0) {
|
||
anc_hdl->state = ANC_STA_OPEN;
|
||
} else {
|
||
/*
|
||
*-EPERM(-1):不支持ANC(非差分MIC,或混合馈使用4M的flash)
|
||
*-EINVAL(-22):参数错误(anc_coeff.bin参数为空, 或不匹配)
|
||
*/
|
||
user_anc_log("audio_anc open Failed:%d\n", anc_ret);
|
||
anc_hdl->mode_switch_lock = 0;
|
||
anc_hdl->state = ANC_STA_INIT;
|
||
anc_hdl->param.mode = ANC_OFF;
|
||
anc_hdl->new_mode = ANC_OFF;
|
||
/*ANC OFF && esco_dec idle*/
|
||
if (bt_phone_dec_is_running() == 0) {
|
||
audio_mic_pwr_ctl(MIC_PWR_OFF);
|
||
}
|
||
break;
|
||
}
|
||
} else {
|
||
audio_anc_run(&anc_hdl->param);
|
||
if (cur_anc_mode == ANC_OFF) {
|
||
anc_hdl->state = ANC_STA_INIT;
|
||
anc_dmic_io_init(&anc_hdl->param, 0);
|
||
/*ANC OFF && esco_dec idle*/
|
||
if (bt_phone_dec_is_running() == 0) {
|
||
audio_mic_pwr_ctl(MIC_PWR_OFF);
|
||
}
|
||
}
|
||
}
|
||
if (cur_anc_mode == ANC_OFF) {
|
||
#if ANC_MODE_SYSVDD_EN
|
||
clock_set_lowest_voltage(SYSVDD_VOL_SEL_084V); //退出ANC恢复普通模式
|
||
#endif/*ANC_MODE_SYSVDD_EN*/
|
||
/*anc关闭,如果没有连接蓝牙,倒计时进入自动关机*/
|
||
/* extern u8 get_total_connect_dev(void); */
|
||
/* if (get_total_connect_dev() == 0) { //已经没有设备连接 */
|
||
/* sys_auto_shut_down_enable(); */
|
||
/* } */
|
||
}
|
||
#if TCFG_AUDIO_DYNAMIC_ADC_GAIN
|
||
if (bt_phone_dec_is_running() && (anc_hdl->state == ANC_STA_OPEN)) {
|
||
if (anc_hdl->mic_dy_state == ANC_MIC_DY_STA_START) {
|
||
audio_anc_drc_ctrl(&anc_hdl->param, anc_hdl->drc_ratio);
|
||
} else if (anc_hdl->mic_dy_state == ANC_MIC_DY_STA_INIT) {
|
||
anc_dynamic_micgain_start(app_var.aec_mic_gain);
|
||
}
|
||
}
|
||
#endif/*TCFG_AUDIO_DYNAMIC_ADC_GAIN*/
|
||
anc_hdl->mode_switch_lock = 0;
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
if (speak_to_chat_flag) {
|
||
cur_anc_mode = ANC_OFF;
|
||
anc_hdl->param.mode = ANC_OFF;
|
||
speak_to_chat_flag = 0;
|
||
}
|
||
#endif /*TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN*/
|
||
if ((anc_hdl->param.mode != ANC_OFF) && anc_hdl->param.anc_fade_en) {
|
||
os_time_dly(6); //延时避免切模式反馈有哒哒声
|
||
}
|
||
audio_anc_lvl_set(anc_hdl->param.anc_lvl, 0);
|
||
anc_fade_in_timer_add(&anc_hdl->param);
|
||
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
audio_icsd_adt_resume();
|
||
audio_speak_to_chat_open_in_anc_done();
|
||
#endif /*TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN*/
|
||
anc_hdl->last_mode = cur_anc_mode;
|
||
#if ANC_MULT_ORDER_ENABLE
|
||
audio_anc_mult_scene_coeff_free();
|
||
#endif/*ANC_MULT_ORDER_ENABLE*/
|
||
break;
|
||
case ANC_MSG_MODE_SYNC:
|
||
user_anc_log("anc_mode_sync:%d", msg[2]);
|
||
anc_mode_switch(msg[2], 0);
|
||
break;
|
||
#if TCFG_USER_TWS_ENABLE
|
||
case ANC_MSG_TONE_SYNC:
|
||
user_anc_log("anc_tone_sync_play:%d", msg[2]);
|
||
#if !ANC_MODE_EN_MODE_NEXT_SW
|
||
if (anc_hdl->mode_switch_lock) {
|
||
user_anc_log("anc mode switch lock\n");
|
||
break;
|
||
}
|
||
anc_hdl->mode_switch_lock = 1;
|
||
#endif/*ANC_MODE_EN_MODE_NEXT_SW*/
|
||
if (msg[2] == SYNC_TONE_ANC_OFF) {
|
||
anc_hdl->param.mode = ANC_OFF;
|
||
} else if (msg[2] == SYNC_TONE_ANC_ON) {
|
||
anc_hdl->param.mode = ANC_ON;
|
||
} else {
|
||
anc_hdl->param.mode = ANC_TRANSPARENCY;
|
||
}
|
||
if (anc_hdl->suspend) {
|
||
anc_hdl->param.tool_enablebit = 0;
|
||
}
|
||
anc_hdl->new_mode = anc_hdl->param.mode; //确保准备切的新模式,与最后一个提示音播放的模式一致
|
||
anc_tone_play_and_mode_switch(anc_tone_tab[anc_hdl->param.mode - 1], ANC_TONE_PREEMPTION, ANC_TONE_END_MODE_SW);
|
||
//anc_mode_switch_deal(anc_hdl->param.mode);
|
||
anc_hdl->sync_busy = 0;
|
||
break;
|
||
#endif/*TCFG_USER_TWS_ENABLE*/
|
||
case ANC_MSG_FADE_END:
|
||
break;
|
||
case ANC_MSG_DRC_TIMER:
|
||
audio_anc_drc_process();
|
||
break;
|
||
case ANC_MSG_DEBUG_OUTPUT:
|
||
audio_anc_debug_data_output();
|
||
break;
|
||
#if ANC_ADAPTIVE_EN
|
||
case ANC_MSG_ADAPTIVE_SYNC:
|
||
user_anc_log("anc_pow_adap_sync:%d %d", msg[2], msg[3]);
|
||
audio_anc_adap_tone_play((u8)msg[2], (u8)msg[3]);
|
||
break;
|
||
#endif/*ANC_ADAPTIVE_EN*/
|
||
|
||
#if ANC_MUSIC_DYNAMIC_GAIN_EN
|
||
case ANC_MSG_MUSIC_DYN_GAIN:
|
||
audio_anc_music_dynamic_gain_process();
|
||
break;
|
||
#endif/*ANC_MUSIC_DYNAMIC_GAIN_EN*/
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
case ANC_MSG_ADT:
|
||
icsd_adt_anctask_handle((u8)msg[2]);
|
||
break;
|
||
#endif /*TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN*/
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
case ANC_MSG_ICSD_ANC_CMD:
|
||
icsd_anc_anctask_cmd_handle((u8)msg[2]);
|
||
break;
|
||
case ANC_MSG_USER_TRAIN_INIT:
|
||
/* anc_hdl->last_sys_clk = clk_get("sys"); */
|
||
/* user_anc_log("sys clk:%d\n", anc_hdl->last_sys_clk); */
|
||
/* sys_clk_set(SYS_160M); //自适应跑最高的时钟 */
|
||
audio_codec_clock_set(ANC_EAR_ADAPTIVE_MODE, AUDIO_CODING_PCM, 0);
|
||
//icsd_anc_init(&anc_hdl->param,0);
|
||
if (++anc_hdl->ear_adaptive_seq == 0xff) {
|
||
anc_hdl->ear_adaptive_seq = 0;
|
||
}
|
||
icsd_anc_init(&anc_hdl->param, 1, anc_hdl->ear_adaptive_seq, ANC_ADAPTIVE_TONE_DELAY, anc_hdl->ear_adaptive_tws_sync);
|
||
break;
|
||
case ANC_MSG_USER_TRAIN_RUN:
|
||
icsd_anc_run();
|
||
break;
|
||
case ANC_MSG_USER_TRAIN_SETPARAM:
|
||
icsd_anc_setparam();
|
||
break;
|
||
case ANC_MSG_USER_TRAIN_TIMEOUT:
|
||
icsd_anc_timeout_handler();
|
||
break;
|
||
case ANC_MSG_USER_TRAIN_END:
|
||
icsd_anc_end(&anc_hdl->param);
|
||
/* sys_clk_set(anc_hdl->last_sys_clk); //自适应结束恢复时钟 */
|
||
audio_codec_clock_del(ANC_EAR_ADAPTIVE_MODE);
|
||
break;
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
case ANC_MSG_MIC_DATA_GET:
|
||
/* extern void anc_spp_mic_data_get(audio_anc_t *param); */
|
||
/* anc_spp_mic_data_get(&anc_hdl->param); */
|
||
break;
|
||
case ANC_MSG_RESET:
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
adt_flag = audio_icsd_adt_is_running();
|
||
if (adt_flag) { ////免摘挂起
|
||
audio_icsd_adt_suspend();
|
||
}
|
||
#endif /*TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN*/
|
||
if (msg[2] && anc_hdl->param.anc_fade_en) {
|
||
int alogm = (anc_hdl->param.mode == ANC_TRANSPARENCY) ? anc_hdl->param.gains.trans_alogm : anc_hdl->param.gains.alogm;
|
||
int dly = audio_anc_fade_dly_get(anc_hdl->param.anc_fade_gain, alogm);
|
||
audio_anc_fade_ctr_set(ANC_FADE_MODE_RESET, AUDIO_ANC_FDAE_CH_ALL, 0);
|
||
os_time_dly(dly / 10 + 1);
|
||
audio_anc_reset(&anc_hdl->param, 1);
|
||
//避免param.anc_fade_gain 被修改,这里使用固定值
|
||
audio_anc_fade_ctr_set(ANC_FADE_MODE_RESET, AUDIO_ANC_FDAE_CH_ALL, ANC_FADE_GAIN_DEFAULT);
|
||
} else {
|
||
audio_anc_reset(&anc_hdl->param, 0);
|
||
}
|
||
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
if (adt_flag) { //免摘恢复, 更新免摘参数coeff gain
|
||
set_icsd_adt_param_updata();
|
||
audio_icsd_adt_resume();
|
||
}
|
||
#endif /*TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN*/
|
||
#if ANC_MULT_ORDER_ENABLE
|
||
audio_anc_mult_scene_coeff_free(); //释放空间
|
||
#endif/*ANC_MULT_ORDER_ENABLE*/
|
||
break;
|
||
#if TCFG_ANC_SELF_DUT_GET_SZ
|
||
case ANC_MSG_SZ_FFT_OPEN:
|
||
audio_codec_clock_set(ANC_DUT_SZ_FFT_MODE, AUDIO_CODING_PCM, 0);
|
||
anc_hdl->param.mode = ANC_TRAIN;
|
||
anc_hdl->new_mode = ANC_TRAIN;
|
||
anc_hdl->param.test_type = ANC_TEST_TYPE_FFT; //设置当前的测试类型
|
||
anc_hdl->param.sz_fft.alogm = ANC_ALOGM3; //设置当前测试模式采样率
|
||
anc_hdl->param.sz_fft.data_sel = msg[2]; //传入目标数据通道
|
||
anc_hdl->param.sz_fft.check_flag = 1; //检查DAC有效数据段
|
||
audio_anc_train(&anc_hdl->param, 1); //打开训练模式
|
||
audio_dac_write_callback_add(&dac_hdl, audio_anc_sz_fft_dac_check_slience_cb); //注册DAC回调接口-静音检测
|
||
break;
|
||
case ANC_MSG_SZ_FFT_RUN:
|
||
audio_anc_sz_fft_run(&anc_hdl->param); //SZ_FFT 频响计算主体
|
||
break;
|
||
case ANC_MSG_SZ_FFT_CLOSE:
|
||
audio_anc_sz_fft_stop(&anc_hdl->param); //SZ_FFT 停止计算
|
||
anc_train_close(); //关闭ANC,模式设置为ANC_OFF
|
||
break;
|
||
#endif/*TCFG_ANC_SELF_DUT_GET_SZ*/
|
||
case ANC_MSG_MODE_SWITCH_IN_ANCTASK:
|
||
user_anc_log("anc_mode_in_anctask:%d, %d", msg[2], msg[3]);
|
||
anc_mode_switch(msg[2], msg[3]);
|
||
break;
|
||
}
|
||
} else {
|
||
user_anc_log("res:%d,%d", res, msg[1]);
|
||
}
|
||
}
|
||
}
|
||
|
||
void anc_param_gain_t_printf(u8 cmd)
|
||
{
|
||
char *str[2] = {
|
||
"ANC_CFG_READ",
|
||
"ANC_CFG_WRITE"
|
||
};
|
||
anc_gain_param_t *gains = &anc_hdl->param.gains;
|
||
user_anc_log("-------------anc_param anc_gain_t-%s--------------\n", str[cmd - 1]);
|
||
user_anc_log("developer_mode %d\n", gains->developer_mode);
|
||
user_anc_log("dac_gain %d\n", gains->dac_gain);
|
||
user_anc_log("l_ffmic_gain %d\n", gains->l_ffmic_gain);
|
||
user_anc_log("l_fbmic_gain %d\n", gains->l_fbmic_gain);
|
||
user_anc_log("r_ffmic_gain %d\n", gains->r_ffmic_gain);
|
||
user_anc_log("r_fbmic_gain %d\n", gains->r_fbmic_gain);
|
||
user_anc_log("cmp_en %d\n", gains->cmp_en);
|
||
user_anc_log("drc_en %d\n", gains->drc_en);
|
||
user_anc_log("ahs_en %d\n", gains->ahs_en);
|
||
user_anc_log("ff_1st_dcc %d\n", gains->ff_1st_dcc);
|
||
user_anc_log("fb_1st_dcc %d\n", gains->fb_1st_dcc);
|
||
user_anc_log("ff_2nd_dcc %d\n", gains->ff_2nd_dcc);
|
||
user_anc_log("fb_2nd_dcc %d\n", gains->fb_2nd_dcc);
|
||
user_anc_log("drc_ff_2dcc %d\n", gains->drc_ff_2dcc);
|
||
user_anc_log("drc_fb_2dcc %d\n", gains->drc_fb_2dcc);
|
||
user_anc_log("drc_dcc_det_time %d\n", gains->drc_dcc_det_time);
|
||
user_anc_log("drc_dcc_res_time %d\n", gains->drc_dcc_res_time);
|
||
|
||
user_anc_log("gain_sign 0X%x\n", gains->gain_sign);
|
||
user_anc_log("noise_lvl 0X%x\n", gains->noise_lvl);
|
||
user_anc_log("fade_step 0X%x\n", gains->fade_step);
|
||
user_anc_log("alogm %d\n", gains->alogm);
|
||
user_anc_log("trans_alogm %d\n", gains->trans_alogm);
|
||
|
||
user_anc_log("ancl_ffgain %d.%d\n", ((int)(gains->l_ffgain * 100.0)) / 100, ((int)(gains->l_ffgain * 100.0)) % 100);
|
||
user_anc_log("ancl_fbgain %d.%d\n", ((int)(gains->l_fbgain * 100.0)) / 100, ((int)(gains->l_fbgain * 100.0)) % 100);
|
||
user_anc_log("ancl_trans_gain %d.%d\n", ((int)(gains->l_transgain * 100.0)) / 100, ((int)(gains->l_transgain * 100.0)) % 100);
|
||
user_anc_log("ancl_cmpgain %d.%d\n", ((int)(gains->l_cmpgain * 100.0)) / 100, ((int)(gains->l_cmpgain * 100.0)) % 100);
|
||
user_anc_log("ancr_ffgain %d.%d\n", ((int)(gains->r_ffgain * 100.0)) / 100, ((int)(gains->r_ffgain * 100.0)) % 100);
|
||
user_anc_log("ancr_fbgain %d.%d\n", ((int)(gains->r_fbgain * 100.0)) / 100, ((int)(gains->r_fbgain * 100.0)) % 100);
|
||
user_anc_log("ancr_trans_gain %d.%d\n", ((int)(gains->r_transgain * 100.0)) / 100, ((int)(gains->r_transgain * 100.0)) % 100);
|
||
user_anc_log("ancr_cmpgain %d.%d\n", ((int)(gains->r_cmpgain * 100.0)) / 100, ((int)(gains->r_cmpgain * 100.0)) % 100);
|
||
|
||
user_anc_log("drcff_zero_det %d\n", gains->drcff_zero_det);
|
||
user_anc_log("drcff_dat_mode %d\n", gains->drcff_dat_mode);
|
||
user_anc_log("drcff_lpf_sel %d\n", gains->drcff_lpf_sel);
|
||
user_anc_log("drcfb_zero_det %d\n", gains->drcfb_zero_det);
|
||
user_anc_log("drcfb_dat_mode %d\n", gains->drcfb_dat_mode);
|
||
user_anc_log("drcfb_lpf_sel %d\n", gains->drcfb_lpf_sel);
|
||
|
||
user_anc_log("drcff_low_thr %d\n", gains->drcff_lthr);
|
||
user_anc_log("drcff_high_thr %d\n", gains->drcff_hthr);
|
||
user_anc_log("drcff_low_gain %d\n", gains->drcff_lgain);
|
||
user_anc_log("drcff_high_gain %d\n", gains->drcff_hgain);
|
||
user_anc_log("drcff_nor_gain %d\n", gains->drcff_norgain);
|
||
|
||
user_anc_log("drcfb_low_thr %d\n", gains->drcfb_lthr);
|
||
user_anc_log("drcfb_high_thr %d\n", gains->drcfb_hthr);
|
||
user_anc_log("drcfb_low_gain %d\n", gains->drcfb_lgain);
|
||
user_anc_log("drcfb_high_gain %d\n", gains->drcfb_hgain);
|
||
user_anc_log("drcfb_nor_gain %d\n", gains->drcfb_norgain);
|
||
|
||
user_anc_log("drctrans_low_thr %d\n", gains->drctrans_lthr);
|
||
user_anc_log("drctrans_high_thr %d\n", gains->drctrans_hthr);
|
||
user_anc_log("drctrans_low_gain %d\n", gains->drctrans_lgain);
|
||
user_anc_log("drctrans_high_gain %d\n", gains->drctrans_hgain);
|
||
user_anc_log("drctrans_nor_gain %d\n", gains->drctrans_norgain);
|
||
|
||
user_anc_log("ahs_dly %d\n", gains->ahs_dly);
|
||
user_anc_log("ahs_tap %d\n", gains->ahs_tap);
|
||
user_anc_log("ahs_wn_shift %d\n", gains->ahs_wn_shift);
|
||
user_anc_log("ahs_wn_sub %d\n", gains->ahs_wn_sub);
|
||
user_anc_log("ahs_shift %d\n", gains->ahs_shift);
|
||
user_anc_log("ahs_u %d\n", gains->ahs_u);
|
||
user_anc_log("ahs_gain %d\n", gains->ahs_gain);
|
||
user_anc_log("ahs_nlms_sel %d\n", gains->ahs_nlms_sel);
|
||
|
||
user_anc_log("audio_drc_thr %d/10\n", (int)(gains->audio_drc_thr * 10.0));
|
||
|
||
user_anc_log("adaptive_ref_en %d\n", gains->adaptive_ref_en);
|
||
user_anc_log("adaptive_ref_fb_f %d/10\n", (int)(gains->adaptive_ref_fb_f * 10.0));
|
||
user_anc_log("adaptive_ref_fb_g %d/10\n", (int)(gains->adaptive_ref_fb_g * 10.0));
|
||
user_anc_log("adaptive_ref_fb_q %d/10\n", (int)(gains->adaptive_ref_fb_q * 10.0));
|
||
|
||
}
|
||
|
||
/*ANC配置参数填充*/
|
||
void anc_param_fill(u8 cmd, anc_gain_t *cfg)
|
||
{
|
||
if (cmd == ANC_CFG_READ) {
|
||
anc_gain_t *db_gain = (anc_gain_t *)anc_db_get(ANC_DB_GAIN, &anc_hdl->param.gains_size);
|
||
cfg->gains = db_gain->gains; //直接读flash区域
|
||
/* cfg->gains = anc_hdl->param.gains; */
|
||
} else if (cmd == ANC_CFG_WRITE) {
|
||
anc_hdl->param.gains = cfg->gains;
|
||
anc_hdl->param.gains.hd_en = 0;
|
||
anc_hdl->param.gains.hd_corr_thr = 225;
|
||
anc_hdl->param.gains.hd_corr_dly = 13;
|
||
anc_hdl->param.gains.hd_corr_gain = 256;
|
||
anc_hdl->param.gains.hd_pwr_rate = 2;
|
||
anc_hdl->param.gains.hd_pwr_ctl_gain_en = 0;
|
||
anc_hdl->param.gains.hd_pwr_ctl_ahsrst_en = 0;
|
||
anc_hdl->param.gains.hd_pwr_thr = 500;
|
||
anc_hdl->param.gains.hd_pwr_ctl_gain = 1638;
|
||
|
||
anc_hdl->param.gains.hd_pwr_ref_ctl_en = 0;
|
||
anc_hdl->param.gains.hd_pwr_ref_ctl_hthr = 2000;
|
||
anc_hdl->param.gains.hd_pwr_ref_ctl_lthr1 = 1000;
|
||
anc_hdl->param.gains.hd_pwr_ref_ctl_lthr2 = 200;
|
||
|
||
anc_hdl->param.gains.hd_pwr_err_ctl_en = 0;
|
||
anc_hdl->param.gains.hd_pwr_err_ctl_hthr = 2000;
|
||
anc_hdl->param.gains.hd_pwr_err_ctl_lthr1 = 1000;
|
||
anc_hdl->param.gains.hd_pwr_err_ctl_lthr2 = 200;
|
||
|
||
anc_hdl->param.gains.developer_mode = anc_hdl->param.developer_mode;
|
||
|
||
audio_anc_param_normalize(&anc_hdl->param);
|
||
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
if (anc_hdl->param.gains.trans_alogm != anc_hdl->param.gains.alogm) {
|
||
user_anc_log("===========================\n\n");
|
||
// anc_hdl->param.gains.trans_alogm = anc_hdl->param.gains.alogm;
|
||
user_anc_log("err : anc_hdl->param.gains.trans_alogm != anc_hdl->param.gains.alogm !!!");
|
||
user_anc_log("\n\n===========================");
|
||
}
|
||
#endif
|
||
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
audio_anc_param_map(0, 1);
|
||
if (anc_hdl->param.anc_coeff_mode == ANC_COEFF_MODE_ADAPTIVE) {
|
||
audio_anc_ear_adaptive_param_init(&anc_hdl->param);
|
||
}
|
||
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
}
|
||
/* anc_param_gain_t_printf(cmd); */
|
||
}
|
||
|
||
//ANC配置文件读取并更新
|
||
int audio_anc_db_cfg_read(void)
|
||
{
|
||
/*读取ANC增益配置*/
|
||
anc_gain_t *db_gain = (anc_gain_t *)anc_db_get(ANC_DB_GAIN, &anc_hdl->param.gains_size);
|
||
if (db_gain) {
|
||
user_anc_log("anc_gain_db get succ,len:%d\n", anc_hdl->param.gains_size);
|
||
if (audio_anc_gains_version_verify(&anc_hdl->param, db_gain)) { //检查版本差异
|
||
user_anc_log("The anc gains version is older,0X%x\n", db_gain->gains.version);
|
||
db_gain = (anc_gain_t *)anc_db_get(ANC_DB_GAIN, &anc_hdl->param.gains_size);
|
||
}
|
||
anc_param_fill(ANC_CFG_WRITE, db_gain);
|
||
} else {
|
||
user_anc_log("anc_gain_db get failed");
|
||
/* anc_param_gain_t_printf(ANC_CFG_READ); */
|
||
return 1;
|
||
}
|
||
/*读取ANC滤波器系数*/
|
||
#if ANC_MULT_ORDER_ENABLE
|
||
return audio_anc_mult_coeff_file_read();
|
||
#endif/*ANC_MULT_ORDER_ENABLE*/
|
||
anc_coeff_t *db_coeff = (anc_coeff_t *)anc_db_get(ANC_DB_COEFF, &anc_hdl->param.coeff_size);
|
||
|
||
if (!anc_coeff_fill(db_coeff)) {
|
||
user_anc_log("anc_coeff_db get succ,len:%d", anc_hdl->param.coeff_size);
|
||
} else {
|
||
user_anc_log("anc_coeff_db get failed");
|
||
return 1;
|
||
#if 0 //测试数据写入是否正常,或写入自己想要的滤波器数据
|
||
extern anc_coeff_t *anc_cfg_test(audio_anc_t *param, u8 coeff_en, u8 gains_en);
|
||
anc_coeff_t *test_coeff = anc_cfg_test(&anc_hdl->param, 1, 1);
|
||
if (test_coeff) {
|
||
int ret = anc_db_put(&anc_hdl->param, NULL, test_coeff);
|
||
if (ret == 0) {
|
||
user_anc_log("anc_db put test succ\n");
|
||
} else {
|
||
user_anc_log("anc_db put test err\n");
|
||
}
|
||
}
|
||
anc_coeff_t *test_coeff1 = (anc_coeff_t *)anc_db_get(ANC_DB_COEFF, &anc_hdl->param.coeff_size);
|
||
anc_coeff_fill(test_coeff1);
|
||
#endif
|
||
}
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
audio_anc_param_map(1, 0);
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
return 0;
|
||
|
||
}
|
||
|
||
|
||
|
||
/*ANC初始化*/
|
||
void anc_init(void)
|
||
{
|
||
anc_hdl = zalloc(sizeof(anc_t));
|
||
user_anc_log("anc_hdl size:%lu\n", sizeof(anc_t));
|
||
ASSERT(anc_hdl);
|
||
audio_anc_param_init(&anc_hdl->param);
|
||
anc_debug_init(&anc_hdl->param);
|
||
audio_anc_fade_ctr_init();
|
||
#if TCFG_ANC_TOOL_DEBUG_ONLINE
|
||
app_online_db_register_handle(DB_PKT_TYPE_ANC, anc_app_online_parse);
|
||
#endif/*TCFG_ANC_TOOL_DEBUG_ONLINE*/
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
anc_hdl->param.adt = zalloc(sizeof(anc_adt_param_t));
|
||
ASSERT(anc_hdl->param.adt);
|
||
#endif /*TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN*/
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
anc_hdl->param.adaptive = zalloc(sizeof(anc_ear_adaptive_param_t));
|
||
ASSERT(anc_hdl->param.adaptive);
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
|
||
#if ANC_MULT_ORDER_ENABLE
|
||
anc_mult_init(&anc_hdl->param);
|
||
anc_hdl->scene_id = ANC_MULT_ORDER_NORMAL_ID; //默认使用场景1滤波器
|
||
anc_hdl->param.mult_gain_set = audio_anc_mult_gains_id_set;
|
||
#endif/*ANC_MULT_ORDER_ENABLE*/
|
||
|
||
anc_hdl->param.post_msg_drc = audio_anc_post_msg_drc;
|
||
anc_hdl->param.post_msg_debug = audio_anc_post_msg_debug;
|
||
anc_hdl->mode_enable = ANC_MODE_ENABLE;
|
||
anc_mode_enable_set(anc_hdl->mode_enable);
|
||
anc_hdl->param.cfg_online_deal_cb = anc_cfg_online_deal;
|
||
anc_hdl->param.adc_set_buffs_cb = esco_adc_mic_set_buffs;
|
||
audio_anc_adc_ch_set();
|
||
anc_hdl->param.mode = ANC_OFF;
|
||
anc_hdl->new_mode = anc_hdl->param.mode;
|
||
anc_hdl->param.production_mode = 0;
|
||
anc_hdl->param.developer_mode = ANC_DEVELOPER_MODE_EN;
|
||
anc_hdl->param.anc_fade_en = ANC_FADE_EN;/*ANC淡入淡出,默认开*/
|
||
anc_hdl->param.anc_fade_gain = 16384;/*ANC淡入淡出增益,16384 (0dB) max:32767*/
|
||
anc_hdl->param.tool_enablebit = ANC_TRAIN_MODE;
|
||
anc_hdl->param.online_busy = 0; //在线调试繁忙标志位
|
||
//36
|
||
anc_hdl->param.dut_audio_enablebit = ANC_DUT_CLOSE;
|
||
anc_hdl->param.fade_time_lvl = ANC_MODE_FADE_LVL;
|
||
anc_hdl->param.enablebit = ANC_TRAIN_MODE;
|
||
anc_hdl->param.adaptive_mode = ANC_ADAPTIVE_MODE;
|
||
anc_hdl->param.ch = ANC_CH;
|
||
anc_hdl->param.mic_type[0] = ANCL_FF_MIC;
|
||
anc_hdl->param.mic_type[1] = ANCL_FB_MIC;
|
||
anc_hdl->param.mic_type[2] = ANCR_FF_MIC;
|
||
anc_hdl->param.mic_type[3] = ANCR_FB_MIC;
|
||
|
||
anc_hdl->param.lff_en = ANC_CONFIG_LFF_EN;
|
||
anc_hdl->param.lfb_en = ANC_CONFIG_LFB_EN;
|
||
anc_hdl->param.rff_en = ANC_CONFIG_RFF_EN;
|
||
anc_hdl->param.rfb_en = ANC_CONFIG_RFB_EN;
|
||
anc_hdl->param.trans_default_coeff = (double *)trans_coeff_test; //推荐通透滤波器
|
||
anc_hdl->param.debug_sel = 0;
|
||
anc_hdl->param.gains.version = ANC_GAINS_VERSION;
|
||
anc_hdl->param.gains.dac_gain = 3;
|
||
anc_hdl->param.gains.l_ffmic_gain = 4;
|
||
anc_hdl->param.gains.l_fbmic_gain = 4;
|
||
anc_hdl->param.gains.r_ffmic_gain = 4;
|
||
anc_hdl->param.gains.r_fbmic_gain = 4;
|
||
anc_hdl->param.gains.cmp_en = 1;
|
||
anc_hdl->param.gains.drc_en = 0;
|
||
anc_hdl->param.gains.ahs_en = 0;
|
||
anc_hdl->param.gains.ff_1st_dcc = 8;
|
||
anc_hdl->param.gains.ff_2nd_dcc = 4;
|
||
anc_hdl->param.gains.fb_1st_dcc = 8;
|
||
anc_hdl->param.gains.fb_2nd_dcc = 1;
|
||
anc_hdl->param.gains.gain_sign = 0;
|
||
anc_hdl->param.gains.alogm = ANC_ALOGM6;
|
||
anc_hdl->param.gains.trans_alogm = ANC_ALOGM4;
|
||
anc_hdl->param.gains.l_ffgain = 1.0f;
|
||
anc_hdl->param.gains.l_fbgain = 1.0f;
|
||
anc_hdl->param.gains.l_cmpgain = 1.0f;
|
||
anc_hdl->param.gains.l_transgain = 1.0f;
|
||
anc_hdl->param.gains.r_ffgain = 1.0f;
|
||
anc_hdl->param.gains.r_fbgain = 1.0f;
|
||
anc_hdl->param.gains.r_cmpgain = 1.0f;
|
||
anc_hdl->param.gains.r_transgain = 1.0f;
|
||
|
||
anc_hdl->param.gains.drcff_zero_det = 0;
|
||
anc_hdl->param.gains.drcff_dat_mode = 0;//hbit control l_gain, lbit control h_gain
|
||
anc_hdl->param.gains.drcff_lpf_sel = 0;
|
||
anc_hdl->param.gains.drcfb_zero_det = 0;
|
||
anc_hdl->param.gains.drcfb_dat_mode = 0;//hbit control l_gain, lbit control h_gain
|
||
anc_hdl->param.gains.drcfb_lpf_sel = 0;
|
||
|
||
anc_hdl->param.gains.drcff_lthr = 0;
|
||
anc_hdl->param.gains.drcff_hthr = 6000 ;
|
||
anc_hdl->param.gains.drcff_lgain = 0;
|
||
anc_hdl->param.gains.drcff_hgain = 512;
|
||
anc_hdl->param.gains.drcff_norgain = 1024 ;
|
||
|
||
anc_hdl->param.gains.drctrans_lthr = 0;
|
||
anc_hdl->param.gains.drctrans_hthr = 32767 ;
|
||
anc_hdl->param.gains.drctrans_lgain = 0;
|
||
anc_hdl->param.gains.drctrans_hgain = 1024;
|
||
anc_hdl->param.gains.drctrans_norgain = 1024 ;
|
||
|
||
anc_hdl->param.gains.drcfb_lthr = 0;
|
||
anc_hdl->param.gains.drcfb_hthr = 6000;
|
||
anc_hdl->param.gains.drcfb_lgain = 0;
|
||
anc_hdl->param.gains.drcfb_hgain = 512;
|
||
anc_hdl->param.gains.drcfb_norgain = 1024;
|
||
|
||
anc_hdl->param.gains.ahs_dly = 1;
|
||
anc_hdl->param.gains.ahs_tap = 100;
|
||
anc_hdl->param.gains.ahs_wn_shift = 9;
|
||
anc_hdl->param.gains.ahs_wn_sub = 1;
|
||
anc_hdl->param.gains.ahs_shift = 210;
|
||
anc_hdl->param.gains.ahs_u = 4000;
|
||
anc_hdl->param.gains.ahs_gain = -1024;
|
||
anc_hdl->param.gains.audio_drc_thr = -6.0f;
|
||
|
||
anc_hdl->param.gains.ahs_nlms_sel = 0;
|
||
|
||
anc_hdl->param.gains.drc_ff_2dcc = 0;
|
||
anc_hdl->param.gains.drc_fb_2dcc = 0;
|
||
anc_hdl->param.gains.drc_dcc_det_time = 300;
|
||
anc_hdl->param.gains.drc_dcc_res_time = 20;
|
||
anc_hdl->param.gains.hd_en = 0;
|
||
anc_hdl->param.gains.hd_corr_thr = 232;
|
||
anc_hdl->param.gains.hd_corr_gain = 256;
|
||
anc_hdl->param.gains.hd_corr_dly = 13;
|
||
anc_hdl->param.gains.hd_pwr_rate = 2;
|
||
anc_hdl->param.gains.hd_pwr_ctl_gain_en = 0;
|
||
anc_hdl->param.gains.hd_pwr_ctl_ahsrst_en = 0;
|
||
anc_hdl->param.gains.hd_pwr_thr = 18000;
|
||
anc_hdl->param.gains.hd_pwr_ctl_gain = 1638;
|
||
|
||
anc_hdl->param.gains.hd_pwr_ref_ctl_en = 0;
|
||
anc_hdl->param.gains.hd_pwr_ref_ctl_hthr = 2000;
|
||
anc_hdl->param.gains.hd_pwr_ref_ctl_lthr1 = 1000;
|
||
anc_hdl->param.gains.hd_pwr_ref_ctl_lthr2 = 200;
|
||
|
||
anc_hdl->param.gains.hd_pwr_err_ctl_en = 0;
|
||
anc_hdl->param.gains.hd_pwr_err_ctl_hthr = 2000;
|
||
anc_hdl->param.gains.hd_pwr_err_ctl_lthr1 = 1000;
|
||
anc_hdl->param.gains.hd_pwr_err_ctl_lthr2 = 200;
|
||
|
||
anc_hdl->param.gains.adaptive_ref_en = 0;
|
||
anc_hdl->param.gains.adaptive_ref_fb_f = 120.0;
|
||
anc_hdl->param.gains.adaptive_ref_fb_g = 15.0;
|
||
anc_hdl->param.gains.adaptive_ref_fb_q = 0.4;
|
||
|
||
#if ANC_COEFF_SAVE_ENABLE
|
||
//1.先读取ANC默认参数
|
||
anc_db_init();
|
||
audio_anc_db_cfg_read(); //读取anc_gains.bin anc_coeff.bin,更新ANC参数
|
||
#endif/*ANC_COEFF_SAVE_ENABLE*/
|
||
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
anc_hdl->param.adt->dma_done_cb = icsd_adt_dma_done;
|
||
anc_hdl->param.ltrans_fbgain = anc_trans_lfb_gain;
|
||
anc_hdl->param.rtrans_fbgain = anc_trans_rfb_gain;
|
||
anc_hdl->param.ltrans_fb_coeff = anc_trans_lfb_coeff;
|
||
anc_hdl->param.rtrans_fb_coeff = anc_trans_rfb_coeff;
|
||
|
||
anc_hdl->param.ltrans_fb_yorder = sizeof(anc_trans_lfb_coeff) / 40;
|
||
anc_hdl->param.rtrans_fb_yorder = sizeof(anc_trans_rfb_coeff) / 40;
|
||
#endif /*TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN*/
|
||
|
||
anc_hdl->param.biquad2ab = icsd_biquad2ab_out;
|
||
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
//2.再读取ANC自适应参数, 若存在则覆盖默认参数
|
||
anc_hdl->param.adaptive->ff_yorder = ANC_ADAPTIVE_FF_ORDER;
|
||
anc_hdl->param.adaptive->fb_yorder = ANC_ADAPTIVE_FB_ORDER;
|
||
anc_hdl->param.adaptive->cmp_yorder = ANC_ADAPTIVE_CMP_ORDER;
|
||
anc_hdl->param.adaptive->dma_done_cb = icsd_anc_dma_done;
|
||
audio_anc_adaptive_data_read(&anc_hdl->adaptive_iir);
|
||
#if ANC_EAR_RECORD_EN
|
||
icsd_anc_vmdata_init(anc_hdl->adaptive_iir.record_FL, anc_hdl->adaptive_iir.record_FR, &anc_hdl->adaptive_iir.record_num);
|
||
#endif/*ANC_EAR_RECORD_EN*/
|
||
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
|
||
/* sys_timer_add(NULL, anc_timer_deal, 5000); */
|
||
|
||
#if ANC_ADAPTIVE_EN
|
||
anc_pow_adap_init(&anc_hdl->param, &anc_adap_param, &anc_adap_param, \
|
||
sizeof(anc_adap_param) / sizeof(anc_adap_param_t), \
|
||
sizeof(anc_adap_param) / sizeof(anc_adap_param_t));
|
||
|
||
anc_hdl->param.pow_adap_fade = audio_anc_pow_adap_fade;
|
||
#endif/*ANC_ADAPTIVE_EN*/
|
||
|
||
|
||
#if TCFG_ANC_SELF_DUT_GET_SZ
|
||
anc_hdl->param.sz_fft.dma_run_hdl = audio_anc_post_msg_sz_fft_run;
|
||
#endif/*TCFG_ANC_SELF_DUT_GET_SZ*/
|
||
|
||
audio_anc_mic_management(&anc_hdl->param);
|
||
anc_mix_out_audio_drc_thr(anc_hdl->param.gains.audio_drc_thr);
|
||
task_create(anc_task, NULL, "anc");
|
||
anc_hdl->state = ANC_STA_INIT;
|
||
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
anc_adt_init();
|
||
#endif /*TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN*/
|
||
user_anc_log("anc_init ok");
|
||
}
|
||
|
||
void anc_train_open(u8 mode, u8 debug_sel)
|
||
{
|
||
user_anc_log("ANC_Train_Open\n");
|
||
local_irq_disable();
|
||
if (anc_hdl && (anc_hdl->state == ANC_STA_INIT)) {
|
||
/*防止重复打开训练模式*/
|
||
if (anc_hdl->param.mode == ANC_TRAIN) {
|
||
local_irq_enable();
|
||
return;
|
||
}
|
||
/*anc工作,退出sniff*/
|
||
user_send_cmd_prepare(USER_CTRL_ALL_SNIFF_EXIT, 0, NULL);
|
||
/*anc工作,关闭自动关机*/
|
||
/* sys_auto_shut_down_disable(); */
|
||
|
||
anc_hdl->param.debug_sel = debug_sel;
|
||
anc_hdl->param.mode = mode;
|
||
anc_hdl->new_mode = anc_hdl->param.mode;
|
||
anc_hdl->param.test_type = ANC_TEST_TYPE_PCM;
|
||
/*训练的时候,申请buf用来保存训练参数*/
|
||
local_irq_enable();
|
||
os_taskq_post_msg("anc", 1, ANC_MSG_TRAIN_OPEN);
|
||
user_anc_log("%s ok\n", __FUNCTION__);
|
||
return;
|
||
}
|
||
local_irq_enable();
|
||
}
|
||
|
||
void anc_train_close(void)
|
||
{
|
||
int ret = 0;
|
||
if (anc_hdl == NULL) {
|
||
return;
|
||
}
|
||
if (anc_hdl && (anc_hdl->param.mode == ANC_TRAIN)) {
|
||
anc_hdl->param.train_para.train_busy = 0;
|
||
anc_hdl->param.mode = ANC_OFF;
|
||
anc_hdl->new_mode = anc_hdl->param.mode;
|
||
anc_hdl->state = ANC_STA_INIT;
|
||
audio_anc_train(&anc_hdl->param, 0);
|
||
user_anc_log("anc_train_close ok\n");
|
||
}
|
||
}
|
||
|
||
/*查询当前ANC是否处于训练状态*/
|
||
int anc_train_open_query(void)
|
||
{
|
||
if (anc_hdl) {
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
if (anc_hdl->ear_adaptive_busy) {
|
||
return 1;
|
||
}
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
if (anc_hdl->param.mode == ANC_TRAIN) {
|
||
return 1;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
extern void audio_dump();
|
||
static void anc_timer_deal(void *priv)
|
||
{
|
||
u8 dac_again_l = JL_ADDA->DAA_CON1 & 0xF;
|
||
u8 dac_again_r = (JL_ADDA->DAA_CON1 >> 4) & 0xF;
|
||
u32 dac_dgain_l = JL_AUDIO->DAC_VL0 & 0xFFFF;
|
||
u32 dac_dgain_r = (JL_AUDIO->DAC_VL0 >> 16) & 0xFFFF;
|
||
u8 mic0_gain = (JL_ADDA->ADA_CON8) & 0x1F;
|
||
u8 mic1_gain = (JL_ADDA->ADA_CON8 >> 5) & 0x1F;
|
||
u8 mic2_gain = (JL_ADDA->ADA_CON8 >> 10) & 0x1F;
|
||
u8 mic3_gain = (JL_ADDA->ADA_CON8 >> 15) & 0x1F;
|
||
|
||
user_anc_log("MIC_G:%d,%d,%d,%d,DAC_AG:%d,%d,DAC_DG:%d,%d\n", mic0_gain, mic1_gain, mic2_gain, mic3_gain, dac_again_l, dac_again_r, dac_dgain_l, dac_dgain_r);
|
||
/* mem_stats(); */
|
||
#if TCFG_USER_TWS_ENABLE
|
||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||
printf("%c, master\n", bt_tws_get_local_channel());
|
||
} else {
|
||
printf("%c, slave\n", bt_tws_get_local_channel());
|
||
}
|
||
#endif/*TCFG_USER_TWS_ENABLE*/
|
||
/* audio_dump(); */
|
||
}
|
||
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
static void anc_tone_play_pre(u8 next_mode)
|
||
{
|
||
user_anc_log("anc_tone_play_pre:%d %d %d\n", anc_hdl->new_mode, next_mode, anc_hdl->ear_adaptive);
|
||
/* if (anc_hdl->new_mode == next_mode) { */
|
||
if (next_mode == ANC_ON && anc_hdl->ear_adaptive) {
|
||
icsd_anc_tone_play_start();
|
||
}
|
||
/* } */
|
||
}
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
|
||
static void anc_tone_play_cb(void *priv, int break_flag)
|
||
{
|
||
u8 next_mode = (u8)priv;
|
||
user_anc_log("anc_tone_play_cb,anc_mode:%d,%d,new_mode:%d, break %d\n", next_mode, anc_hdl->param.mode, anc_hdl->new_mode, break_flag);
|
||
/*
|
||
*当最新的目标ANC模式和即将切过去的模式一致,才进行模式切换实现。
|
||
*否则表示,模式切换操作(比如快速按键切模式)new_mode领先于ANC模式切换实现next_mode
|
||
*则直接在切模式的时候,实现最新的目标模式
|
||
*/
|
||
if (anc_hdl->new_mode == next_mode) {
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
if (next_mode == ANC_ON && anc_hdl->ear_adaptive) {
|
||
anc_hdl->ear_adaptive = 0;
|
||
if (break_flag) { // 提示音被打断,自适应强制停止
|
||
icsd_anc_forced_exit();
|
||
}
|
||
anc_user_train_tone_play_cb();
|
||
} else
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
{
|
||
anc_mode_switch_deal(next_mode);
|
||
}
|
||
} else {
|
||
anc_hdl->mode_switch_lock = 0;
|
||
}
|
||
}
|
||
|
||
/*
|
||
*********************************************************************
|
||
* Audio ANC Tone Play And Mode Switch
|
||
* Description: ANC提示音播放和模式切换
|
||
* Arguments : index 提示音索引
|
||
* preemption 提示音抢断播放标识
|
||
* cb_sel 切模式方式选择
|
||
* Return : None.
|
||
* Note(s) : 通过cb_sel选择是在播放提示音切模式,还是播提示音同时切
|
||
* 模式
|
||
*********************************************************************
|
||
*/
|
||
static void anc_tone_play_and_mode_switch(u8 index, u8 preemption, u8 cb_sel)
|
||
{
|
||
if (!bt_media_is_running() && !bt_phone_dec_is_running()) { //后台没有音频,提示音默认打断播放
|
||
preemption = 1;
|
||
}
|
||
if (cb_sel) {
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
if (anc_hdl->ear_adaptive) { //非ANC模式下切自适应,需要提前开MIC,ADC需要稳定时间
|
||
audio_mic_pwr_ctl(MIC_PWR_ON);
|
||
audio_anc_dac_open(anc_hdl->param.gains.dac_gain, anc_hdl->param.gains.dac_gain);
|
||
anc_hdl->param.adc_set_buffs_cb();
|
||
audio_anc_mic_open(anc_hdl->param.mic_param, 0, anc_hdl->param.adc_ch);
|
||
index = (index == IDEX_TONE_ANC_ON) ? IDEX_TONE_ANC_ADAPTIVE : index;
|
||
}
|
||
#if ANC_USER_TRAIN_TONE_MODE
|
||
anc_tone_play_pre(anc_hdl->param.mode); //播放提示音时,先进行自适应训练
|
||
#endif/*ANC_USER_TRAIN_TONE_MODE*/
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
tone_play_index_with_callback(index, preemption, (void(*)(void *))anc_tone_play_cb, (void *)anc_hdl->param.mode);
|
||
/*ANC打开情况下,播提示音的同时,anc效果淡出*/
|
||
if (anc_hdl->state == ANC_STA_OPEN) {
|
||
audio_anc_fade_ctr_set(ANC_FADE_MODE_SWITCH, AUDIO_ANC_FDAE_CH_ALL, 0);
|
||
}
|
||
} else {
|
||
tone_play_index(index, preemption);
|
||
anc_mode_switch_deal(anc_hdl->param.mode);
|
||
}
|
||
}
|
||
|
||
static void anc_tone_stop(void)
|
||
{
|
||
if (anc_hdl && anc_hdl->mode_switch_lock) {
|
||
tone_play_stop();
|
||
}
|
||
}
|
||
|
||
/*
|
||
*********************************************************************
|
||
* anc_fade_in_timer
|
||
* Description: ANC增益淡入函数
|
||
* Arguments : None.
|
||
* Return : None.
|
||
* Note(s) :通过定时器的控制,使ANC的淡入增益一点一点叠加
|
||
*********************************************************************
|
||
*/
|
||
static void anc_fade_in_timer(void *arg)
|
||
{
|
||
anc_hdl->fade_gain += (anc_hdl->param.anc_fade_gain / anc_hdl->param.fade_time_lvl);
|
||
if (anc_hdl->fade_gain > anc_hdl->param.anc_fade_gain) {
|
||
anc_hdl->fade_gain = anc_hdl->param.anc_fade_gain;
|
||
usr_timer_del(anc_hdl->fade_in_timer);
|
||
}
|
||
audio_anc_fade_ctr_set(ANC_FADE_MODE_SWITCH, AUDIO_ANC_FDAE_CH_ALL, anc_hdl->fade_gain);
|
||
}
|
||
|
||
static void anc_fade_in_timer_add(audio_anc_t *param)
|
||
{
|
||
u32 alogm, dly;
|
||
if (param->anc_fade_en) {
|
||
alogm = (param->mode == ANC_TRANSPARENCY) ? param->gains.trans_alogm : param->gains.alogm;
|
||
dly = audio_anc_fade_dly_get(param->anc_fade_gain, alogm);
|
||
anc_hdl->fade_gain = 0;
|
||
if (param->mode == ANC_ON) { //可自定义模式,当前仅在ANC模式下使用
|
||
user_anc_log("anc_fade_time_lvl %d\n", param->fade_time_lvl);
|
||
anc_hdl->fade_gain = (param->anc_fade_gain / param->fade_time_lvl);
|
||
audio_anc_fade_ctr_set(ANC_FADE_MODE_SWITCH, AUDIO_ANC_FDAE_CH_ALL, anc_hdl->fade_gain);
|
||
if (param->fade_time_lvl > 1) {
|
||
anc_hdl->fade_in_timer = usr_timer_add((void *)0, anc_fade_in_timer, dly, 1);
|
||
}
|
||
} else if (param->mode != ANC_OFF) {
|
||
audio_anc_fade_ctr_set(ANC_FADE_MODE_SWITCH, AUDIO_ANC_FDAE_CH_ALL, param->anc_fade_gain);
|
||
}
|
||
}
|
||
}
|
||
static void anc_fade_out_timeout(void *arg)
|
||
{
|
||
os_taskq_post_msg("anc", 1, ANC_MSG_RUN);
|
||
}
|
||
|
||
static void anc_fade(u32 gain)
|
||
{
|
||
u32 alogm, dly;
|
||
if (anc_hdl) {
|
||
alogm = (anc_hdl->last_mode == ANC_TRANSPARENCY) ? anc_hdl->param.gains.trans_alogm : anc_hdl->param.gains.alogm;
|
||
dly = audio_anc_fade_dly_get(anc_hdl->param.anc_fade_gain, alogm);
|
||
user_anc_log("anc_fade:%d,dly:%d", gain, dly);
|
||
audio_anc_fade_ctr_set(ANC_FADE_MODE_SWITCH, AUDIO_ANC_FDAE_CH_ALL, gain);
|
||
if (anc_hdl->param.anc_fade_en) {
|
||
usr_timeout_del(anc_hdl->fade_in_timer);
|
||
usr_timeout_add((void *)0, anc_fade_out_timeout, dly, 1);
|
||
} else {/*不淡入淡出,则直接切模式*/
|
||
os_taskq_post_msg("anc", 1, ANC_MSG_RUN);
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
*mode:降噪/通透/关闭
|
||
*tone_play:切换模式的时候,是否播放提示音
|
||
*/
|
||
static void anc_mode_switch_deal(u8 mode)
|
||
{
|
||
#if TCFG_ANCLED_ENABLE
|
||
if ((mode == ANC_ON) || (mode == ANC_TRANSPARENCY)) {
|
||
gpio_set_pull_up(TCFG_ANCLED_PIN, 1);//头戴耳机ANC指示灯
|
||
gpio_set_pull_down(TCFG_ANCLED_PIN, 0);
|
||
gpio_set_direction(TCFG_ANCLED_PIN, 0);
|
||
gpio_set_output_value(TCFG_ANCLED_PIN, 1);
|
||
} else {
|
||
gpio_set_pull_up(TCFG_ANCLED_PIN, 0);
|
||
gpio_set_pull_down(TCFG_ANCLED_PIN, 0);
|
||
gpio_set_direction(TCFG_ANCLED_PIN, 1);
|
||
gpio_set_die(TCFG_ANCLED_PIN, 0);
|
||
}
|
||
#endif
|
||
user_anc_log("anc switch,state:%s", anc_state_str[anc_hdl->state]);
|
||
anc_hdl->mode_switch_lock = 1;
|
||
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
audio_anc_mode_switch_in_adt(anc_hdl->param.mode);
|
||
#endif
|
||
if (anc_hdl->state == ANC_STA_OPEN) {
|
||
user_anc_log("anc open now,switch mode:%d", mode);
|
||
anc_fade(0);//切模式,先fade_out
|
||
} else if (anc_hdl->state == ANC_STA_INIT) {
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
if ((anc_hdl->param.mode != ANC_OFF) || get_adt_open_in_anc_state()) {
|
||
#else
|
||
if (anc_hdl->param.mode != ANC_OFF) {
|
||
#endif/*TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN*/
|
||
/*anc工作,关闭自动关机*/
|
||
/* sys_auto_shut_down_disable(); */
|
||
os_taskq_post_msg("anc", 1, ANC_MSG_RUN);
|
||
} else {
|
||
user_anc_log("anc close now,new mode is ANC_OFF\n");
|
||
anc_hdl->mode_switch_lock = 0;
|
||
}
|
||
} else {
|
||
user_anc_log("anc state err:%d\n", anc_hdl->state);
|
||
anc_hdl->mode_switch_lock = 0;
|
||
}
|
||
}
|
||
|
||
void anc_gain_app_value_set(int app_value)
|
||
{
|
||
static int anc_gain_app_value = -1;
|
||
if (-1 == app_value && -1 != anc_gain_app_value) {
|
||
/* anc_hdl->param.anc_ff_gain = anc_gain_app_value; */
|
||
}
|
||
anc_gain_app_value = app_value;
|
||
}
|
||
|
||
static void anc_user_train_timeout(void *arg)
|
||
{
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
anc_user_train_tone_play_cb();
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
}
|
||
|
||
#define TWS_ANC_SYNC_TIMEOUT 600 //ms
|
||
void anc_mode_switch(u8 mode, u8 tone_play)
|
||
{
|
||
u8 ignore_same_mode = 0;
|
||
u8 tws_sync_en = 1;
|
||
if (anc_hdl == NULL) {
|
||
return;
|
||
}
|
||
/*模式切换超出范围*/
|
||
if ((mode > ANC_BYPASS) || (mode < ANC_OFF)) {
|
||
user_anc_log("anc mode switch err:%d", mode);
|
||
return;
|
||
}
|
||
|
||
/*模式切换同一个*/
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
if (anc_hdl->ear_adaptive) {
|
||
ignore_same_mode = 1;
|
||
if (!anc_hdl->ear_adaptive_tws_sync) {
|
||
tws_sync_en = 0; //自适应状态关闭左右平衡,则不需要同步切模式
|
||
}
|
||
}
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
/*判断adt是否在关闭过程中切anc*/
|
||
u8 adt_off_state = (audio_icsd_adt_is_running() && !get_icsd_adt_mode()) ? 1 : 0;
|
||
/*需要在切anc模式是开adt || adt关闭时切anc off*/
|
||
if ((get_adt_open_in_anc_state() && get_icsd_adt_mode()) || (adt_off_state && (mode == ANC_OFF))) {
|
||
ignore_same_mode = 1;
|
||
}
|
||
#endif/*TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN*/
|
||
if (anc_hdl->param.mode == mode && (!ignore_same_mode)) {
|
||
|
||
user_anc_log("anc mode switch err:same mode");
|
||
return;
|
||
}
|
||
#if ANC_MODE_EN_MODE_NEXT_SW
|
||
if (anc_hdl->mode_switch_lock) {
|
||
user_anc_log("anc mode switch lock\n");
|
||
return;
|
||
}
|
||
anc_hdl->mode_switch_lock = 1;
|
||
#endif/*ANC_MODE_EN_MODE_NEXT_SW*/
|
||
|
||
anc_hdl->new_mode = mode;/*记录最新的目标ANC模式*/
|
||
#if ANC_TONE_END_MODE_SW && (!ANC_MODE_EN_MODE_NEXT_SW)
|
||
anc_tone_stop();
|
||
#endif/*ANC_TONE_END_MODE_SW*/
|
||
anc_hdl->param.mode = mode;
|
||
|
||
if (anc_hdl->suspend) {
|
||
anc_hdl->param.tool_enablebit = 0;
|
||
}
|
||
|
||
/* anc_gain_app_value_set(-1); */ //没有处理好bypass与ANC_ON的关系
|
||
/*
|
||
*ANC模式提示音播放规则
|
||
*(1)根据应用选择是否播放提示音:tone_play
|
||
*(2)tws连接的时候,主机发起模式提示音同步播放
|
||
*(3)单机的时候,直接播放模式提示音
|
||
*/
|
||
if (tone_play) {
|
||
#if TCFG_USER_TWS_ENABLE
|
||
if (get_tws_sibling_connect_state() && tws_sync_en) {
|
||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||
user_anc_log("[tws_master]anc_tone_sync_play");
|
||
anc_hdl->sync_busy = 1;
|
||
if (anc_hdl->param.mode == ANC_ON) {
|
||
bt_tws_play_tone_at_same_time(SYNC_TONE_ANC_ON, TWS_ANC_SYNC_TIMEOUT);
|
||
} else if (anc_hdl->param.mode == ANC_OFF) {
|
||
bt_tws_play_tone_at_same_time(SYNC_TONE_ANC_OFF, TWS_ANC_SYNC_TIMEOUT);
|
||
} else {
|
||
bt_tws_play_tone_at_same_time(SYNC_TONE_ANC_TRANS, TWS_ANC_SYNC_TIMEOUT);
|
||
}
|
||
}
|
||
return;
|
||
} else {
|
||
user_anc_log("anc_tone_play");
|
||
anc_tone_play_and_mode_switch(anc_tone_tab[mode - 1], ANC_TONE_PREEMPTION, ANC_TONE_END_MODE_SW);
|
||
}
|
||
#else
|
||
anc_tone_play_and_mode_switch(anc_tone_tab[mode - 1], ANC_TONE_PREEMPTION, ANC_TONE_END_MODE_SW);
|
||
#endif/*TCFG_USER_TWS_ENABLE*/
|
||
} else {
|
||
#if ANC_EAR_ADAPTIVE_EN // 不播提示音进入自适应流程
|
||
if (mode == ANC_ON && anc_hdl->ear_adaptive) {
|
||
anc_hdl->ear_adaptive = 0;
|
||
if (anc_hdl->param.anc_fade_en) {
|
||
u32 dly = audio_anc_fade_dly_get(anc_hdl->param.anc_fade_gain, anc_hdl->param.gains.alogm);
|
||
audio_anc_fade_ctr_set(ANC_FADE_MODE_SWITCH, AUDIO_ANC_FDAE_CH_ALL, 0);
|
||
usr_timeout_add((void *)0, anc_user_train_timeout, dly, 1);
|
||
} else {
|
||
anc_user_train_timeout(NULL);
|
||
}
|
||
} else
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
{
|
||
anc_mode_switch_deal(mode);
|
||
}
|
||
/* anc_mode_switch_deal(mode); */
|
||
}
|
||
}
|
||
|
||
static void anc_ui_mode_sel_timer(void *priv)
|
||
{
|
||
if (anc_hdl->ui_mode_sel && (anc_hdl->ui_mode_sel != anc_hdl->param.mode)) {
|
||
/*
|
||
*提示音不打断
|
||
*tws提示音同步播放完成
|
||
*/
|
||
if ((tone_get_status() == 0) && (anc_hdl->sync_busy == 0)) {
|
||
user_anc_log("anc_ui_mode_sel_timer:%d,sync_busy:%d", anc_hdl->ui_mode_sel, anc_hdl->sync_busy);
|
||
anc_mode_switch(anc_hdl->ui_mode_sel, 1);
|
||
sys_timer_del(anc_hdl->ui_mode_sel_timer);
|
||
anc_hdl->ui_mode_sel_timer = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
/*ANC通过ui菜单选择anc模式,处理快速切换的情景*/
|
||
void anc_ui_mode_sel(u8 mode, u8 tone_play)
|
||
{
|
||
/*
|
||
*timer存在表示上个模式还没有完成切换
|
||
*提示音不打断
|
||
*tws提示音同步播放完成
|
||
*/
|
||
if ((anc_hdl->ui_mode_sel_timer == 0) && (tone_get_status() == 0) && (anc_hdl->sync_busy == 0)) {
|
||
user_anc_log("anc_ui_mode_sel[ok]:%d", mode);
|
||
anc_mode_switch(mode, tone_play);
|
||
} else {
|
||
user_anc_log("anc_ui_mode_sel[dly]:%d,timer:%d,sync_busy:%d", mode, anc_hdl->ui_mode_sel_timer, anc_hdl->sync_busy);
|
||
anc_hdl->ui_mode_sel = mode;
|
||
if (anc_hdl->ui_mode_sel_timer == 0) {
|
||
anc_hdl->ui_mode_sel_timer = sys_timer_add(NULL, anc_ui_mode_sel_timer, 50);
|
||
}
|
||
}
|
||
}
|
||
|
||
/*tws同步播放模式提示音,并且同步进入anc模式*/
|
||
void anc_tone_sync_play(int tone_name)
|
||
{
|
||
#if TCFG_USER_TWS_ENABLE
|
||
if (anc_hdl) {
|
||
user_anc_log("anc_tone_sync_play:%d", tone_name);
|
||
os_taskq_post_msg("anc", 2, ANC_MSG_TONE_SYNC, tone_name);
|
||
}
|
||
#endif/*TCFG_USER_TWS_ENABLE*/
|
||
}
|
||
|
||
/*ANC模式同步(tws模式)*/
|
||
void anc_mode_sync(u8 *data)
|
||
{
|
||
//data[0] mode;
|
||
//data[1] adaptive_seq;
|
||
//data[2] scene_id;
|
||
if (anc_hdl) {
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
anc_hdl->ear_adaptive_seq = data[1];
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
|
||
#if ANC_MULT_ORDER_ENABLE
|
||
anc_hdl->scene_id = data[2];
|
||
#endif/*ANC_MULT_ORDER_ENABLE*/
|
||
os_taskq_post_msg("anc", 2, ANC_MSG_MODE_SYNC, data[0]);
|
||
}
|
||
}
|
||
|
||
/*在anc任务里面切换anc模式,避免上一次切换没有完成,这次切换被忽略的情况*/
|
||
void anc_mode_switch_in_anctask(u8 mode, u8 tone_play)
|
||
{
|
||
if (anc_hdl) {
|
||
os_taskq_post_msg("anc", 3, ANC_MSG_MODE_SWITCH_IN_ANCTASK, mode, tone_play);
|
||
}
|
||
}
|
||
|
||
/*ANC挂起*/
|
||
void anc_suspend(void)
|
||
{
|
||
if (anc_hdl) {
|
||
user_anc_log("anc_suspend\n");
|
||
anc_hdl->suspend = 1;
|
||
anc_hdl->param.tool_enablebit = 0; //使能设置为0
|
||
if (anc_hdl->param.anc_fade_en) { //挂起ANC增益淡出
|
||
audio_anc_fade_ctr_set(ANC_FADE_MODE_SUSPEND, AUDIO_ANC_FDAE_CH_ALL, 0);
|
||
}
|
||
audio_anc_en_set(0);
|
||
}
|
||
}
|
||
|
||
/*ANC恢复*/
|
||
void anc_resume(void)
|
||
{
|
||
if (anc_hdl) {
|
||
user_anc_log("anc_resume\n");
|
||
anc_hdl->suspend = 0;
|
||
anc_hdl->param.tool_enablebit = anc_hdl->param.enablebit; //使能恢复
|
||
audio_anc_en_set(1);
|
||
if (anc_hdl->param.anc_fade_en) { //恢复ANC增益淡入
|
||
//避免param.anc_fade_gain 被修改,这里使用固定值
|
||
audio_anc_fade_ctr_set(ANC_FADE_MODE_SUSPEND, AUDIO_ANC_FDAE_CH_ALL, ANC_FADE_GAIN_DEFAULT);
|
||
}
|
||
}
|
||
}
|
||
|
||
/*ANC信息保存*/
|
||
void anc_info_save()
|
||
{
|
||
if (anc_hdl) {
|
||
anc_info_t anc_info;
|
||
int ret = syscfg_read(CFG_ANC_INFO, &anc_info, sizeof(anc_info));
|
||
if (ret == sizeof(anc_info)) {
|
||
#if INEAR_ANC_UI
|
||
if (anc_info.mode == anc_hdl->param.mode && anc_info.inear_tws_mode == inear_tws_ancmode) {
|
||
#else
|
||
if (anc_info.mode == anc_hdl->param.mode) {
|
||
#endif/*INEAR_ANC_UI*/
|
||
user_anc_log("anc info.mode == cur_anc_mode");
|
||
return;
|
||
}
|
||
} else {
|
||
user_anc_log("read anc_info err");
|
||
}
|
||
|
||
user_anc_log("save anc_info");
|
||
anc_info.mode = anc_hdl->param.mode;
|
||
#if INEAR_ANC_UI
|
||
anc_info.inear_tws_mode = inear_tws_ancmode;
|
||
#endif/*INEAR_ANC_UI*/
|
||
ret = syscfg_write(CFG_ANC_INFO, &anc_info, sizeof(anc_info));
|
||
if (ret != sizeof(anc_info)) {
|
||
user_anc_log("anc info save err!\n");
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
/*系统上电的时候,根据配置决定是否进入上次的模式*/
|
||
void anc_poweron(void)
|
||
{
|
||
if (anc_hdl) {
|
||
#if ANC_INFO_SAVE_ENABLE
|
||
anc_info_t anc_info;
|
||
int ret = syscfg_read(CFG_ANC_INFO, &anc_info, sizeof(anc_info));
|
||
if (ret == sizeof(anc_info)) {
|
||
user_anc_log("read anc_info succ,state:%s,mode:%s", anc_state_str[anc_hdl->state], anc_mode_str[anc_info.mode]);
|
||
#if INEAR_ANC_UI
|
||
inear_tws_ancmode = anc_info.inear_tws_mode;
|
||
#endif/*INEAR_ANC_UI*/
|
||
if ((anc_hdl->state == ANC_STA_INIT) && (anc_info.mode != ANC_OFF)) {
|
||
anc_mode_switch(anc_info.mode, 0);
|
||
}
|
||
} else {
|
||
user_anc_log("read anc_info err");
|
||
}
|
||
#endif/*ANC_INFO_SAVE_ENABLE*/
|
||
}
|
||
}
|
||
|
||
/*ANC poweroff*/
|
||
void anc_poweroff(void)
|
||
{
|
||
if (anc_hdl) {
|
||
#if ANC_POWEOFF_SAVE_ADAPTIVE_DATA && ANC_EAR_ADAPTIVE_EN && (!ANC_DEVELOPER_MODE_EN)
|
||
if (anc_hdl->ear_adaptive_data_from == ANC_ADAPTIVE_DATA_FROM_ALOGM) { //表示数据已经更新
|
||
audio_anc_adaptive_data_save(&anc_hdl->adaptive_iir);
|
||
}
|
||
#endif/*ANC_POWEOFF_SAVE_ADAPTIVE_DATA*/
|
||
user_anc_log("anc_cur_state:%s\n", anc_state_str[anc_hdl->state]);
|
||
#if ANC_INFO_SAVE_ENABLE
|
||
anc_info_save();
|
||
#endif/*ANC_INFO_SAVE_ENABLE*/
|
||
if (anc_hdl->state == ANC_STA_OPEN) {
|
||
user_anc_log("anc_poweroff\n");
|
||
/*close anc module when fade_out timeout*/
|
||
anc_hdl->param.mode = ANC_OFF;
|
||
anc_hdl->new_mode = anc_hdl->param.mode;
|
||
anc_fade(0);
|
||
}
|
||
}
|
||
}
|
||
|
||
/*模式切换测试demo*/
|
||
#define ANC_MODE_NUM 3 /*ANC模式循环切换*/
|
||
static const u8 anc_mode_switch_tab[ANC_MODE_NUM] = {
|
||
ANC_OFF,
|
||
ANC_TRANSPARENCY,
|
||
ANC_ON,
|
||
};
|
||
void anc_mode_next(void)
|
||
{
|
||
if (anc_hdl) {
|
||
if (anc_train_open_query()) {
|
||
return;
|
||
}
|
||
u8 next_mode = 0;
|
||
local_irq_disable();
|
||
anc_hdl->param.anc_fade_en = ANC_FADE_EN; //防止被其他地方清0
|
||
for (u8 i = 0; i < ANC_MODE_NUM; i++) {
|
||
if (anc_mode_switch_tab[i] == anc_hdl->param.mode) {
|
||
next_mode = i + 1;
|
||
if (next_mode >= ANC_MODE_NUM) {
|
||
next_mode = 0;
|
||
}
|
||
if ((anc_hdl->mode_enable & BIT(anc_mode_switch_tab[next_mode])) == 0) {
|
||
user_anc_log("anc_mode_filt,next:%d,en:%d", next_mode, anc_hdl->mode_enable);
|
||
next_mode++;
|
||
if (next_mode >= ANC_MODE_NUM) {
|
||
next_mode = 0;
|
||
}
|
||
}
|
||
//g_printf("fine out anc mode:%d,next:%d,i:%d",anc_hdl->param.mode,next_mode,i);
|
||
break;
|
||
}
|
||
}
|
||
local_irq_enable();
|
||
//user_anc_log("anc_next_mode:%d old:%d,new:%d", next_mode, anc_hdl->param.mode, anc_mode_switch_tab[next_mode]);
|
||
u8 new_mode = anc_mode_switch_tab[next_mode];
|
||
user_anc_log("new_mode:%s", anc_mode_str[new_mode]);
|
||
|
||
#if ANC_EAR_ADAPTIVE_EN && ANC_EAR_ADAPTIVE_EVERY_TIME //非通话状态下,每次切模式都自适应
|
||
if ((anc_mode_switch_tab[next_mode] == ANC_ON) && (bt_phone_dec_is_running() == 0)) {
|
||
anc_hdl->param.mode = ANC_ON;
|
||
anc_hdl->new_mode = anc_hdl->param.mode;
|
||
audio_anc_mode_ear_adaptive(1);
|
||
} else
|
||
#endif/*ANC_EAR_ADAPTIVE_EVERY_TIME*/
|
||
{
|
||
anc_mode_switch(anc_mode_switch_tab[next_mode], 1);
|
||
}
|
||
}
|
||
}
|
||
|
||
/*设置ANC支持切换的模式*/
|
||
void anc_mode_enable_set(u8 mode_enable)
|
||
{
|
||
if (anc_hdl) {
|
||
anc_hdl->mode_enable = mode_enable;
|
||
u8 mode_cnt = 0;
|
||
for (u8 i = 1; i < 4; i++) {
|
||
if (mode_enable & BIT(i)) {
|
||
mode_cnt++;
|
||
user_anc_log("%s Select", anc_mode_str[i]);
|
||
}
|
||
}
|
||
user_anc_log("anc_mode_enable_set:%d", mode_cnt);
|
||
anc_hdl->mode_num = mode_cnt;
|
||
}
|
||
}
|
||
|
||
/*获取anc状态,0:空闲,l:忙*/
|
||
u8 anc_status_get(void)
|
||
{
|
||
u8 status = 0;
|
||
if (anc_hdl) {
|
||
if (anc_hdl->state == ANC_STA_OPEN) {
|
||
status = 1;
|
||
}
|
||
}
|
||
return status;
|
||
}
|
||
|
||
/*获取anc当前模式*/
|
||
u8 anc_mode_get(void)
|
||
{
|
||
if (anc_hdl) {
|
||
//user_anc_log("anc_mode_get:%s", anc_mode_str[anc_hdl->param.mode]);
|
||
return anc_hdl->param.mode;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/*获取anc记录的最新的目标ANC模式*/
|
||
u8 anc_new_target_mode_get(void)
|
||
{
|
||
if (anc_hdl) {
|
||
//user_anc_log("anc_mode_get:%s", anc_mode_str[anc_hdl->new_mode]);
|
||
return anc_hdl->new_mode;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/*获取anc模式,dac左右声道的增益*/
|
||
u8 anc_dac_gain_get(u8 ch)
|
||
{
|
||
u8 gain = 0;
|
||
if (anc_hdl) {
|
||
gain = anc_hdl->param.gains.dac_gain;
|
||
}
|
||
return gain;
|
||
}
|
||
|
||
/*获取anc模式,ff_mic的增益*/
|
||
u8 audio_anc_ffmic_gain_get(void)
|
||
{
|
||
u8 gain = 0;
|
||
if (anc_hdl) {
|
||
if (anc_hdl->param.ch & ANC_L_CH) {
|
||
gain = anc_hdl->param.gains.l_ffmic_gain;
|
||
} else {
|
||
gain = anc_hdl->param.gains.r_ffmic_gain;
|
||
}
|
||
}
|
||
return gain;
|
||
}
|
||
|
||
/*获取anc模式,fb_mic的增益*/
|
||
u8 audio_anc_fbmic_gain_get(void)
|
||
{
|
||
u8 gain = 0;
|
||
if (anc_hdl) {
|
||
if (anc_hdl->param.ch & ANC_L_CH) {
|
||
gain = anc_hdl->param.gains.l_fbmic_gain;
|
||
} else {
|
||
gain = anc_hdl->param.gains.r_fbmic_gain;
|
||
}
|
||
}
|
||
return gain;
|
||
}
|
||
|
||
/*获取anc模式,指定mic的增益, mic_sel:目标MIC通道*/
|
||
u8 audio_anc_mic_gain_get(u8 mic_sel)
|
||
{
|
||
return anc_hdl->param.mic_param[mic_sel].gain;
|
||
}
|
||
|
||
|
||
/*anc coeff读接口*/
|
||
int *anc_coeff_read(void)
|
||
{
|
||
#if ANC_BOX_READ_COEFF
|
||
int *coeff = anc_db_get(ANC_DB_COEFF, &anc_hdl->param.coeff_size);
|
||
if (coeff) {
|
||
coeff = (int *)((u8 *)coeff);
|
||
}
|
||
user_anc_log("anc_coeff_read:0x%x", (u32)coeff);
|
||
return coeff;
|
||
#else
|
||
return NULL;
|
||
#endif/*ANC_BOX_READ_COEFF*/
|
||
}
|
||
|
||
|
||
/*anc coeff写接口*/
|
||
int anc_coeff_write(int *coeff, u16 len)
|
||
{
|
||
int ret = 0;
|
||
u8 single_type = 0;
|
||
anc_coeff_t *db_coeff = (anc_coeff_t *)coeff;
|
||
anc_coeff_t *tmp_coeff = NULL;
|
||
#if ANC_MULT_ORDER_ENABLE
|
||
return -1;
|
||
#endif/**/
|
||
|
||
user_anc_log("anc_coeff_write:0x%x, len:%d", (u32)coeff, len);
|
||
ret = anc_coeff_check(db_coeff, len);
|
||
if (ret) {
|
||
return ret;
|
||
}
|
||
if (db_coeff->cnt != 1) {
|
||
ret = anc_db_put(&anc_hdl->param, NULL, (anc_coeff_t *)coeff);
|
||
} else { //保存对应的单项滤波器
|
||
ret = anc_coeff_single_fill(&anc_hdl->param, (anc_coeff_t *)coeff);
|
||
}
|
||
if (ret) {
|
||
user_anc_log("anc_coeff_write err:%d", ret);
|
||
return -1;
|
||
}
|
||
db_coeff = (anc_coeff_t *)anc_db_get(ANC_DB_COEFF, &anc_hdl->param.coeff_size);
|
||
user_anc_log("anc_db coeff_size %d\n", anc_hdl->param.coeff_size);
|
||
anc_coeff_fill(db_coeff);
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
audio_anc_param_map(1, 0);
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
|
||
if (anc_hdl->param.mode != ANC_OFF) { //实时更新填入使用
|
||
audio_anc_reset(&anc_hdl->param, 0);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
static u8 ANC_idle_query(void)
|
||
{
|
||
if (anc_hdl) {
|
||
/*ANC训练模式,不进入低功耗*/
|
||
if (anc_train_open_query()) {
|
||
return 0;
|
||
}
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
static enum LOW_POWER_LEVEL ANC_level_query(void)
|
||
{
|
||
if (anc_hdl == NULL) {
|
||
return LOW_POWER_MODE_SLEEP;
|
||
}
|
||
/*根据anc的状态选择sleep等级*/
|
||
if (anc_status_get() || anc_hdl->mode_switch_lock) {
|
||
/*anc打开,进入轻量级低功耗*/
|
||
return LOW_POWER_MODE_LIGHT_SLEEP;
|
||
}
|
||
/*anc关闭,进入最优低功耗*/
|
||
return LOW_POWER_MODE_DEEP_SLEEP;
|
||
}
|
||
|
||
/* AT_VOLATILE_RAM_CODE */
|
||
AT(.volatile_ram_code)
|
||
u8 is_lowpower_anc_active()
|
||
{
|
||
if (anc_hdl->state == ANC_STA_OPEN || anc_hdl->mode_switch_lock) {
|
||
/* 若anc 开启,则进入轻量级低功耗时,保持住ANC对应时钟 */
|
||
if ((anc_hdl->param.ch == (ANC_L_CH | ANC_R_CH)) && !anc_hdl->param.lr_lowpower_en) {
|
||
return ANC_CLOCK_USE_PLL;
|
||
} else {
|
||
return ANC_CLOCK_USE_BTOSC;
|
||
}
|
||
}
|
||
return ANC_CLOCK_USE_CLOSE;
|
||
}
|
||
|
||
REGISTER_LP_TARGET(ANC_lp_target) = {
|
||
.name = "ANC",
|
||
.level = ANC_level_query,
|
||
.is_idle = ANC_idle_query,
|
||
};
|
||
|
||
void chargestore_uart_data_deal(u8 *data, u8 len)
|
||
{
|
||
/* anc_uart_process(data, len); */
|
||
}
|
||
|
||
#if TCFG_ANC_TOOL_DEBUG_ONLINE
|
||
//回复包
|
||
void anc_ci_send_packet(u32 id, u8 *packet, int size)
|
||
{
|
||
if (DB_PKT_TYPE_ANC == id) {
|
||
app_online_db_ack(anc_hdl->anc_parse_seq, packet, size);
|
||
return;
|
||
}
|
||
/* y_printf("anc_app_spp_tx\n"); */
|
||
ci_send_packet(id, packet, size);
|
||
}
|
||
|
||
//接收函数
|
||
static int anc_app_online_parse(u8 *packet, u8 size, u8 *ext_data, u16 ext_size)
|
||
{
|
||
/* y_printf("anc_app_spp_rx\n"); */
|
||
anc_hdl->anc_parse_seq = ext_data[1];
|
||
anc_spp_rx_packet(packet, size);
|
||
return 0;
|
||
}
|
||
//发送函数
|
||
void anc_btspp_packet_tx(u8 *packet, int size)
|
||
{
|
||
app_online_db_send(DB_PKT_TYPE_ANC, packet, size);
|
||
}
|
||
#endif/*TCFG_ANC_TOOL_DEBUG_ONLINE*/
|
||
|
||
u8 anc_btspp_train_again(u8 mode, u32 dat)
|
||
{
|
||
/* tws_api_detach(TWS_DETACH_BY_POWEROFF); */
|
||
//ANC模式下可直接获取REF+ERRMIC的数据
|
||
/* if((dat == 3) || (dat == 5)) { */
|
||
/* anc_hdl->param.debug_sel = dat; */
|
||
/* os_taskq_post_msg("anc", 1, ANC_MSG_MIC_DATA_GET); */
|
||
/* return 0; */
|
||
/* } */
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
if (anc_hdl->ear_adaptive_busy) { //ANC自适应切换时,不支持获取DMA
|
||
return 0;
|
||
}
|
||
#if TCFG_USER_TWS_ENABLE
|
||
switch (dat) {
|
||
case 2:
|
||
dat = 4;
|
||
break;
|
||
case 3:
|
||
dat = 5;
|
||
break;
|
||
case 6:
|
||
dat = 7;
|
||
break;
|
||
}
|
||
#endif/*TCFG_USER_TWS_ENABLE*/
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
user_anc_log("anc_btspp_train_again\n");
|
||
audio_anc_close();
|
||
anc_hdl->state = ANC_STA_INIT;
|
||
anc_train_open(mode, (u8)dat);
|
||
return 1;
|
||
}
|
||
|
||
u8 audio_anc_develop_get(void)
|
||
{
|
||
return anc_hdl->param.developer_mode;
|
||
}
|
||
|
||
void audio_anc_develop_set(u8 mode)
|
||
{
|
||
#if (!ANC_DEVELOPER_MODE_EN) && ANC_EAR_ADAPTIVE_EN //非强制开发者模式跟随工具设置
|
||
if (mode != anc_hdl->param.developer_mode) {
|
||
anc_hdl->param.developer_mode = mode;
|
||
if (anc_hdl->param.mode != ANC_OFF) {
|
||
anc_mode_switch(ANC_OFF, 0); //避免右耳参数异常,让调试者感受不适
|
||
}
|
||
if (anc_hdl->param.anc_coeff_mode == ANC_COEFF_MODE_ADAPTIVE) {
|
||
return; //自适应模式不更新参数
|
||
}
|
||
if (mode) { //0 -> 1
|
||
audio_anc_param_map(1, 1); //映射ANC参数
|
||
audio_anc_adaptive_poweron_catch_data(&anc_hdl->adaptive_iir); //打包自适应数据,等待工具读取
|
||
} else { //1 -> 0
|
||
audio_anc_db_cfg_read(); //读取ANC配置区的数据
|
||
if (anc_adaptive_data) {
|
||
free_anc_data_packet(anc_adaptive_data);
|
||
anc_adaptive_data = NULL;
|
||
}
|
||
}
|
||
}
|
||
#endif/*ANC_DEVELOPER_MODE_EN*/
|
||
}
|
||
|
||
/*ANC配置在线读取接口*/
|
||
int anc_cfg_online_deal(u8 cmd, anc_gain_t *cfg)
|
||
{
|
||
/*同步在线更新配置*/
|
||
int ret = 0;
|
||
anc_gain_param_t *gains = &anc_hdl->param.gains;
|
||
anc_param_fill(cmd, cfg);
|
||
if (cmd == ANC_CFG_WRITE) {
|
||
/*实时更新ANC配置*/
|
||
audio_anc_dac_gain(gains->dac_gain, gains->dac_gain);
|
||
audio_anc_mic_management(&anc_hdl->param);
|
||
audio_anc_mic_gain(anc_hdl->param.mic_param, 0);
|
||
anc_mix_out_audio_drc_thr(gains->audio_drc_thr);
|
||
if (anc_hdl->param.mode != ANC_OFF) { //实时更新填入使用
|
||
#if ANC_MULT_ORDER_ENABLE
|
||
anc_mult_scene_set(anc_hdl->scene_id); //覆盖增益以及增益符号
|
||
#endif/*ANC_MULT_ORDER_ENABLE*/
|
||
audio_anc_reset(&anc_hdl->param, 0); //不可异步,因为后面会更新ANCIF区域内容
|
||
#if ANC_MULT_ORDER_ENABLE
|
||
audio_anc_mult_scene_coeff_free(); //释放空间
|
||
#endif/*ANC_MULT_ORDER_ENABLE*/
|
||
}
|
||
/*仅修改增益配置*/
|
||
ret = anc_db_put(&anc_hdl->param, cfg, NULL);
|
||
if (ret) {
|
||
user_anc_log("ret %d\n", ret);
|
||
anc_hdl->param.lff_coeff = NULL;
|
||
anc_hdl->param.rff_coeff = NULL;
|
||
anc_hdl->param.lfb_coeff = NULL;
|
||
anc_hdl->param.rfb_coeff = NULL;
|
||
};
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
#if 0
|
||
/*ANC数字MIC IO配置*/
|
||
static atomic_t dmic_mux_ref;
|
||
#define DMIC_SCLK_FROM_PLNK 0
|
||
#define DMIC_SCLK_FROM_ANC 1
|
||
void dmic_io_mux_ctl(u8 en, u8 sclk_sel)
|
||
{
|
||
user_anc_log("dmic_io_mux,en:%d,sclk:%d,ref:%d\n", en, sclk_sel, atomic_read(&dmic_mux_ref));
|
||
if (en) {
|
||
if (atomic_read(&dmic_mux_ref)) {
|
||
user_anc_log("DMIC_IO_MUX open now\n");
|
||
if (sclk_sel == DMIC_SCLK_FROM_ANC) {
|
||
user_anc_log("plink_sclk -> anc_sclk\n");
|
||
gpio_set_fun_output_port(TCFG_AUDIO_PLNK_SCLK_PIN, FO_ANC_MICCK, 0, 1, LOW_POWER_KEEP);
|
||
}
|
||
atomic_inc_return(&dmic_mux_ref);
|
||
return;
|
||
}
|
||
if (sclk_sel == DMIC_SCLK_FROM_ANC) {
|
||
gpio_set_fun_output_port(TCFG_AUDIO_PLNK_SCLK_PIN, FO_ANC_MICCK, 0, 1, LOW_POWER_KEEP);
|
||
} else {
|
||
gpio_set_fun_output_port(TCFG_AUDIO_PLNK_SCLK_PIN, FO_PLNK_SCLK, 0, 1, LOW_POWER_KEEP);
|
||
}
|
||
gpio_set_direction(TCFG_AUDIO_PLNK_SCLK_PIN, 0);
|
||
gpio_set_die(TCFG_AUDIO_PLNK_SCLK_PIN, 0);
|
||
gpio_direction_output(TCFG_AUDIO_PLNK_SCLK_PIN, 1);
|
||
#if TCFG_AUDIO_PLNK_DAT0_PIN != NO_CONFIG_PORT
|
||
//anc data0 port init
|
||
gpio_set_pull_down(TCFG_AUDIO_PLNK_DAT0_PIN, 0);
|
||
gpio_set_pull_up(TCFG_AUDIO_PLNK_DAT0_PIN, 1);
|
||
gpio_set_direction(TCFG_AUDIO_PLNK_DAT0_PIN, 1);
|
||
gpio_set_die(TCFG_AUDIO_PLNK_DAT0_PIN, 1);
|
||
gpio_set_fun_input_port(TCFG_AUDIO_PLNK_DAT0_PIN, PFI_PLNK_DAT0, LOW_POWER_KEEP);
|
||
#endif/*TCFG_AUDIO_PLNK_DAT0_PIN != NO_CONFIG_PORT*/
|
||
|
||
#if TCFG_AUDIO_PLNK_DAT1_PIN != NO_CONFIG_PORT
|
||
//anc data1 port init
|
||
gpio_set_pull_down(TCFG_AUDIO_PLNK_DAT1_PIN, 0);
|
||
gpio_set_pull_up(TCFG_AUDIO_PLNK_DAT1_PIN, 1);
|
||
gpio_set_direction(TCFG_AUDIO_PLNK_DAT1_PIN, 1);
|
||
gpio_set_die(TCFG_AUDIO_PLNK_DAT1_PIN, 1);
|
||
gpio_set_fun_input_port(TCFG_AUDIO_PLNK_DAT1_PIN, PFI_PLNK_DAT1, LOW_POWER_KEEP);
|
||
#endif/*TCFG_AUDIO_PLNK_DAT1_PIN != NO_CONFIG_PORT*/
|
||
atomic_inc_return(&dmic_mux_ref);
|
||
} else {
|
||
if (atomic_read(&dmic_mux_ref)) {
|
||
atomic_dec_return(&dmic_mux_ref);
|
||
if (atomic_read(&dmic_mux_ref)) {
|
||
if (sclk_sel == DMIC_SCLK_FROM_ANC) {
|
||
user_anc_log("anc close now,anc_sclk->plnk_sclk\n");
|
||
gpio_set_fun_output_port(TCFG_AUDIO_PLNK_SCLK_PIN, FO_PLNK_SCLK, 0, 1, LOW_POWER_KEEP);
|
||
} else {
|
||
user_anc_log("plnk close,anc_plnk open\n");
|
||
}
|
||
} else {
|
||
user_anc_log("dmic all close,disable plnk io_mapping output\n");
|
||
gpio_disable_fun_output_port(TCFG_AUDIO_PLNK_SCLK_PIN);
|
||
#if TCFG_AUDIO_PLNK_DAT0_PIN != NO_CONFIG_PORT
|
||
gpio_disable_fun_input_port(TCFG_AUDIO_PLNK_DAT0_PIN);
|
||
#endif/*TCFG_AUDIO_PLNK_DAT0_PIN != NO_CONFIG_PORT*/
|
||
#if TCFG_AUDIO_PLNK_DAT1_PIN != NO_CONFIG_PORT
|
||
gpio_disable_fun_input_port(TCFG_AUDIO_PLNK_DAT1_PIN);
|
||
#endif/*TCFG_AUDIO_PLNK_DAT1_PIN != NO_CONFIG_PORT*/
|
||
}
|
||
} else {
|
||
user_anc_log("dmic_mux_ref NULL\n");
|
||
}
|
||
}
|
||
}
|
||
void anc_dmic_io_init(audio_anc_t *param, u8 en)
|
||
{
|
||
if (en) {
|
||
int i;
|
||
for (i = 0; i < 4; i++) {
|
||
if ((param->mic_type[i] > A_MIC1) && (param->mic_type[i] != MIC_NULL)) {
|
||
user_anc_log("anc_dmic_io_init %d:%d\n", i, param->mic_type[i]);
|
||
dmic_io_mux_ctl(1, DMIC_SCLK_FROM_ANC);
|
||
break;
|
||
}
|
||
}
|
||
} else {
|
||
dmic_io_mux_ctl(0, DMIC_SCLK_FROM_ANC);
|
||
}
|
||
}
|
||
#else
|
||
void anc_dmic_io_init(audio_anc_t *param, u8 en)
|
||
{
|
||
}
|
||
#endif
|
||
|
||
extern void mix_out_drc_threadhold_update(float threadhold);
|
||
static void anc_mix_out_audio_drc_thr(float thr)
|
||
{
|
||
if (thr > 0.0 || thr < -6.0 || anc_hdl->param.enablebit == ANC_FB_EN) {
|
||
thr = 0.0;
|
||
}
|
||
mix_out_drc_threadhold_update(thr);
|
||
}
|
||
|
||
#if TCFG_AUDIO_DYNAMIC_ADC_GAIN
|
||
void anc_dynamic_micgain_start(u8 audio_mic_gain)
|
||
{
|
||
int anc_mic_gain, i, diff_gain;
|
||
u8 flag = 0;
|
||
float ffgain;
|
||
float multiple = 1.259;
|
||
if (!anc_status_get()) {
|
||
anc_hdl->mic_dy_state = ANC_MIC_DY_STA_INIT;
|
||
return;
|
||
}
|
||
memcpy(anc_hdl->dy_mic_param, anc_hdl->param.mic_param, sizeof(audio_adc_mic_mana_t) * 4);
|
||
|
||
for (i = 0; i < 4; i++) { //动态MIC增益调整时,忽略FBmic
|
||
if ((anc_hdl->dy_mic_param[i].type % 2) == 1) {
|
||
anc_hdl->dy_mic_param[i].mult_flag = 0;
|
||
printf("clean anc_hdl->dy_mic_param[%d].mult_flag\n", i);
|
||
}
|
||
}
|
||
anc_hdl->drc_ratio = 1.0;
|
||
ffgain = (float)(anc_hdl->param.mode == ANC_TRANSPARENCY ? anc_hdl->param.gains.drctrans_norgain : anc_hdl->param.gains.drcff_norgain);
|
||
for (i = 0; i < 4; i++) {
|
||
if (anc_hdl->dy_mic_param[i].mult_flag) {
|
||
anc_mic_gain = anc_hdl->dy_mic_param[i].gain;
|
||
anc_hdl->dy_mic_param[i].gain = audio_mic_gain;
|
||
flag = 1;
|
||
user_anc_log("after mic%d en %d, gain %d, type %d, mult_flag %d\n", i, anc_hdl->dy_mic_param[i].en, \
|
||
anc_hdl->dy_mic_param[i].gain, anc_hdl->dy_mic_param[i].type, anc_hdl->dy_mic_param[i].mult_flag);
|
||
}
|
||
}
|
||
if ((!flag) || (!(audio_mic_gain - anc_mic_gain))) {
|
||
user_anc_log("There is no common MIC\n");
|
||
anc_hdl->mic_dy_state = ANC_MIC_DY_STA_STOP;
|
||
return;
|
||
}
|
||
anc_hdl->mic_dy_state = ANC_MIC_DY_STA_START;
|
||
if (anc_hdl->mic_resume_timer) {
|
||
sys_timer_del(anc_hdl->mic_resume_timer);
|
||
anc_hdl->mic_resume_timer = 0;
|
||
}
|
||
anc_hdl->mic_diff_gain = audio_mic_gain - anc_mic_gain;
|
||
multiple = (anc_hdl->mic_diff_gain < 0) ? (1.0f / multiple) : multiple;
|
||
diff_gain = (anc_hdl->mic_diff_gain < 0) ? 0 - anc_hdl->mic_diff_gain : anc_hdl->mic_diff_gain;
|
||
for (i = 0; i < diff_gain; i++) {
|
||
ffgain /= multiple;
|
||
anc_hdl->drc_ratio *= multiple;
|
||
}
|
||
audio_anc_drc_ctrl(&anc_hdl->param, anc_hdl->drc_ratio);
|
||
audio_anc_mic_gain(anc_hdl->dy_mic_param, 1);
|
||
g_printf("dynamic mic:audio_g %d,anc_g %d, diff_g %d, ff_gain %d, mult %d/100\n", audio_mic_gain, anc_mic_gain, anc_hdl->mic_diff_gain, (s16)ffgain, (int)(multiple * 100.0f));
|
||
}
|
||
|
||
void anc_dynamic_micgain_resume_timer(void *priv)
|
||
{
|
||
float multiple = 1.259;
|
||
audio_adc_mic_mana_t mic_param[4];
|
||
if (anc_hdl->mic_diff_gain > 0) {
|
||
anc_hdl->mic_diff_gain--;
|
||
anc_hdl->drc_ratio /= multiple;
|
||
if (!anc_hdl->mic_diff_gain) {
|
||
anc_hdl->drc_ratio = 1.0;
|
||
}
|
||
for (int i = 0; i < 4; i++) {
|
||
if (anc_hdl->dy_mic_param[i].mult_flag) {
|
||
anc_hdl->dy_mic_param[i].gain--;
|
||
}
|
||
}
|
||
} else if (anc_hdl->mic_diff_gain < 0) {
|
||
anc_hdl->mic_diff_gain++;
|
||
anc_hdl->drc_ratio *= multiple;
|
||
if (!anc_hdl->mic_diff_gain) {
|
||
anc_hdl->drc_ratio = 1.0;
|
||
}
|
||
for (int i = 0; i < 4; i++) {
|
||
if (anc_hdl->dy_mic_param[i].mult_flag) {
|
||
anc_hdl->dy_mic_param[i].gain++;
|
||
}
|
||
}
|
||
} else {
|
||
sys_timer_del(anc_hdl->mic_resume_timer);
|
||
anc_hdl->mic_resume_timer = 0;
|
||
}
|
||
audio_anc_drc_ctrl(&anc_hdl->param, anc_hdl->drc_ratio);
|
||
audio_anc_mic_gain(anc_hdl->dy_mic_param, 1);
|
||
}
|
||
|
||
void anc_dynamic_micgain_stop(void)
|
||
{
|
||
if ((anc_hdl->mic_dy_state == ANC_MIC_DY_STA_START) && anc_status_get()) {
|
||
anc_hdl->mic_dy_state = ANC_MIC_DY_STA_STOP;
|
||
anc_hdl->mic_resume_timer = sys_timer_add(NULL, anc_dynamic_micgain_resume_timer, 10);
|
||
}
|
||
}
|
||
#endif/*TCFG_AUDIO_DYNAMIC_ADC_GAIN*/
|
||
|
||
void audio_anc_post_msg_drc(void)
|
||
{
|
||
os_taskq_post_msg("anc", 1, ANC_MSG_DRC_TIMER);
|
||
}
|
||
|
||
void audio_anc_post_msg_debug(void)
|
||
{
|
||
os_taskq_post_msg("anc", 1, ANC_MSG_DEBUG_OUTPUT);
|
||
}
|
||
|
||
void audio_anc_post_msg_icsd_anc_cmd(u8 cmd)
|
||
{
|
||
os_taskq_post_msg("anc", 2, ANC_MSG_ICSD_ANC_CMD, cmd);
|
||
}
|
||
|
||
void audio_anc_post_msg_user_train_init(u8 mode)
|
||
{
|
||
if (mode == ANC_ON) {
|
||
os_taskq_post_msg("anc", 1, ANC_MSG_USER_TRAIN_INIT);
|
||
}
|
||
}
|
||
|
||
void audio_anc_post_msg_user_train_run(void)
|
||
{
|
||
os_taskq_post_msg("anc", 1, ANC_MSG_USER_TRAIN_RUN);
|
||
}
|
||
|
||
void audio_anc_post_msg_user_train_setparam(void)
|
||
{
|
||
os_taskq_post_msg("anc", 1, ANC_MSG_USER_TRAIN_SETPARAM);
|
||
}
|
||
|
||
void audio_anc_post_msg_user_train_timeout(void)
|
||
{
|
||
os_taskq_post_msg("anc", 1, ANC_MSG_USER_TRAIN_TIMEOUT);
|
||
}
|
||
|
||
void audio_anc_post_msg_user_train_end(void)
|
||
{
|
||
os_taskq_post_msg("anc", 1, ANC_MSG_USER_TRAIN_END);
|
||
}
|
||
|
||
#if TCFG_ANC_SELF_DUT_GET_SZ
|
||
void audio_anc_post_msg_sz_fft_open(u8 sel)
|
||
{
|
||
os_taskq_post_msg("anc", 2, ANC_MSG_SZ_FFT_OPEN, sel);
|
||
}
|
||
|
||
void audio_anc_post_msg_sz_fft_run(void)
|
||
{
|
||
os_taskq_post_msg("anc", 1, ANC_MSG_SZ_FFT_RUN);
|
||
}
|
||
|
||
void audio_anc_post_msg_sz_fft_close(void)
|
||
{
|
||
os_taskq_post_msg("anc", 1, ANC_MSG_SZ_FFT_CLOSE);
|
||
}
|
||
|
||
static void audio_anc_sz_fft_dac_check_slience_cb(void *buf, int len)
|
||
{
|
||
if (anc_hdl->param.sz_fft.check_flag) {
|
||
s16 *check_buf = (s16 *)buf;
|
||
for (int i = 0; i < len / 2; i++) {
|
||
if (check_buf[i]) {
|
||
anc_hdl->param.sz_fft.check_flag = 0;
|
||
audio_anc_sz_fft_trigger();
|
||
audio_dac_write_callback_del(&dac_hdl, audio_anc_sz_fft_dac_check_slience_cb);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//SZ_FFT测试函数
|
||
void audio_anc_sz_fft_test(void)
|
||
{
|
||
#if 0
|
||
static u8 cnt = 0;
|
||
g_printf("cnt %d\n", cnt);
|
||
switch (cnt) {
|
||
case 0:
|
||
audio_anc_post_msg_sz_fft_open(4);
|
||
break;
|
||
case 1:
|
||
audio_anc_sz_fft_trigger();
|
||
/* play_tone_file(get_tone_files()->normal); */
|
||
break;
|
||
case 2:
|
||
audio_anc_post_msg_sz_fft_close();
|
||
break;
|
||
case 3:
|
||
audio_anc_sz_fft_outbuf_release();
|
||
break;
|
||
}
|
||
if (++cnt > 3) {
|
||
cnt = 0;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
#endif/* TCFG_ANC_SELF_DUT_GET_SZ*/
|
||
|
||
|
||
void audio_anc_dut_enable_set(u8 enablebit)
|
||
{
|
||
anc_hdl->param.dut_audio_enablebit = enablebit;
|
||
}
|
||
|
||
/*
|
||
ANC结构设置, 下一次切模式或复位ANC时生效
|
||
param: enablebit ANC结构配置,如(ANC_FF_EN/ANC_FB_EN/ANC_HYBRID_EN)
|
||
update_flag 非ANC_OFF时,即时更新效果: 0 不更新;1 更新
|
||
*/
|
||
void audio_anc_enable_set(u8 enablebit, u8 update_flag)
|
||
{
|
||
anc_hdl->param.tool_enablebit = enablebit;
|
||
if ((anc_hdl->param.mode != ANC_OFF) && update_flag) { //实时更新填入使用
|
||
os_taskq_post_msg("anc", 2, ANC_MSG_RESET, 1);
|
||
}
|
||
}
|
||
|
||
void audio_anc_post_msg_adt(u8 cmd)
|
||
{
|
||
os_taskq_post_msg("anc", 2, ANC_MSG_ADT, cmd);
|
||
}
|
||
|
||
void audio_anc_mic_mana_set_gain(audio_anc_t *param, u8 num, u8 type)
|
||
{
|
||
int i;
|
||
switch (type) {
|
||
case 0:
|
||
param->mic_param[num].gain = param->gains.l_ffmic_gain;
|
||
break;
|
||
case 1:
|
||
param->mic_param[num].gain = param->gains.l_fbmic_gain;
|
||
break;
|
||
case 2:
|
||
param->mic_param[num].gain = param->gains.r_ffmic_gain;
|
||
break;
|
||
case 3:
|
||
param->mic_param[num].gain = param->gains.r_fbmic_gain;
|
||
break;
|
||
}
|
||
if ((param->ch == (ANC_L_CH | ANC_R_CH)) && param->mic_param[num].mult_flag) {
|
||
for (i = 0; i < 4; i++) {
|
||
if ((param->mic_param[i].type + 1) % 2) {
|
||
param->mic_param[i].mult_flag = 1;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/*设置fb mic为复用mic*/
|
||
void audio_anc_mic_mana_fb_mult_set(u8 mult_flag)
|
||
{
|
||
if (anc_hdl) {
|
||
audio_anc_t *param = &anc_hdl->param;
|
||
for (int i = 0; i < 4; i++) {
|
||
if ((param->mic_param[i].type == ANC_MIC_TYPE_LFB) || (param->mic_param[i].type == ANC_MIC_TYPE_RFB)) {
|
||
param->mic_param[i].mult_flag = mult_flag;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void audio_anc_mic_management(audio_anc_t *param)
|
||
{
|
||
int i;
|
||
u8 double_mult_flag = 0;
|
||
for (i = 0; i < 4; i++) {
|
||
if (param->mic_type[i] == A_MIC0) {
|
||
param->mic_param[0].en = 1;
|
||
param->mic_param[0].type = i;
|
||
#if TCFG_AUDIO_ADC_MIC_CHA & AUDIO_ADC_MIC_0
|
||
param->mic_param[0].mult_flag = 1;
|
||
#endif/*TCFG_AUDIO_ADC_MIC_CHA & AUDIO_ADC_MIC_0*/
|
||
audio_anc_mic_mana_set_gain(param, 0, i);
|
||
}
|
||
if (param->mic_type[i] == A_MIC1) {
|
||
param->mic_param[1].en = 1;
|
||
param->mic_param[1].type = i;
|
||
#if TCFG_AUDIO_ADC_MIC_CHA & AUDIO_ADC_MIC_1
|
||
param->mic_param[1].mult_flag = 1;
|
||
#endif/*TCFG_AUDIO_ADC_MIC_CHA & AUDIO_ADC_MIC_1*/
|
||
audio_anc_mic_mana_set_gain(param, 1, i);
|
||
}
|
||
if (param->mic_type[i] == A_MIC2) {
|
||
param->mic_param[2].en = 1;
|
||
param->mic_param[2].type = i;
|
||
#if TCFG_AUDIO_ADC_MIC_CHA & AUDIO_ADC_MIC_2
|
||
param->mic_param[2].mult_flag = 1;
|
||
#endif/*TCFG_AUDIO_ADC_MIC_CHA & AUDIO_ADC_MIC_2*/
|
||
audio_anc_mic_mana_set_gain(param, 2, i);
|
||
}
|
||
if (param->mic_type[i] == A_MIC3) {
|
||
param->mic_param[3].en = 1;
|
||
param->mic_param[3].type = i;
|
||
#if TCFG_AUDIO_ADC_MIC_CHA & AUDIO_ADC_MIC_3
|
||
param->mic_param[3].mult_flag = 1;
|
||
#endif/*TCFG_AUDIO_ADC_MIC_CHA & AUDIO_ADC_MIC_3*/
|
||
audio_anc_mic_mana_set_gain(param, 3, i);
|
||
}
|
||
}
|
||
for (i = 0; i < 4; i++) {
|
||
printf("mic%d en %d, gain %d, type %d, mult_flag %d\n", i, param->mic_param[i].en, \
|
||
param->mic_param[i].gain, param->mic_param[i].type, param->mic_param[i].mult_flag);
|
||
}
|
||
}
|
||
|
||
void audio_anc_adc_ch_set(void)
|
||
{
|
||
#if TCFG_AUDIO_ADC_MIC_CHA & AUDIO_ADC_MIC_0
|
||
anc_hdl->param.adc_ch = (anc_hdl->param.adc_ch << 1) | 1;
|
||
#endif/*TCFG_AUDIO_ADC_MIC_CHA & AUDIO_ADC_MIC_0*/
|
||
#if TCFG_AUDIO_ADC_MIC_CHA & AUDIO_ADC_MIC_1
|
||
anc_hdl->param.adc_ch = (anc_hdl->param.adc_ch << 1) | 1;
|
||
#endif/*TCFG_AUDIO_ADC_MIC_CHA & AUDIO_ADC_MIC_1*/
|
||
#if TCFG_AUDIO_ADC_MIC_CHA & AUDIO_ADC_MIC_2
|
||
anc_hdl->param.adc_ch = (anc_hdl->param.adc_ch << 1) | 1;
|
||
#endif/*TCFG_AUDIO_ADC_MIC_CHA & AUDIO_ADC_MIC_2*/
|
||
#if TCFG_AUDIO_ADC_MIC_CHA & AUDIO_ADC_MIC_3
|
||
anc_hdl->param.adc_ch = (anc_hdl->param.adc_ch << 1) | 1;
|
||
#endif/*TCFG_AUDIO_ADC_MIC_CHA & AUDIO_ADC_MIC_3*/
|
||
if (!anc_hdl->param.adc_ch) { //通话没有使用模拟MIC,则adc_ch默认赋1
|
||
anc_hdl->param.adc_ch = 1;
|
||
}
|
||
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
/* 开免摘功能后,根据通话mic和免摘mic个数,取最大值来打开ADC的数字通道,保证免摘ADC取数正常 */
|
||
u8 esco_mic_num = audio_adc_file_get_esco_mic_num();
|
||
u8 adt_mic_num = get_icsd_adt_mic_num();
|
||
u8 mic_num = esco_mic_num > adt_mic_num ? esco_mic_num : adt_mic_num;
|
||
if (mic_num == 2) {
|
||
anc_hdl->param.adc_ch = BIT(1) | BIT(0);
|
||
} else {
|
||
anc_hdl->param.adc_ch = BIT(2) | BIT(1) | BIT(0);
|
||
}
|
||
#endif /*TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN*/
|
||
|
||
}
|
||
#if ANC_ADAPTIVE_EN
|
||
static void audio_anc_adap_tone_play(int ref_lvl, int err_lvl)
|
||
{
|
||
#if ANC_ADAPTIVE_TONE_EN
|
||
if (ref_lvl == 1) {
|
||
tone_play(TONE_ANC_ADAPTIVE_LVL1, 1);
|
||
} else if (ref_lvl == 0) {
|
||
tone_play(TONE_ANC_ADAPTIVE_LVL2, 1);
|
||
}
|
||
#endif/*ANC_ADAPTIVE_TONE_EN*/
|
||
anc_pow_adap_fade_timer_add(ref_lvl, err_lvl);
|
||
}
|
||
|
||
void audio_anc_adap_sync(int ref_lvl, int err_lvl, int err)
|
||
{
|
||
os_taskq_post_msg("anc", 3, ANC_MSG_ADAPTIVE_SYNC, ref_lvl, err_lvl);
|
||
}
|
||
|
||
extern void bt_tws_anc_adap_sync_send(int ref_lvl, int err_lvl, int msec);
|
||
extern int bt_tws_anc_adap_compare_send(int ref_lvl, int err_lvl);
|
||
|
||
void audio_anc_adap_lvl_compare(int ref_lvl, int err_lvl)
|
||
{
|
||
#if TCFG_USER_TWS_ENABLE
|
||
int ref_lvl_temp, err_lvl_temp;
|
||
ref_lvl_temp = anc_pow_adap_lvl_get(ANC_FF_EN);
|
||
err_lvl_temp = anc_pow_adap_lvl_get(ANC_FB_EN);
|
||
g_printf("compare ref_lvl_temp %d, %d, lvl %d, %d\n", ref_lvl_temp, err_lvl_temp, ref_lvl, err_lvl);
|
||
if (ref_lvl_temp >= ref_lvl) {
|
||
bt_tws_anc_adap_sync_send(ref_lvl, err_lvl, 150);
|
||
}
|
||
if (err_lvl_temp >= ref_lvl) {
|
||
bt_tws_anc_adap_sync_send(ref_lvl, err_lvl, 150);
|
||
}
|
||
#endif/*TCFG_USER_TWS_ENABLE*/
|
||
}
|
||
|
||
int audio_anc_pow_adap_deal(int ref_lvl, int err_lvl)
|
||
{
|
||
#if TCFG_USER_TWS_ENABLE
|
||
if (get_tws_sibling_connect_state()) {
|
||
if (tws_api_get_role() == TWS_ROLE_MASTER) {
|
||
user_anc_log("[master]anc_pow_adap send %d %d\n", ref_lvl, err_lvl);
|
||
} else {
|
||
user_anc_log("[slave]anc_pow_adap send %d %d\n", ref_lvl, err_lvl);
|
||
}
|
||
bt_tws_anc_adap_compare_send(ref_lvl, err_lvl);
|
||
} else {
|
||
user_anc_log("[no tws]anc_pow_adap send %d %d\n", ref_lvl, err_lvl);
|
||
audio_anc_adap_tone_play(ref_lvl, err_lvl);
|
||
}
|
||
#else
|
||
user_anc_log("[no tws]anc_pow_adap send %d %d\n", ref_lvl, err_lvl);
|
||
audio_anc_adap_tone_play(ref_lvl, err_lvl);
|
||
#endif/*TCFG_USER_TWS_ENABLE*/
|
||
return 0;
|
||
}
|
||
|
||
/*切换增益模式*/
|
||
void audio_anc_adaptive_mode_set(u8 mode, u8 lvl)
|
||
{
|
||
if (anc_hdl) {
|
||
anc_hdl->param.adaptive_mode = mode;
|
||
audio_anc_pow_export_en((mode == ANC_ADAPTIVE_GAIN_MODE), 0);
|
||
if (anc_hdl->param.mode == ANC_ON) {
|
||
switch (mode) {
|
||
case ANC_ADAPTIVE_MANUAL_MODE:
|
||
user_anc_log("ANC_ADAPTIVE_MANUAL_MODE ,lvl%d\n", lvl);
|
||
audio_anc_pow_adap_stop();
|
||
anc_hdl->param.anc_lvl = lvl;
|
||
audio_anc_lvl_set(lvl, 1);
|
||
break;
|
||
case ANC_ADAPTIVE_GAIN_MODE:
|
||
user_anc_log("ANC_ADAPTIVE_GAIN_MODE\n");
|
||
anc_hdl->param.anc_fade_gain = 16384;
|
||
audio_anc_pow_adap_start();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void audio_anc_pow_adap_fade(u16 gain)
|
||
{
|
||
audio_anc_fade_ctr_set(ANC_FADE_MODE_SCENE_ADAPTIVE, AUDIO_ANC_FDAE_CH_ALL, gain);
|
||
}
|
||
|
||
#endif/*ANC_ADAPTIVE_EN*/
|
||
|
||
#if ANC_MUSIC_DYNAMIC_GAIN_EN
|
||
|
||
#define ANC_MUSIC_DYNAMIC_GAIN_NORGAIN 1024 /*正常默认增益*/
|
||
#define ANC_MUSIC_DYNAMIC_GAIN_TRIGGER_INTERVAL 6 /*音乐响度取样间隔*/
|
||
|
||
#if ANC_MUSIC_DYNAMIC_GAIN_SINGLE_FB
|
||
void audio_anc_music_dyn_gain_resume_timer(void *priv)
|
||
{
|
||
if (anc_hdl->loud_nowgain < anc_hdl->loud_targetgain) {
|
||
anc_hdl->loud_nowgain += 5; ///+5耗时194 * 10ms
|
||
if (anc_hdl->loud_nowgain >= anc_hdl->loud_targetgain) {
|
||
anc_hdl->loud_nowgain = anc_hdl->loud_targetgain;
|
||
sys_timer_del(anc_hdl->loud_timeid);
|
||
anc_hdl->loud_timeid = 0;
|
||
}
|
||
} else if (anc_hdl->loud_nowgain > anc_hdl->loud_targetgain) {
|
||
anc_hdl->loud_nowgain -= 5; ///-5耗时194 * 10ms
|
||
if (anc_hdl->loud_nowgain <= anc_hdl->loud_targetgain) {
|
||
anc_hdl->loud_nowgain = anc_hdl->loud_targetgain;
|
||
sys_timer_del(anc_hdl->loud_timeid);
|
||
anc_hdl->loud_timeid = 0;
|
||
}
|
||
}
|
||
audio_anc_fbgain_set(anc_hdl->loud_nowgain, anc_hdl->loud_nowgain);
|
||
/* user_anc_log("fb resume anc_hdl->loud_nowgain %d\n", anc_hdl->loud_nowgain); */
|
||
}
|
||
|
||
#endif/*ANC_MUSIC_DYNAMIC_GAIN_SINGLE_FB*/
|
||
|
||
void audio_anc_music_dynamic_gain_process(void)
|
||
{
|
||
if (anc_hdl->loud_nowgain != anc_hdl->loud_targetgain) {
|
||
// user_anc_log("low_nowgain %d, targergain %d\n", anc_hdl->loud_nowgain, anc_hdl->loud_targetgain);
|
||
#if ANC_MUSIC_DYNAMIC_GAIN_SINGLE_FB
|
||
if (!anc_hdl->loud_timeid) {
|
||
anc_hdl->loud_timeid = sys_timer_add(NULL, audio_anc_music_dyn_gain_resume_timer, 10);
|
||
}
|
||
#else
|
||
anc_hdl->loud_nowgain = anc_hdl->loud_targetgain;
|
||
audio_anc_fade_ctr_set(ANC_FADE_MODE_MUSIC_DYNAMIC, AUDIO_ANC_FDAE_CH_ALL, anc_hdl->loud_targetgain << 4);
|
||
#endif/*ANC_MUSIC_DYNAMIC_GAIN_SINGLE_FB*/
|
||
}
|
||
}
|
||
|
||
void audio_anc_music_dynamic_gain_reset(u8 effect_reset_en)
|
||
{
|
||
if (anc_hdl->loud_targetgain != ANC_MUSIC_DYNAMIC_GAIN_NORGAIN) {
|
||
/* user_anc_log("audio_anc_music_dynamic_gain_reset\n"); */
|
||
anc_hdl->loud_targetgain = ANC_MUSIC_DYNAMIC_GAIN_NORGAIN;
|
||
if (anc_hdl->loud_timeid) {
|
||
sys_timer_del(anc_hdl->loud_timeid);
|
||
anc_hdl->loud_timeid = 0;
|
||
}
|
||
if (effect_reset_en && anc_hdl->param.mode == ANC_ON) {
|
||
os_taskq_post_msg("anc", 1, ANC_MSG_MUSIC_DYN_GAIN);
|
||
} else {
|
||
anc_hdl->loud_nowgain = ANC_MUSIC_DYNAMIC_GAIN_NORGAIN;
|
||
anc_hdl->loud_dB = 1; //清除上次保留的dB值, 避免切模式后不触发的情况
|
||
anc_hdl->loud_hdl.peak_val = ANC_MUSIC_DYNAMIC_GAIN_THR;
|
||
}
|
||
}
|
||
}
|
||
|
||
void audio_anc_music_dynamic_gain_dB_get(int dB)
|
||
{
|
||
float mult = 1.122f;
|
||
float target_mult = 1.0f;
|
||
int cnt, i, gain;
|
||
#if ANC_MUSIC_DYNAMIC_GAIN_TRIGGER_INTERVAL > 1 //区间变化,避免频繁操作
|
||
if (dB > ANC_MUSIC_DYNAMIC_GAIN_THR) {
|
||
int temp_dB = dB / ANC_MUSIC_DYNAMIC_GAIN_TRIGGER_INTERVAL;
|
||
dB = temp_dB * ANC_MUSIC_DYNAMIC_GAIN_TRIGGER_INTERVAL;
|
||
}
|
||
#endif/*ANC_MUSIC_DYNAMIC_GAIN_TRIGGER_INTERVAL*/
|
||
if (anc_hdl->loud_dB != dB) {
|
||
anc_hdl->loud_dB = dB;
|
||
if (dB > ANC_MUSIC_DYNAMIC_GAIN_THR) {
|
||
cnt = dB - ANC_MUSIC_DYNAMIC_GAIN_THR;
|
||
for (i = 0; i < cnt; i++) {
|
||
target_mult *= mult;
|
||
}
|
||
gain = (int)((float)ANC_MUSIC_DYNAMIC_GAIN_NORGAIN / target_mult);
|
||
// user_anc_log("cnt %d, dB %d, gain %d\n", cnt, dB, gain);
|
||
anc_hdl->loud_targetgain = gain;
|
||
os_taskq_post_msg("anc", 1, ANC_MSG_MUSIC_DYN_GAIN);
|
||
} else {
|
||
audio_anc_music_dynamic_gain_reset(1);
|
||
}
|
||
}
|
||
}
|
||
|
||
void audio_anc_music_dynamic_gain_det(s16 *data, int len)
|
||
{
|
||
/* putchar('l'); */
|
||
if (anc_hdl->param.mode == ANC_ON) {
|
||
loudness_meter_short(&anc_hdl->loud_hdl, data, len >> 1);
|
||
audio_anc_music_dynamic_gain_dB_get(anc_hdl->loud_hdl.peak_val);
|
||
}
|
||
}
|
||
|
||
|
||
void audio_anc_music_dynamic_gain_init(int sr)
|
||
{
|
||
/* user_anc_log("audio_anc_music_dynamic_gain_init %d\n", sr); */
|
||
anc_hdl->loud_nowgain = ANC_MUSIC_DYNAMIC_GAIN_NORGAIN;
|
||
anc_hdl->loud_targetgain = ANC_MUSIC_DYNAMIC_GAIN_NORGAIN;
|
||
anc_hdl->loud_dB = 1; //清除上次保留的dB值
|
||
loudness_meter_init(&anc_hdl->loud_hdl, sr, 50, 0);
|
||
anc_hdl->loud_hdl.peak_val = ANC_MUSIC_DYNAMIC_GAIN_THR;
|
||
}
|
||
#endif/*ANC_MUSIC_DYNAMIC_GAIN_EN*/
|
||
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
extern struct audio_decoder_task decode_task;
|
||
/* 解码任务回调,执行自适应切换 */
|
||
|
||
void audio_anc_dac_check_slience_cb(void *buf, int len)
|
||
{
|
||
if (anc_hdl->dac_check_slience_flag) {
|
||
s16 *check_buf = (s16 *)buf;
|
||
for (int i = 0; i < len / 2; i++) {
|
||
if (check_buf[i]) {
|
||
anc_hdl->dac_check_slience_flag = 0;
|
||
icsd_anctone_dacon(i, dac_hdl.sample_rate);
|
||
audio_dac_write_callback_del(&dac_hdl, audio_anc_dac_check_slience_cb);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void audio_anc_ear_adaptive_open(void)
|
||
{
|
||
#if ANC_MULT_ORDER_ENABLE
|
||
//载入场景参数-提供自适应训练过程使用
|
||
u8 scene_id = ANC_MULT_ADPTIVE_TRAIN_USE_ID ? ANC_MULT_ADPTIVE_TRAIN_USE_ID : anc_hdl->scene_id;
|
||
anc_mult_scene_set(scene_id);
|
||
#endif/*ANC_MULT_ORDER_ENABLE*/
|
||
anc_hdl->ear_adaptive = 1;
|
||
anc_hdl->param.anc_coeff_mode = ANC_COEFF_MODE_ADAPTIVE; //切到自适应的参数
|
||
anc_hdl->ear_adaptive_busy = 1;
|
||
audio_anc_ear_adaptive_param_init(&anc_hdl->param);
|
||
#if ANC_USER_TRAIN_TONE_MODE
|
||
anc_hdl->dac_check_slience_flag = 1;
|
||
audio_dac_write_callback_add(&dac_hdl, audio_anc_dac_check_slience_cb);
|
||
#endif/*ANC_USER_TRAIN_TONE_MODE*/
|
||
/*自适应时需要挂起adt*/
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
audio_anc_mode_switch_in_adt(ANC_ON);
|
||
#endif
|
||
anc_mode_switch(ANC_ON, ANC_USER_TRAIN_TONE_MODE);
|
||
}
|
||
|
||
static int audio_anc_adaptive_wait_handler(struct audio_res_wait *wait, int event)
|
||
{
|
||
if (event == AUDIO_RES_GET) {
|
||
if (anc_hdl->ear_adaptive_dec_wait == ANC_ADAPTIVE_DEC_WAIT_START) {
|
||
//避免重复进入
|
||
anc_hdl->ear_adaptive_dec_wait = ANC_ADAPTIVE_DEC_WAIT_RUN;
|
||
audio_anc_ear_adaptive_open();
|
||
}
|
||
} else {
|
||
g_printf("audio_anc.c AUDIO_RES_PUT\n");
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/* 自适应解码任务注册 */
|
||
static int audio_anc_decoder_task_add(int parm)
|
||
{
|
||
anc_hdl->adaptive_wait.priority = 2; //优先级
|
||
anc_hdl->adaptive_wait.preemption = 1; //打断方式
|
||
anc_hdl->adaptive_wait.handler = audio_anc_adaptive_wait_handler;//解码任务回调
|
||
anc_hdl->ear_adaptive_dec_wait = ANC_ADAPTIVE_DEC_WAIT_START;
|
||
audio_decoder_task_add_wait(&decode_task, &anc_hdl->adaptive_wait);
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
自适应模式-重新检测
|
||
param: tws_sync_en 1 TWS同步自适应,支持TWS降噪平衡,需左右耳一起调用此接口
|
||
0 单耳自适应, 不支持TWS降噪平衡,可TWS状态下单耳自适应
|
||
*/
|
||
int audio_anc_mode_ear_adaptive(u8 tws_sync_en)
|
||
{
|
||
//不支持重入自适应模式,仅在ANC模式,非通话下进入自适应模式
|
||
anc_hdl->ear_adaptive_tws_sync = tws_sync_en;
|
||
|
||
if (anc_hdl->param.mode == ANC_ON && !anc_hdl->ear_adaptive_busy \
|
||
&& (bt_phone_dec_is_running() == 0) && !anc_hdl->mode_switch_lock
|
||
) {
|
||
if (bt_media_is_running()) { //当前处于音乐播放状态, 注册解码任务打断,进入自适应
|
||
/* if (0) { //当前处于音乐播放状态, 注册解码任务打断,进入自适应 */
|
||
if (strcmp(os_current_task(), "app_core") != 0) {
|
||
int *ptr = malloc(2 * sizeof(int));
|
||
ptr[0] = 0;
|
||
ptr[1] = 0;
|
||
OS_SEM *sem = malloc(sizeof(OS_SEM) + 4);
|
||
int *err = (int *)(sem + 1);
|
||
ASSERT(sem);
|
||
int msg[8];
|
||
msg[0] = (int)audio_anc_decoder_task_add;
|
||
msg[1] = 1 | BIT(8) | BIT(9);
|
||
msg[2] = (int)ptr;
|
||
msg[3] = (int)err;
|
||
msg[4] = (int)sem;
|
||
|
||
os_sem_create(sem, 0);
|
||
int ret_err;
|
||
while (1) {
|
||
int ret_err = os_taskq_post_type("app_core", Q_CALLBACK, 5, msg);
|
||
if (ret_err == OS_ERR_NONE) {
|
||
os_sem_pend(sem, 0);
|
||
ret_err = *err;
|
||
break;
|
||
}
|
||
if (ret_err != OS_Q_FULL) {
|
||
break;
|
||
}
|
||
os_time_dly(2);
|
||
}
|
||
free(sem);
|
||
free(ptr);
|
||
g_printf("switch to app_core paly tone ok\n");
|
||
return 0;
|
||
} else {
|
||
audio_anc_decoder_task_add(0);
|
||
return 0;
|
||
}
|
||
}
|
||
audio_anc_ear_adaptive_open();
|
||
return 0;
|
||
}
|
||
#if (RCSP_ADV_EN && RCSP_ADV_ANC_VOICE && RCSP_ADV_ADAPTIVE_NOISE_REDUCTION)
|
||
set_adaptive_noise_reduction_reset_callback(0); // 无法进入自适应,返回失败结果
|
||
#endif
|
||
return 1;
|
||
}
|
||
|
||
|
||
/*自适应结束回调函数*/
|
||
void anc_user_train_cb(u8 mode, u8 result, u8 forced_exit)
|
||
{
|
||
user_anc_log("anc_adaptive end result 0x%x , coeff_use 0x%x\n", result, anc_hdl->adaptive_iir.result);
|
||
audio_anc_t *param = &anc_hdl->param;
|
||
anc_hdl->ear_adaptive_busy = 0;
|
||
|
||
if (forced_exit == 1) {
|
||
//强制打断,自适应定义为失败,使用默认参数
|
||
anc_hdl->adaptive_iir.result = 0;
|
||
//删除自适应DAC回调接口
|
||
audio_dac_write_callback_del(&dac_hdl, audio_anc_dac_check_slience_cb);
|
||
}
|
||
|
||
if (anc_hdl->adaptive_iir.result) { //自适应成功或部分成功
|
||
if (anc_hdl->ear_adaptive_data_from == ANC_ADAPTIVE_DATA_FROM_VM) { //释放掉原来VM使用的资源
|
||
if (anc_hdl->param.adaptive->lff_coeff) {
|
||
free(anc_hdl->param.adaptive->lff_coeff);
|
||
};
|
||
if (anc_hdl->param.adaptive->lfb_coeff) {
|
||
free(anc_hdl->param.adaptive->lfb_coeff);
|
||
};
|
||
if (anc_hdl->param.adaptive->lcmp_coeff) {
|
||
free(anc_hdl->param.adaptive->lcmp_coeff);
|
||
};
|
||
if (anc_hdl->param.adaptive->rff_coeff) {
|
||
free(anc_hdl->param.adaptive->rff_coeff);
|
||
};
|
||
if (anc_hdl->param.adaptive->rfb_coeff) {
|
||
free(anc_hdl->param.adaptive->rfb_coeff);
|
||
};
|
||
if (anc_hdl->param.adaptive->rcmp_coeff) {
|
||
free(anc_hdl->param.adaptive->rcmp_coeff);
|
||
};
|
||
}
|
||
anc_hdl->ear_adaptive_data_from = ANC_ADAPTIVE_DATA_FROM_ALOGM; //自适应参数更新
|
||
#if (ANC_CH & ANC_L_CH)
|
||
param->adaptive->lff_coeff = param->lff_coeff;
|
||
param->adaptive->lfb_coeff = param->lfb_coeff;
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
param->adaptive->lcmp_coeff = param->lcmp_coeff;
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
#endif/*(ANC_CH & ANC_L_CH)*/
|
||
#if (ANC_CH & ANC_R_CH)
|
||
param->adaptive->rff_coeff = param->rff_coeff;
|
||
param->adaptive->rfb_coeff = param->rfb_coeff;
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
param->adaptive->rcmp_coeff = param->rcmp_coeff;
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
#endif/*(ANC_CH & ANC_R_CH)*/
|
||
if (result != ANC_SUCCESS) { //非FF+FB同时成功
|
||
g_printf("no all success");
|
||
audio_anc_coeff_adaptive_set(ANC_COEFF_MODE_NORMAL, 0, 0); //先覆盖默认参数
|
||
audio_anc_coeff_adaptive_set(ANC_COEFF_MODE_ADAPTIVE, 0, 0); //根据自适应结果选择覆盖参数
|
||
}
|
||
|
||
#if (!ANC_POWEOFF_SAVE_ADAPTIVE_DATA) || ANC_DEVELOPER_MODE_EN
|
||
audio_anc_adaptive_data_save(&anc_hdl->adaptive_iir);
|
||
#endif/*ANC_POWEOFF_SAVE_ADAPTIVE_DATA*/
|
||
} else { //自适应失败使用默认的参数
|
||
audio_anc_coeff_adaptive_set(ANC_COEFF_MODE_NORMAL, 0, 0);
|
||
}
|
||
if (anc_hdl->ear_adaptive_dec_wait) {
|
||
anc_hdl->ear_adaptive_dec_wait = ANC_ADAPTIVE_DEC_WAIT_STOP;
|
||
audio_decoder_task_del_wait(&decode_task, &anc_hdl->adaptive_wait);
|
||
}
|
||
anc_mode_switch_deal(mode);
|
||
}
|
||
|
||
/*ANC滤波器模式循环切换*/
|
||
int audio_anc_coeff_adaptive_switch()
|
||
{
|
||
if (anc_hdl->param.mode == ANC_ON && !anc_hdl->ear_adaptive_busy && !anc_hdl->mode_switch_lock) {
|
||
anc_hdl->param.anc_coeff_mode ^= 1;
|
||
audio_anc_coeff_adaptive_set(anc_hdl->param.anc_coeff_mode, 1, 1);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/*当前ANC滤波器模式获取 0:普通参数 1:自适应参数*/
|
||
int audio_anc_coeff_mode_get(void)
|
||
{
|
||
if (!anc_hdl) {
|
||
return 0;
|
||
}
|
||
return anc_hdl->param.anc_coeff_mode;
|
||
}
|
||
|
||
/*
|
||
自适应/普通参数切换
|
||
param: mode 0 使用普通参数; 1 使用自适应参数
|
||
tone_play 0 不播放提示音;1 播放提示音
|
||
update_flag 0 不更新效果; 1 即时更新效果
|
||
*/
|
||
int audio_anc_coeff_adaptive_set(u32 mode, u8 tone_play, u8 update_flag)
|
||
{
|
||
audio_anc_t *param = &anc_hdl->param;
|
||
u8 result = anc_hdl->adaptive_iir.result;
|
||
if (anc_hdl->ear_adaptive_busy) {
|
||
return 0;
|
||
}
|
||
anc_hdl->param.anc_coeff_mode = mode;
|
||
switch (mode) {
|
||
case 0:
|
||
if (tone_play) {
|
||
tone_play_index(IDEX_TONE_ANC_NORMAL_COEFF, ANC_TONE_PREEMPTION);
|
||
}
|
||
#if ANC_COEFF_SAVE_ENABLE
|
||
#if ANC_MULT_ORDER_ENABLE
|
||
//自适应切默认参数,回到当前场景
|
||
anc_mult_scene_set(anc_hdl->scene_id);
|
||
#else
|
||
if (audio_anc_db_cfg_read()) {
|
||
return 1;
|
||
}
|
||
#endif/*ANC_MULT_ORDER_ENABLE*/
|
||
#endif/*ANC_COEFF_SAVE_ENABLE*/
|
||
break;
|
||
case 1:
|
||
if (((!anc_hdl->param.adaptive->lff_coeff) && anc_hdl->param.lff_en) || \
|
||
((!anc_hdl->param.adaptive->lfb_coeff) && anc_hdl->param.lfb_en) || \
|
||
((!anc_hdl->param.adaptive->rff_coeff) && anc_hdl->param.rff_en) || \
|
||
((!anc_hdl->param.adaptive->rfb_coeff) && anc_hdl->param.rfb_en)) {
|
||
g_printf("anc no adaptive data\n");
|
||
return 1;
|
||
}
|
||
if (tone_play) {
|
||
tone_play_index(IDEX_TONE_ANC_ADAPTIVE_COEFF, ANC_TONE_PREEMPTION);
|
||
}
|
||
#if ANC_MULT_ORDER_ENABLE
|
||
//载入场景参数-提供自适应部分成功时,匹配使用。
|
||
u8 scene_id = ANC_MULT_ADPTIVE_MATCH_USE_ID ? ANC_MULT_ADPTIVE_MATCH_USE_ID : anc_hdl->scene_id;
|
||
anc_mult_scene_set(scene_id);
|
||
#endif/*ANC_MULT_ORDER_ENABLE*/
|
||
audio_anc_ear_adaptive_param_init(&anc_hdl->param); //初始化自适应固定配置参数
|
||
#if ANC_CH & ANC_L_CH
|
||
if (result & ANC_ADAPTIVE_RESULT_LFF) {
|
||
user_anc_log("adaptive coeff set lff\n");
|
||
anc_hdl->param.gains.l_ffgain = (anc_hdl->adaptive_iir.lff_gain < 0) ? (0 - anc_hdl->adaptive_iir.lff_gain) : anc_hdl->adaptive_iir.lff_gain;
|
||
anc_hdl->param.lff_yorder = ANC_ADAPTIVE_FF_ORDER;
|
||
anc_hdl->param.lff_coeff = anc_hdl->param.adaptive->lff_coeff;
|
||
}
|
||
if (result & ANC_ADAPTIVE_RESULT_LFB) {
|
||
user_anc_log("adaptive coeff set lfb\n");
|
||
anc_hdl->param.gains.l_fbgain = (anc_hdl->adaptive_iir.lfb_gain < 0) ? (0 - anc_hdl->adaptive_iir.lfb_gain) : anc_hdl->adaptive_iir.lfb_gain;
|
||
anc_hdl->param.lfb_yorder = ANC_ADAPTIVE_FB_ORDER;
|
||
anc_hdl->param.lfb_coeff = anc_hdl->param.adaptive->lfb_coeff;
|
||
}
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
if (result & ANC_ADAPTIVE_RESULT_LCMP) {
|
||
user_anc_log("adaptive coeff set lcmp\n");
|
||
anc_hdl->param.gains.l_cmpgain = (anc_hdl->adaptive_iir.lcmp_gain < 0) ? (0 - anc_hdl->adaptive_iir.lcmp_gain) : anc_hdl->adaptive_iir.lcmp_gain;
|
||
anc_hdl->param.lcmp_coeff = anc_hdl->param.adaptive->lcmp_coeff;
|
||
anc_hdl->param.lcmp_yorder = ANC_ADAPTIVE_CMP_ORDER;
|
||
}
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
#endif/*ANC_CH*/
|
||
|
||
#if ANC_CH & ANC_R_CH
|
||
if (result & ANC_ADAPTIVE_RESULT_RFF) {
|
||
user_anc_log("adaptive coeff set rff\n");
|
||
anc_hdl->param.gains.r_ffgain = (anc_hdl->adaptive_iir.rff_gain < 0) ? (0 - anc_hdl->adaptive_iir.rff_gain) : anc_hdl->adaptive_iir.rff_gain;
|
||
anc_hdl->param.rff_yorder = ANC_ADAPTIVE_FF_ORDER;
|
||
anc_hdl->param.rff_coeff = anc_hdl->param.adaptive->rff_coeff;
|
||
}
|
||
if (result & ANC_ADAPTIVE_RESULT_RFB) {
|
||
user_anc_log("adaptive coeff set rfb\n");
|
||
anc_hdl->param.gains.r_fbgain = (anc_hdl->adaptive_iir.rfb_gain < 0) ? (0 - anc_hdl->adaptive_iir.rfb_gain) : anc_hdl->adaptive_iir.rfb_gain;
|
||
anc_hdl->param.rfb_yorder = ANC_ADAPTIVE_FB_ORDER;
|
||
anc_hdl->param.rfb_coeff = anc_hdl->param.adaptive->rfb_coeff;
|
||
}
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
if (result & ANC_ADAPTIVE_RESULT_RCMP) {
|
||
user_anc_log("adaptive coeff set rcmp\n");
|
||
anc_hdl->param.gains.r_cmpgain = (anc_hdl->adaptive_iir.rcmp_gain < 0) ? (0 - anc_hdl->adaptive_iir.rcmp_gain) : anc_hdl->adaptive_iir.rcmp_gain;
|
||
anc_hdl->param.rcmp_coeff = anc_hdl->param.adaptive->rcmp_coeff;
|
||
anc_hdl->param.rcmp_yorder = ANC_ADAPTIVE_CMP_ORDER;
|
||
}
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
#endif/*ANC_CH*/
|
||
|
||
break;
|
||
default:
|
||
return 1;
|
||
}
|
||
if ((anc_hdl->param.mode == ANC_ON) && update_flag) { //实时更新填入使用
|
||
os_taskq_post_msg("anc", 2, ANC_MSG_RESET, 1);
|
||
/* audio_anc_reset(&anc_hdl->param); */
|
||
}
|
||
|
||
//put_buf(param->lff_coeff, ANC_ADAPTIVE_FF_ORDER * 5 * 8);
|
||
//put_buf(param->lfb_coeff, ANC_ADAPTIVE_FB_ORDER * 5 * 8);
|
||
//put_buf(param->lcmp_coeff, ANC_ADAPTIVE_CMP_ORDER * 5 * 8);
|
||
return 0;
|
||
}
|
||
|
||
void audio_anc_adaptive_data_format(anc_adaptive_iir_t *iir)
|
||
{
|
||
if (anc_hdl->ear_adaptive_data_from == ANC_ADAPTIVE_DATA_EMPTY) {
|
||
anc_hdl->ear_adaptive_data_from = ANC_ADAPTIVE_DATA_FROM_VM;
|
||
if (anc_hdl->param.lff_en) {
|
||
anc_hdl->param.adaptive->lff_coeff = malloc(ANC_ADAPTIVE_FF_ORDER * sizeof(double) * 5);
|
||
}
|
||
if (anc_hdl->param.lfb_en) {
|
||
anc_hdl->param.adaptive->lfb_coeff = malloc(ANC_ADAPTIVE_FB_ORDER * sizeof(double) * 5);
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
anc_hdl->param.adaptive->lcmp_coeff = malloc(ANC_ADAPTIVE_CMP_ORDER * sizeof(double) * 5);
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
}
|
||
if (anc_hdl->param.rff_en) {
|
||
anc_hdl->param.adaptive->rff_coeff = malloc(ANC_ADAPTIVE_FF_ORDER * sizeof(double) * 5);
|
||
}
|
||
if (anc_hdl->param.rfb_en) {
|
||
anc_hdl->param.adaptive->rfb_coeff = malloc(ANC_ADAPTIVE_FB_ORDER * sizeof(double) * 5);
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
anc_hdl->param.adaptive->rcmp_coeff = malloc(ANC_ADAPTIVE_CMP_ORDER * sizeof(double) * 5);
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
}
|
||
|
||
anc_iir_t iir_lib; // 库与外部指针分离
|
||
#if ANC_CONFIG_LFF_EN
|
||
iir_lib.lff = anc_hdl->adaptive_iir.lff;
|
||
#endif/*ANC_CONFIG_LFF_EN*/
|
||
#if ANC_CONFIG_LFB_EN
|
||
iir_lib.lfb = anc_hdl->adaptive_iir.lfb;
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
iir_lib.lcmp = anc_hdl->adaptive_iir.lcmp;
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
#endif/*ANC_CONFIG_LFB_EN*/
|
||
#if ANC_CONFIG_RFF_EN
|
||
iir_lib.rff = anc_hdl->adaptive_iir.rff;
|
||
#endif/*ANC_CONFIG_RFF_EN*/
|
||
#if ANC_CONFIG_RFB_EN
|
||
iir_lib.rfb = anc_hdl->adaptive_iir.rfb;
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
iir_lib.rcmp = anc_hdl->adaptive_iir.rcmp;
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
#endif/*ANC_CONFIG_RFB_EN*/
|
||
audio_anc_adaptive_data_analsis(&iir_lib);
|
||
}
|
||
}
|
||
|
||
int audio_anc_adaptive_data_save(anc_adaptive_iir_t *iir)
|
||
{
|
||
printf("%s\n", __func__);
|
||
#if ANC_DEVELOPER_MODE_EN
|
||
//保存前做数据格式处理,避免数据异常导致上电转换数据死机
|
||
anc_hdl->ear_adaptive_data_from = ANC_ADAPTIVE_DATA_EMPTY;
|
||
audio_anc_adaptive_data_format(iir);
|
||
#endif/*ANC_DEVELOPER_MODE_EN*/
|
||
int ret = syscfg_write(CFG_ANC_ADAPTIVE_DATA_ID, (u8 *)iir, sizeof(anc_adaptive_iir_t));
|
||
/* printf("vmdata_num %d\n", *vmdata_num); */
|
||
/* put_buf((u8*)vmdata_FL, EAR_RECORD_MAX*25*4); */
|
||
/* put_buf((u8*)vmdata_FR, EAR_RECORD_MAX*25*4); */
|
||
g_printf("ret %d, %d\n", ret, sizeof(anc_adaptive_iir_t));
|
||
return ret;
|
||
}
|
||
|
||
|
||
int audio_anc_adaptive_data_read(anc_adaptive_iir_t *iir)
|
||
{
|
||
int ret = syscfg_read(CFG_ANC_ADAPTIVE_DATA_ID, (u8 *)iir, sizeof(anc_adaptive_iir_t));
|
||
if (ret == sizeof(anc_adaptive_iir_t)) { //能读取到参数, 则默认进入自适应
|
||
if (!CRC16((u8 *)iir, sizeof(anc_adaptive_iir_t))) { //读到的数全为0
|
||
r_printf("adaptive data is emtpy!!!\n");
|
||
return -1;
|
||
}
|
||
g_printf("do adaptive, ret %d\n", ret);
|
||
|
||
} else {
|
||
return -1;
|
||
//给予自适应默认参数
|
||
}
|
||
|
||
audio_anc_adaptive_poweron_catch_data(iir); //开机需确认左右耳
|
||
audio_anc_adaptive_data_format(iir);
|
||
audio_anc_coeff_adaptive_set(ANC_COEFF_MODE_ADAPTIVE, 0, 0);
|
||
return 0;
|
||
}
|
||
|
||
/*判断当前是否处于训练中*/
|
||
u8 audio_anc_adaptive_busy_get(void)
|
||
{
|
||
return anc_hdl->ear_adaptive_busy;
|
||
}
|
||
|
||
/* 自适应默认参数更新 */
|
||
void audio_anc_ear_adaptive_param_init(audio_anc_t *param)
|
||
{
|
||
param->gains.ff_1st_dcc = icsd_dcc[0];
|
||
param->gains.ff_2nd_dcc = icsd_dcc[1];
|
||
param->gains.fb_1st_dcc = icsd_dcc[2];
|
||
param->gains.fb_2nd_dcc = icsd_dcc[3];
|
||
}
|
||
|
||
void audio_anc_adaptive_fr_fail_fill(u8 *dat, u8 order, u8 result)
|
||
{
|
||
u8 fr_fail[13] = {0x2, 0x0, 0x0, 0xc8, 0x42, \
|
||
0x0, 0x0, 0x0, 0x0, \
|
||
0x0, 0x0, 0x80, 0x3f
|
||
};
|
||
if (!result) {
|
||
for (int i = 0; i < order; i++) {
|
||
memcpy(dat + 4 + i * 13, fr_fail, 13);
|
||
}
|
||
}
|
||
}
|
||
|
||
extern void anc_packet_show(anc_packet_data_t *packet);
|
||
void audio_anc_adaptive_data_packet(struct icsd_anc_tool_data *TOOL_DATA)
|
||
{
|
||
int len = TOOL_DATA->h_len;
|
||
int fb_yorder = TOOL_DATA->yorderb;
|
||
int ff_yorder = TOOL_DATA->yorderf;
|
||
int cmp_yorder = TOOL_DATA->yorderc;
|
||
|
||
int ff_dat_len = sizeof(anc_fr_t) * ff_yorder + 4;
|
||
int fb_dat_len = sizeof(anc_fr_t) * fb_yorder + 4;
|
||
int cmp_dat_len = sizeof(anc_fr_t) * cmp_yorder + 4;
|
||
anc_adaptive_iir_t *iir = &anc_hdl->adaptive_iir;
|
||
u8 *ff_dat, *fb_dat, *cmp_dat, *rff_dat, *rfb_dat, *rcmp_dat;
|
||
u8 result = icsd_anc_train_result_get(TOOL_DATA);
|
||
|
||
anc_hdl->adaptive_iir.result = result; //记录当前参数的保存结果;
|
||
|
||
#if ANC_CONFIG_LFF_EN
|
||
ff_dat = (u8 *)&iir->lff_gain;
|
||
audio_anc_fr_format(ff_dat, TOOL_DATA->data_out5, ff_yorder, ff_iir_type);
|
||
audio_anc_adaptive_fr_fail_fill(ff_dat, ff_yorder, (result & ANC_ADAPTIVE_RESULT_LFF));
|
||
#endif/*ANC_CONFIG_LFF_EN*/
|
||
#if ANC_CONFIG_LFB_EN
|
||
fb_dat = (u8 *)&iir->lfb_gain;
|
||
audio_anc_fr_format(fb_dat, TOOL_DATA->data_out4, fb_yorder, fb_iir_type);
|
||
audio_anc_adaptive_fr_fail_fill(fb_dat, fb_yorder, (result & ANC_ADAPTIVE_RESULT_LFB));
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
cmp_dat = (u8 *)&iir->lcmp_gain;
|
||
audio_anc_fr_format(cmp_dat, TOOL_DATA->data_out11, cmp_yorder, cmp_iir_type);
|
||
audio_anc_adaptive_fr_fail_fill(cmp_dat, cmp_yorder, (result & ANC_ADAPTIVE_RESULT_LCMP));
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
#endif/*ANC_CONFIG_LFB_EN*/
|
||
#if ANC_CONFIG_RFF_EN
|
||
rff_dat = (u8 *)&iir->rff_gain;
|
||
if (!ANC_CONFIG_LFF_EN) { //TWS 单R声道使用
|
||
ff_dat = rff_dat;
|
||
audio_anc_fr_format(ff_dat, TOOL_DATA->data_out5, ff_yorder, ff_iir_type);
|
||
audio_anc_adaptive_fr_fail_fill(ff_dat, ff_yorder, (result & ANC_ADAPTIVE_RESULT_LFF));
|
||
} else {
|
||
audio_anc_fr_format(rff_dat, TOOL_DATA->data_out10, ff_yorder, ff_iir_type);
|
||
audio_anc_adaptive_fr_fail_fill(rff_dat, ff_yorder, (result & ANC_ADAPTIVE_RESULT_RFF));
|
||
}
|
||
#endif/*ANC_CONFIG_RFF_EN*/
|
||
#if ANC_CONFIG_RFB_EN
|
||
rfb_dat = (u8 *)&iir->rfb_gain;
|
||
if (!ANC_CONFIG_LFB_EN) { //TWS 单R声道使用
|
||
fb_dat = rfb_dat;
|
||
audio_anc_fr_format(fb_dat, TOOL_DATA->data_out4, fb_yorder, fb_iir_type);
|
||
audio_anc_adaptive_fr_fail_fill(fb_dat, fb_yorder, (result & ANC_ADAPTIVE_RESULT_LFB));
|
||
} else {
|
||
audio_anc_fr_format(rfb_dat, TOOL_DATA->data_out9, fb_yorder, fb_iir_type);
|
||
audio_anc_adaptive_fr_fail_fill(rfb_dat, fb_yorder, (result & ANC_ADAPTIVE_RESULT_RFB));
|
||
}
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
rcmp_dat = (u8 *)&iir->rcmp_gain;
|
||
if (!ANC_CONFIG_LFB_EN) { //TWS 单R声道使用
|
||
cmp_dat = rcmp_dat;
|
||
audio_anc_fr_format(cmp_dat, TOOL_DATA->data_out11, cmp_yorder, cmp_iir_type);
|
||
audio_anc_adaptive_fr_fail_fill(cmp_dat, cmp_yorder, (result & ANC_ADAPTIVE_RESULT_LCMP));
|
||
} else {
|
||
audio_anc_fr_format(rcmp_dat, TOOL_DATA->data_out12, cmp_yorder, cmp_iir_type);
|
||
audio_anc_adaptive_fr_fail_fill(rcmp_dat, cmp_yorder, (result & ANC_ADAPTIVE_RESULT_RCMP));
|
||
}
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
#endif/*ANC_CONFIG_RFB_EN*/
|
||
|
||
if (anc_hdl->param.developer_mode) {
|
||
printf("-- len = %d\n", len);
|
||
printf("-- ff_yorder = %d\n", ff_yorder);
|
||
printf("-- fb_yorder = %d\n", fb_yorder);
|
||
printf("-- cmp_yorder = %d\n", cmp_yorder);
|
||
/* 先统一申请空间,因为下面不知道什么情况下调用函数 anc_data_catch 时令参数 init_flag 为1 */
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, NULL, 0, 0, 1);
|
||
|
||
#if (ANC_CH == (ANC_L_CH | ANC_R_CH)) //头戴式
|
||
r_printf("ANC ear-adaptive send data\n");
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->h_freq, len * 4, ANC_R_ADAP_FRE, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->data_out6, len * 8, ANC_R_ADAP_SZPZ, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->data_out7, len * 8, ANC_R_ADAP_PZ, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->data_out8, len * 8, ANC_R_ADAP_TARGET, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->data_out14, len * 8, ANC_R_ADAP_TARGET_CMP, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)rff_dat, ff_dat_len, ANC_R_FF_IIR, 0); //R_ff
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)rfb_dat, fb_dat_len, ANC_R_FB_IIR, 0); //R_fb
|
||
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->h_freq, len * 4, ANC_L_ADAP_FRE, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->data_out1, len * 8, ANC_L_ADAP_SZPZ, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->data_out2, len * 8, ANC_L_ADAP_PZ, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->data_out3, len * 8, ANC_L_ADAP_TARGET, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->data_out13, len * 8, ANC_L_ADAP_TARGET_CMP, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)ff_dat, ff_dat_len, ANC_L_FF_IIR, 0); //L_ff
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)fb_dat, fb_dat_len, ANC_L_FB_IIR, 0); //L_fb
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)cmp_dat, cmp_dat_len, ANC_L_CMP_IIR, 0); //L_cmp
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)rcmp_dat, cmp_dat_len, ANC_R_CMP_IIR, 0); //R_cmp
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
#else //入耳式
|
||
#if TCFG_USER_TWS_ENABLE
|
||
extern char bt_tws_get_local_channel(void);
|
||
if (bt_tws_get_local_channel() == 'R') {
|
||
r_printf("ANC ear-adaptive send data, ch:R\n");
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->h_freq, len * 4, ANC_R_ADAP_FRE, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->data_out1, len * 8, ANC_R_ADAP_SZPZ, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->data_out2, len * 8, ANC_R_ADAP_PZ, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->data_out3, len * 8, ANC_R_ADAP_TARGET, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->data_out13, len * 8, ANC_R_ADAP_TARGET_CMP, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)ff_dat, ff_dat_len, ANC_R_FF_IIR, 0); //R_ff
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)fb_dat, fb_dat_len, ANC_R_FB_IIR, 0); //R_fb
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)cmp_dat, cmp_dat_len, ANC_R_CMP_IIR, 0); //R_cmp
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
} else
|
||
#endif/*TCFG_USER_TWS_ENABLE*/
|
||
{
|
||
r_printf("ANC ear-adaptive send data, ch:L\n");
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->h_freq, len * 4, ANC_L_ADAP_FRE, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->data_out1, len * 8, ANC_L_ADAP_SZPZ, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->data_out2, len * 8, ANC_L_ADAP_PZ, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->data_out3, len * 8, ANC_L_ADAP_TARGET, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)TOOL_DATA->data_out13, len * 8, ANC_L_ADAP_TARGET_CMP, 0);
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)ff_dat, ff_dat_len, ANC_L_FF_IIR, 0); //L_ff
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)fb_dat, fb_dat_len, ANC_L_FB_IIR, 0); //L_fb
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)cmp_dat, cmp_dat_len, ANC_L_CMP_IIR, 0); //L_cmp
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
}
|
||
#endif /* ANC_CH == (ANC_L_CH | ANC_R_CH) */
|
||
|
||
}
|
||
|
||
}
|
||
|
||
//开机自适应数据拼包,预备工具读取
|
||
void audio_anc_adaptive_poweron_catch_data(anc_adaptive_iir_t *iir)
|
||
{
|
||
if (anc_hdl->param.developer_mode) {
|
||
int i;
|
||
int ff_dat_len = sizeof(anc_fr_t) * ANC_ADAPTIVE_FF_ORDER + 4;
|
||
int fb_dat_len = sizeof(anc_fr_t) * ANC_ADAPTIVE_FB_ORDER + 4;
|
||
int cmp_dat_len = sizeof(anc_fr_t) * ANC_ADAPTIVE_CMP_ORDER + 4;
|
||
u8 *ff_dat, *fb_dat, *cmp_dat, *rff_dat, *rfb_dat, *rcmp_dat;
|
||
audio_anc_t *param = &anc_hdl->param;
|
||
#if ANC_CONFIG_LFF_EN
|
||
ff_dat = (u8 *)&iir->lff_gain;
|
||
#endif/*ANC_CONFIG_LFF_EN*/
|
||
#if ANC_CONFIG_LFB_EN
|
||
fb_dat = (u8 *)&iir->lfb_gain;
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
cmp_dat = (u8 *)&iir->lcmp_gain;
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
#endif/*ANC_CONFIG_LFB_EN*/
|
||
#if ANC_CONFIG_RFF_EN
|
||
rff_dat = (u8 *)&iir->rff_gain;
|
||
if (ff_dat == NULL) { //TWS ANC_R_CH使用
|
||
ff_dat = rff_dat;
|
||
}
|
||
#endif/*ANC_CONFIG_RFF_EN*/
|
||
#if ANC_CONFIG_RFB_EN
|
||
rfb_dat = (u8 *)&iir->rfb_gain;
|
||
if (fb_dat == NULL) { //TWS ANC_R_CH使用
|
||
fb_dat = rfb_dat;
|
||
}
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
rcmp_dat = (u8 *)&iir->rcmp_gain;
|
||
if (cmp_dat == NULL) { //TWS ANC_R_CH使用
|
||
cmp_dat = rcmp_dat;
|
||
}
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
#endif/*ANC_CONFIG_RFB_EN*/
|
||
|
||
/* 先统一申请空间,因为下面不知道什么情况下调用函数 anc_data_catch 时令参数 init_flag 为1 */
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, NULL, 0, 0, 1);
|
||
#if (ANC_CH == (ANC_L_CH | ANC_R_CH)) //头戴式的耳机
|
||
r_printf("ANC ear-adaptive send data\n");
|
||
if (param->lff_en && param->rff_en) {
|
||
if (iir->result & ANC_ADAPTIVE_RESULT_LFF) {
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)ff_dat, ff_dat_len, ANC_L_FF_IIR, 0); //L_ff
|
||
}
|
||
if (iir->result & ANC_ADAPTIVE_RESULT_RFF) {
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)rff_dat, ff_dat_len, ANC_R_FF_IIR, 0); //R_ff
|
||
}
|
||
}
|
||
if (iir->result & ANC_ADAPTIVE_RESULT_LFB) {
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)fb_dat, fb_dat_len, ANC_L_FB_IIR, 0); //L_fb
|
||
}
|
||
if (iir->result & ANC_ADAPTIVE_RESULT_RFB) {
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)rfb_dat, fb_dat_len, ANC_R_FB_IIR, 0); //R_fb
|
||
}
|
||
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
if (iir->result & ANC_ADAPTIVE_RESULT_LCMP) {
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)cmp_dat, cmp_dat_len, ANC_L_CMP_IIR, 0); //L_cmp
|
||
}
|
||
if (iir->result & ANC_ADAPTIVE_RESULT_RCMP) {
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)rcmp_dat, cmp_dat_len, ANC_R_CMP_IIR, 0); //R_cmp
|
||
}
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
#else //入耳式的
|
||
#if TCFG_USER_TWS_ENABLE
|
||
extern char bt_tws_get_local_channel(void);
|
||
if (bt_tws_get_local_channel() == 'R') {
|
||
r_printf("ANC ear-adaptive send data, ch:R\n");
|
||
if (param->lff_en || param->rff_en) {
|
||
if (iir->result & ANC_ADAPTIVE_RESULT_RFF) {
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)ff_dat, ff_dat_len, ANC_R_FF_IIR, 0); //R_ff
|
||
}
|
||
}
|
||
if (iir->result & ANC_ADAPTIVE_RESULT_RFB) {
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)fb_dat, fb_dat_len, ANC_R_FB_IIR, 0); //R_fb
|
||
}
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
if (iir->result & ANC_ADAPTIVE_RESULT_RCMP) {
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)cmp_dat, cmp_dat_len, ANC_R_CMP_IIR, 0); //R_cmp
|
||
}
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
} else
|
||
#endif/*TCFG_USER_TWS_ENABLE*/
|
||
{
|
||
r_printf("ANC ear-adaptive send data, ch:L\n");
|
||
if (param->lff_en || param->rff_en) {
|
||
if (iir->result & ANC_ADAPTIVE_RESULT_LFF) {
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)ff_dat, ff_dat_len, ANC_L_FF_IIR, 0); //L_ff
|
||
}
|
||
}
|
||
if (iir->result & ANC_ADAPTIVE_RESULT_LFB) {
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)fb_dat, fb_dat_len, ANC_L_FB_IIR, 0); //L_fb
|
||
}
|
||
#if ANC_EAR_ADAPTIVE_CMP_EN
|
||
if (iir->result & ANC_ADAPTIVE_RESULT_LCMP) {
|
||
anc_adaptive_data = anc_data_catch(anc_adaptive_data, (u8 *)cmp_dat, cmp_dat_len, ANC_L_CMP_IIR, 0); //L_cmp
|
||
}
|
||
#endif/*ANC_EAR_ADAPTIVE_CMP_EN*/
|
||
}
|
||
#endif /* ANC_CH == (ANC_L_CH | ANC_R_CH) */
|
||
}
|
||
}
|
||
|
||
//左右参数映射
|
||
void audio_anc_param_map(u8 coeff_en, u8 gain_en)
|
||
{
|
||
#if TCFG_USER_TWS_ENABLE && (ANC_CH != (ANC_L_CH | ANC_R_CH))
|
||
if (anc_hdl->param.developer_mode) { //开发者模式左右耳区分使用参数
|
||
if (coeff_en && (!anc_hdl->param.lff_coeff || !anc_hdl->param.rff_coeff || \
|
||
!anc_hdl->param.lfb_coeff || !anc_hdl->param.rfb_coeff)) {
|
||
#if ANC_DEVELOPER_MODE_EN
|
||
ASSERT(0, "(ERROR)ANC adaptive coeff map %x, %x, %x, %x, Maybe anc_coeff.bin is ERR!", \
|
||
anc_hdl->param.lff_coeff, anc_hdl->param.rff_coeff, \
|
||
anc_hdl->param.lfb_coeff, anc_hdl->param.rfb_coeff);
|
||
#else
|
||
user_anc_log("(ERROR)ANC adaptive coeff map %x, %x, %x, %x, Maybe anc_coeff.bin is ERR!", \
|
||
anc_hdl->param.lff_coeff, anc_hdl->param.rff_coeff, \
|
||
anc_hdl->param.lfb_coeff, anc_hdl->param.rfb_coeff);
|
||
#endif/*ANC_DEVELOPER_MODE_EN*/
|
||
}
|
||
if ((ANC_CH == ANC_L_CH) && (bt_tws_get_local_channel() == 'R')) {
|
||
user_anc_log("ANC MAP TWS_RIGHT_CHANNEL\n");
|
||
if (gain_en) {
|
||
anc_hdl->param.gains.l_ffgain = anc_hdl->param.gains.r_ffgain;
|
||
anc_hdl->param.gains.l_fbgain = anc_hdl->param.gains.r_fbgain;
|
||
anc_hdl->param.gains.l_transgain = anc_hdl->param.gains.r_transgain;
|
||
anc_hdl->param.gains.l_cmpgain = anc_hdl->param.gains.r_cmpgain;
|
||
anc_hdl->param.gains.l_ffmic_gain = anc_hdl->param.gains.r_ffmic_gain;
|
||
anc_hdl->param.gains.l_fbmic_gain = anc_hdl->param.gains.r_fbmic_gain;
|
||
anc_hdl->param.gains.gain_sign = (anc_hdl->param.gains.gain_sign >> 4);
|
||
}
|
||
if (coeff_en) {
|
||
anc_hdl->param.lff_coeff = anc_hdl->param.rff_coeff;
|
||
anc_hdl->param.lfb_coeff = anc_hdl->param.rfb_coeff;
|
||
anc_hdl->param.ltrans_coeff = anc_hdl->param.rtrans_coeff;
|
||
anc_hdl->param.lcmp_coeff = anc_hdl->param.rcmp_coeff;
|
||
|
||
anc_hdl->param.lff_yorder = anc_hdl->param.rff_yorder;
|
||
anc_hdl->param.lfb_yorder = anc_hdl->param.rfb_yorder;
|
||
anc_hdl->param.ltrans_yorder = anc_hdl->param.rtrans_yorder;
|
||
anc_hdl->param.lcmp_yorder = anc_hdl->param.rcmp_yorder;
|
||
}
|
||
} else if ((ANC_CH == ANC_R_CH) && (bt_tws_get_local_channel() == 'L')) {
|
||
user_anc_log("ANC MAP TWS_LEFT_CHANNEL\n");
|
||
if (gain_en) {
|
||
anc_hdl->param.gains.r_ffgain = anc_hdl->param.gains.l_ffgain;
|
||
anc_hdl->param.gains.r_fbgain = anc_hdl->param.gains.l_fbgain;
|
||
anc_hdl->param.gains.r_transgain = anc_hdl->param.gains.l_transgain;
|
||
anc_hdl->param.gains.r_cmpgain = anc_hdl->param.gains.l_cmpgain;
|
||
anc_hdl->param.gains.r_ffmic_gain = anc_hdl->param.gains.l_ffmic_gain;
|
||
anc_hdl->param.gains.r_fbmic_gain = anc_hdl->param.gains.l_fbmic_gain;
|
||
anc_hdl->param.gains.gain_sign = (anc_hdl->param.gains.gain_sign << 4);
|
||
}
|
||
if (coeff_en) {
|
||
anc_hdl->param.rff_coeff = anc_hdl->param.lff_coeff;
|
||
anc_hdl->param.rfb_coeff = anc_hdl->param.lfb_coeff;
|
||
anc_hdl->param.rtrans_coeff = anc_hdl->param.ltrans_coeff;
|
||
anc_hdl->param.rcmp_coeff = anc_hdl->param.lcmp_coeff;
|
||
|
||
anc_hdl->param.rff_yorder = anc_hdl->param.lff_yorder;
|
||
anc_hdl->param.rfb_yorder = anc_hdl->param.lfb_yorder;
|
||
anc_hdl->param.rtrans_yorder = anc_hdl->param.ltrans_yorder;
|
||
anc_hdl->param.rcmp_yorder = anc_hdl->param.lcmp_yorder;
|
||
}
|
||
}
|
||
}
|
||
#endif/*TCFG_USER_TWS_ENABLE*/
|
||
|
||
}
|
||
|
||
//临时接口
|
||
void icsd_audio_adc_mic_open(u8 mic_idx, u8 gain, u16 sr, u8 mic_2_dac)
|
||
{
|
||
|
||
}
|
||
|
||
u8 anc_ear_adaptive_seq_get(void)
|
||
{
|
||
if (anc_hdl) {
|
||
return anc_hdl->ear_adaptive_seq;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
void anc_ear_adaptive_forced_exit(void)
|
||
{
|
||
if (anc_hdl) {
|
||
if (anc_hdl->ear_adaptive_busy) {
|
||
icsd_anc_forced_exit();
|
||
anc_tone_stop();
|
||
}
|
||
}
|
||
}
|
||
|
||
//ANC自适应训练失败处理回调函数
|
||
void audio_anc_adaptive_fail_callback(u8 anc_err)
|
||
{
|
||
#if (RCSP_ADV_EN && RCSP_ADV_ANC_VOICE && RCSP_ADV_ADAPTIVE_NOISE_REDUCTION)
|
||
extern void set_adaptive_noise_reduction_reset_callback(u8 result);
|
||
set_adaptive_noise_reduction_reset_callback(!anc_err);
|
||
#endif
|
||
if (anc_err == 0) {
|
||
/* user_anc_log("ANC_ADAPTIVE SUCCESS==========================\n"); */
|
||
}
|
||
if (anc_err & ANC_ERR_LR_BALANCE) {
|
||
user_anc_log("ANC_ERR_LR_BALANCE==========================\n");
|
||
}
|
||
if (anc_err & ANC_ERR_SOUND_PRESSURE) {
|
||
user_anc_log("ANC_ERR_SOUND_PRESSURE==========================\n");
|
||
}
|
||
if (anc_err & ANC_ERR_SHAKE) {
|
||
user_anc_log("ANC_ERR_SHAKE==========================\n");
|
||
}
|
||
}
|
||
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
|
||
#if ANC_MULT_ORDER_ENABLE
|
||
|
||
void audio_anc_mult_scene_set(u16 scene_id, u8 update_flag)
|
||
{
|
||
user_anc_log(" audio_anc_mult scene_id set %d\n", scene_id);
|
||
if (audio_anc_mult_scene_id_check(scene_id)) {
|
||
user_anc_log("anc_mult_scene id set err id = %d", scene_id);
|
||
return;
|
||
}
|
||
anc_hdl->scene_id = scene_id;
|
||
#if ANC_EAR_ADAPTIVE_EN
|
||
if (anc_hdl->ear_adaptive_busy) {
|
||
anc_ear_adaptive_forced_exit();
|
||
return;
|
||
}
|
||
//非自适应训练状态,切场景自动切回普通参数
|
||
anc_hdl->param.anc_coeff_mode = ANC_COEFF_MODE_NORMAL;
|
||
#endif/*ANC_EAR_ADAPTIVE_EN*/
|
||
if ((anc_hdl->param.mode != ANC_OFF) && update_flag && \
|
||
!anc_hdl->mode_switch_lock) { //实时更新填入使用
|
||
anc_mult_scene_set(scene_id);
|
||
os_taskq_post_msg("anc", 2, ANC_MSG_RESET, 1);
|
||
}
|
||
}
|
||
|
||
u8 audio_anc_mult_scene_get(void)
|
||
{
|
||
return anc_hdl->scene_id;
|
||
}
|
||
|
||
void audio_anc_mult_scene_max_set(u8 scene_cnt)
|
||
{
|
||
anc_hdl->scene_max = scene_cnt;
|
||
}
|
||
|
||
u8 audio_anc_mult_scene_max_get(void)
|
||
{
|
||
return anc_hdl->scene_max;
|
||
}
|
||
|
||
void audio_anc_mult_scene_switch(u8 tone_flag)
|
||
{
|
||
static u8 cnt = 1;
|
||
if (cnt < audio_anc_mult_scene_max_get()) {
|
||
cnt++;
|
||
} else {
|
||
cnt = 1;
|
||
}
|
||
if (tone_flag) {
|
||
tone_play_index(IDEX_TONE_NUM_0 + cnt, 0);
|
||
}
|
||
audio_anc_mult_scene_set(cnt, 1);
|
||
}
|
||
#endif/*ANC_MULT_ORDER_ENABLE*/
|
||
|
||
//ANC产测/调试模式
|
||
extern struct adc_platform_data adc_data;
|
||
void audio_anc_prodution_mode_set(u8 mode)
|
||
{
|
||
//产测 or 调试模式 关闭非必要的流程
|
||
if (mode && (!anc_hdl->param.production_mode)) { //0->1
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
/*关闭ACOUSTIC_DETECTOR所有模块*/
|
||
if (audio_icsd_adt_is_running()) {
|
||
audio_icsd_adt_close_all();
|
||
}
|
||
adc_data.anc_adt_en = 0; //关闭adc_ch绑定,否则产测使用ADC中断数据会异常
|
||
#endif/* TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN*/
|
||
} else if (!mode && (anc_hdl->param.production_mode)) { //1->0
|
||
#if TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN
|
||
adc_data.anc_adt_en = 1; //恢复adc_ch绑定
|
||
#endif/* TCFG_AUDIO_ANC_ACOUSTIC_DETECTOR_EN*/
|
||
}
|
||
anc_hdl->param.production_mode = mode;
|
||
}
|
||
|
||
#endif/*TCFG_AUDIO_ANC_ENABLE*/
|