Android 10 版本對音頻政策管理器進行了重大重構,有助于更靈活地支持復雜的車載使用情形:
- 提供了 OEM 專用路由策略。
- 針對使用相同音量曲線的舊版音頻流類型組提供了可自定義音量組。
- 路由策略由音頻政策引擎聲明,而不是采用硬編碼格式。
- 音量曲線和組由音頻政策引擎管理。
- 進行了內部重構,目的是為將來分離公共代碼和可配置代碼做準備,并提供更豐富的音頻設備管理功能。例如,在政策規則中使用所有設備屬性,而不僅僅是其類型。
Android 7.0 引入了音頻政策配置文件格式 (XML),用于描述音頻拓撲。
以前的 Android 版本需要使用 device/<company>/<device>/audio/audio_policy.conf 來聲明您的產品上存在的音頻設備(您可以在 device/samsung/tuna/audio/audio_policy.conf 中查看此文件針對 Galaxy Nexus 音頻硬件的示例)。但是,CONF 是一種簡單的專有格式,有較大的局限性,無法描述電視和汽車等行業的復雜拓撲。
Android 7.0 已棄用 audio_policy.conf 并添加了對使用 XML 文件格式定義音頻拓撲的支持,該文件格式更易于閱讀,可使用各種修改和解析工具,并且足夠靈活,可以描述復雜的音頻拓撲。Android 7.0 使用 USE_XML_AUDIO_POLICY_CONF 構建標志來選擇 XML 格式的配置文件。
USE_XML_AUDIO_POLICY_CONF 構建標志的支持,因此無法使用已棄用的 CONF 格式。
XML 格式的優勢
與在 CONF 文件中一樣,XML 文件支持定義輸出輸入流配置文件、可用于播放和捕獲的設備以及音頻屬性的數量和類型。此外,XML 格式還提供以下增強功能:
- 在 Android 10 中,允許同時使用多個正在運行的錄音應用。
- 開始錄音的請求絕不會因為存在并發情況而遭到拒絕。
registerAudioRecordingCallback(AudioManager.AudioRecordingCallback cb)回調會將捕獲路徑更改通知客戶端。
- 在以下情況下,客戶端會獲取無聲音頻樣本:
- 對隱私敏感的用例(例如,
VOICE_COMMUNICATION)處于活動狀態。 - 客戶端沒有前臺服務或前臺界面。
- 政策識別到了特殊的角色:
- 無障礙服務:即使對隱私敏感的用例處于活動狀態,也可以錄音。
- Google 助理:如果相應界面位于頂層,則視為隱私敏感。
- 對隱私敏感的用例(例如,
- 音頻配置文件的結構類似于 HDMI 簡單音頻描述符,支持每種音頻格式使用一組不同的采樣率/聲道掩碼。
- 設備和流之間所有可能的連接都有顯式定義。以前,隱式規則可以使連接到同一 HAL 模塊的所有設備互連,從而阻止音頻政策控制使用音頻補丁程序 API 請求的連接。在 XML 格式中,拓撲描述定義了連接限制。
- 對“包含”的支持可避免出現重復的標準 A2DP、USB 或重新導向提交定義。
- 音量曲線可自定義。以前,音量表采用硬編碼格式。在 XML 格式中,音量表通過描述來定義,并且可自定義。
frameworks/av/services/audiopolicy/config/audio_policy_configuration.xml 中的模板展示了很多已在使用的上述功能。
文件格式和位置
新的音頻政策配置文件是 audio_policy_configuration.xml,位于 /system/etc。以下示例顯示了適用于 Android 12 及 Android 12 以下版本且采用 XML 文件格式的簡單音頻政策配置。
<?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 硬件模塊對應的模塊,其中每個模塊都有一系列混音端口、設備端口和導向:
- 混音端口描述了可以在音頻 HAL 處打開以供播放和捕獲的流的可能配置文件。
- 設備端口描述了可以附上其類型(以及(可選)地址和音頻屬性,如果相關)的設備。
- 導向已從混音端口描述符中分離出來,支持描述從設備到設備或從流到設備的導向。
音量表是定義用于將界面索引轉換為音量(以 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 模塊配置信息復制到所有音頻政策配置文件(這樣做容易出錯)。我們為以下音頻 HAL 提供了標準音頻政策配置 XML 文件:
- 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 |
實現相關規則,這些規則定義應將哪些設備和音量用于指定用例。該模塊會實現標準接口(包含通用部分),例如,為指定的播放或捕獲用例獲取適當的設備,或設置可以改變導向選擇的已連接設備或外部狀態(即強制使用的調用狀態)。 該模塊有兩種版本:可配置版本和默認版本。如需了解如何選擇版本,請參閱使用參數框架的配置。 |
/engineconfigurable |
依賴參數框架的政策引擎實現(請參閱下文)。配置基于參數框架,相關政策由 XML 文件定義。 |
/enginedefault |
基于以前的 Android 音頻政策管理中心實現的政策引擎實現。這是默認模塊,包含 Nexus 和 AOSP 實現對應的硬編碼規則。 |
/service |
包含 Binder 接口、線程和鎖定實現(包含連接框架其余部分的接口)。 |
使用參數框架的配置
平臺對音頻策略代碼進行了組織,使其易于理解和維護,同時也支持完全由配置文件定義的音頻政策。組織和音頻政策設計基于 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 引入了一個公共 Enumeration and Selection API,位于音頻補丁程序/音頻端口基礎架構之上。借助它,應用開發者可以為連接的音頻錄制或軌道指明特定設備輸出或輸入的偏好設置。
在 Android 7.0 中,Enumeration and Selection API 通過了 CTS 測試的驗證,并經過擴展,可導向原生 C/C++ (OpenSL ES) 音頻流。原生流的路由仍然由 Java 完成,另外還添加了 AudioRouting 接口,該接口會取代、合并和廢棄特定于 AudioTrack 和 AudioRecord 類的顯式路由方法。
如需詳細了解 Enumeration and Selection API,請參閱 Android 配置接口和 OpenSLES_AndroidConfiguration.h。如需詳細了解音頻導向,請參閱 AudioRouting。
多聲道支持
如果您的硬件和驅動程序通過 HDMI 支持多聲道音頻,則可以將音頻流直接輸出到音頻硬件(這樣可以繞過 AudioFlinger 混音器,也就不會被降混成兩個聲道)。音頻 HAL 必須公開輸出流配置文件是否支持多聲道音頻功能。如果 HAL 公開其功能,默認的政策管理中心會允許通過 HDMI 進行多聲道播放。如需了解實現詳情,請參閱 device/samsung/tuna/audio/audio_hw.c。
如需指定您的產品包含多聲道音頻輸出,請修改音頻政策配置文件,對產品的多聲道輸出進行描述。以下示例來自 frameworks/av/services/audiopolicy/config/primary_audio_policy_configuration_tv.xml,它展示了動態聲道掩碼,這表示音頻政策管理中心會在連接后查詢 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 的混音器會自動將該內容降混成立體聲。
媒體編解碼器
確保針對您的產品正確聲明您的硬件和驅動程序支持的音頻編解碼器。如需了解詳情,請參閱向框架公開編解碼器。
浙公網安備 33010602011771號