示例:ACX/SDCA 架构、构建部署与源码解析)
示例工程【免费下载链接】Windows-driver-samplesThis repo contains driver samples prepared for use with Microsoft Visual Studio and the Windows Driver Kit (WDK). It contains both Universal Windows Driver and desktop-only driver samples.项目地址https://gitcode.com/gh_mirrors/wi/Windows-driver-samples点击查看免费下载本指南以 audio/SoundWire/Samples/SdcaVad/README.md 为骨架系统讲解 Microsoft SDCA 虚拟音频设备驱动SdcaVad示例它是 Windows 驱动开发中首个同时涵盖 ACXAudio Class eXtension音频框架与 SDCASound Device Class for Audio规范的分层驱动样例由虚拟 Codec、虚拟 DSP、虚拟 XU 三个内核驱动加一个关键词唤醒 APO、一个事件检测适配器组成。读完本文你将掌握该示例解决方案的工程结构、从 Visual Studio 编译到目标机部署测试的完整流程、以及 HLK 音频测试的已知边界并能对照仓库源码理解 ACX 复合电路Composite Circuit组合、SDCA 特殊流Special Stream创建与关键词检测KWS的底层实现。示例概览一套完整的 SDCA 音频设备分层SdcaVad 的核心目标是展示如何基于 ACX/SDCA 开发支持 SDCA 音频设备的驱动。它不依赖真实硬件而是用软件模拟出一个完整的 SDCA 音频设备栈——这也是 README 将其称为 Virtual Audio Device 的原因虚拟 Codec、虚拟 DSP 与虚拟 XU 分别扮演 SDCA 规范中的不同角色并以 ACX 电路Circuit模板的形式组合成端到端的音频通路。README 给出了各个子目录的功能定位下表为原文表格的完整继承目录说明SdcaVCodecSDCA 虚拟 Codec 驱动Virtual Codec DriverSdcaVDspSDCA 虚拟 DSP 驱动Virtual DSP DriverSdcaVXuSDCA 虚拟 XU 驱动Virtual XU DriverApo\kws示例 APO通过 KSPROPERTY_INTERLEAVEDAUDIO_FORMATINFORMATION 判断关键词点测keyword spotter引脚是否将回环loopback音频与麦克风音频交织并识别哪些声道包含回环音频若为交织则剥离回环音频仅向上游传递麦克风音频。由于声道数据被移除APO 协商出的输出格式与输入格式不同EventDetectorAdapter示例事件检测适配器Event Detector Adapter从解决方案文件 SDCAVad.sln 可以看到整个解决方案包含6 个项目SDCAVCodec、SDCAVDsp、SDCAVXu 三个驱动项目KWSApo关键词唤醒 APOEventDetectorContosoAdapter事件检测适配器以及负责打包的 package 项目与 README 中 one solution that has six projects 的描述一一对应。三种虚拟驱动在 SDCA 栈中的角色从源码结构可以清晰看出三者的分工SdcaVCodec虚拟 Codec作为根枚举设备ROOT\SDCAVCodec见 SdcaVCodec.inx加载负责建立完整的音频通路render capture并通过复合电路模板把 Codec 电路、XU 扩展电路、DSP 电路组合在一起。device.cpp 中定义了 Render/Capture 两组电路元数据扬声器电路DSP_CIRCUIT_SPEAKER_GUID、麦克风电路DSP_CIRCUIT_MICROPHONE_GUID、DSP 工厂 URIacpi:obj-path:\_SB.PC00.HDAS以及厂商 blobStreaming_Speaker/Streaming_MicrophoneArray。SdcaVDsp虚拟 DSP以SOUNDWIRETEST\DSP硬件 ID 加载见 SdcaVDsp.inx并且是 README 所述可动态枚举子设备的一端——其 INF 同时把扬声器/麦克风作为子设备{4DCB0606-...}\Render、{4DCB0606-...}\Capture枚举。它负责流引擎streamengine.h与关键词检测KeywordDetector.cpp。SdcaVXu虚拟 XU以ClassExtension、ExtensionId{790C1DE0-AA33-4CB8-BB0C-F523C73B4AA1}的扩展驱动形式安装见 SdcaVXu.inx作为 SDCAVCodec 的 LowerFilter 挂载AddFilterSDCAVXu其 PDO 由 Codec 驱动枚举出来模拟 SDCA 规范中的 XUeXchange Unit实体。从 device.cpp 的Codec_AddComposites可以看到三个电路模板的组装顺序先创建 Codec 电路模板对应 Codec URI若检测到 XUdevCtx-SdcaXuData.bSdcaXu则追加 XU 扩展电路模板最后追加 DSP 电路模板带AcxCircuitTemplateCircuitOnDemand标志即按需实例化的 DSP 电路随后调用AcxCompositeTemplateAssignCircuits把三块电路绑定进复合电路并通过AcxCompositeTemplateSetCoreCircuit将 Codec 电路指定为核心电路。这正是 ACX 框架下多驱动协作组成单一音频端点的标准范式也是本样例最值得研读的架构点。构建示例从打开解决方案到拿到驱动包如果只是编译该示例驱动、不打算运行或测试则不需要目标计算机测试计算机若要部署、运行和测试则需要第二台计算机作为目标机。README 对构建流程给出了四个步骤以下完整继承并补充细节。1. 在 Visual Studio 中打开驱动解决方案打开 Microsoft Visual Studio点击文件打开项目/解决方案…导航到包含示例文件的目录例如C:\Windows-driver-samples\audio\SdcaVad双击sdcavad解决方案文件仓库中对应 SDCAVad.sln。若 Solution Explorer 未显示从视图菜单打开它——可以看到一个解决方案、六个项目三个驱动、一个 APO、一个适配器、一个打包项目。2. 设置示例的配置与平台在 Solution Explorer 中右键Solution sdcavad (6 of 6 projects)选择Configuration Manager。确保六个项目的配置和平台设置一致全部设为Debug配置、x64平台。如果只改动其中某个项目的配置或平台必须为其余所有项目做相同修改否则打包环节会因架构混用而失败。3. 使用 Visual Studio 构建在 Visual Studio 中点击生成生成解决方案。构建成功后SDCAVCodec / SDCAVDsp / SDCAVXu 三个驱动会被编译为.sysKWS APO 与事件检测适配器被编译为.dll并统一收进 package 项目生成的驱动包目录。4. 定位生成的驱动包在文件资源管理器中进入示例目录。驱动包的存放位置取决于 Configuration Manager 中选择的配置与平台例如选择Debug与x64时包位于x64\Debug\package文件夹。README 给出了包的完整文件清单逐项继承如下文件说明SdcaVCodec.sysSDCA 虚拟 Codec 驱动文件SdcaVCodec.inf安装 SDCA 虚拟 Codec 驱动所需的信息INF文件SdcaVDsp.sysSDCA 虚拟 DSP 驱动文件SdcaVDsp.inf安装 SDCA 虚拟 DSP 驱动的信息INF文件SdcaVXu.sysSDCA 虚拟 XU 驱动文件SdcaVXu.inf安装 SDCA 虚拟 XU 驱动的信息INF文件EventDetectorContosoAdapter.dll示例事件检测适配器SdcaVKwsApo.dllKWS关键词唤醒APOSdcaVApo.inf安装 APO 设备的信息INF文件sdcavad.cat已签名目录文件作为整个包的签名构建相关源码速览在构建层面三个驱动都遵循标准的 WDF ACX 初始化模板。以 SdcaVCodec/driver.cpp 的DriverEntry为例先通过WdfDriverCreate创建 WDF 驱动对象并注册Codec_DriverUnload使用WppRecorderLogCreate创建 WPP Recorder 日志日志标识SDCAVCodec调用AcxDriverInitialize完成 ACX 框架初始化用AcxDriverIsVersionAvailable校验 ACX 库版本要求版本 1.0 可用并调用Test_ClientVersionHigherThanFramework演示如何用ACX_IS_FIELD_AVAILABLE宏判断较新的框架字段如ACX_DEVICEINIT_CONFIG.SynchronizationScope是否可用——这是编写同时兼容新旧 ACX 库的驱动时的实用技巧。运行示例目标机准备、安装与验证安装驱动的机器称为目标计算机target / test computer编译驱动包的机器称为主机host computer。将驱动包移动到目标机并安装的过程称为部署deployingSdcaVad 支持自动部署与手动部署两种方式。准备目标计算机目标机需先安装最新版 Windows Driver KitWDK最低版本要求为25926对应 Canary 频道这是 README 明确标注的硬性版本门槛低于该版本将无法编译/加载依赖新 ACX 接口的组件。手动部署前必须通过以下方式准备目标机开启测试签名、安装证书、定位 WDK 中的 DevCon 工具。以管理员身份打开命令提示符输入以下命令开启测试签名bcdedit /set TESTSIGNING ON然后重启目标机。[!IMPORTANT] 在使用 BCDEdit 修改启动信息之前可能需要临时挂起 BitLocker 和 Secure Boot 等 Windows 安全功能。测试完成后应重新启用这些安全功能并妥善管理处于安全功能关闭状态下的测试机。重启后进入 WDK 安装目录下的 Tools 文件夹定位 DevCon 工具例如C:\Program Files (x86)\Windows Kits\10\Tools\x64\devcon.exe将devcon.exe复制到目标机上一个容易找到的目录例如创建C:\Tools并复制进去。然后在目标机创建驱动包目录如C:\SdcaVad把主机上构建出的驱动包中所有文件复制过去。为构建过程生成的证书单独建一个目录如C:\Certificates把主机上与package文件夹同级的package.cer复制过去在目标机上右键证书文件 →安装按提示安装测试证书。若需要更详细的手动部署准备步骤README 指向了 Preparing a Computer for Manual Driver Deployment 文档。关于签名的说明由于这些二进制大部分在内核模式下执行签名可选地接入内核调试器至关重要无任何签名且未接内核调试器时驱动无法安装到目标机接入内核调试器时驱动可以安装.sys文件会被加载但用户态.dll文件不会被加载要让整个示例.sys、.dll、.cat全部加载执行唯一的方式是全部文件由可信证书签名——这样即使没有内核调试器整个驱动也能被加载。这也是 SdcaVad 的package项目默认输出sdcavad.cat已签名目录文件的原因。安装驱动单 INF 文件方式每个示例驱动各自带一个 INF 文件用于安装对应驱动。在目标机上以管理员身份打开命令提示符进入驱动包目录后依次执行devcon install SdcaVDsp.inf SOUNDWIRETEST\DSP devcon install SdcaVCodec.inf Root\SDCAVCodec随后安装 XU 的 INFSdcaVXu.inf与 APO 的 INFSdcaVApo.inf——右键 INF 文件并选择安装即可这两者采用右键安装方式而非 devcon。值得注意的安装顺序与层次devcon install SdcaVDsp.inf SOUNDWIRETEST\DSP先让 DSP 驱动以测试硬件 ID 加载devcon install SdcaVCodec.inf Root\SDCAVCodec再让 Codec 驱动以根枚举方式出现而 XU 作为 Codec 的 LowerFilterSdcaVXu.inx 中的AddFilterSDCAVXu与 DSP 的动态枚举子设备则由驱动的 PnP 回调自动建立。驱动安装成功后即可开始测试。测试驱动在目标机命令提示符输入devmgmt.msc打开设备管理器在查看菜单选择按类型列出设备在设备树中找到SDCA Virtual Dsp Audio Driver通常位于声音、视频和游戏控制器节点下。打开控制面板 →硬件和声音→管理音频设备在声音对话框中选择标签为SDCA Virtual Codec Audio Driver的扬声器图标点击设为默认但不要点击确定保持对话框打开。然后双击目标机上的 MP3 或其他音频文件播放回到声音对话框确认SDCA Virtual Codec Audio Driver对应的音量指示条有活动。HLK 测试与已知边界该示例使用最新可用版本的 HLK 测试以确保通过当前 playlist 中的全部音频测试。但由于它是虚拟音频驱动未实现混音mixing并用生成的正弦音tone模拟采集与回环因此存在部分依赖上述真实功能的 HLK 测试预期失败。README 明确列举了两类例外Hardware Offload of Audio Processing Test该测试面向支持 offload 能力的设备。对 SdcaVad 而言带 offload 和 loopback 的端点会失败——offload 端点失败是因为驱动包含 offload 引脚但未实现带音量、静音、峰值表等节点的混音器loopback 端点失败是因为驱动用正弦音模拟回环而不是真正混合 host/offload 引脚上的流。当前版本还未通过 General Audio Test 与 Device Power State Transition Test官方正在调查失败原因。源码侧与这两条边界直接相关的实现证据streamengine.h 中定义DEFAULT_FREQUENCY (220)与LOOPBACK_FREQUENCY (500)配合 ToneGenerator.h 的正弦波生成器印证了 README用 tone 模拟 capture 和 loopback的描述KeywordDetector.cpp 的 DPC 例程也以RtlZeroMemory填充采样TODO 注释建议未来可接入 ToneGenerator再次说明该虚拟设备不执行真实的音频信号处理。深入源码两条值得重点研读的实现链路链路一SDCA 特殊流Special Stream的创建与启停circuitstream.cpp 展示了 DSP 驱动如何通过 SDCA 属性集KSPROPERTYSETID_Sdca向下游 Codec 电路下发特殊流路径控制Dsp_PrepareSpecialStreamForStream在 host/offload 引脚准备硬件时启动IV SenseSpecialStreamTypeIvSense流在 loopback 引脚上启动Reference StreamSpecialStreamTypeReferenceStream流。优先使用KSPROPERTY_SDCA_CREATE_PATH2携带完整 path descriptor2否则复制下游返回的SDCA_PATH_DESCRIPTORS按FunctionBitMask过滤音频功能、将格式收敛到 48 kHz 单一格式、数据端口收敛到 1再以KSPROPERTY_SDCA_CREATE_PATH下发circuitstream.cppDsp_StartSpecialStreamsForStream/Dsp_StopSpecialStreamsForStream/Dsp_ReleaseSpecialStreamsForStream分别以KSPROPERTY_SDCA_START_PATH、KSPROPERTY_SDCA_STOP_PATH、KSPROPERTY_SDCA_DESTROY_PATH控制路径并通过电路上下文中的InterlockedIncrement/Decrement引用计数保证多个流共享同一条特殊流硬件时只在最后一个使用者退出时才销毁路径。这段代码是理解ACX 多电路协作下DSP 通过属性请求驱动 Codec 侧真实硬件通路的极佳范本也是 SDCA 规范中 Sense/Reference stream 机制在驱动层的完整落地。链路二关键词检测KWS与事件检测适配器的协作KWS 链路横跨内核DSP 驱动与用户态APO 适配器两层内核侧KeywordDetector.cpp 定义了三态机——Disarmed解除武装、Armed Suspended武装但挂起即 Codec 驱动需要访问硬件导致的失聪期、Armed Prepared武装且已准备正在检测。状态迁移通过KSPROPERTY_SDCAKWS_CONFIGURE_VAD_PORT/KSPROPERTY_SDCAKWS_CLEANUP_VAD_PORT配置 VAD 流并通过KSPROPERTY_SDCAKWS_ACCESS_EVENTS注册 Suspend/Resume 通知事件KeywordDetector.cpp。检测数据的包缓冲packet fifo、QPC 时间戳对齐、关键词起止时间戳均在此实现其中起止时间戳还可通过注册表KeywordDetectorStartTimestamp/KeywordDetectorStopTimestampREG_QWORD读取KeywordDetector.cpp。用户态侧EventDetectorContosoAdapter.cpp 实现IEventDetectorOemAdapterGetCapabilities声明 16 kHz 单声道 PCM{WAVE_FORMAT_PCM, 1, 16000, 32000, 2, 16, 0}、语言 0x0409en-US、无用户录音GetCapabilitiesForLanguage上报两个检测事件CONTOSO_KEYWORD1 / CONTOSO_KEYWORD2GUID 定义见 Inc/ContosoEventDetector.hBuildArmingPatternData生成CONTOSO_KEYWORDCONFIGURATION模式数据ParseDetectionResultData解析CONTOSO_KEYWORDDETECTIONRESULT并回填事件起止时间戳。适配器的 CLSID{207F3D0C-5C79-496F-A94C-D3D2934DBFA9}由 SdcaVDsp.inx 注册进HKCR\CLSIDREADME 也提示驱动开发者应将该 CLSID 替换为自己的关键词检测 OEM 适配器。结合 INF 理解端点枚举与 APO 挂载三个 INF 共同刻画了虚拟设备的端点拓扑SdcaVCodec.inx 以AddInterface注册Speaker0KSCATEGORY_AUDIO KSCATEGORY_TOPOLOGY与Microphone0并对端点写入了PKEY_AudioEndpoint_Supports_EventDriven_Mode1等属性显式选择拉模式pull modeSdcaVDsp.inx 则同时注册 KSCATEGORY_RENDER / KSCATEGORY_CAPTURE / KSCATEGORY_REALTIME 接口其中 render 端点的 capture 接口被注释掉用作 loopback 说明并把事件检测适配器 DLL 一并复制到系统目录APO 的挂载由 SdcaVApo.inf 完成位于包内源码目录中未见单独 INX 源文件它安装一个 APO 设备把SdcaVKwsApo.dll与 Codec 的麦克风端点关联。而 KWS APO 的核心处理逻辑在 Apo/kws/KWSApo.cpp 的ProcessBuffer中一目了然依据INTERLEAVED_AUDIO_FORMAT_INFORMATIONPrimaryChannelStartPosition/PrimaryChannelCount/InterleavedChannelCount只把主声道麦克风数据拷贝到输出跳过交织的回环声道配合 KWSApoEfx.cpp 中Initialize通过IKsControl-KsProperty查询KSPROPERTY_INTERLEAVEDAUDIO_FORMATINFORMATION以及IsOutputFormatSupported把输出声道数收敛为PrimaryChannelCount——这就是 README 所述APO 协商出与输入不同的输出格式的源码级证据。小结SdcaVad 是一个覆盖 ACX 驱动开发全链路的样例构建6 项目解决方案、Debug/x64 打包、部署WDK 25926、测试签名、DevCon 单 INF 安装、验证设备管理器 声音面板、HLK 测试已知的 offload/loopback 例外与待调查失败项。深入源码还可获得两条进阶主线复合电路模板Codec XU DSP的组合机制与SDCA 特殊流 / 关键词检测的分层协作。对于准备开发真实 SDCA Codec、DSP 或关键词唤醒KWS驱动的开发者这是一个可以直接作为起点并对照移植的参考实现。赞分享示例工程【免费下载链接】Windows-driver-samplesThis repo contains driver samples prepared for use with Microsoft Visual Studio and the Windows Driver Kit (WDK). It contains both Universal Windows Driver and desktop-only driver samples.项目地址https://gitcode.com/gh_mirrors/wi/Windows-driver-samples点击查看免费下载相关推荐SysVAD 虚拟音频设备驱动示例详解基于 WaveRT 与音频卸载的 WDM 音频驱动框架Windows-driver-samplesSysVAD 虚拟音频设备驱动示例详解基于 WaveRT 与音频卸载的 WDM 音频驱动框架Windows driver samples 本指南以 Mic示例工程Windows 驱动开发实战SimpleAudioSample 虚拟音频设备驱动详解构建、部署与架构剖析Windows 驱动开发实战SimpleAudioSample 虚拟音频设备驱动详解构建、部署与架构剖析 导读 本文围绕 Windows driver s示例工程Windows-driver-samples 中的 NDIS 虚拟微型端口驱动示例 netvmini 深度解析Windows driver samples 中的 NDIS 虚拟微型端口驱动示例 netvmini 深度解析 本指南围绕 Windows driver sam示例工程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考