Android10 车载音频架构之动态路由的配置

打印 上一主题 下一主题

主题 984|帖子 984|积分 2952


启用 AAOS 路由
xref: /packages/services/Car/service/res/values/config.xml
  1. <resources>
  2.     <bool name="audioUseDynamicRouting">true</bool>
  3. </resources>
复制代码
假如设为 false,路由和大部分 CarAudioService 将被停用,并且 AAOS 会回退到 AudioService 的默认举动。
xref: /packages/services/Car/service/src/com/android/car/audio/CarAudioService.java
  1. 202      public CarAudioService(Context context) {
  2. 203          mContext = context;
  3. 204          mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
  4. 205          mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
  5. 206          mUseDynamicRouting = mContext.getResources().getBoolean(R.bool.audioUseDynamicRouting);
  6. 207          mPersistMasterMuteState = mContext.getResources().getBoolean(
  7. 208                  R.bool.audioPersistMasterMuteState);
  8. 209          mUidToZoneMap = new HashMap<>();
  9. 210      }
  10. 211  
  11. 212      /**
  12. 213       * Dynamic routing and volume groups are set only if
  13. 214       * {@link #mUseDynamicRouting} is {@code true}. Otherwise, this service runs in legacy mode.
  14. 215       */
  15. 216      @Override
  16. 217      public void init() {
  17. 218          synchronized (mImplLock) {
  18. 219              if (mUseDynamicRouting) {
  19. 220                  // Enumerate all output bus device ports
  20. 221                  AudioDeviceInfo[] deviceInfos = mAudioManager.getDevices(
  21. 222                          AudioManager.GET_DEVICES_OUTPUTS);
  22. 223                  if (deviceInfos.length == 0) {
  23. 224                      Log.e(CarLog.TAG_AUDIO, "No output device available, ignore");
  24. 225                      return;
  25. 226                  }
  26. 227                  SparseArray<CarAudioDeviceInfo> busToCarAudioDeviceInfo = new SparseArray<>();
  27. 228                  for (AudioDeviceInfo info : deviceInfos) {
  28. 229                      Log.v(CarLog.TAG_AUDIO, String.format("output id=%d address=%s type=%s",
  29. 230                              info.getId(), info.getAddress(), info.getType()));
  30. 231                      if (info.getType() == AudioDeviceInfo.TYPE_BUS) {
  31. 232                          final CarAudioDeviceInfo carInfo = new CarAudioDeviceInfo(info);
  32. 233                          // See also the audio_policy_configuration.xml,
  33. 234                          // the bus number should be no less than zero.
  34. 235                          if (carInfo.getBusNumber() >= 0) {
  35. 236                              busToCarAudioDeviceInfo.put(carInfo.getBusNumber(), carInfo);
  36. 237                              Log.i(CarLog.TAG_AUDIO, "Valid bus found " + carInfo);
  37. 238                          }
  38. 239                      }
  39. 240                  }
  40. 241                  setupDynamicRouting(busToCarAudioDeviceInfo);
  41. 242              } else {
  42. 243                  Log.i(CarLog.TAG_AUDIO, "Audio dynamic routing not enabled, run in legacy mode");
  43. 244                  setupLegacyVolumeChangedListener();
  44. 245              }
  45. 246  
  46. 247              // Restore master mute state if applicable
  47. 248              if (mPersistMasterMuteState) {
  48. 249                  boolean storedMasterMute = Settings.Global.getInt(mContext.getContentResolver(),
  49. 250                          VOLUME_SETTINGS_KEY_MASTER_MUTE, 0) != 0;
  50. 251                  setMasterMute(storedMasterMute, 0);
  51. 252              }
  52. 253          }
  53. 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
  1. 41      /**
  2. 42       * Parse device address. Expected format is BUS%d_%s, address, usage hint
  3. 43       * @return valid address (from 0 to positive) or -1 for invalid address.
  4. 44       */
  5. 45      static int parseDeviceAddress(String address) {
  6. 46          String[] words = address.split("_");
  7. 47          int addressParsed = -1;
  8. 48          if (words[0].toLowerCase().startsWith("bus")) {
  9. 49              try {
  10. 50                  addressParsed = Integer.parseInt(words[0].substring(3));
  11. 51              } catch (NumberFormatException e) {
  12. 52                  //ignore
  13. 53              }
  14. 54          }
  15. 55          if (addressParsed < 0) {
  16. 56              return -1;
  17. 57          }
  18. 58          return addressParsed;
  19. 59      }
  20. .....................................
  21. 77      CarAudioDeviceInfo(AudioDeviceInfo audioDeviceInfo) {
  22. 78          mAudioDeviceInfo = audioDeviceInfo;
  23. 79          mBusNumber = parseDeviceAddress(audioDeviceInfo.getAddress());
  24. 80          mSampleRate = getMaxSampleRate(audioDeviceInfo);
  25. 81          mEncodingFormat = getEncodingFormat(audioDeviceInfo);
  26. 82          mChannelCount = getMaxChannels(audioDeviceInfo);
  27. 83          final AudioGain audioGain = Preconditions.checkNotNull(
  28. 84                  getAudioGain(), "No audio gain on device port " + audioDeviceInfo);
  29. 85          mDefaultGain = audioGain.defaultValue();
  30. 86          mMaxGain = audioGain.maxValue();
  31. 87          mMinGain = audioGain.minValue();
  32. 88  
  33. 89          mCurrentGain = -1; // Not initialized till explicitly set
  34. 90      }
复制代码
解析device address获取到busNumber,找到bus和第一个"_"中心的字符截取出来转成int。

xref: /packages/services/Car/service/src/com/android/car/audio/CarAudioService.java
  1. 99      private static final String[] AUDIO_CONFIGURATION_PATHS = new String[] {
  2. 100              "/vendor/etc/car_audio_configuration.xml",
  3. 101              "/system/etc/car_audio_configuration.xml"
  4. 102      };
  5. ...........................
  6. 439      private void setupDynamicRouting(SparseArray<CarAudioDeviceInfo> busToCarAudioDeviceInfo) {
  7. 440          final AudioPolicy.Builder builder = new AudioPolicy.Builder(mContext);
  8. 441          builder.setLooper(Looper.getMainLooper());
  9. 442  
  10. 443          mCarAudioConfigurationPath = getAudioConfigurationPath();
  11. 444          if (mCarAudioConfigurationPath != null) {
  12. 445              try (InputStream inputStream = new FileInputStream(mCarAudioConfigurationPath)) {
  13. 446                  CarAudioZonesHelper zonesHelper = new CarAudioZonesHelper(mContext, inputStream,
  14. 447                          busToCarAudioDeviceInfo);
  15. 448                  mCarAudioZones = zonesHelper.loadAudioZones();
  16. 449              } catch (IOException | XmlPullParserException e) {
  17. 450                  throw new RuntimeException("Failed to parse audio zone configuration", e);
  18. 451              }
  19. 452          } else {
  20. 453              // In legacy mode, context -> bus mapping is done by querying IAudioControl HAL.
  21. 454              final IAudioControl audioControl = getAudioControl();
  22. 455              if (audioControl == null) {
  23. 456                  throw new RuntimeException(
  24. 457                          "Dynamic routing requested but audioControl HAL not available");
  25. 458              }
  26. 459              CarAudioZonesHelperLegacy legacyHelper = new CarAudioZonesHelperLegacy(mContext,
  27. 460                      R.xml.car_volume_groups, busToCarAudioDeviceInfo, audioControl);
  28. 461              mCarAudioZones = legacyHelper.loadAudioZones();
  29. 462          }
  30. 463          for (CarAudioZone zone : mCarAudioZones) {
  31. 464              if (!zone.validateVolumeGroups()) {
  32. 465                  throw new RuntimeException("Invalid volume groups configuration");
  33. 466              }
  34. 467              // Ensure HAL gets our initial value
  35. 468              zone.synchronizeCurrentGainIndex();
  36. 469              Log.v(CarLog.TAG_AUDIO, "Processed audio zone: " + zone);
  37. 470          }
  38. 471  
  39. 472          // Setup dynamic routing rules by usage
  40. 473          final CarAudioDynamicRouting dynamicRouting = new CarAudioDynamicRouting(mCarAudioZones);
  41. 474          dynamicRouting.setupAudioDynamicRouting(builder);
  42. 475  
  43. 476          // Attach the {@link AudioPolicyVolumeCallback}
  44. 477          builder.setAudioPolicyVolumeCallback(mAudioPolicyVolumeCallback);
  45. 478  
  46. 479          if (sUseCarAudioFocus) {
  47. 480              // Configure our AudioPolicy to handle focus events.
  48. 481              // This gives us the ability to decide which audio focus requests to accept and bypasses
  49. 482              // the framework ducking logic.
  50. 483              mFocusHandler = new CarZonesAudioFocus(mAudioManager,
  51. 484                      mContext.getPackageManager(),
  52. 485                      mCarAudioZones);
  53. 486              builder.setAudioPolicyFocusListener(mFocusHandler);
  54. 487              builder.setIsAudioFocusPolicy(true);
  55. 488          }
  56. 489  
  57. 490          mAudioPolicy = builder.build();
  58. 491          if (sUseCarAudioFocus) {
  59. 492              // Connect the AudioPolicy and the focus listener
  60. 493              mFocusHandler.setOwningPolicy(this, mAudioPolicy);
  61. 494          }
  62. 495  
  63. 496          int r = mAudioManager.registerAudioPolicy(mAudioPolicy);
  64. 497          if (r != AudioManager.SUCCESS) {
  65. 498              throw new RuntimeException("registerAudioPolicy failed " + r);
  66. 499          }
  67. 500      }
复制代码
        通过getAudioConfigurationPath获取配置文件路径,然后解析配置文件。
xref: /packages/services/Car/service/src/com/android/car/audio/CarAudioZonesHelper.java
  1. 64      private static final Map<String, Integer> CONTEXT_NAME_MAP;
  2. 65  
  3. 66      static {
  4. 67          CONTEXT_NAME_MAP = new HashMap<>();
  5. 68          CONTEXT_NAME_MAP.put("music", ContextNumber.MUSIC);
  6. 69          CONTEXT_NAME_MAP.put("navigation", ContextNumber.NAVIGATION);
  7. 70          CONTEXT_NAME_MAP.put("voice_command", ContextNumber.VOICE_COMMAND);
  8. 71          CONTEXT_NAME_MAP.put("call_ring", ContextNumber.CALL_RING);
  9. 72          CONTEXT_NAME_MAP.put("call", ContextNumber.CALL);
  10. 73          CONTEXT_NAME_MAP.put("alarm", ContextNumber.ALARM);
  11. 74          CONTEXT_NAME_MAP.put("notification", ContextNumber.NOTIFICATION);
  12. 75          CONTEXT_NAME_MAP.put("system_sound", ContextNumber.SYSTEM_SOUND);
  13. 76      }
  14. ......................................
  15. 232      private void parseVolumeGroupContexts(
  16. 233              XmlPullParser parser, CarVolumeGroup group, int busNumber)
  17. 234              throws XmlPullParserException, IOException {
  18. 235          while (parser.next() != XmlPullParser.END_TAG) {
  19. 236              if (parser.getEventType() != XmlPullParser.START_TAG) continue;
  20. 237              if (TAG_CONTEXT.equals(parser.getName())) {
  21. 238                  group.bind(
  22. 239                          parseContextNumber(parser.getAttributeValue(NAMESPACE, ATTR_CONTEXT_NAME)),
  23. 240                          busNumber, mBusToCarAudioDeviceInfo.get(busNumber));
  24. 241              }
  25. 242              // Always skip to upper level since we're at the lowest.
  26. 243              skip(parser);
  27. 244          }
  28. 245      }
  29. ......................................
  30. 264      private int parseContextNumber(String context) {
  31. 265          return CONTEXT_NAME_MAP.getOrDefault(context.toLowerCase(), ContextNumber.INVALID);
  32. 266      }
复制代码
xref: /packages/services/Car/service/src/com/android/car/audio/CarVolumeGroup.java
  1. 134      /**
  2. 135       * Binds the context number to physical bus number and audio device port information.
  3. 136       * Because this may change the groups min/max values, thus invalidating an index computed from
  4. 137       * a gain before this call, all calls to this function must happen at startup before any
  5. 138       * set/getGainIndex calls.
  6. 139       *
  7. 140       * @param contextNumber Context number as defined in audio control HAL
  8. 141       * @param busNumber Physical bus number for the audio device port
  9. 142       * @param info {@link CarAudioDeviceInfo} instance relates to the physical bus
  10. 143       */
  11. 144      void bind(int contextNumber, int busNumber, CarAudioDeviceInfo info) {
  12. 145          if (mBusToCarAudioDeviceInfo.size() == 0) {
  13. 146              mStepSize = info.getAudioGain().stepValue();
  14. 147          } else {
  15. 148              Preconditions.checkArgument(
  16. 149                      info.getAudioGain().stepValue() == mStepSize,
  17. 150                      "Gain controls within one group must have same step value");
  18. 151          }
  19. 152  
  20. 153          mContextToBus.put(contextNumber, busNumber);
  21. 154          mBusToCarAudioDeviceInfo.put(busNumber, info);
  22. 155  
  23. 156          if (info.getDefaultGain() > mDefaultGain) {
  24. 157              // We're arbitrarily selecting the highest bus default gain as the group's default.
  25. 158              mDefaultGain = info.getDefaultGain();
  26. 159          }
  27. 160          if (info.getMaxGain() > mMaxGain) {
  28. 161              mMaxGain = info.getMaxGain();
  29. 162          }
  30. 163          if (info.getMinGain() < mMinGain) {
  31. 164              mMinGain = info.getMinGain();
  32. 165          }
  33. 166          if (mStoredGainIndex < getMinGainIndex() || mStoredGainIndex > getMaxGainIndex()) {
  34. 167              // We expected to load a value from last boot, but if we didn't (perhaps this is the
  35. 168              // first boot ever?), then use the highest "default" we've seen to initialize
  36. 169              // ourselves.
  37. 170              mCurrentGainIndex = getIndexForGain(mDefaultGain);
  38. 171          } else {
  39. 172              // Just use the gain index we stored last time the gain was set (presumably during our
  40. 173              // last boot cycle).
  41. 174              mCurrentGainIndex = mStoredGainIndex;
  42. 175          }
  43. 176      }
复制代码
 mContextToBus.put(contextNumber, busNumber);将contextNumber与busNumber 相对应。 mBusToCarAudioDeviceInfo.put(busNumber, info);将busNumber与info相对应。如许每个contextNumber都对应着具体的输出设备。接下来看contextNumber是如何产生的。

car_audio_configuration.xml
  1. 1 <?xml version="1.0" encoding="utf-8"?>
  2. 2 <carAudioConfiguration version="1">
  3. 3     <zones>
  4. 4         <zone name="primary zone" isPrimary="true">
  5. 5             <volumeGroups>
  6. 6                 <group>
  7. 7                     <device address="bus0_media_out">
  8. 8                         <context context="music"/>
  9. 9                     </device>
  10. 10                     <device address="bus3_call_ring_out">
  11. 11                         <context context="call_ring"/>
  12. 12                     </device>
  13. 13                 </group>
  14. 14                 <group>
  15. 15                     <device address="bus1_navigation_out">
  16. 16                         <context context="navigation"/>
  17. 17                     </device>
  18. 18                 </group>
  19. 19             </volumeGroups>
  20. 20             <displays>
  21. 21                 <display port="1"/>
  22. 22                 <display port="2"/>
  23. 23             </displays>
  24. 24         </zone>
  25. 25         <zone name="rear seat zone">
  26. 26             <volumeGroups>
  27. 27                 <group>
  28. 28                     <device address="bus100_rear_seat">
  29. 29                         <context context="music"/>
  30. 30                         <context context="navigation"/>
  31. 31                         <context context="voice_command"/>
  32. 32                         <context context="call_ring"/>
  33. 33                         <context context="call"/>
  34. 34                         <context context="alarm"/>
  35. 35                         <context context="notification"/>
  36. 36                         <context context="system_sound"/>
  37. 37                     </device>
  38. 38                 </group>
  39. 39             </volumeGroups>
  40. 40         </zone>
  41. 41     </zones>
  42. 42 </carAudioConfiguration>
复制代码
audio_policy_configuration.xml
  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. 2 <!-- Copyright (C) 2018 The Android Open Source Project
  3. 3
  4. 4      Licensed under the Apache License, Version 2.0 (the "License");
  5. 5      you may not use this file except in compliance with the License.
  6. 6      You may obtain a copy of the License at
  7. 7
  8. 8           http://www.apache.org/licenses/LICENSE-2.0
  9. 9
  10. 10      Unless required by applicable law or agreed to in writing, software
  11. 11      distributed under the License is distributed on an "AS IS" BASIS,
  12. 12      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. 13      See the License for the specific language governing permissions and
  14. 14      limitations under the License.
  15. 15 -->
  16. 16
  17. 17 <audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
  18. 18     <!-- version section contains a “version” tag in the form “major.minor” e.g version=”1.0” -->
  19. 19
  20. 20     <!-- Global configuration Decalaration -->
  21. 21     <globalConfiguration speaker_drc_enabled="true"/>
  22. 22
  23. 23     <!-- Modules section:
  24. 24         There is one section per audio HW module present on the platform.
  25. 25         Each module section will contains two mandatory tags for audio HAL “halVersion” and “name”.
  26. 26         The module names are the same as in current .conf file:
  27. 27                 “primary”, “A2DP”, “remote_submix”, “USB”
  28. 28         Each module will contain the following sections:
  29. 29         “devicePorts”: a list of device descriptors for all input and output devices accessible via this
  30. 30         module.
  31. 31         This contains both permanently attached devices and removable devices.
  32. 32             "gain": constraints applied to the millibel values:
  33. 33                 - maxValueMB >= minValueMB
  34. 34                 - defaultValueMB >= minValueMB && defaultValueMB <= maxValueMB
  35. 35                 - (maxValueMB - minValueMB) % stepValueMB == 0
  36. 36                 - (defaultValueMB - minValueMB) % stepValueMB == 0
  37. 37         “mixPorts”: listing all output and input streams exposed by the audio HAL
  38. 38         “routes”: list of possible connections between input and output devices or between stream and
  39. 39         devices.
  40. 40             "route": is defined by an attribute:
  41. 41                 -"type": <mux|mix> means all sources are mutual exclusive (mux) or can be mixed (mix)
  42. 42                 -"sink": the sink involved in this route
  43. 43                 -"sources": all the sources than can be connected to the sink via vis route
  44. 44         “attachedDevices”: permanently attached devices.
  45. 45         The attachedDevices section is a list of devices names. The names correspond to device names
  46. 46         defined in <devicePorts> section.
  47. 47         “defaultOutputDevice”: device to be used by default when no policy rule applies
  48. 48     -->
  49. 49     <modules>
  50. 50         <!-- Primary Audio HAL -->
  51. 51         <module name="primary" halVersion="3.0">
  52. 52             <attachedDevices>
  53. 53                 <!-- One bus per context -->
  54. 54                 <item>bus0_media_out</item>
  55. 55                 <item>bus1_navigation_out</item>
  56. 56                 <item>bus2_voice_command_out</item>
  57. 57                 <item>bus3_call_ring_out</item>
  58. 58                 <item>bus4_call_out</item>
  59. 59                 <item>bus5_alarm_out</item>
  60. 60                 <item>bus6_notification_out</item>
  61. 61                 <item>bus7_system_sound_out</item>
  62. 62                 <item>bus100_rear_seat</item>
  63. 63                 <item>Built-In Mic</item>
  64. 64                 <item>Built-In Back Mic</item>
  65. 65                 <item>Echo-Reference Mic</item>
  66. 66                 <item>FM Tuner</item>
  67. 67             </attachedDevices>
  68. 68             <defaultOutputDevice>bus0_media_out</defaultOutputDevice>
  69. 69             <mixPorts>
  70. 70                 <mixPort name="mixport_bus0_media_out" role="source"
  71. 71                         flags="AUDIO_OUTPUT_FLAG_PRIMARY">
  72. 72                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  73. 73                              samplingRates="48000"
  74. 74                              channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  75. 75                 </mixPort>
  76. 76                 <mixPort name="mixport_bus1_navigation_out" role="source"
  77. 77                         flags="AUDIO_OUTPUT_FLAG_PRIMARY">
  78. 78                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  79. 79                              samplingRates="48000"
  80. 80                              channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  81. 81                 </mixPort>
  82. 82                 <mixPort name="mixport_bus2_voice_command_out" role="source"
  83. 83                         flags="AUDIO_OUTPUT_FLAG_PRIMARY">
  84. 84                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  85. 85                              samplingRates="48000"
  86. 86                              channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  87. 87                 </mixPort>
  88. 88                 <mixPort name="mixport_bus3_call_ring_out" role="source"
  89. 89                         flags="AUDIO_OUTPUT_FLAG_PRIMARY">
  90. 90                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  91. 91                              samplingRates="48000"
  92. 92                              channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  93. 93                 </mixPort>
  94. 94                 <mixPort name="mixport_bus4_call_out" role="source"
  95. 95                         flags="AUDIO_OUTPUT_FLAG_PRIMARY">
  96. 96                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  97. 97                              samplingRates="48000"
  98. 98                              channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  99. 99                 </mixPort>
  100. 100                 <mixPort name="mixport_bus5_alarm_out" role="source"
  101. 101                         flags="AUDIO_OUTPUT_FLAG_PRIMARY">
  102. 102                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  103. 103                              samplingRates="48000"
  104. 104                              channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  105. 105                 </mixPort>
  106. 106                 <mixPort name="mixport_bus6_notification_out" role="source"
  107. 107                         flags="AUDIO_OUTPUT_FLAG_PRIMARY">
  108. 108                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  109. 109                              samplingRates="48000"
  110. 110                              channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  111. 111                 </mixPort>
  112. 112                 <mixPort name="mixport_bus7_system_sound_out" role="source"
  113. 113                         flags="AUDIO_OUTPUT_FLAG_PRIMARY">
  114. 114                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  115. 115                              samplingRates="48000"
  116. 116                              channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  117. 117                 </mixPort>
  118. 118                 <mixPort name="mixport_bus100_rear_seat" role="source"
  119. 119                         flags="AUDIO_OUTPUT_FLAG_PRIMARY">
  120. 120                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  121. 121                              samplingRates="48000"
  122. 122                              channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  123. 123                 </mixPort>
  124. 124                 <mixPort name="primary input" role="sink">
  125. 125                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  126. 126                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
  127. 127                              channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
  128. 128                 </mixPort>
  129. 129                 <mixPort name="mixport_tuner0" role="sink">
  130. 130                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  131. 131                              samplingRates="48000"
  132. 132                              channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
  133. 133                 </mixPort>
  134. 134             </mixPorts>
  135. 135             <devicePorts>
  136. 136                 <devicePort tagName="bus0_media_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
  137. 137                         address="bus0_media_out">
  138. 138                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  139. 139                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  140. 140                     <gains>
  141. 141                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
  142. 142                                 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
  143. 143                     </gains>
  144. 144                 </devicePort>
  145. 145                 <devicePort tagName="bus1_navigation_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
  146. 146                         address="bus1_navigation_out">
  147. 147                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  148. 148                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  149. 149                     <gains>
  150. 150                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
  151. 151                                 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
  152. 152                     </gains>
  153. 153                 </devicePort>
  154. 154                 <devicePort tagName="bus2_voice_command_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
  155. 155                         address="bus2_voice_command_out">
  156. 156                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  157. 157                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  158. 158                     <gains>
  159. 159                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
  160. 160                                 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
  161. 161                     </gains>
  162. 162                 </devicePort>
  163. 163                 <devicePort tagName="bus3_call_ring_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
  164. 164                         address="bus3_call_ring_out">
  165. 165                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  166. 166                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  167. 167                     <gains>
  168. 168                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
  169. 169                                 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
  170. 170                     </gains>
  171. 171                 </devicePort>
  172. 172                 <devicePort tagName="bus4_call_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
  173. 173                         address="bus4_call_out">
  174. 174                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  175. 175                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  176. 176                     <gains>
  177. 177                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
  178. 178                                 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
  179. 179                     </gains>
  180. 180                 </devicePort>
  181. 181                 <devicePort tagName="bus5_alarm_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
  182. 182                         address="bus5_alarm_out">
  183. 183                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  184. 184                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  185. 185                     <gains>
  186. 186                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
  187. 187                                 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
  188. 188                     </gains>
  189. 189                 </devicePort>
  190. 190                 <devicePort tagName="bus6_notification_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
  191. 191                         address="bus6_notification_out">
  192. 192                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  193. 193                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  194. 194                     <gains>
  195. 195                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
  196. 196                                 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
  197. 197                     </gains>
  198. 198                 </devicePort>
  199. 199                 <devicePort tagName="bus7_system_sound_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
  200. 200                         address="bus7_system_sound_out">
  201. 201                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  202. 202                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  203. 203                     <gains>
  204. 204                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
  205. 205                                 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
  206. 206                     </gains>
  207. 207                 </devicePort>
  208. 208                 <devicePort tagName="bus100_rear_seat" role="sink" type="AUDIO_DEVICE_OUT_BUS"
  209. 209                         address="bus100_rear_seat">
  210. 210                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  211. 211                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  212. 212                     <gains>
  213. 213                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
  214. 214                                 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
  215. 215                     </gains>
  216. 216                 </devicePort>
  217. 217                 <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
  218. 218                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  219. 219                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
  220. 220                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
  221. 221                 </devicePort>
  222. 222                 <devicePort tagName="Built-In Back Mic" type="AUDIO_DEVICE_IN_BACK_MIC" role="source">
  223. 223                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  224. 224                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
  225. 225                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
  226. 226                 </devicePort>
  227. 227                 <devicePort tagName="Echo-Reference Mic" type="AUDIO_DEVICE_IN_ECHO_REFERENCE" role="source">
  228. 228                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  229. 229                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
  230. 230                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
  231. 231                 </devicePort>
  232. 232                 <devicePort tagName="FM Tuner" type="AUDIO_DEVICE_IN_FM_TUNER" role="source"
  233. 233                         address="tuner0">
  234. 234                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
  235. 235                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
  236. 236                     <gains>
  237. 237                         <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
  238. 238                                 minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
  239. 239                     </gains>
  240. 240                 </devicePort>
  241. 241             </devicePorts>
  242. 242             <!-- route declaration, i.e. list all available sources for a given sink -->
  243. 243             <routes>
  244. 244                 <route type="mix" sink="bus0_media_out" sources="mixport_bus0_media_out"/>
  245. 245                 <route type="mix" sink="bus1_navigation_out" sources="mixport_bus1_navigation_out"/>
  246. 246                 <route type="mix" sink="bus2_voice_command_out" sources="mixport_bus2_voice_command_out"/>
  247. 247                 <route type="mix" sink="bus3_call_ring_out" sources="mixport_bus3_call_ring_out"/>
  248. 248                 <route type="mix" sink="bus4_call_out" sources="mixport_bus4_call_out"/>
  249. 249                 <route type="mix" sink="bus5_alarm_out" sources="mixport_bus5_alarm_out"/>
  250. 250                 <route type="mix" sink="bus6_notification_out" sources="mixport_bus6_notification_out"/>
  251. 251                 <route type="mix" sink="bus7_system_sound_out" sources="mixport_bus7_system_sound_out"/>
  252. 252                 <route type="mix" sink="bus100_rear_seat" sources="mixport_bus100_rear_seat"/>
  253. 253                 <route type="mix" sink="primary input" sources="Built-In Mic,Built-In Back Mic,Echo-Reference Mic"/>
  254. 254                 <route type="mix" sink="mixport_tuner0" sources="FM Tuner"/>
  255. 255             </routes>
  256. 256
  257. 257         </module>
  258. 258
  259. 259         <!-- A2dp Audio HAL -->
  260. 260         <xi:include href="a2dp_audio_policy_configuration.xml"/>
  261. 261
  262. 262         <!-- Usb Audio HAL -->
  263. 263         <xi:include href="usb_audio_policy_configuration.xml"/>
  264. 264
  265. 265         <!-- Remote Submix Audio HAL -->
  266. 266         <xi:include href="r_submix_audio_policy_configuration.xml"/>
  267. 267
  268. 268     </modules>
  269. 269     <!-- End of Modules section -->
  270. 270
  271. 271     <!-- Volume section -->
  272. 272
  273. 273     <xi:include href="audio_policy_volumes.xml"/>
  274. 274     <xi:include href="default_volume_tables.xml"/>
  275. 275
  276. 276     <!-- End of Volume section -->
  277. 277     <!-- End of Modules section -->
  278. 278
  279. 279 </audioPolicyConfiguration>
复制代码
通过CONTEXT_NAME_MAP​​​​​​​关系,根据context可以找到contextNumber​​​​​​​。

xref: /packages/services/Car/service/src/com/android/car/audio/CarAudioService.java
  1. 472          // Setup dynamic routing rules by usage
  2. 473          final CarAudioDynamicRouting dynamicRouting = new CarAudioDynamicRouting(mCarAudioZones);
  3. 474          dynamicRouting.setupAudioDynamicRouting(builder);
复制代码
通过usage设置动态路由计谋

xref: /packages/services/Car/service/src/com/android/car/audio/CarAudioDynamicRouting.java
  1. 50      static final SparseIntArray USAGE_TO_CONTEXT = new SparseIntArray();
  2. ...............................................
  3. 67      static {
  4. 68          USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_UNKNOWN, ContextNumber.MUSIC);
  5. 69          USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_MEDIA, ContextNumber.MUSIC);
  6. 70          USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_VOICE_COMMUNICATION, ContextNumber.CALL);
  7. 71          USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING,
  8. 72                  ContextNumber.CALL);
  9. 73          USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_ALARM, ContextNumber.ALARM);
  10. 74          USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_NOTIFICATION, ContextNumber.NOTIFICATION);
  11. 75          USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_NOTIFICATION_RINGTONE, ContextNumber.CALL_RING);
  12. 76          USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST,
  13. 77                  ContextNumber.NOTIFICATION);
  14. 78          USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT,
  15. 79                  ContextNumber.NOTIFICATION);
  16. 80          USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_DELAYED,
  17. 81                  ContextNumber.NOTIFICATION);
  18. 82          USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_NOTIFICATION_EVENT, ContextNumber.NOTIFICATION);
  19. 83          USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY,
  20. 84                  ContextNumber.VOICE_COMMAND);
  21. 85          USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
  22. 86                  ContextNumber.NAVIGATION);
  23. 87          USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION,
  24. 88                  ContextNumber.SYSTEM_SOUND);
  25. 89          USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_GAME, ContextNumber.MUSIC);
  26. 90          USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_VIRTUAL_SOURCE, ContextNumber.INVALID);
  27. 91          USAGE_TO_CONTEXT.put(AudioAttributes.USAGE_ASSISTANT, ContextNumber.VOICE_COMMAND);
  28. 92      }
  29. .......................................
  30. 100      void setupAudioDynamicRouting(AudioPolicy.Builder builder) {
  31. 101          for (CarAudioZone zone : mCarAudioZones) {
  32. 102              for (CarVolumeGroup group : zone.getVolumeGroups()) {
  33. 103                  setupAudioDynamicRoutingForGroup(group, builder);
  34. 104              }
  35. 105          }
  36. 106      }
  37. 107  
  38. 108      /**
  39. 109       * Enumerates all physical buses in a given volume group and attach the mixing rules.
  40. 110       * @param group {@link CarVolumeGroup} instance to enumerate the buses with
  41. 111       * @param builder {@link AudioPolicy.Builder} to attach the mixing rules
  42. 112       */
  43. 113      private void setupAudioDynamicRoutingForGroup(CarVolumeGroup group,
  44. 114              AudioPolicy.Builder builder) {
  45. 115          // Note that one can not register audio mix for same bus more than once.
  46. 116          for (int busNumber : group.getBusNumbers()) {
  47. 117              boolean hasContext = false;
  48. 118              CarAudioDeviceInfo info = group.getCarAudioDeviceInfoForBus(busNumber);
  49. 119              AudioFormat mixFormat = new AudioFormat.Builder()
  50. 120                      .setSampleRate(info.getSampleRate())
  51. 121                      .setEncoding(info.getEncodingFormat())
  52. 122                      .setChannelMask(info.getChannelCount())
  53. 123                      .build();
  54. 124              AudioMixingRule.Builder mixingRuleBuilder = new AudioMixingRule.Builder();
  55. 125              for (int contextNumber : group.getContextsForBus(busNumber)) {
  56. 126                  hasContext = true;
  57. 127                  int[] usages = getUsagesForContext(contextNumber);
  58. 128                  for (int usage : usages) {
  59. 129                      mixingRuleBuilder.addRule(
  60. 130                              new AudioAttributes.Builder().setUsage(usage).build(),
  61. 131                              AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE);
  62. 132                  }
  63. 133                  Log.d(CarLog.TAG_AUDIO, "Bus number: " + busNumber
  64. 134                          + " contextNumber: " + contextNumber
  65. 135                          + " sampleRate: " + info.getSampleRate()
  66. 136                          + " channels: " + info.getChannelCount()
  67. 137                          + " usages: " + Arrays.toString(usages));
  68. 138              }
  69. 139              if (hasContext) {
  70. 140                  // It's a valid case that an audio output bus is defined in
  71. 141                  // audio_policy_configuration and no context is assigned to it.
  72. 142                  // In such case, do not build a policy mix with zero rules.
  73. 143                  AudioMix audioMix = new AudioMix.Builder(mixingRuleBuilder.build())
  74. 144                          .setFormat(mixFormat)
  75. 145                          .setDevice(info.getAudioDeviceInfo())
  76. 146                          .setRouteFlags(AudioMix.ROUTE_FLAG_RENDER)
  77. 147                          .build();
  78. 148                  builder.addMix(audioMix);
  79. 149              }
  80. 150          }
  81. 151      }
  82. 152  
  83. 153      private int[] getUsagesForContext(int contextNumber) {
  84. 154          final List<Integer> usages = new ArrayList<>();
  85. 155          for (int i = 0; i < CarAudioDynamicRouting.USAGE_TO_CONTEXT.size(); i++) {
  86. 156              if (CarAudioDynamicRouting.USAGE_TO_CONTEXT.valueAt(i) == contextNumber) {
  87. 157                  usages.add(CarAudioDynamicRouting.USAGE_TO_CONTEXT.keyAt(i));
  88. 158              }
  89. 159          }
  90. 160          return usages.stream().mapToInt(i -> i).toArray();
  91. 161      }
  92. 162  }
复制代码
        通过contextNumber获取到usages,遍历usages将usage添加到mixingRuleBuilder中,然后再将mixingRuleBuilder添加到AudioMix中,将AudioMix addMix 到AudioPolicy中, 如许usage和device就关联上了。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

涛声依旧在

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表