本 科 毕 业 设 计
VS_WR_Cmd(SPI_MODE,0x1804); //MIC,录音激活 delay_ms(5); //等待至少1.35ms
第 30 页 共 33页
VS_Load_Patch((u16*)wav_plugin,40);//VS1053的WAV录音需要patch }
//初始化WAV头.
void recoder_wav_init(__WaveHeader* wavhead) //初始化WAV头 {
wavhead->riff.ChunkID=0X46464952; //\
wavhead->riff.ChunkSize=0; //还未确定,最后需要计算 wavhead->riff.Format=0X45564157; //\ wavhead->fmt.ChunkID=0X20746D66; //\
wavhead->fmt.ChunkSize=16; //大小为16个字节
wavhead->fmt.AudioFormat=0X01; //0X01,表示PCM;0X01,表示IMA ADPCM wavhead->fmt.NumOfChannels=1; //单声道
wavhead->fmt.SampleRate=8000; //8Khz采样率 采样速率 wavhead->fmt.ByteRate=wavhead->fmt.SampleRate*2;//16位,即2个字节 wavhead->fmt.BlockAlign=2; //块大小,2个字节为一个块 wavhead->fmt.BitsPerSample=16; //16位PCM wavhead->data.ChunkID=0X61746164; //\
wavhead->data.ChunkSize=0; //数据大小,还需要计算 } //录音机
//所有录音文件,均保存在SD卡RECORDER文件夹内. u8 recoder_play(void) { u8 res; u8 key; u8 rval=0;
__WaveHeader *wavhead=0; u32 sectorsize=0; FIL* f_rec=0; //文件 DIR recdir; //目录 u8 *recbuf; //数据内存 u16 w; u16 idx=0;
u8 rec_sta=0;//录音状态
//[7]:0,没有录音;1,有录音; //[6:1]:保留
//[0]:0,正在录音;1,暂停录音;
本 科 毕 业 设 计
u8 *pname=0;
u8 timecnt=0; //计时器 u32 recsec=0; //录音时间 u8 recagc=4; //默认增益为4
第 31 页 共 33页
while(f_opendir(&recdir,\打开录音文件夹 {
Show_Str(60,230,240,16,\文件夹错误!\ delay_ms(200);
LCD_Fill(60,230,240,246,WHITE); //清除显示 delay_ms(200);
f_mkdir(\创建该目录 }
f_rec=(FIL *)mymalloc(SRAMIN,sizeof(FIL));//开辟FIL字节的内存区域 if(f_rec==NULL)rval=1; //申请失败
wavhead=(__WaveHeader*)mymalloc(SRAMIN,sizeof(__WaveHeader));//开辟__WaveHeader字节的内存区域 if(wavhead==NULL)rval=1; recbuf=mymalloc(SRAMIN,512); if(recbuf==NULL)rval=1;
pname=mymalloc(SRAMIN,30); //申请30个字节内存,类似\ if(pname==NULL)rval=1;
if(rval==0) //内存申请OK {
recoder_enter_rec_mode(1024*recagc);
while(VS_RD_Reg(SPI_HDAT1)>>8); //等到buf 较为空闲再开始 recoder_show_time(recsec); //显示时间 recoder_show_agc(recagc); //显示agc
pname[0]=0; //pname没有任何文件名 while(rval==0) {
key=KEY_Scan(0); switch(key) {
case KEY_LEFT: //STOP&SAVE if(rec_sta&0X80) //有录音 {
wavhead->riff.ChunkSize=sectorsize*512+36;//整个文件的大小-8; wavhead->data.ChunkSize=sectorsize*512;//数据大小 f_lseek(f_rec,0);//偏移到文件头.
本 科 毕 业 设 计
数据
f_close(f_rec); sectorsize=0; }
rec_sta=0; recsec=0;
第 32 页 共 33页
f_write(f_rec,(const void*)wavhead,sizeof(__WaveHeader),&bw);//写入头
LED1=1; //关闭DS1
LCD_Fill(60,230,240,246,WHITE); //清除显示,清除之前显示的录音文件名 recoder_show_time(recsec); //显示时间 break;
case KEY_RIGHT: //REC/PAUSE
if(rec_sta&0X01 //原来是暂停,继续录音 {
rec_sta&=0XFE; //取消暂停
}else if(rec_sta&0X80)//已经在录音了,暂停 {
rec_sta|=0X01;//暂停 }else//还没开始录音 {
rec_sta|=0X80; //开始录音
recoder_new_pathname(pname); //得到新的名字 Show_Str(60,230,240,16,pname+11,16,0); //显示当前录音文件名字 recoder_wav_init(wavhead); //初始化wav数据 res=f_open(f_rec,(const TCHAR*)pname, FA_CREATE_ALWAYS | FA_WRITE);
if(res) //文件创建失败 {
rec_sta=0; //创建文件失败,不能录音 rval=0XFE; //提示是否存在SD卡 }else res=f_write(f_rec,(const void*)wavhead,sizeof(__WaveHeader),&bw);//写入头数据 }
if(rec_sta&0X01)LED1=0; //提示正在暂停 else LED1=1; break;
case KEY_UP: //AGC+ case KEY_DOWN: //AGC- if(key==KEY_UP)recagc++; else if(recagc)recagc--;
本 科 毕 业 设 计
其他AGC倍数
recoder_show_agc(recagc);
第 33 页 共 33页
if(recagc>15)recagc=15; //范围限定为0~15.0,自动AGC.
VS_WR_Cmd(SPI_AICTRL1,1024*recagc);//设置增益,0,自动增益.1024相当于1倍,512相当于0.5倍 break;
}