這項功能可同時將音訊串流至多個音訊裝置,透過這項功能,具備特殊權限的應用程式可以透過系統 API,為特定策略選取多個偏好的裝置。應用程式可使用這項功能提供的公開 API,更精確地探索音訊裝置的功能。在 Android 11 以下版本中,音訊架構實作項目對同時連線的多個同類型音訊裝置 (例如 2 個藍牙 A2DP 耳機) 支援有限。此外,根據預設的音訊路徑規則,使用者無法為特定用途選取多個相同類型的裝置。
自 Android 12 起,系統已移除這些限制,以便支援新的用途,例如音訊廣播、向一組 BLE 音訊耳機進行多點傳播,或同時選取多張 USB 音效卡。系統不支援同時將音訊傳送至多個 USB 裝置。
自 Android 14 起,USB 架構支援將音訊路徑傳送至多個 USB 裝置,前提是這些 USB 裝置屬於不同類型的音訊裝置,且核心和供應商支援同時連線至多個 USB 裝置。
本頁說明如何實作支援將音訊串流至多個音訊裝置的功能,以及如何驗證這項功能的實作方式。
支援將音訊串流到多部音訊裝置
Android 12 有兩組 API 支援這項功能:
- 系統 API 會處理策略的多個偏好裝置。
- 供應商實作的 HIDL 介面是音訊 HAL 的一部分,可回報裝置功能。
以下各節將詳細說明這些 API。
處理策略的多個偏好裝置
音訊政策管理工具提供系統 API,可同時將音訊串流傳輸至多個音訊裝置。這些系統 API 可為特定策略設定、取得及移除多個偏好裝置。在 Android 12 之前,這項功能僅支援單一裝置。
音訊政策管理工具導入了「使用中媒體裝置」的概念,用來描述最有可能選取播放媒體的裝置。連接可拆卸裝置時,可能必須開啟可路由至該裝置的音訊 HAL 輸出串流,並探查支援的屬性。
開啟輸出串流時,必須指定音訊裝置。當輸出串流在這個情境中開啟時,系統會使用作用中的媒體裝置。
實際連線或中斷連線的裝置可能會影響媒體裝置的選取狀態。音訊政策管理工具會使用下列一系列規則選擇有效的媒體裝置:
- 如果所有偏好的媒體裝置都可用,系統會選擇所有裝置做為有效裝置。
- 否則系統會選擇上次連線的可移除式裝置。
- 如果沒有連線可移除的裝置,系統會套用選擇輸出裝置的預設音訊政策規則,選擇要啟用的裝置。
輸出串流必須符合下列條件,才能重新開啟並傳送至有效裝置,以便選取最佳設定來播放:
- 輸出串流必須支援有效裝置。
- 輸出串流必須支援動態設定檔。
- 輸出串流目前不得傳送至使用中的裝置。
如要套用新的裝置選取項目,音訊政策管理員會在裝置連線時關閉並重新開啟輸出串流 (如果輸出串流處於閒置狀態),或延後套用,直到輸出串流進入待機狀態為止。
音訊政策管理員提供下列系統 API 清單(如 AudioManager.java
中所定義):
setPreferredDeviceForStrategy
為指定策略設定音訊路徑的偏好裝置。請注意,設定偏好裝置時,該裝置可能無法使用,但一旦可用就會使用。
removePreferredDeviceForStrategy
移除先前使用
setPreferredDeviceForStrategy
或setPreferredDevicesForStrategy
設定的偏好音訊裝置。getPreferredDeviceForStrategy
傳回先前透過
setPreferredDeviceForStrategy
或setPreferredDevicesForStrategy
設定的音訊策略偏好裝置。setPreferredDevicesForStrategy
為指定策略設定偏好的裝置。
getPreferredDevicesForStrategy
傳回先前透過
setPreferredDeviceForStrategy
或setPreferredDevicesForStrategy
設定的音訊策略偏好裝置。OnPreferredDevicesForStrategyChangedListener
定義介面,用於通知特定音訊策略所設偏好音訊裝置的變更。
addOnPreferredDevicesForStrategyChangedListener
新增監聽器,以便在策略偏好的音訊裝置變更時收到通知。
removeOnPreferredDevicesForStrategyChangedListener
移除先前新增的監聽器,用於監聽策略偏好的音訊裝置變更。
回報裝置功能
在實作 Audio HAL 時,供應商會實作支援回報裝置功能的 API。本節說明用於回報裝置功能的資料型別和方法,並列出音訊 HIDL HAL V7 中為支援多部裝置所做的部分變更。
資料類型
在音訊 HIDL HAL V7 中,裝置功能是使用 AudioProfile
和 AudioTransport
結構體回報。AudioTransport
結構會說明音訊埠的功能,其中包含已知音訊格式的 AudioProfile
,或平台未知的格式原始硬體描述元。AudioProfile
結構包含音訊格式、設定檔支援的取樣率,以及聲道遮罩清單,如下列 types.hal
的程式碼區塊所示:
/**
* Configurations supported for a certain audio format.
*/
struct AudioProfile {
AudioFormat format;
/** List of the sample rates (in Hz) supported by the profile. */
vec<uint32_t> sampleRates;
/** List of channel masks supported by the profile. */
vec<AudioChannelMask> channelMasks;
};
在音訊 HIDL HAL V7 中,AudioPort
資料型別是使用 AudioTransport
和 AudioProfile
結構定義,用於說明裝置的功能。
音訊 HAL 方法
音訊政策管理員會使用下列方法查詢裝置功能:
getParameters:
用於擷取供應商專屬參數值 (例如支援的音訊格式和各自的取樣率) 的一般方法。getAudioPort:
傳回指定音訊埠支援的屬性清單 (例如取樣率、格式、聲道遮罩、增益控制器)。
IDevice.hal
中的下列程式碼顯示 getAudioPort
方法的介面:
/**
* Returns the list of supported attributes for a given audio port.
*
* As input, 'port' contains the information (type, role, address etc...)
* needed by the HAL to identify the port.
*
* As output, 'resultPort' contains possible attributes (sampling rates,
* formats, channel masks, gain controllers...) for this port.
*
* @param port port identifier.
* @return retval operation completion status.
* @return resultPort port descriptor with all parameters filled up.
*/
getAudioPort(AudioPort port)
generates (Result retval, AudioPo
rt resultPort);
舊版 API 異動
為支援多個音訊設定檔,舊版 API 3.2 版新增名為 audio_port_v7
的結構。詳情請參閱原始碼。
由於新增了 audio_port_v7
,舊版 API 3.2 版新增了名為 get_audio_port_v7
的 API,可使用 audio_port_v7
結構查詢裝置功能。
以下 audio.h
中的程式碼顯示 get_audio_port_v7
API 的定義:
/**
* Fills the list of supported attributes for a given audio port.
* As input, "port" contains the information (type, role, address etc...)
* needed by the HAL to identify the port.
* As output, "port" contains possible attributes (sampling rates,
* formats, channel masks, gain controllers...) for this port. The
* possible attributes are saved as audio profiles, which contains audio
* format and the supported sampling rates and channel masks.
*/
int (*get_audio_port_v7)(struct audio_hw_device *dev,
struct au
dio_port_v7 *port);
如果舊版 get_audio_port
API 版本低於 3.2,且 HIDL HAL 版本為 7 以上,則必須將舊版 API 的資料填入新的 AudioPort
格式。在這種情況下,系統會假設所有傳回的格式都支援 get_audio_port
回報的所有取樣率和聲道遮罩,因此可直接將 get_audio_port
值對應至新的 AudioPort
結構。
API 導入範例
本節說明幾個測試套件,其中包含使用前幾節所述 API 的方法。如需這些 API 的實作和使用範例,請參閱這些方法。
setPreferredDevicesForStrategy
、getPreferredDevicesForStrategy
、removePreferredDeviceForStrategy
和 OnPreferredDevicesForStrategyChangedListener
系統 API 的使用範例位於 GTS 的 PreferredDeviceRoutingTest
方法中。
如要查看 AudioDeviceInfo
中使用的新結構範例,請參閱 CTS 中的 AudioManagerTest#testGetDevices
方法。
get_audio_port_v7
的實作範例位於 audio_hal.c
,其中說明如何查詢多部裝置的功能。
驗證
本節提供音訊管理員的 CTS 和 GTS (Google Mobile Services Test Suite) 驗證資訊。
CTS 測試
CTS 測試位於 android.media.cts.AudioManagerTest
。
以下列出可用的音訊管理員測試:
AudioManagerTest#testGetDevices
驗證音訊裝置的精確功能。此外,這項測試也會驗證
AudioDeviceInfo
結構中傳回的音訊設定檔是否保留舊版扁平陣列格式的內容,但採用新的AudioProfile
格式。AudioManagerTest#testPreferredDevicesForStrategy
和AudioManagerTest#testPreferredDeviceForCapturePreset
確認策略和擷取預設相關 API 測試在偏好的裝置上順利完成。
GTS 測試
GTS 測試位於 com.google.android.gts.audioservice.AudioServiceHostTest
。
如要驗證策略和擷取預設設定的偏好裝置 API 是否正常運作,請執行 AudioServiceHostTest#testPreferredDeviceRouting
和 AudioServiceHostTest#testPreferredDeviceRoutingForCapturePreset
測試。