当前位置: 首页 > news >正文

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

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

相关文章:

  • RabbitMQ基础
  • 在 Mac 上通过“启动转换助理”安装 Windows 10
  • swiftUI中的可变属性和封装
  • huawei services HK华为云服务
  • mysql启动报错:ERROR! The server quit without updating PID file
  • 从0开始回顾MySQL --- 三范式与表设计
  • 腾讯云对象存储的在Java使用步骤介绍
  • Vue学习日记 Day7 —— json-server工具、基于VueCli自定义创建项目、postcss插件
  • C语言中volatile关键字的用法
  • 华为配置敏捷分布式SFN漫游实验
  • 【Golang】golang使用三方SDK操作容器指南
  • 爬虫(五)
  • 面向对象编程第二式:继承 (Java篇)
  • oppo前端开发一面
  • 24计算机考研调剂 | 重庆工商大学
  • 【Amaple教程】5. 插件
  • css布局,左右固定中间自适应实现
  • ES6 学习笔记(一)let,const和解构赋值
  • export和import的用法总结
  • HTTP请求重发
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • maven工程打包jar以及java jar命令的classpath使用
  • pdf文件如何在线转换为jpg图片
  • Promise初体验
  • Python中eval与exec的使用及区别
  • sessionStorage和localStorage
  • vue.js框架原理浅析
  • win10下安装mysql5.7
  • Zepto.js源码学习之二
  • 阿里云Kubernetes容器服务上体验Knative
  • 包装类对象
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 规范化安全开发 KOA 手脚架
  • 基于 Babel 的 npm 包最小化设置
  • 前端相关框架总和
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • 摩拜创始人胡玮炜也彻底离开了,共享单车行业还有未来吗? ...
  • ​LeetCode解法汇总518. 零钱兑换 II
  • ​决定德拉瓦州地区版图的关键历史事件
  • ​香农与信息论三大定律
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • (k8s中)docker netty OOM问题记录
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (四) 虚拟摄像头vivi体验
  • (四)库存超卖案例实战——优化redis分布式锁
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • (转载)CentOS查看系统信息|CentOS查看命令
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析
  • .NET Framework 4.6.2改进了WPF和安全性
  • .NET 回调、接口回调、 委托
  • .net 简单实现MD5
  • .NET 中什么样的类是可使用 await 异步等待的?
  • .netcore如何运行环境安装到Linux服务器