第十八篇 ANDROID的声音管理系统及服务
声音管理系统用来实现声音的输入和输出、声音的控制和路由等功能,包括主和各种音源的音量调节、声音焦点控制,声音外设的检测和状态管理,声音源输入和输出的策略管理、音效的播放、音轨设置和播放、录音设置和启动等功能。
整个声音管理系统相关类图如下:主要由JAVA端的系统服务AudioService及两个本地服务声音输入输出策略管理服务AudioPolicyService及声音输出投射服务AudioFlinger来实现相关功能。
应用主要通过AudioManage接口来使用AudioService提供的服务。系统服务AudioService与两个本地服务之间通过AudioSystem类提供的接口借助JNI进行交互。
系统服务AudioService使用蓝牙监听对象BluetoothProfile.ServiceListener来监听蓝牙框架服务HeadsetProfile及HeadsetProfile的连接,并获得两个蓝牙框架服务的客户端对象BluetoothHeadset和BluetoothA2dp来与对应的蓝牙框架服务实现交互。使用一个AudioServiceBroadcastReceiver广播接收对象来监听基座状态事件、蓝牙连接状态改变事件、外设插拔事件、声音状态改变事件、屏幕打开关闭事件、配置改变事件、用户切换事件等事件并进行相应处理。
当检测到需要切换声音路由时,由相关应用通过AudioManage接口调用AudioService系统服务提供的setWiredDeviceConnectionState、setBluetoothA2dpDeviceConnectionState()接口来发起或AudioService系统服务本身检测到相关的事件来触发媒体路由切换,并通过IAudioRoutesObserver接口调用dispatchAudioRoutesChanged()函数来通知媒体路由切换相关进程和服务进行相应处理。
声音焦点控制主要有AudioService系统服务提供的MediaFocusControl对象进行控制。声音焦点控制实现同时只有一个应用能够获得焦点播放同种类型的声音,ANDROID提供和支持STREAM_VOICE_CALL(电话呼叫)、STREAM_SYSTEM(系统)、STREAM_RING(振铃和消息提示)、STREAM_MUSIC(音乐媒体播放)、STREAM_ALARM(警报声)、STREAM_NOTIFICATION(通知音)、STREAM_BLUETOOTH_SCO(蓝牙电话)、STREAM_SYSTEM_ENFORCED(强制系统声音)、STREAM_DTMF(DTMF拨号音)及STREAM_TTS(文本识别音)九种声音流类型,每种类型可以独立的调节声音大小,其中除了STREAM_MUSIC类型是应用播放媒体使用的类型外其它都是系统要处理的声音类型。MediaFocusControl对象的相关类图如下:
本地服务AudioPolicyService提供不同声音流类型对应的输入输出设备的策略获取及策略的选择和控制(输入输出选择、输入输出设备的打开和停止、关闭等)、设置和获取声音设备的连接状态以及不同流类型对应的设备的音量的设置和获取、音频参数的设置、音效设置等功能。类图如下:
AudioPolicyService有一个内部线程类AudioCommandThread,顾名思义,所有的命令(音量控制,输入、输出的切换等)最终都会在该线程中排队执行;
在AudioPolicyService实例化时调用audio_policy_dev_open函数打开一个声音策略设备,并通过声音策略设备的create_audio_policy接口返回一个audio_policy策略函数结构体指针,AudioPolicyService对应的函数通过这个audio_policy函数结构体指针调用声音策略设备的对应函数实现设备的策略控制,在AudioPolicyService调用create_audio_policy函数时也把AudioPolicyService内部的一个audio_policy_service_ops函数结构体传给声音策略设备对象,供声音策略设备对象内部调用。声音策略设备使用create_audio_policy函数除了为audio_policy策略函数结构体函数指针赋值以外,还实例了两个对象,一个AudioPolicyClientInterface对象,作为AudioPolicyService客户端使用,声音策略设备使用AudioPolicyClientInterface对象通过AudioPolicyService的内部接口audio_policy_service_op调用AudioPolicyService的相关函数;另外一个对象为具体的实现相关声音策略接口的AudioPolicyInterface对象,这里采用的是设计模式的策略模式,这也是AudioPolicyService称为声音策略服务的原因吧,
AudioPolicyInterface接口的具体实例的创建采用了工厂方法。
下面以AudioPolicyService的getInput函数为例子具体说明整个调用流程。AudioPolicyService的getInput函数实现根据函数传进来的声音输入类型、采样率、声音格式、通道掩码参数打开一个输入设备,整个流程为:
AudioPolicyService的getInput首先通过create_audio_policy获得的audio_policy函数结构体指针调用其get_input函数;
get_input函数然后调用create_audio_policy内部采用工厂方法createAudioPolicyManager创建的具体AudioPolicyInterface对象的getInput函数。
AudioPolicyInterface对象的getInput函数内部首先调用getDeviceForInputSource函数根据函数传进来的输入源类型获得对应的audio_devices_t设备类型,然后调用getInputProfile函数根据传进来的声音采样率、声音格式、通道掩码等参数与获得的设备支持的Input
Profile比较返回一个与设备Profile匹配的IOProfile,然后根据返回的IOProfile对象构造一个AudioInputDescriptor对象添加到输入描述数组中,并调用create_audio_policy内部创建的一个具体AudioPolicyClientInterface对象的openInput函数;AudioPolicyClientInterface对象的openInput函数调用AudioPolicyService内部audio_policy_service_op函数结构体的open_input_on_module函数;
audio_policy_service_op函数结构体的open_input_on_module函数指针指向AudioPolicyService的aps_open_input_on_module函数,因此调用aps_open_input_on_module,aps_open_input_on_module内部首先AudioSystem类的get_audio_flinger函数获得IAudioFlinger接口,然后通过IAudioFlinger接口调用AudioFlinger服务的openInput函数,打开选择的输入设备,返回AudioPolicyService的getInput函数一个audio_io_handle_t句柄;
AudioPolicyService的getInput函数接着根据传进来的audioSession参数构造一个InputDesc对象,把getInput函数返回的audio_io_handle_t句柄添加到向量数组中,根据输入源类型从支持的输入源向量列表获得该输入源支持的EffectDesc数组,并对每一个EffectDesc根据EffectDesc的Uuid、返回的audio_io_handle_t句柄及audioSession参数实例化一个AudioEffect对象,并调用AudioEffect对象的setParameter函数为每一个EffectDesc设置声音参数。每个AudioEffect对象也添加到InputDesc对象AudioEffect的数组中。完成整个流程。
版权所有,转载时请尊重原创显要处注明链接,谢谢!
第十七篇 --ANDROID DisplayManager 服务解析一
第十八篇 ANDROID的声音管理系统及服务的更多相关文章
- Python之路【第十八篇】:Web框架们
Python之路[第十八篇]:Web框架们 Python的WEB框架 Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Pytho ...
- Egret入门学习日记 --- 第十八篇(书中 8.5~8.7 节 内容)
第十八篇(书中 8.5~8.7 节 内容) 其实语法篇,我感觉没必要写录入到日记里. 我也犹豫了好久,到底要不要录入. 这样,我先读一遍语法篇的所有内容,我觉得值得留下的,我就录入日记里. 不然像昨天 ...
- Android UI开发第二十八篇——Fragment中使用左右滑动菜单
Fragment实现了Android UI的分片管理,尤其在平板开发中,好处多多.这一篇将借助Android UI开发第二十六篇——Fragment间的通信. Android UI开发第二十七篇——实 ...
- Android高手进阶教程(二十八)之---Android ViewPager控件的使用(基于ViewPager的横向相册)!!!
分类: Android高手进阶 Android基础教程 2012-09-14 18:10 29759人阅读 评论(35) 收藏 举报 android相册layoutobjectclassloade ...
- Android笔记(五十八)Android总结:四大组件——Activity篇
什么是Activity Activity是一种包含用户界面的组件,主要用于和用户进行交互,一个APP通常由多个Activity组成. 每个Activity都对应一个布局文件,通过setContentV ...
- Python开发【第十八篇】Web框架之Django【基础篇】
一.简介 Python下有许多款不同的 Web 框架,Django 是重量级选手中最有代表性的一位,许多成功的网站和APP都基于 Django. Django 是一个开放源代码的Web应用框架,由 P ...
- 十八、Android引导界面
一.所需素材 很有必要整理一下,里面附带友盟的社会化分享组件,我就不去掉了. 二.代码 import com.umeng.update.UmengUpdateAgent; import android ...
- 第五十八篇、iOS 微信聊天发送小视频的秘密
对于播放视频,大家应该一开始就想到比较方便快捷使用简单的MPMoviePlayerController类,确实用这个苹果官方为我们包装好了的 API 确实有很多事情都不用我们烦心,我们可以很快的做出一 ...
- python【第十八篇】Django基础
1.什么是Django? Django是一个Python写成的开源Web应用框架.python流行的web框架还有很多,如tornado.flask.web.py等.django采用了MVC的框架模式 ...
随机推荐
- Java安全套接字扩展——JSSE
上节已经介绍了SSL/TLS协议的通信模式,而对于这些底层协议,如果要每个开发者都自己去实现显然会带来不必要的麻烦,正是为了解决这个问题Java为广大开发者提供了Java安全套接字扩展--JSSE,它 ...
- Dynamics CRM2015 Update1 新功能之表单增强功能
CRM2015 Update 1发布后,系统的界面的变化很大,仔细观察后会发现表单窗体也有些不同了,在CRM2015 Update1的官方介绍中对此变化的解释是起用了新的窗体呈现引擎,让界面更好看加载 ...
- Dynamics CRM2016 新功能之Solution enhancements
CRM2016中对解决方案的功能有了一定的加强,CRM自2011版本开始引入了solution的概念,但大家的共识是solution的导出导入以及发布都非常的慢,常常会出现发布超时的情况很是头疼. 以 ...
- Hibernate系列学习之(二) 多对一、一对一、一对多、多对多的配置方法
这是近期做案件录入.java项目中体会的几点:项目理解很是深刻,和大家共勉! hihernate一对多关联映射(单向Classes----->Student) 一对多关联映射利用了多对一关联映射 ...
- TortoiseSVN文件夹图标不显示
伴随着十二月的脚步,小编带领的市委组织部项目有条不紊的进行着,在最近的项目中遇到一个问题TortoiseSVN文件夹的图标不显示,为什么小编已经安装好TortoiseSVN了,发现文件夹的图标还是系统 ...
- 后端分布式系列:分布式存储-HDFS NameNode 设计实现解析
接前文 分布式存储-HDFS 架构解析,我们总体分析了 HDFS 架构的主要构成组件包括:NameNode.DataNode 和 Client.本文首先进一步解析 HDFS NameNode 的设计和 ...
- springMVC源码分析--容器初始化(二)DispatcherServlet
在上一篇博客springMVC源码分析--容器初始化(一)中我们介绍了spring web初始化IOC容器的过程,springMVC作为spring项目中的子项目,其可以和spring web容器很好 ...
- 【图的DFS】图的DFS非递归算法
在DFS的递归算法中,DFS框架如下: 1访问起点v0 2依次以v0的未访问的连接点为起点,DFS搜索图,直至图中所有与v0路径相通的顶点都被访问. 3若该图为非连通图,则图中一定还存在未被访问的顶点 ...
- 【Unity技巧】自定义消息框(弹出框)
写在前面 这一篇我个人认为还是很常用的,一开始也是实习的时候学到的,所以我觉得实习真的是一个快速学习工程技巧的途径. 提醒:这篇教程比较复杂,如果你不熟悉NGUI.iTween.C#的回调函数机制,那 ...
- ROS_Kinetic_15 ROS使用Qt
ROS_Kinetic_15 ROS使用Qt 在网页http://www.qt.io/download-open-source/#section-2 下载并安装Qt ~/下载$ chmod +x qt ...