Merge pull request #139 from girishpattabiraman/master

SysVad sample for Windows Creators Update (1703)
This commit is contained in:
Wei Mao 2017-05-15 14:37:31 -07:00 коммит произвёл GitHub
Родитель 4c5c5e0297 62d5b79db3
Коммит ed1df9a8b8
59 изменённых файлов: 6326 добавлений и 301 удалений

Просмотреть файл

@ -0,0 +1,297 @@
/*++
Copyright (c) Microsoft Corporation All Rights Reserved
Module Name:
AudioModule0.h
Abstract:
Declaration of Audio Module 0 (system module).
--*/
#ifndef _SYSVAD_AUDIOMODULE0_H_
#define _SYSVAD_AUDIOMODULE0_H_
#include "AudioModuleHelper.h"
#define AUDIOMODULE0_MAJOR 0x1
#define AUDIOMODULE0_MINOR 0X0
static const GUID AudioModule0Id =
{ 0xe24c8b6f, 0xede7, 0x4255, 0x8b, 0x39, 0x77, 0x97, 0x60, 0x15, 0xd5, 0x93 };
enum AudioModule0_Parameter {
AudioModule0Parameter1 = 0,
AudioModule0Parameter2
};
typedef struct _AUDIOMODULE0_CUSTOM_COMMAND {
ULONG Verb; // get, set and support
AudioModule0_Parameter ParameterId;
} AUDIOMODULE0_CUSTOM_COMMAND, *PAUDIOMODULE0_CUSTOM_COMMAND;
enum AudioModule0_Notification_Type {
AudioModule0ParameterChanged = 0,
};
typedef struct _AUDIOMODULE0_CUSTOM_NOTIFICATION {
ULONG Type;
union {
struct {
ULONG ParameterId;
} ParameterChanged;
};
} AUDIOMODULE0_CUSTOM_NOTIFICATION, *PAUDIOMODULE0_CUSTOM_NOTIFICATION;
typedef struct _AUDIOMODULE0_NOTIFICATION {
KSAUDIOMODULE_NOTIFICATION Header;
AUDIOMODULE0_CUSTOM_NOTIFICATION CustomNotification;
} AUDIOMODULE0_NOTIFICATION, *PAUDIOMODULE0_NOTIFICATION;
typedef struct _AUDIOMODULE0_CONTEXT {
ULONG Parameter1;
BYTE Parameter2;
ULONG InstanceId;
AUDIOMODULE0_NOTIFICATION Notification;
PPORTCLSNOTIFICATIONS PortNotifications;
} AUDIOMODULE0_CONTEXT, *PAUDIOMODULE0_CONTEXT;
static
ULONG AudioModule0_ValidParameter1List[] =
{
1, 2, 5
};
static
AUDIOMODULE_PARAMETER_INFO AudioModule0_ParameterInfo[] =
{
{
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
AUDIOMODULE_PARAMETER_FLAG_CHANGE_NOTIFICATION,
(ULONG)RTL_FIELD_SIZE(AUDIOMODULE0_CONTEXT, Parameter1),
VT_UI4,
AudioModule0_ValidParameter1List,
SIZEOF_ARRAY(AudioModule0_ValidParameter1List)
},
{
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
0,
(ULONG)RTL_FIELD_SIZE(AUDIOMODULE0_CONTEXT, Parameter2),
VT_UI1,
NULL,
0
},
};
inline
#pragma code_seg("PAGE")
NTSTATUS
AudioModule0_InitClass(
_In_ const AUDIOMODULE_DESCRIPTOR * Module,
_Inout_opt_ PVOID Context,
_In_ size_t Size,
_In_ KSAUDIOMODULE_NOTIFICATION * NotificationHeader,
_In_opt_ PPORTCLSNOTIFICATIONS PortNotifications
)
{
PAUDIOMODULE0_CONTEXT ctx = (PAUDIOMODULE0_CONTEXT)Context;
UNREFERENCED_PARAMETER(Module);
PAGED_CODE();
if (Context == NULL)
{
ASSERT(FALSE); // this should not happen.
return STATUS_INTERNAL_ERROR;
}
ASSERT(Size != 0);
RtlZeroMemory(Context, Size);
ctx->Notification.Header = *NotificationHeader;
ctx->PortNotifications = PortNotifications;
if (ctx->PortNotifications != NULL)
{
ctx->PortNotifications->AddRef();
}
return STATUS_SUCCESS;
}
inline
#pragma code_seg("PAGE")
NTSTATUS
AudioModule0_InitInstance(
_In_ const AUDIOMODULE_DESCRIPTOR * Module,
_In_opt_ PVOID TemplateContext,
_Inout_opt_ PVOID Context,
_In_ size_t Size,
_In_ ULONG InstanceId
)
{
PAUDIOMODULE0_CONTEXT ctx = (PAUDIOMODULE0_CONTEXT)Context;
UNREFERENCED_PARAMETER(Module);
PAGED_CODE();
if (Context == NULL)
{
ASSERT(FALSE); // this should not happen.
return STATUS_INTERNAL_ERROR;
}
ASSERT(TemplateContext != NULL);
ASSERT(Size != 0);
RtlCopyMemory(Context, TemplateContext, Size);
ctx->InstanceId = InstanceId;
ctx->Notification.Header.ProviderId.InstanceId = InstanceId;
if (ctx->PortNotifications != NULL)
{
ctx->PortNotifications->AddRef();
}
return STATUS_SUCCESS;
}
inline
#pragma code_seg("PAGE")
VOID
AudioModule0_Cleanup(
_In_ PVOID Context
)
{
PAUDIOMODULE0_CONTEXT ctx = (PAUDIOMODULE0_CONTEXT)Context;
PAGED_CODE();
if (Context == NULL)
{
ASSERT(FALSE); // this should not happen.
return;
}
SAFE_RELEASE(ctx->PortNotifications);
}
inline
#pragma code_seg("PAGE")
NTSTATUS
AudioModule0_Handler(
_Inout_opt_ PVOID Context,
_In_reads_bytes_(InBufferCb) PVOID InBuffer,
_In_ ULONG InBufferCb,
_Out_writes_bytes_opt_(*OutBufferCb) PVOID OutBuffer,
_Inout_ ULONG * OutBufferCb
)
{
NTSTATUS status = STATUS_SUCCESS;
BOOL fNewValue = FALSE;
PVOID currentValue;
PVOID inBuffer = NULL;
ULONG inBufferCb = 0;
PAUDIOMODULE0_CONTEXT ctx = (PAUDIOMODULE0_CONTEXT)Context;
AUDIOMODULE_PARAMETER_INFO * parameterInfo = NULL;
AUDIOMODULE0_CUSTOM_COMMAND * command = NULL;
PAGED_CODE();
if (ctx == NULL)
{
ASSERT(FALSE); // this should not happen.
status = STATUS_INTERNAL_ERROR;
goto exit;
}
//
// Basic parameter validation (module specific).
//
if (InBuffer == NULL || InBufferCb == 0)
{
return STATUS_INVALID_PARAMETER;
}
if (InBufferCb < sizeof(AUDIOMODULE0_CUSTOM_COMMAND))
{
return STATUS_INVALID_PARAMETER;
}
command = (AUDIOMODULE0_CUSTOM_COMMAND*)InBuffer;
//
// Validate the parameter referenced in the command.
//
switch (command->ParameterId)
{
case AudioModule0Parameter1:
currentValue = &ctx->Parameter1;
parameterInfo = &AudioModule0_ParameterInfo[AudioModule0Parameter1];
break;
case AudioModule0Parameter2:
currentValue = &ctx->Parameter2;
parameterInfo = &AudioModule0_ParameterInfo[AudioModule0Parameter2];
break;
default:
status = STATUS_INVALID_PARAMETER;
goto exit;
}
//
// Update input buffer ptr/size.
//
inBuffer = (PVOID)((ULONG_PTR)InBuffer + sizeof(AUDIOMODULE0_CUSTOM_COMMAND));
inBufferCb = InBufferCb - sizeof(AUDIOMODULE0_CUSTOM_COMMAND);
if (inBufferCb == 0)
{
inBuffer = NULL;
}
status = AudioModule_GenericHandler(
command->Verb,
command->ParameterId,
parameterInfo,
currentValue,
inBuffer,
inBufferCb,
OutBuffer,
OutBufferCb,
&fNewValue);
if (!NT_SUCCESS(status))
{
goto exit;
}
if (fNewValue && ctx->PortNotifications &&
(parameterInfo->Flags & AUDIOMODULE_PARAMETER_FLAG_CHANGE_NOTIFICATION))
{
// This logic assumes that access to this function is serialized.
ctx->Notification.CustomNotification.Type = AudioModule0ParameterChanged;
ctx->Notification.CustomNotification.ParameterChanged.ParameterId =
command->ParameterId;
AudioModule_SendNotification(ctx->PortNotifications,
(PVOID)&ctx->Notification,
(USHORT)sizeof(ctx->Notification));
}
// Normalize error code.
status = STATUS_SUCCESS;
exit:
return status;
}
#endif // _SYSVAD_AUDIOMODULE0_H_

Просмотреть файл

@ -0,0 +1,312 @@
/*++
Copyright (c) Microsoft Corporation All Rights Reserved
Module Name:
AudioModule1.h
Abstract:
Declaration of Audio Module 1.
--*/
#ifndef _SYSVAD_AUDIOMODULE1_H_
#define _SYSVAD_AUDIOMODULE1_H_
#include "AudioModuleHelper.h"
#define AUDIOMODULE1_MAJOR 0x2
#define AUDIOMODULE1_MINOR 0X1
static const GUID AudioModule1Id =
{ 0x5ce55c8e, 0x84df, 0x4317, 0x98, 0xc7, 0x79, 0x2d, 0xe8, 0x33, 0x66, 0xcc };
enum AudioModule1_Parameter {
AudioModule1Parameter1 = 0,
AudioModule1Parameter2,
AudioModule1Parameter3
};
typedef struct _AUDIOMODULE1_CUSTOM_COMMAND {
ULONG Verb; // get, set and support
AudioModule1_Parameter ParameterId;
} AUDIOMODULE1_CUSTOM_COMMAND, *PAUDIOMODULE1_CUSTOM_COMMAND;
enum AudioModule1_Notification_Type {
AudioModule1ParameterChanged = 0,
};
typedef struct _AUDIOMODULE1_CUSTOM_NOTIFICATION {
ULONG Type;
union {
struct {
ULONG ParameterId;
} ParameterChanged;
};
} AUDIOMODULE1_CUSTOM_NOTIFICATION, *PAUDIOMODULE1_CUSTOM_NOTIFICATION;
typedef struct _AUDIOMODULE1_NOTIFICATION {
KSAUDIOMODULE_NOTIFICATION Header;
AUDIOMODULE1_CUSTOM_NOTIFICATION CustomNotification;
} AUDIOMODULE1_NOTIFICATION, *PAUDIOMODULE1_NOTIFICATION;
typedef struct _AUDIOMODULE1_CONTEXT {
BYTE Parameter1;
ULONGLONG Parameter2;
DWORD Parameter3;
ULONG InstanceId;
AUDIOMODULE1_NOTIFICATION Notification;
PPORTCLSNOTIFICATIONS PortNotifications;
} AUDIOMODULE1_CONTEXT, *PAUDIOMODULE1_CONTEXT;
static
BYTE AudioModule1_ValidParameter1List[] =
{
0, 1, 2
};
static
AUDIOMODULE_PARAMETER_INFO AudioModule1_ParameterInfo[] =
{
{
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
AUDIOMODULE_PARAMETER_FLAG_CHANGE_NOTIFICATION,
(ULONG)RTL_FIELD_SIZE(AUDIOMODULE1_CONTEXT, Parameter1),
VT_UI1,
AudioModule1_ValidParameter1List,
SIZEOF_ARRAY(AudioModule1_ValidParameter1List)
},
{
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
0,
(ULONG)RTL_FIELD_SIZE(AUDIOMODULE1_CONTEXT, Parameter2),
VT_UI8,
NULL,
0
},
{
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
AUDIOMODULE_PARAMETER_FLAG_CHANGE_NOTIFICATION,
(ULONG)RTL_FIELD_SIZE(AUDIOMODULE1_CONTEXT, Parameter3),
VT_UI4,
NULL,
0
},
};
inline
#pragma code_seg("PAGE")
NTSTATUS
AudioModule1_InitClass(
_In_ const AUDIOMODULE_DESCRIPTOR * Module,
_Inout_opt_ PVOID Context,
_In_ size_t Size,
_In_ KSAUDIOMODULE_NOTIFICATION * NotificationHeader,
_In_opt_ PPORTCLSNOTIFICATIONS PortNotifications
)
{
PAUDIOMODULE1_CONTEXT ctx = (PAUDIOMODULE1_CONTEXT)Context;
UNREFERENCED_PARAMETER(Module);
PAGED_CODE();
if (Context == NULL)
{
ASSERT(FALSE); // this should not happen.
return STATUS_INTERNAL_ERROR;
}
ASSERT(Size != 0);
RtlZeroMemory(Context, Size);
ctx->Notification.Header = *NotificationHeader;
ctx->PortNotifications = PortNotifications;
if (ctx->PortNotifications != NULL)
{
ctx->PortNotifications->AddRef();
}
return STATUS_SUCCESS;
}
inline
#pragma code_seg("PAGE")
NTSTATUS
AudioModule1_InitInstance(
_In_ const AUDIOMODULE_DESCRIPTOR * Module,
_In_opt_ PVOID TemplateContext,
_Inout_opt_ PVOID Context,
_In_ size_t Size,
_In_ ULONG InstanceId
)
{
PAUDIOMODULE1_CONTEXT ctx = (PAUDIOMODULE1_CONTEXT)Context;
UNREFERENCED_PARAMETER(Module);
PAGED_CODE();
if (Context == NULL)
{
ASSERT(FALSE); // this should not happen.
return STATUS_INTERNAL_ERROR;
}
ASSERT(TemplateContext != NULL);
ASSERT(Size != 0);
RtlCopyMemory(Context, TemplateContext, Size);
ctx->InstanceId = InstanceId;
ctx->Notification.Header.ProviderId.InstanceId = InstanceId;
if (ctx->PortNotifications != NULL)
{
ctx->PortNotifications->AddRef();
}
return STATUS_SUCCESS;
}
inline
#pragma code_seg("PAGE")
VOID
AudioModule1_Cleanup(
_In_ PVOID Context
)
{
PAUDIOMODULE1_CONTEXT ctx = (PAUDIOMODULE1_CONTEXT)Context;
PAGED_CODE();
if (Context == NULL)
{
ASSERT(FALSE); // this should not happen.
return;
}
SAFE_RELEASE(ctx->PortNotifications);
}
inline
#pragma code_seg("PAGE")
NTSTATUS
AudioModule1_Handler(
_Inout_opt_ PVOID Context,
_In_reads_bytes_(InBufferCb) PVOID InBuffer,
_In_ ULONG InBufferCb,
_Out_writes_bytes_opt_(*OutBufferCb) PVOID OutBuffer,
_Inout_ ULONG * OutBufferCb
)
{
NTSTATUS status = STATUS_SUCCESS;
BOOL fNewValue = FALSE;
PVOID currentValue;
PVOID inBuffer = NULL;
ULONG inBufferCb = 0;
PAUDIOMODULE1_CONTEXT ctx = (PAUDIOMODULE1_CONTEXT)Context;
AUDIOMODULE_PARAMETER_INFO * parameterInfo = NULL;
AUDIOMODULE1_CUSTOM_COMMAND * command = NULL;
PAGED_CODE();
if (ctx == NULL)
{
ASSERT(FALSE); // this should not happen.
status = STATUS_INTERNAL_ERROR;
goto exit;
}
//
// Basic parameter validation (module specific).
//
if (InBuffer == NULL || InBufferCb == 0)
{
return STATUS_INVALID_PARAMETER;
}
if (InBufferCb < sizeof(AUDIOMODULE1_CUSTOM_COMMAND))
{
return STATUS_INVALID_PARAMETER;
}
command = (AUDIOMODULE1_CUSTOM_COMMAND*)InBuffer;
//
// Validate the parameter referenced in the command.
//
switch (command->ParameterId)
{
case AudioModule1Parameter1:
currentValue = &ctx->Parameter1;
parameterInfo = &AudioModule1_ParameterInfo[AudioModule1Parameter1];
break;
case AudioModule1Parameter2:
currentValue = &ctx->Parameter2;
parameterInfo = &AudioModule1_ParameterInfo[AudioModule1Parameter2];
break;
case AudioModule1Parameter3:
currentValue = &ctx->Parameter3;
parameterInfo = &AudioModule1_ParameterInfo[AudioModule1Parameter3];
break;
default:
status = STATUS_INVALID_PARAMETER;
goto exit;
}
//
// Update input buffer ptr/size.
//
inBuffer = (PVOID)((ULONG_PTR)InBuffer + sizeof(AUDIOMODULE1_CUSTOM_COMMAND));
inBufferCb = InBufferCb - sizeof(AUDIOMODULE1_CUSTOM_COMMAND);
if (inBufferCb == 0)
{
inBuffer = NULL;
}
status = AudioModule_GenericHandler(
command->Verb,
command->ParameterId,
parameterInfo,
currentValue,
inBuffer,
inBufferCb,
OutBuffer,
OutBufferCb,
&fNewValue);
if (!NT_SUCCESS(status))
{
goto exit;
}
if (fNewValue && ctx->PortNotifications &&
(parameterInfo->Flags & AUDIOMODULE_PARAMETER_FLAG_CHANGE_NOTIFICATION))
{
// This logic assumes that access to this function is serialized.
ctx->Notification.CustomNotification.Type = AudioModule1ParameterChanged;
ctx->Notification.CustomNotification.ParameterChanged.ParameterId =
command->ParameterId;
AudioModule_SendNotification(ctx->PortNotifications,
(PVOID)&ctx->Notification,
(USHORT)sizeof(ctx->Notification));
}
// Normalize error code.
status = STATUS_SUCCESS;
exit:
return status;
}
#endif // _SYSVAD_AUDIOMODULE1_H_

Просмотреть файл

@ -0,0 +1,296 @@
/*++
Copyright (c) Microsoft Corporation All Rights Reserved
Module Name:
AudioModule2.h
Abstract:
Declaration of Audio Module 2.
--*/
#ifndef _SYSVAD_AUDIOMODULE2_H_
#define _SYSVAD_AUDIOMODULE2_H_
#include "AudioModuleHelper.h"
#define AUDIOMODULE2_MAJOR 0x2
#define AUDIOMODULE2_MINOR 0X0
static const GUID AudioModule2Id =
{ 0xcc2a9527, 0x19d9, 0x4784, 0x8d, 0xd4, 0x6c, 0x1f, 0xe0, 0x1e, 0x37, 0x26 };
enum AudioModule2_Parameter {
AudioModule2Parameter1 = 0,
AudioModule2Parameter2
};
typedef struct _AUDIOMODULE2_CUSTOM_COMMAND {
ULONG Verb; // get, set and support
AudioModule2_Parameter ParameterId;
} AUDIOMODULE2_CUSTOM_COMMAND, *PAUDIOMODULE2_CUSTOM_COMMAND;
enum AudioModule2_Notification_Type {
AudioModule2ParameterChanged = 0,
};
typedef struct _AUDIOMODULE2_CUSTOM_NOTIFICATION {
ULONG Type;
union {
struct {
ULONG ParameterId;
} ParameterChanged;
};
} AUDIOMODULE2_CUSTOM_NOTIFICATION, *PAUDIOMODULE2_CUSTOM_NOTIFICATION;
typedef struct _AUDIOMODULE2_NOTIFICATION {
KSAUDIOMODULE_NOTIFICATION Header;
AUDIOMODULE2_CUSTOM_NOTIFICATION CustomNotification;
} AUDIOMODULE2_NOTIFICATION, *PAUDIOMODULE2_NOTIFICATION;
typedef struct _AUDIOMODULE2_CONTEXT {
ULONG Parameter1;
USHORT Parameter2;
ULONG InstanceId;
AUDIOMODULE2_NOTIFICATION Notification;
PPORTCLSNOTIFICATIONS PortNotifications;
} AUDIOMODULE2_CONTEXT, *PAUDIOMODULE2_CONTEXT;
static
ULONG AudioModule2_ValidParameter1List[] =
{
1, 0xfffffffe
};
static
AUDIOMODULE_PARAMETER_INFO AudioModule2_ParameterInfo[] =
{
{
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
AUDIOMODULE_PARAMETER_FLAG_CHANGE_NOTIFICATION,
(ULONG)RTL_FIELD_SIZE(AUDIOMODULE2_CONTEXT, Parameter1),
VT_UI4,
AudioModule2_ValidParameter1List,
SIZEOF_ARRAY(AudioModule2_ValidParameter1List)
},
{
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
0,
(ULONG)RTL_FIELD_SIZE(AUDIOMODULE2_CONTEXT, Parameter2),
VT_UI2,
NULL,
0
},
};
inline
#pragma code_seg("PAGE")
NTSTATUS
AudioModule2_InitClass(
_In_ const AUDIOMODULE_DESCRIPTOR * Module,
_Inout_opt_ PVOID Context,
_In_ size_t Size,
_In_ KSAUDIOMODULE_NOTIFICATION * NotificationHeader,
_In_opt_ PPORTCLSNOTIFICATIONS PortNotifications
)
{
PAUDIOMODULE2_CONTEXT ctx = (PAUDIOMODULE2_CONTEXT)Context;
UNREFERENCED_PARAMETER(Module);
PAGED_CODE();
if (Context == NULL)
{
ASSERT(FALSE); // this should not happen.
return STATUS_INTERNAL_ERROR;
}
ASSERT(Size != 0);
RtlZeroMemory(Context, Size);
ctx->Notification.Header = *NotificationHeader;
ctx->PortNotifications = PortNotifications;
if (ctx->PortNotifications != NULL)
{
ctx->PortNotifications->AddRef();
}
return STATUS_SUCCESS;
}
inline
#pragma code_seg("PAGE")
NTSTATUS
AudioModule2_InitInstance(
_In_ const AUDIOMODULE_DESCRIPTOR * Module,
_In_opt_ PVOID TemplateContext,
_Inout_opt_ PVOID Context,
_In_ size_t Size,
_In_ ULONG InstanceId
)
{
PAUDIOMODULE2_CONTEXT ctx = (PAUDIOMODULE2_CONTEXT)Context;
UNREFERENCED_PARAMETER(Module);
PAGED_CODE();
if (Context == NULL)
{
ASSERT(FALSE); // this should not happen.
return STATUS_INTERNAL_ERROR;
}
ASSERT(TemplateContext != NULL);
ASSERT(Size != 0);
RtlCopyMemory(Context, TemplateContext, Size);
ctx->InstanceId = InstanceId;
ctx->Notification.Header.ProviderId.InstanceId = InstanceId;
if (ctx->PortNotifications != NULL)
{
ctx->PortNotifications->AddRef();
}
return STATUS_SUCCESS;
}
inline
#pragma code_seg("PAGE")
VOID
AudioModule2_Cleanup(
_In_ PVOID Context
)
{
PAUDIOMODULE2_CONTEXT ctx = (PAUDIOMODULE2_CONTEXT)Context;
PAGED_CODE();
if (Context == NULL)
{
ASSERT(FALSE); // this should not happen.
return;
}
SAFE_RELEASE(ctx->PortNotifications);
}
inline
#pragma code_seg("PAGE")
NTSTATUS
AudioModule2_Handler(
_Inout_opt_ PVOID Context,
_In_reads_bytes_(InBufferCb) PVOID InBuffer,
_In_ ULONG InBufferCb,
_Out_writes_bytes_opt_(*OutBufferCb) PVOID OutBuffer,
_Inout_ ULONG * OutBufferCb
)
{
NTSTATUS status = STATUS_SUCCESS;
BOOL fNewValue = FALSE;
PVOID currentValue;
PVOID inBuffer = NULL;
ULONG inBufferCb = 0;
PAUDIOMODULE2_CONTEXT ctx = (PAUDIOMODULE2_CONTEXT)Context;
AUDIOMODULE_PARAMETER_INFO * parameterInfo = NULL;
AUDIOMODULE2_CUSTOM_COMMAND * command = NULL;
PAGED_CODE();
if (ctx == NULL)
{
ASSERT(FALSE); // this should not happen.
status = STATUS_INTERNAL_ERROR;
goto exit;
}
//
// Basic parameter validation (module specific).
//
if (InBuffer == NULL || InBufferCb == 0)
{
return STATUS_INVALID_PARAMETER;
}
if (InBufferCb < sizeof(AUDIOMODULE2_CUSTOM_COMMAND))
{
return STATUS_INVALID_PARAMETER;
}
command = (AUDIOMODULE2_CUSTOM_COMMAND*)InBuffer;
//
// Validate the parameter referenced in the command.
//
switch (command->ParameterId)
{
case AudioModule2Parameter1:
currentValue = &ctx->Parameter1;
parameterInfo = &AudioModule2_ParameterInfo[AudioModule0Parameter1];
break;
case AudioModule2Parameter2:
currentValue = &ctx->Parameter2;
parameterInfo = &AudioModule2_ParameterInfo[AudioModule2Parameter2];
break;
default:
status = STATUS_INVALID_PARAMETER;
goto exit;
}
//
// Update input buffer ptr/size.
//
inBuffer = (PVOID)((ULONG_PTR)InBuffer + sizeof(AUDIOMODULE2_CUSTOM_COMMAND));
inBufferCb = InBufferCb - sizeof(AUDIOMODULE2_CUSTOM_COMMAND);
if (inBufferCb == 0)
{
inBuffer = NULL;
}
status = AudioModule_GenericHandler(
command->Verb,
command->ParameterId,
parameterInfo,
currentValue,
inBuffer,
inBufferCb,
OutBuffer,
OutBufferCb,
&fNewValue);
if (!NT_SUCCESS(status))
{
goto exit;
}
if (fNewValue && ctx->PortNotifications &&
(parameterInfo->Flags & AUDIOMODULE_PARAMETER_FLAG_CHANGE_NOTIFICATION))
{
// This logic assumes that access to this function is serialized.
ctx->Notification.CustomNotification.Type = AudioModule2ParameterChanged;
ctx->Notification.CustomNotification.ParameterChanged.ParameterId =
command->ParameterId;
AudioModule_SendNotification(ctx->PortNotifications,
(PVOID)&ctx->Notification,
(USHORT)sizeof(ctx->Notification));
}
// Normalize error code.
status = STATUS_SUCCESS;
exit:
return status;
}
#endif // _SYSVAD_AUDIOMODULE2_H_

Просмотреть файл

@ -0,0 +1,644 @@
/*++
Copyright (c) Microsoft Corporation All Rights Reserved
Module Name:
AudioModuleHelper.cpp
Abstract:
Simple helper for Audio Modules logic.
--*/
#pragma warning (disable : 4127)
#include <sysvad.h>
#include <limits.h>
#include <ntintsafe.h>
#include "SysVadShared.h"
#include "AudioModuleHelper.h"
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
AudioModule_GenericHandler_BasicSupport(
_In_ PAUDIOMODULE_PARAMETER_INFO ParameterInfo,
_Out_writes_bytes_opt_(*BufferCb) PVOID Buffer,
_Inout_ ULONG * BufferCb
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
ULONG cbFullProperty = 0;
ULONG cbDataListSize = 0;
DPF_ENTER(("[AudioModule_GenericHandler_BasicSupport]"));
PAGED_CODE();
ASSERT(ParameterInfo);
ASSERT(BufferCb);
//
// Compute total size of property.
//
ntStatus = RtlULongMult(ParameterInfo->Size,
ParameterInfo->ValidSetCount,
&cbDataListSize);
if (!NT_SUCCESS(ntStatus))
{
ASSERT(FALSE);
*BufferCb = 0;
return ntStatus;
}
ntStatus = RtlULongAdd(cbDataListSize,
(ULONG)(sizeof(KSPROPERTY_DESCRIPTION) +
sizeof(KSPROPERTY_MEMBERSHEADER)),
&cbFullProperty);
if (!NT_SUCCESS(ntStatus))
{
ASSERT(FALSE);
*BufferCb = 0;
return ntStatus;
}
//
// Return the info the caller is asking for.
//
if (*BufferCb == 0)
{
// caller wants to know the size of the buffer.
*BufferCb = cbFullProperty;
ntStatus = STATUS_BUFFER_OVERFLOW;
}
else if (*BufferCb >= (sizeof(KSPROPERTY_DESCRIPTION)))
{
PKSPROPERTY_DESCRIPTION propDesc = PKSPROPERTY_DESCRIPTION(Buffer);
propDesc->AccessFlags = ParameterInfo->AccessFlags;
propDesc->DescriptionSize = cbFullProperty;
propDesc->PropTypeSet.Set = KSPROPTYPESETID_General;
propDesc->PropTypeSet.Id = ParameterInfo->VtType;
propDesc->PropTypeSet.Flags = 0;
propDesc->MembersListCount = 1;
propDesc->Reserved = 0;
// if return buffer can also hold a list description, return it too
if(*BufferCb >= cbFullProperty)
{
// fill in the members header
PKSPROPERTY_MEMBERSHEADER members =
PKSPROPERTY_MEMBERSHEADER(propDesc + 1);
members->MembersFlags = KSPROPERTY_MEMBER_VALUES;
members->MembersSize = ParameterInfo->Size;
members->MembersCount = ParameterInfo->ValidSetCount;
members->Flags = KSPROPERTY_MEMBER_FLAG_DEFAULT;
// fill in valid array.
BYTE* array = (BYTE*)(members + 1);
RtlCopyMemory(array, ParameterInfo->ValidSet, cbDataListSize);
// set the return value size
*BufferCb = cbFullProperty;
}
else
{
*BufferCb = sizeof(KSPROPERTY_DESCRIPTION);
}
}
else if(*BufferCb >= sizeof(ULONG))
{
// if return buffer can hold a ULONG, return the access flags
PULONG accessFlags = PULONG(Buffer);
*BufferCb = sizeof(ULONG);
*accessFlags = ParameterInfo->AccessFlags;
}
else
{
*BufferCb = 0;
ntStatus = STATUS_BUFFER_TOO_SMALL;
}
return ntStatus;
} // PropertyHandlerBasicSupportVolume
//=============================================================================
#pragma code_seg("PAGE")
BOOLEAN
IsAudioModuleParameterValid(
_In_ PAUDIOMODULE_PARAMETER_INFO ParameterInfo,
_In_reads_bytes_opt_(BufferCb) PVOID Buffer,
_In_ ULONG BufferCb
)
{
PAGED_CODE();
DPF_ENTER(("[IsAudioModuleParameterValid]"));
ULONG i = 0;
ULONG j = 0;
BOOLEAN validParam = FALSE;
//
// Validate buffer ptr and size.
//
if (Buffer == NULL || BufferCb == 0)
{
validParam = FALSE;
goto exit;
}
//
// Check its size.
//
if (BufferCb < ParameterInfo->Size)
{
validParam = FALSE;
goto exit;
}
//
// Check the valid list.
//
if (ParameterInfo->ValidSet && ParameterInfo->ValidSetCount)
{
BYTE* buffer = (BYTE*)ParameterInfo->ValidSet;
BYTE* pattern = (BYTE*)Buffer;
//
// Scan the valid list.
//
for (i = 0; i < ParameterInfo->ValidSetCount; ++i)
{
for (j=0; j < ParameterInfo->Size; ++j)
{
if (buffer[j] != pattern[j])
{
break;
}
}
if (j == ParameterInfo->Size)
{
// got a match.
break;
}
buffer += ParameterInfo->Size;
}
//
// If end of list, we didn't find the value.
//
if (i == ParameterInfo->ValidSetCount)
{
validParam = FALSE;
goto exit;
}
}
else
{
//
// Negative-testing support. Fail request if value is -1.
//
BYTE* buffer = (BYTE*)Buffer;
for (i = 0; i < ParameterInfo->Size; ++i)
{
if (buffer[i] != 0xFF)
{
break;
}
}
//
// If value is -1, return error.
//
if (i == ParameterInfo->Size)
{
validParam = FALSE;
goto exit;
}
}
validParam = TRUE;
exit:
return validParam;
}
//=============================================================================
#pragma code_seg("PAGE")
AUDIOMODULE *
AudioModule_FindModuleInList(
_In_ AUDIOMODULE * AudioModules,
_In_ ULONG AudioModuleCount,
_In_ GUID * ClassId,
_In_ ULONG InstanceId
)
{
for (ULONG i=0; i<AudioModuleCount; ++i)
{
AUDIOMODULE * module = &AudioModules[i];
if (IsEqualGUIDAligned(*(module->Descriptor->ClassId), *ClassId) &&
module->InstanceId == InstanceId)
{
return module;
}
}
return NULL;
}
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
AudioModule_GenericHandler(
_In_ ULONG Verb,
_In_ ULONG ParameterId,
_In_ PAUDIOMODULE_PARAMETER_INFO ParameterInfo,
_Inout_updates_bytes_(ParameterInfo->Size) PVOID CurrentValue,
_In_reads_bytes_opt_(InBufferCb) PVOID InBuffer,
_In_ ULONG InBufferCb,
_Out_writes_bytes_opt_(*OutBufferCb) PVOID OutBuffer,
_Inout_ ULONG * OutBufferCb,
_In_ BOOL * ParameterChanged
)
{
PAGED_CODE();
DPF_ENTER(("[AudioModule_GenericHandler]"));
UNREFERENCED_PARAMETER(ParameterId);
*ParameterChanged = FALSE;
// Handle KSPROPERTY_TYPE_BASICSUPPORT query
if (Verb & KSPROPERTY_TYPE_BASICSUPPORT)
{
return AudioModule_GenericHandler_BasicSupport(ParameterInfo, OutBuffer, OutBufferCb);
}
ULONG cbMinSize = ParameterInfo->Size;
if (Verb & KSPROPERTY_TYPE_GET)
{
// Verify module parameter supports 'get'.
if (!(ParameterInfo->AccessFlags & KSPROPERTY_TYPE_GET))
{
*OutBufferCb = 0;
return STATUS_INVALID_DEVICE_REQUEST;
}
// Verify value size
if (*OutBufferCb == 0)
{
*OutBufferCb = cbMinSize;
return STATUS_BUFFER_OVERFLOW;
}
if (*OutBufferCb < cbMinSize)
{
*OutBufferCb = 0;
return STATUS_BUFFER_TOO_SMALL;
}
else
{
RtlCopyMemory(OutBuffer, CurrentValue, ParameterInfo->Size);
*OutBufferCb = cbMinSize;
return STATUS_SUCCESS;
}
}
else if (Verb & KSPROPERTY_TYPE_SET)
{
*OutBufferCb = 0;
// Verify it is a write prop.
if (!(ParameterInfo->AccessFlags & KSPROPERTY_TYPE_SET))
{
return STATUS_INVALID_DEVICE_REQUEST;
}
// Validate parameter.
if (!IsAudioModuleParameterValid(ParameterInfo, InBuffer, InBufferCb))
{
return STATUS_INVALID_PARAMETER;
}
if (ParameterInfo->Size !=
RtlCompareMemory(CurrentValue, InBuffer, ParameterInfo->Size))
{
RtlCopyMemory(CurrentValue, InBuffer, ParameterInfo->Size);
*ParameterChanged = TRUE;
}
return STATUS_SUCCESS;
}
return STATUS_INVALID_DEVICE_REQUEST;
}
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
AudioModule_GenericHandler_ModulesListRequest(
_In_ PPCPROPERTY_REQUEST PropertyRequest,
_In_ AUDIOMODULE * AudioModules,
_In_ ULONG AudioModuleCount
)
{
NTSTATUS ntStatus;
// This specific APO->driver communication example is mainly added to show how this communication is done.
// The module list only lives on the wave filter and it can have modules that are for all pins and some that
// are only on specific pins.
PAGED_CODE();
DPF_ENTER(("[AudioModule_PropertyHandlerModulesListRequest]"));
//
// Note: return an empty list when no modules are present.
//
// Handle KSPROPERTY_TYPE_BASICSUPPORT query
if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
{
ULONG flags = KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT;
return PropertyHandler_BasicSupport(PropertyRequest, flags, VT_ILLEGAL);
}
if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
{
PKSMULTIPLE_ITEM ksMultipleItem;
ULONG cbMinSize = 0;
PKSAUDIOMODULE_DESCRIPTOR modules = NULL;
//
// Compute min value size requirements
//
ntStatus = RtlULongMult(AudioModuleCount,
(ULONG)sizeof(KSAUDIOMODULE_DESCRIPTOR),
&cbMinSize);
if (!NT_SUCCESS(ntStatus))
{
ASSERT(FALSE);
return ntStatus;
}
ntStatus = RtlULongAdd(cbMinSize, sizeof(KSMULTIPLE_ITEM), &cbMinSize);
if (!NT_SUCCESS(ntStatus))
{
ASSERT(FALSE);
return ntStatus;
}
// Verify value size
if (PropertyRequest->ValueSize == 0)
{
PropertyRequest->ValueSize = cbMinSize;
return STATUS_BUFFER_OVERFLOW;
}
if (PropertyRequest->ValueSize < cbMinSize)
{
return STATUS_BUFFER_TOO_SMALL;
}
// Value is a KSMULTIPLE_ITEM followed by list of modules.
ksMultipleItem = (PKSMULTIPLE_ITEM)PropertyRequest->Value;
modules = (PKSAUDIOMODULE_DESCRIPTOR)(ksMultipleItem + 1);
// Copy modules
for (ULONG i = 0; i<AudioModuleCount; ++i, ++modules)
{
const AUDIOMODULE_DESCRIPTOR * moduleDesc = AudioModules[i].Descriptor;
modules->ClassId = *moduleDesc->ClassId;
modules->InstanceId = AudioModules[i].InstanceId;
modules->VersionMajor = moduleDesc->VersionMajor;
modules->VersionMinor = moduleDesc->VersionMinor;
RtlStringCchCopyW(modules->Name,
AUDIOMODULE_MAX_NAME_CCH_SIZE, // includes null char
moduleDesc->Name);
}
// Miniport filled in the list of modules. Fill in the KSMULTIPLE_ITEM header.
ksMultipleItem->Size = cbMinSize;
ksMultipleItem->Count = AudioModuleCount;
PropertyRequest->ValueSize = ksMultipleItem->Size;
return STATUS_SUCCESS;
}
return STATUS_INVALID_DEVICE_REQUEST;
} // AudioModule_GenericHandler_ModulesListRequest
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
AudioModule_GenericHandler_ModuleCommand(
_In_ PPCPROPERTY_REQUEST PropertyRequest,
_In_ AUDIOMODULE * AudioModules,
_In_ ULONG AudioModuleCount
)
{
AUDIOMODULE * module = NULL;
PAGED_CODE();
DPF_ENTER(("[AudioModule_GenericHandler_ModuleCommand]"));
//
// Basic parameter validation.
//
if (AudioModules == NULL || AudioModuleCount == 0)
{
// endpoint/stream doesn't have any modules.
return STATUS_INVALID_DEVICE_REQUEST;
}
// Verify instance data stores at least KSAUDIOMODULE_PROPERTY fields
// beyond KSPPROPERTY.
if (PropertyRequest->InstanceSize < (sizeof(KSAUDIOMODULE_PROPERTY) -
RTL_SIZEOF_THROUGH_FIELD(KSAUDIOMODULE_PROPERTY, Property)))
{
return STATUS_INVALID_PARAMETER;
}
// Extract property descriptor from property request instance data
PKSAUDIOMODULE_PROPERTY moduleProperty = CONTAINING_RECORD(
PropertyRequest->Instance, KSAUDIOMODULE_PROPERTY, ClassId);
// Get a ptr to the module.
module = AudioModule_FindModuleInList(AudioModules,
AudioModuleCount,
&moduleProperty->ClassId,
moduleProperty->InstanceId);
//
// Invoke the handler.
//
if (module == NULL ||
module->Descriptor == NULL ||
module->Descriptor->Handler == NULL)
{
return STATUS_INVALID_PARAMETER;
}
// Handle KSPROPERTY_TYPE_BASICSUPPORT query
if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
{
ULONG flags = KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT;
return PropertyHandler_BasicSupport(PropertyRequest, flags, VT_ILLEGAL);
}
// Only KS-get is supported.
if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
{
NTSTATUS status;
ULONG inBufferCb = 0;
ULONG outBufferCb = 0;
PVOID inBuffer = NULL;
PVOID outBuffer = NULL;
outBufferCb = PropertyRequest->ValueSize;
outBuffer = PropertyRequest->Value;
ASSERT((outBufferCb != 0 && outBuffer != NULL) ||
(outBufferCb == 0 && outBuffer == NULL));
// this is guaranteed to work b/c of the validation above.
inBufferCb = PropertyRequest->InstanceSize +
sizeof(KSPROPERTY) -
sizeof(KSAUDIOMODULE_PROPERTY);
if (inBufferCb != 0)
{
inBuffer = (PVOID)(moduleProperty+1);
}
status = module->Descriptor->Handler(module->Context,
inBuffer,
inBufferCb,
outBuffer,
&outBufferCb);
//
// Set the size of the returned output data, or in the case of
// buffer overflow error, return the expected buffer length.
//
PropertyRequest->ValueSize = outBufferCb;
return status;
}
PropertyRequest->ValueSize = 0;
return STATUS_INVALID_DEVICE_REQUEST;
} // AudioModule_GenericHandler_ModuleCommand
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
AudioModule_GenericHandler_ModuleNotificationDeviceId(
_In_ PPCPROPERTY_REQUEST PropertyRequest,
_In_ const GUID * NotificationDeviceId
)
{
PAGED_CODE();
DPF_ENTER(("[AudioModule_GenericHandler_ModuleNotificationDeviceId]"));
//
// Basic parameter validation.
//
if (NotificationDeviceId == NULL)
{
return STATUS_INVALID_DEVICE_REQUEST;
}
// Handle KSPROPERTY_TYPE_BASICSUPPORT query
if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
{
ULONG flags = KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT;
return PropertyHandler_BasicSupport(PropertyRequest, flags, VT_ILLEGAL);
}
ULONG cbMinSize = sizeof(GUID);
GUID *dataPtr = static_cast<GUID*>(PropertyRequest->Value);
if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
{
// Verify value size
if (PropertyRequest->ValueSize == 0)
{
PropertyRequest->ValueSize = cbMinSize;
return STATUS_BUFFER_OVERFLOW;
}
if (PropertyRequest->ValueSize < cbMinSize)
{
return STATUS_BUFFER_TOO_SMALL;
}
else
{
*dataPtr = *NotificationDeviceId;
PropertyRequest->ValueSize = cbMinSize;
return STATUS_SUCCESS;
}
}
return STATUS_INVALID_DEVICE_REQUEST;
}
//=============================================================================
#pragma code_seg("PAGE")
VOID
AudioModule_SendNotification(
_In_ PPORTCLSNOTIFICATIONS PortNotifications,
_In_ PVOID NotificationBuffer,
_In_ USHORT NotificationBufferCb
)
{
NTSTATUS status = STATUS_SUCCESS;
PPCNOTIFICATION_BUFFER buffer = NULL;
PAGED_CODE();
DPF_ENTER(("[AudioModule_SendNotification]"));
// Allocate a notification buffer.
status = PortNotifications->AllocNotificationBuffer(PagedPool,
NotificationBufferCb,
&buffer);
if (!NT_SUCCESS(status))
{
goto exit;
}
// Notification buffer is only guaranteed to be LONG aligned,
// it is received as ULONGLONG aligned on the receiving end.
RtlCopyMemory(buffer, NotificationBuffer, NotificationBufferCb);
//
// Generate notification (async).
//
PortNotifications->SendNotification(&KSNOTIFICATIONID_AudioModule, buffer);
exit:
if (buffer != NULL)
{
// Free notification buffer.
PortNotifications->FreeNotificationBuffer(buffer);
buffer = NULL;
}
}

Просмотреть файл

@ -0,0 +1,95 @@
/*++
Copyright (c) Microsoft Corporation All Rights Reserved
Module Name:
AudioModuleHelper.h
Abstract:
Simple helper for Audio Modules logic.
--*/
#ifndef _SYSVAD_AUDIOMODULEHELPER_H_
#define _SYSVAD_AUDIOMODULEHELPER_H_
//
// Module helper functions.
//
#pragma code_seg("PAGE")
NTSTATUS
AudioModule_GenericHandler_BasicSupport(
_In_ PAUDIOMODULE_PARAMETER_INFO ParameterInfo,
_Out_writes_bytes_opt_(*BufferCb) PVOID Buffer,
_Inout_ ULONG * BufferCb
);
#pragma code_seg("PAGE")
BOOLEAN
IsAudioModuleParameterValid(
_In_ PAUDIOMODULE_PARAMETER_INFO ParameterInfo,
_In_reads_bytes_opt_(BufferCb) PVOID Buffer,
_In_ ULONG BufferCb
);
#pragma code_seg("PAGE")
AUDIOMODULE *
AudioModule_FindModuleInList(
_In_ AUDIOMODULE * AudioModules,
_In_ ULONG AudioModuleCount,
_In_ GUID * ClassId,
_In_ ULONG InstanceId
);
#pragma code_seg("PAGE")
NTSTATUS
AudioModule_GenericHandler(
_In_ ULONG Verb,
_In_ ULONG ParameterId,
_In_ PAUDIOMODULE_PARAMETER_INFO ParameterInfo,
_Inout_updates_bytes_(ParameterInfo->Size) PVOID CurrentValue,
_In_reads_bytes_opt_(InBufferCb) PVOID InBuffer,
_In_ ULONG InBufferCb,
_Out_writes_bytes_opt_(*OutBufferCb) PVOID OutBuffer,
_Inout_ ULONG * OutBufferCb,
_In_ BOOL * ParameterChanged
);
//
// Miniport/Stream helper functions.
//
#pragma code_seg("PAGE")
NTSTATUS
AudioModule_GenericHandler_ModulesListRequest(
_In_ PPCPROPERTY_REQUEST PropertyRequest,
_In_ AUDIOMODULE * AudioModules,
_In_ ULONG AudioModuleCount
);
#pragma code_seg("PAGE")
NTSTATUS
AudioModule_GenericHandler_ModuleCommand(
_In_ PPCPROPERTY_REQUEST PropertyRequest,
_In_ AUDIOMODULE * AudioModules,
_In_ ULONG AudioModuleCount
);
#pragma code_seg("PAGE")
NTSTATUS
AudioModule_GenericHandler_ModuleNotificationDeviceId(
_In_ PPCPROPERTY_REQUEST PropertyRequest,
_In_ const GUID * NotificationDeviceId
);
#pragma code_seg("PAGE")
VOID
AudioModule_SendNotification(
_In_ PPORTCLSNOTIFICATIONS PortNotifications,
_In_ PVOID NotificationBuffer,
_In_ USHORT NotificationBufferCb
);
#endif // _SYSVAD_AUDIOMODULEHELPER_H_

Просмотреть файл

@ -157,6 +157,7 @@
</Midl> </Midl>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="AudioModuleHelper.cpp" />
<ClCompile Include="bthhfpmictopo.cpp" /> <ClCompile Include="bthhfpmictopo.cpp" />
<ClCompile Include="bthhfpminwavert.cpp" /> <ClCompile Include="bthhfpminwavert.cpp" />
<ClCompile Include="bthhfpspeakertopo.cpp" /> <ClCompile Include="bthhfpspeakertopo.cpp" />

Просмотреть файл

@ -0,0 +1,62 @@
<?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>{CDBBEDA3-98E9-4C7A-BDB1-25EC47D0B087}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
<UniqueIdentifier>{FA3DF57E-BA19-4783-831B-CF9D4D594F70}</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>{CB830E4F-01DA-4D35-9789-E7DB0D02A79C}</UniqueIdentifier>
</Filter>
<Filter Include="Driver Files">
<Extensions>inf;inv;inx;mof;mc;</Extensions>
<UniqueIdentifier>{49F92783-3B39-4D0C-A153-8C346F754749}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="AudioModuleHelper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<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>

Просмотреть файл

@ -996,3 +996,4 @@ NTSTATUS CMiniportWaveRTStream::SetStreamCurrentWritePositionForLastBuffer(_In_
return ntStatus; return ntStatus;
} }

Просмотреть файл

@ -22,6 +22,8 @@ Abstract:
#include "minwavert.h" #include "minwavert.h"
#include "minwavertstream.h" #include "minwavertstream.h"
#include "IHVPrivatePropertySet.h" #include "IHVPrivatePropertySet.h"
#include "AudioModuleHelper.h"
//============================================================================= //=============================================================================
// CMiniportWaveRT // CMiniportWaveRT
@ -37,7 +39,7 @@ CreateMiniportWaveRTSYSVAD
_In_opt_ PUNKNOWN UnknownOuter, _In_opt_ PUNKNOWN UnknownOuter,
_When_((PoolType & NonPagedPoolMustSucceed) != 0, _When_((PoolType & NonPagedPoolMustSucceed) != 0,
__drv_reportError("Must succeed pool allocations are forbidden. " __drv_reportError("Must succeed pool allocations are forbidden. "
"Allocation failures cause a system crash")) "Allocation failures cause a system crash"))
_In_ POOL_TYPE PoolType, _In_ POOL_TYPE PoolType,
_In_ PUNKNOWN UnknownAdapter, _In_ PUNKNOWN UnknownAdapter,
_In_opt_ PVOID DeviceContext, _In_opt_ PVOID DeviceContext,
@ -161,6 +163,12 @@ Return Value:
m_pPortEvents = NULL; m_pPortEvents = NULL;
} }
if (m_pPortClsNotifications)
{
m_pPortClsNotifications->Release();
m_pPortClsNotifications = NULL;
}
if (m_SystemStreams) if (m_SystemStreams)
{ {
ExFreePoolWithTag( m_SystemStreams, MINWAVERT_POOLTAG ); ExFreePoolWithTag( m_SystemStreams, MINWAVERT_POOLTAG );
@ -178,7 +186,13 @@ Return Value:
ExFreePoolWithTag( m_LoopbackStreams, MINWAVERT_POOLTAG ); ExFreePoolWithTag( m_LoopbackStreams, MINWAVERT_POOLTAG );
m_LoopbackStreams = NULL; m_LoopbackStreams = NULL;
} }
if (m_pAudioModules)
{
FreeStreamAudioModules(m_pAudioModules, GetAudioModuleListCount());
m_pAudioModules = NULL;
}
#ifdef SYSVAD_BTH_BYPASS #ifdef SYSVAD_BTH_BYPASS
if (IsBthHfpDevice()) if (IsBthHfpDevice())
{ {
@ -392,6 +406,80 @@ Return Value:
m_LoopbackProtection = CONSTRICTOR_OPTION_DISABLE; m_LoopbackProtection = CONSTRICTOR_OPTION_DISABLE;
RtlZeroMemory(&m_MixDrmRights, sizeof(m_MixDrmRights)); RtlZeroMemory(&m_MixDrmRights, sizeof(m_MixDrmRights));
//
// For port notification support.
//
if (!NT_SUCCESS(Port_->QueryInterface(IID_IPortClsNotifications, (PVOID *)&m_pPortClsNotifications)))
{
m_pPortClsNotifications = NULL;
}
//
// Init all the modules associated to this miniport.
//
ULONG cModules = GetAudioModuleListCount();
if (cModules)
{
//
// Module list size.
//
size = cModules * sizeof(AUDIOMODULE);
m_pAudioModules = (AUDIOMODULE *)ExAllocatePoolWithTag(NonPagedPoolNx, size, MINWAVERT_POOLTAG);
if (m_pAudioModules == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(m_pAudioModules, size);
for (ULONG i=0; i<cModules; ++i)
{
PAUDIOMODULE_DESCRIPTOR moduleDesc = &m_pMiniportPair->ModuleList[i];
//
// Init run-time module element.
//
m_pAudioModules[i].Descriptor = moduleDesc;
m_pAudioModules[i].Context = NULL;
m_pAudioModules[i].InstanceId = moduleDesc->InstanceId;
m_pAudioModules[i].Enabled = TRUE;
//
// Module context size.
//
size = moduleDesc->ContextSize;
if (size)
{
m_pAudioModules[i].Context =
ExAllocatePoolWithTag(NonPagedPoolNx, size, MINWAVERT_POOLTAG);
if (m_pAudioModules[i].Context == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(m_pAudioModules[i].Context, size);
}
if (moduleDesc->InitClass)
{
KSAUDIOMODULE_NOTIFICATION NotificationHeader;
NotificationHeader.ProviderId.DeviceId = *GetAudioModuleNotificationDeviceId();
NotificationHeader.ProviderId.ClassId = *moduleDesc->ClassId;
NotificationHeader.ProviderId.InstanceId = moduleDesc->InstanceId;
ntStatus = moduleDesc->InitClass(moduleDesc,
m_pAudioModules[i].Context,
size,
&NotificationHeader,
m_pPortClsNotifications);
if (!NT_SUCCESS(ntStatus))
{
ASSERT(FALSE);
return ntStatus;
}
}
}
}
// //
// Init the audio-engine used by the render devices. // Init the audio-engine used by the render devices.
// //
@ -1294,6 +1382,63 @@ CMiniportWaveRT::PropertyHandlerProposedFormat
return ntStatus; return ntStatus;
} // PropertyHandlerProposedFormat } // PropertyHandlerProposedFormat
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
CMiniportWaveRT::PropertyHandlerModulesListRequest
(
_In_ PPCPROPERTY_REQUEST PropertyRequest
)
{
// This specific APO->driver communication example is mainly added to show how this communication is done.
// The module list only lives on the wave filter and it can have modules that are for all pins and some that
// are only on specific pins.
PAGED_CODE();
DPF_ENTER(("[CMiniportWaveRT::PropertyHandlerModulesListRequest]"));
return AudioModule_GenericHandler_ModulesListRequest(
PropertyRequest,
GetAudioModuleList(),
GetAudioModuleListCount());
} // PropertyHandlerModulesListRequest
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
CMiniportWaveRT::PropertyHandlerModuleCommand
(
_In_ PPCPROPERTY_REQUEST PropertyRequest
)
{
PAGED_CODE();
DPF_ENTER(("[CMiniportWaveRT::PropertyHandlerModuleCommand]"));
return AudioModule_GenericHandler_ModuleCommand(
PropertyRequest,
GetAudioModuleList(),
GetAudioModuleListCount());
} // PropertyHandlerModuleCommand
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
CMiniportWaveRT::PropertyHandlerModuleNotificationDeviceId
(
_In_ PPCPROPERTY_REQUEST PropertyRequest
)
{
PAGED_CODE();
DPF_ENTER(("[CMiniportWaveRT::PropertyHandlerModuleNotificationDeviceId]"));
return AudioModule_GenericHandler_ModuleNotificationDeviceId(
PropertyRequest,
GetAudioModuleNotificationDeviceId());
} // PropertyHandlerModuleNotificationDeviceId
//============================================================================= //=============================================================================
#pragma code_seg("PAGE") #pragma code_seg("PAGE")
@ -1675,6 +1820,203 @@ Return Value:
return ntStatus; return ntStatus;
} // UpdateDrmRights } // UpdateDrmRights
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
CMiniportWaveRT::AllocStreamAudioModules
(
_In_ const GUID * SignalProcessingMode,
_Out_ AUDIOMODULE ** ppAudioModules,
_Out_ ULONG * pAudioModuleCount
)
{
NTSTATUS ntStatus = STATUS_INVALID_DEVICE_STATE;
AUDIOMODULE * pAudioModules = NULL;
ULONG cModules = 0;
ULONG i, j;
size_t size;
PAGED_CODE();
//
// Init out parameters.
//
*ppAudioModules = NULL;
*pAudioModuleCount = 0;
//
// Nothing to do if there are no modules.
//
if (m_pAudioModules == NULL)
{
ntStatus = STATUS_SUCCESS;
goto exit;
}
//
// Find the # of modules associated with this stream.
//
for (i=0; i<GetAudioModuleListCount(); ++i)
{
const AUDIOMODULE_DESCRIPTOR * moduleDesc = m_pAudioModules[i].Descriptor;
if (IsEqualGUIDAligned(*moduleDesc->ProcessingMode, *SignalProcessingMode) ||
IsEqualGUIDAligned(*moduleDesc->ProcessingMode, NULL_GUID))
{
cModules++;
}
}
//
// All done if module count is zero.
//
if (cModules == 0)
{
ntStatus = STATUS_SUCCESS;
goto exit;
}
//
// Alloc modules infrastructure.
//
size = cModules * sizeof(AUDIOMODULE);
#pragma prefast(suppress:__WARNING_MEMORY_LEAK,"No leaking, stream obj dtor calls FreeStreamAudioModules")
pAudioModules = (AUDIOMODULE *)ExAllocatePoolWithTag(NonPagedPoolNx, size, MINWAVERT_POOLTAG);
if (pAudioModules == NULL)
{
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
RtlZeroMemory(pAudioModules, size);
for (i=0, j=0; i<GetAudioModuleListCount() && j<cModules; ++i)
{
const AUDIOMODULE_DESCRIPTOR * moduleDesc = m_pAudioModules[i].Descriptor;
if (IsEqualGUIDAligned(*moduleDesc->ProcessingMode, *SignalProcessingMode) ||
IsEqualGUIDAligned(*moduleDesc->ProcessingMode, NULL_GUID))
{
ULONG CfgInstanceId;
//
// Init run-time module element.
//
pAudioModules[j].Descriptor = moduleDesc;
pAudioModules[j].Context = NULL;
//
// Create a unique InstanceId for this module instance.
// This sample uses 24bits index which wraps around after 16M
// module instances for a specific class ID/Class config id.
// A real driver should reuse instance ids of deleted module
// instances, i.e., the driver should use a mapping between
// index <--> module info.
//
CfgInstanceId = InterlockedIncrement((LONG*)&m_pAudioModules[i].NextCfgInstanceId);
pAudioModules[j].InstanceId =
AUDIOMODULE_INSTANCE_ID(AUDIOMODULE_GET_CLASSCFGID(m_pAudioModules[i].InstanceId),
CfgInstanceId);
pAudioModules[j].Enabled = m_pAudioModules[i].Enabled;
//
// Alloc context for module instance.
//
size = moduleDesc->ContextSize;
if (size)
{
#pragma prefast(suppress:__WARNING_MEMORY_LEAK,"No leaking, stream obj dtor calls FreeStreamAudioModules")
pAudioModules[j].Context =
ExAllocatePoolWithTag(NonPagedPoolNx, size, MINWAVERT_POOLTAG);
if (pAudioModules[j].Context == NULL)
{
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
RtlZeroMemory(pAudioModules[j].Context, size);
}
//
// Init this module instance.
//
if (moduleDesc->InitInstance)
{
ntStatus = moduleDesc->InitInstance(moduleDesc,
m_pAudioModules[i].Context,
pAudioModules[j].Context,
size,
pAudioModules[j].InstanceId);
if (!NT_SUCCESS(ntStatus))
{
ASSERT(FALSE);
goto exit;
}
}
//
// Update stream module array index.
//
j++;
}
}
//
// Return the list of modules.
//
*ppAudioModules = pAudioModules;
*pAudioModuleCount = cModules;
ntStatus = STATUS_SUCCESS;
exit:
if (!NT_SUCCESS(ntStatus))
{
if (pAudioModules != NULL)
{
FreeStreamAudioModules(pAudioModules, cModules);
pAudioModules = NULL;
cModules = 0;
}
}
return ntStatus;
}
#pragma code_seg("PAGE")
VOID
CMiniportWaveRT::FreeStreamAudioModules
(
_In_ AUDIOMODULE * pAudioModules,
_In_ ULONG AudioModuleCount
)
{
PAGED_CODE();
if (pAudioModules != NULL)
{
ASSERT(AudioModuleCount);
for (ULONG i=0; i<AudioModuleCount; ++i)
{
if (pAudioModules[i].Context)
{
if (pAudioModules[i].Descriptor->Cleanup)
{
pAudioModules[i].Descriptor->Cleanup(pAudioModules[i].Context);
}
ExFreePoolWithTag(pAudioModules[i].Context, MINWAVERT_POOLTAG);
pAudioModules[i].Context = NULL;
}
}
ExFreePoolWithTag(pAudioModules, MINWAVERT_POOLTAG);
}
}
//============================================================================= //=============================================================================
#pragma code_seg("PAGE") #pragma code_seg("PAGE")
@ -1937,6 +2279,24 @@ Return Value:
DPF(D_TERSE, ("[PropertyHandler_WaveFilter: Invalid Device Request]")); DPF(D_TERSE, ("[PropertyHandler_WaveFilter: Invalid Device Request]"));
} }
} }
else if (IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_AudioModule))
{
switch (PropertyRequest->PropertyItem->Id)
{
case KSPROPERTY_AUDIOMODULE_DESCRIPTORS:
ntStatus = pWaveHelper->PropertyHandlerModulesListRequest(PropertyRequest);
break;
case KSPROPERTY_AUDIOMODULE_COMMAND:
ntStatus = pWaveHelper->PropertyHandlerModuleCommand(PropertyRequest);
break;
case KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID:
ntStatus = pWaveHelper->PropertyHandlerModuleNotificationDeviceId(PropertyRequest);
break;
default:
DPF(D_TERSE, ("[PropertyHandler_WaveFilter: Invalid Device Request]"));
}
}
else if ((pWaveHelper->m_DeviceType == eHdmiRenderDevice || else if ((pWaveHelper->m_DeviceType == eHdmiRenderDevice ||
pWaveHelper->m_DeviceType == eCellularDevice || pWaveHelper->m_DeviceType == eCellularDevice ||
pWaveHelper->m_DeviceType == eHandsetSpeakerDevice) && pWaveHelper->m_DeviceType == eHandsetSpeakerDevice) &&
@ -2061,6 +2421,69 @@ PropertyHandler_OffloadPin
return ntStatus; return ntStatus;
} }
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
PropertyHandler_GenericPin
(
_In_ PPCPROPERTY_REQUEST PropertyRequest
)
{
NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
CMiniportWaveRT* pWave = NULL;
CMiniportWaveRTStream * pStream = NULL;
PAGED_CODE();
if (PropertyRequest->MajorTarget == NULL ||
PropertyRequest->MinorTarget == NULL)
{
ntStatus = STATUS_INVALID_PARAMETER;
goto exit;
}
//
// Get a ref to the miniport.
//
pWave = MajorTarget_to_Obj(PropertyRequest->MajorTarget);
pWave->AddRef();
//
// Get a ref to the stream.
//
pStream = MinorTarget_to_Obj(PropertyRequest->MinorTarget);
pStream->AddRef();
//
// Invoke appropriate handle.
//
if (IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_AudioModule))
{
switch (PropertyRequest->PropertyItem->Id)
{
case KSPROPERTY_AUDIOMODULE_DESCRIPTORS:
ntStatus = pStream->PropertyHandlerModulesListRequest(PropertyRequest);
break;
case KSPROPERTY_AUDIOMODULE_COMMAND:
ntStatus = pStream->PropertyHandlerModuleCommand(PropertyRequest);
break;
case KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID:
// Filter handles this prop.
ntStatus = pWave->PropertyHandlerModuleNotificationDeviceId(PropertyRequest);
break;
default:
DPF(D_TERSE, ("[PropertyHandler_GenericPin: Invalid Device Request]"));
}
}
exit:
SAFE_RELEASE(pStream);
SAFE_RELEASE(pWave);
return ntStatus;
}
// ISSUE-2014/10/20 Add synchronization mechanism throughout this class // ISSUE-2014/10/20 Add synchronization mechanism throughout this class
// ISSUE-2014/10/20 Add comment headers and commenting throughout // ISSUE-2014/10/20 Add comment headers and commenting throughout

Просмотреть файл

@ -148,11 +148,14 @@ private:
#endif // SYSVAD_BTH_BYPASS #endif // SYSVAD_BTH_BYPASS
}; };
AUDIOMODULE * m_pAudioModules;
protected: protected:
PADAPTERCOMMON m_pAdapterCommon; PADAPTERCOMMON m_pAdapterCommon;
ULONG m_DeviceFlags; ULONG m_DeviceFlags;
eDeviceType m_DeviceType; eDeviceType m_DeviceType;
PPORTEVENTS m_pPortEvents; PPORTEVENTS m_pPortEvents;
PPORTCLSNOTIFICATIONS m_pPortClsNotifications;
PENDPOINT_MINIPAIR m_pMiniportPair; PENDPOINT_MINIPAIR m_pMiniportPair;
@ -231,7 +234,9 @@ public:
m_DeviceFormatsAndModes(MiniportPair->PinDeviceFormatsAndModes), m_DeviceFormatsAndModes(MiniportPair->PinDeviceFormatsAndModes),
m_DeviceFormatsAndModesCount(MiniportPair->PinDeviceFormatsAndModesCount), m_DeviceFormatsAndModesCount(MiniportPair->PinDeviceFormatsAndModesCount),
m_DeviceFlags(MiniportPair->DeviceFlags), m_DeviceFlags(MiniportPair->DeviceFlags),
m_pMiniportPair(MiniportPair) m_pMiniportPair(MiniportPair),
m_pAudioModules(NULL),
m_pPortClsNotifications(NULL)
{ {
PAGED_CODE(); PAGED_CODE();
@ -266,7 +271,6 @@ public:
} }
} }
#ifdef SYSVAD_BTH_BYPASS #ifdef SYSVAD_BTH_BYPASS
if (IsBthHfpDevice()) if (IsBthHfpDevice())
{ {
@ -316,6 +320,22 @@ public:
( (
_In_ PPCPROPERTY_REQUEST PropertyRequest _In_ PPCPROPERTY_REQUEST PropertyRequest
); );
NTSTATUS PropertyHandlerModulesListRequest
(
_In_ PPCPROPERTY_REQUEST PropertyRequest
);
NTSTATUS PropertyHandlerModuleCommand
(
_In_ PPCPROPERTY_REQUEST PropertyRequest
);
NTSTATUS PropertyHandlerModuleNotificationDeviceId
(
_In_ PPCPROPERTY_REQUEST PropertyRequest
);
PADAPTERCOMMON GetAdapterCommObj() PADAPTERCOMMON GetAdapterCommObj()
{ {
@ -629,8 +649,70 @@ protected:
ASSERT(!IsCellularDevice()); ASSERT(!IsCellularDevice());
return KSPIN_WAVE_RENDER_SINK_OFFLOAD; return KSPIN_WAVE_RENDER_SINK_OFFLOAD;
} }
#pragma code_seg() #pragma code_seg()
ULONG
GetAudioModuleDescriptorListCount()
{
return m_pMiniportPair->ModuleListCount;
}
const PAUDIOMODULE_DESCRIPTOR
GetAudioModuleDescriptor(
_In_ ULONG Index
)
{
ASSERT(Index < GetAudioModuleDescriptorListCount());
return &m_pMiniportPair->ModuleList[Index];
}
const PAUDIOMODULE_DESCRIPTOR
GetAudioModuleDescriptorList()
{
return m_pMiniportPair->ModuleList;
}
ULONG
GetAudioModuleListCount()
{
return GetAudioModuleDescriptorListCount();
}
AUDIOMODULE *
GetAudioModule(
_In_ ULONG Index
)
{
ASSERT(Index < GetAudioModuleListCount());
return &m_pAudioModules[Index];
}
AUDIOMODULE *
GetAudioModuleList()
{
return m_pAudioModules;
}
const GUID *
GetAudioModuleNotificationDeviceId()
{
return m_pMiniportPair->ModuleNotificationDeviceId;
}
NTSTATUS
AllocStreamAudioModules(
_In_ const GUID * SignalProcessingMode,
_Out_ AUDIOMODULE ** AudioModule,
_Out_ ULONG * AudioModuleCount
);
VOID
FreeStreamAudioModules(
_In_ AUDIOMODULE * AudioModule,
_In_ ULONG AudioModuleCount
);
#ifdef SYSVAD_BTH_BYPASS #ifdef SYSVAD_BTH_BYPASS
public: public:
#pragma code_seg("PAGE") #pragma code_seg("PAGE")

Просмотреть файл

@ -5,6 +5,7 @@
#include "minwavert.h" #include "minwavert.h"
#include "minwavertstream.h" #include "minwavertstream.h"
#include "UnittestData.h" #include "UnittestData.h"
#include "AudioModuleHelper.h"
#define MINWAVERTSTREAM_POOLTAG 'SRWM' #define MINWAVERTSTREAM_POOLTAG 'SRWM'
#pragma warning (disable : 4127) #pragma warning (disable : 4127)
@ -34,8 +35,16 @@ Return Value:
--*/ --*/
{ {
PAGED_CODE(); PAGED_CODE();
if (NULL != m_pMiniport) if (NULL != m_pMiniport)
{ {
if (m_pAudioModules)
{
m_pMiniport->FreeStreamAudioModules(m_pAudioModules, m_AudioModuleCount);
m_pAudioModules = NULL;
m_AudioModuleCount = 0;
}
if (m_bUnregisterStream) if (m_bUnregisterStream)
{ {
m_pMiniport->StreamClosed(m_ulPin, this); m_pMiniport->StreamClosed(m_ulPin, this);
@ -181,6 +190,8 @@ Return Value:
m_SignalProcessingMode = SignalProcessingMode; m_SignalProcessingMode = SignalProcessingMode;
m_bEoSReceived = FALSE; m_bEoSReceived = FALSE;
m_bLastBufferRendered = FALSE; m_bLastBufferRendered = FALSE;
m_pAudioModules = NULL;
m_AudioModuleCount = 0;
#ifdef SYSVAD_BTH_BYPASS #ifdef SYSVAD_BTH_BYPASS
m_ScoOpen = FALSE; m_ScoOpen = FALSE;
@ -268,6 +279,17 @@ Return Value:
} }
RtlZeroMemory(m_plPeakMeter, m_pWfExt->Format.nChannels * sizeof(LONG)); RtlZeroMemory(m_plPeakMeter, m_pWfExt->Format.nChannels * sizeof(LONG));
//
// Allocate stream audio module resources.
//
ntStatus = m_pMiniport->AllocStreamAudioModules(&SignalProcessingMode,
&m_pAudioModules,
&m_AudioModuleCount);
if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}
if (m_bCapture) if (m_bCapture)
{ {
DWORD toneFrequency = 0; DWORD toneFrequency = 0;
@ -784,6 +806,7 @@ Done:
// //
// ISSUE-2014/10/4 Will this work correctly across pause/play? // ISSUE-2014/10/4 Will this work correctly across pause/play?
#pragma code_seg() #pragma code_seg()
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS CMiniportWaveRTStream::GetReadPacket NTSTATUS CMiniportWaveRTStream::GetReadPacket
( (
_Out_ ULONG *PacketNumber, _Out_ ULONG *PacketNumber,
@ -854,7 +877,7 @@ NTSTATUS CMiniportWaveRTStream::GetReadPacket
// Compute and return timestamp corresponding to start of the available packet. In a real hardware // Compute and return timestamp corresponding to start of the available packet. In a real hardware
// driver, the timestamp would be computed in a driver and hardware specific manner. In this sample // driver, the timestamp would be computed in a driver and hardware specific manner. In this sample
// driver, it is extrapolated from the sample driver's internal simulated position corrleation // driver, it is extrapolated from the sample driver's internal simulated position correlation
// [m_ullLinearPosition @ m_ullDmaTimeStamp] and the sample's internal 64-bit packet counter, subtracting // [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. // 1 from the packet counter to compute the time at the start of that last completed packet.
ULONGLONG linearPositionOfAvailablePacket = (packetCounter - 1) * (m_ulDmaBufferSize / m_ulNotificationsPerBuffer); ULONGLONG linearPositionOfAvailablePacket = (packetCounter - 1) * (m_ulDmaBufferSize / m_ulNotificationsPerBuffer);
@ -895,6 +918,7 @@ NTSTATUS CMiniportWaveRTStream::GetReadPacket
} }
#pragma code_seg() #pragma code_seg()
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS CMiniportWaveRTStream::SetWritePacket NTSTATUS CMiniportWaveRTStream::SetWritePacket
( (
_In_ ULONG PacketNumber, _In_ ULONG PacketNumber,
@ -987,6 +1011,7 @@ NTSTATUS CMiniportWaveRTStream::SetWritePacket
//============================================================================= //=============================================================================
#pragma code_seg() #pragma code_seg()
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS CMiniportWaveRTStream::GetOutputStreamPresentationPosition NTSTATUS CMiniportWaveRTStream::GetOutputStreamPresentationPosition
( (
_Out_ KSAUDIO_PRESENTATION_POSITION *pPresentationPosition _Out_ KSAUDIO_PRESENTATION_POSITION *pPresentationPosition
@ -1005,6 +1030,7 @@ NTSTATUS CMiniportWaveRTStream::GetOutputStreamPresentationPosition
//============================================================================= //=============================================================================
#pragma code_seg() #pragma code_seg()
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS CMiniportWaveRTStream::GetPacketCount NTSTATUS CMiniportWaveRTStream::GetPacketCount
( (
_Out_ ULONG *pPacketCount _Out_ ULONG *pPacketCount
@ -1505,6 +1531,47 @@ Return Value:
} }
#endif // SYSVAD_BTH_BYPASS #endif // SYSVAD_BTH_BYPASS
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
CMiniportWaveRTStream::PropertyHandlerModulesListRequest
(
_In_ PPCPROPERTY_REQUEST PropertyRequest
)
{
// This specific APO->driver communication example is mainly added to show
// how this communication is done. The instance module list lives on the
// stream object and it can only have modules associated with the underline
// stream's pin.
PAGED_CODE();
DPF_ENTER(("[CMiniportWaveRTStream::PropertyHandlerModulesListRequest]"));
return AudioModule_GenericHandler_ModulesListRequest(
PropertyRequest,
GetAudioModuleList(),
GetAudioModuleListCount());
} // PropertyHandlerModulesListRequest
//=============================================================================
#pragma code_seg("PAGE")
NTSTATUS
CMiniportWaveRTStream::PropertyHandlerModuleCommand
(
_In_ PPCPROPERTY_REQUEST PropertyRequest
)
{
PAGED_CODE();
DPF_ENTER(("[CMiniportWaveRTStream::PropertyHandlerModuleCommand]"));
return AudioModule_GenericHandler_ModuleCommand(
PropertyRequest,
GetAudioModuleList(),
GetAudioModuleListCount());
} // PropertyHandlerModuleCommand
//============================================================================= //=============================================================================
#pragma code_seg() #pragma code_seg()
void void
@ -1550,10 +1617,10 @@ TimerNotifyRT
goto End; goto End;
} }
// Carry forward the remainder of this division // Carry forward the time greater than notification interval to adjust time to signal next buffer completion event accordingly.
_this->m_hnsDPCTimeCarryForward = (hnsCurrentTime - _this->m_ullLastDPCTimeStamp + _this->m_hnsDPCTimeCarryForward) % 10000; _this->m_hnsDPCTimeCarryForward = hnsCurrentTime - _this->m_ullLastDPCTimeStamp + _this->m_hnsDPCTimeCarryForward - (_this->m_ulNotificationIntervalMs * 10000);
// Save the last time DPC ran at notification interval // Save the last time DPC ran at notification interval
_this->m_ullLastDPCTimeStamp = (ULONG)hnsCurrentTime; _this->m_ullLastDPCTimeStamp = hnsCurrentTime;
_this->UpdatePosition(qpc); _this->UpdatePosition(qpc);

Просмотреть файл

@ -125,6 +125,8 @@ protected:
BOOLEAN m_bEoSReceived; BOOLEAN m_bEoSReceived;
BOOLEAN m_bLastBufferRendered; BOOLEAN m_bLastBufferRendered;
KSPIN_LOCK m_PositionSpinLock; KSPIN_LOCK m_PositionSpinLock;
AUDIOMODULE * m_pAudioModules;
ULONG m_AudioModuleCount;
#ifdef SYSVAD_BTH_BYPASS #ifdef SYSVAD_BTH_BYPASS
BOOLEAN m_ScoOpen; BOOLEAN m_ScoOpen;
@ -227,10 +229,45 @@ public:
{ {
return m_SignalProcessingMode; return m_SignalProcessingMode;
} }
NTSTATUS PropertyHandlerModulesListRequest
(
_In_ PPCPROPERTY_REQUEST PropertyRequest
);
NTSTATUS PropertyHandlerModuleCommand
(
_In_ PPCPROPERTY_REQUEST PropertyRequest
);
private: private:
//
// Helper functions. // Helper functions.
//
#pragma code_seg()
ULONG
GetAudioModuleListCount()
{
return m_AudioModuleCount;
}
AUDIOMODULE *
GetAudioModule(
_In_ ULONG Index
)
{
ASSERT(Index < GetAudioModuleListCount());
return &m_pAudioModules[Index];
}
AUDIOMODULE *
GetAudioModuleList()
{
return m_pAudioModules;
}
VOID WriteBytes VOID WriteBytes
( (
_In_ ULONG ByteDisplacement _In_ ULONG ByteDisplacement

Просмотреть файл

@ -0,0 +1,46 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
TARGETNAME=EndpointsCommon
TARGETTYPE=LIBRARY
KM_LIBRARY=1
INCLUDES= \
$(DDK_INC_PATH); \
..
C_DEFINES = $(C_DEFINES) -D_USE_WAVERT_ -DSYSVAD_BTH_BYPASS
#C_DEFINES = $(C_DEFINES) -D_USE_WAVERT_
DDK_TARGET_PLATFORM=Universal
#
# Indicate to the WDK that this sample only supports Win10[+]
#
MINIMUM_NT_TARGET_VERSION=$(_NT_TARGET_VERSION_WINTHRESHOLD)
#
# Audio driver is a KMDF miniport.
#
KMDF_VERSION_MAJOR=1
SOURCES=$(SOURCES) \
mintopo.cpp \
minwavert.cpp \
minwavertstream.cpp \
MiniportAudioEngineNode.cpp\
MiniportStreamAudioEngineNode.cpp\
micarraytopo.cpp \
speakertopo.cpp \
speakerhptopo.cpp \
bthhfptopo.cpp \
bthhfpmictopo.cpp \
bthhfpspeakertopo.cpp \
bthhfpminwavert.cpp \
AudioModuleHelper.cpp \

Просмотреть файл

@ -15,6 +15,9 @@ Abstract:
#ifndef _SYSVAD_SPEAKERHPWAVTABLE_H_ #ifndef _SYSVAD_SPEAKERHPWAVTABLE_H_
#define _SYSVAD_SPEAKERHPWAVTABLE_H_ #define _SYSVAD_SPEAKERHPWAVTABLE_H_
#include "AudioModule0.h"
#include "AudioModule1.h"
#include "AudioModule2.h"
// To keep the code simple assume device supports only 48KHz, 16-bit, stereo (PCM and NON-PCM) // To keep the code simple assume device supports only 48KHz, 16-bit, stereo (PCM and NON-PCM)
@ -578,6 +581,33 @@ PKSDATARANGE SpeakerHpPinDataRangePointersBridge[] =
//============================================================================= //=============================================================================
static
PCPROPERTY_ITEM PropertiesSpeakerHpHostPin[] =
{
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_DESCRIPTORS,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_GenericPin
},
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_COMMAND,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_GenericPin
},
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_GenericPin
},
};
DEFINE_PCAUTOMATION_TABLE_PROP(AutomationSpeakerHpHostPin, PropertiesSpeakerHpHostPin);
//=============================================================================
static static
PCPROPERTY_ITEM PropertiesSpeakerHpOffloadPin[] = PCPROPERTY_ITEM PropertiesSpeakerHpOffloadPin[] =
{ {
@ -592,7 +622,25 @@ PCPROPERTY_ITEM PropertiesSpeakerHpOffloadPin[] =
KSPROPERTY_OFFLOAD_PIN_VERIFY_STREAM_OBJECT_POINTER, // define properties KSPROPERTY_OFFLOAD_PIN_VERIFY_STREAM_OBJECT_POINTER, // define properties
KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT, KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_OffloadPin PropertyHandler_OffloadPin
} },
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_DESCRIPTORS,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_GenericPin
},
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_COMMAND,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_GenericPin
},
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_GenericPin
},
}; };
DEFINE_PCAUTOMATION_TABLE_PROP(AutomationSpeakerHpOffloadPin, PropertiesSpeakerHpOffloadPin); DEFINE_PCAUTOMATION_TABLE_PROP(AutomationSpeakerHpOffloadPin, PropertiesSpeakerHpOffloadPin);
@ -606,7 +654,7 @@ PCPIN_DESCRIPTOR SpeakerHpWaveMiniportPins[] =
SPEAKERHP_MAX_INPUT_SYSTEM_STREAMS, SPEAKERHP_MAX_INPUT_SYSTEM_STREAMS,
SPEAKERHP_MAX_INPUT_SYSTEM_STREAMS, SPEAKERHP_MAX_INPUT_SYSTEM_STREAMS,
0, 0,
NULL, &AutomationSpeakerHpHostPin, // AutomationTable
{ {
0, 0,
NULL, NULL,
@ -722,9 +770,84 @@ PCPROPERTY_ITEM PropertiesSpeakerHpWaveFilter[] =
KSPROPERTY_PIN_PROPOSEDATAFORMAT, KSPROPERTY_PIN_PROPOSEDATAFORMAT,
KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT, KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_WaveFilter PropertyHandler_WaveFilter
},
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_DESCRIPTORS,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_WaveFilter
},
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_COMMAND,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_WaveFilter
},
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_WaveFilter
},
};
//
// Endpoint audio module list.
//
static
AUDIOMODULE_DESCRIPTOR SpeakerHpModulesWaveFilter[] =
{
{ // 0
&AudioModule0Id, // class id.
&NULL_GUID, // generic, mode independent.
L"Generic system module",
AUDIOMODULE_INSTANCE_ID(0,0),
AUDIOMODULE0_MAJOR,
AUDIOMODULE0_MINOR,
AUDIOMODULE_DESCRIPTOR_FLAG_NONE,
sizeof(AUDIOMODULE0_CONTEXT),
AudioModule0_InitClass,
AudioModule0_InitInstance,
AudioModule0_Cleanup,
AudioModule0_Handler
},
{ // 1
&AudioModule1Id, // class id.
&AUDIO_SIGNALPROCESSINGMODE_MOVIE,
L"Speaker HP endpoint, EQ effect module, Movie mode",
AUDIOMODULE_INSTANCE_ID(0,0),
AUDIOMODULE1_MAJOR,
AUDIOMODULE1_MINOR,
AUDIOMODULE_DESCRIPTOR_FLAG_NONE,
sizeof(AUDIOMODULE1_CONTEXT),
AudioModule1_InitClass,
AudioModule1_InitInstance,
AudioModule1_Cleanup,
AudioModule1_Handler
},
{ // 2
&AudioModule2Id, // class id.
&AUDIO_SIGNALPROCESSINGMODE_DEFAULT,
L"Speaker HP endpoint, Echo Cancellation effect module, Default mode",
AUDIOMODULE_INSTANCE_ID(0,0),
AUDIOMODULE2_MAJOR,
AUDIOMODULE2_MINOR,
AUDIOMODULE_DESCRIPTOR_FLAG_NONE,
sizeof(AUDIOMODULE2_CONTEXT),
AudioModule2_InitClass,
AudioModule2_InitInstance,
AudioModule2_Cleanup,
AudioModule2_Handler
} }
}; };
//
// Audio module notification device id.
// NOTE: do not use this guid for real driver, generate a new one.
//
const GUID SpeakerHpModuleNotificationDeviceId =
{0x3A66BE17,0x5440,0x48E7,0x83,0x76,0xB7,0x5A,0x0B,0x1A,0x92,0x2D};
DEFINE_PCAUTOMATION_TABLE_PROP(AutomationSpeakerHpWaveFilter, PropertiesSpeakerHpWaveFilter); DEFINE_PCAUTOMATION_TABLE_PROP(AutomationSpeakerHpWaveFilter, PropertiesSpeakerHpWaveFilter);
//============================================================================= //=============================================================================

Просмотреть файл

@ -16,6 +16,8 @@ Abstract:
#define _SYSVAD_SPEAKERWAVTABLE_H_ #define _SYSVAD_SPEAKERWAVTABLE_H_
#include "SysVadShared.h" #include "SysVadShared.h"
#include "AudioModule0.h"
#include "AudioModule1.h"
// To keep the code simple assume device supports only 48KHz, 16-bit, stereo (PCM and NON-PCM) // To keep the code simple assume device supports only 48KHz, 16-bit, stereo (PCM and NON-PCM)
@ -580,6 +582,33 @@ PKSDATARANGE SpeakerPinDataRangePointersBridge[] =
//============================================================================= //=============================================================================
static
PCPROPERTY_ITEM PropertiesSpeakerHostPin[] =
{
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_DESCRIPTORS,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_GenericPin
},
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_COMMAND,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_GenericPin
},
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_GenericPin
},
};
DEFINE_PCAUTOMATION_TABLE_PROP(AutomationSpeakerHostPin, PropertiesSpeakerHostPin);
//=============================================================================
static static
PCPROPERTY_ITEM PropertiesSpeakerOffloadPin[] = PCPROPERTY_ITEM PropertiesSpeakerOffloadPin[] =
{ {
@ -594,7 +623,25 @@ PCPROPERTY_ITEM PropertiesSpeakerOffloadPin[] =
KSPROPERTY_OFFLOAD_PIN_VERIFY_STREAM_OBJECT_POINTER, // define properties KSPROPERTY_OFFLOAD_PIN_VERIFY_STREAM_OBJECT_POINTER, // define properties
KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT, KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_OffloadPin PropertyHandler_OffloadPin
} },
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_DESCRIPTORS,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_GenericPin
},
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_COMMAND,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_GenericPin
},
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_GenericPin
},
}; };
DEFINE_PCAUTOMATION_TABLE_PROP(AutomationSpeakerOffloadPin, PropertiesSpeakerOffloadPin); DEFINE_PCAUTOMATION_TABLE_PROP(AutomationSpeakerOffloadPin, PropertiesSpeakerOffloadPin);
@ -608,7 +655,7 @@ PCPIN_DESCRIPTOR SpeakerWaveMiniportPins[] =
SPEAKER_MAX_INPUT_SYSTEM_STREAMS, SPEAKER_MAX_INPUT_SYSTEM_STREAMS,
SPEAKER_MAX_INPUT_SYSTEM_STREAMS, SPEAKER_MAX_INPUT_SYSTEM_STREAMS,
0, 0,
NULL, &AutomationSpeakerHostPin, // AutomationTable
{ {
0, 0,
NULL, NULL,
@ -730,9 +777,84 @@ PCPROPERTY_ITEM PropertiesSpeakerWaveFilter[] =
KSPROPERTY_SYSVAD_DEFAULTSTREAMEFFECTS, KSPROPERTY_SYSVAD_DEFAULTSTREAMEFFECTS,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT, KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_WaveFilter PropertyHandler_WaveFilter
},
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_DESCRIPTORS,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_WaveFilter
},
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_COMMAND,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_WaveFilter
},
{
&KSPROPSETID_AudioModule,
KSPROPERTY_AUDIOMODULE_NOTIFICATION_DEVICE_ID,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_WaveFilter
},
};
//
// Endpoint audio module list.
//
static
AUDIOMODULE_DESCRIPTOR SpeakerModulesWaveFilter[] =
{
{ // 0
&AudioModule0Id, // class id.
&NULL_GUID, // generic, mode independent.
L"Generic system module",
AUDIOMODULE_INSTANCE_ID(0,0),
AUDIOMODULE0_MAJOR,
AUDIOMODULE0_MINOR,
AUDIOMODULE_DESCRIPTOR_FLAG_NONE,
sizeof(AUDIOMODULE0_CONTEXT),
AudioModule0_InitClass,
AudioModule0_InitInstance,
AudioModule0_Cleanup,
AudioModule0_Handler
},
{ // 1
&AudioModule1Id, // class id.
&AUDIO_SIGNALPROCESSINGMODE_MOVIE,
L"Speaker endpoint, EQ effect module, Movie mode",
AUDIOMODULE_INSTANCE_ID(0,0),
AUDIOMODULE1_MAJOR,
AUDIOMODULE1_MINOR,
AUDIOMODULE_DESCRIPTOR_FLAG_NONE,
sizeof(AUDIOMODULE1_CONTEXT),
AudioModule1_InitClass,
AudioModule1_InitInstance,
AudioModule1_Cleanup,
AudioModule1_Handler
},
{ // 2
&AudioModule1Id, // class id.
&AUDIO_SIGNALPROCESSINGMODE_DEFAULT,
L"Speaker endpoint, EQ effect module, Default mode",
AUDIOMODULE_INSTANCE_ID(1,0),
AUDIOMODULE1_MAJOR,
AUDIOMODULE1_MINOR,
AUDIOMODULE_DESCRIPTOR_FLAG_NONE,
sizeof(AUDIOMODULE1_CONTEXT),
AudioModule1_InitClass,
AudioModule1_InitInstance,
AudioModule1_Cleanup,
AudioModule1_Handler
} }
}; };
//
// Audio module notification device id.
// NOTE: do not use this guid for real driver, generate a new one.
//
const GUID SpeakerModuleNotificationDeviceId =
{0xC01C987A,0x30A9,0x4DB7,0x8D,0x69,0x69,0x6C,0xFF,0x41,0xE4,0xB9};
DEFINE_PCAUTOMATION_TABLE_PROP(AutomationSpeakerWaveFilter, PropertiesSpeakerWaveFilter); DEFINE_PCAUTOMATION_TABLE_PROP(AutomationSpeakerWaveFilter, PropertiesSpeakerWaveFilter);
//============================================================================= //=============================================================================

Просмотреть файл

@ -115,8 +115,8 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
<RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreaded</RuntimeLibrary>
<RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions> <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
@ -139,8 +139,8 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreaded</RuntimeLibrary>
<RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions> <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
@ -163,8 +163,8 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreaded</RuntimeLibrary>
<RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions> <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
@ -187,8 +187,8 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreaded</RuntimeLibrary>
<RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions> <PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>

Просмотреть файл

@ -0,0 +1,39 @@
<?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>{75C3E63D-04EA-4EB3-B9F1-505497C51F71}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
<UniqueIdentifier>{5E8F8D4C-2886-4109-9E78-CE5EA6DB4AC4}</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>{75D3016A-4ED8-4FAF-9817-394BE1112534}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="KeywordDetectorContosoAdapter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<Midl Include="KeywordDetectorContosoAdapter.idl">
<Filter>Source Files</Filter>
</Midl>
<None Include="KeywordDetectorContosoAdapter.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="KeywordDetectorContosoAdapter.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,53 @@
TARGETTYPE=DYNLINK
TARGETNAME=KeywordDetectorContosoAdapter
DLLENTRY=_DllMainCRTStartup
DLLDEF=KeywordDetectorContosoAdapter.def
#USE_ATL=1
USE_LIBCMT=1
MSC_WARNING_LEVEL=-W4 \
-WX
C_DEFINES=$(C_DEFINES) \
-D_WINDLL \
-D_USRDLL \
-DUNICODE \
-D_UNICODE
#
# Indicate to the WDK that this sample only supports Win10[+]
#
MINIMUM_NT_TARGET_VERSION=$(_NT_TARGET_VERSION_WINTHRESHOLD)
# Indicate that this DLL must be included in the driver package
DDK_NO_PACKAGE_PROJECT=0
DDK_INCLUDE_PACKAGE_PROJECT=1
INCLUDES= \
$(DDK_INC_PATH); \
..\inc;..\; \
SOURCES=KeywordDetectorContosoAdapter.idl \
KeywordDetectorContosoAdapter.rc \
dllmain.cpp \
KeywordDetectorContosoAdapter.cpp \
stdafx.cpp \
TARGETLIBS= \
$(SDK_LIB_PATH)\onecore_downlevel.lib \
$(SDK_LIB_PATH)\onecore_downlevel.lib \
$(SDK_LIB_PATH)\oleaut32.lib \
\
$(ONECORE_PRIV_SDK_LIB_PATH)\OneCore_Forwarder_user32.lib \
$(INTERNAL_SDK_LIB_PATH)\onecoreuapuuid.lib \
$(SDK_LIB_PATH)\mfplat.lib \
$(SDK_LIB_PATH)\runtimeobject.lib \
MUI_VERIFY_NO_LOC_RESOURCE=1

Просмотреть файл

@ -0,0 +1,99 @@
<?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>
<ItemGroup>
<ProjectReference Include="..\KeywordDetectorAdapter\KeywordDetectorContosoAdapter.vcxproj">
<Project>{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}</Project>
</ProjectReference>
<ProjectReference Include="..\PhoneAudioSample\PhoneAudioSample.vcxproj">
<Project>{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}</Project>
</ProjectReference>
<ProjectReference Include="..\SwapAPO\APO\SwapAPO.vcxproj">
<Project>{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}</Project>
</ProjectReference>
<ProjectReference Include="..\SwapAPO\DelayAPO\DelayAPO.vcxproj">
<Project>{8851AB85-70B3-4798-A149-BA366DF9EC25}</Project>
</ProjectReference>
<ProjectReference Include="..\SwapAPO\PropPageExtensions\PropPageExt.vcxproj">
<Project>{D253C552-154D-49E1-820A-B2CD9D9FF13E}</Project>
</ProjectReference>
<ProjectReference Include="..\TabletAudioSample\TabletAudioSample.vcxproj">
<Project>{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}</Project>
</ProjectReference>
</ItemGroup>
<PropertyGroup Label="PropertySheets">
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Utility</ConfigurationType>
<DriverType>Package</DriverType>
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
<Configuration>Debug</Configuration>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Globals">
<ProjectGuid>{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}</ProjectGuid>
<SampleGuid>{E9D167E6-E633-4284-8F02-FF86DF3B6D7F}</SampleGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<PropertyGroup>
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<ImportToStore>False</ImportToStore>
<InstallMode>None</InstallMode>
<HardwareIdString />
<CommandLine />
<ScriptPath />
<DeployFiles />
<ScriptName />
<ScriptDeviceQuery>%PathToInf%</ScriptDeviceQuery>
<EnableVerifier>False</EnableVerifier>
<AllDrivers>False</AllDrivers>
<VerifyProjectOutput>True</VerifyProjectOutput>
<VerifyDrivers />
<VerifyFlags>133563</VerifyFlags>
</PropertyGroup>
<ItemDefinitionGroup>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

Просмотреть файл

@ -0,0 +1,21 @@
<?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>{0924612D-FBA7-477E-BBB9-B3B6EA7C6B03}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
<UniqueIdentifier>{97311738-0AD8-4F7E-AC88-9C9BEAF53AEE}</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>{8DC1C4F0-C285-400E-A983-77A339891354}</UniqueIdentifier>
</Filter>
<Filter Include="Driver Files">
<Extensions>inf;inv;inx;mof;mc;</Extensions>
<UniqueIdentifier>{9F086F34-79D2-4FAA-87FD-C2DBEFCED0BA}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,73 @@
<?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>{6BC89CB0-7C76-439F-8D55-E3125E355A42}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
<UniqueIdentifier>{02E55FC1-89F6-4E2D-A10B-A6476FF89B86}</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>{B836489B-8D2E-41DD-A232-0D6C40243B08}</UniqueIdentifier>
</Filter>
<Filter Include="Driver Files">
<Extensions>inf;inv;inx;mof;mc;</Extensions>
<UniqueIdentifier>{850E3B99-7C84-454B-9E04-6A7CF9852E6C}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\adapter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\basetopo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\hw.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\kshelper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\savedata.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\tonegenerator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cellulartopo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cellularwave.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fmtopo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="fmwave.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="handsetmictopo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="handsetspeakertopo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="michstopo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="speakerhstopo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\sysvad.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

Просмотреть файл

@ -185,7 +185,10 @@ ENDPOINT_MINIPAIR SpeakerMiniports =
SIZEOF_ARRAY(SpeakerPinDeviceFormatsAndModes), SIZEOF_ARRAY(SpeakerPinDeviceFormatsAndModes),
SpeakerTopologyPhysicalConnections, SpeakerTopologyPhysicalConnections,
SIZEOF_ARRAY(SpeakerTopologyPhysicalConnections), SIZEOF_ARRAY(SpeakerTopologyPhysicalConnections),
ENDPOINT_OFFLOAD_SUPPORTED ENDPOINT_OFFLOAD_SUPPORTED,
SpeakerModulesWaveFilter,
SIZEOF_ARRAY(SpeakerModulesWaveFilter),
&SpeakerModuleNotificationDeviceId,
}; };
/********************************************************************* /*********************************************************************
@ -227,7 +230,8 @@ ENDPOINT_MINIPAIR SpeakerHsMiniports =
SIZEOF_ARRAY(SpeakerHsPinDeviceFormatsAndModes), SIZEOF_ARRAY(SpeakerHsPinDeviceFormatsAndModes),
SpeakerHsTopologyPhysicalConnections, SpeakerHsTopologyPhysicalConnections,
SIZEOF_ARRAY(SpeakerHsTopologyPhysicalConnections), SIZEOF_ARRAY(SpeakerHsTopologyPhysicalConnections),
ENDPOINT_OFFLOAD_SUPPORTED ENDPOINT_OFFLOAD_SUPPORTED,
NULL, 0, NULL, // audio module settings.
}; };
// //
@ -271,7 +275,8 @@ ENDPOINT_MINIPAIR MicHsMiniports =
SIZEOF_ARRAY(MicHsPinDeviceFormatsAndModes), SIZEOF_ARRAY(MicHsPinDeviceFormatsAndModes),
MicHsTopologyPhysicalConnections, MicHsTopologyPhysicalConnections,
SIZEOF_ARRAY(MicHsTopologyPhysicalConnections), SIZEOF_ARRAY(MicHsTopologyPhysicalConnections),
ENDPOINT_NO_FLAGS ENDPOINT_NO_FLAGS,
NULL, 0, NULL, // audio module settings.
}; };
@ -317,7 +322,8 @@ ENDPOINT_MINIPAIR MicArray1Miniports =
SIZEOF_ARRAY(MicArrayPinDeviceFormatsAndModes), SIZEOF_ARRAY(MicArrayPinDeviceFormatsAndModes),
MicArray1TopologyPhysicalConnections, MicArray1TopologyPhysicalConnections,
SIZEOF_ARRAY(MicArray1TopologyPhysicalConnections), SIZEOF_ARRAY(MicArray1TopologyPhysicalConnections),
ENDPOINT_SOUNDDETECTOR_SUPPORTED ENDPOINT_SOUNDDETECTOR_SUPPORTED,
NULL, 0, NULL, // audio module settings.
}; };
/********************************************************************* /*********************************************************************
@ -370,7 +376,8 @@ ENDPOINT_MINIPAIR CellularMiniports =
SIZEOF_ARRAY(CellularPinDeviceFormatsAndModes), SIZEOF_ARRAY(CellularPinDeviceFormatsAndModes),
CellularTopologyPhysicalConnections, CellularTopologyPhysicalConnections,
SIZEOF_ARRAY(CellularTopologyPhysicalConnections), SIZEOF_ARRAY(CellularTopologyPhysicalConnections),
ENDPOINT_CELLULAR_PROVIDER1 ENDPOINT_CELLULAR_PROVIDER1,
NULL, 0, NULL, // audio module settings.
}; };
@ -401,7 +408,8 @@ ENDPOINT_MINIPAIR CellularMiniports2 =
SIZEOF_ARRAY(CellularPinDeviceFormatsAndModes), SIZEOF_ARRAY(CellularPinDeviceFormatsAndModes),
CellularTopologyPhysicalConnections2, CellularTopologyPhysicalConnections2,
SIZEOF_ARRAY(CellularTopologyPhysicalConnections2), SIZEOF_ARRAY(CellularTopologyPhysicalConnections2),
ENDPOINT_CELLULAR_PROVIDER2 ENDPOINT_CELLULAR_PROVIDER2,
NULL, 0, NULL, // audio module settings.
}; };
/********************************************************************* /*********************************************************************
@ -443,7 +451,8 @@ ENDPOINT_MINIPAIR HandsetSpeakerMiniports =
SIZEOF_ARRAY(HandsetSpeakerPinDeviceFormatsAndModes), SIZEOF_ARRAY(HandsetSpeakerPinDeviceFormatsAndModes),
HandsetSpeakerTopologyPhysicalConnections, HandsetSpeakerTopologyPhysicalConnections,
SIZEOF_ARRAY(HandsetSpeakerTopologyPhysicalConnections), SIZEOF_ARRAY(HandsetSpeakerTopologyPhysicalConnections),
ENDPOINT_NO_FLAGS ENDPOINT_NO_FLAGS,
NULL, 0, NULL, // audio module settings.
}; };
// //
@ -487,7 +496,8 @@ ENDPOINT_MINIPAIR HandsetMicMiniports =
SIZEOF_ARRAY(HandsetMicPinDeviceFormatsAndModes), SIZEOF_ARRAY(HandsetMicPinDeviceFormatsAndModes),
HandsetMicTopologyPhysicalConnections, HandsetMicTopologyPhysicalConnections,
SIZEOF_ARRAY(HandsetMicTopologyPhysicalConnections), SIZEOF_ARRAY(HandsetMicTopologyPhysicalConnections),
ENDPOINT_NO_FLAGS ENDPOINT_NO_FLAGS,
NULL, 0, NULL, // audio module settings.
}; };
/********************************************************************* /*********************************************************************
@ -527,7 +537,8 @@ ENDPOINT_MINIPAIR FmRxMiniports =
SIZEOF_ARRAY(FmRxPinDeviceFormatsAndModes), SIZEOF_ARRAY(FmRxPinDeviceFormatsAndModes),
FmRxTopologyPhysicalConnections, FmRxTopologyPhysicalConnections,
SIZEOF_ARRAY(FmRxTopologyPhysicalConnections), SIZEOF_ARRAY(FmRxTopologyPhysicalConnections),
ENDPOINT_NO_FLAGS ENDPOINT_NO_FLAGS,
NULL, 0, NULL, // audio module settings.
}; };
//============================================================================= //=============================================================================

Просмотреть файл

@ -0,0 +1,58 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
!include ..\sources.inc
TARGETNAME=PhoneAudioSample
TARGETLIBS= \
$(TARGETLIBS) \
$(OBJ_PATH)\..\EndpointsCommon\$(O)\EndpointsCommon.lib
C_DEFINES = $(C_DEFINES) -D_USE_WAVERT_ -DSYSVAD_BTH_BYPASS
#C_DEFINES = $(C_DEFINES) -D_USE_WAVERT_
#
# Indicate to the WDK that this sample only supports Win10[+]
#
MINIMUM_NT_TARGET_VERSION=$(_NT_TARGET_VERSION_WINTHRESHOLD)
DDK_TARGET_PLATFORM=Universal
#
# Audio driver is a KMDF miniport.
#
KMDF_VERSION_MAJOR=1
#
# Uncomment one of the following lines to select the right power management.
# Note that the single-component/multi-state feature requires also a registry
# value set via the INF. The name of the registry value is SingleComponentMultiFxStates.
# see INF file for more info.
#
C_DEFINES= $(C_DEFINES) -D_USE_IPortClsRuntimePower
#C_DEFINES= $(C_DEFINES) -D_USE_SingleComponentMultiFxStates
INCLUDES= \
$(INCLUDES); \
..\EndpointsCommon; \
SOURCES=$(SOURCES) \
cellulartopo.cpp \
fmtopo.cpp \
handsetspeakertopo.cpp \
handsetmictopo.cpp \
michstopo.cpp \
speakerhstopo.cpp \
cellularwave.cpp \
fmwave.cpp \
# Indicate that this module must be included in the driver package
DDK_NO_PACKAGE_PROJECT=0
DDK_INCLUDE_PACKAGE_PROJECT=1
MUI_VERIFY_NO_LOC_RESOURCE=1

Просмотреть файл

@ -1,7 +1,7 @@
Slate Virtual Audio Device Driver Sample SysVAD Virtual Audio Device Driver Sample
======================================== ========================================
The Microsoft Slate Virtual Audio Device Driver (SYSVAD) shows how to develop a WDM audio driver that exposes support for multiple audio devices. The Microsoft SysVAD Virtual Audio Device Driver (SYSVAD) shows how to develop a WDM audio driver that exposes support for multiple audio devices.
Some of these audio devices are embedded in the system (for example, speakers, microphone arrays) while others are pluggable (like headphones, speakers, microphones, Bluetooth headsets etc.). The driver uses WaveRT and audio offloading for rendering devices. The driver uses a "virtual audio device" instead of an actual hardware-based adapter, and highlights the different aspects of the audio offloading WDM audio driver architecture. Some of these audio devices are embedded in the system (for example, speakers, microphone arrays) while others are pluggable (like headphones, speakers, microphones, Bluetooth headsets etc.). The driver uses WaveRT and audio offloading for rendering devices. The driver uses a "virtual audio device" instead of an actual hardware-based adapter, and highlights the different aspects of the audio offloading WDM audio driver architecture.
@ -48,11 +48,13 @@ The package should contain these files:
File | Description File | Description
-----|------------ -----|------------
TabletAudioSample.sys OR PhoneAudioSample| The driver file.
SwapAPO.dll | A sample APO.
DelayAPO.dll | A sample APO.
PropPageExt.dll | A sample driver extension for a property page. PropPageExt.dll | A sample driver extension for a property page.
SlateAudioSample.sys | The driver file.
SwapAPO.dll | A sample driver extension for a UI to manage APOs.
sysvad.cat | A signed catalog file, which serves as the signature for the entire package. sysvad.cat | A signed catalog file, which serves as the signature for the entire package.
sysvad.inf | An information (INF) file that contains information needed to install the driver. TabletAudioSample.inf | An information (INF) file that contains information needed to install the driver.
PhoneAudioSample.inf | An information (INF) file that contains information needed to install the driver.
WdfCoinstaller01011.dll | The coinstaller for version 1.xx of KMDF. WdfCoinstaller01011.dll | The coinstaller for version 1.xx of KMDF.
Run the sample Run the sample
@ -60,7 +62,7 @@ Run the sample
The computer where you install the driver is called the *target computer* or the *test computer*. Typically this is a separate computer from the computer on which you develop and build the driver package. The computer where you develop and build the driver is called the *host computer*. The computer where you install the driver is called the *target computer* or the *test computer*. Typically this is a separate computer from the computer on which you develop and build the driver package. The computer where you develop and build the driver is called the *host computer*.
The process of moving the driver package to the target computer and installing the driver is called *deploying* the driver. You can deploy the sample driver, SlateAudioSample, automatically or manually. The process of moving the driver package to the target computer and installing the driver is called *deploying* the driver. You can deploy the sample driver, TabletAudioSample or PhoneAudioSample, automatically or manually.
### Automatic deployment ### Automatic deployment
@ -88,7 +90,7 @@ If you haven't already done so, then preform the steps in the **Build the sample
In Visual Studio, in Solution Explorer, right click **package** (lower case), and choose **Properties**. Navigate to **Configuration Properties** \> **Driver Install** \> **Deployment**. In Visual Studio, in Solution Explorer, right click **package** (lower case), and choose **Properties**. Navigate to **Configuration Properties** \> **Driver Install** \> **Deployment**.
Check , **Enable deployment** and check **Remove previous driver versions before deployment**. For **Target Computer Name**, select the name of a target computer that you provisioned previously. Select **Hardware ID Driver Update**, and enter *\*SYSVAD\_SLATEAUDIO* for the hardware ID. Click **OK**. Check , **Enable deployment** and check **Remove previous driver versions before deployment**. For **Target Computer Name**, select the name of a target computer that you provisioned previously. Select **Hardware ID Driver Update**, and enter *\*Root\sysvad_TabletAudioSample* for the hardware ID. Click **OK**.
On the **Build** menu, choose **Deploy Package** or **Build Solution**. This will deploy the sample driver to your target computer. On the **Build** menu, choose **Deploy Package** or **Build Solution**. This will deploy the sample driver to your target computer.
@ -118,19 +120,19 @@ If you need more detailed instructions for setting up the target computer, see [
**2. Install the driver** **2. Install the driver**
The SlateAudioSample driver package contains a sample driver and 2 driver extension samples. The following instructions show you how to install and test the sample driver. Here's the general syntax for the devcon tool that you will use to install the driver: The TabletAudioSample or PhoneAudioSample driver package contains a sample driver and 2 driver extension samples. The following instructions show you how to install and test the sample driver. Here's the general syntax for the devcon tool that you will use to install the driver:
**devcon install \<*INF file*>\<*hardware ID*\>** **devcon install \<*INF file*>\<*hardware ID*\>**
The INF file required for installing this driver is *sysvad.inf*. Here's how to find the hardware ID for installing the *SlateAudioSample.sys* sample: On the target computer, navigate to the folder that contains the files for your driver (for example, *C:\\SysvadDriver*). Then right-click the INF file (*sysvad.inf*) and open it with Notepad. Use Ctrl+F to find the [MicrosoftDS] section. Note that there is a comma-separated element at the end of the row. The element after the comma shows the hardware ID. So for this sample, the hardware ID is \*SYSVAD\_SLATEAUDIO. The INF file required for installing this driver is *sysvad.inf*. Here's how to find the hardware ID for installing the *TabletAudioSample.sys or PhoneAudioSample* sample: On the target computer, navigate to the folder that contains the files for your driver (for example, *C:\\SysvadDriver*). Then right-click the INF file (*sysvad.inf*) and open it with Notepad. Use Ctrl+F to find the [MicrosoftDS] section. Note that there is a comma-separated element at the end of the row. The element after the comma shows the hardware ID. So for this sample, the hardware ID is \*ROOT\sysvad_TabletAudioSample.
On the target computer, open a Command Prompt window as Administrator. Navigate to your driver package folder, and enter the following command: On the target computer, open a Command Prompt window as Administrator. Navigate to your driver package folder, and enter the following command:
**devcon install sysvad.inf \*SYSVAD\_SLATEAUDIO** **devcon install sysvad.inf \*ROOT\sysvad_TabletAudioSample*
If you get an error message about *devcon* not being recognized, try adding the path to the *devcon* tool. For example, if you copied it to a folder called *C:\\Tools*, then try using the following command: If you get an error message about *devcon* not being recognized, try adding the path to the *devcon* tool. For example, if you copied it to a folder called *C:\\Tools*, then try using the following command:
**c:\\tools\\devcon install sysvad.inf \*SYSVAD\_SLATEAUDIO** **c:\\tools\\devcon install sysvad.inf \*ROOT\sysvad_TabletAudioSample**
For more detailed instructions, see [Configuring a Computer for Driver Deployment, Testing, and Debugging](http://msdn.microsoft.com/en-us/library/windows/hardware/hh698272(v=vs.85).aspx). For more detailed instructions, see [Configuring a Computer for Driver Deployment, Testing, and Debugging](http://msdn.microsoft.com/en-us/library/windows/hardware/hh698272(v=vs.85).aspx).
@ -138,9 +140,9 @@ After successfully installing the sample driver, you're now ready to test it.
### Test the driver ### Test the driver
On the target computer, in a Command Prompt window, enter **devmgmt** to open Device Manager. In Device Manager, on the **View** menu, choose **Devices by type**. In the device tree, locate *Microsoft Virtual Audio Device (WDM) - Slate Sample*. This is typically under the **Sound, video and game controllers** node. On the target computer, in a Command Prompt window, enter **devmgmt** to open Device Manager. In Device Manager, on the **View** menu, choose **Devices by type**. In the device tree, locate *Microsoft Virtual Audio Device (WDM) - Tablet Audio Sample*. This is typically under the **Sound, video and game controllers** node.
On the target computer, open Control Panel and navigate to **Hardware and Sound** \> **Manage audio devices**. In the Sound dialog box, select the speaker icon labeled as *Microsoft Virtual Audio Device (WDM) - Slate Sample*, then click **Set Default**, but do not click **OK**. This will keep the Sound dialog box open. On the target computer, open Control Panel and navigate to **Hardware and Sound** \> **Manage audio devices**. In the Sound dialog box, select the speaker icon labeled as *Microsoft Virtual Audio Device (WDM) - Tablet Audio Sample*, then click **Set Default**, but do not click **OK**. This will keep the Sound dialog box open.
Locate an MP3 or other audio file on the target computer and double-click to play it. Then in the Sound dialog box, verify that there is activity in the volume level indicator associated with the *Microsoft Virtual Audio Device (WDM) - Slate Sample* driver. Locate an MP3 or other audio file on the target computer and double-click to play it. Then in the Sound dialog box, verify that there is activity in the volume level indicator associated with the *Microsoft Virtual Audio Device (WDM) - Tablet Audio Sample* driver.

Просмотреть файл

@ -29,13 +29,6 @@ _Analysis_mode_(_Analysis_code_type_user_driver_)
// //
// {B8EC75BA-00ED-434C-A732-064A0F00788E} // {B8EC75BA-00ED-434C-A732-064A0F00788E}
DEFINE_GUID(SwapEffectId, 0xb8ec75ba, 0x00ed, 0x434c, 0xa7, 0x32, 0x06, 0x4a, 0x0f, 0x00, 0x78, 0x8e); DEFINE_GUID(SwapEffectId, 0xb8ec75ba, 0x00ed, 0x434c, 0xa7, 0x32, 0x06, 0x4a, 0x0f, 0x00, 0x78, 0x8e);
// {29FBFBB5-9002-4ABC-DCBC-DD45462478C8}
DEFINE_GUID(DelayEffectId, 0x29FBFBB5, 0x9002, 0x4ABC, 0xDC, 0xBC, 0xDD, 0x45, 0x46, 0x24, 0x78, 0xC8);
// 1000 ms of delay
#define HNS_DELAY HNS_PER_SECOND
#define FRAMES_FROM_HNS(hns) (ULONG)(1.0 * hns / HNS_PER_SECOND * GetFramesPerSecond() + 0.5)
LONG GetCurrentEffectsSetting(IPropertyStore* properties, PROPERTYKEY pkeyEnable, GUID processingMode); LONG GetCurrentEffectsSetting(IPropertyStore* properties, PROPERTYKEY pkeyEnable, GUID processingMode);
@ -59,9 +52,6 @@ public:
, m_hEffectsChangedEvent(NULL) , m_hEffectsChangedEvent(NULL)
, m_AudioProcessingMode(AUDIO_SIGNALPROCESSINGMODE_DEFAULT) , m_AudioProcessingMode(AUDIO_SIGNALPROCESSINGMODE_DEFAULT)
, m_fEnableSwapMFX(FALSE) , m_fEnableSwapMFX(FALSE)
, m_fEnableDelayMFX(FALSE)
, m_nDelayFrames(0)
, m_iDelayIndex(0)
{ {
m_pf32Coefficients = NULL; m_pf32Coefficients = NULL;
} }
@ -141,7 +131,6 @@ public:
public: public:
LONG m_fEnableSwapMFX; LONG m_fEnableSwapMFX;
LONG m_fEnableDelayMFX;
GUID m_AudioProcessingMode; GUID m_AudioProcessingMode;
CComPtr<IPropertyStore> m_spAPOSystemEffectsProperties; CComPtr<IPropertyStore> m_spAPOSystemEffectsProperties;
CComPtr<IMMDeviceEnumerator> m_spEnumerator; CComPtr<IMMDeviceEnumerator> m_spEnumerator;
@ -150,10 +139,6 @@ public:
// Locked memory // Locked memory
FLOAT32 *m_pf32Coefficients; FLOAT32 *m_pf32Coefficients;
CComHeapPtr<FLOAT32> m_pf32DelayBuffer;
UINT32 m_nDelayFrames;
UINT32 m_iDelayIndex;
private: private:
CCriticalSection m_EffectsLock; CCriticalSection m_EffectsLock;
HANDLE m_hEffectsChangedEvent; HANDLE m_hEffectsChangedEvent;
@ -182,8 +167,6 @@ public:
, m_AudioProcessingMode(AUDIO_SIGNALPROCESSINGMODE_DEFAULT) , m_AudioProcessingMode(AUDIO_SIGNALPROCESSINGMODE_DEFAULT)
, m_fEnableSwapSFX(FALSE) , m_fEnableSwapSFX(FALSE)
, m_fEnableDelaySFX(FALSE) , m_fEnableDelaySFX(FALSE)
, m_nDelayFrames(0)
, m_iDelayIndex(0)
{ {
} }
@ -255,10 +238,6 @@ public:
CCriticalSection m_EffectsLock; CCriticalSection m_EffectsLock;
HANDLE m_hEffectsChangedEvent; HANDLE m_hEffectsChangedEvent;
CComHeapPtr<FLOAT32> m_pf32DelayBuffer;
UINT32 m_nDelayFrames;
UINT32 m_iDelayIndex;
}; };
#pragma AVRT_VTABLES_END #pragma AVRT_VTABLES_END
@ -284,22 +263,6 @@ void ProcessSwapScale(
UINT32 u32SamplesPerFrame, UINT32 u32SamplesPerFrame,
FLOAT32 *pf32Coefficients ); FLOAT32 *pf32Coefficients );
//
// Declaration of the ProcessDelay routine.
//
void ProcessDelay(
_Out_writes_(u32ValidFrameCount * u32SamplesPerFrame)
FLOAT32 *pf32OutputFrames,
_In_reads_(u32ValidFrameCount * u32SamplesPerFrame)
const FLOAT32 *pf32InputFrames,
UINT32 u32ValidFrameCount,
UINT32 u32SamplesPerFrame,
_Inout_updates_(u32DelayFrames * u32SamplesPerFrame)
FLOAT32 *pf32DelayBuffer,
UINT32 u32DelayFrames,
_Inout_
UINT32 *pu32DelayIndex );
// //
// Convenience methods // Convenience methods
// //

Просмотреть файл

@ -0,0 +1,45 @@
<?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>{296F0C2A-85AF-4624-97D4-6D3251998382}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
<UniqueIdentifier>{655A91B5-15BB-4151-B3B5-8185B5FA1ABB}</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>{A9DFA5D3-3035-416E-BBD8-8D0745973136}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Swap.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SwapAPODll.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SwapAPOMFX.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SwapAPOSFX.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<Midl Include="SwapAPODll.idl">
<Filter>Source Files</Filter>
</Midl>
<Midl Include="SwapAPOInterface.idl">
<Filter>Source Files</Filter>
</Midl>
<None Include="SwapAPODll.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="SwapAPODll.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,36 @@
#############################################################################
#
# Copyright (c) Microsoft Corporation.
# All Rights Reserved.
#
# Makefile for wdm\audio\sysfx\apo
#
#############################################################################
## NT BUILD ENVIROMENT
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the components of NT.
#
!if defined(IA64)
!message This sample is not to be built for IA64 targets
!else
!IF DEFINED(_NT_TARGET_VERSION)
#! IF $(_NT_TARGET_VERSION)>=0x501
! IF $(_NT_TARGET_VERSION)>=0x600
! INCLUDE $(NTMAKEENV)\makefile.def
! ELSE
# Only warn once per directory
! INCLUDE $(NTMAKEENV)\makefile.plt
! IF "$(BUILD_PASS)"=="PASS1"
! message BUILDMSG: Warning : Building the sample "$(MAKEDIR)" for downlevel build environments is temporarily disabled in WDK for Beta2.
! ENDIF
! ENDIF
!ELSE
! INCLUDE $(NTMAKEENV)\makefile.def
!ENDIF
!endif

Просмотреть файл

@ -0,0 +1,13 @@
!include ..\sources.inc
TARGETNAME=SwapAPO
DLLDEF=SwapAPODll.def
SOURCES=SwapAPOInterface.idl \
SwapAPOMFX.cpp \
SwapAPOSFX.cpp \
Swap.cpp \
SwapAPODll.idl \
SwapAPODll.rc \
SwapAPODll.cpp \

Просмотреть файл

@ -112,72 +112,3 @@ void ProcessSwapScale(
} }
} }
#pragma AVRT_CODE_END #pragma AVRT_CODE_END
#pragma AVRT_CODE_BEGIN
void ProcessDelay(
_Out_writes_(u32ValidFrameCount * u32SamplesPerFrame)
FLOAT32 *pf32OutputFrames,
_In_reads_(u32ValidFrameCount * u32SamplesPerFrame)
const FLOAT32 *pf32InputFrames,
UINT32 u32ValidFrameCount,
UINT32 u32SamplesPerFrame,
_Inout_updates_(u32DelayFrames * u32SamplesPerFrame)
FLOAT32 *pf32DelayBuffer,
UINT32 u32DelayFrames,
_Inout_
UINT32 *pu32DelayIndex )
{
ASSERT_REALTIME();
ATLASSERT( IS_VALID_TYPED_READ_POINTER(pf32InputFrames) );
ATLASSERT( IS_VALID_TYPED_READ_POINTER(pf32OutputFrames) );
if (u32DelayFrames == 0)
{
CopyFrames( pf32OutputFrames,
pf32InputFrames,
u32ValidFrameCount,
u32SamplesPerFrame );
}
else
{
// Invariants:
// 0 <= (*pu32DelayIndex) < u32DelayFrames
// pf32OutputFrames[0 ... u32ValidFrameCount * u32SamplesPerFrame - 1] is writable
// pf32InputFrames[0 ... u32ValidFrameCount * u32SamplesPerFrame - 1] is readable
while (u32ValidFrameCount > 0)
{
// copy either the rest of the input/output buffer,
// or the rest of the delay buffer,
// whichever is smaller
UINT32 framesToCopy = min(u32ValidFrameCount, u32DelayFrames - (*pu32DelayIndex));
// delay => output
#pragma prefast(suppress: __WARNING_POTENTIAL_BUFFER_OVERFLOW_HIGH_PRIORITY, "this copy to pf32OutputFrames is in-range")
CopyFrames( pf32OutputFrames,
&pf32DelayBuffer[(*pu32DelayIndex) * u32SamplesPerFrame],
framesToCopy,
u32SamplesPerFrame );
// input => delay
CopyFrames( &pf32DelayBuffer[(*pu32DelayIndex) * u32SamplesPerFrame],
pf32InputFrames,
framesToCopy,
u32SamplesPerFrame );
pf32OutputFrames += framesToCopy * u32SamplesPerFrame;
pf32InputFrames += framesToCopy * u32SamplesPerFrame;
u32ValidFrameCount -= framesToCopy;
*pu32DelayIndex += framesToCopy;
if (*pu32DelayIndex == u32DelayFrames)
{
*pu32DelayIndex = 0;
}
}
}
}
#pragma AVRT_CODE_END

Просмотреть файл

@ -181,36 +181,17 @@ STDMETHODIMP_(void) CSwapAPOMFX::APOProcess(
m_u32SamplesPerFrame, m_pf32Coefficients ); m_u32SamplesPerFrame, m_pf32Coefficients );
} }
// copy to the delay buffer // copy the memory only if there is an output connection, and input/output pointers are unequal
if ( if ( (0 != u32NumOutputConnections) &&
!IsEqualGUID(m_AudioProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW) && (ppOutputConnections[0]->pBuffer != ppInputConnections[0]->pBuffer) )
m_fEnableDelayMFX
)
{ {
ProcessDelay(pf32OutputFrames, pf32InputFrames, CopyFrames( pf32OutputFrames, pf32InputFrames,
ppInputConnections[0]->u32ValidFrameCount, ppInputConnections[0]->u32ValidFrameCount,
GetSamplesPerFrame(), GetSamplesPerFrame() );
m_pf32DelayBuffer,
m_nDelayFrames,
&m_iDelayIndex);
// we don't try to remember silence
ppOutputConnections[0]->u32BufferFlags = BUFFER_VALID;
}
else
{
// copy the memory only if there is an output connection, and input/output pointers are unequal
if ( (0 != u32NumOutputConnections) &&
(ppOutputConnections[0]->pBuffer != ppInputConnections[0]->pBuffer) )
{
CopyFrames( pf32OutputFrames, pf32InputFrames,
ppInputConnections[0]->u32ValidFrameCount,
GetSamplesPerFrame() );
}
// pass along buffer flags
ppOutputConnections[0]->u32BufferFlags = ppInputConnections[0]->u32BufferFlags;
} }
// pass along buffer flags
ppOutputConnections[0]->u32BufferFlags = ppInputConnections[0]->u32BufferFlags;
// Set the valid frame count. // Set the valid frame count.
ppOutputConnections[0]->u32ValidFrameCount = ppInputConnections[0]->u32ValidFrameCount; ppOutputConnections[0]->u32ValidFrameCount = ppInputConnections[0]->u32ValidFrameCount;
@ -247,15 +228,8 @@ STDMETHODIMP CSwapAPOMFX::GetLatency(HNSTIME* pTime)
IF_TRUE_ACTION_JUMP(NULL == pTime, hr = E_POINTER, Exit); IF_TRUE_ACTION_JUMP(NULL == pTime, hr = E_POINTER, Exit);
if (IsEqualGUID(m_AudioProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW)) *pTime = 0;
{
*pTime = 0;
}
else
{
*pTime = (m_fEnableDelayMFX ? HNS_DELAY : 0);
}
Exit: Exit:
return hr; return hr;
} }
@ -290,29 +264,6 @@ STDMETHODIMP CSwapAPOMFX::LockForProcess(UINT32 u32NumInputConnections,
ppInputConnections, u32NumOutputConnections, ppOutputConnections); ppInputConnections, u32NumOutputConnections, ppOutputConnections);
IF_FAILED_JUMP(hr, Exit); IF_FAILED_JUMP(hr, Exit);
if (!IsEqualGUID(m_AudioProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW) && m_fEnableDelayMFX)
{
m_nDelayFrames = FRAMES_FROM_HNS(HNS_DELAY);
m_iDelayIndex = 0;
m_pf32DelayBuffer.Free();
// Allocate one second's worth of audio
//
// This allocation is being done using CoTaskMemAlloc because the delay is very large
// This introduces a risk of glitches if the delay buffer gets paged out
//
// A more typical approach would be to allocate the memory using AERT_Allocate, which locks the memory
// But for the purposes of this APO, CoTaskMemAlloc suffices, and the risk of glitches is not important
m_pf32DelayBuffer.Allocate(GetSamplesPerFrame() * m_nDelayFrames);
WriteSilence(m_pf32DelayBuffer, m_nDelayFrames, GetSamplesPerFrame());
if (nullptr == m_pf32DelayBuffer)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
}
Exit: Exit:
return hr; return hr;
} }
@ -460,7 +411,6 @@ HRESULT CSwapAPOMFX::Initialize(UINT32 cbDataSize, BYTE* pbyData)
if (m_spAPOSystemEffectsProperties != NULL) if (m_spAPOSystemEffectsProperties != NULL)
{ {
m_fEnableSwapMFX = GetCurrentEffectsSetting(m_spAPOSystemEffectsProperties, PKEY_Endpoint_Enable_Channel_Swap_MFX, m_AudioProcessingMode); m_fEnableSwapMFX = GetCurrentEffectsSetting(m_spAPOSystemEffectsProperties, PKEY_Endpoint_Enable_Channel_Swap_MFX, m_AudioProcessingMode);
m_fEnableDelayMFX = GetCurrentEffectsSetting(m_spAPOSystemEffectsProperties, PKEY_Endpoint_Enable_Delay_MFX, m_AudioProcessingMode);
} }
// //
@ -549,7 +499,6 @@ STDMETHODIMP CSwapAPOMFX::GetEffectsList(_Outptr_result_buffer_maybenull_(*pcEff
EffectControl list[] = EffectControl list[] =
{ {
{ SwapEffectId, m_fEnableSwapMFX }, { SwapEffectId, m_fEnableSwapMFX },
{ DelayEffectId, m_fEnableDelayMFX },
}; };
if (!IsEqualGUID(m_AudioProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW)) if (!IsEqualGUID(m_AudioProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW))
@ -713,7 +662,6 @@ HRESULT CSwapAPOMFX::OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERT
// If either the master disable or our APO's enable properties changed... // If either the master disable or our APO's enable properties changed...
if (PK_EQUAL(key, PKEY_Endpoint_Enable_Channel_Swap_MFX) || if (PK_EQUAL(key, PKEY_Endpoint_Enable_Channel_Swap_MFX) ||
PK_EQUAL(key, PKEY_Endpoint_Enable_Delay_MFX) ||
PK_EQUAL(key, PKEY_AudioEndpoint_Disable_SysFx)) PK_EQUAL(key, PKEY_AudioEndpoint_Disable_SysFx))
{ {
LONG nChanges = 0; LONG nChanges = 0;
@ -730,7 +678,6 @@ HRESULT CSwapAPOMFX::OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERT
KeyControl controls[] = KeyControl controls[] =
{ {
{ PKEY_Endpoint_Enable_Channel_Swap_MFX, &m_fEnableSwapMFX }, { PKEY_Endpoint_Enable_Channel_Swap_MFX, &m_fEnableSwapMFX },
{ PKEY_Endpoint_Enable_Delay_MFX, &m_fEnableDelayMFX },
}; };
for (int i = 0; i < ARRAYSIZE(controls); i++) for (int i = 0; i < ARRAYSIZE(controls); i++)

Просмотреть файл

@ -128,38 +128,19 @@ STDMETHODIMP_(void) CSwapAPOSFX::APOProcess(
ppInputConnections[0]->u32ValidFrameCount, ppInputConnections[0]->u32ValidFrameCount,
m_u32SamplesPerFrame); m_u32SamplesPerFrame);
} }
// copy to the delay buffer
if (
!IsEqualGUID(m_AudioProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW) &&
m_fEnableDelaySFX
)
{
ProcessDelay(pf32OutputFrames, pf32InputFrames,
ppInputConnections[0]->u32ValidFrameCount,
GetSamplesPerFrame(),
m_pf32DelayBuffer,
m_nDelayFrames,
&m_iDelayIndex);
// we don't try to remember silence // copy the memory only if there is an output connection, and input/output pointers are unequal
ppOutputConnections[0]->u32BufferFlags = BUFFER_VALID; if ( (0 != u32NumOutputConnections) &&
} (ppOutputConnections[0]->pBuffer != ppInputConnections[0]->pBuffer) )
else
{ {
// copy the memory only if there is an output connection, and input/output pointers are unequal CopyFrames( pf32OutputFrames, pf32InputFrames,
if ( (0 != u32NumOutputConnections) && ppInputConnections[0]->u32ValidFrameCount,
(ppOutputConnections[0]->pBuffer != ppInputConnections[0]->pBuffer) ) GetSamplesPerFrame() );
{
CopyFrames( pf32OutputFrames, pf32InputFrames,
ppInputConnections[0]->u32ValidFrameCount,
GetSamplesPerFrame() );
}
// pass along buffer flags
ppOutputConnections[0]->u32BufferFlags = ppInputConnections[0]->u32BufferFlags;
} }
// pass along buffer flags
ppOutputConnections[0]->u32BufferFlags = ppInputConnections[0]->u32BufferFlags;
// Set the valid frame count. // Set the valid frame count.
ppOutputConnections[0]->u32ValidFrameCount = ppInputConnections[0]->u32ValidFrameCount; ppOutputConnections[0]->u32ValidFrameCount = ppInputConnections[0]->u32ValidFrameCount;
@ -195,14 +176,7 @@ STDMETHODIMP CSwapAPOSFX::GetLatency(HNSTIME* pTime)
IF_TRUE_ACTION_JUMP(NULL == pTime, hr = E_POINTER, Exit); IF_TRUE_ACTION_JUMP(NULL == pTime, hr = E_POINTER, Exit);
if (IsEqualGUID(m_AudioProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW)) *pTime = 0;
{
*pTime = 0;
}
else
{
*pTime = (m_fEnableDelaySFX ? HNS_DELAY : 0);
}
Exit: Exit:
return hr; return hr;
@ -238,30 +212,6 @@ STDMETHODIMP CSwapAPOSFX::LockForProcess(UINT32 u32NumInputConnections,
ppInputConnections, u32NumOutputConnections, ppOutputConnections); ppInputConnections, u32NumOutputConnections, ppOutputConnections);
IF_FAILED_JUMP(hr, Exit); IF_FAILED_JUMP(hr, Exit);
if (!IsEqualGUID(m_AudioProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW) && m_fEnableDelaySFX)
{
m_nDelayFrames = FRAMES_FROM_HNS(HNS_DELAY);
m_iDelayIndex = 0;
m_pf32DelayBuffer.Free();
// Allocate one second's worth of audio
//
// This allocation is being done using CoTaskMemAlloc because the delay is very large
// This introduces a risk of glitches if the delay buffer gets paged out
//
// A more typical approach would be to allocate the memory using AERT_Allocate, which locks the memory
// But for the purposes of this APO, CoTaskMemAlloc suffices, and the risk of glitches is not important
m_pf32DelayBuffer.Allocate(GetSamplesPerFrame() * m_nDelayFrames);
WriteSilence(m_pf32DelayBuffer, m_nDelayFrames, GetSamplesPerFrame());
if (nullptr == m_pf32DelayBuffer)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
}
Exit: Exit:
return hr; return hr;
} }
@ -417,7 +367,6 @@ HRESULT CSwapAPOSFX::Initialize(UINT32 cbDataSize, BYTE* pbyData)
if (m_spAPOSystemEffectsProperties != NULL) if (m_spAPOSystemEffectsProperties != NULL)
{ {
m_fEnableSwapSFX = GetCurrentEffectsSetting(m_spAPOSystemEffectsProperties, PKEY_Endpoint_Enable_Channel_Swap_SFX, m_AudioProcessingMode); m_fEnableSwapSFX = GetCurrentEffectsSetting(m_spAPOSystemEffectsProperties, PKEY_Endpoint_Enable_Channel_Swap_SFX, m_AudioProcessingMode);
m_fEnableDelaySFX = GetCurrentEffectsSetting(m_spAPOSystemEffectsProperties, PKEY_Endpoint_Enable_Delay_SFX, m_AudioProcessingMode);
} }
// //
@ -508,7 +457,6 @@ STDMETHODIMP CSwapAPOSFX::GetEffectsList(_Outptr_result_buffer_maybenull_(*pcEff
EffectControl list[] = EffectControl list[] =
{ {
{ SwapEffectId, m_fEnableSwapSFX }, { SwapEffectId, m_fEnableSwapSFX },
{ DelayEffectId, m_fEnableDelaySFX },
}; };
if (!IsEqualGUID(m_AudioProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW)) if (!IsEqualGUID(m_AudioProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW))
@ -591,7 +539,6 @@ HRESULT CSwapAPOSFX::OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERT
// If either the master disable or our APO's enable properties changed... // If either the master disable or our APO's enable properties changed...
if (PK_EQUAL(key, PKEY_Endpoint_Enable_Channel_Swap_SFX) || if (PK_EQUAL(key, PKEY_Endpoint_Enable_Channel_Swap_SFX) ||
PK_EQUAL(key, PKEY_Endpoint_Enable_Delay_SFX) ||
PK_EQUAL(key, PKEY_AudioEndpoint_Disable_SysFx)) PK_EQUAL(key, PKEY_AudioEndpoint_Disable_SysFx))
{ {
LONG nChanges = 0; LONG nChanges = 0;
@ -608,7 +555,6 @@ HRESULT CSwapAPOSFX::OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERT
KeyControl controls[] = KeyControl controls[] =
{ {
{ PKEY_Endpoint_Enable_Channel_Swap_SFX, &m_fEnableSwapSFX }, { PKEY_Endpoint_Enable_Channel_Swap_SFX, &m_fEnableSwapSFX },
{ PKEY_Endpoint_Enable_Delay_SFX, &m_fEnableDelaySFX },
}; };
for (int i = 0; i < ARRAYSIZE(controls); i++) for (int i = 0; i < ARRAYSIZE(controls); i++)

Просмотреть файл

@ -0,0 +1,112 @@
//
// Delay.cpp -- Copyright (c) Microsoft Corporation. All rights reserved.
//
// Description:
//
// Implementation of ProcessDelay
//
#include <atlbase.h>
#include <atlcom.h>
#include <atlcoll.h>
#include <atlsync.h>
#include <mmreg.h>
#include <audioenginebaseapo.h>
#include <baseaudioprocessingobject.h>
#include <resource.h>
#include <float.h>
#include "DelayAPO.h"
#pragma AVRT_CODE_BEGIN
void WriteSilence(
_Out_writes_(u32FrameCount * u32SamplesPerFrame)
FLOAT32 *pf32Frames,
UINT32 u32FrameCount,
UINT32 u32SamplesPerFrame )
{
ZeroMemory(pf32Frames, sizeof(FLOAT32) * u32FrameCount * u32SamplesPerFrame);
}
#pragma AVRT_CODE_END
#pragma AVRT_CODE_BEGIN
void CopyFrames(
_Out_writes_(u32FrameCount * u32SamplesPerFrame)
FLOAT32 *pf32OutFrames,
_In_reads_(u32FrameCount * u32SamplesPerFrame)
const FLOAT32 *pf32InFrames,
UINT32 u32FrameCount,
UINT32 u32SamplesPerFrame )
{
CopyMemory(pf32OutFrames, pf32InFrames, sizeof(FLOAT32) * u32FrameCount * u32SamplesPerFrame);
}
#pragma AVRT_CODE_END
#pragma AVRT_CODE_BEGIN
void ProcessDelay(
_Out_writes_(u32ValidFrameCount * u32SamplesPerFrame)
FLOAT32 *pf32OutputFrames,
_In_reads_(u32ValidFrameCount * u32SamplesPerFrame)
const FLOAT32 *pf32InputFrames,
UINT32 u32ValidFrameCount,
UINT32 u32SamplesPerFrame,
_Inout_updates_(u32DelayFrames * u32SamplesPerFrame)
FLOAT32 *pf32DelayBuffer,
UINT32 u32DelayFrames,
_Inout_
UINT32 *pu32DelayIndex )
{
ASSERT_REALTIME();
ATLASSERT( IS_VALID_TYPED_READ_POINTER(pf32InputFrames) );
ATLASSERT( IS_VALID_TYPED_READ_POINTER(pf32OutputFrames) );
if (u32DelayFrames == 0)
{
CopyFrames( pf32OutputFrames,
pf32InputFrames,
u32ValidFrameCount,
u32SamplesPerFrame );
}
else
{
// Invariants:
// 0 <= (*pu32DelayIndex) < u32DelayFrames
// pf32OutputFrames[0 ... u32ValidFrameCount * u32SamplesPerFrame - 1] is writable
// pf32InputFrames[0 ... u32ValidFrameCount * u32SamplesPerFrame - 1] is readable
while (u32ValidFrameCount > 0)
{
// copy either the rest of the input/output buffer,
// or the rest of the delay buffer,
// whichever is smaller
UINT32 framesToCopy = min(u32ValidFrameCount, u32DelayFrames - (*pu32DelayIndex));
// delay => output
#pragma prefast(suppress: __WARNING_POTENTIAL_BUFFER_OVERFLOW_HIGH_PRIORITY, "this copy to pf32OutputFrames is in-range")
CopyFrames( pf32OutputFrames,
&pf32DelayBuffer[(*pu32DelayIndex) * u32SamplesPerFrame],
framesToCopy,
u32SamplesPerFrame );
// input => delay
CopyFrames( &pf32DelayBuffer[(*pu32DelayIndex) * u32SamplesPerFrame],
pf32InputFrames,
framesToCopy,
u32SamplesPerFrame );
pf32OutputFrames += framesToCopy * u32SamplesPerFrame;
pf32InputFrames += framesToCopy * u32SamplesPerFrame;
u32ValidFrameCount -= framesToCopy;
*pu32DelayIndex += framesToCopy;
if (*pu32DelayIndex == u32DelayFrames)
{
*pu32DelayIndex = 0;
}
}
}
}
#pragma AVRT_CODE_END

Просмотреть файл

@ -0,0 +1,294 @@
//
// DelayAPO.h -- Copyright (c) Microsoft Corporation. All rights reserved.
//
// Description:
//
// Declaration of the CDelayAPO class.
//
#pragma once
#include <audioenginebaseapo.h>
#include <BaseAudioProcessingObject.h>
#include <DelayAPOInterface.h>
#include <DelayAPODll.h>
#include <commonmacros.h>
#include <devicetopology.h>
_Analysis_mode_(_Analysis_code_type_user_driver_)
#define PK_EQUAL(x, y) ((x.fmtid == y.fmtid) && (x.pid == y.pid))
//
// Define a GUID identifying the type of this APO's custom effect.
//
// APOs generally should not define new GUIDs for types of effects and instead
// should use predefined effect types. Only define a new GUID if the effect is
// truly very different from all predefined types of effects.
//
// {29FBFBB5-9002-4ABC-DCBC-DD45462478C8}
DEFINE_GUID(DelayEffectId, 0x29FBFBB5, 0x9002, 0x4ABC, 0xDC, 0xBC, 0xDD, 0x45, 0x46, 0x24, 0x78, 0xC8);
// 1000 ms of delay
#define HNS_DELAY HNS_PER_SECOND
#define FRAMES_FROM_HNS(hns) (ULONG)(1.0 * hns / HNS_PER_SECOND * GetFramesPerSecond() + 0.5)
LONG GetCurrentEffectsSetting(IPropertyStore* properties, PROPERTYKEY pkeyEnable, GUID processingMode);
#pragma AVRT_VTABLES_BEGIN
// Delay APO class - MFX
class CDelayAPOMFX :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CDelayAPOMFX, &CLSID_DelayAPOMFX>,
public CBaseAudioProcessingObject,
public IMMNotificationClient,
public IAudioSystemEffects2,
// IAudioSystemEffectsCustomFormats may be optionally supported
// by APOs that attach directly to the connector in the DEFAULT mode streaming graph
public IAudioSystemEffectsCustomFormats,
public IDelayAPOMFX
{
public:
// constructor
CDelayAPOMFX()
: CBaseAudioProcessingObject(sm_RegProperties)
, m_hEffectsChangedEvent(NULL)
, m_AudioProcessingMode(AUDIO_SIGNALPROCESSINGMODE_DEFAULT)
, m_fEnableDelayMFX(FALSE)
, m_nDelayFrames(0)
, m_iDelayIndex(0)
{
m_pf32Coefficients = NULL;
}
virtual ~CDelayAPOMFX(); // destructor
DECLARE_REGISTRY_RESOURCEID(IDR_DELAYAPOMFX)
BEGIN_COM_MAP(CDelayAPOMFX)
COM_INTERFACE_ENTRY(IDelayAPOMFX)
COM_INTERFACE_ENTRY(IAudioSystemEffects)
COM_INTERFACE_ENTRY(IAudioSystemEffects2)
// IAudioSystemEffectsCustomFormats may be optionally supported
// by APOs that attach directly to the connector in the DEFAULT mode streaming graph
COM_INTERFACE_ENTRY(IAudioSystemEffectsCustomFormats)
COM_INTERFACE_ENTRY(IMMNotificationClient)
COM_INTERFACE_ENTRY(IAudioProcessingObjectRT)
COM_INTERFACE_ENTRY(IAudioProcessingObject)
COM_INTERFACE_ENTRY(IAudioProcessingObjectConfiguration)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
public:
STDMETHOD_(void, APOProcess)(UINT32 u32NumInputConnections,
APO_CONNECTION_PROPERTY** ppInputConnections, UINT32 u32NumOutputConnections,
APO_CONNECTION_PROPERTY** ppOutputConnections);
STDMETHOD(GetLatency)(HNSTIME* pTime);
STDMETHOD(LockForProcess)(UINT32 u32NumInputConnections,
APO_CONNECTION_DESCRIPTOR** ppInputConnections,
UINT32 u32NumOutputConnections, APO_CONNECTION_DESCRIPTOR** ppOutputConnections);
STDMETHOD(Initialize)(UINT32 cbDataSize, BYTE* pbyData);
// IAudioSystemEffects2
STDMETHOD(GetEffectsList)(_Outptr_result_buffer_maybenull_(*pcEffects) LPGUID *ppEffectsIds, _Out_ UINT *pcEffects, _In_ HANDLE Event);
virtual HRESULT ValidateAndCacheConnectionInfo(
UINT32 u32NumInputConnections,
APO_CONNECTION_DESCRIPTOR** ppInputConnections,
UINT32 u32NumOutputConnections,
APO_CONNECTION_DESCRIPTOR** ppOutputConnections);
// IMMNotificationClient
STDMETHODIMP OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState)
{
UNREFERENCED_PARAMETER(pwstrDeviceId);
UNREFERENCED_PARAMETER(dwNewState);
return S_OK;
}
STDMETHODIMP OnDeviceAdded(LPCWSTR pwstrDeviceId)
{
UNREFERENCED_PARAMETER(pwstrDeviceId);
return S_OK;
}
STDMETHODIMP OnDeviceRemoved(LPCWSTR pwstrDeviceId)
{
UNREFERENCED_PARAMETER(pwstrDeviceId);
return S_OK;
}
STDMETHODIMP OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDefaultDeviceId)
{
UNREFERENCED_PARAMETER(flow);
UNREFERENCED_PARAMETER(role);
UNREFERENCED_PARAMETER(pwstrDefaultDeviceId);
return S_OK;
}
STDMETHODIMP OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key);
// IAudioSystemEffectsCustomFormats
// This interface may be optionally supported by APOs that attach directly to the connector in the DEFAULT mode streaming graph
STDMETHODIMP GetFormatCount(UINT* pcFormats);
STDMETHODIMP GetFormat(UINT nFormat, IAudioMediaType** ppFormat);
STDMETHODIMP GetFormatRepresentation(UINT nFormat, _Outptr_ LPWSTR* ppwstrFormatRep);
public:
LONG m_fEnableDelayMFX;
GUID m_AudioProcessingMode;
CComPtr<IPropertyStore> m_spAPOSystemEffectsProperties;
CComPtr<IMMDeviceEnumerator> m_spEnumerator;
static const CRegAPOProperties<1> sm_RegProperties; // registration properties
// Locked memory
FLOAT32 *m_pf32Coefficients;
CComHeapPtr<FLOAT32> m_pf32DelayBuffer;
UINT32 m_nDelayFrames;
UINT32 m_iDelayIndex;
private:
CCriticalSection m_EffectsLock;
HANDLE m_hEffectsChangedEvent;
HRESULT ProprietaryCommunicationWithDriver(APOInitSystemEffects2 *_pAPOSysFxInit2);
};
#pragma AVRT_VTABLES_END
#pragma AVRT_VTABLES_BEGIN
// Delay APO class - SFX
class CDelayAPOSFX :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CDelayAPOSFX, &CLSID_DelayAPOSFX>,
public CBaseAudioProcessingObject,
public IMMNotificationClient,
public IAudioSystemEffects2,
public IDelayAPOSFX
{
public:
// constructor
CDelayAPOSFX()
: CBaseAudioProcessingObject(sm_RegProperties)
, m_hEffectsChangedEvent(NULL)
, m_AudioProcessingMode(AUDIO_SIGNALPROCESSINGMODE_DEFAULT)
, m_fEnableDelaySFX(FALSE)
, m_nDelayFrames(0)
, m_iDelayIndex(0)
{
}
virtual ~CDelayAPOSFX(); // destructor
DECLARE_REGISTRY_RESOURCEID(IDR_DELAYAPOSFX)
BEGIN_COM_MAP(CDelayAPOSFX)
COM_INTERFACE_ENTRY(IDelayAPOSFX)
COM_INTERFACE_ENTRY(IAudioSystemEffects)
COM_INTERFACE_ENTRY(IAudioSystemEffects2)
COM_INTERFACE_ENTRY(IMMNotificationClient)
COM_INTERFACE_ENTRY(IAudioProcessingObjectRT)
COM_INTERFACE_ENTRY(IAudioProcessingObject)
COM_INTERFACE_ENTRY(IAudioProcessingObjectConfiguration)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
public:
STDMETHOD_(void, APOProcess)(UINT32 u32NumInputConnections,
APO_CONNECTION_PROPERTY** ppInputConnections, UINT32 u32NumOutputConnections,
APO_CONNECTION_PROPERTY** ppOutputConnections);
STDMETHOD(GetLatency)(HNSTIME* pTime);
STDMETHOD(LockForProcess)(UINT32 u32NumInputConnections,
APO_CONNECTION_DESCRIPTOR** ppInputConnections,
UINT32 u32NumOutputConnections, APO_CONNECTION_DESCRIPTOR** ppOutputConnections);
STDMETHOD(Initialize)(UINT32 cbDataSize, BYTE* pbyData);
// IAudioSystemEffects2
STDMETHOD(GetEffectsList)(_Outptr_result_buffer_maybenull_(*pcEffects) LPGUID *ppEffectsIds, _Out_ UINT *pcEffects, _In_ HANDLE Event);
// IMMNotificationClient
STDMETHODIMP OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState)
{
UNREFERENCED_PARAMETER(pwstrDeviceId);
UNREFERENCED_PARAMETER(dwNewState);
return S_OK;
}
STDMETHODIMP OnDeviceAdded(LPCWSTR pwstrDeviceId)
{
UNREFERENCED_PARAMETER(pwstrDeviceId);
return S_OK;
}
STDMETHODIMP OnDeviceRemoved(LPCWSTR pwstrDeviceId)
{
UNREFERENCED_PARAMETER(pwstrDeviceId);
return S_OK;
}
STDMETHODIMP OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDefaultDeviceId)
{
UNREFERENCED_PARAMETER(flow);
UNREFERENCED_PARAMETER(role);
UNREFERENCED_PARAMETER(pwstrDefaultDeviceId);
return S_OK;
}
STDMETHODIMP OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key);
public:
LONG m_fEnableDelaySFX;
GUID m_AudioProcessingMode;
CComPtr<IPropertyStore> m_spAPOSystemEffectsProperties;
CComPtr<IMMDeviceEnumerator> m_spEnumerator;
static const CRegAPOProperties<1> sm_RegProperties; // registration properties
CCriticalSection m_EffectsLock;
HANDLE m_hEffectsChangedEvent;
CComHeapPtr<FLOAT32> m_pf32DelayBuffer;
UINT32 m_nDelayFrames;
UINT32 m_iDelayIndex;
};
#pragma AVRT_VTABLES_END
OBJECT_ENTRY_AUTO(__uuidof(DelayAPOMFX), CDelayAPOMFX)
OBJECT_ENTRY_AUTO(__uuidof(DelayAPOSFX), CDelayAPOSFX)
//
// Declaration of the ProcessDelay routine.
//
void ProcessDelay(
_Out_writes_(u32ValidFrameCount * u32SamplesPerFrame)
FLOAT32 *pf32OutputFrames,
_In_reads_(u32ValidFrameCount * u32SamplesPerFrame)
const FLOAT32 *pf32InputFrames,
UINT32 u32ValidFrameCount,
UINT32 u32SamplesPerFrame,
_Inout_updates_(u32DelayFrames * u32SamplesPerFrame)
FLOAT32 *pf32DelayBuffer,
UINT32 u32DelayFrames,
_Inout_
UINT32 *pu32DelayIndex );
//
// Convenience methods
//
void WriteSilence(
_Out_writes_(u32FrameCount * u32SamplesPerFrame)
FLOAT32 *pf32Frames,
UINT32 u32FrameCount,
UINT32 u32SamplesPerFrame );
void CopyFrames(
_Out_writes_(u32FrameCount * u32SamplesPerFrame)
FLOAT32 *pf32OutFrames,
_In_reads_(u32FrameCount * u32SamplesPerFrame)
const FLOAT32 *pf32InFrames,
UINT32 u32FrameCount,
UINT32 u32SamplesPerFrame );

Просмотреть файл

@ -0,0 +1,250 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|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>{8851ab85-70b3-4798-a149-ba366df9ec25}</ProjectGuid>
<RootNamespace>$(MSBuildProjectName)</RootNamespace>
<SupportsPackaging>false</SupportsPackaging>
<RequiresPackageProject>true</RequiresPackageProject>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
<SampleGuid>{D5CCDCB1-348E-414E-BB0F-33C773760034}</SampleGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>False</UseDebugLibraries>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>True</UseDebugLibraries>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<EmbedManifest>false</EmbedManifest>
<DriverType />
<PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</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>DelayAPO</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetName>DelayAPO</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<TargetName>DelayAPO</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetName>DelayAPO</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
<EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
<EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Link>
<EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
<EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Link>
<EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
<EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Link>
<EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
<EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
</Link>
</ItemDefinitionGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<UseOfAtl>Dynamic</UseOfAtl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<UseOfAtl>Dynamic</UseOfAtl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<UseOfAtl>Dynamic</UseOfAtl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<UseOfAtl>Dynamic</UseOfAtl>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<TreatWarningAsError>true</TreatWarningAsError>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
<ExceptionHandling>
</ExceptionHandling>
<RuntimeLibrary />
</ClCompile>
<Midl>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
<ModuleDefinitionFile>DelayAPODll.def</ModuleDefinitionFile>
<AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<TreatWarningAsError>true</TreatWarningAsError>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
<ExceptionHandling>
</ExceptionHandling>
<RuntimeLibrary />
</ClCompile>
<Midl>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
<ModuleDefinitionFile>DelayAPODll.def</ModuleDefinitionFile>
<AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<TreatWarningAsError>true</TreatWarningAsError>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
<ExceptionHandling>
</ExceptionHandling>
<RuntimeLibrary />
</ClCompile>
<Midl>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
<ModuleDefinitionFile>DelayAPODll.def</ModuleDefinitionFile>
<AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<TreatWarningAsError>true</TreatWarningAsError>
<WarningLevel>Level4</WarningLevel>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
<ExceptionHandling>
</ExceptionHandling>
<RuntimeLibrary />
</ClCompile>
<Midl>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions);_WINDLL;_USRDLL;UNICODE;_UNICODE</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\</AdditionalIncludeDirectories>
</ResourceCompile>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);Kernel32.lib;ole32.lib;oleaut32.lib;advapi32.lib;user32.lib;uuid.lib;AudioBaseProcessingObjectV140.lib;audiomediatypecrt.lib;AudioEng.lib</AdditionalDependencies>
<ModuleDefinitionFile>DelayAPODll.def</ModuleDefinitionFile>
<AdditionalOptions>/ignore:4217,4049 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Delay.cpp" />
<ClCompile Include="DelayAPODll.cpp" />
<ClCompile Include="DelayAPOMFX.cpp " />
<ClCompile Include="DelayAPOSFX.cpp" />
<Midl Include="DelayAPODll.idl" />
<Midl Include="DelayAPOInterface.idl" />
<ResourceCompile Include="DelayAPODll.rc" />
</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>

Просмотреть файл

@ -0,0 +1,148 @@
//
// DelayAPODll.cpp -- Copyright (c) Microsoft Corporation. All rights reserved.
//
// Author:
//
// Description:
//
// DelayAPODll.cpp : Implementation of DLL Exports.
#include <atlbase.h>
#include <atlcom.h>
#include <atlcoll.h>
#include <atlsync.h>
#include <mmreg.h>
#include "resource.h"
#include "DelayAPODll.h"
#include <DelayAPO.h>
#include <DelayAPODll_i.c>
//-------------------------------------------------------------------------
// Array of APO_REG_PROPERTIES structures implemented in this module.
// Each new APO implementation will be added to this array.
//
APO_REG_PROPERTIES const *gCoreAPOs[] =
{
&CDelayAPOMFX::sm_RegProperties.m_Properties,
&CDelayAPOSFX::sm_RegProperties.m_Properties
};
// {secret}
class CDelayAPODllModule : public CAtlDllModuleT< CDelayAPODllModule >
{
public :
DECLARE_LIBID(LIBID_DelayAPODlllib)
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_DELAYAPODLL, "{0A21D954-674A-4C09-806E-DB4FBE8F199C}")
public:
HRESULT DllRegisterServer(BOOL bRegTypeLib = TRUE) throw();
HRESULT DllUnregisterServer(BOOL bUnRegTypeLib = TRUE) throw();
};
// {secret}
CDelayAPODllModule _AtlModule;
HRESULT CDelayAPODllModule::DllRegisterServer(BOOL bRegTypeLib) throw()
{
HRESULT hResult;
UINT32 u32APORegIndex = 0;
UINT32 u32APOUnregIndex = 0;
// Register all APOs implemented in this module.
for (u32APORegIndex = 0; u32APORegIndex < SIZEOF_ARRAY(gCoreAPOs); u32APORegIndex++)
{
hResult = RegisterAPO(gCoreAPOs[u32APORegIndex]);
if (FAILED(hResult))
{
goto ExitFailed;
}
}
// Register the module.
hResult = CAtlDllModuleT<CDelayAPODllModule>::DllRegisterServer(bRegTypeLib);
if (FAILED(hResult))
{
goto ExitFailed;
}
return hResult;
ExitFailed:
// Unregister all registered APOs if something failed.
for (u32APOUnregIndex = 0; u32APOUnregIndex < u32APORegIndex; u32APOUnregIndex++)
{
ATLVERIFY(SUCCEEDED(UnregisterAPO(gCoreAPOs[u32APOUnregIndex]->clsid)));
}
return hResult;
} // DllRegisterServer
HRESULT CDelayAPODllModule::DllUnregisterServer(BOOL bUnRegTypeLib) throw()
{
HRESULT hResult;
UINT32 u32APOUnregIndex = 0;
// Unregister the module.
hResult = CAtlDllModuleT<CDelayAPODllModule>::UnregisterServer(bUnRegTypeLib);
if (FAILED(hResult))
{
goto Exit;
}
// Unregister all the APOs that are implemented in this module.
for (u32APOUnregIndex = 0; u32APOUnregIndex < SIZEOF_ARRAY(gCoreAPOs); u32APOUnregIndex++)
{
hResult = UnregisterAPO(gCoreAPOs[u32APOUnregIndex]->clsid);
ATLASSERT(SUCCEEDED(hResult));
}
Exit:
return hResult;
} // DllUnregisterServer
// {secret}
extern "C" BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD dwReason, LPVOID lpReserved)
{
if (DLL_PROCESS_ATTACH == dwReason)
{
}
// do necessary cleanup only if the DLL is being unloaded dynamically
else if ((DLL_PROCESS_DETACH == dwReason) && (NULL == lpReserved))
{
}
return _AtlModule.DllMain(dwReason, lpReserved);
}
// {secret}
STDAPI DllCanUnloadNow(void)
{
return _AtlModule.DllCanUnloadNow();
}
// {secret}
STDAPI DllGetClassObject(_In_ REFCLSID rclsid,_In_ REFIID riid, _Outptr_ LPVOID* ppv)
{
return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
}
// {secret}
STDAPI DllRegisterServer(void)
{
// registers object, typelib and all interfaces in typelib
HRESULT hr = _AtlModule.DllRegisterServer();
return hr;
}
// {secret}
STDAPI DllUnregisterServer(void)
{
HRESULT hr = _AtlModule.DllUnregisterServer();
return hr;
}

Просмотреть файл

@ -0,0 +1,6 @@
EXPORTS
DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE

Просмотреть файл

@ -0,0 +1,54 @@
//
// DelayAPODll.idl -- Copyright (c) Microsoft Corporation. All rights reserved.
//
// Author:
//
// Description:
//
// DelayAPODll.idl : Definition of COM interfaces and coclasses for the DLL.
import "oaidl.idl";
import "ocidl.idl";
import "DelayAPOInterface.idl";
//-------------------------------------------------------------------------
// DelayAPODlllib
//
[
uuid(8009693f-5bc2-42bb-86bf-82cc651f127f),
version(1.0)
]
library DelayAPODlllib
{
importlib("stdole2.tlb");
// for Delay APO - MFX
[
uuid(b6c7032b-1f17-4cc6-bcdb-fd96deabc8a9)
]
coclass DelayAPOMFX
{
interface IAudioProcessingObject;
interface IAudioProcessingObjectRT;
interface IAudioProcessingObjectConfiguration;
interface IMMNotificationClient;
interface IAudioSystemEffects;
[default] interface IDelayAPOMFX;
};
// for Delay APO - SFX
[
uuid(77802b45-a5a0-455a-8204-3dba30eee7b4)
]
coclass DelayAPOSFX
{
interface IAudioProcessingObject;
interface IAudioProcessingObjectRT;
interface IAudioProcessingObjectConfiguration;
interface IMMNotificationClient;
interface IAudioSystemEffects;
[default] interface IDelayAPOSFX;
};
}

Просмотреть файл

@ -0,0 +1,24 @@
#if 0
Copyright (c) Microsoft Corporation. All Rights Reserved
#endif
#include "resource.h"
#include "winres.h"
#include <ntverp.h>
#define VER_FILETYPE VFT_DLL
#define VER_FILESUBTYPE VFT_UNKNOWN
#define VER_FILEDESCRIPTION_STR "Delay APO"
#define VER_INTERNALNAME_STR "DELAYAPODll"
#define VER_ORIGINALFILENAME_STR "DelayAPODll.Dll"
#include <Common.ver>
IDR_DELAYAPODLL REGISTRY "DelayAPODll.rgs"
IDR_DELAYAPOMFX REGISTRY "DelayAPOMFX.rgs"
IDR_DELAYAPOSFX REGISTRY "DelayAPOSFX.rgs"
// ICON
IDI_EFFECT_ICON RCDATA "DelayApo.png"
#if 0
1 TYPELIB "DelayAPODll.tlb"
#endif

Просмотреть файл

@ -0,0 +1,11 @@
HKCR
{
NoRemove AppID
{
'%APPID%' = s 'DelayAPODll'
'DelayAPODll.DLL'
{
val AppID = s '%APPID%'
}
}
}

Просмотреть файл

@ -0,0 +1,29 @@
//
// DelayAPOInterface.idl -- Copyright (c) Microsoft Corporation. All rights reserved.
//
// Description:
//
// The interface and type definitions for Delay APO functionality.
//
import "oaidl.idl";
import "ocidl.idl";
import "audioenginebaseapo.idl";
[
object,
uuid(4c0531b4-f2ca-4eae-80cd-020266923bc1),
pointer_default(unique)
]
interface IDelayAPOMFX : IUnknown
{
};
[
object,
uuid(6269b338-5162-4f14-a94d-8422ee93ec13),
pointer_default(unique)
]
interface IDelayAPOSFX : IUnknown
{
};

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,13 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {b6c7032b-1f17-4cc6-bcdb-fd96deabc8a9} = s 'DelayAPOMFX Class'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Both'
}
}
}
}

Просмотреть файл

@ -0,0 +1,662 @@
//
// DelayAPOSFX.cpp -- Copyright (c) Microsoft Corporation. All rights reserved.
//
// Description:
//
// Implementation of CDelayAPOSFX
//
#include <atlbase.h>
#include <atlcom.h>
#include <atlcoll.h>
#include <atlsync.h>
#include <mmreg.h>
#include <audioenginebaseapo.h>
#include <baseaudioprocessingobject.h>
#include <resource.h>
#include <float.h>
#include "DelayAPO.h"
#include <devicetopology.h>
#include <CustomPropKeys.h>
// Static declaration of the APO_REG_PROPERTIES structure
// associated with this APO. The number in <> brackets is the
// number of IIDs supported by this APO. If more than one, then additional
// IIDs are added at the end
#pragma warning (disable : 4815)
const AVRT_DATA CRegAPOProperties<1> CDelayAPOSFX::sm_RegProperties(
__uuidof(DelayAPOSFX), // clsid of this APO
L"CDelayAPOSFX", // friendly name of this APO
L"Copyright (c) Microsoft Corporation", // copyright info
1, // major version #
0, // minor version #
__uuidof(IDelayAPOSFX) // iid of primary interface
//
// If you need to change any of these attributes, uncomment everything up to
// the point that you need to change something. If you need to add IIDs, uncomment
// everything and add additional IIDs at the end.
//
// , DEFAULT_APOREG_FLAGS
// , DEFAULT_APOREG_MININPUTCONNECTIONS
// , DEFAULT_APOREG_MAXINPUTCONNECTIONS
// , DEFAULT_APOREG_MINOUTPUTCONNECTIONS
// , DEFAULT_APOREG_MAXOUTPUTCONNECTIONS
// , DEFAULT_APOREG_MAXINSTANCES
//
);
#pragma AVRT_CODE_BEGIN
//-------------------------------------------------------------------------
// Description:
//
// Do the actual processing of data.
//
// Parameters:
//
// u32NumInputConnections - [in] number of input connections
// ppInputConnections - [in] pointer to list of input APO_CONNECTION_PROPERTY pointers
// u32NumOutputConnections - [in] number of output connections
// ppOutputConnections - [in] pointer to list of output APO_CONNECTION_PROPERTY pointers
//
// Return values:
//
// void
//
// Remarks:
//
// This function processes data in a manner dependent on the implementing
// object. This routine can not fail and can not block, or call any other
// routine that blocks, or touch pagable memory.
//
STDMETHODIMP_(void) CDelayAPOSFX::APOProcess(
UINT32 u32NumInputConnections,
APO_CONNECTION_PROPERTY** ppInputConnections,
UINT32 u32NumOutputConnections,
APO_CONNECTION_PROPERTY** ppOutputConnections)
{
UNREFERENCED_PARAMETER(u32NumInputConnections);
UNREFERENCED_PARAMETER(u32NumOutputConnections);
FLOAT32 *pf32InputFrames, *pf32OutputFrames;
ATLASSERT(m_bIsLocked);
// assert that the number of input and output connectins fits our registration properties
ATLASSERT(m_pRegProperties->u32MinInputConnections <= u32NumInputConnections);
ATLASSERT(m_pRegProperties->u32MaxInputConnections >= u32NumInputConnections);
ATLASSERT(m_pRegProperties->u32MinOutputConnections <= u32NumOutputConnections);
ATLASSERT(m_pRegProperties->u32MaxOutputConnections >= u32NumOutputConnections);
// check APO_BUFFER_FLAGS.
switch( ppInputConnections[0]->u32BufferFlags )
{
case BUFFER_INVALID:
{
ATLASSERT(false); // invalid flag - should never occur. don't do anything.
break;
}
case BUFFER_VALID:
case BUFFER_SILENT:
{
// get input pointer to connection buffer
pf32InputFrames = reinterpret_cast<FLOAT32*>(ppInputConnections[0]->pBuffer);
ATLASSERT( IS_VALID_TYPED_READ_POINTER(pf32InputFrames) );
// get output pointer to connection buffer
pf32OutputFrames = reinterpret_cast<FLOAT32*>(ppOutputConnections[0]->pBuffer);
ATLASSERT( IS_VALID_TYPED_WRITE_POINTER(pf32OutputFrames) );
if (BUFFER_SILENT == ppInputConnections[0]->u32BufferFlags)
{
WriteSilence( pf32InputFrames,
ppInputConnections[0]->u32ValidFrameCount,
GetSamplesPerFrame() );
}
// copy to the delay buffer
if (
!IsEqualGUID(m_AudioProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW) &&
m_fEnableDelaySFX
)
{
ProcessDelay(pf32OutputFrames, pf32InputFrames,
ppInputConnections[0]->u32ValidFrameCount,
GetSamplesPerFrame(),
m_pf32DelayBuffer,
m_nDelayFrames,
&m_iDelayIndex);
// we don't try to remember silence
ppOutputConnections[0]->u32BufferFlags = BUFFER_VALID;
}
else
{
// copy the memory only if there is an output connection, and input/output pointers are unequal
if ( (0 != u32NumOutputConnections) &&
(ppOutputConnections[0]->pBuffer != ppInputConnections[0]->pBuffer) )
{
CopyFrames( pf32OutputFrames, pf32InputFrames,
ppInputConnections[0]->u32ValidFrameCount,
GetSamplesPerFrame() );
}
// pass along buffer flags
ppOutputConnections[0]->u32BufferFlags = ppInputConnections[0]->u32BufferFlags;
}
// Set the valid frame count.
ppOutputConnections[0]->u32ValidFrameCount = ppInputConnections[0]->u32ValidFrameCount;
break;
}
default:
{
ATLASSERT(false); // invalid flag - should never occur
break;
}
} // switch
} // APOProcess
#pragma AVRT_CODE_END
//-------------------------------------------------------------------------
// Description:
//
// Report delay added by the APO between samples given on input
// and samples given on output.
//
// Parameters:
//
// pTime - [out] hundreds-of-nanoseconds of delay added
//
// Return values:
//
// S_OK on success, a failure code on failure
STDMETHODIMP CDelayAPOSFX::GetLatency(HNSTIME* pTime)
{
ASSERT_NONREALTIME();
HRESULT hr = S_OK;
IF_TRUE_ACTION_JUMP(NULL == pTime, hr = E_POINTER, Exit);
if (IsEqualGUID(m_AudioProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW))
{
*pTime = 0;
}
else
{
*pTime = (m_fEnableDelaySFX ? HNS_DELAY : 0);
}
Exit:
return hr;
}
//-------------------------------------------------------------------------
// Description:
//
// Verifies that the APO is ready to process and locks its state if so.
//
// Parameters:
//
// u32NumInputConnections - [in] number of input connections attached to this APO
// ppInputConnections - [in] connection descriptor of each input connection attached to this APO
// u32NumOutputConnections - [in] number of output connections attached to this APO
// ppOutputConnections - [in] connection descriptor of each output connection attached to this APO
//
// Return values:
//
// S_OK Object is locked and ready to process.
// E_POINTER Invalid pointer passed to function.
// APOERR_INVALID_CONNECTION_FORMAT Invalid connection format.
// APOERR_NUM_CONNECTIONS_INVALID Number of input or output connections is not valid on
// this APO.
STDMETHODIMP CDelayAPOSFX::LockForProcess(UINT32 u32NumInputConnections,
APO_CONNECTION_DESCRIPTOR** ppInputConnections,
UINT32 u32NumOutputConnections, APO_CONNECTION_DESCRIPTOR** ppOutputConnections)
{
ASSERT_NONREALTIME();
HRESULT hr = S_OK;
hr = CBaseAudioProcessingObject::LockForProcess(u32NumInputConnections,
ppInputConnections, u32NumOutputConnections, ppOutputConnections);
IF_FAILED_JUMP(hr, Exit);
if (!IsEqualGUID(m_AudioProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW) && m_fEnableDelaySFX)
{
m_nDelayFrames = FRAMES_FROM_HNS(HNS_DELAY);
m_iDelayIndex = 0;
m_pf32DelayBuffer.Free();
// Allocate one second's worth of audio
//
// This allocation is being done using CoTaskMemAlloc because the delay is very large
// This introduces a risk of glitches if the delay buffer gets paged out
//
// A more typical approach would be to allocate the memory using AERT_Allocate, which locks the memory
// But for the purposes of this APO, CoTaskMemAlloc suffices, and the risk of glitches is not important
m_pf32DelayBuffer.Allocate(GetSamplesPerFrame() * m_nDelayFrames);
WriteSilence(m_pf32DelayBuffer, m_nDelayFrames, GetSamplesPerFrame());
if (nullptr == m_pf32DelayBuffer)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
}
Exit:
return hr;
}
// The method that this long comment refers to is "Initialize()"
//-------------------------------------------------------------------------
// Description:
//
// Generic initialization routine for APOs.
//
// Parameters:
//
// cbDataSize - [in] the size in bytes of the initialization data.
// pbyData - [in] initialization data specific to this APO
//
// Return values:
//
// S_OK Successful completion.
// E_POINTER Invalid pointer passed to this function.
// E_INVALIDARG Invalid argument
// AEERR_ALREADY_INITIALIZED APO is already initialized
//
// Remarks:
//
// This method initializes the APO. The data is variable length and
// should have the form of:
//
// struct MyAPOInitializationData
// {
// APOInitBaseStruct APOInit;
// ... // add additional fields here
// };
//
// If the APO needs no initialization or needs no data to initialize
// itself, it is valid to pass NULL as the pbyData parameter and 0 as
// the cbDataSize parameter.
//
// As part of designing an APO, decide which parameters should be
// immutable (set once during initialization) and which mutable (changeable
// during the lifetime of the APO instance). Immutable parameters must
// only be specifiable in the Initialize call; mutable parameters must be
// settable via methods on whichever parameter control interface(s) your
// APO provides. Mutable values should either be set in the initialize
// method (if they are required for proper operation of the APO prior to
// LockForProcess) or default to reasonable values upon initialize and not
// be required to be set before LockForProcess.
//
// Within the mutable parameters, you must also decide which can be changed
// while the APO is locked for processing and which cannot.
//
// All parameters should be considered immutable as a first choice, unless
// there is a specific scenario which requires them to be mutable; similarly,
// no mutable parameters should be changeable while the APO is locked, unless
// a specific scenario requires them to be. Following this guideline will
// simplify the APO's state diagram and implementation and prevent certain
// types of bug.
//
// If a parameter changes the APOs latency or MaxXXXFrames values, it must be
// immutable.
//
// The default version of this function uses no initialization data, but does verify
// the passed parameters and set the m_bIsInitialized member to true.
//
// Note: This method may not be called from a real-time processing thread.
//
HRESULT CDelayAPOSFX::Initialize(UINT32 cbDataSize, BYTE* pbyData)
{
HRESULT hr = S_OK;
CComPtr<IMMDevice> spMyDevice;
CComPtr<IDeviceTopology> spMyDeviceTopology;
CComPtr<IConnector> spMyConnector;
GUID processingMode;
IF_TRUE_ACTION_JUMP( ((NULL == pbyData) && (0 != cbDataSize)), hr = E_INVALIDARG, Exit);
IF_TRUE_ACTION_JUMP( ((NULL != pbyData) && (0 == cbDataSize)), hr = E_INVALIDARG, Exit);
if (cbDataSize == sizeof(APOInitSystemEffects2))
{
//
// Initialize for mode-specific signal processing
//
APOInitSystemEffects2* papoSysFxInit2 = (APOInitSystemEffects2*)pbyData;
// Save reference to the effects property store. This saves effects settings
// and is the communication medium between this APO and any associated UI.
m_spAPOSystemEffectsProperties = papoSysFxInit2->pAPOSystemEffectsProperties;
// Windows should pass a valid collection.
ATLASSERT(papoSysFxInit2->pDeviceCollection != nullptr);
IF_TRUE_ACTION_JUMP(papoSysFxInit2->pDeviceCollection == nullptr, hr = E_INVALIDARG, Exit);
// Get the IDeviceTopology and IConnector interfaces to communicate with this
// APO's counterpart audio driver. This can be used for any proprietary
// communication.
hr = papoSysFxInit2->pDeviceCollection->Item(papoSysFxInit2->nSoftwareIoDeviceInCollection, &spMyDevice);
IF_FAILED_JUMP(hr, Exit);
hr = spMyDevice->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL, NULL, (void**)&spMyDeviceTopology);
IF_FAILED_JUMP(hr, Exit);
hr = spMyDeviceTopology->GetConnector(papoSysFxInit2->nSoftwareIoConnectorIndex, &spMyConnector);
IF_FAILED_JUMP(hr, Exit);
// Save the processing mode being initialized.
processingMode = papoSysFxInit2->AudioProcessingMode;
}
else if (cbDataSize == sizeof(APOInitSystemEffects))
{
//
// Initialize for default signal processing
//
APOInitSystemEffects* papoSysFxInit = (APOInitSystemEffects*)pbyData;
// Save reference to the effects property store. This saves effects settings
// and is the communication medium between this APO and any associated UI.
m_spAPOSystemEffectsProperties = papoSysFxInit->pAPOSystemEffectsProperties;
// Assume default processing mode
processingMode = AUDIO_SIGNALPROCESSINGMODE_DEFAULT;
}
else
{
// Invalid initialization size
hr = E_INVALIDARG;
goto Exit;
}
// Validate then save the processing mode. Note an endpoint effects APO
// does not depend on the mode. Windows sets the APOInitSystemEffects2
// AudioProcessingMode member to GUID_NULL for an endpoint effects APO.
IF_TRUE_ACTION_JUMP((processingMode != AUDIO_SIGNALPROCESSINGMODE_DEFAULT &&
processingMode != AUDIO_SIGNALPROCESSINGMODE_RAW &&
processingMode != AUDIO_SIGNALPROCESSINGMODE_COMMUNICATIONS &&
processingMode != AUDIO_SIGNALPROCESSINGMODE_SPEECH &&
processingMode != AUDIO_SIGNALPROCESSINGMODE_MEDIA &&
processingMode != AUDIO_SIGNALPROCESSINGMODE_MOVIE), hr = E_INVALIDARG, Exit);
m_AudioProcessingMode = processingMode;
//
// An APO that implements signal processing more complex than this sample
// would configure its processing for the processingMode determined above.
// If necessary, the APO would also use the IDeviceTopology and IConnector
// interfaces retrieved above to communicate with its counterpart audio
// driver to configure any additional signal processing in the driver and
// associated hardware.
//
//
// Get the current values
//
if (m_spAPOSystemEffectsProperties != NULL)
{
m_fEnableDelaySFX = GetCurrentEffectsSetting(m_spAPOSystemEffectsProperties, PKEY_Endpoint_Enable_Delay_SFX, m_AudioProcessingMode);
}
//
// Register for notification of registry updates
//
hr = m_spEnumerator.CoCreateInstance(__uuidof(MMDeviceEnumerator));
IF_FAILED_JUMP(hr, Exit);
hr = m_spEnumerator->RegisterEndpointNotificationCallback(this);
IF_FAILED_JUMP(hr, Exit);
m_bIsInitialized = true;
Exit:
return hr;
}
//-------------------------------------------------------------------------
//
// GetEffectsList
//
// Retrieves the list of signal processing effects currently active and
// stores an event to be signaled if the list changes.
//
// Parameters
//
// ppEffectsIds - returns a pointer to a list of GUIDs each identifying a
// class of effect. The caller is responsible for freeing this memory by
// calling CoTaskMemFree.
//
// pcEffects - returns a count of GUIDs in the list.
//
// Event - passes an event handle. The APO signals this event when the list
// of effects changes from the list returned from this function. The APO
// uses this event until either this function is called again or the APO
// is destroyed. The passed handle may be NULL. In this case, the APO
// stops using any previous handle and does not signal an event.
//
// Remarks
//
// An APO imlements this method to allow Windows to discover the current
// effects applied by the APO. The list of effects may depend on what signal
// processing mode the APO initialized (see AudioProcessingMode in the
// APOInitSystemEffects2 structure) as well as any end user configuration.
//
// If there are no effects then the function still succeeds, ppEffectsIds
// returns a NULL pointer, and pcEffects returns a count of 0.
//
STDMETHODIMP CDelayAPOSFX::GetEffectsList(_Outptr_result_buffer_maybenull_(*pcEffects) LPGUID *ppEffectsIds, _Out_ UINT *pcEffects, _In_ HANDLE Event)
{
HRESULT hr;
BOOL effectsLocked = FALSE;
UINT cEffects = 0;
IF_TRUE_ACTION_JUMP(ppEffectsIds == NULL, hr = E_POINTER, Exit);
IF_TRUE_ACTION_JUMP(pcEffects == NULL, hr = E_POINTER, Exit);
// Synchronize access to the effects list and effects changed event
m_EffectsLock.Enter();
effectsLocked = TRUE;
// Always close existing effects change event handle
if (m_hEffectsChangedEvent != NULL)
{
CloseHandle(m_hEffectsChangedEvent);
m_hEffectsChangedEvent = NULL;
}
// If an event handle was specified, save it here (duplicated to control lifetime)
if (Event != NULL)
{
if (!DuplicateHandle(GetCurrentProcess(), Event, GetCurrentProcess(), &m_hEffectsChangedEvent, EVENT_MODIFY_STATE, FALSE, 0))
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Exit;
}
}
// naked scope to force the initialization of list[] to be after we enter the critical section
{
struct EffectControl
{
GUID effect;
BOOL control;
};
EffectControl list[] =
{
{ DelayEffectId, m_fEnableDelaySFX },
};
if (!IsEqualGUID(m_AudioProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW))
{
// count the active effects
for (UINT i = 0; i < ARRAYSIZE(list); i++)
{
if (list[i].control)
{
cEffects++;
}
}
}
if (0 == cEffects)
{
*ppEffectsIds = NULL;
*pcEffects = 0;
}
else
{
GUID *pEffectsIds = (LPGUID)CoTaskMemAlloc(sizeof(GUID) * cEffects);
if (pEffectsIds == nullptr)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
// pick up the active effects
UINT j = 0;
for (UINT i = 0; i < ARRAYSIZE(list); i++)
{
if (list[i].control)
{
pEffectsIds[j++] = list[i].effect;
}
}
*ppEffectsIds = pEffectsIds;
*pcEffects = cEffects;
}
hr = S_OK;
}
Exit:
if (effectsLocked)
{
m_EffectsLock.Leave();
}
return hr;
}
//-------------------------------------------------------------------------
// Description:
//
//
//
// Parameters:
//
//
//
// Return values:
//
//
//
// Remarks:
//
//
HRESULT CDelayAPOSFX::OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key)
{
HRESULT hr = S_OK;
UNREFERENCED_PARAMETER(pwstrDeviceId);
if (!m_spAPOSystemEffectsProperties)
{
return hr;
}
// If either the master disable or our APO's enable properties changed...
if (PK_EQUAL(key, PKEY_Endpoint_Enable_Delay_SFX) ||
PK_EQUAL(key, PKEY_AudioEndpoint_Disable_SysFx))
{
LONG nChanges = 0;
// Synchronize access to the effects list and effects changed event
m_EffectsLock.Enter();
struct KeyControl
{
PROPERTYKEY key;
LONG *value;
};
KeyControl controls[] =
{
{ PKEY_Endpoint_Enable_Delay_SFX, &m_fEnableDelaySFX },
};
for (int i = 0; i < ARRAYSIZE(controls); i++)
{
LONG fOldValue;
LONG fNewValue = true;
// Get the state of whether channel swap MFX is enabled or not
fNewValue = GetCurrentEffectsSetting(m_spAPOSystemEffectsProperties, controls[i].key, m_AudioProcessingMode);
// Delay in the new setting
fOldValue = InterlockedExchange(controls[i].value, fNewValue);
if (fNewValue != fOldValue)
{
nChanges++;
}
}
// If anything changed and a change event handle exists
if ((nChanges > 0) && (m_hEffectsChangedEvent != NULL))
{
SetEvent(m_hEffectsChangedEvent);
}
m_EffectsLock.Leave();
}
return hr;
}
//-------------------------------------------------------------------------
// Description:
//
// Destructor.
//
// Parameters:
//
// void
//
// Return values:
//
// void
//
// Remarks:
//
// This method deletes whatever was allocated.
//
// This method may not be called from a real-time processing thread.
//
CDelayAPOSFX::~CDelayAPOSFX(void)
{
//
// unregister for callbacks
//
if (m_bIsInitialized)
{
m_spEnumerator->UnregisterEndpointNotificationCallback(this);
}
if (m_hEffectsChangedEvent != NULL)
{
CloseHandle(m_hEffectsChangedEvent);
}
} // ~CDelayAPOSFX

Просмотреть файл

@ -0,0 +1,13 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {77802b45-a5a0-455a-8204-3dba30eee7b4} = s 'DelayAPOSFX Class'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Both'
}
}
}
}

Просмотреть файл

@ -0,0 +1,20 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by DelayAPODll.rc
//
#define IDS_PROJNAME 100
#define IDR_DELAYAPODLL 101
#define IDR_DELAYAPOMFX 110
#define IDR_DELAYAPOSFX 111
#define IDI_EFFECT_ICON 200
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 201
#define _APS_NEXT_COMMAND_VALUE 32768
#define _APS_NEXT_CONTROL_VALUE 201
#define _APS_NEXT_SYMED_VALUE 132
#endif
#endif

Двоичные данные
audio/sysvad/SwapAPO/DelayAPO/delayapo.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Просмотреть файл

@ -0,0 +1,34 @@
#############################################################################
#
# Copyright (c) Microsoft Corporation.
# All Rights Reserved.
#
#############################################################################
## NT BUILD ENVIROMENT
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the components of NT.
#
!if defined(IA64)
!message This sample is not to be built for IA64 targets
!else
!IF DEFINED(_NT_TARGET_VERSION)
#! IF $(_NT_TARGET_VERSION)>=0x501
! IF $(_NT_TARGET_VERSION)>=0x600
! INCLUDE $(NTMAKEENV)\makefile.def
! ELSE
# Only warn once per directory
! INCLUDE $(NTMAKEENV)\makefile.plt
! IF "$(BUILD_PASS)"=="PASS1"
! message BUILDMSG: Warning : Building the sample "$(MAKEDIR)" for downlevel build environments is temporarily disabled in WDK for Beta2.
! ENDIF
! ENDIF
!ELSE
! INCLUDE $(NTMAKEENV)\makefile.def
!ENDIF
!endif

Просмотреть файл

@ -0,0 +1,12 @@
!include ..\sources.inc
TARGETNAME=DelayAPO
DLLDEF=DelayAPODll.def
SOURCES=DelayAPOInterface.idl \
DelayAPOMFX.cpp \
DelayAPOSFX.cpp \
Delay.cpp \
DelayAPODll.idl \
DelayAPODll.rc \
DelayAPODll.cpp \

Просмотреть файл

@ -0,0 +1,51 @@
<?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>{413921B3-AEE4-4E51-B616-E356BEC9E42E}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
<UniqueIdentifier>{0B044B82-EDD8-49A9-ACEE-2E7C98CCA3DC}</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>{1E3956FB-B7AD-48BF-AD18-28527349BEED}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="AdvEndpointPropPage.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CplExt.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Parts.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="stdafxsrc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SwapPropPage.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TopologyExaminers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="UIWidgets.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<Midl Include="CplExt.idl">
<Filter>Source Files</Filter>
</Midl>
<None Include="PropPageExt.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="CplExt.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,36 @@
#############################################################################
#
# Copyright (c) Microsoft Corporation.
# All Rights Reserved.
#
# Makefile for wdm\audio\sysfx\apo
#
#############################################################################
## NT BUILD ENVIROMENT
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the components of NT.
#
!if defined(IA64)
!message This sample is not to be built for IA64 targets
!else
!IF DEFINED(_NT_TARGET_VERSION)
#! IF $(_NT_TARGET_VERSION)>=0x501
! IF $(_NT_TARGET_VERSION)>=0x600
! INCLUDE $(NTMAKEENV)\makefile.def
! ELSE
# Only warn once per directory
! INCLUDE $(NTMAKEENV)\makefile.plt
! IF "$(BUILD_PASS)"=="PASS1"
! message BUILDMSG: Warning : Building the sample "$(MAKEDIR)" for downlevel build environments is temporarily disabled in WDK for Beta2.
! ENDIF
! ENDIF
!ELSE
! INCLUDE $(NTMAKEENV)\makefile.def
!ENDIF
!endif

Просмотреть файл

@ -0,0 +1,60 @@
TARGETNAME=PropPageExt
TARGETTYPE=DYNLINK
USE_ATL=1
USE_NATIVE_EH=1
DLLENTRY=_DllMainCRTStartup
PRECOMPILED_CXX=1
PRECOMPILED_INCLUDE=stdafx.h
PRECOMPILED_PCH=stdafx.pch
MSC_WARNING_LEVEL=-W4 \
-WX
#
# stdafx.h defines _ATL_ALL_WARNINGS
# Disabling 4127 is necessary to allow this driver to build in the WDK environment.
#
USER_C_FLAGS=/wd4127
C_DEFINES=-DUNICODE \
-D_UNICODE
#
# Indicate to the WDK that this sample only supports Win10[+]
#
MINIMUM_NT_TARGET_VERSION=$(_NT_TARGET_VERSION_WINTHRESHOLD)
# Indicate that this DLL must be included in the driver package
DDK_NO_PACKAGE_PROJECT=0
DDK_INCLUDE_PACKAGE_PROJECT=1
INCLUDES=$(INCLUDES); \
..\Inc; \
$(DDK_INC_PATH);
SOURCES=CplExt.idl \
CplExt.rc \
CplExt.cpp \
SwapPropPage.cpp \
AdvEndpointPropPage.cpp \
UIWidgets.cpp \
TopologyExaminers.cpp \
Parts.cpp \
TARGETLIBS= \
\
$(SDK_LIB_PATH)\onecore_downlevel.lib \
$(ONECORE_PRIV_SDK_LIB_PATH)\OneCore_Forwarder_user32.lib \
$(SDK_LIB_PATH)\onecore_downlevel.lib \
$(SDK_LIB_PATH)\oleaut32.lib \
$(INTERNAL_SDK_LIB_PATH)\onecoreuapuuid.lib \
$(SDK_LIB_PATH)\shlwapi.lib \
$(SDK_LIB_PATH)\comctl32.lib \
$(SDK_LIB_PATH)\rpcrt4.lib \

Просмотреть файл

@ -0,0 +1,58 @@
<?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>{7FE326AE-6214-4FE0-A27B-F229A098BDBC}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
<UniqueIdentifier>{64C16D2B-849C-4264-A615-18A8E8AC9505}</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>{46FAF4E8-F18C-4797-9CFA-2F3473BCB316}</UniqueIdentifier>
</Filter>
<Filter Include="Driver Files">
<Extensions>inf;inv;inx;mof;mc;</Extensions>
<UniqueIdentifier>{EE8F0A00-C1F0-4CB4-80E3-5FCC378E0BF4}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\adapter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\basetopo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\common.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\hw.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\kshelper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\savedata.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\tonegenerator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="hdmitopo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="micintopo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="spdiftopo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\sysvad.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

Просмотреть файл

@ -177,7 +177,10 @@ ENDPOINT_MINIPAIR SpeakerMiniports =
SIZEOF_ARRAY(SpeakerPinDeviceFormatsAndModes), SIZEOF_ARRAY(SpeakerPinDeviceFormatsAndModes),
SpeakerTopologyPhysicalConnections, SpeakerTopologyPhysicalConnections,
SIZEOF_ARRAY(SpeakerTopologyPhysicalConnections), SIZEOF_ARRAY(SpeakerTopologyPhysicalConnections),
ENDPOINT_OFFLOAD_SUPPORTED ENDPOINT_OFFLOAD_SUPPORTED,
SpeakerModulesWaveFilter,
SIZEOF_ARRAY(SpeakerModulesWaveFilter),
&SpeakerModuleNotificationDeviceId,
}; };
/********************************************************************* /*********************************************************************
@ -219,7 +222,10 @@ ENDPOINT_MINIPAIR SpeakerHpMiniports =
SIZEOF_ARRAY(SpeakerHpPinDeviceFormatsAndModes), SIZEOF_ARRAY(SpeakerHpPinDeviceFormatsAndModes),
SpeakerHpTopologyPhysicalConnections, SpeakerHpTopologyPhysicalConnections,
SIZEOF_ARRAY(SpeakerHpTopologyPhysicalConnections), SIZEOF_ARRAY(SpeakerHpTopologyPhysicalConnections),
ENDPOINT_OFFLOAD_SUPPORTED ENDPOINT_OFFLOAD_SUPPORTED,
SpeakerHpModulesWaveFilter,
SIZEOF_ARRAY(SpeakerHpModulesWaveFilter),
&SpeakerHpModuleNotificationDeviceId,
}; };
/********************************************************************* /*********************************************************************
@ -261,7 +267,8 @@ ENDPOINT_MINIPAIR HdmiMiniports =
SIZEOF_ARRAY(HdmiPinDeviceFormatsAndModes), SIZEOF_ARRAY(HdmiPinDeviceFormatsAndModes),
HdmiTopologyPhysicalConnections, HdmiTopologyPhysicalConnections,
SIZEOF_ARRAY(HdmiTopologyPhysicalConnections), SIZEOF_ARRAY(HdmiTopologyPhysicalConnections),
ENDPOINT_NO_FLAGS ENDPOINT_NO_FLAGS,
NULL, 0, NULL, // audio module settings.
}; };
/********************************************************************* /*********************************************************************
@ -304,7 +311,8 @@ ENDPOINT_MINIPAIR SpdifMiniports =
SIZEOF_ARRAY(SpdifPinDeviceFormatsAndModes), SIZEOF_ARRAY(SpdifPinDeviceFormatsAndModes),
SpdifTopologyPhysicalConnections, SpdifTopologyPhysicalConnections,
SIZEOF_ARRAY(SpdifTopologyPhysicalConnections), SIZEOF_ARRAY(SpdifTopologyPhysicalConnections),
ENDPOINT_OFFLOAD_SUPPORTED ENDPOINT_OFFLOAD_SUPPORTED,
NULL, 0, NULL, // audio module settings.
}; };
// //
@ -348,7 +356,8 @@ ENDPOINT_MINIPAIR MicInMiniports =
SIZEOF_ARRAY(MicInPinDeviceFormatsAndModes), SIZEOF_ARRAY(MicInPinDeviceFormatsAndModes),
MicInTopologyPhysicalConnections, MicInTopologyPhysicalConnections,
SIZEOF_ARRAY(MicInTopologyPhysicalConnections), SIZEOF_ARRAY(MicInTopologyPhysicalConnections),
ENDPOINT_NO_FLAGS ENDPOINT_NO_FLAGS,
NULL, 0, NULL, // audio module settings.
}; };
/********************************************************************* /*********************************************************************
@ -389,7 +398,8 @@ ENDPOINT_MINIPAIR MicArray1Miniports =
SIZEOF_ARRAY(MicArrayPinDeviceFormatsAndModes), SIZEOF_ARRAY(MicArrayPinDeviceFormatsAndModes),
MicArray1TopologyPhysicalConnections, MicArray1TopologyPhysicalConnections,
SIZEOF_ARRAY(MicArray1TopologyPhysicalConnections), SIZEOF_ARRAY(MicArray1TopologyPhysicalConnections),
ENDPOINT_SOUNDDETECTOR_SUPPORTED ENDPOINT_SOUNDDETECTOR_SUPPORTED,
NULL, 0, NULL, // audio module settings.
}; };
/********************************************************************* /*********************************************************************
@ -429,7 +439,8 @@ ENDPOINT_MINIPAIR MicArray2Miniports =
SIZEOF_ARRAY(MicArrayPinDeviceFormatsAndModes), SIZEOF_ARRAY(MicArrayPinDeviceFormatsAndModes),
MicArray2TopologyPhysicalConnections, MicArray2TopologyPhysicalConnections,
SIZEOF_ARRAY(MicArray2TopologyPhysicalConnections), SIZEOF_ARRAY(MicArray2TopologyPhysicalConnections),
ENDPOINT_SOUNDDETECTOR_SUPPORTED ENDPOINT_SOUNDDETECTOR_SUPPORTED,
NULL, 0, NULL, // audio module settings.
}; };
/********************************************************************* /*********************************************************************
@ -469,7 +480,8 @@ ENDPOINT_MINIPAIR MicArray3Miniports =
SIZEOF_ARRAY(MicArray3PinDeviceFormatsAndModes), SIZEOF_ARRAY(MicArray3PinDeviceFormatsAndModes),
MicArray3TopologyPhysicalConnections, MicArray3TopologyPhysicalConnections,
SIZEOF_ARRAY(MicArray3TopologyPhysicalConnections), SIZEOF_ARRAY(MicArray3TopologyPhysicalConnections),
ENDPOINT_NO_FLAGS ENDPOINT_NO_FLAGS,
NULL, 0, NULL, // audio module settings.
}; };
//============================================================================= //=============================================================================

Просмотреть файл

@ -0,0 +1,53 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
!include ..\sources.inc
TARGETNAME=TabletAudioSample
TARGETLIBS= \
$(TARGETLIBS) \
$(OBJ_PATH)\..\EndpointsCommon\$(O)\EndpointsCommon.lib \
C_DEFINES = $(C_DEFINES) -D_USE_WAVERT_ -DSYSVAD_BTH_BYPASS
#C_DEFINES = $(C_DEFINES) -D_USE_WAVERT_
#
# Indicate to the WDK that this sample only supports Win10[+]
#
MINIMUM_NT_TARGET_VERSION=$(_NT_TARGET_VERSION_WINTHRESHOLD)
#
# Audio driver is a KMDF miniport.
#
KMDF_VERSION_MAJOR=1
#
# Uncomment one of the following lines to select the right power management.
# Note that the single-component/multi-state feature requires also a registry
# value set via the INF. The name of the registry value is SingleComponentMultiFxStates.
# see INF file for more info.
#
#C_DEFINES= $(C_DEFINES) -D_USE_IPortClsRuntimePower
C_DEFINES= $(C_DEFINES) -D_USE_SingleComponentMultiFxStates
INCLUDES= \
$(INCLUDES); \
..\EndpointsCommon; \
SOURCES=$(SOURCES) \
hdmitopo.cpp \
spdiftopo.cpp \
micintopo.cpp \
# Indicate that this module must be included in the driver package
DDK_NO_PACKAGE_PROJECT=0
DDK_INCLUDE_PACKAGE_PROJECT=1
MUI_VERIFY_NO_LOC_RESOURCE=1

Двоичный файл не отображается.

Просмотреть файл

@ -187,6 +187,126 @@ typedef struct _PIN_DEVICE_FORMATS_AND_MODES
} PIN_DEVICE_FORMATS_AND_MODES, *PPIN_DEVICE_FORMATS_AND_MODES; } PIN_DEVICE_FORMATS_AND_MODES, *PPIN_DEVICE_FORMATS_AND_MODES;
//
// Parameter module handler function prototypes.
//
static const GUID NULL_GUID =
{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}};
static const GUID MODULETYPE_HWEFFECT =
{0x2608993c,0x361e,0x488c,{0xa0,0xbc,0x8f,0x3d,0xe7,0xba,0x12,0xb4}};
//
// Forward declaration.
//
struct AUDIOMODULE_DESCRIPTOR;
typedef AUDIOMODULE_DESCRIPTOR *PAUDIOMODULE_DESCRIPTOR;
typedef struct _AUDIOMODULE_PARAMETER_INFO
{
USHORT AccessFlags; // get/set/basic-support attributes.
USHORT Flags;
ULONG Size;
DWORD VtType;
PVOID ValidSet;
ULONG ValidSetCount;
} AUDIOMODULE_PARAMETER_INFO, *PAUDIOMODULE_PARAMETER_INFO;
#define AUDIOMODULE_PARAMETER_FLAG_CHANGE_NOTIFICATION 0x00000001
//
// Module callbacks.
//
typedef
NTSTATUS
(*FN_AUDIOMODULE_INIT_CLASS)
(
_In_ const AUDIOMODULE_DESCRIPTOR * Module,
_Inout_opt_ PVOID Context,
_In_ size_t Size,
_In_ KSAUDIOMODULE_NOTIFICATION * NotificationHeader,
_In_opt_ PPORTCLSNOTIFICATIONS PortNotifications
);
typedef
NTSTATUS
(*FN_AUDIOMODULE_INIT_INSTANCE)
(
_In_ const AUDIOMODULE_DESCRIPTOR * Module,
_In_opt_ PVOID TemplateContext,
_Inout_opt_ PVOID Context,
_In_ size_t Size,
_In_ ULONG InstanceId
);
typedef
VOID
(*FN_AUDIOMODULE_CLEANUP)
(
_In_ PVOID Context
);
typedef
NTSTATUS
(*FN_AUDIOMODULE_HANDLER)
(
_Inout_opt_ PVOID Context,
_In_reads_bytes_(InBufferCb) PVOID InBuffer,
_In_ ULONG InBufferCb,
_Out_writes_bytes_opt_(*OutBufferCb) PVOID OutBuffer,
_Inout_ ULONG * OutBufferCb
);
//
// Module description.
//
struct AUDIOMODULE_DESCRIPTOR
{
const GUID * ClassId;
const GUID * ProcessingMode;
WCHAR Name[AUDIOMODULE_MAX_NAME_CCH_SIZE];
ULONG InstanceId;
ULONG VersionMajor;
ULONG VersionMinor;
ULONG Flags;
size_t ContextSize;
FN_AUDIOMODULE_INIT_CLASS InitClass;
FN_AUDIOMODULE_INIT_INSTANCE InitInstance;
FN_AUDIOMODULE_CLEANUP Cleanup;
FN_AUDIOMODULE_HANDLER Handler;
};
#define AUDIOMODULE_DESCRIPTOR_FLAG_NONE 0x00000000
//
// Audio module instance defintion.
// This sample driver generates an instance id by combinding the
// configuration set # for a class module id with the instance of that
// configuration. Real driver should use a more robust scheme, such as
// an indirect mapping from/to an instance id to/from a configuration set
// + location in the pipeline + any other info the driver needs.
//
#define AUDIOMODULE_CLASS_CFG_ID_MASK 0xFF
#define AUDIOMODULE_CLASS_CFG_INSTANCE_ID_MASK 0xFFFFFF
#define AUDIOMODULE_INSTANCE_ID(ClassCfgId, ClassCfgInstanceId) \
((ULONG(ClassCfgId & AUDIOMODULE_CLASS_CFG_ID_MASK) << 24) | \
(ULONG(ClassCfgInstanceId & AUDIOMODULE_CLASS_CFG_INSTANCE_ID_MASK)))
#define AUDIOMODULE_GET_CLASSCFGID(InstanceId) \
(ULONG(InstanceId) >> 24 & AUDIOMODULE_CLASS_CFG_ID_MASK)
//
// Used to track run-time audio module changes.
//
struct AUDIOMODULE
{
const AUDIOMODULE_DESCRIPTOR * Descriptor;
PVOID Context;
ULONG InstanceId;
ULONG NextCfgInstanceId; // used by filter modules
BOOL Enabled;
};
// forward declaration. // forward declaration.
typedef struct _ENDPOINT_MINIPAIR *PENDPOINT_MINIPAIR; typedef struct _ENDPOINT_MINIPAIR *PENDPOINT_MINIPAIR;
@ -252,6 +372,11 @@ typedef struct _ENDPOINT_MINIPAIR
// General endpoint flags (one of more ENDPOINT_<flag-type>, see above) // General endpoint flags (one of more ENDPOINT_<flag-type>, see above)
ULONG DeviceFlags; ULONG DeviceFlags;
// Static module list description.
AUDIOMODULE_DESCRIPTOR * ModuleList;
ULONG ModuleListCount;
const GUID * ModuleNotificationDeviceId;
} ENDPOINT_MINIPAIR; } ENDPOINT_MINIPAIR;
//============================================================================= //=============================================================================

34
audio/sysvad/sources.inc Normal file
Просмотреть файл

@ -0,0 +1,34 @@
TARGETTYPE=DRIVER
TARGETLIBS= \
$(DDK_LIB_PATH)\portcls.lib\
$(DDK_LIB_PATH)\stdunk.lib \
$(SDK_LIB_PATH)\libcntpr.lib
INCLUDES= \
$(DDK_INC_PATH); \
..
MSC_WARNING_LEVEL=-W4 -WX
C_DEFINES= $(C_DEFINES) -D_WIN32 -DUNICODE -D_UNICODE -DPC_IMPLEMENTATION
#
# Different levels of debug printage. First is nothing but
# catastrophic errors, last is everything under the sun.
#
#C_DEFINES= $(C_DEFINES) -DDEBUG_LEVEL=DEBUGLVL_ERROR
C_DEFINES= $(C_DEFINES) -DDEBUG_LEVEL=DEBUGLVL_TERSE
#C_DEFINES= $(C_DEFINES) -DDEBUG_LEVEL=DEBUGLVL_VERBOSE
#C_DEFINES= $(C_DEFINES) -DDEBUG_LEVEL=DEBUGLVL_BLAB
SOURCES=\
..\adapter.cpp \
..\basetopo.cpp \
..\common.cpp \
..\hw.cpp \
..\kshelper.cpp \
..\savedata.cpp \
..\tonegenerator.cpp \
..\sysvad.rc

Просмотреть файл

@ -229,6 +229,15 @@ typedef struct _PortClassDeviceContext // 32 64 Byte off
// This actually goes on for (64*sizeof(ULONG_PTR)) but it is all opaque. // This actually goes on for (64*sizeof(ULONG_PTR)) but it is all opaque.
} PortClassDeviceContext; } PortClassDeviceContext;
//
// Major/MinorTarget to object casting.
//
#define MajorTarget_to_Obj(ptr) \
reinterpret_cast<CMiniportWaveRT*>(ptr)
#define MinorTarget_to_Obj(ptr) \
static_cast<CMiniportWaveRTStream*>(reinterpret_cast<PMINIPORTWAVERTSTREAM>(ptr))
// //
// Global settings. // Global settings.
// //
@ -257,6 +266,11 @@ NTSTATUS PropertyHandler_OffloadPin
_In_ PPCPROPERTY_REQUEST PropertyRequest _In_ PPCPROPERTY_REQUEST PropertyRequest
); );
NTSTATUS PropertyHandler_GenericPin
(
_In_ PPCPROPERTY_REQUEST PropertyRequest
);
// common.h uses some of the above definitions. // common.h uses some of the above definitions.
#include "common.h" #include "common.h"
#include "kshelper.h" #include "kshelper.h"

Просмотреть файл

@ -1,8 +1,10 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14 # Visual Studio 14
VisualStudioVersion = 14.0.25420.1 VisualStudioVersion = 14.0.25431.01
MinimumVisualStudioVersion = 12.0 MinimumVisualStudioVersion = 12.0
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Package", "Package", "{FA56D96B-290B-4C73-A5E1-02C1861D3224}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "KeywordDetectorAdapter", "KeywordDetectorAdapter", "{DBD14E7B-7F95-4743-86E3-4E16FA43F990}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "KeywordDetectorAdapter", "KeywordDetectorAdapter", "{DBD14E7B-7F95-4743-86E3-4E16FA43F990}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PropPageExtensions", "PropPageExtensions", "{50D3DF82-019A-4434-B17F-72BBC291415F}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PropPageExtensions", "PropPageExtensions", "{50D3DF82-019A-4434-B17F-72BBC291415F}"
@ -17,12 +19,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PhoneAudioSample", "PhoneAu
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TabletAudioSample", "TabletAudioSample", "{C06F6070-75EE-4F57-8D35-4AC2AB08D029}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TabletAudioSample", "TabletAudioSample", "{C06F6070-75EE-4F57-8D35-4AC2AB08D029}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "package\package.VcxProj", "{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeywordDetectorContosoAdapter", "KeywordDetectorAdapter\KeywordDetectorContosoAdapter.vcxproj", "{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KeywordDetectorContosoAdapter", "KeywordDetectorAdapter\KeywordDetectorContosoAdapter.vcxproj", "{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PropPageExt", "SwapAPO\PropPageExtensions\PropPageExt.vcxproj", "{D253C552-154D-49E1-820A-B2CD9D9FF13E}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PropPageExt", "SwapAPO\PropPageExtensions\PropPageExt.vcxproj", "{D253C552-154D-49E1-820A-B2CD9D9FF13E}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SwapAPO", "SwapAPO\APO\SwapAPO.vcxproj", "{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SwapAPO", "SwapAPO\APO\SwapAPO.vcxproj", "{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DelayAPO", "SwapAPO\DelayAPO\DelayAPO.vcxproj", "{8851AB85-70B3-4798-A149-BA366DF9EC25}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EndpointsCommon", "EndpointsCommon\EndpointsCommon.vcxproj", "{33E61864-6F2C-4F9F-BE70-8F8985A4F283}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EndpointsCommon", "EndpointsCommon\EndpointsCommon.vcxproj", "{33E61864-6F2C-4F9F-BE70-8F8985A4F283}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PhoneAudioSample", "PhoneAudioSample\PhoneAudioSample.vcxproj", "{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PhoneAudioSample", "PhoneAudioSample\PhoneAudioSample.vcxproj", "{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}"
@ -38,57 +44,73 @@ EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32 Release|Win32 = Release|Win32
Debug|x64 = Debug|x64
Release|x64 = Release|x64 Release|x64 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|Win32.ActiveCfg = Debug|Win32
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|Win32.Build.0 = Debug|Win32
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|Win32.ActiveCfg = Release|Win32
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|Win32.Build.0 = Release|Win32
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|x64.ActiveCfg = Debug|x64
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Debug|x64.Build.0 = Debug|x64
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|x64.ActiveCfg = Release|x64
{830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A}.Release|x64.Build.0 = Release|x64
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|Win32.ActiveCfg = Debug|Win32 {E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|Win32.ActiveCfg = Debug|Win32
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|Win32.Build.0 = Debug|Win32 {E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|Win32.Build.0 = Debug|Win32
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|x64.ActiveCfg = Debug|x64
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|x64.Build.0 = Debug|x64
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|Win32.ActiveCfg = Release|Win32 {E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|Win32.ActiveCfg = Release|Win32
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|Win32.Build.0 = Release|Win32 {E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|Win32.Build.0 = Release|Win32
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|x64.ActiveCfg = Debug|x64
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Debug|x64.Build.0 = Debug|x64
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|x64.ActiveCfg = Release|x64 {E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|x64.ActiveCfg = Release|x64
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|x64.Build.0 = Release|x64 {E0F02048-78A4-4FE8-B863-66E6CB6A2C37}.Release|x64.Build.0 = Release|x64
{D253C552-154D-49E1-820A-B2CD9D9FF13E}.Debug|Win32.ActiveCfg = Debug|Win32 {D253C552-154D-49E1-820A-B2CD9D9FF13E}.Debug|Win32.ActiveCfg = Debug|Win32
{D253C552-154D-49E1-820A-B2CD9D9FF13E}.Debug|Win32.Build.0 = Debug|Win32 {D253C552-154D-49E1-820A-B2CD9D9FF13E}.Debug|Win32.Build.0 = Debug|Win32
{D253C552-154D-49E1-820A-B2CD9D9FF13E}.Debug|x64.ActiveCfg = Debug|x64
{D253C552-154D-49E1-820A-B2CD9D9FF13E}.Debug|x64.Build.0 = Debug|x64
{D253C552-154D-49E1-820A-B2CD9D9FF13E}.Release|Win32.ActiveCfg = Release|Win32 {D253C552-154D-49E1-820A-B2CD9D9FF13E}.Release|Win32.ActiveCfg = Release|Win32
{D253C552-154D-49E1-820A-B2CD9D9FF13E}.Release|Win32.Build.0 = Release|Win32 {D253C552-154D-49E1-820A-B2CD9D9FF13E}.Release|Win32.Build.0 = Release|Win32
{D253C552-154D-49E1-820A-B2CD9D9FF13E}.Debug|x64.ActiveCfg = Debug|x64
{D253C552-154D-49E1-820A-B2CD9D9FF13E}.Debug|x64.Build.0 = Debug|x64
{D253C552-154D-49E1-820A-B2CD9D9FF13E}.Release|x64.ActiveCfg = Release|x64 {D253C552-154D-49E1-820A-B2CD9D9FF13E}.Release|x64.ActiveCfg = Release|x64
{D253C552-154D-49E1-820A-B2CD9D9FF13E}.Release|x64.Build.0 = Release|x64 {D253C552-154D-49E1-820A-B2CD9D9FF13E}.Release|x64.Build.0 = Release|x64
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|Win32.ActiveCfg = Debug|Win32 {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|Win32.ActiveCfg = Debug|Win32
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|Win32.Build.0 = Debug|Win32 {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|Win32.Build.0 = Debug|Win32
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|x64.ActiveCfg = Debug|x64
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|x64.Build.0 = Debug|x64
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|Win32.ActiveCfg = Release|Win32 {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|Win32.ActiveCfg = Release|Win32
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|Win32.Build.0 = Release|Win32 {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|Win32.Build.0 = Release|Win32
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|x64.ActiveCfg = Debug|x64
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Debug|x64.Build.0 = Debug|x64
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|x64.ActiveCfg = Release|x64 {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|x64.ActiveCfg = Release|x64
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|x64.Build.0 = Release|x64 {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601}.Release|x64.Build.0 = Release|x64
{8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|Win32.ActiveCfg = Debug|Win32
{8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|Win32.Build.0 = Debug|Win32
{8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|Win32.ActiveCfg = Release|Win32
{8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|Win32.Build.0 = Release|Win32
{8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|x64.ActiveCfg = Debug|x64
{8851AB85-70B3-4798-A149-BA366DF9EC25}.Debug|x64.Build.0 = Debug|x64
{8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|x64.ActiveCfg = Release|x64
{8851AB85-70B3-4798-A149-BA366DF9EC25}.Release|x64.Build.0 = Release|x64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|Win32.ActiveCfg = Debug|Win32 {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|Win32.ActiveCfg = Debug|Win32
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|Win32.Build.0 = Debug|Win32 {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|Win32.Build.0 = Debug|Win32
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|x64.ActiveCfg = Debug|x64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|x64.Build.0 = Debug|x64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|Win32.ActiveCfg = Release|Win32 {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|Win32.ActiveCfg = Release|Win32
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|Win32.Build.0 = Release|Win32 {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|Win32.Build.0 = Release|Win32
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|x64.ActiveCfg = Debug|x64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Debug|x64.Build.0 = Debug|x64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|x64.ActiveCfg = Release|x64 {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|x64.ActiveCfg = Release|x64
{33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|x64.Build.0 = Release|x64 {33E61864-6F2C-4F9F-BE70-8F8985A4F283}.Release|x64.Build.0 = Release|x64
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Debug|Win32.ActiveCfg = Debug|Win32 {FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Debug|Win32.ActiveCfg = Debug|Win32
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Debug|Win32.Build.0 = Debug|Win32 {FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Debug|Win32.Build.0 = Debug|Win32
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Debug|x64.ActiveCfg = Debug|x64
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Debug|x64.Build.0 = Debug|x64
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Release|Win32.ActiveCfg = Release|Win32 {FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Release|Win32.ActiveCfg = Release|Win32
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Release|Win32.Build.0 = Release|Win32 {FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Release|Win32.Build.0 = Release|Win32
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Debug|x64.ActiveCfg = Debug|x64
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Debug|x64.Build.0 = Debug|x64
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Release|x64.ActiveCfg = Release|x64 {FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Release|x64.ActiveCfg = Release|x64
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Release|x64.Build.0 = Release|x64 {FABA4668-DB5E-4F6C-9D25-A0B25AD084EE}.Release|x64.Build.0 = Release|x64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|Win32.ActiveCfg = Debug|Win32 {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|Win32.ActiveCfg = Debug|Win32
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|Win32.Build.0 = Debug|Win32 {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|Win32.Build.0 = Debug|Win32
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|x64.ActiveCfg = Debug|x64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|x64.Build.0 = Debug|x64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|Win32.ActiveCfg = Release|Win32 {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|Win32.ActiveCfg = Release|Win32
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|Win32.Build.0 = Release|Win32 {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|Win32.Build.0 = Release|Win32
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|x64.ActiveCfg = Debug|x64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Debug|x64.Build.0 = Debug|x64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|x64.ActiveCfg = Release|x64 {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|x64.ActiveCfg = Release|x64
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|x64.Build.0 = Release|x64 {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
@ -96,13 +118,15 @@ Global
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{50D3DF82-019A-4434-B17F-72BBC291415F} = {684FF1CF-64CC-430E-81F7-9D603EF56D59} {830B14D5-0E32-4F9E-AEFA-4C9F6FC13C2A} = {FA56D96B-290B-4C73-A5E1-02C1861D3224}
{367FF255-7280-48C4-90AC-767124A8D5F7} = {684FF1CF-64CC-430E-81F7-9D603EF56D59}
{E0F02048-78A4-4FE8-B863-66E6CB6A2C37} = {DBD14E7B-7F95-4743-86E3-4E16FA43F990} {E0F02048-78A4-4FE8-B863-66E6CB6A2C37} = {DBD14E7B-7F95-4743-86E3-4E16FA43F990}
{D253C552-154D-49E1-820A-B2CD9D9FF13E} = {50D3DF82-019A-4434-B17F-72BBC291415F} {D253C552-154D-49E1-820A-B2CD9D9FF13E} = {50D3DF82-019A-4434-B17F-72BBC291415F}
{691F1D0F-CA50-46CD-8BBA-A59E9E8EB601} = {367FF255-7280-48C4-90AC-767124A8D5F7} {691F1D0F-CA50-46CD-8BBA-A59E9E8EB601} = {367FF255-7280-48C4-90AC-767124A8D5F7}
{8851AB85-70B3-4798-A149-BA366DF9EC25} = {367FF255-7280-48C4-90AC-767124A8D5F7}
{33E61864-6F2C-4F9F-BE70-8F8985A4F283} = {0B4B8E51-20A8-43A4-A8DA-42FF90D628AC} {33E61864-6F2C-4F9F-BE70-8F8985A4F283} = {0B4B8E51-20A8-43A4-A8DA-42FF90D628AC}
{FABA4668-DB5E-4F6C-9D25-A0B25AD084EE} = {D0DBEBE9-0DCC-4EA7-966B-C029C1334D9E} {FABA4668-DB5E-4F6C-9D25-A0B25AD084EE} = {D0DBEBE9-0DCC-4EA7-966B-C029C1334D9E}
{E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF} = {C06F6070-75EE-4F57-8D35-4AC2AB08D029} {E4DF0EEE-D35B-47F2-A9B1-41EA97C465FF} = {C06F6070-75EE-4F57-8D35-4AC2AB08D029}
{50D3DF82-019A-4434-B17F-72BBC291415F} = {684FF1CF-64CC-430E-81F7-9D603EF56D59}
{367FF255-7280-48C4-90AC-767124A8D5F7} = {684FF1CF-64CC-430E-81F7-9D603EF56D59}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal