Android 10 リリースでは、オーディオ ポリシー マネージャーの重要なリファクタリングが含まれており、自動車の複雑なユースケースをサポートするために次のような柔軟性が強化されています。
OEM 固有のルーティング ストラテジー
同一のボリューム カーブを使用し、従来のストリーム タイプを持つグループのカスタマイズが可能なボリューム グループ
ハード コーディングではなく、オーディオ ポリシー エンジンによってルーティング ストラテジーを宣言
ボリューム カーブとグループをオーディオ ポリシー エンジンによって管理
共通コードおよび構成可能なコードの将来的な分割の必要性に備えた内部リファクタリングと、より豊富なオーディオ デバイス管理の提供(たとえば、ポリシールールのプロパティ タイプだけでなく、すべてのデバイス プロパティを使用できます)
Android 7.0 では、オーディオ トポロジを記述するためのオーディオ ポリシー構成ファイル形式(XML)が導入されました。
以前の Android リリースでは、デバイスに存在するオーディオ デバイスの宣言に device/<company>/<device>/audio/audio_policy.conf
を使用する必要がありました(このファイルの具体例については、Galaxy Nexus のオーディオ ハードウェアの例を device/samsung/tuna/audio/audio_policy.conf
で参照できます)。しかし、CONF はシンプルな上に独自の形式であったため、テレビや自動車などの複雑なトポロジを記述するには多くの制約がありました。
Android 7.0 では audio_policy.conf
が廃止され、XML ファイル形式を使用してオーディオ トポロジを定義するためのサポートが追加されました。XML ファイル形式は人間が読み取れる形式で、さまざまな編集および解析ツールが存在します。また、複雑なオーディオ トポロジを記述できる十分な柔軟性も備えています。オーディオ ポリシー構成ファイルに XML 形式を使うため、Android 7.0 では USE_XML_AUDIO_POLICY_CONF
ビルドフラグを使用します。
注: USE_XML_AUDIO_POLICY_CONF
ビルドフラグのサポートは Android 10 で削除され、それに伴って非推奨 CONF 形式も廃止されました。
XML 形式のメリット
XML ファイルでも、CONF ファイルと同様に、出力および入力ストリーム プロファイルの数やタイプ、再生とキャプチャに使用できるデバイス、オーディオ属性を定義できます。加えて、XML 形式には次のような利点があります。
Android 10 では、同時に複数の録音アプリを実行できます。
同時実行が原因で録音開始が拒否されることはありません。
registerAudioRecordingCallback(AudioManager.AudioRecordingCallback cb)
コールバックによって、クライアントにキャプチャパスの変更が通知されます。
クライアントは、次の状況でサイレント オーディオ サンプルを取得します。
プライバシーに配慮が必要なユースケース(VOICE_COMMUNICATION
など)の場合。
クライアントにフォアグラウンド サービスまたはフォアグラウンド UI がない場合。
ポリシーによって次に示す特別なロールが認識される場合。
アクセシビリティ サービス: プライバシーに配慮が必要なユースケースの場合でも録音できます。
アシスタント: UI が上位にある場合は機密性が高いと見なされます。
オーディオ プロファイルは、HDMI シンプル オーディオ記述子に類似した構造を持ち、各オーディオ形式に対して、サンプリング レート / チャンネル マスクのさまざまな組み合わせを有効にします。
デバイスとストリーム間で可能なすべての接続が、明示的に定義されています。
以前はルールが明確化されておらず、同じ HAL モジュールに接続されたすべてのデバイスを接続できたため、オーディオ パッチ API でリクエストされた接続をオーディオ ポリシーによって制御できないことがありました。XML 形式では、トポロジの記述によって接続の制限を定義します。
「インクルード」のサポートによって、標準の A2DP、USB の繰り返し、または送信定義の再ルーティングが回避されます。
ボリューム カーブはカスタマイズ可能です。以前は、ボリューム テーブルがハード コードされていました。XML 形式ではボリューム テーブルを記述するため、カスタマイズが可能です。
frameworks/av/services/audiopolicy/config/audio_policy_configuration.xml
のテンプレートには、これらの機能の実際の使用例が示されています。
新しいオーディオ ポリシー構成ファイルは audio_policy_configuration.xml
で、/system/etc
にあります。次の例は、Android 12 とそれ以前のバージョンにおける XML ファイル形式の単純なオーディオ ポリシー設定を示しています。
Android 12 のオーディオ ポリシーの例
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude">
<globalConfiguration speaker_drc_enabled="true"/>
<modules>
<module name="primary" halVersion="3.0">
<attachedDevices>
<item>Speaker</item>
<item>Earpiece</item>
<item>Built-In Mic</item>
</attachedDevices>
<defaultOutputDevice>Speaker</defaultOutputDevice>
<mixPorts>
<mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
<mixPort name="primary input" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000 16000 48000"
channelMasks="AUDIO_CHANNEL_IN_MONO"/>
</mixPort>
</mixPorts>
<devicePorts>
<devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
</devicePort>
<devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</devicePort>
<devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</devicePort>
<devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000 16000 48000"
channelMasks="AUDIO_CHANNEL_IN_MONO"/>
</devicePort>
<devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000 16000 48000"
channelMasks="AUDIO_CHANNEL_IN_MONO"/>
</devicePort>
</devicePorts>
<routes>
<route type="mix" sink="Earpiece" sources="primary output"/>
<route type="mix" sink="Speaker" sources="primary output"/>
<route type="mix" sink="Wired Headset" sources="primary output"/>
<route type="mix" sink="primary input" sources="Built-In Mic,Wired Headset Mic"/>
</routes>
</module>
<xi:include href="a2dp_audio_policy_configuration.xml"/>
</modules>
<xi:include href="audio_policy_volumes.xml"/>
<xi:include href="default_volume_tables.xml"/>
</audioPolicyConfiguration>
Android 12 より前のバージョンのオーディオ ポリシーの例
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
<globalConfiguration speaker_drc_enabled="true"/>
<modules>
<module name="primary" halVersion="3.0">
<attachedDevices>
<item>Speaker</item>
<item>Earpiece</item>
<item>Built-In Mic</item>
</attachedDevices>
<defaultOutputDevice>Speaker</defaultOutputDevice>
<mixPorts>
<mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
<mixPort name="primary input" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO"/>
</mixPort>
</mixPorts>
<devicePorts>
<devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
</devicePort>
<devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</devicePort>
<devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</devicePort>
<devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO"/>
</devicePort>
<devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO"/>
</devicePort>
</devicePorts>
<routes>
<route type="mix" sink="Earpiece" sources="primary output"/>
<route type="mix" sink="Speaker" sources="primary output"/>
<route type="mix" sink="Wired Headset" sources="primary output"/>
<route type="mix" sink="primary input" sources="Built-In Mic,Wired Headset Mic"/>
</routes>
</module>
<xi:include href="a2dp_audio_policy_configuration.xml"/>
</modules>
<xi:include href="audio_policy_volumes.xml"/>
<xi:include href="default_volume_tables.xml"/>
</audioPolicyConfiguration>
最上位の構造にはそれぞれのオーディオ HAL ハードウェア モジュールに対応するモジュールが含まれており、各モジュールは、ミックスポート、デバイスポート、およびルートのリストを持ちます。
ミックスポート(mixPort) は、再生およびキャプチャのためにオーディオ HAL で開くことが可能な、ストリーム用の構成プロファイルについて記述します。
デバイスポート(devicePorts) は、各デバイスタイプで接続可能なデバイスを記述します(必要に応じて、アドレスやオーディオ プロパティも指定できます)。
ルート(route) は、ミックスポート記述子とは別に、デバイス対デバイス、ストリーム対デバイスのルートの記述を行います。
ボリューム テーブル(volume_tables)とは、UI インデックスから dB にボリュームを変換するための曲線を定義するポイントを含んだ単純なリストです。独立したインクルード ファイルはデフォルトの曲線を持ちますが、特定のユースケースやデバイス カテゴリの各曲線は上書きできます。
ボリューム テーブルの例
<?xml version="1.0" encoding="UTF-8"?>
<volumes>
<reference name="FULL_SCALE_VOLUME_CURVE">
<point>0,0</point>
<point>100,0</point>
</reference>
<reference name="SILENT_VOLUME_CURVE">
<point>0,-9600</point>
<point>100,-9600</point>
</reference>
<reference name="DEFAULT_VOLUME_CURVE">
<point>1,-4950</point>
<point>33,-3350</point>
<point>66,-1700</point>
<point>100,0</point>
</reference>
</volumes>
ボリュームの例
<?xml version="1.0" encoding="UTF-8"?>
<volumes>
<volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER">
<point>1,-5500</point>
<point>20,-4300</point>
<point>86,-1200</point>
<point>100,0</point>
</volume>
<volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="SILENT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="SILENT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="SILENT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/>
</volumes>
ファイルのインクルージョン
XML インクルージョン(XInclude)メソッドを使用して、他の XML ファイルにあるオーディオ ポリシー設定情報をインクルードできます。インクルードするすべてのファイルは上記の構造に準拠する必要があります。また、次の制限も適用されます。
ファイルには上位レベル要素のみを含めることができる。
ファイルに XInclude 要素を含めることはできない。
インクルードを使用して、標準の Android オープンソース プロジェクト(AOSP)のオーディオ HAL モジュールの構成情報を、すべてのオーディオ ポリシー構成ファイルにコピーしないようにします(エラーが発生しやすいため)。標準オーディオ ポリシー設定 XML ファイルは、次のオーディオ HAL 用に用意されています。
A2DP: a2dp_audio_policy_configuration.xml
サブミックスの再ルーティング: rsubmix_audio_policy_configuration.xml
USB: usb_audio_policy_configuration.xml
オーディオ ポリシー コードの構成
AudioPolicyManager.cpp
はいくつかのモジュールに分割されているため、メンテナンスや構成が容易です。frameworks/av/services/audiopolicy
の構成には、次のモジュールが含まれます。
モジュール
説明
/managerdefault
すべてのアプリに共通の一般的なインターフェースと動作の実装が含まれます。エンジン機能と抽象化された共通概念を備える AudioPolicyManager.cpp
に類似しています。
/common
基本クラス(入出力オーディオ ストリーム プロファイルのデータ構造、オーディオ デバイス記述子、オーディオ パッチ、オーディオ ポートなど)を定義します。以前は AudioPolicyManager.cpp
内で定義されていました。
/engine
特定のユースケースで使用するデバイスおよびボリュームを定義するルールを実装します。特定のユースケースの再生またはキャプチャに適したデバイスを取得する、接続デバイスまたは外部ステート(強制使用の呼び出し状態)を設定するなど、ルーティング決定の変更を伴い得るような、汎用部分との標準インターフェースを実装します。
構成可能 とデフォルト の 2 つのバージョンがあります。バージョンの選択方法については、パラメータ フレームワークを使用した構成 をご覧ください。
/engineconfigurable
パラメータ フレームワーク(下記参照)に依存するポリシー エンジンの実装です。
設定はパラメータ フレームワークに基づいており、ポリシーは XML ファイルで定義されています。
/enginedefault
以前の Android オーディオ ポリシー マネージャーの実装に基づくポリシー エンジンの実装。この実装はデフォルトで、Nexus および AOSP の実装に対応するハード コードされたルールが含まれます。
/service
フレームワークの他の部分へのインターフェースを備えた、バインダー インターフェース、スレッド化、ロッキングの実装を含みます。
パラメータ フレームワークを使用した構成
オーディオ ポリシー コードは、構成ファイルで完全に定義されたオーディオ ポリシーをサポートすると同時に、理解やメンテナンスがしやすいように編成されています。構成やオーディオ ポリシーの設計は、パラメータを処理するためのプラグインベースおよびルールベースのフレームワークである Intel のパラメータ フレームワークに基づいています。
ベンダー OEM は、設定可能なオーディオ ポリシーを使用して次のことが行えます。
システムの構造とそのパラメータを XML で記述する。
記述されたパラメータにアクセスするためのバックエンド(プラグイン)を作成(C++ で)するか、再利用する。
パラメータが特定の値を取る必要がある条件やルールを定義(XML またはドメイン固有の言語で)する。
AOSP には、Frameworks/av/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml
でパラメータ フレームワークを使用するオーディオ ポリシー構成ファイルの例が含まれています。詳細については、パラメータ フレームワーク に関する Intel のドキュメントをご覧ください。
Android 10 以前では、ビルド オプション USE_CONFIGURABLE_AUDIO_POLICY
を使用して、構成可能なオーディオ ポリシーを選択します。Android 11 以降では、audio_policy_configuration.xml
ファイルでオーディオ ポリシー エンジンのバージョンを選択します。構成可能なオーディオ ポリシー エンジンを選択するには、次の例に示すように、globalConfiguration
要素の engine_library
属性の値を configurable
に設定します。
<audioPolicyConfiguration>
<globalConfiguration engine_library="configurable" />
...
</audioPolicyConfiguration>
オーディオ ポリシー ルーティング API
Android 6.0 では、列挙および選択 API(公開)が導入されました。これは、オーディオ パッチ / オーディオ ポート インフラストラクチャ上にあり、アプリ デベロッパーが、接続されたオーディオ レコードまたはトラックに対して優先すべきデバイス出力または入力を指定できるようになっていました。
Android 7.0 では、列挙および選択 API は CTS テストにより検証され、ネイティブ C/C++(OpenSL ES)オーディオ ストリームのルーティングを含むように拡張されています。
ネイティブ ストリームのルーティングは Java で引き続き実行されますが、AudioTrack
クラスと AudioRecord
クラスに固有だった明示的なルーティング メソッドを廃止し、これより優先され、これらを統合する AudioRouting
インターフェースが追加されています。
列挙および選択 API の詳細については、Android 構成インターフェース および OpenSLES_AndroidConfiguration.h
をご覧ください。オーディオ ルーティングの詳細については、AudioRouting をご覧ください。
マルチチャンネル サポート
ハードウェアとドライバで HDMI 経由のマルチチャンネル オーディオがサポートされている場合、オーディオ ストリームをオーディオ ハードウェアに直接出力できます(2 チャンネルにダウンミックスされることのないよう、AudioFlinger ミキサーをバイパスします)。オーディオ HAL で、出力ストリーム プロファイルがマルチチャンネル オーディオ機能をサポートしているかどうかを公開する必要があります。HAL でその機能を公開している場合、デフォルトのポリシー マネージャーによって HDMI 経由のマルチチャンネル再生が許可されます。実装の詳細については、device/samsung/tuna/audio/audio_hw.c
をご覧ください。
デバイスにマルチチャンネル オーディオ出力が含まれることを指定するには、オーディオ ポリシー構成ファイルを編集して、デバイスのマルチチャンネル出力を記述します。次の frameworks/av/services/audiopolicy/config/primary_audio_policy_configuration_tv.xml
の例は、動的な チャンネル マスクを示しています。ここでいう「動的」とは、オーディオ ポリシー マネージャーが、HDMI シンクがサポートするチャンネル マスクのクエリを接続後に実行することを意味します。
HDMI デバイス設定の例
<module name="primary" halVersion="2.0">
<attachedDevices>
<item>Speaker</item>
</attachedDevices>
<defaultOutputDevice>Speaker</defaultOutputDevice>
<mixPorts>
<mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
<mixPort name="direct" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT" />
<mixPort name="tunnel" role="source"
flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_HW_AV_SYNC" />
</mixPorts>
<devicePorts>
<devicePort tagName="Speaker" type="AUDIO_DEVICE_OUT_SPEAKER" role="sink" />
<devicePort tagName="Out Aux Digital" type="AUDIO_DEVICE_OUT_AUX_DIGITAL" role="sink"
encodedFormats="AUDIO_FORMAT_AC3 AUDIO_FORMAT_IEC61937" />
</devicePorts>
<routes>
<route type="mix" sink="Speaker" sources="primary output"/>
<route type="mix" sink="Out Aux Digital" sources="primary output,direct,tunnel"/>
</routes>
</module>
AUDIO_CHANNEL_OUT_5POINT1
などの静的チャンネル マスクを指定することもできます。AudioFlinger のミキサーは、マルチチャンネル オーディオをサポートしていないオーディオ デバイスに送信されると、自動的にコンテンツをステレオにダウンミックスします。
メディア コーデック
ハードウェアとドライバでサポートされているオーディオ コーデックが、デバイスに対して適切に宣言されていることを確認してください。詳細については、フレームワークにコーデックを公開する をご覧ください。