Android Automotive OS (AAOS) は、コア Android オーディオ スタック上に構築され、車両内のインフォテインメント システムとして動作するユースケースをサポートします。 AAOS はインフォテインメント サウンド (つまり、メディア、ナビゲーション、通信) を担当しますが、可用性とタイミングの厳密な要件があるチャイムや警告については直接担当しません。 AAOS は、車両がオーディオを管理するのに役立つ信号とメカニズムを提供しますが、最終的には、ドライバーと同乗者にどのようなサウンドを再生するかを決定するのは車両次第であり、安全上の重要な音と規制音が適切に聞こえるようにする必要があります。中断。
Android が車両のメディア エクスペリエンスを管理するため、ラジオ チューナーなどの外部メディア ソースは、ソースのオーディオ フォーカスやメディア キー イベントを処理できるアプリで表す必要があります。
Android 11 には、自動車関連のオーディオ サポートに対する次の変更が含まれています。
- 関連するユーザー ID に基づいた自動オーディオ ゾーン選択
- 自動車特有のサウンドをサポートするための新しいシステムの使用法
- HALオーディオフォーカスのサポート
- 非一時的なストリームの遅延オーディオ フォーカス
- ナビゲーションと通話の間の対話を制御するユーザー設定
Android のサウンドとストリーム
車載オーディオ システムは、次のサウンドとストリームを処理します。
図 1.ストリーム中心のアーキテクチャ図
Android は、Android アプリからのサウンドを管理し、それらのアプリを制御し、サウンドの種類に基づいて HAL の出力デバイスにサウンドをルーティングします。
- コアオーディオ用語ではソースとして知られる論理ストリームには、オーディオ属性のタグが付けられます。
- コアオーディオ用語ではデバイスとして知られる物理ストリームには、ミキシング後のコンテキスト情報がありません。
信頼性を高めるため、外部サウンド(シートベルト警告チャイムなどの独立したソースからのもの) は、Android の外部、HAL の下、または別のハードウェア内で管理されます。システム実装者は、Android から 1 つ以上のサウンド入力ストリームを受け入れ、それらのストリームを車両に必要な外部音源と適切な方法で組み合わせるミキサーを提供する必要があります。
HAL 実装と外部ミキサーは、安全性が重要な外部サウンドが確実に聞こえるようにし、Android が提供するストリームをミキシングして適切なスピーカーにルーティングする役割を果たします。
アンドロイドの音
アプリには、標準 Android API (たとえば、フォーカス制御用のAudioManagerやストリーミング用のMediaPlayer ) を介して対話し、オーディオ データの 1 つ以上の論理ストリームを出力する 1 つ以上のプレーヤーが含まれる場合があります。このデータは単一チャンネルのモノラルまたは 7.1 サラウンドである可能性がありますが、ルーティングされ、単一のソースとして扱われます。アプリ ストリームは、オーディオをどのように表現すべきかに関するヒントをシステムに提供するAudioAttributesに関連付けられています。
論理ストリームは AudioService を通じて送信され、利用可能な物理出力ストリームの 1 つ (および 1 つだけ) にルーティングされます。各ストリームは AudioFlinger 内のミキサーの出力です。オーディオ属性が物理ストリームにミックスダウンされると、それらは利用できなくなります。
各物理ストリームは、ハードウェア上でレンダリングするために Audio HAL に配信されます。自動車アプリでは、レンダリング ハードウェアはローカル コーデック (モバイル デバイスと同様)、または車両の物理ネットワーク全体のリモート プロセッサになります。いずれにせよ、実際のサンプル データを配信し、それを聞こえるようにするのは、Audio HAL 実装の仕事です。
外部ストリーム
Android 経由でルーティングすべきではないサウンド ストリーム (認証またはタイミング上の理由から) は、外部ミキサーに直接送信される場合があります。 Android 11 以降、HAL はこれらの外部サウンドのフォーカスをリクエストして、メディアを一時停止したり、他のユーザーがフォーカスを取得できないようにしたりするなど、適切なアクションを実行できるように Android に通知できるようになりました。
外部ストリームが、Android が生成するサウンド環境と対話する必要があるメディア ソースである場合 (たとえば、外部チューナーがオンになっているときに MP3 再生を停止する)、それらの外部ストリームは Android アプリで表す必要があります。このようなアプリは、HAL ではなくメディア ソースに代わってオーディオ フォーカスを要求し、Android フォーカス ポリシーに適合するために必要に応じて外部ソースを開始/停止することでフォーカス通知に応答します。このアプリは、再生/一時停止などのメディア キー イベントの処理も担当します。このような外部デバイスを制御するために推奨されるメカニズムの 1 つは、 HwAudioSourceです。
出力デバイス
オーディオ HAL レベルでは、デバイス タイプAUDIO_DEVICE_OUT_BUS
、車両オーディオ システムで使用するための汎用出力デバイスを提供します。バス デバイスは、アドレス指定可能なポート (各ポートが物理ストリームのエンドポイントとなる) をサポートしており、車両でサポートされる唯一の出力デバイス タイプであることが期待されます。
システム実装では、すべての Android サウンドに対して 1 つのバス ポートを使用できます。この場合、Android はすべてをミックスして 1 つのストリームとして配信します。あるいは、HAL は各CarAudioContext
に 1 つのバス ポートを提供して、任意のサウンド タイプの同時配信を可能にすることもできます。これにより、HAL 実装では、必要に応じてさまざまなサウンドをミックスしたりダッキングしたりすることが可能になります。
出力デバイスへのオーディオ コンテキストの割り当ては、 car_audio_configuration.xml
を通じて行われます。
マイク入力
オーディオをキャプチャするとき、Audio HAL は、マイク入力の処理方法を示すAudioSource
引数を含むopenInputStream
呼び出しを受け取ります。
VOICE_RECOGNITION
ソース (具体的には Google アシスタント) は、エコー キャンセル効果 (利用可能な場合) を持つステレオ マイク ストリームを期待しますが、他の処理は適用されません。ビームフォーミングはアシスタントによって実行されることが想定されています。
マルチチャンネルマイク入力
3 つ以上のチャンネル (ステレオ) を持つデバイスからオーディオをキャプチャするには、位置インデックス マスク ( CHANNEL_IN_LEFT
など) の代わりにチャンネル インデックス マスクを使用します。例:
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);
setChannelMask
とsetChannelIndexMask
の両方が設定されている場合、 AudioRecord
setChannelMask
で設定された値のみを使用します (最大 2 チャネル)。
同時キャプチャ
Android 10 以降、Android フレームワークは入力の同時キャプチャをサポートしていますが、ユーザーのプライバシーを保護するための制限があります。これらの制限の一部として、 AUDIO_SOURCE_FM_TUNER
などの仮想ソースは無視されるため、通常の入力 (マイクなど) と同時にキャプチャすることが許可されます。 HwAudioSources
も同時キャプチャ制限の一部とはみなされません。
AUDIO_DEVICE_IN_BUS
デバイスまたはセカンダリAUDIO_DEVICE_IN_FM_TUNER
デバイスで動作するように設計されたアプリは、それらのデバイスを明示的に識別し、 AudioRecord.setPreferredDevice()
を使用して Android のデフォルトのソース選択ロジックをバイパスすることに依存する必要があります。
オーディオの使用
AAOS は主に、ルーティング、音量調整、フォーカス管理にAudioAttributes.AttributeUsages
を利用します。使用状況は、ストリームが再生される「理由」を表します。したがって、すべてのストリームとオーディオ フォーカス リクエストでは、オーディオ再生の使用法を指定する必要があります。 AudioAttributes オブジェクトの構築時に特に設定されていない場合、使用法はデフォルトのUSAGE_UNKNOWN
になります。現在、これはUSAGE_MEDIA
と同じように扱われますが、この動作はメディアの再生に依存すべきではありません。
システムの使用法
Android 11 では、システムの使用法が導入されました。これらの使用方法は、以前に確立された使用方法と同様に動作しますが、 android.permission.MODIFY_AUDIO_ROUTING
と同様にシステム API を使用する必要がある点が異なります。新しいシステムの用途は次のとおりです。
-
USAGE_EMERGENCY
-
USAGE_SAFETY
-
USAGE_VEHICLE_STATUS
-
USAGE_ANNOUNCEMENT
システム使用法を使用してAudioAttributes
を構築するには、 setUsage
の代わりにAudioAttributes.Builder#setSystemUsage
を使用します。システム以外の使用法でこのメソッドを呼び出すと、 IllegalArgumentException
がスローされます。また、システム使用法と使用法の両方がビルダーに設定されている場合、ビルド時にIllegalArgumentException
がスローされます。
AudioAttributes
インスタンスにどのような使用法が関連付けられているかを確認するには、 AudioAttributes#getSystemUsage
を呼び出します。これは、関連付けられている使用状況またはシステム使用状況を返します。
オーディオコンテキスト
AAOS オーディオの設定を簡素化するために、同様の使用法がCarAudioContext
にグループ化されています。これらのオーディオ コンテキストは、ルーティング、ボリューム グループ、オーディオ フォーカス管理を定義するためにCarAudioService
全体で使用されます。
Android 11 のオーディオ コンテキストは次のとおりです。
カーオーディオコンテキスト | 関連する属性の使用法 |
---|---|
MUSIC | UNKNOWN, GAME, MEDIA |
NAVIGATION | ASSISTANCE_NAVIGATION_GUIDANCE |
VOICE_COMMAND | ASSISTANT, ASSISTANCE_ACCESSIBILITY |
CALL_RING | NOTIFICATION_RINGTONE |
CALL | VOICE_COMMUNICATION, VOICE_COMMUNICATION_SIGNALING |
ALARM | ALARM |
NOTIFICATION | NOTIFICATION, NOTIFICATION_* |
SYSTEM_SOUND | ASSISTANCE_SONIFICATION |
EMERGENCY | EMERGENCY |
SAFETY | SAFETY |
VEHICLE_STATUS | VEHICLE_STATUS |
ANNOUNCEMENT | ANNOUNCEMENT |
オーディオコンテキストと使用法の間のマッピング。ハイライト表示された行は、新しいシステムの使用法を示します。
マルチゾーンオーディオ
自動車では、同時ユーザーがプラットフォームを操作し、別のメディアを消費しようとする一連の新しいユースケースが登場します。たとえば、後部座席の乗客が背面ディスプレイで YouTube ビデオを見ている間、ドライバーは車室内で音楽を再生できます。マルチゾーン オーディオは、車両のさまざまな領域でさまざまなオーディオ ソースを同時に再生できるようにすることでこれを可能にします。
Android 10 以降のマルチゾーン オーディオにより、OEM はオーディオを個別のゾーンに構成できるようになります。各ゾーンは、独自のボリューム グループ、コンテキストのルーティング設定、およびフォーカス管理を備えた車両内のデバイスの集合です。このようにして、メインキャビンを 1 つのオーディオ ゾーンとして構成し、リア ディスプレイのヘッドフォン ジャックを 2 番目のゾーンとして構成できます。
ゾーンはcar_audio_configuration.xml
の一部として定義されます。次に、 CarAudioService
設定を読み取り、AudioService が関連するゾーンに基づいてオーディオ ストリームをルーティングできるようにします。各ゾーンは引き続き、コンテキストとアプリケーション uid に基づいてルーティングのルールを定義します。プレーヤーが作成されると、 CarAudioService
プレーヤーがどのゾーンに関連付けられているかを決定し、使用状況に基づいて、AudioFlinger がオーディオをルーティングするデバイスを決定します。
フォーカスもオーディオ ゾーンごとに独立して維持されます。これにより、異なるゾーンにあるアプリケーションが、ゾーン内でのフォーカスの変更を考慮しながら、互いに干渉することなく独立してオーディオを生成できるようになります。 CarAudioService
内のCarZonesAudioFocus
、各ゾーンのフォーカスを管理します。
図 2. マルチゾーン オーディオの構成
オーディオ HAL
車載オーディオの実装は、次のような標準の Android オーディオ HAL に依存しています。
-
IDevice.hal
。入力ストリームと出力ストリームを作成し、メインボリュームとミュートを処理し、以下を使用します。-
createAudioPatch
。デバイス間の外部-外部パッチを作成します。 -
IDevice.setAudioPortConfig()
各物理ストリームのボリュームを提供します。
-
-
IStream.hal
。入力および出力バリアントとともに、ハードウェアとの間のオーディオ サンプルのストリーミングを管理します。
車載機器の種類
次のデバイス タイプは自動車プラットフォームに関連します。
デバイスタイプ | 説明 |
---|---|
AUDIO_DEVICE_OUT_BUS | Android からのプライマリ出力 (これにより、Android からのすべてのオーディオが車両に配信されます)。各コンテキストのストリームを明確にするためのアドレスとして使用されます。 |
AUDIO_DEVICE_OUT_TELEPHONY_TX | 送信のために携帯無線にルーティングされる音声に使用されます。 |
AUDIO_DEVICE_IN_BUS | 他に分類されていない入力に使用されます。 |
AUDIO_DEVICE_IN_FM_TUNER | 放送ラジオ入力にのみ使用されます。 |
AUDIO_DEVICE_IN_TV_TUNER | TV デバイスが存在する場合は、テレビ デバイスに使用されます。 |
AUDIO_DEVICE_IN_LINE | AUX入力端子に使用します。 |
AUDIO_DEVICE_IN_BLUETOOTH_A2DP | Bluetooth 経由で受信した音楽。 |
AUDIO_DEVICE_IN_TELEPHONY_RX | 電話に関連する携帯無線から受信した音声に使用されます。 |
オーディオデバイスの設定
Android に表示されるオーディオ デバイスは、次のコンポーネントを含む/audio_policy_configuration.xml
で定義する必要があります。
- モジュール名。 「プライマリ」(自動車のユースケースに使用)、「A2DP」、「remote_submix」、および「USB」をサポートします。モジュール名と対応するオーディオ ドライバーは
audio.primary.$(variant).so
にコンパイルする必要があります。 - デバイスポート。このモジュールからアクセスできるすべての入力および出力デバイス (永続的に接続されたデバイスとリムーバブル デバイスを含む) のデバイス記述子のリストが含まれます。
- 出力デバイスごとに、ミリベル単位の最小/最大/デフォルト/ステップ値で構成されるゲイン制御を定義できます (1 ミリベル = 1/100 dB = 1/1000 ベル)。
-
AUDIO_DEVICE_OUT_BUS
と同じデバイス タイプを持つデバイスが複数ある場合でも、 devicePort インスタンスの address 属性を使用してデバイスを検索できます。 - ミックスポート。オーディオ HAL によって公開されるすべての出力および入力ストリームのリストが含まれます。各 mixPort インスタンスは、Android AudioService への物理ストリームとみなすことができます。
- ルート。入力デバイスと出力デバイスの間、またはストリームとデバイスの間で可能な接続のリストを定義します。
次の例では、すべての Android オーディオ ストリームが mixer_bus0_phone_out によってミックスされる出力デバイス Bus0_phone_out を定義します。このルートは、 mixer_bus0_phone_out
の出力ストリームをデバイスbus0_phone_out
に導きます。
<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude"> <modules> <module name="primary" halVersion="3.0"> <attachedDevices> <item>bus0_phone_out</item> <defaultOutputDevice>bus0_phone_out</defaultOutputDevice> <mixPorts> <mixPort name="mixport_bus0_phone_out" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </mixPort> </mixPorts> <devicePorts> <devicePort tagName="bus0_phone_out" role="sink" type="AUDIO_DEVICE_OUT_BUS" address="BUS00_PHONE"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> <gains> <gain name="" mode="AUDIO_GAIN_MODE_JOINT" minValueMB="-8400" maxValueMB="4000" defaultValueMB="0" stepValueMB="100"/> </gains> </devicePort> </devicePorts> <routes> <route type="mix" sink="bus0_phone_out" sources="mixport_bus0_phone_out"/> </routes> </module> </modules> </audioPolicyConfiguration>