回采的数据是在中断函数au0_dma_isr_data_output里面给的,而给算法的时候是在主程序karaok_sdadc_process,这样子就会出现中断给的数据和当前的mic帧不匹配,或者说每次的差值不一定,算法就会有问题,解决办法是讲回采数据放入队列,给个缓冲区来循环取放值,这样子缓存去的数据先进先出,就可以实现存取长时间的数据,在这长时间的情况下,一定能轮到另外一边主程序karaok_sdadc_process运行,以拿到数据
错误模型如下,没加循环缓存
#include "include.h"
#include "func.h"
#include "karaok_list.h"#if SYS_KARAOK_EN
#define AUDIO_DEBUG/****************************************************************************** Module :*****************************************************************************/
extern u8 mdac_spr_hold; //开启将MDAC的采样率固定为跟LR一样
void bt_aec_process(u8 *ptr, u32 samples, int ch_mode);
void bt_sco_tx_process(u8 *ptr, u32 samples, int ch_mode);static karaok_list_cfg_t karaok_list_cfg AT(.func_list.cfg.karaok);static module_link_list_str_t karaok_link_list_tbl[] = {
/* 模块类型, 使能, 初始化, 输入接口, 设置输出*/{KARAOK_INPUT_TYPE, 1, karaok_audio_init, karaok_audio_input, karaok_audio_output_callback_set}, // {MIC_MSC_HIFI4_EFFECT_TYPE, 1, mic_hifi4_effect_audio_init, mic_hifi4_effect_audio_buf_input, mic_hifi4_effect_audio_output_callback_set},// {SRC1_OUT_TYPE, 1, src1_out_init, src1_out_audio_input, NULL}, {SRC2_OUT_TYPE, 1, src2_out_init, src2_out_audio_input, NULL},
};
#define MICBUF_LENGTH 4096
WEAK uint32_t micbuf_length_weak = MICBUF_LENGTH;
u8 ude_micbuf[MICBUF_LENGTH] AT(.ude.aubuf);//这个变量也要跟buf一样大小
short mic_buff[MIC_SAMPLES_LEN] AT(.mic_algo.buf);
short aec_mic_buff[AEC_MIC_48K_EACH_SAMPLES_LEN] AT(.mic_algo.buf);
short aec222_mic_buff[AEC_MIC_48K_EACH_SAMPLES_LEN] AT(.usb_222dev.buf);
#ifdef TEST_MODE
short interleaved_channel_buff[MIC_SAMPLES_16K_STEP] AT(.mic_algo.buf);
#endif#if DAC_DMA_OUTPUT_EN || FUNC_REC_EN
#define DAC_DMA_OUTPUT_SAMPLES MIC_EACH_BUFF_LEN //byte not shortu8 au0_dma_buff[DAC_DMA_OUTPUT_SAMPLES*4] AT(.au0out_buf); //DMA OUT的中断缓存,至少为 au0_dma_start_do 的 samples*2*(1<<is_24bits)*2 Bytevoid au0_dma_start_do(u32 type, u8 *au0_dma_addr, u16 samples, u8 is_24bits);AT(.text.au0dma) WEAK
void au0_dma_start(u32 type)
{au0_dma_start_do(type, au0_dma_buff, DAC_DMA_OUTPUT_SAMPLES, 0);
}#if DAC_DMA_OUTPUT_EN#ifdef AUDIO_DEBUG
AT(.com_text.au0dma1)
const char au0_dma_output_str[] = "au0_size_1s_sampling_rate:%d, size:%d\n";
#endifAT(.com_text.au0dma)
void au0_dma_isr_data_output(void *ptr/*16bit stereo*/, u32 size/*Byte*/)//采样率只可以设置成48k或者44.1k
{// for (u32 i = MIC_SAMPLES_AEC_STEP, j = 0; i < MIC_SAMPLES_LEN; i+=3, j+=2){// mic_buff[i] = (*((short *)ptr+j) + *((short *)ptr+j+1))/2;// }// for (u32 i = MIC_SAMPLES_AEC_STEP, j = 0; i < MIC_SAMPLES_16K_STEP; i++, j+=2){// mic_buff[i] = (*((short *)ptr+j) + *((short *)ptr+j+1))/2;// } for (u32 i = 0, j = 0; i < AEC_MIC_48K_EACH_SAMPLES_LEN; i++, j+=2){aec_mic_buff[i] = (*((short *)ptr+j) + *((short *)ptr+j+1))/2;}
#ifdef AUDIO_DEBUGstatic u32 ticks = 0;static u32 sampling_rate = 0;sampling_rate += size/4;//双通道,16位,byte,48kif (tick_check_expire(ticks, 1000)) {ticks = tick_get();my_printf(au0_dma_output_str, sampling_rate, size);//采样率只可以设置成48k或者44.1ksampling_rate = 0;}
#endif }
#endif // DAC_DMA_OUTPUT_EN
#endif // DAC_DMA_OUTPUT_EN || FUNC_REC_ENAT(.com_text.func_list.karaok)
void my_algo_process(short *ptr)
{ for(int i = 0; i < MIC_48K_EACH_SAMPLES_LEN; i++){ptr[i] = 10 * ptr[i + MIC_SAMPLES_MIC_STEP];//algo} for(int i = 0, j = 0; i < MIC_48K_EACH_SAMPLES_LEN; i+=3, j++){ptr[j + MIC_SAMPLES_16K_STEP] = ptr[i];//16k} for(int i = 0, j = 0; i < MIC_48K_EACH_SAMPLES_LEN; i+=6, j++){ptr[j + MIC_SAMPLES_8K_STEP] = ptr[i];//8k}
}#ifdef TEST_MODE
AT(.com_text.func_list.karaok)
void interleaved_channel(short *scr, short *dst)
{ for(int i = 0, j = 0; i < MIC_48K_EACH_SAMPLES_LEN; i++, j+=3){dst[j] = scr[i + MIC_SAMPLES_ALGO_STEP];//algodst[j + 1] = scr[i + MIC_SAMPLES_MIC_STEP];//micdst[j + 2] = scr[i + MIC_SAMPLES_AEC_STEP];//aec}
}
#endifAT(.com_text.func_list.karaok)
void karaok_audio_init(u8 sample_rate, u16 samples, u8 channel)
{memset(&karaok_list_cfg, 0, sizeof(karaok_list_cfg_t));karaok_list_cfg.sample_rate = sample_rate;my_printf("%s: MDACVOLCON %x\n", __func__, MDACVOLCON);my_printf("%s: sample_rate %d\n", __func__, sample_rate);// bsp_change_md_volume(4, 1);//调节mdac输出音量my_printf("%s: MDACVOLCON %x\n", __func__, MDACVOLCON);my_printf("%s: bt_sco_is_msbd %d\n", __func__, bt_sco_is_msbc());//判断蓝牙录音的采样率:1(16k),0(8k)// mdac_spr_set(SPR_16000);mdac_spr_hold = 0;}AT(.com_text.func_list.karaok)
void karaok_audio_input(u8 *ptr, u32 samples, int ch_mode, u32 is_24bits, void *param)
{if (karaok_list_cfg.callback) {karaok_list_cfg.callback((u8 *)mic_buff, samples, MIC_CHANNEL, is_24bits, param);}
}AT(.text.src)
void karaok_audio_output_callback_set(audio_callback_t callback)
{karaok_list_cfg.callback = callback;
}AT(.text.bsp.bsp.unicast)
void karaok_module_init(u8 sample_rate)
{
// my_printf("%s\n", __func__);my_printf("%s: sample_rate %d\n", __func__, sample_rate);module_link_list_init(karaok_link_list_tbl,sizeof(karaok_link_list_tbl)/sizeof(module_link_list_str_t), sample_rate, 10, 2);
}AT(.text.bsp.bsp.unicast)
void karaok_module_exit(void)
{
// my_printf("%s\n", __func__);src1_fade_out();
}//AT(.com_text.karaok.proc1)
//const char k_sdadc_str[] = "get_karaok_sco_sta():%d, sample_cnt:%d\n";
AT(.com_text.karaok.proc)
void karaok_sdadc_process(u8 *ptr, u32 samples, int ch_mode)
{u8 channel = (ch_mode&BIT(0)) + 1;u8 in_24bits = (ch_mode&BIT(1)) ? 1 : 0;memcpy(mic_buff + MIC_SAMPLES_MIC_STEP, ptr, MIC_48K_EACH_SAMPLES_LEN * sizeof(short));memcpy(mic_buff + MIC_SAMPLES_AEC_STEP, aec_mic_buff, MIC_48K_EACH_SAMPLES_LEN * sizeof(short));
#ifdef AUDIO_DEBUGstatic u32 p_algo_ticks = 0;static u32 n_algo_ticks = 0;static u32 lastTimestamp = 0;static u32 timeInterval = 0; p_algo_ticks = tick_get();if (lastTimestamp != 0) {timeInterval = p_algo_ticks - lastTimestamp;}lastTimestamp = p_algo_ticks;
#endif //AUDIO_DEBUGhifi4_effect_mic_process_new(XTP_EFFECT_ID_SPEAKER, (u8 *)mic_buff, MIC_SAMPLES_LEN, MIC_CHANNEL, 0);// my_algo_process(mic_buff);#ifdef AUDIO_DEBUGn_algo_ticks = tick_get();
#endif//AUDIO_DEBUGif (dev_is_online(DEV_USBPC)) {
#ifdef TEST_MODEinterleaved_channel(mic_buff, interleaved_channel_buff);usbmic_sdadc_process((u8 *)interleaved_channel_buff, samples, MIC_TEST_CHANNEL);
#elseusbmic_sdadc_process((u8 *)mic_buff, samples, MIC_CHANNEL);
#endif//TEST_MODE }audio_process_param_t audio_process_param;audio_process_param.link_id = INPUT_MIC_ID;if (get_karaok_sco_sta()) {if (bt_sco_is_msbc()) {bt_sco_tx_process((u8 *)(mic_buff + MIC_SAMPLES_16K_STEP), MIC_16K_EACH_SAMPLES_LEN, 0);}else{bt_sco_tx_process((u8 *)(mic_buff + MIC_SAMPLES_8K_STEP), MIC_8K_EACH_SAMPLES_LEN, 0);}}// mdac_spr_set(SPR_16000);karaok_audio_input((u8 *)mic_buff, samples, channel, in_24bits, &audio_process_param);#ifdef AUDIO_DEBUG static u32 ticks = 0; static u32 sampling_rate = 0;sampling_rate += samples; if (tick_check_expire(ticks, 1000)) {ticks = tick_get();printf("%s: samples = %d, sampling_rate = %d, channel = %d, usb_connect = %d, bt_phone = %d, bt_is_16k = %d, algo_time = %d timeInterval = %d\n", __func__, samples, sampling_rate, channel, dev_is_online(DEV_USBPC), get_karaok_sco_sta(), bt_sco_is_msbc(), n_algo_ticks - p_algo_ticks, timeInterval);sampling_rate = 0;}
#endif//AUDIO_DEBUG }#endif //SYS_KARAOK_EN
正确模型如下,加循环缓存
#include "include.h"
#include "func.h"
#include "karaok_list.h"#if SYS_KARAOK_EN
// #define AUDIO_DEBUG/****************************************************************************** Module :*****************************************************************************/
extern u8 mdac_spr_hold; //开启将MDAC的采样率固定为跟LR一样
void bt_aec_process(u8 *ptr, u32 samples, int ch_mode);
void bt_sco_tx_process(u8 *ptr, u32 samples, int ch_mode);static karaok_list_cfg_t karaok_list_cfg AT(.func_list.cfg.karaok);static module_link_list_str_t karaok_link_list_tbl[] = {
/* 模块类型, 使能, 初始化, 输入接口, 设置输出*/{KARAOK_INPUT_TYPE, 1, karaok_audio_init, karaok_audio_input, karaok_audio_output_callback_set}, // {MIC_MSC_HIFI4_EFFECT_TYPE, 1, mic_hifi4_effect_audio_init, mic_hifi4_effect_audio_buf_input, mic_hifi4_effect_audio_output_callback_set},// {SRC1_OUT_TYPE, 1, src1_out_init, src1_out_audio_input, NULL}, {SRC2_OUT_TYPE, 1, src2_out_init, src2_out_audio_input, NULL},
};
#define MICBUF_LENGTH 4096
WEAK uint32_t micbuf_length_weak = MICBUF_LENGTH;
u8 ude_micbuf[MICBUF_LENGTH] AT(.ude.aubuf);//这个变量也要跟buf一样大小
short mic_buff[MIC_SAMPLES_LEN] AT(.mic_algo.buf);
short aec_mic_stm_buff[AEC_MIC_48K_EACH_SAMPLES_LEN * 3] AT(.aec_mic.buf);
au_stm_t aw_stm AT(.aec_mic.buf);
#ifdef TEST_MODE
short interleaved_channel_buff[MIC_SAMPLES_16K_STEP] AT(.mic_algo.buf);
#endif#if DAC_DMA_OUTPUT_EN || FUNC_REC_EN
#define DAC_DMA_OUTPUT_SAMPLES MIC_EACH_BUFF_LEN //byte not shortu8 au0_dma_buff[DAC_DMA_OUTPUT_SAMPLES*4] AT(.au0out_buf); //DMA OUT的中断缓存,至少为 au0_dma_start_do 的 samples*2*(1<<is_24bits)*2 Bytevoid au0_dma_start_do(u32 type, u8 *au0_dma_addr, u16 samples, u8 is_24bits);AT(.text.au0dma) WEAK
void au0_dma_start(u32 type)
{memset(aec_mic_stm_buff, 0, sizeof(aec_mic_stm_buff));memset(&aw_stm, 0, sizeof(au_stm_t));aw_stm.buf = (u8 *)aec_mic_stm_buff;aw_stm.size = sizeof(aec_mic_stm_buff);aw_stm.len = 0;aw_stm.wptr = (u8 *)aec_mic_stm_buff;aw_stm.rptr = (u8 *)aec_mic_stm_buff;//初始化循环bufau0_dma_start_do(type, au0_dma_buff, DAC_DMA_OUTPUT_SAMPLES, 0);
}#if DAC_DMA_OUTPUT_EN#ifdef AUDIO_DEBUG
AT(.com_text.au0dma1)
const char au0_dma_output_str[] = "au0_size_1s_sampling_rate:%d, size:%d\n";
#endifAT(.com_text.au0dma)
void au0_dma_isr_data_output(void *ptr/*16bit stereo*/, u32 size/*Byte*/)//采样率只可以设置成48k或者44.1k
{short aec_mic_buff[AEC_MIC_48K_EACH_SAMPLES_LEN]; for (u32 i = 0, j = 0; i < AEC_MIC_48K_EACH_SAMPLES_LEN; i++, j+=2){aec_mic_buff[i] = (*((short *)ptr+j) + *((short *)ptr+j+1))/2;} puts_stm_buf(&aw_stm, (u8 *)aec_mic_buff, sizeof(aec_mic_buff));//数据放入循环buf
#ifdef AUDIO_DEBUGstatic u32 ticks = 0;static u32 sampling_rate = 0;sampling_rate += size/4;//双通道,16位,byte,48kif (tick_check_expire(ticks, 1000)) {ticks = tick_get();my_printf(au0_dma_output_str, sampling_rate, size);//采样率只可以设置成48k或者44.1ksampling_rate = 0;}
#endif }
#endif // DAC_DMA_OUTPUT_EN
#endif // DAC_DMA_OUTPUT_EN || FUNC_REC_ENAT(.com_text.func_list.karaok)
void my_algo_process(short *ptr)
{ for(int i = 0; i < MIC_48K_EACH_SAMPLES_LEN; i++){ptr[i] = 10 * ptr[i + MIC_SAMPLES_MIC_STEP];//algo} for(int i = 0, j = 0; i < MIC_48K_EACH_SAMPLES_LEN; i+=3, j++){ptr[j + MIC_SAMPLES_16K_STEP] = ptr[i];//16k} for(int i = 0, j = 0; i < MIC_48K_EACH_SAMPLES_LEN; i+=6, j++){ptr[j + MIC_SAMPLES_8K_STEP] = ptr[i];//8k}
}#ifdef TEST_MODE
AT(.com_text.func_list.karaok)
void interleaved_channel(short *scr, short *dst)
{ for(int i = 0, j = 0; i < MIC_48K_EACH_SAMPLES_LEN; i++, j+=3){dst[j] = scr[i + MIC_SAMPLES_ALGO_STEP];//algodst[j + 1] = scr[i + MIC_SAMPLES_MIC_STEP];//micdst[j + 2] = scr[i + MIC_SAMPLES_AEC_STEP];//aec}
}
#endifAT(.com_text.func_list.karaok)
void karaok_audio_init(u8 sample_rate, u16 samples, u8 channel)
{memset(&karaok_list_cfg, 0, sizeof(karaok_list_cfg_t));karaok_list_cfg.sample_rate = sample_rate;my_printf("%s: MDACVOLCON %x\n", __func__, MDACVOLCON);my_printf("%s: sample_rate %d\n", __func__, sample_rate);// bsp_change_md_volume(4, 1);//调节mdac输出音量my_printf("%s: MDACVOLCON %x\n", __func__, MDACVOLCON);my_printf("%s: bt_sco_is_msbd %d\n", __func__, bt_sco_is_msbc());//判断蓝牙录音的采样率:1(16k),0(8k)// mdac_spr_set(SPR_16000);mdac_spr_hold = 0;}AT(.com_text.func_list.karaok)
void karaok_audio_input(u8 *ptr, u32 samples, int ch_mode, u32 is_24bits, void *param)
{if (karaok_list_cfg.callback) {karaok_list_cfg.callback((u8 *)mic_buff, samples, MIC_CHANNEL, is_24bits, param);}
}AT(.text.src)
void karaok_audio_output_callback_set(audio_callback_t callback)
{karaok_list_cfg.callback = callback;
}AT(.text.bsp.bsp.unicast)
void karaok_module_init(u8 sample_rate)
{
// my_printf("%s\n", __func__);my_printf("%s: sample_rate %d\n", __func__, sample_rate);module_link_list_init(karaok_link_list_tbl,sizeof(karaok_link_list_tbl)/sizeof(module_link_list_str_t), sample_rate, 10, 2);
}AT(.text.bsp.bsp.unicast)
void karaok_module_exit(void)
{
// my_printf("%s\n", __func__);src1_fade_out();
}//AT(.com_text.karaok.proc1)
//const char k_sdadc_str[] = "get_karaok_sco_sta():%d, sample_cnt:%d\n";
AT(.com_text.karaok.proc)
void karaok_sdadc_process(u8 *ptr, u32 samples, int ch_mode)
{u8 channel = (ch_mode&BIT(0)) + 1;u8 in_24bits = (ch_mode&BIT(1)) ? 1 : 0;memcpy(mic_buff + MIC_SAMPLES_MIC_STEP, ptr, MIC_48K_EACH_SAMPLES_LEN * sizeof(short));gets_stm_buf(&aw_stm, (u8 *)(mic_buff + MIC_SAMPLES_AEC_STEP), AEC_MIC_48K_EACH_SAMPLES_LEN * sizeof(short));//从循环buf拿数据
#ifdef AUDIO_DEBUGstatic u32 p_algo_ticks = 0;static u32 n_algo_ticks = 0;static u32 lastTimestamp = 0;static u32 timeInterval = 0; p_algo_ticks = tick_get();if (lastTimestamp != 0) {timeInterval = p_algo_ticks - lastTimestamp;}lastTimestamp = p_algo_ticks;
#endif //AUDIO_DEBUG// hifi4_effect_mic_process_new(XTP_EFFECT_ID_SPEAKER, (u8 *)mic_buff, MIC_SAMPLES_LEN, MIC_CHANNEL, 0);my_algo_process(mic_buff);#ifdef AUDIO_DEBUGn_algo_ticks = tick_get();
#endif//AUDIO_DEBUGif (dev_is_online(DEV_USBPC)) {
#ifdef TEST_MODEinterleaved_channel(mic_buff, interleaved_channel_buff);usbmic_sdadc_process((u8 *)interleaved_channel_buff, samples, MIC_TEST_CHANNEL);
#elseusbmic_sdadc_process((u8 *)mic_buff, samples, MIC_CHANNEL);
#endif//TEST_MODE }audio_process_param_t audio_process_param;audio_process_param.link_id = INPUT_MIC_ID;if (get_karaok_sco_sta()) {if (bt_sco_is_msbc()) {bt_sco_tx_process((u8 *)(mic_buff + MIC_SAMPLES_16K_STEP), MIC_16K_EACH_SAMPLES_LEN, 0);}else{bt_sco_tx_process((u8 *)(mic_buff + MIC_SAMPLES_8K_STEP), MIC_8K_EACH_SAMPLES_LEN, 0);}}// mdac_spr_set(SPR_16000);karaok_audio_input((u8 *)mic_buff, samples, channel, in_24bits, &audio_process_param);#ifdef AUDIO_DEBUG static u32 ticks = 0; static u32 sampling_rate = 0;sampling_rate += samples; if (tick_check_expire(ticks, 1000)) {ticks = tick_get();printf("%s: samples = %d, sampling_rate = %d, channel = %d, usb_connect = %d, bt_phone = %d, bt_is_16k = %d, algo_time = %d timeInterval = %d\n", __func__, samples, sampling_rate, channel, dev_is_online(DEV_USBPC), get_karaok_sco_sta(), bt_sco_is_msbc(), n_algo_ticks - p_algo_ticks, timeInterval);sampling_rate = 0;}
#endif//AUDIO_DEBUG }#endif //SYS_KARAOK_EN