新手上路
- 积分
- 26
- 金钱
- 26
- 注册时间
- 2019-4-5
- 在线时间
- 6 小时
|
最近要做个无线语音的,抄了正点原子代码,稍微修改下,利用32自身内存做缓冲,测试录音和播放功能,使用ADPCM模式,核心代码如下:
void recoder_enter_rec_mode(u16 agc)
{
VS_WR_Cmd(SPI_BASS,0x0000);
VS_WR_Cmd(SPI_AICTRL0,12); //设置采样率,设置为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,2); //左通道(MIC单声道输入),ADPCM录音
VS_WR_Cmd(SPI_CLOCKF,0X2000); //设置VS10XX的时钟,MULT:2倍频;ADD:不允许;CLK:12.288Mhz
VS_WR_Cmd(SPI_MODE,0x1804); //0x1804:MIC,录音激活 0x5804 INE_IN,录音激活
delay_ms(5); //等待至少1.35ms
VS_Load_Patch((u16*)wav_plugin,40);//VS1053的WAV录音需要patch
}
//初始化WAV头.
void recoder_wav_init(__WaveHeader* wavhead) //初始化WAV头
{
wavhead->riff.ChunkID=0X46464952; //"RIFF"
wavhead->riff.ChunkSize=0; //还未确定,最后需要计算
wavhead->riff.Format=0X45564157; //"WAVE"
wavhead->fmt.ChunkID=0X20746D66; //"fmt "
wavhead->fmt.ChunkSize=20; //块大小
wavhead->fmt.AudioFormat=0X11; //0X01,表示PCM;0X11,表示IMA ADPCM
wavhead->fmt.NumOfChannels=1; //单声道
wavhead->fmt.SampleRate=8000; //采样率,单位:Hz,
wavhead->fmt.ByteRate=0xfd7; //字节速率,
wavhead->fmt.BlockAlign=0x100; //块对齐
wavhead->fmt.BitsPerSample=4; //单个采样数据大小;4位ADPCM,设置为4
wavhead->fmt.ByteExtraData=2; //固定
wavhead->fmt.ExtraData=0x1f9; //固定
wavhead->fact.ChunkID=0x74636166; //"fact"
wavhead->fact.ChunkSize=4; //块大小
// wavhead->fact.NumOfSamples=0x00971514; //采样数量
wavhead->data.ChunkID=0X61746164; //"data"
wavhead->data.ChunkSize=0; //数据大小,还需要计算
}
void paly_voice(u8 *voiceData, u16 len)
{
u16 i = 0;
do
{
if(VS_Send_MusicData(voiceData+i)==0)
i+=32;
}while(i<len);
}
void recoder_play(void)
{
u8 rval=0;
__WaveHeader *wavhead=0;
u8 *voiceBuf, *dataBuf; //数据内存
u16 w, sectorsize = 0;
u16 idx=0, cnt=0;
u8 recagc=8; //默认增益为4
dataBuf=mymalloc(SRAMIN, 512 * 24 + sizeof(__WaveHeader));
if(dataBuf==NULL)rval=1;
wavhead=(__WaveHeader*)dataBuf;
voiceBuf = dataBuf + sizeof(__WaveHeader);
recoder_wav_init(wavhead); //初始化wav数据
while(rval ==0)
{
LED0 = !LED0;
recoder_enter_rec_mode(1024*recagc);
while(VS_RD_Reg(SPI_HDAT1)>>8){}; //等到buf 较为空闲再开始
idx = 0;
sectorsize = 0;
while(sectorsize < 24)
{
cnt = 0;
w=VS_RD_Reg(SPI_HDAT1);
if((w>=256)&&(w<896))
{
while(cnt<512) //一次读取512字节
{
w=VS_RD_Reg(SPI_HDAT0);
voiceBuf[idx++]=w>>8; //ADPCM与PCM格式顺序相反,ADPCM先高后低
voiceBuf[idx++]=w&0XFF;
cnt += 2;
}
sectorsize++;
}
}
LED0 = !LED0;
wavhead->riff.ChunkSize=sectorsize * 512 + 36;
wavhead->data.ChunkSize=sectorsize * 512; //数据大小
VS_Soft_Reset(); //软复位
VS_Set_All();
VS_Reset_DecodeTime(); //复位解码时间
VS_SPI_SpeedHigh(); //高速
paly_voice(dataBuf, sectorsize * 512 + sizeof(__WaveHeader));
// USART1_Send_Data(recbuf, 512);
}
myfree(SRAMIN,dataBuf);
}
相比PCM模式,数据压缩4倍左右,灯亮起录音约3秒,接着熄灭播放,循环下去,声音清晰。
|
|