Android Audio System 之三: AudioPolicyService 和 AudioPolicyManager

原创 2010年10月18日 17:25:00

引言

    AudioPolicyService是Android音频系统的两大服务之一,另一个服务是AudioFlinger,这两大服务都在系统启动时有MediaSever加载,加载的代码位于:frameworks/base/media/mediaserver/main_mediaserver.cpp。AudioFlinger主要负责管理音频数据处理以及和硬件抽象层相关的工作。本文主要介绍AudioPolicyService。

AudioPolicyService

    AudioPolicyService主要完成以下任务:

  • JAVA应用层通过JNI,经由IAudioPolicyService接口,访问AudioPolicyService提供的服务
  • 输入输出设备的连接状态
  • 系统的音频策略(strategy)的切换
  • 音量/音频参数的设置

    AudioPolicyService的构成

    下面这张图描述了AudioPolicyService的静态结构:

 

进一步说明:

1. AudioPolicyService继承了IAudioPolicyService接口,这样AudioPolicyService就可以基于Android的Binder机制,向外部提供服务;

2. AudioPolicyService同时也继承了AudioPolicyClientInterface类,他有一个AudioPolicyInterface类的成员指针mpPolicyManager,实际上就是指向了AudioPolicyManager;

3. AudioPolicyManager类继承了AudioPolicyInterface类以便向AudioPolicyService提供服务,反过来同时还有一个AudioPolicyClientInterface指针,该指针在构造函数中被初始化,指向了AudioPolicyService,实际上,AudioPolicyService是通过成员指针mpPolicyManager访问AudioPolicyManager,而AudioPolicyManager则通过AudioPolicyClientInterface(mpClientInterface)访问AudioPolicyService;

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

AudioPolicyManager

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

输入输出设备管理

音频系统为音频设备定义了一个枚举:AudioSystem::audio_devices,例如:DEVICE_OUT_SPEAKER,DEVICE_OUT_WIRED_HEADPHONE,DEVICE_OUT_BLUETOOTH_A2DP,DEVICE_IN_BUILTIN_MIC,DEVICE_IN_VOICE_CALL等等,每一个枚举值其实对应一个32bit整数的某一个位,所以这些值是可以进行位或操作的,例如我希望同时打开扬声器和耳机,那么可以这样:

AudioPolicyManager中有两个成员变量:mAvailableOutputDevices和mAvailableInputDevices,他们记录了当前可用的输入和输出设备,当系统检测到耳机或者蓝牙已连接好时,会调用AudioPolicyManager的成员函数:

该函数根据传入的device值和state(DEVICE_STATE_AVAILABLE/DEVICE_STATE_UNAVAILABLE)设置mAvailableOutputDevices或者mAvailableInputDevices,然后选择相应的输入或者输出设备。

其他一些相关的函数:

  • setForceUse()  设置某种场合强制使用某一设备,例如setForceUse(FOR_MEDIA, FORCE_SPEAKER)会在播放音乐时打开扬声器
  • startOutput()/stopOutput()
  • startInput()/stopInput()

音量管理

AudioPolicyManager提供了一下几个与音量相关的函数:

  • initStreamVolume(AudioSystem::stream_type stream, int indexMin, int indexMax)
  • setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
  • getStreamVolumeIndex(AudioSystem::stream_type stream)

AudioService.java中定义了每一种音频流的最大音量级别:

由此可见,电话铃声可以有7个级别的音量,而音乐则可以有15个音量级别,java的代码通过jni,最后调用AudioPolicyManager的initStreamVolume(),把这个数组的内容传入AudioPolicyManager中,这样AudioPolicyManager也就记住了每一个音频流的音量级别。应用程序可以调用setStreamVolumeIndex设置各个音频流的音量级别,setStreamVolumeIndex会把这个整数的音量级别转化为适合人耳的对数级别,然后通过AudioPolicyService的AudioCommandThread,最终会将设置应用到AudioFlinger的相应的Track中。

音频策略管理

 我想首先要搞清楚stream_type,device,strategy三者之间的关系:

  • AudioSystem::stream_type  音频流的类型,一共有10种类型
  • AudioSystem::audio_devices  音频输入输出设备,每一个bit代表一种设备,见前面的说明
  • AudioPolicyManager::routing_strategy 音频路由策略,可以有4种策略

getStrategy(stream_type)根据stream type,返回对应的routing strategy值,getDeviceForStrategy()则是根据routing strategy,返回可用的device。Android把10种stream type归纳为4种路由策略,然后根据路由策略决定具体的输出设备。

 

成员变量mOutputs

这是AudioPolocyManager用管理输出的键值对向量(数组),通常AudioPolocyManager会打开3个输出句柄(audio_io_handle_t),关于audio_io_handle_t,请参考另一编博客:http://blog.csdn.net/DroidPhone/archive/2010/10/14/5941344.aspx,它实际上就是AudioFlinger中某个PlaybackTread的ID。这3个句柄分别是:

  • mHardwareOutput            // hardware output handler
  • mA2dpOutput                   // A2DP output handler
  • mDuplicatedOutput          // duplicated output handler: outputs to hardware and A2DP

可以通过startOutput()把某一个stream type放入到相应的输出中。

 

popCount()

这个函数主要用来计算device变量中有多少个非0位(计算32位数种1的个数),例如该函数返回2,代表同时有两个device要处理。之所以特别介绍它,是因为这个函数的实现很有意思:

不知道各位看懂了么?

 

 

AudioCommandThread

    这是AudioPolicyService中的一个线程,主要用于处理音频设置相关的命令。包括:

  • START_TONE
  • STOP_TONE
  • SET_VOLUME
  • SET_PARAMETERS
  • SET_VOICE_VOLUME

     每种命令的参数有相应的包装:

  • class ToneData
  • class VolumeData
  • class ParametersData
  • class VoiceVolumeData

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

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

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

    SET_PARAMETERS:通过一个KeyValuePairs形式的字符串进行参数设置,KeyValuePairs的格式可以这样:

 

  •  "sampling_rate=44100"
  • "channels=2"
  • "sampling_rate=44100;channels=2"     // 组合形式

    这些KeyValuePairs可以通过AudioPolicyService的成员函数setParameters()传入。

 

深入剖析Android音频之AudioPolicyService

AudioPolicyService是策略的制定者,比如什么时候打开音频接口设备、某种Stream类型的音频对应什么设备等等。而AudioFlinger则是策略的执行者,例如具体如何与音频设备通信,如...

android audio 架构分析(2) AudioPolicyService 的结构

AudioPolicyService简介 AudioPolicyService是android audio system中两大服务之一,另外一个是AudioFlinger。 主要的功能: 1...

深入剖析Android音频之AudioPolicyService

文章出自:http://blog.csdn.net/yangwen123/article/details/39497375 AudioPolicyService是策略的制定者,比如什么时候打开音频接...
  • BHJ1119
  • BHJ1119
  • 2017年10月13日 10:48
  • 107

Android 7.0 Audio: AudioPolicyService和他的码农APM

AudioPolicyService负责音频策略处理,包括根据手机的各种状态和器件的存在、插拔状态、用户使能状态,给不同的audio stream选择不同的输入输出设备,控制不同设备的增益等。 代码层...

Audio Policy 分析

一 目的 上回我们说了AudioFlinger(AF),总感觉代码里边有好多东西没说清楚,心里发毛。就看了看AF的流程,我们敢说自己深入了解了Android系统吗?AudioPolicyServic...
  • hgl868
  • hgl868
  • 2011年10月19日 14:29
  • 4401

Android音频系统之AudioPolicyService

1.1 AudioPolicy Service 在AudioFlinger小节,我们反复强调它只是策略的执行者,而AudioPolicyService则是策略的制定者。这种分离方式有效地降低了整...

Android AudioPolicyService服务启动过程

Android AudioPolicyService服务启动过程 AudioPolicyService是策略的制定者,比如什么时候打开音频接口设备、某种Stream类型的音频对应什么设备等等。而...

Android音频系统之四AudioPolicy

4.1 AudioPolicy的诞生 AudioPolicyService是Android音频系统的两大服务之一,另一个服务是AudioFlinger,这两大服务都在系统启动时有MediaSev...

【Android 7.0 Audio】: AudioPolicyService和他的码农APM

转载自http://blog.csdn.net/xiashaohua/article/details/53694987 AudioPolicyService负责音频策略处理,包括根据手机的各种状...

AudioFlinger,AudioPolicyService and Audio track分析

Contents Android音频系统之AudioFlinger(一).. 2 1.1 AudioFlinger. 2 1.1.1 AudioFlinger服务的启动和运行... 2 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android Audio System 之三: AudioPolicyService 和 AudioPolicyManager
举报原因:
原因补充:

(最多只允许输入30个字)