WAV 文件格式详解¶
1、WAV 文件概述¶
WAV 是微软公司开发的一种音频格式文件,用于保存 Windows 平台的音频信息资源,它符合 资源互换文件格式(Resource Interchange File Format,RIFF)文件规范。
主要特点:
-
高质量音频:标准格式化的 WAV 文件采用 44.1kHz 采样频率,16 位量化数字,音质与 CD 相差无几
-
无损存储:通常用来保存 PCM 格式的原始音频数据,被称为无损音频
-
格式灵活:也可以存储其它压缩格式的音频数据
2、WAV 文件格式结构¶
WAV 符合 RIFF 文件格式标准,其基本组成单元是 chunk(数据块)。
2.1 基本结构¶
一个 WAV 文件通常包含以下数据块(按顺序排列):
-
RIFF chunk(必须)
-
Format chunk(必须)
-
Fact chunk(可选,附加块)
-
Data chunk(必须)
2.2 整体结构图¶
┌─────────────────────────────────────────────────┐
│ RIFF Chunk │
│ ID: "RIFF" Size: 文件总大小-8 Type: "WAVE" │
├─────────────────────────────────────────────────┤
│ Format Chunk (必须) │
│ ID: "fmt " Size: 16/18/40 音频格式信息 │
├─────────────────────────────────────────────────┤
│ Fact Chunk (可选) │
│ ID: "fact" Size: ≥4 采样总数 │
├─────────────────────────────────────────────────┤
│ Data Chunk (必须) │
│ ID: "data" Size: N 音频数据 │
└─────────────────────────────────────────────────┘
3、各个 Chunk 的具体内容¶
3.1 RIFF Chunk(资源交换文件块)¶
| 字段 | 大小 | 值/含义 | 示例(十六进制) |
|---|---|---|---|
| ID | 4 字节 | "RIFF"(固定) | 52 49 46 46 |
| Size | 4 字节 | ChunkData 字段的大小(文件总大小 - 8) | F4 FE 83 01 |
| ChunkData | - | 包含 FormType 和其他 chunk | - |
| FormType | 4 字节 | "WAVE"(固定) | 57 41 56 45 |
3.2 Format Chunk(格式块)¶
| 字段 | 大小 | 含义 | 说明 |
|---|---|---|---|
| ID | 4 字节 | "fmt "(注意最后的空格) | 66 6D 74 20 |
| Size | 4 字节 | Data 字段的大小 | 一般为 16(PCM) |
| Data 字段内容 | |||
| audio_format | 2 字节 | 音频数据格式 | 1 = PCM,其他见第 4 节 |
| channels | 2 字节 | 声道数 | 1 = 单声道,2 = 立体声 |
| sample_rate | 4 字节 | 采样频率(Hz) | 如 44100 = 44 AC 00 00 |
| bytes_per_sec | 4 字节 | 音频码率 | 每秒字节数 = 声道数 × 采样率 × 位深度 / 8 |
| block_align | 2 字节 | 块对齐 | 每个采样点字节数 = 声道数 × 位深度 / 8 |
| bits_per_sample | 2 字节 | 量化位数 | 16, 24, 32 等 |
| 扩展字段 | |||
| cbSize | 2 字节 | 扩展块长度 | 0 或 22(可选) |
| cbContent | 0/22 字节 | 扩展块内容 | 具体见第 5 节 |
3.3 Fact Chunk(可选)¶
| 字段 | 大小 | 含义 | 说明 |
|---|---|---|---|
| ID | 4 字节 | "fact" | 66 61 63 74 |
| Size | 4 字节 | 数据字段长度 | 最小为 4 |
| Data | 4 字节 | 采样总数 | 每个声道的采样总数 |
注意:采用压缩编码的 WAV 文件必须包含 Fact chunk。
3.4 Data Chunk(数据块)¶
| 字段 | 大小 | 含义 | 说明 |
|---|---|---|---|
| ID | 4 字节 | "data" | 64 61 74 61 |
| Size | 4 字节 | 音频数据长度 | N 字节 |
| Data | N 字节 | 音频数据 | 具体的采样数据 |
4、音频数据格式类型¶
在 Format chunk 中的 audio_format 字段定义了音频编码方式:
| 值(十六进制) | 名称 | 是否包含 Fact Chunk |
|---|---|---|
0x0001 |
WAVE_FORMAT_PCM | 否 |
0x0002 |
WAVE_FORMAT_ADPCM | 是 |
0x0006 |
WAVE_FORMAT_ALAW | 是 |
0x0007 |
WAVE_FORMAT_MULAW | 是 |
最常见的是 0x0001(PCM 格式)。
5、Format Chunk 扩展块¶
当 WAV 文件使用非 PCM 编码时,需要扩展格式块:
扩展块结构:
┌─────────────┬─────────────┬────────────────────────┐
| cbSize | cbContent |
| (2字节) | (0或22字节) |
├─────────────┼─────────────┼────────────────────────┤
| | valid_bits_per_sample (2字节) |
| | channel_mask (4字节) |
| | sub_format (16字节) |
└─────────────┴─────────────┴────────────────────────┘
字段说明:
-
cbSize:扩展块长度(0 或 22)
-
valid_bits_per_sample:有效采样位数
-
channel_mask:声道掩码(定义声道映射)
-
sub_format:16 字节的数据格式码
需要使用 WAVE_FORMAT_EXTENSIBLE 的情况:
-
PCM 数据量化位数 > 16
-
音频采样声道数 > 2
-
实际量化位数不是 8 的倍数
-
需要指定声道顺序到声卡播放顺序的映射
6、声音数据存储格式¶
Data chunk 中的音频数据按以下规则存储:
6.1 字节序¶
- 多字节样本采用小端模式(低位在前,高位在后)
6.2 声道排列¶
-
多声道采用交叉存储方式
-
立体声示例:L1, R1, L2, R2, L3, R3, ...
6.3 具体布局示例¶
(1) 8-bit 单声道
| 采样 1 | 采样 2 |
|---|---|
| 数据 1 | 数据 2 |
(2) 8-bit 双声道(立体声)
| 声道 1 采样 1 | 声道 2 采样 1 | 声道 1 采样 2 | 声道 2 采样 2 |
|---|---|---|---|
| L1 | R1 | L2 | R2 |
(3) 16-bit 单声道
| 采样 1 低字节 | 采样 1 高字节 | 采样 2 低字节 | 采样 2 高字节 |
|---|---|---|---|
| L1_lo | L1_hi | L2_lo | L2_hi |
(4) 16-bit 双声道(立体声)
声道 1 采样 1 声道 2 采样 1
┌──────┬──────┐ ┌──────┬──────┐
│L1_lo │L1_hi │ │R1_lo │R1_hi │
└──────┴──────┘ └──────┴──────┘
声道 1 采样 2 声道 2 采样 2
┌──────┬──────┐ ┌──────┬──────┐
│L2_lo │L2_hi │ │R2_lo │R2_hi │
└──────┴──────┘ └──────┴──────┘
7、WAV 文件实例分析¶
使用 WinHex 打开 WAV 文件的十六进制视图示例:
| 偏移地址 | 字节数 | 十六进制值 | 解析内容 |
|---|---|---|---|
| 00H | 4 | 52 49 46 46 |
'RIFF' 标识符 |
| 04H | 4 | F4 FE 83 01 |
数据长度:0x0183FEF4(小端) |
| 08H | 4 | 57 41 56 45 |
'WAVE' 标识符 |
| 0CH | 4 | 66 6D 74 20 |
'fmt '(注意末尾空格) |
| 10H | 4 | 10 00 00 00 |
Format chunk 大小:0x10(16 字节) |
| 14H | 2 | 01 00 |
编码格式:0x0001(PCM) |
| 16H | 2 | 02 00 |
声道数:0x0002(立体声) |
| 18H | 4 | 44 AC 00 00 |
采样率:0x0000AC44(44100 Hz) |
| 1CH | 4 | 10 B1 02 00 |
字节率:0x0002B110(176400 字节/秒) |
| 20H | 2 | 04 00 |
块对齐:0x0004(4 字节) |
| 22H | 2 | 10 00 |
位深度:0x0010(16 位) |
| 24H | 4 | 64 61 74 61 |
'data' 标识符 |
| 28H | 4 | 48 FE 83 01 |
音频数据长度:0x0183FE48 |
从偏移量 2CH 开始就是实际的音频数据。
8、重要计算公式¶
8.1 关键参数计算¶
-
字节率 = 采样率 × 声道数 × 位深度 / 8
-
块对齐 = 声道数 × 位深度 / 8
- 音频数据大小 = 采样数 × 声道数 × 位深度 / 8
- 播放时长 = 音频数据大小 / 字节率
8.2 示例计算(44.1kHz 16-bit 立体声)¶
采样率:44100 Hz
声道数:2
位深度:16 bits
字节率 = 44100 × 2 × 16 / 8 = 176400 字节/秒
块对齐 = 2 × 16 / 8 = 4 字节
1分钟音频大小 = 60 × 176400 ≈ 10.1 MB
9、工具推荐¶
9.1 十六进制查看工具¶
-
WinHex(Windows)
-
Hex Fiend(macOS)
-
xxd(命令行,跨平台)