关于audio_policy.conf文件
2018-01-02 20:44 wulizhi 阅读(6520) 评论(0) 编辑 收藏 举报Android系统可以通过配置audio_policy.conf文件,来实现不同产品的差异化,audio_policy.conf文件中,配置了当前项目audio策略中支持的输入输出设备,对应的播放模式,采样率,采样精度,声道数等等。例如下面:
1 Primary { 2 sampling_rates 44100|48000 3 channel_masks AUDIO_CHANNEL_OUT_STEREO 4 formats AUDIO_FORMAT_PCM_16_BIT 5 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_PROXY|AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET|AUDIO_DEVICE_OUT_FM|AUDIO_DEVICE_OUT_FM_TX 6 flags AUDIO_OUTPUT_FLAG_PRIMARY 7 } 8 low_latency { 9 sampling_rates 44100|48000 10 channel_masks AUDIO_CHANNEL_OUT_STEREO 11 formats AUDIO_FORMAT_PCM_16_BIT 12 devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET|AUDIO_DEVICE_OUT_FM|AUDIO_DEVICE_OUT_FM_TX 13 flags AUDIO_OUTPUT_FLAG_FAST 14 } 15 compress_offload { 16 sampling_rates 8000|11025|16000|22050|32000|44100|48000 17 channel_masks AUDIO_CHANNEL_OUT_MONO|AUDIO_CHANNEL_OUT_STEREO 18 formats AUDIO_FORMAT_MP3|AUDIO_FORMAT_AAC_LC|AUDIO_FORMAT_AAC_HE_V1|AUDIO_FORMAT_AAC_HE_V2 19 devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET|AUDIO_DEVICE_OUT_FM_TX 20 flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING 21 }
1 a2dp { 2 outputs { 3 a2dp { 4 sampling_rates 44100 5 channel_masks AUDIO_CHANNEL_OUT_STEREO 6 formats AUDIO_FORMAT_PCM_16_BIT 7 devices AUDIO_DEVICE_OUT_ALL_A2DP 8 } 9 } 10 } 11 usb { 12 outputs { 13 usb_accessory { 14 sampling_rates 44100 15 channel_masks AUDIO_CHANNEL_OUT_STEREO 16 formats AUDIO_FORMAT_PCM_16_BIT 17 devices AUDIO_DEVICE_OUT_USB_ACCESSORY 18 } 19 usb_device { 20 sampling_rates dynamic 21 channel_masks dynamic 22 formats dynamic 23 devices AUDIO_DEVICE_OUT_USB_DEVICE 24 } 25 } 26 inputs { 27 usb_device { 28 sampling_rates dynamic 29 channel_masks AUDIO_CHANNEL_IN_STEREO 30 formats AUDIO_FORMAT_PCM_16_BIT 31 devices AUDIO_DEVICE_IN_USB_DEVICE 32 } 33 } 34 }
在AudioPolicyManager中会解析此文件,获取此信息,那什么时候会需要修改此文件呢,例如:如果所在项目没有听筒设备,所以在接听电话的时候需要默认切换到喇叭输出,这个时候就需要修改此文件,把听筒设备AUDIO_DEVICE_OUT_EARPIECE从所有场景下支持的输出设备中删除,这样的话,就会切换到默认输出设备喇叭下。这个文件的信息,也可以通过指令
adb shell dumpsys media.audio_policy 打印出来,如下:
1 HW Modules dump: 2 - HW Module 1: 3 - name: primary 4 - handle: 1 5 - version: 2.0 6 - outputs: 7 output 0: 8 - name: primary 9 - sampling rates: 44100, 48000 10 - channel masks: 0x0003 11 - formats: AUDIO_FORMAT_PCM_16_BIT 12 - flags: 0x0002 13 - devices: 14 Device 1: 15 - type: AUDIO_DEVICE_OUT_EARPIECE 16 Device 2: 17 - type: AUDIO_DEVICE_OUT_SPEAKER 18 Device 3: 19 - type: AUDIO_DEVICE_OUT_WIRED_HEADSET 20 Device 4: 21 - type: AUDIO_DEVICE_OUT_WIRED_HEADPHONE 22 Device 5: 23 - type: AUDIO_DEVICE_OUT_ALL_SCO 24 Device 6: 25 - type: AUDIO_DEVICE_OUT_PROXY 26 Device 7: 27 - type: AUDIO_DEVICE_OUT_AUX_DIGITAL 28 Device 8: 29 - type: AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET 30 Device 9: 31 - type: AUDIO_DEVICE_OUT_FM 32 Device 10: 33 - type: AUDIO_DEVICE_OUT_FM_TX 34 output 1: 35 - name: low_latency 36 - sampling rates: 44100, 48000 37 - channel masks: 0x0003 38 - formats: AUDIO_FORMAT_PCM_16_BIT 39 - flags: 0x0004 40 - devices: 41 Device 1: 42 - type: AUDIO_DEVICE_OUT_SPEAKER 43 Device 2: 44 - type: AUDIO_DEVICE_OUT_EARPIECE 45 Device 3: 46 - type: AUDIO_DEVICE_OUT_WIRED_HEADSET 47 Device 4: 48 - type: AUDIO_DEVICE_OUT_WIRED_HEADPHONE 49 Device 5: 50 - type: AUDIO_DEVICE_OUT_ALL_SCO 51 Device 6: 52 - type: AUDIO_DEVICE_OUT_AUX_DIGITAL 53 Device 7: 54 - type: AUDIO_DEVICE_OUT_PROXY 55 Device 8: 56 - type: AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET 57 Device 9: 58 - type: AUDIO_DEVICE_OUT_FM 59 Device 10:
在文件系统里,有两个地方存放此文件/system/etc/audio_policy.conf 和 /vendor/etc/audio_policy.conf, 在创建AudioPolicyManager的时候会加载此配置文件:
1 AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface) 2 { 3 /*将默认输出设备设置成SPEAKER*/ 4 mDefaultOutputDevice = new DeviceDescriptor(String8(""), AUDIO_DEVICE_OUT_SPEAKER); 5 /*加载audio_policy.conf文件,先默认去加载vendor目录下的文件,如果找不到就去加载system目录下的*/ 6 if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) { 7 if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) { 8 ALOGE("could not load audio policy configuration file, setting defaults"); 9 /*如果两个目录都没有找到,就去加载一个默认的配置,默认的配置中会创建一个Primary module, 10 为它创建一个默认的输出设备speaker和默认输出设备主Mic. 11 */ 12 defaultAudioPolicyConfig(); 13 } 14 } 15 16 /*把所有的输入输出设备都会操作打开一遍,检查该设备是否是有效的*/ 17 // open all output streams needed to access attached devices 18 audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types(); 19 audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN; 20 for (size_t i = 0; i < mHwModules.size(); i++) { 21 mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName); 22 if (mHwModules[i]->mHandle == 0) { 23 ALOGW("could not open HW module %s", mHwModules[i]->mName); 24 continue; 25 } 26 // open all output streams needed to access attached devices 27 // except for direct output streams that are only opened when they are actually 28 // required by an app. 29 // This also validates mAvailableOutputDevices list 30 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) 31 { 32 const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j]; 33 34 if (outProfile->mSupportedDevices.isEmpty()) { 35 ALOGW("Output profile contains no device on module %s", mHwModules[i]->mName); 36 continue; 37 } 38 39 if ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) { 40 continue; 41 } 42 audio_devices_t profileType = outProfile->mSupportedDevices.types(); 43 if ((profileType & mDefaultOutputDevice->mDeviceType) != AUDIO_DEVICE_NONE) { 44 profileType = mDefaultOutputDevice->mDeviceType; 45 } else { 46 // chose first device present in mSupportedDevices also part of 47 // outputDeviceTypes 48 for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) { 49 profileType = outProfile->mSupportedDevices[k]->mDeviceType; 50 if ((profileType & outputDeviceTypes) != 0) { 51 break; 52 } 53 } 54 } 55 if ((profileType & outputDeviceTypes) == 0) { 56 continue; 57 } 58 sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(outProfile); 59 60 outputDesc->mDevice = profileType; 61 audio_config_t config = AUDIO_CONFIG_INITIALIZER; 62 config.sample_rate = outputDesc->mSamplingRate; 63 config.channel_mask = outputDesc->mChannelMask; 64 config.format = outputDesc->mFormat; 65 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE; 66 status_t status = mpClientInterface->openOutput(outProfile->mModule->mHandle, 67 &output, 68 &config, 69 &outputDesc->mDevice, 70 String8(""), 71 &outputDesc->mLatency, 72 outputDesc->mFlags); 73 74 if (status != NO_ERROR) { 75 ALOGW("Cannot open output stream for device %08x on hw module %s", 76 outputDesc->mDevice, 77 mHwModules[i]->mName); 78 } else { 79 outputDesc->mSamplingRate = config.sample_rate; 80 outputDesc->mChannelMask = config.channel_mask; 81 outputDesc->mFormat = config.format; 82 83 for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) { 84 audio_devices_t type = outProfile->mSupportedDevices[k]->mDeviceType; 85 ssize_t index = 86 mAvailableOutputDevices.indexOf(outProfile->mSupportedDevices[k]); 87 /*如果打开的输出设备有效,为它分配一个 有效的ID,赋值对应的module*/ 88 // give a valid ID to an attached device once confirmed it is reachable 89 if ((index >= 0) && (mAvailableOutputDevices[index]->mId == 0)) { 90 mAvailableOutputDevices[index]->mId = nextUniqueId(); 91 mAvailableOutputDevices[index]->mModule = mHwModules[i]; 92 } 93 } 94 if (mPrimaryOutput == 0 && 95 outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 96 mPrimaryOutput = output; 97 } 98 addOutput(output, outputDesc); 99 setOutputDevice(output, 100 outputDesc->mDevice, 101 true); 102 } 103 } 104 // open input streams needed to access attached devices to validate 105 // mAvailableInputDevices list 106 for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) 107 { 108 const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j]; 109 110 if (inProfile->mSupportedDevices.isEmpty()) { 111 ALOGW("Input profile contains no device on module %s", mHwModules[i]->mName); 112 continue; 113 } 114 // chose first device present in mSupportedDevices also part of 115 // inputDeviceTypes 116 audio_devices_t profileType = AUDIO_DEVICE_NONE; 117 for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) { 118 profileType = inProfile->mSupportedDevices[k]->mDeviceType; 119 if (profileType & inputDeviceTypes) { 120 break; 121 } 122 } 123 if ((profileType & inputDeviceTypes) == 0) { 124 continue; 125 } 126 sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(inProfile); 127 128 inputDesc->mInputSource = AUDIO_SOURCE_MIC; 129 inputDesc->mDevice = profileType; 130 131 // find the address 132 DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType); 133 // the inputs vector must be of size 1, but we don't want to crash here 134 String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress 135 : String8(""); 136 ALOGV(" for input device 0x%x using address %s", profileType, address.string()); 137 ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!"); 138 139 audio_config_t config = AUDIO_CONFIG_INITIALIZER; 140 config.sample_rate = inputDesc->mSamplingRate; 141 config.channel_mask = inputDesc->mChannelMask; 142 config.format = inputDesc->mFormat; 143 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE; 144 status_t status = mpClientInterface->openInput(inProfile->mModule->mHandle, 145 &input, 146 &config, 147 &inputDesc->mDevice, 148 address, 149 AUDIO_SOURCE_MIC, 150 AUDIO_INPUT_FLAG_NONE); 151 152 if (status == NO_ERROR) { 153 for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) { 154 audio_devices_t type = inProfile->mSupportedDevices[k]->mDeviceType; 155 ssize_t index = 156 mAvailableInputDevices.indexOf(inProfile->mSupportedDevices[k]); 157 // give a valid ID to an attached device once confirmed it is reachable 158 if ((index >= 0) && (mAvailableInputDevices[index]->mId == 0)) { 159 mAvailableInputDevices[index]->mId = nextUniqueId(); 160 mAvailableInputDevices[index]->mModule = mHwModules[i]; 161 } 162 } 163 mpClientInterface->closeInput(input); 164 } else { 165 ALOGW("Cannot open input stream for device %08x on hw module %s", 166 inputDesc->mDevice, 167 mHwModules[i]->mName); 168 } 169 } 170 } 171 172 /*确认mAvailableOutputDevices设备列表中的所有输出设备的id是有效的,如果无效,移除该设备*/ 173 // make sure all attached devices have been allocated a unique ID 174 for (size_t i = 0; i < mAvailableOutputDevices.size();) { 175 if (mAvailableOutputDevices[i]->mId == 0) { 176 ALOGW("Input device %08x unreachable", mAvailableOutputDevices[i]->mDeviceType); 177 mAvailableOutputDevices.remove(mAvailableOutputDevices[i]); 178 continue; 179 } 180 i++; 181 } 182 for (size_t i = 0; i < mAvailableInputDevices.size();) { 183 if (mAvailableInputDevices[i]->mId == 0) { 184 ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->mDeviceType); 185 mAvailableInputDevices.remove(mAvailableInputDevices[i]); 186 continue; 187 } 188 i++; 189 } 190 191 /*确认默认输出设备是有效的*/ 192 // make sure default device is reachable 193 if (mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) { 194 ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->mDeviceType); 195 } 196 197 ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output"); 198 199 /*更新下音频策略*/ 200 updateDevicesAndOutputs(); 201 }
在创建AudioPolicyManager的时候,会load audio_policy.conf文件建立起有效输出设备列表mAvailableOutputDevices 和有效输入设备列表mAvailableInputDevices。
1 status_t AudioPolicyManager::loadAudioPolicyConfig(const char *path) 2 { 3 cnode *root; 4 char *data; 5 6 data = (char *)load_file(path, NULL); 7 if (data == NULL) { 8 return -ENODEV; 9 } 10 root = config_node("", ""); 11 config_load(root, data); 12 13 /*根据配置文件支持的module,分别load audio.<primary/a2dp/usb>.<device>.so 这三个so文件 */ 14 loadHwModules(root); 15 // legacy audio_policy.conf files have one global_configuration section 16 /*加载audio_policy.conf 中的global_configuration 配置*/ 17 loadGlobalConfig(root, getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)); 18 config_free(root); 19 free(root); 20 free(data); 21 22 ALOGI("loadAudioPolicyConfig() loaded %s\n", path); 23 } 24 25
配置文件中可以看到,一般平台都会支持primary, a2dp, usb三中输出方式,所以,这里会分别load三个module的so文件。如果两个地方配置文件找不到,也会创建一个默认的primary module来进行音频的输入输出。
为什么会想到看这个呢,是因为在播放的音乐的时候,选用播放模式的时候,会判断是否可以用compress_offload模式,其中,有一项判断,就是判断它的设置是否在compress_offload支持的范围,而compress_offload支持的参数,就是在此conf文件中配置的。
例如,它支持8k~48k之间的采样率,支持MP3,AAC格式,支持常见的喇叭,听筒,耳机等输出,如果设置的参数,不在此配置内,就不能使用compress_offload模式进行播放
1 compress_offload { 2 sampling_rates 8000|11025|16000|22050|32000|44100|48000 3 channel_masks AUDIO_CHANNEL_OUT_MONO|AUDIO_CHANNEL_OUT_STEREO 4 formats AUDIO_FORMAT_MP3|AUDIO_FORMAT_AAC_LC|AUDIO_FORMAT_AAC_HE_V1|AUDIO_FORMAT_AAC_HE_V2 5 devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET|AUDIO_DEVICE_OUT_FM_TX 6 flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING
2018/03/14 补充:
在旧的平台中,所有的音频策略的配置都是在audio_policy.conf文件中配置的,但新的平台改到audio_policy_configuration.xml文件中配置了,大致内容一致。具体使用哪个文件是由USE_XML_AUDIO_POLICY_CONF 宏来控制,文件的解析和读取是在AudioPolicyManager.cpp构造函数中。下面针对此做些小总结:
- USE_XML_AUDIO_POLICY_CONF 宏定义在hardware/qcom/audio/configs/sdm845/sdm845.mk 文件中
- audio_policy.conf和audio_policy_configuration.xml文件默认都放在源码的 hardware/qcom/audio/configs/sdm845/目录下
- 在解析读取中,会依次读取/odm/etc/, /vendor/etc/audio/, /vendor/etc/, /system/etc/这四个目录
- 编译的时候拷贝的是哪个目录下面的配置文件,具体可参考hardware/qcom/audio/configs/sdm845/sdm845.mk文件
- 每次修改完文件,可以使用dumpsys media.audio_policy 查看修改是否已经生效,再进行测试。
- 关于audio_policy配置文件作用,audio_policy文件为音频策略配置文件,里面配置此机器支持的输入输出设备即及对应支持的采样率,声道数和采样精度。可根据项目具体 需求对其做一定程度的更改