1. 课程导入

车载音频不是“把手机音频搬到车上”这么简单。车内有多个音源(媒体、导航、电话、语音助手、倒车雷达、ADAS 提示音)、多个输出区(主驾、副驾、后排、头枕、外放)、多种总线(I2S、TDM、A2B、MOST、SPDIF)以及严格的实时性与安全要求。Android Audio HAL 正是连接 Android 音频框架与底层车载音频硬件的关键层:它把 AudioFlinger 的流、设备、音量、路由请求,翻译成具体 SoC/DSP/功放能执行的配置与数据通道。

本课程的目标不是背 API,而是建立“从应用请求到扬声器出声”的完整链路认知:能读懂 HAL 接口、能定位音频不通的环节、能按车规要求设计路由与音量策略,并能与驱动、DSP、功放团队高效协作。

一、学习目标:从“会用”到“能改、能调、能排障”

  • 理解框架:掌握 Android Audio 架构中 App → AudioService → AudioFlinger → Audio HAL → Driver/DSP → Codec/Amp 的数据与控制路径。
  • 掌握接口:熟悉 HIDL/AIDL 两种 HAL 形态,理解 IDevice、IStreamOut、IStreamIn 等核心接口的职责边界。
  • 能配路由:根据场景(媒体/导航/电话/语音)配置 audio_policy_configuration.xml、audio_policy_volumes.xml 等策略文件。
  • 能调参数:理解采样率、位深、通道数、period size、latency、增益、混音策略对音质与延迟的影响。
  • 能排故障:从 logcat、dumpsys media.audio_flinger、tinyplay/tinycap、HAL 日志逐层定位“没声音、爆音、断续、路由错”。

二、核心概念:先建立一张“音频地图”

Android 音频系统可以按“控制面”和“数据面”两条线理解。控制面负责设备枚举、路由选择、音量映射、策略决策;数据面负责 PCM 采样数据的搬运与混音。Audio HAL 同时横跨两面:它既向上报告“我有哪些设备、支持哪些格式”,也向下执行“把这条流送到这个设备、用这个增益”。

概念所在层关键作用车载关注点
AudioTrack / AudioRecord应用层播放/录制 PCM 流多音源并发、焦点抢占
AudioService / AudioPolicy框架层策略、焦点、音量、路由决策驾驶安全优先级、分区音量
AudioFlinger框架层混音、重采样、流管理低延迟、多区混音
Audio HALHAL 层设备/流抽象,连接框架与驱动HIDL/AIDL、车规稳定性
ALSA / DSP / Amp内核与硬件PCM 传输、DSP 处理、功放驱动I2S/TDM/A2B、上电时序

三、整体框架:一张图看清 Audio HAL 的位置

下面的 SVG 展示了从应用请求到扬声器输出的完整链路,以及 Audio HAL 在其中的“翻译官”角色。注意控制面与数据面是并行的:策略决定“走哪条路”,HAL 与驱动负责“把数据搬过去”。

Android 车载音频链路与 Audio HAL 位置 应用层 媒体 / 导航 / 电话 / 语音 框架层 AudioService / AudioPolicy AudioFlinger 混音 / 重采样 / 流管理 Audio HAL HIDL / AIDL 接口 控制面:策略 / 路由 / 音量 内核 / 驱动 ALSA / I2S / TDM / A2B DSP / 功放 EQ / 延时 / 增益 扬声器 / 分区 主驾 / 副驾 / 后排 / 头枕 数据面:PCM 流 / 混音后输出 关键理解 1. 控制面决定“用哪个设备、走哪条路由、音量多大”,由 AudioPolicy 与 HAL 的设备枚举共同完成。 2. 数据面决定“PCM 数据如何搬运、混音、重采样”,由 AudioFlinger 与 HAL 的流接口协作。 3. 车载场景中,安全提示音(倒车雷达、ADAS)通常拥有更高优先级,可能触发闪避或强制路由。 4. 排障时先看控制面(路由/音量是否正确),再看数据面(流是否打开、PCM 是否有数据)。

四、方法流程:一次播放请求的完整旅程

以“导航播报同时播放音乐”为例,理解 Audio HAL 的工作流程:

  1. 导航 App 创建 AudioTrack,声明 usage=ASSISTANCE_NAVIGATION_GUIDANCE。
  2. AudioPolicy 根据策略决定导航流走“主驾扬声器”,音乐流走“全车扬声器”,并可能对音乐做闪避(duck)。
  3. AudioFlinger 为两条流分别建立输出线程,混音后写入对应的 HAL 输出流。
  4. Audio HAL 的 IStreamOut::write() 接收 PCM 数据,按配置写入 ALSA 设备节点或 DSP 通道。
  5. DSP 执行 EQ、延时、分频,功放驱动扬声器发声。
  6. 若导航播报结束,AudioPolicy 恢复音乐音量,HAL 无需感知“闪避”本身,只执行音量/路由变更。
# 典型排查命令
adb shell dumpsys media.audio_flinger
adb shell dumpsys media.audio_policy
adb shell logcat -s AudioFlinger AudioPolicyManager AudioHal
adb shell tinyplay /data/test.wav -D 0 -d 0
adb shell tinycap /data/rec.wav -D 0 -d 0 -c 2 -r 48000

五、案例/场景:车载音频的典型挑战

假设车辆启动后,用户发现“导航有声音,但音乐没有”。按链路逐层排查:先确认 AudioPolicy 是否把媒体流路由到了正确设备;再检查 AudioFlinger 是否创建了对应输出流;然后看 HAL 是否收到 write 调用;最后用 tinyplay 直接测试 HAL 以下是否出声。若 tinyplay 正常而 App 无声,问题多在策略或焦点;若 tinyplay 也无声,问题在 HAL、驱动或硬件。

车载音频与手机音频最大的差异在于“多区、多优先级、多总线”。学习时始终带着三个问题:这条流属于哪个 usage?应该送到哪个 zone?与其它流冲突时谁让谁?

六、误区与复盘

  • 误区一:把 HAL 当驱动。HAL 是抽象层,不直接操作寄存器;它通过 ALSA/DSP 接口与内核交互。
  • 误区二:只关注数据面。大量“没声音”问题其实出在路由与音量策略,而非 PCM 搬运。
  • 误区三:忽略车规时序。功放上电、I2S 时钟稳定、DSP 加载都需要时间,HAL 打开流时若未等待就绪,会出现爆音或静音。
  • 复盘方法:每次排障后记录“现象 → 层级 → 证据 → 根因 → 修复”,形成自己的车载音频故障树。

七、学习路径建议

建议按“框架 → 接口 → 策略 → 调试 → 实战”五步推进:先建立整体链路认知,再深入 HIDL/AIDL 接口定义,接着掌握 audio_policy_configuration.xml 等策略配置,然后熟练使用 dumpsys、logcat、tinyplay 等工具,最后通过多音区、低延迟、语音交互等真实场景巩固。每学完一个模块,都回到本节的框架图,确认自己能在图上指出对应的位置与数据流向。

本课程涉及大量配置与日志,请务必在真实或模拟车载环境中动手验证。只看不练,很难建立对路由、时序和优先级的直觉。