Compartilhar via


Implementar a comunicação do módulo de áudio

Um módulo de áudio é uma parte distinta da lógica de processamento de áudio que executa uma função relativamente atômica. Um módulo de áudio pode residir no driver de áudio ou no DSP de áudio. Um exemplo de módulo de áudio seria o processamento de áudio baseado em DSP.

A partir do Windows 10, versão 1703, há APIs e DDIs para oferecer suporte à comunicação de aplicativos da Plataforma Universal do Windows (UWP) e drivers de dispositivo de modo kernel.

Este tópico fornece informações sobre como implementar a comunicação do módulo de áudio no driver de dispositivo do kernel.

Para obter informações sobre como enviar comandos e receber notificações de alteração de módulos de dispositivo de áudio usando um aplicativo UWP, consulte Configurar e consultar módulos de dispositivo de áudio.

Por que usar módulos de áudio?

Os OEMs normalmente agrupam um aplicativo de configuração em seu sistema que permite ao cliente controlar aspectos desse sistema de áudio e ajustá-lo de acordo com sua preferência. O subsistema de áudio pode conter vários componentes, como objetos de processamento de áudio no host, processamento DSP de hardware e hardware especializado, como um amplificador inteligente (tudo além do próprio codec de áudio). Na maioria dos casos, esses componentes são criados e vendidos por diferentes fornecedores. Historicamente, os IHVs criaram suas próprias APIs privadas para se integrarem e enviarem informações entre os componentes individuais. Os aplicativos de configuração WIN32 existentes aproveitariam essas APIs privadas.

A Plataforma Universal do Windows (UWP) fornece um conjunto de APIs que permitem que um único aplicativo seja executado em vários dispositivos. A UWP também lançou uma nova aparência que se tornou a expectativa do cliente para aplicativos executados no Windows 10. Muitos OEMs gostariam de criar seus aplicativos de configuração de áudio na UWP. No entanto, um recurso de segurança principal da UWP (a área restrita AppContainer) impede a comunicação de um aplicativo com outros componentes no subsistema de áudio. Isso torna as APIs privadas usadas anteriormente por aplicativos de configuração inacessíveis na UWP.

A partir do Windows 10, versão 1703, a API UWP dos módulos de áudio permite que o aplicativo de configuração e os componentes do modo de usuário se comuniquem com módulos no kernel e na camada de hardware que podem ser descobertos por meio de um novo conjunto de propriedades do KS. IHV de áudio e ISVs podem escrever aplicativos e serviços que podem se comunicar com seus módulos de hardware usando uma interface bem definida fornecida pelo Windows. Para obter mais informações sobre a API de módulos de áudio, consulte Namespace Windows.Media.Devices

Definições do módulo de áudio

Essas definições são específicas para módulos de áudio.

Termo Definição
Módulo de Áudio Uma peça distinta da lógica de processamento de áudio executando uma função relativamente atômica. Pode residir no driver de áudio ou no DSP de áudio. Um exemplo de módulo de áudio seria um objeto de processamento de áudio (APO).

Definições de áudio comuns

Essas definições são normalmente usadas ao trabalhar com drivers de áudio.

Termo Definição
OEM Fabricante do equipamento original
IHV Fornecedor independente de hardware
ISV Fornecedores de software independentes
HSA Aplicativo de Suporte de Hardware
UWP Plataforma Universal do Windows
APO Objeto de processamento de áudio
DSP Processamento de sinal digital

Arquitetura

Os Módulos de Áudio implementam um mecanismo suportado pelo Windows para enviar mensagens entre o modo de usuário e os componentes de áudio do modo kernel. Uma distinção importante é que os módulos de áudio padronizam o pipeline de transporte. Ele não estabelece o protocolo de comunicação sobre esse transporte e depende dos ISVs e IHVs para definir o protocolo. A intenção é permitir que projetos de terceiros existentes migrem facilmente para módulos de áudio com poucas alterações.

<Diagrama pendente>

A API do Módulo de Áudio fornece acesso aos módulos por meio de dois métodos de segmentação diferentes: o filtro de onda KS e um pino (fluxo) KS inicializado. A colocação e o acesso a módulos específicos são específicos da implementação.

HSAs e outras aplicações só poderão acessar os módulos disponíveis por meio da alça do filtro. Os APOs individuais carregados em um fluxo são os únicos objetos que terão acesso aos módulos de áudio de destino ao fluxo.

Para obter mais informações sobre APOs, consulte Objetos de processamento de áudio do Windows.

Enviar comandos

O caminho do cliente do módulo de áudio para consultar e alterar parâmetros é enviar comandos para os módulos de áudio no kernel e componentes de hardware no subsistema de áudio. A estrutura de comandos da API de Módulos de Áudio é vagamente definida e formaliza a maneira como os módulos são descobertos e se identificam. No entanto, a estrutura de comando detalhada deve ser projetada e implementada pelo ISV e IHV envolvidos para estabelecer o protocolo para quais mensagens podem ser enviadas e a resposta esperada.

Notificações do módulo para clientes do módulo de áudio

A miniporta de áudio também tem uma maneira de notificar e passar informações para clientes do módulo de áudio se o cliente tiver assinado notificações em um módulo específico. As informações passadas nessas notificações não são definidas pela API do Módulo de Áudio, mas sim pelo ISV e/ou IHV.

Habilitar, desabilitar e informações gerais de topologia

As APIs de Módulos de Áudio definem como enumerar e enviar comandos para os módulos. No entanto, elas não definem explicitamente como os clientes do Módulo de Áudio podem habilitar ou desabilitar módulos específicos. Além disso, não estabelecem uma maneira de os clientes encontrarem informações de topologia ou a colocação de módulos em relação uns aos outros. IHVs e ISVs podem determinar se essa funcionalidade é necessária e decidir como implementá-la.

A abordagem recomendada é expor um módulo de driver global. O módulo de driver global manipularia comandos personalizados para essas solicitações específicas de topologia.

DDIs do módulo de áudio

Propriedades do módulo de áudio de streaming do kernel

Um novo conjunto de propriedades KS, identificado por KSPROPSETID_AudioModule, foi definido para três propriedades específicas para módulos de áudio.

Um driver de miniporta PortCls precisa lidar diretamente com a resposta para cada propriedade, pois nenhuma interface auxiliar é fornecida.

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;

Descritores do módulo de áudio

O suporte para a propriedade KSPROPERTY_AUDIOMODULE_DESCRIPTORS identifica o driver como sendo compatível com o módulo de áudio. A propriedade será consultada por meio do filtro ou identificador de pinos e um KSPROPERTY será passado como buffer de entrada para a chamada DeviceIoControl. KSAUDIOMODULE_DESCRIPTOR foi definido para descrever cada módulo dentro do hardware de áudio. Uma matriz desses descritores é retornada em resposta a essa solicitação

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;

Para obter mais informações, consulte KSAUDIOMODULE_DESCRIPTOR.

Comando do módulo de áudio

O suporte para a propriedade KSPROPERTY_AUDIOMODULE_COMMAND permite que os clientes do Módulo de Áudio enviem comandos personalizados para consultar e definir parâmetros em Módulos de Áudio. A propriedade pode ser enviada por meio do filtro ou identificador de pino e um KSAUDIOMODULE_PROPERTY é passado como o buffer de entrada para a chamada DeviceIoControl. Como alternativa, um cliente pode enviar informações adicionais imediatamente adjacentes ao KSAUDIOMODULE_PROPERTY no buffer de entrada para enviar comandos personalizados.

ksmedia.h:

#define AUDIOMODULE_MAX_DATA_SIZE 64000

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

Para saber mais, confira KSAUDIOMODULE_PROPERTY.

ID do dispositivo de notificação do módulo de áudio

O suporte para o KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID é necessário para permitir que a miniporta sinalize notificações e passe informações para clientes do módulo de áudio. O tempo de vida dessa ID está vinculado ao tempo de vida do dispositivo de áudio que está sendo exposto e ativo na pilha de áudio do Windows. A propriedade pode ser enviada por meio do filtro ou identificador de pino e um KSPROPERTY é passado como o buffer de entrada para a chamada DeviceIoControl.

Para saber mais, confira KSAUDIOMODULE_PROPERTY.

Auxiliar de PortCls – Notificações do módulo de áudio

Uma nova interface de porta foi adicionada para ajudar os desenvolvedores de drivers a enviar notificações para clientes do Módulo de Áudio.

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;


Para saber mais, veja:

IPortClsNotifications

IPortClsNotifications::AllocNotificationBuffer

IPortClsNotifications::FreeNotificationBuffer

IPortClsNotifications::SendNotificationBuffer

Sequência de chamadas

A miniporta chamará sua porta para criar e enviar a notificação. A sequência de chamada geral é mostrada neste diagrama.

Diagrama mostrando a sequência de chamada para AudioIPortClsNotifications.