共用方式為


實作音訊處理物件

本主題描述如何實作音訊處理物件 (APO)。 如需 APO 的一般資訊,請參閱 音訊處理物件架構

實作自定義 API

自定義 APO 會實作為同進程 COM 物件,因此會在使用者模式中執行,並封裝在動態連結庫 (DLL) 中。 APO 有三種類型,取決於它們在信號處理圖上的插入位置。

  • 串流效果 (SFX)
  • 模式效果 (MFX)
  • 端點效果 (EFX)

每個邏輯裝置都可以與每種類型的一個 APO 相關聯。 如需模式和效果的詳細資訊,請參閱 音訊號處理模式

您可以在 CBaseAudioProcessingObject 基類上以自定義類別為基礎來實作 APO,該基類是在 Baseaudioprocessingobject.h 檔案中宣告。 此方法牽涉到將新功能新增至 CBaseAudioProcessingObject 基類,以建立自定義的 APO。 CBaseAudioProcessingObject 基類會實作 APO 所需的許多功能。 它提供三個必要介面中大部分方法的默認實作。 主要例外狀況是 IAudioProcessingObjectRT::APOProcess 方法。

執行下列步驟來實作您的自定義 API。

  1. 建立自定義 APO com 物件,以提供所需的音訊處理。
  2. 選擇性地建立使用者介面,以使用 來設定自定義 API。
  3. 建立 INF 檔案,以安裝和註冊 APOs 和自定義使用者介面。

自定義 APO 開發的設計考慮

所有自訂 APO 都必須具有下列一般特性:

  • APO 必須有一個輸入和輸出連線。 這些連線是音訊緩衝區,而且可以有多個通道。

  • APO 只能修改透過 其 IAudioProcessingObjectRT::APOProcess 例程傳遞給它的音訊數據。 APO 無法變更基礎邏輯裝置的設定,包括其 KS 拓撲。

  • 除了 IUnknown 之外,APOs 還必須公開下列介面:

  • 所有 APO 都必須具有即時系統相容性。 這表示:

    • 屬於即時介面成員的所有方法都必須實作為非封鎖成員。 它們不得封鎖、使用分頁記憶體,或呼叫任何封鎖系統例程。

    • APO 處理的所有緩衝區都必須不可分頁。 進程路徑中的所有程式代碼和數據都必須不可分頁。

    • APOs 不應在音訊處理鏈中引入重大的延遲。

  • 自定義 API 不得公開 IAudioProcessingObjectVBR 介面。

備註

如需必要介面的詳細資訊,請參閱 Windows Kits\<build number>\Include\um 資料夾中的 Audioenginebaseapo.h 和 Audioenginebaseapo.idl 檔案。

使用範例程式代碼加速開發程式

使用SYSVAD交換 APO 程式代碼範例作為範本,可以加速自訂 APO 開發程式。 Swap 範例是為了說明音訊處理物件的一些功能而建立的範例。 交換 APO 範例會將左通道與右通道交換,並實作 SFX 和 MFX 效果。 您可以使用 [屬性] 對話框來啟用和停用通道交換音訊效果。

Windows 驅動程式範例 GitHub 上提供 SYSVAD 音訊範例。

您可以在這裡瀏覽 Sysvad 音訊範例。

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

從 GitHub 下載並擷取 Sysvad 音訊範例

請遵循下列步驟來下載並開啟SYSVAD範例。

一。 您可以使用 GitHub 工具來處理範例。 您也可以在一個 zip 檔案中下載通用驅動程式範例。

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

b。 將 master.zip 檔案下載到本機硬碟。

丙. 選取並按住 (或以滑鼠右鍵按兩下) Windows-driver-samples-master.zip,然後選擇 [ 全部擷取]。 指定新的資料夾,或瀏覽至將儲存解壓縮檔的現有資料夾。 例如,您可以將 C:\DriverSamples\ 指定為要擷取檔案的新資料夾。

d。 擷取檔案之後,流覽至下列子資料夾: C:\DriverSamples\Audio\Sysvad

在 Visual Studio 中開啟驅動程式解決方案

在 Microsoft Visual Studio 中,選取 [ 檔案>開啟>專案/方案... ],然後流覽至包含解壓縮文件的資料夾(例如 C:\DriverSamples\Audio\Sysvad)。 雙擊 Sysvad 方案檔案開啟。

在 Visual Studio 中,找到 [方案總管]。 (如果尚未開啟,請從 [檢視] 功能表選擇 [方案總管]。在 [方案總管] 中,您可以看到一個有六個專案的方案。

SwapAPO 範例程序代碼

SYSVAD 範例中有五個專案,其中一個專案對 APO 開發人員有主要興趣。

計畫 說明
SwapAPO 範例 APO 的程式代碼範例

Sysvad 範例中的其他專案摘要如下。

計畫 說明
平板音頻樣本 替代音訊驅動程式的範例程序代碼。
關鍵字檢測器轉接器 關鍵詞偵測器配接器的範例程序代碼
EndpointsCommon 常見端點的範例程序代碼。

SwapAPO 範例的主要頭檔是 swapapo.h。 下列摘要說明其他主要程式代碼元素。

檔案 說明
Swap.cpp C++ 程式碼中包含 Swap APO 的實作。
SwapAPOMFX.cpp CSwapAPOMFX 的實作
SwapAPOSFX.cpp CSwapAPOSFX 的實作
SwapAPODll.cpp DLL 匯出的實現。
SwapAPODll.idl DLL 的 COM 介面和共同類別定義。
SwapAPOInterface.idl 交換 APO 功能的介面和類型定義。
swapapodll.def COM 匯出定義

實作 COM 物件音訊處理程序代碼

您的自定義類別可以基於 CBaseAudioProcessingObject 基類來封裝系統提供的 APO,這個基類是在 Baseaudioprocessingobject.h 檔案中宣告的。 此方法牽涉到將新功能引入 CBaseAudioProcessingObject 基類,以建立自定義的 APO。 CBaseAudioProcessingObject 基類會實作 APO 所需的許多功能。 它提供三個必要介面中大部分方法的默認實作。 主要例外狀況是 IAudioProcessingObjectRT::APOProcess 方法。

藉由使用 CBaseAudioProcessingObject,您可以更輕鬆地實作 APO。 如果 APO 沒有特殊格式需求,而且會以必要的 float32 格式運作, 則 CBaseAudioProcessingObject 中包含的介面方法的預設實作應該就已足夠。 假設預設實作,只需要實作三個主要方法: IAudioProcessingObject::IsInputFormatSupportedIAudioProcessingObjectRT::APOProcessValidateAndCacheConnectionInfo

若要根據 CBaseAudioProcessingObject 類別開發 API,請執行下列步驟:

  1. 建立繼承自 CBaseAudioProcessingObject 的類別。

    下列C++程序代碼範例示範如何建立繼承自 CBaseAudioProcessingObject 的類別。 如需此概念的實際實作,請依照 音訊處理物件驅動程式範例 一節中的指示移至交換範例,然後參考 Swapapo.h 檔案。

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

    注意 由於 SFX APO 所執行的訊號處理與 MFX 或 EFX APO 所執行的訊號處理不同,因此您必須為每個專案建立個別的類別。

  2. 實作下列三種方法:

下列C++程序代碼範例顯示您在步驟 1 中建立之範例類別 的 APOProcess 方法實作。 如需此概念的實際實作,請依照 音訊處理物件驅動程式範例 一節中的指示移至交換範例,然後參考 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.
...
}

下列程式代碼範例示範 ValidateAndCacheConnectionInfo 方法的實作。 如需此方法的實際實作,請依照 音訊處理物件驅動程式範例 一節中的指示移至交換範例,然後參考 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.
...
}

注意 您的類別繼承自 CBaseAudioProcessingObject 的其餘介面和方法會在 Audioenginebaseapo.idl 檔案中詳細說明。

取代系統提供的APOs

實作 APO 介面時,有兩種方法:您可以撰寫自己的實作,或呼叫收件匣 API。

此偽代碼說明封裝系統 APO。

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

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

此虛擬程式代碼說明如何建立您自己的自定義 APO。

CMyFromScratchAPO::IsInputFormatSupported {
    my custom logic
}

當您開發 API 來取代系統提供的 API 時,您必須針對介面和方法使用下列清單中的相同名稱。 除了列出的必要方法之外,有些介面還有更多方法。 請參閱這些介面的參考頁面,以判斷您是否要實作所有方法,或只實作必要的方法。

其餘的實作步驟與自定義 APO 相同。

為 COM 元件實作下列介面和方法:

使用 Visual Studio 和 APOS

在 Visual Studio 中使用 APOs 時,請針對每個 APO 專案執行這些工作。

以 Windows 10 為目標的驅動程式應該動態連結至通用 CRT。

如果您需要支援 Windows 8,1,請在 C/C++ 程式代碼產生中設定項目屬性,以啟用靜態連結。 將「運行時間庫」設定為 /MT 用於發行組建,或設定為 /MTd 用於偵錯組建。 這項變更是因為對於驅動程式而言,重新分發 MSVCRT<n>.dll 二進位檔很困難。 解決方案是靜態連結 libcmt.dll。 如需詳細資訊,請參閱 /MD、/MT、/LD (使用 Run-Time 連結庫)

停用內嵌清單的使用

透過設置 APO 專案屬性來停用使用內嵌清單。 選取 清單工具輸入與輸出。 然後將 [內嵌指令清單] 從預設值 [ ] 變更為 [否]。 如果您有內嵌指令清單,這會觸發使用受保護的環境內禁止的特定 API。 這表示您的 APO 會以 DisableProtectedAudioDG=1 執行,但在移除此測試金鑰後,您的 APO 將無法載入,即使它已取得 WHQL 簽署。

使用驅動程式封裝您的 APO

當您開發自己的音訊驅動程式並封裝或取代系統提供的(APOs)時,您必須提供驅動程式套件來安裝驅動程式和(APOs)。 針對 Windows 10,請參閱 適用於音訊的通用 Windows 驅動程式。 您的音訊相關驅動程式套件應遵循該處詳述的原則和封裝模型。

自訂的 APO 封裝為 DLL,而任何組態 UI 則封裝為獨立的 UWP 或桌面橋接應用程式。 APO 裝置 INF 會將 DLL 複製到相關 INF CopyFile 指示詞中所指示的系統資料夾。 包含 APOs 的 DLL 必須藉由在 INF 檔案中包含 AddReg 區段來註冊本身。

下列段落和 INF 檔案片段會顯示使用標準 INF 檔案來複製和註冊 APOs 所需的修改。

Sysvad 範例隨附的 inf 檔案說明如何註冊 SwapApo.dll APOs。

在 INF 檔案中註冊處理模式和效果的 API

您可以使用某些允許的登錄機碼組合來針對特定模式註冊 APO。 如需哪些效果可用的詳細資訊,以及有關APOS的一般資訊,請參閱 音訊處理物件架構

如需每個 APO INF 檔案設定的資訊,請參閱這些參考主題。

PKEY_FX_StreamEffectClsid

PKEY_FX_ModeEffectClsid

PKEY_FX_EndpointEffectClsid

PKEY_SFX_ProcessingModes_Supported_For_Streaming

PKEY_MFX_ProcessingModes_Supported_For_Streaming(支援串流的 MFX 處理模式鍵)

PKEY_EFX_ProcessingModes_Supported_For_Streaming

下列 INF 檔案範例示範如何註冊特定模式的音訊處理物件(APOS)。 它們說明此清單中可用的可能組合。

  • 使用 PKEY_FX_StreamEffectClsid 與 PKEY_SFX_ProcessingModes_Supported_For_Streaming
  • PKEY_FX_ModeEffectClsid PKEY_MFX_ProcessingModes_Suppoted_For_Streaming
  • 沒有PKEY_MFX_ProcessingModes_Suppoted_For_Streaming的PKEY_FX_ModeEffectClsid
  • PKEY_FX_EndpointEffectClsid 沒有 PKEY_EFX_ProcessingModes_Supported_For_Streaming

這些範例中未顯示另外一個有效的組合。

  • 支援串流的 PKEY_EFX_ProcessingModes_Supported_For_Streaming 之 PKEY_FX_EndpointEffectClsid

SYSVAD 平板電腦多重模式串流效果 APO INF 範例

此範例顯示使用SYSVAD平板電腦INF檔案中的AddReg項目註冊的多模式串流效果。

此範例程式代碼來自SYSVAD音訊範例,可在 GitHub 上取得: https://github.com/Microsoft/Windows-driver-samples/tree/main/audio/sysvad

此範例說明系統效果的這種組合:

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

請注意,在範例 INF 檔案中,EFX_Streaming 屬性會被批注化,因為音訊處理已轉換為該層上方的核心模式,因此不需要串流屬性,而且不會使用。 為探索目的指定PKEY_FX_EndpointEffectClsid是有效的,但指定PKEY_EFX_ProcessingModes_Supported_For_Streaming會是錯誤。 這是因為混合/發球模式會在堆疊中降低,因此無法插入端點 APO。

元件化 APO 安裝

從 Windows 10 版本 1809 開始,APO 在向音訊引擎註冊時會使用模組化音訊驅動程式模型。 使用音訊元件化可建立更順暢且更可靠的安裝體驗,並更支援元件服務。 如需詳細資訊,請參閱 建立元件化音訊驅動程序安裝

下列範例程式代碼會從公用 ComponentizedAudioSampleExtension.inf 和 ComponentizedApoSample.inf 擷取。 請參閱 GitHub 上提供的 SYSVAD 音訊範例: https://github.com/Microsoft/Windows-driver-samples/tree/main/audio/sysvad

使用新建立的 APO 裝置,向音訊引擎註冊 APO。 若要讓音訊引擎使用新的 APO 裝置,它必須是音訊裝置的 PNP 子系,並與音訊端點同屬於一個層級。 新的元件化 APO 設計不允許 APO 全域註冊,並供多個不同驅動程式使用。 每個驅動程式都必須註冊自己的 APO。

APO 的安裝是以兩個部分完成。 首先,驅動程式擴充功能 INF 會將 APO 元件新增至系統:

[DeviceExtension_Install.Components]
AddComponent = SwapApo,,Apo_AddComponent

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

此 APO 元件會在 SYSVAD 範例中觸發第二個元件 APO INF 安裝,這會在 ComponentizedApoSample.inf 中完成。 此 INF 檔案專用於 APO 元件。 它會將元件類別指定為 AudioProcessingObject,並新增 CLSID 註冊和向音訊引擎註冊的所有 APO 屬性。

備註

INF 檔案範例顯示使用 HKR 登錄機碼支援驅動程式套件隔離。 在 Windows 11 版本 22000 之前,範例會使用 HKCR 來儲存 CLSID 註冊的永續性值,而不是 HKR。 從 Windows 10 版本 1809 開始,使用 HKR 註冊的 APO 功能已獲支援。 如需詳細資訊,請參閱 使用通用 INF 檔案

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

當此 INF 安裝元件化 APO 時,桌面系統上的「音訊處理物件」會顯示在 Windows 設備管理器中。

發行新的 APO 版本時,CLSID 的變更

發行新的 APO 版本時,通常建議更新 COM 類別 CLSID,這是一個良好的作法。 使用 GUIDGEN 之類的工具來建立新的 GUID。

從 HKCR 移至 HKR 時更新 CLSID 的需求

在從全域 COM 註冊(HKCR)轉換為裝置相對的 HKR COM 註冊時,需要變更 COM 類別 GUID。 此方法可減少新 COM 物件無法正確註冊且無法載入的可能性。

藍牙音訊範例 APO INF 範本

此範例說明系統效果的這種組合:

  • PKEY_FX_StreamEffectClsid 與 PKEY_SFX_ProcessingModes_Supported_For_Streaming

  • PKEY_FX_ModeEffectClsid PKEY_MFX_ProcessingModes_Suppoted_For_Streaming

此範例程式代碼支援藍牙免持和立體聲裝置。

; 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 音訊範例

此範例 INF 檔案說明下列系統效果組合:

  • PKEY_FX_StreamEffectClsid 與 PKEY_SFX_ProcessingModes_Supported_For_Streaming

  • PKEY_FX_ModeEffectClsid PKEY_MFX_ProcessingModes_Suppoted_For_Streaming

  • PKEY_FX_EndpointEffectClsid 沒有 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%

定義自訂 APO 和 CLSID APO INF 樣本

此範例示範如何為自定義 APO 定義您自己的 CLSID。 此範例使用 MsApoFxProxy CLSID {889C03C8-ABAD-4004-BF0A-BC7BB825E166}。 CoCreate-ing 此 GUID 會在 MsApoFxProxy.dll 中具現化類別,此類別會實作 IAudioProcessingObject 介面,並透過KSPROPSETID_AudioEffectsDiscovery屬性集查詢基礎驅動程式。

此 INF 檔案範例顯示 [BthHfAud] 區段,該區段從 wdmaudio.inf 中的 [BthHfAud.AnlgACapture.AddReg.Wave] 提取 [MsApoFxProxy.Registration],然後將 PKEY_FX_EndpointEffectClsid 註冊為 MsApoFxProxy.dll的已知 CLSID。

此 INF 檔案範例也說明如何使用這個系統效果的組合:

  • PKEY_FX_EndpointEffectClsid 沒有 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 效果註冊

此範例顯示來自 Sysvad ComponentizedApoSample.inx 的 [Apo_AddReg] 區段。 本節會向 COM 註冊交換數據流 GUID,並註冊交換數據流 APO 效果。 [Apo_CopyFiles] 區段的 DestinationDirs 為 13,它會將 swapapo.dll 複製到 Driverstore。 如需詳細資訊,請參閱 驅動程式套件隔離中的「Run From Driverstore」。

如需 INF 檔案的一般資訊,請參閱 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}"

...

APO 註冊

APO 註冊可用來支援使用加權計算動態比對端點效果的程式。 加權計算會使用下列屬性存放區。 每個音訊介面都有零個或多個 端點屬性存放區 和零個或多個 效果屬性存放區,這些存放區均透過 .inf 或在運行時註冊。 最特定的端點屬性存放區和最特定的效果屬性存放區具有最高的權數並使用。 所有其他屬性存放區都會被忽略。

具體性計算如下:

端點屬性儲存權重

  1. 具有特定 KSNODETYPE 的 FX
  2. FX 與 KSNODETYPE_ANY
  3. 具有特定 KSNODETYPE 的 MSFX 揚聲器
  4. MSFX 搭配 KSNODETYPE_ANY

特效屬性存儲了權重信息

  1. 具有特定的 KSNODETYPE 的 EP
  2. 具有KSNODETYPE_ANY的 EP
  3. 具有特定 KSNODETYPE 的 MSEP
  4. 具有 KSNODETYPE_ANY 的 MSEP

數字必須從 0 開始,並循序增加:MSEP\0、MSEP\1、...、MSEP\n 如果遺漏 EP\3,Windows 將會停止尋找 EP\n,而且不會看到 EP\4,即使存在也一樣

PKEY_FX_Association 值(適用於效果屬性存放區)或 PKEY_EP_Association(針對端點屬性存放區)會與 KSPINDESCRIPTOR 的 Category 值進行比較,此值來自訊號路徑硬體末端的 pin 製造器類別,如 Kernel Streaming 所公開。

只有Microsoft收件匣類別驅動程式(可由第三方開發人員包裝)才應該使用 MSEP 和 MSFX;所有第三方驅動程式都應該使用 EP 和 FX。

APO 節點類型相容性

以下的 INF 檔案範例說明如何將 PKEY_FX_Association 金鑰設定為與 APO 相關聯的全域唯一識別碼 (GUID)。

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

由於音訊配接器能夠支援多個輸入和輸出,因此您必須明確指出自定義 APO 相容的核心串流 (KS) 節點類型類型。 在上述 INF 檔案片段中,會顯示 APO 與 %KSNODETYPE_ANY%的 KS 節點類型相關聯。 稍後在此 INF 檔案中,KSNODETYPE_ANY定義如下:

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

KSNODETYPE_ANY的 NULL 值表示此 APO 與任何類型的 KS 節點類型相容。 例如,若要指出您的 APO 只與KSNODETYPE_SPEAKER的 KS 節點類型相容,INF 檔案會顯示 KS 節點類型和 APO 關聯,如下所示:

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

如需不同 KS 節點類型之 GUID 值的詳細資訊,請參閱 Ksmedia.h 頭檔。

APO 載入失敗疑難排解

下列資訊可協助您瞭解如何監視 APOs 的失敗情況。 您可以使用這項資訊來針對無法併入音訊圖表的 API 進行疑難解答。

音訊系統會監視 APO 傳回碼,以判斷 APO 是否成功併入圖形。 它會追蹤任何一個指定方法所傳回的 HRESULT 值,藉此監視傳回碼。 系統會針對要併入圖表的每個SFX、MFX和EFX APO維護個別的失敗計數值。

音訊系統會從下列四種方法監視傳回的 HRESULT 值。

  • CoCreateInstance

  • 是否支援輸入格式

  • 檢查是否支援輸出格式

  • LockForProcess

每次其中一個方法傳回失敗碼時,APO 的失敗計數值就會遞增。 當 APO 傳回表示已成功併入音訊圖形的程式代碼時,失敗計數會重設為零。 成功呼叫LockForProcess方法是 APO 成功整合的一個良好指示。

特別是針對 CoCreateInstance,傳回的 HRESULT 代碼可能會因為多種原因而顯示失敗。 三個主要原因如下:

  • 圖表正在執行受保護的內容,且 APO 未正確簽署。

  • APO 未註冊。

  • APO 已重新命名或遭到竄改。

此外,如果 SFX、MFX 或 EFX APO 的失敗計數值達到系統指定的限制,SFX、MFX 和 EFX APOs 會藉由將PKEY_Endpoint_Disable_SysFx登錄機碼設定為 『1』來停用。 系統指定的限制目前為 10。

Windows 音訊處理物件

建立模組化的音訊驅動程式安裝

驅動程式套件隔離