OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2670|回复: 2

VS1053利用32内部SRAMIN测试录音、播放,ADPCM模式,不要SD卡

[复制链接]

2

主题

32

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2019-4-5
在线时间
6 小时
发表于 2020-5-26 14:14:10 | 显示全部楼层 |阅读模式
最近要做个无线语音的,抄了正点原子代码,稍微修改下,利用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,录音激活    0x5804INE_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秒,接着熄灭播放,循环下去,声音清晰。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

59

帖子

0

精华

初级会员

Rank: 2

积分
91
金钱
91
注册时间
2020-5-2
在线时间
0 小时
发表于 2020-5-26 14:14:13 | 显示全部楼层
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2019-9-3
在线时间
15 小时
发表于 2020-7-27 14:34:18 | 显示全部楼层
请问读取数据时的cnt+=2;是为何?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-8 14:12

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表