iis tx rx说明文档
📎 原始文档:https://www.kdocs.cn/l/ctKffR95q0lW iis tx rx说明文档
代码链接
【金山文档】 ac701n_earphone_release_v1.5.2_beta_iis_txrx
https://kdocs.cn/l/cfxv8yGQKP96
修改板级角色
apps\earphone\board\br28\board_jl701n_demo_cfg.h
#define TCFG_BOARD_ROLE 1//板级角色,0:TX无蓝牙, 1:RX有蓝牙
//0:TX无蓝牙,开机跑IIS task,通话跑第三方算法,dac输出立体声
//1:RX有蓝牙,开tws,开机跑蓝牙模式,通话跑杰理单mic DNS,mic数据从IIS来,dac输出单左声道
还有其他配置与TCFG_BOARD_ROLE相关,具体看代码
mic相关数据接口
- 获取mic的adc采样数据 cpu\br28\iis_tx.c
static void adc_mic_output_handler(void *priv, s16 *data, int len)
假设开的mic是mic0和mic1,data的数据结构就是
| 16bit | 16bit | 16bit | 16bit | 16bit | 16bit | 16bit | 16bit | ...... |
|---|---|---|---|---|---|---|---|---|
| mic0 | mic1 | mic0 | mic1 | mic0 | mic1 | mic0 | mic1 | ...... |
假设开的mic是mic1和mic2,data的数据结构就是
| 16bit | 16bit | 16bit | 16bit | 16bit | 16bit | 16bit | 16bit | ...... |
|---|---|---|---|---|---|---|---|---|
| mic1 | mic2 | mic1 | mic2 | mic1 | mic2 | mic1 | mic2 | ...... |
- mic数据输出到算法处理
audio_aec_inbuf(data, len);//将数据填到主mic数据缓存
audio_aec_inbuf_ref(data, len);//将数据填到参考mic数据缓存
- 添加第三方mic算法处理 在apps\earphone\aec\br28\audio_aec_demo.c文件中找到如下函数,在函数中添加第三方算法处理
/*
*********************************************************************
* Audio AEC RUN
* Description: AEC数据处理核心
* Arguments : in 主mic数据
* inref 参考mic数据(双mic降噪有用)
* inref1 参考mic数据(3 mic降噪有用)
* ref speaker参考数据
* out 数据输出
* Return : 数据运算输出长度
* Note(s) : 在这里实现AEC_core
*********************************************************************
*/
static int audio_aec_run(s16 *in, s16 *inref, s16 *inref1, s16 *ref, s16 *out, u16 points)
- 获取mic算法处理的数据 cpu\br28\iis_tx.c
/**
* @brief mic算法输出回调
*
* @param data 处理后的数据
* @param len 数据长度
* @return int
*/
int aec_output(s16 *data, u16 len)
数据输出接口
- 相关宏控制 cpu\br28\iis_tx.c
#define MIC_TO_AEC_EN (IIS_MODE) //mic信号输出到通话AEC,非0有效
#define MIC_TO_DAC_EN (!IIS_MODE) //mic信号输出到DAC,非0有效
#define AUX_TO_DAC_EN (!IIS_MODE) //aux信号输出到DAC,非0有效
- mic输出到IIS 在cpu\br28\iis_tx.c,aec_output函数中
s16 temp[len];
audio_pcm_mono_to_dual(temp, data, len >> 1);//mic的单声道转为IIS立体声
len <<= 1;
wlen = cbuf_write(&iis_tx.mic_out_cbuf, temp, len);//to iis tx
- mic输出到dac 在cpu\br28\iis_tx.c,aec_output函数中,推送数据到"audio_task"任务
wlen = cbuf_write(&iis_tx.to_audio_l_cbuf, data, len);//to audio l buff
os_sem_set(&iis_tx.to_dac_sem, 0);
os_sem_post(&iis_tx.to_dac_sem);
在cpu\br28\iis_tx.c,audio_data_task函数中,读取数据,拼接为立体声或者混合为单声道,再写到dac输出
#if MIC_TO_AEC_EN || MIC_TO_DAC_EN
l_len = cbuf_get_data_len(&iis_tx.to_audio_l_cbuf);
if(l_len > sizeof(l_buf)){
l_len = sizeof(l_buf);
}
l_len = cbuf_read(&iis_tx.to_audio_l_cbuf, l_buf, l_len);//读取mic数据
#endif
//转为单声道
pcm_dual_to_single(l_buf, l_buf, l_len);
len >>= 1;
#if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)
//立体声输出时,mic做左声道,aux做右声道,可自由调整
for (int i = 0; i < len/2; i++)
{
stereo_buf[2 * i] = l_buf[i];
stereo_buf[2 * i + 1] = r_buf[i];
}
len <<= 1;
#else
//单声道输出时,mic+aux混合
for (int i = 0; i < len/2; i++)
{
stereo_buf[i] = (l_buf[i] + r_buf[i]);// / 2;//aux和mic都输出时要除以二,否则容易破音,可自由调整
}
#endif
#if MIC_TO_DAC_EN || AUX_TO_DAC_EN
int wlen = 0;
u16 ot_cnt = 1000;
while (wlen != len && --ot_cnt)
{
wlen += sound_pcm_dev_write(&iis_tx.dac_ch, ((u8 *)stereo_buf) + wlen, len - wlen);//输出到dac
}
#endif
- 输出到aec算法(杰理自带算法) iis接收mic数据然后输出到aec
在cpu\br28\iis_tx.c,handle_rx函数中,iis收到数据推送到"audio_task"任务
cbuf_write(&iis_tx.to_audio_l_cbuf, buf, len);//输出到audio task任务
if(iis_tx.need_resume){
iis_tx.need_resume = 0;
os_sem_set(&iis_tx.to_dac_sem, 0);
os_sem_post(&iis_tx.to_dac_sem);
}
在cpu\br28\iis_tx.c,audio_data_task函数中,立体声转单声道,采样率转为16K,然后推送到aec
#if MIC_TO_AEC_EN || MIC_TO_DAC_EN
l_len = cbuf_get_data_len(&iis_tx.to_audio_l_cbuf);
if(l_len > sizeof(l_buf)){
l_len = sizeof(l_buf);
}
l_len = cbuf_read(&iis_tx.to_audio_l_cbuf, l_buf, l_len);//读取mic数据
#endif
//转为单声道
pcm_dual_to_single(l_buf, l_buf, l_len);
len >>= 1;
#if MIC_TO_AEC_EN
u16 aec_len = len;
if(sw_src_opt && sw_src_p){
aec_len = sw_src_opt->run(sw_src_p, l_buf, aec_len >> 1, output);//变采样到16K
aec_len <<= 1;
}
cbuf_write(&aec_cbuf, output, aec_len);
if(cbuf_get_data_len(&aec_cbuf) >= 512){//够256点才能输出到aec
cbuf_read(&aec_cbuf, aec_inbuf[aec_index], 512);
audio_aec_inbuf(aec_inbuf[aec_index], 512);
#if(MIC_ADC_CH == 2)
audio_aec_inbuf_ref(aec_inbuf[aec_index], 512);
#endif
if(++aec_index > 2){
aec_index = 0;
}
}
#endif