Маршрутизация аудио на комбинированное аудиоустройство

Функция маршрутизации аудио на несколько устройств позволяет одновременно передавать звук на несколько аудиоустройств. С помощью этой функции привилегированные приложения могут выбирать несколько устройств по умолчанию для определенной стратегии с помощью системных API. Приложения могут точнее определять возможности аудиоустройств, используя общедоступные API, предоставляемые этой функцией. В Android 11 и более ранних версиях фреймворк аудио имеет ограниченную поддержку нескольких аудиоустройств одного типа (например, двух Bluetooth-гарнитур A2DP), подключенных одновременно. Правила маршрутизации аудио по умолчанию также не позволяют пользователям выбирать несколько устройств одного типа для определенного варианта использования.

В Android 12 и более поздних версиях эти ограничения сняты, чтобы можно было использовать новые функции, например трансляцию аудио, многоадресную передачу на группу аудиоустройств Bluetooth Low Energy или одновременный выбор нескольких звуковых карт USB. Маршрутизация на несколько USB-устройств одновременно не поддерживается.

Начиная с Android 14, фреймворк USB поддерживает маршрутизацию на несколько USB-устройств, если они относятся к разным типам аудиоустройств и если ядро и поставщик поддерживают одновременное подключение нескольких USB-устройств.

На этой странице рассказывается, как реализовать поддержку потоковой передачи аудио на несколько аудиоустройств и как проверить реализацию этой функции.

Поддержка потоковой передачи аудио на несколько аудиоустройств

В Android 12 эту функцию поддерживают два набора API:

  • Системные API обрабатывают несколько предпочтительных устройств для стратегии.
  • Интерфейс HIDL, реализованный поставщиком как часть HAL аудио, сообщает о возможностях устройства.

Ниже мы подробнее расскажем о каждом из этих API.

Как работать с несколькими предпочитаемыми устройствами в рамках одной стратегии

Менеджер правил аудио предлагает системные API, которые улучшают поддержку одновременной потоковой передачи аудио на несколько аудиоустройств. Эти системные API позволяют задавать, получать и удалять несколько предпочитаемых устройств для определенной стратегии. До Android 12 эта функция поддерживалась только на одном устройстве.

Менеджер правил аудио использует концепцию используемых медиаустройств, чтобы определить, какие устройства с наибольшей вероятностью будут выбраны для воспроизведения медиаконтента. Когда подключается съемное устройство, выходные потоки аудио HAL, которые можно перенаправить на это устройство, могут быть открыты и проверены на наличие поддерживаемых атрибутов.

При открытии выходного потока необходимо указать аудиоустройство. Активное медиаустройство – это устройство, которое используется, когда в этом контексте открываются выходные потоки.

Выбор активного медиаустройства может меняться в зависимости от того, какие устройства подключены или отключены. Менеджер правил аудио использует следующие правила для выбора активных медиаустройств:

  1. Если все предпочитаемые устройства для воспроизведения медиаконтента доступны, они все будут выбраны в качестве активных.
  2. В противном случае будет выбрано последнее подключенное съемное устройство.
  3. Если съемные устройства не подключены, для выбора активных устройств применяются правила аудио по умолчанию для выбора устройств вывода.

Чтобы выходной поток можно было открыть повторно и перенаправить на активные устройства, чтобы выбрать оптимальную конфигурацию для воспроизведения, он должен соответствовать следующим критериям:

  • Выходной поток должен поддерживать активные устройства.
  • Выходной поток должен поддерживать динамические профили.
  • Выходной поток не должен быть направлен на активные устройства.

Чтобы применить новый выбор устройства, менеджер аудиополитики закрывает и снова открывает выходной поток при подключении устройства, если выходной поток находится в режиме бездействия, или откладывает это действие до тех пор, пока выходной поток не будет переведен в режим ожидания.

Менеджер правил аудио предлагает следующий список системных 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, чтобы описать возможности устройства.

Методы Audio 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

Чтобы поддерживать несколько аудиопрофилей, в версию 3.2 устаревшего API добавлена новая структура audio_port_v7. Подробную информацию можно найти в исходном коде.

В связи с добавлением audio_port_v7 в устаревшую версию API 3.2 был добавлен новый API get_audio_port_v7, который позволяет запрашивать возможности устройств с помощью структуры audio_port_v7.

В следующем коде из audio.h показано определение API get_audio_port_v7:

/**
 * 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 get_audio_port ниже 3.2, а версия HIDL HAL – 7 или выше, данные из устаревшего API должны быть перенесены в новый формат AudioPort. В этом случае предполагается, что все частоты дискретизации и маски каналов, полученные от get_audio_port, поддерживаются для всех возвращаемых форматов, что позволяет легко сопоставить значения get_audio_port со структурой AudioPort.

Примеры реализации API

В этом разделе описано несколько наборов тестов, содержащих методы, которые используют API, описанные в предыдущих разделах. В этих методах приведены примеры того, как реализованы и используются API.

Пример использования системных API setPreferredDevicesForStrategy, getPreferredDevicesForStrategy, removePreferredDeviceForStrategy и OnPreferredDevicesForStrategyChangedListener можно найти в методе PreferredDeviceRoutingTest, который находится в GTS.

Пример использования новой структуры в AudioDeviceInfo можно найти в методе AudioManagerTest#testGetDevices, который находится в CTS.

Пример реализации для get_audio_port_v7 находится в audio_hal.c и показывает, как запрашиваются возможности для нескольких устройств.

Проверка

В этом разделе приведена информация о проверке Audio Manager с помощью CTS и GTS (набора тестов сервисов Google для мобильных устройств).

Тесты CTS

Тесты CTS находятся в android.media.cts.AudioManagerTest.

Ниже приведен список доступных тестов Audio Manager.

  • AudioManagerTest#testGetDevices

    Проверяет точные возможности аудиоустройства. Он также проверяет, что возвращенные аудиопрофили в структуре AudioDeviceInfo сохраняют контент из старого формата плоского массива, но находятся в новом формате AudioProfile.

  • AudioManagerTest#testPreferredDevicesForStrategy и AudioManagerTest#testPreferredDeviceForCapturePreset

    Убедитесь, что тесты API, связанные с устройствами по умолчанию для стратегии и предустановки захвата, успешно завершены.

Тесты GTS

Тесты GTS находятся в каталоге com.google.android.gts.audioservice.AudioServiceHostTest.

Чтобы проверить, правильно ли работают API для предпочтительных устройств для стратегии и набора настроек захвата, запустите тесты AudioServiceHostTest#testPreferredDeviceRouting и AudioServiceHostTest#testPreferredDeviceRoutingForCapturePreset.