綜合音訊裝置轉送

結合音訊裝置路由功能後,系統就能同時將音訊串流至多個音訊裝置。有了這項功能,具備特殊權限的應用程式就能透過系統 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 輸出串流路由至此裝置的串流,並對支援的屬性進行探測。

開啟輸出串流時,必須指定音訊裝置。在這個情境中,當輸出串流開啟時,所使用的裝置即為有效媒體裝置。

活動媒體裝置的選取項目可能會因實際連線或斷線的裝置而異。Audio Policy Manager 會使用下列一系列規則選擇有效的媒體裝置:

  1. 如果所有媒體的偏好裝置皆可使用,系統會將這些裝置都選為有效裝置。
  2. 否則,系統會選擇最近連結的可移除裝置。
  3. 如果沒有連接任何可移除的裝置,系統會套用選擇輸出裝置的預設音訊政策規則,選擇有效的裝置。

輸出串流必須符合下列條件,才能重新開啟並路由至有效裝置,以便為播放選取最佳設定:

  • 輸出串流必須支援有效裝置。
  • 輸出串流必須支援動態設定檔。
  • 輸出串流目前不得導向至有效裝置。

為了套用新的裝置選項,如果輸出串流處於閒置狀態,Audio Policy Manager 會在裝置連線時關閉及重新開啟輸出串流,或是在輸出串流進入待機狀態時延遲。

Audio Policy Manager 提供下列系統 API 清單(如 AudioManager.java 中所定義):

  • setPreferredDeviceForStrategy

    設定特定策略的音訊轉送偏好裝置。請注意,在設定偏好裝置時,裝置可能無法使用,但會在可用時使用。

  • removePreferredDeviceForStrategy

    移除先前使用 setPreferredDeviceForStrategysetPreferredDevicesForStrategy 設定的偏好音訊裝置。

  • getPreferredDeviceForStrategy

    傳回先前使用 setPreferredDeviceForStrategysetPreferredDevicesForStrategy 設定的音訊策略所用的偏好裝置。

  • setPreferredDevicesForStrategy

    設定指定策略的偏好裝置。

  • getPreferredDevicesForStrategy

    傳回先前透過 setPreferredDeviceForStrategysetPreferredDevicesForStrategy 設定的音訊策略所用的偏好裝置。

  • OnPreferredDevicesForStrategyChangedListener

    定義介面,用於通知偏好的音訊裝置變更,這些裝置是針對特定音訊策略設定的。

  • addOnPreferredDevicesForStrategyChangedListener

    新增監聽器,以便在策略偏好的音訊裝置發生變更時收到通知。

  • removeOnPreferredDevicesForStrategyChangedListener

    移除先前新增的策略偏好音訊裝置變更事件監聽器。

回報裝置功能

供應商會在 Audio HAL 實作中,實作支援回報裝置功能的 API。本節將說明用於回報裝置功能的資料類型和方法,並列出 audio HIDL HAL V7 中為了支援多個裝置而進行的部分變更。

資料類型

在音訊 HIDL HAL V7 中,裝置功能會使用 AudioProfileAudioTransport 結構回報。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 資料類型會使用 AudioTransportAudioProfile 結構定義,以便描述裝置的功能。

音訊 HAL 方法

Audio Policy Manager 會使用下列方法查詢裝置功能:

  • 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, AudioPort 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 audio_port_v7 *port);

如果舊版 API 版本低於 3.2,而 HIDL HAL 版本為 7 以上,則必須將舊版 get_audio_port API 的資料填入新的 AudioPort 格式。在這種情況下,系統會假設所有傳回格式都支援 get_audio_port 中所有回報的取樣率和通道遮罩,讓您可以直接將 get_audio_port 值對應至新的 AudioPort 結構。

API 實作範例

本節將說明幾個測試套件,其中包含使用前面各節所述 API 的方法。如需這些 API 的實作和使用方式範例,請參考這些方法。

setPreferredDevicesForStrategygetPreferredDevicesForStrategyremovePreferredDeviceForStrategyOnPreferredDevicesForStrategyChangedListener 系統 API 的使用方式範例,可參考 GTS 中的 PreferredDeviceRoutingTest 方法。

如要查看 AudioDeviceInfo 中新結構體的使用範例,請參閱 CTS 中的 AudioManagerTest#testGetDevices 方法。

get_audio_port_v7 的實作範例位於 audio_hal.c,其中說明如何針對多部裝置查詢功能。

驗證

本節提供 CTS 和 GTS (Google 行動服務測試套件) 對 Audio Manager 進行驗證的相關資訊。

CTS 測試

CTS 測試位於 android.media.cts.AudioManagerTest

以下列出可用的 Audio Manager 測試:

  • AudioManagerTest#testGetDevices

    驗證音訊裝置的確切功能。它也會驗證 AudioDeviceInfo 結構中傳回的音訊設定檔是否保留舊版扁平陣列格式的內容,但採用新的 AudioProfile 格式。

  • AudioManagerTest#testPreferredDevicesForStrategyAudioManagerTest#testPreferredDeviceForCapturePreset

    確認策略的偏好裝置和擷取預設相關 API 測試是否已順利完成。

GTS 測試

GTS 測試位於 com.google.android.gts.audioservice.AudioServiceHostTest 中。

如要驗證策略和擷取預設值所用的偏好裝置 API 是否正常運作,請執行 AudioServiceHostTest#testPreferredDeviceRoutingAudioServiceHostTest#testPreferredDeviceRoutingForCapturePreset 測試。