1.概述
Waveform Audio File Format(WAVE,又或者是因为WAV后缀而被大众所知的),它采用RIFF(Resource Interchange File Format)文件格式结构。通常用来保存PCM格式的原始音频数据,所以通常被称为无损音频。但是严格意义上来讲,WAV也可以存储其它压缩格式的音频数据。
2.格式解析
WAV文件遵循RIFF规则,其内容以区块(chunk)为最小单位进行存储。WAV文件一般由3个区块组成:RIFF chunk、Format chunk和Data chunk。另外,文件中还可能包含一些可选的区块,如:Fact chunk、Cue points chunk、Playlist chunk、Associated data list chunk等。
2.1 RIFF区块
以'RIFF'为标识
Size是整个文件的长度减去ID和Size的长度
Type是WAVE表示后面需要两个子块:Format区块和Data区块
2.2 FORMAT区块
以'fmt '为标识
Size表示该区块数据的长度(不包含ID和Size的长度)
AudioFormat表示Data区块存储的音频数据的格式,PCM音频数据的值为1
NumChannels表示音频数据的声道数,1:单声道,2:双声道
SampleRate表示音频数据的采样率
ByteRate每秒数据字节数 = SampleRate * NumChannels * BitsPerSample / 8
BlockAlign每个采样所需的字节数 = NumChannels * BitsPerSample / 8
BitsPerSample每个采样存储的bit数,8:8bit,16:16bit,32:32bit
2.3 DATA区块
以'data'为标识
Size表示音频数据的长度,N = ByteRate * seconds
Data音频数据
3. 小端存储
WAV文件以小端形式来进行数据存储。
所谓的大端模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
所谓的小端模式,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中
下面解释一下PCM数据在WAV文件中的bit位排列方式
wav文件头格式详解
首先先声明几个变量:
int file_size; //文件大小
int channel; //声道数
int sample_rate; //采样率
int bit_rate; //比特率
int sample_bit; //每个采样点的位数
int data_size; //pcm数据的大小
char *header = new char[44]; //wav文件头
1:
00~03 4字节“RIFF” 资源交换文件标志
header[0] ='R';
header[1] ='I';
header[2] ='F';
header[3] ='F';
2:
04~074字节size=文件大小-8字节 (从下一个字节开始到文件末尾的总字节数)
header[4] = (char) ((file_size -8) & 0xff);
header[5] = (char) (((file_size -8) >> 8) & 0xff);
header[6] = (char) (((file_size -8) >> 16) &0xff);
header[7] = (char) (((file_size -8) >> 24) &0xff);
3:
08~11 4字节“wave” wav文件标志
header[8] ='W';
header[9] ='A';
header[10] ='V';
header[11] ='E';
4:
12~15 4字节“fmt” 波形格式标志,最后一位空格
header[12] ='f';
header[13] ='m';
header[14] ='t';
header[15] =' ';
5:
16~19 4字节过滤字节(一般为00000010H)
header[16] =16;
header[17] =0;
header[18] =0;
header[19] =0;
6:
20~21 2字节格式种类(值为1时,表示数据为线性pcm编码)
header[20] =1;
header[21] =0;
7:
22~23 2字节通道数,单声道为1,双声道为2
header[22] = (char) channel;
header[23] =0;
8:
24~27 4字节采样率
header[24] = (char) (sample_rate &0xff);
header[25] = (char) ((sample_rate >>8) & 0xff);
header[26] = (char) ((sample_rate >>16) & 0xff);
header[27] = (char) ((sample_rate >>24) & 0xff);
9:
28~31 4字节比特率(Byte率=采样频率*音频通道数*每次采样得到的样本位数/8)
header[28] = (char) (bit_rate &0xff);
header[29] = (char) ((bit_rate >>8) & 0xff);
header[30] = (char) ((bit_rate >>16) & 0xff);
header[31] = (char) ((bit_rate >>24) & 0xff);
10:
32~33 2字节数据块长度(每个样本的字节数=通道数*每次采样得到的样本位数/8)
header[32] = (char) (channel* sample_bit / 8);
header[33] =0;
11:
34~35 2字节每个采样点的位数
header[34] = (char) sample_bit;
header[35] =0;
12:
36~39 4字节 “data”数据标志符
header[36] ='d';
header[37] ='a';
header[38] ='t';
header[39] ='a';
13:
40~43 4字节 pcm音频数据大小
header[40] = (char) (data_size &0xff);
header[41] = (char) ((data_size >>8) & 0xff);
header[42] = (char) ((data_size >>16) & 0xff);
header[43] = (char) ((data_size >>24) & 0xff);
当我们在一个.wav文件前写入这44个字节的头,后面接上pcm数据.这样很多播放器都能播放了.
码率
样本的字节数=通道数*每次采样得到的样本位数/8
文件大小计算 16*16000*1/8/1024* time = 31.25 kb * time
32*44100*2/8/1024* time = 344.53125 kb * time