組合音頻設備路由

組合音頻設備路由功能增加了對同時向多個音頻設備流式傳輸音頻的支持。使用此功能,特權的應用程序可以為特定選擇多個首選設備策略的系統API的方式。應用程序可以通過此功能提供的公共 API 更準確地發現音頻設備的功能。對於 Android 11 及以下版本,音頻框架實現對同時連接的多個相同類型的音頻設備(例如,2 個藍牙 A2DP 耳機)的支持有限。默認音頻路由規則也不允許用戶為給定用例選擇多個相同類型的設備。

從 Android 12 開始,這些限制被移除,以允許新的用例,例如音頻廣播、多播到一組 BLE 音頻耳機或同時使用多個 USB 聲卡。

本頁介紹如何實現對流音頻到多個音頻設備的支持,以及如何驗證此功能的實現。

支持將音頻流式傳輸到多個音頻設備

Android 12 中有兩組 API 支持此功能:

  • 系統 API 處理策略的多個首選設備。
  • 由供應商作為音頻 HAL 的一部分實施的 HIDL 接口報告設備功能。

以下部分更詳細地討論了這些 API。

為策略處理多個首選設備

音頻策略管理器提供系統 API 以更好地支持同時將音頻流式傳輸到多個音頻設備。這些系統API使能設置,獲取和對於給定的策略刪除多個優選的器件。在 Android 12 之前,此功能僅支持單個設備。

音頻策略管理器引入了積極的媒體設備的概念來描述了為媒體播放最有可能被挑選的設備。連接可拆卸設備時,可能必須打開可路由到此設備的音頻 HAL 輸出流並探查支持的屬性。

打開輸出流時必須指定音頻設備。活動媒體設備是在此上下文中打開輸出流時使用的設備。

活動媒體設備選擇可以根據實際連接或斷開的設備而改變。音頻策略管理器使用以下一系列規則來選擇活動媒體設備:

  1. 如果所有首選的媒體設備都可用,則它們都將被選為活動設備。
  2. 否則,將選擇最後連接的可移動設備。
  3. 如果沒有連接可移動設備,則應用用於選擇輸出設備的默認音頻策略規則來選擇活動設備。

輸出流必須滿足以下條件才能重新打開並路由到活動設備,以便為播放選擇最佳配置:

  • 輸出流必須支持活動設備。
  • 輸出流必須支持動態配置文件。
  • 當前不得將輸出流路由到活動設備。

為了應用新的設備選擇,如果輸出流空閒,則音頻策略管理器在設備連接時關閉並重新打開輸出流,或者在輸出流進入待機時將其推遲。

音頻策略管理器提供系統API的下面的列表(定義AudioManager.java ):

  • setPreferredDeviceForStrategy

    為給定策略設置音頻路由的首選設備。請注意,該設備在設置首選設備時可能不可用,但一旦可用就會使用。

  • removePreferredDeviceForStrategy

    去除優選的音頻設備(多個)先前設置setPreferredDeviceForStrategysetPreferredDevicesForStrategy

  • getPreferredDeviceForStrategy

    返回先前的音頻策略的優選設備setPreferredDeviceForStrategysetPreferredDevicesForStrategy

  • setPreferredDevicesForStrategy

    為給定策略設置首選設備。

  • getPreferredDevicesForStrategy

    返回先前的音頻策略的優選設備setPreferredDeviceForStrategysetPreferredDevicesForStrategy

  • OnPreferredDevicesForStrategyChangedListener

    定義一個接口,用於通知為給定音頻策略設置的首選音頻設備的更改。

  • addOnPreferredDevicesForStrategyChangedListener

    添加偵聽器以獲取策略首選音頻設備更改的通知。

  • removeOnPreferredDevicesForStrategyChangedListener

    刪除先前添加的更改策略首選音頻設備的偵聽器。

報告設備功能

作為音頻 HAL 實施的一部分,供應商實施支持報告設備功能的 API。本部分介紹了用於報告設備功能的數據類型和方法,並列出了音頻 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 方法

音頻策略管理器使用以下方法來查詢設備的功能:

  • 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版增加了一個所謂的新API get_audio_port_v7使用查詢設備的能力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);

從遺留數據get_audio_port API必須被填充到新AudioPort格式時傳統API版本低於3.2和HIDL HAL版本是7或以上。在這種情況下,所有報導的採樣率和從信道掩碼get_audio_port被假定為所有返回的格式被支持,使得能夠從一個直接的映射get_audio_port值到新的AudioPort結構。

示例 API 實現

本節介紹了幾個測試套件,其中包含使用前幾節中介紹的 API 的方法。有關如何實現和使用這些 API 的一些示例,請參閱這些方法。

所述的使用的一個例子setPreferredDevicesForStrategygetPreferredDevicesForStrategyremovePreferredDeviceForStrategyOnPreferredDevicesForStrategyChangedListener系統API是在PreferredDeviceRoutingTest方法,它位於GTS。

看到在新的結構的一個例子AudioDeviceInfo在使用中,參見AudioManagerTest#testGetDevices方法,其位於CTS。

對於實施的實例get_audio_port_v7位於audio_hal.c ,它顯示能力如何查詢多個設備。

驗證

本節提供有關信息CTS和GTS(谷歌移動服務測試套件)的音頻管理器的驗證。

CTS 測試

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

以下是可用的音頻管理器測試列表:

  • AudioManagerTest#testGetDevices

    驗證音頻設備的精確功能。它還驗證,在返回的音頻模式AudioDeviceInfo結構保持與舊,扁平陣列格式的內容,但在新的AudioProfile格式。

  • AudioManagerTest#testPreferredDevicesForStrategyAudioManagerTest#testPreferredDeviceForCapturePreset

    驗證策略和捕獲預設相關 API 測試的首選設備是否成功完成。

GTS 測試

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

為了驗證是否API進行戰略和捕捉預設工作首選設備正常,運行AudioServiceHostTest#testPreferredDeviceRoutingAudioServiceHostTest#testPreferredDeviceRoutingForCapturePreset測試。