Android audio system linear volume and logarithm volume conversion

Source: Internet
Author: User
Tags natural log

In the android audio system code, after the application adjusts the volume of each audio stream, it will eventually be converted to a factor K. Before all the audio data is output to the hardware, multiplied by the coefficient K. As long as the application sends a call to adjust the volume, the audio system in the middle layer recalculates the coefficient K value. For applications, the volume control is usually adjusted linearly. For example, for an audio stream with a 15-level volume, we expect that the volume changes at each level are equivalent, that is: from 5th to 6th, and from 7th to 8th, we expect people to feel the same volume change. However, in the android code, we see the formula for calculating the coefficient K, which is quite strange. The code is located in frameworks/base/Media/libmedia/audiosystem. cpp:

/*************************************** **************************************** **********************/
Statement: the content of this blog is created at http://blog.csdn.net/droidphone. please refer to it for help. Thank you!
/*************************************** **************************************** **********************/

// convert volume steps to natural log scale// change this value to change volume scalingstatic const float dBPerStep = 0.50f;// shouldn't need to touch thesestatic const float dBConvert = -dBPerStep * 2.302585093f / 20.0f;static const float dBConvertInverse = 1.0f / dBConvert;float AudioSystem::linearToLog(int volume){    // float v = volume ? exp(float(100 - volume) * dBConvert) : 0;    // LOGD("linearToLog(%d)=%f", volume, v);    // return v;    return volume ? exp(float(100 - volume) * dBConvert) : 0;}int AudioSystem::logToLinear(float volume){    // int v = volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0;    // LOGD("logTolinear(%d)=%f", v, volume);    // return v;    return volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0;}


To understand the formulas in the above Code, we must first understand the acoustic psychology model of human ears. According to the research of human voice psychology, the perception of human voice size is not linear, but in a logarithm relationship. In the log format, the unit is dB. In the audio field, we usually define a standard level v0, so the conversion formula of Level X is:

DB = 20log (x/V0 );

For example, when we output the maximum volume at full capacity to the speaker, the level is 1 V. If there is a 15-level volume, volume of a cylinder if it is adjusted linearly, 1/15 = 66. 6mV, we can see that the volume adjustment for each level is:

66. 6mV, 133. 2mV, 200mV, ......, 866. 8mV, 933. 4mV, 1000mV;

If the step is adjusted, the volume changes that the ears feel are not continuous.

Another method is to adjust by logarithm. In the digital audio field, 0 dB usually represents the maximum volume. 0 dB means that no data transformation is performed, and the output is equal to the input, therefore, 20log (v0/V0) = 20log (1) = 0db. This means that the DB value below the maximum volume is a negative number. Now we think 1 V is 0 dB, and the lowest volume is-28 dB. The DB value corresponding to the 15-level volume is:


-28db,-26db,-24db, ......,-4db,-2db, 0db;volume of a sphere

The corresponding level value is (using the formula vx = 10 ^ (dB/20) * V0 ):


39mV, 50mV, 63mV,..., 630mV, 794mV, 1000mV;


Linear volume and logarithm volume adjustment Curve

Back to the android code, it also uses the logarithm adjustment method, which first defines the step value for each adjustment of the volume to 0.5db:

Static const float dbperstep = 0.50f;

Then he defines an intermediate constant for calculation:volume of a rectangular prism


Static const float dbconvert =-dbperstep * 2.302585093f/20366f;volume of a cone

This was a bit difficult to understand at the beginning, especially the strange coefficient: 2.302585093. All these definitions are used to obtain the coefficient K used to multiply the audio data. There are multiple audio streams in Android. The default volume adjustment steps for each audio stream are different. Some are 7 steps and some are 5 steps, some are 15 steps. In order to facilitate the unification of computing, the corresponding steps are first mapped to 0-steps before calculation. Because the step size has been defined as dB, the number of DBS corresponding to the volume levels is as follows:


Volume level 0 1 2 3 ...... 97 98 99 100
DB count Mute -49.5db -49db -48.5db ...... -1.5db 1.0db 0.5db 0db


Obviously, the corresponding dB value will also be known after we know which step the volume is, so what we need to do is to convert the DB value to the coefficient K value, the K value is actually the ratio of X/V0 in the formula DB = 20log (x/V0). According to this formula, the volume level is the K value corresponding to volume:

(1) dB =-dbperstep * (100-volume );

Because:

(2) dB/20 = Log (vx/V0) = Log (k );

Replace (1) with (2:volume formula

(3)-dbperstep * (100-volume)/20 = Log (k );

To obtain K, the two sides take the index at the bottom of 10:

(4) 10 ^ (-dbperstep * (100-volume)/20) = 10 ^ (log (k ));

(5) k = 10 ^ (log (k) = 10 ^ (-dbperstep * (100-volume)/20 );

(6) k = 10 ^ (dbconvert * (100-volume); // order: dbconvert =-dbperstep/20;how to find volume

The coefficient K can be obtained using formula (6), and the base-10 power needs to be calculated. However, this is different from the calculation formula used by Android. The andrioid formula is as follows:

(7) exp (float (100-volume) * dbconvert );

This is because it does not use the power operation with the base 10, but uses the power operation with the base of the natural constant E, because:

(8) ln (10) = 2.302585093;

After we redefine dbconvert as-dbperstep * 2.302585093/20, formula 6 and Formula 7 are actually completely equivalent. That is to say:

(9) e ^ 2.302585093 = e ^ Ln (10) = 10;

Now I know the history of the strange number 2.302585093 !! From the comments of the code, we can know that the minimum volume of the system can be determined by changing the dbperstep size:

Minimum volume =-99 * dbperstep;-49.5db by default; k value: 0.00334965439;

As for the maximum Software Digital Volume, It is 0 dB and cannot be changed. to change it, modify the hardware volume of the underlying audio driver !!





Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.