Поделиться через


Реализация коммуникации аудиомодулем

Звуковой модуль — это отдельная часть логики обработки звука, выполняющая относительно атомарную функцию. Звуковой модуль может находиться в звуковом драйвере или в звуковом DSP. Примером звукового модуля будет обработка звука на основе DSP.

Начиная с Windows 10 версии 1703, существуют API и DDIs для поддержки обмена данными с универсальная платформа Windows приложений и драйверов устройств в режиме ядра.

В этом разделе содержатся сведения о реализации связи аудиомодулем в драйвере устройства ядра.

Сведения о том, как отправлять команды и получать уведомления об изменениях из модулей звуковых устройств с помощью приложения UWP, см. в статье "Настройка и запрос модулей аудиоустройства".

Почему используются звуковые модули?

OEM обычно упаковывают приложение конфигурации в свою систему, что позволяет клиенту контролировать аспекты этой звуковой системы и настраивать его на их предпочтения. Подсистема звука может содержать различные компоненты, такие как объекты обработки звука на узле, аппаратная обработка DSP и специализированное оборудование, например смарт-amp (все в дополнение к самому звуковому кодеку). В большинстве случаев эти компоненты создаются и продаются различными поставщиками. Исторически IHV создали собственные частные API для интеграции друг с другом и отправки информации между отдельными компонентами. Существующие приложения конфигурации WIN32 будут использовать эти частные API.

Универсальная платформа Windows (UWP) предоставляет набор API- интерфейсов, позволяющих одному приложению выполняться на разных устройствах. UWP также представила новый внешний вид и ощущение, что стало ожиданием клиентов для приложений, работающих в Windows 10. Так много изготовителей оборудования хотели бы создать свои приложения конфигурации звука на UWP. Однако основная функция безопасности UWP (песочница AppContainer) запрещает обмен данными с приложением с другими компонентами в звуковой подсистеме. Это отрисовывает частные API, которые ранее использовались приложениями конфигурации, недоступными в UWP.

Начиная с Windows 10 версии 1703 API аудиомодулов UWP позволяет приложению конфигурации и компонентам пользовательского режима взаимодействовать с модулями в ядре и аппаратном уровне, которые можно обнаружить с помощью нового набора свойств KS. Audio IHV и ISV могут создавать приложения и службы, которые могут взаимодействовать с их аппаратными модулями с помощью четко определенного интерфейса, предоставляемого Windows. Дополнительные сведения об API аудиомодулем см. в разделе "Пространство имен Windows.Media.Devices"

Определения звуковых модулей

Эти определения относятся к звуковым модулям.

Термин Определение
Звуковой модуль Отдельная часть логики обработки звука, выполняющая относительно атомарную функцию. Может находиться в звуковом драйвере или в звуковом DSP. Примером звукового модуля будет объект обработки звука (APO).

Распространенные определения звука

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

Термин Определение
HSA Приложение поддержки оборудования
UWP Универсальная платформа Windows
APO Объект обработки звука
DSP Цифровая обработка сигналов
Термин Определение
OEM Изготовитель исходного оборудования
IHV Независимый поставщик оборудования
Независимый поставщик ПО Независимые поставщики программного обеспечения

Архитектура

Звуковые модули помещают поддерживаемый механизм ОС Windows для отправки сообщений между пользовательским режимом и компонентами звука в режиме ядра. Важное различие заключается в том, что звуковые модули стандартизируют транспортный конвейер. Он не устанавливает протокол связи для этого транспорта и полагается на поставщики программного обеспечения и IHV для определения протокола. Цель заключается в том, чтобы существующие сторонние проекты могли легко перенестися в звуковые модули с очень небольшими изменениями.

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

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

Существуют модули устройств и модули потоков, в зависимости от того, доступны ли они из клиентского процесса или APO, работающего в AudioDG, с помощью интерфейса потоковых модулей, предоставленного APO из AudioDG. Общие сведения о конце аудио и графе аудиоустройств (AudioDG) см. в разделе "Архитектура звука Windows".

Драйвер уведомляет Windows.Media.Devices об изменениях модулей с помощью функции IoReportTargetDeviceChangeAsynchronous, которая затем превращается в обратные вызовы из API модулей в клиентский процесс или APO.

API модуля аудио предоставляет доступ к модулям с помощью двух различных методов целевого назначения: фильтра волн KS и инициализированного пин-кода KS (поток). Размещение и доступ к определенным модулям относятся к реализации.

HSAs и другие приложения смогут получить доступ только к модулям, доступным через дескриптор фильтра. Отдельные API, загруженные в поток, являются единственными объектами, которые будут иметь доступ к целевым звуковым модулям потока. Дополнительные сведения об API см. в разделе "Объекты обработки звука Windows".

Отправка команд

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

Уведомления о модуле для клиентов аудиомодулем

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

Включение, отключение и общие сведения о топологии

API аудиомодулей определяют способ перечисления и отправки команд в модули. Однако API-интерфейсы не определяют, как клиенты аудиомодулов могут включать или отключать определенные модули. Кроме того, он не устанавливает способ поиска клиентами сведений о топологии или размещении модулей в отношении друг друга. IHVs и ISV могут определить, требуется ли эта функция и решить, как реализовать ее.

Рекомендуемый подход — предоставление глобального модуля драйвера. Глобальный модуль драйверов будет обрабатывать пользовательские команды для этих запросов топологии.

DDIs аудиомодулем

Свойства модуля потоковой передачи ядра

Новый набор свойств KS, определенный KSPROPSETID_AudioModule, был определен для трех свойств, относящихся к звуковым модулям.

Драйвер минипорта PortCls должен напрямую обрабатывать ответ для каждого свойства, так как не предоставляется вспомогательный интерфейс.

ksmedia.h:

#define STATIC_KSPROPSETID_AudioModule \
    0xc034fdb0, 0xff75, 0x47c8, 0xaa, 0x3c, 0xee, 0x46, 0x71, 0x6b, 0x50, 0xc6
DEFINE_GUIDSTRUCT("C034FDB0-FF75-47C8-AA3C-EE46716B50C6", KSPROPSETID_AudioModule);
#define KSPROPSETID_AudioModule DEFINE_GUIDNAMED(KSPROPSETID_AudioModule)

typedef enum {
    KSPROPERTY_AUDIOMODULE_DESCRIPTORS            = 1,  
    KSPROPERTY_AUDIOMODULE_COMMAND                = 2,
    KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID = 3,
} KSPROPERTY_AUDIOMODULE;

Дескрипторы аудиомодулов

Поддержка свойства KSPROPERTY_AUDIOMODULE_DESCRIPTORS определяет драйвер как распознаваемый звуковой модуль. Свойство будет запрашиваться с помощью фильтра или закрепления, а KSPROPERTY передается в качестве входного буфера для вызова DeviceIoControl. KSAUDIOMODULE_DESCRIPTOR определен для описания каждого модуля в звуковом оборудовании. Массив этих дескрипторов возвращается в ответ на этот запрос.

ksmedia.h:

#define AUDIOMODULE_MAX_NAME_SIZE 128

typedef struct _KSAUDIOMODULE_DESCRIPTOR
{
    GUID    ClassId; 
    ULONG   InstanceId;
    ULONG   VersionMajor;
    ULONG   VersionMinor;
    WCHAR   Name[AUDIOMODULE_MAX_NAME_SIZE];
} KSAUDIOMODULE_DESCRIPTOR, *PKSAUDIOMODULE_DESCRIPTOR;

Дополнительные сведения см. в KSAUDIOMODULE_DESCRIPTOR.

Команда звукового модуля

Поддержка свойства KSPROPERTY_AUDIOMODULE_COMMAND позволяет клиентам модуля audio отправлять пользовательские команды для запроса и задания параметров в звуковых модулях. Свойство можно отправить через дескриптор фильтра или закрепить, а KSAUDIOMODULE_PROPERTY передается в качестве входного буфера для вызова DeviceIoControl. Клиент может при необходимости отправлять дополнительные сведения непосредственно рядом с KSAUDIOMODULE_PROPERTY в входном буфере для отправки пользовательских команд.

ksmedia.h:

#define AUDIOMODULE_MAX_DATA_SIZE 64000

typedef struct _KSPAUDIOMODULE_PROPERTY
{
    KSPROPERTY Property;
    GUID       ClassId;
    ULONG      InstanceId;
} KSAUDIOMODULE_PROPERTY, *PKSPAUDIOMODULE_PROPERTY;

Дополнительные сведения см. в KSAUDIOMODULE_PROPERTY.

Идентификатор устройства уведомления о звуковом модуле

Поддержка KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID необходима для включения мини-порта для передачи уведомлений и передачи информации клиентам модуля аудио. Время существования этого идентификатора связано с временем существования доступного и активного звукового устройства в стеке звука Windows. Свойство можно отправить через дескриптор фильтра или закрепить, а KSPROPERTY передается в качестве входного буфера для вызова DeviceIoControl.

Дополнительные сведения см. в KSAUDIOMODULE_PROPERTY.

Вспомогательный модуль PortCls — уведомления аудиомодулем

Добавлен новый интерфейс порта, помогающий разработчикам драйверов отправлять уведомления клиентам аудиомодуля.

PortCls.h:

typedef struct _PCNOTIFICATION_BUFFER 
{
    UCHAR NotificationBuffer[1];
} PCNOTIFICATION_BUFFER, *PPCNOTIFICATION_BUFFER;

DECLARE_INTERFACE_(IPortClsNotifications,IUnknown)
{
    DEFINE_ABSTRACT_UNKNOWN()   // For IUnknown

    STDMETHOD_(NTSTATUS, AllocNotificationBuffer)
    (   THIS_
        _In_    POOL_TYPE       PoolType,
        _In_    USHORT          NumberOfBytes,
        _Out_   PPCNOTIFICATION_BUFFER* NotificationBuffer
    )   PURE;
    
    STDMETHOD_(void, FreeNotificationBuffer)
    (   THIS_
        _In_    PPCNOTIFICATION_BUFFER NotificationBuffer
    )   PURE;
    
    STDMETHOD_(void, SendNotificationBuffer)
    (   THIS_
        _In_    const GUID*     NotificationId,
        _In_    PPCNOTIFICATION_BUFFER NotificationBuffer
    )   PURE;
};

//
// Audio module notification definitions.
//
#define STATIC_KSNOTIFICATIONID_AudioModule \
    0x9C2220F0, 0xD9A6, 0x4D5C, 0xA0, 0x36, 0x57, 0x38, 0x57, 0xFD, 0x50, 0xD2
DEFINE_GUIDSTRUCT("9C2220F0-D9A6-4D5C-A036-573857FD50D2", KSNOTIFICATIONID_AudioModule);
#define KSNOTIFICATIONID_AudioModule DEFINE_GUIDNAMED(KSNOTIFICATIONID_AudioModule)

typedef struct _KSAUDIOMODULE_NOTIFICATION {
    union {
        struct {
            GUID        DeviceId;
            GUID        ClassId;
            ULONG       InstanceId;
            ULONG       Reserved;
        } ProviderId;
        LONGLONG        Alignment;
    };
} KSAUDIOMODULE_NOTIFICATION, *PKSAUDIOMODULE_NOTIFICATION;


Дополнительные сведения см. в разделе:

IPortClsNotifications

IPortClsNotifications::AllocNotificationBuffer

IPortClsNotifications::FreeNotificationBuffer

IPortClsNotifications::SendNotificationBuffer

Последовательность вызовов

Минипорт вызовет свой порт для создания и отправки уведомления. Общая последовательность вызовов показана на этой схеме.

Схема, показывающая последовательность вызовов для AudioIPortClsNotifications.