[AUDIO-BRINGUP]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Tue, 7 Dec 2010 10:29:57 +0000 (10:29 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Tue, 7 Dec 2010 10:29:57 +0000 (10:29 +0000)
- Fix error message when mmixer library has failed to initialize
- Remove device handle from MIXER_INFO as a mixer can span over more than one device (i.e. mixer, wave)
- Add device handle to mixer control struct
- Store mixer controls in list than in array. Will later be used to add hacks (i.e wave line must have volume controls etc)
- Add reserved member to topology pin struct and mark used pins as reserved. It is then used to add alternative mixers destination lines

svn path=/branches/audio-bringup/; revision=49967

dll/win32/wdmaud.drv/wdmaud.c
dll/win32/wdmaud.drv/wdmaud.h
lib/drivers/sound/mmixer/controls.c
lib/drivers/sound/mmixer/mixer.c
lib/drivers/sound/mmixer/priv.h
lib/drivers/sound/mmixer/sup.c
lib/drivers/sound/mmixer/topology.c

index 8cb69ea..820c77f 100644 (file)
@@ -111,7 +111,6 @@ DriverProc(
     {
         case DRV_LOAD :
         {
-            HANDLE Handle;
             MMRESULT Result;
             SND_TRACE(L"DRV_LOAD\n");
 
@@ -120,11 +119,11 @@ DriverProc(
             if ( ! MMSUCCESS(Result) )
                 return 0L;
 
-            Result = WdmAudOpenSoundDeviceByMMixer(NULL, &Handle);
+            Result = WdmAudOpenSoundDeviceByMMixer();
 
             if ( Result != MMSYSERR_NOERROR )
             {
-                SND_ERR(L"Failed to open \\\\.\\wdmaud\n");
+                SND_ERR(L"Failed to initialize MMixer Library");
                 //UnlistAllSoundDevices();
 
                 return 0L;
index 49cd74e..8367466 100644 (file)
@@ -57,9 +57,7 @@ WdmAudGetCapabilitiesByMMixer(
     IN  DWORD CapabilitiesSize);
 
 MMRESULT
-WdmAudOpenSoundDeviceByMMixer(
-    IN  struct _SOUND_DEVICE* SoundDevice,
-    OUT PVOID* Handle);
+WdmAudOpenSoundDeviceByMMixer();
 
 MMRESULT
 WdmAudCloseSoundDeviceByMMixer(
index dfa2b53..04a3f9a 100644 (file)
@@ -32,28 +32,42 @@ MIXER_STATUS
 MMixerAddMixerControl(
     IN PMIXER_CONTEXT MixerContext,
     IN LPMIXER_INFO MixerInfo,
+    IN HANDLE hMixer,
     IN PTOPOLOGY Topology,
     IN ULONG NodeIndex,
-    IN LPMIXERLINE_EXT MixerLine,
-    OUT LPMIXERCONTROLW MixerControl)
+    IN LPMIXERLINE_EXT MixerLine)
 {
     LPGUID NodeType;
     KSP_NODE Node;
     ULONG BytesReturned;
     MIXER_STATUS Status;
     LPWSTR Name;
+    LPMIXERCONTROL_EXT MixerControl;
+
+    /* allocate mixer control */
+    MixerControl = MixerContext->Alloc(sizeof(MIXERCONTROL_EXT));
+    if (!MixerControl)
+    {
+        /* no memory */
+        return MM_STATUS_NO_MEMORY;
+    }
+
 
     /* initialize mixer control */
-    MixerControl->cbStruct = sizeof(MIXERCONTROLW);
-    MixerControl->dwControlID = MixerInfo->ControlId;
+    MixerControl->hDevice = hMixer;
+    MixerControl->NodeID = NodeIndex;
+    MixerControl->ExtraData = NULL;
+
+    MixerControl->Control.cbStruct = sizeof(MIXERCONTROLW);
+    MixerControl->Control.dwControlID = MixerInfo->ControlId;
 
     /* get node type */
     NodeType = MMixerGetNodeTypeFromTopology(Topology, NodeIndex);
     /* store control type */
-    MixerControl->dwControlType = MMixerGetControlTypeFromTopologyNode(NodeType);
+    MixerControl->Control.dwControlType = MMixerGetControlTypeFromTopologyNode(NodeType);
 
-    MixerControl->fdwControl = MIXERCONTROL_CONTROLF_UNIFORM; /* FIXME */
-    MixerControl->cMultipleItems = 0;
+    MixerControl->Control.fdwControl = MIXERCONTROL_CONTROLF_UNIFORM; /* FIXME */
+    MixerControl->Control.cMultipleItems = 0;
 
     /* setup request to retrieve name */
     Node.NodeId = NodeIndex;
@@ -63,7 +77,7 @@ MMixerAddMixerControl(
     Node.Reserved = 0;
 
     /* get node name size */
-    Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), NULL, 0, &BytesReturned);
+    Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), NULL, 0, &BytesReturned);
 
     if (Status == MM_STATUS_MORE_ENTRIES)
     {
@@ -76,24 +90,28 @@ MMixerAddMixerControl(
         }
 
         /* get node name */
-        Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), (LPVOID)Name, BytesReturned, &BytesReturned);
+        Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Node, sizeof(KSP_NODE), (LPVOID)Name, BytesReturned, &BytesReturned);
 
         if (Status == MM_STATUS_SUCCESS)
         {
-            MixerContext->Copy(MixerControl->szShortName, Name, (min(MIXER_SHORT_NAME_CHARS, wcslen(Name)+1)) * sizeof(WCHAR));
-            MixerControl->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
+            MixerContext->Copy(MixerControl->Control.szShortName, Name, (min(MIXER_SHORT_NAME_CHARS, wcslen(Name)+1)) * sizeof(WCHAR));
+            MixerControl->Control.szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
 
-            MixerContext->Copy(MixerControl->szName, Name, (min(MIXER_LONG_NAME_CHARS, wcslen(Name)+1)) * sizeof(WCHAR));
-            MixerControl->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
+            MixerContext->Copy(MixerControl->Control.szName, Name, (min(MIXER_LONG_NAME_CHARS, wcslen(Name)+1)) * sizeof(WCHAR));
+            MixerControl->Control.szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
         }
 
         /* free name buffer */
         MixerContext->Free(Name);
     }
 
+    /* increment control count */
     MixerInfo->ControlId++;
 
-    if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_MUX)
+    /* insert control */
+    InsertTailList(&MixerLine->ControlsList, &MixerControl->Entry);
+
+    if (MixerControl->Control.dwControlType == MIXERCONTROL_CONTROLTYPE_MUX)
     {
         ULONG NodesCount;
         PULONG Nodes;
@@ -114,24 +132,24 @@ MMixerAddMixerControl(
         MixerContext->Free(Nodes);
 
         /* setup mux bounds */
-        MixerControl->Bounds.dwMinimum = 0;
-        MixerControl->Bounds.dwMaximum = NodesCount - 1;
-        MixerControl->Metrics.dwReserved[0] = NodesCount;
-        MixerControl->cMultipleItems = NodesCount;
-        MixerControl->fdwControl |= MIXERCONTROL_CONTROLF_MULTIPLE;
+        MixerControl->Control.Bounds.dwMinimum = 0;
+        MixerControl->Control.Bounds.dwMaximum = NodesCount - 1;
+        MixerControl->Control.Metrics.dwReserved[0] = NodesCount;
+        MixerControl->Control.cMultipleItems = NodesCount;
+        MixerControl->Control.fdwControl |= MIXERCONTROL_CONTROLF_MULTIPLE;
     }
-    else if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
+    else if (MixerControl->Control.dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
     {
-        MixerControl->Bounds.dwMinimum = 0;
-        MixerControl->Bounds.dwMaximum = 1;
+        MixerControl->Control.Bounds.dwMinimum = 0;
+        MixerControl->Control.Bounds.dwMaximum = 1;
     }
-    else if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_ONOFF)
+    else if (MixerControl->Control.dwControlType == MIXERCONTROL_CONTROLTYPE_ONOFF)
     {
         /* only needs to set bounds */
-        MixerControl->Bounds.dwMinimum = 0;
-        MixerControl->Bounds.dwMaximum = 1;
+        MixerControl->Control.Bounds.dwMinimum = 0;
+        MixerControl->Control.Bounds.dwMaximum = 1;
     }
-    else if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
+    else if (MixerControl->Control.dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
     {
         KSNODEPROPERTY_AUDIO_CHANNEL Property;
         ULONG Length;
@@ -139,9 +157,9 @@ MMixerAddMixerControl(
         PKSPROPERTY_MEMBERSHEADER Members;
         PKSPROPERTY_STEPPING_LONG Range;
 
-        MixerControl->Bounds.dwMinimum = 0;
-        MixerControl->Bounds.dwMaximum = 0xFFFF;
-        MixerControl->Metrics.cSteps = 0xC0; /* FIXME */
+        MixerControl->Control.Bounds.dwMinimum = 0;
+        MixerControl->Control.Bounds.dwMaximum = 0xFFFF;
+        MixerControl->Control.Metrics.cSteps = 0xC0; /* FIXME */
 
         Length = sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) + sizeof(KSPROPERTY_STEPPING_LONG);
         Desc = (PKSPROPERTY_DESCRIPTION)MixerContext->Alloc(Length);
@@ -156,7 +174,7 @@ MMixerAddMixerControl(
         Property.NodeProperty.Property.Set = KSPROPSETID_Audio;
 
         /* get node volume level info */
-        Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSNODEPROPERTY_AUDIO_CHANNEL), Desc, Length, &BytesReturned);
+        Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSNODEPROPERTY_AUDIO_CHANNEL), Desc, Length, &BytesReturned);
 
         if (Status == MM_STATUS_SUCCESS)
         {
@@ -181,7 +199,7 @@ MMixerAddMixerControl(
                 Steps = MaxRange / Range->SteppingDelta + 1;
 
                 /* store mixer control info there */
-                VolumeData->Header.dwControlID = MixerControl->dwControlID;
+                VolumeData->Header.dwControlID = MixerControl->Control.dwControlID;
                 VolumeData->SignedMaximum = Range->Bounds.SignedMaximum;
                 VolumeData->SignedMinimum = Range->Bounds.SignedMinimum;
                 VolumeData->SteppingDelta = Range->SteppingDelta;
@@ -202,13 +220,13 @@ MMixerAddMixerControl(
                     VolumeData->Values[Index] = Value;
                     Value += Range->SteppingDelta;
                 }
-                InsertTailList(&MixerLine->LineControlsExtraData, &VolumeData->Header.Entry);
+                MixerControl->ExtraData = VolumeData;
            }
        }
        MixerContext->Free(Desc);
     }
 
-    DPRINT("Status %x Name %S\n", Status, MixerControl->szName);
+    DPRINT("Status %x Name %S\n", Status, MixerControl->Control.szName);
     return MM_STATUS_SUCCESS;
 }
 
@@ -259,7 +277,7 @@ MMixerCreateDestinationLine(
     wcscpy(DestinationLine->Line.Target.szPname, MixerInfo->MixCaps.szPname);
 
     /* initialize extra line */
-    InitializeListHead(&DestinationLine->LineControlsExtraData);
+    InitializeListHead(&DestinationLine->ControlsList);
 
     /* insert into mixer info */
     InsertTailList(&MixerInfo->LineList, &DestinationLine->Entry);
@@ -275,6 +293,7 @@ MIXER_STATUS
 MMixerGetPinName(
     IN PMIXER_CONTEXT MixerContext,
     IN LPMIXER_INFO MixerInfo,
+    IN HANDLE hMixer,
     IN ULONG PinId,
     IN OUT LPWSTR * OutBuffer)
 {
@@ -291,7 +310,7 @@ MMixerGetPinName(
     Pin.Property.Id = KSPROPERTY_PIN_NAME;
 
     /* try get pin name size */
-    Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), NULL, 0, &BytesReturned);
+    Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), NULL, 0, &BytesReturned);
 
     /* check if buffer overflowed */
     if (Status == MM_STATUS_MORE_ENTRIES)
@@ -305,7 +324,7 @@ MMixerGetPinName(
         }
 
         /* try get pin name */
-        Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)Buffer, BytesReturned, &BytesReturned);
+        Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)Buffer, BytesReturned, &BytesReturned);
         if (Status != MM_STATUS_SUCCESS)
         {
             /* failed to get pin name */
@@ -326,6 +345,7 @@ MIXER_STATUS
 MMixerBuildMixerDestinationLine(
     IN PMIXER_CONTEXT MixerContext,
     IN OUT LPMIXER_INFO MixerInfo,
+    IN HANDLE hMixer,
     IN ULONG PinId,
     IN ULONG bInput)
 {
@@ -333,7 +353,7 @@ MMixerBuildMixerDestinationLine(
     MIXER_STATUS Status;
 
     /* try get pin name */
-    Status = MMixerGetPinName(MixerContext, MixerInfo, PinId, &PinName);
+    Status = MMixerGetPinName(MixerContext, MixerInfo, hMixer, PinId, &PinName);
     if (Status == MM_STATUS_SUCCESS)
     {
         /* create mixer destination line */
@@ -503,6 +523,7 @@ MIXER_STATUS
 MMixerGetChannelCountEnhanced(
     IN PMIXER_CONTEXT MixerContext,
     IN LPMIXER_INFO MixerInfo,
+    IN HANDLE hMixer,
     IN ULONG NodeId,
     OUT PULONG MaxChannels)
 {
@@ -522,7 +543,7 @@ MMixerGetChannelCountEnhanced(
 
 
     /* get description */
-    Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSP_NODE), (PVOID)&Description, sizeof(KSPROPERTY_DESCRIPTION), &BytesReturned);
+    Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSP_NODE), (PVOID)&Description, sizeof(KSPROPERTY_DESCRIPTION), &BytesReturned);
     if (Status == MM_STATUS_SUCCESS)
     {
         if (Description.DescriptionSize >= sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) && (Description.MembersListCount > 0))
@@ -537,7 +558,7 @@ MMixerGetChannelCountEnhanced(
             }
 
             /* get description */
-            Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSP_NODE), (PVOID)NewDescription, Description.DescriptionSize, &BytesReturned);
+            Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSP_NODE), (PVOID)NewDescription, Description.DescriptionSize, &BytesReturned);
             if (Status == MM_STATUS_SUCCESS)
             {
                 /* get header */
@@ -572,6 +593,7 @@ VOID
 MMixerGetChannelCountLegacy(
     IN PMIXER_CONTEXT MixerContext,
     IN LPMIXER_INFO MixerInfo,
+    IN HANDLE hMixer,
     IN ULONG NodeId,
     OUT PULONG MaxChannels)
 {
@@ -592,7 +614,7 @@ MMixerGetChannelCountLegacy(
     do
     {
         /* get channel volume */
-        Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Channel, sizeof(KSNODEPROPERTY_AUDIO_CHANNEL), (PVOID)&Volume, sizeof(LONG), &BytesReturned);
+        Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Channel, sizeof(KSNODEPROPERTY_AUDIO_CHANNEL), (PVOID)&Volume, sizeof(LONG), &BytesReturned);
         if (Status != MM_STATUS_SUCCESS)
             break;
 
@@ -610,18 +632,19 @@ VOID
 MMixerGetMaxChannelsForNode(
     IN PMIXER_CONTEXT MixerContext,
     IN LPMIXER_INFO MixerInfo,
+    IN HANDLE hMixer,
     IN ULONG NodeId,
     OUT PULONG MaxChannels)
 {
     MIXER_STATUS Status;
 
     /* try to get it enhanced */
-    Status = MMixerGetChannelCountEnhanced(MixerContext, MixerInfo, NodeId, MaxChannels);
+    Status = MMixerGetChannelCountEnhanced(MixerContext, MixerInfo, hMixer, NodeId, MaxChannels);
 
     if (Status != MM_STATUS_SUCCESS)
     {
         /* get it old-fashioned way */
-        MMixerGetChannelCountLegacy(MixerContext, MixerInfo, NodeId, MaxChannels);
+        MMixerGetChannelCountLegacy(MixerContext, MixerInfo, hMixer, NodeId, MaxChannels);
     }
 }
 
@@ -629,6 +652,7 @@ MIXER_STATUS
 MMixerAddMixerControlsToMixerLineByNodeIndexArray(
     IN PMIXER_CONTEXT MixerContext,
     IN LPMIXER_INFO MixerInfo,
+    IN HANDLE hMixer,
     IN PTOPOLOGY Topology,
     IN OUT LPMIXERLINE_EXT DstLine,
     IN ULONG NodesCount,
@@ -639,18 +663,6 @@ MMixerAddMixerControlsToMixerLineByNodeIndexArray(
     LPGUID NodeType;
     ULONG MaxChannels;
 
-    /* store nodes array */
-    DstLine->NodeIds = Nodes;
-
-    /* allocate MIXERCONTROLSW array */
-    DstLine->LineControls = MixerContext->Alloc(NodesCount * sizeof(MIXERCONTROLW));
-
-    if (!DstLine->LineControls)
-    {
-        /* out of memory */
-        return MM_STATUS_NO_MEMORY;
-    }
-
     /* initialize control count */
     Count = 0;
 
@@ -674,16 +686,15 @@ MMixerAddMixerControlsToMixerLineByNodeIndexArray(
         if (IsEqualGUIDAligned(NodeType, &KSNODETYPE_VOLUME))
         {
             /* calculate maximum channel count for node */
-            MMixerGetMaxChannelsForNode(MixerContext, MixerInfo, Nodes[Index], &MaxChannels);
+            MMixerGetMaxChannelsForNode(MixerContext, MixerInfo, hMixer, Nodes[Index], &MaxChannels);
 
             DPRINT("NodeId %lu MaxChannels %lu Line %S Id %lu\n", Nodes[Index], MaxChannels, DstLine->Line.szName, DstLine->Line.dwLineID);
             /* calculate maximum channels */
             DstLine->Line.cChannels = min(DstLine->Line.cChannels, MaxChannels);
         }
 
-
         /* now add the mixer control */
-        Status = MMixerAddMixerControl(MixerContext, MixerInfo, Topology, Nodes[Index], DstLine, &DstLine->LineControls[Count]);
+        Status = MMixerAddMixerControl(MixerContext, MixerInfo, hMixer, Topology, Nodes[Index], DstLine);
 
         if (Status == MM_STATUS_SUCCESS)
         {
@@ -703,6 +714,7 @@ MIXER_STATUS
 MMixerGetComponentAndTargetType(
     IN PMIXER_CONTEXT MixerContext,
     IN OUT LPMIXER_INFO MixerInfo,
+    IN HANDLE hMixer,
     IN ULONG PinId,
     OUT PULONG ComponentType,
     OUT PULONG TargetType)
@@ -717,7 +729,7 @@ MMixerGetComponentAndTargetType(
     PKSPIN_PHYSICALCONNECTION Connection;
 
     /* first dataflow type */
-    Status = MMixerGetPinDataFlowAndCommunication(MixerContext, MixerInfo->hMixer, PinId, &DataFlow, &Communication);
+    Status = MMixerGetPinDataFlowAndCommunication(MixerContext, hMixer, PinId, &DataFlow, &Communication);
 
     if (Status != MM_STATUS_SUCCESS)
     {
@@ -734,7 +746,7 @@ MMixerGetComponentAndTargetType(
 
 
     /* get pin category */
-    Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSP_PIN), &Guid, sizeof(GUID), &BytesReturned);
+    Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSP_PIN), &Guid, sizeof(GUID), &BytesReturned);
     if (Status != MM_STATUS_SUCCESS)
     {
         /* failed to get dataflow */
@@ -742,7 +754,7 @@ MMixerGetComponentAndTargetType(
     }
 
     /* check if it has a physical connection */
-    Status = MMixerGetPhysicalConnection(MixerContext, MixerInfo->hMixer, PinId, &Connection);
+    Status = MMixerGetPhysicalConnection(MixerContext, hMixer, PinId, &Connection);
     if (Status == MM_STATUS_SUCCESS)
     {
         /* pin is a brige pin */
@@ -901,6 +913,7 @@ MIXER_STATUS
 MMixerBuildMixerSourceLine(
     IN PMIXER_CONTEXT MixerContext,
     IN OUT LPMIXER_INFO MixerInfo,
+    IN HANDLE hMixer,
     IN PTOPOLOGY Topology,
     IN ULONG PinId,
     IN ULONG NodesCount,
@@ -914,7 +927,7 @@ MMixerBuildMixerSourceLine(
     ULONG ComponentType, TargetType;
 
     /* get component and target type */
-    Status = MMixerGetComponentAndTargetType(MixerContext, MixerInfo, PinId, &ComponentType, &TargetType);
+    Status = MMixerGetComponentAndTargetType(MixerContext, MixerInfo, hMixer, PinId, &ComponentType, &TargetType);
     if (Status != MM_STATUS_SUCCESS)
     {
         /* failed to get component status */
@@ -936,9 +949,7 @@ MMixerBuildMixerSourceLine(
     ASSERT(DstLine);
 
     /* initialize mixer src line */
-    SrcLine->hDevice = MixerInfo->hMixer;
     SrcLine->PinId = PinId;
-    SrcLine->NodeIds = Nodes;
 
     /* initialize mixer line */
     SrcLine->Line.cbStruct = sizeof(MIXERLINEW);
@@ -955,14 +966,14 @@ MMixerBuildMixerSourceLine(
     SrcLine->Line.Target.wMid = MixerInfo->MixCaps.wMid;
     SrcLine->Line.Target.wPid = MixerInfo->MixCaps.wPid;
     SrcLine->Line.Target.vDriverVersion = MixerInfo->MixCaps.vDriverVersion;
-    InitializeListHead(&SrcLine->LineControlsExtraData);
+    InitializeListHead(&SrcLine->ControlsList);
 
     /* copy name */
     ASSERT(MixerInfo->MixCaps.szPname[MAXPNAMELEN-1] == L'\0');
     wcscpy(SrcLine->Line.Target.szPname, MixerInfo->MixCaps.szPname);
 
     /* get pin name */
-    Status = MMixerGetPinName(MixerContext, MixerInfo, PinId, &PinName);
+    Status = MMixerGetPinName(MixerContext, MixerInfo, hMixer, PinId, &PinName);
 
     if (Status == MM_STATUS_SUCCESS)
     {
@@ -978,7 +989,7 @@ MMixerBuildMixerSourceLine(
     }
 
     /* add the controls to mixer line */
-    Status = MMixerAddMixerControlsToMixerLineByNodeIndexArray(MixerContext, MixerInfo, Topology, SrcLine, NodesCount, Nodes);
+    Status = MMixerAddMixerControlsToMixerLineByNodeIndexArray(MixerContext, MixerInfo, hMixer, Topology, SrcLine, NodesCount, Nodes);
     if (Status != MM_STATUS_SUCCESS)
     {
         /* failed */
@@ -995,6 +1006,7 @@ MIXER_STATUS
 MMixerAddMixerSourceLines(
     IN PMIXER_CONTEXT MixerContext,
     IN OUT LPMIXER_INFO MixerInfo,
+    IN HANDLE hMixer,
     IN PTOPOLOGY Topology,
     IN ULONG DestinationLineID,
     IN ULONG LineTerminator)
@@ -1091,7 +1103,7 @@ MMixerAddMixerSourceLines(
             ULONG TempIndex;
 #endif
             /* now build the mixer source line */
-            Status = MMixerBuildMixerSourceLine(MixerContext, MixerInfo, Topology, PinId, AllPinNodesCount, AllPinNodes, DestinationLineID, &SrcLine);
+            Status = MMixerBuildMixerSourceLine(MixerContext, MixerInfo, hMixer, Topology, PinId, AllPinNodesCount, AllPinNodes, DestinationLineID, &SrcLine);
 
              if (Status == MM_STATUS_SUCCESS)
              {
@@ -1100,6 +1112,10 @@ MMixerAddMixerSourceLines(
 
                  /* increment destination line count */
                  DstLine->Line.cConnections++;
+
+                 /* mark pin as reserved */
+                 MMixerSetTopologyPinReserved(Topology, PinId);
+
 #ifdef MMIXER_DEBUG
                  DPRINT1("Adding PinId %lu AllPinNodesCount %lu to DestinationLine %lu\n", PinId, AllPinNodesCount, DestinationLineID);
                  for(TempIndex = 0; TempIndex < AllPinNodesCount; TempIndex++)
@@ -1124,6 +1140,7 @@ MIXER_STATUS
 MMixerAddMixerControlsToDestinationLine(
     IN PMIXER_CONTEXT MixerContext,
     IN OUT LPMIXER_INFO MixerInfo,
+    IN HANDLE hMixer,
     IN PTOPOLOGY Topology,
     IN ULONG PinId,
     IN ULONG bInput,
@@ -1165,7 +1182,7 @@ MMixerAddMixerControlsToDestinationLine(
     if (NodesCount > 0)
     {
         /* add all nodes as mixer controls to the destination line */
-        Status = MMixerAddMixerControlsToMixerLineByNodeIndexArray(MixerContext, MixerInfo, Topology, DstLine, NodesCount, Nodes);
+        Status = MMixerAddMixerControlsToMixerLineByNodeIndexArray(MixerContext, MixerInfo, hMixer, Topology, DstLine, NodesCount, Nodes);
         if (Status != MM_STATUS_SUCCESS)
         {
             /* failed to add controls */
@@ -1185,6 +1202,7 @@ VOID
 MMixerApplyOutputFilterHack(
     IN PMIXER_CONTEXT MixerContext,
     IN LPMIXER_DATA MixerData,
+    IN HANDLE hMixer,
     IN OUT PULONG PinsCount,
     IN OUT PULONG Pins)
 {
@@ -1195,7 +1213,7 @@ MMixerApplyOutputFilterHack(
     for(Index = 0; Index < *PinsCount; Index++)
     {
         /* check if it has a physical connection */
-        Status = MMixerGetPhysicalConnection(MixerContext, MixerData->hDevice, Pins[Index], &Connection);
+        Status = MMixerGetPhysicalConnection(MixerContext, hMixer, Pins[Index], &Connection);
 
         if (Status == MM_STATUS_SUCCESS)
         {
@@ -1249,16 +1267,6 @@ MMixerHandlePhysicalConnection(
 
     DPRINT1("Name %S, Pin %lu bInput %lu\n", OutConnection->SymbolicLinkName, OutConnection->Pin, bInput);
 
-    if (MixerInfo->hMixer != NULL)
-    {
-         /* dont replace mixer destination handles */
-         DPRINT1("MixerInfo hDevice %p MixerData hDevice %p\n", MixerInfo->hMixer, MixerData->hDevice);
-         ASSERT(MixerInfo->hMixer == MixerData->hDevice);
-    }
-
-    /* store connected mixer handle */
-    MixerInfo->hMixer = MixerData->hDevice;
-
     if (MixerData->Topology == NULL)
     {
         /* construct new topology */
@@ -1278,12 +1286,19 @@ MMixerHandlePhysicalConnection(
         Topology = MixerData->Topology;
     }
 
-    /* allocate pin index array which will hold all referenced pins */
-    Status = MMixerAllocateTopologyPinArray(MixerContext, Topology, &Pins);
-    ASSERT(Status == MM_STATUS_SUCCESS);
+    /* mark pin as consumed */
+    MMixerSetTopologyPinReserved(Topology, OutConnection->Pin);
 
     if (!bInput)
     {
+        /* allocate pin index array which will hold all referenced pins */
+        Status = MMixerAllocateTopologyPinArray(MixerContext, Topology, &Pins);
+        if (Status != MM_STATUS_SUCCESS)
+        {
+            /* failed to create topology */
+            return Status;
+        }
+
         /* the mixer is an output mixer
          * find end pin of the node path
          */
@@ -1305,14 +1320,14 @@ MMixerHandlePhysicalConnection(
          * WorkArround: remove all pin ids which have a physical connection
          * because bridge pins may belong to different render paths
          */
-        MMixerApplyOutputFilterHack(MixerContext, MixerData, &PinsCount, Pins);
+        MMixerApplyOutputFilterHack(MixerContext, MixerData, MixerData->hDevice, &PinsCount, Pins);
 
         /* sanity checks */
         ASSERT(PinsCount != 0);
         ASSERT(PinsCount == 1);
 
         /* create destination line */
-        Status = MMixerBuildMixerDestinationLine(MixerContext, MixerInfo, Pins[0], bInput);
+        Status = MMixerBuildMixerDestinationLine(MixerContext, MixerInfo, MixerData->hDevice, Pins[0], bInput);
 
         /* calculate destination line id */
         DestinationLineID = (DESTINATION_LINE + MixerInfo->MixCaps.cDestinations-1);
@@ -1327,13 +1342,19 @@ MMixerHandlePhysicalConnection(
         }
 
         /* add mixer controls to destination line */
-        Status = MMixerAddMixerControlsToDestinationLine(MixerContext, MixerInfo, Topology, Pins[0], bInput, DestinationLineID,  &LineTerminator);
+        Status = MMixerAddMixerControlsToDestinationLine(MixerContext, MixerInfo, MixerData->hDevice, Topology, Pins[0], bInput, DestinationLineID,  &LineTerminator);
 
         if (Status == MM_STATUS_SUCCESS)
         {
             /* now add the rest of the source lines */
-            Status = MMixerAddMixerSourceLines(MixerContext, MixerInfo, Topology, DestinationLineID, LineTerminator);
+            Status = MMixerAddMixerSourceLines(MixerContext, MixerInfo, MixerData->hDevice, Topology, DestinationLineID, LineTerminator);
         }
+
+        /* mark pin as consumed */
+        MMixerSetTopologyPinReserved(Topology, Pins[0]);
+
+        /* free topology pin array */
+        MixerContext->Free(Pins);
     }
     else
     {
@@ -1341,12 +1362,12 @@ MMixerHandlePhysicalConnection(
         DestinationLineID = (DESTINATION_LINE + MixerInfo->MixCaps.cDestinations-1);
 
         /* add mixer controls */
-        Status = MMixerAddMixerControlsToDestinationLine(MixerContext, MixerInfo, Topology, OutConnection->Pin, bInput, DestinationLineID, &LineTerminator);
+        Status = MMixerAddMixerControlsToDestinationLine(MixerContext, MixerInfo, MixerData->hDevice, Topology, OutConnection->Pin, bInput, DestinationLineID, &LineTerminator);
 
         if (Status == MM_STATUS_SUCCESS)
         {
             /* now add the rest of the source lines */
-            Status = MMixerAddMixerSourceLines(MixerContext, MixerInfo, Topology, DestinationLineID, LineTerminator);
+            Status = MMixerAddMixerSourceLines(MixerContext, MixerInfo, MixerData->hDevice, Topology, DestinationLineID, LineTerminator);
         }
     }
 
@@ -1364,7 +1385,7 @@ MMixerInitializeFilter(
     IN ULONG bInputMixer,
     IN OUT LPMIXER_INFO * OutMixerInfo)
 {
-
+    ULONG Index;
     MIXER_STATUS Status;
     PKSPIN_PHYSICALCONNECTION OutConnection;
     ULONG * Pins;
@@ -1431,10 +1452,16 @@ MMixerInitializeFilter(
         return Status;
     }
 
+    /* mark all found pins as reserved */
+    for(Index = 0; Index < PinsFound; Index++)
+    {
+        MMixerSetTopologyPinReserved(Topology, Pins[Index]);
+    }
+
     if (bInputMixer)
     {
         /* pre create the mixer destination line for input mixers */
-        Status = MMixerBuildMixerDestinationLine(MixerContext, MixerInfo, Pins[0], bInputMixer);
+        Status = MMixerBuildMixerDestinationLine(MixerContext, MixerInfo, MixerData->hDevice, Pins[0], bInputMixer);
 
         if (Status != MM_STATUS_SUCCESS)
         {
@@ -1468,6 +1495,9 @@ MMixerInitializeFilter(
 
     if (Status == MM_STATUS_SUCCESS)
     {
+        /* mark pin as reserved */
+        MMixerSetTopologyPinReserved(Topology, Pins[0]);
+
         /* topology on the topoloy filter */
         Status = MMixerHandlePhysicalConnection(MixerContext, MixerList, MixerData, MixerInfo, bInputMixer, OutConnection);
 
@@ -1480,7 +1510,6 @@ MMixerInitializeFilter(
          * handle drivers which expose their topology on the same filter
          */
         ASSERT(0);
-        MixerInfo->hMixer = MixerData->hDevice;
     }
 
     /* free pins */
@@ -1498,6 +1527,32 @@ MMixerInitializeFilter(
     return Status;
 }
 
+VOID
+MMixerHandleAlternativeMixers(
+    IN PMIXER_CONTEXT MixerContext,
+    IN PMIXER_LIST MixerList,
+    IN LPMIXER_DATA MixerData,
+    IN PTOPOLOGY Topology)
+{
+    ULONG Index, PinCount, Reserved;
+
+    DPRINT1("DeviceName %S\n", MixerData->DeviceName);
+
+    /* get topology pin count */
+    MMixerGetTopologyPinCount(Topology, &PinCount);
+
+    for(Index = 0; Index < PinCount; Index++)
+    {
+        MMixerIsTopologyPinReserved(Topology, Index, &Reserved);
+
+        /* check if it has already been reserved */
+        if (Reserved == FALSE)
+        {
+            DPRINT1("MixerName %S Available PinID %lu\n", MixerData->DeviceName, Index);
+        }
+    }
+}
+
 MIXER_STATUS
 MMixerSetupFilter(
     IN PMIXER_CONTEXT MixerContext,
@@ -1567,7 +1622,7 @@ MMixerSetupFilter(
 
     }
 
-    /* TODO: handle alternative mixer types + apply hacks for Wave source line */
+    /* TODO: apply hacks for Wave source line */
 
     /* activate midi devices */
     MMixerInitializeMidiForFilter(MixerContext, MixerList, MixerData, Topology);
index de9c8e0..a473fda 100644 (file)
@@ -306,8 +306,9 @@ MMixerGetLineControls(
 {
     LPMIXER_INFO MixerInfo;
     LPMIXERLINE_EXT MixerLineSrc;
-    LPMIXERCONTROLW MixerControl;
+    LPMIXERCONTROL_EXT MixerControl;
     MIXER_STATUS Status;
+    PLIST_ENTRY Entry;
     ULONG Index;
 
     /* verify mixer context */
@@ -319,6 +320,20 @@ MMixerGetLineControls(
         return Status;
     }
 
+    if (MixerLineControls->cbStruct != sizeof(MIXERLINECONTROLSW))
+    {
+        DPRINT1("Invalid MixerLineControls cbStruct passed %lu expected %lu\n", MixerLineControls->cbStruct, sizeof(MIXERLINECONTROLSW));
+        /* invalid parameter */
+        return MM_STATUS_INVALID_PARAMETER;
+    }
+
+    if (MixerLineControls->cbmxctrl != sizeof(MIXERCONTROLW))
+    {
+        DPRINT1("Invalid MixerLineControls cbmxctrl passed %lu expected %lu\n", MixerLineControls->cbStruct, sizeof(MIXERLINECONTROLSW));
+        /* invalid parameter */
+        return MM_STATUS_INVALID_PARAMETER;
+    }
+
     if ((Flags & (MIXER_OBJECTF_MIXER | MIXER_OBJECTF_HMIXER)) == MIXER_OBJECTF_MIXER)
     {
         /* caller passed mixer id */
@@ -335,12 +350,12 @@ MMixerGetLineControls(
 
     DPRINT("MMixerGetLineControls MixerId %lu Flags %lu\n", MixerId, Flags);
 
-
     if (Flags == MIXER_GETLINECONTROLSF_ALL)
     {
         /* cast to mixer info */
         MixerInfo = (LPMIXER_INFO)MixerHandle;
 
+        /* get mixer line */
         MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLineControls->dwLineID);
 
         if (!MixerLineSrc)
@@ -349,9 +364,31 @@ MMixerGetLineControls(
             DPRINT("MMixerGetLineControls Line not found %lx\n", MixerLineControls->dwLineID);
             return MM_STATUS_INVALID_PARAMETER;
         }
+
+        if (MixerLineSrc->Line.cControls != MixerLineControls->cControls)
+        {
+            /* invalid parameter */
+            DPRINT1("Invalid control count %lu expected %lu\n", MixerLineControls->cControls, MixerLineSrc->Line.cControls);
+            return MM_STATUS_INVALID_PARAMETER;
+        }
+
         /* copy line control(s) */
-        MixerContext->Copy(MixerLineControls->pamxctrl, MixerLineSrc->LineControls, min(MixerLineSrc->Line.cControls, MixerLineControls->cControls) * sizeof(MIXERCONTROLW));
+        Entry = MixerLineSrc->ControlsList.Flink;
+        Index = 0;
+        while(Entry != &MixerLineSrc->ControlsList)
+        {
+            /* get mixer control */
+            MixerControl = (LPMIXERCONTROL_EXT)CONTAINING_RECORD(Entry, MIXERCONTROL_EXT, Entry);
+
+            /* copy mixer control */
+            MixerContext->Copy(&MixerLineControls->pamxctrl[Index], &MixerControl->Control, sizeof(MIXERCONTROLW));
+
+            /* move to next */
+            Entry = Entry->Flink;
 
+            /* increment mixer control offset */
+            Index++;
+        }
         return MM_STATUS_SUCCESS;
     }
     else if (Flags == MIXER_GETLINECONTROLSF_ONEBYTYPE)
@@ -374,19 +411,23 @@ MMixerGetLineControls(
         ASSERT(MixerLineControls->cbmxctrl == sizeof(MIXERCONTROLW));
         ASSERT(MixerLineControls->pamxctrl != NULL);
 
-        Index = 0;
-        for(Index = 0; Index < MixerLineSrc->Line.cControls; Index++)
+        Entry = MixerLineSrc->ControlsList.Flink;
+        while(Entry != &MixerLineSrc->ControlsList)
         {
-            DPRINT1("dwControlType %x\n", MixerLineSrc->LineControls[Index].dwControlType);
-            if (MixerLineControls->dwControlType == MixerLineSrc->LineControls[Index].dwControlType)
+            MixerControl = (LPMIXERCONTROL_EXT)CONTAINING_RECORD(Entry, MIXERCONTROL_EXT, Entry);
+            if (MixerLineControls->dwControlType == MixerControl->Control.dwControlType)
             {
                 /* found a control with that type */
-                MixerContext->Copy(MixerLineControls->pamxctrl, &MixerLineSrc->LineControls[Index], sizeof(MIXERCONTROLW));
+                MixerContext->Copy(MixerLineControls->pamxctrl, &MixerControl->Control, sizeof(MIXERCONTROLW));
                 return MM_STATUS_SUCCESS;
             }
-        }
-        DPRINT("DeviceInfo->u.MixControls.dwControlType %x not found in Line %x cControls %u \n", MixerLineControls->dwControlType, MixerLineControls->dwLineID, MixerLineSrc->Line.cControls);
-        return MM_STATUS_UNSUCCESSFUL;
+
+            /* move to next entry */
+            Entry = Entry->Flink;
+         }
+
+         DPRINT("DeviceInfo->u.MixControls.dwControlType %x not found in Line %x cControls %u \n", MixerLineControls->dwControlType, MixerLineControls->dwLineID, MixerLineSrc->Line.cControls);
+         return MM_STATUS_UNSUCCESSFUL;
     }
     else if (Flags == MIXER_GETLINECONTROLSF_ONEBYID)
     {
@@ -406,10 +447,10 @@ MMixerGetLineControls(
         ASSERT(MixerLineControls->cbmxctrl == sizeof(MIXERCONTROLW));
         ASSERT(MixerLineControls->pamxctrl != NULL);
 
-       DPRINT("MMixerGetLineControls ControlID %lx ControlType %lx Name %S\n", MixerControl->dwControlID, MixerControl->dwControlType, MixerControl->szName);
+       DPRINT("MMixerGetLineControls ControlID %lx ControlType %lx Name %S\n", MixerControl->Control.dwControlID, MixerControl->Control.dwControlType, MixerControl->Control.szName);
 
         /* copy the controls */
-        MixerContext->Copy(MixerLineControls->pamxctrl, MixerControl, sizeof(MIXERCONTROLW));
+        MixerContext->Copy(MixerLineControls->pamxctrl, &MixerControl->Control, sizeof(MIXERCONTROLW));
         MixerLineControls->pamxctrl->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
         MixerLineControls->pamxctrl->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
 
@@ -431,7 +472,7 @@ MMixerSetControlDetails(
     ULONG NodeId;
     LPMIXER_INFO MixerInfo;
     LPMIXERLINE_EXT MixerLine;
-    LPMIXERCONTROLW MixerControl;
+    LPMIXERCONTROL_EXT MixerControl;
 
     /* verify mixer context */
     Status = MMixerVerifyContext(MixerContext);
@@ -439,6 +480,7 @@ MMixerSetControlDetails(
     if (Status != MM_STATUS_SUCCESS)
     {
         /* invalid context passed */
+        DPRINT1("invalid context\n");
         return Status;
     }
 
@@ -450,6 +492,7 @@ MMixerSetControlDetails(
         if (!MixerHandle)
         {
             /* invalid parameter */
+            DPRINT1("invalid handle\n");
             return MM_STATUS_INVALID_PARAMETER;
         }
     }
@@ -464,18 +507,21 @@ MMixerSetControlDetails(
     if (Status != MM_STATUS_SUCCESS)
     {
         /* failed to find control id */
+        DPRINT1("invalid control id %lu\n", MixerControlDetails->dwControlID);
         return MM_STATUS_INVALID_PARAMETER;
     }
 
-    switch(MixerControl->dwControlType)
+    DPRINT1("MMixerSetControlDetails ControlType %lx MixerControlName %S MixerLineName %S NodeID %lu\n", MixerControl->Control.dwControlType, MixerControl->Control.szName, MixerLine->Line.szName, NodeId);
+    switch(MixerControl->Control.dwControlType)
     {
         case MIXERCONTROL_CONTROLTYPE_MUTE:
-            Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo->hMixer, NodeId, MixerLine->Line.dwLineID, MixerControlDetails, TRUE);
+            Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo, MixerControl, MixerLine->Line.dwLineID, MixerControlDetails, TRUE);
             break;
         case MIXERCONTROL_CONTROLTYPE_VOLUME:
-            Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo->hMixer, NodeId, TRUE, MixerControl, MixerControlDetails, MixerLine);
+            Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo, NodeId, TRUE, MixerControl, MixerControlDetails, MixerLine);
             break;
         default:
+            ASSERT(0);
             Status = MM_STATUS_NOT_IMPLEMENTED;
     }
 
@@ -494,7 +540,7 @@ MMixerGetControlDetails(
     ULONG NodeId;
     LPMIXER_INFO MixerInfo;
     LPMIXERLINE_EXT MixerLine;
-    LPMIXERCONTROLW MixerControl;
+    LPMIXERCONTROL_EXT MixerControl;
 
     /* verify mixer context */
     Status = MMixerVerifyContext(MixerContext);
@@ -530,21 +576,60 @@ MMixerGetControlDetails(
         return MM_STATUS_INVALID_PARAMETER;
     }
 
-    switch(MixerControl->dwControlType)
+    switch(MixerControl->Control.dwControlType)
     {
         case MIXERCONTROL_CONTROLTYPE_MUTE:
-            Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo, NodeId, MixerLine->Line.dwLineID, MixerControlDetails, FALSE);
+            Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo, MixerControl, MixerLine->Line.dwLineID, MixerControlDetails, FALSE);
             break;
         case MIXERCONTROL_CONTROLTYPE_VOLUME:
             Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo, NodeId, FALSE, MixerControl, MixerControlDetails, MixerLine);
             break;
         default:
             Status = MM_STATUS_NOT_IMPLEMENTED;
+            DPRINT1("ControlType %lu not implemented\n", MixerControl->Control.dwControlType);
     }
 
     return Status;
 }
 
+VOID
+MMixerPrintMixerLineControls(
+    IN LPMIXERLINE_EXT MixerLine)
+{
+    PLIST_ENTRY Entry;
+    LPMIXERCONTROL_EXT MixerControl;
+    ULONG Index = 0;
+
+    Entry = MixerLine->ControlsList.Flink;
+    while(Entry != &MixerLine->ControlsList)
+    {
+        MixerControl = (LPMIXERCONTROL_EXT)CONTAINING_RECORD(Entry, MIXERCONTROL_EXT, Entry);
+
+        DPRINT1("\n");
+        DPRINT1("Control Index: %lu\n", Index);
+        DPRINT("\n");
+        DPRINT1("cbStruct %u\n", MixerControl->Control.cbStruct);
+        DPRINT1("dwControlID %lu\n", MixerControl->Control.dwControlID);
+        DPRINT1("dwControlType %lx\n", MixerControl->Control.dwControlType);
+        DPRINT1("fdwControl %lu\n", MixerControl->Control.fdwControl);
+        DPRINT1("cMultipleItems %lu\n", MixerControl->Control.cMultipleItems);
+        DPRINT1("szShortName %S\n", MixerControl->Control.szShortName);
+        DPRINT1("szName %S\n", MixerControl->Control.szName);
+        DPRINT1("Bounds.dwMinimum %lu\n", MixerControl->Control.Bounds.dwMinimum);
+        DPRINT1("Bounds.dwMaximum %lu\n", MixerControl->Control.Bounds.dwMaximum);
+
+        DPRINT1("Metrics.Reserved[0] %lu\n", MixerControl->Control.Metrics.dwReserved[0]);
+        DPRINT1("Metrics.Reserved[1] %lu\n", MixerControl->Control.Metrics.dwReserved[1]);
+        DPRINT1("Metrics.Reserved[2] %lu\n", MixerControl->Control.Metrics.dwReserved[2]);
+        DPRINT1("Metrics.Reserved[3] %lu\n", MixerControl->Control.Metrics.dwReserved[3]);
+        DPRINT1("Metrics.Reserved[4] %lu\n", MixerControl->Control.Metrics.dwReserved[4]);
+        DPRINT1("Metrics.Reserved[5] %lu\n", MixerControl->Control.Metrics.dwReserved[5]);
+
+        Entry = Entry->Flink;
+        Index++;
+    }
+}
+
 VOID
 MMixerPrintMixers(
     IN PMIXER_CONTEXT MixerContext,
@@ -583,6 +668,9 @@ MMixerPrintMixers(
 
             /* get destination line */
             DstMixerLine = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
+            DPRINT1("//----------------------------------------------------------------------------------------------\n");
+            DPRINT1("\n");
+            DPRINT1("Destination Index %lu\n", SubIndex);
             DPRINT1("\n");
             DPRINT1("cChannels %lu\n", DstMixerLine->Line.cChannels);
             DPRINT1("cConnections %lu\n", DstMixerLine->Line.cConnections);
@@ -601,7 +689,7 @@ MMixerPrintMixers(
             DPRINT1("Target.vDriverVersion %lx\n", DstMixerLine->Line.Target.vDriverVersion);
             DPRINT1("Target.wMid %lx\n", DstMixerLine->Line.Target.wMid );
             DPRINT1("Target.wPid %lx\n", DstMixerLine->Line.Target.wPid);
-
+            MMixerPrintMixerLineControls(DstMixerLine);
 
             for(SrcIndex = 0; SrcIndex < DstMixerLine->Line.cConnections; SrcIndex++)
             {
@@ -610,8 +698,9 @@ MMixerPrintMixers(
 
                 /* get source line */
                 SrcMixerLine = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
+                DPRINT1("//==============================================================================================\n");
                 DPRINT1("\n");
-                DPRINT1("SourceIndex: %lu\n", SrcIndex);
+                DPRINT1("SrcLineIndex : %lu\n", SrcIndex);
                 DPRINT1("\n");
                 DPRINT1("cChannels %lu\n", SrcMixerLine->Line.cChannels);
                 DPRINT1("cConnections %lu\n", SrcMixerLine->Line.cConnections);
@@ -630,6 +719,7 @@ MMixerPrintMixers(
                 DPRINT1("Target.vDriverVersion %lx\n", SrcMixerLine->Line.Target.vDriverVersion);
                 DPRINT1("Target.wMid %lx\n", SrcMixerLine->Line.Target.wMid );
                 DPRINT1("Target.wPid %lx\n", SrcMixerLine->Line.Target.wPid);
+                MMixerPrintMixerLineControls(SrcMixerLine);
             }
         }
     }
@@ -736,7 +826,17 @@ MMixerInitialize(
         Entry = Entry->Flink;
     }
 
-    MMixerPrintMixers(MixerContext, MixerList);
+    Entry = MixerList->MixerData.Flink;
+    while(Entry != &MixerList->MixerData)
+    {
+        MixerData = (LPMIXER_DATA)CONTAINING_RECORD(Entry, MIXER_DATA, Entry);
+
+        /* now handle alternative mixer types */
+        MMixerHandleAlternativeMixers(MixerContext, MixerList, MixerData, MixerData->Topology);
+        Entry = Entry->Flink;
+    }
+
+    //MMixerPrintMixers(MixerContext, MixerList);
 
     /* done */
     return MM_STATUS_SUCCESS;
index 583499e..815e651 100644 (file)
@@ -55,8 +55,8 @@ typedef struct
     ULONG PinConnectedToCount;
     PULONG PinConnectedTo;
 
-
     ULONG Visited;
+    ULONG Reserved;
 }PIN, *PPIN;
 
 
@@ -74,7 +74,6 @@ typedef struct
 {
     LIST_ENTRY    Entry;
     MIXERCAPSW    MixCaps;
-    HANDLE        hMixer;
     LIST_ENTRY    LineList;
     ULONG         ControlId;
     LIST_ENTRY    EventList;
@@ -83,12 +82,19 @@ typedef struct
 typedef struct
 {
     LIST_ENTRY Entry;
-    ULONG PinId;
+    MIXERCONTROLW Control;
+    ULONG NodeID;
     HANDLE hDevice;
+    PVOID ExtraData;
+}MIXERCONTROL_EXT, *LPMIXERCONTROL_EXT;
+
+typedef struct
+{
+    LIST_ENTRY Entry;
+    ULONG PinId;
     MIXERLINEW Line;
-    LPMIXERCONTROLW LineControls;
-    PULONG          NodeIds;
-    LIST_ENTRY LineControlsExtraData;
+    LIST_ENTRY ControlsList;
+
 }MIXERLINE_EXT, *LPMIXERLINE_EXT;
 
 typedef struct
@@ -272,14 +278,14 @@ MMixerGetMixerControlById(
     LPMIXER_INFO MixerInfo,
     DWORD dwControlID,
     LPMIXERLINE_EXT *MixerLine,
-    LPMIXERCONTROLW *MixerControl,
+    LPMIXERCONTROL_EXT *MixerControl,
     PULONG NodeId);
 
 MIXER_STATUS
 MMixerSetGetMuteControlDetails(
     IN PMIXER_CONTEXT MixerContext,
     IN LPMIXER_INFO MixerInfo,
-    IN ULONG NodeId,
+    IN LPMIXERCONTROL_EXT MixerControl,
     IN ULONG dwLineID,
     IN LPMIXERCONTROLDETAILS MixerControlDetails,
     IN ULONG bSet);
@@ -290,7 +296,7 @@ MMixerSetGetVolumeControlDetails(
     IN LPMIXER_INFO MixerInfo,
     IN ULONG NodeId,
     IN ULONG bSet,
-    LPMIXERCONTROLW MixerControl,
+    LPMIXERCONTROL_EXT MixerControl,
     IN LPMIXERCONTROLDETAILS MixerControlDetails,
     LPMIXERLINE_EXT MixerLine);
 
@@ -359,6 +365,13 @@ MMixerGetPinDataFlowAndCommunication(
     OUT PKSPIN_DATAFLOW DataFlow,
     OUT PKSPIN_COMMUNICATION Communication);
 
+VOID
+MMixerHandleAlternativeMixers(
+    IN PMIXER_CONTEXT MixerContext,
+    IN PMIXER_LIST MixerList,
+    IN LPMIXER_DATA MixerData,
+    IN PTOPOLOGY Topology);
+
 
 /* topology.c */
 
@@ -472,6 +485,17 @@ MMixerIsTopologyNodeReserved(
     IN ULONG NodeIndex,
     OUT PULONG bReserved);
 
+VOID
+MMixerSetTopologyPinReserved(
+    IN PTOPOLOGY Topology,
+    IN ULONG PinId);
+
+VOID
+MMixerIsTopologyPinReserved(
+    IN PTOPOLOGY Topology,
+    IN ULONG PinId,
+    OUT PULONG bReserved);
+
 VOID
 MMixerGetTopologyPinCount(
     IN PTOPOLOGY Topology,
index 126bcb5..4d32abb 100644 (file)
@@ -100,29 +100,6 @@ MMixerGetMixerInfoByIndex(
     return NULL;
 }
 
-LPMIXERCONTROL_DATA
-MMixerGetMixerControlDataById(
-    PLIST_ENTRY ListHead,
-    DWORD dwControlId)
-{
-    PLIST_ENTRY Entry;
-    LPMIXERCONTROL_DATA Control;
-
-    /* get first entry */
-    Entry = ListHead->Flink;
-
-    while(Entry != ListHead)
-    {
-        Control = (LPMIXERCONTROL_DATA)CONTAINING_RECORD(Entry, MIXERCONTROL_DATA, Entry);
-        DPRINT("dwSource %x dwSource %x\n", Control->dwControlID, dwControlId);
-        if (Control->dwControlID == dwControlId)
-            return Control;
-
-        Entry = Entry->Flink;
-    }
-    return NULL;
-}
-
 LPMIXERLINE_EXT
 MMixerGetSourceMixerLineByLineId(
     LPMIXER_INFO MixerInfo,
@@ -187,13 +164,13 @@ MIXER_STATUS
 MMixerGetMixerControlById(
     LPMIXER_INFO MixerInfo,
     DWORD dwControlID,
-    LPMIXERLINE_EXT *MixerLine,
-    LPMIXERCONTROLW *MixerControl,
+    LPMIXERLINE_EXT *OutMixerLine,
+    LPMIXERCONTROL_EXT *OutMixerControl,
     PULONG NodeId)
 {
-    PLIST_ENTRY Entry;
+    PLIST_ENTRY Entry, ControlEntry;
     LPMIXERLINE_EXT MixerLineSrc;
-    ULONG Index;
+    LPMIXERCONTROL_EXT MixerControl;
 
     /* get first entry */
     Entry = MixerInfo->LineList.Flink;
@@ -202,18 +179,21 @@ MMixerGetMixerControlById(
     {
         MixerLineSrc = (LPMIXERLINE_EXT)CONTAINING_RECORD(Entry, MIXERLINE_EXT, Entry);
 
-        for(Index = 0; Index < MixerLineSrc->Line.cControls; Index++)
+        ControlEntry = MixerLineSrc->ControlsList.Flink;
+        while(ControlEntry != &MixerLineSrc->ControlsList)
         {
-            if (MixerLineSrc->LineControls[Index].dwControlID == dwControlID)
+            MixerControl = (LPMIXERCONTROL_EXT)CONTAINING_RECORD(ControlEntry, MIXERCONTROL_EXT, Entry);
+            if (MixerControl->Control.dwControlID == dwControlID)
             {
-                if (MixerLine)
-                    *MixerLine = MixerLineSrc;
-                if (MixerControl)
-                    *MixerControl = &MixerLineSrc->LineControls[Index];
+                if (OutMixerLine)
+                    *OutMixerLine = MixerLineSrc;
+                if (OutMixerControl)
+                    *OutMixerControl = MixerControl;
                 if (NodeId)
-                    *NodeId = MixerLineSrc->NodeIds[Index];
+                    *NodeId = MixerControl->NodeID;
                 return MM_STATUS_SUCCESS;
             }
+            ControlEntry = ControlEntry->Flink;
         }
         Entry = Entry->Flink;
     }
@@ -270,7 +250,7 @@ MIXER_STATUS
 MMixerSetGetMuteControlDetails(
     IN PMIXER_CONTEXT MixerContext,
     IN LPMIXER_INFO MixerInfo,
-    IN ULONG NodeId,
+    IN LPMIXERCONTROL_EXT MixerControl,
     IN ULONG dwLineID,
     IN LPMIXERCONTROLDETAILS MixerControlDetails,
     IN ULONG bSet)
@@ -290,7 +270,7 @@ MMixerSetGetMuteControlDetails(
         Value = Input->fValue;
 
     /* set control details */
-    Status = MMixerSetGetControlDetails(MixerContext, MixerInfo->hMixer, NodeId, bSet, KSPROPERTY_AUDIO_MUTE, 0, &Value);
+    Status = MMixerSetGetControlDetails(MixerContext, MixerControl->hDevice, MixerControl->NodeID, bSet, KSPROPERTY_AUDIO_MUTE, 0, &Value);
 
     if (Status != MM_STATUS_SUCCESS)
         return Status;
@@ -316,7 +296,7 @@ MMixerSetGetVolumeControlDetails(
     IN LPMIXER_INFO MixerInfo,
     IN ULONG NodeId,
     IN ULONG bSet,
-    LPMIXERCONTROLW MixerControl,
+    LPMIXERCONTROL_EXT MixerControl,
     IN LPMIXERCONTROLDETAILS MixerControlDetails,
     LPMIXERLINE_EXT MixerLine)
 {
@@ -329,7 +309,7 @@ MMixerSetGetVolumeControlDetails(
     if (MixerControlDetails->cbDetails != sizeof(MIXERCONTROLDETAILS_SIGNED))
         return MM_STATUS_INVALID_PARAMETER;
 
-    VolumeData = (LPMIXERVOLUME_DATA)MMixerGetMixerControlDataById(&MixerLine->LineControlsExtraData, MixerControl->dwControlID);
+    VolumeData = (LPMIXERVOLUME_DATA)MixerControl->ExtraData;
     if (!VolumeData)
         return MM_STATUS_UNSUCCESSFUL;
 
@@ -355,12 +335,12 @@ MMixerSetGetVolumeControlDetails(
     if (bSet)
     {
         /* TODO */
-        Status = MMixerSetGetControlDetails(MixerContext, MixerInfo->hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 0, &Value);
-        Status = MMixerSetGetControlDetails(MixerContext, MixerInfo->hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 1, &Value);
+        Status = MMixerSetGetControlDetails(MixerContext, MixerControl->hDevice, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 0, &Value);
+        Status = MMixerSetGetControlDetails(MixerContext, MixerControl->hDevice, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, 1, &Value);
     }
     else
     {
-        Status = MMixerSetGetControlDetails(MixerContext, MixerInfo->hMixer, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, Channel, &Value);
+        Status = MMixerSetGetControlDetails(MixerContext, MixerControl->hDevice, NodeId, bSet, KSPROPERTY_AUDIO_VOLUMELEVEL, Channel, &Value);
     }
 
     if (!bSet)
@@ -372,7 +352,7 @@ MMixerSetGetVolumeControlDetails(
     else
     {
         /* notify clients of a line change  MM_MIXM_CONTROL_CHANGE with MixerControl->dwControlID */
-        MMixerNotifyControlChange(MixerContext, MixerInfo, MM_MIXM_CONTROL_CHANGE, MixerControl->dwControlID);
+        MMixerNotifyControlChange(MixerContext, MixerInfo, MM_MIXM_CONTROL_CHANGE, MixerControl->Control.dwControlID);
     }
     return Status;
 }
index d5050e0..ab04756 100644 (file)
@@ -1173,6 +1173,31 @@ MMixerGetNodeTypeFromTopology(
     return &Topology->TopologyNodes[NodeIndex].NodeType;
 }
 
+VOID
+MMixerSetTopologyPinReserved(
+    IN PTOPOLOGY Topology,
+    IN ULONG PinId)
+{
+    /* sanity check */
+    ASSERT(PinId < Topology->TopologyPinsCount);
+
+    /* set reserved */
+    Topology->TopologyPins[PinId].Reserved = TRUE;
+}
+
+VOID
+MMixerIsTopologyPinReserved(
+    IN PTOPOLOGY Topology,
+    IN ULONG PinId,
+    OUT PULONG bReserved)
+{
+    /* sanity check */
+    ASSERT(PinId < Topology->TopologyPinsCount);
+
+    /* get reserved status */
+    *bReserved = Topology->TopologyPins[PinId].Reserved;
+}
+
 VOID
 MMixerSetTopologyNodeReserved(
     IN PTOPOLOGY Topology,