1. HDMI音频概述:接口标准演进、数据包结构与I2S的关系
各位同学,咱们今天聊聊HDMI音频。说实话,我刚开始接触HDMI音频时,也觉得这东西挺玄乎的——明明就是一根线,怎么就能把视频和音频一起传过去?后来做了几个项目,踩了不少坑,才慢慢摸清楚这里面的门道。
1.1 HDMI接口标准的演进
HDMI从2002年诞生到现在,已经走过了二十多年。我最早接触的是HDMI 1.3版本,那时候还在做DVD播放器。嗯,咱们先看看各个版本的变化:
| 版本 | 发布时间 | 音频相关特性 |
|---|---|---|
| HDMI 1.0 | 2002年 | 支持8通道LPCM,192kHz/24bit |
| HDMI 1.3 | 2006年 | 增加Dolby TrueHD、DTS-HD MA无损格式 |
| HDMI 2.0 | 2013年 | 支持32通道音频,1536kHz采样率 |
| HDMI 2.1 | 2017年 | eARC增强音频回传,支持Dolby Atmos |
你可能会问,为什么音频通道数从8路涨到32路?说白了,家庭影院系统越来越复杂了。我记得2015年做一个高端AV接收机项目,客户要求支持11.2声道,那时候HDMI 2.0刚出来,我们团队还专门研究了一下怎么把这么多通道塞进一个数据流里。
核心要点:HDMI音频能力的提升,本质上是在带宽和协议层面不断"挤空间"。每次版本升级,音频通道数、采样率、位深都在涨。
1.2 HDMI音频数据包结构
HDMI传输音频,靠的是TMDS通道里的数据岛(Data Island)。说白了,视频信号占用了大部分带宽,音频数据就插在视频消隐期里传输。我刚开始做驱动时,总觉得这个设计很巧妙——不用额外布线,一根线搞定所有。
音频数据包的结构是这样的:
Audio Sample Packet (ASP) 格式:
┌─────────────────────────────────┐
│ Packet Header (4 bytes) │
│ - Data Byte Count │
│ - Packet Type (0x02 for audio) │
├─────────────────────────────────┤
│ Subpacket 0 (4 bytes) │
│ - Channel Status │
│ - Sample Data (2 bytes) │
├─────────────────────────────────┤
│ Subpacket 1 (4 bytes) │
│ - Channel Status │
│ - Sample Data (2 bytes) │
├─────────────────────────────────┤
│ ...更多Subpacket... │
└─────────────────────────────────┘
每个音频数据包最多携带4个样本(每个样本可以是16、20或24位)。我建议你重点关注Packet Header里的Data Byte Count字段——这个值如果算错了,音频就会断断续续。我曾经在一个项目中,因为把这个值写死了,导致48kHz采样率下正常,但切换到96kHz就出问题。排查了两天才发现是这里的问题。
实战技巧:调试HDMI音频时,先用逻辑分析仪抓一下Data Island的波形。看看Packet Type是不是0x02,Data Byte Count对不对。这招帮我解决过至少5个音频无声的bug。
1.3 I2S与HDMI的关系
I2S是飞利浦在1986年定义的音频总线标准。你想想看,HDMI要传输音频,但SoC内部处理音频用的还是I2S。所以这两者之间需要一个"翻译官"——HDMI发送器(Transmitter)。
典型的音频链路是这样的:
SoC/I2S Master
│
├─ I2S_BCLK (位时钟)
├─ I2S_LRCK (左右声道时钟)
├─ I2S_SDIN (串行数据)
└─ I2S_MCLK (主时钟,可选)
│
▼
HDMI Transmitter (如Silicon Image SiI9134)
│
├─ 将I2S数据打包成Audio Sample Packet
├─ 插入到TMDS数据流中
└─ 通过HDMI线缆发送
│
▼
HDMI Receiver (如ADV7611)
│
├─ 解析Audio Sample Packet
└─ 恢复出I2S信号给DAC或SoC
这里有个关键点:I2S的位时钟(BCLK)和HDMI的TMDS时钟是异步的。我建议你在驱动里处理好时钟域同步问题,否则会出现"噼啪"的爆音。我记得第一次做HDMI音频驱动时,没注意这个细节,结果播放音乐时每隔几秒就"咔"一声,被测试同事吐槽了好久。
避坑指南:我曾经遇到过一个案例——I2S的MCLK没有提供给HDMI Transmitter,导致音频采样率识别错误。HDMI规范里,MCLK不是必须的,但很多Transmitter芯片需要它来做时钟恢复。所以,建议你尽量把MCLK接上,省得后面出问题。
1.4 音频数据格式的映射关系
I2S传过来的数据,到了HDMI这边要做一些格式转换。咱们看看最常见的几种情况:
| I2S格式 | HDMI打包方式 | 注意事项 |
|---|---|---|
| 16位左对齐 | 直接映射到16位样本 | 简单,但动态范围有限 |
| 24位右对齐 | 需要做位对齐处理 | 注意LSB/MSB位置 |
| 32位I2S | 取高24位或高16位 | 取决于接收端能力 |
| TDM多通道 | 拆分成多个Audio Sample Packet | 通道映射要仔细 |
我个人习惯在驱动初始化时,先读取HDMI Transmitter的EDID信息,看看接收端支持什么格式。然后根据这个信息来配置I2S的格式。这样做的好处是——兼容性好,不会出现"有声音但格式不对"的尴尬情况。
总结一下:HDMI音频的核心就是——I2S负责"生产"音频数据,HDMI负责"打包运输"。驱动工程师要做的就是确保这两边的格式、时钟、通道映射都对得上。嗯,说起来简单,做起来嘛...咱们后面几章慢慢聊。
好了,这一章先到这里。下一章咱们会深入HDMI音频驱动的初始化流程,包括EDID解析和音频格式协商。到时候我会分享一个实际项目中的调试案例,保证让你少走弯路。