diff options
| author | Girish Pattabiraman <[email protected]> | 2018-08-13 10:54:19 -0700 |
|---|---|---|
| committer | Adonais Romero González <[email protected]> | 2018-08-13 10:54:19 -0700 |
| commit | 2af3e666d01a60568c2875b4ccbd56b122ad714f (patch) | |
| tree | 29825a7b7cb0f6a9f77f1ab6e5813665d45ca4cc /audio/sysvad/EndpointsCommon/minwavert.cpp | |
| parent | 181c180357cdf9a04d5e3bb21a8e86dc2155ca69 (diff) | |
Update sample to get ready for RS4 changes - merge pre-RS4 fixes. (#256)
* Format Changes
==============
* Add KSEVENT_PINCAPS_FORMATCHANGE to Bluetooth HFP Endpoints
* Remove 8 bit formats from Bluetooth HFP Endpoints
Name Template
==============
* Bluetooth Endpoints are now based on templates in INF and then customized with endpoints specific data
Sideband Common Interface for future Sideband buses
===================================================
* Add ISidebandDevice
* Add current directory to TabletAudioSample include path. Remove unused compiler flags.
* RS4 bug fixes
Diffstat (limited to 'audio/sysvad/EndpointsCommon/minwavert.cpp')
| -rw-r--r-- | audio/sysvad/EndpointsCommon/minwavert.cpp | 641 |
1 files changed, 539 insertions, 102 deletions
diff --git a/audio/sysvad/EndpointsCommon/minwavert.cpp b/audio/sysvad/EndpointsCommon/minwavert.cpp index 35923619..8ad0e09d 100644 --- a/audio/sysvad/EndpointsCommon/minwavert.cpp +++ b/audio/sysvad/EndpointsCommon/minwavert.cpp @@ -16,6 +16,7 @@ Abstract: #include <sysvad.h> #include <limits.h> +#include <MsApoFxProxy.h> #include "ContosoKeywordDetector.h" #include "SysVadShared.h" #include "simple.h" @@ -25,6 +26,8 @@ Abstract: #include "AudioModuleHelper.h" +#define EFFECTS_LIST_COUNT 2 + //============================================================================= // CMiniportWaveRT //============================================================================= @@ -193,12 +196,13 @@ Return Value: m_pAudioModules = NULL; } -#ifdef SYSVAD_BTH_BYPASS - if (IsBthHfpDevice()) +#if defined(SYSVAD_BTH_BYPASS) + if (IsSidebandDevice()) { - SAFE_RELEASE(m_BthHfpDevice); + m_pSidebandDevice->SetFormatChangeHandler(m_DeviceType, NULL, NULL); + SAFE_RELEASE(m_pSidebandDevice); } -#endif // SYSVAD_BTH_BYPASS +#endif // defined(SYSVAD_BTH_BYPASS) } // ~CMiniportWaveRT @@ -387,23 +391,21 @@ Return Value: // // Init class data members // - m_ulLoopbackAllocated = 0; - m_ulSystemAllocated = 0; - m_ulOffloadAllocated = 0; - m_dwCaptureAllocatedModes = 0; - m_dwBiDiCaptureAllocatedModes = 0; - m_dwSystemAllocatedModes = 0; - m_SystemStreams = NULL; - m_OffloadStreams = NULL; - m_LoopbackStreams = NULL; - m_bGfxEnabled = FALSE; - m_pbMuted = NULL; - m_plVolumeLevel = NULL; - m_plPeakMeter = NULL; - m_pMixFormat = NULL; - m_pDeviceFormat = NULL; - m_ulMixDrmContentId = 0; - m_LoopbackProtection = CONSTRICTOR_OPTION_DISABLE; + m_ulLoopbackAllocated = 0; + m_ulSystemAllocated = 0; + m_ulOffloadAllocated = 0; + m_ulKeywordDetectorAllocated = 0; + m_SystemStreams = NULL; + m_OffloadStreams = NULL; + m_LoopbackStreams = NULL; + m_bGfxEnabled = FALSE; + m_pbMuted = NULL; + m_plVolumeLevel = NULL; + m_plPeakMeter = NULL; + m_pMixFormat = NULL; + m_pDeviceFormat = NULL; + m_ulMixDrmContentId = 0; + m_LoopbackProtection = CONSTRICTOR_OPTION_DISABLE; RtlZeroMemory(&m_MixDrmRights, sizeof(m_MixDrmRights)); // @@ -485,9 +487,7 @@ Return Value: // if (IsRenderDevice()) { - // Basic validation - if (m_ulMaxSystemStreams == 0 || - m_ulMaxLoopbackStreams == 0) + if (m_ulMaxSystemStreams == 0 ) { return STATUS_INVALID_DEVICE_STATE; } @@ -501,16 +501,23 @@ Return Value: } RtlZeroMemory(m_SystemStreams, size); - // Loopback streams. - size = sizeof(PCMiniportWaveRTStream) * m_ulMaxLoopbackStreams; - m_LoopbackStreams = (PCMiniportWaveRTStream *)ExAllocatePoolWithTag(NonPagedPoolNx, size, MINWAVERT_POOLTAG); - if (m_LoopbackStreams == NULL) + if (IsLoopbackSupported()) { - return STATUS_INSUFFICIENT_RESOURCES; + if (m_ulMaxLoopbackStreams == 0) + { + return STATUS_INVALID_DEVICE_STATE; + } + + // Loopback streams. + size = sizeof(PCMiniportWaveRTStream) * m_ulMaxLoopbackStreams; + m_LoopbackStreams = (PCMiniportWaveRTStream *)ExAllocatePoolWithTag(NonPagedPoolNx, size, MINWAVERT_POOLTAG); + if (m_LoopbackStreams == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + RtlZeroMemory(m_LoopbackStreams, size); } - RtlZeroMemory(m_LoopbackStreams, size); - // Basic validation if (IsOffloadSupported()) { PKSDATAFORMAT_WAVEFORMATEXTENSIBLE pDeviceFormats; @@ -608,6 +615,25 @@ Return Value: { m_pPortEvents = NULL; } + + // Format change handler is only required for bluetooth HFP implementation +#ifdef SYSVAD_BTH_BYPASS + if (IsSidebandDevice()) + { + PSIDEBANDDEVICECOMMON sidebandDevice = NULL; + + sidebandDevice = GetSidebandDevice(); // weak ref. + ASSERT(sidebandDevice != NULL); + + // + // Register with BthHfpDevice to get notification events. + // + sidebandDevice->SetFormatChangeHandler( + m_DeviceType, + EvtFormatChangeHandler, // handler + PCMiniportWaveRT(this)); // context. + } +#endif // #ifdef SYSVAD_BTH_BYPASS return ntStatus; } // Init @@ -676,7 +702,7 @@ Return Value: // if (NT_SUCCESS(ntStatus)) { - ntStatus = ValidateStreamCreate(Pin, Capture, signalProcessingMode); + ntStatus = ValidateStreamCreate(Pin, Capture); } // Determine if the format is valid. @@ -911,8 +937,7 @@ NTSTATUS CMiniportWaveRT::ValidateStreamCreate ( _In_ ULONG _Pin, - _In_ BOOLEAN _Capture, - _In_ GUID _SignalProcessingMode + _In_ BOOLEAN _Capture ) { PAGED_CODE(); @@ -925,44 +950,26 @@ CMiniportWaveRT::ValidateStreamCreate { if (IsLoopbackPin(_Pin)) { - if (m_ulLoopbackAllocated < m_ulMaxLoopbackStreams) - { - ntStatus = STATUS_SUCCESS; - } - else - { - ntStatus = STATUS_INSUFFICIENT_RESOURCES; - } - } - else if (IsSystemCapturePin(_Pin)) - { - VERIFY_MODE_RESOURCES_AVAILABLE(m_dwCaptureAllocatedModes, _SignalProcessingMode, ntStatus) + VERIFY_PIN_INSTANCE_RESOURCES_AVAILABLE(ntStatus, m_ulLoopbackAllocated, m_ulMaxLoopbackStreams); } - else if (IsCellularBiDiCapturePin(_Pin)) + else if (IsSystemCapturePin(_Pin) || IsCellularBiDiCapturePin(_Pin)) { - VERIFY_MODE_RESOURCES_AVAILABLE(m_dwBiDiCaptureAllocatedModes, _SignalProcessingMode, ntStatus) + VERIFY_PIN_INSTANCE_RESOURCES_AVAILABLE(ntStatus, m_ulSystemAllocated, m_ulMaxSystemStreams); } - else if (m_DeviceFormatsAndModes[_Pin].PinType == PINTYPE::KeywordCapturePin) + else if (IsKeywordDetectorPin(_Pin)) { - ntStatus = STATUS_SUCCESS; + VERIFY_PIN_INSTANCE_RESOURCES_AVAILABLE(ntStatus, m_ulKeywordDetectorAllocated, m_ulMaxKeywordDetectorStreams); } } else { if (IsSystemRenderPin(_Pin)) { - VERIFY_MODE_RESOURCES_AVAILABLE(m_dwSystemAllocatedModes, _SignalProcessingMode, ntStatus) + VERIFY_PIN_INSTANCE_RESOURCES_AVAILABLE(ntStatus, m_ulSystemAllocated, m_ulMaxSystemStreams); } else if (IsOffloadPin(_Pin)) { - if (m_ulOffloadAllocated < m_ulMaxOffloadStreams) - { - ntStatus = STATUS_SUCCESS; - } - else - { - ntStatus = STATUS_INSUFFICIENT_RESOURCES; - } + VERIFY_PIN_INSTANCE_RESOURCES_AVAILABLE(ntStatus, m_ulOffloadAllocated, m_ulMaxOffloadStreams); } } @@ -983,35 +990,34 @@ CMiniportWaveRT::StreamCreated PCMiniportWaveRTStream * streams = NULL; ULONG count = 0; - DPF_ENTER(("[CMiniportWaveRT::StreamOpened]")); + DPF_ENTER(("[CMiniportWaveRT::StreamCreated]")); - if (IsSystemCapturePin(_Pin)) + if (IsSystemCapturePin(_Pin) || IsCellularBiDiCapturePin(_Pin)) { - ALLOCATE_MODE_RESOURCES(m_dwCaptureAllocatedModes, _Stream->GetSignalProcessingMode()) + ALLOCATE_PIN_INSTANCE_RESOURCES(m_ulSystemAllocated); return STATUS_SUCCESS; } - if (IsCellularBiDiCapturePin(_Pin)) + if (IsKeywordDetectorPin(_Pin)) { - ALLOCATE_MODE_RESOURCES(m_dwBiDiCaptureAllocatedModes, _Stream->GetSignalProcessingMode()) + ALLOCATE_PIN_INSTANCE_RESOURCES(m_ulKeywordDetectorAllocated); return STATUS_SUCCESS; } else if (IsLoopbackPin(_Pin)) { - m_ulLoopbackAllocated++; + ALLOCATE_PIN_INSTANCE_RESOURCES(m_ulLoopbackAllocated); streams = m_LoopbackStreams; count = m_ulMaxLoopbackStreams; _Stream->m_SaveData.Disable(m_MixDrmRights.CopyProtect); } else if (IsSystemRenderPin(_Pin)) { - ALLOCATE_MODE_RESOURCES(m_dwSystemAllocatedModes, _Stream->GetSignalProcessingMode()) - m_ulSystemAllocated++; + ALLOCATE_PIN_INSTANCE_RESOURCES(m_ulSystemAllocated); streams = m_SystemStreams; count = m_ulMaxSystemStreams; } else if (IsOffloadPin(_Pin)) { - m_ulOffloadAllocated++; + ALLOCATE_PIN_INSTANCE_RESOURCES(m_ulOffloadAllocated); streams = m_OffloadStreams; count = m_ulMaxOffloadStreams; } @@ -1053,33 +1059,32 @@ CMiniportWaveRT::StreamClosed DPF_ENTER(("[CMiniportWaveRT::StreamClosed]")); - if (IsSystemCapturePin(_Pin)) + if (IsSystemCapturePin(_Pin) || IsCellularBiDiCapturePin(_Pin)) { - FREE_MODE_RESOURCES(m_dwCaptureAllocatedModes, _Stream->GetSignalProcessingMode()) + FREE_PIN_INSTANCE_RESOURCES(m_ulSystemAllocated); return STATUS_SUCCESS; } - if (IsCellularBiDiCapturePin(_Pin)) + if (IsKeywordDetectorPin(_Pin)) { - FREE_MODE_RESOURCES(m_dwBiDiCaptureAllocatedModes, _Stream->GetSignalProcessingMode()) + FREE_PIN_INSTANCE_RESOURCES(m_ulKeywordDetectorAllocated); return STATUS_SUCCESS; } else if (IsLoopbackPin(_Pin)) { - m_ulLoopbackAllocated--; + FREE_PIN_INSTANCE_RESOURCES(m_ulLoopbackAllocated); streams = m_LoopbackStreams; count = m_ulMaxLoopbackStreams; } else if (IsSystemRenderPin(_Pin)) { - FREE_MODE_RESOURCES(m_dwSystemAllocatedModes, _Stream->GetSignalProcessingMode()) - m_ulSystemAllocated--; + FREE_PIN_INSTANCE_RESOURCES(m_ulSystemAllocated); streams = m_SystemStreams; count = m_ulMaxSystemStreams; updateDrmRights = true; } else if (IsOffloadPin(_Pin)) { - m_ulOffloadAllocated--; + FREE_PIN_INSTANCE_RESOURCES(m_ulOffloadAllocated); streams = m_OffloadStreams; count = m_ulMaxOffloadStreams; updateDrmRights = true; @@ -1278,7 +1283,74 @@ CMiniportWaveRT::IsFormatSupported } return ntStatus; -} +} + +#ifdef SYSVAD_BTH_BYPASS +//============================================================================= +#pragma code_seg() +VOID +CMiniportWaveRT::EvtFormatChangeHandler +( + _In_opt_ PVOID Context +) +{ + DPF_ENTER(("[CMiniportWaveRT::EvtFormatChangeHandler]")); + + PCMiniportWaveRT This = PCMiniportWaveRT(Context); + if (This == NULL) + { + DPF(D_ERROR, ("EvtFormatChangeHandler: context is null")); + return; + } + + /* + _In_opt_ GUID *Set, + _In_ ULONG EventId, + _In_ BOOL PinEvent, + _In_ ULONG PinId, + _In_ BOOL NodeEvent, + _In_ ULONG NodeId + */ + + if (This->IsSidebandDevice()) + { + if (This->m_DeviceType == eBthHfpMicDevice) + { + // swap the device formats and modes for bt + ExAcquireFastMutex(&This->m_DeviceFormatsAndModesLock); + + This->m_DeviceFormatsAndModes = This->m_pSidebandDevice->GetFormatsAndModes(This->m_DeviceType); + + ExReleaseFastMutex(&This->m_DeviceFormatsAndModesLock); + + This->GenerateEventList( + (GUID*)&KSEVENTSETID_PinCapsChange, + KSEVENT_PINCAPS_FORMATCHANGE, + TRUE, + 1, + FALSE, + ULONG(-1)); + } + else if(This->m_DeviceType == eBthHfpSpeakerDevice) + { + // swap the device formats and modes for bt + ExAcquireFastMutex(&This->m_DeviceFormatsAndModesLock); + + This->m_DeviceFormatsAndModes = This->m_pSidebandDevice->GetFormatsAndModes(This->m_DeviceType); + + ExReleaseFastMutex(&This->m_DeviceFormatsAndModesLock); + + This->GenerateEventList( + (GUID*)&KSEVENTSETID_PinCapsChange, + KSEVENT_PINCAPS_FORMATCHANGE, + TRUE, + 0, + FALSE, + ULONG(-1)); + } + } +} +#endif // #ifdef SYSVAD_BTH_BYPASS //============================================================================= #pragma code_seg("PAGE") @@ -1314,7 +1386,8 @@ CMiniportWaveRT::PropertyHandlerProposedFormat if (IsSystemRenderPin(kspPin->PinId) || IsLoopbackPin(kspPin->PinId) || IsOffloadPin(kspPin->PinId) || - IsSystemCapturePin(kspPin->PinId)|| + IsSystemCapturePin(kspPin->PinId) || + IsKeywordDetectorPin(kspPin->PinId) || IsCellularBiDiCapturePin(kspPin->PinId)) { ntStatus = STATUS_SUCCESS; @@ -1354,35 +1427,257 @@ CMiniportWaveRT::PropertyHandlerProposedFormat return STATUS_BUFFER_TOO_SMALL; } +#if 0 // Only SET is supported for this property if ((PropertyRequest->Verb & KSPROPERTY_TYPE_SET) == 0) { return STATUS_INVALID_DEVICE_REQUEST; } +#endif - pKsFormat = (PKSDATAFORMAT)PropertyRequest->Value; - ntStatus = IsFormatSupported(kspPin->PinId, - IsSystemCapturePin(kspPin->PinId) || IsCellularBiDiCapturePin(kspPin->PinId) || - IsLoopbackPin(kspPin->PinId), - pKsFormat); - if (!NT_SUCCESS(ntStatus)) + if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) { - return ntStatus; - } + ntStatus = STATUS_INVALID_DEVICE_REQUEST; +#if defined(SYSVAD_BTH_BYPASS) + if (IsSidebandDevice()) + { + if (m_DeviceType == eBthHfpMicDevice || + m_DeviceType == eBthHfpSpeakerDevice) + { + KSDATAFORMAT_WAVEFORMATEXTENSIBLE *propFormat = (KSDATAFORMAT_WAVEFORMATEXTENSIBLE *)PropertyRequest->Value; + ULONG numModes = 0; + MODE_AND_DEFAULT_FORMAT *modeInfo = NULL; + MODE_AND_DEFAULT_FORMAT *modeInfo_RAW = NULL; + numModes = GetPinSupportedDeviceModes(kspPin->PinId, &modeInfo); + BOOL bFound = FALSE; + ULONG i = 0; - // - // Make sure there are enough resources to handle a new pin creation with - // this format. - // - if (IsOffloadPin(kspPin->PinId)) + // For loopback pin, get default format from host pin structures + if (IsLoopbackPin(kspPin->PinId)) + { + for (i = 0; i < m_DeviceFormatsAndModesCount; i++) + { + if (m_DeviceFormatsAndModes[i].PinType == SystemRenderPin) + { + modeInfo = m_DeviceFormatsAndModes[i].ModeAndDefaultFormat; + numModes = m_DeviceFormatsAndModes[i].ModeAndDefaultFormatCount; + break; + } + } + } + + // Iterate through FormatsAndModes to find the 'DefaultFormat' for the 'DEFAULT' processing mode + // Make note of the RAW format for cases where DEFAULT mode is not supported by endpoint + for (i = 0; i < numModes; i++, ++modeInfo) + { + if ((IsEqualGUIDAligned(modeInfo->Mode, AUDIO_SIGNALPROCESSINGMODE_DEFAULT)) && + (modeInfo->DefaultFormat != NULL)) + { + bFound = TRUE; + break; + } + else if ((IsEqualGUIDAligned(modeInfo->Mode, AUDIO_SIGNALPROCESSINGMODE_RAW)) && + (modeInfo->DefaultFormat != NULL)) + { + modeInfo_RAW = modeInfo; + } + } + + if (!bFound && + modeInfo_RAW) + { + modeInfo = modeInfo_RAW; + bFound = TRUE; + } + + if (!bFound) + { + return STATUS_NOT_SUPPORTED; + } + + RtlCopyMemory(propFormat, modeInfo->DefaultFormat, modeInfo->DefaultFormat->FormatSize); + PropertyRequest->ValueSize = modeInfo->DefaultFormat->FormatSize; + ntStatus = STATUS_SUCCESS; + } + } +#endif // defined(SYSVAD_BTH_BYPASS) + } + else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) { - ntStatus = ValidateStreamCreate(kspPin->PinId, FALSE, AUDIO_SIGNALPROCESSINGMODE_DEFAULT); + pKsFormat = (PKSDATAFORMAT)PropertyRequest->Value; + ntStatus = IsFormatSupported(kspPin->PinId, + IsSystemCapturePin(kspPin->PinId) || IsCellularBiDiCapturePin(kspPin->PinId) || + IsLoopbackPin(kspPin->PinId), + pKsFormat); + if (!NT_SUCCESS(ntStatus)) + { + return ntStatus; + } + + // + // Make sure there are enough resources to handle a new pin creation with + // this format. + // + if (IsOffloadPin(kspPin->PinId)) + { + ntStatus = ValidateStreamCreate(kspPin->PinId, FALSE); + } } return ntStatus; } // PropertyHandlerProposedFormat //============================================================================= +#pragma code_seg() +VOID +CMiniportWaveRT::GenerateEventList +( + _In_opt_ GUID *Set, + _In_ ULONG EventId, + _In_ BOOL PinEvent, + _In_ ULONG PinId, + _In_ BOOL NodeEvent, + _In_ ULONG NodeId +) +/*++ + +Routine Description: + + The GenerateEventList method notifies clients through the port driver's list + of event entries that a particular event has occurred. + +Arguments: + + Set - + + EventId - + + PinEvent - + + PinId - + + NodeEvent - + + NodeId - + +--*/ +{ + DPF_ENTER(("[CMiniportWaveRT::GenerateEventList]")); + + ASSERT(m_pPortEvents != NULL); + + m_pPortEvents->GenerateEventList( + Set, + EventId, + PinEvent, + PinId, + NodeEvent, + NodeId); +} + +//============================================================================= +#pragma code_seg("PAGE") +NTSTATUS +CMiniportWaveRT::PropertyHandlerAudioEffectsDiscoveryEffectsList +( + _In_ PPCPROPERTY_REQUEST PropertyRequest +) +{ + PAGED_CODE(); + + DPF_ENTER(("[CMiniportWaveRT::PropertyHandlerAudioEffectsDiscoveryEffectsList]")); + + PKSP_PIN kspPin = NULL; + NTSTATUS ntStatus = STATUS_INVALID_PARAMETER; + PKSP_PINMODE pKspPinmode = NULL; + GUID signalProcessingMode = AUDIO_SIGNALPROCESSINGMODE_DEFAULT; + + // Verify instance data stores at least KSP_PIN fields beyond KSPPROPERTY. + if (PropertyRequest->InstanceSize < (sizeof(KSP_PIN) - RTL_SIZEOF_THROUGH_FIELD(KSP_PIN, Property))) + { + return STATUS_INVALID_PARAMETER; + } + + // Extract property descriptor from property request instance data + kspPin = CONTAINING_RECORD(PropertyRequest->Instance, KSP_PIN, PinId); + + // Get the mode if specified. + pKspPinmode = (PKSP_PINMODE)kspPin; + signalProcessingMode = pKspPinmode->AudioProcessingMode; + + if (PropertyRequest->InstanceSize >= sizeof(ULONG)) + { + // This prop is only supported on Keyword Detector pins. + if (IsKeywordDetectorPin(kspPin->PinId)) + { + ntStatus = STATUS_SUCCESS; + } + else + { + ntStatus = STATUS_NOT_SUPPORTED; + } + } + + IF_FAILED_JUMP(ntStatus, Done); + + // Valid actions: get and basicsupport. + ntStatus = STATUS_INVALID_PARAMETER; + + if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) + { + ntStatus = + PropertyHandler_BasicSupport + ( + PropertyRequest, + KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET, + VT_ILLEGAL + ); + } + else if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) + { + if (IsKeywordDetectorPin(kspPin->PinId)) + { + // Compute total size, two effects: NS and EC (see below). + ULONG cbMinSize = 0; + + if(signalProcessingMode == AUDIO_SIGNALPROCESSINGMODE_SPEECH) + { + cbMinSize = sizeof(GUID) * EFFECTS_LIST_COUNT; + } + + if (PropertyRequest->ValueSize == 0) + { + PropertyRequest->ValueSize = cbMinSize; + ntStatus = STATUS_BUFFER_OVERFLOW; + } + else if (PropertyRequest->ValueSize < cbMinSize) + { + ntStatus = STATUS_BUFFER_TOO_SMALL; + } + else if (signalProcessingMode == AUDIO_SIGNALPROCESSINGMODE_SPEECH) + { + PGUID effectList = PGUID(PropertyRequest->Value); + + *effectList = AUDIO_EFFECT_TYPE_ACOUSTIC_ECHO_CANCELLATION; + *(effectList + 1) = AUDIO_EFFECT_TYPE_NOISE_SUPPRESSION; + + PropertyRequest->ValueSize = cbMinSize; + ntStatus = STATUS_SUCCESS; + } + else + { + PropertyRequest->ValueSize = 0; + ntStatus = STATUS_SUCCESS; + } + } + } + +Done: + + return ntStatus; +} // PropertyHandlerAudioEffectsDiscoveryEffectsList + +//============================================================================= #pragma code_seg("PAGE") NTSTATUS CMiniportWaveRT::PropertyHandlerModulesListRequest @@ -1439,6 +1734,70 @@ CMiniportWaveRT::PropertyHandlerModuleNotificationDeviceId GetAudioModuleNotificationDeviceId()); } // PropertyHandlerModuleNotificationDeviceId +//============================================================================= +#pragma code_seg() +NTSTATUS +CMiniportWaveRT_EventHandler_PinCapsChange +( +_In_ PPCEVENT_REQUEST EventRequest +) +{ + CMiniportWaveRT* miniport = reinterpret_cast<CMiniportWaveRT*>(EventRequest->MajorTarget); + return miniport->EventHandler_PinCapsChange(EventRequest); +} + +//============================================================================= +#pragma code_seg() +NTSTATUS +CMiniportWaveRT::EventHandler_PinCapsChange +( +_In_ PPCEVENT_REQUEST EventRequest +) +{ + if (*EventRequest->EventItem->Set != KSEVENTSETID_PinCapsChange) + { + return STATUS_INVALID_PARAMETER; + } + + switch (EventRequest->Verb) + { + // Do we support event handling?!? + case PCEVENT_VERB_SUPPORT: + break; + // We should add the event now! + case PCEVENT_VERB_ADD: + // If we have the interface and EventEntry is defined ... + if (EventRequest->EventEntry) + { + switch (EventRequest->EventItem->Id) + { + // Add pincaps format change event to support the force sample rate feature + case KSEVENT_PINCAPS_FORMATCHANGE: + m_pPortEvents->AddEventToEventList(EventRequest->EventEntry); + break; + default: + return STATUS_INVALID_PARAMETER; + break; + } + } + else + { + return STATUS_UNSUCCESSFUL; + } + break; + + case PCEVENT_VERB_REMOVE: + // We cannot remove the event but we can stop generating the + // events. However, it also doesn't hurt to always generate them ... + break; + + default: + return STATUS_INVALID_PARAMETER; + } + + return STATUS_SUCCESS; +} + //============================================================================= #pragma code_seg("PAGE") @@ -2188,6 +2547,8 @@ DEFINE_CLASSPROPERTYHANDLER(CMiniportWaveRT, Get_SoundDetectorMatchResult) value->Header.Size = sizeof(CONTOSO_KEYWORDDETECTIONRESULT); value->Header.PatternType = CONTOSO_KEYWORDCONFIGURATION_IDENTIFIER; value->ContosoDetectorResultData = m_KeywordDetector.GetDetectorData(); + value->KeywordStartTimestamp = m_KeywordDetector.GetStartTimestamp(); + value->KeywordStopTimestamp = m_KeywordDetector.GetStopTimestamp(); PropertyRequest->ValueSize = sizeof(*value); @@ -2217,7 +2578,6 @@ NTSTATUS CMiniportWaveRT::EventHandler_SoundDetectorMatchDetected } return STATUS_SUCCESS; } - #pragma code_seg("PAGE") NTSTATUS PropertyHandler_WaveFilter @@ -2297,6 +2657,18 @@ Return Value: DPF(D_TERSE, ("[PropertyHandler_WaveFilter: Invalid Device Request]")); } } + else if (IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_AudioEffectsDiscovery)) + { + switch(PropertyRequest->PropertyItem->Id) + { + case KSPROPERTY_AUDIOEFFECTSDISCOVERY_EFFECTSLIST: + ntStatus = pWaveHelper->PropertyHandlerAudioEffectsDiscoveryEffectsList(PropertyRequest); + break; + + default: + DPF(D_TERSE, ("[PropertyHandler_WaveFilter: Invalid Device Request]")); + } + } else if ((pWaveHelper->m_DeviceType == eHdmiRenderDevice || pWaveHelper->m_DeviceType == eCellularDevice || pWaveHelper->m_DeviceType == eHandsetSpeakerDevice) && @@ -2493,7 +2865,9 @@ CKeywordDetector::CKeywordDetector() m_qpcStartCapture(0), m_nLastQueuedPacket(-1), m_SoundDetectorArmed(FALSE), - m_SoundDetectorData(0) + m_SoundDetectorData(0), + m_ullKeywordStartTimestamp(0), + m_ullKeywordStopTimestamp(0) { PAGED_CODE(); @@ -2505,6 +2879,53 @@ CKeywordDetector::CKeywordDetector() #pragma code_seg("PAGE") _IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS CKeywordDetector::ReadKeywordTimestampRegistry() +{ + PAGED_CODE(); + + NTSTATUS ntStatus; + UNICODE_STRING parametersPath; + + RTL_QUERY_REGISTRY_TABLE paramTable[] = { + // QueryRoutine Flags Name EntryContext DefaultType DefaultData DefaultLength + { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"KeywordDetectorStartTimestamp", &m_ullKeywordStartTimestamp, (REG_QWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_QWORD, &m_ullKeywordStartTimestamp, sizeof(ULONGLONG) }, + { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK, L"KeywordDetectorStopTimestamp", &m_ullKeywordStopTimestamp, (REG_QWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_QWORD, &m_ullKeywordStopTimestamp, sizeof(ULONGLONG) }, + { NULL, 0, NULL, NULL, 0, NULL, 0 } + }; + + RtlInitUnicodeString(¶metersPath, NULL); + + // The sizeof(WCHAR) is added to the maximum length, for allowing a space for null termination of the string. + parametersPath.MaximumLength = + g_RegistryPath.Length + sizeof(L"\\Parameters") + sizeof(WCHAR); + + parametersPath.Buffer = (PWCH)ExAllocatePoolWithTag(PagedPool, parametersPath.MaximumLength, MINWAVERT_POOLTAG); + if (parametersPath.Buffer == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlZeroMemory(parametersPath.Buffer, parametersPath.MaximumLength); + + RtlAppendUnicodeToString(¶metersPath, g_RegistryPath.Buffer); + RtlAppendUnicodeToString(¶metersPath, L"\\Parameters"); + + ntStatus = RtlQueryRegistryValues( + RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, + parametersPath.Buffer, + ¶mTable[0], + NULL, + NULL + ); + + ExFreePool(parametersPath.Buffer); + + return ntStatus; +} + + +#pragma code_seg("PAGE") +_IRQL_requires_max_(PASSIVE_LEVEL) VOID CKeywordDetector::ResetDetector() { PAGED_CODE(); @@ -2532,6 +2953,24 @@ LONGLONG CKeywordDetector::GetDetectorData() #pragma code_seg("PAGE") _IRQL_requires_max_(PASSIVE_LEVEL) +ULONGLONG CKeywordDetector::GetStartTimestamp() +{ + PAGED_CODE(); + + return m_ullKeywordStartTimestamp; +} + +#pragma code_seg("PAGE") +_IRQL_requires_max_(PASSIVE_LEVEL) +ULONGLONG CKeywordDetector::GetStopTimestamp() +{ + PAGED_CODE(); + + return m_ullKeywordStopTimestamp; +} + +#pragma code_seg("PAGE") +_IRQL_requires_max_(PASSIVE_LEVEL) VOID CKeywordDetector::ResetFifo() { PAGED_CODE(); @@ -2555,14 +2994,16 @@ NTSTATUS CKeywordDetector::SetArmed(_In_ BOOL Arm) PAGED_CODE(); BOOL previousArming = m_SoundDetectorArmed; + NTSTATUS ntStatus = STATUS_SUCCESS; m_SoundDetectorArmed = Arm; if (Arm && !previousArming && m_qpcStartCapture == 0) { + ntStatus = ReadKeywordTimestampRegistry(); StartBufferingStream(); } - return STATUS_SUCCESS; + return ntStatus; } #pragma code_seg("PAGE") @@ -2632,7 +3073,6 @@ VOID CKeywordDetector::DpcRoutine(_In_ LONGLONG PerformanceCounter, _In_ LONGLON { LIST_ENTRY* packetListEntry; PACKET_ENTRY* packetEntry; - LONGLONG* signature; do { @@ -2656,12 +3096,6 @@ VOID CKeywordDetector::DpcRoutine(_In_ LONGLONG PerformanceCounter, _In_ LONGLON RtlZeroMemory(&packetEntry->Samples[0], sizeof(packetEntry->Samples)); - // For test purposes, embed the packet number and sample time into the audio data - signature = (LONGLONG*)(&packetEntry->Samples[0]); - - signature[0] = packetEntry->PacketNumber; - signature[1] = packetEntry->QpcWhenSampled; - ExInterlockedInsertTailList(&PacketFifoHead, packetListEntry, &PacketFifoSpinLock); packetsToQueue -= 1; @@ -2718,3 +3152,6 @@ Exit: return ntStatus; } +#pragma code_seg() + + |
