VS1053B的ADPCM录音设置

2019-07-21 05:49发布

这两天调通了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]


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。