Author: janderwald
Date: Fri May 8 17:02:08 2009
New Revision: 40837
URL:
http://svn.reactos.org/svn/reactos?rev=40837&view=rev
Log:
- Partly implement IMasterClock
- Implement IAllocatorMXF for IPortPinDMus
- Implement rendering midi streams using IMXF object
- WIP, not tested yet
Modified:
trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c
trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h
trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c [iso-8859-1] Fri May 8
17:02:08 2009
@@ -65,12 +65,14 @@
const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80,
0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
-const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001, 0x0000, 0x0010, {0x80,
0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
+const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001L, 0x0000, 0x0010, {0x80,
0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf,
0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5,
0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87,
0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5,
0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
+
+const GUID IID_IAllocatorMXF = {0xa5f0d62cL, 0xb30f, 0x11d2, {0xb7,
0xa3, 0x00, 0x60, 0x08, 0x33, 0x16, 0xc1}};
///
/// undocumented guids
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] Fri May 8
17:02:08 2009
@@ -678,4 +678,6 @@
IN PDEVICE_OBJECT DeviceObject) PURE;
};
+#undef INTERFACE
+
#endif
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c [iso-8859-1] Fri May 8
17:02:08 2009
@@ -14,6 +14,9 @@
{
IPortPinDMusVtbl *lpVtbl;
IServiceSinkVtbl *lpVtblServiceSink;
+ IMasterClockVtbl *lpVtblMasterClock;
+ IAllocatorMXFVtbl *lpVtblAllocatorMXF;
+ IMXFVtbl *lpVtblMXF;
LONG ref;
IPortDMus * Port;
@@ -23,6 +26,11 @@
PSERVICEGROUP ServiceGroup;
+ PMXF Mxf;
+ ULONGLONG SchedulePreFetch;
+ NPAGED_LOOKASIDE_LIST LookAsideEvent;
+ NPAGED_LOOKASIDE_LIST LookAsideBuffer;
+
PMINIPORTMIDI MidiMiniport;
PMINIPORTMIDISTREAM MidiStream;
@@ -39,8 +47,15 @@
ULONG PreCompleted;
ULONG PostCompleted;
+ ULONG LastTag;
+
}IPortPinDMusImpl;
+typedef struct
+{
+ DMUS_KERNEL_EVENT Event;
+ PVOID Tag;
+}DMUS_KERNEL_EVENT_WITH_TAG, *PDMUS_KERNEL_EVENT_WITH_TAG;
typedef struct
{
@@ -49,10 +64,263 @@
KSSTATE State;
}SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT;
-NTSTATUS
-NTAPI
-IPortDMus_fnProcessNewIrp(
- IPortPinDMusImpl * This);
+//==================================================================================================================================
+
+
+static
+NTSTATUS
+NTAPI
+IMasterClock_fnQueryInterface(
+ IMasterClock* iface,
+ IN REFIID refiid,
+ OUT PVOID* Output)
+{
+ IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface,
IPortPinDMusImpl, lpVtblMasterClock);
+
+ DPRINT("IServiceSink_fnQueryInterface entered\n");
+
+ if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
+ {
+ *Output = &This->lpVtblServiceSink;
+ InterlockedIncrement(&This->ref);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+static
+ULONG
+NTAPI
+IMasterClock_fnAddRef(
+ IMasterClock* iface)
+{
+ IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface,
IPortPinDMusImpl, lpVtblMasterClock);
+ DPRINT("IServiceSink_fnAddRef entered\n");
+
+ return InterlockedIncrement(&This->ref);
+}
+
+static
+ULONG
+NTAPI
+IMasterClock_fnRelease(
+ IMasterClock* iface)
+{
+ IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface,
IPortPinDMusImpl, lpVtblMasterClock);
+
+ InterlockedDecrement(&This->ref);
+
+ DPRINT("IServiceSink_fnRelease entered %u\n", This->ref);
+
+ if (This->ref == 0)
+ {
+ FreeItem(This, TAG_PORTCLASS);
+ return 0;
+ }
+ /* Return new reference count */
+ return This->ref;
+}
+
+static
+NTSTATUS
+NTAPI
+IMasterClock_fnGetTime(
+ IMasterClock* iface,
+ OUT REFERENCE_TIME *prtTime)
+{
+ UNIMPLEMENTED
+ return STATUS_SUCCESS;
+}
+
+static IMasterClockVtbl vt_IMasterClock =
+{
+ IMasterClock_fnQueryInterface,
+ IMasterClock_fnAddRef,
+ IMasterClock_fnRelease,
+ IMasterClock_fnGetTime
+};
+
+//==================================================================================================================================
+
+
+static
+NTSTATUS
+NTAPI
+IAllocatorMXF_fnQueryInterface(
+ IAllocatorMXF* iface,
+ IN REFIID refiid,
+ OUT PVOID* Output)
+{
+ IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface,
IPortPinDMusImpl, lpVtblAllocatorMXF);
+
+ DPRINT("IServiceSink_fnQueryInterface entered\n");
+
+ if (IsEqualGUIDAligned(refiid, &IID_IAllocatorMXF) ||
+ IsEqualGUIDAligned(refiid, &IID_IUnknown))
+ {
+ *Output = &This->lpVtblServiceSink;
+ InterlockedIncrement(&This->ref);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+static
+ULONG
+NTAPI
+IAllocatorMXF_fnAddRef(
+ IAllocatorMXF* iface)
+{
+ IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface,
IPortPinDMusImpl, lpVtblAllocatorMXF);
+ DPRINT("IServiceSink_fnAddRef entered\n");
+
+ return InterlockedIncrement(&This->ref);
+}
+
+static
+ULONG
+NTAPI
+IAllocatorMXF_fnRelease(
+ IAllocatorMXF* iface)
+{
+ IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface,
IPortPinDMusImpl, lpVtblAllocatorMXF);
+
+ InterlockedDecrement(&This->ref);
+
+ DPRINT("IServiceSink_fnRelease entered %u\n", This->ref);
+
+ if (This->ref == 0)
+ {
+ FreeItem(This, TAG_PORTCLASS);
+ return 0;
+ }
+ /* Return new reference count */
+ return This->ref;
+}
+
+static
+NTSTATUS
+NTAPI
+IAllocatorMXF_fnGetMessage(
+ IAllocatorMXF* iface,
+ OUT PDMUS_KERNEL_EVENT * ppDMKEvt)
+{
+ PVOID Buffer;
+ IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface,
IPortPinDMusImpl, lpVtblAllocatorMXF);
+
+ Buffer = ExAllocateFromNPagedLookasideList(&This->LookAsideEvent);
+ if (!Buffer)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ *ppDMKEvt = Buffer;
+ RtlZeroMemory(Buffer, sizeof(DMUS_KERNEL_EVENT));
+ return STATUS_SUCCESS;
+}
+
+static
+USHORT
+NTAPI
+IAllocatorMXF_fnGetBufferSize(
+ IAllocatorMXF* iface)
+{
+ return PAGE_SIZE;
+}
+
+static
+NTSTATUS
+NTAPI
+IAllocatorMXF_fnGetBuffer(
+ IAllocatorMXF* iface,
+ OUT PBYTE * ppBuffer)
+{
+ PVOID Buffer;
+ IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface,
IPortPinDMusImpl, lpVtblAllocatorMXF);
+
+ Buffer = ExAllocateFromNPagedLookasideList(&This->LookAsideBuffer);
+ if (!Buffer)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ *ppBuffer = Buffer;
+ RtlZeroMemory(Buffer, PAGE_SIZE);
+ return STATUS_SUCCESS;
+}
+
+static
+NTSTATUS
+NTAPI
+IAllocatorMXF_fnPutBuffer(
+ IAllocatorMXF* iface,
+ IN PBYTE pBuffer)
+{
+ PDMUS_KERNEL_EVENT_WITH_TAG Event = (PDMUS_KERNEL_EVENT_WITH_TAG)pBuffer;
+ IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface,
IPortPinDMusImpl, lpVtblAllocatorMXF);
+
+ This->IrpQueue->lpVtbl->ReleaseMappingWithTag(This->IrpQueue,
Event->Tag);
+
+ ExFreeToNPagedLookasideList(&This->LookAsideBuffer, pBuffer);
+ return STATUS_SUCCESS;
+}
+
+static
+NTSTATUS
+NTAPI
+IAllocatorMXF_fnSetState(
+ IAllocatorMXF* iface,
+ IN KSSTATE State)
+{
+ UNIMPLEMENTED
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static
+NTSTATUS
+NTAPI
+IAllocatorMXF_fnPutMessage(
+ IAllocatorMXF* iface,
+ IN PDMUS_KERNEL_EVENT pDMKEvt)
+{
+ IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface,
IPortPinDMusImpl, lpVtblAllocatorMXF);
+
+ ExFreeToNPagedLookasideList(&This->LookAsideEvent, pDMKEvt);
+ return STATUS_SUCCESS;
+}
+
+static
+NTSTATUS
+NTAPI
+IAllocatorMXF_fnConnectOutput(
+ IAllocatorMXF* iface,
+ IN PMXF sinkMXF)
+{
+ UNIMPLEMENTED
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static
+NTSTATUS
+NTAPI
+IAllocatorMXF_fnDisconnectOutput(
+ IAllocatorMXF* iface,
+ IN PMXF sinkMXF)
+{
+ UNIMPLEMENTED
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+static IAllocatorMXFVtbl vt_IAllocatorMXF =
+{
+ IAllocatorMXF_fnQueryInterface,
+ IAllocatorMXF_fnAddRef,
+ IAllocatorMXF_fnRelease,
+ IAllocatorMXF_fnSetState,
+ IAllocatorMXF_fnPutMessage,
+ IAllocatorMXF_fnConnectOutput,
+ IAllocatorMXF_fnDisconnectOutput,
+ IAllocatorMXF_fnGetMessage,
+ IAllocatorMXF_fnGetBufferSize,
+ IAllocatorMXF_fnGetBuffer,
+ IAllocatorMXF_fnPutBuffer
+};
//==================================================================================================================================
@@ -110,6 +378,8 @@
/* Return new reference count */
return This->ref;
}
+
+
static
VOID
NTAPI
@@ -118,8 +388,9 @@
IN PVOID Context)
{
IPortPinDMusImpl * This;
+ KSSTATE State;
+ NTSTATUS Status;
PSETSTREAM_CONTEXT Ctx = (PSETSTREAM_CONTEXT)Context;
- KSSTATE State;
This = Ctx->Pin;
State = Ctx->State;
@@ -132,9 +403,18 @@
return;
/* Set the state */
- if (NT_SUCCESS(This->MidiStream->lpVtbl->SetState(This->MidiStream,
State)))
- {
- /* Set internal state to stop */
+ if (This->MidiStream)
+ {
+ Status = This->MidiStream->lpVtbl->SetState(This->MidiStream,
State);
+ }
+ else
+ {
+ Status = This->Mxf->lpVtbl->SetState(This->Mxf, State);
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ /* Set internal state to requested state */
This->State = State;
if (This->State == KSSTATE_STOP)
@@ -237,6 +517,59 @@
}
+VOID
+TransferMidiDataToDMus(
+ IPortPinDMusImpl * This)
+{
+ NTSTATUS Status;
+ PHYSICAL_ADDRESS PhysicalAddress;
+ ULONG BufferSize, Flags;
+ PVOID Buffer;
+ PDMUS_KERNEL_EVENT_WITH_TAG Event, LastEvent = NULL, Root = NULL;
+
+ do
+ {
+ This->LastTag++;
+ Status = This->IrpQueue->lpVtbl->GetMappingWithTag(This->IrpQueue,
UlongToPtr(This->LastTag), &PhysicalAddress, &Buffer, &BufferSize,
&Flags);
+ if (!NT_SUCCESS(Status))
+ {
+ break;
+ }
+
+ Status =
IAllocatorMXF_fnGetMessage((IAllocatorMXF*)&This->lpVtblAllocatorMXF,
(PDMUS_KERNEL_EVENT*)&Event);
+ if (!NT_SUCCESS(Status))
+ break;
+
+ //FIXME
+ //set up struct
+ //Event->Event.usFlags = DMUS_KEF_EVENT_COMPLETE;
+ Event->Event.cbStruct = sizeof(DMUS_KERNEL_EVENT);
+ Event->Event.cbEvent = BufferSize;
+ Event->Event.uData.pbData = Buffer;
+
+
+ if (!Root)
+ Root = Event;
+ else
+ LastEvent->Event.pNextEvt = (struct _DMUS_KERNEL_EVENT *)Event;
+
+ LastEvent = Event;
+ LastEvent->Event.pNextEvt = NULL;
+ LastEvent->Tag = UlongToPtr(This->LastTag);
+
+ }while(TRUE);
+
+ if (!Root)
+ {
+ SetStreamState(This, KSSTATE_STOP);
+ return;
+ }
+
+ Status = This->Mxf->lpVtbl->PutMessage(This->Mxf,
(PDMUS_KERNEL_EVENT)Root);
+ DPRINT("Status %x\n", Status);
+}
+
+
static
VOID
NTAPI
@@ -251,8 +584,10 @@
{
TransferMidiData(This);
}
-
-
+ else if (This->Mxf)
+ {
+ TransferMidiDataToDMus(This);
+ }
}
static IServiceSinkVtbl vt_IServiceSink =
@@ -486,7 +821,7 @@
PCLOSESTREAM_CONTEXT Ctx;
IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
- if (This->MidiStream)
+ if (This->MidiStream || This->Mxf)
{
Ctx = AllocateItem(NonPagedPool, sizeof(CLOSESTREAM_CONTEXT), TAG_PORTCLASS);
if (!Ctx)
@@ -756,6 +1091,38 @@
if (!NT_SUCCESS(Status))
return Status;
+ }
+ else
+ {
+ Status = This->Miniport->lpVtbl->NewStream(This->Miniport,
+ &This->Mxf,
+ NULL,
+ NonPagedPool,
+ ConnectDetails->PinId,
+ Capture, //FIXME
+ This->Format,
+ &This->ServiceGroup,
+
(PAllocatorMXF)&This->lpVtblAllocatorMXF,
+
(PMASTERCLOCK)&This->lpVtblMasterClock,
+ &This->SchedulePreFetch);
+
+ DPRINT("IPortPinDMus_fnInit Status %x\n", Status);
+
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ if (Capture == DMUS_STREAM_MIDI_CAPTURE)
+ {
+ Status = This->Mxf->lpVtbl->ConnectOutput(This->Mxf,
(PMXF)&This->lpVtblMXF);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IMXF_ConnectOutput failed with Status %x\n", Status);
+ return Status;
+ }
+ }
+
+ ExInitializeNPagedLookasideList(&This->LookAsideEvent, NULL, NULL, 0,
sizeof(DMUS_KERNEL_EVENT_WITH_TAG), TAG_PORTCLASS, 0);
+ ExInitializeNPagedLookasideList(&This->LookAsideBuffer, NULL, NULL, 0,
PAGE_SIZE, TAG_PORTCLASS, 0);
}
if (This->ServiceGroup)
@@ -832,6 +1199,8 @@
This->ref = 1;
This->lpVtbl = &vt_IPortPinDMus;
This->lpVtblServiceSink = &vt_IServiceSink;
+ This->lpVtblMasterClock = &vt_IMasterClock;
+ This->lpVtblAllocatorMXF = &vt_IAllocatorMXF;
/* store result */
@@ -839,6 +1208,3 @@
return STATUS_SUCCESS;
}
-
-
-