Partilhar via


Implementar objetos de processamento de áudio

Este tópico descreve como implementar um objeto de processamento de áudio (APO). Para obter informações gerais sobre APOs, veja Arquitetura de objeto de processamento de áudio.

Implementação de APOs personalizados

APOs personalizados são implementados como objetos COM em processo, portanto, eles são executados no modo de usuário e são empacotados em uma biblioteca de vínculo dinâmico (DLL). Existem três tipos de APO, com base no local onde eles estão inseridos no gráfico de processamento de sinais.

  • Efeitos de transmissão (SFX)
  • Efeitos de modo (MFX)
  • Efeitos de ponto de extremidade (EFX)

Cada dispositivo lógico pode ser associado a um APO de cada tipo. Para obter mais informações sobre modos e efeitos, veja Modos de processamento de sinal de áudio.

Você pode implementar um APO baseando sua classe personalizada na classe base CBaseAudioProcessingObject, que é declarada no arquivo Baseaudioprocessingobject.h. Essa abordagem envolve a adição de nova funcionalidade à classe base CBaseAudioProcessingObject para criar um APO personalizado. A classe base CBaseAudioProcessingObject implementa grande parte da funcionalidade que um APO requer. Ele fornece implementações padrão para a maioria dos métodos nas três interfaces necessárias. A principal exceção é o método IAudioProcessingObjectRT::APOProcess.

Execute as etapas a seguir para implementar APOs personalizados.

  1. Crie objetos APO personalizados para fornecer o processamento de áudio desejado.
  2. Opcionalmente, crie uma interface de usuário para configurar os APOs personalizados usando um.
  3. Crie um arquivo INF para instalar e registrar os APOs e a interface de usuário personalizada.

Considerações de design para desenvolvimento de APO personalizado

Todos os APOs personalizados devem ter as seguintes características gerais:

  • O APO deve ter uma conexão de entrada e uma de saída. Essas conexões são buffers de áudio e podem ter vários canais.

  • Um APO pode modificar apenas os dados de áudio que são passados para ele através de sua rotina IAudioProcessingObjectRT::APOProcess. O APO não pode alterar as configurações do dispositivo lógico subjacente, incluindo sua topologia KS.

  • Além de IUnknown, APOs devem expor as seguintes interfaces:

  • Todos os APOs devem ter compatibilidade de sistema em tempo real. Isso significa que:

    • Todos os métodos que são membros de interfaces em tempo real devem ser implementados como membros sem bloqueio. Eles não devem bloquear, usar memória paginada ou chamar qualquer rotina do sistema de bloqueio.

    • Todos os buffers processados pelo APO devem ser não pagináveis. Todos os códigos e dados no caminho do processo devem ser não pagináveis.

    • Os APOs não devem introduzir latência significativa na cadeia de processamento de áudio.

  • APOs personalizados não devem expor a interface IAudioProcessingObjectVBR.

Observação

Para obter informações detalhadas sobre as interfaces necessárias, consulte os arquivos Audioenginebaseapo.h e Audioenginebaseapo.idl na pasta Windows Kits\<build number>\Include\um.

Uso de código de exemplo para acelerar o processo de desenvolvimento

O uso do exemplo de código SYSVAD Swap APO como um modelo pode acelerar o processo de desenvolvimento de APO personalizado. O exemplo Swap é o exemplo que foi desenvolvido para ilustrar alguns recursos de objetos de processamento de áudio. O exemplo de APO de permuta o canal esquerdo pelo canal direito e implementa efeitos SFX e MFX. Você pode habilitar e desabilitar os efeitos de áudio de troca de canal usando a caixa de diálogo de propriedades.

O exemplo de áudio SYSVAD está disponível no GitHub de exemplos de driver do Windows.

Você pode navegar pelo exemplo de áudio do Sysvad aqui:

https://github.com/Microsoft/Windows-driver-samples/tree/main/audio/sysvad

Baixar e extrair o exemplo de áudio Sysvad do GitHub

Siga estas etapas para baixar e abrir a amostra SYSVAD:

a. Você pode usar as ferramentas do GitHub para trabalhar com os exemplos. Você também pode baixar as amostras de driver universal em um arquivo zip.

https://github.com/Microsoft/Windows-driver-samples/archive/master.zip

b. Baixe o arquivo master.zip no disco rígido local.

c. Selecione e segure (ou clique com o botão direito do mouse) Windows-driver-samples-master.zip e selecione Extrair tudo. Especifique uma nova pasta ou navegue até uma existente que armazenará os arquivos extraídos. Por exemplo, você pode especificar C:\DriverSamples\ como a nova pasta da qual os arquivos serão extraídos.

d. Após extrair os arquivos, navegue para a seguinte subpasta: C:\DriverSamples\Audio\Sysvad

Abra a solução do driver no Visual Studio.

No Microsoft Visual Studio, selecione Arquivo>Abrir>Projeto/Solução... e navegue até a pasta que contém os arquivos extraídos; por exemplo, C:\DriverSamples\Audio\Sysvad). Clique duas vezes no arquivo de solução Sysvad para abri-lo.

No Visual Studio, localize o Gerenciador de Soluções. (Se isso ainda não estiver aberto, escolha Explorer de soluções no menu Exibir.) No Explorer de soluções, você pode ver uma solução com seis projetos.

Código de exemplo SwapAPO

Há cinco projetos no exemplo SYSVAD, um dos quais é de interesse primário para o desenvolvedor APO.

Projeto Descrição
SwapAPO Código de exemplo para um APO de exemplo

Os outros projetos no exemplo do Sysvad são resumidos abaixo.

Projeto Descrição
TabletAudioSample Código de exemplo para um driver de áudio alternativo.
KeywordDetectorAdapter Código de exemplo para um adaptador de detector de palavra-chave
EndpointsCommon Código de exemplo para pontos de extremidade comuns.

Os arquivos de cabeçalho primários para o exemplo SwapAPO é swapapo.h. Os outros elementos de código primário são resumidos abaixo.

Arquivo Descrição
Swap.cpp Código C++ que contém a implementação do Swap APO.
SwapAPOMFX.cpp Implementação do CSwapAPOMFX
SwapAPOSFX.cpp Implementação do CSwapAPOSFX
SwapAPODll.cpp Implementação de Exportações de DLL.
SwapAPODll.idl Definição de interfaces COM e coclasses para a DLL.
SwapAPOInterface.idl As definições de interface e tipo para a funcionalidade Swap APO.
swapapodll.def Definições de exportações COM

Implementação do código de processamento de áudio do objeto COM

Você pode encapsular um APO fornecido pelo sistema baseando sua classe personalizada na classe base CBaseAudioProcessingObject , que é declarada no arquivo Baseaudioprocessingobject.h. Essa abordagem envolve a introdução de nova funcionalidade à classe base CBaseAudioProcessingObject para criar um APO personalizado. A classe base CBaseAudioProcessingObject implementa grande parte da funcionalidade que um APO requer. Ele fornece implementações padrão para a maioria dos métodos nas três interfaces necessárias. A principal exceção é o método IAudioProcessingObjectRT::APOProcess.

Ao usar CBaseAudioProcessingObject, você pode implementar mais facilmente um APO. Se um APO não tiver requisitos de formato especiais e operar no formato float32 necessário, as implementações padrão dos métodos de interface incluídos em CBaseAudioProcessingObject deverão ser suficientes. Dadas as implementações padrão, apenas três métodos principais devem ser implementados: IAudioProcessingObject::IsInputFormatSupported, IAudioProcessingObjectRT::APOProcess e ValidateAndCacheConnectionInfo.

Para desenvolver seus APOs com base na classe CBaseAudioProcessingObject, execute as seguintes etapas:

  1. Crie uma classe que herda de CBaseAudioProcessingObject.

    O exemplo de código C++ a seguir mostra a criação de uma classe que herda de CBaseAudioProcessingObject. Para obter uma implementação real desse conceito, siga as instruções na seção Exemplo de driver de objetos de processamento de áudio para ir para o exemplo de permuta e, em seguida, consulte o arquivo Swapapo.h .

    // Custom APO class - SFX
    Class MyCustomAPOSFX: public CBaseAudioProcessingObject
    {
     public:
    //Code for custom class goes here
    ...
    };
    

    Observação Como o processamento de sinal executado por um SFX APO é diferente do processamento de sinal executado por um MFX ou um EFX APO, você deve criar classes separadas para cada um.

  2. Implemente os três métodos a seguir:

    • IAudioProcessingObject::IsInputFormatSupported. Esse método manipula a negociação de formato com o mecanismo de áudio.

    • IAudioProcessingObjectRT::APOProcess. Esse método usa seu algoritmo personalizado para executar o processamento de sinais.

    • ValidateAndCacheConnectionInfo. Esse método aloca memória para armazenar detalhes de formato, por exemplo, contagem de canais, taxa de amostragem, profundidade de amostra e máscara de canal.

O exemplo de código C++ a seguir mostra uma implementação do método APOProcess para a classe de exemplo que você criou na etapa 1. Para obter uma implementação real desse conceito, siga as instruções na seção Exemplo de driver de objetos de processamento de áudio para ir para o exemplo de permuta e, em seguida, consulte o arquivo Swapapolfx.cpp.

// Custom implementation of APOProcess method
STDMETHODIMP_ (Void) MyCustomAPOSFX::APOProcess (...)
{
// Code for method goes here. This code is the algorithm that actually
// processes the digital audio signal.
...
}

O exemplo de código seguinte mostra uma implementação do método ValidateAndCacheConnectionInfo. Para obter uma implementação real desse método, siga as instruções na seção Exemplo de driver de objetos de processamento de áudio para ir para o exemplo de permuta e, em seguida, consulte o arquivo Swapapogfx.cpp.

// Custom implementation of the ValidateAndCacheConnectionInfo method.
HRESULT CSwapAPOGFX::ValidateAndCacheConnectionInfo( ... )
{
// Code for method goes here.
// The code should validate the input/output format pair.
...
}

Observação As interfaces e métodos restantes que sua classe herda de CBaseAudioProcessingObject são descritos em detalhes no arquivo Audioenginebaseapo.idl.

Substituição de APOs fornecidos pelo sistema

Ao implementar as interfaces APO, há duas abordagens: você pode escrever sua própria implementação ou pode chamar APOs da caixa de entrada.

Esse pseudocódigo ilustra o encapsulamento de um APO do sistema.

CMyWrapperAPO::CMyWrapperAPO {
    CoCreateInstance(CLSID_InboxAPO, m_inbox);
}

CMyWrapperAPO::IsInputFormatSupported {
    Return m_inbox->IsInputFormatSupported(…);
}

Esse pseudocódigo ilustra a criação de seu próprio APO personalizado.

CMyFromScratchAPO::IsInputFormatSupported {
    my custom logic
}

Ao desenvolver seus APOs para substituir os fornecidos pelo sistema, você deve usar os mesmos nomes na lista a seguir, para as interfaces e métodos. Algumas das interfaces têm mais métodos, além dos métodos necessários listados. Consulte as páginas de referência dessas interfaces para determinar se você deseja implementar todos os métodos ou apenas os necessários.

O restante das etapas de implementação são as mesmas de um APO personalizado.

Implemente as seguintes interfaces e métodos para o componente COM:

Como trabalhar com o Visual Studio e com APOs

Ao trabalhar com APOs no Visual Studio, execute essas tarefas para cada projeto APO.

Os drivers destinados ao Windows 10 devem se vincular dinamicamente ao CRT universal.

Se você precisar oferecer suporte ao Windows 8,1, habilite a vinculação estática definindo as propriedades do projeto em C/C++, Geração de código. Defina "Runtime Library" como /MT para compilações de versão ou /MTd para compilações de depuração. Essa alteração é feita, porque para um driver é difícil redistribuir o binário MSVCRT<n>.dll. A solução é vincular estaticamente ao libcmt.dll. Para obter mais informações, veja /MD, /MT, /LD (Usar biblioteca em tempo de execução).

Desabilite o uso de um manifesto incorporado

Desative o uso de um manifesto incorporado definindo as propriedades do projeto para seu projeto APO. Selecione Ferramenta de manifesto, Entrada e saída. Em seguida, altere "Incorporar manifesto" do padrão de Sim para Não. Se você tiver um manifesto incorporado, isso acionará o uso de determinadas APIs que são proibidas em um ambiente protegido. Isso significa que seu APO será executado com DisableProtectedAudioDG=1, mas quando essa chave de teste for removida, seu APO não será carregado, mesmo que seja assinado por WHQL.

Como empacotar seu APO com um driver

Ao desenvolver seu próprio driver de áudio e encapsular ou substituir os APOs fornecidos pelo sistema, você deve fornecer um pacote de driver para instalar o driver e os APOs. Para o Windows 10, consulte Drivers universais do Windows para áudio. Seus pacotes de driver relacionados a áudio devem seguir as políticas e o modelo de empacotamento detalhados lá.

O APO personalizado é empacotado como uma DLL, e qualquer interface do usuário de configuração é empacotada como um aplicativo UWP ou Desktop Bridge separado. O INF do dispositivo APO copia as DLLs para as pastas do sistema indicadas na diretiva INF CopyFile associada. A DLL que contém os APOs deve registrar-se incluindo uma seção AddReg no arquivo INF.

Os parágrafos a seguir e fragmentos de arquivo INF mostram as modificações necessárias para usar o arquivo INF padrão para copiar e registrar APOs.

Os arquivos inf incluídos com o exemplo Sysvad ilustram como os APOs SwapApo.dll são registrados.

Como registrar APOs para modos e efeitos de processamento no arquivo INF

Você pode registrar APOs para modos específicos usando certas combinações permitidas de chaves do Registro. Para obter mais informações sobre quais efeitos estão disponíveis e informações gerais sobre APOs, consulte Arquitetura de objeto de processamento de áudio.

Consulte estes tópicos de referência para obter informações sobre cada uma das configurações do arquivo INF do APO.

PKEY_FX_StreamEffectClsid

PKEY_FX_ModeEffectClsid

PKEY_FX_EndpointEffectClsid

PKEY_SFX_ProcessingModes_Supported_For_Streaming

PKEY_MFX_ProcessingModes_Supported_For_Streaming

PKEY_EFX_ProcessingModes_Supported_For_Streaming

Os exemplos de arquivo INF a seguir mostram como registrar objetos de processamento de áudio (APOs) para modos específicos. Eles ilustram as combinações possíveis disponíveis nesta lista.

  • PKEY_FX_StreamEffectClsid com PKEY_SFX_ProcessingModes_Supported_For_Streaming
  • PKEY_FX_ModeEffectClsid com PKEY_MFX_ProcessingModes_Suppoted_For_Streaming
  • PKEY_FX_ModeEffectClsid sem PKEY_MFX_ProcessingModes_Suppoted_For_Streaming
  • PKEY_FX_EndpointEffectClsid sem PKEY_EFX_ProcessingModes_Supported_For_Streaming

Há uma combinação válida adicional que não é mostrada nessas amostras.

  • PKEY_FX_EndpointEffectClsid com PKEY_EFX_ProcessingModes_Supported_For_Streaming

Exemplo de efeito de streaming de vários modos de tablet SYSVAD APO INF

Este exemplo mostra um efeito de streaming de vários modos sendo registrado usando entradas AddReg no arquivo de tablet SYSVAD INF.

Este código de exemplo é da amostra de áudio SYSVAD e está disponível no GitHub: https://github.com/Microsoft/Windows-driver-samples/tree/main/audio/sysvad.

Este exemplo ilustra essa combinação de efeitos do sistema:

  • PKEY_FX_StreamEffectClsid com PKEY_SFX_ProcessingModes_Supported_For_Streaming
  • PKEY_FX_ModeEffectClsid com PKEY_MFX_ProcessingModes_Suppoted_For_Streaming
[SWAPAPO.I.Association0.AddReg]
; Instruct audio endpoint builder to set CLSID for property page provider into the
; endpoint property store
HKR,EP\0,%PKEY_AudioEndpoint_ControlPanelPageProvider%,,%AUDIOENDPOINT_EXT_UI_CLSID%

; Instruct audio endpoint builder to set the CLSIDs for stream, mode, and endpoint APOs
; into the effects property store
HKR,FX\0,%PKEY_FX_StreamEffectClsid%,,%FX_STREAM_CLSID%
HKR,FX\0,%PKEY_FX_ModeEffectClsid%,,%FX_MODE_CLSID%
HKR,FX\0,%PKEY_FX_UserInterfaceClsid%,,%FX_UI_CLSID%

; Driver developer would replace the list of supported processing modes here
; Concatenate GUIDs for DEFAULT, MEDIA, MOVIE
HKR,FX\0,%PKEY_SFX_ProcessingModes_Supported_For_Streaming%,%REG_MULTI_SZ%,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%,%AUDIO_SIGNALPROCESSINGMODE_MEDIA%,%AUDIO_SIGNALPROCESSINGMODE_MOVIE%

; Concatenate GUIDs for DEFAULT, MEDIA, MOVIE
HKR,FX\0,%PKEY_MFX_ProcessingModes_Supported_For_Streaming%,%REG_MULTI_SZ%,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%,%AUDIO_SIGNALPROCESSINGMODE_MEDIA%,%AUDIO_SIGNALPROCESSINGMODE_MOVIE%

;HKR,FX\0,%PKEY_EFX_ProcessingModes_Supported_For_Streaming%,0x00010000,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%

Observe que no arquivo INF de exemplo, a propriedade EFX_Streaming é comentada porque o processamento de áudio fez a transição para o modo kernel acima dessa camada, de modo que a propriedade streaming não é necessária e não seria usada. Seria válido especificar um PKEY_FX_EndpointEffectClsid para fins de descoberta, mas seria um erro especificar PKEY_EFX_ProcessingModes_Supported_For_Streaming. Isso ocorre porque o modo mix/tee acontece mais baixo na pilha, onde não é possível inserir um ponto de extremidade de APO.

Instalação de APO componentizado

A partir do Windows 10, versão 1809, o registro de APO no mecanismo de áudio usa o modelo de driver de áudio componentizado. O uso da componentização de áudio cria uma experiência de instalação mais suave e confiável e oferece melhor suporte à manutenção de componentes. Para obter mais informações, consulte Como criar uma instalação de driver de áudio componentizado.

O código de exemplo a seguir é extraído do público ComponentizedAudioSampleExtension.inf e ComponentizedApoSample.inf. Consulte a amostra de áudio SYSVAD que está disponível no GitHub aqui: https://github.com/Microsoft/Windows-driver-samples/tree/main/audio/sysvad.

O registro do APO com o mecanismo de áudio é feito usando um dispositivo APO recém-criado. Para que o mecanismo de áudio faça uso do novo dispositivo APO, ele deve ser um filho PNP do dispositivo de áudio, irmão dos pontos de extremidade de áudio. O novo design de APO componentizado não permite que um APO seja registrado globalmente e usado por vários drivers diferentes. Cada driver deve registrar seus próprios APO's.

A instalação do APO é feita em duas partes. Primeiro, a extensão de driver INF adicionará um componente APO ao sistema:

[DeviceExtension_Install.Components]
AddComponent = SwapApo,,Apo_AddComponent

[Apo_AddComponent]
ComponentIDs = VEN_SMPL&CID_APO
Description = "Audio Proxy APO Sample"

Este componente APO dispara a segunda parte, a instalação do APO INF, no exemplo SYSVAD isso é feito em ComponentizedApoSample.inf. Este arquivo INF é dedicado ao componente APO. Ele especifica a classe do componente como AudioProcessingObject e adiciona todas as propriedades do APO para registro CLSID e registro com o mecanismo de áudio.

Observação

Os exemplos de arquivo INF mostrados oferecem suporte ao isolamento do pacote de driver usando a chave do Registro HKR. Antes do Windows 11, versão 22000, os exemplos usavam o HKCR para armazenar valores persistentes para registros CLSID, em vez de HKR. O registro de APO tem sido suportado usando HKR a partir do Windows 10, versão 1809. Para obter mais informações, consulte Uso de um arquivo INF universal.

[Version]
...
Class       = AudioProcessingObject
ClassGuid   = {5989fce8-9cd0-467d-8a6a-5419e31529d4}
...

[ApoComponents.NT$ARCH$]
%Apo.ComponentDesc% = ApoComponent_Install,APO\VEN_SMPL&CID_APO

[Apo_AddReg]
; CLSID registration
HKR,Classes\CLSID\%SWAP_FX_STREAM_CLSID%,,,%SFX_FriendlyName%
HKR,Classes\CLSID\%SWAP_FX_STREAM_CLSID%\InProcServer32,,0x00020000,%%SystemRoot%%\System32\swapapo.dll
HKR,Classes\CLSID\%SWAP_FX_STREAM_CLSID%\InProcServer32,ThreadingModel,,"Both"
...
;Audio engine registration
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"FriendlyName",,%SFX_FriendlyName%
...

Quando esse INF instala o APO componentizado, em um sistema desktop "Objetos de processamento de áudio" será mostrado no Gerenciador de dispositivos do Windows.

Atualizações para CLSIDs quando uma nova versão do APO é lançada

Quando uma nova versão do APO é lançada, é uma boa prática e geralmente recomendado atualizar a classe COM CLSID. Use ferramentas como GUIDGEN para criar novos GUIDs.

Requisito para atualizar CLSIDs ao mover de HKCR para HKR

É um requisito ao fazer a mudança de registros COM globais (HKCR) para registros HKR COM relativos ao dispositivo para alterar o GUID da classe COM. Essa abordagem reduz a possibilidade de que os novos objetos COM não sejam registrados corretamente e não sejam carregados.

Amostra de áudio Bluetooth de amostra APO INF

Este exemplo ilustra essa combinação de efeitos do sistema:

  • PKEY_FX_StreamEffectClsid com PKEY_SFX_ProcessingModes_Supported_For_Streaming

  • PKEY_FX_ModeEffectClsid com PKEY_MFX_ProcessingModes_Suppoted_For_Streaming

Este código de exemplo suporta dispositivos Bluetooth mãos-livres e estéreo.

; wdma_bt.inf – example usage
...
[BthA2DP]
Include=ks.inf, wdmaudio.inf, BtaMpm.inf
Needs=KS.Registration,WDMAUDIO.Registration,BtaMPM.CopyFilesOnly,mssysfx.CopyFilesAndRegister
...
[BTAudio.SysFx.Render]
HKR,"FX\\0",%PKEY_ItemNameDisplay%,,%FX_FriendlyName%
HKR,"FX\\0",%PKEY_FX_StreamEffectClsid%,,%FX_STREAM_CLSID%
HKR,"FX\\0",%PKEY_FX_ModeEffectClsid%,,%FX_MODE_CLSID%
HKR,"FX\\0",%PKEY_FX_UiClsid%,,%FX_UI_CLSID%
HKR,"FX\\0",%PKEY_FX_Association%,,%KSNODETYPE_ANY%
HKR,"FX\\0",%PKEY_SFX_ProcessingModes_Supported_For_Streaming%,0x00010000,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%
HKR,"FX\\0",%PKEY_MFX_ProcessingModes_Supported_For_Streaming%,0x00010000,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%
...
[Strings]
FX_UI_CLSID      = "{5860E1C5-F95C-4a7a-8EC8-8AEF24F379A1}"
FX_STREAM_CLSID  = "{62dc1a93-ae24-464c-a43e-452f824c4250}"
PKEY_FX_StreamEffectClsid   = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},5"
PKEY_FX_ModeEffectClsid     = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},6"
PKEY_SFX_ProcessingModes_Supported_For_Streaming = "{D3993A3F-99C2-4402-B5EC-A92A0367664B},5"
PKEY_MFX_ProcessingModes_Supported_For_Streaming = "{D3993A3F-99C2-4402-B5EC-A92A0367664B},6"
AUDIO_SIGNALPROCESSINGMODE_DEFAULT = "{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}"

Amostra de áudio APO INF

Este arquivo INF de exemplo ilustra a seguinte combinação de efeitos do sistema:

  • PKEY_FX_StreamEffectClsid com PKEY_SFX_ProcessingModes_Supported_For_Streaming

  • PKEY_FX_ModeEffectClsid com PKEY_MFX_ProcessingModes_Suppoted_For_Streaming

  • PKEY_FX_EndpointEffectClsid sem PKEY_EFX_ProcessingModes_Supported_For_Streaming

[MyDevice.Interfaces]
AddInterface=%KSCATEGORY_AUDIO%,%MyFilterName%,MyAudioInterface

[MyAudioInterface]
AddReg=MyAudioInterface.AddReg

[MyAudioInterface.AddReg]
;To register an APO for discovery, use the following property keys in the .inf (or at runtime when registering the KSCATEGORY_AUDIO device interface):
HKR,"FX\\0",%PKEY_FX_StreamEffectClsid%,,%FX_STREAM_CLSID%
HKR,"FX\\0",%PKEY_FX_ModeEffectClsid%,,%FX_MODE_CLSID%
HKR,"FX\\0",%PKEY_FX_EndpointEffectClsid%,,%FX_MODE_CLSID%

;To register an APO for streaming and discovery, add the following property keys as well (to the same section):
HKR,"FX\\0",%PKEY_SFX_ProcessingModes_For_Streaming%,%REG_MULTI_SZ%,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%,%AUDIO_SIGNALPROCESSINGMODE_MOVIE%,%AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS%

;To register an APO for streaming in multiple modes, use a REG_MULTI_SZ property and include all the modes:
HKR,"FX\\0",%PKEY_MFX_ProcessingModes_For_Streaming%,%REG_MULTI_SZ%,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT%,%AUDIO_SIGNALPROCESSINGMODE_MOVIE%,%AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS%

Defina um exemplo personalizado de APO e LP APO INF

Este exemplo mostra como definir seu próprio CLSID para um APO personalizado. Este exemplo usa o MsApoFxProxy CLSID {889C03C8-ABAD-4004-BF0A-BC7BB825E166}. CoCreate-ing este GUID representa uma classe em MsApoFxProxy.dll que implementa as interfaces IAudioProcessingObject e consulta o driver subjacente por meio do conjunto de propriedades KSPROPSETID_AudioEffectsDiscovery.

Este exemplo de arquivo INF mostra a seção [BthHfAud], que puxa [MsApoFxProxy.Registration] de wdmaudio.inf [BthHfAud.AnlgACapture.AddReg.Wave], que então registra PKEY_FX_EndpointEffectClsid como o CLSID bem conhecido para MsApoFxProxy.dll.

Este exemplo de arquivo INF também ilustra o uso dessa combinação de efeitos do sistema:

  • PKEY_FX_EndpointEffectClsid sem PKEY_EFX_ProcessingModes_Supported_For_Streaming
;wdma_bt.inf
[BthHfAud]
Include=ks.inf, wdmaudio.inf, BtaMpm.inf
Needs=KS.Registration, WDMAUDIO.Registration, BtaMPM.CopyFilesOnly, MsApoFxProxy.Registration
CopyFiles=BthHfAud.CopyList
AddReg=BthHfAud.AddReg

; Called by needs entry in oem inf
[BthHfAudOEM.CopyFiles]
CopyFiles=BthHfAud.CopyList

[BthHfAud.AnlgACapture.AddReg.Wave]
HKR,,CLSID,,%KSProxy.CLSID%
HKR,"FX\\0",%PKEY_FX_Association%,,%KSNODETYPE_ANY%
HKR,"FX\\0",%PKEY_FX_EndpointEffectClsid%,,%FX_DISCOVER_EFFECTS_APO_CLSID%
#endif

Exemplo de registro de efeito APO

Este exemplo mostra a seção [Apo_AddReg] do Sysvad ComponentizedApoSample.inx. Esta seção registra o GUID da transmissão de permuta com COM e registra o efeito APO da transmissão de permuta. A seção [Apo_CopyFiles] tem um DestinationDirs de 13, que copia swapapo.dll para o Driverstore. Para obter mais informações, consulte "Executar do Driverstore" em Isolamento de pacote de driver.

Para obter informações gerais sobre arquivos INF, consulte Visão geral de arquivos INF.

; ComponentizedApoSample.inx

...

[ApoComponent_Install]
CopyFiles = Apo_CopyFiles
AddReg    = Apo_AddReg

[Apo_CopyFiles]
swapapo.dll

...

[Apo_AddReg]
; Swap Stream effect APO COM registration
HKCR,CLSID\%SWAP_FX_STREAM_CLSID%,,,%SFX_FriendlyName%
HKCR,CLSID\%SWAP_FX_STREAM_CLSID%\InProcServer32,,0x00020000,%13%\swapapo.dll
HKCR,CLSID\%SWAP_FX_STREAM_CLSID%\InProcServer32,ThreadingModel,,"Both"

'''
; Swap Stream effect APO registration
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"FriendlyName",,%SFX_FriendlyName%
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"Copyright",,%Copyright%
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"MajorVersion",0x00010001,1
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"MinorVersion",0x00010001,1
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"Flags",0x00010001,%APO_FLAG_DEFAULT%
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"MinInputConnections",0x00010001,1
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"MaxInputConnections",0x00010001,1
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"MinOutputConnections",0x00010001,1
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"MaxOutputConnections",0x00010001,1
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"MaxInstances",0x00010001,0xffffffff
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"NumAPOInterfaces",0x00010001,1
HKR,AudioEngine\AudioProcessingObjects\%SWAP_FX_STREAM_CLSID%,"APOInterface0",,"{FD7F2B29-24D0-4B5C-B177-592C39F9CA10}"
...

[Strings]
; Driver developers would replace these CLSIDs with those of their own APOs
SWAP_FX_STREAM_CLSID   = "{B48DEA3F-D962-425a-8D9A-9A5BB37A9904}"

...

Registro do APO

O registro de APO é usado para dar suporte a um processo que corresponde dinamicamente os efeitos aos pontos de extremidade usando um cálculo ponderado. O cálculo ponderado usa os seguintes repositórios de propriedades. Cada interface de áudio tem zero ou mais armazenamentos de propriedades de ponto de extremidade e repositórios de propriedades de efeitos registrados por meio do .inf ou em tempo de execução. O armazenamento de propriedades de ponto de extremidade mais específico e o repositório de propriedades de efeitos mais específicos têm os pesos mais altos e são usados. Todas as outras lojas de propriedades são ignoradas.

A especificidade é calculada da seguinte forma:

A ponderação dos repositórios de propriedades de ponto de extremidade

  1. FX com KSNODETYPE específico
  2. FX com KSNODETYPE_ANY
  3. MSFX com KSNODETYPE específico
  4. MSFX com KSNODETYPE_ANY

A ponderação dos repositórios de propriedades do Effects

  1. EP com KSNODETYPE específico
  2. EP com KSNODETYPE_ANY
  3. MSEP com KSNODETYPE específico
  4. MSEP com KSNODETYPE_ANY

Os números devem começar em 0 e aumentar sequencialmente: MSEP\0, MSEP\1, ..., MSEP\n. Se (por exemplo) EP\3 estiver faltando, o Windows deixará de procurar EP\n e não verá EP\4, mesmo que ele exista

O valor de PKEY_FX_Association (para repositórios de propriedades de efeitos) ou PKEY_EP_Association (para repositórios de propriedades de ponto de extremidade) é comparado com o valor KSPINDESCRIPTOR.Category para a fábrica de pinos na extremidade do hardware do caminho do sinal, conforme exposto pelo Kernel Streaming.

Somente os drivers de classe da caixa de entrada da Microsoft (que podem ser encapsulados por um desenvolvedor de terceiros) devem usar MSEP e MSFX; todos os drivers de terceiros devem usar EP e FX.

Compatibilidade de tipo de nó APO

O exemplo de arquivo INF a seguir ilustra a configuração da chave PKEY_FX_Association para um GUID associado ao APO.

;; Property Keys
PKEY_FX_Association = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},0"
"
;; Key value pairs
HKR,"FX\\0",%PKEY_FX_Association%,,%KSNODETYPE_ANY%

Como um adaptador de áudio é capaz de suportar várias entradas e saídas, você deve indicar explicitamente o tipo de nó de streaming de kernel (KS) com o qual seu APO personalizado é compatível. No fragmento de arquivo INF anterior, o APO é mostrado como associado a um tipo de nó KS de %KSNODETYPE_ANY%. Mais adiante neste arquivo INF, KSNODETYPE_ANY é definido da seguinte maneira:

[Strings]
;; Define the strings used in MyINF.inf
...
KSNODETYPE_ANY      = "{00000000-0000-0000-0000-000000000000}"
KSNODETYPE_SPEAKER  = "{DFF21CE1-F70F-11D0-B917-00A0C9223196}"
...

Um valor de NULL para KSNODETYPE_ANY significa que este APO é compatível com qualquer tipo de nó KS. Para indicar, por exemplo, que seu APO só é compatível com um tipo de nó KS de KSNODETYPE_SPEAKER, o arquivo INF mostraria o tipo de nó KS e a associação APO da seguinte maneira:

;; Key value pairs
...
HKR,"FX\\0",%PKEY_FX_Association%,,%KSNODETYPE_SPEAKER%
...

Para obter mais informações sobre os valores GUID para os diferentes tipos de nó KS, consulte o arquivo de cabeçalho Ksmedia.h.

Solucionar falhas ao carregar o APO

As informações a seguir são fornecidas para ajudá-lo a entender como a falha é monitorada para APOs. Você pode usar essas informações para solucionar problemas de APOs que não são incorporados ao gráfico de áudio.

O sistema de áudio monitora os códigos de retorno APO para determinar se os APOs estão sendo incorporados com êxito ao gráfico. Ele monitora os códigos de retorno rastreando os valores HRESULT que são retornados por qualquer um dos métodos designados. O sistema mantém um valor de contagem de falhas separado para cada APO SFX, MFX e EFX que está sendo incorporado ao gráfico.

O sistema de áudio monitora os valores HRESULT retornados dos quatro métodos a seguir.

  • :CoCreateInstance

  • IsInputFormatSupported

  • IsOutputFormatSupported

  • LockForProcess

O valor de contagem de falhas é incrementado para um APO sempre que um desses métodos retorna um código de falha. A contagem de falhas é redefinida para zero quando um APO retorna um código que indica que ele foi incorporado com êxito ao gráfico de áudio. Uma chamada bem-sucedida para o método LockForProcess é uma boa indicação de que o APO foi incorporado com êxito.

Para CoCreateInstance em particular, há uma série de razões pelas quais o código HRESULT retornado pode indicar uma falha. As três razões principais são as seguintes:

  • O gráfico está executando conteúdo protegido e o APO não está assinado corretamente.

  • O APO não está registrado.

  • O APO foi renomeado ou adulterado.

Além disso, se o valor de contagem de falhas para um APO SFX, MFX ou EFX atingir um limite especificado pelo sistema, os APOs SFX, MFX e EFX serão desabilitados definindo a chave do Registro PKEY_Endpoint_Disable_SysFx como "1". O limite especificado pelo sistema é atualmente um valor de 10.

Objetos de processamento de áudio do Windows

Criação de uma instalação de driver de áudio componentizado

Isolamento do pacote de driver