启用 AAOS 路由
xref: /packages/services/Car/service/res/values/config.xml
- <resources>
- <bool name="audioUseDynamicRouting">true</bool>
- </resources>
复制代码 假如设为 false,路由和大部分 CarAudioService 将被停用,并且 AAOS 会回退到 AudioService 的默认举动。
xref: /packages/services/Car/service/src/com/android/car/audio/CarAudioService.java
- 202 public CarAudioService(Context context) {
- 203 mContext = context;
- 204 mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
- 205 mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
- 206 mUseDynamicRouting = mContext.getResources().getBoolean(R.bool.audioUseDynamicRouting);
- 207 mPersistMasterMuteState = mContext.getResources().getBoolean(
- 208 R.bool.audioPersistMasterMuteState);
- 209 mUidToZoneMap = new HashMap<>();
- 210 }
- 211
- 212 /**
- 213 * Dynamic routing and volume groups are set only if
- 214 * {@link #mUseDynamicRouting} is {@code true}. Otherwise, this service runs in legacy mode.
- 215 */
- 216 @Override
- 217 public void init() {
- 218 synchronized (mImplLock) {
- 219 if (mUseDynamicRouting) {
- 220 // Enumerate all output bus device ports
- 221 AudioDeviceInfo[] deviceInfos = mAudioManager.getDevices(
- 222 AudioManager.GET_DEVICES_OUTPUTS);
- 223 if (deviceInfos.length == 0) {
- 224 Log.e(CarLog.TAG_AUDIO, "No output device available, ignore");
- 225 return;
- 226 }
- 227 SparseArray<CarAudioDeviceInfo> busToCarAudioDeviceInfo = new SparseArray<>();
- 228 for (AudioDeviceInfo info : deviceInfos) {
- 229 Log.v(CarLog.TAG_AUDIO, String.format("output id=%d address=%s type=%s",
- 230 info.getId(), info.getAddress(), info.getType()));
- 231 if (info.getType() == AudioDeviceInfo.TYPE_BUS) {
- 232 final CarAudioDeviceInfo carInfo = new CarAudioDeviceInfo(info);
- 233 // See also the audio_policy_configuration.xml,
- 234 // the bus number should be no less than zero.
- 235 if (carInfo.getBusNumber() >= 0) {
- 236 busToCarAudioDeviceInfo.put(carInfo.getBusNumber(), carInfo);
- 237 Log.i(CarLog.TAG_AUDIO, "Valid bus found " + carInfo);
- 238 }
- 239 }
- 240 }
- 241 setupDynamicRouting(busToCarAudioDeviceInfo);
- 242 } else {
- 243 Log.i(CarLog.TAG_AUDIO, "Audio dynamic routing not enabled, run in legacy mode");
- 244 setupLegacyVolumeChangedListener();
- 245 }
- 246
- 247 // Restore master mute state if applicable
- 248 if (mPersistMasterMuteState) {
- 249 boolean storedMasterMute = Settings.Global.getInt(mContext.getContentResolver(),
- 250 VOLUME_SETTINGS_KEY_MASTER_MUTE, 0) != 0;
- 251 setMasterMute(storedMasterMute, 0);
- 252 }
- 253 }
- 254 }
复制代码 解析config.xml文件,假如audioUseDynamicRouting是true,则mUseDynamicRouting也是true,实行init函数的时候将走动态路由计谋。
a.通过AudioManager获取到以是输出总线设备
b.过滤出type是AudioDeviceInfo.TYPE_BUS的输出设备,然后重新封装到CarAudioDeviceInfo中
c.设置动态路由
xref: /packages/services/Car/service/src/com/android/car/audio/CarAudioDeviceInfo.java
- 41 /**
- 42 * Parse device address. Expected format is BUS%d_%s, address, usage hint
- 43 * @return valid address (from 0 to positive) or -1 for invalid address.
- 44 */
- 45 static int parseDeviceAddress(String address) {
- 46 String[] words = address.split("_");
- 47 int addressParsed = -1;
- 48 if (words[0].toLowerCase().startsWith("bus")) {
- 49 try {
- 50 addressParsed = Integer.parseInt(words[0].substring(3));
- 51 } catch (NumberFormatException e) {
- 52 //ignore
- 53 }
- 54 }
- 55 if (addressParsed < 0) {
- 56 return -1;
- 57 }
- 58 return addressParsed;
- 59 }
- .....................................
- 77 CarAudioDeviceInfo(AudioDeviceInfo audioDeviceInfo) {
- 78 mAudioDeviceInfo = audioDeviceInfo;
- 79 mBusNumber = parseDeviceAddress(audioDeviceInfo.getAddress());
- 80 mSampleRate = getMaxSampleRate(audioDeviceInfo);
- 81 mEncodingFormat = getEncodingFormat(audioDeviceInfo);
- 82 mChannelCount = getMaxChannels(audioDeviceInfo);
- 83 final AudioGain audioGain = Preconditions.checkNotNull(
- 84 getAudioGain(), "No audio gain on device port " + audioDeviceInfo);
- 85 mDefaultGain = audioGain.defaultValue();
- 86 mMaxGain = audioGain.maxValue();
- 87 mMinGain = audioGain.minValue();
- 88
- 89 mCurrentGain = -1; // Not initialized till explicitly set
- 90 }
复制代码 解析device address获取到busNumber,找到bus和第一个"_"中心的字符截取出来转成int。
xref: /packages/services/Car/service/src/com/android/car/audio/CarAudioService.java
- 99 private static final String[] AUDIO_CONFIGURATION_PATHS = new String[] {
- 100 "/vendor/etc/car_audio_configuration.xml",
- 101 "/system/etc/car_audio_configuration.xml"
- 102 };
- ...........................
- 439 private void setupDynamicRouting(SparseArray<CarAudioDeviceInfo> busToCarAudioDeviceInfo) {
- 440 final AudioPolicy.Builder builder = new AudioPolicy.Builder(mContext);
- 441 builder.setLooper(Looper.getMainLooper());
- 442
- 443 mCarAudioConfigurationPath = getAudioConfigurationPath();
- 444 if (mCarAudioConfigurationPath != null) {
- 445 try (InputStream inputStream = new FileInputStream(mCarAudioConfigurationPath)) {
- 446 CarAudioZonesHelper zonesHelper = new CarAudioZonesHelper(mContext, inputStream,
- 447 busToCarAudioDeviceInfo);
- 448 mCarAudioZones = zonesHelper.loadAudioZones();
- 449 } catch (IOException | XmlPullParserException e) {
- 450 throw new RuntimeException("Failed to parse audio zone configuration", e);
- 451 }
- 452 } else {
- 453 // In legacy mode, context -> bus mapping is done by querying IAudioControl HAL.
- 454 final IAudioControl audioControl = getAudioControl();
- 455 if (audioControl == null) {
- 456 throw new RuntimeException(
- 457 "Dynamic routing requested but audioControl HAL not available");
- 458 }
- 459 CarAudioZonesHelperLegacy legacyHelper = new CarAudioZonesHelperLegacy(mContext,
- 460 R.xml.car_volume_groups, busToCarAudioDeviceInfo, audioControl);
- 461 mCarAudioZones = legacyHelper.loadAudioZones();
- 462 }
- 463 for (CarAudioZone zone : mCarAudioZones) {
- 464 if (!zone.validateVolumeGroups()) {
- 465 throw new RuntimeException("Invalid volume groups configuration");
- 466 }
- 467 // Ensure HAL gets our initial value
- 468 zone.synchronizeCurrentGainIndex();
- 469 Log.v(CarLog.TAG_AUDIO, "Processed audio zone: " + zone);
- 470 }
- 471
- 472 // Setup dynamic routing rules by usage
- 473 final CarAudioDynamicRouting dynamicRouting = new CarAudioDynamicRouting(mCarAudioZones);
- 474 dynamicRouting.setupAudioDynamicRouting(builder);
- 475
- 476 // Attach the {@link AudioPolicyVolumeCallback}
- 477 builder.setAudioPolicyVolumeCallback(mAudioPolicyVolumeCallback);
- 478
- 479 if (sUseCarAudioFocus) {
- 480 // Configure our AudioPolicy to handle focus events.
- 481 // This gives us the ability to decide which audio focus requests to accept and bypasses
- 482 // the framework ducking logic.
- 483 mFocusHandler = new CarZonesAudioFocus(mAudioManager,
- 484 mContext.getPackageManager(),
- 485 mCarAudioZones);
- 486 builder.setAudioPolicyFocusListener(mFocusHandler);
- 487 builder.setIsAudioFocusPolicy(true);
- 488 }
- 489
- 490 mAudioPolicy = builder.build();
- 491 if (sUseCarAudioFocus) {
- 492 // Connect the AudioPolicy and the focus listener
- 493 mFocusHandler.setOwningPolicy(this, mAudioPolicy);
- 494 }
- 495
- 496 int r = mAudioManager.registerAudioPolicy(mAudioPolicy);
- 497 if (r != AudioManager.SUCCESS) {
- 498 throw new RuntimeException("registerAudioPolicy failed " + r);
- 499 }
- 500 }
复制代码 通过getAudioConfigurationPath获取配置文件路径,然后解析配置文件。
xref: /packages/services/Car/service/src/com/android/car/audio/CarAudioZonesHelper.java
- 64 private static final Map<String, Integer> CONTEXT_NAME_MAP;
- 65
- 66 static {
- 67 CONTEXT_NAME_MAP = new HashMap<>();
- 68 CONTEXT_NAME_MAP.put("music", ContextNumber.MUSIC);
- 69 CONTEXT_NAME_MAP.put("navigation", ContextNumber.NAVIGATION);
- 70 CONTEXT_NAME_MAP.put("voice_command", ContextNumber.VOICE_COMMAND);
- 71 CONTEXT_NAME_MAP.put("call_ring", ContextNumber.CALL_RING);
- 72 CONTEXT_NAME_MAP.put("call", ContextNumber.CALL);
- 73 CONTEXT_NAME_MAP.put("alarm", ContextNumber.ALARM);
- 74 CONTEXT_NAME_MAP.put("notification", ContextNumber.NOTIFICATION);
- 75 CONTEXT_NAME_MAP.put("system_sound", ContextNumber.SYSTEM_SOUND);
- 76 }
- ......................................
- 232 private void parseVolumeGroupContexts(
- 233 XmlPullParser parser, CarVolumeGroup group, int busNumber)
- 234 throws XmlPullParserException, IOException {
- 235 while (parser.next() != XmlPullParser.END_TAG) {
- 236 if (parser.getEventType() != XmlPullParser.START_TAG) continue;
- 237 if (TAG_CONTEXT.equals(parser.getName())) {
- 238 group.bind(
- 239 parseContextNumber(parser.getAttributeValue(NAMESPACE, ATTR_CONTEXT_NAME)),
- 240 busNumber, mBusToCarAudioDeviceInfo.get(busNumber));
- 241 }
- 242 // Always skip to upper level since we're at the lowest.
- 243 skip(parser);
- 244 }
- 245 }
- ......................................
- 264 private int parseContextNumber(String context) {
- 265 return CONTEXT_NAME_MAP.getOrDefault(context.toLowerCase(), ContextNumber.INVALID);
- 266 }
复制代码 xref: /packages/services/Car/service/src/com/android/car/audio/CarVolumeGroup.java
- 134 /**
- 135 * Binds the context number to physical bus number and audio device port information.
- 136 * Because this may change the groups min/max values, thus invalidating an index computed from
- 137 * a gain before this call, all calls to this function must happen at startup before any
- 138 * set/getGainIndex calls.
- 139 *
- 140 * @param contextNumber Context number as defined in audio control HAL
- 141 * @param busNumber Physical bus number for the audio device port
- 142 * @param info {@link CarAudioDeviceInfo} instance relates to the physical bus
- 143 */
- 144 void bind(int contextNumber, int busNumber, CarAudioDeviceInfo info) {
- 145 if (mBusToCarAudioDeviceInfo.size() == 0) {
- 146 mStepSize = info.getAudioGain().stepValue();
- 147 } else {
- 148 Preconditions.checkArgument(
- 149 info.getAudioGain().stepValue() == mStepSize,
- 150 "Gain controls within one group must have same step value");
- 151 }
- 152
- 153 mContextToBus.put(contextNumber, busNumber);
- 154 mBusToCarAudioDeviceInfo.put(busNumber, info);
- 155
- 156 if (info.getDefaultGain() > mDefaultGain) {
- 157 // We're arbitrarily selecting the highest bus default gain as the group's default.
- 158 mDefaultGain = info.getDefaultGain();
- 159 }
- 160 if (info.getMaxGain() > mMaxGain) {
- 161 mMaxGain = info.getMaxGain();
- 162 }
- 163 if (info.getMinGain() < mMinGain) {
- 164 mMinGain = info.getMinGain();
- 165 }
- 166 if (mStoredGainIndex < getMinGainIndex() || mStoredGainIndex > getMaxGainIndex()) {
- 167 // We expected to load a value from last boot, but if we didn't (perhaps this is the
- 168 // first boot ever?), then use the highest "default" we've seen to initialize
- 169 // ourselves.
- 170 mCurrentGainIndex = getIndexForGain(mDefaultGain);
- 171 } else {
- 172 // Just use the gain index we stored last time the gain was set (presumably during our
- 173 // last boot cycle).
- 174 mCurrentGainIndex = mStoredGainIndex;
- 175 }
- 176 }
复制代码 mContextToBus.put(contextNumber, busNumber);将contextNumber与busNumber 相对应。 mBusToCarAudioDeviceInfo.put(busNumber, info);将busNumber与info相对应。如许每个contextNumber都对应着具体的输出设备。接下来看contextNumber是如何产生的。
car_audio_configuration.xml
- 1 <?xml version="1.0" encoding="utf-8"?>
- 2 <carAudioConfiguration version="1">
- 3 <zones>
- 4 <zone name="primary zone" isPrimary="true">
- 5 <volumeGroups>
- 6 <group>
- 7 <device address="bus0_media_out">
- 8 <context context="music"/>
- 9 </device>
- 10 <device address="bus3_call_ring_out">
- 11 <context context="call_ring"/>
- 12 </device>
- 13 </group>
- 14 <group>
- 15 <device address="bus1_navigation_out">
- 16 <context context="navigation"/>
- 17 </device>
- 18 </group>
- 19 </volumeGroups>
- 20 <displays>
- 21 <display port="1"/>
- 22 <display port="2"/>
- 23 </displays>
- 24 </zone>
- 25 <zone name="rear seat zone">
- 26 <volumeGroups>
- 27 <group>
- 28 <device address="bus100_rear_seat">
- 29 <context context="music"/>
- 30 <context context="navigation"/>
- 31 <context context="voice_command"/>
- 32 <context context="call_ring"/>
- 33 <context context="call"/>
- 34 <context context="alarm"/>
- 35 <context context="notification"/>
- 36 <context context="system_sound"/>
- 37 </device>
- 38 </group>
- 39 </volumeGroups>
- 40 </zone>
- 41 </zones>
- 42 </carAudioConfiguration>
复制代码 audio_policy_configuration.xml
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- 2 <!-- Copyright (C) 2018 The Android Open Source Project
- 3
- 4 Licensed under the Apache License, Version 2.0 (the "License");
- 5 you may not use this file except in compliance with the License.
- 6 You may obtain a copy of the License at
- 7
- 8 http://www.apache.org/licenses/LICENSE-2.0
- 9
- 10 Unless required by applicable law or agreed to in writing, software
- 11 distributed under the License is distributed on an "AS IS" BASIS,
- 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- 13 See the License for the specific language governing permissions and
- 14 limitations under the License.
- 15 -->
- 16
- 17 <audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
- 18 <!-- version section contains a “version” tag in the form “major.minor” e.g version=”1.0” -->
- 19
- 20 <!-- Global configuration Decalaration -->
- 21 <globalConfiguration speaker_drc_enabled="true"/>
- 22
- 23 <!-- Modules section:
- 24 There is one section per audio HW module present on the platform.
- 25 Each module section will contains two mandatory tags for audio HAL “halVersion” and “name”.
- 26 The module names are the same as in current .conf file:
- 27 “primary”, “A2DP”, “remote_submix”, “USB”
- 28 Each module will contain the following sections:
- 29 “devicePorts”: a list of device descriptors for all input and output devices accessible via this
- 30 module.
- 31 This contains both permanently attached devices and removable devices.
- 32 "gain": constraints applied to the millibel values:
- 33 - maxValueMB >= minValueMB
- 34 - defaultValueMB >= minValueMB && defaultValueMB <= maxValueMB
- 35 - (maxValueMB - minValueMB) % stepValueMB == 0
- 36 - (defaultValueMB - minValueMB) % stepValueMB == 0
- 37 “mixPorts”: listing all output and input streams exposed by the audio HAL
- 38 “routes”: list of possible connections between input and output devices or between stream and
- 39 devices.
- 40 "route": is defined by an attribute:
- 41 -"type": <mux|mix> means all sources are mutual exclusive (mux) or can be mixed (mix)
- 42 -"sink": the sink involved in this route
- 43 -"sources": all the sources than can be connected to the sink via vis route
- 44 “attachedDevices”: permanently attached devices.
- 45 The attachedDevices section is a list of devices names. The names correspond to device names
- 46 defined in <devicePorts> section.
- 47 “defaultOutputDevice”: device to be used by default when no policy rule applies
- 48 -->
- 49 <modules>
- 50 <!-- Primary Audio HAL -->
- 51 <module name="primary" halVersion="3.0">
- 52 <attachedDevices>
- 53 <!-- One bus per context -->
- 54 <item>bus0_media_out</item>
- 55 <item>bus1_navigation_out</item>
- 56 <item>bus2_voice_command_out</item>
- 57 <item>bus3_call_ring_out</item>
- 58 <item>bus4_call_out</item>
- 59 <item>bus5_alarm_out</item>
- 60 <item>bus6_notification_out</item>
- 61 <item>bus7_system_sound_out</item>
- 62 <item>bus100_rear_seat</item>
- 63 <item>Built-In Mic</item>
- 64 <item>Built-In Back Mic</item>
- 65 <item>Echo-Reference Mic</item>
- 66 <item>FM Tuner</item>
- 67 </attachedDevices>
- 68 <defaultOutputDevice>bus0_media_out</defaultOutputDevice>
- 69 <mixPorts>
- 70 <mixPort name="mixport_bus0_media_out" role="source"
- 71 flags="AUDIO_OUTPUT_FLAG_PRIMARY">
- 72 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 73 samplingRates="48000"
- 74 channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 75 </mixPort>
- 76 <mixPort name="mixport_bus1_navigation_out" role="source"
- 77 flags="AUDIO_OUTPUT_FLAG_PRIMARY">
- 78 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 79 samplingRates="48000"
- 80 channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 81 </mixPort>
- 82 <mixPort name="mixport_bus2_voice_command_out" role="source"
- 83 flags="AUDIO_OUTPUT_FLAG_PRIMARY">
- 84 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 85 samplingRates="48000"
- 86 channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 87 </mixPort>
- 88 <mixPort name="mixport_bus3_call_ring_out" role="source"
- 89 flags="AUDIO_OUTPUT_FLAG_PRIMARY">
- 90 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 91 samplingRates="48000"
- 92 channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 93 </mixPort>
- 94 <mixPort name="mixport_bus4_call_out" role="source"
- 95 flags="AUDIO_OUTPUT_FLAG_PRIMARY">
- 96 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 97 samplingRates="48000"
- 98 channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 99 </mixPort>
- 100 <mixPort name="mixport_bus5_alarm_out" role="source"
- 101 flags="AUDIO_OUTPUT_FLAG_PRIMARY">
- 102 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 103 samplingRates="48000"
- 104 channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 105 </mixPort>
- 106 <mixPort name="mixport_bus6_notification_out" role="source"
- 107 flags="AUDIO_OUTPUT_FLAG_PRIMARY">
- 108 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 109 samplingRates="48000"
- 110 channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 111 </mixPort>
- 112 <mixPort name="mixport_bus7_system_sound_out" role="source"
- 113 flags="AUDIO_OUTPUT_FLAG_PRIMARY">
- 114 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 115 samplingRates="48000"
- 116 channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 117 </mixPort>
- 118 <mixPort name="mixport_bus100_rear_seat" role="source"
- 119 flags="AUDIO_OUTPUT_FLAG_PRIMARY">
- 120 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 121 samplingRates="48000"
- 122 channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 123 </mixPort>
- 124 <mixPort name="primary input" role="sink">
- 125 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 126 samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
- 127 channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
- 128 </mixPort>
- 129 <mixPort name="mixport_tuner0" role="sink">
- 130 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 131 samplingRates="48000"
- 132 channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
- 133 </mixPort>
- 134 </mixPorts>
- 135 <devicePorts>
- 136 <devicePort tagName="bus0_media_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
- 137 address="bus0_media_out">
- 138 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 139 samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 140 <gains>
- 141 <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- 142 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
- 143 </gains>
- 144 </devicePort>
- 145 <devicePort tagName="bus1_navigation_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
- 146 address="bus1_navigation_out">
- 147 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 148 samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 149 <gains>
- 150 <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- 151 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
- 152 </gains>
- 153 </devicePort>
- 154 <devicePort tagName="bus2_voice_command_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
- 155 address="bus2_voice_command_out">
- 156 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 157 samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 158 <gains>
- 159 <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- 160 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
- 161 </gains>
- 162 </devicePort>
- 163 <devicePort tagName="bus3_call_ring_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
- 164 address="bus3_call_ring_out">
- 165 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 166 samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 167 <gains>
- 168 <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- 169 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
- 170 </gains>
- 171 </devicePort>
- 172 <devicePort tagName="bus4_call_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
- 173 address="bus4_call_out">
- 174 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 175 samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 176 <gains>
- 177 <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- 178 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
- 179 </gains>
- 180 </devicePort>
- 181 <devicePort tagName="bus5_alarm_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
- 182 address="bus5_alarm_out">
- 183 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 184 samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 185 <gains>
- 186 <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- 187 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
- 188 </gains>
- 189 </devicePort>
- 190 <devicePort tagName="bus6_notification_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
- 191 address="bus6_notification_out">
- 192 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 193 samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 194 <gains>
- 195 <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- 196 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
- 197 </gains>
- 198 </devicePort>
- 199 <devicePort tagName="bus7_system_sound_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
- 200 address="bus7_system_sound_out">
- 201 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 202 samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 203 <gains>
- 204 <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- 205 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
- 206 </gains>
- 207 </devicePort>
- 208 <devicePort tagName="bus100_rear_seat" role="sink" type="AUDIO_DEVICE_OUT_BUS"
- 209 address="bus100_rear_seat">
- 210 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 211 samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
- 212 <gains>
- 213 <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- 214 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
- 215 </gains>
- 216 </devicePort>
- 217 <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
- 218 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 219 samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
- 220 channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
- 221 </devicePort>
- 222 <devicePort tagName="Built-In Back Mic" type="AUDIO_DEVICE_IN_BACK_MIC" role="source">
- 223 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 224 samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
- 225 channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
- 226 </devicePort>
- 227 <devicePort tagName="Echo-Reference Mic" type="AUDIO_DEVICE_IN_ECHO_REFERENCE" role="source">
- 228 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 229 samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
- 230 channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
- 231 </devicePort>
- 232 <devicePort tagName="FM Tuner" type="AUDIO_DEVICE_IN_FM_TUNER" role="source"
- 233 address="tuner0">
- 234 <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
- 235 samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
- 236 <gains>
- 237 <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
- 238 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
- 239 </gains>
- 240 </devicePort>
- 241 </devicePorts>
- 242 <!-- route declaration, i.e. list all available sources for a given sink -->
- 243 <routes>
- 244 <route type="mix" sink="bus0_media_out" sources="mixport_bus0_media_out"/>
- 245 <route type="mix" sink="bus1_navigation_out" sources="mixport_bus1_navigation_out"/>
- 246 <route type="mix" sink="bus2_voice_command_out" sources="mixport_bus2_voice_command_out"/>
- 247 <route type="mix" sink="bus3_call_ring_out" sources="mixport_bus3_call_ring_out"/>
- 248 <route type="mix" sink="bus4_call_out" sources="mixport_bus4_call_out"/>
- 249 <route type="mix" sink="bus5_alarm_out" sources="mixport_bus5_alarm_out"/>
- 250 <route type="mix" sink="bus6_notification_out" sources="mixport_bus6_notification_out"/>
- 251 <route type="mix" sink="bus7_system_sound_out" sources="mixport_bus7_system_sound_out"/>
- 252 <route type="mix" sink="bus100_rear_seat" sources="mixport_bus100_rear_seat"/>
- 253 <route type="mix" sink="primary input" sources="Built-In Mic,Built-In Back Mic,Echo-Reference Mic"/>
- 254 <route type="mix" sink="mixport_tuner0" sources="FM Tuner"/>
- 255 </routes>
- 256
- 257 </module>
- 258
- 259 <!-- A2dp Audio HAL -->
- 260 <xi:include href="a2dp_audio_policy_configuration.xml"/>
- 261
- 262 <!-- Usb Audio HAL -->
- 263 <xi:include href="usb_audio_policy_configuration.xml"/>
- 264
- 265 <!-- Remote Submix Audio HAL -->
- 266 <xi:include href="r_submix_audio_policy_configuration.xml"/>
- 267
- 268 </modules>
- 269 <!-- End of Modules section -->
- 270
- 271 <!-- Volume section -->
- 272
- 273 <xi:include href="audio_policy_volumes.xml"/>
- 274 <xi:include href="default_volume_tables.xml"/>
- 275
- 276 <!-- End of Volume section -->
- 277 <!-- End of Modules section -->
- 278
- 279 </audioPolicyConfiguration>
复制代码 通过CONTEXT_NAME_MAP关系,根据context可以找到contextNumber。
xref: /packages/services/Car/service/src/com/android/car/audio/CarAudioService.java
- 472 // Setup dynamic routing rules by usage
- 473 final CarAudioDynamicRouting dynamicRouting = new CarAudioDynamicRouting(mCarAudioZones);
- 474 dynamicRouting.setupAudioDynamicRouting(builder);
复制代码 通过usage设置动态路由计谋
xref: /packages/services/Car/service/src/com/android/car/audio/CarAudioDynamicRouting.java
- 50 static final SparseIntArray USAGE_TO_CONTEXT = new SparseIntArray();
- ...............................................
- 67 static {
- 68 USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_UNKNOWN, ContextNumber.MUSIC);
- 69 USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_MEDIA, ContextNumber.MUSIC);
- 70 USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_VOICE_COMMUNICATION, ContextNumber.CALL);
- 71 USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING,
- 72 ContextNumber.CALL);
- 73 USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_ALARM, ContextNumber.ALARM);
- 74 USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_NOTIFICATION, ContextNumber.NOTIFICATION);
- 75 USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_NOTIFICATION_RINGTONE, ContextNumber.CALL_RING);
- 76 USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST,
- 77 ContextNumber.NOTIFICATION);
- 78 USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT,
- 79 ContextNumber.NOTIFICATION);
- 80 USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_DELAYED,
- 81 ContextNumber.NOTIFICATION);
- 82 USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_NOTIFICATION_EVENT, ContextNumber.NOTIFICATION);
- 83 USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY,
- 84 ContextNumber.VOICE_COMMAND);
- 85 USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
- 86 ContextNumber.NAVIGATION);
- 87 USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION,
- 88 ContextNumber.SYSTEM_SOUND);
- 89 USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_GAME, ContextNumber.MUSIC);
- 90 USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_VIRTUAL_SOURCE, ContextNumber.INVALID);
- 91 USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_ASSISTANT, ContextNumber.VOICE_COMMAND);
- 92 }
- .......................................
- 100 void setupAudioDynamicRouting(AudioPolicy.Builder builder) {
- 101 for (CarAudioZone zone : mCarAudioZones) {
- 102 for (CarVolumeGroup group : zone.getVolumeGroups()) {
- 103 setupAudioDynamicRoutingForGroup(group, builder);
- 104 }
- 105 }
- 106 }
- 107
- 108 /**
- 109 * Enumerates all physical buses in a given volume group and attach the mixing rules.
- 110 * @param group {@link CarVolumeGroup} instance to enumerate the buses with
- 111 * @param builder {@link AudioPolicy.Builder} to attach the mixing rules
- 112 */
- 113 private void setupAudioDynamicRoutingForGroup(CarVolumeGroup group,
- 114 AudioPolicy.Builder builder) {
- 115 // Note that one can not register audio mix for same bus more than once.
- 116 for (int busNumber : group.getBusNumbers()) {
- 117 boolean hasContext = false;
- 118 CarAudioDeviceInfo info = group.getCarAudioDeviceInfoForBus(busNumber);
- 119 AudioFormat mixFormat = new AudioFormat.Builder()
- 120 .setSampleRate(info.getSampleRate())
- 121 .setEncoding(info.getEncodingFormat())
- 122 .setChannelMask(info.getChannelCount())
- 123 .build();
- 124 AudioMixingRule.Builder mixingRuleBuilder = new AudioMixingRule.Builder();
- 125 for (int contextNumber : group.getContextsForBus(busNumber)) {
- 126 hasContext = true;
- 127 int[] usages = getUsagesForContext(contextNumber);
- 128 for (int usage : usages) {
- 129 mixingRuleBuilder.addRule(
- 130 new AudioAttributes.Builder().setUsage(usage).build(),
- 131 AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE);
- 132 }
- 133 Log.d(CarLog.TAG_AUDIO, "Bus number: " + busNumber
- 134 + " contextNumber: " + contextNumber
- 135 + " sampleRate: " + info.getSampleRate()
- 136 + " channels: " + info.getChannelCount()
- 137 + " usages: " + Arrays.toString(usages));
- 138 }
- 139 if (hasContext) {
- 140 // It's a valid case that an audio output bus is defined in
- 141 // audio_policy_configuration and no context is assigned to it.
- 142 // In such case, do not build a policy mix with zero rules.
- 143 AudioMix audioMix = new AudioMix.Builder(mixingRuleBuilder.build())
- 144 .setFormat(mixFormat)
- 145 .setDevice(info.getAudioDeviceInfo())
- 146 .setRouteFlags(AudioMix.ROUTE_FLAG_RENDER)
- 147 .build();
- 148 builder.addMix(audioMix);
- 149 }
- 150 }
- 151 }
- 152
- 153 private int[] getUsagesForContext(int contextNumber) {
- 154 final List<Integer> usages = new ArrayList<>();
- 155 for (int i = 0; i < CarAudioDynamicRouting.USAGE_TO_CONTEXT.size(); i++) {
- 156 if (CarAudioDynamicRouting.USAGE_TO_CONTEXT.valueAt(i) == contextNumber) {
- 157 usages.add(CarAudioDynamicRouting.USAGE_TO_CONTEXT.keyAt(i));
- 158 }
- 159 }
- 160 return usages.stream().mapToInt(i -> i).toArray();
- 161 }
- 162 }
复制代码 通过contextNumber获取到usages,遍历usages将usage添加到mixingRuleBuilder中,然后再将mixingRuleBuilder添加到AudioMix中,将AudioMix addMix 到AudioPolicy中, 如许usage和device就关联上了。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |