android 通话音量,(没有最终结论)Android 为何无法将通话音量调到最低

捋一捋代码流程:

上层流程之前有分析过,可以参考这个:

https://blog.csdn.net/bberdong/article/details/51792319(抱歉,那时候写的太随意)

咱们就从AudioPolicyManager::checkAndSetVolume说起:

status_t AudioPolicyManager::checkAndSetVolume(

audio_stream_type_t stream,

int index,

const sp& outputDesc,

audio_devices_t device,

int delayMs,

bool force)

{

...

if (stream == AUDIO_STREAM_VOICE_CALL ||

stream == AUDIO_STREAM_BLUETOOTH_SCO) {

float voiceVolume;

// Force voice volume to max for bluetooth SCO as volume is managed by the headset

if (stream == AUDIO_STREAM_VOICE_CALL) {

voiceVolume = (float)index/(float)mVolumeCurves->getVolumeIndexMax(stream);

} else {

voiceVolume = 1.0;

}

if (voiceVolume != mLastVoiceVolume) {

mpClientInterface->setVoiceVolume(voiceVolume, delayMs);

mLastVoiceVolume = voiceVolume;

}

}

...

}

一般通话音量按照index/最大index来算,getVolumeIndexMax来自哪里?

//AudioService.java

public class VolumeStreamState {

private VolumeStreamState(String settingName, int streamType) {

mIndexMin = MIN_STREAM_VOLUME[streamType] * 10;

mIndexMax = MAX_STREAM_VOLUME[streamType] * 10;

AudioSystem.initStreamVolume(streamType, mIndexMin / 10, mIndexMax / 10);

}

}

MAX_STREAM_VOLUME[STREAM_VOICE_CALL]按照100来算好了。

mIndexMax等于1000.则这次调用相当于

AudioSystem.initStreamVolume(0,0,100)

一路略过,就来到了:

void AudioPolicyManager::initStreamVolume(audio_stream_type_t stream,

int indexMin,

int indexMax)

{

...

mVolumeCurves->initStreamVolume(stream, indexMin, indexMax);

...

}

回到前面

AUDIO_STREAM_VOICE_CALL则voiceVolume = index/100

AUDIO_STREAM_BLUETOOTH_SCO则voiceVolume = 1.0.

那看上去这个voiceVolume就是一个系数。

我们接着追踪setVoiceVolume的调用,一路略过,来到了

//audio_hw.c

static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)

{

int ret;

struct audio_device *adev = (struct audio_device *)dev;

pthread_mutex_lock(&adev->lock);

/* cache volume */

ret = voice_set_volume(adev, volume);

pthread_mutex_unlock(&adev->lock);

return ret;

}

voice_set_volume的实现在这里(原谅我是搜索出来的,结果推原因)

//voice.c

int voice_set_volume(struct audio_device *adev, float volume)

{

//我们在探讨音量无法调到最小,所以这里volume姑且算0

int vol, err = 0;

adev->voice.volume = volume;

if (adev->mode == AUDIO_MODE_IN_CALL) {

if (volume < 0.0) {

volume = 0.0;

} else if (volume > 1.0) {

volume = 1.0;

}

vol = lrint(volume * 100.0);

// Voice volume levels from android are mapped to driver volume levels as follows.

// 0 -> 5, 20 -> 4, 40 ->3, 60 -> 2, 80 -> 1, 100 -> 0

// So adjust the volume to get the correct volume index in driver

vol = 100 - vol;

err = platform_set_voice_volume(adev->platform, vol);

}

//这个应该是voip通话?好像微信语音就走这个

if (adev->mode == AUDIO_MODE_IN_COMMUNICATION)

err = voice_extn_compress_voip_set_volume(adev, volume);

return err;

}

到这里调用变成:

platform_set_voice_volume(adev->platform,100);

接着看代码:

int platform_set_voice_volume(void *platform, int volume)

{

struct platform_data *my_data = (struct platform_data *)platform;

struct audio_device *adev = my_data->adev;

struct mixer_ctl *ctl;

const char *mixer_ctl_name = "Voice Rx Gain";

int vol_index = 0, ret = 0;

uint32_t set_values[ ] = {0,

ALL_SESSION_VSID,

DEFAULT_VOLUME_RAMP_DURATION_MS};

// Voice volume levels are mapped to adsp volume levels as follows.

// 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1 0 -> 0

// But this values don't changed in kernel. So, below change is need.

//percent_to_index返回结果范围,从0到5

vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, MAX_VOL_INDEX);

set_values[0] = vol_index;

ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);

if (!ctl) {

ALOGE("%s: Could not get ctl for mixer cmd - %s",

__func__, mixer_ctl_name);

return -EINVAL;

}

ALOGV("Setting voice volume index: %d", set_values[0]);

mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));

if (my_data->csd != NULL) {

ret = my_data->csd->volume(ALL_SESSION_VSID, volume,

DEFAULT_VOLUME_RAMP_DURATION_MS);

if (ret < 0) {

ALOGE("%s: csd_volume error %d", __func__, ret);

}

}

return ret;

}

vol_index的变化范围从0-5.(0是最大值...),接下来调用的就是tinymix的接口了。再往下,恐怕。。。

只能说kernel层,adsp决定了,通话声音无法调到最小。。。至于为什么这么做,还是没有答案啊!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值