多区音频路由

汽车音频服务使用 Core Audio 动态音频政策来为车载使用场景提供协助。

  • 为每位乘客单独播放音频(称为多区音频),其中每个音频区允许并发播放声音。

  • 动态音频区配置。

  • 乘客主区音频投放。

  • 乘客的音频镜。

在每个用例中,车载音频服务都使用动态音频政策自动将音频路由到指定的输出设备。

多区音频

借助多区音频,多个用户可以同时与 AAOS 互动。一组输出设备与一个音频区相关联,每个音频区都保持音频焦点和音量级别。乘客可以聆听自己的音频,同时驾驶员收听主音频区(通常是主车厢)中的另一个音源。

多区音频架构

汽车音频服务架构

图 1. 汽车音频服务架构。

汽车音频区是音频输出、音频焦点和其他音频设置的抽象化,所有这些设置都可以单独管理。为便于路由,每个音频区均定义为一组音频输出总线设备,按照音频政策配置进行排列。每种音频区定义的设备各不相同。在图 1 中,总线设备 1 到 5 属于音频区 0,总线设备 6 到 8 属于音频区 1,总线设备 9 到 11 属于音频区 2。

车载音频配置

通常,输出设备会分配到一个音频区。每个音频区都在 car_audio_configuration.xml 中定义。以下代码段显示了图 1 的汽车音频配置:

<carAudioConfiguration version="3">
    <zones>
        <zone name="Zone0" audioZneId="0" occupantZoneId="0">
            <zoneConfigs>
                <zoneConfig name="config0" isDefault="true">
                   <volumeGoups>
                        <group>
                            <device address="bus_1">
                                <context context="music"/>
                            </device>
                        </group>
                        <group>
                            <device address="bus_2">
                                <context context="navigation"/>
                            </device>
                        </group>
                        ...
                    </volumeGroups>
                </zoneConfig>
            </zoneConfigs>
        </zone>
        <zone name="Zone1" audioZoneId="1" occupantZoneId="1">
            <zoneConfigs>
                <zoneConfig name="config0" isDefault="true">
                    <volumeGroups>
                        <group>
                            <device address="bus_6">
                                <context context="music"/>
                            </device>
                        </group>
                        <group>
                            <device address="bus_7">
                                <context context="navigation"/>
                           </device>
                       </group>
                       ...
                    </volumeGroups>
                </zoneConfig>
            </zoneConfigs>
        </zone>
        ...
    ...
   </zones>
</carAudioConfiguration>

occupantZoneId 是由 CarOccupantZoneManager 管理的汽车服务定义。它在汽车中用于定义汽车用户到特定座位位置的映射。CarOccupantZoneService 还定义了用户登录显示屏后从乘员区到显示屏、其他外围设备和用户之间的映射。音频区具备以下内容:

  • 音频区 ID 和乘员区 ID。

    • 将音频区映射到乘员区(座位、显示屏和其他外围设备)
    • 在登录时确定为音频区分配哪个用户 ID
  • 音频配置列表。每项音频配置都有一组音量组。每个音量组都有一组音频总线设备。

    • 当音量发生变化时,组中的所有音频设备均以相同的方式进行控制。

    • 每个音频设备都分配有一个音频属性列表。此信息用于构建分配有不同音频属性的音频政策混音。

此配置允许将不同的音频属性使用情况路由到每个音频区中的不同输出设备。不同的声音可以同时播放,具体取决于用例。例如,您可以选择将主驾驶舱(主区)配置为在所有扬声器上播放媒体声音,但仅在离驾驶员最近的扬声器上播放导航声音。通过并发播放声音,主驾驶舱在系统向驾驶员播放导航声音时继续聆听媒体。

多区音频乘客登录工作流程

下面的序列图显示了乘客登录其相应屏幕时启用音频路由的流程:

图片

图 2.

在这个序列中,用户登录信息通过乘员区服务传播到汽车音频服务。

  1. 汽车音频服务(针对特定音频区)使用 AudioPolicy#removeUserIdDeviceAffinity API 取消用户设备关联性。此 API 接受用户 ID。在此示例中为上一个音频区的用户。

  2. AudioPolicy#setUserIdDeviceAffinity API 将新用户分配到某个音频区,该音频区会接受用户 ID 以及特定音频区配置的所有设备。

动态音频区配置

Android 14 中引入了动态音频区配置,以允许 OEM 为乘客配置不同的设备组。该用例允许后座的乘客在后座头枕扬声器和后座耳机外围设备之间切换。

在这种情况下,需要进行两种配置。后座头枕和耳机外围设备各一个。特定用户的音频一次只能路由到一个配置。

动态音频区配置工作流程

图 3. 动态音频区配置工作流程。

图 3 展示了动态音频区配置工作流程的架构。音频区 1 包含两种配置(Config 0Config 1),它们分别与输出设备扬声器和头枕相关联。

登录后,系统会自动为用户分配默认配置。 当用户选择更改配置时(通常通过系统界面),汽车音频服务会在两种配置之间切换。这样,输出设备就会在 Z1 扬声器和 Z1 头枕之间切换。

以下代码段展示了此动态音频区配置的设置。

<carAudioConfiguration version="3">
    <zones>
        <zone name="Zone1" audioZoneId="1" occupantZoneId="1">
            <zoneConfigs>
                <zoneConfig name="Zone 1 Config 0" isDefault="true">
                    <volumeGroups>
                        <group>
                            <device address="bus_100">
                                <context context="music"/>
                                    ***
                            </device>
                        </group>
                    </volumeGroups>
                </zoneConfig>
                <zoneConfig name="Zone 1 Config 1">
                    <volumeGroups>
                        <group>
                            <device address="bus_101">
                                <context context="music"/>
                                    ***
                            </device>
                        </group>
                    </volumeGroups>
                </zoneConfig>
            </zoneConfigs>
        </zone>
    </zones>

为方便管理音频配置,汽车音频管理器会公开用于管理配置的 API:

  • 可用于音频区的查询配置。
  • 查询当前为音频区设置的配置。
  • 切换到其他配置。

系统界面应用或服务可以使用这些 API 管理音频区的配置,如图 4 所示。Query API 向乘客公开这两者。用户可以通过点按所需配置的命令选择其他配置。

动态音频区配置工作流程

图 4. 动态音频区配置工作流程。

主区乘客音频投放

主区乘客音频投放是 Android 14 中引入的一项功能,可让乘客将其媒体音频投放到主区。这样,乘客的媒体音频便可投放到主驾驶舱,同时驾驶员仍保持完全控制。

下图显示了主区乘客媒体音频投放的简化版架构。

动态音频区配置工作流程

图 5. 动态音频区配置工作流程。

此图显示驾驶员的媒体输出设备与乘客共用,这种情况仅在乘客投放到主区模式时才会发生。动态音频政策还可用于管理驾驶员的音频路由,但不会对驾驶员的设备关联性应用任何更改。对于乘客,输出设备列表按如下方式更改:

  • 从设备列表中移除了乘客的媒体输出设备
  • 向设备列表中添加了驾驶员媒体输出设备
  • 乘客音频区的其余输出设备保留在设备列表中

这个新的设备列表由 AudioPolicy#setUserIdDeviceAffinity API 分配给乘客。传递给该 API 的参数是设备列表和乘客用户 ID。当音频系统的音频政策服务查询要为与乘客关联的媒体轨道选择哪个音频混音时,系统会选择与主区相关联的媒体混音。

主区音频投放的一项关键要求是主区的媒体输出设备与其他音频属性使用情况隔离开来。否则,在构建混音期间,系统会向混音中添加其他音频属性。音频系统在选择混音时,连接到混音的所有声音都会在主驾驶舱中选择播放。

乘客区音频镜像

音频镜像功能使乘客能够共享音频。镜像功能会复制每个音频区中的音频数据,以便所有乘客都能聆听相同的音频。在这种情况下,音频焦点会与音频镜像涉及的乘客共享。

音频镜像路由

至少需要两名乘客才能启用音频镜像。因此,仅包含两个乘客音频区的音频配置需要一台镜像输出设备。根据上述定义,可以启动两个并发镜像会话。

下图显示了两名乘客之间的多区音频镜像的简化示意图。两名乘客的音频都被路由到音频镜像设备 bus_1000。音频 HAL 将信号复制到源区。

动态音频区配置工作流程

图 6. 动态音频区配置工作流程。

只有当乘客处于镜像模式时,系统才会启用此路由。否则,系统会将音频区的相应设备分配给乘客。首次为乘客启用镜像时,AudioPolicy#setUserIdDeviceAffinity API 会修改路由:

  • 从设备列表中移除了乘客的媒体输出设备。
  • 已将镜像输出设备添加到设备列表。
  • 乘客音频区的其余输出设备保留在设备列表中。

对于设备列表,使用更新后的设备列表和乘客的用户 ID 调用 API。下面是音频镜像工作流程的序列图。

音频镜像工作流程

图 7. 音频镜像工作流程。

在图 7 中,用于管理音频镜像的车载音频管理器 API 是从媒体系统服务调用的。具体而言,即用于为用户 1 和用户 2 启用音频镜像的 API CarAudioManager#enableMirrorForAudioZones

汽车音频服务按上述方法为用户乘客配置音频路由。汽车音频服务还会向音频 HAL 发送信号,以配置音频并将其从镜像设备复制到相应的音频区。

在上图中,汽车音频服务会发送 mirroring_src=bus_1000;mirroring_dest=bus_10,bus_20

其中

bus_1000 是来源总线,bus_10bus_20 是目标总线。

序列图中未显示通过 AudioManager#setParameters API 发送的信号,该信号通过音频服务到达 HAL。

停用音频镜像后,系统会发送以下信号:mirroring_src=bus_1000;mirroring=off。未启用音频镜像时,HAL 可以使用此信号停用音频复制操作。为了定义音频镜像设备,汽车音频配置文件包含一个名为 mirroringDevices 的部分,如以下代码段所示。

在此代码段中,定义了两个镜像设备(bus_1000bus_2000),以便四名乘客可以使用音频镜像。

<carAudioConfiguration version="3">
   <mirroringDevices>
       <mirroringDevice address="bus_1000"/>
       <mirroringDevice address="bus_2000"/>
   </mirroringDevices>
  <zones>
    ....
  </zones>
</carAudioConfiguration>