Android音频学习(十三)——音量配置文件分析
在Android系统中,音量曲线通常指的是将用户的音量等级(比如0到15级)映射到实际的硬件增益或分贝值的曲线。
1. 音量曲线加载
上一节分析,解析Engine文件时最终调用到loadAudioPolicyEngineConfig() 方法,该方法在加载Engine文件之前,也会加载解析音量曲线文件,该文件在开发板上位于/vendor/etc/audio_policy_volumes.xml或/system/etc,厂商也可以根据自己的需求进行扩展。在代码中路径为: /frameworks/av/services/audiopolicy/config/。
以下是与该xml文件中元素对应的对象
2.音量曲线分析
文件将在audio_policy_configuation.xml中引用:
<!-- Volume section:IMPORTANT NOTE: Volume tables have been moved to engine configuration.Keep it here for legacy.Engine will fallback on these files if none are provided by engine.--><xi:include href="audio_policy_volumes.xml"/><xi:include href="default_volume_tables.xml"/><!-- End of Volume section -->
在audio_policy_volumes.xml中,规定了音频流类型(stream)、输出设备(deviceCategory)和音量曲线(ref)的关系,在default_volume_tables.xml中规定了具体的音量曲线的值
audio_policy_volumes.xml:
<volumes><volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_HEADSET"ref="DEFAULT_MEDIA_VOLUME_CURVE"/><volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER"ref="DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE"/><volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_EARPIECE"ref="DEFAULT_MEDIA_VOLUME_CURVE"/><volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
...
</volumes>
default_volume_tables.xml:
<volumes><reference name="DEFAULT_MEDIA_VOLUME_CURVE"><!-- Default Media reference Volume Curve --><point>1,-5800</point><point>20,-4000</point><point>60,-1700</point><point>100,0</point></reference>
...
</volumes>
例如:DEFAULT_MEDIA_VOLUME_CURVE曲线上的(index、db)值。定义的index范围是1到100, 而db的范围为-5800 到0。音量等级分成4段为100、60、20、1就是音量百分比;0,-1700,-4000,-5800就是对应百分比时衰减的音量,代表衰减-17db,-40db,-58db。
其中,point表示<等级,分贝值>,分贝值单位为 厘贝(cB)(1 dB = 100 cB),<point>20,-4000</point>表示第2等级20对应的音量为-40db。
在audio_policy_volume.xml中,引用DEFAULT_MEDIA_VOLUME_CURVE曲线的device有headset,speaker,earpiece等。
用户的音量等级通常为0~15级,如何通过传入的用户音量级别来查找音量的位置,需要两个步骤。
(1)根据用户的index,找到音量曲线的index。
根据用户传入的index(0~15),找到对应音量曲线(1,100)的位置,加入传入的为x,对应的y,那么x/(15-0)=y/(100-1), 例如用户配置了音量为7,那么对应音量曲线的index为46。
(2)寻找曲线index对应的分贝
46在区间【20~60】,这个区间对应的db区间是【-4000,-1700】。先求这个区间一个index对应多少db 将总的index(60-20)除于总的db(-1700 - (-4000)) 为单位index对应的db。那46对应的有多少index,46对应为 46-20。 将这两者相乘就是46对应在这个区间内的db值, 加上起始的-4000就是最终的db。
db就在这个区间里面算。 所求的db = -4000 + (((- 1700 - (-4000))/(60 -20) x(46 -20)) = -2505。
也等比例计算的一个方式。 相对于一个个区间是独立。起始点是最靠近的上一个区间的index,然后计算区间内一个index对应多少db。传递进去的index相对于起始index的值。
3.调试工具与命令
# 查看当前音量曲线
adb shell dumpsys audio | grep -A 15 "Volume curves"# 示例输出:
Volume curves for stream MUSIC:Speaker: (0%, -60dB) -> (50%, -30dB) -> (100%, 0dB)Headphones: (0%, -55dB) -> (100%, -5dB)# 强制重载配置
adb shell cmd media.audio_policy reload-volumes# 测试音量转换
adb shell cmd media.audio_policy volume-to-db --stream MUSIC --device speaker --level 70
# 返回: -15.2 dB
4.常见问题解决方案
问题现象 | 原因分析 | 解决方案 |
音量调节不灵敏 | 曲线点过少 | 增加中间点(如每10%一个点) |
最大音量太小 | maxDb限制过低 | 调整<point max="值"> |
蓝牙设备音量突变 | 曲线与手机不匹配 | 为蓝牙设备单独定义曲线 |
插入耳机后音量过大 | 不同设备曲线差异过大 | 统一各设备0%和100%的dB基准 |
重启后音量重置 | 持久化配置错误 | 检查/data/system/audio目录权限 |