音量调节接口

我们知道Android Audio的音量调节接口是通过AudioManager的setStreamVolume实现的,这个函数的实现在AudioService的setStreamVolume函数中,然后会调用到setStreamVolumeInt,这个函数首先通过streamState.setIndex发送音量调节的广播通知app更新UI。然后通过消息机制走到setDeviceVolume函数。注:如果要实现硬调音,也就是调节dsp音量不调节安卓音量,可以把config_useFixedVolume这个参数置为true。
我们简单分析一下setDeviceVolume函数

    /*package*/ void setDeviceVolume(VolumeStreamState streamState, int device) {final boolean isAvrcpAbsVolSupported = mDeviceBroker.isAvrcpAbsoluteVolumeSupported();synchronized (VolumeStreamState.class) {// Apply volumestreamState.applyDeviceVolume_syncVSS(device, isAvrcpAbsVolSupported);// Apply change to all streams using this one as aliasint numStreamTypes = AudioSystem.getNumStreamTypes();for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {if (streamType != streamState.mStreamType &&mStreamVolumeAlias[streamType] == streamState.mStreamType) {// Make sure volume is also maxed out on A2DP device for aliased stream// that may have a different device selectedint streamDevice = getDeviceForStream(streamType);if ((device != streamDevice) && isAvrcpAbsVolSupported&& ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0)) {mStreamStates[streamType].applyDeviceVolume_syncVSS(device,isAvrcpAbsVolSupported);}mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice,isAvrcpAbsVolSupported);}}}// Post a persist volume msgsendMsg(mAudioHandler,MSG_PERSIST_VOLUME,SENDMSG_QUEUE,device,0,streamState,PERSIST_DELAY);}

首先是经过applyDeviceVolume_syncVSS函数走到AudioSystem.cpp的setStreamVolumeInt函数(这个后面再继续分析)。然后发送了一个MSG_PERSIST_VOLUME的消息,通过persistVolume函数把音量值存储到setting数据库中。

native层音量调节的实现

我们上面分析到会走到AudioSystem::setStreamVolumeIndex函数,这个函数通过binder最终走到AudioPolicyManager::setStreamVolumeIndex函数中,然后调用AudioPolicyManager::setVolumeIndexForAttributes函数,在这个函数中Android10.0的代码中已经有了组的概念,我们按照正常的流程往下走,会走到AudioPolicyManagerCustom::checkAndSetVolume函数中,然后这个函数会根据audiopolicy中的audio_policy_volumes.xml文件中配置的声音曲线调用computeVolume计算出一个volumeDb值,然后通过AudioOutputDescriptor::setVolume函数去set音量。这个函数通过setCurVolume函数调用mVolumeActivities[vs].setVolume(volumeDb),这个mVolumeActivities就是当前在这个output中活动的track,所以我们跟到了AudioTrack::setVolume函数,这个函数会调用mProxy->setVolumeLR函数

    void        setVolumeLR(gain_minifloat_packed_t volumeLR) {mCblk->mVolumeLR = volumeLR;}

通过上面的代码我们知道就是把现在的增益保存在mCblk->mVolumeLR中,看到mCblk我们就应该能联想到这是与audioflinger通信的环形buffer,所以使用这个音量的地方肯定在AudioFlinger中,我们去AudioFlinger中去找发现是prepareTracks_l函数通过proxy->getVolumeLR拿到的这个增益。我们知道AudioFlinger的threadLoop函数会不断的循环的调用prepareTracks_l函数去准备音频流和混音流的数据,在这里把audiopolicy设置的音量以及track的音量和master音量做一个计算(一般是相乘),所以现在AudioFlinger拿到的pcm数据就已经包含了修改的增益,然后通过threadLoop_wrtie函数把修改了增益的pcm数据写到hal层,到这里整个setStreamVolume的流程就分析完成了。
例:app1:混音数据1 = 音频数据1 * master_volume * stream1_volume * AudioTrack1_volume
app2:混音数据2 = 音频数据2 * master_volume * stream2_volume * AudioTrack2_volume

然而在车机上会有主副屏后排屏的概念,这时候我们可以使用CarAudioManager的setGroupVolume去set音量。

setGroupVolume的实现

setGroupVolume会走到setCurrentGainIndex函数然后把音量值存储到setting数据库中,然后会走到AudioManager的setAudioPortGain函数中

    public static int setAudioPortGain(AudioPort port, AudioGainConfig gain) {if (port == null || gain == null) {return ERROR_BAD_VALUE;}AudioPortConfig activeConfig = port.activeConfig();AudioPortConfig config = new AudioPortConfig(port, activeConfig.samplingRate(),activeConfig.channelMask(), activeConfig.format(), gain);config.mConfigMask = AudioPortConfig.GAIN;return AudioSystem.setAudioPortConfig(config);}

这个函数会把增益等一些参数封装到AudioPortConfig中然后调用AudioSystem.setAudioPortConfig函数,经过一系列的调用会走到AudioPolicyManager::setAudioPortConfig函数,然后通过binder等一系列封装调用会走到AudioFlinger::setAudioPortConfig函数中,最终会走到hal层audio_hw的adev_set_audio_port_config函数中去,最后的实现在auto_hal.c的auto_hal_set_audio_port_config函数中,最终会调用到kernel的set_volume函数中去。这样看来这条通路设置的应该就是dsp的音量,因为并没有修改到AudioFlinger中pcm数据的增益,这个函数留到后面仔细分析。

Android调节音量分析相关推荐

  1. 核心 Android 调节音量的过程

    核心 Android 系统提供的调节音量的方法 核心 Android 系统提供了多种调节音量的方法,这些方法主要包括如下这些. 如在 Android Automotive 调节音量的过程 中我们看到的 ...

  2. android调节音量——AudioManager的应用

    Android中可以通过程序获取系统手机的铃声和音量.同样,也可以设置铃声和音量.Android中给出了AudioManager类来实现音量获取.音量控制. 本篇基于 Android API 中的 A ...

  3. android调节声音大小

    在做Android游戏的时候,游戏音乐的添加是必不可少的,我就自己的理解说说添加背景音乐的一些知识 网上好多关于背景音乐添加用到的类:MediaPlayer,SoundPool,AudioManage ...

  4. Android音频 —— 音量调节

    一.音量相关概念 1. 相关术语解释 track volume : 单个App设置音量时设置的是这个,它只影响本App的音量. stream volume :设置某一stream的音量,Android ...

  5. Android Audio音量设置原理流程分析

    Android Audio音量设置原理流程分析 简介 本篇文章主要介绍Android音量设置从App应用层到framework层执行流程,以及相关的细节和原理分析,建议在阅读此文章前去看博主的混音理论 ...

  6. Android音频——音量调节

    一.音量相关概念 1. 相关术语解释 track volume : 单个App设置音量时设置的是这个,它只影响本App的音量. stream volume :设置某一stream的音量,Android ...

  7. android 音量 广播,Android平台音量调节(一)音量键调节音量

    Android平台音量调节 本文基于Android 8.0讲述Android平台原生音量控制功能. 流的定义 Android中,音量都是分开控制,各种流定义各种流的音量.在Android8.0中,定义 ...

  8. Android系统音量调节策略学习总结

    二.外设类型 USB音箱底座 蓝牙音箱 3.5mm线控耳机 三.相关术语 track volume: 单个App设置音量时设置的是这个,它只影响本App的音量. stream volume: 设置某一 ...

  9. Android - 仿iPhone调节音量/亮度

    项目需要用到调节音量及亮度,效果类似iPhone.需求点击增加音量键后现实音量界面并增加下方小格子,用户不再点击调节音量后音量界面会在4s后消失. 整个功能用Service实现,在Service中创建 ...

最新文章

  1. 2018 Google kickstart Problem A. Planet Distance
  2. (转)Android笔记--handler机制
  3. PHP 安全email
  4. java编译器 Javac 编译原理
  5. Windows Internals 笔记——错误处理
  6. VSFTP服务--Linux学习笔记
  7. linux怎么切换不同版本的r,在linux中用同一个版本的R 同时安装 Seurat2 和 Seurat3
  8. 前端学习(2041)vue之电商管理系统电商系统之只是在发布阶段生效
  9. MyBatis-Plus_查询返回实体对象还是map?
  10. html列目录带图片,根据目录下的图片的个数,往html文件填充对应数量的img标签,请问有没有实现这种需求的工具?...
  11. centos8搭建glusterfs服务
  12. [转]很经典的http协议详解
  13. JavaScript:变量提升作用域
  14. 遐想ORACLE的下步收购
  15. java序列化,看这篇就够了
  16. c语言编写在线考试系统,c语言作业在线考试系统实现
  17. 江民科技董事长王江民因病在北京逝世 享年59岁
  18. Word2016中文字间距突然变大了是怎么回事?
  19. 身份证过期补办,派出所会打电话通知吗?
  20. ubuntu wifi bcm4322 安装驱动

热门文章

  1. 进程隐藏与进程保护(SSDT Hook 实现)(二) 转载自 Zachary.XiaoZhen - 梦想的天空
  2. Android拦截短信的实现,英雄联盟手游新消息,安卓率先测试,ROG游戏手机5将提前上手?...
  3. 陈怡暖:2015.4.29晚间最强现货黄金白银操作建议
  4. C/C++面试笔试详细总结—基本概念及其它问答题
  5. 实现多人聊天——简单群聊服务器的实现
  6. maven聚合项目项目间依赖时,出现错误的解决办法
  7. AC可靠性:双链路双机备份(AP指定配置方式)
  8. 梦幻鸿蒙市质检,《梦幻西游》手游第十七届武神坛开辟鸿蒙VS斜月三星_《梦幻西游》手游官网-人人都玩,无处不在...
  9. 公共计算机课程教学情况调查问卷,信息技术课程标准实施情况调查问卷.doc
  10. 数据结构课程设计(C语言实现)