首页 > 其他分享 >Android Audio分区——车载多区音频基础(一)

Android Audio分区——车载多区音频基础(一)

时间:2024-08-29 09:26:08浏览次数:14  
标签:输出设备 乘客 音频 配置 多区 镜像 Android Audio 设备

        Android Audio 多区音频功能主要针对的是 Android Automotive 这样的场景,它允许在同一个 Android 设备上支持多个独立的音频区域,每个区域可以有不同的音频输出设置。这种功能特别适用于汽车环境,因为车内通常有多个乘客,他们可能希望听不同的音频内容。

一、概念介绍

        在 Android 10 中,多区音频得到了进一步的支持和增强。允许多个音频流同时播放到不同的物理输出设备或区域,支持独立的音量控制和混合,可以构建后座娱乐系统(RSE)解决方案,让后排乘客能够独立控制他们的音频体验。

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

1、Core Audio

        Core Audio 是 Android 中用于处理音频的核心组件,它主要负责音频的播放、录制、混音、路由等功能。

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

  • 动态音频区配置。

  • 乘客主区音频投放。

  • 乘客的音频镜像。

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

2、多区音频

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

多区音频架构

汽车音频服务架构

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

车载音频配置

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

<carAudioConfiguration version="3">
    <zones>
        <zone name="Zone0" audioZneId="0" occupantZoneI="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>
                    <displays>
                        <display port="0"/>
                    </displays>
                </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>
                    <displays>
                        <display port="1"/>
                    </displays>
                </zoneConfig>
            </zoneConfigs>
        </zone>
        ...
    ...
   </zones>
</carAudioConfiguration>

         对于这段代码是不是比较熟悉,我们在前面的《音量Group设置(九)》中介绍过,这里再来看一下。

  • carAudioConfiguration:配置文件的根节点,包含了所有关于车载音频系统的配置信息。其中 version="3" 表示此配置文件的版本号为 3。
  • zones:列出了所有可用的音频区域。
  • zone:定义一个音频区域,每个区域可以有自己的音频配置,包括 name(区域的名称)、audioZoneId(区域唯一标识符)和occupantZoneId(乘客区域标识符,用于区分不同的乘客位置)。
  • zoneConfigs:列出了该区域可用的音频配置。实际开发中该属性可以省略。
  • zoneConfig:定义一个具体的音频配置方案,其中 name 为配置的名称,isDefault 为否为默认配置。
  • volumeGroups:对应配置方案中的音量组,每个音量组可以包含一个或多个音频设备。
  • group:定义一个音量组,该组内的设备共享相同的音量设置。
  • device:定义一个音频输出设备。其中属性 address 为设备的地址,用于标识特定的音频输出设备。
  • context:定义了设备可以播放的内容类型,如 music, navigation 等
  • displays:一组显示设备的容器标签。
  • display:单个显示设备。包含了 port 属性,用于标识显示设备的端口号,端口号通常用于标识不同的输出接口,比如 HDMI、VGA 或 DVI 等。

        可以看到这里的 bus_1 对应 music,说明只有地址为 bus_1 的输出设备才会播放音乐类型的音频流。

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

  • 音频区 ID 和乘员区 ID。

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

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

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

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

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

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

图像

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

  • 汽车音频服务(针对特定音频区)使用 AudioPolicy#removeUserIdDeviceAffinity API 取消用户设备关联性。此 API 接受用户 ID。在此示例中为上一个音频区的用户。
  • AudioPolicy#setUserIdDeviceAffinity API 将新用户分配到某个音频区,该音频区会接受用户 ID 以及特定音频区配置的所有设备。

3、动态音频区配置

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

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

动态音频区配置工作流程

        上图展示了动态音频区配置工作流程的架构。音频区 1 包含两种配置(Config 0 和 Config 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 管理音频区的配置,如下图所示。Query API 向乘客公开这两者。用户可以通过点按所需配置的命令选择其他配置。

动态音频区配置工作流程

4、主区乘客音频投放

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

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

动态音频区配置工作流程

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

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

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

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

5、乘客区音频镜像

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

音频镜像路由

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

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

动态音频区配置工作流程

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

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

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

音频镜像工作流程

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

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

        在上图中,汽车音频服务会发送 mirroring_src=bus_1000,mirroring_dest=bus_10、bus_20。其中 bus_1000 是来源总线,bus_10 和 bus_20 是目标总线。

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

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

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

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

        这篇文章主要参考 Android 官方文档的多区音频介绍,目的是更好的了解多区音频的相关概念,便于理解后面相关代码的分析。

官网地址:多区音频路由  |  Android Open Source Project

标签:输出设备,乘客,音频,配置,多区,镜像,Android,Audio,设备
From: https://blog.csdn.net/c19344881x/article/details/141392934

相关文章

  • Android Qcom USB Driver学习(十一)
    基于TI的FirmwareUpdate固件升级的流程分析usbapplictionlayers的数据USBProtocolPackage①/②maptocheckpasswordcorrectPackageFormat:Byte[0]=ReportIdByte[1]=ValidLength(0x21=33)Byte[2]=BSLCoreCommands(0x11RXPassword)Byte[3]=Val......
  • Android 常用的性能分析工具详解:GPU呈现模式
    此篇将重点介绍几种常用的Android性能分析工具:一、Logcat日志选取Tag=ActivityManager,可以粗略地知道界面Displaying的时间消耗。当我们打开一个Activity的时候,log会打印一串log如下:I/ActivityManager﹕Displayedxxx.xxx.xxx/TestActivity:+1s272ms(total+3s843ms)第一......
  • Android开发 - “效验和”效验数据在传输或存储过程中是否出错解析
    校验和的基本原理校验和的基本原理非常简单,就是把一组数据中的所有字节(或者其他单位)的数值相加,然后得到一个总和,这个总和就是所谓的“校验和”。在传输数据时,发送方会把数据和校验和一起发送出去;接收方收到数据后,也会计算一次校验和,然后与发送方提供的校验和进行比较。如果两个......
  • Android开发 - Runnable 类任务接口定义与后台任务待办解析
    什么是RunnableRunnable接口是用来定义一个任务的接口,这个任务可以在线程中执行。通俗地说,它就像一个“待办事项”,用来描述需要在一个单独的线程中完成的工作。Runnable接口非常简单,只定义了一个方法:run()。当一个类实现了Runnable接口时,它需要提供这个方法的实现,里面写上......
  • 如何在Android上恢复永久删除的照片?
    您是否曾经不小心从Android手机中删除了珍贵的照片,并以为它们已经永远消失了?不要恐慌。我们为您提供了有关如何在Android上恢复永久删除的照片的指南。无论是怀旧之旅还是您需要找回的重要记忆,我们都会引导您完成安全、轻松地取回这些照片的步骤。 第1部分:是否可以恢复......
  • Android经典实战之常见的移动端加密算法和用kotlin进行AES-256加密和解密
    本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点在移动端开发中,数据加密是确保数据传输和存储安全的重要手段。常见的加密算法包括对称加密算法(如AES)、非对称加密算法(如RSA)、散列算法(如SHA-256),以及消息认证码(如......
  • Android经典实战之使用compose时一般用一个activity还是多个
    本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点在使用JetpackCompose开发Android应用时,选择使用一个Activity还是多个Activity主要取决于应用的架构和复杂性。以下是一些权衡和指导建议,可以帮助你做出决......
  • Stable Audio文本转音乐 免费商用无版权限制 本地一键包使用教程
    StabilityAI的发布再次打破了创新的界限。这款前沿模型在其前作的成功基础上,增添了一系列突破性功能,可能彻底改变艺术家和音乐家创建及操作音频内容的方式。StableAudio2.0标志着人工智能生成音频的一个重要里程碑,为音质、多功能性和创意潜力设定了全新标准。这个模型......
  • Android 启动时判断overlay fs是否挂载
    一、背景Android新版本使用super分区替代原来的system、vendor后,就采用了overlayfs文件系统。这种文件系统在执行adbremount后,修改system、vendor分区内容并不是真正存储在原来的位置,而是单独利用super剩余空间或data分区存了一份新的,原来的文件并没有改变。系统使用时判断......
  • Android面试高阶问题:Android屏幕刷新机制与优化指南
    目录1屏幕刷新基础概念1.1CPU与GPU的作用2.2SurfaceFlinger与图形合成2.3帧、帧率与屏幕刷新率2屏幕撕裂与双缓冲机制2.1屏幕撕裂的原因与影响2.2双缓冲机制的工作原理3优化策略与实践3.1性能分析工具与方法3.2优化案例分析与实施3.2.1案例四:异步加载与......