2、数字音频基础:量化、编码、PCM与WAV格式解析

各位好,欢迎来到第二章。上一章我们聊了声音的物理本质和采样定理,算是把「模拟」那半边讲清楚了。这一章我们正式进入数字域,看看模拟信号是怎么变成一串串0和1的。

说白了,数字音频的核心就三件事:量化、编码、封装。我做了十几年音频处理,见过太多新手在这三个环节上踩坑。尤其是量化噪声和WAV头解析,几乎是每个入门者必过的坎。咱们一个一个来拆。

2.1 量化:从连续到离散的「舍入艺术」

采样把时间轴离散化了,但每个采样点的幅度还是连续的。量化要做的,就是把这种连续幅度值映射到有限个离散等级上。

举个例子。假设一个信号幅度范围是 -1V 到 +1V,我们用 3 bit 来量化。3 bit 能表示 2³ = 8 个等级。那么每个等级覆盖的电压范围就是 (1 - (-1)) / 8 = 0.25V。

实际信号落在哪个区间,我们就用该区间的代表值(通常是中点)来近似。这个过程,本质上就是舍入。

核心公式:

量化步长 Δ = (Vmax - Vmin) / 2^N

其中 N 是量化位数,Vmax 和 Vmin 是信号幅度的上下限。

量化位数越高,步长越小,精度越高。但代价是数据量成倍增长。我记得刚入行时做过一个项目,为了省存储空间,把 24 bit 的录音强行截成 8 bit。结果回放时底噪大得吓人,背景里全是「沙沙」声——那就是量化噪声。

2.1.1 量化噪声与信噪比

量化误差是不可避免的。你想想看,一个连续值被强行「挤」到最近的离散等级上,肯定有偏差。这个偏差就是量化噪声。

对于均匀量化(也就是等步长量化),量化噪声的功率可以近似为 Δ²/12。而信号的最大功率是 (Vmax - Vmin)² / 8。两者一除,就得到了理论上的最大信噪比:

SNR ≈ 6.02N + 1.76 dB

这个公式你肯定见过。每增加 1 bit,信噪比提升约 6 dB。CD 用的是 16 bit,理论 SNR 大约是 98 dB。人耳的动态范围大概在 120 dB 左右,所以 16 bit 对于消费级音乐来说基本够用,但专业录音棚通常用 24 bit,就是为了留足余量。

我的经验: 实际量化噪声往往比理论值大 3-6 dB。原因很简单——信号不是理想的正弦波,量化器也不是理想的。做降噪滤波器设计时,我习惯把量化噪声当作一个平坦的底噪来处理,但要注意它其实和信号是相关的,不是纯白噪声。

2.2 编码:把量化值变成二进制

量化完的数值,得用二进制表示出来。这个过程就是编码。最常见的编码方式是脉冲编码调制(PCM)。

PCM 编码其实很简单:每个采样点的量化值,直接转换成对应的二进制数。比如量化值是 127(假设是 8 bit 无符号),二进制就是 01111111。

但这里有个坑——有符号 vs 无符号。音频信号是交流信号,有正有负。如果用无符号整数表示,就得加一个直流偏置。CD 用的就是有符号 16 bit 整数,范围是 -32768 到 +32767。0 值对应静音。

我见过不少新手在写 WAV 解析器时,把有符号数当无符号读,结果波形全偏了,听起来像加了直流偏移的「噗噗」声。嗯,这个坑我年轻时也踩过。

2.2.1 常见的 PCM 编码格式

格式 位数 表示方式 典型应用
整数 PCM 8 / 16 / 24 / 32 有符号或无符号整数 WAV、AIFF、CD
浮点 PCM 32 / 64 IEEE 754 浮点数 专业音频软件内部处理
A-law / μ-law 8 非线性量化 电话语音(G.711)

浮点 PCM 在 DSP 处理中非常常见。它的动态范围极大,几乎不用担心溢出问题。但要注意,浮点运算的精度损失和整数不同,做定点化时得小心。

避坑指南: 我曾经在移植一个浮点降噪算法到嵌入式平台时,直接用了 16 bit 整数。结果算法完全失效——因为浮点滤波器系数需要很高的精度,16 bit 根本不够。后来改用 32 bit 定点数,才勉强跑起来。所以,编码格式的选择直接影响算法性能,别想当然。

2.3 PCM 与 WAV 格式解析

PCM 是编码方式,WAV 是文件容器。WAV 基于 RIFF(Resource Interchange File Format)结构,说白了就是一块一块的数据拼在一起。

一个标准的 WAV 文件包含三个主要块:

  1. RIFF 头:标识文件类型,总文件大小。
  2. fmt 块:描述音频格式信息(采样率、位数、声道数等)。
  3. data 块:实际的 PCM 采样数据。

下面是一个典型的 WAV 文件头结构(44 字节):

偏移量  长度    内容                    说明
0       4       "RIFF"                  RIFF 标识
4       4       文件大小 - 8            整个文件减去前8字节
8       4       "WAVE"                  WAVE 标识
12      4       "fmt "                  fmt 块标识(注意有空格)
16      4       16                      fmt 块大小(PCM 格式固定为16)
20      2       1                       音频格式(1 = PCM)
22      2       2                       声道数(1=单声道,2=立体声)
24      4       44100                   采样率
28      4       176400                  字节率 = 采样率 × 声道数 × 位深/8
32      2       4                       块对齐 = 声道数 × 位深/8
34      2       16                      位深
36      4       "data"                  data 块标识
40      4       数据大小                 PCM 数据的总字节数
44      ...     数据开始                 PCM 采样数据

这个结构我背得滚瓜烂熟。为什么?因为当年写一个实时音频播放器时,WAV 头解析错了,导致播放出来的声音全是「吱吱」的噪声。查了一整天,最后发现是 fmt 块大小字段读错了——有些软件写的不是 16,而是 18 或 40(扩展格式)。从那以后,我写解析器都会先检查 fmt 块大小,再做相应处理。

实用技巧: 解析 WAV 时,不要硬编码偏移量。应该按块结构来读:先读 4 字节块标识,再读 4 字节块大小,然后根据块大小读取块内容。这样即使遇到非标准 WAV 文件,也能正确解析。

2.4 本章知识体系

下面这张图把量化、编码、PCM 和 WAV 的关系串起来了。建议你多看几遍,理解每个环节的输入输出是什么。

数字音频基础:量化、编码、PCM与WAV格式 数字音频基础:量化、编码、PCM与WAV格式 模拟信号 采样 量化 PCM编码 WAV封装 数字信号 关键说明: 1. 采样:将连续时间离散化,核心参数是采样率(如 44.1kHz)。 2. 量化:将连续幅度离散化,核心参数是位深(如 16 bit)。 3. PCM编码:将量化值转换为二进制,是最原始的数字音频表示。 4. WAV封装:在PCM数据外加上文件头,包含格式描述信息。

2.5 小结

这一章我们走完了从模拟到数字的完整链路:采样 → 量化 → 编码 → 封装。量化决定了精度和噪声,编码决定了表示方式,WAV 则是我们最常接触的容器格式。

我个人建议,初学者最好亲手写一个 WAV 解析器。不用多复杂,能读出采样率、位深、声道数,然后把 PCM 数据打印成波形图就行。这个过程会让你对数字音频的理解深一个层次。