Implementación de objetos de procesamiento de audio
En este tema se describe cómo implementar un objeto de procesamiento de audio (APO). Para obtener información general sobre los APO, consulte Arquitectura de objetos de procesamiento de audio.
Implementación de APO personalizados
Los APO personalizados se implementan como objetos COM en proceso, por lo que se ejecutan en modo de usuario y se empaquetan en una biblioteca de vínculos dinámicos (DLL). Hay tres tipos de APO, en función de dónde se insertan en el gráfico de procesamiento de señales.
- Efectos de transmisión (SFX)
- Efectos de modo (MFX)
- Efectos de punto de conexión (EFX)
Cada dispositivo lógico se puede asociar a un APO de cada tipo. Para obtener más información sobre los modos y efectos, consulte Modos de procesamiento de señal de audio.
Puede implementar un APO según la clase personalizada en la clase base CBaseAudioProcessingObject, que se declara en el archivo Baseaudioprocessingobject.h. Este método implica agregar nuevas funciones a la clase base CBaseAudioProcessingObject para crear un APO personalizado. La clase base CBaseAudioProcessingObject implementa gran parte de las funcionalidades que necesita un APO. Ofrece implementaciones predeterminadas para la mayoría de métodos de las tres interfaces necesarias. La excepción principal es el método IAudioProcessingObjectRT::APOProcess.
Realice los siguientes pasos para implementar los APO personalizados.
- Cree objetos COM de APO personalizados para realizar el procesamiento de audio deseado.
- Si lo prefiere, puede crear una interfaz de usuario para configurar los APO personalizados.
- Cree un archivo INF para instalar y registrar los APO y la interfaz de usuario personalizada.
Observaciones de diseño para el desarrollo de APO personalizados
Todos los APO personalizados deben tener las siguientes características generales:
El APO debe tener una conexión de entrada y de salida. Estas conexiones son búferes de audio y pueden tener varios canales.
Un APO solo puede modificar los datos de audio que pasan por él a través de la rutina IAudioProcessingObjectRT::APOProcess. El APO no puede cambiar la configuración del dispositivo lógico subyacente, incluida su topología KS.
Además de IUnknown, los APO deben exponer las interfaces siguientes:
IAudioProcessingObject. Interfaz que controla las tareas de configuración, como la inicialización y la negociación de formatos.
IAudioProcessingObjectConfiguration. La interfaz de configuración.
IAudioProcessingObjectRT. Interfaz en tiempo real que controla el procesamiento de audio. Se puede llamar a partir de un subproceso de procesamiento en tiempo real.
IAudioSystemEffects. La interfaz que hace que el motor de audio reconozca un archivo DLL como un APO de efectos de sistemas.
Todos los APO deben ser compatibles con el sistema en tiempo real. Esto significa que:
Todos los métodos que son miembros de interfaces en tiempo real deben implementarse como miembros que no son de bloqueo. No deben bloquear, usar la memoria paginada ni llamar a ninguna rutina del sistema de bloqueo.
Todos los búferes procesados por el APO deben ser no paginables. Todo el código y los datos de la ruta del proceso deben ser no paginables.
Los APO no deben introducir una latencia significativa en la cadena de procesamiento de audio.
Los APO personalizados no deben exponer la interfaz IAudioProcessingObjectVBR.
Nota:
Para obtener información detallada sobre las interfaces necesarias, consulte los archivos Audioenginebaseapo.h y Audioenginebaseapo.idl en la carpeta Windows Kits\<build number>\Include\um.
Uso de código de ejemplo para acelerar el proceso de desarrollo
El uso del ejemplo de código Swap APO de SYSVAD como plantilla puede acelerar el proceso de desarrollo de APO personalizado. El ejemplo de Swap es el ejemplo que se desarrolló para ilustrar algunas funciones de los objetos de procesamiento de audio. El ejemplo de Swap APO intercambia el canal izquierdo con el canal derecho e implementa efectos SFX y MFX. Puede habilitar y deshabilitar los efectos de audio de intercambio de canales mediante el cuadro de diálogo de propiedades.
El ejemplo de audio SYSVAD está disponible en el GitHub de ejemplos de controladores de Windows.
Puede consultar el ejemplo de audio Sysvad aquí:
https://github.com/Microsoft/Windows-driver-samples/tree/main/audio/sysvad
Descarga y extracción del ejemplo de audio Sysvad de GitHub
Siga estos pasos para descargar y abrir el ejemplo SYSVAD.
a. Puede usar herramientas de GitHub para trabajar con los ejemplos. También puede descargar los ejemplos de controladores universales en un archivo ZIP.
https://github.com/Microsoft/Windows-driver-samples/archive/master.zip
b. Descargue el archivo master.zip en la unidad de disco duro local.
c. Seleccione y mantenga pulsado (o haga clic con el botón derecho) Windows-driver-samples-master.zip y elija Extraer todo. Especifique una nueva carpeta o vaya a una existente que almacenará los archivos extraídos. Por ejemplo, puede indicar C:\DriverSamples\ como la nueva carpeta en la que se van a extraer los archivos.
d. Una vez extraídos los archivos, vaya a la subcarpeta siguiente: C:\DriverSamples\Audio\Sysvad
Apertura de la solución del controlador en Visual Studio
En Microsoft Visual Studio, seleccione Archivo>Abrir>Proyecto/Solución... y vaya a la carpeta que contiene los archivos extraídos (por ejemplo, C:\DriverSamples\Audio\Sysvad). Haga doble clic en el archivo de la solución Sysvad para abrirlo.
En Visual Studio, localice el Explorador de soluciones. (Si aún no está abierto, elija Explorador de soluciones en el menú Ver). En el Explorador de soluciones, puede ver una solución que tiene seis proyectos.
Código de ejemplo de SwapAPO
Hay cinco proyectos en el ejemplo SYSVAD, uno de los cuales es de interés prioritario para el desarrollador de APO.
Proyecto | Descripción |
---|---|
SwapAPO | Código de ejemplo de un APO de muestra |
Los otros proyectos del ejemplo Sysvad se resumen más adelante.
Proyecto | Descripción |
---|---|
TabletAudioSample | Código de ejemplo de un controlador de audio alternativo. |
KeywordDetectorAdapter | Código de ejemplo de un adaptador de detector de palabras clave |
EndpointsCommon | Código de ejemplo de puntos de conexión comunes. |
Los archivos de encabezado principales del ejemplo de SwapAPO son swapapo.h. Los demás elementos del código principal se resumen más adelante.
Archivo | Descripción |
---|---|
Swap.cpp | Código C++ que incluye la implementación del APO de intercambio. |
SwapAPOMFX.cpp | Implementación de CSwapAPOMFX |
SwapAPOSFX.cpp | Implementación de CSwapAPOSFX |
SwapAPODll.cpp | Implementación de exportaciones de DLL. |
SwapAPODll.idl | Definición de interfaces COM y coclases del archivo DLL. |
SwapAPOInterface.idl | Las definiciones de interfaz y tipo para la funcionalidad de Swap APO. |
swapapodll.def | Definiciones de exportaciones COM |
Implementación del código de procesamiento de audio de objetos COM
Puede encapsular un APO facilitado por el sistema si basa la clase personalizada en la clase base CBaseAudioProcessingObject, que se declara en el archivo Baseaudioprocessingobject.h. Este método implica incorporar nuevas funciones a la clase base CBaseAudioProcessingObject para crear un APO personalizado. La clase base CBaseAudioProcessingObject implementa gran parte de las funcionalidades que necesita un APO. Ofrece implementaciones predeterminadas para la mayoría de métodos de las tres interfaces necesarias. La excepción principal es el método IAudioProcessingObjectRT::APOProcess.
Si usa CBaseAudioProcessingObject, puede implementar más fácilmente un APO. Si un APO no tiene requisitos de formato especiales y funciona en el formato float32 correspondientes, las implementaciones predeterminadas de los métodos de interfaz que se incluyen en CBaseAudioProcessingObject deberían ser suficientes. Una vez decididas las implementaciones predeterminadas, solo se deben implementar tres métodos principales: IAudioProcessingObject::IsInputFormatSupported, IAudioProcessingObjectRT::APOProcess y ValidateAndCacheConnectionInfo.
Para desarrollar los APO basadas en la clase CBaseAudioProcessingObject, siga estos pasos:
Cree una clase que se herede de CBaseAudioProcessingObject.
En el siguiente ejemplo de código de C++ se ve cómo se crea una clase que se hereda de CBaseAudioProcessingObject. Para obtener una implementación real de este concepto, siga las instrucciones de la sección Ejemplo de controlador objetos de procesamiento de audio para ir al ejemplo de intercambio y luego consulte el archivo Swapapo.h.
// Custom APO class - SFX Class MyCustomAPOSFX: public CBaseAudioProcessingObject { public: //Code for custom class goes here ... };
Nota Como el procesamiento de señal que realiza un APO de SFX es diferente del procesamiento de señal que realiza un MFX o un APO de EFX, debe crear clases independientes para cada uno.
Implemente los tres métodos siguientes:
IAudioProcessingObject::IsInputFormatSupported. Este método controla la negociación de formato con el motor de audio.
IAudioProcessingObjectRT::APOProcess. Este método usa el algoritmo personalizado para realizar el procesamiento de señales.
ValidateAndCacheConnectionInfo. Este método asigna memoria para almacenar los detalles del formato, por ejemplo, el número de canales, la frecuencia de muestreo, la profundidad de la muestra y la máscara de canal.
En el siguiente ejemplo de código de C++ se ve cómo se implementa el método APOProcess en la clase de ejemplo creada en el paso 1. Para obtener una implementación real de este concepto, siga las instrucciones de la sección Ejemplo de controlador objetos de procesamiento de audio para ir al ejemplo de intercambio y luego consulte el archivo 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.
...
}
En el siguiente código de ejemplo se muestra la implementación del método ValidateAndCacheConnectionInfo. Para obtener una implementación real de este método, siga las instrucciones de la sección Ejemplo de controlador objetos de procesamiento de audio para ir al ejemplo de intercambio y luego consulte el archivo 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.
...
}
Nota Las interfaces y métodos restantes que hereda la clase de CBaseAudioProcessingObject se describen con detalle en el archivo Audioenginebaseapo.idl.
Reemplazar los APO facilitados por el sistema
Al implementar las interfaces de APO, hay dos formas de proceder: puede escribir su propia implementación o puede llamar a los APO de serie.
Este pseudocódigo ilustra cómo se encapsula un APO del sistema.
CMyWrapperAPO::CMyWrapperAPO {
CoCreateInstance(CLSID_InboxAPO, m_inbox);
}
CMyWrapperAPO::IsInputFormatSupported {
Return m_inbox->IsInputFormatSupported(…);
}
Este pseudocódigo muestra cómo se crea un APO personalizado propio.
CMyFromScratchAPO::IsInputFormatSupported {
my custom logic
}
Al desarrollar los APO para reemplazar los facilitados por el sistema, debe usar los mismos nombres en la lista siguiente para las interfaces y los métodos. Algunas de las interfaces tienen más métodos, además de los necesarios ya incluidos. Consulte las páginas de referencia de esas interfaces para determinar si desea implementar todos los métodos o solo los necesarios.
El resto de pasos de la implementación son los mismos que con un APO personalizado.
Implemente las siguientes interfaces y métodos para el componente COM:
- IAudioProcessingObject. Los métodos necesarios para esta interfaz son: Initialize y IsInputFormatSupported.
- IAudioProcessingObjectConfiguration. Los métodos necesarios para esta interfaz son: LockForProcess y UnlockForProcess
- IAudioProcessingObjectRT. El método necesario para esta interfaz es APOProcess y es el método que implementa el algoritmo del DSP.
- IAudioSystemEffects. Esta interfaz hace que el motor de audio reconozca un archivo DLL como APO.
Uso de Visual Studio y APO
Al trabajar con APO en Visual Studio, realice estas tareas en cada proyecto de APO.
Vínculo a CRT
Los controladores que tienen como destino Windows 10 deben vincularse dinámicamente con el CRT universal.
Si necesita usar Windows 8.1, active la vinculación estática creando las propiedades del proyecto en la generación de código de C/C++. Cambie "Biblioteca en tiempo de ejecución" a /MT para compilaciones de versiones o /MTd para compilaciones de depuración. Este cambio se realiza porque para un controlador es difícil redistribuir el archivo binario MSVCRT<n>.dll. La solución consiste en vincular estáticamente libcmt.dll. Para obtener más información, consulte /MD, /MT, /LD (Utilizar biblioteca en tiempo de ejecución).
Deshabilitar el uso de un manifiesto incrustado
Deshabilite la opción de usar un manifiesto incrustado ajustando las propiedades del proyecto de APO. Seleccione Herramienta de manifiesto, Entrada y salida. Después, cambie "Incrustar manifiesto" en el valor predeterminado de Sí a No. Si tiene un manifiesto incrustado, esto hará que se usen determinadas API que están prohibidas en un entorno protegido. Esto significa que el APO se ejecutará con DisableProtectedAudioDG=1, pero cuando se quite esta clave de prueba, el APO no se cargará, aunque esté firmado mediante WHQL.
Empaquetado del APO con un controlador
Al desarrollar su propio controlador de audio y encapsular o reemplazar los APO facilitados por el sistema, debe incluir un paquete de controladores para instalar el controlador y los APO. Para Windows 10, consulte Controladores universales de audio de Windows. Los paquetes de controladores relacionados con audio deben seguir las directivas y el modelo de empaquetado detallados.
El APO personalizado se empaqueta como DLL y cualquier interfaz de usuario de configuración se empaqueta como una aplicación de UWP o Puente de dispositivo de escritorio independiente. El INF del dispositivo APO copia los archivos DLL en las carpetas del sistema que se indican en la directiva CopyFile del INF asociada. El archivo DLL con los APO debe registrarse incluyendo una sección AddReg en el archivo INF.
En los párrafos siguientes y fragmentos del archivo INF se indican las modificaciones necesarias para usar el archivo INF estándar para copiar y registrar los APO.
Los archivos INF incluidos en el ejemplo de Sysvad muestran cómo se registran los APO de SwapApo.dll.
Registro de APO para modos de procesamiento y efectos en el archivo INF
Puede registrar los APO en modos específicos mediante determinadas combinaciones permitidas de claves de registro. Para obtener más información sobre qué efectos están disponibles e información general sobre los APO, consulte Arquitectura de objetos de procesamiento de audio.
Consulte estos temas de referencia para obtener información sobre cada una de las opciones de configuración del archivo INF del APO.
PKEY_SFX_ProcessingModes_Supported_For_Streaming
PKEY_MFX_ProcessingModes_Supported_For_Streaming
PKEY_EFX_ProcessingModes_Supported_For_Streaming
En los siguientes ejemplos de archivos INF se ve cómo registrar objetos de procesamiento de audio (APO) en modos específicos. Reflejan las posibles combinaciones disponibles en esta lista.
- PKEY_FX_StreamEffectClsid con PKEY_SFX_ProcessingModes_Supported_For_Streaming
- PKEY_FX_ModeEffectClsid con PKEY_MFX_ProcessingModes_Suppoted_For_Streaming
- PKEY_FX_ModeEffectClsid sin PKEY_MFX_ProcessingModes_Suppoted_For_Streaming
- PKEY_FX_EndpointEffectClsid sin PKEY_EFX_ProcessingModes_Supported_For_Streaming
Hay una combinación válida adicional que no aparece en estos ejemplos.
- PKEY_FX_EndpointEffectClsid con PKEY_EFX_ProcessingModes_Supported_For_Streaming
Ejemplo de INF de APO de efectos de streaming multimodo en tableta de SYSVAD
En este ejemplo se muestra un efecto de streaming multimodo que se registra mediante entradas AddReg en el archivo INF en tableta de SYSVAD.
Este código de ejemplo procede del ejemplo de audio SYSVAD y está disponible en GitHub: https://github.com/Microsoft/Windows-driver-samples/tree/main/audio/sysvad.
En este ejemplo se muestra esta combinación de efectos del sistema:
- PKEY_FX_StreamEffectClsid con PKEY_SFX_ProcessingModes_Supported_For_Streaming
- PKEY_FX_ModeEffectClsid con 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%
Tenga en cuenta que en el archivo INF de ejemplo, la propiedad EFX_Streaming viene comentada porque el procesamiento de audio ha pasado al modo kernel por encima de esa capa, de modo que la propiedad de streaming no es necesaria y no se usaría. Sería válido indicar un PKEY_FX_EndpointEffectClsid con fines de detección, pero sería un error indicar PKEY_EFX_ProcessingModes_Supported_For_Streaming. Esto se debe a que la combinación de modo o tee se produce en la pila, donde no es posible insertar un APO de punto de conexión.
Instalación de APO con división de componentes
A partir de Windows 10, versión 1809, el registro de APO con el motor de audio usa el modelo de controlador de audio con división de componentes. El uso de la división de componentes de audio crea un sistema de instalación más fluida y fiable y aceptar mejor el mantenimiento de componentes. Para obtener más información, consulte Creación de una instalación de controladores de audio con división de componentes.
El código de ejemplo siguiente se extrae de la clase pública ComponentizedAudioSampleExtension.inf y ComponentizedApoSample.inf. Consulte el ejemplo de audio SYSVAD que está disponible en GitHub aquí: https://github.com/Microsoft/Windows-driver-samples/tree/main/audio/sysvad.
El registro del APO con el motor de audio se realiza mediante un dispositivo APO recién creado. Para que el motor de audio use el nuevo dispositivo APO, debe ser un elemento secundario PNP del dispositivo de audio, del mismo nivel que los puntos de conexión de audio. El nuevo diseño de APO con división de componentes no permite que un APO se registre globalmente y lo usen varios controladores diferentes. Cada controlador debe registrar sus propios APO.
La instalación del APO se realiza en dos partes. En primer lugar, la extensión de controlador INF agregará un componente de APO al sistema:
[DeviceExtension_Install.Components]
AddComponent = SwapApo,,Apo_AddComponent
[Apo_AddComponent]
ComponentIDs = VEN_SMPL&CID_APO
Description = "Audio Proxy APO Sample"
Este componente de APO activa la segunda parte, la instalación del INF del APO, en el ejemplo SYSVAD que se realiza en ComponentizedApoSample.inf. Este archivo INF está destinado al componente de APO. Indica la clase de componente como AudioProcessingObject y agrega todas las propiedades de APO para el registro de CLSID y el registrarse con el motor de audio.
Nota:
Los ejemplos de archivos INF muestran el aislamiento de paquetes de controladores mediante la clave de registro de HKR. Antes de Windows 11, versión 22000, los ejemplos usaban HKCR para almacenar valores persistentes en los registros de CLSID, en lugar de HKR. El registro de APO ya se admite mediante HKR a partir de Windows 10, versión 1809. Para obtener más información, consulte Usar un archivo 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%
...
Cuando el INF instala el APO con división de componentes, en un sistema de escritorio "Objetos de procesamiento de audio", aparecerá en el Administrador de dispositivos de Windows.
Cambios en CLSID cuando se publica una nueva versión de APO
Cuando se publica una nueva versión de APO, se recomienda el procedimiento recomendado y, por lo general, se recomienda actualizar el CLSID de clase COM. Use herramientas como GUIDGEN para crear nuevos GUID.
Requisito de actualizar CLSID al pasar de HKCR a HKR
Es obligatorio realizar el cambio de registros COM globales (HKCR) a registros COM relativos al dispositivo para cambiar el GUID de clase COM. Este procedimiento reduce la posibilidad de que los nuevos objetos COM no se registren correctamente y no se carguen.
Ejemplo de INF de APO de ejemplo de audio Bluetooth
En este ejemplo se muestra esta combinación de efectos del sistema:
PKEY_FX_StreamEffectClsid con PKEY_SFX_ProcessingModes_Supported_For_Streaming
PKEY_FX_ModeEffectClsid con PKEY_MFX_ProcessingModes_Suppoted_For_Streaming
Este código de ejemplo admite dispositivos Bluetooth de manos libres y 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}"
Ejemplo de audio de INF de APO
En este archivo INF de ejemplo figura la siguiente combinación de efectos del sistema:
PKEY_FX_StreamEffectClsid con PKEY_SFX_ProcessingModes_Supported_For_Streaming
PKEY_FX_ModeEffectClsid con PKEY_MFX_ProcessingModes_Suppoted_For_Streaming
PKEY_FX_EndpointEffectClsid sin 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%
Definición de ejemplo de APO personalizado y INF de APO con CLSID
En este ejemplo se ve cómo definir un CLSID propio para un APO personalizado. En este ejemplo se usa el CLSID de MsApoFxProxy {889C03C8-ABAD-4004-BF0A-BC7BB825E166}. Si se cocrea este GUID, se crea la instancia de una clase en MsApoFxProxy.dll que implementa las interfaces IAudioProcessingObject y consulta al controlador subyacente a través del conjunto de propiedades KSPROPSETID_AudioEffectsDiscovery.
En ejemplo de archivo INF aparece la sección [BthHfAud], que extrae [MsApoFxProxy.Registration] de wdmaudio.inf [BthHfAud.AnlgACapture.AddReg.Wave], que luego registra PKEY_FX_EndpointEffectClsid como el CLSID conocido para MsApoFxProxy.dll.
En este ejemplo de archivo INF también se refleja cómo se usa esta combinación de efectos del sistema:
- PKEY_FX_EndpointEffectClsid sin 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
Registro de efectos de APO de ejemplo
En este ejemplo aparece la sección [Apo_AddReg] de ComponentizedApoSample.inx de Sysvad. En esta sección se registra el GUID de la transmisión de intercambio con COM y se registra el efecto de APO de la transmisión de intercambio. La sección [Apo_CopyFiles] incluye un DestinationDirs de 13, que copia swapapo.dll en el almacén de controladores. Para obtener más información, consulte "Ejecutar desde el almacén de controladores" en Aislamiento de paquetes de controladores.
Para obtener información general sobre los archivos INF, consulte Introducción a los archivos 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 de APO
El registro de APO se usa para autorizar un proceso que coincida dinámicamente con los efectos de los puntos de conexión mediante un cálculo ponderado. El cálculo ponderado usa los siguientes almacenes de propiedades. Cada interfaz de audio tiene cero o varios almacenes de propiedades de puntos de conexión y almacenes de propiedades de efectos registrados a través de .inf o en tiempo de ejecución. El almacén de propiedades de puntos de conexión más específico y el almacén de propiedades de efectos más específicos tienen las ponderaciones más altas y se usan. No se tienen en cuenta los demás almacenes de propiedades.
La especificidad se calcula del modo siguiente:
La propiedad Endpoint almacena la ponderación
- FX con KSNODETYPE específico
- FX con KSNODETYPE_ANY
- MSFX con KSNODETYPE específico
- MSFX con KSNODETYPE_ANY
La propiedad Effects almacena la ponderación
- EP con KSNODETYPE específico
- EP con KSNODETYPE_ANY
- MSEP con KSNODETYPE específico
- MSEP con KSNODETYPE_ANY
Los números deben comenzar por 0 y aumentar secuencialmente: MSEP\0, MSEP\1, ..., MSEP\n,. Si falta (por ejemplo) EP\3, Windows dejará de buscar EP\n y no verá EP\4, aunque exista.
El valor de PKEY_FX_Association (para los almacenes de propiedades de efectos) o PKEY_EP_Association (para los almacenes de propiedades de puntos de conexión) se compara con el valor KSPINDESCRIPTOR.Category de la fábrica de pines en el parte de hardware de la ruta de la señal, tal y como expone el streaming de kernel.
Solo los controladores de clase de serie de Microsoft (que los puede ajustar un desarrollador externo) deben usar MSEP y MSFX; todos los controladores de terceros deben usar EP y FX.
Compatibilidad de tipos de nodo de APO
En el siguiente ejemplo de archivo INF se refleja cómo crear la clave de PKEY_FX_Association en un GUID asociado al APO.
;; Property Keys
PKEY_FX_Association = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},0"
"
;; Key value pairs
HKR,"FX\\0",%PKEY_FX_Association%,,%KSNODETYPE_ANY%
Dado que un adaptador de audio es capaz de admitir varias entradas y salidas, debe indicar explícitamente el tipo de nodo de streaming de kernel (KS) con el que es compatible el APO personalizado. En el fragmento de archivo INF anterior, se ve que el APO está asociado a un tipo de nodo de KS de %KSNODETYPE_ANY%. Más adelante en este archivo INF, KSNODETYPE_ANY se define de la siguiente manera:
[Strings]
;; Define the strings used in MyINF.inf
...
KSNODETYPE_ANY = "{00000000-0000-0000-0000-000000000000}"
KSNODETYPE_SPEAKER = "{DFF21CE1-F70F-11D0-B917-00A0C9223196}"
...
El valor de NULL de KSNODETYPE_ANY significa que este APO es compatible con cualquier tipo de tipo de nodo de KS. Para indicar, por ejemplo, que el APO solo es compatible con un tipo de nodo de KS de KSNODETYPE_SPEAKER, el archivo INF mostraría el tipo de nodo de KS y la asociación de APO de la siguiente manera:
;; Key value pairs
...
HKR,"FX\\0",%PKEY_FX_Association%,,%KSNODETYPE_SPEAKER%
...
Para obtener más información sobre los valores del GUID de los distintos tipos de nodo de KS, consulte el archivo de encabezado Ksmedia.h.
Solución de problemas de errores de carga de APO
La siguiente información le ayudará a conocer cómo se analiza y supervisa los errores de los APO. Puede usar esta información para solucionar problemas de APO que no se puedan incorporar al gráfico de audio.
El sistema de audio supervisa los códigos de retorno de APO para determinar si los APO se integran correctamente en el gráfico. Este supervisa los códigos de retorno mediante el seguimiento de los valores HRESULT devueltos por cualquiera de los métodos designados. El sistema mantiene un valor del número de errores independiente por cada APO de SFX, MFX y EFX que se va a incorporar al gráfico.
El sistema de audio controla los valores HRESULT devueltos por medio de los cuatro métodos siguientes.
CoCreateInstance
IsInputFormatSupported
IsOutputFormatSupported
LockForProcess
El valor de número de errores se incrementa por APO cada vez que uno de estos métodos devuelve un código de error. El número de errores se restablece a cero cuando un APO devuelve un código que indica que se ha incorporado correctamente al gráfico de audio. Una llamada correcta al método LockForProcess es una buena indicación de que el APO se ha incorporado correctamente.
En el caso de CoCreateInstance, hay varias razones por las que el código HRESULT devuelto podría indicar un error. Las tres razones principales son las siguientes:
El gráfico ejecuta contenido protegido y el APO no está firmado correctamente.
El APO no está registrado.
Se ha cambiado el nombre del APO o se ha alterado.
Además, si el valor de número de errores de un APO de SFX, MFX o EFX alcanza un límite designado por el sistema, los APO de SFX, MFX y EFX se deshabilitan cambiando la clave de registro de PKEY_Endpoint_Disable_SysFx a "1". El límite indicado por el sistema es actualmente un valor de 10.
Temas relacionados
Objetos de procesamiento de audio de Windows
Creación de una instalación de controladores de audio con división de componentes