`
quanminchaoren
  • 浏览: 919750 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Android Audio System之AudioPolicyService和Audi

阅读更多

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整数的某一个位,所以这些值是可以进行位或操作的,例如我希望同时打开扬声器和耳机,那么可以这样:

  1. newDevice = DEVICE_OUT_SPEAKER | DEVICE_OUT_WIRED_HEADPHONE;  
  2. setOutputDevice(mHardwareOutput, newDevice);  

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

  1. status_t AudioPolicyManager::setDeviceConnectionState(AudioSystem::audio_devices device,  
  2.                                                   AudioSystem::device_connection_state state,  
  3.                                                   const   char  *device_address)  

该函数根据传入的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中定义了每一种音频流的最大音量级别:

  1. /** @hide Maximum volume index values for audio streams */   
  2.     private   int [] MAX_STREAM_VOLUME =  new   int [] {  
  3.         5,  // STREAM_VOICE_CALL   
  4.         7,  // STREAM_SYSTEM   
  5.         7,  // STREAM_RING   
  6.         15, // STREAM_MUSIC   
  7.         7,  // STREAM_ALARM   
  8.         7,  // STREAM_NOTIFICATION   
  9.         15, // STREAM_BLUETOOTH_SCO   
  10.         7,  // STREAM_SYSTEM_ENFORCED   
  11.         15, // STREAM_DTMF   
  12.         15  // STREAM_TTS   
  13.     };  

由此可见,电话铃声可以有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

  1. KeyedVector<audio_io_handle_t, AudioOutputDescriptor *> mOutputs;    // list of output descriptors   

这是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要处理。之所以特别介绍它,是因为这个函数的实现很有意思:

  1. uint32_t AudioSystem::popCount(uint32_t u)  
  2. {  
  3.     u = ((u&0x55555555) + ((u>>1)&0x55555555));  
  4.     u = ((u&0x33333333) + ((u>>2)&0x33333333));  
  5.     u = ((u&0x0f0f0f0f) + ((u>>4)&0x0f0f0f0f));  
  6.     u = ((u&0x00ff00ff) + ((u>>8)&0x00ff00ff));  
  7.     u = ( u&0x0000ffff) + (u>>16);  
  8.     return  u;  
  9. }  

不知道各位看懂了么?

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 P Audio系统笔记:AudioPolicy&AudioFlinger初始化

    AudioFlinger和AudioPolicy两者是Android Audio框架层最主要的两个服务,他们两个是Android框架层的本地服务,在init.rc中启动; AudioPolicyManager负责音频策略定制者,说白了就相当于Audio系统的司令。 Audio...

    Android audio知识总结.pdf

    本文将深入探讨Android音频框架,特别是AudioTrack、AudioRecord、AudioSystem、AudioPolicyService、AudioFlinger以及Audio HAL,并讨论它们在音视频处理中的作用。 1. AudioTrack: AudioTrack是Android应用程序...

    android audio 音频调试技巧

    ### Android Audio 音频调试技巧 在Android平台上进行音频调试是一项重要的技能,它涉及到音频硬件、软件以及系统级配置等多个方面。本文将详细介绍如何利用不同的工具和技术来诊断和解决音频问题,包括查看声卡...

    Android7.0 Audio Framework——framework introduce.pdf

    2. Audio 的 JNI 部分:`frameworks/base/core/jni/android_media_AudioTrack.cpp`、`frameworks/base/core/jni/android_media_AudioRecord.cpp` 和 `frameworks/base/core/jni/android_media_AudioSystem.cpp`。...

    安卓audio-audioflinger、audiopolicy策略加载

    Android音频框架通过AudioPolicyService和AudioFlinger协同工作,实现音频策略的制定和执行。AudioPolicyService作为策略中心,依据audio_policy.conf文件制定出适应不同场景的音频策略,而AudioFlinger则负责将...

    Andoird的Audio系统

    从功能上看,AudioSystem 负责的是 Audio 系统的综合管理功能,而 AudioTrack 和 AudioRecorder 分别负责音频数据的输出和输入,即播放和录制。 另外一个接口是 IAudioFlingerClient,它作为向 IAudioFlinger 中...

    audio上层框架介绍

    本文将深入探讨Android音频上层框架,特别是AudioFlinger和AudioPolicyService,以及它们如何与硬件交互。 AudioFlinger是Android音频系统的核心组件,负责音频的混合、路由和硬件交互。IAudioFlinger.cpp是Audio...

    android的audio图解

    - **简介**:AudioFlinger是Android音频子系统的核心组件之一,负责音频数据的混音和播放。 - **功能**: - 混音处理。 - 将音频数据发送到硬件输出。 - 管理音频流。 2. **AudioPolicyManager** - **简介**...

    Audio系统综述 Android底层开发

    ### Android Audio系统综述:底层开发视角 #### 音频系统框架概览 在深入探讨Android音频系统的细节之前,我们首先需要对整个音频系统的基本框架有所了解。Android的音频系统设计得十分模块化,旨在为应用程序提供...

    Android-audio系统第一季.pdf

    至于输入输出设备管理,Android通过AudioSystem::audio_devices枚举定义了一系列设备类型,如扬声器、有线耳机、蓝牙A2DP等。这些设备的枚举值可以进行位运算,使得系统能够同时启用多个设备。例如,通过位或操作...

    Android-audio系统第一季

    AudioTrack与AudioRecord分别负责声音的播放和录制,是Android音频系统中直接与硬件交互的组件。AudioTrack允许开发者以特定的格式和采样率向用户播放声音,支持多种音频流类型。而AudioRecord则用于捕获来自麦克风...

    android_Audio系统.docx

    Android的音频系统是一个复杂而精细的设计,主要由三个核心组件构成:AudioRecord、AudioTrack和AudioFlinger。本文将深入探讨这些组件的功能及其交互过程。 首先,AudioRecord和AudioTrack是Android音频系统的对外...

    Audio Framework.vsdx

    AudioPolicyService和AudioFLinger、AudioPolicyManager、AudioPolicyClient之间的调用关系

    Android音频详解.pdf

    这个文档是我整理别人博客的,写的非常的不错,通俗易懂,相对来说还是比较全面,讲了linux下的声卡,Android音频 , AudioPolicyService, AudioFlinger, AudioTrack这些都有详细的讲解,然后我也做了书签,方便...

    深入理解Android 卷1.pdf

    第7章对Audio系统进行了深入的分析,尤其是AudioTrack、AudioFlinger和AudioPolicyService等的工作原理。第8章深入讲解了Surface系统的实现原理,分析了Surface与Activity之间以及Surface与SurfaceFlinger之间的关系...

    修改和定制Android音频策略

    Android系统作为目前主流的操作系统之一,在多媒体处理方面提供了丰富的API和支持。然而,默认的音频策略可能无法完全满足特定场景下的需求,如车载导航仪的复杂环境。因此,本文将以车载导航仪为例,探讨如何修改和...

    深入理解Android:卷2

    第7章对Audio系统进行了深入的分析,尤其是AudioTrack、AudioFlinger和AudioPolicyService等的工作原理。第8章深入讲解了Surface系统的实现原理,分析了Surface与Activity之间以及Surface与SurfaceFlinger之间的关系...

Global site tag (gtag.js) - Google Analytics