这两天调通了VS1053B的ADPCM录音方式,在用2.4G通信模块在250KBPS速度下,音质很好!我关键部分的程序贴出来。[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_AUDATA,8000);
VS_WR_Cmd(SPI_MODE,0x1804); //MIC,录音激活
delay_ms(5); //等待至少1.35ms
VS_Load_Patch((u16*)wav_plugin,40);//VS1053的WAV录音需要patch
}
//初始化WAV头.
void recoder_wav_init(__WaveHeader* wavhead,u8 SetType) //初始化WAV头(44个字节)
{
wavhead->riff.ChunkID=0X46464952; //"RIFF"
if(SetType==RecordMode)
{
wavhead->riff.ChunkSize=0; //还未确定,最后需要计算
}
if(SetType==WirelessMode)
{
wavhead->riff.ChunkSize=0xffffffff; //还未确定,最后需要计算
}
wavhead->riff.Format=0X45564157; //"WAVE"
wavhead->fmt.ChunkID=0X20746D66; //"fmt "
wavhead->fmt.ChunkSize=16; //大小为16个字节(4个字节)
wavhead->fmt.AudioFormat=0X01; //0X01,表示PCM;0X01,表示IMA ADPCM(2个字节)
wavhead->fmt.NumOfChannels=1; //单声道(2个字节)
wavhead->fmt.SampleRate=8000; //8Khz采样率 采样速率(4个字节)
wavhead->fmt.ByteRate=wavhead->fmt.SampleRate*2;//16位,即4个字节
wavhead->fmt.BlockAlign=2; //块大小,2个字节为一个块(2个字节)
wavhead->fmt.BitsPerSample=16; //16位PCM(2个字节)
wavhead->data.ChunkID=0X61746164; //"data"(4个字节)
if(SetType==RecordMode)
{
wavhead->data.ChunkSize=0; //数据大小,还需要计算
}
if(SetType==WirelessMode)
{
wavhead->data.ChunkSize=0xffffffff; //数据大小,还需要计算
}
}
void recordagain() //继续录音
{
u8 res;
u16 w; //从MP3芯片里读出来的数据的长度
u16 idx=0;
while(KEYDown.KEY2_Down==1)
{
w=VS_RD_Reg(SPI_HDAT1); //读数据的长度
if((w>=256)&&(w<896))
{
idx=0;
while(idx<512) //一次读取512字节
{
w=VS_RD_Reg(SPI_HDAT0); //读数据
recbuf[idx++]=w&0XFF;
recbuf[idx++]=w>>8;
}
res=f_write(f_rec,recbuf,512,&bw);//写入文件
if(res)
{
break;//写入出错.
}
sectorsize++;//扇区数增加1,约为32ms
}
}
}
void SpeakerTask()
{
u16 w,i;
u8 *recbuf;
recbuf=mymalloc(SRAMIN,512); //为发送数据缓冲区分配内存
wavhead=(__WaveHeader*)mymalloc(SRAMIN,sizeof(__WaveHeader));//开辟__WaveHeader字节的内存区域
recoder_wav_init(wavhead,WirelessMode);
recoder_enter_rec_mode(4096);
while(VS_RD_Reg(SPI_HDAT1)>>8); //等到buf 较为空闲再开始录音
memcpy(recbuf,wavhead,sizeof(__WaveHeader));
i=sizeof(__WaveHeader);
while(KEYDown.KEY9_Down==1) //如果按键状态没有改变,则一直执行如果下程序
{
do
{
w=VS_RD_Reg(SPI_HDAT1);
}while((w<256)||(w>=896));
while(i<512) //一次读取512字节
{
w=VS_RD_Reg(SPI_HDAT0);
recbuf[i++]=w&0XFF;
recbuf[i++]=w>>8;
}
i=0;
while(1)
{
// if(NRF24L01_TxPacket(recbuf+i)==TX_OK)
// {
NRF24L01_TxPacket(recbuf+i);
i += 32;
if(i >= 512)
{
i = 0;
break;
}
// }
}
}
myfree(SRAMIN,recbuf);
myfree(SRAMIN,wavhead);
VS_HD_Reset(); //硬复位
VS_Soft_Reset(); //软复位
}[/mw_shl_code]
[mw_shl_code=c,true]//RIFF块
typedef __packed struct
{
u32 ChunkID; //chunk id;这里固定为"RIFF",即0X46464952
u32 ChunkSize ; //集合大小;文件总大小-8
u32 Format; //格式;WAVE,即0X45564157
}ChunkRIFF ;
//fmt块
typedef __packed struct
{
u32 ChunkID; //chunk id;这里固定为"fmt ",即0X20746D66
u32 ChunkSize ; //子集合大小(不包括ID和Size);这里为:20.
u16 AudioFormat; //音频格式;0X10,表示线性PCM;0X11表示IMA ADPCM
u16 NumOfChannels; //通道数量;1,表示单声道;2,表示双声道;
u32 SampleRate; //采样率;0X1F40,表示8Khz
u32 ByteRate; //字节速率;
u16 BlockAlign; //块对齐(字节);
u16 BitsPerSample; //单个采样数据大小;4位ADPCM,设置为4
// u16 ByteExtraData; //附加的数据字节;2个; 线性PCM,没有这个参数
// u16 ExtraData; //附加的数据,单个采样数据块大小;0X1F9:505字节 线性PCM,没有这个参数
}ChunkFMT;
//fact块
typedef __packed struct
{
u32 ChunkID; //chunk id;这里固定为"fact",即0X74636166;
u32 ChunkSize ; //子集合大小(不包括ID和Size);这里为:4.
u32 NumOfSamples; //采样的数量;
}ChunkFACT;
//data块
typedef __packed struct
{
u32 ChunkID; //chunk id;这里固定为"data",即0X61746164
u32 ChunkSize ; //子集合大小(不包括ID和Size);文件大小-60.
}ChunkDATA;
//wav头
typedef __packed struct
{
ChunkRIFF riff; //riff块
ChunkFMT fmt; //fmt块
//ChunkFACT fact; //fact块 线性PCM,没有这个结构体
ChunkDATA data; //data块
}__WaveHeader; [/mw_shl_code]
在读08寄存器之后存到一个缓存区,然后我是直接通过串口输出了。
一周热门 更多>