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