Implementing Audio Processing Objects

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

Implementieren benutzerdefinierter APOs

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

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

Jedem logischen Gerät kann ein APO jedes Typs zugeordnet werden. Weitere Informationen zu Modi und Effekten finden Sie unter Audiosignalverarbeitungsmodi.

Sie können einen APO implementieren, indem Sie Ihre benutzerdefinierte Klasse auf der Basis der CBaseAudioProcessingObject-Basisklasse basieren, die in der Datei Baseaudioprocessingobject.h deklariert wird. Dieser Ansatz umfasst das Hinzufügen neuer Funktionen zur CBaseAudioProcessingObject-Basisklasse, um einen angepassten 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 mit einem.
  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:

  • Der APO muss über eine Eingabe- 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 ihn übergeben werden. Der 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 verfügbar machen:

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

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

    • Alle Puffer, die vom APO verarbeitet werden, müssen nicht ausserstellbar sein. Der gesamte Code und die Daten im Prozesspfad müssen nicht ausserstellbar sein.

    • APOs sollten keine erhebliche Latenz in die Audioverarbeitungskette bringen.

  • 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. Das Beispiel "Apo austauschen" tauscht den linken Kanal durch den rechten Kanal und implementiert sowohl SFX- als auch MFX-Effekte. Sie können die Audioeffekte für den Kanalaustausch über das Eigenschaftendialogfeld 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

Herunterladen und Extrahieren des Sysvad-Audiobeispiels von GitHub

Führen Sie die folgenden Schritte aus, um das SYSVAD-Beispiel herunterzuladen und zu öffnen.

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

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

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

c. Halten Sie Windows-driver-samples-master.zipgedrückt( oder klicken Sie mit der rechten Maustaste darauf), und wählen Sie Alle extrahieren aus. Geben Sie einen neuen Ordner an, oder navigieren Sie zu einem vorhandenen Ordner, in dem die extrahierten Dateien gespeichert werden. Sie können beispielsweise C:\DriverSamples\ als neuen Ordner angeben, in den die Dateien extrahiert werden.

d. Navigieren Sie nach dem Extrahieren der Dateien zum folgenden Unterordner: C:\DriverSamples\Audio\Sysvad

Öffnen der Treiberlösung in Visual Studio

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

Suchen Sie in Visual Studio nach dem Projektmappen-Explorer. (Wenn dies noch nicht geöffnet ist, wählen Sie im Menü Ansichtdie Option Projektmappen-Explorer aus.) In Projektmappen-Explorer sehen Sie eine Projektmappe mit sechs Projekten.

SwapAPO-Beispielcode

Das SYSVAD-Beispiel enthält fünf Projekte, von denen eines für den APO-Entwickler von primärem Interesse ist.

Projekt Beschreibung
SwapAPO Beispielcode für einen APO-Beispielcode

Die anderen Projekte im Sysvad-Beispiel sind unten zusammengefasst.

Projekt Beschreibung
TabletAudioSample Beispielcode für einen alternativen Audiotreiber.
KeywordDetectorAdapter Beispielcode für einen Schlüsselwort (keyword)-Detektoradapter
EndpunkteCommon Beispielcode für allgemeine Endpunkte.

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

File 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-Objekt-Audioverarbeitungscodes

Sie können einen vom System bereitgestellten APO umschließen, indem Sie Ihre benutzerdefinierte Klasse auf der Basisklasse CBaseAudioProcessingObject basieren, die in der Datei Baseaudioprocessingobject.h deklariert ist. Dieser Ansatz umfasst die Einführung neuer Funktionen in die CBaseAudioProcessingObject-Basisklasse , um ein angepasstes APO zu erstellen. Die CBaseAudioProcessingObject-Basisklasse implementiert einen Großteil der Funktionalität, die ein APO erfordert. Es 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 besonderen Formatanforderungen hat und mit dem erforderlichen float32-Format arbeitet, sollten die Standardimplementierungen der schnittstellenbasierten Methoden, die in CBaseAudioProcessingObject enthalten sind, ausreichend sein. Angesichts der Standardimplementierungen müssen nur drei Standard-Methoden 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. Um eine tatsächliche Implementierung dieses Konzepts zu erhalten, befolgen Sie die Anweisungen im Abschnitt Beispiel für Audioverarbeitungsobjektetreiber , 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 Signalverarbeitung, die von einem SFX APO ausgeführt wird, von der Signalverarbeitung unterscheidet, die von einem MFX- oder EFX-APO ausgeführt wird, müssen Sie für jede einzelne Klasse separate Klassen erstellen.

  2. Implementieren Sie die folgenden drei Methoden:

    • IAudioProcessingObject::IsInputFormatSupported. Diese Methode behandelt die Formatverhandlung mit der Audio-Engine.

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

    • ValidateAndCacheConnectionInfo. Diese Methode ordnet Arbeitsspeicher zu, um Formatdetails zu speichern, z. B. Kanalanzahl, Samplingrate, Stichprobentiefe und Kanalmaske.

Das folgende C++-Codebeispiel zeigt eine Implementierung der APOProcess-Methode für die Beispielklasse, die Sie in Schritt 1 erstellt haben. Um eine tatsächliche Implementierung dieses Konzepts zu erhalten, befolgen Sie die Anweisungen im Abschnitt Beispiel für Audioverarbeitungsobjektetreiber , 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 . Befolgen Sie für eine tatsächliche Implementierung dieser Methode die Anweisungen im Abschnitt Beispiel 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 übrigen Schnittstellen und Methoden, die Ihre Klasse von CBaseAudioProcessingObject erbt, werden in der Datei Audioenginebaseapo.idl ausführlich 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 in 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 Eines eigenen benutzerdefinierten APO.

CMyFromScratchAPO::IsInputFormatSupported {
    my custom logic
}

Wenn Sie Ihre APOs zum Ersetzen der vom System bereitgestellten APOs entwickeln, müssen Sie die gleichen Namen in der folgenden Liste für die Schnittstellen und Methoden verwenden. Einige der Schnittstellen verfügen zusätzlich zu den aufgeführten erforderlichen Methoden über weitere Methoden. Auf den Referenzseiten für diese Schnittstellen können Sie ermitteln, ob Sie alle 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

Führen Sie bei der Arbeit mit APOs in Visual Studio diese Aufgaben für jedes APO-Projekt aus.

Treiber, die auf Windows 10 abzielen, sollten dynamisch mit der 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" für Releasebuilds auf /MT 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 (Verwenden Run-Time-Bibliothek).

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. Dies bedeutet, dass Ihr APO mit DisableProtectedAudioDG=1 ausgeführt wird, aber wenn dieser Testschlüssel entfernt wird, kann Ihr APO nicht geladen werden, auch wenn es WHQL-signiert ist.

Packen Ihres APO mit einem Treiber

Wenn Sie Einen 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 Universelle Windows-Treiber für Audio. Ihre audiobezogenen Treiberpakete sollten den dort beschriebenen Richtlinien und Paketerstellungsmodellen entsprechen.

Der benutzerdefinierte APO wird als DLL gepackt, und jede Konfigurationsbenutzeroberfläche wird als separate UWP- oder Desktop-Brücke-App gepackt. Das APO-Gerät INF kopiert die DLLs in die Systemordner, die in der zugehörigen INF CopyFile-Direktive angegeben sind. Die DLL, die die APOs enthält, muss sich selbst registrieren, indem sie einen AddReg-Abschnitt in die INF-Datei einschließt.

Die folgenden Absätze und INF-Dateifragmente zeigen die Änderungen, 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 mit bestimmten zulässigen Kombinationen von Registrierungsschlüsseln registrieren. Weitere Informationen darüber, welche Effekte verfügbar sind, und allgemeine Informationen zu APOs finden Sie unter Architektur des Audioverarbeitungsobjekts.

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 Audioverarbeitungsobjekte (AUDIO Processing Objects, APOs) für bestimmte Modi registriert werden. Sie veranschaulichen die möglichen Kombinationen, die in dieser Liste verfügbar sind.

  • 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

SYSVAD Tablet Multi-Mode Streaming Effect APO INF-Beispiel

Dieses Beispiel zeigt, wie ein Multimodus-Streamingeffekt 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 BEISPIEL-INF-Datei die EFX_Streaming-Eigenschaft auskommentiert ist, da die Audioverarbeitung in den Kernelmodus oberhalb dieser Ebene gewechselt ist, sodass die Streamingeigenschaft nicht erforderlich ist und nicht verwendet wird. Es wäre gültig, eine PKEY_FX_EndpointEffectClsid für Ermittlungszwecke anzugeben, aber es wäre ein Fehler, PKEY_EFX_ProcessingModes_Supported_For_Streaming anzugeben. Dies liegt daran, dass die Modusmischung/ -ablage niedriger im Stapel erfolgt, wo es nicht möglich ist, einen Endpunkt-APO einzufügen.

Komponenten-APO-Installation

Ab Windows 10, Release 1809, verwendet die APO-Registrierung bei der Audio-Engine das komponentenisierte Audiotreibermodell. Die Verwendung der Audiokomponente sorgt für eine reibungslosere und zuverlässigere Installationsumgebung und unterstützt die Komponentenwartung besser. Weitere Informationen finden Sie unter Erstellen einer komponentenisierten Audiotreiberinstallation.

Der folgende Beispielcode wird aus den öffentlichen Komponenten 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 bei der Audio-Engine erfolgt über ein neu erstelltes APO-Gerät. Damit die Audio-Engine das neue APO-Gerät verwenden kann, muss es sich um ein PNP-untergeordnetes PNP-Element des Audiogeräts handeln, gleichgeordnete Elemente der Audioendpunkte. Der neue komponentenisierte APO-Entwurf lässt nicht zu, dass ein APO global registriert und von mehreren verschiedenen Treibern verwendet wird. Jeder Treiber muss seine eigenen APO's 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, die Installation des APO INF, im SYSVAD-Beispiel aus, dies erfolgt in ComponentizedApoSample.inf. Diese INF-Datei ist für die APO-Komponente reserviert. Es gibt die Komponentenklasse als AudioProcessingObject an und fügt alle APO-Eigenschaften für die CLSID-Registrierung und Registrierung bei der Audio-Engine hinzu.

Hinweis

Die gezeigten INF-Dateibeispiele unterstützen die Treiberpaketisolation mithilfe des HKR-Registrierungsschlüssels. Vor Windows 11 Version 22000 verwendeten die Beispiele hkCR, um persistente Werte für CLSID-Registrierungen anstelle von HKR zu speichern. Die APO-Registrierung wurde mit HKR ab Windows 10, Release 1809, 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 dieses INF den komponentenisierten APO installiert, wird auf einem Desktopsystem "Audioverarbeitungsobjekte" in Windows Geräte-Manager angezeigt.

Updates zu 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 (GLOBAL COM Registrations, HKCR) zu geräterelativen HKR-COM-Registrierungen muss die GUID der COM-Klasse geändert werden. Dieser Ansatz verringert die Wahrscheinlichkeit, dass die neuen COM-Objekte nicht ordnungsgemäß registriert werden und nicht geladen werden können.

APO INF-Beispiel für Bluetooth-Audio

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. CoCreate-ing this GUID instanziiert eine Klasse in MsApoFxProxy.dll, die die IAudioProcessingObject-Schnittstellen implementiert und den zugrunde liegenden Treiber über den KSPROPSETID_AudioEffectsDiscovery-Eigenschaftssatz abfragt.

Dieses INF-Dateibeispiel zeigt den Abschnitt [BthHfAud], der [MsApoFxProxy.Registration] aus wdmaudio.inf [BthHfAud.AnlgACapture.AddReg.Wave] abruft, der dann PKEY_FX_EndpointEffectClsid als die 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

Apo-Effekt-Beispielregistrierung

Dieses Beispiel zeigt den Abschnitt [Apo_AddReg] aus sysvad ComponentizedApoSample.inx. In diesem Abschnitt wird die Swapstream-GUID bei COM registriert und der Effekt Swap Stream APO registriert. Der Abschnitt [Apo_CopyFiles] weist einen DestinationDirs von 13 auf, der swapapo.dll in den Driverstore kopiert. Weitere Informationen finden Sie unter "Ausführen aus Driverstore" unter 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 mit Endpunkten abgleicht. Die gewichtete Berechnung verwendet die folgenden Eigenschaftenspeicher. Jede Audioschnittstelle verfügt über null oder mehr Endpunkteigenschaftenspeicher und Effekteigenschaftenspeicher, die entweder über die INF oder zur Laufzeit registriert sind. Der spezifischste Endpunkteigenschaftenspeicher und der spezifischste Effekteigenschaftenspeicher weisen die höchste Gewichtung auf und werden verwendet. Alle anderen Eigenschaftenspeicher werden ignoriert.

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 der Effects-Eigenschaft

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

Zahlen müssen bei 0 beginnen und sich sequenziell erhöhen: MSEP\0, MSEP\1, ..., MSEP\n Wenn z. B. EP\3 fehlt, sucht Windows nicht mehr nach EP-\n und wird EP\4 nicht angezeigt, auch wenn es vorhanden ist.

Der Wert von PKEY_FX_Association (für Effekteigenschaftenspeicher) oder PKEY_EP_Association (für Endpunkteigenschaftenspeicher) wird mit dem KSPINDESCRIPTOR verglichen. Kategoriewert für die Pinfactory am Hardwareende des Signalpfads, wie vom Kernelstreaming verfügbar gemacht.

Nur Microsoft-Posteingangsklassentreiber (die von einem Drittanbieterentwickler umschlossen werden können) sollten MSEP und MSFX verwenden. Alle Treiber von Drittanbietern sollten EP und FX verwenden.

Kompatibilität des APO-Knotentyps

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 Ein- und Ausgaben unterstützen kann, müssen Sie explizit den Typ des Kernelstreamingknotens (KS) angeben, mit dem Ihr benutzerdefinierter APO kompatibel ist. Im vorherigen INF-Dateifragment wird angezeigt, dass der APO dem KS-Knotentyp %KSNODETYPE_ANY% zugeordnet ist. 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}"
...

Der Wert NULL für KSNODETYPE_ANY bedeutet, dass dieser APO mit jedem KS-Knotentyp kompatibel ist. Um beispielsweise anzugeben, dass Ihr APO nur mit einem KS-Knotentyp 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 helfen Ihnen zu verstehen, wie Fehler für APOs überwacht werden. Sie können diese Informationen verwenden, um APOs zu behandeln, die nicht in das Audiodiagramm integriert werden.

Das Audiosystem überwacht APO-Rückgabecodes, um zu bestimmen, 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ählerwert für jeden SFX-, MFX- und EFX-APO, der in das Diagramm integriert wird.

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

  • Cocreateinstance

  • IsInputFormatSupported

  • IsOutputFormatSupported

  • LockForProcess

Der Fehleranzahlwert wird für eine 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 die 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 die folgenden:

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

  • Der APO ist nicht registriert.

  • Der APO wurde umbenannt oder manipuliert.

Wenn der Fehleranzahlwert für eine SFX-, MFX- oder EFX-APO einen systemspezifischen Grenzwert erreicht, werden die SFX-, MFX- und EFX-APOs deaktiviert, indem der PKEY_Endpoint_Disable_SysFx Registrierungsschlüssel auf "1" festgelegt wird. Der vom System angegebene Grenzwert ist derzeit ein Wert von 10.

Windows-Audioverarbeitungsobjekte

Erstellen einer komponentenisierten Audiotreiberinstallation

Treiberpaketisolation