Freigeben über


Implementing Audio Processing Objects

In diesem Thema wird beschrieben, wie Sie ein Audioverarbeitungsobjekt (APO) implementieren. Allgemeine Informationen zu APOs finden Sie unter Architektur von Audioverarbeitungsobjekten.

Implementieren von benutzerdefinierten APOs

Benutzerdefinierte APOs werden als prozessinterne COM-Objekte implementiert, sodass sie im Benutzermodus ausgeführt und in einer Dynamic Link Library (DLL) paketiert werden. Es gibt drei Arten von APO, basierend darauf, wo sie in das Signalverarbeitungsdiagramm eingefügt werden.

  • Streameffekte (SFX)
  • Moduseffekte (MFX)
  • Endpunkteffekte (EFX)

Jedes logische Gerät kann einem APO jedes Typs zugeordnet werden. Weitere Informationen zu Modi und Effekten finden Sie unter Audiosignalverarbeitungsmodi.

Sie können ein APO implementieren, indem Sie Ihre benutzerdefinierte Klasse auf der Basisklasse CBaseAudioProcessingObject basieren, die in der Datei Baseaudioprocessingobject.h deklariert wird. Bei diesem Ansatz wird der CBaseAudioProcessingObject-Basisklasse neue Funktionen hinzugefügt, um ein angepasstes APO zu erstellen. Die CBaseAudioProcessingObject-Basisklasse implementiert einen Großteil der Funktionalität, die ein APO benötigt. Sie stellt Standardimplementierungen für die meisten Methoden in den drei erforderlichen Schnittstellen bereit. Die primäre Ausnahme ist die IAudioProcessingObjectRT::APOProcess-Methode.

Führen Sie die folgenden Schritte aus, um Ihre benutzerdefinierten APOs zu implementieren.

  1. Erstellen Sie benutzerdefinierte APO-Com-Objekte, um die gewünschte Audioverarbeitung bereitzustellen.
  2. Erstellen Sie optional eine Benutzeroberfläche zum Konfigurieren der benutzerdefinierten APOs.
  3. Erstellen Sie eine INF-Datei, um die APOs und die benutzerdefinierte Benutzeroberfläche zu installieren und zu registrieren.

Entwurfsüberlegungen für die benutzerdefinierte APO-Entwicklung

Alle benutzerdefinierten APOs müssen die folgenden allgemeinen Merkmale aufweisen:

  • Das APO muss über eine Ein- und eine Ausgabeverbindung verfügen. Diese Verbindungen sind Audiopuffer und können über mehrere Kanäle verfügen.

  • Ein APO kann nur die Audiodaten ändern, die über die IAudioProcessingObjectRT::APOProcess-Routine an sie übergeben werden. Das APO kann die Einstellungen des zugrunde liegenden logischen Geräts, einschließlich der KS-Topologie, nicht ändern.

  • Zusätzlich zu IUnknown müssen APOs die folgenden Schnittstellen bereitstellen:

  • Alle APOs müssen über Echtzeitsystemkompatibilität verfügen. Dies bedeutet Folgendes:

    • Alle Methoden, die Member von Echtzeitschnittstellen sind, müssen als nicht blockierende Member implementiert werden. Sie dürfen nicht blockieren, keinen ausgelagerten Speicher verwenden oder blockierende Systemroutinen aufrufen.

    • Alle vom APO verarbeiteten Puffer müssen nicht auslagerbar sein. Der gesamte Code und alle Daten im Prozesspfad müssen nicht auslagerbar sein.

    • APOs sollten keine erhebliche Latenz in die Audioverarbeitungskette einführen.

  • Benutzerdefinierte APOs dürfen die IAudioProcessingObjectVBR-Schnittstelle nicht verfügbar machen.

Hinweis

Ausführliche Informationen zu den erforderlichen Schnittstellen finden Sie in den Dateien „Audioenginebaseapo.h“ und „Audioenginebaseapo.idl“ im Ordner Windows Kits\<build number>\Include\um.

Verwenden von Beispielcode zur Beschleunigung des Entwicklungsprozesses

Die Verwendung des SYSVAD Swap APO-Codebeispiels als Vorlage kann den benutzerdefinierten APO-Entwicklungsprozess beschleunigen. Das Swap-Beispiel ist das Beispiel, das entwickelt wurde, um einige Features von Audioverarbeitungsobjekten zu veranschaulichen. Im Swap APO-Beispiel wird der linke Kanal mit dem rechten Kanal ausgetauscht und sowohl SFX- als auch MFX-Effekte implementiert. Sie können die Audioeffekte beim Kanaltausch mithilfe des Eigenschaftendialogfelds aktivieren und deaktivieren.

Das SYSVAD-Audiobeispiel ist auf dem GitHub für Windows-Treiberbeispiele verfügbar.

Sie können das Sysvad-Audiobeispiel hier durchsuchen:

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

Laden Sie das Sysvad-Audiobeispiel von GitHub herunter, und extrahieren Sie es

Befolgen Sie diese Schritte, um das SYSVAD-Beispiel herunterzuladen und zu öffnen.

a. Sie können GitHub-Tools verwenden, um mit den Beispielen zu arbeiten. Sie können auch die universellen Treiberbeispiele in einer ZIP-Datei herunterladen.

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

b. Laden Sie die Datei „master.zip“ auf Ihre lokale Festplatte herunter.

c. Wählen und halten Sie (oder klicken Sie mit der rechten Maustaste) Windows-driver-samples-master.zip, und wählen Sie Alle extrahieren. Geben Sie einen neuen Ordner an, oder navigieren Sie zu einem vorhandenen Ordner, in dem die extrahierten Dateien gespeichert werden sollen. Sie könnten zum Beispiel C:\DriverSamples\ als neuen Ordner angeben, in den die Dateien extrahiert werden.

d. Nachdem die Dateien extrahiert wurden, navigieren Sie zum folgenden Unterordner: C:\DriverSamples\Audio\Sysvad

Öffnen Sie die Treiberlösung in Visual Studio

Wählen Sie in Microsoft Visual Studio Datei>Öffnen>Projekt/Projektmappe... aus, und navigieren Sie zu dem Ordner, der die extrahierten Dateien enthält (zum Beispiel C:\DriverSamples\Audio\Sysvad). Doppelklicken Sie auf die Projektmappendatei Sysvad, um sie zu öffnen.

Suchen Sie in Visual Studio den Projektmappen-Explorer. (Falls dieser nicht bereits geöffnet ist, wählen Sie Projektmappen-Explorer im Menü Ansicht aus.) Im Projektmappen-Explorer sehen Sie eine Projektmappe, die sechs Projekte enthält.

SwapAPO-Beispielcode

Es gibt fünf Projekte im SYSVAD-Beispiel, von denen eines von primärem Interesse für den APO-Entwickler ist.

Projekt Beschreibung
SwapAPO Beispielcode für ein Beispiel-APO

Die anderen Projekte im Sysvad-Beispiel sind unten zusammengefasst.

Projekt Beschreibung
TabletAudioSample Beispielcode für einen alternativen Audiotreiber.
KeywordDetectorAdapter Beispielcode für einen Schlüsselwortdetektoradapter
EndpointsCommon Beispielcode für allgemeine Endpunkte.

Die primären Headerdateien für das SwapAPO-Beispiel sind swapapo.h. Die anderen primären Codeelemente werden unten zusammengefasst.

Datei Beschreibung
Swap.cpp C++-Code, der die Implementierung des Swap-APO enthält.
SwapAPOMFX.cpp Implementierung von CSwapAPOMFX
SwapAPOSFX.cpp Implementierung von CSwapAPOSFX
SwapAPODll.cpp Implementierung von DLL-Exporten.
SwapAPODll.idl Definition von COM-Schnittstellen und Co-Klassen für die DLL.
SwapAPOInterface.idl Die Schnittstellen- und Typdefinitionen für die Swap-APO-Funktionalität.
swapapodll.def COM-Exportdefinitionen

Implementieren des COM-Objektaudioverarbeitungscodes

Sie können ein vom System bereitgestelltes APO umschließen, indem Sie Ihre benutzerdefinierte Klasse auf der Basisklasse CBaseAudioProcessingObject basieren, die in der Datei „Baseaudioprocessingobject.h“ deklariert wird. Dieser Ansatz beinhaltet die Einführung der neuen Funktionalität in die CBaseAudioProcessingObject-Basisklasse, um ein angepasstes APO zu erstellen. Die CBaseAudioProcessingObject-Basisklasse implementiert einen Großteil der Funktionalität, die ein APO benötigt. Sie stellt Standardimplementierungen für die meisten Methoden in den drei erforderlichen Schnittstellen bereit. Die primäre Ausnahme ist die IAudioProcessingObjectRT::APOProcess-Methode.

Mithilfe von CBaseAudioProcessingObject können Sie ein APO einfacher implementieren. Wenn ein APO keine speziellen Formatanforderungen aufweist und das erforderliche float32-Format verwendet, sollten die Standardimplementierungen der Schnittstellenmethoden, die in CBaseAudioProcessingObject enthalten sind, ausreichen. Angesichts der Standardimplementierungen müssen nur drei Standardmethoden implementiert werden: IAudioProcessingObject::IsInputFormatSupported, IAudioProcessingObjectRT::APOProcess und ValidateAndCacheConnectionInfo.

Führen Sie die folgenden Schritte aus, um Ihre APOs basierend auf der CBaseAudioProcessingObject-Klasse zu entwickeln:

  1. Erstellen Sie eine Klasse, die von CBaseAudioProcessingObject erbt.

    Das folgende C++-Codebeispiel zeigt die Erstellung einer Klasse, die von CBaseAudioProcessingObject erbt. Für eine tatsächliche Implementierung dieses Konzepts befolgen Sie die Anweisungen im Abschnitt Treiberbeispiel für Audioverarbeitungsobjekte, um zum Swap-Beispiel zu wechseln, und verweisen Sie dann auf die Datei Swapapo.h.

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

    Hinweis: Da sich die von einem SFX-APO durchgeführte Signalverarbeitung von der von einem MFX- oder EFX-APO durchgeführten Signalverarbeitung unterscheidet, müssen Sie für jedes separate Klassen erstellen.

  2. Implementieren Sie die folgenden drei Methoden:

    • IAudioProcessingObject::IsInputFormatSupported. Diese Methode behandelt die Formatverhandlung mit dem Audiomodul.

    • IAudioProcessingObjectRT::APOProcess. Diese Methode verwendet Ihren benutzerdefinierten Algorithmus, um die Signalverarbeitung durchzuführen.

    • ValidateAndCacheConnectionInfo. Diese Methode weist Speicher zum Speichern von Formatdetails zu, z. B. Kanalanzahl, Samplingrate, Beispieltiefe und Kanalmaske.

Das folgende C++-Codebeispiel zeigt eine Implementierung der APOProcess-Methode für die Beispielklasse, die Sie in Schritt 1 erstellt haben. Für eine tatsächliche Implementierung dieses Konzepts befolgen Sie die Anweisungen im Abschnitt Treiberbeispiel für Audioverarbeitungsobjekte, um zum Swap-Beispiel zu wechseln, und verweisen Sie dann auf die Datei 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.
...
}

Das folgende Codebeispiel zeigt eine Implementierung der ValidateAndCacheConnectionInfo-Methode. Für eine tatsächliche Implementierung dieser Methode befolgen Sie die Anweisungen im Abschnitt Treiberbeispiel für Audioverarbeitungsobjekte, um zum Swap-Beispiel zu wechseln, und verweisen Sie dann auf die Datei 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.
...
}

Hinweis Die verbleibenden Schnittstellen und Methoden, die Ihre Klasse von CBaseAudioProcessingObject erbt, werden detailliert in der Datei „Audioenginebaseapo.idl“ beschrieben.

Ersetzen von vom System bereitgestellten APOs

Bei der Implementierung der APO-Schnittstellen gibt es zwei Ansätze: Sie können Ihre eigene Implementierung schreiben oder die Posteingangs-APOs aufrufen.

Dieser Pseudocode veranschaulicht das Umschließen eines System-APO.

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

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

Dieser Pseudocode veranschaulicht das Erstellen Ihres eigenen benutzerdefinierten APO.

CMyFromScratchAPO::IsInputFormatSupported {
    my custom logic
}

Wenn Sie Ihre APOs entwickeln, um die vom System bereitgestellten zu ersetzen, müssen Sie für die Schnittstellen und Methoden die gleichen Namen in der folgenden Liste verwenden. Einige der Schnittstellen verfügen zusätzlich zu den aufgeführten erforderlichen Methoden über weitere Methoden. Sehen Sie sich die Referenzseiten für diese Schnittstellen an, um festzustellen, ob Sie alle Methoden oder nur die erforderlichen Methoden implementieren möchten.

Die restlichen Implementierungsschritte sind identisch mit einem benutzerdefinierten APO.

Implementieren Sie die folgenden Schnittstellen und Methoden für die COM-Komponente:

Arbeiten mit Visual Studio und APOs

Wenn Sie mit APOs in Visual Studio arbeiten, führen Sie diese Aufgaben für jedes APO-Projekt aus.

Treiber, die auf Windows 10 abzielen, sollten dynamisch mit dem universellen CRT verknüpft werden.

Wenn Sie Windows 8.1 unterstützen müssen, aktivieren Sie die statische Verknüpfung, indem Sie die Projekteigenschaften in C/C++, Codegenerierung, festlegen. Legen Sie „Runtime Library“ auf /MT für Releasebuilds oder /MTd für Debugbuilds fest. Diese Änderung wird vorgenommen, da es für einen Treiber schwierig ist, die MSVCRT<n>.dll-Binärdatei neu zu verteilen. Die Lösung besteht darin, libcmt.dll statisch zu verknüpfen. Weitere Informationen finden Sie unter /MD, /MT, /LD (Laufzeitbibliothek verwenden).

Deaktivieren der Verwendung eines eingebetteten Manifests

Deaktivieren Sie die Verwendung eines eingebetteten Manifests, indem Sie Projekteigenschaften für Ihr APO-Projekt festlegen. Wählen Sie Manifesttool, Eingabe und Ausgabe aus. Ändern Sie dann „Manifest einbetten“ von der Standardeinstellung Ja in Nein. Wenn Sie über ein eingebettetes Manifest verfügen, löst dies die Verwendung bestimmter APIs aus, die in einer geschützten Umgebung verboten sind. Das bedeutet, dass Ihr APO mit DisableProtectedAudioDG=1 ausgeführt wird, aber wenn dieser Testschlüssel entfernt wird, kann Ihr APO nicht geladen werden, selbst wenn es WHQL-signiert ist.

Paketieren Ihres APO mit einem Treiber

Wenn Sie Ihren eigenen Audiotreiber entwickeln und die vom System bereitgestellten APOs umschließen oder ersetzen, müssen Sie ein Treiberpaket für die Installation des Treibers und der APOs bereitstellen. Informationen zu Windows 10 finden Sie unter Universal Windows Drivers für Audio. Ihre audiobezogenen Treiberpakete sollten den dort beschriebenen Richtlinien und Paketierungsmodellen entsprechen.

Das benutzerdefinierte APO ist als DLL paketiert und jede Konfigurations-Benutzeroberfläche ist als separate UWP- oder Desktop Bridge-App paketiert. Die APO-Geräte-INF kopiert die DLLs in die Systemordner, die in der zugehörigen INF-CopyFile-Anweisung angegeben sind. Die DLL, die die APOs enthält, muss sich selbst registrieren, indem ein AddReg-Abschnitt in die INF-Datei eingeschlossen wird.

Die folgenden Absätze und INF-Dateifragmente zeigen die Änderungen an, die erforderlich sind, um die Standard-INF-Datei zum Kopieren und Registrieren von APOs zu verwenden.

Die im Sysvad-Beispiel enthaltenen INF-Dateien veranschaulichen, wie die SwapApo.dll-APOs registriert werden.

Registrieren von APOs für Verarbeitungsmodi und Effekte in der INF-Datei

Sie können APOs für bestimmte Modi registrieren, indem Sie bestimmte zulässige Kombinationen von Registrierungsschlüsseln verwenden. Weitere Informationen zu den verfügbaren Effekten und allgemeinen Informationen zu APOs finden Sie unter Architektur von Audioverarbeitungsobjekten.

Informationen zu den einzelnen APO-INF-Dateieinstellungen finden Sie in diesen Referenzthemen.

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

Die folgenden INF-Dateibeispiele zeigen, wie Sie Audioverarbeitungsobjekte (APOs) für bestimmte Modi registrieren. Sie veranschaulichen die möglichen Kombinationen aus dieser Liste.

  • PKEY_FX_StreamEffectClsid mit PKEY_SFX_ProcessingModes_Supported_For_Streaming
  • PKEY_FX_ModeEffectClsid mit PKEY_MFX_ProcessingModes_Suppoted_For_Streaming
  • PKEY_FX_ModeEffectClsid ohne PKEY_MFX_ProcessingModes_Suppoted_For_Streaming
  • PKEY_FX_EndpointEffectClsid ohne PKEY_EFX_ProcessingModes_Supported_For_Streaming

Es gibt eine zusätzliche gültige Kombination, die in diesen Beispielen nicht angezeigt wird.

  • PKEY_FX_EndpointEffectClsid mit PKEY_EFX_ProcessingModes_Supported_For_Streaming

APO-INF-Beispiel für SYSVAD-Tablet-Multimodus-Streamingeffekt

Dieses Beispiel zeigt einen Multimodus-Streaming-Effekt, der mithilfe von AddReg-Einträgen in der SYSVAD Tablet INF-Datei registriert wird.

Dieser Beispielcode stammt aus dem SYSVAD-Audiobeispiel und ist auf GitHub verfügbar: https://github.com/Microsoft/Windows-driver-samples/tree/main/audio/sysvad.

In diesem Beispiel wird diese Kombination von Systemeffekten veranschaulicht:

  • PKEY_FX_StreamEffectClsid mit PKEY_SFX_ProcessingModes_Supported_For_Streaming
  • PKEY_FX_ModeEffectClsid mit 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%

Beachten Sie, dass in der INF-Beispieldatei die Eigenschaft EFX_Streaming auskommentiert ist, da die Audioverarbeitung oberhalb dieser Ebene in den Kernelmodus übergegangen ist, sodass die Streaming-Eigenschaft nicht erforderlich ist und nicht verwendet wird. Es wäre gültig, eine PKEY_FX_EndpointEffectClsid für Erkennungszwecke anzugeben, aber es wäre ein Fehler, PKEY_EFX_ProcessingModes_Supported_For_Streaming anzugeben. Dies liegt daran, dass der Modusmix/Tee weiter unten im Stapel stattfindet, wo es nicht möglich ist, einen Endpunkt-APO einzufügen.

Komponentenbasierte APO-Installation

Ab Windows 10, Version 1809, verwendet die APO-Registrierung beim Audiomodul das komponentenbasierte Audiotreibermodell. Die Verwendung der Audiokomponente schafft eine reibungslosere und zuverlässigere Installationserfahrung und unterstützt die Komponentenwartung besser. Weitere Informationen finden Sie unter Erstellen einer komponentenbasierten Audiotreiberinstallation.

Der folgende Beispielcode wird aus den öffentlichen Dateien ComponentizedAudioSampleExtension.inf und ComponentizedApoSample.inf extrahiert. Weitere Informationen finden Sie im SYSVAD-Audiobeispiel, das auf GitHub verfügbar ist: https://github.com/Microsoft/Windows-driver-samples/tree/main/audio/sysvad.

Die Registrierung des APO mit dem Audiomodul erfolgt über ein neu erstelltes APO-Gerät. Damit das Audiomodul das neue APO-Gerät nutzt, muss es sich um ein untergeordnetes PNP-Element des Audiogeräts handeln, das den Audioendpunkten gleicht. Das neue komponentenbasierte APO-Design ermöglicht es nicht, dass ein APO global registriert und von mehreren verschiedenen Treibern verwendet wird. Jeder Treiber muss seine eigenen APOs registrieren.

Die Installation des APO erfolgt in zwei Teilen. Zunächst fügt die Treibererweiterung INF dem System eine APO-Komponente hinzu:

[DeviceExtension_Install.Components]
AddComponent = SwapApo,,Apo_AddComponent

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

Diese APO-Komponente löst den zweiten Teil aus, die Installation des APO INF, im SYSVAD-Beispiel erfolgt dies in ComponentizedApoSample.inf. Diese INF-Datei ist der APO-Komponente zugeordnet. Sie gibt die Komponentenklasse als AudioProcessingObject an und fügt alle APO-Eigenschaften für die CLSID-Registrierung und die Registrierung beim Audiomodul hinzu.

Hinweis

Die INF-Dateibeispiele zeigen die Unterstützung der Treiberpaketisolation mithilfe des HKR-Registrierungsschlüssels. Vor Windows 11, Version 22000, verwendeten die Beispiele anstelle von HKR den HKCR, um persistente Werte für CLSID-Registrierungen zu speichern. Die APO-Registrierung wurde ab Windows 10, Version 1809, mit HKR unterstützt. Weitere Informationen finden Sie unter Verwenden einer universellen INF-Datei.

[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%
...

Wenn diese INF das komponentenbasierte APO installiert, werden auf einem Desktop-System „Audioverarbeitungsobjekte“ im Windows-Geräte-Manager angezeigt.

Updates für CLSIDs, wenn eine neue APO-Version veröffentlicht wird

Wenn eine neue APO-Version veröffentlicht wird, empfiehlt es sich, die COM-Klasse CLSID zu aktualisieren. Verwenden Sie Tools wie GUIDGEN, um neue GUIDs zu erstellen.

Anforderung zum Aktualisieren von CLSIDs beim Wechsel von HKCR zu HKR

Beim Wechsel von globalen COM-Registrierungen (HKCR) zu gerätebezogenen HKR-COM-Registrierungen ist es erforderlich, die COM-Klassen-GUID zu ändern. Dieser Ansatz verringert die Möglichkeit, dass die neuen COM-Objekte nicht ordnungsgemäß registriert werden und nicht geladen werden können.

APO-INF-Beispiel für Bluetooth-Audiobeispiel

In diesem Beispiel wird diese Kombination von Systemeffekten veranschaulicht:

  • PKEY_FX_StreamEffectClsid mit PKEY_SFX_ProcessingModes_Supported_For_Streaming

  • PKEY_FX_ModeEffectClsid mit PKEY_MFX_ProcessingModes_Suppoted_For_Streaming

Dieser Beispielcode unterstützt Bluetooth-Freisprech- und Stereogeräte.

; 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}"

APO-INF-Audiobeispiel

In dieser INF-Beispieldatei wird die folgende Kombination von Systemeffekten veranschaulicht:

  • PKEY_FX_StreamEffectClsid mit PKEY_SFX_ProcessingModes_Supported_For_Streaming

  • PKEY_FX_ModeEffectClsid mit PKEY_MFX_ProcessingModes_Suppoted_For_Streaming

  • PKEY_FX_EndpointEffectClsid ohne 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%

Definieren eines benutzerdefinierten APO- und CLSID-APO-INF-Beispiels

In diesem Beispiel wird gezeigt, wie Sie Ihre eigene CLSID für ein benutzerdefiniertes APO definieren. In diesem Beispiel wird die MsApoFxProxy CLSID {889C03C8-ABAD-4004-BF0A-BC7BB825E166} verwendet. Durch gemeinsames Erstellen dieser GUID wird eine Klasse in MsApoFxProxy.dll instanziiert, die die IAudioProcessingObject-Schnittstellen implementiert und den zugrunde liegenden Treiber über den Eigenschaftensatz KSPROPSETID_AudioEffectsDiscovery abfragt.

In diesem INF-Dateibeispiel wird der Abschnitt [BthHfAud] gezeigt, der [MsApoFxProxy.Registration] von wdmaudio.inf [BthHfAud.AnlgACapture.AddReg.Wave] abruft, der dann PKEY_FX_EndpointEffectClsid als bekannte CLSID für MsApoFxProxy.dll registriert.

Dieses INF-Dateibeispiel veranschaulicht auch die Verwendung dieser Kombination von Systemeffekten:

  • PKEY_FX_EndpointEffectClsid ohne 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

Beispiel-APO-Effektregistrierung

In diesem Beispiel wird der Abschnitt [Apo_AddReg] aus dem Sysvad ComponentizedApoSample.inx gezeigt. In diesem Abschnitt wird die Swap-Stream-GUID bei COM registriert und der Swap-Stream-APO-Effekt registriert. Der Abschnitt [Apo_CopyFiles] enthält ein DestinationDirs von 13, wodurch swapapo.dll in den Driverstore kopiert wird. Weitere Informationen finden Sie unter „Ausführen von Driverstore“ in Treiberpaketisolation.

Allgemeine Informationen zu INF-Dateien finden Sie unter Übersicht über INF-Dateien.

; 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}"

...

APO-Registrierung

Die APO-Registrierung wird verwendet, um einen Prozess zu unterstützen, der die Auswirkungen mithilfe einer gewichteten Berechnung dynamisch den Endpunkten zuordnet. Die gewichtete Berechnung verwendet die folgenden Eigenschaftenspeicher. Jede Audioschnittstelle verfügt über null oder mehr Endpunkteigenschaftenspeicher und Effekteigenschaftenspeicher, die entweder über die INF-Datei oder zur Laufzeit registriert sind. Der spezifischste Endpunkteigenschaftenspeicher und der spezifischste Effekteigenschaftenspeicher weisen die höchsten Gewichtungen auf und werden verwendet. Alle anderen Eigenschaftenspeicher werden ignoriert.

Die Spezifität wird wie folgt berechnet:

Gewichtung von Endpunkteigenschaftenspeichern

  1. FX mit spezifischem KSNODETYPE
  2. FX mit KSNODETYPE_ANY
  3. MSFX mit spezifischem KSNODETYPE
  4. MSFX mit KSNODETYPE_ANY

Gewichtung von Effekteigenschaftenspeichern

  1. EP mit spezifischem KSNODETYPE
  2. EP mit KSNODETYPE_ANY
  3. MSEP mit spezifischem KSNODETYPE
  4. MSEP mit KSNODETYPE_ANY

Die Zahlen müssen bei 0 beginnen und fortlaufend erhöht werden: MSEP\0, MSEP\1, …, MSEP\n Wenn (zum Beispiel) EP\3 fehlt, hört Windows auf, nach EP\n zu suchen, und erkennt EP\4 nicht einmal, auch wenn es existiert

Der Wert von PKEY_FX_Association (für Effekteigenschaftsspeicher) oder PKEY_EP_Association (für Endpunkteigenschaftsspeicher) wird mit dem KSPINDESCRIPTOR.Category-Wert für die Pin-Factory am Hardware-Ende des Signalpfads verglichen, wie durch das Kernel-Streaming bereitgestellt.

Nur Microsoft-Posteingangsklassentreiber (die von einem Drittanbieter-Entwickler eingebunden werden können) sollten MSEP und MSFX verwenden; alle Drittanbietertreiber sollten EP und FX verwenden.

APO-Knotentypkompatibilität

Das folgende INF-Dateibeispiel veranschaulicht das Festlegen des PKEY_FX_Association-Schlüssels auf eine GUID, die dem APO zugeordnet ist.

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

Da ein Audioadapter mehrere Eingaben und Ausgaben unterstützen kann, müssen Sie explizit den Typ des Kernelstreamingknotentyps (KS) angeben, mit dem Ihr benutzerdefiniertes APO kompatibel ist. Im vorherigen INF-Dateifragment wird das APO einem KS-Knotentyp von %KSNODETYPE_ANY% zugeordnet. Später in dieser INF-Datei wird KSNODETYPE_ANY wie folgt definiert:

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

Ein Wert von NULL für KSNODETYPE_ANY bedeutet, dass dieses APO mit jedem Typ des KS-Knotentyps kompatibel ist. Um beispielsweise anzugeben, dass Ihr APO nur mit einem KS-Knotentyp von KSNODETYPE_SPEAKER kompatibel ist, zeigt die INF-Datei den KS-Knotentyp und die APO-Zuordnung wie folgt an:

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

Weitere Informationen zu den GUID-Werten für die verschiedenen KS-Knotentypen finden Sie in der Headerdatei „Ksmedia.h“.

Problembehandlung bei APO-Ladefehlern

Die folgenden Informationen werden bereitgestellt, um zu verstehen, wie Fehler für APOs überwacht werden. Mithilfe dieser Informationen können Sie APOs beheben, die nicht in das Audiodiagramm integriert werden können.

Das Audiosystem überwacht APO-Rückgabecodes, um festzustellen, ob APOs erfolgreich in das Diagramm integriert werden. Es überwacht die Rückgabecodes, indem die HRESULT-Werte nachverfolgt werden, die von einer der angegebenen Methoden zurückgegeben werden. Das System verwaltet einen separaten Fehlerzählwert für jedes SFX-, MFX- und EFX-APO, das in das Diagramm integriert wird.

Das Audiosystem überwacht die zurückgegebenen HRESULT-Werte aus den folgenden vier Methoden.

  • CoCreateInstance

  • IsInputFormatSupported

  • IsOutputFormatSupported

  • LockForProcess

Der Fehlerzählwert wird für ein APO jedes Mal erhöht, wenn eine dieser Methoden einen Fehlercode zurückgibt. Die Fehleranzahl wird auf null zurückgesetzt, wenn ein APO einen Code zurückgibt, der angibt, dass er erfolgreich in das Audiodiagramm integriert wurde. Ein erfolgreicher Aufruf der LockForProcess-Methode ist ein guter Hinweis darauf, dass das APO erfolgreich integriert wurde.

Insbesondere für CoCreateInstance gibt es eine Reihe von Gründen, warum der zurückgegebene HRESULT-Code auf einen Fehler hinweisen kann. Die drei Hauptgründe sind wie folgt:

  • Das Diagramm führt geschützte Inhalte aus, und das APO ist nicht ordnungsgemäß signiert.

  • Das APO ist nicht registriert.

  • Das APO wurde umbenannt oder manipuliert.

Wenn die Fehleranzahl für ein SFX-, MFX- oder EFX-APO einen vom System angegebenen Grenzwert erreicht, werden die SFX-, MFX- und EFX-APOs deaktiviert, indem sie den PKEY_Endpoint_Disable_SysFx Registrierungsschlüssel auf „1“ festlegen. Der vom System angegebene Grenzwert ist derzeit ein Wert von 10.

Windows-Audioverarbeitungsobjekte

Erstellen einer komponentenbasierten Audiotreiberinstallation

Treiberpaketisolation