Android音量控制曲线
来源:互联网 发布:2017年十月经济数据 编辑:程序博客网 时间:2024/05/22 08:00
首先,我们按音量调节键使得media音量逐级增加到最大。STREAM_MUSIC流的音量分为15级,通过AudioManger的handleKeyDown函数调用adjustSuggestedStreamVolume设置,一路找下去,发现在AudioService中adjustSuggestedStreamVolume然后调用adjustStreamVolume,通过消息MSG_SET_SYSTEM_VOLUME调用setSystemVolume,转到AudioSystem中的setStreamVolumeIndex,再通过jni层调用本地层的AudioSystem调用AudioPolicymanagerService,最后到AudiopolicyManagerBase的setStreamVolumeIndex,接下来的由checkAndSetVolume调用computeVolume,马上就要到真相大白的时候了。volIndexToAmpl函数时真正计算音量的地方,我们一起来分析这个函数
[mw_shl_code=java,true]float AudioPolicyManagerBase::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
int indexInUi)
{
device_category deviceCategory = getDeviceCategory(device);
const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory];
// the volume index in the UI is relative to the min and max volume indices for this stream type
int nbSteps = 1 + curve[VOLMAX].mIndex -
curve[VOLMIN].mIndex;//计算预置的曲线区间的范围,这里是(1-100)
ALOGI("VOLUME vol indexInUi=%d, nbSteps=%d, mIndexMin=%d, mIndexMax=%d",indexInUi,nbSteps,streamDesc.mIndexMin,streamDesc.mIndexMax);
int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) /
(streamDesc.mIndexMax - streamDesc.mIndexMin);//(由传进来的UIIndex计算百分比的index,比如现在是第一级 100*(1-0)/(15-0)=6)
// find what part of the curve this index volume belongs to, or if it's out of bounds
int segment = 0;
if (volIdx < curve[VOLMIN].mIndex) { // out of bounds
return 0.0f;
} else if (volIdx < curve[VOLKNEE1].mIndex) {
segment = 0;
} else if (volIdx < curve[VOLKNEE2].mIndex) {
segment = 1;
} else if (volIdx <= curve[VOLMAX].mIndex) {
segment = 2;
} else { // out of bounds
return 1.0f;
}
//第一极6是在区间VOLKNEE1之间,其区间表是在AudioPolicyManager初始化的时候就已经加载,因此它对应的segment为0
// linear interpolation in the attenuation table in dB
float decibels = curve[segment].mDBAttenuation +
((float)(volIdx - curve[segment].mIndex)) *
( (curve[segment+1].mDBAttenuation -
curve[segment].mDBAttenuation) /
((float)(curve[segment+1].mIndex -
curve[segment].mIndex)) );
//计算衰减分贝数 curve[0].db + 该区间每一级index对应的db*index数
float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 )
//由指数公式计算出音量amplification db = 20log(V/Vmax) linearToLog Vmax是一个参考值
ALOGI("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f",
curve[segment].mIndex, volIdx,
curve[segment+1].mIndex,
curve[segment].mDBAttenuation,
decibels,
curve[segment+1].mDBAttenuation,
amplification);
return amplification;
}[/mw_shl_code]
然后通过以上函数计算后得到一个0-1之间的float音量值,最后通过mpClientInterface->setStreamVolume设置到audioflinger中的mStreamTypes[stream].value,在prepareTracks_l中将音量值传入到audiomixer中混合。至此音量调节的全过程介绍完毕,下面六个附表是在AudioPolicyManagerBase中预置的六个音量曲线db分布表
音量刻度13366100输出衰减量db-49.5-33.5-17.00.0表1-1 default volume curve
音量刻度12060100输出衰减量db-58.0-40.0-17.00.0表1-2 default media volume curve
音量刻度12060100输出衰减量db-56.0-34.0-11.00.0表1-3 speaker media volume curve
音量刻度13366100输出衰减量db-29.7-20.1-10.20.0表1-4 speaker sonification volume curve
音量刻度13366100输出衰减量db-24.0-18.0-12.0-6.0表1-5 default system volume curve
音量刻度13366100输出衰减量db-30.0-26.0-22.0-18.0表1-6 headset system volume curve
总结:通过调节音量键这一调节音量的场景,从java层,media本地层,AudioFlinger服务层,硬件抽象层等四层分析音量调节函数是如何完成一个音量调节任务的。总结了从线性UI的Index如何转化为对数关系的人耳的听觉转换的公式,以及预置的区间表,根据不同的硬件,我们可以自己预置适当的区间表,使得音量曲线更符合我们的听感。
- Android音量控制曲线
- Android音量控制曲线
- android音量控制曲线和调用过程
- android音量控制曲线和调用过程
- android音量控制曲线和调用过程
- android音量的控制曲线的计算方法
- Android音量控制调节
- android 音量控制
- Android音量控制调节
- Android--AudioManager控制音量
- Android音量控制
- android软件音量控制
- Android 系统音量控制
- Android AudioManage控制音量
- Android音量控制调节
- android 音量控制setVolumeControlStream
- android音量控制AudioManager
- android音量控制setVolumeControlStream
- Linux下spi驱动开发
- 深入了解信号槽
- Android程序员必备精品资源
- 解析XML文件
- XSL:转换从哪里开始?
- Android音量控制曲线
- lazy evaluation缓式评估
- 一些应届IT求职常考的笔试题举例
- cocos2dx在模版中新建类后无法加载头文件问题
- nyoj71独木舟上的旅行
- 【android】获取屏幕分辨率
- iis发布asp网站出错的问题
- 编译自己的 Code::Blocks ! (一)准备工作
- java 多态