1. 音频系统概述:数字音频基础与总线协议
本章是嵌入式音频开发的基石。理解数字音频的物理含义、数据组织方式以及硬件传输协议,是后续编写 ALSA 驱动和调试 Codec 的前提。我们将从三个核心维度展开:数字音频的量化参数、PCM 数据流的存储与搬运、以及三种主流数字音频总线(I2S、TDM、PDM)的协议细节。
1.1 数字音频基础三要素
模拟声音信号经过采样、量化、编码后变为离散的数字序列。决定这个序列质量与数据量的三个关键参数是:采样率(Sample Rate)、位深(Bit Depth) 和 声道数(Channels)。
| 参数 | 定义 | 常见值 | 对系统的影响 |
|---|---|---|---|
| 采样率 | 每秒对模拟信号采样的次数,单位 Hz (kHz) | 8k (语音)、44.1k (CD)、48k (DVD)、96k/192k (高保真) | 决定最高可还原频率(奈奎斯特频率 = 采样率/2);采样率越高,数据量越大 |
| 位深 | 每个采样点用多少比特表示 | 16-bit、24-bit、32-bit | 决定动态范围(信噪比 ≈ 6.02 × 位深 + 1.76 dB);位深越大,量化噪声越低 |
| 声道数 | 独立音频通道的数量 | 1 (Mono)、2 (Stereo)、6 (5.1)、8 (7.1) | 直接决定总线数据带宽需求;多声道需要 TDM 或更多 I2S 线 |
带宽估算公式:
数据率 (bps) = 采样率 (Hz) × 位深 (bits) × 声道数
示例: 48kHz / 24-bit / 2ch → 48,000 × 24 × 2 = 2,304,000 bps ≈ 2.3 Mbps
这个数值是选择 I2S 时钟频率和 DMA 带宽的重要依据。
数据率 (bps) = 采样率 (Hz) × 位深 (bits) × 声道数
示例: 48kHz / 24-bit / 2ch → 48,000 × 24 × 2 = 2,304,000 bps ≈ 2.3 Mbps
这个数值是选择 I2S 时钟频率和 DMA 带宽的重要依据。
1.2 PCM 数据流
PCM(Pulse Code Modulation,脉冲编码调制) 是最原始、最通用的数字音频表示形式。在嵌入式系统中,PCM 数据通常以 帧(Frame) 为单位在内存和音频外设之间搬运。
- 采样点(Sample):一个声道在一个采样时刻的量化值。对于 16-bit 位深,一个采样点占 2 字节;24-bit 占 3 字节;32-bit 占 4 字节。
- 帧(Frame):所有声道在同一时刻的采样点集合。例如立体声 16-bit 数据,一帧 = 左声道 2 字节 + 右声道 2 字节 = 4 字节。
- 周期(Period):硬件中断或 DMA 传输的粒度。ALSA 驱动中,一个 period 包含若干帧,通常对应一次硬件 FIFO 半满中断。
- 缓冲区(Buffer):由多个 period 组成的循环缓冲区,用于平滑数据流,防止 underrun/overrun。
PCM 数据在内存中的排列(交错模式 Interleaved):
内存地址递增方向 →
[L0][R0][L1][R1][L2][R2] ... [Ln][Rn]
↑ 帧0 ↑ 帧1 ↑ 帧2 ↑ 帧n
非交错模式(Non-interleaved):缓冲区A: [L0][L1][L2] ... [Ln]
缓冲区B: [R0][R1][R2] ... [Rn]
ALSA 驱动默认使用交错模式,但通过 snd_pcm_set_params() 可以配置为非交错。
1.3 I2S 总线协议
I2S(Inter-IC Sound,集成电路内置音频总线) 由飞利浦(现 NXP)制定,是嵌入式音频设备间传输 PCM 数据的事实标准。它使用三根主要信号线:
- BCLK(Bit Clock,位时钟):对应每一位数据的传输。频率 = 采样率 × 位深 × 声道数。
- LRCK(Left/Right Clock,左右声道时钟):也称帧同步时钟(FSYNC)。频率 = 采样率。高电平通常表示左声道,低电平表示右声道(或相反,取决于 Codec 配置)。
- SD(Serial Data,串行数据):传输 PCM 数据,可以是输入(SDI)或输出(SDO)。
I2S 时序要点:
1. 数据在 BCLK 的上升沿被采样,在下降沿变化(标准 Philips 模式)。
2. 数据从 LRCK 切换后的第二个 BCLK 上升沿开始传输(MSB 对齐),且 MSB 先传。
3. 如果位深小于 BCLK 每声道分配的 slot 宽度(例如 16-bit 数据放在 32-bit slot 中),低位会补零。
4. 常见的变体有 左对齐(Left-Justified) 和 右对齐(Right-Justified),驱动中需根据 Codec 数据手册配置。
1. 数据在 BCLK 的上升沿被采样,在下降沿变化(标准 Philips 模式)。
2. 数据从 LRCK 切换后的第二个 BCLK 上升沿开始传输(MSB 对齐),且 MSB 先传。
3. 如果位深小于 BCLK 每声道分配的 slot 宽度(例如 16-bit 数据放在 32-bit slot 中),低位会补零。
4. 常见的变体有 左对齐(Left-Justified) 和 右对齐(Right-Justified),驱动中需根据 Codec 数据手册配置。
1.4 TDM 总线协议
TDM(Time Division Multiplexing,时分复用) 是 I2S 的扩展,用于在单根数据线上传输多个声道。它通过在一个帧同步周期内划分多个 时隙(Slot) 来实现多声道复用。
- 帧同步(FSYNC):频率等于采样率,宽度通常为一个 slot 或一个 BCLK 周期。
- 时隙(Slot):每个声道独占一个固定长度的时隙。例如 8 声道 TDM,每帧包含 8 个 slot。
- Slot 宽度:通常等于位深(如 16-bit、24-bit、32-bit),但也可以大于位深(高位补零)。
- 数据对齐:数据在 slot 内可以是左对齐、右对齐或 I2S 对齐,由 Codec 和 CPU 的 DAI 控制器配置决定。
| 特性 | I2S | TDM |
|---|---|---|
| 声道数 | 固定 2 声道(左/右) | 2 ~ 16 声道(甚至更多) |
| 信号线 | BCLK, LRCK, SD | BCLK, FSYNC, SD(可多数据线) |
| 帧同步 | 50% 占空比方波 | 脉冲信号(通常 1 BCLK 宽度) |
| 典型应用 | 立体声耳机、麦克风 | 多声道音响、智能音箱麦克风阵列 |
| 驱动配置 | 设置格式(Philips/左/右对齐) | 设置 slot 数量、slot 宽度、FSYNC 极性 |
TDM 在 ALSA 驱动中的配置示例(伪代码):
/* 配置 CPU DAI 为 TDM 模式 */
snd_soc_dai_set_tdm_slot(cpu_dai,
tx_mask, /* 发送时隙掩码,如 0xFF 表示使用全部 8 个 slot */
rx_mask, /* 接收时隙掩码 */
slots, /* 总时隙数,如 8 */
slot_width /* 每个时隙的位宽,如 32 */);
/* 配置 Codec DAI 的 TDM 参数 */
snd_soc_dai_set_tdm_slot(codec_dai,
0xFF, /* Codec 在哪些 slot 上发送 */
0xFF, /* Codec 在哪些 slot 上接收 */
8, /* 8 个时隙 */
32); /* 每个时隙 32 位 */
1.5 PDM 总线协议
PDM(Pulse Density Modulation,脉冲密度调制) 是一种 1-bit 过采样调制技术,广泛用于数字麦克风(如 MEMS 麦克风)。与 PCM 不同,PDM 不是直接传输量化后的多比特数值,而是传输一个高速的 1-bit 流,其脉冲密度代表模拟信号的幅度。
- 工作原理:模拟信号被以极高频率(通常 1 MHz ~ 4 MHz)采样,输出一串 0/1 序列。信号幅度高时,1 的密度大;幅度低时,0 的密度大。
- 信号线:通常只需要 CLK(时钟) 和 DATA(数据) 两根线。时钟由 SoC 或 Codec 提供,麦克风在时钟的上升沿或下降沿输出数据。
- 解码需求:SoC 或 Codec 内部必须包含 PDM 转 PCM 的抽取滤波器(Decimation Filter),将高速 1-bit 流转换为标准 PCM 数据(如 48 kHz / 16-bit)。
- 立体声 PDM:两个麦克风可以共用一根 DATA 线,分别在时钟的上升沿和下降沿输出数据(双沿采样),从而节省引脚。
PDM vs PCM 对比:
- PDM 接口简单(2 线),适合小型数字麦克风阵列。
- PDM 数据不能直接被 ALSA 或音频应用使用,必须经过硬件或软件抽取滤波。
- 许多现代 Codec(如 WM8960、NAU88C22)内部集成了 PDM 输入接口,可以直接连接数字麦克风。
- 在驱动中,PDM 接口通常配置为 Codec 的 DAI 或辅助数字接口,需要设置时钟频率和抽取率。
- PDM 接口简单(2 线),适合小型数字麦克风阵列。
- PDM 数据不能直接被 ALSA 或音频应用使用,必须经过硬件或软件抽取滤波。
- 许多现代 Codec(如 WM8960、NAU88C22)内部集成了 PDM 输入接口,可以直接连接数字麦克风。
- 在驱动中,PDM 接口通常配置为 Codec 的 DAI 或辅助数字接口,需要设置时钟频率和抽取率。