Android音量设置流程干货版

1.     音量级数定义

在AudioService.java中定义了最大音量MAX_STREAM_VOLUME,手机的设置property可以覆盖它。

2.     音量初始化

initStreamVolume传入AudioPolicyManagerBase里的StreamDescriptor mStreams[AudioSystem::NUM_STREAM_TYPES];

3.     设置主音量

主音量怎么起作用?

最终音量=主音量*流音量

4.     设置流音量

setStreamVolumeIndex函数,在AudioPolicy中,通过volIndexToAmpl把Index整数转为float型的振幅比,也就是“振幅/参考振幅”。

具体做法是:通过输入的index查表找到对应的声压值db,然后通过下面的公式算出amplifier,这个值就是振幅比。

 

函数volIndexToAmpl中有一行代码

float amplification = exp( decibels * 0.115129f);

就是这个公式。

 

通过这个值乘以音源的振幅,就得到了调节后的音量。这也是数字增益调节的原理。

拿到这个值后,存入AudioFlinger的全局变量mStreamTypes,即:mStreamTypes[stream].volume =value。

在Thread试图播放声音时,在prepareTracks_l中是这么做的(AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTracks_l(
        Vector< sp<Track> > *tracksToRemove)):

 

[cpp] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
  1. // compute volume for this track  
  2. uint32_t vl, vr;       // in U8.24 integer format  
  3. float vlf, vrf, vaf;   // in [0.0, 1.0] float format  
  4. if (track->isPausing() || mStreamTypes[track->streamType()].mute) {  
  5.     vl = vr = 0;  
  6.     vlf = vrf = vaf = 0.;  
  7.     if (track->isPausing()) {  
  8.         track->setPaused();  
  9.     }  
  10. else {  
  11.   
  12.     // read original volumes with volume control  
  13.     float typeVolume = mStreamTypes[track->streamType()].volume;  
  14.     float v = masterVolume * typeVolume;  
  15.     AudioTrackServerProxy *proxy = track->mAudioTrackServerProxy;  
  16.     gain_minifloat_packed_t vlr = proxy->getVolumeLR();  
  17.     vlf = float_from_gain(gain_minifloat_unpack_left(vlr));  
  18.     vrf = float_from_gain(gain_minifloat_unpack_right(vlr));  
  19.     // track volumes come from shared memory, so can't be trusted and must be clamped  
  20.     if (vlf > GAIN_FLOAT_UNITY) {  
  21.         ALOGV("Track left volume out of range: %.3g", vlf);  
  22.         vlf = GAIN_FLOAT_UNITY;  
  23.     }  
  24.     if (vrf > GAIN_FLOAT_UNITY) {  
  25.         ALOGV("Track right volume out of range: %.3g", vrf);  
  26.         vrf = GAIN_FLOAT_UNITY;  
  27.     }  
  28.     // now apply the master volume and stream type volume  
  29.     vlf *= v;  
  30.     vrf *= v;  
  31.     // assuming master volume and stream type volume each go up to 1.0,  
  32.     // then derive vl and vr as U8.24 versions for the effect chain  
  33.     const float scaleto8_24 = MAX_GAIN_INT * MAX_GAIN_INT;  
  34.     vl = (uint32_t) (scaleto8_24 * vlf);  
  35.     vr = (uint32_t) (scaleto8_24 * vrf);  
  36.     // vl and vr are now in U8.24 format  
  37.     uint16_t sendLevel = proxy->getSendLevel_U4_12();  
  38.     // send level comes from shared memory and so may be corrupt  
  39.     if (sendLevel > MAX_GAIN_INT) {  
  40.         ALOGV("Track send level out of range: %04X", sendLevel);  
  41.         sendLevel = MAX_GAIN_INT;  
  42.     }  
  43.     // vaf is represented as [0.0, 1.0] float by rescaling sendLevel  
  44.     vaf = v * sendLevel * (1. / MAX_GAIN_INT);  
  45. }  
  46.   
  47. // Delegate volume control to effect in track effect chain if needed  
  48. if (chain != 0 && chain->setVolume_l(&vl, &vr)) {  
  49.     // Do not ramp volume if volume is controlled by effect  
  50.     param = AudioMixer::VOLUME;  
  51.     // Update remaining floating point volume levels  
  52.     vlf = (float)vl / (1 << 24);  
  53.     vrf = (float)vr / (1 << 24);  
  54.     track->mHasVolumeController = true;  
  55. else {  
  56.     // force no volume ramp when volume controller was just disabled or removed  
  57.     // from effect chain to avoid volume spike  
  58.     if (track->mHasVolumeController) {  
  59.         param = AudioMixer::VOLUME;  
  60.     }  
  61.     track->mHasVolumeController = false;  
  62. }  
  63.   
  64. // XXX: these things DON'T need to be done each time  
  65. mAudioMixer->setBufferProvider(name, track);  
  66. mAudioMixer->enable(name);  
  67.   
  68. mAudioMixer->setParameter(name, param, AudioMixer::VOLUME0, &vlf);  
  69. mAudioMixer->setParameter(name, param, AudioMixer::VOLUME1, &vrf);  
  70. mAudioMixer->setParameter(name, param, AudioMixer::AUXLEVEL, &vaf);  
  71. mAudioMixer->setParameter(  
  72.     name,  
  73.     AudioMixer::TRACK,  
  74.     AudioMixer::FORMAT, (void *)track->format());  
  75. mAudioMixer->setParameter(  
  76.     name,  
  77.     AudioMixer::TRACK,  
  78.     AudioMixer::CHANNEL_MASK, (void *)(uintptr_t)track->channelMask());  
  79. mAudioMixer->setParameter(  
  80.     name,  
  81.     AudioMixer::TRACK,  
  82.     AudioMixer::MIXER_CHANNEL_MASK, (void *)(uintptr_t)mChannelMask  

 

 

在系统静音时,只是很简单的设置下列参数为0:

vl = vr = 0;vlf = vrf = vaf = 0.

设置AudioMixer的参数

mAudioMixer->setParameter(name, param,AudioMixer::VOLUME0, &vlf);

mAudioMixer->setParameter(name, param,AudioMixer::VOLUME1, &vrf);

所以最后还是通过AudioMixer真正去乘以VOLUME0和VOLUME1来设置音量。

如track__16BitsStereo中

 

[cpp] view plain copy
 
 print?在CODE上查看代码片派生到我的代码片
    1. int32_t vl = t->prevVolume[0];  
    2.             int32_t vr = t->prevVolume[1];  
    3.             const int32_t vlInc =t->volumeInc[0];  
    4.            const int32_t vrInc =t->volumeInc[1];  
    5.             do {  
    6.                 *out++ += (vl >> 16) *(int32_t) *in++;  
    7.                 *out++ += (vr >> 16) *(int32_t) *in++;  
    8.                 vl += vlInc;  
    9.                 vr += vrInc;  
    10.             } while (--frameCount);  

posted on 2016-08-24 16:41  jamboo  阅读(2368)  评论(0编辑  收藏  举报

导航