音频数据如果在中断中会随机给的那就放入队列或者缓冲区;队列缓冲区对音频的作用

回采的数据是在中断函数au0_dma_isr_data_output里面给的,而给算法的时候是在主程序karaok_sdadc_process,这样子就会出现中断给的数据和当前的mic帧不匹配,或者说每次的差值不一定,算法就会有问题,解决办法是讲回采数据放入队列,给个缓冲区来循环取放值,这样子缓存去的数据先进先出,就可以实现存取长时间的数据,在这长时间的情况下,一定能轮到另外一边主程序karaok_sdadc_process运行,以拿到数据

错误模型如下,没加循环缓存

cpp 复制代码
#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 short

u8 au0_dma_buff[DAC_DMA_OUTPUT_SAMPLES*4] AT(.au0out_buf);     //DMA OUT的中断缓存,至少为 au0_dma_start_do 的 samples*2*(1<<is_24bits)*2 Byte

void 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";
#endif

AT(.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_DEBUG
    static u32 ticks = 0;
    static u32 sampling_rate = 0;
    sampling_rate += size/4;//双通道,16位,byte,48k
    if (tick_check_expire(ticks, 1000)) {
        ticks = tick_get();
        my_printf(au0_dma_output_str, sampling_rate, size);//采样率只可以设置成48k或者44.1k
        sampling_rate = 0;
    }
#endif   

}
#endif // DAC_DMA_OUTPUT_EN
#endif // DAC_DMA_OUTPUT_EN || FUNC_REC_EN


AT(.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];//algo
        dst[j + 1] = scr[i + MIC_SAMPLES_MIC_STEP];//mic
        dst[j + 2] = scr[i + MIC_SAMPLES_AEC_STEP];//aec
    }         
}
#endif

AT(.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_DEBUG
    static 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_DEBUG
    n_algo_ticks = tick_get(); 
#endif//AUDIO_DEBUG

    if (dev_is_online(DEV_USBPC)) {
#ifdef TEST_MODE
    interleaved_channel(mic_buff, interleaved_channel_buff);
    usbmic_sdadc_process((u8 *)interleaved_channel_buff, samples, MIC_TEST_CHANNEL);
#else
    usbmic_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

正确模型如下,加循环缓存

cpp 复制代码
#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 short

u8 au0_dma_buff[DAC_DMA_OUTPUT_SAMPLES*4] AT(.au0out_buf);     //DMA OUT的中断缓存,至少为 au0_dma_start_do 的 samples*2*(1<<is_24bits)*2 Byte

void 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;//初始化循环buf

    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";
#endif

AT(.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_DEBUG
    static u32 ticks = 0;
    static u32 sampling_rate = 0;
    sampling_rate += size/4;//双通道,16位,byte,48k
    if (tick_check_expire(ticks, 1000)) {
        ticks = tick_get();
        my_printf(au0_dma_output_str, sampling_rate, size);//采样率只可以设置成48k或者44.1k
        sampling_rate = 0;
    }
#endif   

}
#endif // DAC_DMA_OUTPUT_EN
#endif // DAC_DMA_OUTPUT_EN || FUNC_REC_EN


AT(.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];//algo
        dst[j + 1] = scr[i + MIC_SAMPLES_MIC_STEP];//mic
        dst[j + 2] = scr[i + MIC_SAMPLES_AEC_STEP];//aec
    }         
}
#endif

AT(.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_DEBUG
    static 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_DEBUG
    n_algo_ticks = tick_get(); 
#endif//AUDIO_DEBUG

    if (dev_is_online(DEV_USBPC)) {
#ifdef TEST_MODE
    interleaved_channel(mic_buff, interleaved_channel_buff);
    usbmic_sdadc_process((u8 *)interleaved_channel_buff, samples, MIC_TEST_CHANNEL);
#else
    usbmic_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
相关推荐
DogDaoDao2 小时前
Windows 环境下 vscode 配置 C/C++ 环境
c语言·c++·windows·vscode·gcc·mingw-w64
wacpguo2 小时前
windows环境下载ubuntu22.04发行版源码,提示invalid path aux.c
windows
清水白石0082 小时前
如何在windows中使用mac,要详细的教程
windows·macos
内蒙深海大鲨鱼3 小时前
win/mac常用命令
windows·macos
bmseven3 小时前
windows远程桌面连接ubuntu
linux·windows·ubuntu
newxtc3 小时前
【爱给网-注册安全分析报告-无验证方式导致安全隐患】
前端·chrome·windows·安全·媒体
FutureUniant3 小时前
GitHub每日最火火火项目(9.21)
人工智能·计算机视觉·ai·github·音视频
yzkkdhh4 小时前
【Windows 同时安装 MySQL5 和 MySQL8 - 详细图文教程】
windows·mysql·idea
数据蛙苹果恢复专家5 小时前
无损转换:严选4个视频mkv转mp4格式的方法
音视频
EasyCVR5 小时前
视频存储EasyCVR视频监控汇聚管理平台设备录像下载报错404是什么原因?
音视频·视频监控·监控视频接入·视频质量诊断·视频诊断