车载音频复习

车载音频路由分底层硬件定义 audio_policy_configuration.xml + 车载业务路由 car_audio_configuration.xml,两者配合实现「不同音源路由到不同 address」。

一、底层硬件:audio_policy_configuration.xml

作用:定义所有总线设备地址(bus0_media_out /bus1_navigation_out 等)、硬件端口、混音路由,所有 car 配置里用到的 address 必须在这里注册。 路径:vendor/etc/audio_policy_configuration.xml

XML 复制代码
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
    <globalConfiguration speaker_drc_enabled="true"/>
    <modules>
        <!-- 车载主音频HAL模块 -->
        <module name="primary" halVersion="3.0">
            <!-- 声明所有输出总线address(对应功放独立通道) -->
            <attachedDevices>
                <item>bus0_media_out</item>    <!-- 音乐/媒体 -->
                <item>bus1_navigation_out</item><!-- 导航播报 -->
                <item>bus2_voice_cmd_out</item> <!-- 语音助手 -->
                <item>bus4_call_out</item>     <!-- 蓝牙通话 -->
                <item>bus3_ring_out</item>     <!-- 来电铃声 -->
                <item>bus5_alert_out</item>    <!-- 告警/雷达提示音 -->
                <item>primary_mic</item>       <!-- 车载麦克风输入 -->
            </attachedDevices>
            <defaultOutputDevice>bus0_media_out</defaultOutputDevice>

            <!-- 混音源端口:APP音频流输出节点 -->
            <mixPorts>
                <mixPort name="mix_media" role="source" flags="AUDIO_OUTPUT_FLAG_DEEP_BUFFER">
                    <profile format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </mixPort>
                <mixPort name="mix_nav" role="source" flags="AUDIO_OUTPUT_FLAG_FAST">
                    <profile format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </mixPort>
                <mixPort name="mix_call" role="source" flags="AUDIO_OUTPUT_FLAG_FAST">
                    <profile format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
                </mixPort>
            </mixPorts>

            <!-- 硬件输出端口:绑定上面的bus address -->
            <devicePorts>
                <devicePort tagName="bus0_media_out" role="sink" type="AUDIO_DEVICE_OUT_BUS" address="bus0_media_out">
                    <profile format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_5POINT1"/>
                </devicePort>
                <devicePort tagName="bus1_navigation_out" role="sink" type="AUDIO_DEVICE_OUT_BUS" address="bus1_navigation_out">
                    <profile format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </devicePort>
                <devicePort tagName="bus4_call_out" role="sink" type="AUDIO_DEVICE_OUT_BUS" address="bus4_call_out"/>
                <devicePort tagName="primary_mic" role="source" type="AUDIO_DEVICE_IN_BUILTIN_MIC" address="primary_mic"/>
            </devicePorts>

            <!-- 底层硬件路由:mix流 → bus硬件地址 -->
            <routes>
                <route type="mix" sink="bus0_media_out" sources="mix_media"/>
                <route type="mix" sink="bus1_navigation_out" sources="mix_nav"/>
                <route type="mix" sink="bus4_call_out" sources="mix_call"/>
            </routes>
        </module>
    </modules>
    <xi:include href="audio_policy_volumes.xml"/>
</audioPolicyConfiguration>

关键点:

address="bus0_media_out" 就是你说的路由地址,每一路音源对应独立 bus;

AUDIO_DEVICE_OUT_BUS 车载专用总线设备类型,直通功放不同 I2S/SPDIF 通道。

二、车载业务路由:car_audio_configuration.xml(核心音源分流)

作用:绑定音频上下文 context (music/navigation/call)到上面定义的 bus address,实现「音乐走 bus0、导航走 bus1、通话走 bus4」,独立音量、抢占逻辑。 路径:vendor/etc/car_audio_configuration.xml

XML 复制代码
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<audioZoneConfiguration version="3.0">
    <zones>
        <!-- 前排主音频区 isPrimary="true" -->
        <zone name="main_cabin" audioZoneId="0" isPrimary="true">
            <zoneConfigs>
                <zoneConfig name="default_config" isDefault="true">
                    <volumeGroups>
                        <!-- 1. 媒体音量组:音乐、APP多媒体 -->
                        <group>
                            <device address="bus0_media_out">
                                <context context="music"/>
                                <context context="announcement"/>
                            </device>
                        </group>
                        <!-- 2. 导航独立音量组:地图播报 -->
                        <group>
                            <device address="bus1_navigation_out">
                                <context context="navigation"/>
                            </device>
                            <device address="bus2_voice_cmd_out">
                                <context context="voice_command"/>
                            </device>
                        </group>
                        <!-- 3. 通话独立通道:蓝牙电话最高优先级 -->
                        <group>
                            <device address="bus4_call_out">
                                <context context="call"/>
                            </device>
                        </group>
                        <!-- 4. 提示音/告警:雷达、安全带、故障音 -->
                        <group>
                            <device address="bus5_alert_out">
                                <context context="system_sound"/>
                                <context context="safety"/>
                                <context context="vehicle_status"/>
                            </device>
                        </group>
                        <!-- 5. 来电铃声 -->
                        <group>
                            <device address="bus3_ring_out">
                                <context context="call_ring"/>
                            </device>
                        </group>
                    </volumeGroups>
                </zoneConfig>
            </zoneConfigs>
        </zone>

        <!-- 后座娱乐分区(多区车型可选) -->
        <zone name="rear_seat" audioZoneId="1">
            <zoneConfigs>
                <zoneConfig name="rear_default" isDefault="true">
                    <volumeGroups>
                        <group>
                            <device address="bus8_rear_media_out">
                                <context context="music"/>
                            </device>
                        </group>
                    </volumeGroups>
                </zoneConfig>
            </zoneConfigs>
        </zone>
    </zones>
</audioZoneConfiguration>

关键对应关系(回答你开头的疑问)

音源 Audio 类型 context 上下文 路由 address 地址 独立特性
蓝牙音乐 / USB/CarPlay music bus0_media_out 媒体音量,可被导航压低
地图导航播报 navigation bus1_navigation_out 导航单独音量,优先混音
蓝牙通话 / 车载电话 call bus4_call_out 最高抢占优先级,独立降噪
语音助手唤醒反馈 voice_command bus2_voice_cmd_out 语音助手专属通道
倒车雷达 / 提示音 safety bus5_alert_out 固定小音量,不可静音

三、配套开关(必须开启才能生效多地址路由)

vendor/etc/overlay/frameworks/base/core/res/res/values/bools.xml

XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 开启车载动态多总线路由,关闭则所有音源共用bus0 -->
    <bool name="audioUseDynamicRouting">true</bool>
</resources>

四、简单逻辑总结

  1. audio_policy_configuration.xml注册硬件地址 busX_out,告诉系统有多少条独立音频总线;
  2. car_audio_configuration.xml音源→地址绑定,哪种音频流走哪条总线;
  3. 不同 address 对应功放不同硬件通道,实现独立音量、混音优先级、多喇叭分区输出。

===================================================================

AAOS 里一条 busXXX_out 到底代表什么(分层讲清楚)

一、软件抽象层(XML 里看到的 bus)

bus0_media_out / bus1_nav_outAUDIO_DEVICE_OUT_BUS 类型的独立端口地址 ,属于 Android Audio HAL 的软件逻辑流通道

  1. 一条 bus = 一路独立、不与其他音源提前混音的 PCM 数据流
  2. 每个 bus 独占一条 mixPort,Android 上层不会把不同 context 的声音混在一起下发
  3. 作用:让功放 / 底层 DSP 拿到分离的媒体、导航、通话裸流,由硬件侧做闪避、分喇叭、独立音量控制

举个例子:

  • bus0:纯音乐流(48k 立体声)
  • bus1:纯导航播报流(48k 立体声)
  • bus4:纯通话语音流(16k 单声道) 三条流并行同时输出到功放,互不干扰,功放硬件再做混音、压低音乐。

二、对应硬件层(物理链路)

软件 bus 一一映射主机到功放的一条物理数字音频传输链路,常见三种硬件载体:

1. I2S/TDM(最普遍)

一条 bus = 一组完整 I2S 硬件通道(MCLK+BCLK+WS+SD)

  • bus0 → I2S0 硬件口(全车音乐)
  • bus1 → I2S1 硬件口(导航只走前门喇叭) 主机每多一条 bus,就要多一组 I2S 引脚输出 PCM 流给功放 DSP。

2. A²B 汽车音频总线(高端分布式功放)

A²B 是双绞线菊花链,一条物理 A²B 线缆里可以承载多路 TDM 时隙

  • 软件 bus0 = A²B TDM slot0~1(音乐)
  • 软件 bus1 = A²B TDM slot2~3(导航) 此时多条逻辑 bus 复用一条 A²B 物理线,靠时隙区分。

3. SPDIF / 光纤同轴

一条 bus = 一路独立光纤 / 同轴数字输出。

三、业务层面:一条 bus = 一组独立音量组(CarAudio 核心)

car_audio_configuration.xml 里,一个 volumeGroup 绑定一个 bus

  • 一个 bus 对应一套独立音量记忆、独立焦点、独立闪避策略
  • 音乐调音量只改 bus0;导航调音量只改 bus1;通话优先级最高直接抢占 bus4

四、极简总结(一句话)

AAOS XML 里的一条 bus = 一条独立未混音的数字音频流通道,上层软件用来隔离不同音源(music/nav/call),底层对应主机到功放的一组 I2S/TDM 时隙 / A²B 时隙物理链路,实现分音源独立音量、硬件闪避、分区喇叭输出。

=========================================================

每个独立 bus address,运行时会对应一条独立 PlaybackThread(MixerThread)

1. 核心对应关系

AudioFlinger 规则: 一个 HAL output(一条硬件输出流) ↔ 一个 PlaybackThread 而 AAOS 里每一条 busXXX_out 是独立 AUDIO_DEVICE_OUT_BUS 设备,AudioPolicy 会为每个 bus 打开独立 OutputDescriptor,最终在 AudioFlinger 生成独立 MixerThread。

举你车载多 bus 场景:

  • bus0_media_out → Output0 → MixerThread0(音乐混音线程)
  • bus1_navigation_out → Output1 → MixerThread1(导航线程)
  • bus4_call_out → Output2 → MixerThread2(通话线程) 三条线程并行跑、各自独立调度、独立缓冲、独立输出到 HAL

2. 为什么必须分开线程?

  1. 采样率 / 位深 / 声道参数完全独立
    • bus0 音乐:48k stereo
    • bus4 通话:16k mono 同一个 PlaybackThread 只能一套硬件参数,不同规格流不能共用线程。
  2. 独立硬件时钟同步 每条 bus 对应独立 I2S/TDM 时隙,硬件中断周期不同,必须单独线程驱动 HAL 写 PCM。
  3. 互不干扰的混音、闪避、音量控制 音乐线程只管 mix 所有 music 类 Track;导航线程只 mix 导航播报;通话线程独占、高优先级,各自内部独立音量衰减,不用跨线程同步混音逻辑。
  4. 线程优先级隔离 通话 / 导航线程可配置更高调度优先级,避免被音乐大混音线程抢占 CPU。

3. 容易混淆的两个概念(别搞混)

① PlaybackThread(线程)

一条 bus 对应一个线程,负责:

  • 收集本 bus 下所有 AudioTrack(应用声音)
  • 软件混音
  • 周期往 HAL bus 流写 PCM 数据

② Track(应用流)

同一个 bus / 同一个线程里,可以存在N 个 Track(多路声音叠加) 例:bus0 音乐线程内同时存在:蓝牙音乐 + CarPlay 音频 + 本地 U 盘歌,三个 Track 在同一个 MixerThread 内混音后输出 bus0。

4. 两种车载架构对比验证

低配单 bus 方案(仅 bus0)

只有 1 个 Output → 只有 1 条 MixerThread;所有音源上层先混在一起再下发功放。

主流多 bus 车载方案(music/nav/call 分开 bus)

每个 bus 独立 Output → 每个 bus 一条独立 PlaybackThread,上层不混音,裸流分别下发功放 DSP 做硬件闪避、分喇叭输出。

5. 补充边界特例

  1. 同一条 bus 下多个 context:共用同一个线程,内部软件混音;
  2. 同一物理 A²B 线缆多路 TDM bus:逻辑上多条 bus,依然多条独立线程,只是底层复用双绞线;
  3. Tone / 提示音:短音会临时复用对应 bus 的现有线程,不会单独新建线程。

一句话总结

XML 里每一个唯一 busXXX_out 硬件地址,运行时都会创建一条专属 MixerThread(PlaybackThread);同一 bus 内多个音源是在线程内部混音,不同 bus 之间是完全隔离的独立播放线程。

============================================

PlaybackThread 完整分类(基类 + 4 种派生播放线程,车载场景全覆盖)

类继承关系

XML 复制代码
ThreadBase
├─ RecordThread(录制,非播放)
└─ PlaybackThread(播放基类,所有输出线程父类)
   ├─ MixerThread      标准混音线程(车载bus默认用这个)
   ├─ DirectOutputThread 直通线程
   │  └─ OffloadThread 硬解直通线程
   └─ DuplicatingThread 复制分流线程

1. MixerThread(你前面关心的 bus 全部是它)

触发 flag

AUDIO_OUTPUT_FLAG_PRIMARY / DEEP_BUFFER / FAST

核心特点

  1. 内置 AudioMixer,支持多路 Track 软件混音、重采样、独立音量、音效处理
  2. 一条独立 busXXX_out = 一个 Output = 一条独立 MixerThread;
  3. 同一条 bus 内可以叠加无数 Track(蓝牙音乐 + CarPlay + 本地媒体一起混);
  4. AAOS 多 bus 架构(music/nav/call 分总线)全部使用该线程。

车载场景

bus0_media、bus1_nav、bus4_call、bus5_alert 每条 bus 各自一条 MixerThread。

2. DirectOutputThread 直通线程

触发 flag

AUDIO_OUTPUT_FLAG_DIRECT

核心特点

  1. 无软件混音器 ,一个 Output 同一时间只能存在一条 Track
  2. 音频格式、采样率、声道必须和 HAL 硬件端口完全匹配,不做 SRC 重采样;
  3. 省去混音开销,延迟极低;
  4. 不能叠加多路声音,新 Track 会抢占、挤掉旧 Track。

车载使用场景

  • 蓝牙 SCO 通话直通(部分厂商 HAL);
  • 专业低延迟语音助手拾音反馈;
  • 无损 HiFi 比特完美直通(bit-perfect)。

3. OffloadThread 硬件硬解线程(继承自 DirectOutputThread)

触发 flag

AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD

核心特点

  1. 下发压缩码流(AAC/MP3/FLAC),不解 PCM,直接丢给 DSP / 功放硬解;
  2. CPU 占用极低,适合长时间后台音乐;
  3. 同样不支持多路混音,独占输出端口;
  4. 暂停 / 切歌控制交给硬件 DSP,AudioFlinger 只做调度。

车载场景

高配车机本地无损、USB 音乐 offload 模式。

4. DuplicatingThread 复制分流线程(继承自 MixerThread)

触发场景

需要一轨音源同时输出到多个设备(复制流)

核心特点

  1. 输入一路混音流,内部复制多份分别下发多个 Output 设备;
  2. 底层依然依赖 Mixer 做混音,只是多输出分支;
  3. 共享同一条线程,不会新建多条 MixerThread。

车载场景

  • 全车音乐同时输出前门 + 后座娱乐;
  • 蓝牙音乐同时车内喇叭 + 蓝牙耳机双出。

补充:容易混淆的其他音频线程(不属于 PlaybackThread)

  1. RecordThread 录音专用,麦克风输入、通话上行拾音、语音助手收音,和播放线程完全隔离。
  2. AudioTrackThread(APP 进程内) 应用侧客户端线程,负责往共享内存写数据;不在 AudioFlinger 服务端,和上面四类 PlaybackThread 不是一层东西。
  3. FastMixer 子路径 不是独立线程类型,是 MixerThread 内部的低延迟调度分支,优先级更高,用于按键音、导航播报。

车载多 bus 架构线程对应总结

  1. 每一个 busXXX_out → 独立 Output → 独立 MixerThread
  2. 如果某条 bus 配置 DIRECT 直通,则该 bus 创建 DirectOutputThread;
  3. 开启 offload 硬解时,对应 Output 替换为 OffloadThread;
  4. 多区同步输出(主驾 + 后座)会生成 DuplicatingThread 复制流;
  5. 所有播放线程互相独立调度、独立缓冲区、独立 HAL 写入,互不阻塞。

一句话区分

  • MixerThread:多路混音,车载 bus 标准;
  • Direct:单路独占、低延迟、无混音;
  • Offload:压缩码流硬件解码,省电;
  • Duplicating:一份声音复制多设备输出。

==========================================================

三层分工:CarAudioService / 音频焦点 / 功放 DSP,各自核心职责 + DSP 策略来源完整梳理

一、三层核心定位与各自重点(从上到下)

1. 音频焦点(AudioFocus,业务仲裁规则层)

本质:一套「并发交互矩阵」,定义谁能播、谁该停、谁可以共存压低

  • 数据来源:car_audio_configuration.xml 内置上下文优先级矩阵(safety > call > nav > music)
  • 核心重点:
    1. 处理 App 焦点请求栈,判断独占 / 并发 / 拒绝 三种交互模式
      • 来电 call:独占,音乐直接丢 loss,建议暂停;
      • 导航 nav:并发 may_duck,允许一起出声;
      • 倒车告警 safety:最高优先级,压制所有其他音源。
    2. 下发事件通知:给音乐 App 回调「你要被压低 / 暂停」;同步通知 CarAudioService 触发闪避指令。
    3. 业务逻辑、无 PCM 数据操作,只做 "权限分配",不碰音量增益、不混音。
  • 局限:只是上层君子协议,App 可无视焦点回调继续播放;必须靠下层硬件兜底。

2. CarAudioService(车载音频总调度枢纽,框架控制层)

本质:连接焦点、路由、音量、HAL、DSP 指令的中间大脑

  • 核心重点 5 件事:
    1. 路由分配:解析 xml,把 music/nav/call 绑定到独立 bus 地址,决定每条流走哪一路 I2S/TDM;
    2. 音量分组管理:每个 bus 对应独立 volumeGroup,调节媒体 / 导航 / 通话独立音量;
    3. 焦点事件转发 :焦点状态变化后,组装Ducking / 静音控制指令下发 AudioControl HAL;
    4. 车辆信号联动:车速、倒车、车门、档位等 VHAL 信号联动静音 / 衰减;
    5. OEM 扩展钩子(Android14+):厂商自定义焦点、闪避、音量规则插件。
  • 输出产物:标准化控制指令(哪条 bus 要衰减多少 dB、是否静音、持续多久),下发给 HAL 再透传给功放 DSP。

3. 功放 DSP(硬件执行层,最终声音渲染)

本质:多路 PCM 并行接收、实时硬件运算、最终输出喇叭

  • 核心重点:
    1. 接收多条独立 bus 的裸 PCM 流(bus0 音乐、bus1 导航、bus4 通话互不干扰);
    2. 多路硬件混音、动态增益闪避 ducking、分喇叭路由(导航只前门、通话头枕);
    3. EQ、响度补偿、降噪、回声消除、限幅等音效处理;
    4. 根据上层下发的指令动态修改各路通道增益,播报结束自动恢复音量。
  • 关键:真正听到 "音乐变小、导航清晰" 的动作全部在这里硬件完成

二、DSP 执行的策略从哪里来?分 2 套策略(静态基准 + 动态实时指令)

1. 静态基准策略(DSP 固件固化,底层永久生效)

由功放 / DSP 厂商预设,不随场景实时变化:

  1. 各路音源基础增益配比:导航默认比音乐高 6dB、告警音固定增益;
  2. 喇叭分配规则:call 走头枕、nav 前排、music 全车;
  3. 硬件保护逻辑:削波限幅、高低通分频;
  4. 基础闪避曲线:衰减斜率、恢复时长(播报结束平滑回升)。 来源:功放 DSP 固件、调音工程文件(.tap/.bin 调音参数),出厂烧录,AP 无法修改底层曲线。

2. 动态实时控制指令(上层 AAOS 下发,场景临时覆盖静态策略)

完整传递链路:App 请求焦点 → 焦点引擎判定交互类型 → CarAudioService 组装 Ducking 指令 → AudioControl HAL → 功放 DSP 控制通道增益

  1. 源头 1:car_audio_configuration.xml 交互矩阵(定义什么场景该闪避 / 静音) 例:nav gain -12dB、call gain -20dB、safety gain -30dB;
  2. 源头 2:CarAudioService OEM 插件(Android14+,厂商可自定义差异化策略) 比如高速导航只衰减 6dB,城市道路衰减 12dB;倒车时媒体直接静音;
  3. 源头 3:用户手动音量调节(CarAudioService 同步下发对应 bus 基准增益给 DSP);
  4. 源头 4:车辆 VHAL 信号(倒车、开门、车速联动衰减指令)。
一句话链路总结 DSP 动态指令来源

xml交互矩阵规则 + OEM自定义业务逻辑 → CarAudioService 生成增益 / 静音指令 → HAL 透传 → DSP 实时修改各路通道音量。

三、完整场景串联(导航播报压低音乐,看懂三层配合)

  1. 导航 App 请求焦点 AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
  2. 音频焦点引擎 查询交互矩阵:nav 与 music 是并发 duck 关系,授予焦点,通知音乐 App 短暂压低;
  3. CarAudioService 收到焦点变更,读取 xml 配置:music 通道衰减 12dB,组装 Ducking 控制消息下发 AudioControl HAL;
  4. HAL 把指令转发给外置功放 DSP;
  5. DSP 同时接收 bus0 (音乐)、bus1 (导航) 两路独立 PCM:
    • 临时降低 bus0 音乐通道增益 - 12dB;
    • bus1 导航正常音量输出;
    • 两路硬件混音后推喇叭;
  6. 导航播报结束,App 释放焦点;焦点栈恢复,CarAudioService 下发恢复增益指令,DSP 把音乐音量拉回原值。

四、关键区分:三层权责边界(避免混淆)

  1. 音频焦点:只定规则、发通知,不控制硬件音量
  2. CarAudioService:规则翻译官,把焦点业务规则翻译成 DSP 能识别的硬件控制指令,管理路由与音量分组;
  3. DSP:纯粹执行者,自有固定硬件混音 / 闪避曲线,只响应上层下发的实时增益指令,底层声学逻辑由功放固件决定。

五、补充两种降级方案对比,凸显多 bus+DSP 架构优势

  1. 低配单 bus 车机: 所有音源在 AudioFlinger 软件混音,闪避只能靠 CarAudioService 提前软件衰减音乐,无 DSP 多路独立通道,顿挫、恢复生硬;
  2. 高端多 bus 架构(你 XML 的方案): AP 只下发指令,多路裸流直送 DSP,硬件平滑闪避、分喇叭、独立音量,体验最优,也是 AAOS 官方推荐架构。

===============================================================

一、音频焦点相关配置在哪定义,为何 car_audio_configuration.xml 看不到

1. 核心配置文件分工(Android Automotive AAOS)

(1)car_audio_configuration.xml 职责

只定义音频总线 (Audio Bus)、音量组 (Volume Group)、设备映射、流类型分配不存储音频焦点抢占 / 流转规则、优先级矩阵,所以你在这个 xml 里搜不到焦点逻辑。 字段仅包含:

  • audioBus:bus 编号、设备、支持的 usage(音频用途 music/call/nav 等)
  • volumeGroup:绑定多个 bus,统一音量控制
  • audioDevice:硬件输出设备映射

(2)音频焦点 + 优先级矩阵的 3 个定义位置

源码路径:packages/services/Car/car-lib/src/android/car/audio/CarAudioContext.java 内置固定优先级数组,是系统底层静态优先级,无 xml 配置,写死在 Java 代码中。

② 音频焦点抢占 / 打断规则(主流配置文件)

audio_policy_configuration.xml(系统 audio policy 核心)

  • 定义 audio_usage、stream、焦点请求模式(临时抢占 / 混合 / 独占)
  • 配置不同 usage 之间的 duck(音量压低)、pause(暂停)行为
  • 区分跨 bus / 同 bus 焦点处理逻辑
③ 车载专属焦点策略扩展(AAOS)

car_audio_policy_configuration.xml(车载专用音频策略) 补充车载场景规则:

  • 安全提示 (safety) 高优先级强制打断所有音频
  • 通话 (call) 打断导航 / 音乐,导航仅压低音乐不暂停通话
  • 同 bus / 跨 bus 焦点流转逻辑开关

2. 为什么 car_audio_configuration.xml 看不到焦点定义

该文件是车载音频硬件 & 音量分组配置 ,只管硬件通路、音量分组; 音频焦点、打断、优先级属于音频策略 (Audio Policy) 范畴,由 audio_policy 系列 xml + CarAudio 服务硬编码共同管控,两者职责完全隔离。

二、音频焦点是否在不同 bus 之间流转?

结论:会跨 Bus 流转,焦点是全局系统级资源,不受 Bus 隔离

  1. 焦点归属维度:Usage(音频用途),不是 Bus 焦点请求时 APP 传递AudioAttributes.USAGE_MEDIA/USAGE_NAVIGATION/USAGE_VOICE_COMMUNICATION,系统只识别 Usage,不绑定 Bus。
  2. 跨 Bus 流转场景举例
    • Bus0:多媒体音乐(music)正在持有焦点
    • Bus1:蓝牙电话(call)发起焦点请求 系统读取内置优先级 call > music,直接剥夺 Bus0 音乐焦点,将全局焦点切换给 Bus1 通话,完成跨 Bus 流转。
  3. Bus 仅作用:硬件输出通路隔离 同一 Usage 可以绑定多个 Bus;不同 Bus 可以承载同 / 不同 Usage,但焦点是全局唯一,高优先级 Usage 无论在哪条 Bus,都能抢占低优先级 Bus 上的音频焦点。

三、同一 bus 内不同 APP 是否共用同一个音频焦点?

分两种场景,核心看 Usage,不是 Bus

场景 1:多个 APP 同 Usage(例:Bus0 里网易云 + QQ 音乐,都是 USAGE_MEDIA)

共用同一类焦点槽位,互斥

  1. A 音乐持有焦点播放;B 音乐请求焦点时,系统判定为同 Usage,直接夺走焦点,A 被暂停;
  2. 同 Bus 同 UsageAPP 无法同时持有焦点,同一时刻只有一个能播放。

独立焦点,有优先级区分

  1. 音乐持有基础焦点;导航高优先级请求临时焦点,触发 duck(音乐压低),不会完全夺走音乐焦点;
  2. 两个 APP 各自持有对应 Usage 的焦点,同 Bus 共存,由优先级矩阵控制混音行为。

总结

同 Bus 内:同 Usage 共享一个焦点,互斥;不同 Usage 独立焦点,按优先级混音 / 打断。Bus 不隔离焦点,Usage 才是焦点区分核心。

四、同一个音量组 (volumeGroup) 音量是否同步变化?

结论:是,音量组是批量音量控制单元,组内所有 Bus 音量同步联动

整体逻辑串联总结

==============================================================

  1. 配置逻辑(car_audio_configuration.xml 内 volumeGroup 标签)

    XML 复制代码
    <volumeGroup name="media_group">
        <audioBus busNumber="0"/>
        <audioBus busNumber="3"/>
    </volumeGroup>

    Bus0、Bus3 归属同一个 media_group 音量组。 2. 行为表现

  2. 调节多媒体音量条,组内所有绑定 Bus 的输出音量同步增减;

  3. 底层 CarAudioService 统一给组内所有 audioBus 下发相同音量缩放系数;

  4. 边界区分

  5. 不同 volumeGroup 完全独立音量(通话组、多媒体组、安全提示组互不干扰);

  6. 优先级矩阵 (safety>call>nav>music):Java 硬编码,不在 car_audio_configuration.xml;

  7. car_audio_configuration.xml:仅 Bus、音量组、硬件映射;焦点策略在 audio_policy_configuration/car_audio_policy_configuration.xml;

  8. 音频焦点全局流转,可跨 Bus 抢占,优先级由 Usage 决定,Bus 只是硬件通路;

  9. 同 Bus 同 APP Usage 互斥共用焦点,不同 Usage 独立焦点;

  10. volumeGroup 内所有 Bus 基础音量同步调节,组间音量隔离。

    • 音量组只控制硬件输出音量,不影响音频焦点、混音逻辑;焦点打断 duck 压低是软件动态衰减,不会修改音量组基础音量值。

一、系统到底是不是只有一个全局音频焦点?

1. 原生 Android 手机(标准 AudioFocus):同一时刻只有 1 个主焦点持有者

底层规则: 系统维护单一全局焦点锁 ,任意时刻只会有一个 App 拿到AUDIOFOCUS_GAIN(长期主焦点)。 分三种请求类型,对应三种失去焦点回调:

AUDIOFOCUS_GAIN(音乐长期播放) 别人抢长期焦点 → 你收到 AUDIOFOCUS_LOSS,必须暂停 / 停止,完全丢失焦点; AUDIOFOCUS_GAIN_TRANSIENT(临时独占,来电、语音输入) 你收到 AUDIOFOCUS_LOSS_TRANSIENT,建议暂停,临时丢失;播报结束焦点归还; AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK(导航播报、提示音) 你收到 AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK你没有丢失焦点,只是需要压低音量继续播放

关键澄清:"音乐持有基础焦点,导航拿临时 duck 焦点" 是什么意思?

2. AAOS 车载系统(CarAudioService 扩展):支持多 Usage 并行持有有效焦点

手机框架是单焦点互斥;车载做了优先级矩阵增强,允许高优先级 Usage 共存、同时持有有效焦点

二、Duck 闪避:软件层面音量调节,和用户手动调音量组完全隔离

1. 两种音量增益完全分开,互不覆盖

① 用户手动调节音量组(volumeGroup)------ 硬件基础增益

② Duck 闪避衰减 ------ 软件混音临时增益(系统强制 / APP 配合)

两条实现路径:

2. 核心区分:Duck 是临时动态衰减,不改动音量组基准

举例子:

三、同 Bus、跨 Bus 焦点流转补充纠正

四、一句话总结关键点

  1. 音乐依旧是全局唯一主焦点持有者,没有被剥夺焦点;
  2. 导航只是临时叠加一层临时请求标记,系统通知音乐做衰减混音;
  3. 导航播报结束释放临时请求后,音乐直接恢复正常音量,不需要重新申请焦点。 不是系统存在两个独立焦点,而是同一主焦点下允许临时混音闪避
  4. 通话 USAGE_VOICE_COMMUNICATION(最高优先级)长期持有焦点;
  5. 同时导航 USAGE_ASSISTANCE_NAVIGATION 可叠加临时 duck 焦点;
  6. 媒体音乐 USAGE_MEDIA 被 duck 压低,但仍保留自身焦点状态; 底层逻辑: 车载不再是单纯 "一把锁",而是按AudioAttributes.usage做分层优先级调度,不同 Usage 可以同时处于 "持有焦点" 状态,仅做音量衰减区分,这也是车载能同时通话 + 导航 + 背景音乐的根本原因。
  7. 配置:car_audio_configuration.xml volumeGroup
  8. 作用:保存基础音量档位(比如媒体音量 30%),持久化存储;
  9. 实现(AAOS 默认config_useFixedVolume=true):下发到 HAL 硬件功放,硬件整体放大 / 缩小信号;
  10. 特点:duck 不会修改这个基础值,播报结束音量自动回到原档位。
  11. APP 主动兼容(原生标准逻辑) 收到AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK回调,App 内部播放器把音量乘 0.3~0.5 做衰减,属于应用层软件调节;
  12. AAOS 系统强制 Ducking(Android14+ OemCarDuckingService) CarAudioService 检测焦点变化,直接给 AudioFlinger/HAL 下发临时衰减增益,不依赖 APP 配合,底层混音器软件压低对应流,即便 APP 不处理回调也会变小声。
  13. 媒体音量组手动调到 50%(硬件基础增益固定);
  14. 导航播报触发 duck,软件叠加 - 12dB 衰减,音乐实际输出等效 20% 音量;
  15. 导航播报完成,临时软件衰减撤销,立刻回到硬件 50% 基准音量;
  16. 中途手动调媒体音量条,只会修改硬件基础增益,不影响 duck 逻辑。
  17. Bus 只是硬件输出通路,焦点调度完全不看 Bus,只看 Usage 优先级
  18. 同 Bus 多 APP:
    • 同 Usage(多个音乐):互斥,后申请的会夺走主焦点,前者收到 LOSS 完全暂停;
    • 不同 Usage(音乐 + 导航):车载支持共存,音乐 duck,各自保留焦点状态;
  19. 跨 Bus 场景(Bus0 音乐 / Bus1 蓝牙通话): Call 优先级高于 Media,通话直接抢占全局高优先级焦点,音乐被 duck 或暂停,焦点可以跨 Bus 切换。
  20. 原生 Android:全局只有 1 个长期主焦点,duck 只是临时混音标记,音乐没丢焦点;
  21. AAOS 车载增强:按 Usage 分层优先级,允许多类音频同时持有有效焦点并行播放;
  22. Duck 是软件临时衰减增益,和 volumeGroup 硬件基础音量两套独立控制,互不修改;
  23. 音量组仅控制硬件基准音量,duck 播报结束自动恢复原音量档位。
相关推荐
RTC实战笔记1 天前
Android 实时音视频接入教程:媒体补充增强信息(SEI)
音视频·媒体·rtc
潜创微科技2 天前
HDMI1.3 无线传输芯片方案 空旷 150 米量产级音视频方案
音视频
VidDown2 天前
VidDown 工具站:免费、本地优先的开发者工具箱
javascript·编辑器·音视频·视频编解码·视频
换个昵称都难2 天前
音频格式之WAV
音视频
AI创界者2 天前
PilotTTS 一键整合包(Win/Mac):8G 显存畅跑,实测解锁情绪与副语言的精准控制
人工智能·macos·aigc·音视频
u152109648492 天前
S.S.Audio PRO A2音频隔离器
嵌入式硬件·音视频·实时音视频·视频编解码·视频
VidDown2 天前
显卡处理视频技术详解:从硬解码到 NVENC,GPU 如何让视频处理起飞?
javascript·编辑器·音视频·视频编解码·视频
EasyDSS2 天前
全能音视频平台/私有化音视频系统EasyDSS!直播/点播/会议/集群对讲一站式落地
音视频
3DVisionary2 天前
告别数据中断:XTDIC-VG视频引伸计在金属疲劳测试中3个真实案例
人工智能·音视频·应用案例·xtdic-vg·视频引伸计·疲劳测试·实战复盘