summaryrefslogtreecommitdiff
path: root/audio
diff options
context:
space:
mode:
authorAdonais Romero González <[email protected]>2024-05-06 16:21:31 -0700
committerGitHub <[email protected]>2024-05-06 16:21:31 -0700
commita74a241c664c4e1d7c0838287b34076c19d9858a (patch)
tree6ff7562612967b122acf8acf8a69c4dcfd5905db /audio
parentdef8e8e34ed2b7b1deb2fc9112ac4255f1a0f2ba (diff)
parent15477ce52bbb6b42ca591ecdfb484cac089f89ab (diff)
Merge develop changes prior to upcoming WDK release (May 2024)
Diffstat (limited to 'audio')
-rw-r--r--audio/Acx/Samples/AudioCodec/Driver/AudioCodec.infbin0 -> 8526 bytes
-rw-r--r--audio/Acx/Samples/AudioCodec/Driver/AudioCodec.sln60
-rw-r--r--audio/Acx/Samples/AudioCodec/Driver/AudioCodec.vcxproj174
-rw-r--r--audio/Acx/Samples/AudioCodec/Driver/AudioCodec.vcxproj.Filters42
-rw-r--r--audio/Acx/Samples/AudioCodec/Driver/Device.cpp439
-rw-r--r--audio/Acx/Samples/AudioCodec/Driver/Driver.cpp129
-rw-r--r--audio/Acx/Samples/AudioCodec/Driver/DriverSettings.h54
-rw-r--r--audio/Acx/Samples/AudioCodec/Driver/ReadMe.txt42
-rw-r--r--audio/Acx/Samples/AudioCodec/Driver/Resources.rc12
-rw-r--r--audio/Acx/Samples/Common/CaptureCircuit.cpp799
-rw-r--r--audio/Acx/Samples/Common/CircuitHelper.cpp620
-rw-r--r--audio/Acx/Samples/Common/CircuitHelper.h135
-rw-r--r--audio/Acx/Samples/Common/KeywordDetector.cpp484
-rw-r--r--audio/Acx/Samples/Common/KeywordDetector.h145
-rw-r--r--audio/Acx/Samples/Common/NewDelete.cpp91
-rw-r--r--audio/Acx/Samples/Common/NewDelete.h58
-rw-r--r--audio/Acx/Samples/Common/Private.h922
-rw-r--r--audio/Acx/Samples/Common/RenderCircuit.cpp807
-rw-r--r--audio/Acx/Samples/Common/SamplesCommon.vcxproj179
-rw-r--r--audio/Acx/Samples/Common/SaveData.cpp1103
-rw-r--r--audio/Acx/Samples/Common/SaveData.h259
-rw-r--r--audio/Acx/Samples/Common/SimPeakMeter.cpp106
-rw-r--r--audio/Acx/Samples/Common/SimPeakMeter.h51
-rw-r--r--audio/Acx/Samples/Common/StreamEngine.cpp1345
-rw-r--r--audio/Acx/Samples/Common/StreamEngine.h449
-rw-r--r--audio/Acx/Samples/Common/ToneGenerator.cpp297
-rw-r--r--audio/Acx/Samples/Common/ToneGenerator.h88
-rw-r--r--audio/Acx/Samples/Common/Trace_macros.h470
-rw-r--r--audio/Acx/Samples/Common/WaveReader.cpp769
-rw-r--r--audio/Acx/Samples/Common/WaveReader.h196
-rw-r--r--audio/Acx/Samples/Inc/AudioFormats.h959
-rw-r--r--audio/Acx/Samples/Inc/cpp_utils.h71
-rw-r--r--audio/Acx/Samples/Shared/Public.h342
-rw-r--r--audio/Acx/Samples/Shared/Trace.h33
-rw-r--r--audio/simpleaudiosample/Package/package.VcxProj30
-rw-r--r--audio/simpleaudiosample/SimpleAudioSample.sln22
-rw-r--r--audio/simpleaudiosample/Source/Filters/Filters.vcxproj96
-rw-r--r--audio/simpleaudiosample/Source/Inc/Inc.vcxproj90
-rw-r--r--audio/simpleaudiosample/Source/Main/Main.vcxproj156
-rw-r--r--audio/simpleaudiosample/Source/Main/SimpleAudioSample.inxbin15164 -> 15004 bytes
-rw-r--r--audio/simpleaudiosample/Source/Main/adapter.cpp71
-rw-r--r--audio/simpleaudiosample/Source/Main/common.cpp5
-rw-r--r--audio/simpleaudiosample/Source/Main/minwavertstream.cpp47
-rw-r--r--audio/simpleaudiosample/Source/Utilities/Utilities.vcxproj96
-rw-r--r--audio/simpleaudiosample/Source/Utilities/savedata.cpp104
-rw-r--r--audio/sysvad/APO/AecApo/AecApo.h9
-rw-r--r--audio/sysvad/APO/AecApo/AecApo.vcxproj128
-rw-r--r--audio/sysvad/APO/AecApo/AecApoMfx.cpp33
-rw-r--r--audio/sysvad/APO/DelayAPO/DelayAPO.vcxproj132
-rw-r--r--audio/sysvad/APO/DelayAPO/DelayAPOMFX.cpp7
-rw-r--r--audio/sysvad/APO/DelayAPO/DelayAPOSFX.cpp5
-rw-r--r--audio/sysvad/APO/KWSApo/KWSApo.vcxproj128
-rw-r--r--audio/sysvad/APO/SwapAPO/SwapAPO.h6
-rw-r--r--audio/sysvad/APO/SwapAPO/SwapAPO.vcxproj200
-rw-r--r--audio/sysvad/APO/SwapAPO/swapapomfx.cpp47
-rw-r--r--audio/sysvad/APO/SwapAPO/swapaposfx.cpp69
-rw-r--r--audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj90
-rw-r--r--audio/sysvad/EndpointsCommon/MiniportAudioEngineNode.cpp6
-rw-r--r--audio/sysvad/EndpointsCommon/mintopo.cpp94
-rw-r--r--audio/sysvad/EndpointsCommon/mintopo.h8
-rw-r--r--audio/sysvad/EndpointsCommon/minwavert.cpp46
-rw-r--r--audio/sysvad/EndpointsCommon/minwavertstream.cpp46
-rw-r--r--audio/sysvad/EndpointsCommon/speakertopo.cpp9
-rw-r--r--audio/sysvad/EndpointsCommon/speakertoptable.h7
-rw-r--r--audio/sysvad/KeywordDetectorAdapter/KeywordDetectorContosoAdapter.vcxproj120
-rw-r--r--audio/sysvad/Package/package.VcxProj32
-rw-r--r--audio/sysvad/TabletAudioSample/TabletAudioSample.vcxproj130
-rw-r--r--audio/sysvad/adapter.cpp69
-rw-r--r--audio/sysvad/common.cpp5
-rw-r--r--audio/sysvad/savedata.cpp133
-rw-r--r--audio/sysvad/savedata.h8
-rw-r--r--audio/sysvad/sysvad.sln34
72 files changed, 12376 insertions, 1672 deletions
diff --git a/audio/Acx/Samples/AudioCodec/Driver/AudioCodec.inf b/audio/Acx/Samples/AudioCodec/Driver/AudioCodec.inf
new file mode 100644
index 00000000..889f9bdb
--- /dev/null
+++ b/audio/Acx/Samples/AudioCodec/Driver/AudioCodec.inf
Binary files differ
diff --git a/audio/Acx/Samples/AudioCodec/Driver/AudioCodec.sln b/audio/Acx/Samples/AudioCodec/Driver/AudioCodec.sln
new file mode 100644
index 00000000..1cedca27
--- /dev/null
+++ b/audio/Acx/Samples/AudioCodec/Driver/AudioCodec.sln
@@ -0,0 +1,60 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31409.214
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SamplesCommon", "SamplesCommon", "{0DF6D5E6-3B78-414B-B37B-85D9CA454487}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AudioCodec", "AudioCodec", "{0D3B6287-146E-4700-B2EE-11D520014FEA}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SamplesCommon", "..\..\Common\SamplesCommon.vcxproj", "{6A946D59-6690-4ED0-A77D-7D4C3D4B3241}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AudioCodec", "AudioCodec.vcxproj", "{C575002D-5FDE-43C7-AB19-EE846A20083A}"
+ ProjectSection(ProjectDependencies) = postProject
+ {6A946D59-6690-4ED0-A77D-7D4C3D4B3241} = {6A946D59-6690-4ED0-A77D-7D4C3D4B3241}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ARM64 = Debug|ARM64
+ Debug|x64 = Debug|x64
+ Release|ARM64 = Release|ARM64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C575002D-5FDE-43C7-AB19-EE846A20083A}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {C575002D-5FDE-43C7-AB19-EE846A20083A}.Debug|ARM64.Build.0 = Debug|ARM64
+ {C575002D-5FDE-43C7-AB19-EE846A20083A}.Debug|ARM64.Deploy.0 = Debug|ARM64
+ {C575002D-5FDE-43C7-AB19-EE846A20083A}.Debug|x64.ActiveCfg = Debug|x64
+ {C575002D-5FDE-43C7-AB19-EE846A20083A}.Debug|x64.Build.0 = Debug|x64
+ {C575002D-5FDE-43C7-AB19-EE846A20083A}.Debug|x64.Deploy.0 = Debug|x64
+ {C575002D-5FDE-43C7-AB19-EE846A20083A}.Release|ARM64.ActiveCfg = Release|ARM64
+ {C575002D-5FDE-43C7-AB19-EE846A20083A}.Release|ARM64.Build.0 = Release|ARM64
+ {C575002D-5FDE-43C7-AB19-EE846A20083A}.Release|ARM64.Deploy.0 = Release|ARM64
+ {C575002D-5FDE-43C7-AB19-EE846A20083A}.Release|x64.ActiveCfg = Release|x64
+ {C575002D-5FDE-43C7-AB19-EE846A20083A}.Release|x64.Build.0 = Release|x64
+ {C575002D-5FDE-43C7-AB19-EE846A20083A}.Release|x64.Deploy.0 = Release|x64
+ {6A946D59-6690-4ED0-A77D-7D4C3D4B3241}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {6A946D59-6690-4ED0-A77D-7D4C3D4B3241}.Debug|ARM64.Build.0 = Debug|ARM64
+ {6A946D59-6690-4ED0-A77D-7D4C3D4B3241}.Debug|ARM64.Deploy.0 = Debug|ARM64
+ {6A946D59-6690-4ED0-A77D-7D4C3D4B3241}.Debug|x64.ActiveCfg = Debug|x64
+ {6A946D59-6690-4ED0-A77D-7D4C3D4B3241}.Debug|x64.Build.0 = Debug|x64
+ {6A946D59-6690-4ED0-A77D-7D4C3D4B3241}.Debug|x64.Deploy.0 = Debug|x64
+ {6A946D59-6690-4ED0-A77D-7D4C3D4B3241}.Release|ARM64.ActiveCfg = Release|ARM64
+ {6A946D59-6690-4ED0-A77D-7D4C3D4B3241}.Release|ARM64.Build.0 = Release|ARM64
+ {6A946D59-6690-4ED0-A77D-7D4C3D4B3241}.Release|ARM64.Deploy.0 = Release|ARM64
+ {6A946D59-6690-4ED0-A77D-7D4C3D4B3241}.Release|x64.ActiveCfg = Release|x64
+ {6A946D59-6690-4ED0-A77D-7D4C3D4B3241}.Release|x64.Build.0 = Release|x64
+ {6A946D59-6690-4ED0-A77D-7D4C3D4B3241}.Release|x64.Deploy.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {6A946D59-6690-4ED0-A77D-7D4C3D4B3241} = {0DF6D5E6-3B78-414B-B37B-85D9CA454487}
+ {C575002D-5FDE-43C7-AB19-EE846A20083A} = {0D3B6287-146E-4700-B2EE-11D520014FEA}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {8E3043F2-1C76-4A4A-9C60-A645BD6CBF24}
+ EndGlobalSection
+EndGlobal
diff --git a/audio/Acx/Samples/AudioCodec/Driver/AudioCodec.vcxproj b/audio/Acx/Samples/AudioCodec/Driver/AudioCodec.vcxproj
new file mode 100644
index 00000000..0cdc9e61
--- /dev/null
+++ b/audio/Acx/Samples/AudioCodec/Driver/AudioCodec.vcxproj
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|ARM64">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM64">
+ <Configuration>Release</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="ReadMe.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="Device.cpp" />
+ <ClCompile Include="Driver.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="Trace.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="AudioCodec.inf" />
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ACX_VERSION_MAJOR>1</ACX_VERSION_MAJOR>
+ <ACX_VERSION_MINOR>1</ACX_VERSION_MINOR>
+ <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
+ <KMDF_VERSION_MINOR>31</KMDF_VERSION_MINOR>
+ <ProjectGuid>{C575002D-5FDE-43C7-AB19-EE846A20083A}</ProjectGuid>
+ <TemplateGuid>{497e31cb-056b-4f31-abb8-447fd55ee5a5}</TemplateGuid>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
+ <Configuration>Debug</Configuration>
+ <RootNamespace>AudioCodec</RootNamespace>
+ <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>KMDF</DriverType>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>KMDF</DriverType>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>KMDF</DriverType>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>KMDF</DriverType>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">..\..\common\trace_macros.h</WppScanConfigurationData>
+ <WppKernelMode>true</WppKernelMode>
+ <AdditionalIncludeDirectories>$(SDK_INC_PATH);$(DDK_INC_PATH)\acx\km\$(ACX_VERSION_MAJOR).$(ACX_VERSION_MINOR);..\..\common;..\..\inc;..\..\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ACX_VERSION_MAJOR=1;ACX_VERSION_MINOR=1;KMDF_VERSION_MAJOR=1;KMDF_VERSION_MINOR=31;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <DriverSign>
+ <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
+ </DriverSign>
+ <Link>
+ <AdditionalDependencies>$(DDK_LIB_PATH)\libcntpr.lib;wpprecorder.lib;acx\km\$(ACX_VERSION_MAJOR).$(ACX_VERSION_MINOR)\acxstub.lib;..\..\Common\$(IntDir)\SamplesCommon.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">..\..\common\trace_macros.h</WppScanConfigurationData>
+ <WppKernelMode>true</WppKernelMode>
+ <AdditionalIncludeDirectories>$(SDK_INC_PATH);$(DDK_INC_PATH)\acx\km\$(ACX_VERSION_MAJOR).$(ACX_VERSION_MINOR);..\..\common;..\..\inc;..\..\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ACX_VERSION_MAJOR=1;ACX_VERSION_MINOR=1;KMDF_VERSION_MAJOR=1;KMDF_VERSION_MINOR=31;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <DriverSign>
+ <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
+ </DriverSign>
+ <Link>
+ <AdditionalDependencies>$(DDK_LIB_PATH)\libcntpr.lib;wpprecorder.lib;acx\km\$(ACX_VERSION_MAJOR).$(ACX_VERSION_MINOR)\acxstub.lib;..\..\Common\$(IntDir)\SamplesCommon.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">..\..\common\trace_macros.h</WppScanConfigurationData>
+ <WppKernelMode>true</WppKernelMode>
+ <AdditionalIncludeDirectories>$(SDK_INC_PATH);$(DDK_INC_PATH)\acx\km\$(ACX_VERSION_MAJOR).$(ACX_VERSION_MINOR);..\..\common;..\..\inc;..\..\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ACX_VERSION_MAJOR=1;ACX_VERSION_MINOR=1;KMDF_VERSION_MAJOR=1;KMDF_VERSION_MINOR=31;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <DriverSign>
+ <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
+ </DriverSign>
+ <Link>
+ <AdditionalDependencies>$(DDK_LIB_PATH)\libcntpr.lib;wpprecorder.lib;acx\km\$(ACX_VERSION_MAJOR).$(ACX_VERSION_MINOR)\acxstub.lib;..\..\Common\$(IntDir)\SamplesCommon.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">..\..\common\trace_macros.h</WppScanConfigurationData>
+ <WppKernelMode>true</WppKernelMode>
+ <AdditionalIncludeDirectories>$(SDK_INC_PATH);$(DDK_INC_PATH)\acx\km\$(ACX_VERSION_MAJOR).$(ACX_VERSION_MINOR);..\..\common;..\..\inc;..\..\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ACX_VERSION_MAJOR=1;ACX_VERSION_MINOR=1;KMDF_VERSION_MAJOR=1;KMDF_VERSION_MINOR=31;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <DriverSign>
+ <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
+ </DriverSign>
+ <Link>
+ <AdditionalDependencies>$(DDK_LIB_PATH)\libcntpr.lib;wpprecorder.lib;acx\km\$(ACX_VERSION_MAJOR).$(ACX_VERSION_MINOR)\acxstub.lib;..\..\Common\$(IntDir)\SamplesCommon.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <FilesToPackage Include="$(TargetPath)" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/audio/Acx/Samples/AudioCodec/Driver/AudioCodec.vcxproj.Filters b/audio/Acx/Samples/AudioCodec/Driver/AudioCodec.vcxproj.Filters
new file mode 100644
index 00000000..0b882019
--- /dev/null
+++ b/audio/Acx/Samples/AudioCodec/Driver/AudioCodec.vcxproj.Filters
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ <Filter Include="Driver Files">
+ <UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>
+ <Extensions>inf;inv;inx;mof;mc;</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="ReadMe.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="AudioCodec.inf">
+ <Filter>Driver Files</Filter>
+ </Inf>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="Trace.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="Device.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Driver.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/audio/Acx/Samples/AudioCodec/Driver/Device.cpp b/audio/Acx/Samples/AudioCodec/Driver/Device.cpp
new file mode 100644
index 00000000..7e9a0a3c
--- /dev/null
+++ b/audio/Acx/Samples/AudioCodec/Driver/Device.cpp
@@ -0,0 +1,439 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ Device.cpp - Device handling events for example driver.
+
+Abstract:
+
+ This file contains the device entry points and callbacks.
+
+Environment:
+
+ Kernel-mode Driver Framework
+
+--*/
+
+#include <wdm.h>
+#include <windef.h>
+#include "public.h"
+#include <devguid.h>
+#include <ks.h>
+#include <mmsystem.h>
+#include <ksmedia.h>
+#include "streamengine.h"
+#include "DriverSettings.h"
+
+#ifndef __INTELLISENSE__
+#include "device.tmh"
+#endif
+
+UNICODE_STRING g_RegistryPath = { 0 }; // This is used to store the registry settings path for the driver
+
+ULONG DeviceDriverTag = DRIVER_TAG;
+
+ULONG IdleTimeoutMsec = IDLE_TIMEOUT_MSEC;
+
+__drv_requiresIRQL(PASSIVE_LEVEL)
+PAGED_CODE_SEG
+NTSTATUS
+CopyRegistrySettingsPath(
+ _In_ PUNICODE_STRING RegistryPath
+)
+/*++
+
+Routine Description:
+
+Copies the following registry path to a global variable.
+
+\REGISTRY\MACHINE\SYSTEM\ControlSetxxx\Services\<driver>\Parameters
+
+Arguments:
+
+RegistryPath - Registry path passed to DriverEntry
+
+Returns:
+
+NTSTATUS - SUCCESS if able to configure the framework
+
+--*/
+
+{
+ PAGED_CODE();
+
+ //
+ // Initializing the unicode string, so that if it is not allocated it will not be deallocated too.
+ //
+ RtlInitUnicodeString(&g_RegistryPath, nullptr);
+
+ g_RegistryPath.MaximumLength = RegistryPath->Length + sizeof(WCHAR);
+
+ g_RegistryPath.Buffer = (PWCH)ExAllocatePool2(POOL_FLAG_PAGED, g_RegistryPath.MaximumLength, DRIVER_TAG);
+
+ if (g_RegistryPath.Buffer == nullptr)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlAppendUnicodeToString(&g_RegistryPath, RegistryPath->Buffer);
+
+ return STATUS_SUCCESS;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+Codec_EvtBusDeviceAdd(
+ _In_ WDFDRIVER Driver,
+ _Inout_ PWDFDEVICE_INIT DeviceInit
+)
+/*++
+
+Routine Description:
+
+ EvtDeviceAdd is called by the framework in response to AddDevice
+ call from the PnP manager. We create and initialize a device object to
+ represent a new instance of the device. All the software resources
+ should be allocated in this callback.
+
+Arguments:
+ Driver - Handle to a framework driver object created in DriverEntry
+
+ DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.
+
+Return Value:
+
+ NTSTATUS
+
+--*/
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ WDF_OBJECT_ATTRIBUTES attributes;
+ WDF_DEVICE_PNP_CAPABILITIES pnpCaps;
+ ACX_DEVICEINIT_CONFIG devInitCfg;
+ ACX_DEVICE_CONFIG devCfg;
+ WDFDEVICE device = nullptr;
+ PCODEC_DEVICE_CONTEXT devCtx;
+ WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(Driver);
+
+ //
+ // The driver calls this DDI in its AddDevice callback before creating the PnP device.
+ // ACX uses this call to add default/standard settings for the device to be created.
+ //
+ ACX_DEVICEINIT_CONFIG_INIT(&devInitCfg);
+ RETURN_IF_FAILED(AcxDeviceInitInitialize(DeviceInit, &devInitCfg));
+
+ //
+ // Initialize the pnpPowerCallbacks structure. Callback events for PNP
+ // and Power are specified here. If you don't supply any callbacks,
+ // the Framework will take appropriate default actions based on whether
+ // DeviceInit is initialized to be an FDO, a PDO or a filter device
+ // object.
+ //
+ WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
+ pnpPowerCallbacks.EvtDevicePrepareHardware = Codec_EvtDevicePrepareHardware;
+ pnpPowerCallbacks.EvtDeviceReleaseHardware = Codec_EvtDeviceReleaseHardware;
+ pnpPowerCallbacks.EvtDeviceD0Entry = Codec_EvtDeviceD0Entry;
+ pnpPowerCallbacks.EvtDeviceD0Exit = Codec_EvtDeviceD0Exit;
+ WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, CODEC_DEVICE_CONTEXT);
+ attributes.EvtCleanupCallback = Codec_EvtDeviceContextCleanup;
+
+ RETURN_NTSTATUS_IF_FAILED(WdfDeviceCreate(&DeviceInit, &attributes, &device));
+
+ //
+ // Init Codec's device context.
+ //
+ devCtx = GetCodecDeviceContext(device);
+ ASSERT(devCtx != nullptr);
+
+ devCtx->Render = nullptr;
+ devCtx->Capture = nullptr;
+ devCtx->ExcludeD3Cold = WdfFalse;
+
+ //
+ // The driver calls this DDI in its AddDevice callback after creating the PnP
+ // device. ACX uses this call to apply any post device settings.
+ //
+ ACX_DEVICE_CONFIG_INIT(&devCfg);
+ RETURN_NTSTATUS_IF_FAILED(AcxDeviceInitialize(device, &devCfg));
+
+ //
+ // Tell the framework to set the SurpriseRemovalOK in the DeviceCaps so
+ // that you don't get the popup in usermode (on Win2K) when you surprise
+ // remove the device.
+ //
+ WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCaps);
+ pnpCaps.SurpriseRemovalOK = WdfTrue;
+ WdfDeviceSetPnpCapabilities(device, &pnpCaps);
+
+ //
+ // Create a render circuit and capture circuit and add them to the current
+ // device context. These circuits will be added to the device when the
+ // prepare hardware callback is called.
+ //
+ RETURN_NTSTATUS_IF_FAILED(CodecR_AddStaticRender(device, &CODEC_RENDER_COMPONENT_GUID, &renderCircuitName));
+
+ RETURN_NTSTATUS_IF_FAILED(CodecC_AddStaticCapture(device, &CODEC_CAPTURE_COMPONENT_GUID, &MIC_CUSTOM_NAME, &captureCircuitName));
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+Codec_EvtDevicePrepareHardware(
+ _In_ WDFDEVICE Device,
+ _In_ WDFCMRESLIST ResourceList,
+ _In_ WDFCMRESLIST ResourceListTranslated
+)
+/*++
+
+Routine Description:
+
+ In this callback, the driver does whatever is necessary to make the
+ hardware ready to use.
+
+Arguments:
+
+ Device - handle to a device
+
+Return Value:
+
+ NT status value
+
+--*/
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PCODEC_DEVICE_CONTEXT devCtx;
+
+ UNREFERENCED_PARAMETER(ResourceList);
+ UNREFERENCED_PARAMETER(ResourceListTranslated);
+
+ PAGED_CODE();
+
+ devCtx = GetCodecDeviceContext(Device);
+ ASSERT(devCtx != nullptr);
+
+ // NOTE: Download firmware here.
+
+ // NOTE: Register streaming h/w resources here.
+
+ //
+ // Set power policy data.
+ //
+ RETURN_NTSTATUS_IF_FAILED(Codec_SetPowerPolicy(Device));
+
+ //
+ // Setting up the data saving (CSaveData) and wave file reader (CWaveReader)
+ // utility classes which will be used by the virtual streaming engine.
+ //
+ RETURN_NTSTATUS_IF_FAILED(CSaveData::SetDeviceObject(WdfDeviceWdmGetDeviceObject(Device)));
+
+ RETURN_NTSTATUS_IF_FAILED(CSaveData::InitializeWorkItems(WdfDeviceWdmGetDeviceObject(Device)));
+
+ RETURN_NTSTATUS_IF_FAILED(CWaveReader::InitializeWorkItems(WdfDeviceWdmGetDeviceObject(Device)));
+
+ //
+ // The driver uses this DDI to associate a circuit to a device. After
+ // this call the circuit is not visible until the device goes in D0.
+ // For a real driver there should be a check here to make sure the
+ // circuit has not been added already (there could be a situation where
+ // prepareHardware is called multiple times and releaseHardware is only
+ // called once).
+ //
+
+ ASSERT(devCtx->Render);
+ RETURN_NTSTATUS_IF_FAILED(AcxDeviceAddCircuit(Device, devCtx->Render));
+
+ ASSERT(devCtx->Capture);
+ RETURN_NTSTATUS_IF_FAILED(AcxDeviceAddCircuit(Device, devCtx->Capture));
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+Codec_EvtDeviceReleaseHardware(
+ _In_ WDFDEVICE Device,
+ _In_ WDFCMRESLIST ResourceListTranslated
+)
+/*++
+
+Routine Description:
+
+ In this callback, the driver releases the h/w resources allocated in the
+ prepare h/w callback.
+
+Arguments:
+
+ Device - handle to a device
+
+Return Value:
+
+ NT status value
+
+--*/
+{
+ NTSTATUS status;
+ PCODEC_DEVICE_CONTEXT devCtx;
+
+ UNREFERENCED_PARAMETER(Device);
+ UNREFERENCED_PARAMETER(ResourceListTranslated);
+
+ PAGED_CODE();
+
+ devCtx = GetCodecDeviceContext(Device);
+ ASSERT(devCtx != nullptr);
+
+ //
+ // The driver uses this DDI to delete a circuit from the current device.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxDeviceRemoveCircuit(Device, devCtx->Render));
+ RETURN_NTSTATUS_IF_FAILED(AcxDeviceRemoveCircuit(Device, devCtx->Capture));
+
+ // NOTE: Release streaming h/w resources here.
+
+ CSaveData::DestroyWorkItems();
+ CWaveReader::DestroyWorkItems();
+
+ status = STATUS_SUCCESS;
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+Codec_EvtDeviceD0Entry(
+ _In_ WDFDEVICE Device,
+ _In_ WDF_POWER_DEVICE_STATE PreviousState
+)
+{
+ UNREFERENCED_PARAMETER(Device);
+ UNREFERENCED_PARAMETER(PreviousState);
+
+ PAGED_CODE();
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+Codec_EvtDeviceD0Exit(
+ _In_ WDFDEVICE Device,
+ _In_ WDF_POWER_DEVICE_STATE TargetState
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ POWER_ACTION powerAction;
+
+ PAGED_CODE();
+
+ powerAction = WdfDeviceGetSystemPowerAction(Device);
+
+ //
+ // Update the power policy D3-cold info for Connected Standby.
+ //
+ if (TargetState == WdfPowerDeviceD3 && powerAction == PowerActionNone)
+ {
+ PCODEC_DEVICE_CONTEXT devCtx;
+ WDF_TRI_STATE excludeD3Cold = WdfTrue;
+ ACX_DX_EXIT_LATENCY latency;
+
+ devCtx = GetCodecDeviceContext(Device);
+ ASSERT(devCtx != nullptr);
+
+ //
+ // Get the current exit latency.
+ //
+ latency = AcxDeviceGetCurrentDxExitLatency(Device,
+ WdfDeviceGetSystemPowerAction(Device),
+ TargetState);
+
+ //
+ // If the current exit latency for the ACX device is responsive
+ // (not instant or fast) then D3-cold does not need to be excluded.
+ // Otherwise, D3-cold should be excluded because if the hardware
+ // goes into this state it will take too long to go back into D0
+ // and respond.
+ //
+ if (latency == AcxDxExitLatencyResponsive)
+ {
+ excludeD3Cold = WdfFalse;
+ }
+
+ if (devCtx->ExcludeD3Cold != excludeD3Cold)
+ {
+ devCtx->ExcludeD3Cold = excludeD3Cold;
+
+ RETURN_NTSTATUS_IF_FAILED(Codec_SetPowerPolicy(Device));
+ }
+ }
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+Codec_SetPowerPolicy(
+ _In_ WDFDEVICE Device
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PCODEC_DEVICE_CONTEXT devCtx;
+
+ PAGED_CODE();
+
+ devCtx = GetCodecDeviceContext(Device);
+ ASSERT(devCtx != nullptr);
+
+ //
+ // Init the idle policy structure.
+ //
+ WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS idleSettings;
+ WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&idleSettings, IdleCannotWakeFromS0);
+ idleSettings.IdleTimeout = IDLE_POWER_TIMEOUT;
+ idleSettings.IdleTimeoutType = SystemManagedIdleTimeoutWithHint;
+ idleSettings.ExcludeD3Cold = devCtx->ExcludeD3Cold;
+
+ RETURN_NTSTATUS_IF_FAILED(WdfDeviceAssignS0IdleSettings(Device, &idleSettings));
+
+ return status;
+}
+
+VOID
+Codec_EvtDeviceContextCleanup(
+ _In_ WDFOBJECT WdfDevice
+)
+/*++
+
+Routine Description:
+
+ In this callback, it cleans up device context.
+
+Arguments:
+
+ WdfDevice - WDF device object
+
+Return Value:
+
+ nullptr
+
+--*/
+{
+ WDFDEVICE device;
+ PCODEC_DEVICE_CONTEXT devCtx;
+
+ device = (WDFDEVICE)WdfDevice;
+ devCtx = GetCodecDeviceContext(device);
+ ASSERT(devCtx != nullptr);
+
+ if (devCtx->Capture)
+ {
+ CodecC_CircuitCleanup(devCtx->Capture);
+ }
+}
diff --git a/audio/Acx/Samples/AudioCodec/Driver/Driver.cpp b/audio/Acx/Samples/AudioCodec/Driver/Driver.cpp
new file mode 100644
index 00000000..452b0d99
--- /dev/null
+++ b/audio/Acx/Samples/AudioCodec/Driver/Driver.cpp
@@ -0,0 +1,129 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ Driver.cpp
+
+Abstract:
+
+ This file contains the driver entry points and callbacks.
+
+Environment:
+
+ Kernel-mode Driver Framework
+
+--*/
+
+#include "public.h"
+#include "cpp_utils.h"
+
+#ifndef __INTELLISENSE__
+#include "driver.tmh"
+#endif
+
+_Use_decl_annotations_
+void AudioCodecDriverUnload(
+ _In_ WDFDRIVER Driver
+)
+{
+ PAGED_CODE();
+
+ if (!Driver)
+ {
+ ASSERT(FALSE);
+ return;
+ }
+
+ WPP_CLEANUP(WdfDriverWdmGetDriverObject(Driver));
+
+ if (g_RegistryPath.Buffer != nullptr)
+ {
+ ExFreePool(g_RegistryPath.Buffer);
+ RtlZeroMemory(&g_RegistryPath, sizeof(g_RegistryPath));
+ }
+
+ return;
+}
+
+INIT_CODE_SEG
+NTSTATUS
+DriverEntry(
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING RegistryPath
+)
+/*++
+
+Routine Description:
+ DriverEntry initializes the driver and is the first routine called by the
+ system after the driver is loaded. DriverEntry specifies the other entry
+ points in the function driver, such as EvtDevice and DriverUnload.
+
+Parameters Description:
+
+ DriverObject - represents the instance of the function driver that is loaded
+ into memory. DriverEntry must initialize members of DriverObject before it
+ returns to the caller. DriverObject is allocated by the system before the
+ driver is loaded, and it is released by the system after the system unloads
+ the function driver from memory.
+
+ RegistryPath - represents the driver specific path in the Registry.
+ The function driver can use the path to store driver related data between
+ reboots. The path does not store hardware instance specific data.
+
+Return Value:
+
+ STATUS_SUCCESS if successful,
+ STATUS_UNSUCCESSFUL otherwise.
+
+--*/
+{
+ WDF_DRIVER_CONFIG wdfCfg;
+ ACX_DRIVER_CONFIG acxCfg;
+ WDFDRIVER driver;
+ NTSTATUS status = STATUS_SUCCESS;
+ WDF_OBJECT_ATTRIBUTES attributes;
+
+ PAGED_CODE();
+ WPP_INIT_TRACING(DriverObject, RegistryPath);
+
+ auto exit = scope_exit([&status, &DriverObject]() {
+ if (!NT_SUCCESS(status))
+ {
+ WPP_CLEANUP(DriverObject);
+
+ if (g_RegistryPath.Buffer != nullptr)
+ {
+ ExFreePool(g_RegistryPath.Buffer);
+ RtlZeroMemory(&g_RegistryPath, sizeof(g_RegistryPath));
+ }
+ }
+ });
+
+ RETURN_NTSTATUS_IF_FAILED(CopyRegistrySettingsPath(RegistryPath));
+
+ WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
+
+ WDF_DRIVER_CONFIG_INIT(&wdfCfg, Codec_EvtBusDeviceAdd);
+ wdfCfg.EvtDriverUnload = AudioCodecDriverUnload;
+
+ //
+ // Create a framework driver object to represent our driver.
+ //
+ RETURN_NTSTATUS_IF_FAILED(WdfDriverCreate(DriverObject, RegistryPath, &attributes, &wdfCfg, &driver));
+
+ //
+ // Initializing the ACX driver configuration struct which contains size and flags
+ // elements.
+ //
+ ACX_DRIVER_CONFIG_INIT(&acxCfg);
+
+ //
+ // The driver calls this DDI in its DriverEntry callback after creating the WDF driver
+ // object. ACX uses this call to apply any post driver settings.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxDriverInitialize(driver, &acxCfg));
+
+ return status;
+}
diff --git a/audio/Acx/Samples/AudioCodec/Driver/DriverSettings.h b/audio/Acx/Samples/AudioCodec/Driver/DriverSettings.h
new file mode 100644
index 00000000..65aa7f5b
--- /dev/null
+++ b/audio/Acx/Samples/AudioCodec/Driver/DriverSettings.h
@@ -0,0 +1,54 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ DriverSettings.h
+
+Abstract:
+
+ Contains guid definitions and other definitions used by the render and capture circuits
+ for this specific driver. Driver developers should replace these definitions with their
+ own.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+// Defining the component ID for the capture circuit. This ID uniquely identifies the circuit instance (vendor specific):
+DEFINE_GUID(CODEC_CAPTURE_COMPONENT_GUID, 0xc3ee9ec6, 0x8e8c, 0x49e9, 0xaf, 0x4b, 0xa7, 0xfc, 0x28, 0xe9, 0xd2, 0xe7);
+
+// Defines a custom name for the capture circuit bridge pin:
+DEFINE_GUID(MIC_CUSTOM_NAME, 0xd5649dc4, 0x2fa2, 0x418b, 0xb2, 0x78, 0x39, 0x7, 0x64, 0x6b, 0x3, 0xe);
+
+// Defining the component ID for the render circuit. This ID uniquely identifies the circuit instance (vendor specific):
+DEFINE_GUID(CODEC_RENDER_COMPONENT_GUID, 0xd03deb75, 0xe5b2, 0x45f7, 0x91, 0xfa, 0xf7, 0xae, 0x42, 0xdd, 0xf, 0xe0);
+
+// This is always the definition for the system container guid:
+DEFINE_GUID(SYSTEM_CONTAINER_GUID, 0x00000000, 0x0000, 0x0000, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
+
+// Driver developers should update this guid if the container is a device rather than a
+// system. Otherwise, this GUID should stay the same:
+DEFINE_GUID(DEVICE_CONTAINER_GUID, 0x00000000, 0x0000, 0x0000, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
+
+// AudioCodec driver tag:
+#define DRIVER_TAG (ULONG) 'CduA'
+
+// The idle timeout in msec for power policy structure:
+#define IDLE_TIMEOUT_MSEC (ULONG) 10000
+
+// The WPP control GUID defined in Trace.h should also be updated to be unique.
+
+// This string must match the string defined in AudioCodec.inf for the microphone name:
+DECLARE_CONST_UNICODE_STRING(captureCircuitName, L"Microphone0");
+
+// This string must match the string defined in AudioCodec.inf for the speaker name:
+DECLARE_CONST_UNICODE_STRING(renderCircuitName, L"Speaker0");
diff --git a/audio/Acx/Samples/AudioCodec/Driver/ReadMe.txt b/audio/Acx/Samples/AudioCodec/Driver/ReadMe.txt
new file mode 100644
index 00000000..ebc61c6d
--- /dev/null
+++ b/audio/Acx/Samples/AudioCodec/Driver/ReadMe.txt
@@ -0,0 +1,42 @@
+========================================================================
+ AudioCodec Project Overview
+========================================================================
+
+This file contains a summary of what you will find in each of the files that make up your project.
+
+AudioCodec.vcxproj
+ This is the main project file for projects generated using an Application Wizard.
+ It contains information about the version of the product that generated the file, and
+ information about the platforms, configurations, and project features selected with the
+ Application Wizard.
+
+AudioCodec.vcxproj.filters
+ This is the filters file for VC++ projects generated using an Application Wizard.
+ It contains information about the association between the files in your project
+ and the filters. This association is used in the IDE to show grouping of files with
+ similar extensions under a specific node (for e.g. ".cpp" files are associated with the
+ "Source Files" filter).
+
+Driver.cpp & Driver.h
+ DriverEntry and WDFDRIVER related functionality and callbacks. Driver developers should
+ make changes to these files for their specific driver as necessary.
+
+Device.cpp & Device.h
+ WDFDEVICE related functionality and callbacks. Driver developers should make changes to
+ these files for their specific driver as necessary.
+
+Trace.h
+ Definitions for WPP tracing.
+
+DriverSettings.h
+ Contains guid definitions and other definitions used by the render and capture circuits
+ for this specific driver. Driver developers should replace these definitions with their
+ own.
+
+/////////////////////////////////////////////////////////////////////////////
+
+Learn more about Kernel Mode Driver Framework here:
+
+http://msdn.microsoft.com/en-us/library/ff544296(v=VS.85).aspx
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/audio/Acx/Samples/AudioCodec/Driver/Resources.rc b/audio/Acx/Samples/AudioCodec/Driver/Resources.rc
new file mode 100644
index 00000000..788fc416
--- /dev/null
+++ b/audio/Acx/Samples/AudioCodec/Driver/Resources.rc
@@ -0,0 +1,12 @@
+#include <windows.h>
+
+#include <ntverp.h>
+
+#define VER_FILETYPE VFT_DRV
+#define VER_FILESUBTYPE VFT2_DRV_SYSTEM
+#define VER_FILEDESCRIPTION_STR "Audio Codec Acx Sample Driver"
+#define VER_INTERNALNAME_STR "AudioCodec.sys"
+#define VER_ORIGINALFILENAME_STR "AudioCodec.sys"
+
+#include "common.ver"
+
diff --git a/audio/Acx/Samples/Common/CaptureCircuit.cpp b/audio/Acx/Samples/Common/CaptureCircuit.cpp
new file mode 100644
index 00000000..ba205a90
--- /dev/null
+++ b/audio/Acx/Samples/Common/CaptureCircuit.cpp
@@ -0,0 +1,799 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ CaptureCircuit.cpp
+
+Abstract:
+
+ Capture Circuit. This file contains routines to create and handle
+ capture circuit.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include "private.h"
+#include "public.h"
+#include <ks.h>
+#include <mmsystem.h>
+#include <ksmedia.h>
+#include "AudioFormats.h"
+#include "streamengine.h"
+#include "cpp_utils.h"
+#include "circuithelper.h"
+
+#ifndef __INTELLISENSE__
+#include "captureCircuit.tmh"
+#endif
+
+//
+// Controls how the custom name of the bridge pin is read.
+//
+BOOL g_UseCustomInfName = TRUE;
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecC_EvtAcxPinSetDataFormat(
+ _In_ ACXPIN Pin,
+ _In_ ACXDATAFORMAT DataFormat
+)
+/*++
+
+Routine Description:
+
+ This ACX pin callback sets the device/mixed format.
+
+Return Value:
+
+ NTSTATUS
+
+--*/
+{
+ UNREFERENCED_PARAMETER(Pin);
+ UNREFERENCED_PARAMETER(DataFormat);
+
+ PAGED_CODE();
+
+ // NOTE: update device/mixed format here.
+
+ return STATUS_NOT_SUPPORTED;
+}
+
+///////////////////////////////////////////////////////////
+//
+// For more information on volume element see: https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/ksnodetype-volume
+//
+_Use_decl_annotations_
+NTSTATUS
+CodecC_EvtVolumeAssignLevelCallback(
+ _In_ ACXVOLUME Volume,
+ _In_ ULONG Channel,
+ _In_ LONG VolumeLevel
+)
+{
+ PAGED_CODE();
+
+ ASSERT(Volume);
+ PVOLUME_ELEMENT_CONTEXT volumeCtx = GetVolumeElementContext(Volume);
+ ASSERT(volumeCtx);
+
+ if (Channel != ALL_CHANNELS_ID)
+ {
+ volumeCtx->VolumeLevel[Channel] = VolumeLevel;
+ }
+ else
+ {
+ for (ULONG i = 0; i < MAX_CHANNELS; ++i)
+ {
+ volumeCtx->VolumeLevel[i] = VolumeLevel;
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+CodecC_EvtVolumeRetrieveLevelCallback(
+ _In_ ACXVOLUME Volume,
+ _In_ ULONG Channel,
+ _Out_ LONG * VolumeLevel
+)
+{
+ PAGED_CODE();
+
+ ASSERT(Volume);
+ PVOLUME_ELEMENT_CONTEXT volumeCtx = GetVolumeElementContext(Volume);
+ ASSERT(volumeCtx);
+
+ if (Channel == ALL_CHANNELS_ID)
+ {
+ Channel = 0;
+ }
+
+ *VolumeLevel = volumeCtx->VolumeLevel[Channel];
+
+ return STATUS_SUCCESS;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecC_CreateVolumeElement(
+ _In_ ACXCIRCUIT Circuit,
+ _Out_ ACXVOLUME* Element
+)
+/*++
+
+Routine Description:
+
+ This routine creates a volume element.
+
+Return Value:
+
+ NT status value
+--*/
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ WDF_OBJECT_ATTRIBUTES attributes;
+ ACX_VOLUME_CALLBACKS volumeCallbacks;
+ ACX_VOLUME_CONFIG volumeCfg;
+ VOLUME_ELEMENT_CONTEXT * volumeCtx;
+
+ PAGED_CODE();
+
+ //
+ // The driver uses this DDI to assign its volume element callbacks.
+ //
+ ACX_VOLUME_CALLBACKS_INIT(&volumeCallbacks);
+ volumeCallbacks.EvtAcxVolumeAssignLevel = CodecC_EvtVolumeAssignLevelCallback;
+ volumeCallbacks.EvtAcxVolumeRetrieveLevel = CodecC_EvtVolumeRetrieveLevelCallback;
+
+ //
+ // Create Volume element
+ //
+ ACX_VOLUME_CONFIG_INIT(&volumeCfg);
+ volumeCfg.ChannelsCount = MAX_CHANNELS;
+ volumeCfg.Minimum = VOLUME_LEVEL_MINIMUM;
+ volumeCfg.Maximum = VOLUME_LEVEL_MAXIMUM;
+ volumeCfg.SteppingDelta = VOLUME_STEPPING;
+ volumeCfg.Callbacks = &volumeCallbacks;
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, VOLUME_ELEMENT_CONTEXT);
+ attributes.ParentObject = Circuit;
+
+ RETURN_NTSTATUS_IF_FAILED(AcxVolumeCreate(Circuit, &attributes, &volumeCfg, Element));
+
+ ASSERT(*Element != nullptr);
+ volumeCtx = GetVolumeElementContext(*Element);
+ ASSERT(volumeCtx);
+
+ //
+ // (max + min)/2 puts it in the middle of the valid range, divide that by the stepping to get the nearest
+ // valid step, multiply that by stepping to put it back at a level value.
+ //
+ volumeCtx->VolumeLevel[0] = (VOLUME_LEVEL_MAXIMUM + VOLUME_LEVEL_MINIMUM) / 2 / VOLUME_STEPPING * VOLUME_STEPPING;
+ volumeCtx->VolumeLevel[1] = (VOLUME_LEVEL_MAXIMUM + VOLUME_LEVEL_MINIMUM) / 2 / VOLUME_STEPPING * VOLUME_STEPPING;
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecC_EvtAcxPinRetrieveName(
+ _In_ ACXPIN Pin,
+ _Out_ PUNICODE_STRING Name
+)
+/*++
+
+Routine Description:
+
+ If g_UseCustomInfName is false then the ACX
+ pin callback EvtAcxPinRetrieveName calls this
+ function in order to retrieve the pin name.
+
+Return Value:
+
+ NTSTATUS
+
+--*/
+{
+ UNREFERENCED_PARAMETER(Pin);
+
+ PAGED_CODE();
+
+ return RtlUnicodeStringPrintf(Name, L"CustomName2");
+}
+
+VOID
+CodecC_EvtPinContextCleanup(
+ _In_ WDFOBJECT WdfPin
+)
+/*++
+
+Routine Description:
+
+ In this callback, it cleans up pin context.
+
+Arguments:
+
+ WdfDevice - WDF device object
+
+Return Value:
+
+ nullptr
+
+--*/
+{
+ UNREFERENCED_PARAMETER(WdfPin);
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecC_CircuitCleanup(
+ _In_ ACXCIRCUIT Circuit
+)
+{
+ PCODEC_CAPTURE_CIRCUIT_CONTEXT circuitCtx;
+
+ PAGED_CODE();
+
+ //
+ // Remove the static capture circuit.
+ //
+ circuitCtx = GetCaptureCircuitContext(Circuit);
+ ASSERT(circuitCtx != nullptr);
+
+ return STATUS_SUCCESS;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecC_AddStaticCapture(
+ _In_ WDFDEVICE Device,
+ _In_ const GUID * ComponentGuid,
+ _In_ const GUID * MicCustomName,
+ _In_ const UNICODE_STRING * CircuitName
+)
+/*++
+
+Routine Description:
+
+ Creates the static capture circuit (pictured below)
+ and adds it to the device context. This is called
+ when a new device is detected and the AddDevice
+ call is made by the pnp manager.
+
+ ******************************************************
+ * Capture Circuit *
+ * *
+ * +-----------------------+ *
+ * | | *
+ * | +-------------+ | *
+ * Host ------>| | Volume Node | |---> Bridge *
+ * Pin | +-------------+ | Pin *
+ * | | *
+ * +-----------------------+ *
+ * *
+ ******************************************************
+
+Return Value:
+
+ NTSTATUS
+
+--*/
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PCODEC_DEVICE_CONTEXT devCtx;
+ PCAPTURE_DEVICE_CONTEXT captureDevCtx;
+ ACXCIRCUIT captureCircuit = nullptr;
+ WDF_OBJECT_ATTRIBUTES attributes;
+
+ PAGED_CODE();
+
+ devCtx = GetCodecDeviceContext(Device);
+ ASSERT(devCtx != nullptr);
+
+ //
+ // Alloc audio context to current device.
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, CAPTURE_DEVICE_CONTEXT);
+ RETURN_NTSTATUS_IF_FAILED(WdfObjectAllocateContext(Device, &attributes, (PVOID*)&captureDevCtx));
+ ASSERT(captureDevCtx);
+
+ //
+ // Create a capture circuit associated with this child device.
+ //
+ RETURN_NTSTATUS_IF_FAILED(CodecC_CreateCaptureCircuit(Device, ComponentGuid, MicCustomName, CircuitName, &captureCircuit));
+
+ devCtx->Capture = captureCircuit;
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+Capture_AllocateSupportedFormats(
+ _In_ WDFDEVICE Device,
+ _In_reads_bytes_(CodecCapturePinCount) ACXPIN Pin[],
+ _In_ ACXCIRCUIT Circuit,
+ _In_ size_t CodecCapturePinCount
+)
+{
+ UNREFERENCED_PARAMETER(CodecCapturePinCount);
+
+ NTSTATUS status = STATUS_SUCCESS;
+ ACXDATAFORMAT formatPcm44100c1;
+ ACXDATAFORMAT formatPcm48000c1;
+ ACXDATAFORMATLIST formatList;
+
+ WDF_OBJECT_ATTRIBUTES attributes;
+ WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
+
+ ///////////////////////////////////////////////////////////
+ //
+ // Allocate the formats this circuit supports.
+ //
+
+ RETURN_NTSTATUS_IF_FAILED(AllocateFormat(Pcm44100c1, Circuit, Device, &formatPcm44100c1));
+ RETURN_NTSTATUS_IF_FAILED(AllocateFormat(Pcm48000c1, Circuit, Device, &formatPcm48000c1));
+
+ ///////////////////////////////////////////////////////////
+ //
+ // Define supported formats for the host pin.
+ //
+
+ //
+ // The raw processing mode list is associated with each single circuit
+ // by ACX. A driver uses this DDI to retrieve the built-in raw
+ // data-format list.
+ //
+ RETURN_NTSTATUS_IF_TRUE(CodecCaptureHostPin >= CodecCapturePinCount, STATUS_INVALID_PARAMETER);
+ formatList = AcxPinGetRawDataFormatList(Pin[CodecCaptureHostPin]);
+ RETURN_NTSTATUS_IF_TRUE(formatList == nullptr, STATUS_INSUFFICIENT_RESOURCES);
+
+ //
+ // The driver uses this DDI to add data formats to the raw
+ // processing mode list associated with the current circuit.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxDataFormatListAddDataFormat(formatList, formatPcm44100c1));
+ RETURN_NTSTATUS_IF_FAILED(AcxDataFormatListAddDataFormat(formatList, formatPcm48000c1));
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecC_CreateCaptureCircuit(
+ _In_ WDFDEVICE Device,
+ _In_ const GUID * ComponentGuid,
+ _In_ const GUID * MicCustomName,
+ _In_ const UNICODE_STRING * CircuitName,
+ _Out_ ACXCIRCUIT* Circuit
+)
+/*++
+
+Routine Description:
+
+ This routine builds the CODEC capture circuit.
+
+Return Value:
+
+ NT status value
+
+--*/
+{
+ NTSTATUS status;
+ WDF_OBJECT_ATTRIBUTES attributes;
+ ACXCIRCUIT circuit;
+ CODEC_CAPTURE_CIRCUIT_CONTEXT* circuitCtx;
+ ACXPIN pin[CodecCapturePinCount];
+
+ PAGED_CODE();
+
+ //
+ // Init output value.
+ //
+ *Circuit = nullptr;
+
+ ///////////////////////////////////////////////////////////
+ //
+ // Create a circuit.
+ //
+ {
+ PACXCIRCUIT_INIT circuitInit = nullptr;
+ ACX_CIRCUIT_PNPPOWER_CALLBACKS powerCallbacks;
+
+ //
+ // The driver uses this DDI to allocate an ACXCIRCUIT_INIT
+ // structure. This opaque structure is used when creating
+ // a standalone audio circuit representing an audio device.
+ //
+ circuitInit = AcxCircuitInitAllocate(Device);
+
+ //
+ // A driver uses this DDI to free the allocated
+ // ACXCIRCUIT_INIT structure when an error is detected.
+ // Normally the structures is deleted/cleared by ACX when
+ // an ACX circuit is created successfully.
+ //
+ auto circuitInitScope = scope_exit([&circuitInit]() {
+ if (circuitInit) {
+ AcxCircuitInitFree(circuitInit);
+ }
+ });
+
+ //
+ // The driver uses this DDI to specify the Component ID
+ // of the ACX circuit. This ID is a guid that uniquely
+ // identifies the circuit instance (vendor specific).
+ //
+ AcxCircuitInitSetComponentId(circuitInit, ComponentGuid);
+
+ //
+ // The driver uses this DDI to specify the circuit name.
+ // For standalone circuits, this is the audio device name
+ // which is used by clients to open handles to the audio devices.
+ //
+ (VOID)AcxCircuitInitAssignName(circuitInit, CircuitName);
+
+ //
+ // The driver uses this DDI to specify the circuit type. The
+ // circuit type can be AcxCircuitTypeRender, AcxCircuitTypeCapture,
+ // AcxCircuitTypeOther, or AcxCircuitTypeMaximum (for validation).
+ //
+ AcxCircuitInitSetCircuitType(circuitInit, AcxCircuitTypeCapture);
+
+ //
+ // The driver uses this DDI to assign its (if any) power callbacks.
+ //
+ ACX_CIRCUIT_PNPPOWER_CALLBACKS_INIT(&powerCallbacks);
+ powerCallbacks.EvtAcxCircuitPowerUp = CodecC_EvtCircuitPowerUp;
+ powerCallbacks.EvtAcxCircuitPowerDown = CodecC_EvtCircuitPowerDown;
+ AcxCircuitInitSetAcxCircuitPnpPowerCallbacks(circuitInit, &powerCallbacks);
+
+ //
+ // The driver uses this DDI to register for a stream-create callback.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxCircuitInitAssignAcxCreateStreamCallback(circuitInit, CodecC_EvtCircuitCreateStream));
+
+ //
+ // The driver uses this DDI to create a new ACX circuit.
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, CODEC_CAPTURE_CIRCUIT_CONTEXT);
+ RETURN_NTSTATUS_IF_FAILED(AcxCircuitCreate(Device, &attributes, &circuitInit, &circuit));
+
+ circuitInitScope.release();
+
+ circuitCtx = GetCaptureCircuitContext(circuit);
+ ASSERT(circuitCtx);
+ }
+
+ //
+ // Post circuit creation initialization.
+ //
+
+ ///////////////////////////////////////////////////////////
+ //
+ // Create volume element.
+ //
+ {
+ ACXELEMENT elements[CaptureElementCount] = { 0 };
+
+ RETURN_NTSTATUS_IF_FAILED(CodecC_CreateVolumeElement(circuit, (ACXVOLUME*)&elements[CaptureVolumeIndex]));
+
+ //
+ // Saving the volume element in the circuit context.
+ //
+ circuitCtx->VolumeElement = (ACXVOLUME)elements[CaptureVolumeIndex];
+
+ //
+ // The driver uses this DDI post circuit creation to add ACXELEMENTs.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxCircuitAddElements(circuit, elements, SIZEOF_ARRAY(elements)));
+ }
+
+ ///////////////////////////////////////////////////////////
+ //
+ // Create the pins for the circuit.
+ //
+ {
+ ACX_PIN_CALLBACKS pinCallbacks;
+ ACX_PIN_CONFIG pinCfg;
+ CODEC_PIN_CONTEXT* pinCtx;
+
+ ///////////////////////////////////////////////////////////
+ //
+ // Create capture streaming pin.
+ //
+ ACX_PIN_CALLBACKS_INIT(&pinCallbacks);
+ pinCallbacks.EvtAcxPinSetDataFormat = CodecC_EvtAcxPinSetDataFormat;
+
+ ACX_PIN_CONFIG_INIT(&pinCfg);
+ pinCfg.Type = AcxPinTypeSource;
+ pinCfg.Communication = AcxPinCommunicationSink;
+ pinCfg.Category = &KSCATEGORY_AUDIO;
+ pinCfg.PinCallbacks = &pinCallbacks;
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, CODEC_PIN_CONTEXT);
+ attributes.EvtCleanupCallback = CodecC_EvtPinContextCleanup;
+ attributes.ParentObject = circuit;
+
+ //
+ // The driver uses this DDI to create one or more pins on the circuits.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxPinCreate(circuit, &attributes, &pinCfg, &(pin[CodecCaptureHostPin])));
+
+ ASSERT(pin[CodecCaptureHostPin] != nullptr);
+ pinCtx = GetCodecPinContext(pin[CodecCaptureHostPin]);
+ ASSERT(pinCtx);
+ pinCtx->CodecPinType = CodecPinTypeHost;
+
+ ///////////////////////////////////////////////////////////
+ //
+ // Create capture endpoint pin.
+ //
+ ACX_PIN_CALLBACKS_INIT(&pinCallbacks);
+ ACX_PIN_CONFIG_INIT(&pinCfg);
+
+ pinCfg.Type = AcxPinTypeSink;
+ pinCfg.Communication = AcxPinCommunicationNone;
+ pinCfg.Category = &KSNODETYPE_MICROPHONE;
+ pinCfg.PinCallbacks = &pinCallbacks;
+
+ // Specify how to read the custom name.
+ if (g_UseCustomInfName)
+ {
+ pinCfg.Name = MicCustomName;
+ }
+ else
+ {
+ pinCallbacks.EvtAcxPinRetrieveName = CodecC_EvtAcxPinRetrieveName;
+ }
+ g_UseCustomInfName = !g_UseCustomInfName;
+
+ WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
+ attributes.ParentObject = circuit;
+
+ //
+ // The driver uses this DDI to create one or more pins on the circuits.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxPinCreate(circuit, &attributes, &pinCfg, &(pin[CodecCaptureBridgePin])));
+
+ ASSERT(pin[CodecCaptureBridgePin] != nullptr);
+ }
+
+ ///////////////////////////////////////////////////////////
+ //
+ // Add audio jack to bridge pin.
+ // For more information on audio jack see: https://docs.microsoft.com/en-us/windows/win32/api/devicetopology/ns-devicetopology-ksjack_description
+ //
+ {
+ ACX_JACK_CONFIG jackCfg;
+ ACXJACK jack;
+ PJACK_CONTEXT jackCtx;
+
+ ACX_JACK_CONFIG_INIT(&jackCfg);
+ jackCfg.Description.ChannelMapping = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
+ jackCfg.Description.Color = RGB(0, 0, 0);
+ jackCfg.Description.ConnectionType = AcxConnTypeAtapiInternal;
+ jackCfg.Description.GeoLocation = AcxGeoLocFront;
+ jackCfg.Description.GenLocation = AcxGenLocPrimaryBox;
+ jackCfg.Description.PortConnection = AcxPortConnIntegratedDevice;
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, JACK_CONTEXT);
+ attributes.ParentObject = pin[CodecCaptureBridgePin];
+
+ RETURN_NTSTATUS_IF_FAILED(AcxJackCreate(pin[CodecCaptureBridgePin], &attributes, &jackCfg, &jack));
+
+ ASSERT(jack != nullptr);
+
+ jackCtx = GetJackContext(jack);
+ ASSERT(jackCtx);
+ jackCtx->Dummy = 0;
+
+ RETURN_NTSTATUS_IF_FAILED(AcxPinAddJacks(pin[CodecCaptureBridgePin], &jack, 1));
+ }
+
+ RETURN_NTSTATUS_IF_FAILED(Capture_AllocateSupportedFormats(Device, pin, circuit, CodecCapturePinCount));
+
+ ///////////////////////////////////////////////////////////
+ //
+ // The driver uses this DDI post circuit creation to add ACXPINs.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxCircuitAddPins(circuit, pin, CodecCapturePinCount));
+
+ //
+ // Set output value.
+ //
+ *Circuit = circuit;
+
+ //
+ // Done.
+ //
+ status = STATUS_SUCCESS;
+
+ return status;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+CodecC_EvtCircuitPowerUp(
+ _In_ WDFDEVICE Device,
+ _In_ ACXCIRCUIT Circuit,
+ _In_ WDF_POWER_DEVICE_STATE PreviousState
+)
+{
+ UNREFERENCED_PARAMETER(Device);
+ UNREFERENCED_PARAMETER(Circuit);
+ UNREFERENCED_PARAMETER(PreviousState);
+
+ PAGED_CODE();
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+CodecC_EvtCircuitPowerDown(
+ _In_ WDFDEVICE Device,
+ _In_ ACXCIRCUIT Circuit,
+ _In_ WDF_POWER_DEVICE_STATE TargetState
+)
+{
+ UNREFERENCED_PARAMETER(Device);
+ UNREFERENCED_PARAMETER(Circuit);
+ UNREFERENCED_PARAMETER(TargetState);
+
+ PAGED_CODE();
+
+ return STATUS_SUCCESS;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecC_EvtCircuitCreateStream(
+ _In_ WDFDEVICE Device,
+ _In_ ACXCIRCUIT Circuit,
+ _In_ ACXPIN Pin,
+ _In_ PACXSTREAM_INIT StreamInit,
+ _In_ ACXDATAFORMAT StreamFormat,
+ _In_ const GUID * SignalProcessingMode,
+ _In_ ACXOBJECTBAG VarArguments
+)
+/*++
+
+Routine Description:
+
+ This routine creates a stream for the specified circuit.
+
+Return Value:
+
+ NT status value
+
+--*/
+{
+ NTSTATUS status;
+ PCAPTURE_DEVICE_CONTEXT devCtx;
+ WDF_OBJECT_ATTRIBUTES attributes;
+ ACXSTREAM stream;
+ STREAMENGINE_CONTEXT * streamCtx;
+ ACX_STREAM_CALLBACKS streamCallbacks;
+ ACX_RT_STREAM_CALLBACKS rtCallbacks;
+ CCaptureStreamEngine * streamEngine = nullptr;
+ CODEC_CAPTURE_CIRCUIT_CONTEXT * circuitCtx;
+ CODEC_PIN_CONTEXT * pinCtx;
+
+ auto streamEngineScope = scope_exit([&streamEngine]() {
+
+ if (streamEngine)
+ {
+ delete streamEngine;
+ }
+
+ });
+
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(SignalProcessingMode);
+ UNREFERENCED_PARAMETER(VarArguments);
+
+ ASSERT(IsEqualGUID(*SignalProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW));
+
+ devCtx = GetCaptureDeviceContext(Device);
+ ASSERT(devCtx != nullptr);
+
+ circuitCtx = GetCaptureCircuitContext(Circuit);
+ ASSERT(circuitCtx != nullptr);
+
+ pinCtx = GetCodecPinContext(Pin);
+ ASSERT(pinCtx != nullptr);
+
+ //
+ // Init streaming callbacks.
+ //
+ ACX_STREAM_CALLBACKS_INIT(&streamCallbacks);
+ streamCallbacks.EvtAcxStreamPrepareHardware = EvtStreamPrepareHardware;
+ streamCallbacks.EvtAcxStreamReleaseHardware = EvtStreamReleaseHardware;
+ streamCallbacks.EvtAcxStreamRun = EvtStreamRun;
+ streamCallbacks.EvtAcxStreamPause = EvtStreamPause;
+
+ RETURN_NTSTATUS_IF_FAILED(AcxStreamInitAssignAcxStreamCallbacks(StreamInit, &streamCallbacks));
+
+ //
+ // Init RT streaming callbacks.
+ //
+ ACX_RT_STREAM_CALLBACKS_INIT(&rtCallbacks);
+ rtCallbacks.EvtAcxStreamGetHwLatency = EvtStreamGetHwLatency;
+ rtCallbacks.EvtAcxStreamAllocateRtPackets = EvtStreamAllocateRtPackets;
+ rtCallbacks.EvtAcxStreamFreeRtPackets = EvtStreamFreeRtPackets;
+ rtCallbacks.EvtAcxStreamGetCapturePacket = CodecC_EvtStreamGetCapturePacket;
+ rtCallbacks.EvtAcxStreamGetCurrentPacket = EvtStreamGetCurrentPacket;
+ rtCallbacks.EvtAcxStreamGetPresentationPosition = EvtStreamGetPresentationPosition;
+
+ RETURN_NTSTATUS_IF_FAILED(AcxStreamInitAssignAcxRtStreamCallbacks(StreamInit, &rtCallbacks));
+
+ //
+ // Buffer notifications are supported.
+ //
+ AcxStreamInitSetAcxRtStreamSupportsNotifications(StreamInit);
+
+ //
+ // Create the stream.
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, STREAMENGINE_CONTEXT);
+ attributes.EvtDestroyCallback = EvtStreamDestroy;
+ RETURN_NTSTATUS_IF_FAILED(AcxRtStreamCreate(Device, Circuit, &attributes, &StreamInit, &stream));
+
+ streamCtx = GetStreamEngineContext(stream);
+ ASSERT(streamCtx);
+
+ //
+ // Create the virtual streaming engine which will control
+ // streaming logic for the capture circuit.
+ //
+ streamEngine = new (POOL_FLAG_NON_PAGED, DeviceDriverTag) CCaptureStreamEngine(stream, StreamFormat);
+ RETURN_NTSTATUS_IF_TRUE(streamEngine == nullptr, STATUS_INSUFFICIENT_RESOURCES);
+
+ streamCtx->StreamEngine = (PVOID)streamEngine;
+
+ streamEngine = nullptr;
+
+ //
+ // Done.
+ //
+ status = STATUS_SUCCESS;
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecC_EvtStreamGetCapturePacket(
+ _In_ ACXSTREAM Stream,
+ _Out_ ULONG * LastCapturePacket,
+ _Out_ ULONGLONG * QPCPacketStart,
+ _Out_ BOOLEAN * MoreData
+)
+{
+ PSTREAMENGINE_CONTEXT ctx;
+ CCaptureStreamEngine* streamEngine = nullptr;
+
+ PAGED_CODE();
+
+ ctx = GetStreamEngineContext(Stream);
+
+ streamEngine = static_cast<CCaptureStreamEngine*>(ctx->StreamEngine);
+
+ return streamEngine->GetCapturePacket(LastCapturePacket, QPCPacketStart, MoreData);
+}
+
+
diff --git a/audio/Acx/Samples/Common/CircuitHelper.cpp b/audio/Acx/Samples/Common/CircuitHelper.cpp
new file mode 100644
index 00000000..bfff74b2
--- /dev/null
+++ b/audio/Acx/Samples/Common/CircuitHelper.cpp
@@ -0,0 +1,620 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ CircuitHelper.cpp
+
+Abstract:
+
+ This module contains helper functions for circuits.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include "private.h"
+#include "public.h"
+#include "CircuitHelper.h"
+
+#ifndef __INTELLISENSE__
+#include "CircuitHelper.tmh"
+#endif
+
+const ULONG _DSP_STREAM_PROPERTY_UI4_VALUE = 1;
+
+PAGED_CODE_SEG
+NTSTATUS AllocateFormat(
+ _In_ KSDATAFORMAT_WAVEFORMATEXTENSIBLE WaveFormat,
+ _In_ ACXCIRCUIT Circuit,
+ _In_ WDFDEVICE Device,
+ _Out_ ACXDATAFORMAT* Format
+)
+{
+ PAGED_CODE();
+
+ NTSTATUS status = STATUS_SUCCESS;
+
+ WDF_OBJECT_ATTRIBUTES attributes;
+ WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
+
+ ACX_DATAFORMAT_CONFIG formatCfg;
+ ACX_DATAFORMAT_CONFIG_INIT_KS(&formatCfg, &WaveFormat);
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, FORMAT_CONTEXT);
+ attributes.ParentObject = Circuit;
+
+ //
+ // Creates an ACXDATAFORMAT handle for the given wave format.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxDataFormatCreate(Device, &attributes, &formatCfg, Format));
+
+ ASSERT((*Format) != NULL);
+ FORMAT_CONTEXT* formatCtx;
+ formatCtx = GetFormatContext(*Format);
+ ASSERT(formatCtx);
+ UNREFERENCED_PARAMETER(formatCtx);
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS CreateStreamBridge(
+ _In_ ACX_STREAM_BRIDGE_CONFIG StreamCfg,
+ _In_ ACXCIRCUIT Circuit,
+ _In_ ACXPIN Pin,
+ _In_ DSP_PIN_CONTEXT* PinCtx,
+ _In_ BOOL Render)
+{
+ PAGED_CODE();
+
+ NTSTATUS status = STATUS_SUCCESS;
+
+ WDF_OBJECT_ATTRIBUTES attributes;
+ WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
+
+ attributes.ParentObject = Pin;
+
+ ACX_OBJECTBAG_CONFIG objBagCfg;
+ ACXOBJECTBAG objBag = NULL;
+ ACX_OBJECTBAG_CONFIG_INIT(&objBagCfg);
+ WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
+ attributes.ParentObject = Circuit;
+ RETURN_NTSTATUS_IF_FAILED(AcxObjectBagCreate(&attributes, &objBagCfg, &objBag));
+
+ DECLARE_CONST_ACXOBJECTBAG_DRIVER_PROPERTY_NAME(msft, TestUI4);
+ RETURN_NTSTATUS_IF_FAILED(AcxObjectBagAddUI4(objBag, &TestUI4, _DSP_STREAM_PROPERTY_UI4_VALUE));
+
+ //
+ // Add a stream BRIDGE.
+ //
+ PCGUID inModes[] = {
+ &AUDIO_SIGNALPROCESSINGMODE_RAW,
+ &AUDIO_SIGNALPROCESSINGMODE_DEFAULT,
+ };
+
+ if (Render)
+ {
+ StreamCfg.InModesCount = SIZEOF_ARRAY(inModes);
+ StreamCfg.InModes = inModes;
+ }
+
+ //
+ // Do not specify InModes for capture - this will prevent the ACX framework from adding created streams to this stream
+ // bridge automatically. We want to add the stream bridges manually since we don't want KWS streams added.
+ //
+ StreamCfg.OutMode = &AUDIO_SIGNALPROCESSINGMODE_RAW;
+ StreamCfg.OutStreamVarArguments = objBag;
+
+ //
+ // Uncomment this line to reverse the change-state sequence notifications.
+ //
+ // streamCfg.Flags |= AcxStreamBridgeInvertChangeStateSequence;
+
+ ACXSTREAMBRIDGE streamBridge = NULL;
+ RETURN_NTSTATUS_IF_FAILED(AcxStreamBridgeCreate(Circuit, &attributes, &StreamCfg, &streamBridge));
+
+ if (!Render)
+ {
+ PinCtx->HostStreamBridge = streamBridge;
+ }
+
+ RETURN_NTSTATUS_IF_FAILED(AcxPinAddStreamBridges(Pin, &streamBridge, 1));
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS ConnectRenderCircuitElements(
+ _In_ ACXAUDIOENGINE AudioEngineElement,
+ _In_ ACXCIRCUIT Circuit
+)
+{
+ PAGED_CODE();
+
+ NTSTATUS status = STATUS_SUCCESS;
+
+ //
+ // Explicitly connect the circuit/elements. Note that driver doesn't
+ // need to perform this step when circuit/elements are connected in the
+ // same order as they were added to the circuit. By default ACX connects
+ // the elements starting from the sink circuit pin and ending with the
+ // source circuit pin for both render and capture devices.
+ //
+ // Circuit layout
+ // -----------------------------------------
+ // | |
+ // | -------------------- |
+ // Host -0->|-----1->| |-0-------->|-3-> Bridge Pin
+ // | | Audio Engine | |
+ // Offload -1->|-----2->| Node |-3--| |
+ // | |------------------| | |
+ // | | |
+ // Loopback <-2-|<------------------------------ | |
+ // | |
+ // | |
+ // |---------------------------------------|
+ //
+
+ ACX_CONNECTION connections[4];
+
+ ACX_CONNECTION_INIT(&connections[0], Circuit, AudioEngineElement);
+ connections[0].FromPin.Id = RenderHostPin;
+ connections[0].ToPin.Id = 1;
+
+ ACX_CONNECTION_INIT(&connections[1], Circuit, AudioEngineElement);
+ connections[1].FromPin.Id = RenderOffloadPin;
+ connections[1].ToPin.Id = 2;
+
+ ACX_CONNECTION_INIT(&connections[2], AudioEngineElement, Circuit);
+ connections[2].ToPin.Id = RenderLoopbackPin;
+ connections[2].FromPin.Id = 3;
+
+ ACX_CONNECTION_INIT(&connections[3], AudioEngineElement, Circuit);
+ connections[3].ToPin.Id = RenderBridgePin;
+ connections[3].FromPin.Id = 0;
+
+ //
+ // Add the connections linking circuit to elements.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxCircuitAddConnections(Circuit, connections, SIZEOF_ARRAY(connections)));
+
+ return status;
+
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+Codec_GetModeFromAttributeList(
+ _In_ const PKSMULTIPLE_ITEM Attributes,
+ _In_ ULONG AttributesSize,
+ _Out_ GUID * SignalProcessingMode
+ )
+{
+ NTSTATUS status = STATUS_NO_MORE_ENTRIES;
+ PKSATTRIBUTE attributeHeader = NULL;
+ PAGED_CODE();
+ *SignalProcessingMode = AUDIO_SIGNALPROCESSINGMODE_DEFAULT;
+
+ status = FindKsAttributeById(Attributes,
+ AttributesSize,
+ &KSATTRIBUTEID_AUDIOSIGNALPROCESSING_MODE,
+ sizeof(KSATTRIBUTE_AUDIOSIGNALPROCESSING_MODE),
+ &attributeHeader);
+ if (!NT_SUCCESS(status))
+ {
+ goto exit;
+ }
+
+ ASSERT(attributeHeader->Attribute == KSATTRIBUTEID_AUDIOSIGNALPROCESSING_MODE);
+ ASSERT(attributeHeader->Size == sizeof(KSATTRIBUTE_AUDIOSIGNALPROCESSING_MODE));
+
+ KSATTRIBUTE_AUDIOSIGNALPROCESSING_MODE* signalProcessingModeAttribute;
+ signalProcessingModeAttribute = (KSATTRIBUTE_AUDIOSIGNALPROCESSING_MODE*)attributeHeader;
+ *SignalProcessingMode = signalProcessingModeAttribute->SignalProcessingMode;
+ status = STATUS_SUCCESS;
+exit:
+ return status;
+}
+
+struct AFX_FIND_KSATTRIBUTE_BY_ID
+{
+ const _GUID * Id;
+ ULONG Size;
+ PKSATTRIBUTE Attribute;
+};
+
+PAGED_CODE_SEG
+NTSTATUS
+FindKsAttributeByIdVisitor(
+ _In_ PKSATTRIBUTE AttributeHeader,
+ _In_ PVOID Context,
+ _Out_ BOOLEAN * bContinue
+ )
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ AFX_FIND_KSATTRIBUTE_BY_ID * ctx = (AFX_FIND_KSATTRIBUTE_BY_ID *)Context;
+ PAGED_CODE();
+ // Default: continue searching.
+ *bContinue = TRUE;
+
+ if (IsEqualGUIDAligned(AttributeHeader->Attribute, *ctx->Id))
+ {
+ // Validate its size.
+ if (AttributeHeader->Size < ctx->Size)
+ {
+ status = STATUS_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ ctx->Attribute = AttributeHeader;
+ *bContinue = FALSE;
+ }
+exit:
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+FindKsAttributeById(
+ _In_ const PKSMULTIPLE_ITEM Attributes,
+ _In_ ULONG AttributesSize,
+ _In_ const _GUID * AttributeId,
+ _In_ ULONG AttributeSize,
+ _Out_ PKSATTRIBUTE * AttributeHeader
+ )
+{
+ PAGED_CODE();
+ NTSTATUS status;
+ AFX_FIND_KSATTRIBUTE_BY_ID ctx = {0};
+ *AttributeHeader = NULL;
+ ctx.Id = AttributeId;
+ ctx.Size = AttributeSize;
+ status = TraverseKsAttributeList(Attributes, AttributesSize, FindKsAttributeByIdVisitor, &ctx);
+ if (!NT_SUCCESS(status))
+ {
+ goto exit;
+ }
+ if (ctx.Attribute == NULL)
+ {
+ status = STATUS_NO_MORE_ENTRIES;
+ goto exit;
+ }
+ *AttributeHeader = ctx.Attribute;
+exit:
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+TraverseKsAttributeList(
+ _In_ const PKSMULTIPLE_ITEM Attributes,
+ _In_ ULONG AttributesSize,
+ _In_ PFN_KSATTRIBUTES_VISITOR Visitor,
+ _In_ PVOID Context
+ )
+{
+ PAGED_CODE();
+ NTSTATUS status = STATUS_SUCCESS;
+ ULONG cbRemaining = 0;
+ PKSATTRIBUTE attributeHeader = NULL;
+ ASSERT(Visitor);
+ //
+ // Note: multiple-item ptr must have a FILE_QUAD_ALIGNMENT only in relation to the Pin's format size.
+ // I.e., it is not guaranteed that the attributes are FILE_QUAD_ALIGNMENT in memory, unless the caller reallocates
+ // them before calling this function (which is currently not done by anyone in any driver/sample).
+ //
+ //ASSERT((ULONG_PTR)Attributes == (((ULONG_PTR)Attributes + FILE_QUAD_ALIGNMENT) & ~FILE_QUAD_ALIGNMENT));
+ if (AttributesSize < sizeof(KSMULTIPLE_ITEM))
+ {
+ status = STATUS_INVALID_PARAMETER;
+ goto exit;
+ }
+ if (Attributes->Size < sizeof(KSMULTIPLE_ITEM))
+ {
+ status = STATUS_INVALID_PARAMETER;
+ goto exit;
+ }
+ if (AttributesSize < Attributes->Size)
+ {
+ status = STATUS_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ cbRemaining = Attributes->Size;
+ //
+ // Init ptr / size of attributes of list.
+ //
+ cbRemaining -= sizeof(KSMULTIPLE_ITEM);
+ attributeHeader = (PKSATTRIBUTE)(Attributes + 1);
+ for (ULONG i = 0; i < Attributes->Count; i++)
+ {
+ BOOLEAN bContinue = TRUE;
+ size_t cbAttribute = 0;
+
+ if (cbRemaining < sizeof(KSATTRIBUTE))
+ {
+ status = STATUS_INVALID_PARAMETER;
+ goto exit;
+ }
+ if (attributeHeader->Size < sizeof(KSATTRIBUTE))
+ {
+ status = STATUS_INVALID_PARAMETER;
+ goto exit;
+ }
+ if (cbRemaining < attributeHeader->Size)
+ {
+ status = STATUS_INVALID_PARAMETER;
+ goto exit;
+ }
+ //
+ // Invoke the descriptor enumeration routine.
+ //
+ status = Visitor(attributeHeader, Context, &bContinue);
+ if (!NT_SUCCESS(status))
+ {
+ goto exit;
+ }
+
+ if (!bContinue)
+ {
+ break;
+ }
+ //
+ // Adjust pointer and buffer size to next attribute (QWORD aligned)
+ //
+ cbAttribute = CODEC_ALIGN_SIZE_UP_CONSTANT(attributeHeader->Size, FILE_QUAD_ALIGNMENT);
+ if (cbRemaining < cbAttribute)
+ {
+ //
+ // Out of buffer, check if this was the last attribute.
+ //
+ if (i + 1 != Attributes->Count)
+ {
+ //
+ // This was not the last attribute, nevertheless there is no more buffer, error out.
+ //
+ status = STATUS_INVALID_PARAMETER;
+ goto exit;
+ }
+ // This was the final attribute. Exit loop with success status.
+ break;
+ }
+ // Check next attribute.
+ attributeHeader = (PKSATTRIBUTE)(((PBYTE)attributeHeader) + cbAttribute);
+ cbRemaining -= (ULONG)cbAttribute;
+ }
+ // Normalize success code.
+ status = STATUS_SUCCESS;
+exit:
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtJackRetrievePresence(
+ _In_ ACXJACK Jack,
+ _In_ PBOOLEAN IsConnected
+)
+{
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(Jack);
+ UNREFERENCED_PARAMETER(IsConnected);
+
+ NTSTATUS status = STATUS_SUCCESS;
+
+ //
+ // Because this is a sample we always return true (jack is present). A real driver should check
+ // if the device is actually present before returning true.
+ //
+ *IsConnected = true;
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+CreateAudioJack(
+ _In_ ULONG ChannelMapping,
+ _In_ ULONG Color,
+ _In_ ACX_JACK_CONNECTION_TYPE ConnectionType,
+ _In_ ACX_JACK_GEO_LOCATION GeoLocation,
+ _In_ ACX_JACK_GEN_LOCATION GenLocation,
+ _In_ ACX_JACK_PORT_CONNECTION PortConnection,
+ _In_ ULONG Flags,
+ _In_ ACXPIN BridgePin
+ )
+{
+ PAGED_CODE();
+
+ NTSTATUS status = STATUS_SUCCESS;
+ ACX_JACK_CONFIG jackCfg;
+ ACXJACK jack;
+ PJACK_CONTEXT jackCtx;
+ ACX_JACK_CALLBACKS jackCallbacks;
+
+ WDF_OBJECT_ATTRIBUTES attributes;
+ WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
+
+ ACX_JACK_CONFIG_INIT(&jackCfg);
+ jackCfg.Description.ChannelMapping = ChannelMapping;
+ jackCfg.Description.Color = Color;
+ jackCfg.Description.ConnectionType = ConnectionType;
+ jackCfg.Description.GeoLocation = GeoLocation;
+ jackCfg.Description.GenLocation = GenLocation;
+ jackCfg.Description.PortConnection = PortConnection;
+ jackCfg.Flags = Flags;
+
+ ACX_JACK_CALLBACKS_INIT(&jackCallbacks);
+ jackCallbacks.EvtAcxJackRetrievePresenceState = EvtJackRetrievePresence;
+ jackCfg.Callbacks = &jackCallbacks;
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, JACK_CONTEXT);
+ attributes.ParentObject = BridgePin;
+
+ status = AcxJackCreate(BridgePin, &attributes, &jackCfg, &jack);
+ if (!NT_SUCCESS(status))
+ {
+ goto exit;
+ }
+
+ ASSERT(jack != nullptr);
+
+ jackCtx = GetJackContext(jack);
+ ASSERT(jackCtx);
+ jackCtx->Dummy = 0;
+
+ status = AcxPinAddJacks(BridgePin, &jack, 1);
+
+exit:
+ return status;
+}
+
+PAGED_CODE_SEG
+VOID
+CpuResourcesCallbackHelper
+(
+ _In_ WDFOBJECT Object,
+ _In_ WDFREQUEST Request,
+ _In_ ACXELEMENT Element
+)
+{
+ NTSTATUS ntStatus = STATUS_NOT_SUPPORTED;
+ ULONG_PTR outDataCb = 0;
+ ACX_REQUEST_PARAMETERS params;
+ ULONG minSize = sizeof(ULONG);
+
+ PAGED_CODE();
+
+ ACX_REQUEST_PARAMETERS_INIT(&params);
+ AcxRequestGetParameters(Request, &params);
+
+ if ((params.Type != AcxRequestTypeProperty) ||
+ (params.Parameters.Property.ItemType != AcxItemTypeElement))
+ {
+ // Return to acx
+ (VOID) AcxCircuitDispatchAcxRequest((ACXCIRCUIT)Object, Request);
+ Request = NULL;
+ goto exit;
+ }
+
+ if (Element == NULL)
+ {
+ ntStatus = STATUS_NOT_SUPPORTED;
+ goto exit;
+ }
+
+ ULONG elementId = params.Parameters.Property.ItemId;
+ ULONG currentElementId = AcxElementGetId(Element);
+ ULONG valueCb = params.Parameters.Property.ValueCb;
+
+ if (valueCb != 0)
+ {
+ if (params.Parameters.Property.Value == NULL)
+ {
+ ntStatus = STATUS_BUFFER_TOO_SMALL;
+ goto exit;
+ }
+ }
+
+ //
+ // Check to see if the current node is the peakmeter node, if not then return the call to ACX
+ //
+ if (elementId != currentElementId)
+ {
+ (VOID) AcxCircuitDispatchAcxRequest((ACXCIRCUIT)Object, Request);
+ Request = NULL;
+ goto exit;
+ }
+
+ if (params.Parameters.Property.Verb == AcxPropertyVerbGet)
+ {
+
+ if (valueCb == 0)
+ {
+ outDataCb = minSize;
+ ntStatus = STATUS_BUFFER_OVERFLOW;
+ goto exit;
+ }
+ else if (valueCb < minSize)
+ {
+ outDataCb = 0;
+ ntStatus = STATUS_BUFFER_TOO_SMALL;
+ goto exit;
+ }
+ else
+ {
+ *((PULONG)params.Parameters.Property.Value) = KSAUDIO_CPU_RESOURCES_NOT_HOST_CPU;
+ params.Parameters.Property.ValueCb = sizeof(ULONG);
+ outDataCb = params.Parameters.Property.ValueCb;
+ ntStatus = STATUS_SUCCESS;
+ }
+ }
+ else if (params.Parameters.Property.Verb == AcxPropertyVerbBasicSupport)
+ {
+ if ((valueCb != sizeof(ULONG)) && (valueCb != sizeof(KSPROPERTY_DESCRIPTION)))
+ {
+ outDataCb = minSize;
+ ntStatus = STATUS_BUFFER_OVERFLOW;
+ goto exit;
+ }
+
+ if (valueCb >= sizeof(KSPROPERTY_DESCRIPTION))
+ {
+ // if return buffer can hold a KSPROPERTY_DESCRIPTION, return it
+ //
+ PKSPROPERTY_DESCRIPTION PropDesc = (PKSPROPERTY_DESCRIPTION)params.Parameters.Property.Value;
+
+ PropDesc->AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET;
+ PropDesc->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION);
+ PropDesc->PropTypeSet.Set = KSPROPTYPESETID_General;
+ PropDesc->PropTypeSet.Id = VT_UI4;
+ PropDesc->PropTypeSet.Flags = 0;
+ PropDesc->MembersListCount = 0;
+ PropDesc->Reserved = 0;
+ outDataCb = sizeof(KSPROPERTY_DESCRIPTION);
+ ntStatus = STATUS_SUCCESS;
+ }
+ else if (valueCb >= sizeof(ULONG))
+ {
+ // if return buffer can hold a ULONG, return the access flags
+ //
+ *((PULONG)params.Parameters.Property.Value) = KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET;
+ outDataCb = minSize;
+ ntStatus = STATUS_SUCCESS;
+ }
+ else if (valueCb > 0)
+ {
+ outDataCb = 0;
+ ntStatus = STATUS_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ outDataCb = minSize;
+ ntStatus = STATUS_BUFFER_OVERFLOW;
+ }
+ }
+ else
+ {
+ //
+ // Just give it back to ACX. After this call the request is gone.
+ //
+ (VOID) AcxCircuitDispatchAcxRequest((ACXCIRCUIT)Object, Request);
+ Request = NULL;
+ goto exit;
+ }
+
+exit:
+ if (Request != NULL)
+ {
+ WdfRequestCompleteWithInformation(Request, ntStatus, outDataCb);
+ }
+} // EvtAudioCpuResourcesCallback
diff --git a/audio/Acx/Samples/Common/CircuitHelper.h b/audio/Acx/Samples/Common/CircuitHelper.h
new file mode 100644
index 00000000..58938153
--- /dev/null
+++ b/audio/Acx/Samples/Common/CircuitHelper.h
@@ -0,0 +1,135 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ CircuitHelper.h
+
+Abstract:
+
+ This module contains helper functions for endpoints.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+// size_t
+// __inline
+// CODEC_ALIGN_SIZE_DOWN_CONSTANT(
+// IN size_t Length,
+// IN size_t AlignTo
+// )
+#define CODEC_ALIGN_SIZE_DOWN_CONSTANT(Length, AlignTo) ((Length) & ~((AlignTo)-1))
+
+#define CODEC_ALIGN_SIZE_DOWN CODEC_ALIGN_SIZE_DOWN_CONSTANT
+
+// size_t
+// __inline
+// CODEC_ALIGN_SIZE_UP_CONSTANT(
+// IN size_t Length,
+// IN size_t AlignTo
+// )
+#define CODEC_ALIGN_SIZE_UP_CONSTANT(Length, AlignTo) CODEC_ALIGN_SIZE_DOWN_CONSTANT((Length) + (AlignTo)-1, (AlignTo))
+
+#define CODEC_ALIGN_SIZE_UP CODEC_ALIGN_SIZE_UP_CONSTANT
+
+PAGED_CODE_SEG
+NTSTATUS
+Codec_GetModeFromAttributeList(
+ _In_ const PKSMULTIPLE_ITEM Attributes,
+ _In_ ULONG AttributesSize,
+ _Out_ GUID * SignalProcessingMode
+ );
+
+//
+// Enumeration visitor callback.
+//
+typedef
+NTSTATUS
+(EVT_KSATTRIBUTES_VISITOR)(
+ _In_ PKSATTRIBUTE AttributeHeader,
+ _In_ PVOID Context,
+ _Out_ BOOLEAN * bContinue
+ );
+
+typedef EVT_KSATTRIBUTES_VISITOR *PFN_KSATTRIBUTES_VISITOR;
+
+static
+PAGED_CODE_SEG
+EVT_KSATTRIBUTES_VISITOR FindKsAttributeByIdVisitor;
+
+PAGED_CODE_SEG
+NTSTATUS
+FindKsAttributeById(
+ _In_ const PKSMULTIPLE_ITEM Attributes,
+ _In_ ULONG AttributesSize,
+ _In_ const _GUID * AttributeId,
+ _In_ ULONG AttributeSize,
+ _Out_ PKSATTRIBUTE * AttributeHeader
+ );
+
+PAGED_CODE_SEG
+NTSTATUS
+TraverseKsAttributeList(
+ _In_ const PKSMULTIPLE_ITEM Attributes,
+ _In_ ULONG AttributesSize,
+ _In_ PFN_KSATTRIBUTES_VISITOR Visitor,
+ _In_ PVOID Context
+ );
+
+PAGED_CODE_SEG
+NTSTATUS AllocateFormat(
+ _In_ KSDATAFORMAT_WAVEFORMATEXTENSIBLE WaveFormat,
+ _In_ ACXCIRCUIT Circuit,
+ _In_ WDFDEVICE Device,
+ _Out_ ACXDATAFORMAT* Format
+);
+
+PAGED_CODE_SEG
+NTSTATUS CreateStreamBridge(
+ _In_ ACX_STREAM_BRIDGE_CONFIG StreamCfg,
+ _In_ ACXCIRCUIT Circuit,
+ _In_ ACXPIN Pin,
+ _In_ DSP_PIN_CONTEXT* PinCtx,
+ _In_ BOOL Render
+);
+
+PAGED_CODE_SEG
+NTSTATUS ConnectRenderCircuitElements(
+ _In_ ACXAUDIOENGINE AudioEngineElement,
+ _In_ ACXCIRCUIT Circuit
+);
+
+PAGED_CODE_SEG
+NTSTATUS CreateAudioJack(
+ _In_ ULONG ChannelMapping,
+ _In_ ULONG Color,
+ _In_ ACX_JACK_CONNECTION_TYPE ConnectionType,
+ _In_ ACX_JACK_GEO_LOCATION GeoLocation,
+ _In_ ACX_JACK_GEN_LOCATION GenLocation,
+ _In_ ACX_JACK_PORT_CONNECTION PortConnection,
+ _In_ ULONG Flags,
+ _In_ ACXPIN BridgePin
+);
+
+PAGED_CODE_SEG
+NTSTATUS EvtJackRetrievePresence(
+ _In_ ACXJACK Jack,
+ _In_ PBOOLEAN IsConnected
+);
+
+PAGED_CODE_SEG
+VOID CpuResourcesCallbackHelper(
+ _In_ WDFOBJECT Object,
+ _In_ WDFREQUEST Request,
+ _In_ ACXELEMENT Element
+);
+
diff --git a/audio/Acx/Samples/Common/KeywordDetector.cpp b/audio/Acx/Samples/Common/KeywordDetector.cpp
new file mode 100644
index 00000000..f3476745
--- /dev/null
+++ b/audio/Acx/Samples/Common/KeywordDetector.cpp
@@ -0,0 +1,484 @@
+/*++
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ KeywordDetector.cpp
+
+Abstract:
+
+ Sample keyword detector management.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include "private.h"
+#include "public.h"
+#include <ks.h>
+#include <mmsystem.h>
+#include <ksmedia.h>
+#include "streamengine.h"
+#include "KeywordDetector.h"
+
+PAGED_CODE_SEG
+CKeywordDetector::CKeywordDetector()
+ :
+ m_streamRunning(FALSE),
+ m_qpcStartCapture(0),
+ m_nLastQueuedPacket(-1),
+ m_SoundDetectorArmed1(FALSE),
+ m_SoundDetectorArmed2(FALSE),
+ m_SoundDetectorData1(0),
+ m_SoundDetectorData2(0),
+ m_ullKeywordStartTimestamp(0),
+ m_ullKeywordStopTimestamp(0)
+{
+ PAGED_CODE();
+
+ // Initialize our pool of packets and the list structures
+ KeInitializeSpinLock(&PacketPoolSpinLock);
+ KeInitializeSpinLock(&PacketFifoSpinLock);
+ ResetFifo();
+}
+
+PAGED_CODE_SEG
+_IRQL_requires_max_(PASSIVE_LEVEL)
+NTSTATUS CKeywordDetector::ReadKeywordTimestampRegistry()
+{
+ PAGED_CODE();
+
+ NTSTATUS ntStatus;
+ PDRIVER_OBJECT DriverObject;
+ HANDLE DriverKey;
+
+ RTL_QUERY_REGISTRY_TABLE paramTable[] = {
+ // QueryRoutine Flags Name EntryContext DefaultType DefaultData DefaultLength
+ { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"KeywordDetectorStartTimestamp", &m_ullKeywordStartTimestamp, (REG_QWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_QWORD, &m_ullKeywordStartTimestamp, sizeof(ULONGLONG) },
+ { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"KeywordDetectorStopTimestamp", &m_ullKeywordStopTimestamp, (REG_QWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_QWORD, &m_ullKeywordStopTimestamp, sizeof(ULONGLONG) },
+ { NULL, 0, NULL, NULL, 0, NULL, 0 }
+ };
+
+ DriverObject = WdfDriverWdmGetDriverObject(WdfGetDriver());
+ DriverKey = NULL;
+ ntStatus = IoOpenDriverRegistryKey(DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &DriverKey);
+
+ if (!NT_SUCCESS(ntStatus))
+ {
+ return ntStatus;
+ }
+
+ ntStatus = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
+ (PCWSTR) DriverKey,
+ &paramTable[0],
+ NULL,
+ NULL);
+ if (DriverKey)
+ {
+ ZwClose(DriverKey);
+ }
+
+ return ntStatus;
+}
+
+
+PAGED_CODE_SEG
+_IRQL_requires_max_(PASSIVE_LEVEL)
+NTSTATUS CKeywordDetector::ResetDetector(_In_ GUID eventId)
+{
+ PAGED_CODE();
+
+ if (eventId == CONTOSO_KEYWORD1)
+ {
+ m_SoundDetectorData1 = 0;
+ m_SoundDetectorArmed1 = FALSE;
+ }
+ else if(eventId == CONTOSO_KEYWORD2)
+ {
+ m_SoundDetectorData2 = 0;
+ m_SoundDetectorArmed2 = FALSE;
+ }
+ else if(eventId == GUID_NULL)
+ {
+ // When DownloadDetectorData is called to set the pattern for multiple keywords
+ // at once, all keyword detectors must be reset. Also used during keyword detector
+ // initialization and cleanup to restore it back to initial state and power down.
+ m_SoundDetectorData1 = 0;
+ m_SoundDetectorArmed1 = FALSE;
+ m_SoundDetectorData2 = 0;
+ m_SoundDetectorArmed2 = FALSE;
+ }
+ else
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+PAGED_CODE_SEG
+_IRQL_requires_max_(PASSIVE_LEVEL)
+NTSTATUS CKeywordDetector::DownloadDetectorData(_In_ GUID eventId, _In_ LONGLONG Data)
+{
+ PAGED_CODE();
+
+ // reset the detector for this event Id
+ ResetDetector(eventId);
+
+ // In this example, the driver supports detection data
+ // set with a single call for both detectors, or each
+ // detector set individually.
+ if (eventId == CONTOSO_KEYWORD1)
+ {
+ m_SoundDetectorData1 = Data;
+ }
+ else if(eventId == CONTOSO_KEYWORD2)
+ {
+ m_SoundDetectorData2 = Data;
+ }
+ else if(eventId == GUID_NULL)
+ {
+ // in this simplified example "Data" is set on both detectors,
+ // however in a real system "Data" could be a data structure which
+ // contains different values for each detector.
+ m_SoundDetectorData1 = m_SoundDetectorData2 = Data;
+ }
+ else
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+// The following function is only applicable to single keyword detection systems,
+// and assumes keyword detector #1.
+PAGED_CODE_SEG
+_IRQL_requires_max_(PASSIVE_LEVEL)
+NTSTATUS CKeywordDetector::GetDetectorData(_In_ GUID eventId, _Out_ LONGLONG *Data)
+{
+ PAGED_CODE();
+
+ if (eventId == CONTOSO_KEYWORD1)
+ {
+ *Data = m_SoundDetectorData1;
+ }
+ else if(eventId == CONTOSO_KEYWORD2)
+ {
+ *Data = m_SoundDetectorData2;
+ }
+ else
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+
+ return STATUS_SUCCESS;
+}
+
+PAGED_CODE_SEG
+_IRQL_requires_max_(PASSIVE_LEVEL)
+ULONGLONG CKeywordDetector::GetStartTimestamp()
+{
+ PAGED_CODE();
+
+ return m_ullKeywordStartTimestamp;
+}
+
+PAGED_CODE_SEG
+_IRQL_requires_max_(PASSIVE_LEVEL)
+ULONGLONG CKeywordDetector::GetStopTimestamp()
+{
+ PAGED_CODE();
+
+ return m_ullKeywordStopTimestamp;
+}
+
+PAGED_CODE_SEG
+_IRQL_requires_max_(PASSIVE_LEVEL)
+VOID CKeywordDetector::ResetFifo()
+{
+ PAGED_CODE();
+
+ m_qpcStartCapture = 0;
+ m_nLastQueuedPacket = (-1);
+ InitializeListHead(&PacketPoolHead);
+ InitializeListHead(&PacketFifoHead);
+
+ for (int i = 0; i < ARRAYSIZE(PacketPool); i++)
+ {
+ InsertTailList(&PacketPoolHead, &PacketPool[i].ListEntry);
+ }
+ return;
+}
+
+PAGED_CODE_SEG
+_IRQL_requires_max_(PASSIVE_LEVEL)
+NTSTATUS CKeywordDetector::SetArmed(_In_ GUID eventId, _In_ BOOLEAN Arm)
+{
+ PAGED_CODE();
+
+ BOOL previousArming = FALSE;
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ // the previous state is "armed" if either detector is armed.
+ // this reflects the fact that both detectors are sharing the
+ // same stream.
+ previousArming = m_SoundDetectorArmed1 || m_SoundDetectorArmed2;
+
+ if (eventId == CONTOSO_KEYWORD1)
+ {
+ m_SoundDetectorArmed1 = Arm;
+ }
+ else if(eventId == CONTOSO_KEYWORD2)
+ {
+ m_SoundDetectorArmed2 = Arm;
+ }
+ else
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (Arm && !previousArming && m_qpcStartCapture == 0)
+ {
+ StartBufferingStream();
+ }
+ else if (!Arm && previousArming && !m_streamRunning)
+ {
+ // if it's not actively streaming and everything has been disarmed,
+ // then stop buffering.
+ ResetFifo();
+ }
+
+ return ntStatus;
+}
+
+PAGED_CODE_SEG
+_IRQL_requires_max_(PASSIVE_LEVEL)
+NTSTATUS CKeywordDetector::GetArmed(_In_ GUID eventId, _Out_ BOOLEAN *Arm)
+{
+ PAGED_CODE();
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ if (eventId == CONTOSO_KEYWORD1)
+ {
+ *Arm = m_SoundDetectorArmed1;
+ }
+ else if(eventId == CONTOSO_KEYWORD2)
+ {
+ *Arm = m_SoundDetectorArmed2;
+ }
+ else
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ return ntStatus;
+}
+
+PAGED_CODE_SEG
+_IRQL_requires_max_(PASSIVE_LEVEL)
+VOID CKeywordDetector::Run()
+{
+ PAGED_CODE();
+
+ if (m_qpcStartCapture == 0)
+ {
+ StartBufferingStream();
+ }
+
+ m_streamRunning = TRUE;
+}
+
+PAGED_CODE_SEG
+_IRQL_requires_max_(PASSIVE_LEVEL)
+VOID CKeywordDetector::Stop()
+{
+ PAGED_CODE();
+
+ ResetFifo();
+ m_streamRunning = FALSE;
+}
+
+PAGED_CODE_SEG
+_IRQL_requires_max_(PASSIVE_LEVEL)
+VOID CKeywordDetector::StartBufferingStream()
+{
+ LARGE_INTEGER qpc;
+ LARGE_INTEGER qpcFrequency;
+
+ PAGED_CODE();
+
+ qpc = KeQueryPerformanceCounter(&qpcFrequency);
+ m_qpcStartCapture = qpc.QuadPart;
+ m_qpcFrequency = qpcFrequency.QuadPart;
+
+ return;
+}
+
+PAGED_CODE_SEG
+_IRQL_requires_max_(PASSIVE_LEVEL)
+VOID CKeywordDetector::NotifyDetection()
+{
+ PAGED_CODE();
+
+ // A detection will only happen if armed and the
+ // stream is already running. If there isn't a client
+ // running, then set the stream start time to align
+ // with this detection.
+ if (!m_streamRunning)
+ {
+ StartBufferingStream();
+
+ // The following code is for testing purposes only.
+ // m_qpcFrequency is defined to be the number of ticks in 1 second.
+ // Use the stream start time (the current time retrieved in StartBufferStream) to
+ // mark when the keyword ended, and the start time minus 1 second worth of ticks
+ // to mark when the keyword started. Also, adjust the stream start time to align
+ // to this new keyword start time, so that the simulated stream contains the full keyword.
+
+ m_ullKeywordStopTimestamp = m_qpcStartCapture; // stop time is the current time
+ m_qpcStartCapture = m_qpcStartCapture - m_qpcFrequency; // buffer start time is 1 second ago
+ m_ullKeywordStartTimestamp = m_qpcStartCapture; // buffer start time = keyword start time
+
+ }
+ else
+ {
+ // The following code is for testing purposes only.
+ // If the stream is running, we cannot modify qpcStartCapture to be in
+ // the past, so instead make the keyword start & stop times fit within the
+ // time period that the keyword has been running. If it has been running
+ // for more than 1 second, then set the keyword start time to be 1 second back
+ // into the stream, as though we just figured out there was a keyword there.
+ // If it has been running less than one second, then the keyword size ends
+ // up being however long the stream has been running.
+
+ LARGE_INTEGER qpc;
+ qpc = KeQueryPerformanceCounter(NULL);
+
+ m_ullKeywordStopTimestamp = qpc.QuadPart; // stop time is the current time
+
+ if (m_qpcStartCapture < (qpc.QuadPart - m_qpcFrequency))
+ {
+ m_ullKeywordStartTimestamp = (qpc.QuadPart - m_qpcFrequency);
+ }
+ else
+ {
+ m_ullKeywordStartTimestamp = m_qpcStartCapture;
+ }
+
+ }
+
+ return;
+}
+
+_IRQL_requires_min_(DISPATCH_LEVEL)
+VOID CKeywordDetector::DpcRoutine(_In_ LONGLONG PerformanceCounter, _In_ LONGLONG PerformanceFrequency)
+{
+ LONGLONG currentPacket;
+ LONGLONG packetsToQueue;
+
+ // TODO: the timer only runs when the stream is open, but really for KWS it should be building up a collection of burst data
+ // in the queue from 1.5 sec before the trigger happens. Is there some way to simulate that behavior here? Without doing that,
+ // there isn't really a burst that happens, just a trickle because while the timestamps will be right, the queue won't contain
+ // anything until the timer fires at the normal rate.
+
+ if (m_qpcStartCapture <= 0)
+ {
+ return;
+ }
+
+ currentPacket = (PerformanceCounter - m_qpcStartCapture) * (SamplesPerSecond / SamplesPerPacket) / PerformanceFrequency;
+ packetsToQueue = currentPacket - m_nLastQueuedPacket;
+
+ while (packetsToQueue > 0)
+ {
+ LIST_ENTRY* packetListEntry;
+ PACKET_ENTRY* packetEntry;
+
+ do
+ {
+ packetListEntry = ExInterlockedRemoveHeadList(&PacketPoolHead, &PacketPoolSpinLock);
+ if (packetListEntry != NULL) break;
+
+ // Pool is empty, no room to buffer more, an overrun is occurring. Drop and reuse the
+ // oldest packet from head of fifo.
+
+ // Since the pool is empty, the fifo should be full. However, although unlikely, the
+ // driver might empty the fifo before this routine removes a packet. In that case, the
+ // pool should have packets available again. Therefore this is a retry loop.
+ packetListEntry = ExInterlockedRemoveHeadList(&PacketFifoHead, &PacketFifoSpinLock);
+ if (packetListEntry != NULL) break;
+ } while (TRUE);
+
+ packetEntry = CONTAINING_RECORD(packetListEntry, PACKET_ENTRY, ListEntry);
+
+ packetEntry->PacketNumber = ++m_nLastQueuedPacket;
+ packetEntry->QpcWhenSampled = m_qpcStartCapture + (packetEntry->PacketNumber * PerformanceFrequency * SamplesPerPacket / SamplesPerSecond);
+
+ // TODO: this should really put something real in the buffer. Use the sine tone generator maybe?
+ RtlZeroMemory(&packetEntry->Samples[0], sizeof(packetEntry->Samples));
+
+ ExInterlockedInsertTailList(&PacketFifoHead, packetListEntry, &PacketFifoSpinLock);
+
+ packetsToQueue -= 1;
+ }
+}
+
+_IRQL_requires_max_(PASSIVE_LEVEL)
+NTSTATUS CKeywordDetector::GetReadPacket
+(
+ _In_ ULONG PacketCount,
+ _In_ ULONG PacketSize,
+ _Out_writes_(PacketSize) PVOID *Packets,
+ _Out_ ULONG *PacketNumber,
+ _Out_ ULONG64 *PerformanceCounterValue,
+ _Out_ BOOLEAN *MoreData
+)
+{
+ NTSTATUS ntStatus;
+ BYTE *packetData;
+ PACKET_ENTRY *packetEntry;
+ LIST_ENTRY *packetListEntry = NULL;
+
+ packetListEntry = ExInterlockedRemoveHeadList(&PacketFifoHead, &PacketFifoSpinLock);
+ if (packetListEntry == NULL)
+ {
+ ntStatus = STATUS_DEVICE_NOT_READY;
+ goto Exit;
+ }
+ packetEntry = CONTAINING_RECORD(packetListEntry, PACKET_ENTRY, ListEntry);
+
+ ntStatus = RtlLongLongToULong(packetEntry->PacketNumber, PacketNumber);
+ if (!NT_SUCCESS(ntStatus))
+ {
+ goto Exit;
+ }
+
+ packetData = (PBYTE) Packets[(*PacketNumber) % PacketCount];
+
+ *PerformanceCounterValue = packetEntry->QpcWhenSampled;
+ *MoreData = !IsListEmpty(&PacketFifoHead);
+
+ // TODO: the packet size here needs to line up to the packet size allocated.
+ // Also, handle the first packet offset
+ RtlCopyMemory(packetData, packetEntry->Samples, min(sizeof(packetEntry->Samples), PacketSize));
+
+Exit:
+ if (packetListEntry != NULL)
+ {
+ ExInterlockedInsertTailList(&PacketPoolHead, packetListEntry, &PacketPoolSpinLock);
+ }
+
+ return ntStatus;
+}
diff --git a/audio/Acx/Samples/Common/KeywordDetector.h b/audio/Acx/Samples/Common/KeywordDetector.h
new file mode 100644
index 00000000..2d5293b8
--- /dev/null
+++ b/audio/Acx/Samples/Common/KeywordDetector.h
@@ -0,0 +1,145 @@
+/*++
+
+Copyright (c) Microsoft Corporation All Rights Reserved
+
+Module Name:
+
+ KeywordDetector.h
+
+Abstract:
+
+ Sample Keyword Detector.
+
+
+--*/
+
+#pragma once
+
+typedef struct
+{
+ SOUNDDETECTOR_PATTERNHEADER Header;
+ LONGLONG ContosoDetectorConfigurationData;
+} CONTOSO_KEYWORDCONFIGURATION;
+
+typedef struct
+{
+ SOUNDDETECTOR_PATTERNHEADER Header;
+ LONGLONG ContosoDetectorResultData;
+ ULONGLONG KeywordStartTimestamp;
+ ULONGLONG KeywordStopTimestamp;
+ GUID EventId;
+} CONTOSO_KEYWORDDETECTIONRESULT;
+
+DEFINE_GUID(CONTOSO_KEYWORDCONFIGURATION_IDENTIFIER2,
+0x207f3d0c, 0x5c79, 0x496f, 0xa9, 0x4c, 0xd3, 0xd2, 0x93, 0x4d, 0xbf, 0xa9);
+
+// {A537F559-2D67-463B-B10E-BEB750A21F31}
+DEFINE_GUID(CONTOSO_KEYWORD1,
+0xa537f559, 0x2d67, 0x463b, 0xb1, 0xe, 0xbe, 0xb7, 0x50, 0xa2, 0x1f, 0x31);
+// {655E417A-80A5-4A77-B3F1-512EAF67ABCF}
+DEFINE_GUID(CONTOSO_KEYWORD2,
+0x655e417a, 0x80a5, 0x4a77, 0xb3, 0xf1, 0x51, 0x2e, 0xaf, 0x67, 0xab, 0xcf);
+
+#define KEYWORDDETECTOR_POOLTAG 'KWS0'
+
+class CKeywordDetector
+{
+public:
+ PAGED_CODE_SEG
+ CKeywordDetector();
+
+ _IRQL_requires_max_(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS ResetDetector(_In_ GUID eventId);
+
+ _IRQL_requires_max_(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS DownloadDetectorData(_In_ GUID eventId, _In_ LONGLONG Data);
+
+ _IRQL_requires_max_(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS GetDetectorData(_In_ GUID eventId, _Out_ LONGLONG *Data);
+
+ _IRQL_requires_max_(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ ULONGLONG GetStartTimestamp();
+
+ _IRQL_requires_max_(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ ULONGLONG GetStopTimestamp();
+
+ _IRQL_requires_max_(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS SetArmed(_In_ GUID eventId, _In_ BOOLEAN Arm);
+
+ _IRQL_requires_max_(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ VOID NotifyDetection();
+
+ _IRQL_requires_max_(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS GetArmed(_In_ GUID eventId, _Out_ BOOLEAN *Arm);
+
+ _IRQL_requires_max_(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ VOID Run();
+
+ _IRQL_requires_max_(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ VOID Stop();
+
+ _IRQL_requires_min_(DISPATCH_LEVEL)
+ VOID DpcRoutine(_In_ LONGLONG PerformanceCounter, _In_ LONGLONG PerformanceFrequency);
+
+ _IRQL_requires_max_(PASSIVE_LEVEL)
+ NTSTATUS GetReadPacket(_In_ ULONG PacketCount, _In_ ULONG PacketSize, _Out_writes_(PacketSize) PVOID *Packets, _Out_ ULONG *PacketNumber, _Out_ ULONGLONG *PerformanceCount, _Out_ BOOLEAN *MoreData);
+
+private:
+ _IRQL_requires_max_(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ VOID ResetFifo();
+
+ _IRQL_requires_max_(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS ReadKeywordTimestampRegistry();
+
+ _IRQL_requires_max_(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ VOID StartBufferingStream();
+
+ // The Contoso keyword detector processes 10ms packets of 16KHz 16-bit PCM
+ // audio samples
+ static const int SamplesPerSecond = 16000;
+ static const int SamplesPerPacket = (10 * SamplesPerSecond / 1000);
+
+ typedef struct
+ {
+ LIST_ENTRY ListEntry;
+ LONGLONG PacketNumber;
+ LONGLONG QpcWhenSampled;
+ UINT16 Samples[SamplesPerPacket];
+ } PACKET_ENTRY;
+
+ BOOLEAN m_streamRunning;
+
+ BOOLEAN m_SoundDetectorArmed1;
+ BOOLEAN m_SoundDetectorArmed2;
+ LONGLONG m_SoundDetectorData1;
+ LONGLONG m_SoundDetectorData2;
+
+ LONGLONG m_qpcStartCapture;
+ LONGLONG m_qpcFrequency;
+ LONGLONG m_nLastQueuedPacket;
+
+ ULONGLONG m_ullKeywordStartTimestamp;
+ ULONGLONG m_ullKeywordStopTimestamp;
+
+ KSPIN_LOCK PacketPoolSpinLock;
+ LIST_ENTRY PacketPoolHead;
+ PACKET_ENTRY PacketPool[1 * SamplesPerSecond / SamplesPerPacket]; // Enough storage for 1 second of audio data
+
+ KSPIN_LOCK PacketFifoSpinLock;
+ LIST_ENTRY PacketFifoHead;
+
+};
+
diff --git a/audio/Acx/Samples/Common/NewDelete.cpp b/audio/Acx/Samples/Common/NewDelete.cpp
new file mode 100644
index 00000000..583d36c5
--- /dev/null
+++ b/audio/Acx/Samples/Common/NewDelete.cpp
@@ -0,0 +1,91 @@
+/*++
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+Module Name:
+ newdelete.cpp
+Abstract:
+ Contains overloaded placement new and delete operators
+Environment:
+ Kernel mode
+--*/
+
+#include "private.h"
+#include "NewDelete.h"
+
+/*****************************************************************************
+ * ::new(POOL_FLAGS)
+ *****************************************************************************
+ * New function for creating objects with a specified pool flags.
+ */
+PVOID operator new(
+ _In_ size_t size,
+ _In_ POOL_FLAGS poolFlags
+)
+{
+ PVOID result = ExAllocatePool2(poolFlags, size, 'wNwS');
+
+ return result;
+}
+
+/*****************************************************************************
+ * ::new(POOL_FLAGS, TAG)
+ *****************************************************************************
+ * New function for creating objects with specified pool flags and allocation tag.
+ */
+PVOID operator new(
+ _In_ size_t size,
+ _In_ POOL_FLAGS poolFlags,
+ _In_ ULONG tag
+)
+{
+ PVOID result = ExAllocatePool2(poolFlags, size, tag);
+
+ return result;
+}
+
+void __cdecl operator delete(PVOID buffer)
+{
+ if (buffer)
+ {
+ ExFreePool(buffer);
+ }
+}
+
+void __cdecl operator delete(PVOID buffer, ULONG tag)
+{
+ if (buffer)
+ {
+ ExFreePoolWithTag(buffer, tag);
+ }
+}
+
+void __cdecl operator delete(_Pre_maybenull_ __drv_freesMem(Mem) PVOID buffer, _In_ size_t cbSize)
+{
+ UNREFERENCED_PARAMETER(cbSize);
+
+ if (buffer)
+ {
+ ExFreePool(buffer);
+ }
+}
+
+void __cdecl operator delete[](_Pre_maybenull_ __drv_freesMem(Mem) PVOID buffer)
+{
+ if (buffer)
+ {
+ ExFreePool(buffer);
+ }
+}
+
+void __cdecl operator delete[](_Pre_maybenull_ __drv_freesMem(Mem) PVOID buffer, _In_ size_t cbSize)
+{
+ UNREFERENCED_PARAMETER(cbSize);
+
+ if (buffer)
+ {
+ ExFreePool(buffer);
+ }
+}
+
diff --git a/audio/Acx/Samples/Common/NewDelete.h b/audio/Acx/Samples/Common/NewDelete.h
new file mode 100644
index 00000000..fb660ff9
--- /dev/null
+++ b/audio/Acx/Samples/Common/NewDelete.h
@@ -0,0 +1,58 @@
+/*++
+Copyright (c) Microsoft Corporation. All rights reserved.
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+Module Name:
+ NewDelete.h
+Abstract:
+ Contains overloaded placement new and delete operators
+Environment:
+ Kernel mode
+--*/
+
+/*****************************************************************************
+ * ::new(POOL_FLAGS)
+ *****************************************************************************
+ * New function for creating objects with a specified pool flags.
+ */
+PVOID operator new(
+ _In_ size_t size,
+ _In_ POOL_FLAGS poolFlags
+);
+
+/*****************************************************************************
+ * ::new(POOL_FLAGS, TAG)
+ *****************************************************************************
+ * New function for creating objects with specified pool flags and allocation tag.
+ */
+PVOID operator new(
+ _In_ size_t size,
+ _In_ POOL_FLAGS poolFlags,
+ _In_ ULONG tag
+);
+
+/*****************************************************************************
+ * ::delete()
+ *****************************************************************************
+ * Delete function.
+ */
+void __cdecl operator delete(PVOID buffer);
+
+/*****************************************************************************
+ * ::delete()
+ *****************************************************************************
+ * Delete function.
+ */
+void __cdecl operator delete(PVOID buffer, ULONG tag);
+
+void __cdecl operator delete[](PVOID pVoid, _In_ size_t cbSize);
+
+void __cdecl operator delete(_Pre_maybenull_ __drv_freesMem(Mem) PVOID buffer, _In_ size_t cbSize);
+
+void __cdecl operator delete[](_Pre_maybenull_ __drv_freesMem(Mem) PVOID buffer);
+
+void __cdecl operator delete[](_Pre_maybenull_ __drv_freesMem(Mem) PVOID buffer, _In_ size_t cbSize);
+
+
diff --git a/audio/Acx/Samples/Common/Private.h b/audio/Acx/Samples/Common/Private.h
new file mode 100644
index 00000000..da89ef78
--- /dev/null
+++ b/audio/Acx/Samples/Common/Private.h
@@ -0,0 +1,922 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ Private.h
+
+Abstract:
+
+ Contains structure definitions and function prototypes private to
+ the Common library.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#ifndef _PRIVATE_H_
+#define _PRIVATE_H_
+
+
+#include <wdm.h>
+#include <windef.h>
+#include "cpp_utils.h"
+#include <mmsystem.h>
+#include <ks.h>
+#include <ksmedia.h>
+#include "NewDelete.h"
+
+/* make prototypes usable from C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <initguid.h>
+#include <ntddk.h>
+#include <ntstrsafe.h>
+#include <ntintsafe.h>
+#include "Trace.h"
+
+#include <wdf.h>
+#include <acx.h>
+
+#define PAGED_CODE_SEG __declspec(code_seg("PAGE"))
+#define INIT_CODE_SEG __declspec(code_seg("INIT"))
+
+extern const GUID DSP_CIRCUIT_SPEAKER_GUID;
+extern const GUID DSP_CIRCUIT_MICROPHONE_GUID;
+extern const GUID DSP_CIRCUIT_UNIVERSALJACK_RENDER_GUID;
+extern const GUID DSP_CIRCUIT_UNIVERSALJACK_CAPTURE_GUID;
+
+/////////////////////////////////////////////////////////
+//
+// Driver wide definitions
+//
+
+// Copied from cfgmgr32.h
+#if !defined(MAX_DEVICE_ID_LEN)
+#define MAX_DEVICE_ID_LEN 200
+#endif
+
+// Number of millisecs per sec.
+#define MS_PER_SEC 1000
+
+// Number of hundred nanosecs per sec.
+#define HNS_PER_SEC 10000000
+
+#define REQUEST_TIMEOUT_SECONDS 5
+
+#undef MIN
+#undef MAX
+#define MIN(a,b) ((a) > (b) ? (b) : (a))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+#ifndef BOOL
+typedef int BOOL;
+#endif
+
+#ifndef SIZEOF_ARRAY
+#define SIZEOF_ARRAY(ar) (sizeof(ar)/sizeof((ar)[0]))
+#endif // !defined(SIZEOF_ARRAY)
+
+#ifndef RGB
+#define RGB(r, g, b) (DWORD)(r << 16 | g << 8 | b)
+#endif
+
+#define ALL_CHANNELS_ID UINT32_MAX
+#define MAX_CHANNELS 2
+
+//
+// Ks support.
+//
+#define KSPROPERTY_TYPE_ALL KSPROPERTY_TYPE_BASICSUPPORT | \
+ KSPROPERTY_TYPE_GET | \
+ KSPROPERTY_TYPE_SET
+
+//
+// Define struct to hold signal processing mode and corresponding
+// list of supported formats.
+//
+typedef struct
+{
+ GUID SignalProcessingMode;
+ KSDATAFORMAT_WAVEFORMATEXTENSIBLE* FormatList;
+ ULONG FormatListCount;
+} SUPPORTED_FORMATS_LIST;
+
+//
+// Define CAPTURE device context.
+//
+typedef struct _CAPTURE_DEVICE_CONTEXT {
+ ACXCIRCUIT Circuit;
+ BOOLEAN FirstTimePrepareHardware;
+} CAPTURE_DEVICE_CONTEXT, * PCAPTURE_DEVICE_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(CAPTURE_DEVICE_CONTEXT, GetCaptureDeviceContext)
+
+//
+// Define RENDER device context.
+//
+typedef struct _RENDER_DEVICE_CONTEXT {
+ ACXCIRCUIT Circuit;
+ BOOLEAN FirstTimePrepareHardware;
+} RENDER_DEVICE_CONTEXT, * PRENDER_DEVICE_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(RENDER_DEVICE_CONTEXT, GetRenderDeviceContext)
+
+//
+// Define circuit/stream element context.
+//
+typedef struct _ELEMENT_CONTEXT {
+ BOOLEAN Dummy;
+} ELEMENT_CONTEXT, *PELEMENT_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(ELEMENT_CONTEXT, GetElementContext)
+
+//
+// Define circuit/stream element context.
+//
+typedef struct _MUTE_ELEMENT_CONTEXT {
+ BOOL MuteState[MAX_CHANNELS];
+} MUTE_ELEMENT_CONTEXT, *PMUTE_ELEMENT_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(MUTE_ELEMENT_CONTEXT, GetMuteElementContext)
+
+//
+// Define circuit/stream element context.
+//
+typedef struct _VOLUME_ELEMENT_CONTEXT {
+ LONG VolumeLevel[MAX_CHANNELS];
+} VOLUME_ELEMENT_CONTEXT, *PVOLUME_ELEMENT_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(VOLUME_ELEMENT_CONTEXT, GetVolumeElementContext)
+
+#define VOLUME_STEPPING 0x8000
+#define VOLUME_LEVEL_MAXIMUM 0x00000000
+#define VOLUME_LEVEL_MINIMUM (-96 * 0x10000)
+
+//
+// Define mute timer context.
+//
+typedef struct _MUTE_TIMER_CONTEXT {
+ ACXELEMENT MuteElement;
+ ACXEVENT Event;
+} MUTE_TIMER_CONTEXT, *PMUTE_TIMER_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(MUTE_TIMER_CONTEXT, GetMuteTimerContext)
+
+//
+// Define format context.
+//
+typedef struct _FORMAT_CONTEXT {
+ BOOLEAN Dummy;
+} FORMAT_CONTEXT, *PFORMAT_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(FORMAT_CONTEXT, GetFormatContext)
+
+//
+// Define jack context.
+//
+typedef struct _JACK_CONTEXT {
+ ULONG Dummy;
+} JACK_CONTEXT, * PJACK_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(JACK_CONTEXT, GetJackContext)
+
+//
+// Define audio engine context.
+//
+typedef struct _ENGINE_CONTEXT {
+ ACXDATAFORMAT MixFormat;
+} ENGINE_CONTEXT, * PENGINE_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(ENGINE_CONTEXT, GetEngineContext)
+
+//
+// Define stream audio engine context.
+//
+typedef struct _STREAMAUDIOENGINE_CONTEXT {
+ BOOLEAN Dummy;
+} STREAMAUDIOENGINE_CONTEXT, * PSTREAMAUDIOENGINE_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(STREAMAUDIOENGINE_CONTEXT, GetStreamAudioEngineContext)
+
+//
+// Define keyword spotter context
+//
+typedef struct _KEYWORDSPOTTER_CONTEXT {
+ ACXPNPEVENT Event;
+ PVOID KeywordDetector;
+} KEYWORDSPOTTER_CONTEXT, * PKEYWORDSPOTTER_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(KEYWORDSPOTTER_CONTEXT, GetKeywordSpotterContext)
+
+//
+// Define pnp event context.
+//
+typedef struct _PNPEVENT_CONTEXT {
+ BOOLEAN Dummy;
+} PNPEVENT_CONTEXT, * PPNPEVENT_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(PNPEVENT_CONTEXT, GetPnpEventContext)
+
+//
+// Define peakmeter element context.
+//
+typedef struct _PEAKMETER_ELEMENT_CONTEXT {
+ LONG PeakMeterLevel[MAX_CHANNELS];
+} PEAKMETER_ELEMENT_CONTEXT, * PPEAKMETER_ELEMENT_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(PEAKMETER_ELEMENT_CONTEXT, GetPeakMeterElementContext)
+
+//
+// Define DSP circuit's peakmeter element context.
+//
+typedef struct _DSP_PEAKMETER_ELEMENT_CONTEXT
+{
+ PVOID peakMeter;
+} DSP_PEAKMETER_ELEMENT_CONTEXT, *PDSP_PEAKMETER_ELEMENT_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DSP_PEAKMETER_ELEMENT_CONTEXT, GetDspPeakMeterElementContext)
+
+//
+// Define stream engine context.
+//
+typedef struct _STREAMENGINE_CONTEXT {
+ PVOID StreamEngine;
+} STREAMENGINE_CONTEXT, * PSTREAMENGINE_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(STREAMENGINE_CONTEXT, GetStreamEngineContext)
+
+#define PEAKMETER_STEPPING_DELTA 0x1000
+#define PEAKMETER_MAXIMUM LONG_MAX
+#define PEAKMETER_MINIMUM LONG_MIN
+
+/////////////////////////////////////////////////////////////
+// Codec driver defintions
+//
+
+typedef enum _CODEC_PIN_TYPE {
+ CodecPinTypeHost,
+ CodecPinTypeOffload,
+ CodecPinTypeLoopback,
+ CodecPinTypeKeyword,
+ CodecPinTypeDevice
+} CODEC_PIN_TYPE, * PCODEC_PIN_TYPE;
+
+typedef struct _CODEC_PIN_CONTEXT {
+ CODEC_PIN_TYPE CodecPinType;
+} CODEC_PIN_CONTEXT, * PCODEC_PIN_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(CODEC_PIN_CONTEXT, GetCodecPinContext)
+
+///////////////////////////////////////////////////////////
+// Dsp driver definitions
+//
+
+typedef enum {
+ CaptureHostPin = 0,
+ CaptureBridgePin = 1,
+ CaptureKWSPin = 2,
+ CapturePinCount = 3
+} CAPTURE_PIN_TYPE;
+
+typedef enum {
+ RenderHostPin = 0,
+ RenderOffloadPin = 1,
+ RenderLoopbackPin = 2,
+ RenderBridgePin = 3,
+ RenderPinCount = 4
+} RENDER_PIN_TYPE;
+
+typedef struct _DSP_PIN_CONTEXT {
+ ACXTARGETCIRCUIT TargetCircuit;
+ ULONG TargetPinId;
+ RENDER_PIN_TYPE RenderPinType;
+ CAPTURE_PIN_TYPE CapturePinType;
+
+ // The stream bridge below will only be valid for the Capture circuit Bridge Pin
+
+ // Host stream bridge will be used to ensure host stream creations are passed
+ // to the downlevel circuits. Since the HostStreamBridge won't have InModes set,
+ // the ACX framework will not add streams automatically. We will add streams for
+ // non KWS pin.
+ ACXSTREAMBRIDGE HostStreamBridge;
+} DSP_PIN_CONTEXT, * PDSP_PIN_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DSP_PIN_CONTEXT, GetDspPinContext)
+
+/////////////////////////////////////////////////////////////
+// Multicircuit Dsp driver definitions
+//
+
+//
+// Circuit context for multi circuit dsp circuits.
+//
+typedef struct _DSP_CIRCUIT_CONTEXT
+{
+ ACXAUDIOENGINE AudioEngineElement;
+ ACXPEAKMETER PeakMeterElement;
+ PVOID peakMeter;
+ ACXKEYWORDSPOTTER KeywordSpotter;
+ BOOLEAN IsRenderCircuit;
+} DSP_CIRCUIT_CONTEXT, *PDSP_CIRCUIT_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DSP_CIRCUIT_CONTEXT, GetDspCircuitContext)
+
+typedef struct _DSP_ENGINE_CONTEXT
+{
+ ACXDATAFORMAT MixFormat;
+ BOOLEAN GFxEnabled;
+} DSP_ENGINE_CONTEXT, *PDSP_ENGINE_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DSP_ENGINE_CONTEXT, GetDspEngineContext)
+
+typedef struct _DSP_STREAMAUDIOENGINE_CONTEXT
+{
+ BOOLEAN LFxEnabled;
+} DSP_STREAMAUDIOENGINE_CONTEXT, *PDSP_STREAMAUDIOENGINE_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DSP_STREAMAUDIOENGINE_CONTEXT, GetDspStreamAudioEngineContext)
+
+/////////////////////////////////////////////////////////
+//
+// Codec Render (speaker) definitions
+//
+
+//
+// Define render circuit context.
+//
+typedef struct _CODEC_RENDER_CIRCUIT_CONTEXT {
+ ACXVOLUME VolumeElement;
+ ACXMUTE MuteElement;
+ ACXPEAKMETER PeakMeterElement;
+ ACXAUDIOENGINE AudioEngineElement;
+} CODEC_RENDER_CIRCUIT_CONTEXT, * PCODEC_RENDER_CIRCUIT_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(CODEC_RENDER_CIRCUIT_CONTEXT, GetRenderCircuitContext)
+
+typedef enum {
+ CodecRenderHostPin = 0,
+ CodecRenderBridgePin = 1,
+ CodecRenderPinCount = 2
+} CODEC_RENDER_PINS;
+
+typedef enum {
+ RenderVolumeIndex = 0,
+ RenderMuteIndex = 1,
+ RenderElementCount = 2
+} CODEC_RENDER_ELEMENTS;
+
+// Render callbacks.
+
+EVT_ACX_CIRCUIT_CREATE_STREAM CodecR_EvtCircuitCreateStream;
+EVT_ACX_CIRCUIT_POWER_UP CodecR_EvtCircuitPowerUp;
+EVT_ACX_CIRCUIT_POWER_DOWN CodecR_EvtCircuitPowerDown;
+EVT_ACX_STREAM_SET_RENDER_PACKET CodecR_EvtStreamSetRenderPacket;
+EVT_ACX_STREAM_GET_CAPTURE_PACKET CodecR_EvtStreamGetLoopbackPacket;
+EVT_ACX_PIN_SET_DATAFORMAT CodecR_EvtAcxPinSetDataFormat;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP CodecR_EvtPinContextCleanup;
+EVT_ACX_MUTE_ASSIGN_STATE CodecR_EvtMuteAssignState;
+EVT_ACX_MUTE_RETRIEVE_STATE CodecR_EvtMuteRetrieveState;
+EVT_ACX_VOLUME_ASSIGN_LEVEL CodecR_EvtVolumeAssignLevel;
+EVT_ACX_VOLUME_RETRIEVE_LEVEL CodecR_EvtVolumeRetrieveLevel;
+EVT_ACX_PEAKMETER_RETRIEVE_LEVEL CodecR_EvtPeakMeterRetrieveLevelCallback;
+EVT_ACX_RAMPED_VOLUME_ASSIGN_LEVEL CodecR_EvtRampedVolumeAssignLevel;
+EVT_ACX_AUDIOENGINE_RETRIEVE_BUFFER_SIZE_LIMITS CodecR_EvtAcxAudioEngineRetrieveBufferSizeLimits;
+EVT_ACX_AUDIOENGINE_RETRIEVE_EFFECTS_STATE CodecR_EvtAcxAudioEngineRetrieveEffectsState;
+EVT_ACX_AUDIOENGINE_ASSIGN_EFFECTS_STATE CodecR_EvtAcxAudioEngineAssignEffectsState;
+EVT_ACX_AUDIOENGINE_ASSIGN_ENGINE_FORMAT CodecR_EvtAcxAudioEngineAssignEngineDeviceFormat;
+EVT_ACX_AUDIOENGINE_RETRIEVE_ENGINE_FORMAT CodecR_EvtAcxAudioEngineRetrieveEngineMixFormat;
+EVT_ACX_STREAMAUDIOENGINE_RETRIEVE_EFFECTS_STATE CodecR_EvtAcxStreamAudioEngineRetrieveEffectsState;
+EVT_ACX_STREAMAUDIOENGINE_ASSIGN_EFFECTS_STATE CodecR_EvtAcxStreamAudioEngineAssignEffectsState;
+EVT_ACX_STREAMAUDIOENGINE_RETRIEVE_PRESENTATION_POSITION CodecR_EvtAcxStreamAudioEngineRetrievePresentationPosition;
+EVT_ACX_STREAMAUDIOENGINE_ASSIGN_CURRENT_WRITE_POSITION CodecR_EvtAcxStreamAudioEngineAssignCurrentWritePosition;
+EVT_ACX_STREAMAUDIOENGINE_RETRIEVE_LINEAR_BUFFER_POSITION CodecR_EvtAcxStreamAudioEngineRetrieveLinearBufferPosition;
+EVT_ACX_STREAMAUDIOENGINE_ASSIGN_LAST_BUFFER_POSITION CodecR_EvtAcxStreamAudioEngineAssignLastBufferPosition;
+EVT_ACX_STREAMAUDIOENGINE_ASSIGN_LOOPBACK_PROTECTION CodecR_EvtAcxStreamAudioEngineAssignLoopbackProtection;
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecR_CreateRenderCircuit(
+ _In_ WDFDEVICE Device,
+ _In_ const GUID * ComponentGuid,
+ _In_ const UNICODE_STRING * CircuitName,
+ _Out_ ACXCIRCUIT * Circuit
+);
+
+/////////////////////////////////////////////////////////
+//
+// Codec Capture (microphone) definitions
+//
+
+//
+// Define capture circuit context.
+//
+typedef struct _CODEC_CAPTURE_CIRCUIT_CONTEXT {
+ ACXVOLUME BoostElement;
+ ACXVOLUME VolumeElement;
+ ACXKEYWORDSPOTTER KeywordSpotter;
+} CODEC_CAPTURE_CIRCUIT_CONTEXT, * PCODEC_CAPTURE_CIRCUIT_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(CODEC_CAPTURE_CIRCUIT_CONTEXT, GetCaptureCircuitContext)
+
+typedef enum {
+ CodecCaptureHostPin = 0,
+ CodecCaptureBridgePin = 1,
+ CodecCapturePinCount = 2
+} CODEC_CAPTURE_PINS;
+
+typedef enum {
+ CaptureVolumeIndex = 0,
+ CaptureElementCount = 1
+} CAPTURE_ELEMENTS;
+
+// Capture callbacks.
+
+EVT_ACX_CIRCUIT_CREATE_STREAM CodecC_EvtCircuitCreateStream;
+EVT_ACX_CIRCUIT_POWER_UP CodecC_EvtCircuitPowerUp;
+EVT_ACX_CIRCUIT_POWER_DOWN CodecC_EvtCircuitPowerDown;
+EVT_ACX_VOLUME_ASSIGN_LEVEL CodecC_EvtVolumeAssignLevelCallback;
+EVT_ACX_VOLUME_RETRIEVE_LEVEL CodecC_EvtVolumeRetrieveLevelCallback;
+EVT_ACX_VOLUME_ASSIGN_LEVEL CodecC_EvtBoostAssignLevelCallback;
+EVT_ACX_VOLUME_RETRIEVE_LEVEL CodecC_EvtBoostRetrieveLevelCallback;
+EVT_ACX_STREAM_GET_CAPTURE_PACKET CodecC_EvtStreamGetCapturePacket;
+EVT_ACX_PIN_SET_DATAFORMAT CodecC_EvtAcxPinSetDataFormat;
+EVT_ACX_PIN_RETRIEVE_NAME CodecC_EvtAcxPinRetrieveName;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP CodecC_EvtPinContextCleanup;
+EVT_ACX_KEYWORDSPOTTER_RETRIEVE_ARM CodecC_EvtAcxKeywordSpotterRetrieveArm;
+EVT_ACX_KEYWORDSPOTTER_ASSIGN_ARM CodecC_EvtAcxKeywordSpotterAssignArm;
+EVT_ACX_KEYWORDSPOTTER_ASSIGN_PATTERNS CodecC_EvtAcxKeywordSpotterAssignPatterns;
+EVT_ACX_KEYWORDSPOTTER_ASSIGN_RESET CodecC_EvtAcxKeywordSpotterAssignReset;
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecC_CreateCaptureCircuit(
+ _In_ WDFDEVICE Device,
+ _In_ const GUID * ComponentGuid,
+ _In_ const GUID * MicCustomName,
+ _In_ const UNICODE_STRING * CircuitName,
+ _Out_ ACXCIRCUIT * Circuit
+);
+
+/////////////////////////////////////////////////////////
+//
+// MicArray definitions
+//
+
+//
+// Define MicArray circuit context.
+//
+typedef struct _MICARRAY_CIRCUIT_CONTEXT {
+ ACXMUTE MuteElement;
+ ACXVOLUME VolumeElement;
+ ACXPEAKMETER PeakMeterElement;
+ ACXKEYWORDSPOTTER KeywordSpotter;
+} MICARRAY_CIRCUIT_CONTEXT, * PMICARRAY_CIRCUIT_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(MICARRAY_CIRCUIT_CONTEXT, GetMicArrayCircuitContext)
+
+typedef enum {
+ MicArrayVolumeIndex = 0,
+ MicArrayMuteIndex = 1,
+ MicArrayPeakmeterIndex = 2,
+ MicArrayKWSIndex = 3,
+ MicArrayElementCount = 4
+} MICARRAY_ELEMENTS;
+
+// MicArray callbacks.
+
+EVT_ACX_MUTE_ASSIGN_STATE MicArray_EvtMuteAssignState;
+EVT_ACX_MUTE_RETRIEVE_STATE MicArray_EvtMuteRetrieveState;
+EVT_ACX_PEAKMETER_RETRIEVE_LEVEL MicArray_EvtPeakMeterRetrieveLevelCallback;
+EVT_ACX_CIRCUIT_CREATE_STREAM MicArray_EvtCircuitCreateStream;
+EVT_ACX_CIRCUIT_POWER_UP MicArray_EvtCircuitPowerUp;
+EVT_ACX_CIRCUIT_POWER_DOWN MicArray_EvtCircuitPowerDown;
+EVT_ACX_VOLUME_ASSIGN_LEVEL MicArray_EvtVolumeAssignLevelCallback;
+EVT_ACX_VOLUME_RETRIEVE_LEVEL MicArray_EvtVolumeRetrieveLevelCallback;
+EVT_ACX_STREAM_GET_CAPTURE_PACKET MicArray_EvtStreamGetCapturePacket;
+EVT_ACX_PIN_SET_DATAFORMAT MicArray_EvtAcxPinSetDataFormat;
+EVT_ACX_PIN_RETRIEVE_NAME MicArray_EvtAcxPinRetrieveName;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP MicArray_EvtPinContextCleanup;
+EVT_ACX_KEYWORDSPOTTER_RETRIEVE_ARM MicArray_EvtAcxKeywordSpotterRetrieveArm;
+EVT_ACX_KEYWORDSPOTTER_ASSIGN_ARM MicArray_EvtAcxKeywordSpotterAssignArm;
+EVT_ACX_KEYWORDSPOTTER_ASSIGN_PATTERNS MicArray_EvtAcxKeywordSpotterAssignPatterns;
+EVT_ACX_KEYWORDSPOTTER_ASSIGN_RESET MicArray_EvtAcxKeywordSpotterAssignReset;
+EVT_ACX_PIN_CONNECTED MicArray_EvtPinConnected;
+EVT_ACX_PIN_DISCONNECTED MicArray_EvtPinDisconnected;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP MicArray_EvtDeviceContextCleanup;
+EVT_ACX_OBJECT_PROCESS_REQUEST MicArray_EvtPinProposeDataFormat2Callback;
+EVT_ACX_OBJECT_PREPROCESS_REQUEST MicArray_EvtAudioCpuResourcesCallback;
+
+PAGED_CODE_SEG
+NTSTATUS
+MicArray_CreateCaptureCircuit(
+ _In_ WDFDEVICE Device,
+ _In_ GUID ComponentGuid,
+ _In_ GUID MicCustomName,
+ _In_ UNICODE_STRING CircuitName,
+ _Out_ ACXCIRCUIT * Circuit
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+MicArray_SetPowerPolicy(
+ _In_ WDFDEVICE Device
+);
+
+/////////////////////////////////////////////////////////
+//
+// Microphone (external: headphone) definitions
+//
+
+//
+// Define MicrophoneHp circuit context.
+//
+typedef struct _MICROPHONEHP_CIRCUIT_CONTEXT {
+ ACXMUTE MuteElement;
+ ACXVOLUME VolumeElement;
+ ACXPEAKMETER PeakMeterElement;
+} MICROPHONEHP_CIRCUIT_CONTEXT, * PMICROPHONEHP_CIRCUIT_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(MICROPHONEHP_CIRCUIT_CONTEXT, GetMicrophoneHpCircuitContext)
+
+typedef enum {
+ MicrophoneHpVolumeIndex = 0,
+ MicrophoneHpMuteIndex = 1,
+ MicrophoneHpPeakmeterIndex = 2,
+ MicrophoneHpElementCount = 3
+} MICROPHONEHP_ELEMENTS;
+
+// MicrophoneHp callbacks.
+
+EVT_ACX_MUTE_ASSIGN_STATE MicrophoneHp_EvtMuteAssignState;
+EVT_ACX_MUTE_RETRIEVE_STATE MicrophoneHp_EvtMuteRetrieveState;
+EVT_ACX_PEAKMETER_RETRIEVE_LEVEL MicrophoneHp_EvtPeakMeterRetrieveLevelCallback;
+EVT_ACX_CIRCUIT_CREATE_STREAM MicrophoneHp_EvtCircuitCreateStream;
+EVT_ACX_CIRCUIT_POWER_UP MicrophoneHp_EvtCircuitPowerUp;
+EVT_ACX_CIRCUIT_POWER_DOWN MicrophoneHp_EvtCircuitPowerDown;
+EVT_ACX_VOLUME_ASSIGN_LEVEL MicrophoneHp_EvtVolumeAssignLevelCallback;
+EVT_ACX_VOLUME_RETRIEVE_LEVEL MicrophoneHp_EvtVolumeRetrieveLevelCallback;
+EVT_ACX_STREAM_GET_CAPTURE_PACKET MicrophoneHp_EvtStreamGetCapturePacket;
+EVT_ACX_PIN_SET_DATAFORMAT MicrophoneHp_EvtAcxPinSetDataFormat;
+EVT_ACX_PIN_RETRIEVE_NAME MicrophoneHp_EvtAcxPinRetrieveName;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP MicrophoneHp_EvtPinContextCleanup;
+EVT_ACX_PIN_CONNECTED MicrophoneHp_EvtPinConnected;
+EVT_ACX_PIN_DISCONNECTED MicrophoneHp_EvtPinDisconnected;
+EVT_ACX_OBJECT_PREPROCESS_REQUEST MicrophoneHp_EvtAudioCpuResourcesCallback;
+
+PAGED_CODE_SEG
+NTSTATUS
+MicrophoneHp_CreateCaptureCircuit(
+ _In_ WDFDEVICE Device,
+ _In_ GUID ComponentGuid,
+ _In_ GUID MicCustomName,
+ _In_ UNICODE_STRING CircuitName,
+ _Out_ ACXCIRCUIT * Circuit
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+MicrophoneHp_SetPowerPolicy(
+ _In_ WDFDEVICE Device
+);
+
+/////////////////////////////////////////////////////////
+//
+// Speaker definitions
+//
+
+//
+// Define circuit context for Speaker and SpeakerHp.
+//
+typedef struct _DSP_RENDER_CIRCUIT_CONTEXT {
+ ACXPEAKMETER PeakMeterElement;
+ ACXAUDIOENGINE AudioEngineElement;
+ PVOID PeakMeter;
+} DSP_RENDER_CIRCUIT_CONTEXT, * PDSP_RENDER_CIRCUIT_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DSP_RENDER_CIRCUIT_CONTEXT, GetSpeakerCircuitContext)
+
+// Speaker callbacks.
+
+EVT_ACX_CIRCUIT_CREATE_STREAM Speaker_EvtCircuitCreateStream;
+EVT_ACX_CIRCUIT_POWER_UP Speaker_EvtCircuitPowerUp;
+EVT_ACX_CIRCUIT_POWER_DOWN Speaker_EvtCircuitPowerDown;
+EVT_ACX_STREAM_SET_RENDER_PACKET Speaker_EvtStreamSetRenderPacket;
+EVT_ACX_STREAM_GET_CAPTURE_PACKET Speaker_EvtStreamGetLoopbackPacket;
+EVT_ACX_PIN_SET_DATAFORMAT Speaker_EvtAcxPinSetDataFormat;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP Speaker_EvtPinContextCleanup;
+EVT_ACX_PIN_CONNECTED Speaker_EvtPinConnected;
+EVT_ACX_PIN_DISCONNECTED Speaker_EvtPinDisconnected;
+
+//Render Audio Engine callbacks.
+
+EVT_ACX_MUTE_ASSIGN_STATE Speaker_EvtMuteAssignState;
+EVT_ACX_MUTE_RETRIEVE_STATE Speaker_EvtMuteRetrieveState;
+EVT_ACX_VOLUME_RETRIEVE_LEVEL Speaker_EvtVolumeRetrieveLevel;
+EVT_ACX_PEAKMETER_RETRIEVE_LEVEL Speaker_EvtPeakMeterRetrieveLevelCallback;
+EVT_ACX_RAMPED_VOLUME_ASSIGN_LEVEL Speaker_EvtRampedVolumeAssignLevel;
+EVT_ACX_AUDIOENGINE_RETRIEVE_BUFFER_SIZE_LIMITS Speaker_EvtAcxAudioEngineRetrieveBufferSizeLimits;
+EVT_ACX_AUDIOENGINE_RETRIEVE_EFFECTS_STATE Speaker_EvtAcxAudioEngineRetrieveEffectsState;
+EVT_ACX_AUDIOENGINE_ASSIGN_EFFECTS_STATE Speaker_EvtAcxAudioEngineAssignEffectsState;
+EVT_ACX_AUDIOENGINE_ASSIGN_ENGINE_FORMAT Speaker_EvtAcxAudioEngineAssignEngineDeviceFormat;
+EVT_ACX_AUDIOENGINE_RETRIEVE_ENGINE_FORMAT Speaker_EvtAcxAudioEngineRetrieveEngineMixFormat;
+EVT_ACX_STREAMAUDIOENGINE_RETRIEVE_EFFECTS_STATE Speaker_EvtAcxStreamAudioEngineRetrieveEffectsState;
+EVT_ACX_STREAMAUDIOENGINE_ASSIGN_EFFECTS_STATE Speaker_EvtAcxStreamAudioEngineAssignEffectsState;
+EVT_ACX_STREAMAUDIOENGINE_RETRIEVE_PRESENTATION_POSITION Speaker_EvtAcxStreamAudioEngineRetrievePresentationPosition;
+EVT_ACX_STREAMAUDIOENGINE_ASSIGN_CURRENT_WRITE_POSITION Speaker_EvtAcxStreamAudioEngineAssignCurrentWritePosition;
+EVT_ACX_STREAMAUDIOENGINE_RETRIEVE_LINEAR_BUFFER_POSITION Speaker_EvtAcxStreamAudioEngineRetrieveLinearBufferPosition;
+EVT_ACX_STREAMAUDIOENGINE_ASSIGN_LAST_BUFFER_POSITION Speaker_EvtAcxStreamAudioEngineAssignLastBufferPosition;
+EVT_ACX_STREAMAUDIOENGINE_ASSIGN_LOOPBACK_PROTECTION Speaker_EvtAcxStreamAudioEngineAssignLoopbackProtection;
+
+PAGED_CODE_SEG
+NTSTATUS
+Speaker_SetPowerPolicy(
+ _In_ WDFDEVICE Device
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+Speaker_CreateRenderCircuit(
+ _In_ WDFDEVICE Device,
+ _In_ GUID ComponentGuid,
+ _In_ UNICODE_STRING CircuitName,
+ _In_ BOOLEAN IsHeadphones,
+ _Out_ ACXCIRCUIT * Circuit
+);
+
+/////////////////////////////////////////////////////////
+//
+// HDMI definitions
+//
+
+//
+// Define HDMI circuit context.
+//
+typedef struct _DSP_HDMI_CIRCUIT_CONTEXT {
+ ACXVOLUME VolumeElement;
+ ACXMUTE MuteElement;
+ ACXPEAKMETER PeakmeterElement;
+} DSP_HDMI_CIRCUIT_CONTEXT, * PDSP_HDMI_CIRCUIT_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DSP_HDMI_CIRCUIT_CONTEXT, GetHDMICircuitContext)
+
+typedef enum {
+ HDMIVolumeIndex = 0,
+ HDMIMuteIndex = 1,
+ HDMIPeakmeterIndex = 2,
+ HDMIElementCount = 3
+} HDMI_ELEMENTS;
+
+typedef enum {
+ HDMIHostPin = 0,
+ HDMILoopbackPin = 1,
+ HDMIBridgePin = 2,
+ HDMIPinCount = 3
+} HDMI_PIN_TYPE;
+
+typedef struct _HDMI_PIN_CONTEXT {
+ ACXTARGETCIRCUIT TargetCircuit;
+ ULONG TargetPinId;
+ HDMI_PIN_TYPE PinType;
+ CAPTURE_PIN_TYPE CapturePinType;
+} HDMI_PIN_CONTEXT, * PHDMI_PIN_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(HDMI_PIN_CONTEXT, GetHDMIPinContext)
+
+typedef struct _HDMI_STREAM_CONTEXT {
+ HDMI_PIN_TYPE PinType;
+ CAPTURE_PIN_TYPE CapturePinType;
+} HDMI_STREAM_CONTEXT, * PHDMI_STREAM_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(HDMI_STREAM_CONTEXT, GetHDMIStreamContext)
+
+// HDMI callbacks.
+EVT_ACX_CIRCUIT_CREATE_STREAM HDMI_EvtCircuitCreateStream;
+EVT_ACX_CIRCUIT_POWER_UP HDMI_EvtCircuitPowerUp;
+EVT_ACX_CIRCUIT_POWER_DOWN HDMI_EvtCircuitPowerDown;
+EVT_ACX_STREAM_SET_RENDER_PACKET HDMI_EvtStreamSetRenderPacket;
+EVT_ACX_STREAM_GET_CAPTURE_PACKET HDMI_EvtStreamGetLoopbackPacket;
+EVT_ACX_PIN_SET_DATAFORMAT HDMI_EvtAcxPinSetDataFormat;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP HDMI_EvtPinContextCleanup;
+EVT_ACX_PIN_CONNECTED HDMI_EvtPinConnected;
+EVT_ACX_PIN_DISCONNECTED HDMI_EvtPinDisconnected;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP HDMI_EvtDeviceContextCleanup;
+EVT_ACX_MUTE_ASSIGN_STATE HDMI_EvtMuteAssignState;
+EVT_ACX_MUTE_RETRIEVE_STATE HDMI_EvtMuteRetrieveState;
+EVT_ACX_VOLUME_ASSIGN_LEVEL HDMI_EvtRampedVolumeAssignLevel;
+EVT_ACX_VOLUME_RETRIEVE_LEVEL HDMI_EvtVolumeRetrieveLevel;
+EVT_ACX_PEAKMETER_RETRIEVE_LEVEL HDMI_EvtPeakMeterRetrieveLevelCallback;
+EVT_ACX_OBJECT_PREPROCESS_REQUEST HDMI_EvtAudioCpuResourcesCallback;
+
+PAGED_CODE_SEG
+NTSTATUS
+HDMI_SetPowerPolicy(
+ _In_ WDFDEVICE Device
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+HDMI_CreateRenderCircuit(
+ _In_ WDFDEVICE Device,
+ _In_ GUID ComponentGuid,
+ _In_ UNICODE_STRING CircuitName,
+ _Out_ ACXCIRCUIT * Circuit
+);
+
+/////////////////////////////////////////////////////////
+//
+// Multi circuit codec Render (speaker) definitions
+//
+
+// Uses the same circuit context, render pin, and render element definitions as Codec Render.
+
+// Render callbacks.
+EVT_ACX_CIRCUIT_CREATE_STREAM RenderMC_EvtCircuitCreateStream;
+EVT_ACX_CIRCUIT_POWER_UP RenderMC_EvtCircuitPowerUp;
+EVT_ACX_CIRCUIT_POWER_DOWN RenderMC_EvtCircuitPowerDown;
+EVT_ACX_PIN_SET_DATAFORMAT RenderMC_EvtAcxPinSetDataFormat;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP RenderMC_EvtPinContextCleanup;
+EVT_ACX_MUTE_ASSIGN_STATE RenderMC_EvtMuteAssignState;
+EVT_ACX_MUTE_RETRIEVE_STATE RenderMC_EvtMuteRetrieveState;
+EVT_ACX_VOLUME_RETRIEVE_LEVEL RenderMC_EvtVolumeRetrieveLevel;
+EVT_ACX_RAMPED_VOLUME_ASSIGN_LEVEL RenderMC_EvtRampedVolumeAssignLevel;
+
+PAGED_CODE_SEG
+NTSTATUS
+RenderMC_CreateRenderCircuit(
+ _In_ WDFDEVICE Device,
+ _In_ const GUID * ComponentGuid,
+ _In_ const UNICODE_STRING * CircuitName,
+ _In_ const UNICODE_STRING * Uri,
+ _Out_ ACXCIRCUIT * Circuit
+);
+
+/////////////////////////////////////////////////////////
+//
+// Multi circuit codec Capture (microphone) definitions
+//
+
+// Uses the same circuit context, render pin, and render element definitions as Codec Capture.
+
+// Capture callbacks.
+EVT_ACX_CIRCUIT_CREATE_STREAM CaptureMC_EvtCircuitCreateStream;
+EVT_ACX_CIRCUIT_POWER_UP CaptureMC_EvtCircuitPowerUp;
+EVT_ACX_CIRCUIT_POWER_DOWN CaptureMC_EvtCircuitPowerDown;
+EVT_ACX_STREAM_GET_CAPTURE_PACKET CaptureMC_EvtStreamGetCapturePacket;
+EVT_ACX_PIN_SET_DATAFORMAT CaptureMC_EvtAcxPinSetDataFormat;
+EVT_ACX_PIN_RETRIEVE_NAME CaptureMC_EvtAcxPinRetrieveName;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP CaptureMC_EvtPinContextCleanup;
+
+PAGED_CODE_SEG
+NTSTATUS
+CaptureMC_CreateCaptureCircuit(
+ _In_ WDFDEVICE Device,
+ _In_ const GUID * ComponentGuid,
+ _In_ const GUID * MicCustomName,
+ _In_ const UNICODE_STRING * CircuitName,
+ _In_ const UNICODE_STRING * Uri,
+ _Out_ ACXCIRCUIT * Circuit
+);
+
+/////////////////////////////////////////////////////////
+//
+// Multi circuit dsp Render (speaker) definitions
+//
+
+// Uses the same circuit context, render pin, and render element definitions as Codec Render.
+
+// Render callbacks.
+EVT_ACX_CIRCUIT_COMPOSITE_CIRCUIT_INITIALIZE RenderMCDsp_EvtCircuitCompositeCircuitInitialize;
+EVT_ACX_CIRCUIT_COMPOSITE_INITIALIZE RenderMCDsp_EvtCircuitCompositeInitialize;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP RenderMCDsp_EvtCircuitContextCleanup;
+EVT_WDF_DEVICE_PREPARE_HARDWARE RenderMCDsp_EvtDevicePrepareHardware;
+EVT_WDF_DEVICE_RELEASE_HARDWARE RenderMCDsp_EvtDeviceReleaseHardware;
+EVT_WDF_DEVICE_SELF_MANAGED_IO_INIT RenderMCDsp_EvtDeviceSelfManagedIoInit;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP RenderMCDsp_EvtDeviceContextCleanup;
+EVT_ACX_CIRCUIT_CREATE_STREAM RenderMCDsp_EvtCircuitCreateStream;
+EVT_ACX_CIRCUIT_POWER_UP RenderMCDsp_EvtCircuitPowerUp;
+EVT_ACX_CIRCUIT_POWER_DOWN RenderMCDsp_EvtCircuitPowerDown;
+EVT_ACX_STREAM_SET_RENDER_PACKET RenderMCDsp_EvtStreamSetRenderPacket;
+EVT_ACX_PIN_SET_DATAFORMAT RenderMCDsp_EvtAcxPinSetDataFormat;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP RenderMCDsp_EvtPinContextCleanup;
+EVT_ACX_PIN_CONNECTED RenderMCDsp_EvtPinConnected;
+EVT_ACX_PIN_DISCONNECTED RenderMCDsp_EvtPinDisconnected;
+
+// Render Audio Engine
+EVT_ACX_MUTE_ASSIGN_STATE DspR_EvtMuteAssignState;
+EVT_ACX_MUTE_RETRIEVE_STATE DspR_EvtMuteRetrieveState;
+EVT_ACX_VOLUME_RETRIEVE_LEVEL DspR_EvtVolumeRetrieveLevel;
+EVT_ACX_PEAKMETER_RETRIEVE_LEVEL DspR_EvtPeakMeterRetrieveLevelCallback;
+EVT_ACX_RAMPED_VOLUME_ASSIGN_LEVEL DspR_EvtRampedVolumeAssignLevel;
+EVT_ACX_AUDIOENGINE_RETRIEVE_BUFFER_SIZE_LIMITS DspR_EvtAcxAudioEngineRetrieveBufferSizeLimits;
+EVT_ACX_AUDIOENGINE_RETRIEVE_EFFECTS_STATE DspR_EvtAcxAudioEngineRetrieveEffectsState;
+EVT_ACX_AUDIOENGINE_ASSIGN_EFFECTS_STATE DspR_EvtAcxAudioEngineAssignEffectsState;
+EVT_ACX_AUDIOENGINE_RETRIEVE_ENGINE_FORMAT DspR_EvtAcxAudioEngineRetrieveEngineMixFormat;
+EVT_ACX_AUDIOENGINE_ASSIGN_ENGINE_FORMAT DspR_EvtAcxAudioEngineAssignEngineDeviceFormat;
+EVT_ACX_STREAMAUDIOENGINE_RETRIEVE_EFFECTS_STATE DspR_EvtAcxStreamAudioEngineRetrieveEffectsState;
+EVT_ACX_STREAMAUDIOENGINE_ASSIGN_EFFECTS_STATE DspR_EvtAcxStreamAudioEngineAssignEffectsState;
+EVT_ACX_STREAMAUDIOENGINE_RETRIEVE_PRESENTATION_POSITION DspR_EvtAcxStreamAudioEngineRetrievePresentationPosition;
+EVT_ACX_STREAMAUDIOENGINE_ASSIGN_CURRENT_WRITE_POSITION DspR_EvtAcxStreamAudioEngineAssignCurrentWritePosition;
+EVT_ACX_STREAMAUDIOENGINE_RETRIEVE_LINEAR_BUFFER_POSITION DspR_EvtAcxStreamAudioEngineRetrieveLinearBufferPosition;
+EVT_ACX_STREAMAUDIOENGINE_ASSIGN_LAST_BUFFER_POSITION DspR_EvtAcxStreamAudioEngineAssignLastBufferPosition;
+EVT_ACX_STREAMAUDIOENGINE_ASSIGN_LOOPBACK_PROTECTION DspR_EvtAcxStreamAudioEngineAssignLoopbackProtection;
+
+PAGED_CODE_SEG
+NTSTATUS
+RenderMCDsp_SetPowerPolicy(
+ _In_ WDFDEVICE Device
+);
+
+PAGED_CODE_SEG
+NTSTATUS CreateRenderCircuit(
+ _In_ PACXCIRCUIT_INIT CircuitInit,
+ _In_ UNICODE_STRING CircuitName,
+ _In_ WDFDEVICE Device,
+ _Out_ ACXCIRCUIT* Circuit
+);
+
+PAGED_CODE_SEG
+NTSTATUS CreateRenderMCDspPin(
+ _In_ ACX_PIN_TYPE PinType,
+ _In_ ACXCIRCUIT Circuit,
+ _In_ ACX_PIN_COMMUNICATION Communication,
+ _In_ const GUID* Category,
+ _In_ ACX_PIN_CALLBACKS* PinCallbacks,
+ _In_ bool Mic,
+ _Out_ ACXPIN* Pin
+);
+
+PAGED_CODE_SEG
+NTSTATUS CreateAudioEngine(
+ _In_ ACXCIRCUIT Circuit,
+ _In_reads_(PinCount) ACXPIN* Pins,
+ _In_ ULONG PinCount,
+ _Out_ ACXAUDIOENGINE* AudioEngineElement
+);
+
+/////////////////////////////////////////////////////////
+//
+// Multi circuit dsp Capture (microphone) definitions
+//
+
+// Uses the same circuit context, capture pin and capture element definitions as Codec Capture.
+
+// Capture callbacks.
+EVT_ACX_CIRCUIT_COMPOSITE_CIRCUIT_INITIALIZE CaptureMCDsp_EvtCircuitCompositeCircuitInitialize;
+EVT_ACX_CIRCUIT_COMPOSITE_INITIALIZE CaptureMCDsp_EvtCircuitCompositeInitialize;
+EVT_WDF_DEVICE_PREPARE_HARDWARE CaptureMCDsp_EvtDevicePrepareHardware;
+EVT_WDF_DEVICE_RELEASE_HARDWARE CaptureMCDsp_EvtDeviceReleaseHardware;
+EVT_WDF_DEVICE_SELF_MANAGED_IO_INIT CaptureMCDsp_EvtDeviceSelfManagedIoInit;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP CaptureMCDsp_EvtDeviceContextCleanup;
+EVT_ACX_CIRCUIT_CREATE_STREAM CaptureMCDsp_EvtCircuitCreateStream;
+EVT_ACX_CIRCUIT_POWER_UP CaptureMCDsp_EvtCircuitPowerUp;
+EVT_ACX_CIRCUIT_POWER_DOWN CaptureMCDsp_EvtCircuitPowerDown;
+EVT_ACX_STREAM_GET_CAPTURE_PACKET CaptureMCDsp_EvtStreamGetCapturePacket;
+EVT_ACX_PIN_SET_DATAFORMAT CaptureMCDsp_EvtAcxPinSetDataFormat;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP CaptureMCDsp_EvtPinContextCleanup;
+EVT_ACX_PIN_CONNECTED CaptureMCDsp_EvtPinConnected;
+EVT_ACX_PIN_DISCONNECTED CaptureMCDsp_EvtPinDisconnected;
+
+PAGED_CODE_SEG
+NTSTATUS
+CaptureMCDsp_SetPowerPolicy(
+ _In_ WDFDEVICE Device
+);
+
+PAGED_CODE_SEG
+NTSTATUS CreateCaptureCircuit(
+ _In_ PACXCIRCUIT_INIT CircuitInit,
+ _In_ UNICODE_STRING CircuitName,
+ _In_ WDFDEVICE Device,
+ _Out_ ACXCIRCUIT* Circuit
+);
+
+PAGED_CODE_SEG
+NTSTATUS CreateCaptureMCDspPin(
+ _In_ ACX_PIN_TYPE PinType,
+ _In_ ACXCIRCUIT Circuit,
+ _In_ ACX_PIN_COMMUNICATION Communication,
+ _In_ const GUID* Category,
+ _In_ ACX_PIN_CALLBACKS* PinCallbacks,
+ _In_ bool Mic,
+ _Out_ ACXPIN* Pin
+);
+
+/* make internal prototypes usable from C++ */
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif // _PRIVATE_H_
diff --git a/audio/Acx/Samples/Common/RenderCircuit.cpp b/audio/Acx/Samples/Common/RenderCircuit.cpp
new file mode 100644
index 00000000..2f5abd13
--- /dev/null
+++ b/audio/Acx/Samples/Common/RenderCircuit.cpp
@@ -0,0 +1,807 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ RenderCircuit.cpp
+
+Abstract:
+
+ Render Circuit. This file contains routines to create and handle
+ render circuit with no offload.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include "private.h"
+#include "public.h"
+#include <ks.h>
+#include <mmsystem.h>
+#include <ksmedia.h>
+#include "AudioFormats.h"
+#include "streamengine.h"
+#include "cpp_utils.h"
+#include "circuithelper.h"
+
+#ifndef __INTELLISENSE__
+#include "renderCircuit.tmh"
+#endif
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecR_EvtAcxPinSetDataFormat(
+ _In_ ACXPIN Pin,
+ _In_ ACXDATAFORMAT DataFormat
+)
+/*++
+
+Routine Description:
+
+ This ACX pin callback sets the device/mixed format.
+
+Return Value:
+
+ NTSTATUS
+
+--*/
+{
+ UNREFERENCED_PARAMETER(Pin);
+ UNREFERENCED_PARAMETER(DataFormat);
+
+ PAGED_CODE();
+
+ // NOTE: update device/mixed format here.
+
+ return STATUS_NOT_SUPPORTED;
+}
+
+///////////////////////////////////////////////////////////
+//
+// For more information on mute element see: https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/ksnodetype-mute
+//
+_Use_decl_annotations_
+NTSTATUS
+NTAPI
+CodecR_EvtMuteAssignState(
+ _In_ ACXMUTE Mute,
+ _In_ ULONG Channel,
+ _In_ ULONG State
+)
+{
+ PMUTE_ELEMENT_CONTEXT muteCtx;
+ ULONG i;
+
+ PAGED_CODE();
+
+ muteCtx = GetMuteElementContext(Mute);
+ ASSERT(muteCtx);
+
+ //
+ // Use first channel for all channels setting.
+ //
+ if (Channel != ALL_CHANNELS_ID)
+ {
+ muteCtx->MuteState[Channel] = State;
+ }
+ else
+ {
+ for (i = 0; i < MAX_CHANNELS; ++i)
+ {
+ muteCtx->MuteState[i] = State;
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+NTAPI
+CodecR_EvtMuteRetrieveState(
+ _In_ ACXMUTE Mute,
+ _In_ ULONG Channel,
+ _Out_ ULONG * State
+)
+{
+ PMUTE_ELEMENT_CONTEXT muteCtx;
+
+ PAGED_CODE();
+
+ muteCtx = GetMuteElementContext(Mute);
+ ASSERT(muteCtx);
+
+ //
+ // Use first channel for all channels setting.
+ //
+ if (Channel != ALL_CHANNELS_ID)
+ {
+ *State = muteCtx->MuteState[Channel];
+ }
+ else
+ {
+ *State = muteCtx->MuteState[0];
+ }
+
+ return STATUS_SUCCESS;
+}
+
+///////////////////////////////////////////////////////////
+//
+// For more information on volume element see: https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/ksnodetype-volume
+//
+_Use_decl_annotations_
+NTSTATUS
+NTAPI
+CodecR_EvtRampedVolumeAssignLevel(
+ _In_ ACXVOLUME Volume,
+ _In_ ULONG Channel,
+ _In_ LONG VolumeLevel,
+ _In_ ACX_VOLUME_CURVE_TYPE CurveType,
+ _In_ ULONGLONG CurveDuration
+)
+{
+ PVOLUME_ELEMENT_CONTEXT volumeCtx;
+ ULONG i;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(CurveType);
+ UNREFERENCED_PARAMETER(CurveDuration);
+
+ volumeCtx = GetVolumeElementContext(Volume);
+ ASSERT(volumeCtx);
+
+ if (Channel != ALL_CHANNELS_ID)
+ {
+ volumeCtx->VolumeLevel[Channel] = VolumeLevel;
+ }
+ else
+ {
+ for (i = 0; i < MAX_CHANNELS; ++i)
+ {
+ volumeCtx->VolumeLevel[i] = VolumeLevel;
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+NTAPI
+CodecR_EvtVolumeRetrieveLevel(
+ _In_ ACXVOLUME Volume,
+ _In_ ULONG Channel,
+ _Out_ LONG * VolumeLevel
+)
+{
+ PVOLUME_ELEMENT_CONTEXT volumeCtx;
+
+ PAGED_CODE();
+
+ volumeCtx = GetVolumeElementContext(Volume);
+ ASSERT(volumeCtx);
+
+ if (Channel != ALL_CHANNELS_ID)
+ {
+ *VolumeLevel = volumeCtx->VolumeLevel[Channel];
+ }
+ else
+ {
+ *VolumeLevel = volumeCtx->VolumeLevel[0];
+ }
+
+ return STATUS_SUCCESS;
+}
+
+VOID
+CodecR_EvtPinContextCleanup(
+ _In_ WDFOBJECT WdfPin
+)
+/*++
+
+Routine Description:
+
+ In this callback, it cleans up pin context.
+
+Arguments:
+
+ WdfDevice - WDF device object
+
+Return Value:
+
+ nullptr
+
+--*/
+{
+
+ UNREFERENCED_PARAMETER(WdfPin);
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecR_AddStaticRender(
+ _In_ WDFDEVICE Device,
+ _In_ const GUID * ComponentGuid,
+ _In_ const UNICODE_STRING * CircuitName
+)
+/*++
+
+Routine Description:
+
+ Creates the static render circuit (pictured below) and
+ adds it to the device context. This is called when a
+ new device is detected and the AddDevice call is made
+ by the pnp manager.
+
+ ***************************************************************************
+ * Render Circuit *
+ * *
+ * +--------------------------------------------+ *
+ * | | *
+ * | +-------------+ +-------------+ | *
+ * Host ------>| | Volume Node | | Mute Node | |---> Bridge *
+ * Pin | +-------------+ +-------------+ | Pin *
+ * | | *
+ * +--------------------------------------------+ *
+ * *
+ ***************************************************************************
+
+Return Value:
+
+ NTSTATUS
+
+--*/
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PCODEC_DEVICE_CONTEXT devCtx;
+ PRENDER_DEVICE_CONTEXT renderDevCtx;
+ ACXCIRCUIT renderCircuit = nullptr;
+ WDF_OBJECT_ATTRIBUTES attributes;
+
+ PAGED_CODE();
+
+ devCtx = GetCodecDeviceContext(Device);
+ ASSERT(devCtx != nullptr);
+
+ //
+ // Alloc audio context to current device.
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, RENDER_DEVICE_CONTEXT);
+ RETURN_NTSTATUS_IF_FAILED(WdfObjectAllocateContext(Device, &attributes, (PVOID*)&renderDevCtx));
+ ASSERT(renderDevCtx);
+
+ //
+ // Create a render circuit associated with this child device.
+ //
+ RETURN_NTSTATUS_IF_FAILED(CodecR_CreateRenderCircuit(Device, ComponentGuid, CircuitName, &renderCircuit));
+
+ devCtx->Render = renderCircuit;
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+Render_AllocateSupportedFormats(
+ _In_ WDFDEVICE Device,
+ _In_reads_bytes_(CodecRenderPinCount) ACXPIN Pin[],
+ _In_ ACXCIRCUIT Circuit,
+ _In_ size_t CodecRenderPinCount
+)
+{
+ UNREFERENCED_PARAMETER(CodecRenderPinCount);
+
+ NTSTATUS status = STATUS_SUCCESS;
+ ACXDATAFORMAT formatPcm44100c2;
+ ACXDATAFORMAT formatPcm48000c2;
+ ACXDATAFORMATLIST formatList;
+
+ WDF_OBJECT_ATTRIBUTES attributes;
+ WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
+
+ ///////////////////////////////////////////////////////////
+ //
+ // Allocate the formats this circuit supports.
+ //
+
+ RETURN_NTSTATUS_IF_FAILED(AllocateFormat(Pcm44100c2, Circuit, Device, &formatPcm44100c2));
+ RETURN_NTSTATUS_IF_FAILED(AllocateFormat(Pcm48000c2, Circuit, Device, &formatPcm48000c2));
+
+ ///////////////////////////////////////////////////////////
+ //
+ // Define supported formats for the host pin.
+ //
+
+ //
+ // The raw processing mode list is associated with each single circuit
+ // by ACX. The driver uses this DDI to retrieve the built-in raw
+ // data-format list.
+ //
+ RETURN_NTSTATUS_IF_TRUE(CodecRenderHostPin >= CodecRenderPinCount, STATUS_INVALID_PARAMETER);
+ formatList = AcxPinGetRawDataFormatList(Pin[CodecRenderHostPin]);
+ RETURN_NTSTATUS_IF_TRUE(formatList == nullptr, STATUS_INSUFFICIENT_RESOURCES);
+
+ //
+ // The driver uses this DDI to add data formats to the raw
+ // processing mode list associated with the current circuit.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxDataFormatListAddDataFormat(formatList, formatPcm44100c2));
+ RETURN_NTSTATUS_IF_FAILED(AcxDataFormatListAddDataFormat(formatList, formatPcm48000c2));
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecR_CreateRenderCircuit(
+ _In_ WDFDEVICE Device,
+ _In_ const GUID * ComponentGuid,
+ _In_ const UNICODE_STRING * CircuitName,
+ _Out_ ACXCIRCUIT* Circuit
+)
+/*++
+
+Routine Description:
+
+ This routine builds the CODEC render circuit.
+
+Return Value:
+
+ NT status value
+
+--*/
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ WDF_OBJECT_ATTRIBUTES attributes;
+ ACXCIRCUIT circuit;
+ CODEC_RENDER_CIRCUIT_CONTEXT* circuitCtx;
+ ACXPIN pin[CodecRenderPinCount];
+
+ PAGED_CODE();
+
+ //
+ // Init output value.
+ //
+ *Circuit = nullptr;
+
+ ///////////////////////////////////////////////////////////
+ //
+ // Create a circuit.
+ //
+ {
+ PACXCIRCUIT_INIT circuitInit = nullptr;
+ ACX_CIRCUIT_PNPPOWER_CALLBACKS powerCallbacks;
+
+ //
+ // The driver uses this DDI to allocate an ACXCIRCUIT_INIT
+ // structure. This opaque structure is used when creating
+ // a standalone audio circuit representing an audio device.
+ //
+ circuitInit = AcxCircuitInitAllocate(Device);
+
+ //
+ // The driver uses this DDI to free the allocated
+ // ACXCIRCUIT_INIT structure when an error is detected.
+ // Normally the structures is deleted/cleared by ACX when
+ // an ACX circuit is created successfully.
+ //
+ auto circuitInitScope = scope_exit([&circuitInit]() {
+ if (circuitInit) {
+ AcxCircuitInitFree(circuitInit);
+ }
+ });
+
+ //
+ // The driver uses this DDI to specify the Component ID
+ // of the ACX circuit. This ID is a guid that uniquely
+ // identifies the circuit instance (vendor specific).
+ //
+ AcxCircuitInitSetComponentId(circuitInit, ComponentGuid);
+
+ //
+ // The driver uses this DDI to specify the circuit name.
+ // For standalone circuits, this is the audio device name
+ // which is used by clients to open handles to the audio devices.
+ //
+ (VOID)AcxCircuitInitAssignName(circuitInit, CircuitName);
+
+ //
+ // The driver uses this DDI to specify the circuit type. The
+ // circuit type can be AcxCircuitTypeRender, AcxCircuitTypeCapture,
+ // AcxCircuitTypeOther, or AcxCircuitTypeMaximum (for validation).
+ //
+ AcxCircuitInitSetCircuitType(circuitInit, AcxCircuitTypeRender);
+
+ //
+ // The driver uses this DDI to assign its (if any) power callbacks.
+ //
+ ACX_CIRCUIT_PNPPOWER_CALLBACKS_INIT(&powerCallbacks);
+ powerCallbacks.EvtAcxCircuitPowerUp = CodecR_EvtCircuitPowerUp;
+ powerCallbacks.EvtAcxCircuitPowerDown = CodecR_EvtCircuitPowerDown;
+ AcxCircuitInitSetAcxCircuitPnpPowerCallbacks(circuitInit, &powerCallbacks);
+
+ //
+ // The driver uses this DDI to register for a stream-create callback.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxCircuitInitAssignAcxCreateStreamCallback(circuitInit, CodecR_EvtCircuitCreateStream));
+
+ //
+ // The driver uses this DDI to create a new ACX circuit.
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, CODEC_RENDER_CIRCUIT_CONTEXT);
+ RETURN_NTSTATUS_IF_FAILED(AcxCircuitCreate(Device, &attributes, &circuitInit, &circuit));
+
+ circuitInitScope.release();
+
+ circuitCtx = GetRenderCircuitContext(circuit);
+ ASSERT(circuitCtx);
+ }
+
+ //
+ // Post circuit creation initialization.
+ //
+
+ ///////////////////////////////////////////////////////////
+ //
+ // Create mute and volume elements.
+ //
+ {
+ ACXELEMENT elements[RenderElementCount] = { 0 };
+
+ //
+ // The driver uses this DDI to assign its volume element callbacks.
+ //
+ ACX_VOLUME_CALLBACKS volumeCallbacks;
+ ACX_VOLUME_CALLBACKS_INIT(&volumeCallbacks);
+ volumeCallbacks.EvtAcxRampedVolumeAssignLevel = CodecR_EvtRampedVolumeAssignLevel;
+ volumeCallbacks.EvtAcxVolumeRetrieveLevel = CodecR_EvtVolumeRetrieveLevel;
+
+ //
+ // Create Volume element
+ //
+ ACX_VOLUME_CONFIG volumeCfg;
+ ACX_VOLUME_CONFIG_INIT(&volumeCfg);
+ volumeCfg.ChannelsCount = MAX_CHANNELS;
+ volumeCfg.Minimum = VOLUME_LEVEL_MINIMUM;
+ volumeCfg.Maximum = VOLUME_LEVEL_MAXIMUM;
+ volumeCfg.SteppingDelta = VOLUME_STEPPING;
+ volumeCfg.Name = &KSAUDFNAME_VOLUME_CONTROL;
+ volumeCfg.Callbacks = &volumeCallbacks;
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, VOLUME_ELEMENT_CONTEXT);
+ attributes.ParentObject = circuit;
+
+ RETURN_NTSTATUS_IF_FAILED(AcxVolumeCreate(circuit, &attributes, &volumeCfg, (ACXVOLUME*)&elements[RenderVolumeIndex]));
+
+ //
+ // The driver uses this DDI to assign its mute element callbacks.
+ //
+ ACX_MUTE_CALLBACKS muteCallbacks;
+ ACX_MUTE_CALLBACKS_INIT(&muteCallbacks);
+ muteCallbacks.EvtAcxMuteAssignState = CodecR_EvtMuteAssignState;
+ muteCallbacks.EvtAcxMuteRetrieveState = CodecR_EvtMuteRetrieveState;
+
+ //
+ // Create Mute element
+ //
+ ACX_MUTE_CONFIG muteCfg;
+ ACX_MUTE_CONFIG_INIT(&muteCfg);
+ muteCfg.ChannelsCount = MAX_CHANNELS;
+ muteCfg.Name = &KSAUDFNAME_WAVE_MUTE;
+ muteCfg.Callbacks = &muteCallbacks;
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, MUTE_ELEMENT_CONTEXT);
+ attributes.ParentObject = circuit;
+
+ RETURN_NTSTATUS_IF_FAILED(AcxMuteCreate(circuit, &attributes, &muteCfg, (ACXMUTE*)&elements[RenderMuteIndex]));
+
+ //
+ // Saving the volume and mute elements in the circuit context.
+ //
+ circuitCtx->VolumeElement = (ACXVOLUME)elements[RenderVolumeIndex];
+ circuitCtx->MuteElement = (ACXMUTE)elements[RenderMuteIndex];
+
+ //
+ // The driver uses this DDI post circuit creation to add ACXELEMENTs.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxCircuitAddElements(circuit, elements, SIZEOF_ARRAY(elements)));
+ }
+
+ ///////////////////////////////////////////////////////////
+ //
+ // Create the pins for the circuit.
+ //
+ {
+ ACX_PIN_CONFIG pinCfg;
+ CODEC_PIN_CONTEXT* pinCtx;
+ ACX_PIN_CALLBACKS pinCallbacks;
+
+ ///////////////////////////////////////////////////////////
+ //
+ // Create Render Pin.
+ //
+
+ ACX_PIN_CALLBACKS_INIT(&pinCallbacks);
+ pinCallbacks.EvtAcxPinSetDataFormat = CodecR_EvtAcxPinSetDataFormat;
+
+ ACX_PIN_CONFIG_INIT(&pinCfg);
+ pinCfg.Type = AcxPinTypeSink;
+ pinCfg.Communication = AcxPinCommunicationSink;
+ pinCfg.Category = &KSCATEGORY_AUDIO;
+ pinCfg.PinCallbacks = &pinCallbacks;
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, CODEC_PIN_CONTEXT);
+ attributes.EvtCleanupCallback = CodecR_EvtPinContextCleanup;
+ attributes.ParentObject = circuit;
+
+ //
+ // The driver uses this DDI to create one or more pins on the circuits.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxPinCreate(circuit, &attributes, &pinCfg, &pin[CodecRenderHostPin]));
+
+ ASSERT(pin[CodecRenderHostPin] != nullptr);
+ pinCtx = GetCodecPinContext(pin[CodecRenderHostPin]);
+ ASSERT(pinCtx);
+ pinCtx->CodecPinType = CodecPinTypeHost;
+
+ ///////////////////////////////////////////////////////////
+ //
+ // Create Device Bridge Pin.
+ //
+
+ ACX_PIN_CONFIG_INIT(&pinCfg);
+ pinCfg.Type = AcxPinTypeSource;
+ pinCfg.Communication = AcxPinCommunicationNone;
+ pinCfg.Category = &KSNODETYPE_SPEAKER;
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, CODEC_PIN_CONTEXT);
+ attributes.EvtCleanupCallback = CodecR_EvtPinContextCleanup;
+ attributes.ParentObject = circuit;
+
+ //
+ // The driver uses this DDI to create one or more pins on the circuits.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxPinCreate(circuit, &attributes, &pinCfg, &pin[CodecRenderBridgePin]));
+
+ ASSERT(pin[CodecRenderBridgePin] != nullptr);
+ pinCtx = GetCodecPinContext(pin[CodecRenderBridgePin]);
+ ASSERT(pinCtx);
+ pinCtx->CodecPinType = CodecPinTypeDevice;
+ }
+
+ ///////////////////////////////////////////////////////////
+ //
+ // Add audio jack to bridge pin.
+ // For more information on audio jack see: https://docs.microsoft.com/en-us/windows/win32/api/devicetopology/ns-devicetopology-ksjack_description
+ //
+ {
+ ACX_JACK_CONFIG jackCfg;
+ ACXJACK jack;
+ PJACK_CONTEXT jackCtx;
+
+ ACX_JACK_CONFIG_INIT(&jackCfg);
+ jackCfg.Description.ChannelMapping = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
+ jackCfg.Description.Color = RGB(0, 0, 0);
+ jackCfg.Description.ConnectionType = AcxConnTypeAtapiInternal;
+ jackCfg.Description.GeoLocation = AcxGeoLocFront;
+ jackCfg.Description.GenLocation = AcxGenLocPrimaryBox;
+ jackCfg.Description.PortConnection = AcxPortConnIntegratedDevice;
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, JACK_CONTEXT);
+ attributes.ParentObject = pin[CodecRenderBridgePin];
+
+ RETURN_NTSTATUS_IF_FAILED(AcxJackCreate(pin[CodecRenderBridgePin], &attributes, &jackCfg, &jack));
+
+ ASSERT(jack != nullptr);
+
+ jackCtx = GetJackContext(jack);
+ ASSERT(jackCtx);
+ jackCtx->Dummy = 0;
+
+ RETURN_NTSTATUS_IF_FAILED(AcxPinAddJacks(pin[CodecRenderBridgePin], &jack, 1));
+ }
+
+ RETURN_NTSTATUS_IF_FAILED(Render_AllocateSupportedFormats(Device, pin, circuit, CodecRenderPinCount));
+
+ ///////////////////////////////////////////////////////////
+ //
+ // The driver uses this DDI post circuit creation to add ACXPINs.
+ //
+ RETURN_NTSTATUS_IF_FAILED(AcxCircuitAddPins(circuit, pin, CodecRenderPinCount));
+
+ //
+ // Set output value.
+ //
+ *Circuit = circuit;
+
+ //
+ // Done.
+ //
+ status = STATUS_SUCCESS;
+
+ return status;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+CodecR_EvtCircuitPowerUp(
+ _In_ WDFDEVICE Device,
+ _In_ ACXCIRCUIT Circuit,
+ _In_ WDF_POWER_DEVICE_STATE PreviousState
+)
+{
+ UNREFERENCED_PARAMETER(Device);
+ UNREFERENCED_PARAMETER(Circuit);
+ UNREFERENCED_PARAMETER(PreviousState);
+
+ PAGED_CODE();
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+NTSTATUS
+CodecR_EvtCircuitPowerDown(
+ _In_ WDFDEVICE Device,
+ _In_ ACXCIRCUIT Circuit,
+ _In_ WDF_POWER_DEVICE_STATE TargetState
+)
+{
+ UNREFERENCED_PARAMETER(Device);
+ UNREFERENCED_PARAMETER(Circuit);
+ UNREFERENCED_PARAMETER(TargetState);
+
+ PAGED_CODE();
+
+ return STATUS_SUCCESS;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecR_EvtCircuitCreateStream(
+ _In_ WDFDEVICE Device,
+ _In_ ACXCIRCUIT Circuit,
+ _In_ ACXPIN Pin,
+ _In_ PACXSTREAM_INIT StreamInit,
+ _In_ ACXDATAFORMAT StreamFormat,
+ _In_ const GUID* SignalProcessingMode,
+ _In_ ACXOBJECTBAG VarArguments
+)
+/*++
+
+Routine Description:
+
+ This routine creates a stream for the specified circuit.
+
+Return Value:
+
+ NT status value
+
+--*/
+{
+ NTSTATUS status;
+ PRENDER_DEVICE_CONTEXT devCtx;
+ WDF_OBJECT_ATTRIBUTES attributes;
+ ACXSTREAM stream;
+ STREAMENGINE_CONTEXT * streamCtx;
+ ACX_STREAM_CALLBACKS streamCallbacks;
+ ACX_RT_STREAM_CALLBACKS rtCallbacks;
+ CRenderStreamEngine* renderStreamEngine = nullptr;
+ CODEC_PIN_TYPE codecPinType;
+ PCODEC_PIN_CONTEXT pinCtx;
+ ACX_PIN_TYPE pinType;
+ CODEC_RENDER_CIRCUIT_CONTEXT* circuitCtx;
+
+ auto streamEngineScope = scope_exit([&renderStreamEngine]() {
+
+ delete renderStreamEngine;
+
+ });
+
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(SignalProcessingMode);
+ UNREFERENCED_PARAMETER(VarArguments);
+
+ ASSERT(IsEqualGUID(*SignalProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW));
+
+ ASSERT(Circuit != nullptr);
+ circuitCtx = GetRenderCircuitContext(Circuit);
+ ASSERT(circuitCtx);
+
+ devCtx = GetRenderDeviceContext(Device);
+ ASSERT(devCtx != nullptr);
+ UNREFERENCED_PARAMETER(devCtx);
+
+ pinCtx = GetCodecPinContext(Pin);
+ codecPinType = pinCtx->CodecPinType;
+
+ pinType = AcxPinGetType(Pin);
+
+ //
+ // Init streaming callbacks.
+ //
+ ACX_STREAM_CALLBACKS_INIT(&streamCallbacks);
+ streamCallbacks.EvtAcxStreamPrepareHardware = EvtStreamPrepareHardware;
+ streamCallbacks.EvtAcxStreamReleaseHardware = EvtStreamReleaseHardware;
+ streamCallbacks.EvtAcxStreamRun = EvtStreamRun;
+ streamCallbacks.EvtAcxStreamPause = EvtStreamPause;
+
+ RETURN_NTSTATUS_IF_FAILED(AcxStreamInitAssignAcxStreamCallbacks(StreamInit, &streamCallbacks));
+
+ //
+ // Init RT streaming callbacks.
+ //
+ ACX_RT_STREAM_CALLBACKS_INIT(&rtCallbacks);
+ rtCallbacks.EvtAcxStreamGetHwLatency = EvtStreamGetHwLatency;
+ rtCallbacks.EvtAcxStreamAllocateRtPackets = EvtStreamAllocateRtPackets;
+ rtCallbacks.EvtAcxStreamFreeRtPackets = EvtStreamFreeRtPackets;
+ rtCallbacks.EvtAcxStreamSetRenderPacket = CodecR_EvtStreamSetRenderPacket;
+ rtCallbacks.EvtAcxStreamGetCurrentPacket = EvtStreamGetCurrentPacket;
+ rtCallbacks.EvtAcxStreamGetPresentationPosition = EvtStreamGetPresentationPosition;
+
+ RETURN_NTSTATUS_IF_FAILED(AcxStreamInitAssignAcxRtStreamCallbacks(StreamInit, &rtCallbacks));
+
+ //
+ // Buffer notifications are supported.
+ //
+ AcxStreamInitSetAcxRtStreamSupportsNotifications(StreamInit);
+
+ //
+ // Create the stream.
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, STREAMENGINE_CONTEXT);
+ attributes.EvtDestroyCallback = EvtStreamDestroy;
+ RETURN_NTSTATUS_IF_FAILED(AcxRtStreamCreate(Device, Circuit, &attributes, &StreamInit, &stream));
+
+ //
+ // Create the virtual streaming engine which will control
+ // streaming logic for the render circuit.
+ //
+ renderStreamEngine = new (POOL_FLAG_NON_PAGED, DeviceDriverTag) CRenderStreamEngine(stream, StreamFormat, FALSE, NULL);
+ RETURN_NTSTATUS_IF_TRUE(renderStreamEngine == nullptr, STATUS_INSUFFICIENT_RESOURCES);
+
+ streamCtx = GetStreamEngineContext(stream);
+ ASSERT(streamCtx);
+ streamCtx->StreamEngine = (PVOID)renderStreamEngine;
+
+ renderStreamEngine = nullptr;
+
+ //
+ // Done.
+ //
+ status = STATUS_SUCCESS;
+
+ return status;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecR_EvtStreamSetRenderPacket(
+ _In_ ACXSTREAM Stream,
+ _In_ ULONG Packet,
+ _In_ ULONG Flags,
+ _In_ ULONG EosPacketLength
+)
+{
+ PSTREAMENGINE_CONTEXT ctx;
+ CRenderStreamEngine* streamEngine = nullptr;
+
+ PAGED_CODE();
+
+ ctx = GetStreamEngineContext(Stream);
+
+ streamEngine = static_cast<CRenderStreamEngine*>(ctx->StreamEngine);
+
+ return streamEngine->SetRenderPacket(Packet, Flags, EosPacketLength);
+}
+
diff --git a/audio/Acx/Samples/Common/SamplesCommon.vcxproj b/audio/Acx/Samples/Common/SamplesCommon.vcxproj
new file mode 100644
index 00000000..0932d59a
--- /dev/null
+++ b/audio/Acx/Samples/Common/SamplesCommon.vcxproj
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|ARM64">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM64">
+ <Configuration>Release</Configuration>
+ <Platform>ARM64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{6A946D59-6690-4ED0-A77D-7D4C3D4B3241}</ProjectGuid>
+ <TemplateGuid>{497e31cb-056b-4f31-abb8-447fd55ee5a5}</TemplateGuid>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
+ <Configuration>Debug</Configuration>
+ <RootNamespace>SamplesCommon</RootNamespace>
+ <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <DriverType>KMDF</DriverType>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
+ <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
+ <KMDF_VERSION_MINOR>31</KMDF_VERSION_MINOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <DriverType>KMDF</DriverType>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
+ <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
+ <KMDF_VERSION_MINOR>31</KMDF_VERSION_MINOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <DriverType>KMDF</DriverType>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
+ <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
+ <KMDF_VERSION_MINOR>31</KMDF_VERSION_MINOR>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <DriverType>KMDF</DriverType>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
+ <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
+ <KMDF_VERSION_MINOR>31</KMDF_VERSION_MINOR>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace_macros.h</WppScanConfigurationData>
+ <WppKernelMode>true</WppKernelMode>
+ <AdditionalIncludeDirectories>$(SDK_INC_PATH);$(DDK_INC_PATH)\acx\km\1.1;..\inc;..\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ACX_VERSION_MAJOR=1;ACX_VERSION_MINOR=1;KMDF_VERSION_MAJOR=1;KMDF_VERSION_MINOR=31;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <DriverSign>
+ <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
+ </DriverSign>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace_macros.h</WppScanConfigurationData>
+ <WppKernelMode>true</WppKernelMode>
+ <AdditionalIncludeDirectories>$(SDK_INC_PATH);$(DDK_INC_PATH)\acx\km\1.1;..\inc;..\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ACX_VERSION_MAJOR=1;ACX_VERSION_MINOR=1;KMDF_VERSION_MAJOR=1;KMDF_VERSION_MINOR=31;KMDF_VERSION_MINOR=31;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <DriverSign>
+ <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
+ </DriverSign>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace_macros.h</WppScanConfigurationData>
+ <WppKernelMode>true</WppKernelMode>
+ <AdditionalIncludeDirectories>$(SDK_INC_PATH);$(DDK_INC_PATH)\acx\km\1.1;..\inc;..\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ACX_VERSION_MAJOR=1;ACX_VERSION_MINOR=1;KMDF_VERSION_MAJOR=1;KMDF_VERSION_MINOR=31;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <DriverSign>
+ <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
+ </DriverSign>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+ <ClCompile>
+ <WppEnabled>true</WppEnabled>
+ <WppRecorderEnabled>true</WppRecorderEnabled>
+ <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace_macros.h</WppScanConfigurationData>
+ <WppKernelMode>true</WppKernelMode>
+ <AdditionalIncludeDirectories>$(SDK_INC_PATH);$(DDK_INC_PATH)\acx\km\1.1;..\inc;..\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ACX_VERSION_MAJOR=1;ACX_VERSION_MINOR=1;KMDF_VERSION_MAJOR=1;KMDF_VERSION_MINOR=31;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <DriverSign>
+ <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
+ </DriverSign>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <FilesToPackage Include="$(TargetPath)" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="NewDelete.h" />
+ <ClInclude Include="CircuitHelper.h" />
+ <ClInclude Include="KeywordDetector.h" />
+ <ClInclude Include="Private.h" />
+ <ClInclude Include="Public.h" />
+ <ClInclude Include="SaveData.h" />
+ <ClInclude Include="SimPeakMeter.h" />
+ <ClInclude Include="StreamEngine.h" />
+ <ClInclude Include="ToneGenerator.h" />
+ <ClInclude Include="Trace.h" />
+ <ClInclude Include="Trace_macros.h" />
+ <ClInclude Include="WaveReader.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="NewDelete.cpp" />
+ <ClCompile Include="captureCircuit.cpp" />
+ <ClCompile Include="CircuitHelper.cpp" />
+ <ClCompile Include="KeywordDetector.cpp" />
+ <ClCompile Include="renderCircuit.cpp" />
+ <ClCompile Include="SaveData.cpp" />
+ <ClCompile Include="SimPeakMeter.cpp" />
+ <ClCompile Include="StreamEngine.cpp" />
+ <ClCompile Include="ToneGenerator.cpp" />
+ <ClCompile Include="WaveReader.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/audio/Acx/Samples/Common/SaveData.cpp b/audio/Acx/Samples/Common/SaveData.cpp
new file mode 100644
index 00000000..72e98850
--- /dev/null
+++ b/audio/Acx/Samples/Common/SaveData.cpp
@@ -0,0 +1,1103 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ SaveData.cpp
+
+Abstract:
+
+ Implementation of data saving class for ACX driver samples.
+
+ To save the playback data to disk, this class maintains a circular data
+ buffer, associated frame structures and worker items to save frames to
+ disk.
+ Each frame structure represents a portion of buffer. When that portion
+ of frame is full, a workitem is scheduled to save it to disk.
+
+
+
+--*/
+#pragma warning (disable : 4127)
+#pragma warning (disable : 26165)
+
+
+#include "private.h"
+#include <devguid.h>
+#include <ks.h>
+#include <mmsystem.h>
+#include <ksmedia.h>
+#include "savedata.h"
+#include <ntstrsafe.h> // This is for using RtlStringCbPrintf
+
+#define SAVEDATA_POOLTAG 'TDVS'
+#define SAVEDATA_POOLTAG1 '1DVS'
+#define SAVEDATA_POOLTAG2 '2DVS'
+#define SAVEDATA_POOLTAG3 '3DVS'
+#define SAVEDATA_POOLTAG4 '4DVS'
+#define SAVEDATA_POOLTAG5 '5DVS'
+#define SAVEDATA_POOLTAG6 '6DVS'
+#define SAVEDATA_POOLTAG7 '7DVS'
+
+//=============================================================================
+// Defines
+//=============================================================================
+#define RIFF_TAG 0x46464952;
+#define WAVE_TAG 0x45564157;
+#define FMT__TAG 0x20746D66;
+#define DATA_TAG 0x61746164;
+
+#define DEFAULT_FRAME_COUNT 4
+#define DEFAULT_FRAME_SIZE PAGE_SIZE * 4
+#define DEFAULT_BUFFER_SIZE DEFAULT_FRAME_SIZE * DEFAULT_FRAME_COUNT
+
+#define DEFAULT_FILE_FOLDER1 L"\\DriverData\\Audio_Samples"
+#define DEFAULT_FILE_FOLDER2 L"\\DriverData\\Audio_Samples\\AudioCodec"
+#define DEFAULT_FILE_NAME L"\\DriverData\\Audio_Samples\\AudioCodec\\STREAM"
+#define OFFLOAD_FILE_NAME L"OFFLOAD"
+#define HOST_FILE_NAME L"HOST"
+
+#define MAX_WORKER_ITEM_COUNT 15
+
+
+PSAVEWORKER_PARAM CSaveData::m_pWorkItems = NULL;
+PDEVICE_OBJECT CSaveData::m_pDeviceObject = NULL;
+
+//=============================================================================
+// Statics
+//=============================================================================
+ULONG CSaveData::m_ulStreamId = 0;
+ULONG CSaveData::m_ulOffloadStreamId = 0;
+
+//=============================================================================
+// CSaveData
+//=============================================================================
+
+//=============================================================================
+_Use_decl_annotations_
+PAGED_CODE_SEG
+CSaveData::CSaveData()
+: m_pDataBuffer(NULL),
+ m_FileHandle(NULL),
+ m_ulFrameCount(DEFAULT_FRAME_COUNT),
+ m_ulBufferSize(DEFAULT_BUFFER_SIZE),
+ m_ulFrameSize(DEFAULT_FRAME_SIZE),
+ m_ulBufferOffset(0),
+ m_ulFrameIndex(0),
+ m_fFrameUsed(NULL),
+ m_waveFormat(NULL),
+ m_pFilePtr(NULL),
+ m_fWriteDisabled(FALSE),
+ m_bInitialized(FALSE)
+{
+ PAGED_CODE();
+
+ m_FileHeader.dwRiff = RIFF_TAG;
+ m_FileHeader.dwFileSize = 0;
+ m_FileHeader.dwWave = WAVE_TAG;
+ m_FileHeader.dwFormat = FMT__TAG;
+ m_FileHeader.dwFormatLength = sizeof(WAVEFORMATEX);
+
+ m_DataHeader.dwData = DATA_TAG;
+ m_DataHeader.dwDataLength = 0;
+
+ RtlZeroMemory(&m_objectAttributes, sizeof(m_objectAttributes));
+} // CSaveData
+
+//=============================================================================
+_Use_decl_annotations_
+PAGED_CODE_SEG
+CSaveData::~CSaveData()
+{
+ PAGED_CODE();
+ Cleanup();
+} // CSaveData
+
+void
+_Use_decl_annotations_
+PAGED_CODE_SEG
+CSaveData::Cleanup
+(
+ void
+)
+{
+ PAGED_CODE();
+
+ // Update the wave header in data file with real file size.
+ //
+ if(m_pFilePtr)
+ {
+ // RIFF header, whose size is the whole file size minus RIFF header.
+ m_FileHeader.dwFileSize =
+ (DWORD)m_pFilePtr->QuadPart - 2 * sizeof(DWORD);
+ // The data length is the size of all the audio that was written.
+ // It gets calculated by taking:
+ m_DataHeader.dwDataLength = (DWORD)m_pFilePtr->QuadPart - // the whole file size,
+ sizeof(m_FileHeader) - // minus the file header,
+ m_FileHeader.dwFormatLength - // minus the format,
+ sizeof(m_DataHeader); // minus the data header itself.
+
+ if (STATUS_SUCCESS == KeWaitForSingleObject
+ (
+ &m_FileSync,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL
+ ))
+ {
+ if (NT_SUCCESS(FileOpen(FALSE)))
+ {
+ FileWriteHeader();
+
+ FileClose();
+ }
+
+ KeReleaseMutex(&m_FileSync, FALSE);
+ }
+
+ m_FileHeader.dwRiff = RIFF_TAG;
+ m_FileHeader.dwFileSize = 0;
+ m_FileHeader.dwWave = WAVE_TAG;
+ m_FileHeader.dwFormat = FMT__TAG;
+ m_FileHeader.dwFormatLength = sizeof(WAVEFORMATEX);
+
+ m_DataHeader.dwData = DATA_TAG;
+ m_DataHeader.dwDataLength = 0;
+ m_pFilePtr = NULL;
+ }
+
+ if (m_waveFormat)
+ {
+ ExFreePoolWithTag(m_waveFormat, SAVEDATA_POOLTAG1);
+ m_waveFormat = NULL;
+ }
+
+ if (m_fFrameUsed)
+ {
+ ExFreePoolWithTag(m_fFrameUsed, SAVEDATA_POOLTAG2);
+ m_fFrameUsed = NULL;
+ }
+
+ if (m_FileName.Buffer)
+ {
+ ExFreePoolWithTag(m_FileName.Buffer, SAVEDATA_POOLTAG3);
+ m_FileName.Buffer = NULL;
+ }
+
+ if (m_pDataBuffer)
+ {
+ ExFreePoolWithTag(m_pDataBuffer, SAVEDATA_POOLTAG4);
+ m_pDataBuffer = NULL;
+ }
+}
+
+//=============================================================================
+_Use_decl_annotations_
+PAGED_CODE_SEG
+void
+CSaveData::DestroyWorkItems
+(
+ void
+)
+{
+ PAGED_CODE();
+
+ if (m_pWorkItems)
+ {
+ for (int i = 0; i < MAX_WORKER_ITEM_COUNT; i++)
+ {
+ if (m_pWorkItems[i].WorkItem!=NULL)
+ {
+ IoFreeWorkItem(m_pWorkItems[i].WorkItem);
+ m_pWorkItems[i].WorkItem = NULL;
+ }
+ }
+ ExFreePoolWithTag(m_pWorkItems, SAVEDATA_POOLTAG);
+ m_pWorkItems = NULL;
+ }
+
+} // DestroyWorkItems
+
+//=============================================================================
+_Use_decl_annotations_
+PAGED_CODE_SEG
+void
+CSaveData::Disable
+(
+ _In_ BOOL fDisable
+)
+{
+ PAGED_CODE();
+
+ m_fWriteDisabled = fDisable;
+} // Disable
+
+//=============================================================================
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CSaveData::FileClose(void)
+{
+ PAGED_CODE();
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ if (m_FileHandle)
+ {
+ ntStatus = ZwClose(m_FileHandle);
+ m_FileHandle = NULL;
+ }
+
+ return ntStatus;
+} // FileClose
+
+//=============================================================================
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CSaveData::FileOpen
+(
+ _In_ BOOL fOverWrite
+)
+{
+ PAGED_CODE();
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ IO_STATUS_BLOCK ioStatusBlock;
+
+ if( FALSE == m_bInitialized )
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if(!m_FileHandle)
+ {
+ ntStatus =
+ ZwCreateFile
+ (
+ &m_FileHandle,
+ GENERIC_WRITE | SYNCHRONIZE,
+ &m_objectAttributes,
+ &ioStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ 0,
+ fOverWrite ? FILE_OVERWRITE_IF : FILE_OPEN_IF,
+ FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
+ NULL,
+ 0
+ );
+ }
+
+ return ntStatus;
+} // FileOpen
+
+//=============================================================================
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CSaveData::FileWrite
+(
+ _In_reads_bytes_(ulDataSize) PBYTE pData,
+ _In_ ULONG ulDataSize
+)
+{
+ PAGED_CODE();
+
+ ASSERT(pData);
+ ASSERT(m_pFilePtr);
+
+ NTSTATUS ntStatus;
+
+ if (m_FileHandle)
+ {
+ IO_STATUS_BLOCK ioStatusBlock;
+
+ ntStatus = ZwWriteFile( m_FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &ioStatusBlock,
+ pData,
+ ulDataSize,
+ m_pFilePtr,
+ NULL);
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ ASSERT(ioStatusBlock.Information == ulDataSize);
+
+ m_pFilePtr->QuadPart += ulDataSize;
+ }
+ }
+ else
+ {
+ ntStatus = STATUS_INVALID_HANDLE;
+ }
+
+ return ntStatus;
+} // FileWrite
+
+//=============================================================================
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CSaveData::FileWriteHeader(void)
+{
+ PAGED_CODE();
+
+ NTSTATUS ntStatus;
+
+ if (m_FileHandle && m_waveFormat)
+ {
+ IO_STATUS_BLOCK ioStatusBlock;
+
+ m_pFilePtr->QuadPart = 0;
+
+ m_FileHeader.dwFormatLength = (m_waveFormat->wFormatTag == WAVE_FORMAT_PCM) ?
+ sizeof( PCMWAVEFORMAT ) :
+ sizeof( WAVEFORMATEX ) + m_waveFormat->cbSize;
+
+ ntStatus = ZwWriteFile( m_FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &ioStatusBlock,
+ &m_FileHeader,
+ sizeof(m_FileHeader),
+ m_pFilePtr,
+ NULL);
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ m_pFilePtr->QuadPart += sizeof(m_FileHeader);
+
+ ntStatus = ZwWriteFile( m_FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &ioStatusBlock,
+ m_waveFormat,
+ m_FileHeader.dwFormatLength,
+ m_pFilePtr,
+ NULL);
+ }
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ m_pFilePtr->QuadPart += m_FileHeader.dwFormatLength;
+
+ ntStatus = ZwWriteFile( m_FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &ioStatusBlock,
+ &m_DataHeader,
+ sizeof(m_DataHeader),
+ m_pFilePtr,
+ NULL);
+ }
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ m_pFilePtr->QuadPart += sizeof(m_DataHeader);
+ }
+ }
+ else
+ {
+ ntStatus = STATUS_INVALID_HANDLE;
+ }
+
+
+ return ntStatus;
+} // FileWriteHeader
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CSaveData::SetDeviceObject
+(
+ _In_ PDEVICE_OBJECT DeviceObject
+)
+{
+ PAGED_CODE();
+
+ ASSERT(DeviceObject);
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ m_pDeviceObject = DeviceObject;
+ return ntStatus;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+PDEVICE_OBJECT
+CSaveData::GetDeviceObject
+(
+ void
+)
+{
+ PAGED_CODE();
+
+ return m_pDeviceObject;
+}
+
+//=============================================================================
+_Use_decl_annotations_
+PSAVEWORKER_PARAM
+CSaveData::GetNewWorkItem
+(
+ void
+)
+{
+ LARGE_INTEGER timeOut = { 0 };
+ NTSTATUS ntStatus;
+
+ for (int i = 0; i < MAX_WORKER_ITEM_COUNT; i++)
+ {
+ ntStatus =
+ KeWaitForSingleObject
+ (
+ &m_pWorkItems[i].EventDone,
+ Executive,
+ KernelMode,
+ FALSE,
+ &timeOut
+ );
+ if (STATUS_SUCCESS == ntStatus)
+ {
+ if (m_pWorkItems[i].WorkItem)
+ return &(m_pWorkItems[i]);
+ else
+ return NULL;
+ }
+ }
+
+ return NULL;
+} // GetNewWorkItem
+
+//=============================================================================
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CSaveData::Initialize
+(
+ _In_ BOOL _bOffloaded
+)
+{
+ PAGED_CODE();
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ WCHAR szTemp[MAX_PATH];
+ size_t cLen = 0;
+ IO_STATUS_BLOCK ioStatusBlock = {0};
+ HANDLE fileHandle;
+ OBJECT_ATTRIBUTES objectAttributes;
+ UNICODE_STRING fileName;
+
+ if (_bOffloaded)
+ {
+ m_ulOffloadStreamId++;
+ }
+ else
+ {
+ m_ulStreamId++;
+ }
+
+ RtlInitUnicodeString(&fileName, DEFAULT_FILE_FOLDER1);
+ InitializeObjectAttributes(
+ &objectAttributes,
+ &fileName,
+ OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ // Create the folder.
+ ntStatus = ZwCreateFile(
+ &fileHandle,
+ 0,
+ &objectAttributes,
+ &ioStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ 0,
+ FILE_OPEN_IF,
+ FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
+ NULL,
+ 0);
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ ZwClose(fileHandle);
+ fileHandle = NULL;
+
+ RtlInitUnicodeString(&fileName, DEFAULT_FILE_FOLDER2);
+ InitializeObjectAttributes(
+ &objectAttributes,
+ &fileName,
+ OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ // Create the folder.
+ ntStatus = ZwCreateFile(
+ &fileHandle,
+ 0,
+ &objectAttributes,
+ &ioStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ 0,
+ FILE_OPEN_IF,
+ FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
+ NULL,
+ 0);
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ ZwClose(fileHandle);
+ fileHandle = NULL;
+ }
+ }
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ // Allocate data file name.
+ //
+ RtlStringCchPrintfW(szTemp, MAX_PATH, L"%s_%s_%d.wav", DEFAULT_FILE_NAME, _bOffloaded ? OFFLOAD_FILE_NAME : HOST_FILE_NAME, _bOffloaded ? m_ulOffloadStreamId : m_ulStreamId);
+ m_FileName.Length = 0;
+ ntStatus = RtlStringCchLengthW (szTemp, sizeof(szTemp)/sizeof(szTemp[0]), &cLen);
+ }
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ m_FileName.MaximumLength = (USHORT)((cLen * sizeof(WCHAR)) + sizeof(WCHAR));//convert to wchar and add room for NULL
+ m_FileName.Buffer = (PWSTR)
+ ExAllocatePool2
+ (
+ POOL_FLAG_PAGED,
+ m_FileName.MaximumLength,
+ SAVEDATA_POOLTAG3
+ );
+ if (!m_FileName.Buffer)
+ {
+ ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ // Allocate memory for data buffer.
+ //
+ if (NT_SUCCESS(ntStatus))
+ {
+ RtlStringCbCopyW(m_FileName.Buffer, m_FileName.MaximumLength, szTemp);
+ m_FileName.Length = (USHORT)wcslen(m_FileName.Buffer) * sizeof(WCHAR);
+
+ m_pDataBuffer = (PBYTE)
+ ExAllocatePool2
+ (
+ POOL_FLAG_NON_PAGED,
+ m_ulBufferSize,
+ SAVEDATA_POOLTAG4
+ );
+ if (!m_pDataBuffer)
+ {
+ ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ // Allocate memory for frame usage flags and m_pFilePtr.
+ //
+ if (NT_SUCCESS(ntStatus))
+ {
+ m_fFrameUsed = (PBOOL)
+ ExAllocatePool2
+ (
+ POOL_FLAG_NON_PAGED,
+ m_ulFrameCount * sizeof(BOOL) +
+ sizeof(LARGE_INTEGER),
+ SAVEDATA_POOLTAG2
+ );
+ if (!m_fFrameUsed)
+ {
+ ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ // Initialize the spinlock to synchronize access to the frames
+ //
+ KeInitializeSpinLock ( &m_FrameInUseSpinLock ) ;
+
+ // Initialize the file mutex
+ //
+ KeInitializeMutex( &m_FileSync, 1 ) ;
+
+ // Open the data file.
+ //
+ if (NT_SUCCESS(ntStatus))
+ {
+ // m_fFrameUsed has additional memory to hold m_pFilePtr
+ //
+ m_pFilePtr = (PLARGE_INTEGER)
+ (((PBYTE) m_fFrameUsed) + m_ulFrameCount * sizeof(BOOL));
+
+ // Create data file.
+ InitializeObjectAttributes
+ (
+ &m_objectAttributes,
+ &m_FileName,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL
+ );
+
+ m_bInitialized = TRUE;
+
+ // Write wave header information to data file.
+ ntStatus = KeWaitForSingleObject
+ (
+ &m_FileSync,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL
+ );
+
+ if (STATUS_SUCCESS == ntStatus)
+ {
+ ntStatus = FileOpen(TRUE);
+ if (NT_SUCCESS(ntStatus))
+ {
+ ntStatus = FileWriteHeader();
+
+ FileClose();
+ }
+
+ KeReleaseMutex( &m_FileSync, FALSE );
+ }
+ }
+
+ return ntStatus;
+} // Initialize
+
+//=============================================================================
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CSaveData::InitializeWorkItems
+(
+ _In_ PDEVICE_OBJECT DeviceObject
+)
+{
+ PAGED_CODE();
+
+ ASSERT(DeviceObject);
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ if (m_pWorkItems != NULL)
+ {
+ return ntStatus;
+ }
+
+ m_pWorkItems = (PSAVEWORKER_PARAM)
+ ExAllocatePool2
+ (
+ POOL_FLAG_NON_PAGED,
+ sizeof(SAVEWORKER_PARAM) * MAX_WORKER_ITEM_COUNT,
+ SAVEDATA_POOLTAG
+ );
+ if (m_pWorkItems)
+ {
+ for (int i = 0; i < MAX_WORKER_ITEM_COUNT; i++)
+ {
+
+ m_pWorkItems[i].WorkItem = IoAllocateWorkItem(DeviceObject);
+ if(m_pWorkItems[i].WorkItem == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ KeInitializeEvent
+ (
+ &m_pWorkItems[i].EventDone,
+ NotificationEvent,
+ TRUE
+ );
+ }
+ }
+ else
+ {
+ ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ return ntStatus;
+} // InitializeWorkItems
+
+//=============================================================================
+_Use_decl_annotations_
+PAGED_CODE_SEG
+VOID
+SaveFrameWorkerCallback
+(
+ _In_ PDEVICE_OBJECT pDeviceObject,
+ _In_opt_ PVOID Context
+)
+{
+ UNREFERENCED_PARAMETER(pDeviceObject);
+
+ PAGED_CODE();
+
+ ASSERT(Context);
+
+ PSAVEWORKER_PARAM pParam = (PSAVEWORKER_PARAM) Context;
+ PCSaveData pSaveData;
+
+ if (NULL == pParam)
+ {
+ // This is completely unexpected, assert here.
+ //
+ ASSERT(pParam);
+ return;
+ }
+
+ ASSERT(pParam->pSaveData);
+ ASSERT(pParam->pSaveData->m_fFrameUsed);
+
+ if (pParam->WorkItem)
+ {
+ pSaveData = pParam->pSaveData;
+
+ if (STATUS_SUCCESS == KeWaitForSingleObject
+ (
+ &pSaveData->m_FileSync,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL
+ ))
+ {
+ if (NT_SUCCESS(pSaveData->FileOpen(FALSE)))
+ {
+ pSaveData->FileWrite(pParam->pData, pParam->ulDataSize);
+ pSaveData->FileClose();
+ }
+ InterlockedExchange( (LONG *)&(pSaveData->m_fFrameUsed[pParam->ulFrameNo]), FALSE );
+
+ KeReleaseMutex( &pSaveData->m_FileSync, FALSE );
+ }
+ }
+
+ KeSetEvent(&pParam->EventDone, 0, FALSE);
+} // SaveFrameWorkerCallback
+
+//=============================================================================
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CSaveData::SetDataFormat
+(
+ _In_ PKSDATAFORMAT pDataFormat
+)
+{
+ PAGED_CODE();
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ ASSERT(pDataFormat);
+
+ PWAVEFORMATEX pwfx = NULL;
+
+ if (IsEqualGUIDAligned(pDataFormat->Specifier,
+ KSDATAFORMAT_SPECIFIER_DSOUND))
+ {
+ pwfx =
+ &(((PKSDATAFORMAT_DSOUND) pDataFormat)->BufferDesc.WaveFormatEx);
+ }
+ else if (IsEqualGUIDAligned(pDataFormat->Specifier,
+ KSDATAFORMAT_SPECIFIER_WAVEFORMATEX))
+ {
+ pwfx = &((PKSDATAFORMAT_WAVEFORMATEX) pDataFormat)->WaveFormatEx;
+ }
+
+ if (pwfx)
+ {
+ // Free the previously allocated waveformat
+ if (m_waveFormat)
+ {
+ ExFreePoolWithTag(m_waveFormat, SAVEDATA_POOLTAG1);
+ }
+
+ m_waveFormat = (PWAVEFORMATEX)
+ ExAllocatePool2
+ (
+ POOL_FLAG_NON_PAGED,
+ (pwfx->wFormatTag == WAVE_FORMAT_PCM) ?
+ sizeof( PCMWAVEFORMAT ) :
+ sizeof( WAVEFORMATEX ) + pwfx->cbSize,
+ SAVEDATA_POOLTAG1
+ );
+
+ if(m_waveFormat)
+ {
+ RtlCopyMemory( m_waveFormat,
+ pwfx,
+ (pwfx->wFormatTag == WAVE_FORMAT_PCM) ?
+ sizeof( PCMWAVEFORMAT ) :
+ sizeof( WAVEFORMATEX ) + pwfx->cbSize);
+ }
+ else
+ {
+ ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+ return ntStatus;
+} // SetDataFormat
+
+//=============================================================================
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CSaveData::SetMaxWriteSize
+(
+ _In_ ULONG ulMaxWriteSize
+)
+{
+ PAGED_CODE();
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ ULONG bufferSize = 0;
+ PBYTE buffer = NULL;
+
+ //
+ // Compute new buffer size.
+ //
+ ntStatus = RtlULongMult(ulMaxWriteSize, DEFAULT_FRAME_COUNT, &bufferSize);
+ if (!NT_SUCCESS(ntStatus))
+ {
+ ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ goto Done;
+ }
+
+ //
+ // Alloc memory for buffer.
+ //
+ buffer = (PBYTE)
+ ExAllocatePool2
+ (
+ POOL_FLAG_NON_PAGED,
+ bufferSize,
+ SAVEDATA_POOLTAG4
+ );
+ if (!buffer)
+ {
+ ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ goto Done;
+ }
+
+ //
+ // Free old one.
+ //
+ if (m_pDataBuffer)
+ {
+ ExFreePoolWithTag(m_pDataBuffer, SAVEDATA_POOLTAG4);
+ m_pDataBuffer = NULL;
+ }
+
+ //
+ // Init new buffer settings.
+ //
+ m_pDataBuffer = buffer;
+ m_ulBufferSize = bufferSize;
+ m_ulFrameSize = ulMaxWriteSize;
+
+ ntStatus = STATUS_SUCCESS;
+
+Done:
+ return ntStatus;
+} // SetDataFormat
+
+//=============================================================================
+_Use_decl_annotations_
+PAGED_CODE_SEG
+void
+CSaveData::ReadData
+(
+ _Inout_updates_bytes_all_(ulByteCount) PBYTE pBuffer,
+ _In_ ULONG ulByteCount
+)
+{
+ UNREFERENCED_PARAMETER(pBuffer);
+ UNREFERENCED_PARAMETER(ulByteCount);
+
+ PAGED_CODE();
+
+ // Not implemented yet.
+} // ReadData
+
+//=============================================================================
+_Use_decl_annotations_
+void
+CSaveData::SaveFrame
+(
+ _In_ ULONG ulFrameNo,
+ _In_ ULONG ulDataSize
+)
+{
+ PSAVEWORKER_PARAM pParam = NULL;
+
+ pParam = GetNewWorkItem();
+ if (pParam)
+ {
+ pParam->pSaveData = this;
+ pParam->ulFrameNo = ulFrameNo;
+ pParam->ulDataSize = ulDataSize;
+ pParam->pData = m_pDataBuffer + ulFrameNo * m_ulFrameSize;
+ KeResetEvent(&pParam->EventDone);
+ IoQueueWorkItem(pParam->WorkItem, SaveFrameWorkerCallback,
+ CriticalWorkQueue, (PVOID)pParam);
+ }
+} // SaveFrame
+
+//=============================================================================
+void
+_Use_decl_annotations_
+PAGED_CODE_SEG
+CSaveData::WaitAllWorkItems
+(
+ void
+)
+{
+ PAGED_CODE();
+
+ // Save the last partially-filled frame
+ if (m_ulBufferOffset > m_ulFrameIndex * m_ulFrameSize)
+ {
+ ULONG size;
+
+ size = m_ulBufferOffset - m_ulFrameIndex * m_ulFrameSize;
+ SaveFrame(m_ulFrameIndex, size);
+ }
+
+ for (int i = 0; i < MAX_WORKER_ITEM_COUNT; i++)
+ {
+ KeWaitForSingleObject
+ (
+ &(m_pWorkItems[i].EventDone),
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL
+ );
+ }
+} // WaitAllWorkItems
+
+//=============================================================================
+_Use_decl_annotations_
+void
+CSaveData::WriteData
+(
+ _In_reads_bytes_(ulByteCount) PBYTE pBuffer,
+ _In_ ULONG ulByteCount
+)
+{
+ ASSERT(pBuffer);
+
+ BOOL fSaveFrame = FALSE;
+ ULONG ulSaveFrameIndex = 0;
+ KIRQL oldIrql;
+
+ // If stream writing is disabled, then exit.
+ //
+ if (m_fWriteDisabled)
+ {
+ return;
+ }
+
+ if( 0 == ulByteCount )
+ {
+ return;
+ }
+
+ // The logic below assumes that write size is <= than frame size.
+ if (ulByteCount > m_ulFrameSize)
+ {
+ ulByteCount = m_ulFrameSize;
+ }
+
+ // Check to see if this frame is available.
+ KeAcquireSpinLock(&m_FrameInUseSpinLock, &oldIrql);
+ if (!m_fFrameUsed[m_ulFrameIndex])
+ {
+ KeReleaseSpinLock(&m_FrameInUseSpinLock, oldIrql );
+
+ ULONG ulWriteBytes = ulByteCount;
+
+ if( (m_ulBufferSize - m_ulBufferOffset) < ulWriteBytes )
+ {
+ ulWriteBytes = m_ulBufferSize - m_ulBufferOffset;
+ }
+
+ RtlCopyMemory(m_pDataBuffer + m_ulBufferOffset, pBuffer, ulWriteBytes);
+ m_ulBufferOffset += ulWriteBytes;
+
+ // Check to see if we need to save this frame
+ if (m_ulBufferOffset >= ((m_ulFrameIndex + 1) * m_ulFrameSize))
+ {
+ fSaveFrame = TRUE;
+ }
+
+ // Loop the buffer, if we reached the end.
+ if (m_ulBufferOffset == m_ulBufferSize)
+ {
+ fSaveFrame = TRUE;
+ m_ulBufferOffset = 0;
+ }
+
+ if (fSaveFrame)
+ {
+ InterlockedExchange( (LONG *)&(m_fFrameUsed[m_ulFrameIndex]), TRUE );
+ ulSaveFrameIndex = m_ulFrameIndex;
+ m_ulFrameIndex = (m_ulFrameIndex + 1) % m_ulFrameCount;
+ }
+
+ // Write the left over if the next frame is available.
+ if (ulWriteBytes != ulByteCount)
+ {
+ KeAcquireSpinLock(&m_FrameInUseSpinLock, &oldIrql );
+ if (!m_fFrameUsed[m_ulFrameIndex])
+ {
+ KeReleaseSpinLock(&m_FrameInUseSpinLock, oldIrql );
+ RtlCopyMemory
+ (
+ m_pDataBuffer + m_ulBufferOffset,
+ pBuffer + ulWriteBytes,
+ ulByteCount - ulWriteBytes
+ );
+
+ m_ulBufferOffset += ulByteCount - ulWriteBytes;
+ }
+ else
+ {
+ KeReleaseSpinLock(&m_FrameInUseSpinLock, oldIrql);
+ }
+ }
+
+ if (fSaveFrame)
+ {
+ SaveFrame(ulSaveFrameIndex, m_ulFrameSize);
+ }
+ }
+ else
+ {
+ KeReleaseSpinLock(&m_FrameInUseSpinLock, oldIrql );
+ }
+
+} // WriteData
+
+
diff --git a/audio/Acx/Samples/Common/SaveData.h b/audio/Acx/Samples/Common/SaveData.h
new file mode 100644
index 00000000..9138352f
--- /dev/null
+++ b/audio/Acx/Samples/Common/SaveData.h
@@ -0,0 +1,259 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ SaveData.h
+
+Abstract:
+
+ Declaration of data saving class for ACX driver samples. This class supplies services
+to save data to disk.
+
+
+--*/
+
+#pragma once
+
+//-----------------------------------------------------------------------------
+// Forward declaration
+//-----------------------------------------------------------------------------
+class CSaveData;
+typedef CSaveData *PCSaveData;
+
+
+//-----------------------------------------------------------------------------
+// Structs
+//-----------------------------------------------------------------------------
+
+// Parameter to workitem.
+#include <pshpack1.h>
+typedef struct _SAVEWORKER_PARAM {
+ PIO_WORKITEM WorkItem;
+ ULONG ulFrameNo;
+ ULONG ulDataSize;
+ PBYTE pData;
+ PCSaveData pSaveData;
+ KEVENT EventDone;
+} SAVEWORKER_PARAM;
+typedef SAVEWORKER_PARAM *PSAVEWORKER_PARAM;
+#include <poppack.h>
+
+// wave file header.
+#include <pshpack1.h>
+typedef struct _OUTPUT_FILE_HEADER
+{
+ DWORD dwRiff;
+ DWORD dwFileSize;
+ DWORD dwWave;
+ DWORD dwFormat;
+ DWORD dwFormatLength;
+} OUTPUT_FILE_HEADER;
+typedef OUTPUT_FILE_HEADER *POUTPUT_FILE_HEADER;
+
+typedef struct _OUTPUT_DATA_HEADER
+{
+ DWORD dwData;
+ DWORD dwDataLength;
+} OUTPUT_DATA_HEADER;
+typedef OUTPUT_DATA_HEADER *POUTPUT_DATA_HEADER;
+
+#include <poppack.h>
+
+//-----------------------------------------------------------------------------
+// Classes
+//-----------------------------------------------------------------------------
+
+///////////////////////////////////////////////////////////////////////////////
+// CSaveData
+// Saves the wave data to disk.
+//
+__drv_maxIRQL(PASSIVE_LEVEL)
+PAGED_CODE_SEG
+IO_WORKITEM_ROUTINE SaveFrameWorkerCallback;
+
+class CSaveData
+{
+protected:
+ UNICODE_STRING m_FileName; // DataFile name.
+ HANDLE m_FileHandle; // DataFile handle.
+ PBYTE m_pDataBuffer; // Data buffer.
+ ULONG m_ulBufferSize; // Total buffer size.
+
+ ULONG m_ulFrameIndex; // Current Frame.
+ ULONG m_ulFrameCount; // Frame count.
+ ULONG m_ulFrameSize;
+ ULONG m_ulBufferOffset; // index in buffer.
+ PBOOL m_fFrameUsed; // Frame usage table.
+ KSPIN_LOCK m_FrameInUseSpinLock; // Spinlock for synch.
+ KMUTEX m_FileSync; // Synchronizes file access
+
+ OBJECT_ATTRIBUTES m_objectAttributes; // Used for opening file.
+
+ OUTPUT_FILE_HEADER m_FileHeader;
+ PWAVEFORMATEX m_waveFormat;
+ OUTPUT_DATA_HEADER m_DataHeader;
+ PLARGE_INTEGER m_pFilePtr;
+
+ static PDEVICE_OBJECT m_pDeviceObject;
+ static ULONG m_ulStreamId;
+ static ULONG m_ulOffloadStreamId;
+ static PSAVEWORKER_PARAM m_pWorkItems;
+
+ BOOL m_fWriteDisabled;
+
+ BOOL m_bInitialized;
+
+public:
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ CSaveData();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ ~CSaveData();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ void
+ Cleanup(
+ void
+ );
+
+ static
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ InitializeWorkItems(
+ _In_ PDEVICE_OBJECT DeviceObject
+ );
+
+ static
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ void
+ DestroyWorkItems(
+ void
+ );
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ void
+ Disable(
+ _In_ BOOL fDisable
+ );
+
+ static
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ PSAVEWORKER_PARAM
+ GetNewWorkItem(
+ void
+ );
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ Initialize(
+ _In_ BOOL _bOffloaded
+ );
+
+ static
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ SetDeviceObject(
+ _In_ PDEVICE_OBJECT DeviceObject
+ );
+
+ static
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ PDEVICE_OBJECT
+ GetDeviceObject(
+ void
+ );
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ void
+ ReadData(
+ _Inout_updates_bytes_all_(ulByteCount) PBYTE pBuffer,
+ _In_ ULONG ulByteCount
+ );
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ SetDataFormat(
+ _In_ PKSDATAFORMAT pDataFormat
+ );
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ SetMaxWriteSize(
+ _In_ ULONG ulMaxWriteSize
+ );
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ void
+ WaitAllWorkItems(
+ void
+ );
+
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ void
+ WriteData(
+ _In_reads_bytes_(ulByteCount) PBYTE pBuffer,
+ _In_ ULONG ulByteCount
+ );
+
+private:
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ FileClose(
+ void
+ );
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ FileOpen(
+ _In_ BOOL fOverWrite
+ );
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ FileWrite(
+ _In_reads_bytes_(ulDataSize) PBYTE pData,
+ _In_ ULONG ulDataSize
+ );
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ FileWriteHeader(
+ void
+ );
+
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ void
+ SaveFrame(
+ _In_ ULONG ulFrameNo,
+ _In_ ULONG ulDataSize
+ );
+
+ friend
+ IO_WORKITEM_ROUTINE SaveFrameWorkerCallback;
+};
+typedef CSaveData *PCSaveData;
+
diff --git a/audio/Acx/Samples/Common/SimPeakMeter.cpp b/audio/Acx/Samples/Common/SimPeakMeter.cpp
new file mode 100644
index 00000000..0dfbd4e5
--- /dev/null
+++ b/audio/Acx/Samples/Common/SimPeakMeter.cpp
@@ -0,0 +1,106 @@
+/*++
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ SimPeakMeter.cpp
+
+Abstract:
+
+ Virtual Peakmeter - aggregates all streams
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include "private.h"
+#include "SimPeakMeter.h"
+
+#ifndef __INTELLISENSE__
+#include "SimPeakMeter.tmh"
+#endif
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+CSimPeakMeter::CSimPeakMeter()
+{
+ PAGED_CODE();
+ m_NumStreams = 0;
+ m_PeakMeterIndex = 0;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+CSimPeakMeter::~CSimPeakMeter()
+{
+ PAGED_CODE();
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+LONG CSimPeakMeter::GetValue(ULONG Channel)
+{
+ PAGED_CODE();
+
+ // Ignore channel
+ UNREFERENCED_PARAMETER(Channel);
+
+#define PEAKMETER_VALUE_FULL (PEAKMETER_MAXIMUM / PEAKMETER_STEPPING_DELTA * PEAKMETER_STEPPING_DELTA)
+#define PEAKMETER_VALUE_HALF (PEAKMETER_MAXIMUM / 2 / PEAKMETER_STEPPING_DELTA * PEAKMETER_STEPPING_DELTA)
+#define PEAKMETER_VALUE_QUARTER (PEAKMETER_MAXIMUM / 4 / PEAKMETER_STEPPING_DELTA * PEAKMETER_STEPPING_DELTA)
+#define PEAKMETER_VALUE_ONE_EIGTH (PEAKMETER_MAXIMUM / 8 / PEAKMETER_STEPPING_DELTA * PEAKMETER_STEPPING_DELTA)
+
+ LONG PeakMeterValues[] = {
+ PEAKMETER_VALUE_ONE_EIGTH,
+ PEAKMETER_VALUE_QUARTER,
+ PEAKMETER_VALUE_HALF,
+ PEAKMETER_VALUE_FULL,
+ PEAKMETER_VALUE_HALF,
+ PEAKMETER_VALUE_QUARTER
+ };
+
+ if (m_NumStreams)
+ {
+ LONG pmi = InterlockedIncrement(&m_PeakMeterIndex);
+ if (pmi == ARRAYSIZE(PeakMeterValues))
+ {
+ pmi = 0;
+ InterlockedExchange(&m_PeakMeterIndex, 0);
+ }
+
+ return PeakMeterValues[pmi];
+ }
+
+ //
+ // No active streams. Peak meter = 0
+ //
+ return 0;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS CSimPeakMeter::StartStream()
+{
+ PAGED_CODE();
+ InterlockedIncrement(&m_NumStreams);
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS CSimPeakMeter::StopStream()
+{
+ PAGED_CODE();
+
+ ASSERT(m_NumStreams);
+ InterlockedDecrement(&m_NumStreams);
+
+ return STATUS_SUCCESS;
+}
diff --git a/audio/Acx/Samples/Common/SimPeakMeter.h b/audio/Acx/Samples/Common/SimPeakMeter.h
new file mode 100644
index 00000000..7203f299
--- /dev/null
+++ b/audio/Acx/Samples/Common/SimPeakMeter.h
@@ -0,0 +1,51 @@
+/*++
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ SimPeakMeter.h
+
+Abstract:
+
+ Virtual Peakmeter - aggregates all streams
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#pragma once
+
+class CSimPeakMeter
+{
+public:
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ CSimPeakMeter();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ ~CSimPeakMeter();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ LONG GetValue(_In_ ULONG Channel);
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS StartStream();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS StopStream();
+
+private:
+ LONG m_NumStreams;
+ LONG m_PeakMeterIndex;
+};
+
diff --git a/audio/Acx/Samples/Common/StreamEngine.cpp b/audio/Acx/Samples/Common/StreamEngine.cpp
new file mode 100644
index 00000000..be90bac6
--- /dev/null
+++ b/audio/Acx/Samples/Common/StreamEngine.cpp
@@ -0,0 +1,1345 @@
+/*++
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ StreamEngine.cpp
+
+Abstract:
+
+ Virtual Streaming Engine - this module controls streaming logic for
+ the device.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include "private.h"
+#include "public.h"
+#include <devguid.h>
+#include <ks.h>
+#include <mmsystem.h>
+#include <ksmedia.h>
+#include "streamengine.h"
+
+#ifndef __INTELLISENSE__
+#include "streamengine.tmh"
+#endif
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+CStreamEngine::CStreamEngine(
+ _In_ ACXSTREAM Stream,
+ _In_ ACXDATAFORMAT StreamFormat,
+ _In_ BOOL Offload,
+ _In_opt_ CSimPeakMeter *CircuitPeakmeter
+)
+ : m_PacketsCount(0),
+ m_PacketSize(0),
+ m_FirstPacketOffset(0),
+ m_NotificationTimer(NULL),
+ m_CurrentState(AcxStreamStateStop),
+ m_CurrentPacket(0),
+ m_Position(0),
+ m_Stream(Stream),
+ m_StreamFormat(StreamFormat),
+ m_StartTime(0),
+ m_StartPosition(0),
+ m_GlitchAdjust(0),
+ m_ToneFrequency(DEFAULT_FREQUENCY),
+ m_Offload(Offload),
+ m_pCircuitPeakmeter(CircuitPeakmeter)
+{
+ PAGED_CODE();
+
+ KeQueryPerformanceCounter(&m_PerformanceCounterFrequency);
+ RtlZeroMemory(m_Packets, sizeof(m_Packets));
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+CStreamEngine::~CStreamEngine()
+{
+ PAGED_CODE();
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CStreamEngine::AllocateRtPackets(
+ _In_ ULONG PacketCount,
+ _In_ ULONG PacketSize,
+ _Out_ PACX_RTPACKET* Packets
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PACX_RTPACKET packets = NULL;
+ PVOID packetBuffer = NULL;
+ ULONG i;
+ ULONG packetAllocSizeInPages = 0;
+ ULONG packetAllocSizeInBytes = 0;
+ ULONG firstPacketOffset = 0;
+ size_t packetsSize = 0;
+
+ PAGED_CODE();
+
+ if (PacketCount > MAX_PACKET_COUNT)
+ {
+ ASSERT(FALSE);
+ status = STATUS_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ status = RtlSizeTMult(PacketCount, sizeof(ACX_RTPACKET), &packetsSize);
+ if (!NT_SUCCESS(status))
+ {
+ ASSERT(FALSE);
+ goto exit;
+ }
+
+ packets = (PACX_RTPACKET)ExAllocatePool2(POOL_FLAG_NON_PAGED, packetsSize, DeviceDriverTag);
+ if (!packets)
+ {
+ status = STATUS_NO_MEMORY;
+ ASSERT(FALSE);
+ goto exit;
+ }
+
+ //
+ // We need to allocate page-aligned buffers, to ensure no kernel memory leaks
+ // to user space. Round up the packet size to page aligned, then calculate
+ // the first packet's buffer offset so packet 0 ends on a page boundary and
+ // packet 1 begins on a page boundary.
+ //
+ status = RtlULongAdd(PacketSize, PAGE_SIZE - 1, &packetAllocSizeInPages);
+ if (!NT_SUCCESS(status))
+ {
+ ASSERT(FALSE);
+ goto exit;
+ }
+ packetAllocSizeInPages = packetAllocSizeInPages / PAGE_SIZE;
+ packetAllocSizeInBytes = PAGE_SIZE * packetAllocSizeInPages;
+ firstPacketOffset = packetAllocSizeInBytes - PacketSize;
+
+ for (i = 0; i < PacketCount; ++i)
+ {
+ PMDL pMdl = NULL;
+
+ ACX_RTPACKET_INIT(&packets[i]);
+
+ packetBuffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, packetAllocSizeInBytes, DeviceDriverTag);
+ if (packetBuffer == NULL)
+ {
+ status = STATUS_NO_MEMORY;
+ goto exit;
+ }
+
+ pMdl = IoAllocateMdl(packetBuffer, packetAllocSizeInBytes, FALSE, TRUE, NULL);
+ if (pMdl == NULL)
+ {
+ status = STATUS_NO_MEMORY;
+ goto exit;
+ }
+
+ MmBuildMdlForNonPagedPool(pMdl);
+
+ WDF_MEMORY_DESCRIPTOR_INIT_MDL(&((packets)[i].RtPacketBuffer), pMdl, packetAllocSizeInBytes);
+
+ packets[i].RtPacketSize = PacketSize;
+ if (i == 0)
+ {
+ packets[i].RtPacketOffset = firstPacketOffset;
+ }
+ else
+ {
+ packets[i].RtPacketOffset = 0;
+ }
+ m_Packets[i] = packetBuffer;
+
+ packetBuffer = NULL;
+ }
+
+ *Packets = packets;
+ packets = NULL;
+ m_PacketsCount = PacketCount;
+ m_PacketSize = PacketSize;
+ m_FirstPacketOffset = firstPacketOffset;
+
+exit:
+ if (packetBuffer)
+ {
+ ExFreePoolWithTag(packetBuffer, DeviceDriverTag);
+ }
+ if (packets)
+ {
+ FreeRtPackets(packets, PacketCount);
+ }
+ return status;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+VOID
+CStreamEngine::FreeRtPackets(
+ _Frees_ptr_ PACX_RTPACKET Packets,
+ _In_ ULONG PacketCount
+)
+{
+ ULONG i;
+ PVOID buffer;
+
+ PAGED_CODE();
+
+ for (i = 0; i < PacketCount; ++i)
+ {
+ if (Packets[i].RtPacketBuffer.u.MdlType.Mdl)
+ {
+ buffer = MmGetMdlVirtualAddress(Packets[i].RtPacketBuffer.u.MdlType.Mdl);
+ IoFreeMdl(Packets[i].RtPacketBuffer.u.MdlType.Mdl);
+ ExFreePool(buffer);
+ }
+ }
+
+ ExFreePool(Packets);
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CStreamEngine::PrepareHardware()
+{
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
+ WDF_TIMER_CONFIG timerConfig;
+ WDF_OBJECT_ATTRIBUTES timerAttributes;
+ PSTREAM_TIMER_CONTEXT timerCtx;
+
+ PAGED_CODE();
+
+ //
+ // If already in this state, do nothing.
+ //
+ if (m_CurrentState == AcxStreamStatePause)
+ {
+ // Nothing to do.
+ status = STATUS_SUCCESS;
+ goto exit;
+ }
+
+ if (m_CurrentState != AcxStreamStateStop)
+ {
+ // Error out.
+ status = STATUS_INVALID_STATE_TRANSITION;
+ goto exit;
+ }
+
+ //
+ // Stop to Pause.
+ //
+ WDF_TIMER_CONFIG_INIT(&timerConfig, CStreamEngine::s_EvtStreamPassCallback);
+ timerConfig.AutomaticSerialization = TRUE;
+ timerConfig.UseHighResolutionTimer = WdfTrue;
+ timerConfig.Period = 0;
+
+ WDF_OBJECT_ATTRIBUTES_INIT(&timerAttributes);
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&timerAttributes, STREAM_TIMER_CONTEXT);
+ timerAttributes.ParentObject = m_Stream;
+
+ status = WdfTimerCreate(&timerConfig, &timerAttributes, &m_NotificationTimer);
+ if (!NT_SUCCESS(status))
+ {
+ goto exit;
+ }
+
+ timerCtx = GetStreamTimerContext(m_NotificationTimer);
+ timerCtx->StreamEngine = this;
+
+ m_CurrentState = AcxStreamStatePause;
+ status = STATUS_SUCCESS;
+
+exit:
+ return status;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CStreamEngine::ReleaseHardware()
+{
+ PAGED_CODE();
+
+ //
+ // If already in this state, do nothing.
+ //
+ if (m_CurrentState == AcxStreamStateStop)
+ {
+ // Nothing to do.
+ goto exit;
+ }
+
+ //
+ // Just assert we are in the correct state.
+ // On the way down we always want to succeed.
+ //
+ ASSERT(m_CurrentState == AcxStreamStatePause);
+
+ //
+ // Pause to Stop.
+ //
+ if (m_NotificationTimer)
+ {
+ WdfTimerStop(m_NotificationTimer, TRUE);
+ WdfObjectDelete(m_NotificationTimer);
+ m_NotificationTimer = NULL;
+ }
+
+ KeFlushQueuedDpcs();
+
+ m_Position = 0;
+ m_GlitchAdjust = 0;
+ m_CurrentPacket = 0;
+
+ m_CurrentState = AcxStreamStateStop;
+
+exit:
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CStreamEngine::Pause()
+{
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
+
+ PAGED_CODE();
+
+ if (m_CurrentState == AcxStreamStatePause)
+ {
+ // Nothing to do.
+ status = STATUS_SUCCESS;
+ goto exit;
+ }
+
+ if (m_CurrentState != AcxStreamStateRun)
+ {
+ // Error out.
+ status = STATUS_INVALID_STATE_TRANSITION;
+ goto exit;
+ }
+
+ m_PeakMeter.StopStream();
+ if (m_pCircuitPeakmeter)
+ {
+ m_pCircuitPeakmeter->StopStream();
+ }
+
+ //
+ // Run to Pause.
+ //
+ WdfTimerStop(m_NotificationTimer, TRUE);
+
+ // Save the position we paused at.
+ UpdatePosition();
+
+ m_CurrentState = AcxStreamStatePause;
+ status = STATUS_SUCCESS;
+
+exit:
+ return status;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CStreamEngine::Run()
+{
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
+
+ PAGED_CODE();
+
+ if (m_CurrentState == AcxStreamStateRun)
+ {
+ // Nothing to do.
+ status = STATUS_SUCCESS;
+ goto exit;
+ }
+
+ if (m_CurrentState != AcxStreamStatePause)
+ {
+ status = STATUS_INVALID_STATE_TRANSITION;
+ goto exit;
+ }
+
+ m_PeakMeter.StartStream();
+ if (m_pCircuitPeakmeter)
+ {
+ m_pCircuitPeakmeter->StartStream();
+ }
+
+ //
+ // Pause to Run.
+ //
+ // Save the time and position - if we ran and paused previously, the StartTime and StartPosition will allow
+ // us to continue scheduling packet completions correctly, while still reporting absolute position from the
+ // start of the stream.
+ //
+ m_StartTime = KSCONVERT_PERFORMANCE_TIME(m_PerformanceCounterFrequency.QuadPart, KeQueryPerformanceCounter(NULL));
+ m_StartPosition = m_Position;
+
+ // Reset time we've lost to glitches
+ m_GlitchAdjust = 0;
+
+ ScheduleNextPass();
+
+ m_CurrentState = AcxStreamStateRun;
+ status = STATUS_SUCCESS;
+
+exit:
+ return status;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CStreamEngine::GetPresentationPosition(
+ _Out_ PULONGLONG PositionInBlocks,
+ _Out_ PULONGLONG QPCPosition
+)
+{
+ ULONG blockAlign;
+ LARGE_INTEGER qpc;
+
+ PAGED_CODE();
+
+ blockAlign = AcxDataFormatGetBlockAlign(m_StreamFormat);
+
+ // Update the position based on the current time
+ UpdatePosition();
+ qpc = KeQueryPerformanceCounter(NULL);
+
+ *PositionInBlocks = m_Position / blockAlign;
+ *QPCPosition = (ULONGLONG)qpc.QuadPart;
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CStreamEngine::GetLinearBufferPosition(
+ _Out_ PULONGLONG Position
+)
+{
+ UNREFERENCED_PARAMETER(Position);
+ PAGED_CODE();
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CStreamEngine::SetCurrentWritePosition(
+ _In_ ULONG Position
+)
+{
+ UNREFERENCED_PARAMETER(Position);
+ PAGED_CODE();
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CStreamEngine::SetLastBufferPosition(
+ _In_ ULONG Position
+)
+{
+ UNREFERENCED_PARAMETER(Position);
+ PAGED_CODE();
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CStreamEngine::AssignDrmContentId(
+ ULONG DrmContentId,
+ PACXDRMRIGHTS DrmRights
+)
+{
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(DrmContentId);
+ UNREFERENCED_PARAMETER(DrmRights);
+
+ //
+ // At this point the driver should enforce the new DrmRights.
+ //
+ // HDMI render: if DigitalOutputDisable or CopyProtect is true, enable HDCP.
+ //
+ // From MSDN:
+ //
+ // This sample doesn't forward protected content, but if your driver uses
+ // lower layer drivers or a different stack to properly work, please see the
+ // following info from MSDN:
+ //
+ // "Before allowing protected content to flow through a data path, the system
+ // verifies that the data path is secure. To do so, the system authenticates
+ // each module in the data path beginning at the upstream end of the data path
+ // and moving downstream. As each module is authenticated, that module gives
+ // the system information about the next module in the data path so that it
+ // can also be authenticated. To be successfully authenticated, a module's
+ // binary file must be signed as DRM-compliant.
+ //
+ // Two adjacent modules in the data path can communicate with each other in
+ // one of several ways. If the upstream module calls the downstream module
+ // through IoCallDriver, the downstream module is part of a WDM driver. In
+ // this case, the upstream module calls the AcxDrmForwardContentToDeviceObject
+ // function to provide the system with the device object representing the
+ // downstream module. (If the two modules communicate through the downstream
+ // module's content handlers, the upstream module calls AcxDrmAddContentHandlers
+ // instead.)
+ //
+ // For more information, see MSDN's DRM Functions and Interfaces.
+ //
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CStreamEngine::GetHWLatency(
+ _Out_ ULONG* FifoSize,
+ _Out_ ULONG* Delay
+)
+{
+ PAGED_CODE();
+
+ *FifoSize = 128;
+ *Delay = 0;
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+CSimPeakMeter *
+CStreamEngine::GetPeakMeter()
+{
+ PAGED_CODE();
+
+ return &m_PeakMeter;
+}
+
+_Use_decl_annotations_
+VOID
+CStreamEngine::s_EvtStreamPassCallback(
+ _In_ WDFTIMER Timer
+)
+{
+ CStreamEngine* This;
+ PSTREAM_TIMER_CONTEXT timerCtx;
+
+ // Get our stream engine pointer from the timer context
+ timerCtx = GetStreamTimerContext(Timer);
+ This = timerCtx->StreamEngine;
+
+ // Call the StreamPassCallback for the engine
+ This->StreamPassCallback();
+}
+
+// This is run every time the stream timer fires
+_Use_decl_annotations_
+VOID
+CStreamEngine::StreamPassCallback()
+{
+ ULONGLONG completedPacket;
+ ULONGLONG qpcCompleted;
+
+ // Process the packet (e.g. save render to file/generate capture data)
+ ProcessPacket();
+
+ // We've completed a packet! Increment our currently active packet
+ completedPacket = (ULONG)InterlockedIncrement((LONG*)&m_CurrentPacket) - 1;
+ // Save the time at which we moved to the next packet
+ qpcCompleted = (ULONGLONG)KeQueryPerformanceCounter(NULL).QuadPart;
+
+ InterlockedExchange64(&m_LastPacketStart.QuadPart, m_CurrentPacketStart.QuadPart);
+ InterlockedExchange64(&m_CurrentPacketStart.QuadPart, qpcCompleted);
+
+ // Tell ACX we've completed the packet.
+ (void)AcxRtStreamNotifyPacketComplete(m_Stream, completedPacket, qpcCompleted);
+
+ // Schedule when our new current packet will finish
+ ScheduleNextPass();
+}
+
+_Use_decl_annotations_
+VOID
+CStreamEngine::ScheduleNextPass()
+{
+ LONGLONG delay = 0;
+ ULONG bytesPerSecond;
+ ULONGLONG nextPacket = 0;
+ ULONGLONG nextPacketStartPosition = 0;
+ ULONGLONG nextPacketPositionFromLastPause = 0;
+ ULONGLONG nextPacketTimeFromLastPauseHns = 0;
+ ULONGLONG nextPacketTime = 0;
+ ULONGLONG currentTime;
+ BOOLEAN inTimerQueue = FALSE;
+
+ // Get the number of bytes per second from our stored stream format
+ bytesPerSecond = GetBytesPerSecond();
+
+ // Calculate the absolute position of the beginning of the next packet from the beginning of the stream
+ nextPacket = m_CurrentPacket + 1;
+ nextPacketStartPosition = nextPacket * m_PacketSize;
+
+ // Adjust next packet position to account for the last time we resumed from Pause
+ nextPacketPositionFromLastPause = nextPacketStartPosition - m_StartPosition;
+
+ // Convert from bytes to HNS (to prevent truncation, multiply first then divide)
+ nextPacketTimeFromLastPauseHns = nextPacketPositionFromLastPause * HNS_PER_SEC / bytesPerSecond;
+
+ // Next packet time is Time @ resume from Pause, offset for lost time due to glitch, with next packet time added
+ nextPacketTime = m_StartTime + m_GlitchAdjust + nextPacketTimeFromLastPauseHns;
+
+ currentTime = KSCONVERT_PERFORMANCE_TIME(m_PerformanceCounterFrequency.QuadPart, KeQueryPerformanceCounter(NULL));
+
+ // Determine how long we want to wait, in HNS. Negative since it's a relative wait
+ delay = -(LONGLONG)(nextPacketTime - currentTime);
+
+ // If the delay isn't negative, this means we lost some time (e.g. broken into kernel debugger). Update
+ // our glitch adjust to account for that lost time, and attempt to schedule again
+ if (delay >= 0)
+ {
+ // Glitch!!!
+ // Update the glitch adjustment and set the new delay.
+ m_GlitchAdjust += delay;
+
+ StreamPassCallback();
+
+ return;
+ }
+
+ // Start the timer for our next pass! Note the timer isn't periodic.
+ inTimerQueue = WdfTimerStart(m_NotificationTimer, delay);
+
+ // We shouldn't be scheduling our next pass if the timer was previously still pending
+ ASSERT(inTimerQueue == FALSE);
+}
+
+_Use_decl_annotations_
+VOID
+CStreamEngine::UpdatePosition()
+{
+ ULONGLONG currentTime;
+ ULONG bytesPerSecond;
+
+ if (m_CurrentState != AcxStreamStateRun)
+ {
+ return;
+ }
+ bytesPerSecond = GetBytesPerSecond();
+ currentTime = KSCONVERT_PERFORMANCE_TIME(m_PerformanceCounterFrequency.QuadPart, KeQueryPerformanceCounter(NULL));
+
+ // Update position
+ m_Position = m_StartPosition - m_GlitchAdjust + (currentTime - m_StartTime) * bytesPerSecond / HNS_PER_SEC;
+}
+
+_Use_decl_annotations_
+ULONG
+CStreamEngine::GetBytesPerSecond()
+{
+ ULONG bytesPerSecond;
+
+ bytesPerSecond = AcxDataFormatGetAverageBytesPerSec(m_StreamFormat);
+
+ return bytesPerSecond;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CStreamEngine::GetCurrentPacket(
+ _Out_ PULONG CurrentPacket
+)
+{
+ ULONG currentPacket;
+ PAGED_CODE();
+
+ currentPacket = (ULONG)InterlockedCompareExchange((LONG*)&m_CurrentPacket, -1, -1);
+
+ *CurrentPacket = currentPacket;
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+CRenderStreamEngine::CRenderStreamEngine(
+ _In_ ACXSTREAM Stream,
+ _In_ ACXDATAFORMAT StreamFormat,
+ _In_ BOOL Offload,
+ _In_ CSimPeakMeter * CircuitPeakmeter
+
+)
+ : CStreamEngine(Stream, StreamFormat, Offload, CircuitPeakmeter)
+{
+ PAGED_CODE();
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+CRenderStreamEngine::~CRenderStreamEngine()
+{
+ PAGED_CODE();
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CRenderStreamEngine::PrepareHardware()
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ PAGED_CODE();
+
+ status = CStreamEngine::PrepareHardware();
+ if (!NT_SUCCESS(status))
+ {
+ goto exit;
+ }
+
+ status = m_SaveData.SetDataFormat((PKSDATAFORMAT)AcxDataFormatGetKsDataFormat(m_StreamFormat));
+ if (!NT_SUCCESS(status))
+ {
+ status = STATUS_SUCCESS;
+ goto exit;
+ }
+
+ status = m_SaveData.Initialize(m_Offload);
+ if (!NT_SUCCESS(status))
+ {
+ status = STATUS_SUCCESS;
+ goto exit;
+ }
+
+ status = m_SaveData.SetMaxWriteSize(m_PacketSize * m_PacketsCount * 16);
+ if (!NT_SUCCESS(status))
+ {
+ status = STATUS_SUCCESS;
+ goto exit;
+ }
+
+exit:
+ return status;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CRenderStreamEngine::ReleaseHardware()
+{
+ PAGED_CODE();
+
+ m_SaveData.WaitAllWorkItems();
+ m_SaveData.Cleanup();
+
+ return CStreamEngine::ReleaseHardware();
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CRenderStreamEngine::AssignDrmContentId(
+ ULONG DrmContentId,
+ PACXDRMRIGHTS DrmRights
+ )
+{
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(DrmContentId);
+
+ //
+ // At this point the driver should enforce the new DrmRights.
+ // The sample driver handles DrmRights per stream basis, and
+ // stops writing the stream to disk, if CopyProtect = TRUE.
+ //
+ // HDMI render: if DigitalOutputDisable or CopyProtect is true, enable HDCP.
+ // Loopback: if CopyProtect is true, disable loopback stream.
+ //
+
+ //
+ // Sample writes each stream seperately to disk. If the rights for this
+ // stream indicates that the stream is CopyProtected, stop writing to disk.
+ //
+ m_SaveData.Disable(DrmRights->CopyProtect);
+
+ //
+ // From MSDN:
+ //
+ // This sample doesn't forward protected content, but if your driver uses
+ // lower layer drivers or a different stack to properly work, please see the
+ // following info from MSDN:
+ //
+ // "Before allowing protected content to flow through a data path, the system
+ // verifies that the data path is secure. To do so, the system authenticates
+ // each module in the data path beginning at the upstream end of the data path
+ // and moving downstream. As each module is authenticated, that module gives
+ // the system information about the next module in the data path so that it
+ // can also be authenticated. To be successfully authenticated, a module's
+ // binary file must be signed as DRM-compliant.
+ //
+ // Two adjacent modules in the data path can communicate with each other in
+ // one of several ways. If the upstream module calls the downstream module
+ // through IoCallDriver, the downstream module is part of a WDM driver. In
+ // this case, the upstream module calls the AcxDrmForwardContentToDeviceObject
+ // function to provide the system with the device object representing the
+ // downstream module. (If the two modules communicate through the downstream
+ // module's content handlers, the upstream module calls AcxDrmAddContentHandlers
+ // instead.)
+ //
+ // For more information, see MSDN's DRM Functions and Interfaces.
+ //
+
+ return STATUS_SUCCESS;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CRenderStreamEngine::SetRenderPacket(
+ _In_ ULONG Packet,
+ _In_ ULONG Flags,
+ _In_ ULONG EosPacketLength
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ ULONG currentPacket;
+
+ UNREFERENCED_PARAMETER(Flags);
+ UNREFERENCED_PARAMETER(EosPacketLength);
+
+ PAGED_CODE();
+
+ currentPacket = (ULONG)InterlockedCompareExchange((LONG*)&m_CurrentPacket, -1, -1);
+
+ if (Packet <= currentPacket)
+ {
+ //ASSERT(FALSE);
+ status = STATUS_DATA_LATE_ERROR;
+ }
+ else if (Packet > currentPacket + 1)
+ {
+ //ASSERT(FALSE);
+ status = STATUS_DATA_OVERRUN;
+ }
+
+ return status;
+}
+
+_Use_decl_annotations_
+VOID
+CRenderStreamEngine::ProcessPacket()
+{
+ ULONG currentPacket;
+ ULONG packetIndex;
+ PBYTE packetBuffer;
+
+ currentPacket = (ULONG)InterlockedCompareExchange((LONG*)&m_CurrentPacket, -1, -1);
+
+ packetIndex = currentPacket % m_PacketsCount;
+ packetBuffer = (PBYTE)m_Packets[packetIndex];
+ // Packet 0 starts at an offset if the size isn't a multiple of page_size
+ if (packetIndex == 0)
+ {
+ packetBuffer += m_FirstPacketOffset;
+ }
+
+ m_SaveData.WriteData(packetBuffer, m_PacketSize);
+}
+
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+CCaptureStreamEngine::CCaptureStreamEngine(
+ _In_ ACXSTREAM Stream,
+ _In_ ACXDATAFORMAT StreamFormat
+)
+ : CStreamEngine(Stream, StreamFormat, FALSE, NULL),
+ m_EnableWaveCapture(0)
+{
+ PAGED_CODE();
+
+ m_CurrentPacketStart.QuadPart = 0;
+ m_LastPacketStart.QuadPart = 0;
+
+ RtlInitUnicodeString(&m_HostCaptureFileName, NULL);
+ RtlInitUnicodeString(&m_LoopbackCaptureFileName, NULL);
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+CCaptureStreamEngine::~CCaptureStreamEngine()
+{
+ PAGED_CODE();
+
+ RtlFreeUnicodeString(&m_HostCaptureFileName);
+ RtlFreeUnicodeString(&m_LoopbackCaptureFileName);
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CCaptureStreamEngine::PrepareHardware()
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PWAVEFORMATEXTENSIBLE pwfext = NULL;
+
+ PAGED_CODE();
+
+ status = CStreamEngine::PrepareHardware();
+ if (!NT_SUCCESS(status))
+ {
+ goto exit;
+ }
+
+ (void)ReadRegistrySettings();
+
+ pwfext = (PWAVEFORMATEXTENSIBLE)AcxDataFormatGetWaveFormatExtensible(m_StreamFormat);
+ if (pwfext == NULL)
+ {
+ // Cannot initialize reader or generator with a format that's not understood
+ status = STATUS_NO_MATCH;
+ ASSERT(FALSE);
+ goto exit;
+ }
+
+ if (m_EnableWaveCapture)
+ {
+ status = m_WaveReader.Init(pwfext, &m_HostCaptureFileName);
+ if (!NT_SUCCESS(status))
+ {
+ m_EnableWaveCapture = FALSE;
+ }
+ }
+
+ if (!m_EnableWaveCapture)
+ {
+ status = m_ToneGenerator.Init(m_ToneFrequency, pwfext);
+ }
+
+exit:
+ return status;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CCaptureStreamEngine::ReleaseHardware()
+{
+ PAGED_CODE();
+
+ if (m_EnableWaveCapture)
+ {
+ m_WaveReader.WaitAllWorkItems();
+ }
+
+ return CStreamEngine::ReleaseHardware();
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CCaptureStreamEngine::GetCapturePacket(
+ _Out_ ULONG* LastCapturePacket,
+ _Out_ ULONGLONG* QPCPacketStart,
+ _Out_ BOOLEAN* MoreData
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ ULONG currentPacket;
+ LONGLONG qpcPacketStart;
+
+ PAGED_CODE();
+
+ currentPacket = (ULONG)InterlockedCompareExchange((LONG*)&m_CurrentPacket, -1, -1);
+ qpcPacketStart = InterlockedCompareExchange64(&m_LastPacketStart.QuadPart, -1, -1);
+
+ *LastCapturePacket = currentPacket - 1;
+ *QPCPacketStart = (ULONGLONG)qpcPacketStart;
+ *MoreData = FALSE;
+
+ return status;
+}
+
+_Use_decl_annotations_
+VOID
+CCaptureStreamEngine::ProcessPacket()
+{
+ ULONG currentPacket;
+ ULONG packetIndex;
+ PBYTE packetBuffer;
+
+ currentPacket = (ULONG)InterlockedCompareExchange((LONG*)&m_CurrentPacket, -1, -1);
+
+ packetIndex = currentPacket % m_PacketsCount;
+ packetBuffer = (PBYTE)m_Packets[packetIndex];
+
+ // Packet 0 starts at an offset if the size isn't a multiple of page_size
+ if (packetIndex == 0)
+ {
+ packetBuffer += m_FirstPacketOffset;
+ }
+
+ if (m_EnableWaveCapture)
+ {
+ m_WaveReader.ReadWaveData(packetBuffer, m_PacketSize);
+ }
+ else
+ {
+ m_ToneGenerator.GenerateSine(packetBuffer, m_PacketSize);
+ }
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CCaptureStreamEngine::ReadRegistrySettings()
+{
+ NTSTATUS status;
+ PDRIVER_OBJECT DriverObject;
+ HANDLE DriverKey;
+
+ RTL_QUERY_REGISTRY_TABLE paramTable[] = {
+ // QueryRoutine Flags Name EntryContext DefaultType DefaultData DefaultLength
+ { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"EnableWaveCapture", &m_EnableWaveCapture, (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD, &m_EnableWaveCapture, sizeof(DWORD) },
+ { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"HostCaptureFileName", &m_HostCaptureFileName, (REG_SZ << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_SZ, &m_HostCaptureFileName, sizeof(UNICODE_STRING) },
+ { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"LoopbackCaptureFileName", &m_LoopbackCaptureFileName, (REG_SZ << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_SZ, &m_LoopbackCaptureFileName, sizeof(UNICODE_STRING) },
+ { NULL, 0, NULL, NULL, 0, NULL, 0 }
+ };
+
+ PAGED_CODE();
+
+ DriverObject = WdfDriverWdmGetDriverObject(WdfGetDriver());
+ DriverKey = NULL;
+ status = IoOpenDriverRegistryKey(DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &DriverKey);
+
+ if (!NT_SUCCESS(status))
+ {
+ ASSERT(FALSE);
+ goto exit;
+ }
+
+ status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
+ (PCWSTR) DriverKey,
+ &paramTable[0],
+ NULL,
+ NULL);
+
+ if (DriverKey)
+ {
+ ZwClose(DriverKey);
+ }
+
+exit:
+ if (!NT_SUCCESS(status))
+ {
+ m_EnableWaveCapture = FALSE;
+ }
+
+ return status;
+}
+_Use_decl_annotations_
+PAGED_CODE_SEG
+CBufferedCaptureStreamEngine::CBufferedCaptureStreamEngine(
+ _In_ ACXSTREAM Stream,
+ _In_ ACXDATAFORMAT StreamFormat,
+ _In_ CKeywordDetector* KeywordDetector
+
+)
+ : CCaptureStreamEngine(Stream, StreamFormat),
+ m_KeywordDetector(KeywordDetector)
+{
+ PAGED_CODE();
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+CBufferedCaptureStreamEngine::~CBufferedCaptureStreamEngine()
+{
+ PAGED_CODE();
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CBufferedCaptureStreamEngine::Pause()
+{
+ PAGED_CODE();
+
+ m_KeywordDetector->Stop();
+ return CCaptureStreamEngine::Pause();
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CBufferedCaptureStreamEngine::Run()
+{
+ PAGED_CODE();
+
+ m_KeywordDetector->Run();
+ return CCaptureStreamEngine::Run();
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS
+CBufferedCaptureStreamEngine::GetCapturePacket(
+ _Out_ ULONG* LastCapturePacket,
+ _Out_ ULONGLONG* QPCPacketStart,
+ _Out_ BOOLEAN* MoreData
+)
+{
+ PAGED_CODE();
+
+ // retrieve the packet from the fifo queue
+ return m_KeywordDetector->GetReadPacket(m_PacketsCount, m_PacketSize, m_Packets, LastCapturePacket, QPCPacketStart, MoreData);
+}
+
+_Use_decl_annotations_
+VOID
+CBufferedCaptureStreamEngine::ProcessPacket()
+{
+ LARGE_INTEGER qpc;
+ LARGE_INTEGER qpcFrequency;
+
+ qpc = KeQueryPerformanceCounter(&qpcFrequency);
+
+ // Add the next packet to the fifo queue
+ m_KeywordDetector->DpcRoutine(qpc.QuadPart, qpcFrequency.QuadPart);
+}
+
+//Streamengine callbacks
+
+VOID
+EvtStreamDestroy(
+ _In_ WDFOBJECT Object
+)
+{
+ PSTREAMENGINE_CONTEXT ctx;
+ CStreamEngine* streamEngine = NULL;
+
+ ctx = GetStreamEngineContext((ACXSTREAM)Object);
+
+ streamEngine = (CStreamEngine*)ctx->StreamEngine;
+ ctx->StreamEngine = NULL;
+ delete streamEngine;
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamGetHwLatency(
+ _In_ ACXSTREAM Stream,
+ _Out_ ULONG* FifoSize,
+ _Out_ ULONG* Delay
+)
+{
+ PSTREAMENGINE_CONTEXT ctx;
+ CStreamEngine* streamEngine = NULL;
+
+ PAGED_CODE();
+
+ ctx = GetStreamEngineContext(Stream);
+
+ streamEngine = (CStreamEngine*)ctx->StreamEngine;
+
+ return streamEngine->GetHWLatency(FifoSize, Delay);
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamAllocateRtPackets(
+ _In_ ACXSTREAM Stream,
+ _In_ ULONG PacketCount,
+ _In_ ULONG PacketSize,
+ _Out_ PACX_RTPACKET* Packets
+)
+{
+ PSTREAMENGINE_CONTEXT ctx;
+ CStreamEngine* streamEngine = NULL;
+
+ PAGED_CODE();
+
+ ctx = GetStreamEngineContext(Stream);
+
+ streamEngine = (CStreamEngine*)ctx->StreamEngine;
+
+ return streamEngine->AllocateRtPackets(PacketCount, PacketSize, Packets);
+}
+
+PAGED_CODE_SEG
+VOID
+EvtStreamFreeRtPackets(
+ _In_ ACXSTREAM Stream,
+ _In_ PACX_RTPACKET Packets,
+ _In_ ULONG PacketCount
+)
+{
+ PSTREAMENGINE_CONTEXT ctx;
+ CStreamEngine* streamEngine = NULL;
+
+ PAGED_CODE();
+
+ ctx = GetStreamEngineContext(Stream);
+
+ streamEngine = (CStreamEngine*)ctx->StreamEngine;
+
+ return streamEngine->FreeRtPackets(Packets, PacketCount);
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamPrepareHardware(
+ _In_ ACXSTREAM Stream
+)
+{
+ PSTREAMENGINE_CONTEXT ctx;
+ CStreamEngine* streamEngine = NULL;
+
+ PAGED_CODE();
+
+ ctx = GetStreamEngineContext(Stream);
+
+ streamEngine = (CStreamEngine*)ctx->StreamEngine;
+
+ return streamEngine->PrepareHardware();
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamReleaseHardware(
+ _In_ ACXSTREAM Stream
+)
+{
+ PSTREAMENGINE_CONTEXT ctx;
+ CStreamEngine* streamEngine = NULL;
+
+ PAGED_CODE();
+
+ ctx = GetStreamEngineContext(Stream);
+
+ streamEngine = (CStreamEngine*)ctx->StreamEngine;
+
+ return streamEngine->ReleaseHardware();
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamRun(
+ _In_ ACXSTREAM Stream
+)
+{
+ PSTREAMENGINE_CONTEXT ctx;
+ CStreamEngine* streamEngine = NULL;
+
+ PAGED_CODE();
+
+ ctx = GetStreamEngineContext(Stream);
+
+ streamEngine = (CStreamEngine*)ctx->StreamEngine;
+
+ return streamEngine->Run();
+}
+
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamPause(
+ _In_ ACXSTREAM Stream
+)
+{
+ PSTREAMENGINE_CONTEXT ctx;
+ CStreamEngine* streamEngine = NULL;
+
+ PAGED_CODE();
+
+ ctx = GetStreamEngineContext(Stream);
+
+ streamEngine = (CStreamEngine*)ctx->StreamEngine;
+
+ return streamEngine->Pause();
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamAssignDrmContentId(
+ _In_ ACXSTREAM Stream,
+ _In_ ULONG DrmContentId,
+ _In_ PACXDRMRIGHTS DrmRights
+)
+{
+ PSTREAMENGINE_CONTEXT ctx;
+ CStreamEngine * streamEngine = NULL;
+
+ PAGED_CODE();
+
+ ctx = GetStreamEngineContext(Stream);
+
+ streamEngine = (CStreamEngine*)ctx->StreamEngine;
+
+ return streamEngine->AssignDrmContentId(DrmContentId, DrmRights);
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamGetCurrentPacket(
+ _In_ ACXSTREAM Stream,
+ _Out_ PULONG CurrentPacket
+)
+{
+ PSTREAMENGINE_CONTEXT ctx;
+ CStreamEngine* streamEngine = NULL;
+
+ PAGED_CODE();
+
+ ctx = GetStreamEngineContext(Stream);
+
+ streamEngine = static_cast<CStreamEngine*>(ctx->StreamEngine);
+
+ return streamEngine->GetCurrentPacket(CurrentPacket);
+}
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamGetPresentationPosition(
+ _In_ ACXSTREAM Stream,
+ _Out_ PULONGLONG PositionInBlocks,
+ _Out_ PULONGLONG QPCPosition
+)
+{
+ PSTREAMENGINE_CONTEXT ctx;
+ CStreamEngine* streamEngine = NULL;
+
+ PAGED_CODE();
+
+ ctx = GetStreamEngineContext(Stream);
+
+ streamEngine = static_cast<CStreamEngine*>(ctx->StreamEngine);
+
+ return streamEngine->GetPresentationPosition(PositionInBlocks, QPCPosition);
+}
+
diff --git a/audio/Acx/Samples/Common/StreamEngine.h b/audio/Acx/Samples/Common/StreamEngine.h
new file mode 100644
index 00000000..deeff95a
--- /dev/null
+++ b/audio/Acx/Samples/Common/StreamEngine.h
@@ -0,0 +1,449 @@
+#pragma once
+
+#include "savedata.h"
+#include "tonegenerator.h"
+#include "WaveReader.h"
+#include "SimPeakMeter.h"
+#include "keyworddetector.h"
+
+#define HNSTIME_PER_MILLISECOND 10000
+
+#define MAX_PACKET_COUNT 2
+
+#define DEFAULT_FREQUENCY 220
+#define LOOPBACK_FREQUENCY 500
+
+// Stream callbacks shared between Capture and Render
+
+VOID
+EvtStreamDestroy(
+ _In_ WDFOBJECT Object
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamGetHwLatency(
+ _In_ ACXSTREAM Stream,
+ _Out_ ULONG* FifoSize,
+ _Out_ ULONG* Delay
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamAllocateRtPackets(
+ _In_ ACXSTREAM Stream,
+ _In_ ULONG PacketCount,
+ _In_ ULONG PacketSize,
+ _Out_ PACX_RTPACKET* Packets
+);
+
+PAGED_CODE_SEG
+VOID
+EvtStreamFreeRtPackets(
+ _In_ ACXSTREAM Stream,
+ _In_ PACX_RTPACKET Packets,
+ _In_ ULONG PacketCount
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamPrepareHardware(
+ _In_ ACXSTREAM Stream
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamReleaseHardware(
+ _In_ ACXSTREAM Stream
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamRun(
+ _In_ ACXSTREAM Stream
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamPause(
+ _In_ ACXSTREAM Stream
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamAssignDrmContentId(
+ _In_ ACXSTREAM Stream,
+ _In_ ULONG DrmContentId,
+ _In_ PACXDRMRIGHTS DrmRights
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamGetCurrentPacket(
+ _In_ ACXSTREAM Stream,
+ _Out_ PULONG CurrentPacket
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+EvtStreamGetPresentationPosition(
+ _In_ ACXSTREAM Stream,
+ _Out_ PULONGLONG PositionInBlocks,
+ _Out_ PULONGLONG QPCPosition
+);
+
+
+class CStreamEngine
+{
+public:
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ AllocateRtPackets(
+ _In_ ULONG PacketCount,
+ _In_ ULONG PacketSize,
+ _Out_ PACX_RTPACKET * Packets
+ );
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ VOID
+ FreeRtPackets(
+ _Frees_ptr_ PACX_RTPACKET Packets,
+ _In_ ULONG PacketCount
+ );
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ PrepareHardware();
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ ReleaseHardware();
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ Run();
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ Pause();
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ GetPresentationPosition(
+ _Out_ PULONGLONG PositionInBlocks,
+ _Out_ PULONGLONG QPCPosition
+ );
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ GetLinearBufferPosition(
+ _Out_ PULONGLONG Position
+ );
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ SetCurrentWritePosition(
+ _In_ ULONG Position
+ );
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ SetLastBufferPosition(
+ _In_ ULONG Position
+ );
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ GetCurrentPacket(
+ _Out_ PULONG CurrentPacket
+ );
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ GetHWLatency(
+ _Out_ ULONG * FifoSize,
+ _Out_ ULONG * Delay
+ );
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ AssignDrmContentId(
+ _In_ ULONG DrmContentId,
+ _In_ PACXDRMRIGHTS DrmRights
+ );
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ CSimPeakMeter *
+ GetPeakMeter();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ CStreamEngine(
+ _In_ ACXSTREAM Stream,
+ _In_ ACXDATAFORMAT StreamFormat,
+ _In_ BOOL Offload,
+ _In_opt_ CSimPeakMeter *CircuitPeakmeter
+ );
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ ~CStreamEngine();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ VOID
+ SetFrequency(
+ _In_ DWORD ToneFrequency
+ )
+ {
+ PAGED_CODE();
+
+ m_ToneFrequency = ToneFrequency;
+ }
+
+protected:
+ PVOID m_Packets[MAX_PACKET_COUNT];
+ ULONG m_PacketsCount;
+ ULONG m_PacketSize;
+ ULONG m_FirstPacketOffset;
+ WDFTIMER m_NotificationTimer;
+ ACX_STREAM_STATE m_CurrentState;
+ ULONG m_CurrentPacket;
+ ULONGLONG m_Position;
+ ACXSTREAM m_Stream;
+ ACXDATAFORMAT m_StreamFormat;
+ ULONGLONG m_StartTime;
+ ULONGLONG m_StartPosition;
+ ULONGLONG m_GlitchAdjust;
+ LARGE_INTEGER m_PerformanceCounterFrequency;
+ LARGE_INTEGER m_CurrentPacketStart;
+ LARGE_INTEGER m_LastPacketStart;
+ DWORD m_ToneFrequency;
+ BOOL m_Offload;
+ CSimPeakMeter m_PeakMeter;
+ CSimPeakMeter* m_pCircuitPeakmeter;
+
+ static
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ _Function_class_(EVT_WDF_TIMER)
+ VOID s_EvtStreamPassCallback(
+ _In_ WDFTIMER Timer
+ );
+
+ // This is run every time the stream timer fires
+ virtual
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ VOID
+ StreamPassCallback();
+
+ virtual
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ VOID
+ ScheduleNextPass();
+
+ virtual
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ VOID
+ UpdatePosition();
+
+ virtual
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ ULONG
+ GetBytesPerSecond();
+
+ virtual
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ VOID
+ ProcessPacket() = 0;
+};
+
+class CRenderStreamEngine : public CStreamEngine
+{
+public:
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ CRenderStreamEngine(
+ _In_ ACXSTREAM Stream,
+ _In_ ACXDATAFORMAT StreamFormat,
+ _In_ BOOL Offload,
+ _In_ CSimPeakMeter *CircuitPeakmeter
+ );
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ ~CRenderStreamEngine();
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ PrepareHardware();
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ ReleaseHardware();
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ AssignDrmContentId(
+ _In_ ULONG DrmContentId,
+ _In_ PACXDRMRIGHTS DrmRights
+ );
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ SetRenderPacket(
+ _In_ ULONG Packet,
+ _In_ ULONG Flags,
+ _In_ ULONG EosPacketLength
+ );
+
+protected:
+ CSaveData m_SaveData;
+
+ virtual
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ VOID
+ ProcessPacket();
+
+};
+
+class CCaptureStreamEngine : public CStreamEngine
+{
+public:
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ CCaptureStreamEngine(
+ _In_ ACXSTREAM Stream,
+ _In_ ACXDATAFORMAT StreamFormat
+ );
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ ~CCaptureStreamEngine();
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ PrepareHardware();
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ ReleaseHardware();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ GetCapturePacket(
+ _Out_ ULONG * LastCapturePacket,
+ _Out_ ULONGLONG * QPCPacketStart,
+ _Out_ BOOLEAN * MoreData
+ );
+
+protected:
+ ToneGenerator m_ToneGenerator;
+ CWaveReader m_WaveReader;
+ DWORD m_EnableWaveCapture;
+ UNICODE_STRING m_HostCaptureFileName;
+ UNICODE_STRING m_LoopbackCaptureFileName;
+
+ virtual
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ VOID
+ ProcessPacket();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ ReadRegistrySettings();
+};
+
+class CBufferedCaptureStreamEngine : public CCaptureStreamEngine
+{
+public:
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ CBufferedCaptureStreamEngine(
+ _In_ ACXSTREAM Stream,
+ _In_ ACXDATAFORMAT StreamFormat,
+ _In_ CKeywordDetector * KeywordDetector
+ );
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ ~CBufferedCaptureStreamEngine();
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ Run();
+
+ virtual
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ Pause();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ GetCapturePacket(
+ _Out_ ULONG * LastCapturePacket,
+ _Out_ ULONGLONG * QPCPacketStart,
+ _Out_ BOOLEAN * MoreData
+ );
+
+protected:
+ virtual
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ VOID
+ ProcessPacket();
+
+ CKeywordDetector * m_KeywordDetector;
+};
+
+// Define circuit/stream pin context.
+//
+typedef struct _STREAM_TIMER_CONTEXT {
+ CStreamEngine * StreamEngine;
+} STREAM_TIMER_CONTEXT, *PSTREAM_TIMER_CONTEXT;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(STREAM_TIMER_CONTEXT, GetStreamTimerContext)
diff --git a/audio/Acx/Samples/Common/ToneGenerator.cpp b/audio/Acx/Samples/Common/ToneGenerator.cpp
new file mode 100644
index 00000000..fc30e3b2
--- /dev/null
+++ b/audio/Acx/Samples/Common/ToneGenerator.cpp
@@ -0,0 +1,297 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ ToneGenerator.cpp
+
+Abstract:
+
+ Implementation of sine wave generator for ACX driver samples
+
+
+--*/
+#include "private.h"
+#include "public.h"
+#include <devguid.h>
+#include <ks.h>
+#include <mmsystem.h>
+#include <ksmedia.h>
+#include "ToneGenerator.h"
+
+#define TONEGENERATOR_POOLTAG 'rGnT'
+
+const double TONE_AMPLITUDE = 0.5; // Scalar value, should be between 0.0 - 1.0
+const double TWO_PI = M_PI * 2;
+
+DWORD g_DisableToneGenerator = 0; // default is to generate tones.
+
+#define IF_FAILED_JUMP(result, tag) do {if (!NT_SUCCESS(result)) {goto tag;}} while(false)
+#define IF_TRUE_JUMP(result, tag) do {if (result) {goto tag;}} while(false)
+#define IF_TRUE_ACTION_JUMP(result, action, tag) do {if (result) {action; goto tag;}} while(false)
+
+//
+// Double to short conversion.
+//
+__drv_maxIRQL(DISPATCH_LEVEL)
+short ConvertToShort(double Value)
+{
+ return (short)(Value * _I16_MAX);
+};
+
+//
+// Double to char conversion.
+//
+__drv_maxIRQL(DISPATCH_LEVEL)
+unsigned char ConvertToUChar(double Value)
+{
+ const double F_127_5 = 127.5;
+ return (unsigned char)(Value * F_127_5 + F_127_5);
+};
+
+//
+// Ctor: basic init.
+//
+_Use_decl_annotations_
+PAGED_CODE_SEG
+ToneGenerator::ToneGenerator()
+: m_Frequency(0),
+ m_ChannelCount(0),
+ m_BitsPerSample(0),
+ m_SamplesPerSecond(0),
+ m_Mute(false),
+ m_PartialFrame(NULL),
+ m_PartialFrameBytes(0),
+ m_FrameSize(0)
+{
+ PAGED_CODE();
+
+ // Theta (double) and SampleIncrement (double) are init in the Init() method
+ // after saving the floating point state.
+}
+
+//
+// Dtor: free resources.
+//
+_Use_decl_annotations_
+PAGED_CODE_SEG
+ToneGenerator::~ToneGenerator()
+{
+ PAGED_CODE();
+
+ if (m_PartialFrame)
+ {
+ ExFreePoolWithTag(m_PartialFrame, TONEGENERATOR_POOLTAG);
+ m_PartialFrame = NULL;
+ m_PartialFrameBytes = 0;
+ }
+}
+
+//
+// Init a new frame.
+// Note: caller will save and restore the floatingpoint state.
+//
+#pragma warning(push)
+// Caller wraps this routine between KeSaveFloatingPointState/KeRestoreFloatingPointState calls.
+#pragma warning(disable: 28110)
+
+_Use_decl_annotations_
+VOID ToneGenerator::InitNewFrame
+(
+ _Out_writes_bytes_(FrameSize) BYTE* Frame,
+ _In_ DWORD FrameSize
+)
+{
+ double sinValue = TONE_AMPLITUDE * sin( m_Theta );
+
+ if (FrameSize != (DWORD)m_ChannelCount * m_BitsPerSample/8)
+ {
+ ASSERT(FALSE);
+ RtlZeroMemory(Frame, FrameSize);
+ return;
+ }
+
+ for(ULONG i = 0; i < m_ChannelCount; ++i)
+ {
+ if (m_BitsPerSample == 8)
+ {
+ unsigned char *dataBuffer = reinterpret_cast<unsigned char *>(Frame);
+ dataBuffer[i] = ConvertToUChar(sinValue);
+ }
+ else // 16 bits per sample
+ {
+ short *dataBuffer = reinterpret_cast<short *>(Frame);
+ dataBuffer[i] = ConvertToShort(sinValue);
+ }
+ }
+
+ m_Theta += m_SampleIncrement;
+ if (m_Theta >= TWO_PI)
+ {
+ m_Theta -= TWO_PI;
+ }
+}
+#pragma warning(pop)
+
+//
+// GenerateSamples()
+//
+// Generate a sine wave that fits into the specified buffer.
+//
+// Buffer - Buffer to hold the samples
+// BufferLength - Length of the buffer.
+//
+// Note: this function supports 16bit and 8bit samples only.
+//
+_Use_decl_annotations_
+void ToneGenerator::GenerateSine
+(
+ _Out_writes_bytes_(BufferLength) BYTE *Buffer,
+ _In_ size_t BufferLength
+)
+{
+ NTSTATUS status;
+ KFLOATING_SAVE saveData;
+ BYTE * buffer;
+ size_t length;
+ size_t copyBytes;
+
+ // if muted, or tone generator disabled via registry,
+ // we deliver silence.
+ if (m_Mute || g_DisableToneGenerator)
+ {
+ goto ZeroBuffer;
+ }
+
+ status = KeSaveFloatingPointState(&saveData);
+ if (!NT_SUCCESS(status))
+ {
+ goto ZeroBuffer;
+ }
+
+ buffer = Buffer;
+ length = BufferLength;
+
+ //
+ // Check if we have any residual frame bytes from the last time.
+ //
+ if (m_PartialFrameBytes)
+ {
+ ASSERT(m_FrameSize > m_PartialFrameBytes);
+ DWORD offset = m_FrameSize - m_PartialFrameBytes;
+ copyBytes = MIN(m_PartialFrameBytes, length);
+ RtlCopyMemory(buffer, m_PartialFrame + offset, copyBytes);
+ RtlZeroMemory(m_PartialFrame + offset, copyBytes);
+ length -= copyBytes;
+ buffer += copyBytes;
+ m_PartialFrameBytes = 0;
+ }
+
+ IF_TRUE_JUMP(length == 0, Done);
+
+ //
+ // Copy all the aligned frames.
+ //
+
+ size_t frames = length/m_FrameSize;
+
+ for (size_t i = 0; i < frames; ++i)
+ {
+ InitNewFrame(buffer, m_FrameSize);
+ buffer += m_FrameSize;
+ length -= m_FrameSize;
+ }
+
+ IF_TRUE_JUMP(length == 0, Done);
+
+ //
+ // Copy any partial frame at the end.
+ //
+ ASSERT(m_FrameSize > length);
+ InitNewFrame(m_PartialFrame, m_FrameSize);
+ RtlCopyMemory(buffer, m_PartialFrame, length);
+ RtlZeroMemory(m_PartialFrame, length);
+ m_PartialFrameBytes = m_FrameSize - (DWORD)length;
+
+Done:
+ KeRestoreFloatingPointState(&saveData);
+ return;
+
+ZeroBuffer:
+ RtlZeroMemory(Buffer, BufferLength);
+ return;
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS ToneGenerator::Init
+(
+ _In_ DWORD ToneFrequency,
+ _In_ PWAVEFORMATEXTENSIBLE WfExt
+)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ KFLOATING_SAVE saveData;
+
+ PAGED_CODE();
+
+ //
+ // This sample supports PCM 16bit formats only.
+ //
+ if ((WfExt->Format.wFormatTag != WAVE_FORMAT_PCM &&
+ !(WfExt->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
+ IsEqualGUIDAligned(WfExt->SubFormat, KSDATAFORMAT_SUBTYPE_PCM))) ||
+ (WfExt->Format.wBitsPerSample != 16 &&
+ WfExt->Format.wBitsPerSample != 8))
+ {
+ status = STATUS_NOT_SUPPORTED;
+ }
+ IF_FAILED_JUMP(status, Done);
+
+ //
+ // Save floating state (just in case).
+ //
+ status = KeSaveFloatingPointState(&saveData);
+ IF_FAILED_JUMP(status, Done);
+
+ //
+ // Basic init.
+ //
+ RtlZeroMemory(&m_Theta, sizeof(m_Theta));
+ m_Frequency = ToneFrequency;
+ m_ChannelCount = WfExt->Format.nChannels; // # channels.
+ m_BitsPerSample = WfExt->Format.wBitsPerSample; // bits per sample.
+ m_SamplesPerSecond = WfExt->Format.nSamplesPerSec; // samples per sec.
+ m_Mute = false;
+ m_SampleIncrement = (m_Frequency * TWO_PI) / (double)m_SamplesPerSecond;
+ m_FrameSize = (DWORD)m_ChannelCount * m_BitsPerSample/8;
+ ASSERT(m_FrameSize == WfExt->Format.nBlockAlign);
+
+ //
+ // Restore floating state.
+ //
+ KeRestoreFloatingPointState(&saveData);
+
+ //
+ // Allocate a buffer to hold a partial frame.
+ //
+ m_PartialFrame = (BYTE*)ExAllocatePool2(
+ POOL_FLAG_NON_PAGED,
+ m_FrameSize,
+ TONEGENERATOR_POOLTAG);
+
+ IF_TRUE_ACTION_JUMP(m_PartialFrame == NULL, status = STATUS_INSUFFICIENT_RESOURCES, Done);
+
+ status = STATUS_SUCCESS;
+
+Done:
+ return status;
+}
+
+
diff --git a/audio/Acx/Samples/Common/ToneGenerator.h b/audio/Acx/Samples/Common/ToneGenerator.h
new file mode 100644
index 00000000..9de138f8
--- /dev/null
+++ b/audio/Acx/Samples/Common/ToneGenerator.h
@@ -0,0 +1,88 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ ToneGenerator.h
+
+Abstract:
+
+ Declaration of sine wave generator for ACX driver samples.
+
+
+--*/
+#pragma once
+
+#define _USE_MATH_DEFINES
+#include <math.h>
+#include <limits.h>
+
+class ToneGenerator
+{
+public:
+ DWORD m_Frequency;
+ WORD m_ChannelCount;
+ WORD m_BitsPerSample;
+ DWORD m_SamplesPerSecond;
+ double m_Theta;
+ double m_SampleIncrement;
+ bool m_Mute;
+ BYTE* m_PartialFrame;
+ DWORD m_PartialFrameBytes;
+ DWORD m_FrameSize;
+
+public:
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ ToneGenerator();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ ~ToneGenerator();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS
+ Init
+ (
+ _In_ DWORD ToneFrequency,
+ _In_ PWAVEFORMATEXTENSIBLE WfExt
+ );
+
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ VOID
+ GenerateSine
+ (
+ _Out_writes_bytes_(BufferLength) BYTE *Buffer,
+ _In_ size_t BufferLength
+ );
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ VOID
+ SetMute
+ (
+ _In_ bool Value
+ )
+ {
+ PAGED_CODE();
+
+ m_Mute = Value;
+ }
+
+private:
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ VOID InitNewFrame
+ (
+ _Out_writes_bytes_(FrameSize) BYTE* Frame,
+ _In_ DWORD FrameSize
+ );
+};
+
+
diff --git a/audio/Acx/Samples/Common/Trace_macros.h b/audio/Acx/Samples/Common/Trace_macros.h
new file mode 100644
index 00000000..5291b391
--- /dev/null
+++ b/audio/Acx/Samples/Common/Trace_macros.h
@@ -0,0 +1,470 @@
+#pragma once
+
+#include <stdarg.h> // for va_start, etc.
+
+#pragma region Tracing level definitions
+
+#if !defined(FAILED_NTSTATUS)
+#define FAILED_NTSTATUS(status) (((NTSTATUS)(status)) < 0)
+#endif
+
+#if !defined(SUCCEEDED_NTSTATUS)
+#define SUCCEEDED_NTSTATUS(status) (((NTSTATUS)(status)) >= 0)
+#endif
+
+//! Define shorter versions of the ETW trace levels
+#define LEVEL_CRITICAL TRACE_LEVEL_CRITICAL
+#define LEVEL_ERROR TRACE_LEVEL_ERROR
+#define LEVEL_WARNING TRACE_LEVEL_WARNING
+#define LEVEL_INFO TRACE_LEVEL_INFORMATION
+#define LEVEL_VERBOSE TRACE_LEVEL_VERBOSE
+
+//! This is a special LEVEL that changes the trace macro level from ERROR to VERBOSE
+//! depending on whether the return value passed to the macro was non-zero or zero,
+//! respectively.
+#define LEVEL_COND 0xFF
+#pragma endregion
+
+//! Logger and Enabled that supports both level and flag.
+//! \link https://msdn.microsoft.com/en-us/library/windows/hardware/ff542492(v=vs.85).aspx
+#define WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS) WPP_LEVEL_LOGGER(FLAGS)
+#define WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS) (WPP_LEVEL_ENABLED(FLAGS) && (WPP_CONTROL(WPP_BIT_ ## FLAGS).Level >= LEVEL))
+
+//! This macro is to be used by the WPP custom macros below that want to do conditional
+//! logging based on return value. If LEVEL_VERBOSE is specified when calling a macro that
+//! uses this, the level will be set to LEVEL_INFO if return code is 0 or
+//! LEVEL_ERROR if the return code is not 0. This can be called in any PRE macro.
+//!
+//! The "LEVEL == LEVEL_COND" check generates a compiler warning that the "conditional
+//! expression is constant" so we explicitly disable that.
+#define WPP_CONDITIONAL_LEVEL_FLAGS_OVERRIDE(LEVEL, FLAGS, HR) \
+ BOOL bEnabled = WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS); \
+ __pragma(warning(push)) \
+ __pragma(warning(disable: 4127)) \
+ if (LEVEL == LEVEL_COND) \
+ { \
+ if (SUCCEEDED(HR)) \
+ { \
+ bEnabled = WPP_LEVEL_FLAGS_ENABLED(LEVEL_VERBOSE, FLAGS); \
+ } \
+ else \
+ { \
+ bEnabled = WPP_LEVEL_FLAGS_ENABLED(LEVEL_ERROR, FLAGS); \
+ } \
+ } \
+ __pragma(warning(pop))
+
+#define WPP_CONDITIONAL_LEVEL_FLAGS_OVERRIDE_NTSTATUS(LEVEL, FLAGS, STATUS) \
+ BOOLEAN bEnabled = WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS); \
+ __pragma(warning(push)) \
+ __pragma(warning(disable: 4127)) \
+ if (LEVEL == LEVEL_COND) \
+ { \
+ if (SUCCEEDED_NTSTATUS(STATUS)) \
+ { \
+ bEnabled = WPP_LEVEL_FLAGS_ENABLED(LEVEL_VERBOSE, FLAGS); \
+ } \
+ else \
+ { \
+ bEnabled = WPP_LEVEL_FLAGS_ENABLED(LEVEL_ERROR, FLAGS); \
+ } \
+ } \
+ __pragma(warning(pop))
+
+
+#define WPP_LEVEL_FLAGS_IFRLOG_ENABLED(LEVEL, FLAGS, IFRLOG) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS)
+#define WPP_LEVEL_FLAGS_IFRLOG_LOGGER(LEVEL, FLAGS, IFRLOG) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS)
+#define WPP_LEVEL_IFRLOG_FLAGS_ENABLED(LEVEL, IFRLOG, FLAGS) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS)
+#define WPP_LEVEL_IFRLOG_FLAGS_LOGGER(LEVEL, IFRLOG, FLAGS) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS)
+
+#define WPP_LEVEL_FLAGS_HR_PRE(LEVEL, FLAGS, HR) { WPP_CONDITIONAL_LEVEL_FLAGS_OVERRIDE(LEVEL, FLAGS, HR)
+#define WPP_LEVEL_FLAGS_HR_POST(LEVEL, FLAGS, HR) ;}
+#define WPP_LEVEL_FLAGS_HR_ENABLED(LEVEL, FLAGS, HR) bEnabled
+#define WPP_LEVEL_FLAGS_HR_LOGGER(LEVEL, FLAGS, HR) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS)
+
+#define WPP_LEVEL_FLAGS_RETVAL_ENABLED(LEVEL, FLAGS, RETVAL) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS)
+#define WPP_LEVEL_FLAGS_RETVAL_LOGGER(LEVEL, FLAGS, RETVAL) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS)
+
+#define WPP_LEVEL_FLAGS_FI_ENABLED(LEVEL, FLAGS, FI) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS)
+#define WPP_LEVEL_FLAGS_FI_LOGGER(LEVEL, FLAGS, FI) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS)
+
+#define WPP_LEVEL_FLAGS_STATUS_PRE(LEVEL, FLAGS, STATUS) { WPP_CONDITIONAL_LEVEL_FLAGS_OVERRIDE_NTSTATUS(LEVEL, FLAGS, STATUS)
+#define WPP_LEVEL_FLAGS_STATUS_POST(LEVEL, FLAGS, STATUS) ;}
+#define WPP_LEVEL_FLAGS_STATUS_ENABLED(LEVEL, FLAGS, STATUS) bEnabled
+#define WPP_LEVEL_FLAGS_STATUS_LOGGER(LEVEL, FLAGS, STATUS) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS)
+
+#define WPP_LEVEL_FLAGS_RETSTATUS_PRE(LEVEL, FLAGS, RETSTATUS) do { NTSTATUS __statusRet = (RETSTATUS); if (FAILED_NTSTATUS(__statusRet)) {
+#define WPP_LEVEL_FLAGS_RETSTATUS_POST(LEVEL, FLAGS, RETSTATUS) ; return __statusRet; } } while (0, 0)
+#define WPP_LEVEL_FLAGS_RETSTATUS_ENABLED(LEVEL, FLAGS, RETSTATUS) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS)
+#define WPP_LEVEL_FLAGS_RETSTATUS_LOGGER(LEVEL, FLAGS, RETSTATUS) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS)
+
+#define WPP_LEVEL_FLAGS_IFRLOG_RETSTATUS_PRE(LEVEL, FLAGS, IFRLOG, RETSTATUS) do { NTSTATUS __statusRet = (RETSTATUS); if (FAILED_NTSTATUS(__statusRet)) {
+#define WPP_LEVEL_FLAGS_IFRLOG_RETSTATUS_POST(LEVEL, FLAGS, IFRLOG, RETSTATUS) ; return __statusRet; } } while (0, 0)
+#define WPP_LEVEL_FLAGS_IFRLOG_RETSTATUS_ENABLED(LEVEL, FLAGS, IFRLOG, RETSTATUS) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS)
+#define WPP_LEVEL_FLAGS_IFRLOG_RETSTATUS_LOGGER(LEVEL, FLAGS, IFRLOG, RETSTATUS) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS)
+
+#define WPP_LEVEL_FLAGS_IFRLOG_RETSTATUS_ALLOWEDSTATUS_PRE(LEVEL, FLAGS, IFRLOG, RETSTATUS, ALLOWEDSTATUS) do {\
+NTSTATUS __statusRet = (RETSTATUS);\
+if(__statusRet == ALLOWEDSTATUS)\
+{\
+ __statusRet = STATUS_SUCCESS;\
+}\
+if (FAILED_NTSTATUS(__statusRet)) {
+#define WPP_LEVEL_FLAGS_IFRLOG_RETSTATUS_ALLOWEDSTATUS_POST(LEVEL, FLAGS, IFRLOG, RETSTATUS, ALLOWEDSTATUS) ; return __statusRet; } } while (0, 0)
+#define WPP_LEVEL_FLAGS_IFRLOG_RETSTATUS_ALLOWEDSTATUS_ENABLED(LEVEL, FLAGS, IFRLOG, RETSTATUS, ALLOWEDSTATUS) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS)
+#define WPP_LEVEL_FLAGS_IFRLOG_RETSTATUS_ALLOWEDSTATUS_LOGGER(LEVEL, FLAGS, IFRLOG, RETSTATUS, ALLOWEDSTATUS) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS)
+
+#define WPP_LEVEL_FLAGS_RETPTR_PRE(LEVEL, FLAGS, RETPTR) do { if ((RETPTR) == nullptr) {
+#define WPP_LEVEL_FLAGS_RETPTR_POST(LEVEL, FLAGS, RETPTR) ; return STATUS_INSUFFICIENT_RESOURCES; } } while (0, 0)
+#define WPP_LEVEL_FLAGS_RETPTR_ENABLED(LEVEL, FLAGS, RETPTR) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS)
+#define WPP_LEVEL_FLAGS_RETPTR_LOGGER(LEVEL, FLAGS, RETPTR) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS)
+
+#define WPP_LEVEL_FLAGS_RETSTATUS_RETPTR_PRE(LEVEL, FLAGS, RETSTATUS, RETPTR) do { NTSTATUS __statusRet = (RETSTATUS); if ((RETPTR) == nullptr) {
+#define WPP_LEVEL_FLAGS_RETSTATUS_RETPTR_POST(LEVEL, FLAGS, RETSTATUS, RETPTR) ; return __statusRet; } } while (0, 0)
+#define WPP_LEVEL_FLAGS_RETSTATUS_RETPTR_ENABLED(LEVEL, FLAGS, RETSTATUS, RETPTR) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS)
+#define WPP_LEVEL_FLAGS_RETSTATUS_RETPTR_LOGGER(LEVEL, FLAGS, RETSTATUS, RETPTR) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS)
+
+#define WPP_LEVEL_FLAGS_RETSTATUS_POSCOND_PRE(LEVEL, FLAGS, RETSTATUS, POSCOND) do { NTSTATUS __statusRet = (RETSTATUS); if ((POSCOND)) {
+#define WPP_LEVEL_FLAGS_RETSTATUS_POSCOND_POST(LEVEL, FLAGS, RETSTATUS, POSCOND) ; return __statusRet; } } while (0, 0)
+#define WPP_LEVEL_FLAGS_RETSTATUS_POSCOND_ENABLED(LEVEL, FLAGS, RETSTATUS, POSCOND) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS)
+#define WPP_LEVEL_FLAGS_RETSTATUS_POSCOND_LOGGER(LEVEL, FLAGS, RETSTATUS, POSCOND) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS)
+
+#define WPP_LEVEL_FLAGS_IFRLOG_POSCOND_RETSTATUS_PRE(LEVEL, FLAGS, IFRLOG, POSCOND, RETSTATUS) do { NTSTATUS __statusRet = (RETSTATUS); if ((POSCOND)) {
+#define WPP_LEVEL_FLAGS_IFRLOG_POSCOND_RETSTATUS_POST(LEVEL, FLAGS, IFRLOG, POSCOND, RETSTATUS) ; return __statusRet; } } while (0, 0)
+#define WPP_LEVEL_FLAGS_IFRLOG_POSCOND_RETSTATUS_ENABLED(LEVEL, FLAGS, IFRLOG, POSCOND, RETSTATUS) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS)
+#define WPP_LEVEL_FLAGS_IFRLOG_POSCOND_RETSTATUS_LOGGER(LEVEL, FLAGS, IFRLOG, POSCOND, RETSTATUS) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS)
+
+#define WPP_LEVEL_FLAGS_RETSTATUS_NEGCOND_PRE(LEVEL, FLAGS, RETSTATUS, NEGCOND) do { NTSTATUS __statusRet = (RETSTATUS); if (!(NEGCOND)) {
+#define WPP_LEVEL_FLAGS_RETSTATUS_NEGCOND_POST(LEVEL, FLAGS, RETSTATUS, NEGCOND) ; return __statusRet; } } while (0, 0)
+#define WPP_LEVEL_FLAGS_RETSTATUS_NEGCOND_ENABLED(LEVEL, FLAGS, RETSTATUS, NEGCOND) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS)
+#define WPP_LEVEL_FLAGS_RETSTATUS_NEGCOND_LOGGER(LEVEL, FLAGS, RETSTATUS, NEGCOND) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS)
+
+#pragma region IFR Enablement Macros
+
+// Opt-in to a WPP recorder feature that enables independent evaluation of conditions to decide if a
+// message needs to be sent to the recorder, an enabled session, or both.
+#define ENABLE_WPP_TRACE_FILTERING_WITH_WPP_RECORDER 1
+
+// Logger/Enabled macros used to decide if a message that is being sent to a custom recorder should
+// also go to an enabled session. These do not depend on the custom recorder itself, so just
+// delegate to the default.
+#define WPP_IFRLOG_LEVEL_FLAGS_LOGGER(IFRLOG, LEVEL, FLAGS) WPP_LEVEL_FLAGS_LOGGER(LEVEL, FLAGS)
+#define WPP_IFRLOG_LEVEL_FLAGS_ENABLED(IFRLOG, LEVEL, FLAGS) WPP_LEVEL_FLAGS_ENABLED(LEVEL, FLAGS)
+
+#define WPP_RECORDER_CONDITIONAL_LEVEL_FLAGS_OVERRIDE(LEVEL, FLAGS, HR) \
+ ((LEVEL == LEVEL_COND) ? \
+ (FAILED(HR) ? \
+ WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL_ERROR, FLAGS) : WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL_VERBOSE, FLAGS)) : \
+ WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL, FLAGS))
+
+#define WPP_RECORDER_CONDITIONAL_LEVEL_FLAGS_OVERRIDE_NTSTATUS(LEVEL, FLAGS, STATUS) \
+ ((LEVEL == LEVEL_COND) ? \
+ (FAILED_NTSTATUS(STATUS) ? \
+ WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL_ERROR, FLAGS) : WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL_VERBOSE, FLAGS)) : \
+ WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL, FLAGS))
+
+#define WPP_RECORDER_LEVEL_FLAGS_HR_ARGS(LEVEL, FLAGS, RETVAL) WPP_RECORDER_LEVEL_FLAGS_ARGS(LEVEL, FLAGS)
+#define WPP_RECORDER_LEVEL_FLAGS_HR_FILTER(LEVEL, FLAGS, RETVAL) WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL, FLAGS)
+
+#define WPP_RECORDER_LEVEL_FLAGS_RETVAL_ARGS(LEVEL, FLAGS, RETVAL) WPP_RECORDER_LEVEL_FLAGS_ARGS(LEVEL, FLAGS)
+#define WPP_RECORDER_LEVEL_FLAGS_RETVAL_FILTER(LEVEL, FLAGS, RETVAL) WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL, FLAGS)
+
+#define WPP_RECORDER_LEVEL_FLAGS_FI_ARGS(LEVEL, FLAGS, RETVAL) WPP_RECORDER_LEVEL_FLAGS_ARGS(LEVEL, FLAGS)
+#define WPP_RECORDER_LEVEL_FLAGS_FI_FILTER(LEVEL, FLAGS, RETVAL) WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL, FLAGS)
+
+#define WPP_RECORDER_LEVEL_FLAGS_STATUS_ARGS(LEVEL, FLAGS, STATUS) WPP_RECORDER_LEVEL_FLAGS_ARGS(LEVEL, FLAGS)
+#define WPP_RECORDER_LEVEL_FLAGS_STATUS_FILTER(LEVEL, FLAGS, STATUS) WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL, FLAGS)
+
+#define WPP_RECORDER_LEVEL_FLAGS_RETSTATUS_ARGS(LEVEL, FLAGS, RETSTATUS) WPP_RECORDER_LEVEL_FLAGS_ARGS(LEVEL, FLAGS)
+#define WPP_RECORDER_LEVEL_FLAGS_RETSTATUS_FILTER(LEVEL, FLAGS, RETSTATUS) WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL, FLAGS)
+
+#define WPP_RECORDER_LEVEL_FLAGS_IFRLOG_RETSTATUS_ARGS(LEVEL, FLAGS, IFRLOG, RETSTATUS) WPP_RECORDER_LEVEL_FLAGS_ARGS(LEVEL, FLAGS)
+#define WPP_RECORDER_LEVEL_FLAGS_IFRLOG_RETSTATUS_FILTER(LEVEL, FLAGS, IFRLOG, RETSTATUS) WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL, FLAGS)
+
+#define WPP_RECORDER_LEVEL_FLAGS_IFRLOG_RETSTATUS_ALLOWEDSTATUS_ARGS(LEVEL, FLAGS, IFRLOG, RETSTATUS, ALLOWEDSTATUS) WPP_RECORDER_LEVEL_FLAGS_ARGS(LEVEL, FLAGS)
+#define WPP_RECORDER_LEVEL_FLAGS_IFRLOG_RETSTATUS_ALLOWEDSTATUS_FILTER(LEVEL, FLAGS, IFRLOG, RETSTATUS, ALLOWEDSTATUS) WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL, FLAGS)
+
+#define WPP_RECORDER_LEVEL_FLAGS_RETPTR_ARGS(LEVEL, FLAGS, RETPTR) WPP_RECORDER_LEVEL_FLAGS_ARGS(LEVEL, FLAGS)
+#define WPP_RECORDER_LEVEL_FLAGS_RETPTR_FILTER(LEVEL, FLAGS, RETPTR) WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL, FLAGS)
+
+#define WPP_RECORDER_LEVEL_FLAGS_RETSTATUS_RETPTR_ARGS(LEVEL, FLAGS, RETSTATUS, RETPTR) WPP_RECORDER_LEVEL_FLAGS_ARGS(LEVEL, FLAGS)
+#define WPP_RECORDER_LEVEL_FLAGS_RETSTATUS_RETPTR_FILTER(LEVEL, FLAGS, RETSTATUS, RETPTR) WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL, FLAGS)
+
+#define WPP_RECORDER_LEVEL_FLAGS_RETSTATUS_POSCOND_ARGS(LEVEL, FLAGS, RETSTATUS, POSCOND) WPP_RECORDER_LEVEL_FLAGS_ARGS(LEVEL, FLAGS)
+#define WPP_RECORDER_LEVEL_FLAGS_RETSTATUS_POSCOND_FILTER(LEVEL, FLAGS, RETSTATUS, POSCOND) WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL, FLAGS)
+
+#define WPP_RECORDER_LEVEL_FLAGS_IFRLOG_POSCOND_RETSTATUS_ARGS(LEVEL, FLAGS, IFRLOG, RETSTATUS, POSCOND) WPP_RECORDER_LEVEL_FLAGS_ARGS(LEVEL, FLAGS)
+#define WPP_RECORDER_LEVEL_FLAGS_IFRLOG_POSCOND_RETSTATUS_FILTER(LEVEL, FLAGS, IFRLOG, RETSTATUS, POSCOND) WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL, FLAGS)
+
+#define WPP_RECORDER_LEVEL_FLAGS_RETSTATUS_NEGCOND_ARGS(LEVEL, FLAGS, RETSTATUS, NEGCOND) WPP_RECORDER_LEVEL_FLAGS_ARGS(LEVEL, FLAGS)
+#define WPP_RECORDER_LEVEL_FLAGS_RETSTATUS_NEGCOND_FILTER(LEVEL, FLAGS, RETSTATUS, NEGCOND) WPP_RECORDER_LEVEL_FLAGS_FILTER(LEVEL, FLAGS)
+#pragma endregion
+
+#pragma region Custom tracing macros
+
+// begin_wpp config
+// USEPREFIX(DrvLogCritical, "%!STDPREFIX!CRIT: ");
+// USEPREFIX(DrvLogError, "%!STDPREFIX!ERROR: ");
+// USEPREFIX(DrvLogWarning, "%!STDPREFIX!WARN: ");
+// USEPREFIX(DrvLogInfo, "%!STDPREFIX!INFO: ");
+// USEPREFIX(DrvLogVerbose, "%!STDPREFIX!VERB: ");
+// USEPREFIX(DrvLogEnter, "%!STDPREFIX!ENTER");
+// USEPREFIX(DrvLogExit, "%!STDPREFIX!EXIT");
+// end_wpp
+
+// begin_wpp config
+// FUNC DrvLogCritical{LEVEL=TRACE_LEVEL_CRITICAL}(IFRLOG,FLAGS,MSG,...);
+// FUNC DrvLogError{LEVEL=TRACE_LEVEL_ERROR}(IFRLOG,FLAGS,MSG,...);
+// FUNC DrvLogWarning{LEVEL=TRACE_LEVEL_WARNING}(IFRLOG,FLAGS,MSG,...);
+// FUNC DrvLogInfo{LEVEL=TRACE_LEVEL_INFORMATION}(IFRLOG,FLAGS,MSG,...);
+// FUNC DrvLogEnter{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=FLAG_FUNCTION}(IFRLOG,...);
+// FUNC DrvLogVerbose{LEVEL=TRACE_LEVEL_VERBOSE}(IFRLOG,FLAGS,MSG,...);
+// FUNC DrvLogExit{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=FLAG_FUNCTION}(IFRLOG,...);
+// end_wpp
+
+
+#ifdef __INTELLISENSE__
+#define FLAG_DEVICE_ALL 0x01
+#define FLAG_FUNCTION 0x02
+#define FLAG_INFO 0x04
+#define FLAG_PNP 0x08
+#define FLAG_POWER 0x10
+#define FLAG_STREAM 0x20
+#define FLAG_INIT 0x40
+#define FLAG_DDI 0x80
+#define FLAG_GENERIC 0x100
+void DrvLogCritical(void* log, int flags, const WCHAR* fmt, ...);
+void DrvLogError(void* log, int flags, const WCHAR* fmt, ...);
+void DrvLogWarning(void* log, int flags, const WCHAR* fmt, ...);
+void DrvLogInfo(void* log, int flags, const WCHAR* fmt, ...);
+void DrvLogEnter(void* log, ...);
+void DrvLogVerbose(void* log, int flags, const WCHAR* fmt, ...);
+void DrvLogExit(void* log, ...);
+
+void RETURN_IF_FAILED(NTSTATUS status);
+void RETURN_NTSTATUS_IF_FAILED(NTSTATUS status);
+void RETURN_NTSTATUS_IF_FAILED_MSG(NTSTATUS status, const WCHAR* fmt, ...);
+void RETURN_NTSTATUS_IF_FAILED_UNLESS_ALLOWED(NTSTATUS returnStatus, NTSTATUS allowedStatus);
+void RETURN_NTSTATUS_IF_NULL_ALLOC(PVOID ptr);
+void RETURN_NTSTATUS_IF_NULL(PVOID ptr);
+void RETURN_NTSTATUS_IF_TRUE(BOOL condition, NTSTATUS status);
+void RETURN_NTSTATUS_IF_TRUE_MSG(BOOL condition, NTSTATUS status, const WCHAR* fmt, ...);
+void RETURN_NTSTATUS_IF_FALSE(BOOL condition, NTSTATUS status);
+void RETURN_NTSTATUS(NTSTATUS status);
+void RETURN_NTSTATUS_MSG(NTSTATUS status, const WCHAR* fmt, ...);
+#endif// __INTELLISENSE__
+
+//*********************************************************
+// MACRO: TRACE_METHOD_LINE
+//
+// begin_wpp config
+// FUNC TRACE_METHOD_LINE(LEVEL, FLAGS, MSG, ...);
+// USESUFFIX (TRACE_METHOD_LINE, ", this=0x%p", this);
+// end_wpp
+
+//*********************************************************
+// MACRO: TRACE_METHOD_ENTRY
+//
+// begin_wpp config
+// FUNC TRACE_METHOD_ENTRY(LEVEL, FLAGS);
+// USESUFFIX (TRACE_METHOD_ENTRY, "Enter, this=0x%p", this);
+// end_wpp
+
+//*********************************************************
+// MACRO: TRACE_METHOD_EXIT
+//
+// begin_wpp config
+// FUNC TRACE_METHOD_EXIT(LEVEL, FLAGS);
+// USESUFFIX (TRACE_METHOD_EXIT, "Exit, this=0x%p", this);
+// end_wpp
+
+//*********************************************************
+// MACRO: TRACE_METHOD_EXIT_HR
+//
+// begin_wpp config
+// FUNC TRACE_METHOD_EXIT_HR(LEVEL, FLAGS, HR);
+// USESUFFIX (TRACE_METHOD_EXIT_HR, "Exit, this=0x%p, hr=%!HRESULT!", this, HR);
+// end_wpp
+
+//*********************************************************
+// MACRO: TRACE_METHOD_EXIT_DWORD
+//
+// begin_wpp config
+// FUNC TRACE_METHOD_EXIT_DWORD(LEVEL, FLAGS, RETVAL);
+// USESUFFIX (TRACE_METHOD_EXIT_DWORD, "Exit, this=0x%p, ret=0x%08Ix ", this, RETVAL);
+// end_wpp
+
+//*********************************************************
+// MACRO: TRACE_METHOD_EXIT_PTR
+//
+// begin_wpp config
+// FUNC TRACE_METHOD_EXIT_PTR(LEVEL, FLAGS, RETVAL);
+// USESUFFIX (TRACE_METHOD_EXIT_PTR,"Exit, this=0x%p, retptr=0x%p", this, RETVAL);
+// end_wpp
+
+//*********************************************************
+// MACRO: TRACE_METHOD_EXIT_STATUS
+//
+// begin_wpp config
+// FUNC TRACE_METHOD_EXIT_STATUS(LEVEL, FLAGS, STATUS);
+// USESUFFIX (TRACE_METHOD_EXIT_STATUS, "Exit, this=0x%p, status=%!STATUS!", this, STATUS);
+// end_wpp
+
+//*********************************************************
+// MACRO: TRACE_FUNCTION_ENTRY
+//
+// begin_wpp config
+// FUNC TRACE_FUNCTION_ENTRY(LEVEL, FLAGS);
+// USESUFFIX (TRACE_FUNCTION_ENTRY, "Enter");
+// end_wpp
+
+//*********************************************************
+// MACRO: TRACE_FUNCTION_EXIT
+//
+// begin_wpp config
+// FUNC TRACE_FUNCTION_EXIT(LEVEL, FLAGS);
+// USESUFFIX (TRACE_FUNCTION_EXIT, "Exit");
+// end_wpp
+
+//*********************************************************
+// MACRO: TRACE_FUNCTION_EXIT_HR
+//
+// begin_wpp config
+// FUNC TRACE_FUNCTION_EXIT_HR(LEVEL, FLAGS, HR);
+// USESUFFIX (TRACE_FUNCTION_EXIT_HR, "Exit, hr=%!HRESULT!", HR);
+// end_wpp
+
+//*********************************************************
+// MACRO: TRACE_FUNCTION_EXIT_DWORD
+//
+// begin_wpp config
+// FUNC TRACE_FUNCTION_EXIT_DWORD(LEVEL, FLAGS, RETVAL);
+// USESUFFIX (TRACE_FUNCTION_EXIT_DWORD, "Exit, ret=0x%08Ix", RETVAL);
+// end_wpp
+
+//*********************************************************
+// MACRO: TRACE_FUNCTION_EXIT_PTR
+//
+// begin_wpp config
+// FUNC TRACE_FUNCTION_EXIT_PTR(LEVEL, FLAGS, RETVAL);
+// USESUFFIX (TRACE_FUNCTION_EXIT_PTR, "Exit, retptr=0x%p", RETVAL);
+// end_wpp
+
+//*********************************************************
+// MACRO: TRACE_FUNCTION_EXIT_STATUS
+//
+// begin_wpp config
+// FUNC TRACE_FUNCTION_EXIT_STATUS(LEVEL, FLAGS, STATUS);
+// USESUFFIX (TRACE_FUNCTION_EXIT_STATUS, "Exit, status=%!STATUS!", STATUS);
+// end_wpp
+
+//*********************************************************
+// MACRO: TRACE_LINE
+//
+// begin_wpp config
+// FUNC TRACE_LINE(LEVEL, FLAGS, MSG, ...);
+// end_wpp
+
+//*********************************************************
+// MACRO: TRACE_HRESULT
+//
+// begin_wpp config
+// FUNC TRACE_HRESULT(LEVEL, FLAGS, HR, MSG, ...);
+// USESUFFIX (TRACE_HRESULT, ", ret=%!HRESULT!", HR);
+// end_wpp
+
+//*********************************************************
+// MACRO: TRACE_FAILURE_INFO (WIL FailureInfo logging)
+// see: https://github.com/microsoft/wil/blob/master/include/wil/result_macros.h
+//
+// begin_wpp config
+// FUNC TRACE_FAILURE_INFO(LEVEL, FLAGS, FI);
+// USESUFFIX(TRACE_FAILURE_INFO, " [%04X] '%ws', hr=%!HRESULT! ['%s' (%u)]", FI.threadId, FI.pszMessage, FI.hr, FI.pszFile, FI.uLineNumber);
+// end_wpp
+
+// MACRO: RETURN_IF_FAILED
+//
+// begin_wpp config
+// FUNC RETURN_IF_FAILED{LEVEL=LEVEL_ERROR,FLAGS=FLAG_DEVICE_ALL,IFRLOG=g_AudioDspLog}(RETSTATUS);
+// USEPREFIX(RETURN_IF_FAILED, "%!STDPREFIX!ERROR:");
+// USESUFFIX(RETURN_IF_FAILED, " File:%s, Line:%d - status=%!STATUS!", __FILE__, __LINE__, __statusRet);
+// end_wpp
+
+
+// MACRO: RETURN_NTSTATUS_IF_FAILED
+//
+// begin_wpp config
+// FUNC RETURN_NTSTATUS_IF_FAILED{LEVEL=LEVEL_ERROR,FLAGS=FLAG_DEVICE_ALL,IFRLOG=g_AudioDspLog}(RETSTATUS);
+// USEPREFIX(RETURN_NTSTATUS_IF_FAILED, "%!STDPREFIX!ERROR:");
+// USESUFFIX(RETURN_NTSTATUS_IF_FAILED, " File:%s, Line:%d - status=%!STATUS!", __FILE__, __LINE__, __statusRet);
+// end_wpp
+
+// MACRO: RETURN_NTSTATUS_IF_FAILED_MSG
+//
+// begin_wpp config
+// FUNC RETURN_NTSTATUS_IF_FAILED_MSG{LEVEL=LEVEL_ERROR,FLAGS=FLAG_DEVICE_ALL,IFRLOG=g_AudioDspLog}(RETSTATUS, MSG, ...);
+// USEPREFIX(RETURN_NTSTATUS_IF_FAILED_MSG, "%!STDPREFIX!ERROR:");
+// USESUFFIX(RETURN_NTSTATUS_IF_FAILED_MSG, " - status=%!STATUS!",__statusRet);
+// end_wpp
+
+// MACRO: RETURN_NTSTATUS_IF_FAILED_UNLESS_ALLOWED
+//
+// begin_wpp config
+// FUNC RETURN_NTSTATUS_IF_FAILED_UNLESS_ALLOWED{LEVEL=LEVEL_ERROR,FLAGS=FLAG_DEVICE_ALL,IFRLOG=g_AudioDspLog}(RETSTATUS, ALLOWEDSTATUS);
+// USEPREFIX(RETURN_NTSTATUS_IF_FAILED_UNLESS_ALLOWED, "%!STDPREFIX!ERROR:");
+// USESUFFIX(RETURN_NTSTATUS_IF_FAILED_UNLESS_ALLOWED, " File:%s, Line:%d - status=%!STATUS!", __FILE__, __LINE__, __statusRet);
+// end_wpp
+
+// MACRO: RETURN_NTSTATUS_IF_NULL_ALLOC
+//
+// begin_wpp config
+// FUNC RETURN_NTSTATUS_IF_NULL_ALLOC{LEVEL=LEVEL_ERROR,FLAGS=DUMMY}(RETPTR);
+// USESUFFIX(RETURN_NTSTATUS_IF_NULL, "status=STATUS_INSUFFICIENT_RESOURCES");
+// end_wpp
+
+// MACRO: RETURN_NTSTATUS_IF_NULL
+//
+// begin_wpp config
+// FUNC RETURN_NTSTATUS_IF_NULL{LEVEL=LEVEL_ERROR,FLAGS=DUMMY}(RETSTATUS, RETPTR);
+// USESUFFIX(RETURN_NTSTATUS_IF_NULL, "status=%!STATUS!", __statusRet);
+// end_wpp
+
+// MACRO: RETURN_NTSTATUS_IF_TRUE
+//
+// begin_wpp config
+// FUNC RETURN_NTSTATUS_IF_TRUE{LEVEL=LEVEL_ERROR,FLAGS=FLAG_DEVICE_ALL,IFRLOG=g_AudioDspLog}(POSCOND, RETSTATUS);
+// USESUFFIX(RETURN_NTSTATUS_IF_TRUE, " File:%s, Line:%d - status=%!STATUS!", __FILE__, __LINE__, __statusRet);
+// end_wpp
+
+// MACRO: RETURN_NTSTATUS_IF_TRUE_MSG
+//
+// begin_wpp config
+// FUNC RETURN_NTSTATUS_IF_TRUE_MSG{LEVEL=LEVEL_ERROR,FLAGS=FLAG_DEVICE_ALL,IFRLOG=g_AudioDspLog}(POSCOND, RETSTATUS, MSG, ...);
+// USESUFFIX(RETURN_NTSTATUS_IF_TRUE_MSG, " - status=%!STATUS!", __statusRet);
+// end_wpp
+
+// MACRO: RETURN_NTSTATUS_IF_FALSE
+//
+// begin_wpp config
+// FUNC RETURN_NTSTATUS_IF_FALSE{LEVEL=LEVEL_ERROR,FLAGS=DUMMY}(RETSTATUS, NEGCOND);
+// USESUFFIX(RETURN_NTSTATUS_IF_FALSE, " File:%s, Line:%d - status=%!STATUS!", __FILE__, __LINE__, __statusRet);
+// end_wpp
+
+// MACRO: RETURN_NTSTATUS
+//
+// begin_wpp config
+// FUNC RETURN_NTSTATUS{LEVEL=LEVEL_ERROR,FLAGS=FLAG_DEVICE_ALL,IFRLOG=g_AudioDspLog}(RETSTATUS);
+// USESUFFIX(RETURN_NTSTATUS, " File:%s, Line:%d - status=%!STATUS!", __FILE__, __LINE__, __statusRet);
+// end_wpp
+
+// MACRO: RETURN_NTSTATUS_MSG
+//
+// begin_wpp config
+// FUNC RETURN_NTSTATUS_MSG{LEVEL=LEVEL_ERROR,FLAGS=FLAG_DEVICE_ALL,IFRLOG=g_AudioDspLog}(RETSTATUS, MSG, ...);
+// USESUFFIX(RETURN_NTSTATUS_MSG, " - status=%!STATUS!", __statusRet);
+// end_wpp
+
+#define W32
+#define WPP_CHECK_FOR_NULL_STRING //to prevent exceptions due to NULL strings
+
+#pragma endregion
diff --git a/audio/Acx/Samples/Common/WaveReader.cpp b/audio/Acx/Samples/Common/WaveReader.cpp
new file mode 100644
index 00000000..4fa6eae9
--- /dev/null
+++ b/audio/Acx/Samples/Common/WaveReader.cpp
@@ -0,0 +1,769 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+ WaveReader.cpp
+
+Abstract:
+ Implementation of wave file reader for ACX sample drivers.
+
+ To read data from disk, this class maintains a circular data buffer. This buffer is segmented into multiple chunks of
+ big buffer (Though we only need two, so it is set to two now). Initially we fill first two chunks and once a chunk gets emptied
+ by OS, we schedule a workitem to fill the next available chunk.
+
+
+--*/
+
+#pragma warning (disable : 4127)
+#pragma warning (disable : 26165)
+
+#include "private.h"
+#include <devguid.h>
+#include <ks.h>
+#include <mmsystem.h>
+#include <ksmedia.h>
+#include "WaveReader.h"
+
+#define FILE_NAME_BUFFER_TAG 'WRT1'
+#define WAVE_DATA_BUFFER_TAG 'WRT2'
+#define WORK_ITEM_BUFFER_TAG 'WRT3'
+
+#define MAX_READ_WORKER_ITEM_COUNT 15
+
+#define IF_FAILED_JUMP(result, tag) do {if (!NT_SUCCESS(result)) {goto tag;}} while(false)
+#define IF_TRUE_JUMP(result, tag) do {if (result) {goto tag;}} while(false)
+#define IF_TRUE_ACTION_JUMP(result, action, tag) do {if (result) {action; goto tag;}} while(false)
+
+PREADWORKER_PARAM CWaveReader::m_pWorkItems = NULL;
+PDEVICE_OBJECT CWaveReader::m_pDeviceObject = NULL;
+
+
+/*++
+
+Routine Description:
+ Ctor: basic init.
+
+--*/
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+CWaveReader::CWaveReader()
+: m_ChannelCount(0),
+ m_BitsPerSample(0),
+ m_SamplesPerSecond(0),
+ m_Mute(false),
+ m_FileHandle(NULL)
+{
+ PAGED_CODE();
+ m_WaveDataQueue.pWavData = NULL;
+ KeInitializeMutex(&m_FileSync, 0);
+}
+
+/*++
+
+Routine Description:
+ Dtor: free resources.
+
+--*/
+_Use_decl_annotations_
+PAGED_CODE_SEG
+CWaveReader::~CWaveReader()
+{
+ PAGED_CODE();
+ if (STATUS_SUCCESS == KeWaitForSingleObject
+ (
+ &m_FileSync,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL
+ ))
+ {
+ if (m_WaveDataQueue.pWavData != NULL)
+ {
+ ExFreePoolWithTag(m_WaveDataQueue.pWavData, WAVE_DATA_BUFFER_TAG);
+ m_WaveDataQueue.pWavData = NULL;
+ }
+
+ FileClose();
+ KeReleaseMutex(&m_FileSync, FALSE);
+ }
+
+}
+
+/*++
+
+Routine Description:
+ - Initializing the workitems. These workitems will be scheduled asynchronously by the OS.
+ - When these work items will be scheduled the wave file will be read and the data
+ - will be put inside the big chunks.
+
+Arguments:
+ Device object
+
+Return Value:
+ NT status code.
+
+--*/
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS CWaveReader::InitializeWorkItems(_In_ PDEVICE_OBJECT DeviceObject)
+{
+ PAGED_CODE();
+
+ ASSERT(DeviceObject);
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ if (m_pWorkItems != NULL)
+ {
+ return ntStatus;
+ }
+
+ m_pWorkItems = (PREADWORKER_PARAM)
+ ExAllocatePool2
+ (
+ POOL_FLAG_NON_PAGED,
+ sizeof(READWORKER_PARAM) * MAX_READ_WORKER_ITEM_COUNT,
+ 'RDPT'
+ );
+ if (m_pWorkItems)
+ {
+ for (int i = 0; i < MAX_READ_WORKER_ITEM_COUNT; i++)
+ {
+
+ m_pWorkItems[i].WorkItem = IoAllocateWorkItem(DeviceObject);
+ if (m_pWorkItems[i].WorkItem == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ KeInitializeEvent
+ (
+ &m_pWorkItems[i].EventDone,
+ NotificationEvent,
+ TRUE
+ );
+ }
+ }
+ else
+ {
+ ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ return ntStatus;
+}
+
+/*++
+
+Routine Description:
+- Wait for all the scheduled workitems to finish.
+
+--*/
+
+
+//=============================================================================
+_Use_decl_annotations_
+PAGED_CODE_SEG
+void CWaveReader::WaitAllWorkItems()
+{
+ PAGED_CODE();
+
+ for (int i = 0; i < MAX_READ_WORKER_ITEM_COUNT; i++)
+ {
+ KeWaitForSingleObject
+ (
+ &(m_pWorkItems[i].EventDone),
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL
+ );
+ }
+}
+
+/*++
+
+Routine Description:
+ - Deallocating the workitems.
+
+--*/
+
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+VOID CWaveReader::DestroyWorkItems()
+{
+ PAGED_CODE();
+
+ if (m_pWorkItems)
+ {
+ for (int i = 0; i < MAX_READ_WORKER_ITEM_COUNT; i++)
+ {
+ if (m_pWorkItems[i].WorkItem != NULL)
+ {
+ IoFreeWorkItem(m_pWorkItems[i].WorkItem);
+ m_pWorkItems[i].WorkItem = NULL;
+ }
+ }
+ ExFreePoolWithTag(m_pWorkItems, WORK_ITEM_BUFFER_TAG);
+ m_pWorkItems = NULL;
+ }
+}
+
+/*++
+
+Routine Description:
+ - Get a free work item to schedule a file read operation.
+
+--*/
+_Use_decl_annotations_
+PREADWORKER_PARAM CWaveReader::GetNewWorkItem()
+{
+ LARGE_INTEGER timeOut = { 0 };
+ NTSTATUS ntStatus;
+
+ for (int i = 0; i < MAX_READ_WORKER_ITEM_COUNT; i++)
+ {
+ ntStatus =
+ KeWaitForSingleObject
+ (
+ &m_pWorkItems[i].EventDone,
+ Executive,
+ KernelMode,
+ FALSE,
+ &timeOut
+ );
+ if (STATUS_SUCCESS == ntStatus)
+ {
+ if (m_pWorkItems[i].WorkItem)
+ return &(m_pWorkItems[i]);
+ else
+ return NULL;
+ }
+ }
+
+ return NULL;
+}
+
+/*++
+Routine Description:
+- This routine will enqueue a workitem for reading wave file and putting
+- the data into the chunk buffer.
+
+Arguments:
+ Chunk descriptor for the chunk to be filled.
+--*/
+
+_Use_decl_annotations_
+VOID CWaveReader::ReadWavChunk(PCHUNKDESCRIPTOR pChunkDescriptor)
+{
+ PREADWORKER_PARAM pParam = NULL;
+
+ pParam = GetNewWorkItem();
+ if (pParam)
+ {
+ pParam->PtrWaveReader = this;
+ pParam->PtrChunkDescriptor = pChunkDescriptor;
+ KeResetEvent(&pParam->EventDone);
+ IoQueueWorkItem(pParam->WorkItem, ReadFrameWorkerCallback,
+ DelayedWorkQueue, (PVOID)pParam);
+ }
+}
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+IO_WORKITEM_ROUTINE ReadFrameWorkerCallback;
+/*
+Routine Description:
+- This routine will be called by the OS. It will fill the chunk buffer, defined by the chunk descriptor
+- If end of file is reached it will mark the end of file as true.
+
+Arguments:
+ pDeviceObject - Device object
+ Context - pointer to reader worker params
+*/
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+VOID ReadFrameWorkerCallback
+(
+ _In_ PDEVICE_OBJECT pDeviceObject,
+ _In_opt_ PVOID Context
+)
+{
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(pDeviceObject);
+ pWaveReader pWavRd;
+ PREADWORKER_PARAM pParam = (PREADWORKER_PARAM)Context;
+
+ if (NULL == pParam)
+ {
+ // This is completely unexpected, assert here.
+ //
+ ASSERT(pParam);
+ goto exit;
+ }
+
+ pWavRd = pParam->PtrWaveReader;
+
+ if (pWavRd == NULL)
+ {
+ goto exit;
+ }
+ if (STATUS_SUCCESS == KeWaitForSingleObject
+ (
+ &pWavRd->m_FileSync,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL
+ ))
+ {
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ ASSERT(Context);
+
+ IO_STATUS_BLOCK ioStatusBlock;
+
+ if (pParam->WorkItem)
+ {
+ if (pWavRd->m_WaveDataQueue.bEofReached || pWavRd->m_WaveDataQueue.pWavData == NULL)
+ {
+ KeReleaseMutex(&pWavRd->m_FileSync, FALSE);
+ goto exit;
+ }
+
+ if (pParam->PtrChunkDescriptor->pStartAddress != NULL)
+ {
+ ntStatus = ZwReadFile(pWavRd->m_FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &ioStatusBlock,
+ pParam->PtrChunkDescriptor->pStartAddress,
+ pParam->PtrChunkDescriptor->ulChunkLength,
+ NULL,
+ NULL);
+
+ pParam->PtrChunkDescriptor->bIsChunkEmpty = false;
+
+ if (ioStatusBlock.Information != pParam->PtrChunkDescriptor->ulChunkLength)
+ {
+ pWavRd->m_WaveDataQueue.bEofReached = true;
+ }
+ }
+ }
+
+ KeReleaseMutex(&pWavRd->m_FileSync, FALSE);
+ }
+
+exit:
+ KeSetEvent(&pParam->EventDone, 0, FALSE);
+}
+
+/*++
+
+Routine Description:
+- If all the chunks are empty this resturn true.
+
+--*/
+
+_Use_decl_annotations_
+bool CWaveReader::IsAllChunkEmpty()
+{
+ for (int i = 0; i < NUM_OF_CHUNK_FOR_FILE_READ; i++)
+ {
+ if (!m_WaveDataQueue.sChunkDescriptor[i].bIsChunkEmpty)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+/*++
+Routine Description:
+ - This routine does the actual copy of data from the chunk buffer to the buffer provided by OS.
+ - If it empties the current chunk buffer, then it sets it state to empty and then enqueue a workitem
+ - to read data from the wave file and put it to the next available chunk buffer.
+
+Arguments:
+ Buffer - Pointer to the OS buffer
+ BufferLength - Length of the data to be filled (in bytes)
+
+--*/
+_Use_decl_annotations_
+VOID CWaveReader::CopyDataFromRingBuffer
+(
+ _Out_writes_bytes_(BufferLength) BYTE *Buffer,
+ _In_ ULONG BufferLength
+)
+{
+ if (IsAllChunkEmpty())
+ {
+ RtlZeroMemory(Buffer, BufferLength);
+ }
+ else
+ {
+ ULONG prevChunk = (m_WaveDataQueue.ulReadPtr*NUM_OF_CHUNK_FOR_FILE_READ )/ m_WaveDataQueue.ulLength;
+
+ /////////////////
+ BYTE *currentBuf = Buffer;
+ ULONG length = BufferLength;
+ while (length > 0)
+ {
+ ULONG runWrite = min(length, m_WaveDataQueue.ulLength - m_WaveDataQueue.ulReadPtr);
+
+ // Copy the wave buffer data to OS buffer
+ RtlCopyMemory(currentBuf, m_WaveDataQueue.pWavData + m_WaveDataQueue.ulReadPtr, runWrite);
+ // Zero out the wave buffer, so that if wave end of file is reached we should copy only zeros
+ RtlZeroMemory(m_WaveDataQueue.pWavData + m_WaveDataQueue.ulReadPtr, runWrite);
+ // Update the read pointer
+ m_WaveDataQueue.ulReadPtr = (m_WaveDataQueue.ulReadPtr + runWrite) % m_WaveDataQueue.ulLength;
+ currentBuf += runWrite;
+ length = length - runWrite;
+ }
+
+ ULONG curChunk = (m_WaveDataQueue.ulReadPtr*NUM_OF_CHUNK_FOR_FILE_READ) / m_WaveDataQueue.ulLength;
+
+ if (curChunk != prevChunk)
+ {
+ m_WaveDataQueue.currentExecutedChunk++;
+ // Schedule a workitem to read data from the wave file
+ ULONG chunkNo = m_WaveDataQueue.currentExecutedChunk % NUM_OF_CHUNK_FOR_FILE_READ;
+ m_WaveDataQueue.sChunkDescriptor[chunkNo].bIsChunkEmpty = true;
+ if (!m_WaveDataQueue.bEofReached)
+ {
+ ReadWavChunk(&m_WaveDataQueue.sChunkDescriptor[chunkNo]);
+ }
+ }
+ }
+}
+
+/*++
+Routine Description:
+ - Just a high level read buffer call.
+
+ Arguments:
+ Buffer - Pointer to the OS buffer
+ BufferLength - Length of the data to be filled (in bytes)
+--*/
+
+_Use_decl_annotations_
+VOID CWaveReader::ReadWaveData
+(
+ _Out_writes_bytes_(BufferLength) BYTE *Buffer,
+ _In_ ULONG BufferLength
+)
+{
+ if (m_Mute)
+ {
+ RtlZeroMemory(Buffer, BufferLength);
+ }
+ else
+ {
+ CopyDataFromRingBuffer(Buffer, BufferLength);
+ }
+}
+
+/*++
+Routine Description:
+- initialization for the wavereader member variables,
+- Allocating memory for the 1 second buffer
+- Preread the one second buffer data, so that when OS comes to read the data we have it available in the memory.
+
+Arguments:
+ WfExt - Format which should be used for capture
+ fileNameString - name of the file to be read
+
+Return:
+ NTStatus
+--*/
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS CWaveReader::Init
+(
+ _In_ PWAVEFORMATEXTENSIBLE WfExt,
+ _In_ PUNICODE_STRING puiFileName
+)
+{
+ PAGED_CODE();
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ KFLOATING_SAVE saveData;
+
+ // Save floating state (just in case).
+ ntStatus = KeSaveFloatingPointState(&saveData);
+ if (!NT_SUCCESS(ntStatus))
+ {
+ return ntStatus;
+ }
+
+ //
+ // This sample supports PCM 16bit formats only.
+ //
+ if ((WfExt->Format.wFormatTag != WAVE_FORMAT_PCM &&
+ !(WfExt->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
+ IsEqualGUIDAligned(WfExt->SubFormat, KSDATAFORMAT_SUBTYPE_PCM))) ||
+ (WfExt->Format.wBitsPerSample != 16 &&
+ WfExt->Format.wBitsPerSample != 8))
+ {
+ ntStatus = STATUS_NOT_SUPPORTED;
+ }
+ IF_FAILED_JUMP(ntStatus, Done);
+
+ // Basic init.
+ m_ChannelCount = WfExt->Format.nChannels; // # channels.
+ m_BitsPerSample = WfExt->Format.wBitsPerSample; // bits per sample.
+ m_SamplesPerSecond = WfExt->Format.nSamplesPerSec; // samples per sec.
+ m_Mute = false;
+
+ // Wave data queue initialization
+ m_WaveDataQueue.ulLength = WfExt->Format.nAvgBytesPerSec;
+ m_WaveDataQueue.bEofReached = false;
+ m_WaveDataQueue.ulReadPtr = 0;
+
+ // Mark all the chunk empty
+ for (int i = 0; i < NUM_OF_CHUNK_FOR_FILE_READ; i++)
+ {
+ m_WaveDataQueue.sChunkDescriptor[i].bIsChunkEmpty = true;
+ }
+
+ ntStatus = OpenWaveFile(puiFileName);
+ IF_FAILED_JUMP(ntStatus, Done);
+
+ ntStatus = AllocateBigBuffer();
+ IF_FAILED_JUMP(ntStatus, Done);
+
+ ntStatus = ReadHeaderAndFillBuffer();
+
+Done:
+ (void)KeRestoreFloatingPointState(&saveData);
+ return ntStatus;
+}
+
+/*++
+Routine Description:
+ This function read the wave header file and compare the header info with the
+ stream info. Currently we are using only number of channel, sampling frequency
+ and bits per sample as the primary parameters for the wave file to compare against
+ stream params. If the params don't match we return success but streams zeros.
+
+Return:
+ NTStatus
+--*/
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS CWaveReader::ReadHeaderAndFillBuffer()
+{
+ PAGED_CODE();
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ ntStatus = FileReadHeader();
+
+ if(NT_SUCCESS(ntStatus))
+ {
+ if (m_WaveHeader.numChannels != m_ChannelCount ||
+ m_WaveHeader.bitsPerSample != m_BitsPerSample ||
+ m_WaveHeader.sampleRate != m_SamplesPerSecond)
+ {
+ // If the wave file format don't match we wont treat this as error
+ // and we will stream zeros. So we return from here and will not read the
+ // wave file and wont fill the buffers.
+ return STATUS_SUCCESS;
+ }
+ }
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ // If the wave file format is same as the stream format we will stream the data
+ // else we will just stream zeros.
+ ReadWavChunk(&m_WaveDataQueue.sChunkDescriptor[0]); // Fill the first chunk
+ ReadWavChunk(&m_WaveDataQueue.sChunkDescriptor[1]); // Fill the second chunk
+ // Set the current executed chunk to 1. Once OS finishs the data for the first chunk
+ // use the currentExecutedChunk to find the next chunk and schedule a workitem to fill the
+ // data into the next chunk
+ m_WaveDataQueue.currentExecutedChunk = 1;
+ }
+
+ return ntStatus;
+}
+
+/*++
+Routine Description:
+ This function allocates 1 second buffer.
+ Segments the buffer into multiple (currently two) chunks. Assigns the start pointer and length
+ for each chunk.
+
+Return:
+ NTStatus
+--*/
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS CWaveReader::AllocateBigBuffer()
+{
+ PAGED_CODE();
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ m_WaveDataQueue.pWavData = (PBYTE)
+ ExAllocatePool2
+ (
+ POOL_FLAG_NON_PAGED,
+ m_WaveDataQueue.ulLength,
+ WAVE_DATA_BUFFER_TAG
+ );
+ if (!m_WaveDataQueue.pWavData)
+ {
+ ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ else
+ {
+ ULONG chunklLength = m_WaveDataQueue.ulLength / NUM_OF_CHUNK_FOR_FILE_READ;
+ for (int i = 0; i < NUM_OF_CHUNK_FOR_FILE_READ; i++)
+ {
+ m_WaveDataQueue.sChunkDescriptor[i].pStartAddress = m_WaveDataQueue.pWavData + chunklLength*i;
+ m_WaveDataQueue.sChunkDescriptor[i].ulChunkLength = chunklLength;
+ }
+ }
+ return ntStatus;
+}
+
+/*++
+Routine Description:
+ This function opens wave file.
+
+Arguments:
+ fileNameString - Name of the wave file
+
+Return:
+ NTStatus
+--*/
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS CWaveReader::OpenWaveFile(PUNICODE_STRING puiFileName)
+{
+ PAGED_CODE();
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ if (NT_SUCCESS(ntStatus) && puiFileName->Buffer != NULL)
+ {
+ // Create data file.
+ InitializeObjectAttributes
+ (
+ &m_objectAttributes,
+ puiFileName,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL
+ );
+
+ // Open Wave File
+ ntStatus = FileOpen();
+ }
+
+ return ntStatus;
+}
+
+/*++
+Routine Description:
+ This function closes wave file handle.
+
+Return:
+ NTStatus
+--*/
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS CWaveReader::FileClose()
+{
+ PAGED_CODE();
+
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+
+ if (m_FileHandle)
+ {
+ ntStatus = ZwClose(m_FileHandle);
+ m_FileHandle = NULL;
+ }
+
+ return ntStatus;
+}
+
+/*++
+Routine Description:
+ Reads the wave file file header information
+
+Return:
+ NTStatus
+--*/
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS CWaveReader::FileReadHeader()
+{
+ PAGED_CODE();
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ IO_STATUS_BLOCK ioStatusBlock;
+
+
+ ntStatus = ZwReadFile(m_FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &ioStatusBlock,
+ &m_WaveHeader,
+ sizeof(WAVEHEADER),
+ NULL,
+ NULL);
+
+ return ntStatus;
+}
+
+/*++
+Routine Description:
+ This function opens wave file.
+
+Return:
+ NTStatus
+--*/
+
+_Use_decl_annotations_
+PAGED_CODE_SEG
+NTSTATUS CWaveReader::FileOpen()
+{
+
+ PAGED_CODE();
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ IO_STATUS_BLOCK ioStatusBlock;
+
+ if (!m_FileHandle)
+ {
+ ntStatus =
+ ZwCreateFile
+ (
+ &m_FileHandle,
+ GENERIC_READ,
+ &m_objectAttributes,
+ &ioStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ,
+ FILE_OPEN,
+ FILE_SYNCHRONOUS_IO_NONALERT,
+ NULL,
+ 0
+ );
+ }
+
+ return ntStatus;
+}
+
diff --git a/audio/Acx/Samples/Common/WaveReader.h b/audio/Acx/Samples/Common/WaveReader.h
new file mode 100644
index 00000000..08516be7
--- /dev/null
+++ b/audio/Acx/Samples/Common/WaveReader.h
@@ -0,0 +1,196 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ WaveReader.h
+
+Abstract:
+
+ Declaration of wave reader for ACX sample drivers.
+
+
+--*/
+#pragma once
+
+#define _USE_MATH_DEFINES
+#include <math.h>
+#include <limits.h>
+
+#define NUM_OF_CHUNK_FOR_FILE_READ 2
+
+class CWaveReader;
+
+// Wave header structure decleration
+typedef CWaveReader *pWaveReader;
+typedef struct _WAVEHEADER
+{
+ BYTE chunkId[4];
+ ULONG chunkSize;
+ BYTE format[4];
+ BYTE subChunkId[4];
+ ULONG subChunkSize;
+ WORD audioFormat;
+ WORD numChannels;
+ ULONG sampleRate;
+ ULONG bytesPerSecond;
+ WORD blockAlign;
+ WORD bitsPerSample;
+ BYTE dataChunkId[4];
+ ULONG dataSize;
+}WAVEHEADER;
+
+typedef struct _CHUNKDESCRIPTOR
+{
+ PBYTE pStartAddress; // Starting address of the chunk
+ ULONG ulChunkLength; // Length of the chunk
+ bool bIsChunkEmpty; // If the chunk is empty
+}CHUNKDESCRIPTOR;
+typedef CHUNKDESCRIPTOR *PCHUNKDESCRIPTOR;
+
+/*
+ The idea here is to allocate one second long worth of buffer and divide it into NUM_OF_CHUNK_FOR_FILE_READ chunks.
+ In one file read operation we read and fill one chunk data . The chunk will be emptied every 10 ms by OS.
+ Once the OS empties one chunk data we schedule a workitem to read and fill next available chunk.
+*/
+
+typedef struct _WAVEDATAQUEUE
+{
+ PBYTE pWavData; // Pointer to the temporary buffer for reading one second worth of data from wave file
+ ULONG ulLength; // length of pWavData in bytes
+ ULONG ulReadPtr; // current reading position in pWavData in bytes
+ bool bEofReached; // This will be set once the eof is reached.
+ WORD currentExecutedChunk;
+ CHUNKDESCRIPTOR sChunkDescriptor[NUM_OF_CHUNK_FOR_FILE_READ];
+}WAVEDATAQUEUE;
+typedef WAVEDATAQUEUE *PWAVEDATAQUEUE;
+
+// Parameter to workitem.
+#include <pshpack1.h>
+typedef struct _READWORKER_PARAM {
+ PIO_WORKITEM WorkItem; // Pointer to the workitem
+ KEVENT EventDone; // Used for synchronizing a workitem for scheduling.
+ pWaveReader PtrWaveReader; // pointer to the wavereader class.
+ PCHUNKDESCRIPTOR PtrChunkDescriptor; // chunk descriptor for the chunk, which needs to be filled after file read
+} READWORKER_PARAM;
+typedef READWORKER_PARAM *PREADWORKER_PARAM;
+#include <poppack.h>
+
+__drv_maxIRQL(PASSIVE_LEVEL)
+PAGED_CODE_SEG
+IO_WORKITEM_ROUTINE ReadFrameWorkerCallback;
+
+// Wave Reader class
+
+class CWaveReader
+{
+
+public:
+ HANDLE m_FileHandle; // Wave File handle.
+ WORD m_ChannelCount; // Number of Channels for the stream during stream init
+ WORD m_BitsPerSample; // Number of Bits per sample for the stream during stream init
+ DWORD m_SamplesPerSecond; // Number of Sample per second for the stream during stream init
+ bool m_Mute; // Capture Zero buffer if mute
+ OBJECT_ATTRIBUTES m_objectAttributes; // Used for opening file.
+ WAVEDATAQUEUE m_WaveDataQueue; // Big buffer data object and its current state
+ KMUTEX m_FileSync; // Synchronizes file access
+ WAVEHEADER m_WaveHeader;
+
+public:
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ CWaveReader();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ ~CWaveReader();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS Init
+ (
+ _In_ PWAVEFORMATEXTENSIBLE WfExt,
+ _In_ PUNICODE_STRING puiFileName
+ );
+
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ VOID ReadWaveData
+ (
+ _Out_writes_bytes_(BufferLength) BYTE *Buffer,
+ _In_ ULONG BufferLength
+ );
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ VOID SetMute(_In_ bool Value)
+ {
+ PAGED_CODE();
+
+ m_Mute = Value;
+ }
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ void WaitAllWorkItems();
+
+ // Static allocation totally related to the workitems for reading data from wavefile and putting it to chunk buffer
+ static PDEVICE_OBJECT m_pDeviceObject;
+ static PREADWORKER_PARAM m_pWorkItems;
+ PAGED_CODE_SEG
+ static NTSTATUS InitializeWorkItems(_In_ PDEVICE_OBJECT DeviceObject);
+
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ static PREADWORKER_PARAM GetNewWorkItem();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ static VOID DestroyWorkItems();
+
+private:
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ VOID ReadWavChunk(PCHUNKDESCRIPTOR PtrChunkDescriptor);
+
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ bool IsAllChunkEmpty();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS OpenWaveFile(PUNICODE_STRING puiFileName);
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS FileClose();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS FileReadHeader();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS FileOpen();
+
+ __drv_maxIRQL(DISPATCH_LEVEL)
+ VOID CopyDataFromRingBuffer
+ (
+ _Out_writes_bytes_(BufferLength) BYTE *Buffer,
+ _In_ ULONG BufferLength
+ );
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS AllocateBigBuffer();
+
+ __drv_maxIRQL(PASSIVE_LEVEL)
+ PAGED_CODE_SEG
+ NTSTATUS ReadHeaderAndFillBuffer();
+
+ friend IO_WORKITEM_ROUTINE ReadFrameWorkerCallback;
+};
+
+
diff --git a/audio/Acx/Samples/Inc/AudioFormats.h b/audio/Acx/Samples/Inc/AudioFormats.h
new file mode 100644
index 00000000..8a48b1cf
--- /dev/null
+++ b/audio/Acx/Samples/Inc/AudioFormats.h
@@ -0,0 +1,959 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ AudioFormats.h
+
+Abstract:
+
+ Contains Audio formats supported for the ACX Sample Drivers
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#pragma once
+
+#define NOBITMAP
+#include <mmreg.h>
+
+//
+// Basic-testing formats.
+//
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm44100c2 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 44100,
+ 176400,
+ 4,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_STEREO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm44100c2_24in32 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 44100,
+ 352800,
+ 8,
+ 32,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 24,
+ KSAUDIO_SPEAKER_STEREO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm48000c2 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 48000,
+ 192000,
+ 4,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_STEREO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm48000c2_24in32 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 48000,
+ 384000,
+ 8,
+ 32,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 24,
+ KSAUDIO_SPEAKER_STEREO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm192000c2 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 192000,
+ 768000,
+ 4,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_STEREO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm44100c1 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 1,
+ 44100,
+ 88200,
+ 2,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_MONO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm48000c1 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 1,
+ 48000,
+ 96000,
+ 2,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_MONO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm16000c1 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 1,
+ 16000,
+ 32000,
+ 2,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_MONO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm32000c2 =
+{ // 14
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 32000,
+ 128000,
+ 4,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_STEREO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm88200c2 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 88200,
+ 352800,
+ 4,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_STEREO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm96000c2 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 96000,
+ 384000,
+ 4,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_STEREO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm24000c2 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 24000,
+ 96000,
+ 4,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_STEREO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm16000c2 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 16000,
+ 64000,
+ 4,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm8000c1 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 1,
+ 8000,
+ 16000,
+ 2,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_MONO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm11025c1 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 1,
+ 11025,
+ 22050,
+ 2,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_MONO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm22050c1 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 1,
+ 22050,
+ 44100,
+ 2,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_MONO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm24000c1 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 1,
+ 24000,
+ 48000,
+ 2,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_MONO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm32000c1 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 1,
+ 32000,
+ 64000,
+ 2,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_MONO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+//
+// Definitions of HDMI specific audio formats.
+//
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE DolbyDigital =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 48000,
+ 192000,
+ 4,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_STEREO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE DolbyDigitalPlus =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL_PLUS),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 192000,
+ 768000,
+ 4,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_STEREO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL_PLUS)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE DolbyDigitalPlusAtmos =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL_PLUS_ATMOS),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 192000,
+ 768000,
+ 4,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_STEREO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL_PLUS_ATMOS)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE DolbyMlp =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MLP),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 8,
+ 192000,
+ 3072000,
+ 16,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_7POINT1,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MLP)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE DolbyMlpSurround =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MLP),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 8,
+ 192000,
+ 3072000,
+ 16,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_7POINT1_SURROUND,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MLP)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE DtsSurround =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTS),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 48000,
+ 192000,
+ 4,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_STEREO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTS)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE DtsHD =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTS_HD),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 8,
+ 192000,
+ 3072000,
+ 16,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_7POINT1,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTS_HD)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE DtsHDLowBitRate =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTS_HD),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 192000,
+ 3072000,
+ 16,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_STEREO,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTS_HD)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE DtsXE1 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTSX_E1),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 8,
+ 192000,
+ 3072000,
+ 16,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_7POINT1,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTSX_E1)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE DtsXE2 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTSX_E2),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 8,
+ 192000,
+ 3072000,
+ 16,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_7POINT1,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DTSX_E2)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE DolbyMAT20 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MAT20),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 8,
+ 192000,
+ 3072000,
+ 16,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_7POINT1,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MAT20)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE DolbyMAT21 =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MAT21),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 8,
+ 192000,
+ 3072000,
+ 16,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ KSAUDIO_SPEAKER_7POINT1,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_MAT21)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm44100c2nomask =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 44100,
+ 176400,
+ 4,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX)
+ },
+ 16,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+// No Mask version is used for 2ch Capture, where the mask is not meaningful
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm48000c2nomask =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 2,
+ 48000,
+ 192000,
+ 4,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
+
+static
+KSDATAFORMAT_WAVEFORMATEXTENSIBLE Pcm16000c4nomask =
+{
+ {
+ sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
+ 0,
+ 0,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
+ STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
+ },
+ {
+ {
+ WAVE_FORMAT_EXTENSIBLE,
+ 4,
+ 16000,
+ 128000,
+ 8,
+ 16,
+ sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
+ },
+ 16,
+ 0,
+ STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
+ }
+};
diff --git a/audio/Acx/Samples/Inc/cpp_utils.h b/audio/Acx/Samples/Inc/cpp_utils.h
new file mode 100644
index 00000000..f4ed6220
--- /dev/null
+++ b/audio/Acx/Samples/Inc/cpp_utils.h
@@ -0,0 +1,71 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ cpp_utils.h
+
+Abstract:
+
+ Contains CPP utilities
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#pragma once
+
+// Function scope_exit instantiates scope_exit object
+// Constructor accepts lamda as parameter.
+// Assign tasks in lamdba to be executed on scope exit.
+template <typename F>
+auto scope_exit(F f)
+{
+ class scope_exit
+ {
+ public:
+ scope_exit(F f) :
+ _f{ f }
+ {
+ }
+
+ ~scope_exit()
+ {
+ if (_call)
+ {
+ _f();
+ }
+ }
+
+ // Ensures the scope_exit lambda will not be called
+ void release()
+ {
+ _call = false;
+ }
+
+ // Executes the scope_exit lambda immediately if not yet run; ensures it will not run again
+ void reset()
+ {
+ if (_call)
+ {
+ _f();
+ _call = false;
+ }
+ }
+
+ private:
+ F _f;
+ bool _call = true;
+ };
+
+ return scope_exit{ f };
+};
+
diff --git a/audio/Acx/Samples/Shared/Public.h b/audio/Acx/Samples/Shared/Public.h
new file mode 100644
index 00000000..f1e9da3b
--- /dev/null
+++ b/audio/Acx/Samples/Shared/Public.h
@@ -0,0 +1,342 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ Public.h
+
+Abstract:
+
+ Contains structure definitions and function prototypes for the driver
+ that are public.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+/* make prototypes usable from C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <initguid.h>
+#include <ntddk.h>
+#include <ntstrsafe.h>
+#include <ntintsafe.h>
+#include "Trace.h"
+
+#include <wdf.h>
+#include <acx.h>
+
+#define PAGED_CODE_SEG __declspec(code_seg("PAGE"))
+#define INIT_CODE_SEG __declspec(code_seg("INIT"))
+
+// Number of msec for idle timeout.
+#define IDLE_POWER_TIMEOUT 5000
+
+extern RECORDER_LOG g_AudioDspLog;
+extern RECORDER_LOG g_AudioDspMcLog;
+
+//
+// Define CODEC device context.
+//
+typedef struct _CODEC_DEVICE_CONTEXT {
+ ACXCIRCUIT Render;
+ ACXCIRCUIT Capture;
+ WDF_TRI_STATE ExcludeD3Cold;
+} CODEC_DEVICE_CONTEXT, * PCODEC_DEVICE_CONTEXT;
+
+//
+// Codec driver prototypes.
+//
+EVT_WDF_DRIVER_DEVICE_ADD Codec_EvtBusDeviceAdd;
+DRIVER_INITIALIZE DriverEntry;
+EVT_WDF_DRIVER_UNLOAD AudioCodecDriverUnload;
+
+//
+// Codec device callbacks.
+//
+EVT_WDF_DEVICE_PREPARE_HARDWARE Codec_EvtDevicePrepareHardware;
+EVT_WDF_DEVICE_RELEASE_HARDWARE Codec_EvtDeviceReleaseHardware;
+EVT_WDF_DEVICE_D0_ENTRY Codec_EvtDeviceD0Entry;
+EVT_WDF_DEVICE_D0_EXIT Codec_EvtDeviceD0Exit;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP Codec_EvtDeviceContextCleanup;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(CODEC_DEVICE_CONTEXT, GetCodecDeviceContext)
+
+//
+// Define DSP device context.
+//
+typedef struct _DSP_DEVICE_CONTEXT {
+ ACXCIRCUIT Speaker;
+ ACXCIRCUIT MicArray;
+ ACXCIRCUIT SpeakerHp;
+ ACXCIRCUIT MicrophoneHp;
+ ACXCIRCUIT HDMI;
+ WDF_TRI_STATE ExcludeD3Cold;
+} DSP_DEVICE_CONTEXT, * PDSP_DEVICE_CONTEXT;
+
+//
+// Dsp driver prototypes.
+//
+EVT_WDF_DRIVER_DEVICE_ADD Dsp_EvtBusDeviceAdd;
+EVT_WDF_DRIVER_UNLOAD AudioDspDriverUnload;
+
+//
+// Dsp device callbacks.
+//
+EVT_WDF_DEVICE_PREPARE_HARDWARE Dsp_EvtDevicePrepareHardware;
+EVT_WDF_DEVICE_RELEASE_HARDWARE Dsp_EvtDeviceReleaseHardware;
+EVT_WDF_DEVICE_D0_ENTRY Dsp_EvtDeviceD0Entry;
+EVT_WDF_DEVICE_D0_EXIT Dsp_EvtDeviceD0Exit;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP Dsp_EvtDeviceContextCleanup;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DSP_DEVICE_CONTEXT, GetDspDeviceContext)
+
+//
+// Define CODECMC (multicircuit codec) device context.
+//
+typedef struct _CODECMC_DEVICE_CONTEXT
+{
+ ACXCIRCUIT Render;
+ ACXCIRCUIT Capture;
+ ACXCOMPOSITETEMPLATE Composite[2];
+ ULONG refComposite[2];
+ WDF_TRI_STATE ExcludeD3Cold;
+} CODECMC_DEVICE_CONTEXT, *PCODECMC_DEVICE_CONTEXT;
+
+//
+// Multicircuit codec driver prototypes.
+//
+EVT_WDF_DRIVER_DEVICE_ADD CodecMc_EvtBusDeviceAdd;
+DRIVER_INITIALIZE DriverEntry;
+EVT_WDF_DRIVER_UNLOAD AudioCodecMcDriverUnload;
+
+//
+// Multicircuit codec device callbacks.
+//
+EVT_WDF_DEVICE_PREPARE_HARDWARE CodecMc_EvtDevicePrepareHardware;
+EVT_WDF_DEVICE_RELEASE_HARDWARE CodecMc_EvtDeviceReleaseHardware;
+EVT_WDF_DEVICE_D0_ENTRY CodecMc_EvtDeviceD0Entry;
+EVT_WDF_DEVICE_D0_EXIT CodecMc_EvtDeviceD0Exit;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP CodecMc_EvtDeviceContextCleanup;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(CODECMC_DEVICE_CONTEXT, GetCodecMcDeviceContext)
+
+//
+// Composite type definition used in multicircuit codec.
+//
+typedef enum
+{
+ CompositeType_RENDER,
+ CompositeType_CAPTURE
+} CompositeType;
+
+//
+// Define DSPMC (multicircuit dsp) device context.
+//
+typedef struct _DSPMC_DEVICE_CONTEXT
+{
+ ACXCIRCUIT Render;
+ ACXCIRCUIT Capture;
+ WDF_TRI_STATE ExcludeD3Cold;
+} DSPMC_DEVICE_CONTEXT, *PDSPMC_DEVICE_CONTEXT;
+
+//
+// Multicircuit dsp driver prototypes.
+//
+EVT_WDF_DRIVER_DEVICE_ADD DspMc_EvtBusDeviceAdd;
+EVT_WDF_DRIVER_UNLOAD AudioDspMcDriverUnload;
+
+//
+// Multicircuit dsp device callbacks.
+//
+EVT_WDF_DEVICE_PREPARE_HARDWARE DspMc_EvtDevicePrepareHardware;
+EVT_WDF_DEVICE_RELEASE_HARDWARE DspMc_EvtDeviceReleaseHardware;
+EVT_WDF_DEVICE_D0_ENTRY DspMc_EvtDeviceD0Entry;
+EVT_WDF_DEVICE_D0_EXIT DspMc_EvtDeviceD0Exit;
+EVT_WDF_DEVICE_CONTEXT_CLEANUP DspMc_EvtDeviceContextCleanup;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DSPMC_DEVICE_CONTEXT, GetDspMcDeviceContext)
+
+// Factory circuit callbacks for multicircuit dsp.
+EVT_ACX_FACTORY_CIRCUIT_CREATE_CIRCUITDEVICE RenderMCDsp_EvtAcxFactoryCircuitCreateCircuitDevice;
+EVT_ACX_FACTORY_CIRCUIT_CREATE_CIRCUIT RenderMCDsp_EvtAcxFactoryCircuitCreateCircuit;
+
+EVT_ACX_FACTORY_CIRCUIT_CREATE_CIRCUITDEVICE CaptureMCDsp_EvtAcxFactoryCircuitCreateCircuitDevice;
+EVT_ACX_FACTORY_CIRCUIT_CREATE_CIRCUIT CaptureMCDsp_EvtAcxFactoryCircuitCreateCircuit;
+
+
+/* make internal prototypes usable from C++ */
+#ifdef __cplusplus
+}
+#endif
+
+// Used to store the registry settings path for the driver:
+extern UNICODE_STRING g_RegistryPath;
+
+// Driver tag name:
+extern ULONG DeviceDriverTag;
+
+// The idle timeout in msec for power policy structure:
+extern ULONG IdleTimeoutMsec;
+
+#define DECLARE_CONST_ACXOBJECTBAG_MULTICIRCUIT_SAMPLE_PROPERTY_NAME(name) \
+ DECLARE_CONST_UNICODE_STRING(name, L"mc_" #name)
+
+__drv_requiresIRQL(PASSIVE_LEVEL)
+PAGED_CODE_SEG
+NTSTATUS
+CopyRegistrySettingsPath(
+ _In_ PUNICODE_STRING RegistryPath
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+Codec_SetPowerPolicy(
+ _In_ WDFDEVICE Device
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+Dsp_SetPowerPolicy(
+ _In_ WDFDEVICE Device
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecMc_SetPowerPolicy(
+ _In_ WDFDEVICE Device
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+DspMc_SetPowerPolicy(
+ _In_ WDFDEVICE Device
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecR_AddStaticRender(
+ _In_ WDFDEVICE Device,
+ _In_ const GUID * ComponentGuid,
+ _In_ const UNICODE_STRING * CircuitName
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecC_AddStaticCapture(
+ _In_ WDFDEVICE Device,
+ _In_ const GUID * ComponentGuid,
+ _In_ const GUID * MicCustomName,
+ _In_ const UNICODE_STRING * CircuitName
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+Speaker_AddStaticRender(
+ _In_ WDFDEVICE Device,
+ _In_ GUID ComponentGuid,
+ _In_ UNICODE_STRING CircuitName,
+ _In_ BOOLEAN IsHeadphones
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+MicArray_AddStaticCapture(
+ _In_ WDFDEVICE Device,
+ _In_ GUID ComponentGuid,
+ _In_ GUID MicCustomName,
+ _In_ UNICODE_STRING CircuitName
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+MicrophoneHp_AddStaticCapture(
+ _In_ WDFDEVICE Device,
+ _In_ GUID ComponentGuid,
+ _In_ GUID MicCustomName,
+ _In_ UNICODE_STRING CircuitName
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+SpeakerHp_AddStaticRender(
+ _In_ WDFDEVICE Device,
+ _In_ GUID ComponentGuid,
+ _In_ UNICODE_STRING CircuitName
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+HDMI_AddStaticRender(
+ _In_ WDFDEVICE Device,
+ _In_ GUID ComponentGuid,
+ _In_ UNICODE_STRING CircuitName
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+RenderMC_AddStaticRender(
+ _In_ WDFDEVICE Device,
+ _In_ const GUID * ComponentGuid,
+ _In_ const UNICODE_STRING * CircuitName,
+ _In_ const UNICODE_STRING * Uri
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+CaptureMC_AddStaticCapture(
+ _In_ WDFDEVICE Device,
+ _In_ const GUID * ComponentGuid,
+ _In_ const GUID * MicCustomName,
+ _In_ const UNICODE_STRING * CircuitName,
+ _In_ const UNICODE_STRING * Uri
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecC_CircuitCleanup(
+ _In_ ACXCIRCUIT Device
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+MicArray_CircuitCleanup(
+ _In_ ACXCIRCUIT Device
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+CaptureMCDsp_CircuitCleanup(
+ _In_ ACXCIRCUIT Device
+);
+
+PAGED_CODE_SEG
+NTSTATUS
+DspMc_AddFactoryCircuit(
+ _In_ WDFDRIVER Driver,
+ _In_ WDFDEVICE Device
+);
+
+NTSTATUS
+CodecMc_AddRenderComposites(_In_ WDFDEVICE Device);
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecMc_AddCaptureComposites(_In_ WDFDEVICE Device);
+
+PAGED_CODE_SEG
+NTSTATUS
+CodecMc_AddComposites(_In_ WDFDEVICE Device, _In_ CompositeType compositeType);
+
+NTSTATUS
+CodecMc_RemoveComposites(_In_ WDFDEVICE Device);
diff --git a/audio/Acx/Samples/Shared/Trace.h b/audio/Acx/Samples/Shared/Trace.h
new file mode 100644
index 00000000..01478bfc
--- /dev/null
+++ b/audio/Acx/Samples/Shared/Trace.h
@@ -0,0 +1,33 @@
+/*++
+
+Copyright (c) Microsoft Corporation
+
+Module Name:
+
+Trace.h
+
+--*/
+
+#pragma once
+
+#include <WppRecorder.h>
+#include <evntrace.h> // For TRACE_LEVEL definitions
+
+#define WPP_TOTAL_BUFFER_SIZE (PAGE_SIZE)
+#define WPP_ERROR_PARTITION_SIZE (WPP_TOTAL_BUFFER_SIZE/4)
+
+// {1945C417-844C-48C6-9BCE-3AA2113A2B69}
+#define WPP_CONTROL_GUIDS \
+WPP_DEFINE_CONTROL_GUID(DrvLogger,(1945C417,844C,48C6,9BCE,3AA2113A2B69), \
+ WPP_DEFINE_BIT(FLAG_DEVICE_ALL) /* bit 0 = 0x00000001 */ \
+ WPP_DEFINE_BIT(FLAG_FUNCTION) /* bit 1 = 0x00000002 */ \
+ WPP_DEFINE_BIT(FLAG_INFO) /* bit 2 = 0x00000004 */ \
+ WPP_DEFINE_BIT(FLAG_PNP) /* bit 3 = 0x00000008 */ \
+ WPP_DEFINE_BIT(FLAG_POWER) /* bit 4 = 0x00000010 */ \
+ WPP_DEFINE_BIT(FLAG_STREAM) /* bit 5 = 0x00000020 */ \
+ WPP_DEFINE_BIT(FLAG_INIT) /* bit 6 = 0x00000040 */ \
+ WPP_DEFINE_BIT(FLAG_DDI) /* bit 7 = 0x00000080 */ \
+ WPP_DEFINE_BIT(FLAG_GENERIC) /* bit 8 = 0x00000100 */ \
+ )
+
+#include "trace_macros.h"
diff --git a/audio/simpleaudiosample/Package/package.VcxProj b/audio/simpleaudiosample/Package/package.VcxProj
index a70e4820..7921c8d3 100644
--- a/audio/simpleaudiosample/Package/package.VcxProj
+++ b/audio/simpleaudiosample/Package/package.VcxProj
@@ -1,22 +1,14 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
@@ -44,14 +36,6 @@
<SampleGuid>{E9D167E6-E633-4284-8F02-FF86DF3B6D7F}</SampleGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>true</UseDebugLibraries>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>false</UseDebugLibraries>
- </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
@@ -92,16 +76,6 @@
<VerifyDrivers />
<VerifyFlags>133563</VerifyFlags>
</PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
@@ -125,4 +99,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project>
+</Project> \ No newline at end of file
diff --git a/audio/simpleaudiosample/SimpleAudioSample.sln b/audio/simpleaudiosample/SimpleAudioSample.sln
index 407838ba..8fc1ef17 100644
--- a/audio/simpleaudiosample/SimpleAudioSample.sln
+++ b/audio/simpleaudiosample/SimpleAudioSample.sln
@@ -29,71 +29,49 @@ EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
- Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|ARM64 = Release|ARM64
- Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|ARM64.ActiveCfg = Debug|ARM64
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|ARM64.Build.0 = Debug|ARM64
- {830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|Win32.ActiveCfg = Debug|Win32
- {830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|Win32.Build.0 = Debug|Win32
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|x64.ActiveCfg = Debug|x64
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|x64.Build.0 = Debug|x64
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|ARM64.ActiveCfg = Release|ARM64
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|ARM64.Build.0 = Release|ARM64
- {830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|Win32.ActiveCfg = Release|Win32
- {830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|Win32.Build.0 = Release|Win32
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|x64.ActiveCfg = Release|x64
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|x64.Build.0 = Release|x64
{771312CF-E5A2-4676-8142-86CEBDF99E2B}.Debug|ARM64.ActiveCfg = Debug|ARM64
{771312CF-E5A2-4676-8142-86CEBDF99E2B}.Debug|ARM64.Build.0 = Debug|ARM64
- {771312CF-E5A2-4676-8142-86CEBDF99E2B}.Debug|Win32.ActiveCfg = Debug|Win32
- {771312CF-E5A2-4676-8142-86CEBDF99E2B}.Debug|Win32.Build.0 = Debug|Win32
{771312CF-E5A2-4676-8142-86CEBDF99E2B}.Debug|x64.ActiveCfg = Debug|x64
{771312CF-E5A2-4676-8142-86CEBDF99E2B}.Debug|x64.Build.0 = Debug|x64
{771312CF-E5A2-4676-8142-86CEBDF99E2B}.Release|ARM64.ActiveCfg = Release|ARM64
{771312CF-E5A2-4676-8142-86CEBDF99E2B}.Release|ARM64.Build.0 = Release|ARM64
- {771312CF-E5A2-4676-8142-86CEBDF99E2B}.Release|Win32.ActiveCfg = Release|Win32
- {771312CF-E5A2-4676-8142-86CEBDF99E2B}.Release|Win32.Build.0 = Release|Win32
{771312CF-E5A2-4676-8142-86CEBDF99E2B}.Release|x64.ActiveCfg = Release|x64
{771312CF-E5A2-4676-8142-86CEBDF99E2B}.Release|x64.Build.0 = Release|x64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|ARM64.ActiveCfg = Debug|ARM64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|ARM64.Build.0 = Debug|ARM64
- {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|Win32.ActiveCfg = Debug|Win32
- {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|Win32.Build.0 = Debug|Win32
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|x64.ActiveCfg = Debug|x64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|x64.Build.0 = Debug|x64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|ARM64.ActiveCfg = Release|ARM64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|ARM64.Build.0 = Release|ARM64
- {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|Win32.ActiveCfg = Release|Win32
- {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|Win32.Build.0 = Release|Win32
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|x64.ActiveCfg = Release|x64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|x64.Build.0 = Release|x64
{4B664BA5-057A-41B8-B365-2C99065C4DFA}.Debug|ARM64.ActiveCfg = Debug|ARM64
{4B664BA5-057A-41B8-B365-2C99065C4DFA}.Debug|ARM64.Build.0 = Debug|ARM64
- {4B664BA5-057A-41B8-B365-2C99065C4DFA}.Debug|Win32.ActiveCfg = Debug|Win32
- {4B664BA5-057A-41B8-B365-2C99065C4DFA}.Debug|Win32.Build.0 = Debug|Win32
{4B664BA5-057A-41B8-B365-2C99065C4DFA}.Debug|x64.ActiveCfg = Debug|x64
{4B664BA5-057A-41B8-B365-2C99065C4DFA}.Debug|x64.Build.0 = Debug|x64
{4B664BA5-057A-41B8-B365-2C99065C4DFA}.Release|ARM64.ActiveCfg = Release|ARM64
{4B664BA5-057A-41B8-B365-2C99065C4DFA}.Release|ARM64.Build.0 = Release|ARM64
- {4B664BA5-057A-41B8-B365-2C99065C4DFA}.Release|Win32.ActiveCfg = Release|Win32
- {4B664BA5-057A-41B8-B365-2C99065C4DFA}.Release|Win32.Build.0 = Release|Win32
{4B664BA5-057A-41B8-B365-2C99065C4DFA}.Release|x64.ActiveCfg = Release|x64
{4B664BA5-057A-41B8-B365-2C99065C4DFA}.Release|x64.Build.0 = Release|x64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|ARM64.ActiveCfg = Debug|ARM64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|ARM64.Build.0 = Debug|ARM64
- {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|Win32.ActiveCfg = Debug|Win32
- {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|Win32.Build.0 = Debug|Win32
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|x64.ActiveCfg = Debug|x64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|x64.Build.0 = Debug|x64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|ARM64.ActiveCfg = Release|ARM64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|ARM64.Build.0 = Release|ARM64
- {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|Win32.ActiveCfg = Release|Win32
- {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|Win32.Build.0 = Release|Win32
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|x64.ActiveCfg = Release|x64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|x64.Build.0 = Release|x64
EndGlobalSection
diff --git a/audio/simpleaudiosample/Source/Filters/Filters.vcxproj b/audio/simpleaudiosample/Source/Filters/Filters.vcxproj
index 82fd07dc..1b343b45 100644
--- a/audio/simpleaudiosample/Source/Filters/Filters.vcxproj
+++ b/audio/simpleaudiosample/Source/Filters/Filters.vcxproj
@@ -1,22 +1,14 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
@@ -31,14 +23,14 @@
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <Platform Condition="'$(Platform)' == ''">x64</Platform>
<SampleGuid>{F51739CE-5253-42B5-9191-57F28B5842C6}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -46,7 +38,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -54,7 +46,7 @@
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -62,23 +54,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType>KMDF</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>StaticLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType>KMDF</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>StaticLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -99,12 +75,6 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
<ItemGroup Label="WrappedTaskItems" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>Filters</TargetName>
@@ -118,12 +88,6 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetName>Filters</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetName>Filters</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetName>Filters</TargetName>
- </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ResourceCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
@@ -216,52 +180,6 @@
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc;.</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
- <ExceptionHandling>
- </ExceptionHandling>
- <DisableSpecificWarnings>4595;%(DisableSpecificWarnings)</DisableSpecificWarnings>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_</PreprocessorDefinitions>
- </Midl>
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc;.</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
- <ExceptionHandling>
- </ExceptionHandling>
- <DisableSpecificWarnings>4595;%(DisableSpecificWarnings)</DisableSpecificWarnings>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_</PreprocessorDefinitions>
- </Midl>
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="micarraytopo.cpp" />
<ClCompile Include="speakertopo.cpp" />
@@ -279,4 +197,4 @@
<ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/audio/simpleaudiosample/Source/Inc/Inc.vcxproj b/audio/simpleaudiosample/Source/Inc/Inc.vcxproj
index ab768d84..46846d71 100644
--- a/audio/simpleaudiosample/Source/Inc/Inc.vcxproj
+++ b/audio/simpleaudiosample/Source/Inc/Inc.vcxproj
@@ -1,22 +1,14 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
@@ -31,14 +23,14 @@
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <Platform Condition="'$(Platform)' == ''">x64</Platform>
<SampleGuid>{F51739CE-5253-42B5-9191-57F28B5842C6}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -46,7 +38,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -54,7 +46,7 @@
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -62,23 +54,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType>KMDF</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>StaticLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType>KMDF</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>StaticLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -99,12 +75,6 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
<ItemGroup Label="WrappedTaskItems" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>Inc</TargetName>
@@ -118,12 +88,6 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetName>Inc</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetName>Inc</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetName>Inc</TargetName>
- </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ResourceCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
@@ -204,46 +168,6 @@
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
- <ExceptionHandling>
- </ExceptionHandling>
- <DisableSpecificWarnings>4595;%(DisableSpecificWarnings)</DisableSpecificWarnings>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_</PreprocessorDefinitions>
- </Midl>
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
- <ExceptionHandling>
- </ExceptionHandling>
- <DisableSpecificWarnings>4595;%(DisableSpecificWarnings)</DisableSpecificWarnings>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_</PreprocessorDefinitions>
- </Midl>
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
<ItemGroup>
<Inf Exclude="@(Inf)" Include="*.inf" />
<FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
@@ -257,4 +181,4 @@
<ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/audio/simpleaudiosample/Source/Main/Main.vcxproj b/audio/simpleaudiosample/Source/Main/Main.vcxproj
index a68d0242..b569da4d 100644
--- a/audio/simpleaudiosample/Source/Main/Main.vcxproj
+++ b/audio/simpleaudiosample/Source/Main/Main.vcxproj
@@ -1,22 +1,14 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
@@ -33,14 +25,14 @@
<SupportsPackaging>false</SupportsPackaging>
<RequiresPackageProject>true</RequiresPackageProject>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <Platform Condition="'$(Platform)' == ''">x64</Platform>
<SampleGuid>{2A9A946E-F017-4E0D-BF75-AD81E7E97D64}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
@@ -48,7 +40,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
@@ -56,7 +48,7 @@
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
@@ -64,23 +56,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType>KMDF</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>Driver</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType>KMDF</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>Driver</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
@@ -101,12 +77,6 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
<ItemGroup Label="WrappedTaskItems" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
@@ -208,56 +178,6 @@
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\portcls.lib;$(DDK_LIB_PATH)\stdunk.lib;$(DDK_LIB_PATH)\libcntpr.lib</AdditionalDependencies>
- </Link>
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
- </Midl>
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\portcls.lib;$(DDK_LIB_PATH)\stdunk.lib;$(DDK_LIB_PATH)\libcntpr.lib</AdditionalDependencies>
- </Link>
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
- </Midl>
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>SimpleAudioSample</TargetName>
</PropertyGroup>
@@ -270,12 +190,6 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetName>SimpleAudioSample</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetName>SimpleAudioSample</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetName>SimpleAudioSample</TargetName>
- </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
<AdditionalDependencies>%(AdditionalDependencies);.\..\Utilities\$(IntDir)\Utilities.lib</AdditionalDependencies>
@@ -396,62 +310,6 @@
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);.\..\Utilities\$(IntDir)\Utilities.lib</AdditionalDependencies>
- </Link>
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);.\..\Filters\$(IntDir)\Filters.lib</AdditionalDependencies>
- </Link>
- <ClCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;_USE_IPortClsRuntimePower;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Utilities;.</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Filters;.</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc;.</AdditionalIncludeDirectories>
- <ExceptionHandling>
- </ExceptionHandling>
- </ClCompile>
- <Midl>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;_USE_IPortClsRuntimePower</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Utilities</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Filters</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc</AdditionalIncludeDirectories>
- </Midl>
- <ResourceCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;_USE_IPortClsRuntimePower</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Utilities</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Filters</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc</AdditionalIncludeDirectories>
- </ResourceCompile>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);.\..\Utilities\$(IntDir)\Utilities.lib</AdditionalDependencies>
- </Link>
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);.\..\Filters\$(IntDir)\Filters.lib</AdditionalDependencies>
- </Link>
- <ClCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;_USE_IPortClsRuntimePower;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Utilities;.</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Filters;.</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc;.</AdditionalIncludeDirectories>
- <ExceptionHandling>
- </ExceptionHandling>
- </ClCompile>
- <Midl>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;_USE_IPortClsRuntimePower</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Utilities</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Filters</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc</AdditionalIncludeDirectories>
- </Midl>
- <ResourceCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;_USE_IPortClsRuntimePower</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Utilities</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Filters</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc</AdditionalIncludeDirectories>
- </ResourceCompile>
- </ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="adapter.cpp" />
<ClCompile Include="basetopo.cpp" />
@@ -475,4 +333,4 @@
<ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/audio/simpleaudiosample/Source/Main/SimpleAudioSample.inx b/audio/simpleaudiosample/Source/Main/SimpleAudioSample.inx
index a63bb0ba..d0835f1f 100644
--- a/audio/simpleaudiosample/Source/Main/SimpleAudioSample.inx
+++ b/audio/simpleaudiosample/Source/Main/SimpleAudioSample.inx
Binary files differ
diff --git a/audio/simpleaudiosample/Source/Main/adapter.cpp b/audio/simpleaudiosample/Source/Main/adapter.cpp
index 105f7fde..a66ee5a2 100644
--- a/audio/simpleaudiosample/Source/Main/adapter.cpp
+++ b/audio/simpleaudiosample/Source/Main/adapter.cpp
@@ -45,10 +45,10 @@ _Dispatch_type_(IRP_MJ_PNP)
DRIVER_DISPATCH PnpHandler;
//
-// Rendering streams are saved to a file by default. Use the registry value
-// DoNotCreateDataFiles (DWORD) > 0 to override this default.
+// Rendering streams are not saved to a file by default. Use the registry value
+// DoNotCreateDataFiles (DWORD) = 0 to override this default.
//
-DWORD g_DoNotCreateDataFiles = 0; // default is off.
+DWORD g_DoNotCreateDataFiles = 1; // default is off.
DWORD g_DisableToneGenerator = 0; // default is to generate tones.
UNICODE_STRING g_RegistryPath; // This is used to store the registry settings path for the driver
@@ -59,6 +59,8 @@ UNICODE_STRING g_RegistryPath; // This is used to store the registry settin
#pragma code_seg("PAGE")
void ReleaseRegistryStringBuffer()
{
+ PAGED_CODE();
+
if (g_RegistryPath.Buffer != NULL)
{
ExFreePool(g_RegistryPath.Buffer);
@@ -192,7 +194,8 @@ Returns:
{
NTSTATUS ntStatus;
- UNICODE_STRING parametersPath;
+ PDRIVER_OBJECT DriverObject;
+ HANDLE DriverKey;
RTL_QUERY_REGISTRY_TABLE paramTable[] = {
// QueryRoutine Flags Name EntryContext DefaultType DefaultData DefaultLength
{ NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"DoNotCreateDataFiles", &g_DoNotCreateDataFiles, (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD, &g_DoNotCreateDataFiles, sizeof(ULONG)},
@@ -202,29 +205,27 @@ Returns:
DPF(D_TERSE, ("[GetRegistrySettings]"));
- PAGED_CODE();
-
- RtlInitUnicodeString(&parametersPath, NULL);
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(RegistryPath);
- parametersPath.MaximumLength =
- RegistryPath->Length + sizeof(L"\\Parameters") + sizeof(WCHAR);
+ DriverObject = WdfDriverWdmGetDriverObject(WdfGetDriver());
+ DriverKey = NULL;
+ ntStatus = IoOpenDriverRegistryKey(DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &DriverKey);
- parametersPath.Buffer = (PWCH) ExAllocatePool2(POOL_FLAG_PAGED, parametersPath.MaximumLength, MINADAPTER_POOLTAG);
- if (parametersPath.Buffer == NULL)
+ if (!NT_SUCCESS(ntStatus))
{
- return STATUS_INSUFFICIENT_RESOURCES;
+ return ntStatus;
}
- RtlAppendUnicodeToString(&parametersPath, RegistryPath->Buffer);
- RtlAppendUnicodeToString(&parametersPath, L"\\Parameters");
-
- ntStatus = RtlQueryRegistryValues(
- RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
- parametersPath.Buffer,
- &paramTable[0],
- NULL,
- NULL
- );
+ ntStatus = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
+ (PCWSTR) DriverKey,
+ &paramTable[0],
+ NULL,
+ NULL);
if (!NT_SUCCESS(ntStatus))
{
@@ -240,10 +241,10 @@ Returns:
DPF(D_VERBOSE, ("DoNotCreateDataFiles: %u", g_DoNotCreateDataFiles));
DPF(D_VERBOSE, ("DisableToneGenerator: %u", g_DisableToneGenerator));
- //
- // Cleanup.
- //
- ExFreePool(parametersPath.Buffer);
+ if (DriverKey)
+ {
+ ZwClose(DriverKey);
+ }
return STATUS_SUCCESS;
}
@@ -292,15 +293,6 @@ Return Value:
ntStatus,
DPF(D_ERROR, ("Registry path copy error 0x%x", ntStatus)),
Done);
-
- //
- // Get registry configuration.
- //
- ntStatus = GetRegistrySettings(RegistryPathName);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Registry Configuration error 0x%x", ntStatus)),
- Done);
WDF_DRIVER_CONFIG_INIT(&config, WDF_NO_EVENT_CALLBACK);
//
@@ -324,6 +316,15 @@ Return Value:
Done);
//
+ // Get registry configuration.
+ //
+ ntStatus = GetRegistrySettings(RegistryPathName);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Registry Configuration error 0x%x", ntStatus)),
+ Done);
+
+ //
// Tell the class driver to initialize the driver.
//
ntStatus = PcInitializeAdapterDriver(DriverObject,
diff --git a/audio/simpleaudiosample/Source/Main/common.cpp b/audio/simpleaudiosample/Source/Main/common.cpp
index 8843d3a4..457bdb17 100644
--- a/audio/simpleaudiosample/Source/Main/common.cpp
+++ b/audio/simpleaudiosample/Source/Main/common.cpp
@@ -2547,6 +2547,7 @@ Exit:
return ntStatus;
}
+#pragma code_seg("PAGE")
NTSTATUS
CopyRegistryKey(HANDLE _hSourceKey, HANDLE _hDestinationKey, BOOL _bOverwrite = FALSE)
/*++
@@ -2686,7 +2687,7 @@ Exit:
return ntStatus;
}
-
+#pragma code_seg("PAGE")
NTSTATUS CAdapterCommon::MigrateDeviceInterfaceTemplateParameters
(
_In_ PUNICODE_STRING SymbolicLinkName,
@@ -2729,6 +2730,8 @@ Return Value:
UNICODE_STRING TemplateSymbolicLinkName;
UNICODE_STRING referenceString;
+ PAGED_CODE();
+
RtlInitUnicodeString(&TemplateSymbolicLinkName, NULL);
RtlInitUnicodeString(&referenceString, TemplateReferenceString);
diff --git a/audio/simpleaudiosample/Source/Main/minwavertstream.cpp b/audio/simpleaudiosample/Source/Main/minwavertstream.cpp
index 27289a0e..c189c939 100644
--- a/audio/simpleaudiosample/Source/Main/minwavertstream.cpp
+++ b/audio/simpleaudiosample/Source/Main/minwavertstream.cpp
@@ -108,8 +108,8 @@ NTSTATUS CMiniportWaveRTStream::ReadRegistrySettings()
PAGED_CODE();
NTSTATUS ntStatus;
- UNICODE_STRING parametersPath;
-
+ PDRIVER_OBJECT DriverObject;
+ HANDLE DriverKey;
RTL_QUERY_REGISTRY_TABLE paramTable[] = {
// QueryRoutine Flags Name EntryContext DefaultType DefaultData DefaultLength
{ NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"HostCaptureToneFrequency", &m_ulHostCaptureToneFrequency, (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD, &m_ulHostCaptureToneFrequency, sizeof(DWORD) },
@@ -119,30 +119,37 @@ NTSTATUS CMiniportWaveRTStream::ReadRegistrySettings()
{ NULL, 0, NULL, NULL, 0, NULL, 0 }
};
- RtlInitUnicodeString(&parametersPath, NULL);
-
- // The sizeof(WCHAR) is added to the maximum length, for allowing a space for null termination of the string.
- parametersPath.MaximumLength =
- g_RegistryPath.Length + sizeof(L"\\Parameters") + sizeof(WCHAR);
+ DriverObject = WdfDriverWdmGetDriverObject(WdfGetDriver());
+ DriverKey = NULL;
+ ntStatus = IoOpenDriverRegistryKey(DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &DriverKey);
- parametersPath.Buffer = (PWCH)ExAllocatePool2(POOL_FLAG_PAGED, parametersPath.MaximumLength, MINWAVERT_POOLTAG);
- if (parametersPath.Buffer == NULL)
+ if (!NT_SUCCESS(ntStatus))
{
- return STATUS_INSUFFICIENT_RESOURCES;
+ return ntStatus;
}
- RtlAppendUnicodeToString(&parametersPath, g_RegistryPath.Buffer);
- RtlAppendUnicodeToString(&parametersPath, L"\\Parameters");
+ ntStatus = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
+ (PCWSTR) DriverKey,
+ &paramTable[0],
+ NULL,
+ NULL);
- ntStatus = RtlQueryRegistryValues(
- RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
- parametersPath.Buffer,
- &paramTable[0],
- NULL,
- NULL
- );
+ if (!NT_SUCCESS(ntStatus))
+ {
+ DPF(D_VERBOSE, ("RtlQueryRegistryValues failed, using default values, 0x%x", ntStatus));
+ //
+ // Don't return error because we will operate with default values.
+ //
+ }
- ExFreePool(parametersPath.Buffer);
+ if (DriverKey)
+ {
+ ZwClose(DriverKey);
+ }
return ntStatus;
}
diff --git a/audio/simpleaudiosample/Source/Utilities/Utilities.vcxproj b/audio/simpleaudiosample/Source/Utilities/Utilities.vcxproj
index 0a71bf42..5efe1068 100644
--- a/audio/simpleaudiosample/Source/Utilities/Utilities.vcxproj
+++ b/audio/simpleaudiosample/Source/Utilities/Utilities.vcxproj
@@ -1,22 +1,14 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
@@ -31,14 +23,14 @@
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <Platform Condition="'$(Platform)' == ''">x64</Platform>
<SampleGuid>{F51739CE-5253-42B5-9191-57F28B5842C6}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -46,7 +38,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -54,7 +46,7 @@
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -62,23 +54,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType>KMDF</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>StaticLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType>KMDF</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>StaticLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -99,12 +75,6 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
<ItemGroup Label="WrappedTaskItems" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>Utilities</TargetName>
@@ -118,12 +88,6 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetName>Utilities</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetName>Utilities</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetName>Utilities</TargetName>
- </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ResourceCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
@@ -216,52 +180,6 @@
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc;.</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
- <ExceptionHandling>
- </ExceptionHandling>
- <DisableSpecificWarnings>4595;%(DisableSpecificWarnings)</DisableSpecificWarnings>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_</PreprocessorDefinitions>
- </Midl>
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc;.</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
- <ExceptionHandling>
- </ExceptionHandling>
- <DisableSpecificWarnings>4595;%(DisableSpecificWarnings)</DisableSpecificWarnings>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\Inc</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_</PreprocessorDefinitions>
- </Midl>
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="hw.cpp" />
<ClCompile Include="kshelper.cpp" />
@@ -281,4 +199,4 @@
<ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/audio/simpleaudiosample/Source/Utilities/savedata.cpp b/audio/simpleaudiosample/Source/Utilities/savedata.cpp
index 7b2a11e9..02c3f602 100644
--- a/audio/simpleaudiosample/Source/Utilities/savedata.cpp
+++ b/audio/simpleaudiosample/Source/Utilities/savedata.cpp
@@ -44,8 +44,9 @@ Abstract:
#define DEFAULT_FRAME_SIZE PAGE_SIZE * 4
#define DEFAULT_BUFFER_SIZE DEFAULT_FRAME_SIZE * DEFAULT_FRAME_COUNT
-#define DEFAULT_FILE_NAME L"\\DosDevices\\C:\\STREAM"
-#define OSDATA_FILE_NAME L"\\DosDevices\\O:\\STREAM"
+#define DEFAULT_FILE_FOLDER1 L"\\DriverData\\Audio_Samples"
+#define DEFAULT_FILE_FOLDER2 L"\\DriverData\\Audio_Samples\\SimpleAudioSample"
+#define DEFAULT_FILE_NAME L"\\DriverData\\Audio_Samples\\SimpleAudioSample\\STREAM"
#define OFFLOAD_FILE_NAME L"OFFLOAD"
#define HOST_FILE_NAME L"HOST"
@@ -444,59 +445,86 @@ CSaveData::Initialize
{
PAGED_CODE();
- NTSTATUS ntStatus = STATUS_SUCCESS;
- WCHAR szTemp[MAX_PATH];
- size_t cLen;
- OBJECT_ATTRIBUTES objectAttributes;
- UNICODE_STRING osDataVolumeString;
- HANDLE osDataFileHandle = NULL;
- IO_STATUS_BLOCK ioStatusBlock;
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ WCHAR szTemp[MAX_PATH];
+ size_t cLen = 0;
+ IO_STATUS_BLOCK ioStatusBlock = {0};
+ HANDLE fileHandle;
+ OBJECT_ATTRIBUTES objectAttributes;
+ UNICODE_STRING fileName;
DPF_ENTER(("[CSaveData::Initialize]"));
m_ulStreamId++;
- // Probe if OSData volume exists.
- //
- RtlStringCchPrintfW(szTemp, MAX_PATH, L"%s_probe.txt", OSDATA_FILE_NAME);
- RtlInitUnicodeString(&osDataVolumeString, szTemp);
- InitializeObjectAttributes
- (
- &objectAttributes,
- &osDataVolumeString,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL
- );
+ RtlInitUnicodeString(&fileName, DEFAULT_FILE_FOLDER1);
+ InitializeObjectAttributes(
+ &objectAttributes,
+ &fileName,
+ OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
- ntStatus =
- ZwCreateFile
- (
- &osDataFileHandle,
- GENERIC_WRITE | SYNCHRONIZE,
+ // Create the folder.
+ ntStatus = ZwCreateFile(
+ &fileHandle,
+ 0,
&objectAttributes,
&ioStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
- FILE_OVERWRITE_IF,
- FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
+ FILE_OPEN_IF,
+ FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
- 0
- );
+ 0);
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ ZwClose(fileHandle);
+ fileHandle = NULL;
+
+ RtlInitUnicodeString(&fileName, DEFAULT_FILE_FOLDER2);
+ InitializeObjectAttributes(
+ &objectAttributes,
+ &fileName,
+ OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ // Create the folder.
+ ntStatus = ZwCreateFile(
+ &fileHandle,
+ 0,
+ &objectAttributes,
+ &ioStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ 0,
+ FILE_OPEN_IF,
+ FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
+ NULL,
+ 0);
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ ZwClose(fileHandle);
+ fileHandle = NULL;
+ }
+ }
+
if (NT_SUCCESS(ntStatus))
{
- ZwClose(osDataFileHandle);
+ // Allocate data file name.
+ //
+ RtlStringCchPrintfW(szTemp, MAX_PATH, L"%s_%s_%d.wav", DEFAULT_FILE_NAME, HOST_FILE_NAME, m_ulStreamId);
+ m_FileName.Length = 0;
+ ntStatus = RtlStringCchLengthW (szTemp, sizeof(szTemp)/sizeof(szTemp[0]), &cLen);
}
- // Allocate data file name.
- //
- RtlStringCchPrintfW(szTemp, MAX_PATH, L"%s_%s_%d.wav", NT_SUCCESS(ntStatus) ? OSDATA_FILE_NAME : DEFAULT_FILE_NAME, HOST_FILE_NAME, m_ulStreamId);
- m_FileName.Length = 0;
- ntStatus = RtlStringCchLengthW (szTemp, sizeof(szTemp)/sizeof(szTemp[0]), &cLen);
if (NT_SUCCESS(ntStatus))
{
- m_FileName.MaximumLength = (USHORT)((cLen * sizeof(WCHAR)) + sizeof(WCHAR));//convert to wchar and add room for NULL
+ m_FileName.MaximumLength = (USHORT)((cLen * sizeof(WCHAR)) + sizeof(WCHAR));//convert to wchar and add room for NULL
m_FileName.Buffer = (PWSTR)
ExAllocatePool2
(
@@ -574,7 +602,7 @@ CSaveData::Initialize
(
&m_objectAttributes,
&m_FileName,
- OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL
);
diff --git a/audio/sysvad/APO/AecApo/AecApo.h b/audio/sysvad/APO/AecApo/AecApo.h
index a62b69ce..7c96314d 100644
--- a/audio/sysvad/APO/AecApo/AecApo.h
+++ b/audio/sysvad/APO/AecApo/AecApo.h
@@ -99,13 +99,8 @@ public:
) override;
// IAudioSystemEffects3
- STDMETHODIMP GetControllableSystemEffectsList(_Outptr_result_buffer_maybenull_(*numEffects) AUDIO_SYSTEMEFFECT** effects, _Out_ UINT* numEffects, _In_opt_ HANDLE event) override
- {
- UNREFERENCED_PARAMETER(effects);
- UNREFERENCED_PARAMETER(numEffects);
- UNREFERENCED_PARAMETER(event);
- return S_OK;
- }
+ STDMETHOD(GetControllableSystemEffectsList)(
+ _Outptr_result_buffer_maybenull_(*numEffects) AUDIO_SYSTEMEFFECT** effects, _Out_ UINT* numEffects, _In_opt_ HANDLE event) override;
STDMETHODIMP SetAudioSystemEffectState(GUID, AUDIO_SYSTEMEFFECT_STATE) override {return S_OK;}
diff --git a/audio/sysvad/APO/AecApo/AecApo.vcxproj b/audio/sysvad/APO/AecApo/AecApo.vcxproj
index f40ce919..7de1a862 100644
--- a/audio/sysvad/APO/AecApo/AecApo.vcxproj
+++ b/audio/sysvad/APO/AecApo/AecApo.vcxproj
@@ -1,22 +1,14 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
@@ -32,14 +24,14 @@
<SupportsPackaging>false</SupportsPackaging>
<RequiresPackageProject>true</RequiresPackageProject>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <Platform Condition="'$(Platform)' == ''">x64</Platform>
<SampleGuid>{D5CCDCB1-348E-414E-BB0F-33C773760034}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
@@ -48,7 +40,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
@@ -57,7 +49,7 @@
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
@@ -66,25 +58,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <EmbedManifest>false</EmbedManifest>
- <DriverType />
- <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <EmbedManifest>false</EmbedManifest>
- <DriverType />
- <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
@@ -106,12 +80,6 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
<ItemGroup Label="WrappedTaskItems" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>AecApo</TargetName>
@@ -125,46 +93,24 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetName>AecApo</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetName>AecApo</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetName>AecApo</TargetName>
- </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -179,12 +125,6 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<UseOfAtl>Dynamic</UseOfAtl>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <UseOfAtl>Dynamic</UseOfAtl>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <UseOfAtl>Dynamic</UseOfAtl>
- </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<TreatWarningAsError>true</TreatWarningAsError>
@@ -283,54 +223,6 @@
<AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.;..\..\..\..\wil\include</AdditionalIncludeDirectories>
- <ExceptionHandling>
- </ExceptionHandling>
- <RuntimeLibrary />
- </ClCompile>
- <Midl>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </Midl>
- <ResourceCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
- <ModuleDefinitionFile>AecApoDll.def</ModuleDefinitionFile>
- <AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.;..\..\..\..\wil\include</AdditionalIncludeDirectories>
- <ExceptionHandling>
- </ExceptionHandling>
- <RuntimeLibrary />
- </ClCompile>
- <Midl>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </Midl>
- <ResourceCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
- <ModuleDefinitionFile>AecApoDll.def</ModuleDefinitionFile>
- <AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
- </Link>
- </ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="AecApoDll.cpp" />
<ClCompile Include="AecApoMFX.cpp" />
diff --git a/audio/sysvad/APO/AecApo/AecApoMfx.cpp b/audio/sysvad/APO/AecApo/AecApoMfx.cpp
index 21f2c20d..0c16f348 100644
--- a/audio/sysvad/APO/AecApo/AecApoMfx.cpp
+++ b/audio/sysvad/APO/AecApo/AecApoMfx.cpp
@@ -375,6 +375,39 @@ STDMETHODIMP CAecApoMFX::GetEffectsList(_Outptr_result_buffer_maybenull_(*pcEffe
return S_OK;
}
+STDMETHODIMP CAecApoMFX::GetControllableSystemEffectsList(_Outptr_result_buffer_maybenull_(*numEffects) AUDIO_SYSTEMEFFECT** effects, _Out_ UINT* numEffects, _In_opt_ HANDLE event)
+{
+ UNREFERENCED_PARAMETER(event);
+
+ RETURN_HR_IF_NULL(E_POINTER, effects);
+ RETURN_HR_IF_NULL(E_POINTER, numEffects);
+
+ *effects = nullptr;
+ *numEffects = 0;
+
+ if (m_audioSignalProcessingMode == AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS)
+ {
+ // Return the list of effects implemented by this APO for COMMUNICATIONS processing mode
+ static const GUID effectsList[] = {AUDIO_EFFECT_TYPE_ACOUSTIC_ECHO_CANCELLATION};
+
+ wil::unique_cotaskmem_array_ptr<AUDIO_SYSTEMEFFECT> audioEffects(
+ static_cast<AUDIO_SYSTEMEFFECT*>(CoTaskMemAlloc(ARRAYSIZE(effectsList) * sizeof(AUDIO_SYSTEMEFFECT))), ARRAYSIZE(effectsList));
+ RETURN_IF_NULL_ALLOC(audioEffects.get());
+
+ for (UINT i = 0; i < ARRAYSIZE(effectsList); i++)
+ {
+ audioEffects[i].id = effectsList[i];
+ audioEffects[i].state = AUDIO_SYSTEMEFFECT_STATE_ON;
+ audioEffects[i].canSetState = FALSE;
+ }
+
+ *numEffects = (UINT)audioEffects.size();
+ *effects = audioEffects.release();
+ }
+
+ return S_OK;
+}
+
HRESULT IsInputFormatSupportedForAec(IAudioMediaType* pMediaType, BOOL * pSupported)
{
ASSERT_NONREALTIME();
diff --git a/audio/sysvad/APO/DelayAPO/DelayAPO.vcxproj b/audio/sysvad/APO/DelayAPO/DelayAPO.vcxproj
index ecdaf321..a5d6ff37 100644
--- a/audio/sysvad/APO/DelayAPO/DelayAPO.vcxproj
+++ b/audio/sysvad/APO/DelayAPO/DelayAPO.vcxproj
@@ -1,22 +1,14 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
@@ -32,14 +24,14 @@
<SupportsPackaging>false</SupportsPackaging>
<RequiresPackageProject>true</RequiresPackageProject>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <Platform Condition="'$(Platform)' == ''">x64</Platform>
<SampleGuid>{D5CCDCB1-348E-414E-BB0F-33C773760034}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
@@ -48,7 +40,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
@@ -57,7 +49,7 @@
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
@@ -66,25 +58,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <EmbedManifest>false</EmbedManifest>
- <DriverType />
- <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <EmbedManifest>false</EmbedManifest>
- <DriverType />
- <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
@@ -106,12 +80,6 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
<ItemGroup Label="WrappedTaskItems" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>DelayAPO</TargetName>
@@ -125,46 +93,24 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetName>DelayAPO</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetName>DelayAPO</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetName>DelayAPO</TargetName>
- </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -179,12 +125,6 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<UseOfAtl>Dynamic</UseOfAtl>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <UseOfAtl>Dynamic</UseOfAtl>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <UseOfAtl>Dynamic</UseOfAtl>
- </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<TreatWarningAsError>true</TreatWarningAsError>
@@ -283,58 +223,10 @@
<AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
- <ExceptionHandling>
- </ExceptionHandling>
- <RuntimeLibrary />
- </ClCompile>
- <Midl>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </Midl>
- <ResourceCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
- <ModuleDefinitionFile>DelayAPODll.def</ModuleDefinitionFile>
- <AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
- <ExceptionHandling>
- </ExceptionHandling>
- <RuntimeLibrary />
- </ClCompile>
- <Midl>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </Midl>
- <ResourceCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
- <ModuleDefinitionFile>DelayAPODll.def</ModuleDefinitionFile>
- <AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
- </Link>
- </ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Delay.cpp" />
<ClCompile Include="DelayAPODll.cpp" />
- <ClCompile Include="DelayAPOMFX.cpp " />
+ <ClCompile Include="DelayAPOMFX.cpp " />
<ClCompile Include="DelayAPOSFX.cpp" />
<Midl Include="DelayAPODll.idl" />
<Midl Include="DelayAPOInterface.idl" />
@@ -353,4 +245,4 @@
<ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/audio/sysvad/APO/DelayAPO/DelayAPOMFX.cpp b/audio/sysvad/APO/DelayAPO/DelayAPOMFX.cpp
index 8778b252..af67571b 100644
--- a/audio/sysvad/APO/DelayAPO/DelayAPOMFX.cpp
+++ b/audio/sysvad/APO/DelayAPO/DelayAPOMFX.cpp
@@ -292,7 +292,7 @@ STDMETHODIMP CDelayAPOMFX::LockForProcess(UINT32 u32NumInputConnections,
//
// A more typical approach would be to allocate the memory using AERT_Allocate, which locks the memory
// But for the purposes of this APO, CoTaskMemAlloc suffices, and the risk of glitches is not important
- m_pf32DelayBuffer.Allocate(GetSamplesPerFrame() * m_nDelayFrames);
+ m_pf32DelayBuffer.Allocate((size_t) GetSamplesPerFrame() * m_nDelayFrames);
WriteSilence(m_pf32DelayBuffer, m_nDelayFrames, GetSamplesPerFrame());
if (nullptr == m_pf32DelayBuffer)
{
@@ -430,7 +430,8 @@ HRESULT CDelayAPOMFX::Initialize(UINT32 cbDataSize, BYTE* pbyData)
processingMode != AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS &&
processingMode != AUDIO_SIGNALPROCESSINGMODE_SPEECH &&
processingMode != AUDIO_SIGNALPROCESSINGMODE_MEDIA &&
- processingMode != AUDIO_SIGNALPROCESSINGMODE_MOVIE), hr = E_INVALIDARG, Exit);
+ processingMode != AUDIO_SIGNALPROCESSINGMODE_MOVIE &&
+ processingMode != AUDIO_SIGNALPROCESSINGMODE_NOTIFICATION), hr = E_INVALIDARG, Exit);
m_AudioProcessingMode = processingMode;
//
@@ -1165,4 +1166,4 @@ HRESULT CDelayAPOMFX::CheckCustomFormats(IAudioMediaType *pRequestedFormat)
}
return hResult;
-} \ No newline at end of file
+}
diff --git a/audio/sysvad/APO/DelayAPO/DelayAPOSFX.cpp b/audio/sysvad/APO/DelayAPO/DelayAPOSFX.cpp
index 81594bb7..67ae2788 100644
--- a/audio/sysvad/APO/DelayAPO/DelayAPOSFX.cpp
+++ b/audio/sysvad/APO/DelayAPO/DelayAPOSFX.cpp
@@ -241,7 +241,7 @@ STDMETHODIMP CDelayAPOSFX::LockForProcess(UINT32 u32NumInputConnections,
//
// A more typical approach would be to allocate the memory using AERT_Allocate, which locks the memory
// But for the purposes of this APO, CoTaskMemAlloc suffices, and the risk of glitches is not important
- m_pf32DelayBuffer.Allocate(GetSamplesPerFrame() * m_nDelayFrames);
+ m_pf32DelayBuffer.Allocate((size_t) GetSamplesPerFrame() * m_nDelayFrames);
WriteSilence(m_pf32DelayBuffer, m_nDelayFrames, GetSamplesPerFrame());
if (nullptr == m_pf32DelayBuffer)
@@ -388,7 +388,8 @@ HRESULT CDelayAPOSFX::Initialize(UINT32 cbDataSize, BYTE* pbyData)
processingMode != AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS &&
processingMode != AUDIO_SIGNALPROCESSINGMODE_SPEECH &&
processingMode != AUDIO_SIGNALPROCESSINGMODE_MEDIA &&
- processingMode != AUDIO_SIGNALPROCESSINGMODE_MOVIE), hr = E_INVALIDARG, Exit);
+ processingMode != AUDIO_SIGNALPROCESSINGMODE_MOVIE &&
+ processingMode != AUDIO_SIGNALPROCESSINGMODE_NOTIFICATION), hr = E_INVALIDARG, Exit);
m_AudioProcessingMode = processingMode;
//
diff --git a/audio/sysvad/APO/KWSApo/KWSApo.vcxproj b/audio/sysvad/APO/KWSApo/KWSApo.vcxproj
index b34e03d9..938e5974 100644
--- a/audio/sysvad/APO/KWSApo/KWSApo.vcxproj
+++ b/audio/sysvad/APO/KWSApo/KWSApo.vcxproj
@@ -1,22 +1,14 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
@@ -32,14 +24,14 @@
<SupportsPackaging>false</SupportsPackaging>
<RequiresPackageProject>true</RequiresPackageProject>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <Platform Condition="'$(Platform)' == ''">x64</Platform>
<SampleGuid>{D5CCDCB1-348E-414E-BB0F-33C773760034}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
@@ -48,7 +40,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
@@ -57,7 +49,7 @@
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
@@ -66,25 +58,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <EmbedManifest>false</EmbedManifest>
- <DriverType />
- <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <EmbedManifest>false</EmbedManifest>
- <DriverType />
- <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
@@ -106,12 +80,6 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
<ItemGroup Label="WrappedTaskItems" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>KWSApo</TargetName>
@@ -125,46 +93,24 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetName>KWSApo</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetName>KWSApo</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetName>KWSApo</TargetName>
- </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -179,12 +125,6 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<UseOfAtl>Dynamic</UseOfAtl>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <UseOfAtl>Dynamic</UseOfAtl>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <UseOfAtl>Dynamic</UseOfAtl>
- </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<TreatWarningAsError>true</TreatWarningAsError>
@@ -283,54 +223,6 @@
<AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.;..\..\..\..\wil\include</AdditionalIncludeDirectories>
- <ExceptionHandling>
- </ExceptionHandling>
- <RuntimeLibrary />
- </ClCompile>
- <Midl>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </Midl>
- <ResourceCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
- <ModuleDefinitionFile>KWSApoDll.def</ModuleDefinitionFile>
- <AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.;..\..\..\..\wil\include</AdditionalIncludeDirectories>
- <ExceptionHandling>
- </ExceptionHandling>
- <RuntimeLibrary />
- </ClCompile>
- <Midl>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </Midl>
- <ResourceCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
- <ModuleDefinitionFile>KWSApoDll.def</ModuleDefinitionFile>
- <AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
- </Link>
- </ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="KWSApo.cpp" />
<ClCompile Include="KWSApoDll.cpp" />
diff --git a/audio/sysvad/APO/SwapAPO/SwapAPO.h b/audio/sysvad/APO/SwapAPO/SwapAPO.h
index aeb9d259..d169d9db 100644
--- a/audio/sysvad/APO/SwapAPO/SwapAPO.h
+++ b/audio/sysvad/APO/SwapAPO/SwapAPO.h
@@ -195,7 +195,8 @@ public:
public:
LONG m_fEnableSwapMFX;
GUID m_AudioProcessingMode;
- wil::com_ptr_nothrow<IMMDevice> m_device;
+ wil::com_ptr_nothrow<IMMDevice> m_deviceTopologyMMDevice;
+ wil::com_ptr_nothrow<IMMDevice> m_audioEndpoint;
CComPtr<IPropertyStore> m_spAPOSystemEffectsProperties;
CComPtr<IMMDeviceEnumerator> m_spEnumerator;
static const CRegAPOProperties<1> sm_RegProperties; // registration properties
@@ -315,7 +316,8 @@ public:
LONG m_fEnableSwapSFX;
LONG m_fEnableDelaySFX;
GUID m_AudioProcessingMode;
- wil::com_ptr_nothrow<IMMDevice> m_device;
+ wil::com_ptr_nothrow<IMMDevice> m_deviceTopologyMMDevice;
+ wil::com_ptr_nothrow<IMMDevice> m_audioEndpoint;
CComPtr<IPropertyStore> m_spAPOSystemEffectsProperties;
CComPtr<IMMDeviceEnumerator> m_spEnumerator;
static const CRegAPOProperties<1> sm_RegProperties; // registration properties
diff --git a/audio/sysvad/APO/SwapAPO/SwapAPO.vcxproj b/audio/sysvad/APO/SwapAPO/SwapAPO.vcxproj
index 2a26307e..61bea0cb 100644
--- a/audio/sysvad/APO/SwapAPO/SwapAPO.vcxproj
+++ b/audio/sysvad/APO/SwapAPO/SwapAPO.vcxproj
@@ -5,18 +5,10 @@
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
@@ -32,14 +24,14 @@
<SupportsPackaging>false</SupportsPackaging>
<RequiresPackageProject>true</RequiresPackageProject>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <Platform Condition="'$(Platform)' == ''">x64</Platform>
<SampleGuid>{D5CCDCB1-348E-414E-BB0F-33C773760034}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
@@ -48,7 +40,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
@@ -57,7 +49,7 @@
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
@@ -66,25 +58,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <EmbedManifest>false</EmbedManifest>
- <DriverType />
- <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <EmbedManifest>false</EmbedManifest>
- <DriverType />
- <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
@@ -106,12 +80,6 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
<ItemGroup Label="WrappedTaskItems" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>SwapAPO</TargetName>
@@ -125,64 +93,24 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetName>SwapAPO</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetName>SwapAPO</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
- <TargetName>SwapAPO</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetName>SwapAPO</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
- <TargetName>SwapAPO</TargetName>
- </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
- <Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
- <Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -197,18 +125,6 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<UseOfAtl>Dynamic</UseOfAtl>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <UseOfAtl>Dynamic</UseOfAtl>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
- <UseOfAtl>Dynamic</UseOfAtl>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <UseOfAtl>Dynamic</UseOfAtl>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
- <UseOfAtl>Dynamic</UseOfAtl>
- </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<TreatWarningAsError>true</TreatWarningAsError>
@@ -307,104 +223,6 @@
<AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.;..\..\..\..\wil\include</AdditionalIncludeDirectories>
- <ExceptionHandling>
- </ExceptionHandling>
- <RuntimeLibrary />
- </ClCompile>
- <Midl>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </Midl>
- <ResourceCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib;rtworkq.lib</AdditionalDependencies>
- <ModuleDefinitionFile>SwapAPODll.def</ModuleDefinitionFile>
- <AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
- <ClCompile>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
- <ExceptionHandling>
- </ExceptionHandling>
- <RuntimeLibrary>
- </RuntimeLibrary>
- </ClCompile>
- <Midl>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </Midl>
- <ResourceCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib;rtworkq.lib</AdditionalDependencies>
- <ModuleDefinitionFile>SwapAPODll.def</ModuleDefinitionFile>
- <AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.;..\..\..\..\wil\include</AdditionalIncludeDirectories>
- <ExceptionHandling>
- </ExceptionHandling>
- <RuntimeLibrary />
- </ClCompile>
- <Midl>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </Midl>
- <ResourceCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib;rtworkq.lib</AdditionalDependencies>
- <ModuleDefinitionFile>SwapAPODll.def</ModuleDefinitionFile>
- <AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
- <ClCompile>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\;.</AdditionalIncludeDirectories>
- <ExceptionHandling>
- </ExceptionHandling>
- <RuntimeLibrary>
- </RuntimeLibrary>
- </ClCompile>
- <Midl>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </Midl>
- <ResourceCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib;rtworkq.lib</AdditionalDependencies>
- <ModuleDefinitionFile>SwapAPODll.def</ModuleDefinitionFile>
- <AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
- </Link>
- </ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Swap.cpp" />
<ClCompile Include="SwapAPODll.cpp" />
diff --git a/audio/sysvad/APO/SwapAPO/swapapomfx.cpp b/audio/sysvad/APO/SwapAPO/swapapomfx.cpp
index 7a772a07..b05b1568 100644
--- a/audio/sysvad/APO/SwapAPO/swapapomfx.cpp
+++ b/audio/sysvad/APO/SwapAPO/swapapomfx.cpp
@@ -458,10 +458,38 @@ HRESULT CSwapAPOMFX::Initialize(UINT32 cbDataSize, BYTE* pbyData)
// that need to run at a real-time priority. The work queue ID is used with the Rtwq APIs.
hr = apoRtQueueService->GetRealTimeWorkQueue(&m_queueId);
IF_FAILED_JUMP(hr, Exit);
-
+
// Windows should pass a valid collection.
ATLASSERT(papoSysFxInit3->pDeviceCollection != nullptr);
IF_TRUE_ACTION_JUMP(papoSysFxInit3->pDeviceCollection == nullptr, hr = E_INVALIDARG, Exit);
+
+ // Use IMMDevice to activate IAudioSystemEffectsPropertyStore that contains the default, user and
+ // volatile settings.
+ IMMDeviceCollection* deviceCollection = reinterpret_cast<APOInitSystemEffects3*>(pbyData)->pDeviceCollection;
+ UINT32 numDevices;
+ // Get the endpoint on which this APO has been created
+ // (It is the last device in the device collection)
+ hr = deviceCollection->GetCount(&numDevices);
+ IF_FAILED_JUMP(hr, Exit);
+
+ hr = numDevices > 0 ? S_OK : E_UNEXPECTED;
+ IF_FAILED_JUMP(hr, Exit);
+
+ hr = deviceCollection->Item(numDevices - 1, &m_audioEndpoint);
+ IF_FAILED_JUMP(hr, Exit);
+
+ wil::unique_prop_variant activationParam;
+ hr = InitPropVariantFromCLSID(SWAP_APO_SFX_CONTEXT, &activationParam);
+ IF_FAILED_JUMP(hr, Exit);
+
+ wil::com_ptr_nothrow<IAudioSystemEffectsPropertyStore> effectsPropertyStore;
+ hr = m_audioEndpoint->Activate(__uuidof(effectsPropertyStore), CLSCTX_ALL, &activationParam, effectsPropertyStore.put_void());
+ IF_FAILED_JUMP(hr, Exit);
+
+ // This is where an APO might want to open the volatile or default property stores as well
+ // Use STGM_READWRITE if IPropertyStore::SetValue is needed.
+ hr = effectsPropertyStore->OpenUserPropertyStore(STGM_READ, m_userStore.put());
+ IF_FAILED_JUMP(hr, Exit);
// Save the processing mode being initialized.
processingMode = papoSysFxInit3->AudioProcessingMode;
@@ -523,7 +551,8 @@ HRESULT CSwapAPOMFX::Initialize(UINT32 cbDataSize, BYTE* pbyData)
processingMode != AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS &&
processingMode != AUDIO_SIGNALPROCESSINGMODE_SPEECH &&
processingMode != AUDIO_SIGNALPROCESSINGMODE_MEDIA &&
- processingMode != AUDIO_SIGNALPROCESSINGMODE_MOVIE), hr = E_INVALIDARG, Exit);
+ processingMode != AUDIO_SIGNALPROCESSINGMODE_MOVIE &&
+ processingMode != AUDIO_SIGNALPROCESSINGMODE_NOTIFICATION), hr = E_INVALIDARG, Exit);
m_AudioProcessingMode = processingMode;
//
@@ -755,7 +784,7 @@ HRESULT CSwapAPOMFX::SetAudioSystemEffectState(GUID effectId, AUDIO_SYSTEMEFFECT
if (oldState != effectInfo.state)
{
SetEvent(m_hEffectsChangedEvent);
- m_apoLoggingService->ApoLog(APO_LOG_LEVEL_INFO, L"SetAudioSystemEffectState - effect: " GUID_FORMAT_STRING L", state: %i", effectInfo.id, effectInfo.state);
+ m_apoLoggingService->ApoLog(APO_LOG_LEVEL_INFO, L"CSwapAPOMFX::SetAudioSystemEffectState - effect: " GUID_FORMAT_STRING L", state: %i", effectInfo.id, effectInfo.state);
}
m_EffectsLock.Leave();
@@ -772,8 +801,6 @@ HRESULT CSwapAPOMFX::GetApoNotificationRegistrationInfo(_Out_writes_(*count) APO
*apoNotifications = nullptr;
*count = 0;
- RETURN_HR_IF_NULL(E_FAIL, m_device);
-
// Let the OS know what notifications we are interested in by returning an array of
// APO_NOTIFICATION_DESCRIPTORs.
constexpr DWORD numDescriptors = 1;
@@ -785,7 +812,7 @@ HRESULT CSwapAPOMFX::GetApoNotificationRegistrationInfo(_Out_writes_(*count) APO
// Our APO wants to get notified when a endpoint property changes on the audio endpoint.
apoNotificationDescriptors[0].type = APO_NOTIFICATION_TYPE_ENDPOINT_PROPERTY_CHANGE;
- (void)m_device.query_to(&apoNotificationDescriptors[0].audioEndpointPropertyChange.device);
+ (void)m_audioEndpoint.query_to(&apoNotificationDescriptors[0].audioEndpointPropertyChange.device);
*apoNotifications = apoNotificationDescriptors.release();
*count = numDescriptors;
@@ -811,7 +838,7 @@ void CSwapAPOMFX::HandleNotification(APO_NOTIFICATION *apoNotification)
{PKEY_Endpoint_Enable_Channel_Swap_MFX, &m_fEnableSwapMFX},
};
- m_apoLoggingService->ApoLog(APO_LOG_LEVEL_INFO, L"HandleNotification - pkey: " GUID_FORMAT_STRING L" %d", GUID_FORMAT_ARGS(apoNotification->audioEndpointPropertyChange.propertyKey.fmtid), apoNotification->audioEndpointPropertyChange.propertyKey.pid);
+ m_apoLoggingService->ApoLog(APO_LOG_LEVEL_INFO, L"CSwapAPOMFX::HandleNotification - pkey: " GUID_FORMAT_STRING L" %d", GUID_FORMAT_ARGS(apoNotification->audioEndpointPropertyChange.propertyKey.fmtid), apoNotification->audioEndpointPropertyChange.propertyKey.pid);
for (int i = 0; i < ARRAYSIZE(controls); i++)
{
@@ -847,11 +874,11 @@ HRESULT CSwapAPOMFX::ProprietaryCommunicationWithDriver(IMMDeviceCollection *pDe
}
// Get the target IMMDevice
- hr = pDeviceCollection->Item(nSoftwareIoDeviceInCollection, &m_device);
+ hr = pDeviceCollection->Item(nSoftwareIoDeviceInCollection, &m_deviceTopologyMMDevice);
IF_FAILED_JUMP(hr, Exit);
// Instantiate a device topology instance
- hr = m_device->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL, NULL, (void**)&spMyDeviceTopology);
+ hr = m_deviceTopologyMMDevice->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL, NULL, (void**)&spMyDeviceTopology);
IF_FAILED_JUMP(hr, Exit);
// retrieve connect instance
@@ -859,7 +886,7 @@ HRESULT CSwapAPOMFX::ProprietaryCommunicationWithDriver(IMMDeviceCollection *pDe
IF_FAILED_JUMP(hr, Exit);
// activate IKsControl on the IMMDevice
- hr = m_device->Activate(__uuidof(IKsControl), CLSCTX_INPROC_SERVER, NULL, (void**)&spKsControl);
+ hr = m_deviceTopologyMMDevice->Activate(__uuidof(IKsControl), CLSCTX_INPROC_SERVER, NULL, (void**)&spKsControl);
IF_FAILED_JUMP(hr, Exit);
// get KS pin id
diff --git a/audio/sysvad/APO/SwapAPO/swapaposfx.cpp b/audio/sysvad/APO/SwapAPO/swapaposfx.cpp
index 8483d8df..ef418f75 100644
--- a/audio/sysvad/APO/SwapAPO/swapaposfx.cpp
+++ b/audio/sysvad/APO/SwapAPO/swapaposfx.cpp
@@ -297,48 +297,48 @@ HRESULT CSwapAPOSFX::Initialize(UINT32 cbDataSize, BYTE* pbyData)
hr = papoSysFxInit3->pServiceProvider->QueryService(SID_AudioProcessingObjectLoggingService, IID_PPV_ARGS(&m_apoLoggingService));
IF_FAILED_JUMP(hr, Exit);
- // SampleApo supports the new IAudioSystemEffects3 interface so it will receive APOInitSystemEffects3
+ // SampleApo supports the new IAudioSystemEffects3 interface so it will receive APOInitSystemEffects3
// in pbyData if the audio driver has declared support for this.
+ // Windows should pass a valid collection.
+ ATLASSERT(papoSysFxInit3->pDeviceCollection != nullptr);
+ IF_TRUE_ACTION_JUMP(papoSysFxInit3->pDeviceCollection == nullptr, hr = E_INVALIDARG, Exit);
+
// Use IMMDevice to activate IAudioSystemEffectsPropertyStore that contains the default, user and
// volatile settings.
IMMDeviceCollection* deviceCollection = reinterpret_cast<APOInitSystemEffects3*>(pbyData)->pDeviceCollection;
- if (deviceCollection != nullptr)
- {
- UINT32 numDevices;
- wil::com_ptr_nothrow<IMMDevice> endpoint;
+ UINT32 numDevices;
+ // Get the endpoint on which this APO has been created
+ // (It is the last device in the device collection)
+ hr = deviceCollection->GetCount(&numDevices);
+ IF_FAILED_JUMP(hr, Exit);
- // Get the endpoint on which this APO has been created
- // (It is the last device in the device collection)
- if (SUCCEEDED(deviceCollection->GetCount(&numDevices)) && numDevices > 0 &&
- SUCCEEDED(deviceCollection->Item(numDevices - 1, &endpoint)))
- {
- wil::unique_prop_variant activationParam;
- hr = InitPropVariantFromCLSID(SWAP_APO_SFX_CONTEXT, &activationParam);
- IF_FAILED_JUMP(hr, Exit);
+ hr = numDevices > 0 ? S_OK : E_UNEXPECTED;
+ IF_FAILED_JUMP(hr, Exit);
- wil::com_ptr_nothrow<IAudioSystemEffectsPropertyStore> effectsPropertyStore;
- hr = endpoint->Activate(__uuidof(effectsPropertyStore), CLSCTX_ALL, &activationParam, effectsPropertyStore.put_void());
- IF_FAILED_JUMP(hr, Exit);
+ hr = deviceCollection->Item(numDevices - 1, &m_audioEndpoint);
+ IF_FAILED_JUMP(hr, Exit);
- // This is where an APO might want to open the volatile or default property stores as well
- // Use STGM_READWRITE if IPropertyStore::SetValue is needed.
- hr = effectsPropertyStore->OpenUserPropertyStore(STGM_READ, m_userStore.put());
- IF_FAILED_JUMP(hr, Exit);
- }
- }
+ wil::unique_prop_variant activationParam;
+ hr = InitPropVariantFromCLSID(SWAP_APO_SFX_CONTEXT, &activationParam);
+ IF_FAILED_JUMP(hr, Exit);
- // Windows should pass a valid collection.
- ATLASSERT(papoSysFxInit2->pDeviceCollection != nullptr);
- IF_TRUE_ACTION_JUMP(papoSysFxInit3->pDeviceCollection == nullptr, hr = E_INVALIDARG, Exit);
+ wil::com_ptr_nothrow<IAudioSystemEffectsPropertyStore> effectsPropertyStore;
+ hr = m_audioEndpoint->Activate(__uuidof(effectsPropertyStore), CLSCTX_ALL, &activationParam, effectsPropertyStore.put_void());
+ IF_FAILED_JUMP(hr, Exit);
+
+ // This is where an APO might want to open the volatile or default property stores as well
+ // Use STGM_READWRITE if IPropertyStore::SetValue is needed.
+ hr = effectsPropertyStore->OpenUserPropertyStore(STGM_READ, m_userStore.put());
+ IF_FAILED_JUMP(hr, Exit);
// Get the IDeviceTopology and IConnector interfaces to communicate with this
// APO's counterpart audio driver. This can be used for any proprietary
// communication.
- hr = papoSysFxInit3->pDeviceCollection->Item(papoSysFxInit3->nSoftwareIoDeviceInCollection, &m_device);
+ hr = papoSysFxInit3->pDeviceCollection->Item(papoSysFxInit3->nSoftwareIoDeviceInCollection, &m_deviceTopologyMMDevice);
IF_FAILED_JUMP(hr, Exit);
- hr = m_device->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL, NULL, (void**)&spMyDeviceTopology);
+ hr = m_deviceTopologyMMDevice->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL, NULL, (void**)&spMyDeviceTopology);
IF_FAILED_JUMP(hr, Exit);
hr = spMyDeviceTopology->GetConnector(papoSysFxInit3->nSoftwareIoConnectorIndex, &spMyConnector);
@@ -365,10 +365,10 @@ HRESULT CSwapAPOSFX::Initialize(UINT32 cbDataSize, BYTE* pbyData)
// Get the IDeviceTopology and IConnector interfaces to communicate with this
// APO's counterpart audio driver. This can be used for any proprietary
// communication.
- hr = papoSysFxInit2->pDeviceCollection->Item(papoSysFxInit2->nSoftwareIoDeviceInCollection, &m_device);
+ hr = papoSysFxInit2->pDeviceCollection->Item(papoSysFxInit2->nSoftwareIoDeviceInCollection, &m_deviceTopologyMMDevice);
IF_FAILED_JUMP(hr, Exit);
- hr = m_device->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL, NULL, (void**)&spMyDeviceTopology);
+ hr = m_deviceTopologyMMDevice->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL, NULL, (void**)&spMyDeviceTopology);
IF_FAILED_JUMP(hr, Exit);
hr = spMyDeviceTopology->GetConnector(papoSysFxInit2->nSoftwareIoConnectorIndex, &spMyConnector);
@@ -407,7 +407,8 @@ HRESULT CSwapAPOSFX::Initialize(UINT32 cbDataSize, BYTE* pbyData)
processingMode != AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS &&
processingMode != AUDIO_SIGNALPROCESSINGMODE_SPEECH &&
processingMode != AUDIO_SIGNALPROCESSINGMODE_MEDIA &&
- processingMode != AUDIO_SIGNALPROCESSINGMODE_MOVIE), hr = E_INVALIDARG, Exit);
+ processingMode != AUDIO_SIGNALPROCESSINGMODE_MOVIE &&
+ processingMode != AUDIO_SIGNALPROCESSINGMODE_NOTIFICATION), hr = E_INVALIDARG, Exit);
m_AudioProcessingMode = processingMode;
//
@@ -640,7 +641,7 @@ HRESULT CSwapAPOSFX::SetAudioSystemEffectState(GUID effectId, AUDIO_SYSTEMEFFECT
if (oldState != effectInfo.state)
{
SetEvent(m_hEffectsChangedEvent);
- m_apoLoggingService->ApoLog(APO_LOG_LEVEL_INFO, L"SetAudioSystemEffectState - effect: " GUID_FORMAT_STRING L", state: %i", effectInfo.id, effectInfo.state);
+ m_apoLoggingService->ApoLog(APO_LOG_LEVEL_INFO, L"CSwapAPOSFX::SetAudioSystemEffectState - effect: " GUID_FORMAT_STRING L", state: %i", effectInfo.id, effectInfo.state);
}
m_EffectsLock.Leave();
@@ -733,8 +734,6 @@ HRESULT CSwapAPOSFX::GetApoNotificationRegistrationInfo(_Out_writes_(*count) APO
*apoNotifications = nullptr;
*count = 0;
- RETURN_HR_IF_NULL(E_FAIL, m_device);
-
// Let the OS know what notifications we are interested in by returning an array of
// APO_NOTIFICATION_DESCRIPTORs.
constexpr DWORD numDescriptors = 1;
@@ -746,7 +745,7 @@ HRESULT CSwapAPOSFX::GetApoNotificationRegistrationInfo(_Out_writes_(*count) APO
// Our APO wants to get notified when a endpoint property changes on the audio endpoint.
apoNotificationDescriptors[0].type = APO_NOTIFICATION_TYPE_ENDPOINT_PROPERTY_CHANGE;
- (void)m_device.query_to(&apoNotificationDescriptors[0].audioEndpointPropertyChange.device);
+ (void)m_audioEndpoint.query_to(&apoNotificationDescriptors[0].audioEndpointPropertyChange.device);
*apoNotifications = apoNotificationDescriptors.release();
*count = numDescriptors;
@@ -772,7 +771,7 @@ void CSwapAPOSFX::HandleNotification(APO_NOTIFICATION *apoNotification)
{PKEY_Endpoint_Enable_Channel_Swap_SFX, &m_fEnableSwapSFX},
};
- m_apoLoggingService->ApoLog(APO_LOG_LEVEL_INFO, L"HandleNotification - pkey: " GUID_FORMAT_STRING L" %d", GUID_FORMAT_ARGS(apoNotification->audioEndpointPropertyChange.propertyKey.fmtid), apoNotification->audioEndpointPropertyChange.propertyKey.pid);
+ m_apoLoggingService->ApoLog(APO_LOG_LEVEL_INFO, L"CSwapAPOSFX::HandleNotification - pkey: " GUID_FORMAT_STRING L" %d", GUID_FORMAT_ARGS(apoNotification->audioEndpointPropertyChange.propertyKey.fmtid), apoNotification->audioEndpointPropertyChange.propertyKey.pid);
for (int i = 0; i < ARRAYSIZE(controls); i++)
{
diff --git a/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj b/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj
index 5b819cf3..aa5cc3e2 100644
--- a/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj
+++ b/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj
@@ -1,22 +1,14 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
@@ -31,14 +23,14 @@
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <Platform Condition="'$(Platform)' == ''">x64</Platform>
<SampleGuid>{F51739CE-5253-42B5-9191-57F28B5842C6}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -46,7 +38,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -54,7 +46,7 @@
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -62,23 +54,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType>KMDF</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>StaticLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType>KMDF</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>StaticLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType>KMDF</DriverType>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>StaticLibrary</ConfigurationType>
@@ -99,12 +75,6 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
<ItemGroup Label="WrappedTaskItems" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>EndpointsCommon</TargetName>
@@ -118,12 +88,6 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetName>EndpointsCommon</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetName>EndpointsCommon</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetName>EndpointsCommon</TargetName>
- </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ResourceCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
@@ -204,46 +168,6 @@
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS;SYSVAD_USB_SIDEBAND</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS;SYSVAD_USB_SIDEBAND;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
- <ExceptionHandling>
- </ExceptionHandling>
- <DisableSpecificWarnings>4595;%(DisableSpecificWarnings)</DisableSpecificWarnings>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS;SYSVAD_USB_SIDEBAND</PreprocessorDefinitions>
- </Midl>
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS;SYSVAD_USB_SIDEBAND</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..;.</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS;SYSVAD_USB_SIDEBAND;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
- <ExceptionHandling>
- </ExceptionHandling>
- <DisableSpecificWarnings>4595;%(DisableSpecificWarnings)</DisableSpecificWarnings>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS;SYSVAD_USB_SIDEBAND</PreprocessorDefinitions>
- </Midl>
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="a2dphpminwavert.cpp" />
<ClCompile Include="a2dphpspeakertopo.cpp" />
@@ -280,4 +204,4 @@
<ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/audio/sysvad/EndpointsCommon/MiniportAudioEngineNode.cpp b/audio/sysvad/EndpointsCommon/MiniportAudioEngineNode.cpp
index 34477606..8c3979f2 100644
--- a/audio/sysvad/EndpointsCommon/MiniportAudioEngineNode.cpp
+++ b/audio/sysvad/EndpointsCommon/MiniportAudioEngineNode.cpp
@@ -57,9 +57,9 @@ Remarks:
} KSAUDIOENGINE_DESCRIPTOR, *PKSAUDIOENGINE_DESCRIPTOR;
The fields are defined as:
- nHostPinId – The ID of the pin factory connected to the audio engine node that is intended for host processed audio data. This is the pin factory on which a software audio engine will run.
- nOffloadPinId – The ID of the pin factory connected to the audio engine node that is intended for offloaded streams.
- nLoopbackPinId – The ID of the pin factory connected to the audio engine that is intended for supplying a post-mix loopback or reference stream.
+ nHostPinId - The ID of the pin factory connected to the audio engine node that is intended for host processed audio data. This is the pin factory on which a software audio engine will run.
+ nOffloadPinId - The ID of the pin factory connected to the audio engine node that is intended for offloaded streams.
+ nLoopbackPinId - The ID of the pin factory connected to the audio engine that is intended for supplying a post-mix loopback or reference stream.
All pin ids need to be unique for each audio engine node.
diff --git a/audio/sysvad/EndpointsCommon/mintopo.cpp b/audio/sysvad/EndpointsCommon/mintopo.cpp
index c1e4bc14..9fb2cc21 100644
--- a/audio/sysvad/EndpointsCommon/mintopo.cpp
+++ b/audio/sysvad/EndpointsCommon/mintopo.cpp
@@ -581,6 +581,100 @@ Return Value:
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
+CMiniportTopology::PropertyHandlerJackDescription3
+(
+ _In_ PPCPROPERTY_REQUEST PropertyRequest,
+ _In_ ULONG cJackDescriptions,
+ _In_reads_(cJackDescriptions) PKSJACK_DESCRIPTION * JackDescriptions,
+ _In_ ULONG ConfigId
+)
+/*++
+
+Routine Description:
+
+ Handles ( KSPROPSETID_Jack, KSPROPERTY_JACK_DESCRIPTION3 )
+
+Arguments:
+
+ PropertyRequest -
+ cJackDescriptions - # of elements in the jack descriptions array.
+ JackDescriptions - Array of jack descriptions pointers.
+ ConfigId - Current endpoint config id
+
+Return Value:
+
+ NT status code.
+
+--*/
+{
+ PAGED_CODE();
+
+ ASSERT(PropertyRequest);
+
+ DPF_ENTER(("[PropertyHandlerJackDescription3]"));
+
+ NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
+ ULONG nPinId = (ULONG)-1;
+
+ if (PropertyRequest->InstanceSize >= sizeof(ULONG))
+ {
+ nPinId = *(PULONG(PropertyRequest->Instance));
+
+ if ((nPinId < cJackDescriptions) && (JackDescriptions[nPinId] != NULL))
+ {
+ if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
+ {
+ ntStatus =
+ PropertyHandler_BasicSupport
+ (
+ PropertyRequest,
+ KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET,
+ VT_ILLEGAL
+ );
+ }
+ else
+ {
+ ULONG cbNeeded = sizeof(KSMULTIPLE_ITEM) + sizeof(KSJACK_DESCRIPTION3);
+
+ if (PropertyRequest->ValueSize == 0)
+ {
+ PropertyRequest->ValueSize = cbNeeded;
+ ntStatus = STATUS_BUFFER_OVERFLOW;
+ }
+ else if (PropertyRequest->ValueSize < cbNeeded)
+ {
+ ntStatus = STATUS_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
+ {
+ PKSMULTIPLE_ITEM pMI = (PKSMULTIPLE_ITEM)PropertyRequest->Value;
+ PKSJACK_DESCRIPTION3 pDesc = (PKSJACK_DESCRIPTION3)(pMI+1);
+
+ pMI->Size = cbNeeded;
+ pMI->Count = 1;
+
+ RtlZeroMemory(pDesc, sizeof(KSJACK_DESCRIPTION3));
+
+ //
+ // hardware config id
+ //
+ pDesc->ConfigId = ConfigId;
+
+ ntStatus = STATUS_SUCCESS;
+ }
+ }
+ }
+ }
+ }
+
+ return ntStatus;
+}
+
+//=============================================================================
+#pragma code_seg("PAGE")
+NTSTATUS
CMiniportTopology::PropertyHandlerAudioResourceGroup
(
_In_ PPCPROPERTY_REQUEST PropertyRequest
diff --git a/audio/sysvad/EndpointsCommon/mintopo.h b/audio/sysvad/EndpointsCommon/mintopo.h
index 596e13b1..f0bae44d 100644
--- a/audio/sysvad/EndpointsCommon/mintopo.h
+++ b/audio/sysvad/EndpointsCommon/mintopo.h
@@ -100,6 +100,14 @@ public:
_In_ DWORD JackCapabilities
);
+ NTSTATUS PropertyHandlerJackDescription3
+ (
+ _In_ PPCPROPERTY_REQUEST PropertyRequest,
+ _In_ ULONG cJackDescriptions,
+ _In_reads_(cJackDescriptions) PKSJACK_DESCRIPTION *JackDescriptions,
+ _In_ ULONG ConfigId
+ );
+
NTSTATUS PropertyHandlerAudioResourceGroup
(
_In_ PPCPROPERTY_REQUEST PropertyRequest
diff --git a/audio/sysvad/EndpointsCommon/minwavert.cpp b/audio/sysvad/EndpointsCommon/minwavert.cpp
index bd81c110..c6b8e8c3 100644
--- a/audio/sysvad/EndpointsCommon/minwavert.cpp
+++ b/audio/sysvad/EndpointsCommon/minwavert.cpp
@@ -3452,7 +3452,8 @@ NTSTATUS CKeywordDetector::ReadKeywordTimestampRegistry()
PAGED_CODE();
NTSTATUS ntStatus;
- UNICODE_STRING parametersPath;
+ PDRIVER_OBJECT DriverObject;
+ HANDLE DriverKey;
RTL_QUERY_REGISTRY_TABLE paramTable[] = {
// QueryRoutine Flags Name EntryContext DefaultType DefaultData DefaultLength
@@ -3461,30 +3462,37 @@ NTSTATUS CKeywordDetector::ReadKeywordTimestampRegistry()
{ NULL, 0, NULL, NULL, 0, NULL, 0 }
};
- RtlInitUnicodeString(&parametersPath, NULL);
+ DriverObject = WdfDriverWdmGetDriverObject(WdfGetDriver());
+ DriverKey = NULL;
+ ntStatus = IoOpenDriverRegistryKey(DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &DriverKey);
- // The sizeof(WCHAR) is added to the maximum length, for allowing a space for null termination of the string.
- parametersPath.MaximumLength =
- g_RegistryPath.Length + sizeof(L"\\Parameters") + sizeof(WCHAR);
-
- parametersPath.Buffer = (PWCH)ExAllocatePool2(POOL_FLAG_PAGED, parametersPath.MaximumLength, MINWAVERT_POOLTAG);
- if (parametersPath.Buffer == NULL)
+ if (!NT_SUCCESS(ntStatus))
{
- return STATUS_INSUFFICIENT_RESOURCES;
+ return ntStatus;
}
- RtlAppendUnicodeToString(&parametersPath, g_RegistryPath.Buffer);
- RtlAppendUnicodeToString(&parametersPath, L"\\Parameters");
+ ntStatus = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
+ (PCWSTR) DriverKey,
+ &paramTable[0],
+ NULL,
+ NULL);
- ntStatus = RtlQueryRegistryValues(
- RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
- parametersPath.Buffer,
- &paramTable[0],
- NULL,
- NULL
- );
+ if (!NT_SUCCESS(ntStatus))
+ {
+ DPF(D_VERBOSE, ("RtlQueryRegistryValues failed, using default values, 0x%x", ntStatus));
+ //
+ // Don't return error because we will operate with default values.
+ //
+ }
- ExFreePool(parametersPath.Buffer);
+ if (DriverKey)
+ {
+ ZwClose(DriverKey);
+ }
return ntStatus;
}
diff --git a/audio/sysvad/EndpointsCommon/minwavertstream.cpp b/audio/sysvad/EndpointsCommon/minwavertstream.cpp
index 08467e05..adea0c82 100644
--- a/audio/sysvad/EndpointsCommon/minwavertstream.cpp
+++ b/audio/sysvad/EndpointsCommon/minwavertstream.cpp
@@ -121,7 +121,8 @@ NTSTATUS CMiniportWaveRTStream::ReadRegistrySettings()
PAGED_CODE();
NTSTATUS ntStatus;
- UNICODE_STRING parametersPath;
+ PDRIVER_OBJECT DriverObject;
+ HANDLE DriverKey;
RTL_QUERY_REGISTRY_TABLE paramTable[] = {
// QueryRoutine Flags Name EntryContext DefaultType DefaultData DefaultLength
@@ -136,30 +137,37 @@ NTSTATUS CMiniportWaveRTStream::ReadRegistrySettings()
{ NULL, 0, NULL, NULL, 0, NULL, 0 }
};
- RtlInitUnicodeString(&parametersPath, NULL);
+ DriverObject = WdfDriverWdmGetDriverObject(WdfGetDriver());
+ DriverKey = NULL;
+ ntStatus = IoOpenDriverRegistryKey(DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &DriverKey);
- // The sizeof(WCHAR) is added to the maximum length, for allowing a space for null termination of the string.
- parametersPath.MaximumLength =
- g_RegistryPath.Length + sizeof(L"\\Parameters") + sizeof(WCHAR);
-
- parametersPath.Buffer = (PWCH)ExAllocatePool2(POOL_FLAG_PAGED, parametersPath.MaximumLength, MINWAVERT_POOLTAG);
- if (parametersPath.Buffer == NULL)
+ if (!NT_SUCCESS(ntStatus))
{
- return STATUS_INSUFFICIENT_RESOURCES;
+ return ntStatus;
}
- RtlAppendUnicodeToString(&parametersPath, g_RegistryPath.Buffer);
- RtlAppendUnicodeToString(&parametersPath, L"\\Parameters");
+ ntStatus = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
+ (PCWSTR) DriverKey,
+ &paramTable[0],
+ NULL,
+ NULL);
- ntStatus = RtlQueryRegistryValues(
- RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
- parametersPath.Buffer,
- &paramTable[0],
- NULL,
- NULL
- );
+ if (!NT_SUCCESS(ntStatus))
+ {
+ DPF(D_VERBOSE, ("RtlQueryRegistryValues failed, using default values, 0x%x", ntStatus));
+ //
+ // Don't return error because we will operate with default values.
+ //
+ }
- ExFreePool(parametersPath.Buffer);
+ if (DriverKey)
+ {
+ ZwClose(DriverKey);
+ }
return ntStatus;
}
diff --git a/audio/sysvad/EndpointsCommon/speakertopo.cpp b/audio/sysvad/EndpointsCommon/speakertopo.cpp
index fba72036..002b1174 100644
--- a/audio/sysvad/EndpointsCommon/speakertopo.cpp
+++ b/audio/sysvad/EndpointsCommon/speakertopo.cpp
@@ -75,6 +75,15 @@ Return Value:
0 // jack capabilities
);
}
+ else if (PropertyRequest->PropertyItem->Id == KSPROPERTY_JACK_DESCRIPTION3)
+ {
+ ntStatus = pMiniport->PropertyHandlerJackDescription3(
+ PropertyRequest,
+ ARRAYSIZE(SpeakerJackDescriptions),
+ SpeakerJackDescriptions,
+ 42 // jack config id
+ );
+ }
}
else if (IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_AudioResourceManagement))
{
diff --git a/audio/sysvad/EndpointsCommon/speakertoptable.h b/audio/sysvad/EndpointsCommon/speakertoptable.h
index 3d31d7a4..ea3890f7 100644
--- a/audio/sysvad/EndpointsCommon/speakertoptable.h
+++ b/audio/sysvad/EndpointsCommon/speakertoptable.h
@@ -142,6 +142,13 @@ PCPROPERTY_ITEM PropertiesSpeakerTopoFilter[] =
PropertyHandler_SpeakerTopoFilter
},
{
+ &KSPROPSETID_Jack,
+ KSPROPERTY_JACK_DESCRIPTION3,
+ KSPROPERTY_TYPE_GET |
+ KSPROPERTY_TYPE_BASICSUPPORT,
+ PropertyHandler_SpeakerTopoFilter
+ },
+ {
&KSPROPSETID_AudioResourceManagement,
KSPROPERTY_AUDIORESOURCEMANAGEMENT_RESOURCEGROUP,
KSPROPERTY_TYPE_SET,
diff --git a/audio/sysvad/KeywordDetectorAdapter/KeywordDetectorContosoAdapter.vcxproj b/audio/sysvad/KeywordDetectorAdapter/KeywordDetectorContosoAdapter.vcxproj
index d1675201..592fefb2 100644
--- a/audio/sysvad/KeywordDetectorAdapter/KeywordDetectorContosoAdapter.vcxproj
+++ b/audio/sysvad/KeywordDetectorAdapter/KeywordDetectorContosoAdapter.vcxproj
@@ -5,18 +5,10 @@
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
@@ -32,14 +24,14 @@
<SupportsPackaging>false</SupportsPackaging>
<RequiresPackageProject>true</RequiresPackageProject>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <Platform Condition="'$(Platform)' == ''">x64</Platform>
<SampleGuid>{C1851F27-BDAA-4DF1-8CA5-9D0176FD2B33}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -47,7 +39,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -55,7 +47,7 @@
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -63,23 +55,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType />
- <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType />
- <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverTargetPlatform>Windows Driver</DriverTargetPlatform>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -100,12 +76,6 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
<ItemGroup Label="WrappedTaskItems" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>KeywordDetectorContosoAdapter</TargetName>
@@ -119,46 +89,24 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetName>KeywordDetectorContosoAdapter</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetName>KeywordDetectorContosoAdapter</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetName>KeywordDetectorContosoAdapter</TargetName>
- </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Link>
- <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
- <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ <EntryPointSymbol>_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -257,54 +205,6 @@
<ModuleDefinitionFile>KeywordDetectorContosoAdapter.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreaded</RuntimeLibrary>
- <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\</AdditionalIncludeDirectories>
- <ExceptionHandling>
- </ExceptionHandling>
- </ClCompile>
- <Midl>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\</AdditionalIncludeDirectories>
- </Midl>
- <ResourceCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;mfplat.lib;runtimeobject.lib</AdditionalDependencies>
- <ModuleDefinitionFile>KeywordDetectorContosoAdapter.def</ModuleDefinitionFile>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreaded</RuntimeLibrary>
- <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\</AdditionalIncludeDirectories>
- <ExceptionHandling>
- </ExceptionHandling>
- </ClCompile>
- <Midl>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\</AdditionalIncludeDirectories>
- </Midl>
- <ResourceCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;mfplat.lib;runtimeobject.lib</AdditionalDependencies>
- <ModuleDefinitionFile>KeywordDetectorContosoAdapter.def</ModuleDefinitionFile>
- </Link>
- </ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="KeywordDetectorContosoAdapter.cpp" />
@@ -325,4 +225,4 @@
<ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/audio/sysvad/Package/package.VcxProj b/audio/sysvad/Package/package.VcxProj
index 0d3bb44a..9af11965 100644
--- a/audio/sysvad/Package/package.VcxProj
+++ b/audio/sysvad/Package/package.VcxProj
@@ -1,22 +1,14 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
@@ -59,14 +51,6 @@
<SampleGuid>{E9D167E6-E633-4284-8F02-FF86DF3B6D7F}</SampleGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>true</UseDebugLibraries>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>false</UseDebugLibraries>
- </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
@@ -107,16 +91,6 @@
<VerifyDrivers />
<VerifyFlags>133563</VerifyFlags>
</PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
@@ -127,7 +101,7 @@
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
@@ -140,4 +114,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project>
+</Project> \ No newline at end of file
diff --git a/audio/sysvad/TabletAudioSample/TabletAudioSample.vcxproj b/audio/sysvad/TabletAudioSample/TabletAudioSample.vcxproj
index 6e4e4c44..8e6e6ee4 100644
--- a/audio/sysvad/TabletAudioSample/TabletAudioSample.vcxproj
+++ b/audio/sysvad/TabletAudioSample/TabletAudioSample.vcxproj
@@ -1,22 +1,14 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
@@ -33,7 +25,7 @@
<SupportsPackaging>false</SupportsPackaging>
<RequiresPackageProject>true</RequiresPackageProject>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <Platform Condition="'$(Platform)' == ''">x64</Platform>
<SampleGuid>{2A9A946E-F017-4E0D-BF75-AD81E7E97D64}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
@@ -69,22 +61,6 @@
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
</PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>False</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType>KMDF</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>Driver</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetVersion>Windows10</TargetVersion>
- <UseDebugLibraries>True</UseDebugLibraries>
- <DriverTargetPlatform>Universal</DriverTargetPlatform>
- <DriverType>KMDF</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>Driver</ConfigurationType>
- </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup>
<OutDir>$(IntDir)</OutDir>
@@ -101,12 +77,6 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
</ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
<ItemGroup Label="WrappedTaskItems" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
@@ -196,50 +166,6 @@
<PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
</Midl>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\portcls.lib;$(DDK_LIB_PATH)\stdunk.lib;$(DDK_LIB_PATH)\libcntpr.lib</AdditionalDependencies>
- </Link>
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
- </Midl>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\portcls.lib;$(DDK_LIB_PATH)\stdunk.lib;$(DDK_LIB_PATH)\libcntpr.lib</AdditionalDependencies>
- </Link>
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <TreatWarningAsError>true</TreatWarningAsError>
- <WarningLevel>Level4</WarningLevel>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_WIN32;UNICODE;_UNICODE;PC_IMPLEMENTATION</PreprocessorDefinitions>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);DEBUG_LEVEL=DEBUGLVL_TERSE</PreprocessorDefinitions>
- </Midl>
- </ItemDefinitionGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetName>TabletAudioSample</TargetName>
</PropertyGroup>
@@ -252,12 +178,6 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetName>TabletAudioSample</TargetName>
</PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetName>TabletAudioSample</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetName>TabletAudioSample</TargetName>
- </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
<AdditionalDependencies>%(AdditionalDependencies);.\..\EndpointsCommon\$(IntDir)\EndpointsCommon.lib</AdditionalDependencies>
@@ -354,50 +274,6 @@
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
</ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);.\..\EndpointsCommon\$(IntDir)\EndpointsCommon.lib</AdditionalDependencies>
- </Link>
- <ClCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS;SYSVAD_USB_SIDEBAND;_USE_IPortClsRuntimePower;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon;.</AdditionalIncludeDirectories>
- <ExceptionHandling>
- </ExceptionHandling>
- </ClCompile>
- <Midl>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS;SYSVAD_USB_SIDEBAND;_USE_IPortClsRuntimePower</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
- </Midl>
- <ResourceCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS;SYSVAD_USB_SIDEBAND;_USE_IPortClsRuntimePower</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
- </ResourceCompile>
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Link>
- <AdditionalDependencies>%(AdditionalDependencies);.\..\EndpointsCommon\$(IntDir)\EndpointsCommon.lib</AdditionalDependencies>
- </Link>
- <ClCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS;SYSVAD_USB_SIDEBAND;_USE_IPortClsRuntimePower;_NEW_DELETE_OPERATORS_</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon;.</AdditionalIncludeDirectories>
- <ExceptionHandling>
- </ExceptionHandling>
- </ClCompile>
- <Midl>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS;SYSVAD_USB_SIDEBAND;_USE_IPortClsRuntimePower</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
- </Midl>
- <ResourceCompile>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS;SYSVAD_USB_SIDEBAND;_USE_IPortClsRuntimePower</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\EndpointsCommon</AdditionalIncludeDirectories>
- </ResourceCompile>
- <DriverSign>
- <FileDigestAlgorithm>sha256</FileDigestAlgorithm>
- </DriverSign>
- </ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\A2dpHpDevice.cpp" />
<ClCompile Include="..\adapter.cpp" />
@@ -427,4 +303,4 @@
<ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/audio/sysvad/adapter.cpp b/audio/sysvad/adapter.cpp
index ef48e5f4..0f44c593 100644
--- a/audio/sysvad/adapter.cpp
+++ b/audio/sysvad/adapter.cpp
@@ -246,10 +246,10 @@ _Dispatch_type_(IRP_MJ_PNP)
DRIVER_DISPATCH PnpHandler;
//
-// Rendering streams are saved to a file by default. Use the registry value
-// DoNotCreateDataFiles (DWORD) > 0 to override this default.
+// Rendering streams are not saved to a file by default. Use the registry value
+// DoNotCreateDataFiles (DWORD) = 0 to override this default.
//
-DWORD g_DoNotCreateDataFiles = 0; // default is off.
+DWORD g_DoNotCreateDataFiles = 1; // default is off.
DWORD g_DisableToneGenerator = 0; // default is to generate tones.
UNICODE_STRING g_RegistryPath; // This is used to store the registry settings path for the driver
@@ -425,7 +425,8 @@ Returns:
{
NTSTATUS ntStatus;
- UNICODE_STRING parametersPath;
+ PDRIVER_OBJECT DriverObject;
+ HANDLE DriverKey;
RTL_QUERY_REGISTRY_TABLE paramTable[] = {
// QueryRoutine Flags Name EntryContext DefaultType DefaultData DefaultLength
{ NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"DoNotCreateDataFiles", &g_DoNotCreateDataFiles, (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD, &g_DoNotCreateDataFiles, sizeof(ULONG)},
@@ -441,29 +442,27 @@ Returns:
DPF(D_TERSE, ("[GetRegistrySettings]"));
- PAGED_CODE();
-
- RtlInitUnicodeString(&parametersPath, NULL);
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(RegistryPath);
- parametersPath.MaximumLength =
- RegistryPath->Length + sizeof(L"\\Parameters") + sizeof(WCHAR);
+ DriverObject = WdfDriverWdmGetDriverObject(WdfGetDriver());
+ DriverKey = NULL;
+ ntStatus = IoOpenDriverRegistryKey(DriverObject,
+ DriverRegKeyParameters,
+ KEY_READ,
+ 0,
+ &DriverKey);
- parametersPath.Buffer = (PWCH) ExAllocatePool2(POOL_FLAG_PAGED, parametersPath.MaximumLength, MINADAPTER_POOLTAG);
- if (parametersPath.Buffer == NULL)
+ if (!NT_SUCCESS(ntStatus))
{
- return STATUS_INSUFFICIENT_RESOURCES;
+ return ntStatus;
}
- RtlAppendUnicodeToString(&parametersPath, RegistryPath->Buffer);
- RtlAppendUnicodeToString(&parametersPath, L"\\Parameters");
-
- ntStatus = RtlQueryRegistryValues(
- RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
- parametersPath.Buffer,
- &paramTable[0],
- NULL,
- NULL
- );
+ ntStatus = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
+ (PCWSTR) DriverKey,
+ &paramTable[0],
+ NULL,
+ NULL);
if (!NT_SUCCESS(ntStatus))
{
@@ -485,10 +484,10 @@ Returns:
DPF(D_VERBOSE, ("DisableUsbSideband: %u", g_DisableUsbSideband));
#endif // SYSVAD_USB_SIDEBAND
- //
- // Cleanup.
- //
- ExFreePool(parametersPath.Buffer);
+ if (DriverKey)
+ {
+ ZwClose(DriverKey);
+ }
return STATUS_SUCCESS;
}
@@ -537,15 +536,6 @@ Return Value:
ntStatus,
DPF(D_ERROR, ("Registry path copy error 0x%x", ntStatus)),
Done);
-
- //
- // Get registry configuration.
- //
- ntStatus = GetRegistrySettings(RegistryPathName);
- IF_FAILED_ACTION_JUMP(
- ntStatus,
- DPF(D_ERROR, ("Registry Configuration error 0x%x", ntStatus)),
- Done);
WDF_DRIVER_CONFIG_INIT(&config, WDF_NO_EVENT_CALLBACK);
//
@@ -569,6 +559,15 @@ Return Value:
Done);
//
+ // Get registry configuration.
+ //
+ ntStatus = GetRegistrySettings(RegistryPathName);
+ IF_FAILED_ACTION_JUMP(
+ ntStatus,
+ DPF(D_ERROR, ("Registry Configuration error 0x%x", ntStatus)),
+ Done);
+
+ //
// Tell the class driver to initialize the driver.
//
ntStatus = PcInitializeAdapterDriver(DriverObject,
diff --git a/audio/sysvad/common.cpp b/audio/sysvad/common.cpp
index 9bc3e644..1334411e 100644
--- a/audio/sysvad/common.cpp
+++ b/audio/sysvad/common.cpp
@@ -50,7 +50,6 @@ Abstract:
// CSaveData statics
//-----------------------------------------------------------------------------
-PSAVEWORKER_PARAM CSaveData::m_pWorkItems = NULL;
PDEVICE_OBJECT CSaveData::m_pDeviceObject = NULL;
//=============================================================================
// Classes
@@ -642,8 +641,6 @@ Return Value:
delete m_pHW;
m_pHW = NULL;
}
-
- CSaveData::DestroyWorkItems();
SAFE_RELEASE(m_pPortClsEtwHelper);
SAFE_RELEASE(m_pServiceGroupWave);
@@ -841,8 +838,6 @@ Return Value:
// Initialize SaveData class.
//
CSaveData::SetDeviceObject(DeviceObject); //device object is needed by CSaveData
- ntStatus = CSaveData::InitializeWorkItems(DeviceObject);
- IF_FAILED_JUMP(ntStatus, Done);
Done:
return ntStatus;
diff --git a/audio/sysvad/savedata.cpp b/audio/sysvad/savedata.cpp
index cb5f5cfc..39789f3b 100644
--- a/audio/sysvad/savedata.cpp
+++ b/audio/sysvad/savedata.cpp
@@ -47,12 +47,13 @@ Abstract:
#define DEFAULT_FRAME_SIZE PAGE_SIZE * 4
#define DEFAULT_BUFFER_SIZE DEFAULT_FRAME_SIZE * DEFAULT_FRAME_COUNT
-#define DEFAULT_FILE_NAME L"\\DosDevices\\C:\\STREAM"
-#define OSDATA_FILE_NAME L"\\DosDevices\\O:\\STREAM"
+#define DEFAULT_FILE_FOLDER1 L"\\DriverData\\Audio_Samples"
+#define DEFAULT_FILE_FOLDER2 L"\\DriverData\\Audio_Samples\\Sysvad"
+#define DEFAULT_FILE_NAME L"\\DriverData\\Audio_Samples\\Sysvad\\STREAM"
#define OFFLOAD_FILE_NAME L"OFFLOAD"
#define HOST_FILE_NAME L"HOST"
-#define MAX_WORKER_ITEM_COUNT 15
+#define MAX_WORKER_ITEM_COUNT 8
//=============================================================================
// Statics
@@ -91,6 +92,7 @@ CSaveData::CSaveData()
m_DataHeader.dwData = DATA_TAG;
m_DataHeader.dwDataLength = 0;
+ RtlZeroMemory(&m_FileName, sizeof(m_FileName));
RtlZeroMemory(&m_objectAttributes, sizeof(m_objectAttributes));
} // CSaveData
@@ -101,6 +103,12 @@ CSaveData::~CSaveData()
DPF_ENTER(("[CSaveData::~CSaveData]"));
+ //
+ // All write activity is done at this point (see acquire->stop stream transition).
+ // Safe to call even if the Initialize function failed.
+ //
+ DestroyWorkItems();
+
// Update the wave header in data file with real file size.
//
if(m_pFilePtr)
@@ -415,6 +423,7 @@ CSaveData::GetNewWorkItem
{
LARGE_INTEGER timeOut = { 0 };
NTSTATUS ntStatus;
+ PSAVEWORKER_PARAM saveWorker = NULL;
for (int i = 0; i < MAX_WORKER_ITEM_COUNT; i++)
{
@@ -430,13 +439,16 @@ CSaveData::GetNewWorkItem
if (STATUS_SUCCESS == ntStatus)
{
if (m_pWorkItems[i].WorkItem)
- return &(m_pWorkItems[i]);
- else
- return NULL;
+ {
+ saveWorker = &(m_pWorkItems[i]);
+ KeResetEvent(&saveWorker->EventDone);
+ break;
+ }
}
}
- return NULL;
+
+ return saveWorker;
} // GetNewWorkItem
#pragma code_seg("PAGE")
@@ -449,13 +461,13 @@ CSaveData::Initialize
{
PAGED_CODE();
- NTSTATUS ntStatus = STATUS_SUCCESS;
- WCHAR szTemp[MAX_PATH];
- size_t cLen;
- OBJECT_ATTRIBUTES objectAttributes;
- UNICODE_STRING osDataVolumeString;
- HANDLE osDataFileHandle = NULL;
- IO_STATUS_BLOCK ioStatusBlock;
+ NTSTATUS ntStatus = STATUS_SUCCESS;
+ WCHAR szTemp[MAX_PATH];
+ size_t cLen = 0;
+ IO_STATUS_BLOCK ioStatusBlock = {0};
+ HANDLE fileHandle;
+ OBJECT_ATTRIBUTES objectAttributes;
+ UNICODE_STRING fileName;
DPF_ENTER(("[CSaveData::Initialize]"));
@@ -468,47 +480,74 @@ CSaveData::Initialize
m_ulStreamId++;
}
- // Probe if OSData volume exists.
- //
- RtlStringCchPrintfW(szTemp, MAX_PATH, L"%s_probe.txt", OSDATA_FILE_NAME);
- RtlInitUnicodeString(&osDataVolumeString, szTemp);
- InitializeObjectAttributes
- (
- &objectAttributes,
- &osDataVolumeString,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL
- );
+ RtlInitUnicodeString(&fileName, DEFAULT_FILE_FOLDER1);
+ InitializeObjectAttributes(
+ &objectAttributes,
+ &fileName,
+ OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
- ntStatus =
- ZwCreateFile
- (
- &osDataFileHandle,
- GENERIC_WRITE | SYNCHRONIZE,
+ // Create the folder.
+ ntStatus = ZwCreateFile(
+ &fileHandle,
+ 0,
&objectAttributes,
&ioStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
- FILE_OVERWRITE_IF,
- FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
+ FILE_OPEN_IF,
+ FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
- 0
- );
+ 0);
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ ZwClose(fileHandle);
+ fileHandle = NULL;
+
+ RtlInitUnicodeString(&fileName, DEFAULT_FILE_FOLDER2);
+ InitializeObjectAttributes(
+ &objectAttributes,
+ &fileName,
+ OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ // Create the folder.
+ ntStatus = ZwCreateFile(
+ &fileHandle,
+ 0,
+ &objectAttributes,
+ &ioStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ 0,
+ FILE_OPEN_IF,
+ FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
+ NULL,
+ 0);
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ ZwClose(fileHandle);
+ fileHandle = NULL;
+ }
+ }
+
if (NT_SUCCESS(ntStatus))
{
- ZwClose(osDataFileHandle);
+ // Allocate data file name.
+ //
+ RtlStringCchPrintfW(szTemp, MAX_PATH, L"%s_%s_%d.wav", DEFAULT_FILE_NAME, _bOffloaded ? OFFLOAD_FILE_NAME : HOST_FILE_NAME, _bOffloaded ? m_ulOffloadStreamId : m_ulStreamId);
+ m_FileName.Length = 0;
+ ntStatus = RtlStringCchLengthW (szTemp, sizeof(szTemp)/sizeof(szTemp[0]), &cLen);
}
- // Allocate data file name.
- //
- RtlStringCchPrintfW(szTemp, MAX_PATH, L"%s_%s_%d.wav", NT_SUCCESS(ntStatus) ? OSDATA_FILE_NAME : DEFAULT_FILE_NAME, _bOffloaded ? OFFLOAD_FILE_NAME : HOST_FILE_NAME, _bOffloaded ? m_ulOffloadStreamId : m_ulStreamId);
- m_FileName.Length = 0;
- ntStatus = RtlStringCchLengthW (szTemp, sizeof(szTemp)/sizeof(szTemp[0]), &cLen);
if (NT_SUCCESS(ntStatus))
{
- m_FileName.MaximumLength = (USHORT)((cLen * sizeof(WCHAR)) + sizeof(WCHAR));//convert to wchar and add room for NULL
+ m_FileName.MaximumLength = (USHORT)((cLen * sizeof(WCHAR)) + sizeof(WCHAR));//convert to wchar and add room for NULL
m_FileName.Buffer = (PWSTR)
ExAllocatePool2
(
@@ -572,6 +611,13 @@ CSaveData::Initialize
//
KeInitializeMutex( &m_FileSync, 1 ) ;
+ // Allocate work-items.
+ //
+ if (NT_SUCCESS(ntStatus))
+ {
+ ntStatus = InitializeWorkItems(m_pDeviceObject);
+ }
+
// Open the data file.
//
if (NT_SUCCESS(ntStatus))
@@ -586,7 +632,7 @@ CSaveData::Initialize
(
&m_objectAttributes,
&m_FileName,
- OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL
);
@@ -896,7 +942,6 @@ CSaveData::SaveFrame
pParam->ulFrameNo = ulFrameNo;
pParam->ulDataSize = ulDataSize;
pParam->pData = m_pDataBuffer + ulFrameNo * m_ulFrameSize;
- KeResetEvent(&pParam->EventDone);
IoQueueWorkItem(pParam->WorkItem, SaveFrameWorkerCallback,
CriticalWorkQueue, (PVOID)pParam);
}
diff --git a/audio/sysvad/savedata.h b/audio/sysvad/savedata.h
index a1525bda..94221025 100644
--- a/audio/sysvad/savedata.h
+++ b/audio/sysvad/savedata.h
@@ -98,7 +98,7 @@ protected:
static PDEVICE_OBJECT m_pDeviceObject;
static ULONG m_ulStreamId;
static ULONG m_ulOffloadStreamId;
- static PSAVEWORKER_PARAM m_pWorkItems;
+ PSAVEWORKER_PARAM m_pWorkItems;
BOOL m_fWriteDisabled;
@@ -108,11 +108,11 @@ public:
CSaveData();
~CSaveData();
- static NTSTATUS InitializeWorkItems
+ NTSTATUS InitializeWorkItems
(
_In_ PDEVICE_OBJECT DeviceObject
);
- static void DestroyWorkItems
+ void DestroyWorkItems
(
void
);
@@ -120,7 +120,7 @@ public:
(
_In_ BOOL fDisable
);
- static PSAVEWORKER_PARAM GetNewWorkItem
+ PSAVEWORKER_PARAM GetNewWorkItem
(
void
);
diff --git a/audio/sysvad/sysvad.sln b/audio/sysvad/sysvad.sln
index 39041665..8ee722a7 100644
--- a/audio/sysvad/sysvad.sln
+++ b/audio/sysvad/sysvad.sln
@@ -34,107 +34,73 @@ EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
- Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|ARM64 = Release|ARM64
- Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|ARM64.ActiveCfg = Debug|ARM64
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|ARM64.Build.0 = Debug|ARM64
- {830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|Win32.ActiveCfg = Debug|Win32
- {830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|Win32.Build.0 = Debug|Win32
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|x64.ActiveCfg = Debug|x64
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|x64.Build.0 = Debug|x64
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|ARM64.ActiveCfg = Release|ARM64
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|ARM64.Build.0 = Release|ARM64
- {830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|Win32.ActiveCfg = Release|Win32
- {830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|Win32.Build.0 = Release|Win32
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|x64.ActiveCfg = Release|x64
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|x64.Build.0 = Release|x64
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|ARM64.ActiveCfg = Debug|ARM64
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|ARM64.Build.0 = Debug|ARM64
- {E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|Win32.ActiveCfg = Debug|Win32
- {E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|Win32.Build.0 = Debug|Win32
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|x64.ActiveCfg = Debug|x64
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|x64.Build.0 = Debug|x64
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|ARM64.ActiveCfg = Release|ARM64
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|ARM64.Build.0 = Release|ARM64
- {E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|Win32.ActiveCfg = Release|Win32
- {E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|Win32.Build.0 = Release|Win32
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|x64.ActiveCfg = Release|x64
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|x64.Build.0 = Release|x64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|ARM64.ActiveCfg = Debug|ARM64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|ARM64.Build.0 = Debug|ARM64
- {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|Win32.ActiveCfg = Debug|Win32
- {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|Win32.Build.0 = Debug|Win32
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|x64.ActiveCfg = Debug|x64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|x64.Build.0 = Debug|x64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|ARM64.ActiveCfg = Release|ARM64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|ARM64.Build.0 = Release|ARM64
- {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|Win32.ActiveCfg = Release|Win32
- {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|Win32.Build.0 = Release|Win32
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|x64.ActiveCfg = Release|x64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|x64.Build.0 = Release|x64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|ARM64.ActiveCfg = Debug|ARM64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|ARM64.Build.0 = Debug|ARM64
- {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|Win32.ActiveCfg = Debug|Win32
- {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|Win32.Build.0 = Debug|Win32
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|x64.ActiveCfg = Debug|x64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|x64.Build.0 = Debug|x64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|ARM64.ActiveCfg = Release|ARM64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|ARM64.Build.0 = Release|ARM64
- {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|Win32.ActiveCfg = Release|Win32
- {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|Win32.Build.0 = Release|Win32
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|x64.ActiveCfg = Release|x64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|x64.Build.0 = Release|x64
{8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|ARM64.ActiveCfg = Debug|ARM64
{8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|ARM64.Build.0 = Debug|ARM64
- {8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|Win32.ActiveCfg = Debug|Win32
- {8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|Win32.Build.0 = Debug|Win32
{8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|x64.ActiveCfg = Debug|x64
{8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|x64.Build.0 = Debug|x64
{8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|ARM64.ActiveCfg = Release|ARM64
{8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|ARM64.Build.0 = Release|ARM64
- {8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|Win32.ActiveCfg = Release|Win32
- {8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|Win32.Build.0 = Release|Win32
{8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|x64.ActiveCfg = Release|x64
{8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|x64.Build.0 = Release|x64
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|ARM64.ActiveCfg = Debug|ARM64
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|ARM64.Build.0 = Debug|ARM64
- {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|Win32.ActiveCfg = Debug|Win32
- {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|Win32.Build.0 = Debug|Win32
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|x64.ActiveCfg = Debug|x64
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|x64.Build.0 = Debug|x64
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|ARM64.ActiveCfg = Release|ARM64
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|ARM64.Build.0 = Release|ARM64
- {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|Win32.ActiveCfg = Release|Win32
- {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|Win32.Build.0 = Release|Win32
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|x64.ActiveCfg = Release|x64
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|x64.Build.0 = Release|x64
{47358AD6-A48A-465B-965F-0A66F8BDFE23}.Debug|ARM64.ActiveCfg = Debug|ARM64
{47358AD6-A48A-465B-965F-0A66F8BDFE23}.Debug|ARM64.Build.0 = Debug|ARM64
- {47358AD6-A48A-465B-965F-0A66F8BDFE23}.Debug|Win32.ActiveCfg = Debug|Win32
- {47358AD6-A48A-465B-965F-0A66F8BDFE23}.Debug|Win32.Build.0 = Debug|Win32
{47358AD6-A48A-465B-965F-0A66F8BDFE23}.Debug|x64.ActiveCfg = Debug|x64
{47358AD6-A48A-465B-965F-0A66F8BDFE23}.Debug|x64.Build.0 = Debug|x64
{47358AD6-A48A-465B-965F-0A66F8BDFE23}.Release|ARM64.ActiveCfg = Release|ARM64
{47358AD6-A48A-465B-965F-0A66F8BDFE23}.Release|ARM64.Build.0 = Release|ARM64
- {47358AD6-A48A-465B-965F-0A66F8BDFE23}.Release|Win32.ActiveCfg = Release|Win32
- {47358AD6-A48A-465B-965F-0A66F8BDFE23}.Release|Win32.Build.0 = Release|Win32
{47358AD6-A48A-465B-965F-0A66F8BDFE23}.Release|x64.ActiveCfg = Release|x64
{47358AD6-A48A-465B-965F-0A66F8BDFE23}.Release|x64.Build.0 = Release|x64
{83A1B9B0-3CB7-4249-ADEC-C336B0EDDE76}.Debug|ARM64.ActiveCfg = Debug|ARM64
{83A1B9B0-3CB7-4249-ADEC-C336B0EDDE76}.Debug|ARM64.Build.0 = Debug|ARM64
- {83A1B9B0-3CB7-4249-ADEC-C336B0EDDE76}.Debug|Win32.ActiveCfg = Debug|Win32
- {83A1B9B0-3CB7-4249-ADEC-C336B0EDDE76}.Debug|Win32.Build.0 = Debug|Win32
{83A1B9B0-3CB7-4249-ADEC-C336B0EDDE76}.Debug|x64.ActiveCfg = Debug|x64
{83A1B9B0-3CB7-4249-ADEC-C336B0EDDE76}.Debug|x64.Build.0 = Debug|x64
{83A1B9B0-3CB7-4249-ADEC-C336B0EDDE76}.Release|ARM64.ActiveCfg = Release|ARM64
{83A1B9B0-3CB7-4249-ADEC-C336B0EDDE76}.Release|ARM64.Build.0 = Release|ARM64
- {83A1B9B0-3CB7-4249-ADEC-C336B0EDDE76}.Release|Win32.ActiveCfg = Release|Win32
- {83A1B9B0-3CB7-4249-ADEC-C336B0EDDE76}.Release|Win32.Build.0 = Release|Win32
{83A1B9B0-3CB7-4249-ADEC-C336B0EDDE76}.Release|x64.ActiveCfg = Release|x64
{83A1B9B0-3CB7-4249-ADEC-C336B0EDDE76}.Release|x64.Build.0 = Release|x64
EndGlobalSection