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

回采的数据是在中断函数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 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

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

注意:由于给算法的回采数据和mic数据需要以下要求:

1.回采数据要优先于mic采集到的喇叭数据给算法,即因果性,为了实现这个,做了mic的缓存区,并判断缓冲区的数据长度来实现缓存mic的操作,最后实现mic后于回采数据

2.回采数据和mic数据同时给算法的时候,回采数据和mic数据的每次采集的相位差要一样,所以为了防止回采中拿中断的突发性,我给回采的数据加了缓存区

#include "include.h"
#include "func.h"
#include "karaok_list.h"
#include "sfr.h"

#if SYS_KARAOK_EN
// #define AUDIO_DEBUG

#ifdef AUDIO_DEBUG
static u32 aec_ticks AT(.mic_algo.buf);
static u32 aec_sampling_rate AT(.mic_algo.buf);
static u32 p_algo_ticks AT(.mic_algo.buf);
static u32 n_algo_ticks AT(.mic_algo.buf);
static u32 lastTimestamp AT(.mic_algo.buf);
static u32 timeInterval AT(.mic_algo.buf);
static u32 mic_ticks AT(.mic_algo.buf);
static u32 mic_sampling_rate AT(.mic_algo.buf);
AT(.com_text)
const char karaok_sdadc_process_str[] = "samples = %d, sampling_rate = %d, channel = %d,  usb_connect = %d, bt_phone = %d, bt_is_16k = %d, algo_time = %d timeInterval = %d\n";
#endif


/*****************************************************************************
 * 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 + 1] AT(.uac_out.buf);
short mic_stm_buff[MIC_48K_EACH_SAMPLES_LEN * 4 + 1] AT(.uac_out.buf);
au_stm_t aw_aec_stm AT(.aec_mic.buf);
au_stm_t aw_mic_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_aec_stm, 0, sizeof(au_stm_t));
    aw_aec_stm.buf = (u8 *)aec_mic_stm_buff;
    aw_aec_stm.size = sizeof(aec_mic_stm_buff);
    aw_aec_stm.len = 0;
    aw_aec_stm.wptr = (u8 *)aec_mic_stm_buff;
    aw_aec_stm.rptr = (u8 *)aec_mic_stm_buff;

    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_aec_stm, (u8 *)aec_mic_buff, sizeof(aec_mic_buff));
#ifdef AUDIO_DEBUG
    aec_sampling_rate += size/4;//双通道,16位,byte,48k
    if (tick_check_expire(aec_ticks, 1000)) {
        aec_ticks = tick_get();
        my_printf(au0_dma_output_str, aec_sampling_rate, size);//采样率只可以设置成48k或者44.1k
        aec_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;

    memset(mic_stm_buff, 0, sizeof(mic_stm_buff));
    memset(&aw_mic_stm, 0, sizeof(au_stm_t));
    aw_mic_stm.buf = (u8 *)mic_stm_buff;
    aw_mic_stm.size = sizeof(mic_stm_buff);
    aw_mic_stm.len = 0;
    aw_mic_stm.wptr = (u8 *)mic_stm_buff;
    aw_mic_stm.rptr = (u8 *)mic_stm_buff;

}

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.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;
    if (sys_cb.mic_mute == 0)
    {
        puts_stm_buf(&aw_mic_stm, (u8 *)ptr, MIC_48K_EACH_SAMPLES_LEN *  sizeof(short));

        gets_stm_buf(&aw_aec_stm, (u8 *)(mic_buff + MIC_SAMPLES_AEC_STEP), AEC_MIC_48K_EACH_SAMPLES_LEN * sizeof(short));
        if (gets_stm_len(&aw_mic_stm) >= MIC_48K_EACH_SAMPLES_LEN *  sizeof(short) * 4) {
            gets_stm_buf(&aw_mic_stm, (u8 *)(mic_buff + MIC_SAMPLES_MIC_STEP), MIC_48K_EACH_SAMPLES_LEN * sizeof(short));
        }else{
            memset(mic_buff + MIC_SAMPLES_MIC_STEP, 0, MIC_48K_EACH_SAMPLES_LEN * sizeof(short));
        }

#ifdef AUDIO_DEBUG
        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
        
    }else{
        memset(mic_buff, 0, sizeof(mic_buff));
        memset(interleaved_channel_buff, 0, sizeof(interleaved_channel_buff));
    }



    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
    mic_sampling_rate += samples;
    if (tick_check_expire(mic_ticks, 1000)) {
        mic_ticks = tick_get();
        my_printf(karaok_sdadc_process_str, samples, mic_sampling_rate, channel, 
        dev_is_online(DEV_USBPC), get_karaok_sco_sta(), bt_sco_is_msbc(), n_algo_ticks - p_algo_ticks, timeInterval);
        mic_sampling_rate = 0;
    }
#endif//AUDIO_DEBUG

}

#endif //SYS_KARAOK_EN

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

文武先生hh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值