车载音频配置

在 Android 10 中,car_audio_configuration.xml 取代了 car_volumes_groups.xmlIAudioControl.getBusForContext。音频政策文件通常包含在 vendor 分区中,表示主板的音频硬件配置。car_audio_configuration.xml 中引用的所有设备都必须在 audio_policy_configuration.xml 中进行定义。

下方图 1 展示了车载音频服务架构的简要概览,其中车载音频服务会读取车载音频配置文件来为设备设置音频。

车载音频架构概览

图 1. 车载音频架构概览。

将车载音频配置文件放在设备的 vendor\etc\system\etc\ 中,车载音频服务会首先在 vendor\etc\ 中搜索该文件。车载音频服务会读取 car_audio_configuration.xml 来确定音频配置。

车载音频区:

  • 每个音频区均包含唯一的音频区 ID。
  • 每个音频区都可以映射到乘员区。
  • 每个音频区中的音频操作彼此独立:

    • 音频焦点
    • 音频路由
    • 音频闪避
  • 车载音量组:

    • 包含音量组的所有音频设备都通过相同的增益变化统一控制。组内所有设备的音频增益配置应相同。

    • 音频上下文与音频设备的映射。使用此功能可构建音频混音,将音频用法映射到输出设备。

    • 所有音频上下文都应在一个音频区内表示。这样可以为所有音频属性用法准确设置音频路由。

音频上下文

为了简化 AAOS 音频的配置,类似用法均已归入 CarAudioContexts。这些音频上下文会在整个 CarAudioService 中使用,以定义路由、音量组、音频焦点和闪避管理。下面列出了 AAOS 中的静态音频上下文。

下表介绍了音频上下文和用法之间的对应关系。突出显示的行供新的系统使用。

CarAudioContext 关联的 AttributeUsages
MUSIC UNKNOWN
GAME
MEDIA
NAVIGATION ASSISTANCE_NAVIGATION_GUIDANCE
VOICE_COMMAND ASSISTANT
ASSISTANCE_ACCESSIBILITY
CALL_RING NOTIFICATION_RINGTONE
CALL VOICE_COMMUNICATION
VOICE_COMMUNICATION_SIGNALING
ALARM ALARM
NOTIFICATION NOTIFICATION
NOTIFICATION_*
SYSTEM_SOUND ASSISTANCE_SONIFICATION
EMERGENCY EMERGENCY
SAFETY SAFETY
VEHICLE_STATUS VEHICLE_STATUS
ANNOUNCEMENT ANNOUNCEMENT

启用 AAOS 路由

如需使用基于 AAOS 的路由,您必须将 audioUseDynamicRouting 标志设为 true

<resources>
    <bool name="audioUseDynamicRouting">true</bool>
</resources>

如果设为 false,路由和大部分 CarAudioService 将被停用,并且 AAOS 会回退到 AudioService 的默认行为。

主音频区

默认情况下,所有音频都会路由到主音频区。只有一个主音频区,该音频区在配置中通过属性 isPrimary="true" 进行指示。系统会自动为主音频区分配 Audiomanager.PRIMARY_AUDIO_ZONE

示例配置(版本 2)

例如,车辆可能拥有两个音频区:主音频区和后座娱乐系统。在这种情况下,您可以按如下方式设计可行的 car_audio_configuration.xml 版本 2:

<audioZoneConfiguration version="2.0">
       <zone name="primary zone" isPrimary="true">
           <volumeGroups>
               <group>
                   <device address="bus0_media_out">
                       <context context="music"/>
                       <context context="announcement"/>
                   </device>
                   <device address="bus3_call_ring_out">
                       <context context="call_ring"/>
                   </device>
                   <device address="bus6_notification_out">
                       <context context="notification"/>
                   </device>
               </group>
               <group>
                   <device address="bus1_navigation_out">
                       <context context="navigation"/>
                   </device>
                   <device address="bus2_voice_command_out">
                       <context context="voice_command"/>
                   </device>
               </group>
               <group>
                   <device address="bus4_call_out">
                       <context context="call"/>
                   </device>
               </group>
               <group>
                   <device address="bus5_alarm_out">
                       <context context="alarm"/>
                   </device>
               </group>
               <group>
                   <device address="bus7_system_sound_out">
                       <context context="system_sound"/>
                       <context context="emergency"/>
                       <context context="safety"/>
                       <context context="vehicle_status"/>
                   </device>
               </group>
           </volumeGroups>
       </zone>
        <zone name="rear seat zone" audioZoneId="1">
           <volumeGroups>
               <group>
                   <device address="bus100_rear_seat">
                       <context context="music"/>
                       <context context="navigation"/>
                       <context context="voice_command"/>
                       <context context="call_ring"/>
                       <context context="call"/>
                       <context context="alarm"/>
                       <context context="notification"/>
                       <context context="system_sound"/>
                       <context context="emergency"/>
                       <context context="safety"/>
                       <context context="vehicle_status"/>
                       <context context="announcement"/>
                   </device>
               </group>
           </volumeGroups>
    </zones>
</audioZoneConfiguration>

在此示例中,主音频区将一些音频上下文分隔到不同的设备。这样一来,HAL 便可使用车辆的硬件,在各个设备中应用不同的后处理效果和混合输出。设备已划分为几个音量组:媒体、导航、通话、闹钟和系统声音。如果系统配置为 useFixedVolume,则每个组的音量级别都会传递到 HAL,以应用于这些设备的输出。

对于主音频区,我们建议将系统声音与其他声音分开。这样一来,系统就能以更高的优先级处理车辆声音。车载音频服务已经在焦点和闪避管理方面对车辆声音进行了这些区分。例如,紧急声音焦点请求的优先级高于其他焦点请求。

为简单起见,在辅助音频区示例中,所有音频上下文均路由到单台设备和一个音量组。

乘员区的音频配置

在 Android 11 中,car_audio_configuration.xml 引入了 audioZoneIdoccupantZoneId 这两个新字段。您可以使用 audioZoneId 来控制音频区管理,并可以使用 occupantZoneId 根据用户 ID 配置路由。

如果想重新访问上述音频配置,但利用该新字段进行乘员区 ID 和音频区 ID 之间的映射,则可按如下所示设置不含音量组定义的新配置。

<audioZoneConfiguration version="2.0">
       <zone name="primary zone" isPrimary="true" occupantZoneId="0">
         ...
       </zone>
       <zone name="rear seat zone" audioZoneId="1" occupantZoneId="1">
         ...
       </zone>
    </zones>
</audioZoneConfiguration>

上面的配置定义了主音频区到乘员区 0 以及 audioZoneId 1 到 occupantZoneId 1 的映射。一般来说,可以配置乘员区和音频区之间的任何映射。但是,这种映射必须是一对一的。下面列出了定义这两个新字段的规则。

  • 主音频区的 audioZoneId 始终为 PRIMARY_AUDIO_ZONE ID。如果定义了 isPrimary="true",则无需 audioZoneId

  • audioZoneIdoccupantZoneId 的编号不能重复。

  • audioZoneIdoccupantZoneId 之间只能是一对一的映射。

Android 14 车载音频配置

在 Android 14 中,AAOS 引入了原始设备制造商 (OEM) 插件服务,可让您更主动地管理由车载音频服务监督的音频行为。除了新的插件服务之外,车载音频配置文件中还添加了以下更改:

  • OEM 定义的车载音频上下文
  • 非主音频区动态配置

OEM 定义的车载音频上下文

为了实现灵活的音频配置,在 Android 14 中,车载音频服务允许以不同于上面定义的静态音频上下文的方式对音频用法进行分组。这个 OEM 定义的上下文可以在 car_audio_configuration.xml 版本 3 文件中定义。

取而代之的是当前定义的静态音频上下文。OEM 定义的车载音频上下文的常规格式如下所示。

每个 OEM 上下文都需要 name 以及分配给上下文的音频属性用法的列表。在上面的示例中,定义了两个上下文:

<carAudioConfiguration version="3">
    <oemContexts>
        <oemContext name="media">
            <audioAttributes>
                <usage value="AUDIO_USAGE_MEDIA" />
    <usage value="AUDIO_USAGE_UNKNOWN"/>
            </audioAttributes>
        </oemContext>
        <oemContext name="game">
            <audioAttributes>
                <usage value="AUDIO_USAGE_GAME" />
            </audioAttributes>
        </oemContext>
...
  • media 上下文包含 AUDIO_USAGE_MEDIAAUDIO_USAGE_UNKNOWN
  • game 上下文包含 AUDIO_USAGE_GAME

上下文必须在 car_audio_configuration.xml 文件的顶部定义。定义 OEM 上下文后,车载音频配置的其余部分可以像以前一样继续。以下规则适用于车载音频上下文:

  • OEM 上下文定义为可选设置,可改用静态音频上下文

  • 不要重复上下文名称。

  • 不要将音频属性用法分配给多个上下文。

  • AudioAttributes 中定义的所有音频用法都应用来构建上下文。

严格来说,音频用法的 android.audio.policy.configuration.V7_0.AudioUsage 字符串表示必须用于 OEM 音频上下文定义。未来,较新的音频属性用法会被分配给最合适的上下文,以减少从一个 Android 版本迁移到另一个 Android 版本时出现的错误。

虽然引入 OEM 定义的上下文是为了进一步扩展 OEM 插件音频服务,但它仍然可以在没有 OEM 插件服务的情况下使用。音频行为类似于静态音频服务的行为:

  • 音频焦点交互。音频属性用于确定由音频焦点交互矩阵设置的最佳匹配行为。如需了解详情,请参阅音频焦点

  • 音频音量控制音频属性用于确定最佳匹配:

    • 基于 OEM 定义的上下文的音量组。
    • 配置的静态音量列表中的优先级。
  • 音频闪避行为:

    • 当前音频焦点的音频属性用法用于映射到车载音频配置文件中定义的输出音频设备信息。

    • 根据静态音频闪避矩阵,音频属性用于映射相应的静态上下文进行闪避。

动态音频区配置

在 Android 14 中,为了适应动态音频区配置,用于定义音频区的车载音频配置架构也更新到了版本 3。新架构需要为每个音频区设置配置。

<carAudioConfiguration version="3">
    <!-- optional OEM context -->
    <oemContexts>
      <oemContext name="media">
        <audioAttributes>
          <usage value="AUDIO_USAGE_MEDIA" />
          <usage value="AUDIO_USAGE_UNKNOWN"/>
        </audioAttributes>
      </oemContext>
      <oemContext name="game">
        <audioAttributes>
          <usage value="AUDIO_USAGE_GAME" />
        </audioAttributes>
      </oemContext>
...
    </oemContexts>
  <zones>
    <zone name="primary zone" isPrimary="true" occupantZoneId="0">
      <zoneConfigs>
        <zoneConfig name="primary zone config 0" isDefault="true">
          <volumeGroups>
            <group>
              <device address="bus0_media_out">
                <context context="media"/>
            <context context="game"/>
                <context context="announcement"/>
              </device>
              <device address="bus6_notification_out">
                <context context="notification"/>
              </device>
            </group>
  ...
      </zoneConfigs>
    </zone
  </zones>

如需了解详情,请参阅 device/generic/car/emulator/audio/car_audio_configuration.xml 中定义的版本 3 文件。从 Android 14 开始,主音频区只能有一 (1) 项配置。非主音频区可以有多项配置。以下规则适用于车载音频配置:

  • 主音频区能有一项配置。

  • 非主音频区可以有多项配置。

  • 每个音频区和音频区配置的名称必须是唯一的。

  • 在一个音频区中,音频配置可能有所不同:

    • 音量组的设置不必相同。
    • 音频上下文分配不必相同。
  • 音频输出设备名称在各个音频区或配置中应该是唯一的。在音频配置或音频区中,设备名称应出现一次。

  • 属于同一音量组的音频设备应具有相同的音频增益配置。

  • 必须为每项音频配置分配所有音频上下文(OEM 或静态)。

向前兼容性

虽然新版本的 car_audio_configuration.xml 在每次更新中都引入了新功能,但您仍然可以在较新版本的 AAOS 中使用旧文件。更新到新版 Android 的 OEM 可以重复使用 car_audio_configuration.xml 文件。

如需使用需要 car_audio_configuration.xml 中所含新信息的新功能,必须更新版本。如果尝试将某个旧版文件与该文件版本不支持的信息搭配使用,则会在启动汽车服务时抛出 IllegalStateException。该异常消息包含所用信息以及所需最低版本的相关信息。