1. 音频系统概述:数字音频基础与总线协议

音频驱动开发的核心是理解声音如何从模拟信号转换为数字数据,再通过系统总线传输到编解码器(Codec)最终驱动扬声器或耳机。本章从数字音频的三个基本参数——采样率、位深、声道——开始,逐步深入到PCM数据流在内存中的组织方式,最后讲解I2S/TDM总线协议如何物理传输这些数据。这些概念是后续配置ALSA驱动和DMA传输的基石。

1.1 数字音频三要素:采样率、位深、声道

模拟声音信号在时间上和幅度上都是连续的。数字音频通过三个维度来描述一段声音:

参数 定义 常见值 对音质/带宽的影响
采样率 (Sample Rate) 每秒对模拟信号采样的次数,单位 Hz (kHz) 8k (电话), 44.1k (CD), 48k (DVD/HDMI), 96k/192k (高解析) 决定频率上限(奈奎斯特频率 = 采样率/2)。越高越能保留高频细节,但数据量线性增长。
位深 (Bit Depth) 每个采样点用多少比特表示幅度,决定动态范围 16-bit (CD), 24-bit (录音室), 32-bit float (处理) 动态范围 ≈ 6.02 × 位深 + 1.76 dB。16-bit 约 96 dB,24-bit 约 144 dB。位深越大,信噪比越高。
声道数 (Channels) 独立音频信号的数量 1 (Mono), 2 (Stereo), 6 (5.1), 8 (7.1) 决定空间感和数据并行度。每增加一个声道,数据吞吐量翻倍。
工程师经验: 在嵌入式系统中,采样率和位深直接决定了DMA传输的带宽需求。例如,48kHz / 24-bit / 2声道的数据率 = 48000 × 3字节 × 2 = 288,000 字节/秒 ≈ 2.3 Mbps。如果系统总线或DMA通道带宽不足,就会出现断音(XRUN)。

1.2 PCM数据流:从内存到Codec的管道

PCM(Pulse Code Modulation,脉冲编码调制)是数字音频最基础的未压缩格式。在Linux ALSA系统中,PCM数据流是应用程序与音频硬件之间的数据通道。

一个典型的PCM数据流包含以下逻辑层次:

  1. 应用程序缓冲区: 用户空间程序(如aplay、媒体播放器)填充PCM数据。
  2. ALSA中间层缓冲区: 内核中的环形缓冲区(Ring Buffer),由ALSA PCM中间层管理。
  3. DMA传输: DMA控制器将数据从内存搬运到I2S/TDM控制器的FIFO。
  4. 串行总线: I2S/TDM控制器将并行数据转换为串行位流发送给Codec。
  5. Codec DAC: 数模转换器将数字位流还原为模拟信号。
PCM数据在内存中的排列(交错模式):
对于2声道、16-bit立体声,一个采样帧(Frame)包含左声道和右声道各2字节,共4字节。
内存顺序:[L0][R0][L1][R1][L2][R2] ...
这种模式称为交错(Interleaved),是嵌入式系统中最常用的格式。

下面这张SVG图展示了PCM数据从应用程序到Codec的完整流动路径:

PCM数据流架构图 PCM数据流:从应用程序到Codec 应用程序 ALSA 环形缓冲区 DMA 控制器 I2S 控制器 Codec (DAC) 数据流向说明: 应用程序写入PCM数据 → ALSA内核缓冲区 → DMA搬运到I2S FIFO → I2S串行发送 → Codec还原为模拟信号

1.3 I2S总线协议:数字音频的脊梁

I2S(Inter-IC Sound,集成电路内置音频总线)是飞利浦公司制定的串行总线标准,专门用于连接数字音频设备(如CPU与Codec、DSP与Codec)。它使用三根主要信号线:

  • BCLK (位时钟): 对应数字信号的每一位。频率 = 采样率 × 位深 × 声道数。
  • LRCK (左右声道时钟/帧同步): 指示当前传输的是左声道还是右声道。频率 = 采样率。
  • SD (串行数据): 二进制PCM数据,通常以二进制补码格式传输。

I2S标准时序特点:

  • LRCK为低电平时传输左声道数据,高电平时传输右声道数据(Philips标准)。
  • 数据在BCLK的上升沿被采样,MSB(最高有效位)先传输。
  • 数据位宽可以小于BCLK周期数,未使用的BCLK周期填充0。

下面这张SVG图展示了I2S总线的典型时序波形:

I2S总线时序图 I2S总线时序(Philips标准,16-bit数据) BCLK LRCK SD 左声道数据 (LRCK=低) 右声道数据 (LRCK=高) BCLK频率 = 采样率 × 位深 × 声道数 = 48k × 16 × 2 = 1.536 MHz LRCK频率 = 采样率 = 48 kHz,一个LRCK周期内传输一个声道的完整采样

1.4 TDM总线协议:多声道扩展

TDM(Time Division Multiplexing,时分复用)是I2S的扩展,允许在一条数据线上传输多个声道。TDM在I2S的三线基础上,将LRCK替换为帧同步信号(FSYNC),并在一个帧周期内划分多个时隙(Slot),每个时隙对应一个声道。

特性 I2S TDM
声道数 固定2声道(左/右) 可配置,最多支持16或32声道
帧同步信号 LRCK,50%占空比 FSYNC,通常为1个位时钟宽度的脉冲
数据线 1条SD 1条或多条(可配置)
典型应用 立体声耳机/麦克风 多麦克风阵列、环绕声系统、数字信号处理器互联
时隙对齐 LRCK边沿对齐 FSYNC脉冲后第一个BCLK对齐

下面这张SVG图展示了TDM协议在一个帧周期内传输4个声道数据的结构:

TDM总线帧结构图 TDM总线帧结构(4声道,16-bit数据) FSYNC BCLK SD Slot 0 (CH1) Slot 1 (CH2) Slot 2 (CH3) Slot 3 (CH4) 一个TDM帧包含4个时隙,每个时隙16个BCLK周期,对应一个声道的完整采样数据。 FSYNC脉冲标志帧起始,后续数据按配置的时隙顺序排列。 TDM常用于多麦克风阵列(如智能音箱的远场拾音)或环绕声输出。

1.5 关键参数计算与配置示例

在实际驱动开发中,需要根据硬件规格计算并配置I2S/TDM控制器的时钟分频系数。以下是一个典型的计算流程:

示例:配置I2S接口播放48kHz / 24-bit / 2声道音频
系统主时钟 (MCLK) = 12.288 MHz (常见音频主时钟)
所需BCLK = 48,000 × 24 × 2 = 2,304,000 Hz = 2.304 MHz
BCLK分频系数 = MCLK / BCLK = 12.288 MHz / 2.304 MHz = 5.333...
实际配置时,通常选择整数分频或使用PLL精确合成。许多Codec要求MCLK是采样率的整数倍(如256×fs、384×fs)。
/* 伪代码:I2S控制器时钟配置 */
#define SAMPLE_RATE    48000
#define BIT_DEPTH      24
#define CHANNELS       2

/* 计算BCLK */
uint32_t bclk_freq = SAMPLE_RATE * BIT_DEPTH * CHANNELS;  /* 2.304 MHz */

/* 假设MCLK来自外部晶振12.288 MHz */
uint32_t mclk_freq = 12288000;
uint32_t bclk_div = mclk_freq / bclk_freq;  /* 分频系数 = 5 */

/* 配置I2S控制器寄存器 */
i2s_regs->I2SCKF = bclk_div - 1;  /* 分频值写入时钟分频寄存器 */
i2s_regs->I2SMOD = (CHANNELS == 2) ? I2S_MODE_STEREO : I2S_MODE_MONO;
i2s_regs->I2SDWP = BIT_DEPTH;    /* 数据字长配置 */
常见陷阱: 在配置TDM模式时,务必确认Codec支持的时隙数量和位宽。有些Codec要求每个时隙的BCLK数必须等于位深,而有些则允许填充额外的BCLK周期。错误的时隙配置会导致声道错位或数据丢失。

1.6 本章小结