實作音訊模組通訊
音訊模組是執行相對不可部分完成函式的不同音訊處理邏輯片段。 音訊模組可能位於音訊驅動程式或音訊 DSP 中。 音訊模組範例是以 DSP 為基礎的音訊處理。
從 Windows 10 版本 1703 開始,有 API 和 DIS 都支援來自 通用 Windows 平台 (UWP) 應用程式和核心模式設備驅動器的通訊。
本主題提供在核心設備驅動器中實作音訊模組通訊的相關信息。
如需如何使用 UWP 應用程式從音訊裝置模組傳送命令和接收變更通知的資訊,請參閱 設定及查詢音訊裝置模組。
為什麼要使用音訊模組?
OEM 通常會將其系統上的設定應用程式組合在一起,讓客戶能夠控制此音訊系統的各個層面,並調整其喜好設定。 音訊子系統可以包含各種元件,例如主機音訊處理對象、硬體 DSP 處理,以及智慧型手機的特殊硬體(除了音訊編解碼器本身之外)。 在大部分情況下,這些元件是由不同的廠商所建立和銷售。 在過去,IHV 已建立自己的私人 API,彼此整合,並在個別元件之間傳送資訊。 現有的 WIN32 組態應用程式接著會利用這些私人 API。
通用 Windows 平台 (UWP)提供一組 API,可讓單一應用程式跨各種裝置執行。 UWP 也引進了新的外觀與風格,成為客戶對在 Windows 10 上執行之應用程式的期望。 這麼多 OEM 想要在 UWP 上建置其音訊設定應用程式。 不過,UWP 的核心安全性功能(AppContainer 沙盒)可防止從應用程式與音訊子系統中的其他元件進行通訊。 這會轉譯 UWP 中無法存取的組態應用程式先前使用的私人 API。
從 Windows 10 版本 1703 開始,音訊模組 UWP API 可讓設定應用程式和使用者模式元件與核心和硬體層中的模組通訊,這些模組可透過新的 KS 屬性集來探索。 音訊 IHV 和 ISV 可以撰寫應用程式和服務,這些應用程式和服務可以使用 Windows 所提供的定義完善的介面與其硬體模塊通訊。 如需音訊模組 API 的詳細資訊,請參閱 Windows.Media.Devices Namespace
音訊模組定義
這些定義是音訊模組特有的。
詞彙 | 定義 |
---|---|
音訊模組 | 執行相對不可部分完成功能的音訊處理邏輯片段。 可能位於音訊驅動程式或音訊 DSP 中。 音訊模組範例是音訊處理物件 (APO)。 |
一般音訊定義
使用音訊驅動程式時,通常會使用這些定義。
詞彙 | 定義 |
---|---|
HSA | 硬體支援應用程式 |
UWP | 通用 Windows 平台 |
APO | 音訊處理物件 |
DSP | 數位訊號處理 |
詞彙 | 定義 |
---|---|
OEM | 原始設備製造商 |
IHV | 獨立硬體廠商 |
ISV | 獨立軟體廠商 |
架構
音訊模組 會放置 Windows OS 支援的機制,以在使用者模式和核心模式音訊元件之間傳送訊息。 重要的區別在於音訊模組會標準化傳輸管線。 它不會透過該傳輸建立通訊協定,並依賴ISV和IHV來定義通訊協定。 其意圖是允許現有的第三方設計輕鬆地移轉至音訊模組,但變更很少。
此圖顯示音訊資料如何透過音訊模組 API 從使用者應用程式向向音訊驅動程式。
裝置模組和串流模組存在,視它們是從客戶端進程存取,還是使用從 AudioDG 提供給 APO 的串流模組介面在 AudioDG 中執行的 APO 來存取。 如需音訊 endgine 和音訊裝置圖形 (AudioDG) 的一般資訊,請參閱 Windows 音頻架構。
驅動程式會透過 IoReportTargetDeviceChangeAsynchronous函式通知 Windows.Media.Devices 模組變更,然後從模組 API 轉換為用戶端進程或 APO 的回呼。
音訊模組 API 可透過兩種不同的目標方法存取模組:KS 波篩選器和初始化的 KS 針腳(資料流)。 特定模組的放置和存取是實作特定的。
HSA 和其他應用程式只能存取可透過篩選句柄取得的模組。 在數據流上載入的個別 APO 是唯一能夠存取數據流目標音訊模組的物件。 如需APOs的詳細資訊,請參閱 Windows 音訊處理物件。
傳送命令
音訊模組客戶端查詢和變更參數的途徑是將命令傳送至音訊子系統核心和硬體元件中的音訊模組。 音訊模組 API 的命令結構是鬆散定義,並正規化模組探索和識別自己的方式。 不過,相關ISV和IHV必須設計及實作詳細的命令結構,以建立可傳送訊息和預期回應的通訊協定。
對音訊模組用戶端的模組通知
如果用戶端已訂閱特定模組上的通知,音訊迷你埠也可以通知和傳遞資訊給音訊模組用戶端。 傳入這些通知的資訊不是由音訊模組 API 所定義,而是由ISV和/或 IHV 定義。
啟用、停用和一般拓撲資訊
音訊模組 API 會定義如何列舉命令,並將命令傳送至模組。 不過,API 不會明確定義音訊模組用戶端如何啟用或停用特定模組。 此外,它不會建立客戶端尋找拓撲資訊的方式,也不會建立彼此相關的模組位置。 IHV 和 ISV 可以判斷是否需要此功能,並決定如何實作此功能。
建議的方法是公開全域驅動程序模組。 全域驅動程式模組會處理這些拓撲特定要求的自定義命令。
音訊模組 DIS
核心串流音訊模組屬性
KSPROPSETID_AudioModule所識別的新 KS 屬性集已針對音訊模組特定的三個屬性定義。
PortCls 迷你埠驅動程序必須直接處理每個屬性的回應,因為未提供協助程式介面。
ksmedia.h:
#define STATIC_KSPROPSETID_AudioModule \
0xc034fdb0, 0xff75, 0x47c8, 0xaa, 0x3c, 0xee, 0x46, 0x71, 0x6b, 0x50, 0xc6
DEFINE_GUIDSTRUCT("C034FDB0-FF75-47C8-AA3C-EE46716B50C6", KSPROPSETID_AudioModule);
#define KSPROPSETID_AudioModule DEFINE_GUIDNAMED(KSPROPSETID_AudioModule)
typedef enum {
KSPROPERTY_AUDIOMODULE_DESCRIPTORS = 1,
KSPROPERTY_AUDIOMODULE_COMMAND = 2,
KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID = 3,
} KSPROPERTY_AUDIOMODULE;
音訊模組描述元
支援 KSPROPERTY_AUDIOMODULE_DESCRIPTORS 屬性會將驅動程序識別為音訊模組感知。 屬性會透過篩選或釘選句柄進行查詢,並將 KSPROPERTY 當做 DeviceIoControl 呼叫的輸入緩衝區傳遞。 KSAUDIOMODULE_DESCRIPTOR已定義,以描述音訊硬體內的每個模組。 傳回這些描述元的陣列,以回應此要求
ksmedia.h:
#define AUDIOMODULE_MAX_NAME_SIZE 128
typedef struct _KSAUDIOMODULE_DESCRIPTOR
{
GUID ClassId;
ULONG InstanceId;
ULONG VersionMajor;
ULONG VersionMinor;
WCHAR Name[AUDIOMODULE_MAX_NAME_SIZE];
} KSAUDIOMODULE_DESCRIPTOR, *PKSAUDIOMODULE_DESCRIPTOR;
如需詳細資訊,請參閱 KSAUDIOMODULE_DESCRIPTOR。
音訊模組命令
支援 KSPROPERTY_AUDIOMODULE_COMMAND 屬性可讓音訊模組用戶端傳送自定義命令,以查詢和設定音訊模組上的參數。 屬性可以透過篩選或釘選句柄傳送,並將 KSAUDIOMODULE_PROPERTY 當做DeviceIoControl呼叫的輸入緩衝區傳遞。 用戶端可以選擇性地傳送與輸入緩衝區中KSAUDIOMODULE_PROPERTY相鄰的其他資訊,以傳送自定義命令。
ksmedia.h:
#define AUDIOMODULE_MAX_DATA_SIZE 64000
typedef struct _KSPAUDIOMODULE_PROPERTY
{
KSPROPERTY Property;
GUID ClassId;
ULONG InstanceId;
} KSAUDIOMODULE_PROPERTY, *PKSPAUDIOMODULE_PROPERTY;
如需詳細資訊,請參閱 KSAUDIOMODULE_PROPERTY。
音訊模組通知裝置標識碼
需要支援KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID,才能讓迷你埠發出通知訊號,並將信息傳遞至音訊模組用戶端。 此標識碼的存留期會系結至要公開且作用中至 Windows 音訊堆疊的音訊裝置存留期。 屬性可以透過篩選或釘選句柄傳送,並將 KSPROPERTY 當做 DeviceIoControl 呼叫的輸入緩衝區傳遞。
如需詳細資訊,請參閱 KSAUDIOMODULE_PROPERTY。
PortCls 協助程式 - 音訊模組通知
已新增新的埠介面,可協助驅動程式開發人員將通知傳送至音訊模組用戶端。
PortCls.h:
typedef struct _PCNOTIFICATION_BUFFER
{
UCHAR NotificationBuffer[1];
} PCNOTIFICATION_BUFFER, *PPCNOTIFICATION_BUFFER;
DECLARE_INTERFACE_(IPortClsNotifications,IUnknown)
{
DEFINE_ABSTRACT_UNKNOWN() // For IUnknown
STDMETHOD_(NTSTATUS, AllocNotificationBuffer)
( THIS_
_In_ POOL_TYPE PoolType,
_In_ USHORT NumberOfBytes,
_Out_ PPCNOTIFICATION_BUFFER* NotificationBuffer
) PURE;
STDMETHOD_(void, FreeNotificationBuffer)
( THIS_
_In_ PPCNOTIFICATION_BUFFER NotificationBuffer
) PURE;
STDMETHOD_(void, SendNotificationBuffer)
( THIS_
_In_ const GUID* NotificationId,
_In_ PPCNOTIFICATION_BUFFER NotificationBuffer
) PURE;
};
//
// Audio module notification definitions.
//
#define STATIC_KSNOTIFICATIONID_AudioModule \
0x9C2220F0, 0xD9A6, 0x4D5C, 0xA0, 0x36, 0x57, 0x38, 0x57, 0xFD, 0x50, 0xD2
DEFINE_GUIDSTRUCT("9C2220F0-D9A6-4D5C-A036-573857FD50D2", KSNOTIFICATIONID_AudioModule);
#define KSNOTIFICATIONID_AudioModule DEFINE_GUIDNAMED(KSNOTIFICATIONID_AudioModule)
typedef struct _KSAUDIOMODULE_NOTIFICATION {
union {
struct {
GUID DeviceId;
GUID ClassId;
ULONG InstanceId;
ULONG Reserved;
} ProviderId;
LONGLONG Alignment;
};
} KSAUDIOMODULE_NOTIFICATION, *PKSAUDIOMODULE_NOTIFICATION;
如需詳細資訊,請參閱
IPortClsNotifications::AllocNotificationBuffer
IPortClsNotifications::FreeNotificationBuffer
IPortClsNotifications::SendNotificationBuffer
呼叫順序
迷你埠會呼叫其埠,以建立並傳送通知。 此圖顯示一般呼叫順序。