1、什么是WAV?
WAV即WAVE文件,是最常用的数字化声音文件格式之一,其扩展名为“.wav”。符合RIFF(Resource Interchange File Format)文件规范,用于保存Windows平台的音频信息资源,被Windows平台及其应用程序所广泛支持。
WAV格式还支持MS ADPCM,CCITT ALAW等多种压缩运算法,支持多种音频数字,取样频率和声道。标准格式化的WAV文件和CD格式一样,也是44.1K的取样频率,16位量化数字,因此在文件质量和CD相差无几。
2、WAV组成
WAV是由若干个Chunk组成的。按照文件中的出现位置包括:
1)RIFF WAVE Chunk
2)Format Chunk
3)Fact Chunk(可选)
4)Data Chunk
每个Chunk由块标识符、数据大小和数据三部分组成,如下图所示:
其中标识符由4个ASCII码构成,数据大小则标出紧跟其后的数据的长度(单位为字节),注意这个长度不包含块标识符和数据大小的长度,即不包含最前面的8个字节。所以Chunk的大小为数据大小+8。
1)RIFF块,该块以“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
}ChunkRIF;
2)Format块,该块以“fmt ” 作为标识(注意fmt后面有个空格),一般情况下,该段的大小为16个字节,但是有些软件生成的wav格式,该部分可能有18个字节,含有2个字节的附加信息。
Format块的Chunk结构如下:
//fmt块
typedef __packed struct
{
u32 ChunkID; //chunk id:这里固定为"fmt ",即0X20746D66
u32 ChunkSize; //子集大小(不包括ID和Size)
u16 AudioFormat;//音频格式:一般为0X0001,表示线性PCM
u16 NumOfChannels;//通道数量:1,表示单声道,2表示双声道
u32 SampleRate; //采样率:0X1F40,表示8Khz
u32 ByteRate;//字节速率=采样率×通道数×(ADC位数/8)
u16 BlockAlign;//块对齐(字节)=通道数×(ADC位数/8)
u16 BitsPerSample;//单个采样的位数:16位PCM,设置为16
u16 ByteExtraData;//附加的数据字节:2个;线性PCM,没有这个参数
}ChunkFMT;
3)Fact块,该块为可选块,以fact作为标识,不是每个WAV文件都有,在非PCM格式的文件中,一般在Format结构后面加入一个Fact块,该块Chunk结构如下:
//fact块
typedef __packed sturct
{
u32 ChunkID;//chunk id:这里固定为“fact”,即0X74636166
u32 ChunkSize;//子集合大小(不包括ID和Size),这里为4
u32 DataFactSize;//数据转换为PCM格式后的大小
}ChunkFACT;
DATa Fact Size是这个Chunk中最重要的数据,如果这是某种压缩格式的声音文件,那么从这里就可以知道他压缩后的大小。
4)数据块(Data Chunk),该块是真正保存wav数据的地方,以“data”作为该Chunk的标示,然后是数据大小。数据块的Chunk结构如下:
//data块
typedef __packed struct
{
u32 ChunkID;//chunk id:这里固定为“data”,即0X61746164
u32 ChunkSize;//子集合大小(不包括ID和Size);
}ChunkDATA;
ChunkSize的大小是音频数据的大小(仅指音频数据大小,不包括Chunk ID之类的数据),在ChunkSize之后,紧跟音频数据。
根据Format Chunk中的声道数以及采样bit数,wav数据的bit位置可以分成如下表所示的几种形式:
3、WM8978简介
WM8978是Wolfson推出的一款全功能音频处理器。它带有HI-FI级数字信号处理内核,支持增强3D硬件环绕音效,和5频段的硬件均衡器,可以有效改善音质。同时集成了对麦克风的支持和一个输出功率达0.9W的高质量功效。
WM8978进一步提升了耳机放大器功率输出,在推动16欧姆耳机的时候,每声道最大功率高达40毫瓦!可以连接市面上绝大多数适合随身听的高端HI-FI耳机。
4、WM8978特点
1)I2S接口,支持最高192K,24bit音频播放
2)DAC信噪比98dB;ADC信噪比90dB
3)支持无电容耳机驱动(提供40mW@8Ω的驱动能力)
4)支持立体声差分输入/麦克风输入
5)支持左右声道音量独立调节
6)支持3D效果,支持5路EQ调节
5、WM8978接口
WM8978通过I2S接口(即数字音频接口)同MCU进行音频数据传输(支持音频接收和发送),通过两线(MODE=0,即IIC接口)或三线(MODE=1)接口进行配置。WM8978的I2S接口,由4个引脚组成:
1、ADCDAT:ADC数据输出
2、DACDAT:DAC数据输入
3、LRC:数据左/右对齐时钟
4、BCLK:位时钟,用于同步
WM8978的I2S接口支持多种不同的音频数据模式:左(MSB)对齐标准、右(LSB)对齐标准、飞利浦(I2S)标准等。
飞利浦(I2S)标准模式,数据在跟随LRC传输的BCLK的第二个上升沿时传输MSB,其他位一直到LSB按顺序传输。传输依赖于字长、BCLK频率和采样率,在每个采样的LSB和下一个采样的MSB之间都应该有未用的BCLK周期。飞利浦标准I2S数据传输协议如下图所示:
图中,fs即音频信号的采样率,比如44.1Khz,因此:LRC的频率就是音频信号的采样率。另外,WM8978还需要一个MCLK时钟。
6、WM8978框图
左边:从上到下(AUXR AUXL、LIN、LIP、L2/GPIO2、RIN、RIP、R2/GPIO3)是输入,LIN和LIP、RIN和RIP接MIC输入;L2/GPIO2和R2/GPIO3接Linein的输入
右边:从上到下(OUT4、OUT3、LOUT1、ROUT1、LOUT2、ROUT2)是输出,LOUT2、ROUT2接喇叭,LOUT1、ROUT1可以接耳机。
下面:BCLK、DACDAT、LRC、ADCDAT是I2S接口,MCLK是主时钟输入口(内部PLL没用到),I2S右边是控制器口。
内部:左声道ADC、右声道ADC,左通道DAC、右通道DAC,以及3D效果设置。
WM8978内部有很多的模拟开关用来选择通道,同时还有很多调节器,用来设置增益和音量。
7、相关寄存器
1、R0寄存器(00h)
该寄存器用于控制WM8978的软复位,写任意值到该寄存器地址,即可实现软复位WM8978。
(注意:WM8978的寄存器是9为的,而且是不可读的,只可以写,不可以读)
2、R1寄存器(01h)
BIASEN位设置1,模拟部分的放大器才会工作,才可以听到声音。
3、R2寄存器(02h)
该寄存器设置ROUT1EN(bit8),LOUT1EN(bit7)和SLEEP(bit6)等三位,ROUT1EN和LOUT1EN,设置为1,使能耳机输出,SLEEP设置为0,进入正常工作模式。
4、R3寄存器(03h)
该寄存器设置LOUT2EN(bit6)、ROUT2EN(bit5)、RMIXER(bit3)、LMIXER(bit2)、DACENR(bit1)和DACENL(bit0)等6个位。LOUT2EN和ROUT2EN,设置为1,使能喇叭输出;LMIXER和RMIXER设置为1,使能左右声道混合器;DACENL和DACENR则是使能左右声道DAC,必须设置为1。
5、R4寄存器(04h)
该寄存器要设置WL(bit6:5)和FMT(bit4:3)等4个位。WL(bit6:5)用于设置字长(即设置音频数据有效位数),00表示16位音频,10表示24位音频;FMT(bit4:3)用于设置I2S音频数据格式(模式),一般设置为10,表示I2S格式,即飞利浦模式。
6、R6寄存器(06h)
该寄存器直接全部设置为0即可,设置MCLK和BCLK都来自外部,即由STM32F4提供。
7、R10寄存器(0Ah)
该寄存器要设置SOFTMUTE(bit6)和DACOSR128(bit3)等两个位,SOFTMUTE设置为0,关闭软件静音;DACOSR128设置为1,DAC得到最好的SNR。
8、R49寄存器(31h)
该寄存器要设置SPKBOOST(bit)和TSDEN(bit1)这两个位。SPKBOOST用于设置喇叭的增益,设置0即可(gain=-1),如想获得更大的声音,可设置为1(gain=+1.5)即可;TSDEN用于设置过热保护,设置为1(开启)即可。
9、R50&R51寄存器(32h&33h)
上图为R50寄存器描述,用于设置左声道,另外一个用于设置右声道(R51).只需要设置这两个寄存器的最低位为1即可,将左右声道的DAC输出接入左右声道混合器里面,才能在耳机/喇叭里听到音乐。
10、R52&R53寄存器(34h&35h)
上图为R52寄存器描述,用于设置耳机输出左声道(R52),另一个用于设置耳机输出右声道(R53).这两个寄存器的最高位(HPVU)用于设置是否更新左右声道的音量,最低6位用于设置左右声道的音量。我们可以先设置好两个寄存器的音量值,最后设置其中一个寄存器最高位为1,即可更新音量设置。
11、R54&R55寄存器(36h&37h)
图
这两个寄存器用于设置喇叭音量,同R52、R53设置一样。
经过这些寄存器的设置,我们即可实现利用WM8978播放音乐。