android 声卡 音量控制,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_volum     mpAudioPolicy->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& 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->device.common.tag = HARDWARE_DEVICE_TAG;

| | dev->device.common.version = 0;

| | dev->device.common.module = const_cast(module);

| | dev->device.common.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->device.common;

| |

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

|

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android USB声卡是一种通过USB接口连接到Android设备的外部音频设备,用于提供更高质量的音频输入和输出。它可以替代手机或平板自带的内部声卡,提供更好的音频处理和音频效果。 Android USB声卡通常由一个USB接口和音频输入输出接口组成。通过连接USB接口,可以将声卡连接到Android设备上。利用声卡的音频输入接口,可以将外部麦克风或乐器等音频信号输入到Android设备上,进行录音或音频处理。利用声卡的音频输出接口,可以将Android设备上的音频信号输出到外部音响、耳机或音箱等设备上,提供更好的音频体验。 通过使用Android USB声卡,用户可以获得更高质量的音频输入输出。与手机或平板自带的内部声卡相比,USB声卡通常具有更高的采样率和比特深度,可以捕捉更真实、清晰的声音和音乐细节。此外,USB声卡通常还提供了更多的音频接口,比如耳机输出、音频输入等,方便用户根据不同的需求进行连接。 此外,在音乐制作、录音和混音等专业领域,Android USB声卡也发挥着重要的作用。相对于内部声卡,USB声卡通常具有更好的音频处理和效果处理能力,可以满足专业用户的需求。用户可以通过连接USB声卡,将专业麦克风、乐器等设备连接到Android设备上,进行更高水平的音频创作和编辑。 综上所述,Android USB声卡可以提供更高质量的音频输入输出,以及更好的音频处理和效果处理能力。无论是普通用户还是专业音乐人,都可以通过使用Android USB声卡,获得更出色的音频体验和创作效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值