介绍
音频无非是把音频数据放到指定的声卡上进行播放,音频路由就是要解决把某种类型的音频流,放到对应的声卡设备进行播放的策略。包括配置音频设备的采样率,播放类型,音频格式等。
音频路由策略配置
音频路由是通过配置audio_policy_configuration.xml
文件进行定制的。写明了audio音频部分有哪些设备、哪些流以及它们支持的编码、格式以及通道存储布局等。
节点 | 描述 |
---|---|
module | 音频模块,对应hal层不同的音频驱动程序。如module名称为primary对应的音频驱动为:audio.primary.$(variant).so |
attachedDevices | 所有的音频设备列表 |
defaultOutputDevice | 默认音频输出设备 |
mixPorts | 包含由音频 HAL 提供的所有输出声音流和输入声音流的列表。每个 mixPort 实例都可被视为传输到 Android AudioService 的物理声音流。 |
routes | 定义输入和输出设备之间或声音流和设备之间可能存在的连接的列表。 |
devicePorts | 包含可从此模块访问的所有输入和输出设备(包括永久连接的设备和可移除设备)的设备描述符列表。 |
profile | 用来描述音频设备支持的音频格式,采样率,声道等。 |
gain | 当前音频设备的增益 |
deviceport中的与车载平台相关的设备类型:
设备类型 | 说明 |
---|---|
AUDIO_DEVICE_OUT_BUS | Android 的主要输出(Android 的所有音频均通过这种方式提供给车辆) |
AUDIO_DEVICE_OUT_TELEPHONY_TX | 用于传输路由到手机无线装置的音频。 |
AUDIO_DEVICE_IN_BUS | 用于尚未进行分类的输入。 |
AUDIO_DEVICE_IN_FM_TUNER | 仅用于广播无线装置输入 |
AUDIO_DEVICE_IN_TV_TUNER | 用于电视设备(如果存在)。 |
AUDIO_DEVICE_IN_LINE | 用于 AUX 输入耳机插孔。 |
AUDIO_DEVICE_IN_BLUETOOTH_A2DP | 通过蓝牙接收到的音乐。 |
AUDIO_DEVICE_IN_TELEPHONY_RX | 用于从手机无线装置接收到的与通话相关联的音频。 |
audio_policy_configuration.xml
示例
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
<globalConfiguration speaker_drc_enabled="true"/>
<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>
<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_OUT_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"/>
</routes>
</module>
</audioPolicyConfiguration>
结合节点及属性我们可知,这个示例定义了:
1.定义了一个module,module中包含了一个音频设备devicePort,一个混音处理器mixPort,一个路由route。
2.devicePort名称为bus0_phone_out,在音频分区配置的时候也是根据这个设备地址进行关联配置。指定数据格式为AUDIO_FORMAT_PCM_16_BIT。
3.type为“AUDIO_DEVICE_OUT_BUS”,代表这是一个输出设备。
4.<route>表示将bus0_phone_out与mixport_bus0_phone_out链接,注意这俩个是一一对应的。将bus0_phone_out设备的输出流都传递到mixport_bus0_phone_out混音器中进行混音后播放输出。
car_audio_configuration.xml配置文件的加载
1.在AudioPolicyManager初始化的时候解析。
//frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
: AudioPolicyManager(clientInterface, false /*forTesting*/)
{
loadConfig();//加载配置
}
void AudioPolicyManager::loadConfig() {
if (deserializeAudioPolicyXmlConfig(getConfig()) != NO_ERROR) {//解析xml
ALOGE("could not load audio policy configuration file, setting defaults");
getConfig().setDefault();
}
}
static status_t deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) {
//判断文件是否存在
if (std::string audioPolicyXmlConfigFile = audio_get_audio_policy_config_file();
!audioPolicyXmlConfigFile.empty()) {
status_t ret = deserializeAudioPolicyFile(audioPolicyXmlConfigFile.c_str(), &config);
if (ret == NO_ERROR) {
config.setSource(audioPolicyXmlConfigFile);
}
return ret;
}
return BAD_VALUE;
}
audio_get_audio_policy_config_file
配置文件在audio_config.h
中进行了定义
system/media/audio/include/system/audio_config.h
static inline std::string audio_get_audio_policy_config_file() {
static constexpr const char *apmXmlConfigFileName = "audio_policy_configuration.xml";
...
return audioPolicyXmlConfigFile.empty() ?
audio_find_readable_configuration_file(apmXmlConfigFileName) : audioPolicyXmlConfigFile;
}
网友评论