安卓音量管理

  • 1、Android音量的保存
  • 2、特殊音量
  • 3、音量的加载
  • 4、音量设置
    • 4.1、默认音量
    • 4.2、最大音量
  • 4、音量曲线

AudioService.java
AudioSystem.java

1、Android音量的保存

存放到数据库

AudioHandler.persistVolume

private void persistVolume(VolumeStreamState streamState, int device) {...System.putIntForUser(mContentResolver,streamState.getSettingNameForDevice(device),(streamState.getIndex(device) + 5)/ 10,UserHandle.USER_CURRENT);
...
}

VolumeStreamState .getSettingNameForDevice

public @Nullable String getSettingNameForDevice(int device) {...final String suffix = AudioSystem.getOutputDeviceName(device);
...return mVolumeIndexSettingName + "_" + suffix;
}

mVolumeIndexSettingName 为初始化多个stream type的实例时给定,每个stream type的name不一样(根据System.VOLUME_SETTINGS_INT数组中返回)

AudioService.createStreamStates

private void createStreamStates() {int numStreamTypes = AudioSystem.getNumStreamTypes();VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes];for (int i = 0; i < numStreamTypes; i++) {streams[i] = new VolumeStreamState(System.VOLUME_SETTINGS_INT[mStreamVolumeAlias[i]], i);}
}

System.java

数据库的字串为: mVolumeIndexSettingName (System.VOLUME_SETTINGS_INT字符数组) + AudioSystem.getOutputDeviceName设备名称 。
例如:
Music 类型的speaker音量存储的string为:volume_music_speaker
Music 类型的hdmi arc音量存储的string为:volume_music_hmdi_arc
音量存储在android数据库的system区,可通过命令获取

settings list system |grep music

2、特殊音量

固定音量的设备

音量为最大或者0
mFixedVolumeDevices// Devices for which the volume is fixed (volume is either max or muted)
Set<Integer> mFixedVolumeDevices = new HashSet<>(Arrays.asList(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET,AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,AudioSystem.DEVICE_OUT_HDMI_ARC,AudioSystem.DEVICE_OUT_AUX_LINE));

音量总是最大的设备

mFullVolumeDevices

3、音量的加载

每个type拥有一个VolumeStreamState实例

private void createStreamStates() {int numStreamTypes = AudioSystem.getNumStreamTypes();// 加载多条type的音量实例VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes];for (int i = 0; i < numStreamTypes; i++) {streams[i] = new VolumeStreamState(System.VOLUME_SETTINGS_INT[mStreamVolumeAlias[i]], i);}checkAllFixedVolumeDevices();checkAllAliasStreamVolumes();checkMuteAffectedStreams();updateDefaultVolumes();
}

创建实例时会将每一个type的各个device的音量加载到该实例的map mIndexMap中去

VolumeStreamState.readSettings

 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {// retrieve current volume for device// if no volume stored for current stream and device, use default volume if default// device, continue otherwiseint defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ?AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType] : -1;int index;if (!hasValidSettingsName()) {index = defaultIndex;} else {String name = getSettingNameForDevice(device);index = Settings.System.getIntForUser(mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT);}if (index == -1) {continue;}mIndexMap.put(device, getValidIndex(10 * index, true /*hasModifyAudioSettings*/));}

4、音量设置

单板目录 /product/build.prop (Android R)

4.1、默认音量

开机起来AUDIO_STREAM_MUSIC的默认音量prop设置为,见上图

ro.config.media_vol_default

不配置该prop的逻辑处理如下:

int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1);
if (defaultMusicVolume != -1 &&defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] &&defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume;
} else {if (isPlatformTelevision()) {AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4;} else {AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3;}
}

4.2、最大音量

AUDIO_STREAM_MUSIC的UI可设置的最大音量prop为,见上图

ro.config.media_vol_steps

例如:UI可设置最大音量为0-100

不配置该prop的逻辑处理如下:

int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1);
if (maxMusicVolume != -1) {MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume;
}

4、音量曲线

这里以AUDIO_STREAM_ACCESSIBILITY(10)类型的music在Speaker播放为例
hippoaudio是小编的sample可执行文件,-t后面的数字是type


则,使用的音量曲线为:通过/vendor/etc/audio_policy_volumes.xml查询可知,使用的为"DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE"数组,路径为/vendor/etc/default_volume_tables.xml



float VolumeCurve::volIndexToDb(int indexInUi, int volIndexMin, int volIndexMax) const
{ALOG_ASSERT(!mCurvePoints.isEmpty(), "Invalid volume curve");if (volIndexMin < 0 || volIndexMax < 0) {// In order to let AudioService initialize the min and max, convention is to use -1return NAN;}ALOGI("[%s:%d]index:%d, min:%d, max:%d, dev:%d", __func__, __LINE__, indexInUi, volIndexMin, volIndexMax, mDeviceCategory);if (indexInUi < volIndexMin) {// an index of 0 means mute request when volIndexMin > 0if (indexInUi == 0) {ALOGV("VOLUME forcing mute for index 0 with min index %d", volIndexMin);return VOLUME_MIN_DB;}ALOGV("VOLUME remapping index from %d to min index %d", indexInUi, volIndexMin);indexInUi = volIndexMin;} else if (indexInUi > volIndexMax) {ALOGV("VOLUME remapping index from %d to max index %d", indexInUi, volIndexMax);indexInUi = volIndexMax;}size_t nbCurvePoints = mCurvePoints.size();// the volume index in the UI is relative to the min and max volume indices for this streamint nbSteps = 1 + mCurvePoints[nbCurvePoints - 1].mIndex - mCurvePoints[0].mIndex;int volIdx = (nbSteps * (indexInUi - volIndexMin)) / (volIndexMax - volIndexMin);ALOGI("[%s:%d] point_size:%d, nbSteps:%d,volIdx:%d max:%d, min:%d", __func__, __LINE__, nbCurvePoints, nbSteps, volIdx, mCurvePoints[nbCurvePoints - 1].mIndex,mCurvePoints[0].mIndex);// Where would this volume index been inserted in the curve pointsize_t indexInUiPosition = mCurvePoints.orderOf(CurvePoint(volIdx, 0));ALOGI("[%s:%d]indexInUiPosition:%d", __func__, __LINE__,indexInUiPosition);if (indexInUiPosition >= nbCurvePoints) {//use last point of tablereturn mCurvePoints[nbCurvePoints - 1].mAttenuationInMb / 100.0f;}if (indexInUiPosition == 0) {if (indexInUiPosition != mCurvePoints[0].mIndex) {return VOLUME_MIN_DB; // out of bounds}return mCurvePoints[0].mAttenuationInMb / 100.0f;}// linear interpolation in the attenuation table in dBfloat decibels = (mCurvePoints[indexInUiPosition - 1].mAttenuationInMb / 100.0f) +((float)(volIdx - mCurvePoints[indexInUiPosition - 1].mIndex)) *( ((mCurvePoints[indexInUiPosition].mAttenuationInMb / 100.0f) -(mCurvePoints[indexInUiPosition - 1].mAttenuationInMb / 100.0f)) /((float)(mCurvePoints[indexInUiPosition].mIndex -mCurvePoints[indexInUiPosition - 1].mIndex)) );ALOGD("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f]",mCurvePoints[indexInUiPosition - 1].mIndex, volIdx,mCurvePoints[indexInUiPosition].mIndex,((float)mCurvePoints[indexInUiPosition - 1].mAttenuationInMb / 100.0f), decibels,((float)mCurvePoints[indexInUiPosition].mAttenuationInMb / 100.0f));return decibels;
}

【Android Audio】安卓音量管理相关推荐

  1. Android Audio开发——音频管理器(三)

    AudioManager,音频管理类.它主要提供了丰富的 API 让开发者对应用的音量和铃声模式进行控制以及访问.主要内容涉及到音频流.声音.蓝牙.扩音器.耳机等等. 一.API接口 1.接口列表 接 ...

  2. Android Audio实战——音量调节(十二)

    对于音量调节上一篇文章已经做了简单介绍,无论是软件调节还是硬件调节,最终实现都是调用到 AudioService.这一篇文章主要分析一下音量调节的相关代码. 一.APP调用 1.音量调节接口 App在 ...

  3. android音频系统(4):AudioService之音量管理

    前言:AudioService这个系统服务包含或者使用了几乎所有与音频有关的内容,AudioService是音频系统在java层的大本营: android音频系统,分为两个部分:数据流和策略: 数据流 ...

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

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

  5. android 声卡 音量控制,android audio 音量调节

    这次的分析是从setting设置开始,进入声音设置,然后进入音量设置! 先上传上来,后期进行整理吧 调用流程: -------------------------------------------- ...

  6. Android内存管理机制详解,【安卓知识普及贴】之关于安卓内存管理机制的一些介绍和阐述。...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 安卓系统其实不需要极度精简,只是一味的精简并不会给系统带来什么好处反而只有害处,因为许多系统应用跟设置里的选项有关联,删除掉就会在选择关联选项的时候FC, ...

  7. android 剪贴板管理器,安卓剪贴板管理(Clipper Plus)

    Clipper Plus是一个功能强大的Android剪贴板增强工具,它能有效地增强安卓系统中剪贴.复制等功能的应用.同时,它还可以让你保存剪贴内容并共享,再也不用担心丢失您剪贴板上的内容,能给我们提 ...

  8. 粘贴板管理 android,安卓剪贴板管理(Clipper Plus)

    安卓系统和window一样,只能记录一个复制片段,pc端有clipx等剪贴板增强软件,安卓手机端也是有的? Clipper Plus能够有效的增强Android系统中剪贴.复制这样的功能的应用.使用C ...

  9. android管理工具,AnyDroid(电脑安卓手机管理工具)V7.3.0.20200910 正式版

    AnyDroid(电脑安卓手机管理工具)是一款很优秀好用的安卓手机管理的辅助工具.如果你需要一款好用的安卓手机管理工具,不妨试试小编带来的这款AnyDroid软件,功能强大全面,使用后可以帮助用户更轻 ...

最新文章

  1. 世界最优秀的分布式文件系统架构演进之路
  2. 【设计模式】访问者模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )
  3. 本科是学计算机研究生学教育学,教育学研究生好考吗?
  4. 通俗讲解分布式锁,看完不懂算作者输
  5. hs300 quant
  6. 科大星云诗社动态20201121
  7. 在数字图像处理中特征点是什么
  8. jzoj4252-QYQ的图【dfs】
  9. DBA_Oracle Table Partition表分区概念汇总(概念)
  10. 新加入“扫码阅读”功能
  11. spring boot Redis集成—RedisTemplate
  12. 大学计算机需要论文吗,关于大学计算机论文范文.docx
  13. 实木地板被机器人弄成坑_实木地板的常规保养
  14. mysql中phpmyadmin安装教程_phpmyadmin安装方法
  15. 物联网通信技术最全科普!你一定要了解的NB-IoT
  16. android手机 不显示本地视频,各位大神们 android怎么获取手机本地视频啊?
  17. vm linux数据恢复,VMWARE虚拟机数据恢复
  18. 《密码编码学与网络安全》和《现代密码学》PDF
  19. 嵌入式开发培训靠谱吗,嵌入式开发培训怎么样?
  20. setTimeout expects a function as first argument but got undefined

热门文章

  1. ubuntu18本地镜像源_Ubuntu 18.04 搭建私有软件镜像源(支持 Ubuntu 和 CentOS)
  2. 大数据面试常见问题(三)——Hadoop部分
  3. 国家集训队论文分类整理
  4. 递归回溯生成和解决数独问题c/c++
  5. 获取svg元素的高度和宽度(或其他属性)
  6. vue移动端网页微信分享
  7. Ubuntu 安装 OpenFOAM + PETSc
  8. 华南联络易-管理培训老师的神助手
  9. 【云开发】全网最详细壁纸小程序教程+源码
  10. 5.12 按照多个条件进行组合排序 [原创Excel教程]