一:VS1053介绍
1.vs1053支持ogg/mp3/aac/wma/midi音频解码,IMA ADPCM编码
2.SPI时序图
二:WAV格式介绍
VS1053 MP3模块支持2种格式的WAV录音: PCM格式或者IMA ADPCM格式,其中PCM(脉冲编码调制)是最基本的WAVE 文件格式,这种文件直接存储采样的声音数
据没有经过任何的压缩。而IAM ADPCM则是使用了压缩算法,压缩比率为4:1。 我们主要讨论 PCM,因为这个最简单。我们将利用 VS1053 实现 16 位,8Khz
采样率的单声道WAV 录音(PCM格式)。
WAVE 文件是由若干个 Chunk 组成的。按照在文件中的出现位置包括:RIFF WAVE Chunk、 Format Chunk、 Fact Chunk(可选)和 Data Chunk。
每个Chunk 由块标识符、数据大小和数据三部分组成,如下所示:
其中块标识符由 4 个 ASCII 码构成,数据大小则标出紧跟其后的数据的长度(单位为字节),注意这个长度不包含块标识符和数据大小的长度,即不包含最前面的 8 个字节。所
以实际Chunk的大小为数据大小加 8。
1.首先,我们来看看 RIFF 块(RIFF WAVE Chunk),该块以“RIFF”作为标示,紧跟wav 文件大小(该大小是 wav 文件的总大小-8),然后数据段为“WAVE”,表示是 wav文件。RIFF块的Chunk 结构如下:
//RIFF块
typedef __packed struct
{
u32 ChunkID; //chunk id;这里固定为"RIFF",即 0X46464952
u32 ChunkSize ; //集合大小;文件总大小-8
u32 Format; //格式;WAVE,即0X45564157
}ChunkRIFF ;
2.Format块(Format Chunk),该块以“fmt ”作为标示(注意有个空格!),一般情况下,该段的大小为 16个字节,但是有些软件生成的 wav格式,该部分可能有18 个字节,含有 2个字节的附加信息。Format块的Chunk 结构如下:
//fmt块
typedef __packed struct
{
u32 ChunkID; //chunk id;这里固定为"fmt ",即 0X20746D66
u32 ChunkSize ; //子集合大小(不包括 ID和Size);这里为:20.
u16 AudioFormat; //音频格式;0X10,表示线性PCM;0X11 表示IMA AD
u16 NumOfChannels; //通道数量;1,表示单声道;2,表示双声道;
u32 SampleRate; //采样率;0X1F40,表示 8Khz
u32 ByteRate; //字节速率;
u16 BlockAlign; //块对齐(字节);
u16 BitsPerSample; //单个采样数据大小;4位ADPCM,设置为4
}ChunkFMT;
3.接下来,我们再看看 Fact 块(Fact Chunk),该块为可选块,以“fact”作为标示,不是每个 WAV 文件都有,在非 PCM 格式的文件中,一般会在 Format 结构后面加入一个
Fact块,该块Chunk 结构如下:
//fact块
typedef __packed struct
{
u32 ChunkID; //chunk id;这里固定为"fact",即 0X74636166;
u32 ChunkSize ; //子集合大小(不包括ID和Size);这里为:4.
u32 DataFactSize; //数据转换为PCM格式后的大小
}ChunkFACT;
4.最后,我们来看看数据块(Data Chunk),该块是真正保存wav数据的地方,以“data”
'作为该Chunk 的标示。然后是数据的大小。紧接着就是 wav数据。根据Format Chunk 中的
声道数以及采样bit数,wav数据的 bit位置可以分成如表所示的几种形式:
我们采用的是 16位,单声道,所以每个取样为 2 个字节,低字节在前,高字节在后。数据块的Chunk结构如下:
//data块
typedef __packed struct
{
u32 ChunkID; //chunk id;这里固定为"data",即0X61746164
u32 ChunkSize ; //子集合大小(不包括 ID和Size);文件大小-60.
}ChunkDATA;
三:激活PCM录音
VS1053激活PCM 录音需要设置的寄存器和相关位如表所示:
通过设置 SCI_MODE 寄存器的 2、12、14 位,来激活 PCM 录音,SCI_MODE 的各位描述见VS1053 的数据手册。SCI_AICTRL0 寄存器用于设置采样率,我们本文档用的是 8K
的采样率,所以设置这个值为 8000即可。SCI_AICTRL1 寄存器用于设置AGC,1024相当于数字增加1,这里建议大家设置 AGC 在4(4*1024)左右比较合适。SCI_AICTRL2 用于设置自动AGC的时候的最大值,当设置为0的时候表示最大 64(65536),这个大家按自己的需要设置即可。最后,SCI_AICTRL3,我们本文档用到的是咪头线性PCM单声道录音,所以设置该寄存器值为6。
通过这几个寄存器的设置,我们就激活VS1053 的PCM录音了。 不过, VS1053 的PCM录音有一个小BUG,必须通过加载 patch才能解决,如果不加载 patch,那么 VS1053 是不输出PCM数据的,VLSI 提供了我们这个patch,只需要通过软件加载即可。
1.读取PCM数据
在激活了PCM录音之后,SCI_HDAT0和 SCI_HDAT1 有了新的功能。VS1053的PCM采样缓冲区由1024个 16位数据组成,如果SCI_HDAT1 大于0,则说明可以从 SCI_HDAT0
读取至少 SCI_HDAT1 个 16 位数据,如果数据没有被及时读取,那么将溢出,并返回空的状态。
注意,如果 SCI_HDAT1≥896,最好等待缓冲区溢出,以免数据混叠。所以,对我们只需要判断SCI_HDAT1 的值非零,然后从 SCI_HDAT0读取对应长度的数据,即完
成一次数据读取,以此循环,即可实现PCM数据的持续采集。
四:实现WAV 录音需要经过哪些步骤:
1) 设置 VS1053 PCM采样参数
这一步,我们要设置 PCM 的格式(线性 PCM)、采样率(8K)、位数(16 位)、通道数(单声道)等重要参数,同时还要选择采样通道(咪头),还包括AGC设置等。可以
说这里的设置直接决定了我们 wav文件的性质。
2) 激活 VS1053的 PCM模式,加载patch
通过激活VS1053的PCM格式,让其开始PCM数据采集,同时,由于VS1053的 BUG,我们需要加载patch,以实现正常的PCM数据接收。
3) 创建WAV文件,并保存 wav头
在前两部设置成功之后,我们即可正常的从SCI_HDAT0 读取我们需要的PCM数据了,不过在这之前,我们需要先在创建一个新的文件,并写入 wav 头,然后才能开始写入我们
的PCM数据。
4) 读取PCM数据
经过前面几步的处理,这一步就比较简单了,只需要不停的从 SCI_HDAT0读取数据,然后存入 wav 文件即可,不过这里我们还需要做文件大小统计,在最后的时候写入 wav 头
里面。
5) 计算整个文件大小,重新保存 wav头并关闭文件
在结束录音的时候,我们必须知道本次录音的大小(数据大小和整个文件大小),然后更新 wav 头,重新写入文件,最后因为 FATFS,在文件创建之后,必须调用 f_close,文件
才会真正体现在文件系统里面,否则是不会写入的!所以最后还需要调用 f_close,以保存文件。
五:vs1053代码驱动程序