summaryrefslogtreecommitdiff
path: root/audio/sysvad/EndpointsCommon
diff options
context:
space:
mode:
authorkarlf <[email protected]>2016-08-11 13:28:13 -0700
committerkarlf <[email protected]>2016-08-11 13:28:13 -0700
commit96eb96dfb613e4c745db6bd1f53a92fe7e2290fc (patch)
treead5f3ede5cbcd6b598677ce41bcf8318471bdd92 /audio/sysvad/EndpointsCommon
parent687b274aa38fd05c8c26e3068932121876d7f745 (diff)
Updated for "Windows 10 Anniversary Update" (Version 1607)
Diffstat (limited to 'audio/sysvad/EndpointsCommon')
-rw-r--r--audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj182
-rw-r--r--audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj.Filters59
-rw-r--r--audio/sysvad/EndpointsCommon/MiniportStreamAudioEngineNode.cpp73
-rw-r--r--audio/sysvad/EndpointsCommon/bthhfpspeakerwavtable.h69
-rw-r--r--audio/sysvad/EndpointsCommon/bthhfpspeakerwbwavtable.h119
-rw-r--r--audio/sysvad/EndpointsCommon/micarray1toptable.h12
-rw-r--r--audio/sysvad/EndpointsCommon/micarraytopo.cpp106
-rw-r--r--audio/sysvad/EndpointsCommon/micarraytopo.h5
-rw-r--r--audio/sysvad/EndpointsCommon/micarraywavtable.h20
-rw-r--r--audio/sysvad/EndpointsCommon/mintopo.cpp17
-rw-r--r--audio/sysvad/EndpointsCommon/mintopo.h7
-rw-r--r--audio/sysvad/EndpointsCommon/minwavert.cpp8
-rw-r--r--audio/sysvad/EndpointsCommon/minwavert.h4
-rw-r--r--audio/sysvad/EndpointsCommon/minwavertstream.cpp226
-rw-r--r--audio/sysvad/EndpointsCommon/minwavertstream.h11
-rw-r--r--audio/sysvad/EndpointsCommon/speakerhpwavtable.h121
-rw-r--r--audio/sysvad/EndpointsCommon/speakerwavtable.h122
17 files changed, 416 insertions, 745 deletions
diff --git a/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj b/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj
deleted file mode 100644
index aef0e973..00000000
--- a/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj
+++ /dev/null
@@ -1,182 +0,0 @@
-<?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|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectGuid>{E3BA10BE-08FF-4244-86C6-C788072CEA25}</ProjectGuid>
- <RootNamespace>$(MSBuildProjectName)</RootNamespace>
- <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
- <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
- <Platform Condition="'$(Platform)' == ''">Win32</Platform>
- <SampleGuid>{4DA68694-1C5F-491B-9272-A8223477E4B7}</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>
- <DriverType>KMDF</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>StaticLibrary</ConfigurationType>
- </PropertyGroup>
- <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <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>
- <DriverType>KMDF</DriverType>
- <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
- <ConfigurationType>StaticLibrary</ConfigurationType>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <PropertyGroup>
- <OutDir>$(IntDir)</OutDir>
- </PropertyGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <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>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <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>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- <ExceptionHandling>
- </ExceptionHandling>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- </Midl>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- <ExceptionHandling>
- </ExceptionHandling>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- </Midl>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- <ExceptionHandling>
- </ExceptionHandling>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- </Midl>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ResourceCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- </ResourceCompile>
- <ClCompile>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- <ExceptionHandling>
- </ExceptionHandling>
- </ClCompile>
- <Midl>
- <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>%(PreprocessorDefinitions);_USE_WAVERT_;SYSVAD_BTH_BYPASS</PreprocessorDefinitions>
- </Midl>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="bthhfpmictopo.cpp" />
- <ClCompile Include="bthhfpminwavert.cpp" />
- <ClCompile Include="bthhfpspeakertopo.cpp" />
- <ClCompile Include="bthhfptopo.cpp" />
- <ClCompile Include="micarraytopo.cpp" />
- <ClCompile Include="MiniportAudioEngineNode.cpp" />
- <ClCompile Include="MiniportStreamAudioEngineNode.cpp" />
- <ClCompile Include="mintopo.cpp" />
- <ClCompile Include="minwavert.cpp" />
- <ClCompile Include="minwavertstream.cpp" />
- <ClCompile Include="speakerhptopo.cpp" />
- <ClCompile Include="speakertopo.cpp" />
- </ItemGroup>
- <ItemGroup>
- <Inf Exclude="@(Inf)" Include="*.inf" />
- <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
- </ItemGroup>
- <ItemGroup>
- <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
- <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
- <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-</Project> \ No newline at end of file
diff --git a/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj.Filters b/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj.Filters
deleted file mode 100644
index 167f0468..00000000
--- a/audio/sysvad/EndpointsCommon/EndpointsCommon.vcxproj.Filters
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup>
- <Filter Include="Source Files">
- <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
- <UniqueIdentifier>{44370F68-49C1-4647-BD26-31F7EBE942A3}</UniqueIdentifier>
- </Filter>
- <Filter Include="Header Files">
- <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
- <UniqueIdentifier>{AEA2BA25-EBF9-454D-BC73-91D1CC36FB6F}</UniqueIdentifier>
- </Filter>
- <Filter Include="Resource Files">
- <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
- <UniqueIdentifier>{95FAF38F-0673-42EF-A3C6-35F98AE2E188}</UniqueIdentifier>
- </Filter>
- <Filter Include="Driver Files">
- <Extensions>inf;inv;inx;mof;mc;</Extensions>
- <UniqueIdentifier>{4D0AE1D8-6C62-4B48-B101-690D5E955972}</UniqueIdentifier>
- </Filter>
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="bthhfpmictopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="bthhfpminwavert.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="bthhfpspeakertopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="bthhfptopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="micarraytopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="MiniportAudioEngineNode.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="MiniportStreamAudioEngineNode.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="mintopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="minwavert.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="minwavertstream.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="speakerhptopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="speakertopo.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- </ItemGroup>
-</Project> \ No newline at end of file
diff --git a/audio/sysvad/EndpointsCommon/MiniportStreamAudioEngineNode.cpp b/audio/sysvad/EndpointsCommon/MiniportStreamAudioEngineNode.cpp
index 3c775d01..deba14f2 100644
--- a/audio/sysvad/EndpointsCommon/MiniportStreamAudioEngineNode.cpp
+++ b/audio/sysvad/EndpointsCommon/MiniportStreamAudioEngineNode.cpp
@@ -457,7 +457,7 @@ NTSTATUS CMiniportWaveRTStream::GetStreamLinearBufferPosition(_Out_ ULONGLONG *_
ASSERT(_pullLinearBufferPosition);
DPF_ENTER(("[CMiniportWaveRTStream::GetStreamLinearBufferPosition]"));
- ntStatus = GetLinearBufferPosition(_pullLinearBufferPosition, NULL);
+ ntStatus = GetPositions(_pullLinearBufferPosition, NULL, NULL);
return ntStatus;
}
@@ -721,23 +721,22 @@ NTSTATUS CMiniportWaveRTStream::SetChannelMute(_In_ UINT32 _uiChannel, _In_ BO
PAGED_CODE ();
DPF_ENTER(("[CMiniportWaveRTStream::SetChannelMute]"));
- m_plVolumeLevel[_uiChannel] = _bMute;
+ m_pbMuted[_uiChannel] = _bMute;
return STATUS_SUCCESS;
}
//presentation
-#pragma code_seg("PAGE")
+#pragma code_seg()
//
// UINT64 u64PositionInBlocks; // The block offset from the start of the stream to the current post-decoded uncompressed
// // position in the stream, where a block is the group of channels in the same sample; for a PCM stream,
-// // a block is same as a frame. For compressed formats, a block is a single sample within a frame
+// // a block is same as a frame. For compressed formats, a block is a single sample within a frame
// // (eg. each MP3 frame has 1152 samples or 1152 blocks)
// UINT64 u64QPCPosition; // The value of the performance counter at the time that the audio endpoint device read the device
// // position (*pu64Position) in response to the KSAUDIO_PRESENTATION_POSITION call.
NTSTATUS CMiniportWaveRTStream::GetPresentationPosition(_Out_ KSAUDIO_PRESENTATION_POSITION *_pPresentationPosition)
{
- PAGED_CODE ();
ASSERT (_pPresentationPosition);
LARGE_INTEGER timeStamp;
PADAPTERCOMMON pAdapterComm = m_pMiniport->GetAdapterCommObj();
@@ -745,19 +744,18 @@ NTSTATUS CMiniportWaveRTStream::GetPresentationPosition(_Out_ KSAUDIO_PRESENTAT
DPF_ENTER(("[CMiniportWaveRTStream::GetPresentationPosition]"));
ULONGLONG ullLinearPosition = {0};
+ ULONGLONG ullPresentationPosition = {0};
NTSTATUS status = STATUS_SUCCESS;
- status = GetLinearBufferPosition(&ullLinearPosition, &timeStamp);
+ status = GetPositions(&ullLinearPosition, &ullPresentationPosition, &timeStamp);
if (!NT_SUCCESS(status))
{
return status;
}
- _pPresentationPosition->u64PositionInBlocks = ullLinearPosition * m_pWfExt->Format.nSamplesPerSec / m_pWfExt->Format.nAvgBytesPerSec;
-
+ _pPresentationPosition->u64PositionInBlocks = ullPresentationPosition * m_pWfExt->Format.nSamplesPerSec / m_pWfExt->Format.nAvgBytesPerSec;
_pPresentationPosition->u64QPCPosition = (UINT64)timeStamp.QuadPart;
-
//Event type: eMINIPORT_GET_PRESENTATION_POSITION
//Parameter 1: Current linear buffer position
//Parameter 2: the previous WaveRtBufferWritePosition that the drive received
@@ -771,9 +769,10 @@ NTSTATUS CMiniportWaveRTStream::GetPresentationPosition(_Out_ KSAUDIO_PRESENTAT
return STATUS_SUCCESS;
}
+
+#pragma code_seg()
NTSTATUS CMiniportWaveRTStream::SetCurrentWritePosition(_In_ ULONG _ulCurrentWritePosition)
{
- PAGED_CODE ();
DPF_ENTER(("[CMiniportWaveRTStream::SetCurrentWritePosition]"));
NTSTATUS ntStatus;
@@ -794,15 +793,19 @@ NTSTATUS CMiniportWaveRTStream::SetCurrentWritePosition(_In_ ULONG _ulCurrentWr
ntStatus = STATUS_INVALID_DEVICE_REQUEST;
goto Done;
}
-
+
+ KIRQL oldIrql;
+ KeAcquireSpinLock(&m_PositionSpinLock, &oldIrql);
ntStatus = SetCurrentWritePositionInternal(_ulCurrentWritePosition);
+ KeReleaseSpinLock(&m_PositionSpinLock, oldIrql);
Done:
return ntStatus;
}
+
+#pragma code_seg()
NTSTATUS CMiniportWaveRTStream::SetCurrentWritePositionInternal(_In_ ULONG _ulCurrentWritePosition)
{
- PAGED_CODE ();
DPF_ENTER(("[CMiniportWaveRTStream::SetCurrentWritePositionInternal]"));
if (_ulCurrentWritePosition > m_ulDmaBufferSize)
@@ -811,7 +814,7 @@ NTSTATUS CMiniportWaveRTStream::SetCurrentWritePositionInternal(_In_ ULONG _ulC
}
PADAPTERCOMMON pAdapterComm = m_pMiniport->GetAdapterCommObj();
-
+
//Event type: eMINIPORT_SET_WAVERT_BUFFER_WRITE_POSITION
//Parameter 1: Current linear buffer position
//Parameter 2: the previous WaveRtBufferWritePosition that the drive received
@@ -846,20 +849,20 @@ NTSTATUS CMiniportWaveRTStream::SetCurrentWritePositionInternal(_In_ ULONG _ulC
m_ulCurrentWritePosition = _ulCurrentWritePosition;
InterlockedExchange(&m_IsCurrentWritePositionUpdated, 1);
-
+
return STATUS_SUCCESS;
}
-//linear position
-#pragma code_seg("PAGE")
-NTSTATUS CMiniportWaveRTStream::GetLinearBufferPosition(_Out_ ULONGLONG *_pullLinearBufferPosition, LARGE_INTEGER *_pliQPCTime)
+
+//linear and presentation positions
+#pragma code_seg()
+NTSTATUS CMiniportWaveRTStream::GetPositions(_Out_ ULONGLONG *_pullLinearBufferPosition, _Out_ ULONGLONG *_pullPresentationPosition, LARGE_INTEGER *_pliQPCTime)
{
- PAGED_CODE ();
ASSERT (_pullLinearBufferPosition);
- DPF_ENTER(("[CMiniportWaveRTStream::GetLinearBufferPosition]"));
+ DPF_ENTER(("[CMiniportWaveRTStream::GetPositions]"));
NTSTATUS ntStatus;
LARGE_INTEGER ilQPC;
-
+ KIRQL oldIrql;
#ifdef SYSVAD_BTH_BYPASS
if (m_ScoOpen)
{
@@ -875,16 +878,25 @@ NTSTATUS CMiniportWaveRTStream::GetLinearBufferPosition(_Out_ ULONGLONG *_pullL
//
// Get the current time and update position.
//
+ KeAcquireSpinLock(&m_PositionSpinLock, &oldIrql);
ilQPC = KeQueryPerformanceCounter(NULL);
if (m_KsState == KSSTATE_RUN)
{
UpdatePosition(ilQPC);
}
+ if (_pullLinearBufferPosition)
+ {
+ *_pullLinearBufferPosition = m_ullLinearPosition;
+ }
+ if (_pullPresentationPosition)
+ {
+ *_pullPresentationPosition = m_ullPresentationPosition;
+ }
+ KeReleaseSpinLock(&m_PositionSpinLock, oldIrql);
if (_pliQPCTime)
{
*_pliQPCTime = ilQPC;
}
- *_pullLinearBufferPosition = m_ullLinearPosition;
ntStatus = STATUS_SUCCESS;
@@ -931,7 +943,7 @@ NTSTATUS CMiniportWaveRTStream::SetLoopbackProtection(_In_ CONSTRICTOR_OPTION pr
return STATUS_SUCCESS;
}
-#pragma code_seg("PAGE")
+#pragma code_seg()
//----------------------------------------------------------------------------------
// Description:
// Set current write position for the very last buffer in a stream
@@ -960,12 +972,25 @@ NTSTATUS CMiniportWaveRTStream::SetLoopbackProtection(_In_ CONSTRICTOR_OPTION pr
NTSTATUS CMiniportWaveRTStream::SetStreamCurrentWritePositionForLastBuffer(_In_ ULONG _ulWritePosition)
{
- PAGED_CODE ();
DPF_ENTER(("[CMiniportWaveRT::SetStreamCurrentWritePositionForLastBuffer]"));
+ NTSTATUS ntStatus;
+ KIRQL oldIrql;
+
+ ASSERT(m_bEoSReceived == FALSE);
+
+ KeAcquireSpinLock(&m_PositionSpinLock, &oldIrql);
- return SetCurrentWritePositionInternal(_ulWritePosition);
// Miniport driver needs to prepare to signal buffer completion event
// when it's done with reading the last valid byte - an _ulWritePosition offset from the beginning WaveRT buffer
// Note: _ulWritePosition will be smaller than buffer size in most of the cases
+ ntStatus = SetCurrentWritePositionInternal(_ulWritePosition);
+ if (NT_SUCCESS(ntStatus))
+ {
+ m_bEoSReceived = TRUE;
+ }
+
+ KeReleaseSpinLock(&m_PositionSpinLock, oldIrql);
+
+ return ntStatus;
}
diff --git a/audio/sysvad/EndpointsCommon/bthhfpspeakerwavtable.h b/audio/sysvad/EndpointsCommon/bthhfpspeakerwavtable.h
index bab3d38a..68f23205 100644
--- a/audio/sysvad/EndpointsCommon/bthhfpspeakerwavtable.h
+++ b/audio/sysvad/EndpointsCommon/bthhfpspeakerwavtable.h
@@ -36,11 +36,11 @@ NTSTATUS PropertyHandler_BthHfpWaveFilter(_In_ PPCPROPERTY_REQUEST PropertyReque
#define BTHHFPSPEAKER_OFFLOAD_MIN_SAMPLE_RATE 8000 // Min Sample Rate
#define BTHHFPSPEAKER_OFFLOAD_MAX_SAMPLE_RATE 8000 // Max Sample Rate
-#define BTHHFPSPEAKER_LOOPBACK_MAX_CHANNELS 1 // Max Channels.
-#define BTHHFPSPEAKER_LOOPBACK_MIN_BITS_PER_SAMPLE 8 // Min Bits Per Sample
-#define BTHHFPSPEAKER_LOOPBACK_MAX_BITS_PER_SAMPLE 16 // Max Bits Per Sample
-#define BTHHFPSPEAKER_LOOPBACK_MIN_SAMPLE_RATE 8000 // Min Sample Rate
-#define BTHHFPSPEAKER_LOOPBACK_MAX_SAMPLE_RATE 8000 // Max Sample Rate
+#define BTHHFPSPEAKER_LOOPBACK_MAX_CHANNELS BTHHFPSPEAKER_HOST_MAX_CHANNELS // Must be equal to host pin's Max Channels.
+#define BTHHFPSPEAKER_LOOPBACK_MIN_BITS_PER_SAMPLE BTHHFPSPEAKER_HOST_MIN_BITS_PER_SAMPLE // Must be equal to host pin's Min Bits Per Sample
+#define BTHHFPSPEAKER_LOOPBACK_MAX_BITS_PER_SAMPLE BTHHFPSPEAKER_HOST_MAX_BITS_PER_SAMPLE // Must be equal to host pin's Max Bits Per Sample
+#define BTHHFPSPEAKER_LOOPBACK_MIN_SAMPLE_RATE BTHHFPSPEAKER_HOST_MIN_SAMPLE_RATE // Must be equal to host pin's Min Sample Rate
+#define BTHHFPSPEAKER_LOOPBACK_MAX_SAMPLE_RATE BTHHFPSPEAKER_HOST_MAX_SAMPLE_RATE // Must be equal to host pin's Max Sample Rate
#define BTHHFPSPEAKER_DOLBY_DIGITAL_MAX_CHANNELS 1 // Max Channels.
#define BTHHFPSPEAKER_DOLBY_DIGITAL_MIN_BITS_PER_SAMPLE 8 // Min Bits Per Sample
@@ -215,61 +215,6 @@ KSDATAFORMAT_WAVEFORMATEXTENSIBLE BthHfpSpeakerOffloadPinSupportedDeviceFormats[
}
};
-static
-KSDATAFORMAT_WAVEFORMATEXTENSIBLE BthHfpSpeakerLoopbackPinSupportedDeviceFormats[] =
-{
- { // 0
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 8000,
- 8000,
- 1,
- 8,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 8,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- { // 1
- {
- 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)
- }
- }
-};
-
//
// Supported modes (only on streaming pins).
//
@@ -314,8 +259,8 @@ PIN_DEVICE_FORMATS_AND_MODES BthHfpSpeakerPinDeviceFormatsAndModes[] =
},
{
RenderLoopbackPin,
- BthHfpSpeakerLoopbackPinSupportedDeviceFormats,
- SIZEOF_ARRAY(BthHfpSpeakerLoopbackPinSupportedDeviceFormats),
+ BthHfpSpeakerHostPinSupportedDeviceFormats, // Must support all the formats supported by host pin
+ SIZEOF_ARRAY(BthHfpSpeakerHostPinSupportedDeviceFormats),
NULL, // loopback doesn't support modes.
0
},
diff --git a/audio/sysvad/EndpointsCommon/bthhfpspeakerwbwavtable.h b/audio/sysvad/EndpointsCommon/bthhfpspeakerwbwavtable.h
index 1c491022..acff7c43 100644
--- a/audio/sysvad/EndpointsCommon/bthhfpspeakerwbwavtable.h
+++ b/audio/sysvad/EndpointsCommon/bthhfpspeakerwbwavtable.h
@@ -37,11 +37,11 @@ NTSTATUS PropertyHandler_BthHfpWaveFilter(_In_ PPCPROPERTY_REQUEST PropertyReque
#define BTHHFPSPEAKERWB_OFFLOAD_MIN_SAMPLE_RATE 8000 // Min Sample Rate
#define BTHHFPSPEAKERWB_OFFLOAD_MAX_SAMPLE_RATE 16000 // Max Sample Rate
-#define BTHHFPSPEAKERWB_LOOPBACK_MAX_CHANNELS 1 // Max Channels.
-#define BTHHFPSPEAKERWB_LOOPBACK_MIN_BITS_PER_SAMPLE 8 // Min Bits Per Sample
-#define BTHHFPSPEAKERWB_LOOPBACK_MAX_BITS_PER_SAMPLE 16 // Max Bits Per Sample
-#define BTHHFPSPEAKERWB_LOOPBACK_MIN_SAMPLE_RATE 8000 // Min Sample Rate
-#define BTHHFPSPEAKERWB_LOOPBACK_MAX_SAMPLE_RATE 16000 // Max Sample Rate
+#define BTHHFPSPEAKERWB_LOOPBACK_MAX_CHANNELS BTHHFPSPEAKERWB_HOST_MAX_CHANNELS // Must be equal to host pin's Max Channels.
+#define BTHHFPSPEAKERWB_LOOPBACK_MIN_BITS_PER_SAMPLE BTHHFPSPEAKERWB_HOST_MIN_BITS_PER_SAMPLE // Must be equal to host pin's Min Bits Per Sample
+#define BTHHFPSPEAKERWB_LOOPBACK_MAX_BITS_PER_SAMPLE BTHHFPSPEAKERWB_HOST_MAX_BITS_PER_SAMPLE // Must be equal to host pin's Max Bits Per Sample
+#define BTHHFPSPEAKERWB_LOOPBACK_MIN_SAMPLE_RATE BTHHFPSPEAKERWB_HOST_MIN_SAMPLE_RATE // Must be equal to host pin's Min Sample Rate
+#define BTHHFPSPEAKERWB_LOOPBACK_MAX_SAMPLE_RATE BTHHFPSPEAKERWB_HOST_MAX_SAMPLE_RATE // Must be equal to host pin's Max Sample Rate
#define BTHHFPSPEAKERWB_DOLBY_DIGITAL_MAX_CHANNELS 1 // Max Channels.
#define BTHHFPSPEAKERWB_DOLBY_DIGITAL_MIN_BITS_PER_SAMPLE 8 // Min Bits Per Sample
@@ -366,111 +366,6 @@ KSDATAFORMAT_WAVEFORMATEXTENSIBLE BthHfpSpeakerWBOffloadPinSupportedDeviceFormat
}
};
-static
-KSDATAFORMAT_WAVEFORMATEXTENSIBLE BthHfpSpeakerWBLoopbackPinSupportedDeviceFormats[] =
-{
- { // 0
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 8000,
- 8000,
- 1,
- 8,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 8,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- { // 1
- {
- 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)
- }
- },
- { // 2
- {
- sizeof(KSDATAFORMAT_WAVEFORMATEXTENSIBLE),
- 0,
- 0,
- 0,
- STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
- STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
- },
- {
- {
- WAVE_FORMAT_EXTENSIBLE,
- 1,
- 16000,
- 16000,
- 1,
- 8,
- sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)
- },
- 8,
- KSAUDIO_SPEAKER_MONO,
- STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM)
- }
- },
- { // 3
- {
- 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)
- }
- }
-};
-
//
// Supported modes (only on streaming pins).
//
@@ -515,8 +410,8 @@ PIN_DEVICE_FORMATS_AND_MODES BthHfpSpeakerWBPinDeviceFormatsAndModes[] =
},
{
RenderLoopbackPin,
- BthHfpSpeakerWBLoopbackPinSupportedDeviceFormats,
- SIZEOF_ARRAY(BthHfpSpeakerWBLoopbackPinSupportedDeviceFormats),
+ BthHfpSpeakerWBHostPinSupportedDeviceFormats, // Must support all the formats supported by host pin
+ SIZEOF_ARRAY(BthHfpSpeakerWBHostPinSupportedDeviceFormats),
NULL, // loopback doesn't support modes.
0
},
diff --git a/audio/sysvad/EndpointsCommon/micarray1toptable.h b/audio/sysvad/EndpointsCommon/micarray1toptable.h
index 26148eff..ee73c854 100644
--- a/audio/sysvad/EndpointsCommon/micarray1toptable.h
+++ b/audio/sysvad/EndpointsCommon/micarray1toptable.h
@@ -201,6 +201,18 @@ PCPROPERTY_ITEM MicArray1PropertiesTopoFilter[] =
KSPROPERTY_AUDIO_MIC_ARRAY_GEOMETRY,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_MicArrayTopoFilter
+ },
+ {
+ &KSPROPSETID_Audio,
+ KSPROPERTY_AUDIO_MIC_SENSITIVITY,
+ KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
+ PropertyHandler_MicArrayTopoFilter
+ },
+ {
+ &KSPROPSETID_Audio,
+ KSPROPERTY_AUDIO_MIC_SNR,
+ KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
+ PropertyHandler_MicArrayTopoFilter
}
};
diff --git a/audio/sysvad/EndpointsCommon/micarraytopo.cpp b/audio/sysvad/EndpointsCommon/micarraytopo.cpp
index 236d03ea..3316ee84 100644
--- a/audio/sysvad/EndpointsCommon/micarraytopo.cpp
+++ b/audio/sysvad/EndpointsCommon/micarraytopo.cpp
@@ -19,6 +19,14 @@ Abstract:
#include "micarraytopo.h"
#include "micarray1toptable.h"
+constexpr float MICARRAY_SENSITIVITY = -46.5f;
+constexpr float MICARRAY_SNR = 66.0f;
+
+constexpr inline LONG FloatToFixedPoint16_16(float fl)
+{
+ return (static_cast<LONG>((fl)* (65536.0f)));
+}
+
#pragma code_seg("PAGE")
//=============================================================================
@@ -498,6 +506,96 @@ Return Value:
//=============================================================================
NTSTATUS
+CMicArrayMiniportTopology::PropertyHandlerMicProperties
+(
+ _In_ PPCPROPERTY_REQUEST PropertyRequest
+)
+/*++
+
+Routine Description:
+
+Handles ( KSPROPSETID_Audio, KSPROPERTY_AUDIO_MIC_SENSITIVITY )
+Handles ( KSPROPSETID_Audio, KSPROPERTY_AUDIO_MIC_SNR )
+
+Arguments:
+
+PropertyRequest -
+
+Return Value:
+
+NT status code.
+
+--*/
+{
+ PAGED_CODE();
+
+ ASSERT(PropertyRequest);
+
+ DPF_ENTER(("[PropertyHandlerMicProperties]"));
+
+ NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
+ ULONG nPinId = (ULONG)-1;
+
+ if (PropertyRequest->InstanceSize >= sizeof(ULONG))
+ {
+ nPinId = *(PULONG(PropertyRequest->Instance));
+
+ if (nPinId == KSPIN_TOPO_MIC_ELEMENTS)
+ {
+ if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
+ {
+ ntStatus =
+ PropertyHandler_BasicSupport
+ (
+ PropertyRequest,
+ KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET,
+ VT_ILLEGAL
+ );
+ }
+ else
+ {
+ ntStatus =
+ ValidatePropertyParams
+ (
+ PropertyRequest,
+ sizeof(LONG),
+ 0
+ );
+
+ if (NT_SUCCESS(ntStatus))
+ {
+ if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
+ {
+ if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_MIC_SENSITIVITY)
+ {
+ LONG* micSensitivity = (LONG*)PropertyRequest->Value;
+ // Return microphone sensitivity information.
+ *micSensitivity = FloatToFixedPoint16_16(MICARRAY_SENSITIVITY); // convert float dBFS to fixed point arithmetic
+ PropertyRequest->ValueSize = sizeof(LONG);
+ ntStatus = STATUS_SUCCESS;
+ }
+ else if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_MIC_SNR)
+ {
+ LONG* micSNR = (LONG*)PropertyRequest->Value;
+ // Return microphone SNR information.
+ *micSNR = FloatToFixedPoint16_16(MICARRAY_SNR); // convert float dB to fixed point arithmetic
+ ntStatus = STATUS_SUCCESS;
+ }
+ }
+ else
+ {
+ ntStatus = STATUS_INVALID_DEVICE_REQUEST;
+ }
+ }
+ }
+ }
+ }
+
+ return ntStatus;
+}
+
+//=============================================================================
+NTSTATUS
CMicArrayMiniportTopology::PropertyHandlerJackDescription
(
_In_ PPCPROPERTY_REQUEST PropertyRequest
@@ -731,6 +829,14 @@ Return Value:
{
ntStatus = pMiniport->PropertyHandlerMicArrayGeometry(PropertyRequest);
}
+ else if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_MIC_SENSITIVITY)
+ {
+ ntStatus = pMiniport->PropertyHandlerMicProperties(PropertyRequest);
+ }
+ else if (PropertyRequest->PropertyItem->Id == KSPROPERTY_AUDIO_MIC_SNR)
+ {
+ ntStatus = pMiniport->PropertyHandlerMicProperties(PropertyRequest);
+ }
}
else if (IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_Jack))
{
diff --git a/audio/sysvad/EndpointsCommon/micarraytopo.h b/audio/sysvad/EndpointsCommon/micarraytopo.h
index 8076a359..41f9a792 100644
--- a/audio/sysvad/EndpointsCommon/micarraytopo.h
+++ b/audio/sysvad/EndpointsCommon/micarraytopo.h
@@ -58,6 +58,11 @@ class CMicArrayMiniportTopology :
_In_ PPCPROPERTY_REQUEST PropertyRequest
);
+ NTSTATUS PropertyHandlerMicProperties
+ (
+ _In_ PPCPROPERTY_REQUEST PropertyRequest
+ );
+
NTSTATUS PropertyHandlerJackDescription
(
_In_ PPCPROPERTY_REQUEST PropertyRequest
diff --git a/audio/sysvad/EndpointsCommon/micarraywavtable.h b/audio/sysvad/EndpointsCommon/micarraywavtable.h
index fb553d67..3b6c2df0 100644
--- a/audio/sysvad/EndpointsCommon/micarraywavtable.h
+++ b/audio/sysvad/EndpointsCommon/micarraywavtable.h
@@ -30,7 +30,7 @@ Abstract:
//
// Max # of pin instances.
//
-#define MICARRAY_MAX_INPUT_STREAMS 2 // Raw + Default streams
+#define MICARRAY_MAX_INPUT_STREAMS 4
//=============================================================================
static
@@ -538,11 +538,29 @@ KSDATARANGE_AUDIO MicArrayPinDataRangesProcessedStream[] =
},
};
+// if MicArrayPinDataRangesProcessedStream is changed, we MUST update MicArrayPinDataRangePointersStream too!
+C_ASSERT(SIZEOF_ARRAY(MicArrayPinDataRangesProcessedStream) == 8);
+
static
PKSDATARANGE MicArrayPinDataRangePointersStream[] =
{
+ // All supported device formats should be listed in the DataRange.
PKSDATARANGE(&MicArrayPinDataRangesProcessedStream[0]),
PKSDATARANGE(&PinDataRangeAttributeList),
+ PKSDATARANGE(&MicArrayPinDataRangesProcessedStream[1]),
+ PKSDATARANGE(&PinDataRangeAttributeList),
+ PKSDATARANGE(&MicArrayPinDataRangesProcessedStream[2]),
+ PKSDATARANGE(&PinDataRangeAttributeList),
+ PKSDATARANGE(&MicArrayPinDataRangesProcessedStream[3]),
+ PKSDATARANGE(&PinDataRangeAttributeList),
+ PKSDATARANGE(&MicArrayPinDataRangesProcessedStream[4]),
+ PKSDATARANGE(&PinDataRangeAttributeList),
+ PKSDATARANGE(&MicArrayPinDataRangesProcessedStream[5]),
+ PKSDATARANGE(&PinDataRangeAttributeList),
+ PKSDATARANGE(&MicArrayPinDataRangesProcessedStream[6]),
+ PKSDATARANGE(&PinDataRangeAttributeList),
+ PKSDATARANGE(&MicArrayPinDataRangesProcessedStream[7]),
+ PKSDATARANGE(&PinDataRangeAttributeList),
PKSDATARANGE(&MicArrayPinDataRangesRawStream[0]),
PKSDATARANGE(&PinDataRangeAttributeList),
};
diff --git a/audio/sysvad/EndpointsCommon/mintopo.cpp b/audio/sysvad/EndpointsCommon/mintopo.cpp
index 47a89cac..42e61868 100644
--- a/audio/sysvad/EndpointsCommon/mintopo.cpp
+++ b/audio/sysvad/EndpointsCommon/mintopo.cpp
@@ -134,6 +134,8 @@ Return Value:
SAFE_RELEASE(m_BthHfpDevice); // IBthHfpDeviceCommon
}
#endif // SYSVAD_BTH_BYPASS
+
+
} // ~CMiniportTopology
//=============================================================================
@@ -729,3 +731,18 @@ Return Value:
#pragma code_seg()
+//=============================================================================
+NTSTATUS CMiniportTopology_EventHandler_JackState
+(
+ _In_ PPCEVENT_REQUEST EventRequest
+)
+{
+ CMiniportTopology* miniport = reinterpret_cast<CMiniportTopology*>(EventRequest->MajorTarget);
+ if (EventRequest->Verb == PCEVENT_VERB_ADD)
+ {
+ miniport->AddEventToEventList(EventRequest->EventEntry);
+ }
+ return STATUS_SUCCESS;
+}
+
+
diff --git a/audio/sysvad/EndpointsCommon/mintopo.h b/audio/sysvad/EndpointsCommon/mintopo.h
index e232e1d7..e73cdd04 100644
--- a/audio/sysvad/EndpointsCommon/mintopo.h
+++ b/audio/sysvad/EndpointsCommon/mintopo.h
@@ -137,9 +137,16 @@ public:
_In_opt_ PVOID Context
);
#endif // SYSVAD_BTH_BYPASS
+
+ PVOID GetDeviceContext() { return m_DeviceContext; }
};
typedef CMiniportTopology *PCMiniportTopology;
+NTSTATUS CMiniportTopology_EventHandler_JackState
+(
+ _In_ PPCEVENT_REQUEST EventRequest
+);
+
#endif // _SYSVAD_MINTOPO_H_
diff --git a/audio/sysvad/EndpointsCommon/minwavert.cpp b/audio/sysvad/EndpointsCommon/minwavert.cpp
index 843706b1..7d021767 100644
--- a/audio/sysvad/EndpointsCommon/minwavert.cpp
+++ b/audio/sysvad/EndpointsCommon/minwavert.cpp
@@ -185,6 +185,7 @@ Return Value:
SAFE_RELEASE(m_BthHfpDevice);
}
#endif // SYSVAD_BTH_BYPASS
+
} // ~CMiniportWaveRT
//=============================================================================
@@ -1293,6 +1294,7 @@ CMiniportWaveRT::PropertyHandlerProposedFormat
return ntStatus;
} // PropertyHandlerProposedFormat
+
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
@@ -1460,9 +1462,6 @@ CMiniportWaveRT::PropertyHandlerProposedFormat2
return STATUS_SUCCESS;
} // PropertyHandlerProposedFormat
-
-
-
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
@@ -1483,7 +1482,7 @@ CMiniportWaveRT::PropertyHandlerEffectListRequest
// This specific APO->driver communication example is mainly added to show to this communication is done.
// It skips the pin id validation and returns pin specific answers to the caller, which a real miniport
- // audio driver probably needs to tate care of.
+ // audio driver probably needs to take care of.
// Handle KSPROPERTY_TYPE_BASICSUPPORT query
if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
@@ -1535,6 +1534,7 @@ CMiniportWaveRT::PropertyHandlerEffectListRequest
return STATUS_INVALID_DEVICE_REQUEST;
} // PropertyHandlerEffectListRequest
+
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
diff --git a/audio/sysvad/EndpointsCommon/minwavert.h b/audio/sysvad/EndpointsCommon/minwavert.h
index c30faa2d..aea83095 100644
--- a/audio/sysvad/EndpointsCommon/minwavert.h
+++ b/audio/sysvad/EndpointsCommon/minwavert.h
@@ -155,6 +155,7 @@ protected:
PPORTEVENTS m_pPortEvents;
PENDPOINT_MINIPAIR m_pMiniportPair;
+
public:
DECLARE_PROPERTYHANDLER(Get_SoundDetectorSupportedPatterns);
DECLARE_PROPERTYHANDLER(Set_SoundDetectorPatterns);
@@ -264,7 +265,8 @@ public:
}
}
}
-
+
+
#ifdef SYSVAD_BTH_BYPASS
if (IsBthHfpDevice())
{
diff --git a/audio/sysvad/EndpointsCommon/minwavertstream.cpp b/audio/sysvad/EndpointsCommon/minwavertstream.cpp
index a343efa7..86d373da 100644
--- a/audio/sysvad/EndpointsCommon/minwavertstream.cpp
+++ b/audio/sysvad/EndpointsCommon/minwavertstream.cpp
@@ -162,20 +162,25 @@ Return Value:
m_ullWritePosition = 0;
m_ullDmaTimeStamp = 0;
m_hnsElapsedTimeCarryForward = 0;
+ m_ullLastDPCTimeStamp = 0;
+ m_hnsDPCTimeCarryForward = 0;
m_ulDmaMovementRate = 0;
+ m_byteDisplacementCarryForward = 0;
m_bLfxEnabled = FALSE;
m_pbMuted = NULL;
m_plVolumeLevel = NULL;
m_plPeakMeter = NULL;
m_pWfExt = NULL;
m_ullLinearPosition = 0;
+ m_ullPresentationPosition = 0;
m_ulContentId = 0;
m_ulCurrentWritePosition = 0;
m_ulLastOsReadPacket = ULONG_MAX;
m_ulLastOsWritePacket = ULONG_MAX;
- m_llEoSPosition = (-1);
m_IsCurrentWritePositionUpdated = 0;
m_SignalProcessingMode = SignalProcessingMode;
+ m_bEoSReceived = FALSE;
+ m_bLastBufferRendered = FALSE;
#ifdef SYSVAD_BTH_BYPASS
m_ScoOpen = FALSE;
@@ -185,6 +190,9 @@ Return Value:
InitializeListHead(&m_NotificationList);
m_ulNotificationIntervalMs = 0;
+ // Initialize the spinlock to synchronize position updates
+ KeInitializeSpinLock(&m_PositionSpinLock);
+
m_pNotificationDpc = (PRKDPC)ExAllocatePoolWithTag(
NonPagedPoolNx,
sizeof(KDPC),
@@ -426,7 +434,9 @@ NTSTATUS CMiniportWaveRTStream::AllocateBufferWithNotification
{
NTSTATUS ntStatus;
- ntStatus = m_SaveData.SetMaxWriteSize(RequestedSize_);
+ // Sysvad uses following buffer to hold data before writing to a file.
+ // Allocating larger buffer will reduce File I/O operations.
+ ntStatus = m_SaveData.SetMaxWriteSize(RequestedSize_ * 4);
if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
@@ -524,6 +534,7 @@ NTSTATUS CMiniportWaveRTStream::RegisterNotificationEvent
nleNew->NotificationEvent = NotificationEvent_;
+ // Fail if the notification event already exists in our list.
if (!IsListEmpty(&m_NotificationList))
{
PLIST_ENTRY leCurrent = m_NotificationList.Flink;
@@ -532,7 +543,6 @@ NTSTATUS CMiniportWaveRTStream::RegisterNotificationEvent
NotificationListEntry* nleCurrent = CONTAINING_RECORD( leCurrent, NotificationListEntry, ListEntry);
if (nleCurrent->NotificationEvent == NotificationEvent_)
{
- RemoveEntryList( leCurrent );
ExFreePoolWithTag( nleNew, MINWAVERTSTREAM_POOLTAG );
return STATUS_UNSUCCESSFUL;
}
@@ -731,6 +741,9 @@ NTSTATUS CMiniportWaveRTStream::GetPosition
return STATUS_NOT_SUPPORTED;
}
+ KIRQL oldIrql;
+ KeAcquireSpinLock(&m_PositionSpinLock, &oldIrql);
+
if (m_KsState == KSSTATE_RUN)
{
//
@@ -743,6 +756,8 @@ NTSTATUS CMiniportWaveRTStream::GetPosition
Position_->PlayOffset = m_ullPlayPosition;
Position_->WriteOffset = m_ullWritePosition;
+ KeReleaseSpinLock(&m_PositionSpinLock, oldIrql);
+
ntStatus = STATUS_SUCCESS;
#ifdef SYSVAD_BTH_BYPASS
@@ -807,19 +822,19 @@ NTSTATUS CMiniportWaveRTStream::GetReadPacket
return ntStatus;
}
- if (m_KsState == KSSTATE_RUN)
- {
- //
- // Get the current time and update simulated position.
- //
- LARGE_INTEGER ilQPC = KeQueryPerformanceCounter(NULL);
+ KIRQL oldIrql;
+ KeAcquireSpinLock(&m_PositionSpinLock, &oldIrql);
- UpdatePosition(ilQPC);
- }
+ LONGLONG packetCounter = m_llPacketCounter;
+ ULONGLONG ullLinearPosition = m_ullLinearPosition;
+ ULONGLONG hnsElapsedTimeCarryForward = m_hnsElapsedTimeCarryForward;
+ ULONGLONG ullDmaTimeStamp = m_ullDmaTimeStamp;
+
+ KeReleaseSpinLock(&m_PositionSpinLock, oldIrql);
// The 0-based number of the last completed packet
// FUTURE-2014/10/27 Update to allow different numbers of packets per WaveRT buffer
- availablePacketNumber = LODWORD(m_llPacketCounter - 1); // Note this might be ULONG_MAX if called during the first packet
+ availablePacketNumber = LODWORD(packetCounter - 1); // Note this might be ULONG_MAX if called during the first packet
// If no new packets are available...
if (availablePacketNumber == m_ulLastOsReadPacket)
@@ -843,10 +858,12 @@ NTSTATUS CMiniportWaveRTStream::GetReadPacket
// driver, it is extrapolated from the sample driver's internal simulated position corrleation
// [m_ullLinearPosition @ m_ullDmaTimeStamp] and the sample's internal 64-bit packet counter, subtracting
// 1 from the packet counter to compute the time at the start of that last completed packet.
- ULONGLONG linearPositionOfAvailablePacket = (m_llPacketCounter - 1) * (m_ulDmaBufferSize / m_ulNotificationsPerBuffer);
- ULONGLONG deltaLinearPosition = m_ullLinearPosition - linearPositionOfAvailablePacket;
+ ULONGLONG linearPositionOfAvailablePacket = (packetCounter - 1) * (m_ulDmaBufferSize / m_ulNotificationsPerBuffer);
+ // Need to divide by (1000 * 10000 because m_ulDmaMovementRate is average bytes per sec
+ ULONGLONG carryForwardBytes = (hnsElapsedTimeCarryForward * m_ulDmaMovementRate) / 10000000;
+ ULONGLONG deltaLinearPosition = ullLinearPosition + carryForwardBytes - linearPositionOfAvailablePacket;
ULONGLONG deltaTimeInHns = deltaLinearPosition * 10000000 / m_ulDmaMovementRate;
- ULONGLONG timeOfAvailablePacketInHns = m_ullDmaTimeStamp - deltaTimeInHns;
+ ULONGLONG timeOfAvailablePacketInHns = ullDmaTimeStamp - deltaTimeInHns;
ULONGLONG timeOfAvailablePacketInQpc = timeOfAvailablePacketInHns * m_ullPerformanceCounterFrequency.QuadPart / 10000000;
*PerformanceCounterValue = timeOfAvailablePacketInQpc;
@@ -882,9 +899,9 @@ NTSTATUS CMiniportWaveRTStream::GetReadPacket
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS CMiniportWaveRTStream::SetWritePacket
(
-_In_ ULONG PacketNumber,
-_In_ DWORD Flags,
-_In_ ULONG EosPacketLength
+ _In_ ULONG PacketNumber,
+ _In_ DWORD Flags,
+ _In_ ULONG EosPacketLength
)
{
NTSTATUS ntStatus;
@@ -898,21 +915,16 @@ _In_ ULONG EosPacketLength
ULONG oldLastOsWritePacket = m_ulLastOsWritePacket;
// This function should not be called once EoS has been set.
- if (m_llEoSPosition >= 0)
+ if (m_bEoSReceived)
{
return STATUS_INVALID_DEVICE_STATE;
}
- // Update linear positions
- if (m_KsState == KSSTATE_RUN)
- {
- // Get the current time and update simulated position.
- LARGE_INTEGER ilQPC = KeQueryPerformanceCounter(NULL);
- UpdatePosition(ilQPC);
- }
-
+ KIRQL oldIrql;
+ KeAcquireSpinLock(&m_PositionSpinLock, &oldIrql);
// 1-based count of completed packets, 0-based packet number of current packet
LONGLONG currentPacket = m_llPacketCounter;
+ KeReleaseSpinLock(&m_PositionSpinLock, oldIrql);
// If not running, the current packet hasn't actually started transfering so OS should be writing
// to the current packet. If running, then the current packing is already transfering to hardware
@@ -949,7 +961,7 @@ _In_ ULONG EosPacketLength
// EOS position will be after the total completed packets, plus the packet in progress,
// plus this EOS packet length
m_ulLastOsWritePacket = PacketNumber;
- m_llEoSPosition = ((m_llPacketCounter + 1) * packetSize) + EosPacketLength;
+ ulCurrentWritePosition += EosPacketLength;
ntStatus = SetStreamCurrentWritePositionForLastBuffer(ulCurrentWritePosition);
}
}
@@ -962,12 +974,13 @@ _In_ ULONG EosPacketLength
// Will not return an error when the passed in parameter is 0.
// Will also check if this function was called with the same write position(in event mode only)
// Underruning will also be checked via timer mechanism
+ KeAcquireSpinLock(&m_PositionSpinLock, &oldIrql);
ntStatus = SetCurrentWritePositionInternal(ulCurrentWritePosition);
+ KeReleaseSpinLock(&m_PositionSpinLock, oldIrql);
}
if (!NT_SUCCESS(ntStatus))
{
- m_llEoSPosition = (-1);
m_ulLastOsWritePacket = oldLastOsWritePacket;
}
@@ -1002,13 +1015,16 @@ NTSTATUS CMiniportWaveRTStream::GetPacketCount
)
{
ASSERT(pPacketCount);
-
+
// The call must be from event driven mode
if(m_ulNotificationsPerBuffer == 0)
{
return STATUS_NOT_SUPPORTED;
}
+ KIRQL oldIrql;
+ KeAcquireSpinLock(&m_PositionSpinLock, &oldIrql);
+
if (m_KsState == KSSTATE_RUN)
{
// Get the current time and update simulated position.
@@ -1017,49 +1033,54 @@ NTSTATUS CMiniportWaveRTStream::GetPacketCount
}
*pPacketCount = LODWORD(m_llPacketCounter);
+ KeReleaseSpinLock(&m_PositionSpinLock, oldIrql);
return STATUS_SUCCESS;
}
//=============================================================================
-#pragma code_seg("PAGE")
+#pragma code_seg()
NTSTATUS CMiniportWaveRTStream::SetState
(
_In_ KSSTATE State_
)
{
- PAGED_CODE();
-
NTSTATUS ntStatus = STATUS_SUCCESS;
PADAPTERCOMMON pAdapterComm = m_pMiniport->GetAdapterCommObj();
+ KIRQL oldIrql;
// Spew an event for a pin state change request from portcls
//Event type: eMINIPORT_PIN_STATE
- //Parameter 1: Current linear buffer position
- //Parameter 2: Current WaveRtBufferWritePosition
+ //Parameter 1: Current linear buffer position
+ //Parameter 2: Current WaveRtBufferWritePosition
//Parameter 3: Pin State 0->KS_STOP, 1->KS_ACQUIRE, 2->KS_PAUSE, 3->KS_RUN
//Parameter 4:0
pAdapterComm->WriteEtwEvent(eMINIPORT_PIN_STATE,
- 100, // replace with the correct "Current linear buffer position"
- m_ulCurrentWritePosition, // replace with the previous WaveRtBufferWritePosition that the drive received
- State_, // repalce with the correct "Data length completed"
+ 100, // replace with the correct "Current linear buffer position"
+ m_ulCurrentWritePosition, // replace with the previous WaveRtBufferWritePosition that the driver received
+ State_, // replace with the correct "Data length completed"
0); // always zero
switch (State_)
{
case KSSTATE_STOP:
+ KeAcquireSpinLock(&m_PositionSpinLock, &oldIrql);
// Reset DMA
m_llPacketCounter = 0;
m_ullPlayPosition = 0;
m_ullWritePosition = 0;
m_ullLinearPosition = 0;
+ m_ullPresentationPosition = 0;
// Reset OS read/write positions
m_ulLastOsReadPacket = ULONG_MAX;
m_ulCurrentWritePosition = 0;
m_ulLastOsWritePacket = ULONG_MAX;
- m_llEoSPosition = (-1);
-
+ m_bEoSReceived = FALSE;
+ m_bLastBufferRendered = FALSE;
+
+ KeReleaseSpinLock(&m_PositionSpinLock, oldIrql);
+
// Wait until all work items are completed.
if (!m_bCapture && !g_DoNotCreateDataFiles)
{
@@ -1116,7 +1137,6 @@ NTSTATUS CMiniportWaveRTStream::SetState
break;
case KSSTATE_PAUSE:
- ULONGLONG ullPositionTemp;
if (m_KsState > KSSTATE_PAUSE)
{
@@ -1136,9 +1156,8 @@ NTSTATUS CMiniportWaveRTStream::SetState
KeFlushQueuedDpcs();
}
}
-
- // This call updates the linear buffer position.
- GetLinearBufferPosition(&ullPositionTemp, NULL);
+ // This call updates the linear buffer and presentation positions.
+ GetPositions(NULL, NULL, NULL);
break;
case KSSTATE_RUN:
@@ -1149,23 +1168,24 @@ NTSTATUS CMiniportWaveRTStream::SetState
m_pMiniport->m_KeywordDetector.Run();
}
ullPerfCounterTemp = KeQueryPerformanceCounter(&m_ullPerformanceCounterFrequency);
- m_ullDmaTimeStamp = KSCONVERT_PERFORMANCE_TIME(m_ullPerformanceCounterFrequency.QuadPart, ullPerfCounterTemp);
- m_hnsElapsedTimeCarryForward = 0;
+ m_ullLastDPCTimeStamp = m_ullDmaTimeStamp = KSCONVERT_PERFORMANCE_TIME(m_ullPerformanceCounterFrequency.QuadPart, ullPerfCounterTemp);
if (m_ulNotificationIntervalMs > 0)
{
LARGE_INTEGER delay;
- delay.QuadPart = (-2) * (((LONGLONG)m_ulNotificationIntervalMs) * HNSTIME_PER_MILLISECOND);
+ delay.QuadPart = (-1) * HNSTIME_PER_MILLISECOND;
- // ISSUE-2014/10/20 Set resolution based on packet size
ExSetTimerResolution(HNSTIME_PER_MILLISECOND, TRUE);
-
+ // Set timer for 1 ms. This will cause DPC to run every 1 ms but driver will send out
+ // notification events only after notification interval. This timer is used by Sysvad to
+ // emulate hardware and send out notification event. Real hardware should not use this
+ // timer to fire notification event as it will drain power if the timer is running at 1 msec.
KeSetTimerEx
(
m_pNotificationTimer,
delay,
- m_ulNotificationIntervalMs,
+ 1, // 1 ms
m_pNotificationDpc
);
}
@@ -1228,22 +1248,44 @@ VOID CMiniportWaveRTStream::UpdatePosition
// lose some bytes, so we will carry the remainder forward to the next GetPosition() call.
//
// need to divide by 1000 because m_ulDmaMovementRate is average bytes per sec.
- ULONG ByteDisplacement = (m_ulDmaMovementRate * TimeElapsedInMS) / 1000;
-
+
+ ULONG ByteDisplacement = ((m_ulDmaMovementRate * TimeElapsedInMS) + m_byteDisplacementCarryForward) / 1000 ;
+ m_byteDisplacementCarryForward = ((m_ulDmaMovementRate * TimeElapsedInMS) + m_byteDisplacementCarryForward) % 1000;
+
+ // Increment presentation position even after last buffer is rendered.
+ m_ullPresentationPosition += ByteDisplacement;
+
if (m_bCapture)
{
// Write sine wave to buffer.
WriteBytes(ByteDisplacement);
}
- else if (!g_DoNotCreateDataFiles)
+ else
{
- // Read from buffer and write to a file.
- ReadBytes(ByteDisplacement);
-
+ if (m_bEoSReceived)
+ {
+ // since EoS flag is set, we'll need to make sure not to read data beyond EOS position.
+ // If driver's current position is less than EoS position, then make sure not to read data beyond EoS.
+ if (m_ullWritePosition <= m_ulCurrentWritePosition)
+ {
+ ByteDisplacement = min(ByteDisplacement, m_ulCurrentWritePosition - (ULONG)m_ullWritePosition);
+ }
+ // If our current position is ahead of EoS position and we'll wrap around after new position then adjust
+ // new position if it crosses EoS.
+ else if ((m_ullWritePosition + ByteDisplacement) % m_ulDmaBufferSize < m_ullWritePosition)
+ {
+ if ((m_ullWritePosition + ByteDisplacement) % m_ulDmaBufferSize > m_ulCurrentWritePosition)
+ {
+ ByteDisplacement = ByteDisplacement - (((ULONG)m_ullWritePosition + ByteDisplacement) % m_ulDmaBufferSize - m_ulCurrentWritePosition);
+ }
+ }
+ }
+
// If the last packet was rendered(read in the sample driver's case), send out an etw event.
- if ( (m_llEoSPosition >= 0)
- && ((m_llEoSPosition - m_ullLinearPosition) < ByteDisplacement))
+ if ( m_bEoSReceived && !m_bLastBufferRendered
+ && (m_ullWritePosition + ByteDisplacement) % m_ulDmaBufferSize == m_ulCurrentWritePosition)
{
+ m_bLastBufferRendered = TRUE;
PADAPTERCOMMON pAdapterComm = m_pMiniport->GetAdapterCommObj();
pAdapterComm->WriteEtwEvent(eMINIPORT_LAST_BUFFER_RENDERED,
m_ullLinearPosition + ByteDisplacement, // Current linear buffer position
@@ -1251,6 +1293,12 @@ VOID CMiniportWaveRTStream::UpdatePosition
0,
0);
}
+
+ if (!g_DoNotCreateDataFiles)
+ {
+ // Read from buffer and write to a file.
+ ReadBytes(ByteDisplacement);
+ }
}
// Increment the DMA position by the number of bytes displaced since the last
@@ -1273,7 +1321,7 @@ VOID CMiniportWaveRTStream::UpdatePosition
#pragma code_seg()
VOID CMiniportWaveRTStream::WriteBytes
(
-_In_ ULONG ByteDisplacement
+ _In_ ULONG ByteDisplacement
)
/*++
@@ -1304,7 +1352,7 @@ ByteDisplacement - # of bytes to process.
#pragma code_seg()
VOID CMiniportWaveRTStream::ReadBytes
(
-_In_ ULONG ByteDisplacement
+ _In_ ULONG ByteDisplacement
)
/*++
@@ -1490,14 +1538,39 @@ TimerNotifyRT
return;
}
- InterlockedIncrement64(&_this->m_llPacketCounter);
+ KIRQL oldIrql;
+ KeAcquireSpinLock(&_this->m_PositionSpinLock, &oldIrql);
+ // Convert ticks to 100ns units.
+ LONGLONG hnsCurrentTime = KSCONVERT_PERFORMANCE_TIME(_this->m_ullPerformanceCounterFrequency.QuadPart, qpc);
+
+ // Calculate the time elapsed since the last we ran DPC that matched Notification interval. Note that the division by 10000
+ // to convert to milliseconds may cause us to lose some of the time, so we will carry the remainder forward.
+
+ ULONG TimeElapsedInMS = (ULONG)(hnsCurrentTime - _this->m_ullLastDPCTimeStamp + _this->m_hnsDPCTimeCarryForward)/10000;
+
+ if (TimeElapsedInMS < _this->m_ulNotificationIntervalMs && !_this->m_bEoSReceived)
+ {
+ goto End;
+ }
+
+ // Carry forward the remainder of this division
+ _this->m_hnsDPCTimeCarryForward = (hnsCurrentTime - _this->m_ullLastDPCTimeStamp + _this->m_hnsDPCTimeCarryForward) % 10000;
+ // Save the last time DPC ran at notification interval
+ _this->m_ullLastDPCTimeStamp = (ULONG)hnsCurrentTime;
+
+ _this->UpdatePosition(qpc);
+
+ if (!_this->m_bEoSReceived)
+ {
+ _this->m_llPacketCounter++;
+ }
#ifdef SYSVAD_BTH_BYPASS
if (_this->m_ScoOpen)
{
if (!NT_SUCCESS(_this->GetScoStreamNtStatus()))
{
- return;
+ goto End;
}
}
#endif // SYSVAD_BTH_BYPASS
@@ -1506,13 +1579,13 @@ TimerNotifyRT
if (_this->m_KsState != KSSTATE_RUN)
{
- return;
+ goto End;
}
PADAPTERCOMMON pAdapterComm = _this->m_pMiniport->GetAdapterCommObj();
// Simple buffer underrun detection.
- if (!_this->IsCurrentWaveRTWritePositionUpdated())
+ if (!_this->IsCurrentWaveRTWritePositionUpdated() && !_this->m_bEoSReceived)
{
//Event type: eMINIPORT_GLITCH_REPORT
//Parameter 1: Current linear buffer position
@@ -1526,21 +1599,23 @@ TimerNotifyRT
0);
}
- if (!IsListEmpty(&_this->m_NotificationList))
+ if (!IsListEmpty(&_this->m_NotificationList) &&
+ (TimeElapsedInMS >= _this->m_ulNotificationIntervalMs || _this->m_bLastBufferRendered))
{
PLIST_ENTRY leCurrent = _this->m_NotificationList.Flink;
while (leCurrent != &_this->m_NotificationList)
{
NotificationListEntry* nleCurrent = CONTAINING_RECORD( leCurrent, NotificationListEntry, ListEntry);
//Event type: eMINIPORT_BUFFER_COMPLETE
- //Parameter 1: Current linear buffer position
- //Parameter 2: the previous WaveRtBufferWritePosition that the drive received
- //Parameter 3: Data length completed
+ //Parameter 1: Current linear buffer position
+ //Parameter 2: the previous WaveRtBufferWritePosition that the driver received
+ //Parameter 3: Data length completed
//Parameter 4:0
+
pAdapterComm->WriteEtwEvent(eMINIPORT_BUFFER_COMPLETE,
- 100, // replace with the correct "Current linear buffer position"
- _this->GetCurrentWaveRTWritePosition(),
- 300, // repalce with the correct "Data length completed"
+ 100, // replace with the correct "Current linear buffer position"
+ _this->GetCurrentWaveRTWritePosition(),
+ 300, // replace with the correct "Data length completed"
0); // always zero
KeSetEvent(nleCurrent->NotificationEvent, 0, 0);
@@ -1548,6 +1623,15 @@ TimerNotifyRT
leCurrent = leCurrent->Flink;
}
}
+
+ if (_this->m_bLastBufferRendered)
+ {
+ KeCancelTimer(_this->m_pNotificationTimer);
+ }
+
+End:
+ KeReleaseSpinLock(&_this->m_PositionSpinLock, oldIrql);
+ return;
}
//=============================================================================
diff --git a/audio/sysvad/EndpointsCommon/minwavertstream.h b/audio/sysvad/EndpointsCommon/minwavertstream.h
index 78be0e15..c429956d 100644
--- a/audio/sysvad/EndpointsCommon/minwavertstream.h
+++ b/audio/sysvad/EndpointsCommon/minwavertstream.h
@@ -102,13 +102,16 @@ protected:
ULONGLONG m_ullPlayPosition;
ULONGLONG m_ullWritePosition;
ULONGLONG m_ullLinearPosition;
+ ULONGLONG m_ullPresentationPosition;
ULONG m_ulLastOsReadPacket;
ULONG m_ulLastOsWritePacket;
- LONGLONG m_llEoSPosition;
LONGLONG m_llPacketCounter;
ULONGLONG m_ullDmaTimeStamp;
LARGE_INTEGER m_ullPerformanceCounterFrequency;
ULONGLONG m_hnsElapsedTimeCarryForward;
+ ULONGLONG m_ullLastDPCTimeStamp;
+ ULONGLONG m_hnsDPCTimeCarryForward;
+ ULONG m_byteDisplacementCarryForward;
ULONG m_ulDmaMovementRate;
BOOL m_bLfxEnabled;
PBOOL m_pbMuted;
@@ -119,6 +122,9 @@ protected:
CSaveData m_SaveData;
ToneGenerator m_ToneGenerator;
GUID m_SignalProcessingMode;
+ BOOLEAN m_bEoSReceived;
+ BOOLEAN m_bLastBufferRendered;
+ KSPIN_LOCK m_PositionSpinLock;
#ifdef SYSVAD_BTH_BYPASS
BOOLEAN m_ScoOpen;
@@ -245,9 +251,10 @@ private:
_In_ ULONG ulCurrentWritePosition
);
- NTSTATUS GetLinearBufferPosition
+ NTSTATUS GetPositions
(
_Out_ ULONGLONG *pullLinearBufferPosition,
+ _Out_ ULONGLONG *pullPresentationPosition,
_Out_ LARGE_INTEGER *_pliQPCTime
);
diff --git a/audio/sysvad/EndpointsCommon/speakerhpwavtable.h b/audio/sysvad/EndpointsCommon/speakerhpwavtable.h
index 2b5b61ed..2f36ac06 100644
--- a/audio/sysvad/EndpointsCommon/speakerhpwavtable.h
+++ b/audio/sysvad/EndpointsCommon/speakerhpwavtable.h
@@ -32,11 +32,11 @@ Abstract:
#define SPEAKERHP_OFFLOAD_MIN_SAMPLE_RATE 44100 // Min Sample Rate
#define SPEAKERHP_OFFLOAD_MAX_SAMPLE_RATE 48000 // Max Sample Rate
-#define SPEAKERHP_LOOPBACK_MAX_CHANNELS 2 // Max Channels.
-#define SPEAKERHP_LOOPBACK_MIN_BITS_PER_SAMPLE 16 // Min Bits Per Sample
-#define SPEAKERHP_LOOPBACK_MAX_BITS_PER_SAMPLE 16 // Max Bits Per Sample
-#define SPEAKERHP_LOOPBACK_MIN_SAMPLE_RATE 24000 // Min Sample Rate
-#define SPEAKERHP_LOOPBACK_MAX_SAMPLE_RATE 48000 // Max Sample Rate
+#define SPEAKERHP_LOOPBACK_MAX_CHANNELS SPEAKERHP_HOST_MAX_CHANNELS // Must be equal to host pin's Max Channels.
+#define SPEAKERHP_LOOPBACK_MIN_BITS_PER_SAMPLE SPEAKERHP_HOST_MIN_BITS_PER_SAMPLE // Must be equal to host pin's Min Bits Per Sample
+#define SPEAKERHP_LOOPBACK_MAX_BITS_PER_SAMPLE SPEAKERHP_HOST_MAX_BITS_PER_SAMPLE // Must be equal to host pin's Max Bits Per Sample
+#define SPEAKERHP_LOOPBACK_MIN_SAMPLE_RATE SPEAKERHP_HOST_MIN_SAMPLE_RATE // Must be equal to host pin's Min Sample Rate
+#define SPEAKERHP_LOOPBACK_MAX_SAMPLE_RATE SPEAKERHP_HOST_MAX_SAMPLE_RATE // Must be equal to host pin's Max Sample Rate
#define SPEAKERHP_DOLBY_DIGITAL_MAX_CHANNELS 2 // Max Channels.
#define SPEAKERHP_DOLBY_DIGITAL_MIN_BITS_PER_SAMPLE 16 // Min Bits Per Sample
@@ -47,7 +47,7 @@ Abstract:
//
// Max # of pin instances.
//
-#define SPEAKERHP_MAX_INPUT_SYSTEM_STREAMS 2 // Raw + Default streams
+#define SPEAKERHP_MAX_INPUT_SYSTEM_STREAMS 6
#define SPEAKERHP_MAX_INPUT_OFFLOAD_STREAMS MAX_INPUT_OFFLOAD_STREAMS
#define SPEAKERHP_MAX_OUTPUT_LOOPBACK_STREAMS MAX_OUTPUT_LOOPBACK_STREAMS
@@ -392,111 +392,6 @@ KSDATAFORMAT_WAVEFORMATEXTENSIBLE SpeakerHpOffloadPinSupportedDeviceFormats[] =
}
};
-static
-KSDATAFORMAT_WAVEFORMATEXTENSIBLE SpeakerHpLoopbackPinSupportedDeviceFormats[] =
-{
- { // 0
- {
- 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)
- }
- },
- { // 1
- {
- 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)
- }
- },
- { // 2
- {
- 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)
- }
- },
- { // 3
- {
- 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)
- }
- }
-};
-
//
// Supported modes (only on streaming pins).
//
@@ -565,8 +460,8 @@ PIN_DEVICE_FORMATS_AND_MODES SpeakerHpPinDeviceFormatsAndModes[] =
},
{
RenderLoopbackPin,
- SpeakerHpLoopbackPinSupportedDeviceFormats,
- SIZEOF_ARRAY(SpeakerHpLoopbackPinSupportedDeviceFormats),
+ SpeakerHpHostPinSupportedDeviceFormats, // Must support all the formats supported by host pin
+ SIZEOF_ARRAY(SpeakerHpHostPinSupportedDeviceFormats),
NULL, // loopback doesn't support modes.
0
},
diff --git a/audio/sysvad/EndpointsCommon/speakerwavtable.h b/audio/sysvad/EndpointsCommon/speakerwavtable.h
index 3322b0a7..cb2c2481 100644
--- a/audio/sysvad/EndpointsCommon/speakerwavtable.h
+++ b/audio/sysvad/EndpointsCommon/speakerwavtable.h
@@ -33,11 +33,11 @@ Abstract:
#define SPEAKER_OFFLOAD_MIN_SAMPLE_RATE 44100 // Min Sample Rate
#define SPEAKER_OFFLOAD_MAX_SAMPLE_RATE 48000 // Max Sample Rate
-#define SPEAKER_LOOPBACK_MAX_CHANNELS 2 // Max Channels.
-#define SPEAKER_LOOPBACK_MIN_BITS_PER_SAMPLE 16 // Min Bits Per Sample
-#define SPEAKER_LOOPBACK_MAX_BITS_PER_SAMPLE 16 // Max Bits Per Sample
-#define SPEAKER_LOOPBACK_MIN_SAMPLE_RATE 24000 // Min Sample Rate
-#define SPEAKER_LOOPBACK_MAX_SAMPLE_RATE 48000 // Max Sample Rate
+#define SPEAKER_LOOPBACK_MAX_CHANNELS SPEAKER_HOST_MAX_CHANNELS // Must be equal to host pin's Max Channels.
+#define SPEAKER_LOOPBACK_MIN_BITS_PER_SAMPLE SPEAKER_HOST_MIN_BITS_PER_SAMPLE // Must be equal to host pin's Min Bits Per Sample
+#define SPEAKER_LOOPBACK_MAX_BITS_PER_SAMPLE SPEAKER_HOST_MAX_BITS_PER_SAMPLE // Must be equal to host pin's Max Bits Per Sample
+#define SPEAKER_LOOPBACK_MIN_SAMPLE_RATE SPEAKER_HOST_MIN_SAMPLE_RATE // Must be equal to host pin's Min Sample Rate
+#define SPEAKER_LOOPBACK_MAX_SAMPLE_RATE SPEAKER_HOST_MAX_SAMPLE_RATE // Must be equal to host pin's Max Sample Rate
#define SPEAKER_DOLBY_DIGITAL_MAX_CHANNELS 2 // Max Channels.
#define SPEAKER_DOLBY_DIGITAL_MIN_BITS_PER_SAMPLE 16 // Min Bits Per Sample
@@ -48,7 +48,7 @@ Abstract:
//
// Max # of pin instances.
//
-#define SPEAKER_MAX_INPUT_SYSTEM_STREAMS 2 // Raw + Default streams
+#define SPEAKER_MAX_INPUT_SYSTEM_STREAMS 6
#define SPEAKER_MAX_INPUT_OFFLOAD_STREAMS MAX_INPUT_OFFLOAD_STREAMS
#define SPEAKER_MAX_OUTPUT_LOOPBACK_STREAMS MAX_OUTPUT_LOOPBACK_STREAMS
@@ -393,111 +393,6 @@ KSDATAFORMAT_WAVEFORMATEXTENSIBLE SpeakerOffloadPinSupportedDeviceFormats[] =
}
};
-static
-KSDATAFORMAT_WAVEFORMATEXTENSIBLE SpeakerLoopbackPinSupportedDeviceFormats[] =
-{
- { // 0
- {
- 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)
- }
- },
- { // 1
- {
- 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)
- }
- },
- { // 2
- {
- 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)
- }
- },
- { // 3
- {
- 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)
- }
- }
-};
-
//
// Supported modes (only on streaming pins).
//
@@ -566,8 +461,8 @@ PIN_DEVICE_FORMATS_AND_MODES SpeakerPinDeviceFormatsAndModes[] =
},
{
RenderLoopbackPin,
- SpeakerLoopbackPinSupportedDeviceFormats,
- SIZEOF_ARRAY(SpeakerLoopbackPinSupportedDeviceFormats),
+ SpeakerHostPinSupportedDeviceFormats, // Must support all the formats supported by host pin
+ SIZEOF_ARRAY(SpeakerHostPinSupportedDeviceFormats),
NULL, // loopback doesn't support modes.
0
},
@@ -836,7 +731,6 @@ PCPROPERTY_ITEM PropertiesSpeakerWaveFilter[] =
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_WaveFilter
}
-
};
DEFINE_PCAUTOMATION_TABLE_PROP(AutomationSpeakerWaveFilter, PropertiesSpeakerWaveFilter);