diff options
| author | karlf <[email protected]> | 2016-08-11 13:28:13 -0700 |
|---|---|---|
| committer | karlf <[email protected]> | 2016-08-11 13:28:13 -0700 |
| commit | 96eb96dfb613e4c745db6bd1f53a92fe7e2290fc (patch) | |
| tree | ad5f3ede5cbcd6b598677ce41bcf8318471bdd92 /audio/sysvad/EndpointsCommon | |
| parent | 687b274aa38fd05c8c26e3068932121876d7f745 (diff) | |
Updated for "Windows 10 Anniversary Update" (Version 1607)
Diffstat (limited to 'audio/sysvad/EndpointsCommon')
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); |
