失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > android audio 音量调节

android audio 音量调节

时间:2023-01-23 21:59:35

相关推荐

android audio 音量调节

这次的分析是从setting设置开始,进入声音设置,然后进入音量设置!

先上传上来,后期进行整理吧

调用流程:

--------------------------------------------------------------------------------------------------------

Setting应用

... ...

RingerVolumePreference(DialogPreference).onClick()

→RingerVolumePreference(DialogPreference).showDialog(Bundle)

→RingerVolumePreference.onBindDialogView(View)

→RingerVolumePreference.updateSlidersAndMutedStates()

→mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);

→mAudioManager.getStreamVolume(streamType);

|

-------------------------|------------------------------------------------------------------------------

| AudioManager

getStreamVolume

|→IAudioService service = getService();

|→service.getStreamVolume(streamType);

|

---------------------------|-----------------------------------------------------------------------------

| AudioService.java AudioService(JAVA层)

getStreamVolume

ensureValidStreamType(streamType);

(mStreamStates[streamType].mLastAudibleIndex + 5) / 10;

|

VolumeStreamState

|①从setting provider中读取上次保存的音量值

|→mLastAudibleIndex = Settings.System.getInt(cr,

| mLastAudibleVolumeIndexSettingName,

| (mIndex > 0) ? mIndex : AudioManager.DEFAULT_STREAM_VOLUME[streamType]);

|②初始化native层的音量值

|→AudioSystem.initStreamVolume(streamType, 0, mIndexMax);

|③设置native层的音量值

|→setStreamVolumeIndex(streamType, mIndex);

|

AudioSystem.setStreamVolumeIndex(stream, (index + 5)/10);

initStreamVolume setStreamVolumeIndex

| |

------------------JNI----------------------------------------------------JNI-------------------------------

| | JNI层

android_media_AudioSystem_initStreamVolume android_media_AudioSystem_setStreamVolumeIndex

| |

|check_AudioSystem_Command |

| |

-------------------|---------------------------------------------------------------------------------------

| | AudioPolicyService客户端

| |

AudioSystem::initStreamVolume AudioSystem::setStreamVolumeIndex

| |

| aps = AudioSystem::get_audio_policy_service(); |

| |

aps->initStreamVolume(stream, indexMin, indexMax); aps->setStreamVolumeIndex(stream, index);

| |

remote()->transact(INIT_STREAM_VOLUME, data, &reply); remote()->transact(SET_STREAM_VOLUME, data, &reply);

| |

-------------------|-------------------binder通信-------------------------|---------------------------------

| | AudioPolicyService服务端

| |

AudioPolicyService::initStreamVolume AudioPolicyService::setStreamVolumeIndex

| |

mpAudioPolicy->init_stream_volummpAudioPolicy->set_stream_volume_index

| |

-------------------|------------------------------------------------------|------------------------------------------

| | Audio policy HAL 硬件抽象层

|

ap_set_stream_volume_index

|

lap->apm->setStreamVolumeIndex((AudioSystem::stream_type)stream,index);

|

AudioPolicyManagerBase::setStreamVolumeIndex

|

checkAndSetVolume(stream, index, mOutputs.keyAt(i), mOutputs.valueAt(i)->device());

|

AudioPolicyManagerBase::checkAndSetVolume

|

mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);

|

AudioPolicyCompatClient::setStreamVolume

|

mServiceOps->set_stream_volume(mService, (audio_stream_type_t)stream,volume, output, delayMs);

|

aps_set_stream_volume AudioPolicyService.cpp

|

audioPolicyService->setStreamVolume(stream, volume, output,delay_ms);

|

mAudioCommandThread->volumeCommand((int)stream, volume,(int)output, delayMs);

|

AudioPolicyService::AudioCommandThread::volumeCommand

|

insertCommand_l(command, delayMs);

至此,我们需要去分析执行command的后台线程,会如何执行这些命令的。

----------------------------------------AudioPolicyService::AudioCommandThread::threadLoop-----------------------------------------------------

bool AudioPolicyService::AudioCommandThread::threadLoop()

{

nsecs_t waitTime = INT64_MAX;

mLock.lock();

while (!exitPending())

{

while(!mAudioCommands.isEmpty()) {

... ...

switch (command->mCommand) {

... ...

case SET_VOLUME: {

VolumeData *data = (VolumeData *)command->mParam;

LOGV("AudioCommandThread() processing set volume stream %d, \

volume %f, output %d", data->mStream, data->mVolume, data->mIO);

command->mStatus = AudioSystem::setStreamVolume(data->mStream,

| data->mVolume,

| data->mIO);

if (command->mWaitStatus) {|

command->mCond.signal();|

mWaitWorkCV.wait(mLock);|

}|

delete data;|

}break;|

... ...|

}|

|

AudioSystem::setStreamVolume

|

|

|→const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();

|→af->setStreamVolume(stream, value, output);

|

|

------------------------------------------------------------|--------------------------------------------------------------------

|AudioFlinger

AudioFlinger::setStreamVolume

|

thread->setStreamVolume(stream, value);

|

AudioFlinger::PlaybackThread::setStreamVolume

|

mStreamTypes[stream].volume = value; 至此音量设置完毕

接下来分析下上面遗留的Init相关的流程:

AudioPolicyService::initStreamVolume

|

----------------------现在有必要搞清楚mpAudioPolicy到底是怎么来的----------------------------------------------------

AudioPolicyService是Android音频系统的两大服务之一,另一个服务是AudioFlinger,这两大服务都在系统启动时由MediaSever加载,

加载的代码位于:frameworks/base/media/mediaserver/main_mediaserver.cpp。AudioFlinger主要负责管理音频数据处理以及和硬件

抽象层相关的工作。下面研究下AudioPolicyService。

AudioPolicyService主要完成以下任务:

JAVA应用层通过JNI,经由IAudioPolicyService接口,访问AudioPolicyService提供的服务

输入输出设备的连接状态

系统的音频策略(strategy)的切换

音量/音频参数的设置

AudioPolicyService有一个内部线程类AudioCommandThread,顾名思义,所有的命令(音量控制,输入、输出的切换等)最终都会在该线程中排队执行;

AudioPolicyService的很大一部分管理工作都是在AudioPolicyManager中完成的。包括音量管理,音频策略(strategy)管理,输入输出设备管理。

我们现在比较关心的是音量的控制,所以我们还是到AudioCommandThread线程中了解一下。

AudioCommandThread线程是在AudioPolicyService的构造函数中创建的。

AudioPolicyService::AudioPolicyService()

→mAudioCommandThread = new AudioCommandThread(String8("ApmCommandThread"));

AudioCommandThread线程的主要工作是在bool AudioPolicyService::AudioCommandThread::threadLoop()中完成的。

threadLoop中主要处理音频设置相关的命令:

▲START_TONE/STOP_TONE:播放电话系统中常用的特殊音调,例如:TONE_DTMF_0,TONE_SUP_BUSY等等。

▲SET_VOLUME:最终会调用AudioFlinger进行音量设置

▲SET_PARAMETERS:最终会调用AudioFlinger进行电话音量设置

▲SET_VOICE_VOLUME:通过一个KeyValuePairs形式的字符串进行参数设置

我们比较关心"音量设置"相关,所以只关注SET_VOLUME.

case SET_VOLUME: {

VolumeData *data = (VolumeData *)command->mParam;

command->mStatus = AudioSystem::setStreamVolume(data->mStream,data->mVolume,data->mIO);

---------------------------------------------------------------------------------------------------------------------------------------------

下面研究一下AudioPolicyManager:

AudioPolicyManager是在AudioPolicyService的构造函数中创建的。

AudioPolicyService::AudioPolicyService

|→hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);

|(获得AudioPolicyHardwareModule,根据模块ID找到硬件模块动态链接库的地址,然后调用load去打开动态链接库并从中获取硬件模块结构体地址。)

|struct legacy_ap_module HAL_MODULE_INFO_SYM = {

|module: {

| common: {

| tag: HARDWARE_MODULE_TAG,

| version_major: 1,

| version_minor: 0,

| id: AUDIO_POLICY_HARDWARE_MODULE_ID, //ID

| name: "LEGACY Audio Policy HAL",

| author: "The Android Open Source Project",

| methods: &legacy_ap_module_methods,

| dso : NULL,

| reserved : {0},

| },

|},

|};

|

|→audio_policy_dev_open(module, &mpAudioPolicyDev); //打开 audio policy device

|→mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,&mpAudioPolicy);

||static int legacy_ap_dev_open(const hw_module_t* module, const char* name,

| | hw_device_t** device)

||{

||struct legacy_ap_device *dev;

||

||if (strcmp(name, AUDIO_POLICY_INTERFACE) != 0)

| | return -EINVAL;

||

||dev = (struct legacy_ap_device *)calloc(1, sizeof(*dev));

||if (!dev)

| | return -ENOMEM;

||

||dev->mon.tag = HARDWARE_DEVICE_TAG;

||dev->mon.version = 0;

||dev->mon.module = const_cast<hw_module_t*>(module);

||dev->mon.close = legacy_ap_dev_close;

||dev->device.create_audio_policy = create_legacy_ap;//create_audio_policy对应的操作函数。

||dev->device.destroy_audio_policy = destroy_legacy_ap;

||

||*device = &dev->mon;

||

||return 0;

||}

||

||→create_legacy_ap

||→lap->policy.init_check = ap_init_check;

||→lap->policy.init_stream_volume = ap_init_stream_volume;

||→lap->policy.set_stream_volume_index = ap_set_stream_volume_index;

||→... ...

||→ap->apm = createAudioPolicyManager(lap->service_client);//创建AudioPolicyManager

||→new AudioPolicyManagerDefault(clientInterface);

||→AudioPolicyManagerBase::AudioPolicyManagerBase

||→mpClientInterface = clientInterface;

|

如果觉得《android audio 音量调节》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。