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]
---------------------------------
拿到应该也不会,变快的话,肯定是wav解码码率没设置好
也就是数据头,没搞好。
一周热门 更多>