音量管理は CarAudioService
に含まれており、音量はソフトウェアではなくハードウェア アンプによって HAL の下に適用されることを想定して、固定音量が使用されます。CarAudioService
は、出力デバイスを音量グループに整理し、音量グループに関連付けられたすべてのデバイスに同じゲインを適用します。
固定ボリューム
AAOS の実装では、ソフトウェア ミキサーではなくハードウェア アンプを使用して音量を調節します。想定外の事態を回避するには、config_useFixedVolume
フラグを true
に設定します(必要に応じてオーバーレイします)。
<resources>
<!-- Car uses hardware amplifier for volume. -->
<bool name="config_useFixedVolume">true</bool>
</resources>
config_useFixedVolume
フラグが設定されていない(または false
に設定されている)場合、アプリで AudioManager.setStreamVolume()
を呼び出して、ソフトウェア ミキサーのストリーム タイプ別に音量を変更できます。これは他のアプリに影響を及ぼす可能性があり、ソフトウェア ミキサーで音量を下げると、ハードウェア アンプで受信した信号で利用できる有効ビットが少なくなるため、望ましくない場合があります。
音量グループ
音量グループは、オーディオ ゾーン内にあるデバイスの集合について、音量を管理します。音量グループごとに音量を個別に調節できます。結果的にゲインは関連するデバイスで設定され、車両のアンプによって適用されます。音量設定はユーザーに対して保持され、ユーザーがログインすると読み込まれます。
ボリューム グループを定義する
CarAudioService は、car_audio_configuration.xml
で定義された音量グループを使用します。
<audioZoneConfiguration version="2.0">
<zones>
<zone name="primary zone" isPrimary="true">
<volumeGroups>
<group>
<device address="bus0_media_out">
<context context="music"/>
</device>
</group>
<group>
<device address="bus1_navigation_out">
<context context="navigation"/>
</device>
<device address="bus2_voice_command_out">
<context context="voice_command"/>
</device>
</group>
...
</volumeGroups>
</zone>
</zones>
</audioZoneConfiguration>
各音量グループには、アドレスが関連付けられた出力デバイスを 1 つ以上含める必要があります。アドレスは、audio_policy_configuration.xml
で定義された出力デバイスに対応している必要があります。
音量グループのゲインを構成する
各音量グループには、最小、最大、デフォルトのゲイン値と、音量グループに関連付けられたデバイスに audio_policy_configuration.xml
で構成された値に基づくステップサイズがあります。
<devicePort tagName="bus0_media_out" role="sink" type="AUDIO_DEVICE_OUT_BUS" address="bus0_media_out">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
<gains>
<gain name="" mode="AUDIO_GAIN_MODE_JOINT"
minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
</gains>
</devicePort>
初期化の際、音量グループは関連するデバイスのゲイン値を確認し、グループを次のように構成します。
- ステップサイズ: 音量グループによって調節されるすべてのデバイスで同じである必要があります。
- 最小ゲイン: グループ内のデバイスの最小ゲインのうち最小のもの。
- 最大ゲイン: グループ内のデバイスの最大ゲインのうち最大のもの。
- デフォルト ゲイン: グループ内のデバイスのデフォルト ゲインのうち最大のもの。
これらの値の構成方法により、音量グループに関連付けられたデバイスでサポートされている範囲外の音量グループのゲインを設定できます。この場合、そのデバイスのゲインは、音量グループの値が範囲より上か下かに基づいて、デバイスの最小または最大ゲイン値に設定されます。
音量グループ ID
ボリューム グループは、XML ファイルで定義された順序で実行時に識別されます。オーディオ ゾーン内の ID の範囲は 0
~N-1
です。ここで N
は、そのゾーン内の音量グループの数です。このように、音量グループ ID はゾーン間で一意ではありません。これらの ID は、音量グループに関連付けられた CarAudioManager
API に使用されます。zoneId
なしで groupId
を使用する API は、デフォルトでプライマリ オーディオ ゾーンになります。
マルチゾーン音量管理
各オーディオ ゾーンには音量グループが 1 つ以上必要であり、各音量グループは 1 つのオーディオ ゾーンにしか関連付けられません。この関係は、car_audio_configuration.xml
の一部として定義されます。詳細については、ボリューム グループを定義するの例をご覧ください。
各ゾーンの現在の音量レベルは、そのゾーンに関連付けられているユーザーに対して保持されます。こうした設定はゾーン固有です。つまり、ユーザーがプライマリ ゾーンに関連付けられたゾーンにログインした後、セカンダリ オーディオ ゾーンに関連付けられたゾーンにログインする場合、最初のゾーン用に読み込まれ保持される音量レベルは、セカンダリ ゾーン用とは異なります。
音量キーイベントを処理する
Android では、次のような音量調節用のいくつかのキーコードを定義しています。
KEYCODE_VOLUME_UP
KEYCODE_VOLUME_DOWN
KEYCODE_VOLUME_MUTE
デフォルトでは、Android は音量キーイベントをアプリにルーティングします。Automotive の実装では、こうしたキーイベントを CarAudioService
によって強制的に処理する必要があります。CarAudioService
は、必要に応じて setGroupVolume
または setMasterMute
を呼び出します。この動作を強制するには、config_handleVolumeKeysInWindowManager
フラグを true
に設定します。
<resources>
<bool name="config_handleVolumeKeysInWindowManager">true</bool>
</resources>
音量キーイベントには現在のところ、どのゾーンを対象としているかを区別する方法はなく、すべてがプライマリ オーディオ ゾーンに関連付けられていると仮定されます。音量キーイベントを受け取ると、CarAudioService
はアクティブなプレーヤーのオーディオ コンテキストを取得してから、優先度が最も高いオーディオ コンテキストに関連付けられた出力デバイスを含む音量グループを調整することで、調整する音量グループを決定します。優先度は、CarVolume.AUDIO_CONTEXT_VOLUME_PRIORITY
で定義された固定の順序に基づいて決定されます。
フェードとバランス
両バージョンの AudioControl HAL には、車両にフェードとバランスを設定するための API が含まれています。CarAudioManager の対応するシステム API は、AudioControl HAL に値を渡します。これらの API には android.car.permission.CAR_CONTROL_AUDIO_VOLUME
が必要です。AudioControl API は次のとおりです。
setBalanceTowardRight(float value)
: スピーカーの音量を車両の右側(+)または左側(-)に切り替えます。- 0.0 は中央に配置されます
- +1.0 は完全右方
- -1.0 は完全左方
- -1 ~ 1 の範囲外の値はエラーです
setFadeTowardFront(float value)
: スピーカーの音量を車両の前方(+)または後方(-)に切り替えます。- 0.0 は中央に配置されます
- +1.0 は完全前方
- -1.0 は完全に後方
- -1 ~ 1 の範囲外の値はエラーです
これらの値をどのように適用し、ユーザーにどのように表示するかは、デベロッパーが決定します。メディアに限定して適用することも、Android のすべてのサウンドに一律に適用することもできます。また Android 11 では、出力デバイスに対するオーディオ エフェクトの適用がサポートされました。これにより、これらの API ではなく、該当する出力デバイスのオーディオ エフェクトを介して、フェードとバランスを管理できます。
他の音量を下げる
オーディオ ダッキングは、車両で 1 つのストリームのゲインを下げることで、同時に再生されている別のストリームを明瞭に聞こえるようにする際に発生します。AAOS では、オーディオのダッキングは HAL によって実装されます。Android では、OS 以外の音を制御できません。2 つの出力デバイスの両方にアクティブなストリームがあるかどうかということが、Android 11 で HAL がダッキングの判断を行うために利用できる主な情報です。
ダッキングするタイミング
HAL によるダッキングの処理方法は個々の OEM が決定しますが、おすすめのガイドラインがいくつかあります。
Android で複数のストリームが再生されるのは、2 つのアプリやサービスが音声フォーカスを同時に保持している場合がほとんどです。Android が同時フォーカスを許可するタイミングについては、制限の種類のインタラクション マトリックスをご覧ください。カーオーディオ プラグインの導入により、これは AudioFocus の管理にも依存するようになりました。
Android で混合されるストリームは、ゲインが適用されるより前に混合されます。そのため、別のストリームと同時に再生されたときにダッキングするストリームは、それらを混合する前に HAL がダッキングを適用できるように、別々の出力デバイスにルーティングする必要があります。
おすすめのダッキング動作
ダッキングを適用することをおすすめする同時インタラクションとしては、次のものが挙げられます。
操作 | アクション |
---|---|
EMERGENCY
| SAFETY を除くすべての音声をダッキングまたはミュートします |
SAFETY |
EMERGENCY を除くすべてをダッキングする |
NAVIGATION |
SAFETY と EMERGENCY を除くすべてをダッキングする |
CALL |
SAFETY 、EMERGENCY 、NAVIGATION を除くすべてをダッキングする |
VOICE |
アヒル CALL_RING |
VEHICLE_SOUNDS |
アクティブなサウンドの重要性と、他のサウンドをダッキングするかどうかを判断します。 |
MUSIC 、ANNOUNCEMENT |
すべてに対してダッキングされます。例外は、SYSTEM_SOUND として再生されるタッチ操作音です。 |
ダッキングする際の考慮事項
一部のアプリやサービス(ナビゲーションやアシスタントなど)では、アクションを実行するために複数のプレーヤーを使用することがあります。出力デバイスを流れるデータのストリームが停止したときにダッキングを解除しすぎないようにします。これは、ナビゲーション アプリまたはアシスタント アプリから次の再生が開始されてダッキングされる前に、メディアの音量が一時的に最大に戻さないためです。
十分に隔離された複数のサウンド ステージを備えた車両の場合、ダッキングではなく、異なる車両エリアにオーディオをルーティングできます。たとえば、車内全体に音楽を通常の音量で再生し続けながら、ナビゲーションの案内をドライバーのヘッドレスト スピーカーにルーティングできます。
安全上重要なサウンド
Android 11 では、HAL オーディオ フォーカス API が導入されました。HAL は、安全上重要なサウンドが他のサウンドよりも優先されるようにします。HAL が USAGE_EMERGENCY
に音声フォーカスを保持していても、Android のアプリやサービスがサウンドを再生しないとは限りません。安全上重要なサウンドを再生するために、Android からどのストリームを混合またはミュートするかは HAL が決定します。
音量設定 UI の構成
AAOS では、音量設定 UI が音量グループの構成と切り離されています。これらは、音量グループのゲインを構成するの説明に従ってオーバーレイできます。この分離により、ボリューム グループの構成が変更されても変更する必要がなくなります。
車両設定 UI では、packages/apps/Car/Settings/res/xml/car_volume_items.xml
には、定義された各 AudioAttributes.USAGE
に関連付けられた UI 要素(タイトルとアイコン リソース)が含まれます。このファイルは、各 VolumeGroup
に含まれる最初に認識された用途に関連付けられたリソースを使用して、定義された VolumeGroups
の適切なレンダリングを可能にします。
たとえば、次の例では、voice_communication
と voice_communication_signalling
を含む VolumeGroup
を定義しています。車両設定 UI のデフォルトの実装では、voice_communication
に関連付けられたリソースを使用して VolumeGroup
をレンダリングします。これがファイル内で最初に一致するためです。
<carVolumeItems xmlns:car="http://schemas.android.com/apk/res-auto">
<item car:usage="voice_communication"
car:title="@*android:string/volume_call"
car:icon="@*android:drawable/ic_audio_ring_notif"/>
<item car:usage="voice_communication_signalling"
car:title="@*android:string/volume_call"
car:icon="@*android:drawable/ic_audio_ring_notif"/>
<item car:usage="media"
car:title="@*android:string/volume_music"
car:icon="@*android:drawable/ic_audio_media"/>
<item car:usage="game"
car:title="@*android:string/volume_music"
car:icon="@*android:drawable/ic_audio_media"/>
<item car:usage="alarm"
car:title="@*android:string/volume_alarm"
car:icon="@*android:drawable/ic_audio_alarm"/>
<item car:usage="assistance_navigation_guidance"
car:title="@string/navi_volume_title"
car:icon="@drawable/ic_audio_navi"/>
<item car:usage="notification_ringtone"
car:title="@*android:string/volume_ringtone"
car:icon="@*android:drawable/ic_audio_ring_notif"/>
<item car:usage="assistant"
car:title="@*android:string/volume_unknown"
car:icon="@*android:drawable/ic_audio_vol"/>
<item car:usage="notification"
car:title="@*android:string/volume_notification"
car:icon="@*android:drawable/ic_audio_ring_notif"/>
<item car:usage="notification_communication_request"
car:title="@*android:string/volume_notification"
car:icon="@*android:drawable/ic_audio_ring_notif"/>
<item car:usage="notification_communication_instant"
car:title="@*android:string/volume_notification"
car:icon="@*android:drawable/ic_audio_ring_notif"/>
<item car:usage="notification_communication_delayed"
car:title="@*android:string/volume_notification"
car:icon="@*android:drawable/ic_audio_ring_notif"/>
<item car:usage="notification_event"
car:title="@*android:string/volume_notification"
car:icon="@*android:drawable/ic_audio_ring_notif"/>
<item car:usage="assistance_accessibility"
car:title="@*android:string/volume_notification"
car:icon="@*android:drawable/ic_audio_ring_notif"/>
<item car:usage="assistance_sonification"
car:title="@*android:string/volume_unknown"
car:icon="@*android:drawable/ic_audio_vol"/>
<item car:usage="unknown"
car:title="@*android:string/volume_unknown"
car:icon="@*android:drawable/ic_audio_vol"/>
</carVolumeItems>
上の構成で使用される属性と値は packages/apps/Car/Settings/res/values/attrs.xml
で宣言されています。音量設定 UI は、次の VolumeGroup
ベースの CarAudioManager API を使用します。
getVolumeGroupCount()
: 描画するコントロールの数を確認します。getGroupMinVolume()
、getGroupMaxVolume()
: 下限値と上限値を取得します。getGroupVolume()
: 現在の音量を取得します。registerVolumeChangeObserver()
: 音量の変更に関する通知を受け取ります。
カー音量グループ イベント
音量の更新とミュート切り替えの自動車用ユースケースには、特定のアプリのアクション(音量設定など)を定義するコンテキスト ベースの基盤があります。カー オーディオ スタックからの現在の音量とミュート コールバックは、限定的なコンテキスト情報を提供します。自動車のユースケースと将来のスケーラビリティをより適切にサポートするために、CarVolumeGroupEvent が Android 14 に追加されました。各イベントには、次の 3 種類の重要な情報が含まれます。
CarVolumeGroupInfo
のリストEventTypes
(ビットマップ)ExtraInfos
のリスト
CarVolumeGroupInfo
イベント コールバックのレシーバは、影響を受けるカー ボリューム グループ情報のリストにすぐにアクセスできます。つまり、アプリは最新の状態を取得するために、カー オーディオ フレームワークを追加で呼び出す必要はありません。受信した CarVolumeGroupInfos
を使用して、UI または内部状態を更新するだけです。アプリが簡単に使用できるように、カー ボリューム グループで変更されたアスペクトも、以下で説明するように EventTypes
の一部として提供されます。
EventTypes
CarVolumeGroupInfo
のどの部分が変更されたかを定義します。アプリはこれを活用して変更を特定し、必要なアクションを実行できます。たとえば、EVENT_TYPE_VOLUME_MAX_INDEX_CHANGED
は、それぞれの CarVolumeGroups
最大音量ゲイン インデックスが変更されたことを示します。これは CarVolumeGroupInfo.getMaxVolumeGainIndex()
でクエリできます。
次の表に、EventType
と CarVolumeGroupInfo
の関係を示します。
EventType | CarVolumeGroupInfo |
---|---|
EVENT_TYPE_VOLUME_GAIN_INDEX_CHANGED | CarVolumeGroupInfo.getVolumeGainIndex() |
EVENT_TYPE_VOLUME_MIN_INDEX_CHANGED | CarVolumeGroupInfo.getMinVolumeGainIndex() |
EVENT_TYPE_VOLUME_MAX_INDEX_CHANGED | CarVolumeGroupInfo.getMaxVolumeGainIndex() |
EVENT_TYPE_MUTE_CHANGED | CarVolumeGroupInfo.isMuted() |
EVENT_TYPE_VOLUME_BLOCKED_CHANGED | CarVolumeGroupInfo.isBlocked() |
EVENT_TYPE_ATTENUATION_CHANGED | CarVolumeGroupInfo.isAttenuated() |
EVENT_TYPE_ZONE_CONFIGURATION_CHANGED | CarVolumeGroupInfo.getAudioAttributes() |
ExtraInfos
CarVolumeGroup
が変更された理由に関する追加情報を提供します。アプリはこの情報を使用して、ユーザーにアクションを促すアラートや通知を表示するための追加のコンテキストを提供できます。たとえば、EXTRA_INFO_TRANSIENT_ATTENUATION_THERMAL
は熱的過負荷によるアクティブな過渡減衰を示します。音量を上げようとしたときに、アプリからユーザーに通知できます。
ExtraInfos
に対しては、いかなるプロセスも適用されません。ExtraInfos
に基づくプロセスの決定は、お客様の裁量に委ねられます。たとえば、EXTRA_INFO_TRANSIENT_ATTENUATION_DUCKED
が原因で減衰が有効になっている場合は、最初に音量バー UI をフェードして、ユーザーが音量を変更できないようにすることもできます。ダッキングが有効になっていることを示すトーストを表示し、ユーザーが音量を変更できるようにすることもできます。
カーオーディオ フレームワークは、推奨される ExtraInfos
を提供するために AudioControl HAL IAudioGainCallback
に依存します。詳細については、オーディオ ゲイン コールバックをご覧ください。
CarVolumeGroupEvent
は、カーオーディオ フレームワークの将来のニーズを満たすようにスケーリングされます。新しい機能は CarVolumeGroupEvent
のみでサポートされる予定です。アプリ デベロッパーは、CarVolumeGroupEvent
を使用してグループ音量とミュート変更を処理することを強くおすすめします。
カー音量グループのイベント コールバック
Android 14 では、特権アプリとプラットフォーム アプリが CarVolumeGroupEvents
を登録して通知を受け取るための新しいコールバックが提供されます。
コールバックを登録するには、
CarAudioManager#registerCarVolumeGroupEventCallback()
を使用します。コールバックの登録を解除するには、
CarAudioManager#unregisterCarVolumeGroupEventCallback()
を使用します。
アプリが新しい CarVolumeGroupEventCallback
と従来の CarVolumeCallback
に登録されている場合、イベント CarVolumeGroupEventCallbacks
が優先されます。カー オーディオ スタックが CarVolumeCallback
をトリガーしなくなりました。これにより、同じイベントに対して同じアプリに重複するトリガーが設定されることがなくなります。
グループの音量とミュート設定の変更を管理するには、CarVolumeGroupEventCallback
を使用することを強くおすすめします。
オーディオ ゲイン コールバック
Android 13 以降、AudioControl HAL は非同期コールバックをトリガーして、カー オーディオ システムの変更による音量レベルの更新を管理できます。
HAL API
AudioControl @2.0 AIDL
AudioControl AIDL HAL のバージョン 2.0 では、次の API が追加されています。
API | 目的 |
---|---|
IAudioControl#registerGainCallback |
AudioControl HAL に IAudioGainCallback のインスタンスを登録します。 |
IAudioGainCallback#onAudioDeviceGainsChanged |
オーディオ ゲイン設定の変更を通知する非同期コールバック。 |
AudioControl HAL コールバックには、理由のリストと、次の要素で構成されるそれぞれの AudioGainConfigInfo
が含まれます。
- ゾーン ID
- デバイスのポートアドレス
- ボリューム インデックス > インデックスは、制限付きインデックスまたは更新インデックスのいずれかです。
理由は、大きく次のカテゴリに分類できます。
- 制限の理由。音量とミュートの動作の一時的な変更。
- 理由を更新します。音量の動作の恒久的な変更。
制限の種類
AudioControl
HAL AIDL
V3
時点で、サポートされている制限の種類は次のとおりです。
- ミュート
- ブロック
- 制限
- 減衰
有効な制限 | ユーザーがトリガーした音量の変更 | ユーザーがトリガーするミュート切り替え |
---|---|---|
ミュート | ❌ | ❌(ミュート解除) ✔(ミュート) |
ブロック | ❌ | ✔ |
制限 | ❌(上限超過) ✔(上限未満) |
✔ |
減衰 | ✔ | ✔ |
制限の優先順位は、ミュート > ブロック > 制限 > 減衰です。
ミュートに関する制限
ミュート制限は次のとおりです。
Reasons.TCU_MUTE
Reasons.REMOTE_MUTE
カーオーディオ フレームワークは、内部で次の 2 つのミュート状態を維持します。
ユーザーのミュート。
CarAudioManager
またはキーイベントを介して、ユーザーのリクエストに応じて切り替わります。HAL ミュート。
AudioGain
コールバックで受信したミュート制限に基づいて切り替わります。
設定アプリなどのリスナーに対して、音量グループ全体のミュート(CarVolumeGroupInfo.isMuted()
)の状態は、上記のミュートのいずれかが有効になっているかどうかに基づいて決まります。
HAL ミュートが有効になっている場合、制限期間中は、受信した音量変更リクエストとグループのミュート解除リクエストはすべて無視されます。
インタラクション ケース: HAL ミュートが有効で、ユーザーがミュート切り替えをリクエストしている
HAL ミュートが有効で、ユーザー ミュートが無効になっている場合:
- ボリューム グループ全体のミュート状態が
true
に変更されます。 - ミュート機能を有効にするようユーザーからリクエストがあった場合は、処理されます。
- 理由: ユーザーのプライバシーを保護するため、ユーザーのミュート リクエストは常に尊重する必要があります。
HAL ミュートとユーザー ミュートが有効になっている場合:
ボリューム グループ全体のミュート状態が
true
に変更されます。ユーザーからのミュート解除リクエストは処理されます。
NOT
キャッシュに保存されたユーザーのミュート状態は有効のままです。理由: ユーザーのミュート解除リクエストは、有効な制限がない場合にのみ承認されます。
理由: キャッシュに保存されたユーザーのミュート状態を解除すると、意図しない音量の増加が発生し、ユーザーの安全を脅かす可能性があります。これは、イグニッション サイクル全体でミュート状態が有効になっている場合、特にユーザーが音量レベルの認識を低下させる場合に当てはまります。
インタラクション ケース: HAL ミュートが有効または無効になっても、ユーザーのミュートは変更されない
HAL ミュートを切り替えると、音量グループ全体のミュート状態が変更されます。ただし、ユーザーのミュート状態は直接更新されません。ユーザーのミュートが無効になっていて、有効にするための HAL ミュート コールバックが受信された場合:
- ボリューム グループ全体のミュート状態が
true
に変更されます。 ユーザーからの音量変更リクエストは、HAL ミュートが有効になっているときに処理されます。
NOT
理由: ミュートが有効になっている間は、ユーザーは音声を認識できません。音量を変更できるようにすると、音が爆発的に大きくなり、ユーザーの安全を脅かす可能性があります。
理由: 音量アプリは、OEM が想定する動作である場合、ユーザーの操作なしでコールバックを登録し、ミュート解除(CarAudioManager.setVolumeGroupMute(...,/* mute=*/ true,..))を自動的にトリガーできます。
ユーザーのミュートが無効になっているときに HAL のミュートが無効になっている場合:
音量グループのミュート状態が
false
に変更されます。理由: ミュート状態を固定してユーザーにミュート解除をリクエストすると、ミュート状態が頻繁に切り替わる場合に、ユーザーの操作が不必要に中断される可能性があります。
音量を変更するユーザーからのリクエストは通常どおり処理されます。
ブロック
ブロック制限は次のとおりです。
Reasons.FORCED_MASTER_MUTE
Reasons.REMOTE_MUTE
Reasons.TCU_MUTE
。
ブロック制限が有効になっている場合、ユーザーからの以下のリクエストは拒否されます。
- 音量の変更は処理されません。
- ミュート切り替えが処理されます。
制限
制限事項は次のとおりです。
Reasons.THERMAL_LIMITATION
Reasons.SUSPEND_EXIT_VOL_LIMITATION
制限が有効になっている場合、ユーザーからの以下のリクエストは拒否されます。
音量を変更する:
- 制限内は処理されます
- 上記の制限を超える申請は処理されません
ミュート切り替えが処理されます。
減衰
減衰の制限は次のとおりです。
Reasons.ADAS_DUCKING
Reasons.NAV_DUCKING
Reasons.PROJECTION_DUCKING
減衰の制限が有効になっている場合、ユーザーからの次のリクエストは拒否されます。
音量の変更が処理されます。新しい現在の音量レベルは、以前の音量ではなく、減衰音量に設定されます。今後の音量の変更はこのレベルから行います。
ミュート切り替えが処理されます。
インデックスの更新
Reasons.EXTERNAL_AMP_VOL_FEEDBACK
は非同期ボリューム インデックス更新と見なされます。
このため、AudioControl HAL はボリューム グループの現在のインデックスを指定されたインデックスに更新できます。これは主に、カーオーディオ フレームワークからの音量変更リクエストに対するオーディオ システムからのフィードバックとして使用されます。インデックスの更新は、インデックスを同期するための CarVolumeGroupEvent
コールバックとしてアプリにも通知されます。
例
ユースケース: ユーザーが音量インデックスを 30 に更新する
ユーザーが音量アプリを使用して音量インデックスを 30 に変更します。
このインデックスは音量ゲインに変換され、Audio HAL に送信されます。
Audio HAL
のベンダー実装は、新しい音量ゲインを受け取り、オーディオ システム(外部アンプなど)を更新します。オーディオ システムは、音量レベルがインデックス 15 にのみ更新されたと応答します(Android では不明な理由)。
AudioControl HAL
トリガーのベンダー実装:IAudioGainCallback.onAudioDeviceGainsChanged(EXTERNAL_AMP_VOL_FEEDBACK, {..., 15 /* New index */})
カー オーディオ サービスは、永続化と音量アプリへのコールバックに使用されるコールバックから新しいインデックスを使用します。ユーザーがリクエストしたインデックスは 30 です。ただし、音声システムの非同期フィードバックにより、インデックスが 15 に更新されます。
ユースケース: スリープ状態から復帰した後の最初の音声再生
休止前の音量インデックスが 95 という高いレベルに設定されている(範囲: [0 ~ 99])。
Android が停止状態になります。
Android が停止すると(再開など):
ベンダー
Audio HAL/AudioControl HAL
は、ローカルで安全なインデックス 30 をオーディオ システムに適用します。ベンダー
AudioControl HAL
は、セーフ インデックスのコールバックもトリガーします。
IAudioGainCallback.onAudioDeviceGainsChanged(SUSPEND_EXIT_VOL_LIMITATION, {..., 30 /* safe index */})
カーオーディオ サービスは、永続化に使用されるコールバックと、インデックスを同期するボリューム アプリに対する独自のコールバックから新しいインデックスを使用します。一時停止前のボリューム インデックスは 95 です。ただし、再開後、このインデックスは
AudioControl HAL
実装者によって安全な音量レベル 30 に設定されます。
動的ボリュームの構成
この機能の主なユースケースは次のとおりです。
車両の End-of-Line(EOL)構成。
自動車メーカーは、車両のオーディオ システムの設定に基づいて、EOL で音量設定を更新することをおすすめします。通常、これは Android SW イメージを更新しないサイドロードです。
自動車メーカーは、サービス スケジュール中にボリューム構成を更新する必要がある場合があります。
ランタイム構成。自動車用オーディオ システムは外部アンプ構成をサポートしており、これらの ECU は起動時にクエリされる音量範囲構成をホストする場合があります。
オンデマンド構成。ユーザーが一定期間、高度なシグナル処理を定期購入するデマンド ベースの音声機能の需要の高まりに対応するために提供されます。新しいボリューム範囲の設定は、定期購入の期間中有効です。
デザイン
動的ボリュームの構成は、次の 3 つのステージで実現されます。
検出。ベンダーの AudioControl HAL 実装は、ベンダーが所有するカスタム IPC メカニズムを通じて、新しい音量範囲の更新を検出します。
検出されると、
AudioControl::IModuleChangeCallback
からコールバックが生成されます。更新します。カー オーディオ スタックは、新しい音量範囲で音量グループの状態を更新します。
音量範囲の更新後も同じ音量レベルを維持するよう努めています。ただし、インデックスが範囲外の場合、現在のボリューム インデックスは安全な値に設定されます。たとえば、コールバック時にベンダーから提供されたデフォルトのレベルなどです。
コールバック。
ボリューム グループの範囲が更新されると、カーオーディオ スタックは
CarVolumeGroupEventCallback
で登録されたアプリへのコールバックをトリガーします。CarVolumeGroupEvent
には、更新されたCarVolumeGroupInfo
、イベントタイプ(変更内容)、追加情報(変更理由)が含まれます。
図 1. 動的ボリュームの構成
HAL API
AudioControl @ 3.0 AIDL
AudioControl AIDL HAL のバージョン 3.0 では、次の API が導入されています。
API | |
---|---|
IAudioControl#setModuleChangeCallback | AudioControl HAL で IModuleChangeCallback のインスタンスを設定します。 |
IAudioControl#clearModuleChangeCallback | AudioControl HAL で以前に設定した IModuleChangeCallback のインスタンスを消去します。 |
IModuleChangeCallback#onAudioPortsChanged | AudioPorts の変更を通知するコールバック |
シーケンス
動的ボリューム構成のシーケンス図を以下に示します。
図 2. 動的ボリューム構成のシーケンス図。
主な特徴
この機能を最適化するには、次の点を考慮してください。
コールバックの一部として指定された AudioPorts は、Automotive BUS の定義と一致している必要があります。
- デバイスのポート。
IN_DEVICE
、OUT_DEVICE
- 接続。
BUS
- 住所。オーディオ HAL 定義で定義されている
- ゲインモード。
JOINT
- デバイスのポート。
ベンダーは、Audio HAL ポリシーで音量範囲定義のスーパーセットを定義し、コールバックを使用して車両のバリエーションに合わせてカスタマイズする必要があります。詳細については、
IModuleChangeCallbac
AIDL 定義をご覧ください。複数のオーディオ BUS が同じ音量グループに属している場合、各 BUS の音量範囲の定義は同じである必要があります。これを行わないと、自動車オーディオ フレームワークは新しい音量範囲の定義を拒否します。