日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android调节音量分析

發布時間:2024/1/18 Android 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android调节音量分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

音量調節接口

我們知道Android Audio的音量調節接口是通過AudioManager的setStreamVolume實現的,這個函數的實現在AudioService的setStreamVolume函數中,然后會調用到setStreamVolumeInt,這個函數首先通過streamState.setIndex發送音量調節的廣播通知app更新UI。然后通過消息機制走到setDeviceVolume函數。注:如果要實現硬調音,也就是調節dsp音量不調節安卓音量,可以把config_useFixedVolume這個參數置為true。
我們簡單分析一下setDeviceVolume函數

/*package*/ void setDeviceVolume(VolumeStreamState streamState, int device) {final boolean isAvrcpAbsVolSupported = mDeviceBroker.isAvrcpAbsoluteVolumeSupported();synchronized (VolumeStreamState.class) {// Apply volumestreamState.applyDeviceVolume_syncVSS(device, isAvrcpAbsVolSupported);// Apply change to all streams using this one as aliasint numStreamTypes = AudioSystem.getNumStreamTypes();for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {if (streamType != streamState.mStreamType &&mStreamVolumeAlias[streamType] == streamState.mStreamType) {// Make sure volume is also maxed out on A2DP device for aliased stream// that may have a different device selectedint streamDevice = getDeviceForStream(streamType);if ((device != streamDevice) && isAvrcpAbsVolSupported&& ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0)) {mStreamStates[streamType].applyDeviceVolume_syncVSS(device,isAvrcpAbsVolSupported);}mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice,isAvrcpAbsVolSupported);}}}// Post a persist volume msgsendMsg(mAudioHandler,MSG_PERSIST_VOLUME,SENDMSG_QUEUE,device,0,streamState,PERSIST_DELAY);}

首先是經過applyDeviceVolume_syncVSS函數走到AudioSystem.cpp的setStreamVolumeInt函數(這個后面再繼續分析)。然后發送了一個MSG_PERSIST_VOLUME的消息,通過persistVolume函數把音量值存儲到setting數據庫中。

native層音量調節的實現

我們上面分析到會走到AudioSystem::setStreamVolumeIndex函數,這個函數通過binder最終走到AudioPolicyManager::setStreamVolumeIndex函數中,然后調用AudioPolicyManager::setVolumeIndexForAttributes函數,在這個函數中Android10.0的代碼中已經有了組的概念,我們按照正常的流程往下走,會走到AudioPolicyManagerCustom::checkAndSetVolume函數中,然后這個函數會根據audiopolicy中的audio_policy_volumes.xml文件中配置的聲音曲線調用computeVolume計算出一個volumeDb值,然后通過AudioOutputDescriptor::setVolume函數去set音量。這個函數通過setCurVolume函數調用mVolumeActivities[vs].setVolume(volumeDb),這個mVolumeActivities就是當前在這個output中活動的track,所以我們跟到了AudioTrack::setVolume函數,這個函數會調用mProxy->setVolumeLR函數

void setVolumeLR(gain_minifloat_packed_t volumeLR) {mCblk->mVolumeLR = volumeLR;}

通過上面的代碼我們知道就是把現在的增益保存在mCblk->mVolumeLR中,看到mCblk我們就應該能聯想到這是與audioflinger通信的環形buffer,所以使用這個音量的地方肯定在AudioFlinger中,我們去AudioFlinger中去找發現是prepareTracks_l函數通過proxy->getVolumeLR拿到的這個增益。我們知道AudioFlinger的threadLoop函數會不斷的循環的調用prepareTracks_l函數去準備音頻流和混音流的數據,在這里把audiopolicy設置的音量以及track的音量和master音量做一個計算(一般是相乘),所以現在AudioFlinger拿到的pcm數據就已經包含了修改的增益,然后通過threadLoop_wrtie函數把修改了增益的pcm數據寫到hal層,到這里整個setStreamVolume的流程就分析完成了。
例:app1:混音數據1 = 音頻數據1 * master_volume * stream1_volume * AudioTrack1_volume
app2:混音數據2 = 音頻數據2 * master_volume * stream2_volume * AudioTrack2_volume

然而在車機上會有主副屏后排屏的概念,這時候我們可以使用CarAudioManager的setGroupVolume去set音量。

setGroupVolume的實現

setGroupVolume會走到setCurrentGainIndex函數然后把音量值存儲到setting數據庫中,然后會走到AudioManager的setAudioPortGain函數中

public static int setAudioPortGain(AudioPort port, AudioGainConfig gain) {if (port == null || gain == null) {return ERROR_BAD_VALUE;}AudioPortConfig activeConfig = port.activeConfig();AudioPortConfig config = new AudioPortConfig(port, activeConfig.samplingRate(),activeConfig.channelMask(), activeConfig.format(), gain);config.mConfigMask = AudioPortConfig.GAIN;return AudioSystem.setAudioPortConfig(config);}

這個函數會把增益等一些參數封裝到AudioPortConfig中然后調用AudioSystem.setAudioPortConfig函數,經過一系列的調用會走到AudioPolicyManager::setAudioPortConfig函數,然后通過binder等一系列封裝調用會走到AudioFlinger::setAudioPortConfig函數中,最終會走到hal層audio_hw的adev_set_audio_port_config函數中去,最后的實現在auto_hal.c的auto_hal_set_audio_port_config函數中,最終會調用到kernel的set_volume函數中去。這樣看來這條通路設置的應該就是dsp的音量,因為并沒有修改到AudioFlinger中pcm數據的增益,這個函數留到后面仔細分析。

總結

以上是生活随笔為你收集整理的Android调节音量分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。