AAOS 音频动态路由流程研究

本文详细阐述了Android车载系统的CarAudioService初始化过程,包括通过CarAudioManager与CarAudioService通信,以及car_audio_configuration.xml配置文件在动态路由中的作用。还介绍了如何利用AudioPolicyManager进行设备选择和多声道播放的处理,涉及车载HAL层接口的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 CarAudioService 初始化的起源

1  给APP的API接口

类AudioManager.java 的CarAudioManager.java

Car Audio API:它是提供给3rd APP调用的各个模块的接口,比如音频的API接口CarAudioManager。CarAudioManager和AudioManager类似,是CarAudioService的代理,与CarAudoService通过Binder进行跨进程通信,CarAudioManager运行在调用方的进程中。

目录:packages/services/Car/car-lib/src/android/car/media/CarAudioManager.java

//一些感兴趣的API

setGroupVolume

getGroupMaxVolume

getGroupMinVolume

getGroupVolume

setFadeTowardFront // 这个是直接通过AudioControl直接调整音箱前后声音的响度

setBalanceTowardRight // 这个是直接通过AudioControl直接调整音箱左右声音的响度

getVolumeGroupCount // 返回某个音区的volime group 数量

getVolumeGroupIdForUsage //返回某个音区中某一个Usage的VolumeGroup

getUsagesForVolumeGroupId //返回某个音区中某一个VolumeGroup的Usage

getVolumeGroupInfo

isPlaybackOnVolumeGroupActive

setPrimaryZoneMediaAudioRequestCallback //监听listen for request to play media audio in primary audio zone

mirror device 相关的接口

音量控制和音量变化回调接口

2 CarService

       针对车机系统扩展的各种框架服务层,比如音频的扩展服务CarAudioService、Activity的扩展服务CarActivityService等。所有的这些扩展服务CarXXXService都是由CarService负责启动和管理生命周期。CarService会被打包进包名为"com.android.car"的CarService.apk中。它是一个System APP,SystemServer进程在启动时,会启动这个CarService。所以,所有的CarXXXService都是运行在"com.android.car"进程中的。源码位置:/packages/services/Car/service-builtin/和/packages/services/Car/service/

ps:

 /packages/services/Car/service-builtin  

 这个目录中的文件改动,编译 make CarService

/packages/services/Car/service/ 这个里面的文件改动,

编译 make com.android.car.framework

Carservice 的加载时序图:

上图来源于Android13音频子系统分析(四)---座舱的多音区框架_carserviceimpl-优快云博客

说明:在ICarImpl.init()函数中,它会遍历调用所有框架服务的init()函数。所以,每个框架服务对象的初始化函数入口有两个:一个是其构造函数、一个是init()函数。

3 CarAudioService 的初始化(重点表达dynamic 路由注册部分)

3.1 CarAudioService init的时候调用setupDynamicRoutingLocked() 加载配置文件 car_audio_configuration.xml的详细时序图

说明:先解析car_audio_configuration.xml配置文件,得到音区,和音区关联的volumeGroups,然后是volumeGroups关联的device address,和device address关联的context(attribute)这些信息,然后封装成audiopolicy的mixer build rule策略,最后通过registerAudioPolicy接口注册到AudioPolicyManager的成员变量mPolicyMixes中,即AudioPolicyMixCollection集合中,留到后面播放声音的时候设备选择使用。

3.2 播放音乐时候根据上面注册的mPolicyMixes选择device 的流程

说明:应用播放声音 createTrack_l()的时候会在getOutputForAttrInt(...attribute)中使用上述注册的audio mixer policy 规则进行设备的选择

PS  如何再AAOS 上实现media 类型的 多声道播放,采用direct output(aaos 原生逻辑:这种存在一个风险是,因为direct output每次只能打开一个,如果前一个direct  output没有关闭的情况下,应用就去打开播放,会存在打开direct output失败的情形,比如播放一个7.1.4声道的音乐,在接着播放一个5.1声道的音乐,那么在7.1.4音乐没有close的时候,5.1的音乐播放使用direct output会失败);其实可以修改这里,在赋值一个flag,让其走mixer 类型的output,不用每次使用都open/close.

使用direct output播放音乐的逻辑如下:

status_t AudioPolicyManager::getOutputForAttrInt(

3.3 AAOS audio 动态路由相关的XML

3.3.1 car_audio_configuration.xm

/device/generic/car/emulator/audio/car_audio_configuration.xml(这个定义zone\zoneconfig\volumegroup\device address\context等 audio mixer policy 策略)

一个典型的场景

3.3.2 audio_policy_configuration.xml

/device/generic/car/emulator/audio/audio_policy_configuration.xml(这个定义HW module name/attachedDevices/defaultOutputDevice/mixPorts/devicePorts/devicePort profile/devicePort profile gain/routes)

详细解读:

(1) module name:

代码的实现在:https://cs.android.com/android/platform/superproject/+/master:hardware/libhardware/hardware.c;l=197?q=hw_get_module_by_class&ss=android

(2)attachedDevices 和 defaultOutputDevices:

(3)mixPort

这里就是对应着audioflinger 中的各类playback / record 线程的名称,它也界定了这个线程对应的采样率、位数和声道数这些信息;还有一个逻辑是audiopolicymamager 初始化的时候会轮询各个mixPort,然后根据上面2中的attachedDevices去筛选支持的output/input mixport,并且是调用open去打开这个mixport,并且加入audiopolicymanager中的mOutputs list( direct output之后会close,Input的会关闭,其余的会一直保留);代码逻辑如下

(Talk is cheap, show me the code.)

(4) deviceport :这个就是定义 device Fe的名称了,这个需要在hal层对应的实现

车机上主要是根据 address name去做设备的区分的

(5)route 就是链接 上面的deviceport和mixport的通路,类似audiomanagerdaemon中的gateway的概率,将sink 和source 链接起来,形成一条独立的通路

4 车载HAL

      需要OEM厂商实现的各种HAL层接口。源码位置:/hardware/interfaces/automotive/

### Android Automotive OS (AAOS) 中按键 Mute 功能实现 在 AAOS 环境下,Mute 按键的功能设计不仅依赖于基础的 Android 输入处理机制,还特别针对汽车环境进行了优化。当按下 Mute 键时,系统会触发一系列特定的操作来控制音频流。 #### 1. Mute 操作流程 Mute 操作主要通过 `AudioManager` 类中的方法实现。具体来说: - 当检测到 Mute 按键被按下时,事件会被传递给相应的广播接收器。 - 广播接收器接收到该事件后调用 `setStreamMute()` 方法[^2]。 ```java // 设置指定音频流静音状态 audioManager.setStreamMute(AudioManager.STREAM_MUSIC, true); ``` 此操作会使当前播放的所有音乐类别的声音立即停止发出,但不会影响其他类型的音频流(如导航提示声)。同时,在某些配置中,可能会显示视觉反馈告知用户已进入静音模式。 #### 2. 处理特殊情况 考虑到车内复杂的使用场景,AAOS 对 Mute 功能做了一些额外考虑: - **来电优先级**:即使处于静音状态下,如果接到来电,则自动解除静音以便能够听到铃声并接听电话。 - **媒体恢复逻辑**:一旦取消静音设置,之前暂停的多媒体应用应能平滑地恢复正常音量输出而不造成突兀感。 - **多区域管理**:对于配备多个独立音响分区的高端车型,可以单独为不同座位上的乘客设定不同的静音选项。 #### 3. 常见问题及解决方案 有时开发者或车主可能遇到如下情况: - **无法响应 Mute 按钮**:这可能是由于应用程序未正确注册监听器或是硬件连接存在问题所致;建议检查权限声明以及物理连线状况。 - **误触导致意外静音**:可以通过增加短暂延迟确认动作的方式减少此类现象发生频率。 - **跨应用一致性维护困难**:确保所有涉及音频的应用遵循统一的标准API接口定义来进行静音控制。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值