3、音频编解码器选型:主流Codec芯片对比与I2S/PCM接口详解
做音频系统这么多年,选Codec芯片这事儿,我踩过的坑真不少。说白了,选对一颗Codec,项目就成功了一半。今天咱们就聊聊三款主流芯片——WM8960、TLV320AIC3204、ES8311,顺便把I2S和PCM接口掰开揉碎了讲清楚。
3.1 三款主流Codec芯片对比
先说说我个人的选型习惯。我一般会先看项目需求:是消费级产品还是工业级?功耗要求多严?需要几个麦克风?嗯,这些条件一列,芯片范围就缩小了。
| 参数 | WM8960 | TLV320AIC3204 | ES8311 |
|---|---|---|---|
| 厂商 | Wolfson (现Cirrus Logic) | TI (德州仪器) | Everest Semiconductor |
| 接口类型 | I2S / PCM | I2S / PCM / TDM | I2S / PCM |
| 采样率 | 8kHz ~ 96kHz | 8kHz ~ 192kHz | 8kHz ~ 96kHz |
| 信噪比(SNR) | 98dB (ADC) / 98dB (DAC) | 92dB (ADC) / 100dB (DAC) | 93dB (ADC) / 95dB (DAC) |
| 功耗 | 约 10mW (播放) | 约 8mW (播放) | 约 5mW (播放) |
| 内置DSP | 无 | 有 (MiniDSP) | 无 |
| 典型应用 | 便携音箱、车载 | 降噪耳机、智能设备 | 低功耗IoT、手表 |
3.2 各芯片实战经验
3.2.1 WM8960:经典中的经典
WM8960是我用得最多的一款。为什么?因为它皮实。我记得有一次做车载项目,环境温度高到离谱,其他芯片都开始跑调了,WM8960愣是稳如老狗。
它的特点很鲜明:
- 双声道D类功放:直接驱动喇叭,省掉外部功放芯片
- 内置PLL:时钟抖动容忍度高,省心
- 3D增强功能:听感调校空间大
3.2.2 TLV320AIC3204:DSP玩家的最爱
如果你要做降噪或者语音增强,AIC3204是首选。它内置的MiniDSP可以跑一些简单的滤波算法,不用额外加MCU。
我有个项目要做双麦克风降噪,用AIC3204的MiniDSP实现了自适应滤波器,效果还不错。不过要注意:
- MiniDSP的编程需要TI的PurePath Studio工具,学习曲线有点陡
- 寄存器配置比WM8960复杂,建议用TI提供的脚本生成工具
3.2.3 ES8311:低功耗小钢炮
ES8311是后起之秀,主打低功耗。做智能手表或者TWS耳机时,我经常推荐它。功耗只有WM8960的一半,但音质也不差。
它的亮点:
- 超低功耗:播放模式5mW,待机模式不到1μW
- 封装小:QFN-28,适合空间受限的产品
- 内置电荷泵:单电源供电即可,省掉负压电路
不过要注意,ES8311的I2S时序要求比较严格。我曾经遇到过BCLK频率不准导致声音断续的问题,后来发现是MCU的I2S时钟分频器配置错了。
3.3 I2S与PCM接口详解
这两个接口是Codec和主控通信的桥梁。很多新手搞混它们,其实说白了,I2S是PCM的一种特殊格式。
3.3.1 I2S接口
I2S(Inter-IC Sound)是飞利浦定义的音频总线标准。它有三根主要信号线:
- BCLK:位时钟,每个bit一个脉冲
- LRCK:左右声道选择,频率等于采样率
- SDATA:串行数据
时序关系是这样的:
BCLK: __ __ __ __ __ __ __ __
| |__| |__| |__| |__| |__| |__| |__|
LRCK: |_____________|_____________|_____________|
左声道 右声道 左声道
SDATA: [MSB ... LSB] [MSB ... LSB] [MSB ... LSB]
I2S有个特点:数据在BCLK的下降沿变化,在上升沿采样。嗯,这个细节很重要,我见过有人把极性搞反,结果数据全错位了。
3.3.2 PCM接口
PCM(Pulse Code Modulation)接口比I2S更灵活。它支持时分复用(TDM),可以同时传输多个声道。
PCM和I2S的主要区别:
- 帧同步信号:I2S用LRCK,PCM用FSYNC(帧同步脉冲)
- 数据对齐:I2S数据在LRCK变化后延迟一个BCLK,PCM数据与FSYNC对齐
- 声道数:I2S固定双声道,PCM可以扩展到8声道甚至更多
3.3.3 时钟配置避坑指南
我曾经在一个项目里,Codec死活不出声。查了三天,最后发现是MCLK频率不对。这里给大家总结一下时钟配置的要点:
- MCLK必须是BCLK的整数倍:通常MCLK = 256 × 采样率,或者128×、512×
- BCLK = 采样率 × 位宽 × 声道数:比如44.1kHz、16bit、立体声,BCLK = 44.1k × 16 × 2 = 1.4112MHz
- LRCK = 采样率:这个最简单,但要注意左右声道极性
3.4 驱动开发要点
最后聊聊驱动。Linux下Codec驱动通常用ASoC(ALSA System on Chip)框架。核心是注册一个snd_soc_codec_driver结构体:
static struct snd_soc_codec_driver soc_codec_dev_wm8960 = {
.probe = wm8960_probe,
.remove = wm8960_remove,
.suspend = wm8960_suspend,
.resume = wm8960_resume,
.controls = wm8960_snd_controls,
.num_controls = ARRAY_SIZE(wm8960_snd_controls),
.dapm_widgets = wm8960_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(wm8960_dapm_widgets),
.dapm_routes = wm8960_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(wm8960_dapm_routes),
};
这里要注意DAPM(动态音频电源管理)的配置。我刚开始写驱动时,DAPM路由配错了,导致播放时喇叭没声音,但耳机有声音。查了半天才发现是路径没打通。
嗯,今天就聊到这儿。下一章咱们讲麦克风阵列的硬件设计,到时候再细聊。