Platform: RK3399
OS: Android 7.1
Kernel: v4.4.83
按模块划分,比如primary,a2dp, usb…
模块里包含硬件设备支持的参数,比如采样率、通道数、数据位深。
audio_hw_modules {
primary {
outputs {
primary {
sampling_rates 44100|48000
channel_masks AUDIO_CHANNEL_OUT_STEREO
formats AUDIO_FORMAT_PCM_16_BIT
devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_SPDIF
flags AUDIO_OUTPUT_FLAG_PRIMARY
}
hdmi {
sampling_rates 44100|48000|192000
channel_masks AUDIO_CHANNEL_OUT_5POINT1|AUDIO_CHANNEL_OUT_STEREO|AUDIO_CHANNEL_OUT_7POINT1
formats AUDIO_FORMAT_PCM_16_BIT
devices AUDIO_DEVICE_OUT_AUX_DIGITAL
flags AUDIO_OUTPUT_FLAG_DIRECT
}
}
}
a2dp {
outputs {
a2dp {
sampling_rates 44100
channel_masks AUDIO_CHANNEL_OUT_STEREO
formats AUDIO_FORMAT_PCM_16_BIT
devices AUDIO_DEVICE_OUT_ALL_A2DP
}
}
}
}
一般有两个地方:
#define AUDIO_POLICY_CONFIG_FILE "/system/etc/audio_policy.conf"
#define AUDIO_POLICY_VENDOR_CONFIG_FILE "/vendor/etc/audio_policy.conf"
一般它都是存在/system/etc/下。
AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface) {
......
//先看/vendor/etc/有没有
if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) {
//再看/system/etc/有没有
if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) {
ALOGE("could not load audio policy configuration file, setting defaults");
//没有就不用config文件,直接加载默认的配置了。
defaultAudioPolicyConfig();
}
}
......
}
默认配置:
void AudioPolicyManagerBase::defaultAudioPolicyConfig(void)
{
HwModule *module;
IOProfile *profile;
mDefaultOutputDevice = AUDIO_DEVICE_OUT_SPEAKER;
mAttachedOutputDevices = AUDIO_DEVICE_OUT_SPEAKER;
mAvailableInputDevices = AUDIO_DEVICE_IN_BUILTIN_MIC & ~AUDIO_DEVICE_BIT_IN;
//默认使用primary模块
module = new HwModule("primary");
//不管是输入还是输出都是以profile的形式保存
profile = new IOProfile(module);
profile->mSamplingRates.add(44100);
profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT);
profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO);
profile->mSupportedDevices = AUDIO_DEVICE_OUT_SPEAKER;
profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY;
module->mOutputProfiles.add(profile);
profile = new IOProfile(module);
profile->mSamplingRates.add(8000);
profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT);
profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO);
profile->mSupportedDevices = AUDIO_DEVICE_IN_BUILTIN_MIC;
module->mInputProfiles.add(profile);
mHwModules.add(module);
}
系统有不同的音频模块,比如primary,a2dp,usb等,每个模块对应有独立的so.如:
kris@eco:~/rk3399/out/target/product/rk3399_mid/system/vendor/lib/hw$ ls
audio.primary.rk30board.so
kris@eco:~/rk3399/out/target/product/rk3399_mid/system/lib/hw$ ls audio*
audio.a2dp.default.so audio.primary.default.so audio.usb.default.so
audio_policy.default.so audio.r_submix.default.so audio.vr_bee_hidraw.default.s
库名字的形式是 audio.
没有的话再加载default so。
库是否加载取决于audio_policy.conf中是否有配置,从上面的代码中看出 audio.primary.
当前使用哪个模块取决于上层参数的选择,比如拿录音举例:
代码会根据当前app使用的stream type确定对应的device
audio_devices_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource)
{
......
case AUDIO_SOURCE_VOICE_RECOGNITION:
case AUDIO_SOURCE_HOTWORD:
case AUDIO_SOURCE_VOICE_COMMUNICATION:
if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO &&
mAvailableInputDevices & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
} else if (mAvailableInputDevices & AUDIO_DEVICE_IN_WIRED_HEADSET) {
device = AUDIO_DEVICE_IN_WIRED_HEADSET;
} else if (mAvailableInputDevices & AUDIO_DEVICE_IN_USB_DEVICE) {
device = AUDIO_DEVICE_IN_USB_DEVICE;
} else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) {
//比如在audio_policy.conf中配置了
device = AUDIO_DEVICE_IN_BUILTIN_MIC;
}
break;
......
}
选择模块中对应的profile:
AudioPolicyManagerBase::IOProfile *AudioPolicyManagerBase::getInputProfile(audio_devices_t device,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask)
{
// Choose an input profile based on the requested capture parameters: select the first available
// profile supporting all requested parameters.
for (size_t i = 0; i < mHwModules.size(); i++)
{
......
for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
{
IOProfile *profile = mHwModules[i]->mInputProfiles[j];
// profile->log();
if (profile->isCompatibleProfile(device, samplingRate, format,
channelMask, AUDIO_OUTPUT_FLAG_NONE)) {
return profile;
}
}
}
return NULL;
}
匹配规则:
bool AudioPolicyManagerBase::IOProfile::isCompatibleProfile(...) const
{
if (samplingRate == 0 || !audio_is_valid_format(format) || channelMask == 0) {
return false;
}
if ((mSupportedDevices & device) != device) {
return false;
}
if ((mFlags & flags) != flags) {
return false;
}
size_t i;
for (i = 0; i < mSamplingRates.size(); i++)
{
if (mSamplingRates[i] == samplingRate) {
break;
}
}
if (i == mSamplingRates.size()) {
return false;
}
for (i = 0; i < mFormats.size(); i++)
{
if (mFormats[i] == format) {
break;
}
}
if (i == mFormats.size()) {
return false;
}
for (i = 0; i < mChannelMasks.size(); i++)
{
if (mChannelMasks[i] == channelMask) {
break;
}
}
if (i == mChannelMasks.size()) {
return false;
}
return true;
}
也就是说app设置的参数,不仅仅是device,还有采样率,格式和通道数要和audio_policy.conf的某个output/input完全匹配才可以。
audio_policy.conf文件分析