Author: janderwald
Date: Wed Dec 8 19:49:28 2010
New Revision: 49990
URL:
http://svn.reactos.org/svn/reactos?rev=49990&view=rev
Log:
[AUDIO-BRINGUP]
- Implement MixerEvent callback in wdmaud.drv
- Comment out assert which is hit in VmWare
- Implement full support mux controls
Modified:
branches/audio-bringup/dll/win32/wdmaud.drv/mmixer.c
branches/audio-bringup/lib/drivers/sound/mmixer/controls.c
branches/audio-bringup/lib/drivers/sound/mmixer/mixer.c
branches/audio-bringup/lib/drivers/sound/mmixer/mmixer.h
branches/audio-bringup/lib/drivers/sound/mmixer/priv.h
branches/audio-bringup/lib/drivers/sound/mmixer/sup.c
branches/audio-bringup/lib/drivers/sound/mmixer/topology.c
Modified: branches/audio-bringup/dll/win32/wdmaud.drv/mmixer.c
URL:
http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/wdmaud.…
==============================================================================
--- branches/audio-bringup/dll/win32/wdmaud.drv/mmixer.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/wdmaud.drv/mmixer.c [iso-8859-1] Wed Dec 8 19:49:28
2010
@@ -663,6 +663,25 @@
return MMSYSERR_NOTSUPPORTED;
}
+VOID
+CALLBACK
+MixerEventCallback(
+ IN PVOID MixerEventContext,
+ IN HANDLE hMixer,
+ IN ULONG NotificationType,
+ IN ULONG Value)
+{
+ PSOUND_DEVICE_INSTANCE Instance = (PSOUND_DEVICE_INSTANCE)MixerEventContext;
+
+ DriverCallback(Instance->WinMM.ClientCallback,
+ HIWORD(Instance->WinMM.Flags),
+ Instance->WinMM.Handle,
+ NotificationType,
+ Instance->WinMM.ClientCallbackInstanceData,
+ (DWORD_PTR)Value,
+ 0);
+}
+
MMRESULT
WdmAudSetMixerDeviceFormatByMMixer(
IN PSOUND_DEVICE_INSTANCE Instance,
@@ -670,11 +689,7 @@
IN PWAVEFORMATEX WaveFormat,
IN DWORD WaveFormatSize)
{
- Instance->hNotifyEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
- if ( ! Instance->hNotifyEvent )
- return MMSYSERR_NOMEM;
-
- if (MMixerOpen(&MixerContext, DeviceId, Instance->hNotifyEvent, NULL /* FIXME
*/, &Instance->Handle) == MM_STATUS_SUCCESS)
+ if (MMixerOpen(&MixerContext, DeviceId, (PVOID)Instance, MixerEventCallback,
&Instance->Handle) == MM_STATUS_SUCCESS)
return MMSYSERR_NOERROR;
return MMSYSERR_BADDEVICEID;
Modified: branches/audio-bringup/lib/drivers/sound/mmixer/controls.c
URL:
http://svn.reactos.org/svn/reactos/branches/audio-bringup/lib/drivers/sound…
==============================================================================
--- branches/audio-bringup/lib/drivers/sound/mmixer/controls.c [iso-8859-1] (original)
+++ branches/audio-bringup/lib/drivers/sound/mmixer/controls.c [iso-8859-1] Wed Dec 8
19:49:28 2010
@@ -1570,7 +1570,7 @@
DPRINT("MixerName %S Available PinID %lu\n", MixerData->DeviceName,
Index);
/* sanity check */
- ASSERT(MixerData->MixerInfo);
+ //ASSERT(MixerData->MixerInfo);
if (!MixerData->MixerInfo)
{
@@ -1730,7 +1730,7 @@
/* initialize notification entry */
EventData->MixerEventContext = MixerEventContext;
- EventData->MixerEventRoutine;
+ EventData->MixerEventRoutine = MixerEventRoutine;
/* store event */
InsertTailList(&MixerInfo->EventList, &EventData->Entry);
Modified: branches/audio-bringup/lib/drivers/sound/mmixer/mixer.c
URL:
http://svn.reactos.org/svn/reactos/branches/audio-bringup/lib/drivers/sound…
==============================================================================
--- branches/audio-bringup/lib/drivers/sound/mmixer/mixer.c [iso-8859-1] (original)
+++ branches/audio-bringup/lib/drivers/sound/mmixer/mixer.c [iso-8859-1] Wed Dec 8
19:49:28 2010
@@ -108,7 +108,6 @@
/* store result */
*MixerHandle = (HANDLE)MixerInfo;
-
return MM_STATUS_SUCCESS;
}
@@ -243,7 +242,7 @@
if (!MixerLineSrc)
{
/* invalid parameter */
- DPRINT1("MMixerGetLineInfo: MixerName %S Line not found %lu\n",
MixerInfo->MixCaps.szPname, MixerLine->dwLineID);
+ DPRINT1("MMixerGetLineInfo: MixerName %S Line not found 0x%lx\n",
MixerInfo->MixCaps.szPname, MixerLine->dwLineID);
return MM_STATUS_INVALID_PARAMETER;
}
@@ -519,8 +518,10 @@
case MIXERCONTROL_CONTROLTYPE_VOLUME:
Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo, NodeId,
TRUE, MixerControl, MixerControlDetails, MixerLine);
break;
+ case MIXERCONTROL_CONTROLTYPE_MUX:
+ Status = MMixerSetGetMuxControlDetails(MixerContext, MixerInfo, NodeId, TRUE,
Flags, MixerControl, MixerControlDetails, MixerLine);
+ break;
default:
- ASSERT(0);
Status = MM_STATUS_NOT_IMPLEMENTED;
}
@@ -583,9 +584,16 @@
case MIXERCONTROL_CONTROLTYPE_VOLUME:
Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo, NodeId,
FALSE, MixerControl, MixerControlDetails, MixerLine);
break;
+ case MIXERCONTROL_CONTROLTYPE_ONOFF:
+ DPRINT1("Not Implemented MIXERCONTROL_CONTROLTYPE_ONOFF\n");
+ break;
+ case MIXERCONTROL_CONTROLTYPE_MUX:
+ Status = MMixerSetGetMuxControlDetails(MixerContext, MixerInfo, NodeId,
FALSE, Flags, MixerControl, MixerControlDetails, MixerLine);
+ break;
+
default:
Status = MM_STATUS_NOT_IMPLEMENTED;
- DPRINT1("ControlType %lu not implemented\n",
MixerControl->Control.dwControlType);
+ DPRINT1("ControlType %lx not implemented\n",
MixerControl->Control.dwControlType);
}
return Status;
Modified: branches/audio-bringup/lib/drivers/sound/mmixer/mmixer.h
URL:
http://svn.reactos.org/svn/reactos/branches/audio-bringup/lib/drivers/sound…
==============================================================================
--- branches/audio-bringup/lib/drivers/sound/mmixer/mmixer.h [iso-8859-1] (original)
+++ branches/audio-bringup/lib/drivers/sound/mmixer/mmixer.h [iso-8859-1] Wed Dec 8
19:49:28 2010
@@ -47,7 +47,7 @@
typedef MIXER_STATUS(*PMIXER_CLOSEKEY)(
IN HANDLE hKey);
-typedef VOID (*PMIXER_EVENT)(
+typedef VOID (CALLBACK *PMIXER_EVENT)(
IN PVOID MixerEventContext,
IN HANDLE hMixer,
IN ULONG NotificationType,
Modified: branches/audio-bringup/lib/drivers/sound/mmixer/priv.h
URL:
http://svn.reactos.org/svn/reactos/branches/audio-bringup/lib/drivers/sound…
==============================================================================
--- branches/audio-bringup/lib/drivers/sound/mmixer/priv.h [iso-8859-1] (original)
+++ branches/audio-bringup/lib/drivers/sound/mmixer/priv.h [iso-8859-1] Wed Dec 8
19:49:28 2010
@@ -302,6 +302,18 @@
LPMIXERLINE_EXT MixerLine);
MIXER_STATUS
+MMixerSetGetMuxControlDetails(
+ IN PMIXER_CONTEXT MixerContext,
+ IN LPMIXER_INFO MixerInfo,
+ IN ULONG NodeId,
+ IN ULONG bSet,
+ IN ULONG Flags,
+ LPMIXERCONTROL_EXT MixerControl,
+ IN LPMIXERCONTROLDETAILS MixerControlDetails,
+ LPMIXERLINE_EXT MixerLine);
+
+
+MIXER_STATUS
MMixerSetGetControlDetails(
IN PMIXER_CONTEXT MixerContext,
IN HANDLE hMixer,
@@ -507,3 +519,9 @@
IN PTOPOLOGY Topology,
OUT PULONG PinCount);
+VOID
+MMixerGetConnectedFromLogicalTopologyPins(
+ IN PTOPOLOGY Topology,
+ IN ULONG NodeIndex,
+ OUT PULONG OutPinCount,
+ OUT PULONG OutPins);
Modified: branches/audio-bringup/lib/drivers/sound/mmixer/sup.c
URL:
http://svn.reactos.org/svn/reactos/branches/audio-bringup/lib/drivers/sound…
==============================================================================
--- branches/audio-bringup/lib/drivers/sound/mmixer/sup.c [iso-8859-1] (original)
+++ branches/audio-bringup/lib/drivers/sound/mmixer/sup.c [iso-8859-1] Wed Dec 8 19:49:28
2010
@@ -54,6 +54,63 @@
return MM_STATUS_SUCCESS;
}
+LPMIXERLINE_EXT
+MMixerGetMixerLineContainingNodeId(
+ IN LPMIXER_INFO MixerInfo,
+ IN ULONG NodeID)
+{
+ PLIST_ENTRY Entry, ControlEntry;
+ LPMIXERLINE_EXT MixerLineSrc;
+ LPMIXERCONTROL_EXT MixerControl;
+
+ /* get first entry */
+ Entry = MixerInfo->LineList.Flink;
+
+ while(Entry != &MixerInfo->LineList)
+ {
+ MixerLineSrc = (LPMIXERLINE_EXT)CONTAINING_RECORD(Entry, MIXERLINE_EXT, Entry);
+
+ ControlEntry = MixerLineSrc->ControlsList.Flink;
+ while(ControlEntry != &MixerLineSrc->ControlsList)
+ {
+ MixerControl = (LPMIXERCONTROL_EXT)CONTAINING_RECORD(ControlEntry,
MIXERCONTROL_EXT, Entry);
+ if (MixerControl->NodeID == NodeID)
+ {
+ return MixerLineSrc;
+ }
+ ControlEntry = ControlEntry->Flink;
+ }
+ Entry = Entry->Flink;
+ }
+
+ return NULL;
+}
+
+VOID
+MMixerGetLowestLogicalTopologyPinOffsetFromArray(
+ IN ULONG LogicalPinArrayCount,
+ IN PULONG LogicalPinArray,
+ OUT PULONG PinOffset)
+{
+ ULONG Index;
+ ULONG LowestId = 0;
+
+ for(Index = 1; Index < LogicalPinArrayCount; Index++)
+ {
+ if (LogicalPinArray[Index] != MAXULONG)
+ {
+ /* sanity check: logical pin id must be unique */
+ ASSERT(LogicalPinArray[Index] != LogicalPinArray[LowestId]);
+ }
+
+ if (LogicalPinArray[Index] < LogicalPinArray[LowestId])
+ LowestId = Index;
+ }
+
+ /* store result */
+ *PinOffset = LowestId;
+}
+
VOID
MMixerFreeMixerInfo(
IN PMIXER_CONTEXT MixerContext,
@@ -66,6 +123,38 @@
MixerContext->Free((PVOID)MixerInfo);
}
+
+
+LPMIXER_DATA
+MMixerGetMixerDataByDeviceHandle(
+ IN PMIXER_CONTEXT MixerContext,
+ IN HANDLE hDevice)
+{
+ LPMIXER_DATA MixerData;
+ PLIST_ENTRY Entry;
+ PMIXER_LIST MixerList;
+
+ /* get mixer list */
+ MixerList = (PMIXER_LIST)MixerContext->MixerContext;
+
+ if (!MixerList->MixerDataCount)
+ return NULL;
+
+ Entry = MixerList->MixerData.Flink;
+
+ while(Entry != &MixerList->MixerData)
+ {
+ MixerData = (LPMIXER_DATA)CONTAINING_RECORD(Entry, MIXER_DATA, Entry);
+
+ if (MixerData->hDevice == hDevice)
+ return MixerData;
+
+ /* move to next mixer entry */
+ Entry = Entry->Flink;
+ }
+ return NULL;
+}
+
LPMIXER_INFO
MMixerGetMixerInfoByIndex(
@@ -255,7 +344,7 @@
PLIST_ENTRY Entry;
PEVENT_NOTIFICATION_ENTRY NotificationEntry;
- /* enumerate list and add a notification entry */
+ /* enumerate list and perform notification */
Entry = MixerInfo->EventList.Flink;
while(Entry != &MixerInfo->EventList)
{
@@ -315,6 +404,247 @@
}
return Status;
+}
+
+MIXER_STATUS
+MMixerSetGetMuxControlDetails(
+ IN PMIXER_CONTEXT MixerContext,
+ IN LPMIXER_INFO MixerInfo,
+ IN ULONG NodeId,
+ IN ULONG bSet,
+ IN ULONG Flags,
+ IN LPMIXERCONTROL_EXT MixerControl,
+ IN LPMIXERCONTROLDETAILS MixerControlDetails,
+ IN LPMIXERLINE_EXT MixerLine)
+{
+ MIXER_STATUS Status;
+ PULONG LogicalNodes, ConnectedNodes;
+ ULONG LogicalNodesCount, ConnectedNodesCount, Index, CurLogicalPinOffset,
BytesReturned, OldLogicalPinOffset;
+ LPMIXER_DATA MixerData;
+ LPMIXERCONTROLDETAILS_LISTTEXTW ListText;
+ LPMIXERCONTROLDETAILS_BOOLEAN Values;
+ LPMIXERLINE_EXT SourceLine;
+ KSNODEPROPERTY Request;
+
+ DPRINT("MixerControlDetails %p\n", MixerControlDetails);
+ DPRINT("bSet %lx\n", bSet);
+ DPRINT("Flags %lx\n", Flags);
+ DPRINT("NodeId %lu\n", MixerControl->NodeID);
+ DPRINT("MixerControlDetails dwControlID %lu\n",
MixerControlDetails->dwControlID);
+ DPRINT("MixerControlDetails cChannels %lu\n",
MixerControlDetails->cChannels);
+ DPRINT("MixerControlDetails cMultipleItems %lu\n",
MixerControlDetails->cMultipleItems);
+ DPRINT("MixerControlDetails cbDetails %lu\n",
MixerControlDetails->cbDetails);
+ DPRINT("MixerControlDetails paDetails %p\n",
MixerControlDetails->paDetails);
+
+ if (MixerControl->Control.fdwControl & MIXERCONTROL_CONTROLF_UNIFORM)
+ {
+ /* control acts uniform */
+ if (MixerControlDetails->cChannels != 1)
+ {
+ /* expected 1 channel */
+ DPRINT1("Expected 1 channel but got %lu\n",
MixerControlDetails->cChannels);
+ return MM_STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ /* check if multiple items match */
+ if (MixerControlDetails->cMultipleItems !=
MixerControl->Control.cMultipleItems)
+ {
+ DPRINT1("MultipleItems mismatch %lu expected %lu\n",
MixerControlDetails->cMultipleItems, MixerControl->Control.cMultipleItems);
+ return MM_STATUS_UNSUCCESSFUL;
+ }
+
+ if (bSet)
+ {
+ if ((Flags & MIXER_SETCONTROLDETAILSF_QUERYMASK) ==
MIXER_SETCONTROLDETAILSF_CUSTOM)
+ {
+ /* tell me when this is hit */
+ ASSERT(FALSE);
+ }
+ else if ((Flags & (MIXER_SETCONTROLDETAILSF_VALUE |
MIXER_SETCONTROLDETAILSF_CUSTOM)) == MIXER_SETCONTROLDETAILSF_VALUE)
+ {
+ /* sanity check */
+ ASSERT(bSet == TRUE);
+ ASSERT(MixerControlDetails->cbDetails ==
sizeof(MIXERCONTROLDETAILS_BOOLEAN));
+
+ Values = (LPMIXERCONTROLDETAILS_BOOLEAN)MixerControlDetails->paDetails;
+ CurLogicalPinOffset = MAXULONG;
+ for(Index = 0; Index < MixerControlDetails->cMultipleItems; Index++)
+ {
+ if (Values[Index].fValue)
+ {
+ /* mux can only activate one line at a time */
+ ASSERT(CurLogicalPinOffset == MAXULONG);
+ CurLogicalPinOffset = Index;
+ }
+ }
+
+ /* setup request */
+ Request.NodeId = NodeId;
+ Request.Reserved = 0;
+ Request.Property.Flags = KSPROPERTY_TYPE_TOPOLOGY | KSPROPERTY_TYPE_GET;
+ Request.Property.Id = KSPROPERTY_AUDIO_MUX_SOURCE;
+ Request.Property.Set = KSPROPSETID_Audio;
+
+ /* perform getting source */
+ Status = MixerContext->Control(MixerControl->hDevice,
IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSNODEPROPERTY), &OldLogicalPinOffset,
sizeof(ULONG), &BytesReturned);
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ /* failed to get source */
+ return Status;
+ }
+
+ DPRINT("OldLogicalPinOffset %lu CurLogicalPinOffset %lu\n",
OldLogicalPinOffset, CurLogicalPinOffset);
+
+ if (OldLogicalPinOffset == CurLogicalPinOffset)
+ {
+ /* cannot be unselected */
+ return MM_STATUS_UNSUCCESSFUL;
+ }
+
+ /* perform setting source */
+ Request.Property.Flags = KSPROPERTY_TYPE_TOPOLOGY | KSPROPERTY_TYPE_SET;
+ Status = MixerContext->Control(MixerControl->hDevice,
IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSNODEPROPERTY), &CurLogicalPinOffset,
sizeof(ULONG), &BytesReturned);
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ /* failed to set source */
+ return Status;
+ }
+
+ /* notify control change */
+ MMixerNotifyControlChange(MixerContext, MixerInfo, MM_MIXM_CONTROL_CHANGE,
MixerControl->Control.dwControlID );
+
+ return Status;
+ }
+ }
+ else
+ {
+ if ((Flags & MIXER_GETCONTROLDETAILSF_QUERYMASK) ==
MIXER_GETCONTROLDETAILSF_VALUE)
+ {
+ /* setup request */
+ Request.NodeId = NodeId;
+ Request.Reserved = 0;
+ Request.Property.Flags = KSPROPERTY_TYPE_TOPOLOGY | KSPROPERTY_TYPE_GET;
+ Request.Property.Id = KSPROPERTY_AUDIO_MUX_SOURCE;
+ Request.Property.Set = KSPROPSETID_Audio;
+
+ /* perform getting source */
+ Status = MixerContext->Control(MixerControl->hDevice,
IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSNODEPROPERTY), &OldLogicalPinOffset,
sizeof(ULONG), &BytesReturned);
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ /* failed to get source */
+ return Status;
+ }
+
+ /* get logical pin nodes */
+ MMixerGetConnectedFromLogicalTopologyPins(MixerData->Topology,
MixerControl->NodeID, &LogicalNodesCount, LogicalNodes);
+
+ /* sanity check */
+ ASSERT(LogicalNodesCount == MixerControlDetails->cMultipleItems);
+ ASSERT(LogicalNodesCount == MixerControl->Control.Metrics.dwReserved[0]);
+
+ Values = (LPMIXERCONTROLDETAILS_BOOLEAN)MixerControlDetails->paDetails;
+ for(Index = 0; Index < ConnectedNodesCount; Index++)
+ {
+ /* getting logical pin offset */
+ MMixerGetLowestLogicalTopologyPinOffsetFromArray(LogicalNodesCount,
LogicalNodes, &CurLogicalPinOffset);
+
+ if (CurLogicalPinOffset == OldLogicalPinOffset)
+ {
+ /* mark index as active */
+ Values[Index].fValue = TRUE;
+ }
+ else
+ {
+ /* index not active */
+ Values[Index].fValue = FALSE;
+ }
+
+ /* mark offset as consumed */
+ LogicalNodes[CurLogicalPinOffset] = MAXULONG;
+ }
+
+ /* cleanup */
+ MixerContext->Free(LogicalNodes);
+
+ /* done */
+ return MM_STATUS_SUCCESS;
+ }
+ else if ((Flags & MIXER_GETCONTROLDETAILSF_QUERYMASK) ==
MIXER_GETCONTROLDETAILSF_LISTTEXT)
+ {
+ /* sanity check */
+ ASSERT(bSet == FALSE);
+
+ /* gets the corresponding mixer data */
+ MixerData = MMixerGetMixerDataByDeviceHandle(MixerContext,
MixerControl->hDevice);
+
+ /* sanity check */
+ ASSERT(MixerData);
+ ASSERT(MixerData->Topology);
+ ASSERT(MixerData->MixerInfo == MixerInfo);
+
+ /* now allocate logical pin array */
+ Status = MMixerAllocateTopologyNodeArray(MixerContext,
MixerData->Topology, &LogicalNodes);
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ /* no memory */
+ return MM_STATUS_NO_MEMORY;
+ }
+
+ /* allocate connected node array */
+ Status = MMixerAllocateTopologyNodeArray(MixerContext,
MixerData->Topology, &ConnectedNodes);
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ /* no memory */
+ MixerContext->Free(LogicalNodes);
+ return MM_STATUS_NO_MEMORY;
+ }
+
+ /* get logical pin nodes */
+ MMixerGetConnectedFromLogicalTopologyPins(MixerData->Topology,
MixerControl->NodeID, &LogicalNodesCount, LogicalNodes);
+
+ /* get connected nodes */
+ MMixerGetNextNodesFromNodeIndex(MixerContext, MixerData->Topology,
MixerControl->NodeID, TRUE, &ConnectedNodesCount, ConnectedNodes);
+
+ /* sanity check */
+ ASSERT(ConnectedNodesCount == LogicalNodesCount);
+ ASSERT(ConnectedNodesCount == MixerControlDetails->cMultipleItems);
+ ASSERT(ConnectedNodesCount ==
MixerControl->Control.Metrics.dwReserved[0]);
+
+ ListText =
(LPMIXERCONTROLDETAILS_LISTTEXTW)MixerControlDetails->paDetails;
+
+ for(Index = 0; Index < ConnectedNodesCount; Index++)
+ {
+ /* getting logical pin offset */
+ MMixerGetLowestLogicalTopologyPinOffsetFromArray(LogicalNodesCount,
LogicalNodes, &CurLogicalPinOffset);
+
+ /* get mixer line with that node */
+ SourceLine = MMixerGetMixerLineContainingNodeId(MixerInfo,
ConnectedNodes[CurLogicalPinOffset]);
+
+ /* sanity check */
+ ASSERT(SourceLine);
+
+ DPRINT1("PinOffset %lu LogicalPin %lu NodeId %lu LineName
%S\n", CurLogicalPinOffset, LogicalNodes[CurLogicalPinOffset],
ConnectedNodes[CurLogicalPinOffset], SourceLine->Line.szName);
+
+ /* copy details */
+ ListText[Index].dwParam1 = SourceLine->Line.dwLineID;
+ ListText[Index].dwParam2 = SourceLine->Line.dwComponentType;
+ MixerContext->Copy(ListText[Index].szName, SourceLine->Line.szName,
(wcslen(SourceLine->Line.szName) + 1) * sizeof(WCHAR));
+
+ /* mark offset as consumed */
+ LogicalNodes[CurLogicalPinOffset] = MAXULONG;
+ }
+
+ /* cleanup */
+ MixerContext->Free(LogicalNodes);
+ MixerContext->Free(ConnectedNodes);
+
+ /* done */
+ return MM_STATUS_SUCCESS;
+ }
+ }
+
+ return MM_STATUS_NOT_IMPLEMENTED;
}
MIXER_STATUS
Modified: branches/audio-bringup/lib/drivers/sound/mmixer/topology.c
URL:
http://svn.reactos.org/svn/reactos/branches/audio-bringup/lib/drivers/sound…
==============================================================================
--- branches/audio-bringup/lib/drivers/sound/mmixer/topology.c [iso-8859-1] (original)
+++ branches/audio-bringup/lib/drivers/sound/mmixer/topology.c [iso-8859-1] Wed Dec 8
19:49:28 2010
@@ -1162,6 +1162,32 @@
return MM_STATUS_SUCCESS;
}
+VOID
+MMixerGetConnectedFromLogicalTopologyPins(
+ IN PTOPOLOGY Topology,
+ IN ULONG NodeIndex,
+ OUT PULONG OutPinCount,
+ OUT PULONG OutPins)
+{
+ ULONG Index;
+ PTOPOLOGY_NODE Node;
+
+ /* sanity check */
+ ASSERT(NodeIndex < Topology->TopologyNodesCount);
+
+ /* get node */
+ Node = &Topology->TopologyNodes[NodeIndex];
+
+ for(Index = 0; Index < Node->NodeConnectedFromCount; Index++)
+ {
+ /* copy logical pin id */
+ OutPins[Index] = Node->LogicalPinNodeConnectedFrom[Index];
+ }
+
+ /* store pin count */
+ *OutPinCount = Node->NodeConnectedFromCount;
+}
+
LPGUID
MMixerGetNodeTypeFromTopology(
IN PTOPOLOGY Topology,