Previously in the Android 4.4 volume adjustment Process Analysis (a) there is a simple analysis of the volume control process, today I would like to continue to analyze the volume size calculation method. There is a fixed-size volume Volume_max for any playback file, and the volume adjustment in the AudioPolicyManagerBase.cpp file is understood to be multiplied by the factor κ (0≤κ≤1) on volume_max basis.
Now the Volindextoampl function in AudioPolicyManagerBase.cpp is analyzed in detail, and the function of Volindextoampl is defined as follows:
1 floatAudiopolicymanagerbase::volindextoampl (audio_devices_t device,Conststreamdescriptor&Streamdesc,2 intIndexinui)3 {4Device_categorydevicecategory=getdevicecategory (device);5 ConstVolumecurvepoint *Curve=Streamdesc.mvolumecurve[devicecategory];6 7 //The volume index in the UI are relative to the min and max volume indices for this stream type8 int nbsteps=1+ Curve[volmax].mindex-9 Curve[volmin].mindex;Ten int Volidx= (Nbsteps * (indexinui-streamdesc.mindexmin))/ One(Streamdesc.mindexmax-streamdesc.mindexmin); A - //Find what part of the curve This index volume belongs to, or if it's out of bounds - int segment=0; the 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) { ASegment =2; at}Else{//Out of bounds - return 1.0f; - } - - //linear interpolation in the attenuation table in DB - float decibels= Curve[segment].mdbattenuation + in((float) (Volidx-curve[segment].mindex)) * -((curve[segment+1].mdbattenuation- toCurve[segment].mdbattenuation)/ +((float) (curve[segment+1].mindex- - Curve[segment].mindex)) ); the * float Amplification= exp (Decibels *0.115129f);//exp (DB * LN (TEN)/+) $ Panax Notoginseng returnamplification; -}
Within the code, the main is to get the following 7 variable values:
1.devicecategory: There are three types of devices in the Android system, Device_category_headset,device_category_speaker & Device_ Category_earpiece. If you are currently using SPEAKER to play the audio stream, the devicecategory corresponds to Device_category_speaker;
2.curve: volume curve is determined by Audio_stream & Device_category , all matching types can be obtained in svolumeprofiles matrix , with Audio_stream = audio_stream_music & device_category = Device_category_speaker As an example, the corresponding volume curve is Sspeakermediavolumecurve;
Sspeakermediavolumecurve: (Numerical calculation with this volume curve as an example)
1 Const Audiopolicymanagerbase::volumecurvepoint 2 Audiopolicymanagerbase::sspeakermediavolumecurve[audiopolicymanagerbase::volcnt] = {3 {1,-59.1f}, {$,-48.3f}, {$,-24.4f}, { 0.0f}4 };
From the Sspeakermediavolumecurve array you can tell that the volume curve is divided into 4 parts by 4 points, 1~20, 20~60, 60~100, respectively. Each of these points has the meaning of the parameter:
class volumecurvepoint{public: int mindex; Percentile the subscript float mdbattenuation; attenuation };
3.nbsteps: In order to avoid repeating decimal in the calculation, the UI interface Volumeindex is converted to 0~100, Sspeakermediavolumecurve as an example Curve[volmax]. Mindex = 100,curve[volmin].mindex = 1, so nbsteps = 1 + 100-1 = 100;
4.Volidx: The solution of VOLIDX is actually the process of converting the volume index of the UI interface into a binary, where audiostream corresponding indexinui_ Max can be obtained in Audioservice.java, stream_music corresponds to a value of 15, so Streamdesc.mindexmax = 15,streamdesc.mindexmin = 0, then volidx = (20 /3) *indexinui.
//Audioservice.java/** @hide Maximum Volume index values for audio streams*/Private StaticFinalint[] Max_stream_volume =New int[] { 5,//Stream_voice_call 7,//Stream_system 7,//stream_ring the,//Stream_music 7,//Stream_alarm 7,//stream_notification the,//Stream_bluetooth_sco 7,//stream_system_enforced the,//STREAM_DTMF the //Stream_tts};
5.segment: is used to determine the UI volume interface in which the Volumeindex is converted into a range within which the binary is placed.
6.decibels: Volumeindex corresponds to the volume attenuation in db. Its calculation formula is as follows:
If you want to achieve the attenuation difference of speaker per scale to M (DB), it is calculated by calculating the difference between Decibels_index_n & Decibels_index_ (n+1). For ease of calculation, the default N & n+1 belong to the same segment, so
Because Curve[volmax].mdbattenuation is generally 0, that is, the state is not attenuated (and of course it may be negative, but curve[volmax].mdbattenuation is the most easily determined value anyway), So the general calculation is calculated from segment = 2, so that the value δdecibels within the 60~100 interval is:
Δdecibels = (20/3) * ((0-curve[2].mdbattenuation)/(100-60)) =-(CURVE[2].MDBATTENUATION/6)
Make δdecibels = M, then curve[2].mdbattenuation = -6m, and so on curve[1].mdbattenuation = -12m,curve[0].mdbattenuation = -15M.
7.Amplification: Zoom in/Zoom out multiple. The obtained decibels into the formula can be directly obtained, there is nothing special to say.
Summary: This article takes Sspeakermediavolumecurve as an example, describes the calculation process of the volume attenuation value. Other volume curve adjustments can be implemented in the same way.