一. WAVE 简介

WAV格式是微软公司(Microsoft)开发的一种声音文件格式,它符合 RIFF(Resource Interchange File Format)文件规范,用于保存 Windows 平台的音频信息资源,被 Windows 平台及其应用程序所广泛支持。

WAVE 是录音时用的标准的 WINDOWS 文件格式,文件的扩展名为“WAV”,数据本身的格式为 PCM 或其他压缩数据,属于无损音乐格式的一种。

所有的 WAV 都有一个文件头,这个文件头记录了音频流的编码参数。WAV文件 = WAV头 + PCM数据

二. 音频编码参数

在介绍 WAVE 文件头之前,需要了解下音频编码的各个参数的含义:

  • 声道数量(NumChannels)
    声道数是指支持能不同发声的音响的个数,它是衡量音响设备的重要指标之一。我们戴的耳机因为只有左右 2 个喇叭,所以最多只能支持 2 个声道数量。
    单声道(mono)的声道数为 1;立体声道(stereo)的声道数默认为 2,即左右声道;四声道即前左、前右,后左、后右供 4 个发音点;目前还有 5.1 声道、7.1 声道。

    对于音频编码存储来说,每多一个声道,就要多存储一份数据。

  • 采样率(SampleRate)
    表示每秒采样的次数,常见的有 8000, 16000, 32000, 44100, 48000。

  • 采样精度(BitPerSample)
    表示每次从每个声道采样的数据的大小,以比特位单位。一般为 16,32。16 即 16 比特,也就是 2 个字节。

  • 比特率(ByteRate)
    表示每秒的音频数据大小,以字节为单位,可以根据上面几个参数求得。
    ByteRate = SampleRate * NumChannels * BitPerSample / 8

三. WAVE 文件头

偏移 字段字节数 字段名 解释
0 4 ChunkID “RIFF”串 十进制大端表示为 0x52494646
4 4 ChunkSize 整个文件的大小减去 8 字节(ChunkID+ChunkSize)。36 + SubChunk2Size或者 4 + (8 + SubChunk1Size) + (8 + SubChunk2Size)
8 4 Format “WAVE”串,十六进制大端表示为 0x57415645
12 4 Subchunk1ID “fmt “串,十六进制大端表示为 0x666d7420
16 4 Subchunk1Size 整个 Subchunk1 的大小减去该字段本身所占的 4 字节,对于 PCM 来说固定为 16
20 2 AudioFormat PCM 格式为 1,大于 1 表示其他压缩格式
22 2 NumChannels 声道数量,如 Mono = 1, Stereo = 2
24 4 SampleRate 采样率,如 8000, 44100 等
28 4 ByteRate 比特率, 等于SampleRate * NumChannels * BitsPerSample/8
32 2 BlockAlign 每个 Sample 的大小,等于NumChannels * BitsPerSample/8
34 2 BitsPerSample 采样精度,如 8,16,32
36 4 Subchunk2ID “data”串,十六进制大端表示为 0x64617461
40 4 Subchunk2Size 实际音频数据的大小,不包含 Subchunk2ID 和 Subchunk2Size 这 2 个字段的大小
44 * Data 实际的音频数据

下图是以十六进制显示的一个 WAV 文件的前 72 字节:

四. 从其他编码转 WAVE

我们可以使用 ffmpeg.exe 将音频从其他编码转为 wave 编码,命令如下:

1
ffmpeg.exe -i input.mp3  output.wav

我们还可以指定输出文件的编码格式,如采用率,采样精度,声道数,如:

1
ffmpeg.exe  -f u16le -ar 44100 -ac 1 -i input.mp3 output.wav

ffmpeg 参数解释见:http://trac.ffmpeg.org/wiki/audio%20types

ffmpeg 生成的 wav 文件的文件头可能和我们上面介绍的不太一样,它可能会包含LISTINFO数据块,这个时候我就需要通过 2 个步骤来生成不包含LISTINFO数据块的 WAV 文件了:
首先通过 ffmpeg.exe 将音频文件转成 pcm 裸数据文件,然后使用其他工具(如audacity)为该 pcm 裸数据加上 wav 头。

ffmpeg 将音频转成 pcm 裸数据命令如下:

1
ffmpeg.exe -f s16le -c:a pcm_u16le  -i input.mp3 output.raw

五、WebRTC 对 Wav 格式支持

WebRTC 源码src\common_audio目录中的wav_header.hwav_file.h提供了对 wav 的读写功能。