2. 音频基础
做音频硬件这些年,我最大的感触就是——信号在模拟域和数字域之间来回穿梭,就像在两个世界之间搭桥。你如果不理解这两边的“语言”,那调试Codec的时候就会一头雾水。这一章,咱们就把这些基础概念掰开揉碎了讲清楚。
模拟信号 vs 数字信号
说白了,模拟信号是连续的,数字信号是离散的。你对着麦克风说话,声带振动带动空气,空气振动推动麦克风振膜,振膜产生一个连续变化的电压——这就是模拟信号。而数字信号呢,是把那个连续电压每隔一小段时间“拍一张照片”,然后用一串0和1来表示。
我刚开始做项目时,总觉得模拟信号“更真实”,数字信号“有损失”。后来发现,数字信号虽然采样过程有量化误差,但它抗干扰能力强啊。你想想看,一根长线缆传模拟信号,走几米就衰减得不行,还容易引入噪声。但数字信号只要0和1没判错,就能完美恢复。
核心区别总结:
- 连续性:模拟信号在时间和幅度上连续;数字信号在时间和幅度上都离散
- 抗干扰:模拟信号易受噪声影响;数字信号有噪声容限,抗干扰能力强
- 存储与处理:模拟信号难以直接存储和计算;数字信号可以用DSP、CPU灵活处理
- 带宽需求:模拟信号理论上无限带宽;数字信号受采样率和位深度限制
采样率与位深度
这两个参数决定了数字音频的质量。我经常跟团队里的新人说:“采样率决定你能录多高的频率,位深度决定你能听多安静的声音。”
采样率
根据奈奎斯特采样定理,采样率必须大于信号最高频率的两倍,才能无失真地重建原始信号。人耳能听到的频率范围大约是20Hz~20kHz,所以CD标准的44.1kHz采样率就是这么来的——刚好覆盖20kHz,留一点余量。
常见的采样率有这些:
| 采样率 | 典型应用 | 最高可重建频率 |
|---|---|---|
| 8 kHz | 电话语音 | 4 kHz |
| 16 kHz | VoIP、语音识别 | 8 kHz |
| 44.1 kHz | CD、MP3 | 22.05 kHz |
| 48 kHz | DVD、影视音频 | 24 kHz |
| 96 kHz | 高解析音频、录音棚 | 48 kHz |
| 192 kHz | 专业录音、母带处理 | 96 kHz |
注意:采样率不是越高越好。我曾经在一个项目中把采样率从48kHz改成192kHz,结果I2S时钟频率翻了两番,PCB走线稍微长一点就出现信号完整性问题。高采样率对硬件设计的要求更高,功耗也更大。选采样率时,够用就好。
位深度
位深度决定了每个采样点的精度。16位就是每个点用16个bit表示,动态范围大约是96dB。24位能到144dB。你想想看,16位和24位差了多少?差了48dB,差不多是8倍的音量范围。
我个人的习惯是:消费类产品用16位就够了,但如果是专业音频设备,至少24位起步。为什么?因为后面还要做音量调节、混音、滤波这些处理,每做一次运算都会引入量化误差,位深度大一点,误差积累的空间就大一些。
小技巧:调试Codec时,如果发现底噪偏大,先检查一下位深度配置。我曾经遇到过Codec的I2S接口配置成了16位,但DSP那边发的是24位数据,结果高位被截断,声音听起来就像隔着一层纱。把两边对齐就好了。
I2S总线协议详解
I2S(Inter-IC Sound)是飞利浦公司在1986年提出的数字音频总线标准。现在几乎所有Codec、DSP、SoC都支持它。说白了,它就是数字音频的“高速公路”,负责把音频数据从一个芯片搬到另一个芯片。
I2S总线有三条核心信号线:
- SCK(位时钟,Bit Clock):也叫BCLK,每个脉冲对应一个数据位
- WS(帧时钟,Word Select):也叫LRCK,左右声道切换信号
- SD(数据线,Serial Data):串行传输音频数据
嗯,这里要注意,有些芯片厂商的命名不一样。比如TI喜欢叫BCLK、WCLK、DIN/DOUT;Cirrus Logic可能叫SCLK、LRCK、SDIN/SDOUT。但功能是一样的,别被名字搞晕了。
时序关系
I2S的时序其实不复杂。WS为低电平时传输左声道数据,高电平时传输右声道数据。数据在SCK的上升沿被采样,MSB(最高有效位)先传。WS的切换发生在SCK的下降沿,比数据位早一个时钟周期——这是为了给接收端留出准备时间。
我画了一张时序图,帮你直观理解:
时钟频率计算
SCK的频率怎么算?很简单:
SCK频率 = 采样率 × 位深度 × 声道数 × 每帧时钟数
举个例子,CD音质(44.1kHz、16位、立体声):
SCK = 44100 × 16 × 2 = 1.4112 MHz
如果是192kHz、24位、立体声:
SCK = 192000 × 24 × 2 = 9.216 MHz
你看,频率上去了,对PCB走线的要求就高了。我做过一个项目,SCK跑到12.288MHz,结果因为走线太长,信号反射严重,Codec经常丢数据。后来把走线缩短到2cm以内,加了个22Ω的串联电阻,问题就解决了。
常见的音频数据格式
I2S协议本身定义了时序,但数据在总线上的排列方式还有几种变体。我遇到过不少工程师,明明I2S时序对了,但声音不对,最后发现是数据格式没配对。
| 格式名称 | 数据对齐方式 | WS与数据关系 | 典型应用 |
|---|---|---|---|
| I2S(标准) | MSB对齐,延迟1个SCK | 数据在WS切换后第2个SCK上升沿开始 | 大多数Codec默认模式 |
| 左对齐(Left-Justified) | MSB对齐,无延迟 | 数据在WS切换后的第1个SCK上升沿开始 | 部分DSP、老式Codec |
| 右对齐(Right-Justified) | LSB对齐 | 数据在SCK帧末尾对齐 | 某些专用音频处理器 |
| TDM(时分复用) | 多声道时分复用 | 一个WS周期内传输多个声道数据 | 多声道音频系统、车载音频 |
避坑指南:我曾经在一个项目中,SoC的I2S控制器默认输出左对齐格式,但Codec配置成了标准I2S格式。结果声音听起来像“卡带”一样,每个采样点都错了一位。用示波器抓了WS和SD的波形,发现数据确实偏移了一个时钟周期。把Codec的格式寄存器改成左对齐,声音就正常了。所以,调试时一定要先确认两边的数据格式一致。
数据位宽与填充
还有一个容易踩的坑:数据位宽。比如你配置了24位数据,但I2S的帧长度是32位(每个声道32个SCK周期)。多出来的8位怎么办?
有两种处理方式:
- 零填充:高位或低位补0,这是最常见的方式
- 符号扩展:用符号位填充多余位,主要用于某些DSP
我个人的建议是:尽量让发送端和接收端的位宽一致。如果实在不一致,优先选择零填充,并且确认填充的是高位还是低位。这个在Codec的数据手册里一般都有说明,别想当然。
调试小技巧:用逻辑分析仪抓I2S总线时,别只看波形对不对。把抓到的数据解码出来,看看每个采样点的数值是否合理。比如静音时数据应该是0或者接近0的小值,如果看到一堆0xFFFF或者0x7FFF,那多半是格式或位宽配错了。
本章知识体系
最后,我用一张图把这一章的核心逻辑串起来:
从模拟信号到数字信号,经过ADC转换,由采样率和位深度决定数字域的质量,再通过I2S总线传输,最后选择合适的数据格式让收发双方对齐。每一步都环环相扣,哪一环出了问题,最终听到的声音都会不对劲。