Glad it’s working :-) From: wdmaudiodev-bounce@xxxxxxxxxxxxx [mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of Justin Davis Sent: Friday, March 6, 2015 10:44 AM To: wdmaudiodev@xxxxxxxxxxxxx Subject: [wdmaudiodev] Re: Help installing custom sAPO for a USB audio device Wow, that was exactly the problem! I changed my INF to use the "GLOBAL" name and my sAPO is now getting loaded (and APOProcess() is being called)! Thank you so much for your help and explanations Matthew! You have made my day :) -Justin On Fri, Mar 6, 2015 at 9:43 AM, Matthew van Eerde <Matthew.van.Eerde@xxxxxxxxxxxxx<mailto:Matthew.van.Eerde@xxxxxxxxxxxxx>> wrote: This is the problem. AddInterface=%KSCATEGORY_AUDIO%,%KSNAME_TopologyMicIn%, TestAudio.SysFx.PrimaryMicTopo Compare: ; wdma_usb.inf AddInterface=%KSCATEGORY_AUDIO%,"GLOBAL",USBAudio.Interface.Curve, The second argument to AddInterface needs to match the name of the Kernel Streaming filter factory where the hardware-connected pin factory is. For a portcls.sys miniport, the filter factories come in pairs – a “wave” filter factory, and a “topology” filter factory. On the other hand, direct AVStream drivers like usbaudio.sys, which don’t go through portcls, have the freedom to put as many filter factories in the signal path as it likes – one, or two, or more. usbaudio.sys happens to choose to expose a single filter factory that contains both the hardware-connected pin factory and the streaming pin factory; it calls this “GLOBAL”. So usbaudio.sys doesn’t have a notion of “wave” or “topology” filter factories. You can use KS Studio to see the name of the filter factory directly and confirm that is it “GLOBAL”. The EP\ and FX\ properties are not being picked up because the filter factory name doesn’t match. The MSEP\ and MSFX\ properties are being looked at, but ignored, because they all have specific PKEY_FX_ASSOCIATION values which don’t match KSNODETYPE_MICROPHONE – usbaudio.sys’s inbox effects only apply to playback devices like speakers and headphones. From: wdmaudiodev-bounce@xxxxxxxxxxxxx<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> [mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>] On Behalf Of Justin Davis Sent: Friday, March 6, 2015 9:27 AM To: wdmaudiodev@xxxxxxxxxxxxx<mailto:wdmaudiodev@xxxxxxxxxxxxx> Subject: [wdmaudiodev] Re: Help installing custom sAPO for a USB audio device Hi Matthew, Thanks for your help so far. I've implemented the changes you suggested (not using RegisterDlls and removing the MFX key). I believe the correct type is KSNODETYPE_MICROPHONE. This is a really simple USB microphone. When I look at the USB descriptors, under the audio control input terminal descriptor, it lists: wTerminalType : 0x0201 (Microphone) According to the page below, it sounds like this corresponds to KSNODETYPE_MICROPHONE. https://msdn.microsoft.com/en-us/library/windows/hardware/ff537742%28v=vs.85%29.aspx My registry keys are making it to HKLM/SYSTEM/ccs/Control/DeviceClasses/{Audio Class GUID}/{device entry}/#TopologyMicIn/Device Parameters/FX/0. But there's also the "#GLOBAL" one in there as well. Maybe the #GLOBAL thing is messing this up? However, the effects listed under #GLOBAL don't seem to be running either. Here's what the HKLM/SYSTEM/ccs/Control/DeviceClasses/{Audio Class GUID}/{device entry}/ key looks like: [Inline image 1] And here's the device entry under HKLM/SOFTWARE/Microsoft/Windows/CurrentVersion/MMDevices/Audio/Capture: [Inline image 2] (Notice that there's no "FxProperties" key) Here's my slightly updated INF file. [Version] Signature="$Windows NT$" Class=MEDIA ClassGUID={4d36e96c-e325-11ce-bfc1-08002be10318} provider=%ProviderName% DriverVer=06/22/2005,6.00.2246.1 [SourceDisksNames] 222=%DiskDescription%,,, [SourceDisksFiles] SwapAPO.dll=222 [DestinationDirs] SfxFx.CopyList=11 ; %windir%\system32 [Manufacturer] %MfgName%=MfgModelSection, NT$ARCH$ [MfgModelSection.NT$ARCH$] %TestMic.DeviceDesc%=TestAudio.SysFx,USB\VID_0C76&PID_1529&MI_00 [TestAudio.SysFx] Include = ks.inf, wdmaudio.inf, wdma_usb.inf Needs = KS.Registration, WDMAUDIO.Registration, USBAudioOEM.CopyFiles, USBAudioOEM.AddReg CopyFiles=SfxFx.CopyList AddReg = SfxFx.COM.AddReg [TestAudio.SysFx.HW] ; Do I need anything here? wdma_usb.inf doesn't seem to have a .HW section [TestAudio.SysFx.Interfaces] AddInterface=%KSCATEGORY_AUDIO%,%KSNAME_WaveMicIn%, TestAudio.SysFx.PrimaryMicWave AddInterface=%KSCATEGORY_REALTIME%,%KSNAME_WaveMicIn%, TestAudio.SysFx.PrimaryMicWave AddInterface=%KSCATEGORY_CAPTURE%,%KSNAME_WaveMicIn%, TestAudio.SysFx.PrimaryMicWave AddInterface=%KSCATEGORY_AUDIO%,%KSNAME_TopologyMicIn%, TestAudio.SysFx.PrimaryMicTopo AddInterface=%KSCATEGORY_TOPOLOGY%,%KSNAME_TopologyMicIn%, TestAudio.SysFx.PrimaryMicTopo [TestAudio.SysFx.PrimaryMicWave] AddReg = TestAudio.SysFx.PrimaryMicWave.AddReg [TestAudio.SysFx.PrimaryMicWave.AddReg] HKR,,FriendlyName,,%PrimaryMicWaveDeviceName% HKR,,CLSID,,%Proxy.CLSID% [TestAudio.SysFx.PrimaryMicTopo] AddReg = TestAudio.PrimaryMicTopo.AddReg, SysFx.AddReg [TestAudio.PrimaryMicTopo.AddReg] HKR,,FriendlyName,,%PrimaryMicTopoDeviceName% HKR,,CLSID,,%Proxy.CLSID% [TestAudio.SysFx.Services] Include = wdma_usb.inf Needs = USBAudio.NT.Services [SfxFx.COM.AddReg] ;; sAPO COM registration HKCR,CLSID\%SYSFX_PREMIX_CLSID%,,,%SYSFX_FriendlyName% HKCR,CLSID\%SYSFX_PREMIX_CLSID%\InProcServer32,,,%11%\swapapo.dll HKCR,CLSID\%SYSFX_PREMIX_CLSID%\InProcServer32,ThreadingModel,,"Both" [SysFx.AddReg] ;; Not exactly sure what this does, but wdma_usb.inf does it... HKR,"EP\\0",%PKEY_AudioEndpoint_Association%,,%KSNODETYPE_ANY% HKR,"FX\\0",%PKEY_ItemNameDisplay%,,%SYSFX_FriendlyName% HKR,"FX\\0",%PKEY_SYSFX_PreMixClsid%,,%SYSFX_PREMIX_CLSID% ;; Note: We have to associate with a specific node type here (ie. not ;; use KSNODETYPE_ANY) or else the MSFX entries in wdma_usb.inf will ;; override our entries here. HKR,"FX\\0",%PKEY_SYSFX_Association%,,%KSNODETYPE_MICROPHONE% ;; I think Win 8.l uses StreamEffectsClsid instead of PreMixClsid HKR,"FX\\0",%PKEY_SYSFX_StreamEffectClsid%,,%SYSFX_PREMIX_CLSID% HKR,"FX\\0",%PKEY_SFX_ProcessingModes_Supported_For_Streaming%,0x00010000,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT% [SfxFx.CopyList] SwapAPO.dll,,,0x0100 [Strings] ProviderName="Test Provider Name" MfgName="Test MFG Name" DiskDescription="Installation Media" TestMic.DeviceDesc = "Test Microphone with Basic Filtering" KSNAME_WaveMicIn = "WaveMicIn" KSNAME_TopologyMicIn = "TopologyMicIn" PrimaryMicWaveDeviceName = "Test Microphone" PrimaryMicTopoDeviceName = "Test Microphone Topo" PKEY_SYSFX_Association = "{D04E05A6-594B-4FB6-A80D-01AF5EED7D1D},0" PKEY_SYSFX_PreMixClsid = "{D04E05A6-594B-4FB6-A80D-01AF5EED7D1D},1" PKEY_ItemNameDisplay = "{B725F130-47EF-101A-A5F1-02608C9EEBAC},10" PKEY_SYSFX_StreamEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},5" SYSFX_PREMIX_CLSID = "{B48DEA3F-D962-425a-8D9A-9A5BB37A9904}" SYSFX_FriendlyName = "Test Microphone Filter Effect" KSCATEGORY_AUDIO = "{6994AD04-93EF-11D0-A3CC-00A0C9223196}" KSCATEGORY_CAPTURE = "{65E8773D-8F56-11D0-A3B9-00A0C9223196}" KSCATEGORY_REALTIME = "{EB115FFC-10C8-4964-831D-6DCB02E6F23F}" KSCATEGORY_TOPOLOGY = "{DDA54A40-1E4C-11D1-A050-405705C10000}" KSNODETYPE_ANY = "{00000000-0000-0000-0000-000000000000}" KSNODETYPE_MICROPHONE = "{DFF21BE1-F70F-11D0-B917-00A0C9223196}" Proxy.CLSID = "{17CCA71B-ECD7-11D0-B908-00A0C9223196}" PKEY_SFX_ProcessingModes_Supported_For_Streaming = "{D3993A3F-99C2-4402-B5EC-A92A0367664B},5" AUDIO_SIGNALPROCESSINGMODE_DEFAULT = "{C18E2F7E-933D-4965-B7D1-1EEF228D2AF3}" PKEY_AudioEndpoint_Association = "{1DA5D803-D492-4EDD-8C23-E0C0FFEE7F0E},2" Thanks, Justin On Thu, Mar 5, 2015 at 4:38 PM, Matthew van Eerde <Matthew.van.Eerde@xxxxxxxxxxxxx<mailto:Matthew.van.Eerde@xxxxxxxxxxxxx>> wrote: > RegisterDlls Don’t use RegisterDlls; instead, declare all your COM registrations statically via AddReg. > My understanding is that these are migrated to the > MMDevices/Audio/Capture/{EP Guid} key...but they don't seem to be Did you confirm that the jack sub type of this particular device is KSNODETYPE_MICROPHONE? > HKR,"FX\\0",%PKEY_MFX_ProcessingModes_Supported_For_Streaming%,0x00010000,%AUDIO_SIGNALPROCESSINGMODE_DEFAULT% Since you only have a stream effect, you should only set the _SFX_ streaming property. Remove the _MFX_ one. HKLM/SYSTEM/ccs/Control/DeviceClasses/{Audio Class GUID}/{device entry}/#GLOBAL/Device Parameters/MSFX What about Device Parameters/FX/0? Are your properties getting this far? From: wdmaudiodev-bounce@xxxxxxxxxxxxx<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> [mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>] On Behalf Of Justin Davis Sent: Thursday, March 5, 2015 4:26 PM To: wdmaudiodev@xxxxxxxxxxxxx<mailto:wdmaudiodev@xxxxxxxxxxxxx> Subject: [wdmaudiodev] Re: Help installing custom sAPO for a USB audio device Ok, So I've had a chance to try this, and so far I'm still not having luck getting my sAPO loaded. Here are a few observations I've made. - When using the inbox usbaudio driver for my microphone (just trying to learn more about how this works), I see sAPO effects registered under HKLM/SYSTEM/ccs/Control/DeviceClasses/{Audio Class GUID}/{device entry}/#GLOBAL/Device Parameters/MSFX. My understanding is that these are migrated to the MMDevices/Audio/Capture/{EP Guid} key...but they don't seem to be. Consequently the effects registered for the microphone by default (looks like they're in wmalfxgfxdsp.dll) are not loaded. Are these disabled by default maybe? - Regardless, I tried changing my .inf file to use KSNODETYPE_MICROPHONE instead of KSNODETYPE_ANY, and that didn't seem to have an effect (keys not migrated to MMDevices, sAPO dll not loaded by audiodg process). Here's the .inf file I'm using. I have a feeling there's probably something else basic that I'm missing. Thank you so much for your help! -Justin ======== [Version] Signature="$Windows NT$" Class=MEDIA ClassGUID={4d36e96c-e325-11ce-bfc1-08002be10318} provider=%ProviderName% DriverVer=06/22/2005,6.00.2246.1 [SourceDisksNames] 222=%DiskDescription%,,, [SourceDisksFiles] SwapAPO.dll=222 [DestinationDirs] SfxFx.CopyList=11 ; %windir%\system32 [Manufacturer] %MfgName%=MfgModelSection, NT$ARCH$ [MfgModelSection.NT$ARCH$] %TestMic.DeviceDesc%=TestAudio.SysFx,USB\VID_0C76&PID_1529&MI_00 [TestAudio.SysFx] Include = ks.inf, wdmaudio.inf, wdma_usb.inf Needs = KS.Registration, WDMAUDIO.Registration, USBAudioOEM.CopyFiles, USBAudioOEM.AddReg CopyFiles=SfxFx.CopyList RegisterDlls=SfxFx.RegisterDlls [TestAudio.SysFx.HW] ; Do I need anything here? wdma_usb.inf doesn't seem to have a .HW section [TestAudio.SysFx.Interfaces] AddInterface=%KSCATEGORY_AUDIO%,%KSNAME_WaveMicIn%, TestAudio.SysFx.PrimaryMicWave AddInterface=%KSCATEGORY_REALTIME%,%KSNAME_WaveMicIn%, TestAudio.SysFx.PrimaryMicWave AddInterface=%KSCATEGORY_CAPTURE%,%KSNAME_WaveMicIn%, TestAudio.SysFx.PrimaryMicWave AddInterface=%KSCATEGORY_AUDIO%,%KSNAME_TopologyMicIn%, TestAudio.SysFx.PrimaryMicTopo AddInterface=%KSCATEGORY_TOPOLOGY%,%KSNAME_TopologyMicIn%, TestAudio.SysFx.PrimaryMicTopo [TestAudio.SysFx.PrimaryMicWave] AddReg = TestAudio.SysFx.PrimaryMicWave.AddReg [TestAudio.SysFx.PrimaryMicWave.AddReg] HKR,,FriendlyName,,%PrimaryMicWaveDeviceName% HKR,,CLSID,,%Proxy.CLSID% [TestAudio.SysFx.PrimaryMicTopo] AddReg = TestAudio.PrimaryMicTopo.AddReg, SysFx.AddReg [TestAudio.PrimaryMicTopo.AddReg] HKR,,FriendlyName,,%PrimaryMicTopoDeviceName% HKR,,CLSID,,%Proxy.CLSID% [TestAudio.SysFx.Services] Include = wdma_usb.inf Needs = USBAudio.NT.Services [SysFx.AddReg] ;; Not exactly sure what this does, but wdma_usb.inf does it... HKR,"EP\\0",%PKEY_AudioEndpoint_Association%,,%KSNODETYPE_ANY% HKR,"FX\\0",%PKEY_ItemNameDisplay%,,%SYSFX_FriendlyName% HKR,"FX\\0",%PKEY_SYSFX_PreMixClsid%,,%SYSFX_PREMIX_CLSID% ;; Note: We have to associate with a specific node type here (ie. not ;; use KSNODETYPE_ANY) or else the MSFX entries in wdma_usb.inf will ;; override our entries here. HKR,"FX\\0",%PKEY_SYSFX_Association%,,%KSNODETYPE_MICROPHONE% ;; I think Win 8.l uses StreamEffectsClsid instead of PreMixClsid HKR,"FX\\0",%PKEY_SYSFX_StreamEffectClsid%,,%SYSFX_PREMIX_CLSID% 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% [SfxFx.CopyList] SwapAPO.dll,,,0x0100 [SfxFx.RegisterDlls] 11,,SwapAPO.dll,1 [Strings] ProviderName="Test Provider Name" MfgName="Test MFG Name" DiskDescription="Installation Media" TestMic.DeviceDesc = "Test Microphone with Basic Filtering" KSNAME_WaveMicIn = "WaveMicIn" KSNAME_TopologyMicIn = "TopologyMicIn" PrimaryMicWaveDeviceName = "Test Microphone" PrimaryMicTopoDeviceName = "Test Microphone Topo" PKEY_SYSFX_Association = "{D04E05A6-594B-4FB6-A80D-01AF5EED7D1D},0" PKEY_SYSFX_PreMixClsid = "{D04E05A6-594B-4FB6-A80D-01AF5EED7D1D},1" PKEY_ItemNameDisplay = "{B725F130-47EF-101A-A5F1-02608C9EEBAC},10" PKEY_SYSFX_StreamEffectClsid = "{D04E05A6-594B-4fb6-A80D-01AF5EED7D1D},5" SYSFX_PREMIX_CLSID = "{B48DEA3F-D962-425a-8D9A-9A5BB37A9904}" SYSFX_FriendlyName = "Test Microphone Filter Effect" KSCATEGORY_AUDIO = "{6994AD04-93EF-11D0-A3CC-00A0C9223196}" KSCATEGORY_CAPTURE = "{65E8773D-8F56-11D0-A3B9-00A0C9223196}" KSCATEGORY_REALTIME = "{EB115FFC-10C8-4964-831D-6DCB02E6F23F}" KSCATEGORY_TOPOLOGY = "{DDA54A40-1E4C-11D1-A050-405705C10000}" KSNODETYPE_ANY = "{00000000-0000-0000-0000-000000000000}" KSNODETYPE_MICROPHONE = "{DFF21BE1-F70F-11D0-B917-00A0C9223196}" Proxy.CLSID = "{17CCA71B-ECD7-11D0-B908-00A0C9223196}" 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}" PKEY_AudioEndpoint_Association = "{1DA5D803-D492-4EDD-8C23-E0C0FFEE7F0E},2" On Mon, Mar 2, 2015 at 9:45 AM, Justin Davis <justindvs@xxxxxxxxx<mailto:justindvs@xxxxxxxxx>> wrote: Thank you so much for the explanation Matthew! That makes sense (I was using KSNODETYPE_ANY). I'll give the specific category a try and report back. Thanks, Justin On Mon, Mar 2, 2015 at 9:36 AM, Matthew van Eerde <Matthew.van.Eerde@xxxxxxxxxxxxx<mailto:Matthew.van.Eerde@xxxxxxxxxxxxx>> wrote: Here’s how effects property registration works, in general. Before registering the KSCATEGORY_AUDIO device interface, set your desired properties with any of the following prefixes: 1. MSFX\n with PKEY_FX_Assocation = KSNODETYPE_ANY, or 2. FX\n with PKEY_FX_Assocation = KSNODETYPE_ANY, or 3. MSFX\n with PKEY_FX_Association = KSPIN_DESCRIPTOR.Category where the pin descriptor is for the pin factory on the hardware end of the signal path, or 4. FX\n with PKEY_FX_Association = KSPIN_DESCRIPTOR.Category where the pin descriptor is for the pin factory on the hardware end of the signal path Stores higher up in the list are overridden by stores lower down in the list. Only Microsoft inbox drivers should use MSFX\n. This allows third-party drivers to use FX\n and override them. You should use FX\n. wdma_usb.inf uses PKEY_FX_Association = KSPIN_DESCRIPTOR.Category: ; wdma_usb.inf HKR,"MSFX\\0",%PKEY_FX_Association%,,%KSNODETYPE_SPEAKER% HKR,"MSFX\\1",%PKEY_FX_Association%,,%KSNODETYPE_HEADPHONES% HKR,"MSFX\\2",%PKEY_FX_Association%,,%KSNODETYPE_DESKTOP_SPEAKER% HKR,"MSFX\\3",%PKEY_FX_Association%,,%KSNODETYPE_HEADSET_SPEAKERS% So you will need to use FX\0 with a PKEY_FX_Association = KSPIN_DESCRIPTOR.Category yourself, or be overridden by the more specific MSFX\n match. > I'm pretty sure those keys need to be installed as part of an "AddInterface" > statement That’s correct; they should be under the “.AddReg” section from an AddInterface=… KSCATEGORY_AUDIO … interface. From: wdmaudiodev-bounce@xxxxxxxxxxxxx<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> [mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx>] On Behalf Of Justin Davis Sent: Saturday, February 28, 2015 3:44 PM To: wdmaudiodev@xxxxxxxxxxxxx<mailto:wdmaudiodev@xxxxxxxxxxxxx> Subject: [wdmaudiodev] Help installing custom sAPO for a USB audio device Hi all, I've developed drivers for a number of years, but I'm a newbie to audio drivers. I'm dipping my toes in the water by trying to install a custom sAPO (the swap example) for a standard USB microphone (and USB headphones at some point too). I've read up on as much info as I can find and I've tried several examples. I've had success building and installing the "slate audio" example from the WDK 8.1 samples. However, I'm having problems adapting this example to my simple USB audio device. I really just want to use the standard USBAudio.sys driver but supplement it with my sAPO. I think I have the proper "Include" and "Needs" section to pull that stuff in from the wdma_usb.inf file. I think the root of my problem is with putting the right sAPO registration data in the registry. I've generally tried to follow the guidance from this page (and the Vista Audio Effects white paper): https://msdn.microsoft.com/en-us/library/windows/hardware/ff536810(v=vs.85).aspx However, it uses lots of INF fragments with HKR, which is relative to how you get to that INF section. So it's not 100% clear where those are supposed to go. Through looking at the example, I'm pretty sure those keys need to be installed as part of an "AddInterface" statement...but again it's not 100% clear. My problem is that I install via my INF, and I can see the registry keys get installed to what looks like the proper locations. But...it sounds like the installation process is supposed to migrate the sAPO registration data to another section (below), and this step doesn't appear to be happening. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Capture\{EP GUID}\FxProperties I've found that if I manually hack the above keys to point to my sAPO, it seems to work (I see my sAPO getting loaded in the audiodg process and my APOProcess() function is being called). However...I know I'm not supposed to hack those keys manually, the INF file is supposed to do something that causes the keys to be migrated there. It's just not clear on what's going wrong in that process. I'm not at my work machine right now so I can't copy the INF file I've been working with (I'll add that on Monday). But any advice on how to troubleshoot this would be greatly appreciated! I feel like what I'm trying to do should be simple, I'm just not familiar enough with the audio subsystem to know what to look for. BTW, I've seen the "Troubleshooting sAPO Load Failures" page, and I do have DisableProtectedAudioDG set. My problem isn't that my sAPO fails to load, it's that the system doesn't even try to load it (verified this in the debugger). Thanks for your help! Justin