配置音频策略

Android 10 版本包括对音频策略管理器的重大重构,从而提供更大的灵活性来支持复杂的汽车用例

  • OEM 特定路由策略。
  • 使用相同音量曲线的旧版流类型组的可自定义音量组。
  • 音频政策引擎声明的路由策略,而非硬编码。
  • 音量曲线和组由音频政策引擎管理。
  • 内部重构为未来在通用代码与可配置代码之间拆分做准备,并提供更丰富的音频设备管理。例如,在政策规则中使用所有设备属性,而不仅仅是设备类型。

Android 7.0 引入了一种音频拓扑结构的音频政策配置文件格式 (XML)。

之前的 Android 版本需要使用 device/<company>/<device>/audio/audio_policy.conf 来声明您的产品上存在的音频设备(您可以在 device/samsung/tuna/audio/audio_policy.conf 中看到 Galaxy Nexus 音频硬件的此文件示例)。但是,CONF 是一种简单的专有格式,其局限性太大,无法描述电视和汽车等垂直行业的复杂拓扑结构。

Android 7.0 已弃用 audio_policy.conf,并添加了对使用 XML 文件格式定义音频拓扑结构的支持,该格式更易于人工阅读,具有广泛的编辑和解析工具,并且足够灵活,可以描述复杂的音频拓扑结构。Android 7.0 使用 USE_XML_AUDIO_POLICY_CONF 构建标志来选择配置文件的 XML 格式。

XML 格式的优势

与 CONF 文件一样,XML 文件可以定义输出和输入流配置文件的数量和类型、可用于播放和捕获的设备以及音频属性。此外,XML 格式还提供以下增强功能

  • 在 Android 10 中,允许多个活跃的录音应用同时运行。
    • 录音启动永远不会因为并发情况而被拒绝。
    • registerAudioRecordingCallback(AudioManager.AudioRecordingCallback cb) 回调会通知客户端捕获路径更改。
  • 在以下情况下,客户端会获得静音音频样本
    • 隐私敏感型用例(例如,VOICE_COMMUNICATION)处于活动状态。
    • 客户端没有前台服务或前台 UI。
    • 特殊角色由政策识别
      • 无障碍功能服务:即使隐私敏感型用例处于活动状态也可以录音。
      • Assistant:如果 UI 位于顶部,则被视为隐私敏感。
  • 音频配置文件具有类似于 HDMI 简单音频描述符的结构,可以为每种音频格式启用不同的采样率/通道掩码。
  • 所有可能的设备和流之间的连接都有明确的定义。以前,一个隐式规则使得连接到同一 HAL 模块的所有设备成为可能,从而阻止音频政策控制通过音频补丁 API 请求的连接。在 XML 格式中,拓扑结构描述定义了连接限制。
  • 包含项的支持避免了重复标准 A2DP、USB 或重新路由提交定义。
  • 音量曲线是可自定义的。以前,音量表是硬编码的。在 XML 格式中,音量表是描述性的,并且可以自定义。

frameworks/av/services/audiopolicy/config/audio_policy_configuration.xml 的模板显示了许多正在使用的这些功能。

文件格式和位置

新的音频政策配置文件是 audio_policy_configuration.xml,位于 /system/etc 中。以下示例显示了适用于 Android 12 和低于 Android 12 的版本的 XML 文件格式的简单音频政策配置。

顶层结构包含模块,这些模块对应于每个音频 HAL 硬件模块,其中每个模块都有一个混合端口、设备端口和路由列表

  • 混合端口描述了可以在音频 HAL 上为播放和捕获打开的流的可能配置配置文件。
  • 设备端口描述了可以附加的设备及其类型(以及可选的地址和音频属性,如果相关)。
  • 路由与混合端口描述符分开,从而可以描述从设备到设备或从流到设备的路由。

音量表是定义曲线的简单点列表,该曲线用于将 UI 索引转换为 dB 音量。一个单独的包含文件提供了默认曲线,但给定用例和设备类别的每个曲线都可以被覆盖。

文件包含项

XML 包含项 (XInclude) 方法可用于包含位于其他 XML 文件中的音频政策配置信息。所有包含的文件都必须遵循上述结构,并具有以下限制

  • 文件只能包含顶层元素。
  • 文件不能包含 XInclude 元素。

使用包含项以避免将标准 Android 开源项目 (AOSP) 音频 HAL 模块配置信息复制到所有音频政策配置文件(这很容易出错)。为以下音频 HAL 提供了标准音频政策配置 XML 文件

  • A2DP: a2dp_audio_policy_configuration.xml
  • 重新路由子混合: rsubmix_audio_policy_configuration.xml
  • USB: usb_audio_policy_configuration.xml

音频政策代码组织

AudioPolicyManager.cpp 被拆分为多个模块,以便于维护和配置。frameworks/av/services/audiopolicy 的组织结构包括以下模块。

模块 描述
/managerdefault 包含所有应用通用的通用接口和行为实现。类似于 AudioPolicyManager.cpp,但引擎功能和通用概念已被抽象出来。
/common 定义基类(例如,输入输出音频流配置文件、音频设备描述符、音频补丁和音频端口的数据结构)。这以前在 AudioPolicyManager.cpp 中定义。
/engine

实现定义应为给定用例使用哪个设备和音量的规则。它实现了与通用部分的标准接口,例如获取给定播放或捕获用例的适当设备,或设置连接的设备或外部状态(即强制使用的呼叫状态),这些状态可能会改变路由决策。

提供两个版本:可配置默认。有关如何选择版本的信息,请参阅使用参数框架进行配置

/engineconfigurable 依赖于参数框架的政策引擎实现(见下文)。配置基于参数框架,政策由 XML 文件定义。
/enginedefault 基于以前的 Android 音频政策管理器实现的政策引擎实现。这是默认设置,包含与 Nexus 和 AOSP 实现对应的硬编码规则。
/service 包含绑定器接口、线程处理和锁定实现以及与框架其余部分的接口。

使用参数框架进行配置

音频政策代码的组织结构使其易于理解和维护,同时还支持完全由配置文件定义的音频政策。组织结构和音频政策设计基于 Intel 的参数框架,这是一种基于插件和规则的框架,用于处理参数。

使用可配置音频政策使供应商 OEM 能够

  • 在 XML 中描述系统的结构及其参数。
  • 编写 (C++) 或重用后端(插件)以访问描述的参数。
  • 定义(在 XML 或特定领域语言中)给定参数必须取给定值的条件/规则。

AOSP 包含一个音频政策配置文件的示例,该文件在 Frameworks/av/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml 中使用了参数框架。有关详细信息,请参阅 Intel 关于参数框架的文档。

在 Android 10 或更低版本中,可配置音频政策是使用构建选项 USE_CONFIGURABLE_AUDIO_POLICY 选择的。在 Android 11 或更高版本中,音频政策引擎的版本在 audio_policy_configuration.xml 文件中选择。要选择可配置音频政策引擎,请将 globalConfiguration 元素的 engine_library 属性的值设置为 configurable,如以下示例所示

<audioPolicyConfiguration>
    <globalConfiguration engine_library="configurable" />
...
</audioPolicyConfiguration>

音频政策路由 API

Android 6.0 引入了一个公共枚举和选择 API,该 API 位于音频补丁/音频端口基础设施之上,允许应用开发者指示对连接的音频记录或音轨的特定设备输出或输入的偏好。

在 Android 7.0 中,枚举和选择 API 通过 CTS 测试验证,并扩展到包括本机 C/C++ (OpenSL ES) 音频流的路由。本机流的路由继续在 Java 中完成,并添加了 AudioRouting 接口,该接口取代、合并和弃用了特定于 AudioTrackAudioRecord 类的显式路由方法。

有关枚举和选择 API 的详细信息,请参阅Android 配置接口OpenSLES_AndroidConfiguration.h。有关音频路由的详细信息,请参阅AudioRouting

多声道支持

如果您的硬件和驱动程序通过 HDMI 支持多声道音频,您可以将音频流直接输出到音频硬件(这会绕过 AudioFlinger 混音器,因此它不会被下混为双声道。)音频 HAL 必须公开输出流配置文件是否支持多声道音频功能。如果 HAL 公开其功能,则默认政策管理器允许通过 HDMI 进行多声道播放。有关实现详情,请参阅 device/samsung/tuna/audio/audio_hw.c

要指定您的产品包含多声道音频输出,请编辑音频政策配置文件以描述您产品的多声道输出。frameworks/av/services/audiopolicy/config/primary_audio_policy_configuration_tv.xml 中的以下示例显示了动态通道掩码,这意味着音频政策管理器在连接后查询 HDMI 接收器支持的通道掩码。

您还可以指定静态通道掩码,例如 AUDIO_CHANNEL_OUT_5POINT1。当发送到不支持多声道音频的音频设备时,AudioFlinger 的混音器会自动将内容下混为立体声。

媒体编解码器

确保为您的产品正确声明了您的硬件和驱动程序支持的音频编解码器。有关详细信息,请参阅向框架公开编解码器