转载:android audio policy
Audio policy basic:https://www.cnblogs.com/CoderTian/p/5705742.html
Set volume flow:https://blog.csdn.net/axlecho/article/details/78510496
https://blog.csdn.net/u014702999/article/details/52488803
audio policy config xml:https://blog.csdn.net/u012188065/article/details/84104275
AudioPolicy在Android系统中主要负责Audio"策略"相关的问题。它和AudioFlinger一起组成了Android Audio系统的两个服务。一个负责管理audio的“路由”,一个负责管理audio“设备”。这两个服务都是在系统启动的过程中,通过MediaServer来加载的。
AudioPolicyService在Android Audio系统中主要完成以下几个任务:
①管理输入输出设备,包括设备的连接、断开状态,设备的选择和切换等
②管理系统的音频策略,比如通话时播放音乐、或者播放音乐时来电话的一系列处理
③管理系统的音量
④上层的一些音频参数也可以通过AudioPolicyService设置到底层去
Audio Policy初始化:
AudioPolicyService是继承自BnAudioPolicyService的,一步步往上推,最终发现它的祖先是RefBase,根据强指针的特性,目标对象在第一次被引用时会调用onFirstRef()。
在第一次被强引用时AudioPolicyService创建了3个AudioCommandThread和AudioPolicyManager。
三个AudioCommandThread线程分别是ApmTone、ApmAudio、ApmOutput
ApmTone用于播放tone音;
ApmAudio用于执行audio命令;
ApmOutput用于执行输出命令;
1.loadconfig
void AudioPolicyManager::loadConfig() {
#ifdef USE_XML_AUDIO_POLICY_CONF
if (deserializeAudioPolicyXmlConfig(getConfig()) != NO_ERROR) {
#else
if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, getConfig()) != NO_ERROR)
&& (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, getConfig()) != NO_ERROR)) {
#endif
ALOGE("could not load audio policy configuration file, setting defaults");
getConfig().setDefault();
}
}
1)如果没有define USE_XML_AUDIO_POLICY_CONF,加载audio_policy.conf配置文件 /system/etc/audio_policy.conf(对于模拟器而言走的是defaultAudioPolicyConfig())
在AudioPolicyManager创建过程中会通过加载audio_policy.conf配置文件来加载音频设备,Android为每种音频接口定义了对应的硬件抽象层。硬件抽象层代码参考写法
hardware/libhardware/modules/audio
external/bluetooth/bluedroid/audio_a2dp_hw/ |
audio.a2dp.default.so |
hardware/libhardware/modules/audio/ |
audio.primary.default.so |
hardware/libhardware/modules/usbaudio/ |
audio.usb.default.so |
每种音频接口定义了不同的输入输出,一个接口可以具有多个输入或者输出,每个输入输出可以支持不同的设备,通过读取audio_policy.conf文件可以获取系统支持的音频接口参数,在AudioPolicyManager中会优先加载/vendor/etc/audio_policy.conf配置文件, 如果该配置文件不存在, 则加载/system/etc/audio_policy.conf配置文件。AudioPolicyManager加载完所有音频接口后,就知道了系统支持的所有音频接口参数,可以为音频输出提供决策。
audio_policy.conf同时定义了多个audio接口,每一个audio接口包含若干output和input,而每个output和input又同时支持多种输入输出模式,每种输入输出模式又支持若干种设备.
ConfigParsingUtils::loadAudioPolicyConfig(....);
分成两部分,第一部分是解析全局标签,第二部分是解析audio_hw_modules标签,其子标签都表示hardware module,有primary和r_submix两种hardware module都被解析到mHwModules,hardware module的子标签有outputs和inputs,outputs的各个子标签被解析到mHwModules 的 mOutputProfiles,inputs的各个子标签被解析到mHwModules 的 mInputProfiles。
2)如果有define USE_XML_AUDIO_POLICY_CONF,则解析audio_policy_configure.xml
<!-- Modules section:
There is one section per audio HW module present on the platform.
Each module section will contains two mandatory tags for audio HAL “halVersion” and “name”.
The module names are the same as in current .conf file:
“primary”, “A2DP”, “remote_submix”, “USB”
Each module will contain the following sections:
“devicePorts”: a list of device descriptors for all input and output devices accessible via this
module.
This contains both permanently attached devices and removable devices.
“mixPorts”: listing all output and input streams exposed by the audio HAL
“routes”: list of possible connections between input and output devices or between stream and
devices.
"route": is defined by an attribute:
-"type": <mux|mix> means all sources are mutual exclusive (mux) or can be mixed (mix)
-"sink": the sink involved in this route
-"sources": all the sources than can be connected to the sink via vis route
“attachedDevices”: permanently attached devices.
The attachedDevices section is a list of devices names. The names correspond to device names
defined in <devicePorts> section.
“defaultOutputDevice”: device to be used by default when no policy rule applies
-->
<modules>
<!-- Primary Audio HAL -->
<module name="primary" halVersion="3.0">
<attachedDevices>
<item>Speaker</item>
<item>Built-In Mic</item>
<item>Built-In Back Mic</item>
</attachedDevices>
<defaultOutputDevice>Speaker</defaultOutputDevice>
<mixPorts>
<mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
<mixPort name="deep_buffer" role="source"
flags="AUDIO_OUTPUT_FLAG_DEEP_BUFFER">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
<mixPort name="compressed_offload" role="source"
flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING">
<profile name="" format="AUDIO_FORMAT_MP3"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
<profile name="" format="AUDIO_FORMAT_AAC"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
<profile name="" format="AUDIO_FORMAT_AAC_LC"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
</mixPort>
<mixPort name="voice_tx" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
</mixPort>
<mixPort name="primary input" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
</mixPort>
<mixPort name="voice_rx" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
</mixPort>
</mixPorts>
<devicePorts>
<!-- Output devices declaration, i.e. Sink DEVICE PORT -->
<devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
</devicePort>
<devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
<gains>
<gain name="gain_1" mode="AUDIO_GAIN_MODE_JOINT"
minValueMB="-8400"
maxValueMB="4000"
defaultValueMB="0"
stepValueMB="100"/>
</gains>
</devicePort>
<devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</devicePort>
<devicePort tagName="Wired Headphones" type="AUDIO_DEVICE_OUT_WIRED_HEADPHONE" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</devicePort>
<devicePort tagName="BT SCO" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
</devicePort>
<devicePort tagName="BT SCO Headset" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
</devicePort>
<devicePort tagName="BT SCO Car Kit" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
</devicePort>
<devicePort tagName="Telephony Tx" type="AUDIO_DEVICE_OUT_TELEPHONY_TX" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
</devicePort> <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
</devicePort>
<devicePort tagName="Built-In Back Mic" type="AUDIO_DEVICE_IN_BACK_MIC" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
</devicePort>
<devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
</devicePort>
<devicePort tagName="BT SCO Headset Mic" type="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
</devicePort>
<devicePort tagName="Telephony Rx" type="AUDIO_DEVICE_IN_TELEPHONY_RX" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
</devicePort>
</devicePorts>
<!-- route declaration, i.e. list all available sources for a given sink -->
<routes>
<route type="mix" sink="Earpiece"
sources="primary output,deep_buffer,BT SCO Headset Mic"/>
<route type="mix" sink="Speaker"
sources="primary output,deep_buffer,compressed_offload,BT SCO Headset Mic,Telephony Rx"/>
<route type="mix" sink="Wired Headset"
sources="primary output,deep_buffer,compressed_offload,BT SCO Headset Mic,Telephony Rx"/>
<route type="mix" sink="Wired Headphones"
sources="primary output,deep_buffer,compressed_offload,BT SCO Headset Mic,Telephony Rx"/>
<route type="mix" sink="primary input"
sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,BT SCO Headset Mic"/>
<route type="mix" sink="Telephony Tx"
sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,BT SCO Headset Mic, voice_tx"/>
<route type="mix" sink="voice_rx"
sources="Telephony Rx"/>
</routes> </module> <!-- A2dp Audio HAL -->
<xi:include href="a2dp_audio_policy_configuration.xml"/> <!-- Usb Audio HAL -->
<xi:include href="usb_audio_policy_configuration.xml"/> <!-- Remote Submix Audio HAL -->
<xi:include href="r_submix_audio_policy_configuration.xml"/> <!-- Hearing aid Audio HAL -->
<xi:include href="hearing_aid_audio_policy_configuration.xml"/> </modules>
<!-- End of Modules section --> <!-- Volume section --> <xi:include href="audio_policy_volumes.xml"/>
<xi:include href="default_volume_tables.xml"/> <!-- End of Volume section --> </audioPolicyConfiguration>
每个 <module>都是一个 audio hal(对应代码中的HwModule类)。
<mixPort>(对应代码中AudioPort的子类IOProfile), 共有两大类role, 一类是"source", 一类是 “sink”。
"source"类的<mixPort> 共同组成了 HwModule 中的mOutputProfiles, "sink"类的<mixPort> 共同组成了 HwModule 中的mInputProfiles, mOutputProfiles + mInputProfiles 共同组成了 HwModule 中的mPorts。
<devicePort>(对应代码中AudioPort和AudioPortConfig的子类DeviceDescriptor),共同组成了 HwModule中的 mDeclaredDevices, 里面的各个device成员也会加载到先前HwModule类中的mPort。
<route>(对应代码中的AudioRoute类),顾名思义,是通路的意思,其连接port和device的作用. 每个<route>实质上是一个MIX或者MUX, 以MIX为例,一个MIX包含一个sink(即AudioRoute的mSink)和多个source(分别add到AudioRoute的mSurce),此时已经将sink和source建立了简单的关系。
2)initialize
load_audio_interface()用来audio hal so,然后打开设备并创建一个audio_hw_device_t实例,音频设备接口所对应的so名称是有一定格式的,如a2dp的模块名可能是audio.a2dp.so或audio.a2dp.default.so等,查找路径主要有两个/system/lib/hw和/vendor/lib/hw
load()dlopen hal so,dlsym返回audio_module:
struct audio_module HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.module_api_version = AUDIO_MODULE_API_VERSION_0_1,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = AUDIO_HARDWARE_MODULE_ID,
.name = "QCOM Audio HAL",
.author = "Code Aurora Forum",
.methods = &hal_module_methods,
},
};
open返回audio_hw_device_t。这样audio policy完成了对Hal module的加载
对于每个outputProfile,创建1个outputDescription, 每个outputDescription调用open来openOutput,返回audio_io_handle_t类型的output handle.并把output handle add到mOutput.然后调用setOutputDevice(在里面createAudioPatch)。
setDeviceConnectionState:当有设备(比如耳机)接入或者断开时 ,会由java层通知audio system来更改输出设备。
设置音量:
getOutput flow:
setForceUse & create patch flow:
Audio policy 与Audio Flinger control block:
转载:android audio policy的更多相关文章
- [转载] Android.Hook框架xposed开发篇
本文转载自: http://www.52pojie.cn/thread-396793-1-1.html 原帖:http://drops.wooyun.org/tips/7488 作者:瘦蛟舞 官方教程 ...
- [Android][Audio] audio_policy.conf文件分析
不同的Android产品在音频的设计上通常是存在差异的,而这些差异可以同过Audio的配置文件audio_policy.conf来获得.在Android系统中音频配置文件存放路径有两处,存放地址可以从 ...
- Android Audio遇到播放无声时的分析
在Android Audio开发过程中,有遇到播放ringtone时无声,但播放Music可以听到声音,关于无声问题的分析,在此做个笔记,方便以后回顾. 分析方向: 1:在音量控制面板中确认该音频流对 ...
- 关于dialog引起的 java.lang.IllegalArgumentException: View=com.android.internal.policy.impl.PhoneWindow$DecorView not attached to window manager 错误的分析
在跑Monkey测试的时候出现了一个比较特别的问题,先来看看Log: // CRASH: com.meizu.media.painter (pid 12491) // Short Msg: java. ...
- [转载]Android开发者必须深入学习的10个应用开源项目
[转载]Android开发者必须深入学习的10个应用开源项目 原文地址:Android开发者必须深入学习的10个应用开源项目(http://blog.sina.com.cn/s/blog_7b8a63 ...
- android在学习——activity关闭和dialog.dismiss冲突的解决(Activity has leaked window com.android.internal.policy.impl.PhoneWindow)
当我们在退出整个程序的时候偶尔会出现这种报错:Activity has leaked window com.android.internal.policy.impl.PhoneWindow 其意思大概 ...
- 转载:android audio flinger
https://blog.csdn.net/innost/article/details/6142812 https://blog.csdn.net/zyuanyun/article/details/ ...
- Android Audio控制和MediaButton远程控制(音视频控制配合)
使用过Android系统的朋友应该都知道,Android里面声音是区分好几种情况,每种情况下的音频大小是独立的.也就是说你调节了电话铃声大小不会影响多媒体播放的声音大小.这个涉及了AudioStrea ...
- [转载] Android Bander设计与实现 - 设计篇
本文转载自: http://blog.csdn.net/chenxiancool/article/details/17454593 摘要 Binder是Android系统进程间通信(IPC)方式之一. ...
随机推荐
- 面试官:Java序列化为什么要实现Serializable接口?我懵了
整理了一些Java方面的架构.面试资料(微服务.集群.分布式.中间件等),有需要的小伙伴可以关注公众号[程序员内点事],无套路自行领取 更多优选 一口气说出 9种 分布式ID生成方式,面试官有点懵了 ...
- Elasticsearch集成IKAnalyzer分析器
1. 查看标准分析器的分词结果 http://127.0.0.1:9200/_analyze?analyzer=standard&text=标准分析器 都分成了单个汉字, ...
- 判定PDF文件是否能够正常打开
下载iTextSharp.dll using iTextSharp.text.pdf; PdfReader reader = new PdfReader(strPath + "\\" ...
- 同一服务器下发布两个不同网站(war包)的方法(这里采用的是二级域名的方法)
这里是在阿里云服务器的上部署 在本地测试好之后,打包,然后发到服务器上的tomcat的webapp目录上(这个可能会有个bug,先启动下服务器,然后关掉,再启动,那个war包对应的文件才会出来) 这里 ...
- 修改Ubuntu的apt-get源为国内镜像源的方法
1.原文件备份 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak 2.编辑源列表文件 sudo vim /etc/apt/sources. ...
- 【pattern】设计模式(1) - 单例模式
前言 好久没写博客,强迫自己写一篇.只是总结一下自己学习的单例模式. 说明 单例模式的定义,摘自baike: 单例模式最初的定义出现于<设计模式>(艾迪生维斯理, 1994):“保证一个类 ...
- 通过编写Java代码让Jvm崩溃
在书上看到一个作者提出一个问题"怎样通过编写Java代码让Jvm崩溃",我看了之后也不懂.带着问题查了一下,百度知道里面有这样一个答案: 1 package jvm; 2 3 pu ...
- scp 后台执行(防止大文件关闭会话丢失)
Linux scp 设置nohup后台运行 Linux scp 设置nohup后台运行 1.正常执行scp命令 2.输入ctrl + z 暂停任务 3.bg将其放入后台 1.正常执行scp命令 从or ...
- 报表平台发行说明(V0.0.0.1)
开发周期:共20天(2019-11-04~2019-11-23) 发布日期:2019-11-23 主要功能说明: 1 整体功能技术选型,前端(html+CSS+javascript)+Web API ...
- 安装jupyter使用notebook
安装jupyter pip3 install jupyter --default-timeout=1000 -i https://pypi.tuna.tsinghua.edu.cn/simple 使用 ...