音量管理

音量管理は 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 に対して強制実行する必要があります。その後、必要に応じて 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 SAFETYEMERGENCY 以外のすべてのダッキング
CALL SAFETYEMERGENCYNAVIGATION 以外のすべてのダッキング
VOICE CALL_RING のダッキング
VEHICLE_SOUNDS アクティブな音の重要性を判断し、他の音をダッキングするかどうかを決定してください。
MUSICANNOUNCEMENT すべてにダッキングされます。例外は、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_communicationvoice_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(): 音量変更が通知されます。

カー音量グループのイベント

音量更新とミュート切り替えの自動車のユースケースには、音量設定のような特定のアプリのアクションを定義する可能性のある、コンテキストの基礎が含まれます。カーオーディオ スタックの現在の音量とミュートのコールバックによって提供されるコンテキスト情報は、限定的です。自動車ユースケースと将来のスケーラビリティを改善するために、Android 14 に CarVolumeGroupEvent が追加されます。各イベントには次の 3 つの重要な情報が含まれています。

  • CarVolumeGroupInfo のリスト
  • EventTypes(ビットマップ)
  • ExtraInfos のリスト

CarVolumeGroupInfo

イベント コールバックの受信者は、影響を受けるカー音量グループ情報のリストにすぐにアクセスできます。つまり、アプリは最新の状態を取得するためにカーオーディオのフレームワークに対して追加の呼び出しをする必要がありません。受信した CarVolumeGroupInfos を使用するだけで、UI や内部状態を更新できます。アプリを使いやすくするために、以下に説明するように、音量グループ内で変更した側面も、EventTypes の一部として提供されます。

EventTypes

CarVolumeGroupInfo のどのアスペクトが変更したかを定義します。アプリはこれを使って変更を特定し、必要なアクションを取ることができます。たとえば、EVENT_TYPE_VOLUME_MAX_INDEX_CHANGED は、それぞれの CarVolumeGroups の最大音量のゲイン インデックスが変更されたことを示し、CarVolumeGroupInfo.getMaxVolumeGainIndex() でクエリを実行できます。

次の表に、EventTypeCarVolumeGroupInfo の関係を示します。

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_CHANGEDCarVolumeGroupInfo.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 をフェードさせることも選択できます。また、ダッキングが有効であることをトーストに表示して、ユーザーが音量を変更できるようにすることもできます。

カーオーディオのフレームワークは、AudioControl HAL IAudioGainCallback に依存して、推奨される ExtraInfos を提供します。詳しくは、オーディオ ゲイン コールバックをご覧ください。

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 に変更されます。

  • ユーザーからのミュートを無効にするリクエストは処理されません。キャッシュに保存されたユーザーのミュート状態は有効のままになります。

    • 理由: ユーザーのミュート解除リクエストは、アクティブな制約がない場合にのみ処理されます。

    • 理由: キャッシュに保存されたユーザー ミュートを解除すると、意図しない爆音が発生し、ユーザーの安全が脅かされる可能性があります。これは、イグニッション サイクル全体でミュート状態が有効になっている場合に特に当てはまります。イグニッション サイクルでは、ユーザーの音量レベルの認識に対する意識が低下するためです。

インタラクション ケース: HAL ミュートが有効化 / 無効化、ユーザー ミュートは変更なし

HAL ミュートを切り替えると、音量グループ全体のミュート状態が変更されます。ただし、ユーザーのミュート状態が直接更新されるわけではありません。ユーザー ミュートが無効で、有効化する HAL ミュート コールバックを受信した場合:

  • 音量グループ全体のミュート状態が true に変更されます。
  • HAL ミュートが有効になっている間は、ユーザーからの音量変更リクエストは処理されません。

    • 理由: ミュートが有効になっている間、ユーザーは知覚できません。音量の変更を許可すると、爆発音が発生し、ユーザーの安全が脅かされる可能性があります。

    • 理由: 音量アプリはコールバックに登録でき、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 に変更します。

  • このインデックスはボリューム ゲインに変換され、オーディオ 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 に設定されました。

動的音量の構成

この機能では、次のような主なユースケースを考慮しています。

  1. 車両エンドオブライン(EOL)構成。

    • 自動車メーカーは、車両のオーディオ システムのセットアップに基づいて、EOL 時に音量設定を更新することを好みます。通常、これは Android SW イメージを更新せずにサイドローディングします。

    • 自動車メーカーは、サービス スケジュール中に音量構成を更新する必要がある場合があります。

  2. 実行時構成。自動車用オーディオ システムは外部アンプ構成をサポートしており、これらの ECU は起動時にクエリに保存される音量範囲の構成をホストしている可能性があります。

  3. オンデマンドの構成。需要ベースのオーディオ機能に対するニーズの高まりをサポートするために提供されます。これにより、ユーザーは一定期間、強化された信号処理を登録します。新しい音量範囲の構成は、登録の有効期間中有効です。

デザイン

動的な音量構成は次の 3 つのステップで実現します。

  • 検出。ベンダーの AudioControl HAL 実装は、ベンダーが所有するカスタム IPC メカニズムから、新しい音量範囲の更新を検出します。

    検出されると、AudioControl::IModuleChangeCallback からコールバックが生成されます。

  • 更新。カーオーディオ スタックは、新しい音量範囲で音量グループの状態を更新します。

    音量範囲の更新後も同じ音量レベルを維持しようとしますが、インデックスが範囲外になった場合は、現在の音量インデックスが安全な値に設定されます。たとえば、コールバック時にベンダーがデフォルトのレベルを提供する場合などです。

  • コールバック。

    • 音量グループ範囲の更新後、カーオーディオ スタックは CarVolumeGroupEventCallback を介して登録したアプリへのコールバックをトリガーします。

    • CarVolumeGroupEvent は更新された CarVolumeGroupInfo、Event-type(変更内容)、Extra-info(変更理由)を伝達します。

画像

図 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_DEVICEOUT_DEVICE
    • 接続: BUS
    • アドレス: オーディオ HAL 定義で定義
    • ゲインモード: JOINT
  • ベンダーは、オーディオ HAL ポリシーのボリューム範囲定義のスーパーセットを定義し、コールバックを使用して車両のバリエーション用にカスタマイズする必要があります。詳しくは、IModuleChangeCallbac AIDL 定義をご覧ください。

  • 複数のオーディオ BUS が同じ音量グループに属する場合、それぞれの音量範囲の定義は同一でなければなりません。そうでない場合、カーオーディオのフレームワークが新しい音量範囲の定義を拒否します。