求助 ALIENTEKMiniSTM32V3.1开发板+VS1053模块 播放录音的语速太快 而且声音有点失真

2019-10-14 23:19发布


1、我用 原子哥的 Ministm32开发板 + vs1053模块, 按照网上的例程,能够实现录音与播放。
2、网上的例子都是将VS1053读取回来的数据以WAV的格式存储到SD卡中,然后再读取SD卡中的录音文件XXX.WAV播放。
3、我现在想把VS1053采集回来的数据以字节的方式,通过串口发送给另一块配有VS1053的板子,然后实现一块板子实时录音,一块板子实时播放。
4、我现在只在一块板子上做实验,录音键按下,就是把VS1053采集回来的数据以txt的方式存储到带有fatfs文件系统的SD卡中,命名为123.txt,录音键松开,录音完毕。然后当按下播放键,现初始化VS1053,然后发送wav头给1053,在去SD卡中读取保存的录音文件,丢给1053,现发现播放出来的录音语速特别的快,而且有点失真。搞几天了,一直没有效果。麻烦懂得大侠们指导下。万分感谢谢谢。

录音部分 [mw_shl_code=c,true]if(KEY1 == 0) { f_unlink("123.txt"); Show_Str(60,70,200,16,"Speaking",16,0); VS_Init();//初始化 recoder_enter_rec_mode(1024*4); //4倍增益 while(VS_RD_Reg(SPI_HDAT1)>>8); //等到buf 较为空闲再开始 delay_ms(1); while(KEY1 == 0) { read_pcm(); //读取VS1053 每读取一次 为512个字节 if(PCM_flag==1) { u16 i = 0,j=0; res1 = f_open(file,"123.txt", FA_OPEN_ALWAYS | FA_WRITE); if(res1 == FR_OK) { f_lseek(file, f_size(file));//将文件指针移动到文件末尾 for(j= 0;j<16;j++)//将512个字节 分成16行 每行32个 方便发送时一行读取32个字节 { for(i= 0;i<32;i++) { sprintf(wBuf,"%4d", recbuf[i+32*j]); f_puts(wBuf, file); } f_printf(file, "%s", " "); } f_close(file); } PCM_flag = 0; } LED0 = !LED0; }[/mw_shl_code]
播放录音代码
[mw_shl_code=c,true]if(KEY0 == 0) { u16 i = 0; while(KEY0 == 0) // { VS_Init();//初始化 VS_HD_Reset(); //硬复位 VS_Soft_Reset(); //软复位 VS_Set_Vol(220); //设置音量 VS_Set_All(); //设置音量等信息 send_wav_header(); //发送wav头 VS_SPI_SpeedHigh(); //设置速度 delay_ms(2); res2 = f_open(file,"123.txt", FA_OPEN_ALWAYS | FA_READ| FA_WRITE); if(res2 == FR_OK) { while(f_gets(rBuf, 200,file))//去123.txt中一行一行读取数据 直到数据读取完毕 { for(i= 0;i<32;i++)//将读取出来的包含32个字节的字符串 分解为32个字节数值 { sendBuf = atoi(&rBuf[i*4]);//将字符串转化为 数值 } VS_Send_MusicData(sendBuf);//发送32个字节 } f_close(file); } printf("发送完毕 "); } }[/mw_shl_code] wav头
 //文件头44字节
u8 wav_header[64] = {0X52,0X49,0X46,0X46,//="RIFF"
                    //0XD4,0X86,0X01,0X00,//文件总长 - 8
                      0XF7,0XFF,0XFF,0XFF,//文件总长 - 8
                    0X57,0X41,0X56,0X45,//"WAVE"
                     0X66,0X6D,0X74,0X20,//"fmt"标记
 
                    0X10,0X00,0X00,0X00, //0x10
                    0X01,0X00,//0x01
                    0X01,0X00,//0x01
                    0X40,0X1F,0X00,0X00,//采样率为8KHZ
                    0X80,0X3E,0X00,0X00,//2*采样率
                     0X02,0X00,//0X02
                     0X10,0X00,//0X10
                     0X64,0X61,0X74,0X61,//"data"
                    0XD3,0XFF,0XFF,0XFF
                    // 0XA0,0X86,0X01,0X00
                     };//WAV文件头 



[mw_shl_code=c,true]//激活PCM 录音模式 //agc:0,自动增益.1024相当于1倍,512相当于0.5倍,最大值65535=64倍 void recoder_enter_rec_mode(u16 agc) { //如果是IMA ADPCM,采样率计算公式如下: //采样率=CLKI/256*d; //假设d=0,并2倍频,外部晶振为12.288M.那么Fc=(2*12288000)/256*6=16Khz //如果是线性PCM,采样率直接就写采样值 VS_WR_Cmd(SPI_BASS,0x0000); VS_WR_Cmd(SPI_AICTRL0,8000); //设置采样率,设置为8Khz VS_WR_Cmd(SPI_AICTRL1,agc); //设置增益,0,自动增益.1024相当于1倍,512相当于0.5倍,最大值65535=64倍 VS_WR_Cmd(SPI_AICTRL2,0); //设置增益最大值,0,代表最大值65536=64X VS_WR_Cmd(SPI_AICTRL3,6); //左通道(MIC单声道输入) VS_WR_Cmd(SPI_CLOCKF,0X2000); //设置VS10XX的时钟,MULT:2倍频;ADD:不允许;CLK:12.288Mhz VS_WR_Cmd(SPI_MODE,0x1804); //MIC,录音激活 delay_ms(5); //等待至少1.35ms VS_Load_Patch((u16*)wav_plugin,40);//VS1053的WAV录音需要patch } //**********************jiaqing*************** //读取PCM,将512字节的数据存储到数据缓冲区recbuf //**********************jiaqing*************** void read_pcm(void) { u16 w; //数据长度 u16 idx=0; w=VS_RD_Reg(SPI_HDAT1); if((w>=256)&&(w<896)) { PCM_flag = 1; idx=0; while(idx<512) //一次读取512字节 { w=VS_RD_Reg(SPI_HDAT0); recbuf[idx++]=w&0XFF; recbuf[idx++]=w>>8; }; } }[/mw_shl_code]


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
20条回答
lixiaoxu186
2019-10-15 20:47

您好,原子哥,您说的数据头的解码率没设置好,就是WAV头没有设置对吧。
这个是我的WAV头 [mw_shl_code=c,true]wav头 //文件头44字节 u8 wav_header[64] = {0X52,0X49,0X46,0X46,//="RIFF" 0XF7,0XFF,0XFF,0XFF,//文件总长 - 8 0X57,0X41,0X56,0X45,//"WAVE" 0X66,0X6D,0X74,0X20,//"fmt"标记 0X10,0X00,0X00,0X00, //0x10 0X01,0X00,//0x01 0X01,0X00,//0x01 0X40,0X1F,0X00,0X00,//采样率为8KHZ 0X80,0X3E,0X00,0X00,//2*采样率 0X02,0X00,//0X02 0X10,0X00,//0X10 0X64,0X61,0X74,0X61,//"data" 0XD3,0XFF,0XFF,0XFF//文件总长 - 44 };//WAV文件头 [/mw_shl_code] 下面是我按您的例子配置的
[mw_shl_code=c,true]//激活PCM 录音模式 //agc:0,自动增益.1024相当于1倍,512相当于0.5倍,最大值65535=64倍 void recoder_enter_rec_mode(u16 agc) { //如果是IMA ADPCM,采样率计算公式如下: //采样率=CLKI/256*d; //假设d=0,并2倍频,外部晶振为12.288M.那么Fc=(2*12288000)/256*6=16Khz //如果是线性PCM,采样率直接就写采样值 VS_WR_Cmd(SPI_BASS,0x0000); VS_WR_Cmd(SPI_AICTRL0,8000); //设置采样率,设置为8Khz VS_WR_Cmd(SPI_AICTRL1,agc); //设置增益,0,自动增益.1024相当于1倍,512相当于0.5倍,最大值65535=64倍 VS_WR_Cmd(SPI_AICTRL2,0); //设置增益最大值,0,代表最大值65536=64X VS_WR_Cmd(SPI_AICTRL3,6); //左通道(MIC单声道输入) VS_WR_Cmd(SPI_CLOCKF,0X2000); //设置VS10XX的时钟,MULT:2倍频;ADD:不允许;CLK:12.288Mhz VS_WR_Cmd(SPI_MODE,0x1804); //MIC,录音激活 delay_ms(5); //等待至少1.35ms VS_Load_Patch((u16*)wav_plugin,40);//VS1053的WAV录音需要patch }[/mw_shl_code]  
麻烦您看下,还有那些我没注意到的吗?
非常期待您的答复~


一周热门 更多>