Android音量控制

背景

  • Platform: RK3399
  • OS: Android7.1.2
  • Kernel: v4.4.103

系统输出音量

总输出音量 = Android系统软件音量 * 音频Codec硬件音量
音频Codec硬件音量 = 音频Codec-DAC音量(数字音量) * 音频Codec-通道音量(AP模拟音量)
Android系统音量(数字音量) = stream Volume master Volume track Volume
注:
stream 音量: 系统控制音量等级,系统针对不同的stream type和不同输出device,有不同的音量level,韦伯定律(可展开,心理,情侣买礼物,金融等,)
Track volume: 通过AudioTrack.setVolume来设置,取值为0~1.0
master Volume: 音效

Android音量计算流程

注:这里所说的音量是上面所说的stream Volume流音量
整个流程即是数字音量增益调节的流程,纯数字实现,与底层音频codec无关.
整个流程大致分为以下2大步

1
2
3
4
5
6
7
AudioPolicyManager::checkAndSetVolume -> frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
  AudioPolicyManager::computeVolume ->
    mEngine->volIndexToDb ->
       Gains::volIndexToDb -> frameworks/av/services/audiopolicy/common/managerdefinitions/src/Gains.cpp
  outputDesc->setVolume ->
    SwAudioOutputDescriptor::setVolume -> frameworks/av/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
      Volume::DbToAmpl -> frameworks/av/services/audiopolicy/common/include/Volume.h

index -> db:

frameworks/av/services/audiopolicy/common/managerdefinitions/src/Gains.cpp
volIndexToDb():index转换成db,主要是依据音量曲线.
index为UI上设置的等级

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
float Gains::volIndexToDb(const VolumeCurvePoint *curve, int indexMin, int indexMax, int indexInUi)
{
///curve为对应流类型的音量曲线,见下面的说明1
///indexMin,indexMax为UI音量等级的最小值和最大值,见下面的说明2

// the volume index in the UI is relative to the min and max volume indices for this stream type
int nbSteps = 1 + curve[Volume::VOLMAX].mIndex - curve[Volume::VOLMIN].mIndex;

int volIdx = (nbSteps * (indexInUi - indexMin)) / (indexMax - indexMin);

// find what part of the curve this index volume belongs to, or if it's out of bounds
int segment = 0;
if (volIdx < curve[Volume::VOLMIN].mIndex) { // out of bounds
return VOLUME_MIN_DB;
} else if (volIdx < curve[Volume::VOLKNEE1].mIndex) {
segment = 0;
} else if (volIdx < curve[Volume::VOLKNEE2].mIndex) {
segment = 1;
} else if (volIdx <= curve[Volume::VOLMAX].mIndex) {
segment = 2;
} else { // out of bounds
return 0.0f;
}

// 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)) );

return decibels;
}

说明1:curve的由来
getVolumeCurvePoint()函数获得,即音量曲线

1
2
3
4
5
getVolumeCurvePoint()  frameworks/av/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp
-> mVolumeCurve
-> sVolumeProfiles
->sSpeakerMediaVolumeCurve //对应响应的流类型
{1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f}

说明2:UI音量等级的最小值和最大值
streamDesc.getVolumeIndexMin()streamDesc.getVolumeIndexMax()获得.
而默认最小值和最大值由MIN_STREAM_VOLUMEMAX_STREAM_VOLUME确定,所在文件为(frameworks/base/services/core/java/com/android/server/audio/AudioService.java),所以修改这里的MAX_STREAM_VOLUME可以修改对应的音量等级
调整默认音量:
frameworks/base/media/java/android/media/AudioSystem.java -> DEFAULT_STREAM_VOLUME

db -> ampl:

DbToAmpl():db转换成振幅,转换公式为exp( dB * ln(10) / 20 ),即是韦伯定理的运用.

1
2
3
4
5
6
7
static inline float DbToAmpl(float decibels)
{
if (decibels <= VOLUME_MIN_DB) {
return 0.0f;
}
return exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 )
}

扩展

音量统一:
frameworks/base/services/core/java/com/android/server/audio/AudioService.java
修改STREAM_VOLUME_ALIAS_DEFAULT数组改成跟STREAM_VOLUME_ALIAS_TELEVISION数组内容一样,所有音量条都属于music分组

1
2
3
4
5
6
7
8
9
10
11
12
private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] {
AudioSystem.STREAM_MUSIC, // STREAM_VOICE_CALL
AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM
AudioSystem.STREAM_MUSIC, // STREAM_RING
AudioSystem.STREAM_MUSIC, // STREAM_MUSIC
AudioSystem.STREAM_MUSIC, // STREAM_ALARM
AudioSystem.STREAM_MUSIC, // STREAM_NOTIFICATION
AudioSystem.STREAM_MUSIC, // STREAM_BLUETOOTH_SCO
AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM_ENFORCED
AudioSystem.STREAM_MUSIC, // STREAM_DTMF
AudioSystem.STREAM_MUSIC // STREAM_TTS
};

参考

  1. https://blog.csdn.net/kris_fei/article/details/72957142
  2. Audio的音量设置流程小结
Donate comment here