1. 音频基础概念:声音的物理特性、采样率与位深度、PCM编码原理、音频文件格式概览

做嵌入式音频开发,说白了就是跟声音打交道。但声音这东西看不见摸不着,你得先理解它的物理本质,才能知道怎么用代码去采集、处理和播放它。这一章我们就把基础打牢。

1.1 声音的物理特性

声音的本质是机械振动在介质中的传播。在空气中,它表现为疏密相间的纵波。我刚开始做音频驱动时,总觉得这些物理概念离代码很远,直到有一次调试麦克风阵列,发现采集到的波形全是噪声——后来才意识到是腔体共振频率没处理好。嗯,物理这东西,绕不过去。

声音有三个核心物理参数:

  • 频率(Frequency):单位Hz,决定音调高低。人耳可听范围约20Hz~20kHz。低于20Hz叫次声波,高于20kHz叫超声波。
  • 振幅(Amplitude):决定响度大小。单位dB(分贝),0dB是人耳能听到的最小声压。
  • 相位(Phase):描述波形在时间轴上的偏移。单位度或弧度。相位差在立体声和降噪算法中非常关键。

关键记忆点:频率决定音调,振幅决定响度,相位决定空间感。这三个参数是后续所有音频处理的基础。

1.2 采样率与位深度

模拟声音是连续的,但计算机只能处理离散的数字信号。怎么把连续信号变成离散数据?靠采样和量化。

采样率(Sample Rate)

采样率就是每秒采集多少个样本点。单位Hz。根据奈奎斯特采样定理:采样率必须大于信号最高频率的2倍,才能无失真地重建原始信号。

采样率 常见用途 最高可还原频率
8 kHz 电话语音 4 kHz
16 kHz VoIP、语音识别 8 kHz
44.1 kHz CD音质音乐 22.05 kHz
48 kHz DVD、专业音频 24 kHz
96 kHz 高解析音频 48 kHz

我的经验:在嵌入式Linux项目中,语音采集我习惯用16kHz,因为人声主要能量集中在4kHz以下,16kHz采样绰绰有余,还能节省CPU和内存。音乐播放则用44.1kHz或48kHz。

位深度(Bit Depth)

位深度决定每个采样点的精度。说白了,就是用一个多少位的整数来表示振幅大小。

  • 8位:256个量化等级,动态范围约48dB。噪声明显,基本不用。
  • 16位:65536个量化等级,动态范围约96dB。CD标准,嵌入式常用。
  • 24位:16777216个量化等级,动态范围约144dB。专业录音用。
  • 32位:浮点或定点,动态范围极大。多用于音频处理内部。

避坑指南:我曾经在一个项目里用了8位采样,结果回放时底噪大到无法接受。后来换成16位,问题立刻解决。记住:嵌入式音频最低用16位,别省那点存储空间。

1.3 PCM编码原理

PCM(Pulse Code Modulation,脉冲编码调制)是最原始、最直接的音频数字编码方式。它不做任何压缩,就是把模拟信号采样、量化、编码成二进制数据。

PCM的编码流程分三步:

  1. 采样:按固定时间间隔采集模拟信号的瞬时值。
  2. 量化:将采样值映射到离散的量化等级上。
  3. 编码:将量化值转换成二进制码字。

举个例子:一个16位、44.1kHz、单声道的PCM音频流,每秒产生的数据量是:

44.1 kHz × 16 bit × 1 channel = 705.6 kbps
换算成字节:705.6 / 8 = 88.2 KB/s

你想想看,一首3分钟的歌曲,光PCM数据就要15.8MB。这就是为什么需要压缩格式。

PCM数据在内存中的排列方式:

  • 小端序(Little-Endian):低字节在前,高字节在后。x86/ARM默认。
  • 大端序(Big-Endian):高字节在前,低字节在后。网络字节序。
  • 交错模式(Interleaved):左右声道数据交替排列。L R L R L R ...
  • 非交错模式(Non-Interleaved):先存完左声道所有样本,再存右声道。L L L ... R R R ...

我个人习惯在嵌入式Linux中使用小端序、交错模式的16位PCM。ALSA驱动默认就是这个格式,省去转换的麻烦。

1.4 音频文件格式概览

音频文件格式本质上就是PCM数据的容器,加上一些元数据头。我整理了一张对比表,方便你快速了解:

格式 扩展名 压缩方式 典型用途 嵌入式适用性
WAV .wav 无压缩(PCM) Windows、专业音频 ★★★★★ 最常用
MP3 .mp3 有损压缩 音乐播放 ★★★★ 需解码库
AAC .aac/.m4a 有损压缩 视频、流媒体 ★★★ 需解码库
FLAC .flac 无损压缩 高保真音乐 ★★★ 需解码库
OGG .ogg 有损/无损 开源项目 ★★ 需解码库
RAW .raw/.pcm 无头PCM 裸数据交换 ★★★★★ 最灵活

我的建议:在嵌入式Linux开发调试阶段,优先用WAV格式。它结构简单,没有编解码开销,用hexdump就能直接看数据。等调通了再考虑加MP3或AAC解码库。

WAV文件头结构(44字节)是每个嵌入式音频工程师必须手写的:

Offset  Size  Description
0       4     "RIFF" 标识
4       4     文件总大小 - 8
8       4     "WAVE" 标识
12      4     "fmt " 子块标识
16      4     子块1大小(16 for PCM)
20      2     音频格式(1 = PCM)
22      2     声道数
24      4     采样率
28      4     字节率
32      2     块对齐
34      2     位深度
36      4     "data" 子块标识
40      4     PCM数据大小

我曾经在调试一个USB音频设备时,发现播放出来的声音全是噪声。用hexdump一看,WAV头里的字节率算错了——声道数写成了2但数据是单声道。这种低级错误,排查起来最费时间。

知识体系总览

下面这张图把本章的核心概念串起来了,你可以把它当作后续学习的导航图:

音频基础概念知识体系 声音物理特性 频率 → 音调 振幅 → 响度 相位 → 空间感 采样率 & 位深度 奈奎斯特采样定理 量化精度与动态范围 常见采样率对比 PCM编码原理 采样 → 量化 → 编码 交错 vs 非交错 大端序 vs 小端序 音频文件格式 WAV MP3 FLAC RAW 核心逻辑:模拟声音 → 采样量化 → PCM编码 → 文件封装 → 存储/传输 嵌入式开发中,WAV和RAW是最常用的调试格式

这一章的内容是后续所有音频开发的基础。采样率和位深度决定了音频质量的上限,PCM编码是理解所有音频数据流的起点,文件格式则是你与存储和网络打交道的接口。把这些概念吃透,后面写驱动、调ALSA、做音频处理时,你心里就有底了。