Android GroupVolume

一、GroupVolume介绍

汽车音频中新增了音量组的概念. 所谓音量组,就是将不同用途的声音进行归纳,按组对相关的音量进行控制,在进一步解释音量组的概念之前,先了解一下音频上下文(Audio Context)和音频属性(Audio Attribute)两个概念。Android中的每段声音都由相应的应用和声音生成的原因来识别, 然后Android设备会使用这些信息来确认如何呈现声音。音频属性与音频上下文的具体对应关系如表:

音频上下文音频属性对象

MUSIC

MEDIA

VOICE_COMMAND

USAGE_ASSISTANT

NAVIGATION

ASSISTANCE_NAVIGATION_GUIDEANCE

CALL

VOICE_COMMUNICATION

RINGTONE

NOTIFICATION_RINGTONE

NOTIFICATION

NOTIFICATION

ALARM

ALARM

SYSTEM_SOUND

ASSISTANCE_SONIFICATION

UNKNOWN

UNKNOWN

也就是说, 应用在使用音频设备时, 需要指定相应的音频属性,而音频属性对应着相关的音频上下文. 音量组就是对音频上下文进行了分组,在同一组内的上下文,音量会同步变化,而如何对音量组进行分类,则由制造商自己定义,如果制造商没有定义,则使用AAOS的默认分组。

在同一组中的音频虽然属于不同的上下文,但是它们的音量变化是联动的. 当然,各制造商可以覆盖以上默认定义,对音频上下文进行不同的组合,或者增加分组的数量. 但是需要满足以下条件:

1. 一个音频上下文只能归属于一个组

2. 除去UNKNOWN, 共有8个有效的音量上下文类型,这8个类型都需要进行分组,不能缺省.

3. 上下文对应的底层的总线设备不应该出现在两个组中

4. 在同一组的音频上下文的单次调节的步长度应该一致.

在Android10之后,为了更好地支持多音区音频的特性,修改了汽车音频配置文件的格式.同时文件也不再以Android资源的形式进行配置,而是通过系统构建时复制到指定的路径下进行读取.

有了音量组,就要通过音量组对音量大小进行控制, 这点和手机不一样, 手机上面使用AudiaManager的setStreamVolume方法进行音量调节,但是在AAOS中该方法很可能是无效的(取决于制造商的配置).

AAOS上建议的是使用车上的硬件放大器完成对音量大小的调节,而非软件混音器. 系统音量的调节需要通过CarAudioManager中提供的接口进行控制. 其中相关的接口都是SystemAPI, 即系统级别的接口,所以普通第三方应用是无法使用的. 也就是说在实际驾驶过程中,第三方应用的音量调节主要依赖系统设置或者相关控制按键(如音量旋钮, 方向盘音量按键)实现.

CarAudioManager实例的获取方法和CarPropertyManager的获取类似,也是通过

Car car = Car.createCar(this);
CarAudioManager carAudioManager = (CarAudioManager)car.getCarManager(Car.AUDIO_SERVICE);

获取到CarAudioManager的实例之后,就可以使用它对音量进行调节了. 以增加某一Group的音量为例子:

int volume = carAudioManager.getGroupVolume(groupID);
carAudioManager.setGroupVolume(groupID, ++volume,
                AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND);

通过getGroupVolume可以获取当前组的音量值,在通过setGroupVolume设置新的值.

那么这里有个疑问?如何知道想要调节的音频属性所对应的groupID呢? 因为制造商是可以重新定义分组的,不推荐开发者使用"硬编码"的方式, 为了使应用有较好的通用性,应用态获取音频属性所属的分组. 这里分为两个步骤实现:

1. 通过getVolumeGroupIdForUsage获取该Usage对应的groupId

2. 在利用获取的groupId设置音量

int groupID = carAudioManager.getVolumeGroupIdForUsage(AudioAttributes.USAGE_MEDIA);

调节音量需要申请对应的权限,因此不要忘记在清单文件中增加声明:

<uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME"/>

同样的,该权限只有系统特权应用可以使用.

可以通过overlay机制覆盖CarAudioService默认的音量组实现音量组的自定义. 当然制造商可以做的和需要完成的事情不仅于此. 本节内容就基于CarAudioService的相关实现,对制造商的音频实现和相关配置进行一些补充.

在AAOS中推荐使用硬件放大器来控制音量, 而在Android手机中,支持软件混音器调节音量,这也是Android框架中的默认配置. 因此,如果要改用硬件放大器调节音量, 首先需要覆盖config_useFixedVolume属性.

<bool name="config_useFixedVolume">false</bool>

config文件位置:

android/frameworks/base/core/res/res/values/config.xml

semidrive x9u使用了overlay,会使用如下文件:

android/device/semidrive/x9u/x9u_ref_a/overlay/frameworks/base/core/res/res/values/config.xml

android/device/semidrive/x9u/x9u_ref_b/overlay/frameworks/base/core/res/res/values/config.xml

默认值为false, 该情况下,应用就可以调用AudioManager.setStreamVolume方法调节不同音频属性的音量.

在车载设备上, 我们一般设置为true, 这样子AudioManager.setStreamVolume就不生效了.

二、GroupVolume相关类

CarAudioService 相关类

AudioPolicy&AudioFlinger相关类

AudioFlinger&AudioHal相关类

CarVolumeGroup

A class encapsulates a volume group in car.

CarVolumeGroup代码位于:

packages/services/Car/service/src/com/android/car/CarVolumeGroup.java

CarVolumeGroup的定义:

final class CarVolumeGroup {
    static final class Builder {}
}

三、GroupVolume相关方法

1、CarAudioManager方法

  • void setGroupVolume(int groupId, int index, int flags) :设置组音量

  • void setGroupVolume(int zoneId, int groupId, int index, int flags):设置组音量

  • int getGroupMaxVolume(int groupId) :获取组最大音量

  • int getGroupMinVolume(int groupId) :获取组最小音量

  • int getGroupVolume(int groupId) :获取组音量

  • int getVolumeGroupCount():获取Volume组数量

  • int getVolumeGroupIdForUsage(@AudioAttributes.AttributeUsage int usage):获取Volume组ID

  • int[] getUsagesForVolumeGroupId(int groupId):获取声音组ID

  • boolean isVolumeGroupMuted(int zoneId, int groupId):Volume组是否静音

  • void setVolumeGroupMute(int zoneId, int groupId, boolean mute, int flags):设置Volume组静音

  • void registerVolumeCallback(in IBinder binder):注册Volume回调

  • void unregisterVolumeCallback(in IBinder binder):解除注册Volume回调

zoneId的定义路径packages/services/Car/car-lib/src/android/car/media/CarAudioManager.java,定义如下:

PRIMARY_AUDIO_ZONE

usage的定义路径frameworks/base/media/java/android/media/AudioAttributes.java,定义如下:

USAGE_MEDIA

USAGE_VOICE_COMMUNICATION

USAGE_ALARM

USAGE_NOTIFICATION

USAGE_NOTIFICATION_RINGTONE

USAGE_NOTIFICATION_COMMUNICATION_REQUEST

USAGE_NOTIFICATION_COMMUNICATION_INSTANT

USAGE_NOTIFICATION_COMMUNICATION_DELAYED

USAGE_NOTIFICATION_EVENT

USAGE_ASSISTANCE_ACCESSIBILITY

USAGE_ASSISTANCE_NAVIGATION_GUIDANCE

USAGE_ASSISTANCE_SONIFICATION

USAGE_GAME

USAGE_VIRTUAL_SOURCE

USAGE_ASSISTANT

USAGE_CALL_ASSISTANT

groupId的定义如下:

2、CarAudioService方法

  • void setGroupVolume(int zoneId, int groupId, int index, int flags):设置组音量

  • int getGroupMaxVolume(int zoneId, int groupId):获取组最大音量

  • int getGroupMinVolume(int zoneId, int groupId):获取组最小音量

  • int getGroupVolume(int zoneId, int groupId):获取组音量

  • int getVolumeGroupCount(int zoneId):获取Volume组数量

  • int getVolumeGroupIdForUsage(int zoneId, int usage):获取Volume组ID

  • int[] getUsagesForVolumeGroupId(int zoneId, int groupId):获取声音组ID

  • boolean isVolumeGroupMuted(int zoneId, int groupId) :Volume组是否静音

  • void setVolumeGroupMute(int zoneId, int groupId, boolean mute, int flags):设置Volume组静音

  • void registerVolumeCallback(in IBinder binder):注册Volume回调

  • void unregisterVolumeCallback(in IBinder binder):解除注册Volume回调

四、GroupVolume流程分析

1、setGroupVolume流程分析

Android13 CarAudioManager setGroupVolume流程分析-CSDN博客

2、setVolumeGroupMute流程分析

Android13 CarAudioManager setVolumeGroupMute流程分析-CSDN博客

  • 21
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值