aboutsummaryrefslogtreecommitdiff
path: root/zh-cn/devices/automotive/audio
diff options
context:
space:
mode:
Diffstat (limited to 'zh-cn/devices/automotive/audio')
-rw-r--r--zh-cn/devices/automotive/audio/audio-control.html395
-rw-r--r--zh-cn/devices/automotive/audio/index.html239
-rw-r--r--zh-cn/devices/automotive/audio/interaction-sequences.html144
-rw-r--r--zh-cn/devices/automotive/audio/multi-zone.html83
4 files changed, 861 insertions, 0 deletions
diff --git a/zh-cn/devices/automotive/audio/audio-control.html b/zh-cn/devices/automotive/audio/audio-control.html
new file mode 100644
index 00000000..d5d0158f
--- /dev/null
+++ b/zh-cn/devices/automotive/audio/audio-control.html
@@ -0,0 +1,395 @@
+<html devsite><head>
+ <title>实现 AudioControl HAL</title>
+ <meta name="project_path" value="/_project.yaml"/>
+ <meta name="book_path" value="/_book.yaml"/>
+ </head>
+
+ <body>
+ <!--
+ Copyright 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<p>
+Android 9 弃用了之前各版车载 HAL 中的 <code>AUDIO_*</code> 属性,并改为使用包含显式函数调用和已输入参数列表的专用音频控制 HAL。
+</p>
+
+<p>
+这个新的 HAL 提供了 <code>IAudioControl</code> 作为主接口对象,该对象负责提供出于配置和音量控制目的与车辆的音频引擎进行交互所需的入口点。系统可以包含该对象的一个实例,即 <code>CarAudioService</code> 启动时创建的实例。该对象是传统 Android 音频 HAL 的汽车扩展;在大多数实现中,发布音频 HAL 接口的进程还应发布 <code>IAudioControl interfaces</code>。
+</p>
+
+<h2 id="supported-interfaces">支持的接口</h2>
+
+<p>
+<code>AudioControl</code> HAL 支持以下接口:
+</p>
+
+<ul>
+ <li><code><strong>getBusforContext</strong></code>:在启动时针对每个上下文调用一次,以获取从 <code>ContextNumber</code> 到 <code>busAddress</code> 的映射。用法示例:
+
+<pre class="prettyprint">
+getBusForContext(ContextNumber contextNumber)
+ generates (uint32_t busNumber);
+</pre>
+
+使车辆能够针对每个上下文告诉框架将物理输出音频流路由到哪里。对于每个上下文,必须返回有效的总线编号(0 - 总线数-1)。如果遇到无法识别的 <code>contextNumber</code>,则应返回 -1。对于任何上下文,如果返回无效的 <code>busNumber</code>,都会路由到总线 0。
+<br /><br />
+任何通过此机制与同一个 <code>busNumber</code> 相关联的并发声音都会先通过 Android <code>AudioFlinger</code> 进行混音,然后才会作为单个音频流提供给音频 HAL。这会取代车载 HAL 属性 <code>AUDIO_HW_VARIANT</code> 和 <code>AUDIO_ROUTING_POLICY</code>。
+ </li>
+
+ <li><code><strong>setBalanceTowardRight</strong></code>:用于控制车载音响设备的右/左平衡设置。用法示例:
+
+<pre class="prettyprint">
+setBalanceTowardRight(float value);
+</pre>
+
+将音响设备音量调向汽车右侧 (+) 或左侧 (-)。0.0 表示在中间,+1.0 表示完全调到右侧,-1.0 表示完全调到左侧,如果值未在 -1 到 1 之间,则是错误的。
+ </li>
+
+ <li><code><strong>setFadeTowardFront</strong></code>:用于控制车载音响设备的前/后淡化设置。用法示例:
+
+<pre class="prettyprint">
+setFadeTowardFront(float value);
+</pre>
+
+将音响设备音量调向汽车前面 (+) 或后面 (-)。0.0 表示在中间,+1.0 表示完全调到前面,-1.0 表示完全调到后面,如果值未在 -1 到 1 之间,则是错误的。
+ </li>
+</ul>
+
+<h2 id="configure-volume">配置音量</h2>
+
+<p>
+Android Automotive 实现应使用硬件放大器(而非软件混音器)来控制音量。为避免产生副作用,请在 <code>device/generic/car/emulator/audio/overlay/frameworks/base/core/res/res/values/config.xml</code> 中将 <code>config_useFixedVolume</code> 标记设为 <code>true</code>(根据需要叠加):
+</p>
+
+<pre class="prettyprint">
+&lt;resources&gt;
+ &lt;!-- Car uses hardware amplifier for volume. --&gt;
+ &lt;bool name="config_useFixedVolume"&gt;true&lt;/bool&gt;
+&lt;/resources&gt;
+</pre>
+
+<p>
+<code>config_useFixedVolume</code> 标记未设置或设为 <code>false</code> 时,应用可以调用 <code>AudioManager.setStreamVolume()</code>,并在软件混音器中按音频流类型更改音量。用户可能不希望出现这种情况,因为这会对其他应用带来潜在影响,而且使用硬件放大器接收信号时,软件混音器中的音量衰减会导致信号中的可用有效位减少。
+</p>
+
+<h2 id="configure-volume-groups">配置音量组</h2>
+
+<p>
+ <code>CarAudioService</code> 使用 <code>packages/services/Car/service/res/xml/car_volume_group.xml</code> 中定义的音量组。您可以替换此文件,以便根据需要重新定义音量组。系统在运行时会按 XML 文件中的定义顺序来识别音量组。ID 介于 0 到 N-1 之间,其中 N 是音量组的数量。示例:
+</p>
+
+<pre class="prettyprint">
+&lt;volumeGroups xmlns:car="http://schemas.android.com/apk/res-auto"&gt;
+ &lt;group&gt;
+ &lt;context car:context="music"/&gt;
+ &lt;context car:context="call_ring"/&gt;
+ &lt;context car:context="notification"/&gt;
+ &lt;context car:context="system_sound"/&gt;
+ &lt;/group&gt;
+ &lt;group&gt;
+ &lt;context car:context="navigation"/&gt;
+ &lt;context car:context="voice_command"/&gt;
+ &lt;/group&gt;
+ &lt;group&gt;
+ &lt;context car:context="call"/&gt;
+ &lt;/group&gt;
+ &lt;group&gt;
+ &lt;context car:context="alarm"/&gt;
+ &lt;/group&gt;
+&lt;/volumeGroups&gt;
+</pre>
+
+<p>
+此配置中使用的属性在 <code>packages/services/Car/service/res/values/attrs.xml</code> 中定义。
+</p>
+
+<h2 id="handle-volumn-key-events">处理音量键事件</h2>
+
+<p>
+Android 定义了一些用于控制音量的键码,包括 <code>KEYCODE_VOLUME_UP</code>、<code>KEYCODE_VOLUME_DOWN</code> 和 <code>KEYCODE_VOLUME_MUTE</code>。默认情况下,Android 会将音量键事件路由到应用。Automotive 实现应强制将这些键事件路由到 <code>CarAudioService</code>,以便该服务可以根据情况适当地调用 <code>setGroupVolume</code> 或 <code>setMasterMute</code>。
+</p>
+
+<p>
+要强制实现此行为,请在 <code>device/generic/car/emulator/car/overlay/frameworks/base/core/res/res/values/config.xml</code> 中将 <code>config_handleVolumeKeysInWindowManager</code> 标记设为 <code>true</code>:
+</p>
+
+<pre class="prettyprint">
+&lt;resources&gt;
+ &lt;bool name="config_handleVolumeKeysInWindowManager"&gt;true&lt;/bool&gt;
+&lt;/resources&gt;
+</pre>
+
+<h2 id="caraudiomanager-api">CarAudioManager API</h2>
+
+<p>
+<code>CarAudioManager</code> 使用 <code>CarAudioService</code> 来配置和控制车载音频系统。该管理器对于系统中的大多数应用来说都是不可见的,但车辆专用组件(如音量控制器)可以使用 <code>CarAudioManager</code> API 与系统交互。
+</p>
+
+<p>
+下文介绍了 Android 9 对 <code>CarAudioManager API</code> 所做的更改。
+</p>
+
+<h3 id="deprecated-apis">弃用的 API</h3>
+
+<p>
+Android 9 通过现有的 <code>AudioManager</code> <code>getDeviceList</code> API 处理设备枚举,因此弃用并移除了以下车辆专用函数:
+</p>
+
+<ul>
+ <li><code>String[] getSupportedExternalSourceTypes()</code></li>
+ <li><code>String[] getSupportedRadioTypes()</code></li>
+</ul>
+
+<p>
+Android 9 使用 <code>AudioAttributes.AttributeUsage</code> 或基于音量组的入口点处理音量,因此移除了以下依赖于 <code>streamType</code> 的 API:
+</p>
+
+<ul>
+ <li><code>void setStreamVolume(int streamType, int index, int flags)</code>
+ </li>
+ <li><code>int getStreamMaxVolume(int streamType)</code></li>
+ <li><code>int getStreamMinVolume(int streamType)</code></li>
+ <li><code>void setVolumeController(IVolumeController controller)</code></li>
+</ul>
+
+<h3 id="new-apis">新增的 API</h3>
+
+<p>
+Android 9 添加了以下用于控制放大器硬件的新 API(明确基于音量组):
+</p>
+
+<ul>
+ <li><code>int getVolumeGroupIdForUsage(@AudioAttributes.AttributeUsage int
+ usage)</code></li>
+ <li><code>int getVolumeGroupCount()</code></li>
+ <li><code>int getGroupVolume(int groupId)</code></li>
+ <li><code>int getGroupMaxVolume(int groupId)</code></li>
+ <li><code>int getGroupMinVolume(int groupId)</code></li>
+</ul>
+
+<p>
+Android 9 还提供了以下全新的系统 API 供系统 GUI 使用:
+</p>
+
+<ul>
+ <li><code>void setGroupVolume(int groupId, int index, int flags)</code></li>
+ <li><code>void registerVolumeChangeObserver(@NonNull ContentObserver
+ observer)</code></li>
+ <li><code>void unregisterVolumeChangeObserver(@NonNull ContentObserver
+ observer)</code></li>
+ <li><code>void registerVolumeCallback(@NonNull IBinder binder)</code></li>
+ <li><code>void unregisterVolumeCallback(@NonNull IBinder binder)</code></li>
+ <li><code>void setFadeToFront(float value)</code></li>
+ <li><code>Void setBalanceToRight(float value)</code></li>
+</ul>
+
+<p>
+此外,Android 9 还添加了用于管理外部来源的新 API。这些 API 主要用于支持根据媒体类型将音频从外部来源路由到输出总线。借助这些 API,第三方应用还能够访问外部设备。
+</p>
+
+<ul>
+ <li><code>String[] getExternalSources()</code>:返回一个地址数组,这些地址用于识别系统中 <code>AUX_LINE</code>、<code>FM_TUNER</code>、<code>TV_TUNER</code> 和 <code>BUS_INPUT</code> 类型的可用音频端口。</li>
+ <li><code>CarPatchHandle createAudioPatch(String sourceAddress, int
+ carUsage)</code>:将来源地址路由到与所提供的 <code>carUsage</code> 关联的输出 <code>BUS</code>。</li>
+ <li><code>int releaseAudioPatch(CarPatchHandle patch)</code>:移除所提供的音频通路。如果 <code>CarPatchHandle</code> 的创建者意外终止,则由 <code>AudioPolicyService::removeNotificationClient()</code> 自动处理。</li>
+</ul>
+
+<h2 id="create-audio-patches">创建音频通路</h2>
+
+<p>
+您可以在两个音频端口(混音端口或设备端口)之间创建音频通路。通常,从混音端口到设备端口的音频通路用于播放音频,而从设备端口到混音端口的音频通路则用于捕获音频。</p>
+
+<p>
+例如,将音频样本直接从 <code>FM_TUNER</code> 来源路由到媒体接收器的音频通路会绕过软件混音器。因此,您必须使用硬件混音器为接收器将来自 Android 和 <code>FM_TUNER</code> 的音频样本进行混音。创建直接从 <code>FM_TUNER</code> 来源到媒体接收器的音频通路时:
+</p>
+
+<ul>
+ <li>音量控制会应用于媒体接收器,并且应该会影响 Android 和 <code>FM_TUNER</code> 音频。</li>
+ <li>用户应该能够通过简单的应用切换在 Android 和 <code>FM_TUNER</code> 音频之间进行切换(应该不需要必须选择显式媒体来源)。</li>
+</ul>
+
+<p>
+Automotive 实现可能还需要在两个设备端口之间创建音频通路。为此,您必须先在 <code>audio_policy_configuration.xml</code> 中声明设备端口和可能的路由,并将混音端口与这些设备端口相关联。
+</p>
+
+<h3 id="example-config">配置示例</h3>
+
+<p>
+另请参阅 <code>device/generic/car/emulator/audio/audio_policy_configuration.xml</code>。
+</p>
+
+<pre class="prettyprint">
+&lt;audioPolicyConfiguration&gt;
+ &lt;modules&gt;
+ &lt;module name="primary" halVersion="3.0"&gt;
+ &lt;attachedDevices&gt;
+ &lt;item&gt;bus0_media_out&lt;/item&gt;
+ &lt;item&gt;bus1_audio_patch_test_in&lt;/item&gt;
+ &lt;/attachedDevices&gt;
+ &lt;mixPorts&gt;
+ &lt;mixPort name="mixport_bus0_media_out" role="source"
+ flags="AUDIO_OUTPUT_FLAG_PRIMARY"&gt;
+ &lt;profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000"
+ channelMasks="AUDIO_CHANNEL_OUT_STEREO"/&gt;
+ &lt;/mixPort&gt;
+ &lt;mixPort name="mixport_audio_patch_in" role="sink"&gt;
+ &lt;profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000"
+ channelMasks="AUDIO_CHANNEL_IN_STEREO"/&gt;
+ &lt;/mixPort&gt;
+ &lt;/mixPorts&gt;
+ &lt;devicePorts&gt;
+ &lt;devicePort tagName="bus0_media_out" role="sink" type="AUDIO_DEVICE_OUT_BUS"
+ address="bus0_media_out"&gt;
+ &lt;profile balance="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/&gt;
+ &lt;gains&gt;
+ &lt;gain name="" mode="AUDIO_GAIN_MODE_JOINT"
+ minValueMB="-8400" maxValueMB="4000" defaultValueMB="0" stepValueMB="100"/&gt;
+ &lt;/gains&gt;
+ &lt;/devicePort&gt;
+ &lt;devicePort tagName="bus1_audio_patch_test_in" type="AUDIO_DEVICE_IN_BUS" role="source"
+ address="bus1_audio_patch_test_in"&gt;
+ &lt;profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/&gt;
+ &lt;gains&gt;
+ &lt;gain name="" mode="AUDIO_GAIN_MODE_JOINT"
+ minValueMB="-8400" maxValueMB="4000" defaultValueMB="0" stepValueMB="100"/&gt;
+ &lt;/gains&gt;
+ &lt;/devicePort&gt;
+ &lt;/devicePorts&gt;
+ &lt;routes&gt;
+ &lt;route type="mix" sink="bus0_media_out" sources="mixport_bus0_media_out,bus1_audio_patch_test_in"/&gt;
+ &lt;route type="mix" sink="mixport_audio_patch_in" sources="bus1_audio_patch_test_in"/&gt;
+ &lt;/routes&gt;
+ &lt;/module&gt;
+ &lt;/modules&gt;
+&lt;/audioPolicyConfiguration&gt;
+</pre>
+
+<h3 id="audio-driver-api">音频驱动程序 API</h3>
+
+<p>
+您可以使用 <code>getExternalSources()</code> 获取可用来源列表(按地址进行标识),然后按音频用法在这些来源和接收器端口之间创建音频通路。音频 HAL 上相应的入口点显示在 <code>IDevice.hal</code> 中:
+</p>
+
+<pre class="prettyprint">
+Interface IDevice {
+...
+/**
+* Creates an audio patch between several source and sink ports. The handle
+* is allocated by the HAL and must be unique for this audio HAL module.
+*
+* @param sources patch sources.
+* @param sinks patch sinks.
+* @return retval operation completion status.
+* @return patch created patch handle.
+*/
+createAudioPatch(vec&lt;AudioPortConfig&gt; sources, vec&lt;AudioPortConfig&gt; sinks)
+ generates (Result retval, AudioPatchHandle patch);
+
+/**
+* Release an audio patch.
+*
+* @param patch patch handle.
+* @return retval operation completion status.
+*/
+releaseAudioPatch(AudioPatchHandle patch) generates (Result retval);
+...
+}
+</pre>
+
+<aside class="note"><strong>注意</strong>:这些 API 钩子从 AUDIO_DEVICE_API_VERSION_3_0 便已开始提供。如需了解更多详情,请参阅 <code>device/generic/car/emulator/audio/driver/audio_hw.c</code>。</aside>
+
+<h2 id="configure-volume-settings-ui">配置音量设置界面</h2>
+
+<p>
+Android 9 将音量设置界面从音量组配置(该配置可叠加,如“配置音量组”中所述)中分离出来。这种分离可确保将来音量组配置发生更改时,无需对音量设置界面进行任何更改。
+</p>
+
+<p>
+在汽车设置界面中,<code>packages/apps/Car/Settings/res/xml/car_volume_items.xml</code> 文件包含与每个定义的 <code>AudioAttributes.USAGE</code> 相关联的界面元素(标题和图标资源)。此文件通过使用与每个 VolumeGroup 中包含的首个识别出的用法相关联的资源,合理呈现已定义的 VolumeGroups。
+</p>
+
+<p>
+例如,以下示例将 VolumeGroup 定义为同时包含 <code>voice_communication</code> 和 <code>voice_communication_signalling</code>。汽车设置界面的默认实现使用与 <code>voice_communication</code> 相关联的资源呈现 VolumeGroup,因为它是文件中的首个匹配项。
+</p>
+
+<pre class="prettyprint">
+&lt;carVolumeItems xmlns:car="http://schemas.android.com/apk/res-auto"&gt;
+ &lt;item car:usage="voice_communication"
+ car:title="@*android:string/volume_call"
+ car:icon="@*android:drawable/ic_audio_ring_notif"/&gt;
+ &lt;item car:usage="voice_communication_signalling"
+ car:title="@*android:string/volume_call"
+ car:icon="@*android:drawable/ic_audio_ring_notif"/&gt;
+ &lt;item car:usage="media"
+ car:title="@*android:string/volume_music"
+ car:icon="@*android:drawable/ic_audio_media"/&gt;
+ &lt;item car:usage="game"
+ car:title="@*android:string/volume_music"
+ car:icon="@*android:drawable/ic_audio_media"/&gt;
+ &lt;item car:usage="alarm"
+ car:title="@*android:string/volume_alarm"
+ car:icon="@*android:drawable/ic_audio_alarm"/&gt;
+ &lt;item car:usage="assistance_navigation_guidance"
+ car:title="@string/navi_volume_title"
+ car:icon="@drawable/ic_audio_navi"/&gt;
+ &lt;item car:usage="notification_ringtone"
+ car:title="@*android:string/volume_ringtone"
+ car:icon="@*android:drawable/ic_audio_ring_notif"/&gt;
+ &lt;item car:usage="assistant"
+ car:title="@*android:string/volume_unknown"
+ car:icon="@*android:drawable/ic_audio_vol"/&gt;
+ &lt;item car:usage="notification"
+ car:title="@*android:string/volume_notification"
+ car:icon="@*android:drawable/ic_audio_ring_notif"/&gt;
+ &lt;item car:usage="notification_communication_request"
+ car:title="@*android:string/volume_notification"
+ car:icon="@*android:drawable/ic_audio_ring_notif"/&gt;
+ &lt;item car:usage="notification_communication_instant"
+ car:title="@*android:string/volume_notification"
+ car:icon="@*android:drawable/ic_audio_ring_notif"/&gt;
+ &lt;item car:usage="notification_communication_delayed"
+ car:title="@*android:string/volume_notification"
+ car:icon="@*android:drawable/ic_audio_ring_notif"/&gt;
+ &lt;item car:usage="notification_event"
+ car:title="@*android:string/volume_notification"
+ car:icon="@*android:drawable/ic_audio_ring_notif"/&gt;
+ &lt;item car:usage="assistance_accessibility"
+ car:title="@*android:string/volume_notification"
+ car:icon="@*android:drawable/ic_audio_ring_notif"/&gt;
+ &lt;item car:usage="assistance_sonification"
+ car:title="@*android:string/volume_unknown"
+ car:icon="@*android:drawable/ic_audio_vol"/&gt;
+ &lt;item car:usage="unknown"
+ car:title="@*android:string/volume_unknown"
+ car:icon="@*android:drawable/ic_audio_vol"/&gt;
+&lt;/carVolumeItems&gt;
+</pre>
+
+<p>
+上述配置中使用的属性和值在 <code>packages/apps/Car/Settings/res/values/attrs.xml</code> 中声明。音量设置界面使用以下基于 <code>VolumeGroup</code> 的 <code>CarAudioManager</code> API:
+</p>
+
+<ul>
+ <li><code>getVolumeGroupCount()</code>:用于了解应绘制多少个控件。</li>
+ <li><code>getGroupMinVolume()</code> 和 <code>getGroupMaxVolume()</code>:用于获取音量上限和下限。</li>
+ <li><code>getGroupVolume()</code>:用于获取当前音量。</li>
+ <li><code>registerVolumeChangeObserver()</code>:用于获取音量更改通知。</li>
+</ul>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/automotive/audio/index.html b/zh-cn/devices/automotive/audio/index.html
new file mode 100644
index 00000000..f362db27
--- /dev/null
+++ b/zh-cn/devices/automotive/audio/index.html
@@ -0,0 +1,239 @@
+<html devsite><head>
+ <title>汽车音频</title>
+ <meta name="project_path" value="/_project.yaml"/>
+ <meta name="book_path" value="/_book.yaml"/>
+ </head>
+
+ <body>
+ <!--
+ Copyright 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<p>
+这一部分详细介绍了与汽车相关的 Android 实现采用的音频架构。实现汽车音频系统的原始设备制造商 (OEM) 和其他 Android 开发者除了查看主要<a href="/devices/audio/">音频</a>部分的内容外,还应仔细查看本部分中的所有内容。
+</p>
+
+<h2 id="key-concepts">主要概念</h2>
+
+<p>
+Android 负责信息娱乐声音(例如媒体、导航和通讯声音),但不直接负责具有严格可用性和时间要求的铃声和警告。外部声源由负责音频焦点的应用表示。不过,您不能依靠音频焦点来选择和混合声音。
+</p>
+
+<p>
+对于与汽车相关的音频支持,Android 9 进行了以下更改:
+</p>
+
+<ul>
+ <li>音频 HAL 上下文映射到 <code>AudioAttributes.usage</code> 以识别声音;音频 HAL 实现负责进行特定于上下文的混音/路由。</li>
+ <li>车辆负责定义用于车载音频系统的通用输出设备 (<code>AUDIO_DEVICE_OUT_BUS</code>);Android 支持一个上下文使用一个 <code>AUDIO_DEVICE_OUT_BUS</code>。</li>
+ <li><code>IAudioControl HAL</code> 向音频 HAL 提供车辆专用扩展;有关示例实现,请参阅 <code>device/generic/car/emulator/audio</code>。Android 9 不包含 <code>AUDIO_* VHAL</code> 属性。</li>
+</ul>
+
+<h2 id="android-sounds-streams">Android 声音和声音流</h2>
+
+<p>
+汽车音频系统可以处理以下声音和声音流:
+</p>
+
+<img src="/devices/automotive/images/audio_streams_all.png"/>
+<figcaption><strong>图 1.</strong> 以声音流为中心的架构图
+</figcaption>
+
+<p>
+Android 负责来自 Android 应用的声音,同时控制这些应用,并根据其声音类型将声音路由到 HAL 中的各个声音流:
+</p>
+
+<ul>
+ <li><strong>逻辑</strong>声音流:在核心音频命名法中称为声源,<em></em>使用<a href="/devices/audio/attributes">音频属性</a>进行标记。</li>
+ <li><strong>物理</strong>声音流:在核心音频命名法中称为设备,<em></em>在混音后没有上下文信息。</li>
+</ul>
+
+<p>
+为了确保可靠性,外部声音(来自独立声源,例如安全带警告铃声)在 Android 外部(HAL 下方,甚至是在单独的硬件中)进行管理。系统实现者必须提供一个混音器,用于接受来自 Android 的一个或多个声音输入流,然后以合适的方式将这些声音流与车辆所需的外部声源组合起来。外部声音流可始终处于开启状态,也可以通过 HAL 中的 <code>createAudioPatch</code> 入口点进行控制。
+</p>
+
+<p>
+HAL 实现和外部混音器负责确保对保障安全至关重要的外部声音能够被用户听到,而且负责在 Android 提供的声音流中进行混音,并将混音结果路由到合适的音响设备。
+</p>
+
+<h3 id="android-sounds">Android 声音</h3>
+
+<p>
+应用可以有一个或多个通过标准 Android API(如用于控制焦点的 <a href="https://developer.android.com/reference/android/media/AudioManager.html" class="external">AudioManager</a> 或用于流式播放的 <a href="https://developer.android.com/reference/android/media/MediaPlayer.html" class="external">MediaPlayer</a>)交互的播放器,以便发出一个或多个音频数据逻辑流。这些数据可能是单声道声音,也可能是 7.1 环绕声,但都会作为单个声源进行路由和处理。应用声音流与 <a href="/devices/audio/attributes">AudioAttributes</a>(可向系统提供有关如何表达音频的提示)相关联。
+</p>
+
+<p>
+逻辑声音流通过 <code>AudioService</code> 发送,并路由到一个(并且只有一个)可用的物理输出声音流,其中每个声音流都是混音器在 <code>AudioFlinger</code> 内的输出。<code>AudioAttributes</code> 在混合到物理声音流后将不再可用。
+</p>
+
+<p>
+然后,每个物理声音流都会传输到音频 HAL,以在硬件上呈现。在汽车应用中,呈现硬件可能是本地编解码器(类似于移动设备),也可能是车辆物理网络中的远程处理器。无论是哪种情况,音频 HAL 实现都需要提供实际样本数据并使其能被用户听见。
+</p>
+
+<h3 id="external-streams">外部声音流</h3>
+
+<p>
+如果声音流因认证或时间原因而不应经由 Android,则可以直接发送到外部混音器。在许多情况下,Android 都不需要知道这些声音的存在,因为外部混音器可以在 Android 声音之外混合它们。如果需要对某个声音进行闪避处理或需要将其路由到不同的音响设备,外部混音器可以通过 Android 不可见的方式进行此类操作。
+</p>
+
+<p>
+如果外部声音流是应与 Android 正在生成的声音环境交互的媒体源(例如,当外部调谐器处于开启状态时,停止 MP3 播放),则这些外部声音流应由 Android 应用表示。此类应用将请求获得音频焦点,并根据需要通过启动/停止外部声音源来响应焦点通知,以符合 Android 声音焦点政策规定。要控制此类外部设备,一种建议使用的机制是 <code>AudioManager.createAudioPatch()</code>。
+</p>
+
+<h3 id="audio-focus">音频焦点</h3>
+
+<p>
+在启动逻辑声音流之前,应用应使用将用于其逻辑声音流的同一个 <code>AudioAttributes</code> 来请求获得音频焦点。虽然我们建议发送此类焦点请求,但系统不会强制要求发送。有些应用可能会明确跳过发送请求的步骤,以实现特定行为(例如,在拨打电话时有意播放声音)。
+</p>
+
+<p>
+为此,您应将焦点视为间接控制媒体播放和消除媒体播放冲突的方式,而不是作为主要的音频控制机制;也就是说,车辆不应依赖于焦点系统来操作音频子系统。焦点感知功能<strong>不是 HAL 的一部分</strong>,<strong>不得用于影响音频路由</strong>。
+</p>
+
+<h3 id="output-bus">输出总线</h3>
+
+<p>
+在音频 HAL 级别,设备类型 <code>AUDIO_DEVICE_OUT_BUS</code> 提供用于车载音频系统的通用输出设备。总线设备支持可寻址端口(其中每个端口都是一个物理声音流的端点),并且应该是车辆内唯一受支持的输出设备类型。
+</p>
+
+<p>
+系统实现可以针对所有 Android 声音使用一个总线端口,在这种情况下,Android 会将所有声音混合在一起,并将混音结果作为一个声音流进行传输。此外,HAL 可以分别为每个上下文提供一个总线端口,以允许并发传输任何声音类型。这样一来,HAL 实现就可以根据需要混合或闪避不同的声音。</p>
+
+<p>
+将上下文分配到总线端口是通过音频控制 HAL 进行的,并会在上下文和总线端口之间创建多对一的关系。
+</p>
+
+<h2 id="mic-input">麦克风输入</h2>
+
+<p>
+在捕获音频时,音频 HAL 会收到 <code>openInputStream</code> 调用,其中包含指示应如何处理麦克风输入的 <code>AudioSource</code> 参数。</p>
+
+<p>
+ <code>VOICE_RECOGNITION</code>(尤其是 Google 助理)需要一个符合以下条件的立体声麦克风流:具有回声消除效果(如果有),但不应用任何其他处理。波束成形应由 Google 助理自行完成。
+</p>
+
+<h3 id="multi-channel-mic-input">多声道麦克风输入</h3>
+
+<p>
+要从具有两个以上声道(立体声)的设备捕获音频,请使用声道索引掩码,而不是定位索引掩码(例如 <code>CHANNEL_IN_LEFT</code>)。示例:
+</p>
+
+<pre class="prettyprint">
+final AudioFormat audioFormat = new AudioFormat.Builder()
+ .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
+ .setSampleRate(44100)
+ .setChannelIndexMask(0xf /* 4 channels, 0..3 */)
+ .build();
+final AudioRecord audioRecord = new AudioRecord.Builder()
+ .setAudioFormat(audioFormat)
+ .build();
+audioRecord.setPreferredDevice(someAudioDeviceInfo);
+</pre>
+
+<p>
+如果 <code>setChannelMask</code> 和 <code>setChannelIndexMask</code> 均已设置,则 <code>AudioRecord</code> 仅使用由 <code>setChannelMask</code> 设置的值(最多两个声道)。
+</p>
+
+<h3 id="concurrent-capture">并发捕获</h3>
+
+<p>
+对于大多数输入音频设备类型,Android 框架都不允许执行并发捕获,但 <code>AUDIO_DEVICE_IN_BUS</code> 和 <code>AUDIO_DEVICE_IN_FM_TUNER</code> 例外,因为框架会将它们作为虚拟设备处理。这样做意味着,框架假定这些设备之间不存在资源竞争,因此允许在捕获某个常规输入设备(例如麦克风)的同时并发捕获任何/所有此类设备。如果这些设备之间存在对并发捕获的硬件限制,则此类限制必须由旨在使用这些输入设备的第一方应用中的自定义应用逻辑来处理。
+</p>
+
+<p>
+旨在与 <code>AUDIO_DEVICE_IN_BUS</code> 设备或辅助 <code>AUDIO_DEVICE_IN_FM_TUNER</code> 设备结合使用的应用必须依赖于以下功能:明确识别这些设备,以及使用 <code>AudioRecord.setPreferredDevice()</code> 绕过 Android 默认声源选择逻辑。
+</p>
+
+<h2 id="volume-and-groups">音量和音量组</h2>
+
+<p>
+Android 8.x 及更低版本支持三个音量组(响铃、媒体和闹钟)以及一个用于手机通话的隐藏组。可以根据输出设备将每个组设为不同的音量,例如为音响设备设置较高音量,为耳机设置较低音量。
+</p>
+
+<p>
+Android 9 添加了一个<em></em>语音音量组以及与汽车相关的上下文,如下所示:
+</p>
+
+<table>
+<thead>
+<tr>
+<th>音量组</th>
+<th>音频上下文</th>
+<th>说明</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>响铃</td>
+<td>CALL_RING_CONTEXT</td>
+<td>语音通话响铃</td>
+</tr>
+<tr>
+<td></td>
+<td>NOTIFICATION_CONTEXT</td>
+<td>通知</td>
+</tr>
+<tr>
+<td></td>
+<td>ALARM_CONTEXT</td>
+<td>Android 闹钟铃声</td>
+</tr>
+<tr>
+<td></td>
+<td>SYSTEM_SOUND_CONTEXT</td>
+<td>Android 系统声音</td>
+</tr>
+<tr>
+<td>媒体</td>
+<td>MUSIC_CONTEXT</td>
+<td>音乐播放</td>
+</tr>
+<tr>
+<td>电话</td>
+<td>CALL_CONTEXT</td>
+<td>语音通话</td>
+</tr>
+<tr>
+<td>语音</td>
+<td>NAVIGATION_CONTEXT</td>
+<td>导航指示</td>
+</tr>
+<tr>
+<td></td>
+<td>VOICE_COMMAND_CONTEXT</td>
+<td>语音指令会话</td>
+</tr>
+</tbody>
+</table>
+
+<p>
+音量组的值更新后,框架的 <code>CarAudioService</code> 会负责设置受影响物理声音流增益。车辆中的物理声音流音量基于音量组(而不是 stream_type),每个音量组包含一个或多个音频上下文。每个 <code>AudioAttributes.USAGE</code> 都会映射到 <code>CarAudioService</code> 中的一个音频上下文,并且可以配置为路由到输出总线(请参阅<a href="/devices/automotive/audio/audio-control.html#configure-volume">配置音量</a>和<a href="/devices/automotive/audio/audio-control.html#configure-volume-groups">配置音量组</a>)。
+</p>
+
+<p>
+Android 9 简化了对放大器中硬件音量的控制:
+</p>
+
+<ul>
+ <li>每个音量组都路由到一个或多个输出总线。可以使用汽车设置界面或通过外部生成的 <code>KEYCODE_VOLUME_DOWN</code> 或 <code>KEYCODE_VOLUME_UP</code> 按键事件更改特定组的音量。
+ </li>
+ <li>作为响应,<code>CarAudioService</code> 会调用 <code>AudioManager.setAudioPortGain()</code>,同时将音频设备端口绑定到目标音量组。在 HAL 中,这表现为一系列 <code>IDevice.setAudioPortConfig()</code> 调用(一次或多次调用),同时将每个物理输出声音流的音量增益值与目标音量组相关联。</li>
+</ul>
+
+<p>
+您可以在 <code>audio_policy_configuration.xml</code> 中为每个音频设备端口配置最大值、最小值和步进增益值。如需示例配置以及关于如何覆盖默认音量组集合的详细信息,请参阅<a href="/devices/automotive/audio/audio-hal.html#configure-audio-devices">配置音频设备。
+</a></p><a href="/devices/automotive/audio/audio-hal.html#configure-audio-devices">
+
+</a></body></html> \ No newline at end of file
diff --git a/zh-cn/devices/automotive/audio/interaction-sequences.html b/zh-cn/devices/automotive/audio/interaction-sequences.html
new file mode 100644
index 00000000..7da74b53
--- /dev/null
+++ b/zh-cn/devices/automotive/audio/interaction-sequences.html
@@ -0,0 +1,144 @@
+<html devsite><head>
+ <title>交互序列示例</title>
+ <meta name="project_path" value="/_project.yaml"/>
+ <meta name="book_path" value="/_book.yaml"/>
+ </head>
+
+ <body>
+ <!--
+ Copyright 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<p>
+ 在下列汽车音响示例中,汽车音响主机运行 Android 9,其中安装有收音机应用和导航应用。此外,车辆调谐器在外部布线,并通过扬声器播放。在实际使用场景中,采用如下做法可能会大有好处:将调谐器处理为 Android 的输入,让收音机应用从调谐器中读取数据并将其写入 <code>AudioTrack</code> 对象。
+</p>
+
+<h2 id="user-starts-radio">用户启动收音机</h2>
+
+<p>
+ 在此交互序列中,当用户对收音机应用中的某个预设频率按<strong>播放</strong>时,车辆内不播放任何媒体内容。收音机应用必须获得焦点,然后调谐器才能通过扬声器播放声音。
+</p>
+
+<p><img src="/devices/automotive/images/audio_auto_focus_radio.png"/></p>
+<figcaption><strong>图 1.</strong> 收音机获得焦点,然后调谐器通过扬声器播放声音</figcaption>
+
+<ol>
+ <li>收音机:“调到 FM 96.5。”</li>
+ <li>收音机:请求焦点 GAIN。</li>
+ <li>AudioManager:授予 GAIN。</li>
+ <li>收音机:<code>createAudioPatch()</code></li>
+ <li>收音机:“播放调谐器输出。”</li>
+ <li>外部布线的调谐器:混音器使调谐器音频路由到放大器。
+ </li>
+</ol>
+
+<h2 id="radio-ducks-nav-prompt">收音机闪避导航提示</h2>
+
+<p>
+ 在此交互序列中,当导航应用为下一个转弯通知生成导航提示时,收音机正在播放内容。导航应用必须先从 <code>AudioManager</code> 获得瞬时焦点,然后才能播放导航提示。
+</p>
+
+<p><img src="/devices/automotive/images/audio_auto_radio_ducks.png"/></p>
+<figcaption><strong>图 2.</strong> 收音机播放闪避导航提示</figcaption>
+
+<ol>
+ <li value="5">收音机:“播放调谐器输出。”</li>
+ <li>外部布线的调谐器:混音器使调谐器音频路由到放大器。
+ </li>
+ <li>导航:从 <code>AudioManager</code> 请求焦点 GAIN TRANSIENT。
+ </li>
+ <li>AudioManager:向导航提供 GAIN TRANSIENT。</li>
+ <li>导航:打开数据流,发送数据包。
+ <ol>
+ <li>导航:在 bus1 上路由上下文 GUIDANCE。</li>
+ <li>混音器:闪避调谐器,以通过扬声器播放 bus1 GUIDANCE。</li>
+ </ol>
+ </li>
+ <li>导航:通知结束,关闭数据流。</li>
+ <li>导航:放弃焦点。</li>
+</ol>
+
+<p>
+ <code>AudioManager</code> 认为收音机播放可以闪避,并且通常会在不通知收音机应用的情况下对音乐流应用一个闪避因子。不过,通过叠加 <code>framework/base/core/res/res/values/config.xml</code> 并将 <code>config_applyInternalDucking</code> 设置为 <code>false</code>,框架闪避被绕过了,因此,外部调谐器会继续提供声音,并且收音机应用未发现任何变化。混音器(位于 HAL 下游)负责合并这两个输入,并且可以选择是闪避收音机播放,还是将收音机播放移至后置扬声器。
+</p>
+
+<p>
+ 导航提示播放完毕后,导航应用将释放焦点,收音机播放将恢复。
+</p>
+
+<h2 id="user-launches-audio-book">用户启动有声读物应用</h2>
+
+<p>
+ 在此交互序列中,用户启动有声读物应用,导致收音机播放停止(按流式传输音乐应用中的“播放”是类似的触发器)。
+</p>
+
+<p><img src="/devices/automotive/images/audio_auto_focus_book.png"/></p>
+<figcaption><strong>图 3.</strong> 有声读物从收音机播放处夺取焦点</figcaption>
+
+<ol>
+ <li value="12">有声读物:从 <code>AudioManager</code> 请求 GAIN 上下文 MEDIA。</li>
+ <li>收音机失去焦点:
+ <ol>
+ <li>AudioManager:LOSS。</li>
+ <li>收音机:<code>releaseAudioPatch()</code></li>
+ </ol>
+ </li>
+ <li>有声读物获得焦点:
+ <ol>
+ <li>授予 GAIN,在 bus0 上路由上下文 MEDIA</li>
+ <li>打开数据流,发送 MEDIA 数据包。</li>
+ </ol>
+ </li>
+</ol>
+
+<p>
+ 有声读物应用发起的焦点请求不是瞬时的,因此上一个焦点持有者(收音机应用)将收到永久性焦点丢失信号;收音机应用会拆除连接到调谐器的补丁程序,以此作为响应。混音器停止接收调谐器信号,并开始处理通过音频 HAL 传输的音频(它还可以选择性地在从收音机过渡到有声读物的过程中执行交错淡出)。
+</p>
+
+<h2 id="nav-prompt-takes-focus">导航提示获得焦点</h2>
+
+<p>
+ 在此交互序列中,当导航应用生成导航提示时,系统正在播放有声读物。
+</p>
+
+<p><img src="/devices/automotive/images/audio_auto_focus_nav.png"/></p>
+<figcaption><strong>图 4.</strong> 导航提示从有声读物处夺取焦点</figcaption>
+
+<ol>
+ <li value="15">有声读物:正在流式播放 MEDIA 数据包,焦点未并发。</li>
+ <li>导航:请求 GAIN TRANSIENT。</li>
+ <li>AudioManager:LOSS TRANSIENT。</li>
+ <li>有声读物:停止。</li>
+ <li>AudioManager:授予 GAIN TRANSIENT。</li>
+ <li>导航:打开数据流,发送数据包。
+ <ol>
+ <li>导航:在 bus1 上路由上下文 GUIDANCE。</li>
+ <li>混音器:播放 bus1 (GUIDANCE)。</li>
+ </ol>
+ </li>
+ <li>导航:通知结束,关闭数据流。</li>
+ <li>导航:放弃焦点。</li>
+ <li>有声读物:GAIN。</li>
+ <li>有声读物:重新启动。</li>
+</ol>
+
+<p>
+ 由于有声读物应用的原始 <code>AudioFocusRequest</code>(在启动 <code>AudioTrack</code> 时发送)包含 <code>AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS</code> 标记,因此 <code>AudioManager</code> 发现无法对有声读物应用进行闪避处理。取而代之的是,<code>AudioManager</code> 会向有声读物应用发送一条 <code>AUDIOFOCUS_LOSS_TRANSIENT</code> 消息,有声读物应用应该通过暂停播放来进行响应。
+</p>
+
+<p> 导航应用现在可以不间断地播放导航提示。导航提示播放完毕后,有声读物将重新获得焦点并恢复播放。
+</p>
+
+</body></html> \ No newline at end of file
diff --git a/zh-cn/devices/automotive/audio/multi-zone.html b/zh-cn/devices/automotive/audio/multi-zone.html
new file mode 100644
index 00000000..0ff29dbb
--- /dev/null
+++ b/zh-cn/devices/automotive/audio/multi-zone.html
@@ -0,0 +1,83 @@
+<html devsite><head>
+ <title>多区音频</title>
+ <meta name="project_path" value="/_project.yaml"/>
+ <meta name="book_path" value="/_book.yaml"/>
+ </head>
+
+ <body>
+ <!--
+ Copyright 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<p>
+虽然 Android 9 不支持多区音频,但 Android 音频团队探索了一些可能有助于实现多区音频的方法。本部分详细介绍了其中的一些方法,这些方法可能有助于系统实现者着手构建后座娱乐系统 (RSE) 解决方案。
+</p>
+
+<h2 id="user-cases">用例</h2>
+
+<ul>
+ <li>后座中的收音机与前座中的不同媒体源同时播放。</li>
+ <li>前座乘客与司机收听不同的媒体源(例如,乘客在自己的屏幕上玩游戏,而司机在主屏幕上查看导航)。</li>
+ <li>四个不同的独立音频区:驾驶座、副驾驶座、后座 1、后座 2。</li>
+</ul>
+
+<h2 id="limitations">限制</h2>
+
+<p>
+由于存在以下限制,Android 9 本身不支持多个音频堆栈(音频区)或不同的优先级:
+</p>
+
+<ul>
+ <li>Android 9 不提供可使应用定位到特定音频区的 API。取而代之的是,应用必须定位到音频类型(媒体、通知等),这需要从 Android 提供的预定义集内进行选择。例如,Android 目前不支持将目标<strong>音频区 2</strong> 的音频类型定义为<strong>媒体</strong>。</li>
+ <li>物理声音流(由 AudioFlinger/内部混音器提供)不会在混音后传输上下文信息(例如,在逻辑声音流内进行标记),这导致音频 HAL 无法将特定逻辑声音流路由到不同的音频区。</li>
+</ul>
+
+<h2 id="scenario-multiple-instances">方案:使用多个实例</h2>
+
+<p>
+此方案使用多个 Android 汽车实例来实现多区音频效果。
+</p>
+
+<ul>
+ <li>每个音频区都有自己的 Android 汽车实例,这些实例可独立管理音频区中的内容。HAL 下方的硬件可合并,并可协调多个实例的输出。</li>
+ <li>实例位于不同的硬件(例如,后座中的平板电脑)之上,或者通过管理程序共享物理硬件。</li>
+ <li>使用一个主音频区将输出静态分配到车载音响设备,或在 HAL 下进行动态分配。</li>
+ <li>第一方应用(安装在每个实例中)通过专有协议进行协作,从而协调各种声音并将其路由到特定音频区。或者,使用 ChromeCast 功能跨不同实例甚至是设备进行通信。</li>
+</ul>
+
+<h2 id="scenario-target-secondary-zones">方案:定位到辅助区</h2>
+
+<p>
+此方案使用第一方应用来明确定位到被 Android 忽略的辅助区。
+</p>
+
+<ul>
+ <li>原始设备制造商 (OEM) 在 <code>audio_policy_configuration.xml</code> 中定义额外的输出音频设备端口。</li>
+ <li>隐式了解车辆配置的第一方应用可以使用 <code>AudioTrack.setPrefereceDevice()</code> API 来枚举可用输出端口,并明确定位到其中任意一个端口。</li>
+</ul>
+
+<h2 id="scenario-audio-policy-rules">方案:使用音频政策规则</h2>
+
+<p>
+此方案使用音频政策规则向其他音频设备动态添加路由专用的 UID。
+</p>
+
+<ul>
+ <li>音频路由引擎根据发出请求的应用的 UID 来定义路由规则。</li>
+ <li>系统级服务或启动器添加相应规则,将特定应用 (UID) 的输出发送到与辅助音频区关联的特定设备。</li>
+ <li>除了为预定义音频上下文的路由提供的设备之外,还要定义这些特定设备。</li>
+</ul>
+
+</body></html> \ No newline at end of file