1. HDMI音频基础:接口标准演进、音频数据在HDMI中的传输方式、I2S与SPDIF协议对比

1.1 HDMI接口标准的演进之路

做音频驱动开发,首先得搞清楚HDMI这个接口到底是怎么一路走来的。我个人习惯把HDMI的演进分成三个阶段来理解,这样脉络更清晰。

第一阶段:HDMI 1.0 - 1.4(奠基期)

2002年HDMI 1.0刚出来的时候,说实话音频能力挺有限的。它只支持8通道的LPCM(线性脉冲编码调制),采样率最高到192kHz,位深24bit。嗯,这在当时已经算不错了,毕竟那时候DVD还是主流。

到了HDMI 1.3(2006年),开始支持Dolby TrueHD和DTS-HD Master Audio这些无损压缩格式。我记得第一次在项目中调试这个版本时,发现带宽从之前的165MHz提升到了340MHz,音频数据量一下子大了不少。

HDMI 1.4(2009年)引入了ARC(音频回传通道)。这个功能很实用——电视可以把音频信号回传给功放,省掉一根光纤线。我在做智能电视项目时,ARC的兼容性问题可没少折腾我。

第二阶段:HDMI 2.0 - 2.1(高带宽期)

HDMI 2.0把带宽干到了18Gbps,支持32通道音频。你想想看,32个声道!这在家庭影院里基本是天花板级别的配置了。采样率也提升到了1536kHz,虽然实际产品很少用到这么高。

HDMI 2.1(2017年)更是夸张,48Gbps的带宽,支持eARC(增强音频回传通道)。eARC相比ARC,带宽从1Mbps提升到了37Mbps,可以传输无损的Dolby Atmos和DTS:X。我在做游戏主机驱动时,2.1的eARC功能是必须拿下的硬骨头。

核心要点:HDMI音频能力的提升,本质上是带宽和通道数的双重扩展。从1.0的8通道到2.1的32通道,从ARC到eARC,每一步都对应着实际应用场景的升级。

1.2 音频数据在HDMI中的传输方式

HDMI传输音频,说白了就是把音频数据包塞进TMDS(最小化传输差分信号)通道里。这里有个关键概念——音频数据岛(Audio Data Island)。

HDMI的传输架构是这样的:视频数据占大头,音频数据被封装成一个个小包,插在视频消隐期(Blanking Interval)里传输。为什么这么做?因为视频信号是连续的,音频数据量相对小,利用消隐期传输可以省掉额外的物理通道。

音频数据包的格式,我直接给个实际项目中用到的结构体:

// HDMI音频数据岛包结构
typedef struct {
    uint8_t header[3];      // 包类型、版本号等
    uint8_t subpacket0[4];  // 音频样本数据
    uint8_t subpacket1[4];  // 音频样本数据
    uint8_t subpacket2[4];  // 音频样本数据
    uint8_t subpacket3[4];  // 音频样本数据
} hdmi_audio_packet_t;

每个音频数据岛包包含4个子包,每个子包4字节。这16字节里,承载着音频样本、通道状态、用户数据等信息。我曾经在调试一个4K@60Hz的HDMI输出时,发现音频偶尔出现爆音。查了两天才定位到问题——音频数据岛包的发送时序和视频消隐期没对齐,导致部分音频包被丢弃了。

传输流程大致如下:

  1. 音频源(比如SoC的I2S接口)输出PCM数据
  2. HDMI发送器将PCM数据封装成音频数据岛包
  3. 在视频消隐期,音频包被插入TMDS通道
  4. 接收端解析音频包,恢复出PCM数据

避坑指南:我曾经在项目中遇到一个坑——某些HDMI接收芯片对音频数据岛的时序要求非常严格。如果音频包发送得太密集,接收端会丢包。解决办法是控制音频包的发送速率,确保每个消隐期内发送的音频包数量不超过接收端的处理能力。

1.3 I2S与SPDIF协议对比

做HDMI音频驱动,I2S和SPDIF这两个协议是绕不开的。它们都是数字音频传输协议,但设计思路完全不同。

I2S(Inter-IC Sound)

I2S是飞利浦在1986年推出的,专门用于芯片之间的音频数据传输。它用三根线:

  • BCLK(位时钟):每个时钟周期传输一个bit
  • LRCLK(左右声道时钟):指示当前是左声道还是右声道
  • SDATA(串行数据):音频数据

I2S的优点是简单、低延迟、支持多通道。我在做多声道音频驱动时,I2S可以轻松扩展到8通道甚至更多。但缺点也很明显——传输距离短,一般不超过几十厘米,而且没有校验机制。

SPDIF(Sony/Philips Digital Interface)

SPDIF是消费电子领域的老将,用同轴电缆或光纤传输。它把音频数据和时钟信号编码在一起,只用一根线就能传。SPDIF的帧结构是这样的:

// SPDIF帧结构(每个子帧32bit)
// bit 0-3: 前导码(用于同步)
// bit 4-27: 音频数据(24bit)
// bit 28: 有效性标志
// bit 29: 用户数据
// bit 30: 通道状态
// bit 31: 奇偶校验

SPDIF的优势是传输距离远(光纤可达10米以上),而且自带校验。但它的通道数有限——标准SPDIF只支持2通道,虽然可以通过多路复用扩展到更多通道,但实现起来比较麻烦。

两者对比表格:

特性 I2S SPDIF
物理接口 3线(BCLK, LRCLK, SDATA) 1线(同轴或光纤)
最大通道数 理论上无限制(实际受硬件限制) 2通道(标准),可扩展
传输距离 几十厘米 同轴10米,光纤更远
时钟方式 独立时钟线 时钟嵌入数据流
校验机制 无 奇偶校验
典型应用 芯片间音频传输 设备间音频传输

在实际的HDMI音频驱动开发中,I2S和SPDIF各有各的用武之地。SoC内部通常用I2S连接音频编解码器和HDMI发送器,而SPDIF则用于外部音频输入。我建议你在设计驱动时,把I2S作为主路径,SPDIF作为备选或辅助路径。

注意事项:I2S和SPDIF的时钟同步问题是个大坑。如果I2S的BCLK和SPDIF的采样率不一致,会导致音频失真或丢帧。我曾经在一个项目中,I2S用48kHz采样率,SPDIF输入却是44.1kHz,结果音频输出全是杂音。解决办法是加一个异步采样率转换器(ASRC),或者统一时钟源。

1.4 小结

这一章我们聊了HDMI接口的演进、音频数据的传输方式,以及I2S和SPDIF的对比。说白了,HDMI音频驱动开发的核心就是理解数据怎么从源端到目的端,中间经过哪些封装、传输、解析步骤。下一章我们会深入HDMI音频驱动的软件架构,讲讲驱动层的具体实现。

嗯,先消化这些基础内容。有问题随时交流。