文章目录
- 1 文件路径
- 2 audio_policy_conf文件内容
- 3 audio_policy_conf加载流程及使用
-
- 3.1 解析
- 3.2 使用
-
- 3.2.1 device获取
- 3.2.2 profile获取
- 3.2.3 小结
- 4 问题小结
- 5 参考文章
1 文件路径
code:vendor\qcom\opensource\audio-hal\primary-hal\configs\XXXX(平台)
设备:/vendor/etc/audio_policy_configuration.xml
2 audio_policy_conf文件内容
<!-- mixer_port -->
<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><!-- device_port -->
<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><!-- route -->
<route type="mix" sink="primary input"sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,BT SCO Headset Mic,FM Tuner,USB Device In,USB Headset In"/>
route连接mixer_port和device_port
mixer_port代表着应用场景
device_port代表着硬件
3 audio_policy_conf加载流程及使用
3.1 解析
参见文章:audio_policy_configuration.xml 解析
在创建AudioPolicyManager的时候会加载配置文件,参见思维导图。
最终audio_policy_conf.xml文件中的三大节点,mixer_port, device_port, route会分别存放到
IOProfile,DeviceDescriptor,AudioRoute。
//1. mixer_port
Element mixPort = new IOProfile(String8(name.c_str()), portRole);//2. device_port
Element deviceDesc = new DeviceDescriptor(type, encodedFormats, String8(name.c_str()));//3. route
Element route = new AudioRoute(routeType);
3.2 使用
创建audiorecord的时候会执行set函数,然后将java层设置的三个参数(sample_rate,channel,format)设置下去,最终交给AudioPolicyManager::getInputForAttr处理,重点查看该函数。
3.2.1 device获取
java层除了三大参数外,还传下来了source,常用的有mic和voice_communication
这个source决定了选择什么样的audio_device,也就是xml文件中定义的device_port信息。
这里的type为"AUDIO_DEVICE_IN_BUILTIN_MIC"很关键。
device_port可以分为输入和输出设备,加载xml文件的时候都存储为DeviceDescriptor。
然后再实际使用的时候会区分为AudioInputDescriptor和SwAudioOutputDescriptor。
其实AudioInputDescriptor中的mDevice会存放DeviceDescriptor,两者的最关键的联系是DeviceDescriptor把type交给了AudioInputDescriptor。
可以查看AudioInputDescriptor::open函数。
<!-- device_port -->
<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"/>
</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>
//根据传入的source选择audio_device
audio_devices_t deviceType = getDeviceForInputSource(attr.source);
3.2.2 profile获取
AudioPolicyManager::getInputForAttr --> AudioPolicyManager::getInputForDevice --> AudioPolicyManager::getInputProfile
在getInputProfile中可以看到传入的参数在这里选择了合适的profile(即xml中,mixer_port下的profile)。
获取完合适的profile之后,会创建AudioInputDescriptor,将获取的profile作为入参传入,并打开。
AudioInputDescriptor::open最终会打开stream,执行到adev_open_input_stream。
3.2.3 小结
- 根据传入的source,获取DeviceDescriptor
- AudioPolicyManager::getInputProfile根据传入的三大参数(Sample_rate,Channel,Format),选择合适的profile
- 创建AudioInputDescriptor,此时将profile作为入参传入
- 将profile的三大参数存为config
- 打开AudioInputDescriptor,最终调用到adev_open_input_stream。
4 问题小结
1、 profile怎么选择 —— ok
AudioPolicyManager::getInputProfile
根据传入的三大参数(Sample_rate,Channel,Format),四种优先顺序,选择合适的profile
2、 AudioInputDescriptor和DeviceDescriptor差异 —— ok
AudioInputDescriptor::open
其实AudioInputDescriptor中的mDevice会存放DeviceDescriptor,两者的最关键的联系是DeviceDescriptor把type交给了AudioInputDescriptor。
3、route如何关联两个port
HwModule::refreshSupportedDevices
5 参考文章
Android开发之音频配置文件audio_policy_configuration.xml解析全过程
Android开发之音频配置文件audio_policy.conf解析全过程