Android 音量控制

Android 7

Android音量控制 | DD'Notes

系统输出音量

总输出音量 = 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: 音效

rack volume : 单个App设置音量时设置的是这个,它只影响本App的音量。
stream volume :设置某一stream的音量,Android系统中支持10种stream。
stream volume alias:设置的是同一组stream的音量,比如使用某个音量调节滑动条设置的音量。比如设置媒体音,所有App的媒体音都受到影响(但是电话音,
闹钟音不受影响)。
master volume :设置它等于设置所有的stream volume和track volume。它可以写到声卡里面去,控制所有声音的音量。也可以不写到声卡里面去,而是作为一个乘数因子来影响所有的音量。

Android音量计算流程

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

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上设置的等级

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()函数获得,即音量曲线

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_VOLUME和MAX_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 ),即是韦伯定理的运用.

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分组

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
};

Android音频(9)——音量调节 - 走看看

参考:

[RK3288][Android6.0] Audio的音量设置流程小结_KrisFei的博客-CSDN博客

[RK3288][Android6.0] Audio的音量计算过程小结_KrisFei的博客-CSDN博客_android 音量计算

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学如逆水行舟,不进则退3038

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值