wav文件格式解析

wav文件格式解析

本文将详细分析不同格式的wav文件。

简介wav即wave(下文统称为wav), 该文件格式是由微软开发的用于音频数字存储的标准,可应用于Windows、Linux和MacOS等多种操作系统,文件扩展名为.wav,是waveform的简写。

wav文件结构在Windows下,大部分多媒体文件都遵循RIFF(Resource Interchange File Format,资源互换文件格式)格式来存储数据。

RIFF文件的基本存储单位称为块(chunk),一个遵循RIFF格式的文件由若干个chunk组成,每个chunk又由块标识、块长度和块数据三部分构成,其基本结构见表1:

Field

Size(bytes)

Type

块标识

4

S8 *

块长度

4

U32

块数据

S8 *

**表1** `chunk`基本结构

块标识:用于标识块中的数据,由4个ASCII字符组成,如不满4个字符则在右边以空格充填,如:RIFF、LIST、fmt 和data等;

块长度:用于标识块数据域中的数据长度,块标识域和块长度域不包括在其中,所以一个chunk的实际长度为该值加8;

块数据:存储块数据,若数据长度为奇数,则在最后添加一个NULL;

特别需要注意的是,RIFF格式规定只有块标识为RIFF或LIST的块可以含有子块(subChunk),而其它块只可以包含数据。块标识为RIFF或LIST的块的结构与表1大致相同,只不过其块数据域分为两部分:

type:由4个ASCII字符组成,代表RIFF文件的类型,如WAVE和AVI ,或者代表LIST块的类型,如avi文件中的列表hdrl和movi;

data:实际的块内容,包含若干subChunk;

wav文件是非常简单的一种RIFF文件,其本身就是由一个块标识为RIFF的chunk和多个subChunk组成的一个chunk,其组成如下:

RIFF chunk:主块,必选,块标识为RIFF,说明这是一个RIFF文件,RIFF文件的第一个块标识必须是RIFF;

Format chunk:子块,必选,块标识为fmt ,用于存储文件的一些参数信息,比如采样率、通道数和编码格式等;

Fact chunk:子块,可选,块标识为fact,基于压缩编码的wav文件必须含有fact块;

List chunk:子块,可选,块标识为LIST,用于记录文件版权和创建时间信息;

Data chunk:子块,必选,块标识为data,用于存储音频数据;

目前业界标准的wav文件仅由RIFF chunk、Format chunk和Data chunk组成:

wav文件头格式wav文件从数据类型上看,主要由文件头和数据体两部分组成:

文件头:由RIFF chunk、Format chunk、List chunk和Fact chunk等组成,用于存储一些文件信息;

数据体:由Data chunk组成,用于存储音频数据;

标准格式标准的wav文件头仅由RIFF chunk和Format chunk组成,长度为44个字节,格式见表2:

file offset(bytes)

Field name

Field size(bytes)

type

endian

description

0

Chunk ID

4

S8 *

big

“RIFF”,表明为RIFF文件

4

Chunk Size

4

U32

little

除了RIFF及自己之外,整个文件的长度,即文件总字节数减去8字节

8

Format

4

S8 *

big

“WAVE”,表明为wav格式

12

Subchunk1 ID

4

S8 *

big

“fmt “

16

Subchunk1 Size

4

U32

little

表示fmt数据块即subchunk1除了Subchunk1 ID和Subchunk1 Size之后剩下的长度,一般为16, 大于16表示存在扩展区域,可选值为16、18、20、40等

20

AudioFormat

2

U16

little

编码格式,即压缩格式,0x01表示pcm格式,无压缩,参见表3

22

NumChannels

2

U16

little

音频通道数,单声道为1,立体声或双声道为2

24

SampleRate

4

U32

little

采样频率,每个通道单位时间采样次数,可选值为16000kHz和44100kHz等

28

ByteRate

4

U32

little

数据传输速率,可用此估算缓冲区长度,ByteRate = SampleRate * NumChannels * (BitsPerSample / 8)

32

BlockAlign

2

U16

little

采样一次的字节数,即一帧的字节数,表示块对齐的内容(数据块的调整数),播放软件一次处理多少个该长度的字节数据,以便将其用于缓冲区的调整,BlockAlign = NumChannels * (BitsPerSample / 8)

34

BitsPerSample

2

U16

little

采样位宽,即每个采样点的bit数,可选值8、16或32等

36

Subchunk2 ID

4

S8 *

big

“data”

40

Subchunk2 Size

4

U32

little

音频数据的总长度,即文件总字节数减去wav文件头的长度

44

Data

little

音频数据

**表2** 标准的`wav`文件头格式

通过wav文件头信息,我们可以计算出音频时长:

1音频时长(s) = Subchunk2 Size / ByteRate

压缩编码格式wav文件几乎支持所有ACM规范的编码格式,其信息存储在wav文件头偏移20、21两个字节中,常见的压缩编码格式见表3:

格式代码

格式名称

Format chunk 长度

是否有Fact chunk

0 (0x0000)

unknown

unknown

unknown

1 (0x0001)

PCM/uncompressed

16

无

2 (0x0002)

Microsoft ADPCM

18

有

3(0x0003)

IEEE float

18

有

6 (0x0006)

ITU G.711 a-law

18

有

7 (0x0007)

ITU G.711 µ-law

18

有

17 (0x0011)

IMA ADPCM

unknown

unknown

20 (0x0016)

ITU G.723 ADPCM (Yamaha)

unknown

unknown

49 (0x0031)

GSM 6.10

20

有

64 (0x0040)

ITU G.721 ADPCM

unknown

有

80 (0x0050)

MPEG

unknown

unknown

65,534 (0xFFFE)

扩展格式标识

40

unknown

65,536 (0xFFFF)

Experimental

unknown

unknown

**表3** 常见的压缩编码格式

扩展格式当然,也不是所有的wav文件头都是44个字节的,比如通过FFmpge编码而来的wav文件头通常大于44个字节,目前比较常见的wav文件头长度有44字节、46字节、58字节和98字节。

Format chunk扩展当wav文件采用非PCM编码即压缩格式时,会扩展Format chunk,在其之后扩充了一个数据结构,见表4:

file offset(bytes)

Field name

Field size(bytes)

type

description

24

extand size

2

U16

除其自身外的扩展区域长度

26

extand area

包含扩展的格式信息,其长度取决于压缩编码类型。当某种编码格式(如ITU G.711 a-law)使扩展区的长度为0时,该字段还必须保留,只是长度字段的数值为0。

**表4** 标准Format chunk扩展格式

由此可以得出,如果Subchunk1 Size等于0x10(16),表示不包含Format chunk扩展,wav文件头长度为44字节;如果大于0x10(16),则包含Format chunk扩展,扩展长度的最小值为18(16+2),此时wav文件头大于44字节。

当编码格式代码为0xFFFE时,Format chunk扩展长度为24字节,格式见表5。

file offset(bytes)

Field name

Field size(bytes)

type

description

24

扩展区长度

2

U16

值为22

26

有效采样位数

2

U16

最大值为 每个采样字节数 * 8

28

扬声器位置

4

U32

声道号与扬声器位置映射的二进制掩码

32

编码格式

2

U16

真正的编码格式代码

34

14

值为{\x00, \x00, \x00, \x00, \x10, \x00, \x80, \x00, \x00, \xAA, \x00, \x38, \x9B, \x71}

**表5** 编码为0xFFFE的Format chunk扩展格式

Fact chunk采用压缩编码(修订版Rev.3以后出现的编码格式)的wav文件必定有含有Fact chunk,其结构符合标准chunk结构,参见表1。

Fact chunk的块标识符为”fact“,块长度至少为4个字节,目前其只有一个块数据内容,即每个声道采样总数,或采样帧总数。该值等于Subchunk2 Size / BlockAlign。

值得注意的是,在实测中发现,将压缩编码格式文件转换成PCM编码格式后,原Fact chunk仍然存在。

wav文件动态解析库wav文件格式是一种极其简单的文件格式,如果对其结构足够熟悉,完全可以通过代码正确读写,从而免去引入一些复杂的中间库,降低复杂度,提高工作效率。

这里提供了一个wav文件动态解析库,欢迎使用。

Reference

WAVE PCM soundfile format

wav音频文件头动态解析–java语言

史上全最的WAV格式详解

wav文件格式分析与详解

✨ 相关作品

最近网上很火的宜婴纸尿裤质量到底好不好?
365bet官网是多少

最近网上很火的宜婴纸尿裤质量到底好不好?

📅 07-13 👁️‍🗨️ 3471
基本类型
365bet官网是多少

基本类型

📅 08-15 👁️‍🗨️ 3229
美颜相机app怎么设置拍照好看一点
网上365不给提款的解决办法

美颜相机app怎么设置拍照好看一点

📅 06-27 👁️‍🗨️ 5184