4. CarService 音频路由策略详解
音频路由是车载语音助手与 CarService 协同的核心环节。CarService 通过 CarAudioManager 和 AudioPolicy 提供了一套多层次的音频路由策略,确保不同场景下的音频流能够正确、无冲突地输出到目标设备。本章将深入解析默认路由规则、基于应用的路由以及基于上下文的动态路由机制。
4.1 默认路由规则
默认路由规则是音频路由的基础,定义了当没有特定上下文或应用约束时,音频流如何被分配到物理输出设备。CarService 在启动时根据车辆硬件配置(如扬声器、蓝牙、AUX 等)建立默认的音频设备映射表。
| 音频设备类型 | 默认路由目标 | 典型使用场景 |
|---|---|---|
| 主扬声器 (Primary Speaker) | 全车扬声器系统 | 媒体播放、系统提示音 |
| 蓝牙 (Bluetooth A2DP) | 已配对的蓝牙设备 | 电话通话、流媒体音乐 |
| AUX 输入 | 外部音源直连 | 手机有线连接播放 |
| USB 音频 | USB 音频设备 | USB 耳机、外置 DAC |
默认路由规则遵循“最近优先”原则:系统会优先将音频路由到当前处于活跃状态的、优先级最高的设备。例如,当蓝牙未连接时,媒体音频默认走主扬声器;一旦蓝牙连接,媒体音频自动切换至蓝牙设备。
audio_policy_configuration.xml 文件定义,OEM 可根据车辆硬件定制该文件,以调整默认路由行为。
4.2 基于应用的路由
基于应用的路由允许系统根据发起音频请求的应用类型(如导航、电话、媒体)来动态调整路由目标。CarService 通过 CarAudioContext 将应用音频流分类,并映射到对应的音频焦点组和设备组。
4.2.1 音频上下文与设备映射
每个应用在请求音频时,必须指定其 CarAudioContext。CarService 根据该上下文选择预定义的设备组。以下为常见的映射关系:
| CarAudioContext | 对应设备组 | 路由行为 |
|---|---|---|
| MUSIC | 主扬声器 / 蓝牙 | 默认路由至全车扬声器,蓝牙连接时切换 |
| NAVIGATION | 驾驶位扬声器 / 头枕扬声器 | 仅驾驶员区域播放,避免干扰乘客 |
| CALL | 蓝牙 / 车载麦克风+扬声器 | 优先蓝牙,无蓝牙时使用车载免提 |
| VOICE_COMMAND | 驾驶位扬声器 + 麦克风阵列 | 语音助手交互,需低延迟回采 |
| SYSTEM_SOUND | 全车扬声器 | 系统提示音、警告音 |
VOICE_COMMAND 上下文,以确保音频路由至驾驶位扬声器并启用麦克风回采,实现高效的语音交互。
4.2.2 应用路由优先级
当多个应用同时请求音频时,CarService 根据音频焦点策略决定路由优先级。高优先级应用(如电话、导航)可以抢占低优先级应用(如媒体)的音频通道。
- 电话 (CALL) — 最高优先级,可暂停所有其他音频。
- 导航 (NAVIGATION) — 高优先级,可混音或短暂打断媒体。
- 语音命令 (VOICE_COMMAND) — 高优先级,通常与导航同级。
- 系统提示 (SYSTEM_SOUND) — 中优先级,可短暂打断媒体。
- 媒体 (MUSIC) — 最低优先级,可被其他音频打断或衰减。
4.3 基于上下文的动态路由
动态路由策略根据车辆当前状态(如行驶模式、乘客位置、通话状态)实时调整音频输出路径。这是车载音频系统智能化的核心体现。
4.3.1 导航场景动态路由
导航音频需要在不干扰媒体播放的前提下,清晰传达给驾驶员。CarService 支持以下动态路由策略:
- 驾驶位独占路由: 导航提示音仅从驾驶位扬声器或头枕扬声器输出,乘客区域的媒体音频不受影响。
- 混音衰减: 导航提示期间,媒体音频自动降低音量(Ducking),导航结束后恢复。
- 蓝牙导航: 若车辆连接了蓝牙耳机,导航音频可单独路由至蓝牙设备,实现私密导航。
4.3.2 电话场景动态路由
电话通话对音频路由有严格的要求:必须保证双向音频(上行麦克风、下行扬声器)的稳定性和隐私性。
- 蓝牙优先: 当蓝牙免提设备(HFP)可用时,通话音频自动路由至蓝牙,提供更好的音质和隐私。
- 车载免提: 无蓝牙时,通话音频路由至车载麦克风和扬声器,系统自动启用回声消除(AEC)和噪声抑制(NS)。
- 隐私模式: 若车辆检测到乘客存在,通话音频可仅从驾驶位扬声器输出,避免隐私泄露。
4.3.3 媒体场景动态路由
媒体音频的路由相对灵活,但需要与其他音频源协调。
| 媒体源 | 动态路由策略 | 说明 |
|---|---|---|
| 本地媒体 | 全车扬声器 / 区域扬声器 | 可根据乘客选择播放区域(如仅后排播放) |
| 蓝牙流媒体 | 蓝牙设备 / 全车扬声器 | 蓝牙连接时优先蓝牙,断开后自动切换回扬声器 |
| USB 媒体 | USB 音频设备 / 扬声器 | USB 设备插入时自动路由,拔出后恢复默认 |
| 在线流媒体 | 全车扬声器 | 通常固定路由至主扬声器系统 |
4.4 动态路由的代码实现示例
以下示例展示了如何在 CarService 中为导航应用设置动态路由:
// 获取 CarAudioManager 实例
CarAudioManager carAudioManager = (CarAudioManager) getSystemService(Context.CAR_AUDIO_SERVICE);
// 创建音频请求,指定上下文为 NAVIGATION
CarAudioRequest request = new CarAudioRequest.Builder(context)
.setCarAudioContext(CarAudioContext.NAVIGATION)
.setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
.build();
// 注册音频焦点监听器,实现动态路由
carAudioManager.registerCarAudioFocusListener(new CarAudioFocusListener() {
@Override
public void onAudioFocusChange(int focusChange, CarAudioRequest request) {
if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
// 导航获得焦点,路由至驾驶位扬声器
carAudioManager.setPreferredDeviceForCarAudioContext(
CarAudioContext.NAVIGATION,
getDriverSeatSpeakerDevice()
);
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
// 导航失去焦点,恢复默认路由
carAudioManager.clearPreferredDeviceForCarAudioContext(
CarAudioContext.NAVIGATION
);
}
}
});
// 请求音频焦点
carAudioManager.requestAudioFocus(request, null,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
AudioRoutingPolicy 类,集中管理所有路由规则,便于调试和扩展。
4.5 路由策略对比总结
| 路由策略 | 触发条件 | 路由粒度 | 典型应用 |
|---|---|---|---|
| 默认路由 | 系统启动 / 无特定上下文 | 设备级别 | 系统提示音、未分类音频 |
| 基于应用的路由 | 应用指定 CarAudioContext | 应用级别 | 导航、电话、媒体 |
| 基于上下文的动态路由 | 车辆状态变化 / 音频焦点事件 | 场景级别 | 导航提示、电话通话、语音交互 |