ReactOS 0.4.15-dev-6069-g56a4501
controls.c File Reference
#include "precomp.h"
#include <debug.h>
Include dependency graph for controls.c:

Go to the source code of this file.

Macros

#define YDEBUG
 

Functions

MIXER_STATUS MMixerAddMixerControl (IN PMIXER_CONTEXT MixerContext, IN LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN PTOPOLOGY Topology, IN ULONG NodeIndex, IN LPMIXERLINE_EXT MixerLine, IN ULONG MaxChannels)
 
MIXER_STATUS MMixerCreateDestinationLine (IN PMIXER_CONTEXT MixerContext, IN LPMIXER_INFO MixerInfo, IN ULONG bInputMixer, IN LPWSTR LineName)
 
MIXER_STATUS MMixerGetPinName (IN PMIXER_CONTEXT MixerContext, IN LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN ULONG PinId, IN OUT LPWSTR *OutBuffer)
 
MIXER_STATUS MMixerBuildMixerDestinationLine (IN PMIXER_CONTEXT MixerContext, IN OUT LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN ULONG PinId, IN ULONG bInput)
 
MIXER_STATUS MMixerBuildTopology (IN PMIXER_CONTEXT MixerContext, IN LPMIXER_DATA MixerData, OUT PTOPOLOGY *OutTopology)
 
MIXER_STATUS MMixerCountMixerControls (IN PMIXER_CONTEXT MixerContext, IN PTOPOLOGY Topology, IN ULONG PinId, IN ULONG bInputMixer, IN ULONG bUpStream, OUT PULONG OutNodesCount, OUT PULONG OutNodes, OUT PULONG OutLineTerminator)
 
MIXER_STATUS MMixerGetChannelCountEnhanced (IN PMIXER_CONTEXT MixerContext, IN LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN ULONG NodeId, OUT PULONG MaxChannels)
 
VOID MMixerGetChannelCountLegacy (IN PMIXER_CONTEXT MixerContext, IN LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN ULONG NodeId, OUT PULONG MaxChannels)
 
VOID MMixerGetMaxChannelsForNode (IN PMIXER_CONTEXT MixerContext, IN LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN ULONG NodeId, OUT PULONG MaxChannels)
 
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, IN PULONG Nodes)
 
MIXER_STATUS MMixerGetComponentAndTargetType (IN PMIXER_CONTEXT MixerContext, IN OUT LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN ULONG PinId, OUT PULONG ComponentType, OUT PULONG TargetType)
 
MIXER_STATUS MMixerBuildMixerSourceLine (IN PMIXER_CONTEXT MixerContext, IN OUT LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN PTOPOLOGY Topology, IN ULONG PinId, IN ULONG NodesCount, IN PULONG Nodes, IN ULONG DestinationLineID, OUT LPMIXERLINE_EXT *OutSrcLine)
 
MIXER_STATUS MMixerAddMixerSourceLines (IN PMIXER_CONTEXT MixerContext, IN OUT LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN PTOPOLOGY Topology, IN ULONG DestinationLineID, IN ULONG LineTerminator)
 
MIXER_STATUS MMixerAddMixerControlsToDestinationLine (IN PMIXER_CONTEXT MixerContext, IN OUT LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN PTOPOLOGY Topology, IN ULONG PinId, IN ULONG bInput, IN ULONG DestinationLineId, OUT PULONG OutLineTerminator)
 
VOID MMixerApplyOutputFilterHack (IN PMIXER_CONTEXT MixerContext, IN LPMIXER_DATA MixerData, IN HANDLE hMixer, IN OUT PULONG PinsCount, IN OUT PULONG Pins)
 
MIXER_STATUS MMixerHandleTopologyFilter (IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, IN LPMIXER_DATA MixerData, IN OUT LPMIXER_INFO MixerInfo, IN ULONG bInput, IN ULONG Pin)
 
MIXER_STATUS MMixerHandlePhysicalConnection (IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, IN LPMIXER_DATA MixerData, IN OUT LPMIXER_INFO MixerInfo, IN ULONG bInput, IN PKSPIN_PHYSICALCONNECTION OutConnection)
 
MIXER_STATUS MMixerInitializeFilter (IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, IN LPMIXER_DATA MixerData, IN LPMIXER_INFO MixerInfo, IN PTOPOLOGY Topology, IN ULONG NodeIndex, IN ULONG bInputMixer, IN OUT LPMIXER_INFO *OutMixerInfo)
 
VOID MMixerHandleAlternativeMixers (IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, IN LPMIXER_DATA MixerData, IN PTOPOLOGY Topology)
 
MIXER_STATUS MMixerSetupFilter (IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, IN LPMIXER_DATA MixerData, IN PULONG DeviceCount)
 
MIXER_STATUS MMixerAddEvent (IN PMIXER_CONTEXT MixerContext, IN OUT LPMIXER_INFO MixerInfo, IN PVOID MixerEventContext, IN PMIXER_EVENT MixerEventRoutine)
 
MIXER_STATUS MMixerRemoveEvent (IN PMIXER_CONTEXT MixerContext, IN OUT LPMIXER_INFO MixerInfo, IN PVOID MixerEventContext, IN PMIXER_EVENT MixerEventRoutine)
 

Variables

const GUID KSNODETYPE_DESKTOP_MICROPHONE = {0xDFF21BE2, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}
 
const GUID KSNODETYPE_LEGACY_AUDIO_CONNECTOR = {0xDFF21FE4, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}
 
const GUID KSNODETYPE_TELEPHONE = {0xDFF21EE2, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}
 
const GUID KSNODETYPE_PHONE_LINE = {0xDFF21EE1, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}
 
const GUID KSNODETYPE_DOWN_LINE_PHONE = {0xDFF21EE3, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}
 
const GUID KSNODETYPE_DESKTOP_SPEAKER = {0xDFF21CE4, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}
 
const GUID KSNODETYPE_ROOM_SPEAKER = {0xDFF21CE5, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}
 
const GUID KSNODETYPE_COMMUNICATION_SPEAKER = {0xDFF21CE6, 0xF70F, 0x11D0, {0xB9,0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}
 
const GUID KSNODETYPE_HEADPHONES = {0xDFF21CE2, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}
 
const GUID KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO = {0xDFF21CE3, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}
 
const GUID KSNODETYPE_MICROPHONE = {0xDFF21BE1, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9,0x22, 0x31, 0x96}}
 
const GUID KSCATEGORY_AUDIO = {0x6994AD04L, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}
 
const GUID KSNODETYPE_SPDIF_INTERFACE = {0xDFF21FE5, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}
 
const GUID KSNODETYPE_ANALOG_CONNECTOR = {0xDFF21FE1, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}
 
const GUID KSNODETYPE_SPEAKER = {0xDFF21CE1, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}
 
const GUID KSNODETYPE_CD_PLAYER = {0xDFF220E3, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}
 
const GUID KSNODETYPE_SYNTHESIZER = {0xDFF220F3, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}
 
const GUID KSNODETYPE_LINE_CONNECTOR = {0xDFF21FE3, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0,0xC9, 0x22, 0x31, 0x96}}
 
const GUID PINNAME_VIDEO_CAPTURE = {0xfb6c4281, 0x353, 0x11d1, {0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba}}
 

Macro Definition Documentation

◆ YDEBUG

#define YDEBUG

Definition at line 11 of file controls.c.

Function Documentation

◆ MMixerAddEvent()

MIXER_STATUS MMixerAddEvent ( IN PMIXER_CONTEXT  MixerContext,
IN OUT LPMIXER_INFO  MixerInfo,
IN PVOID  MixerEventContext,
IN PMIXER_EVENT  MixerEventRoutine 
)

Definition at line 1834 of file controls.c.

1839{
1840 //KSE_NODE Property;
1841 //KSEVENTDATA EventData
1842 //ULONG BytesReturned;
1843 //MIXER_STATUS Status;
1844 PEVENT_NOTIFICATION_ENTRY EventNotification;
1845
1847 if (!EventNotification)
1848 {
1849 /* not enough memory */
1850 return MM_STATUS_NO_MEMORY;
1851 }
1852
1853 /* FIXME: what is it supposed to happen with KSEVENTDATA ? */
1854#if 0
1855 /* setup request */
1859
1860 Property.NodeId = NodeId;
1861 Property.Reserved = 0;
1862
1863 Status = MixerContext->Control(MixerInfo->hMixer, IOCTL_KS_ENABLE_EVENT, (PVOID)&Property, sizeof(KSP_NODE), (PVOID)EventData, sizeof(KSEVENTDATA), &BytesReturned);
1865 {
1866 /* failed to add event */
1867 MixerContext->FreeEventData(EventData);
1868 return Status;
1869 }
1870#endif
1871
1872 /* initialize notification entry */
1873 EventNotification->MixerEventContext = MixerEventContext;
1874 EventNotification->MixerEventRoutine = MixerEventRoutine;
1875
1876 /* store event */
1877 InsertTailList(&MixerInfo->EventList, &EventNotification->Entry);
1878 return MM_STATUS_SUCCESS;
1879}
MIXER_CONTEXT MixerContext
Definition: mmixer.c:41
#define InsertTailList(ListHead, Entry)
Status
Definition: gdiplustypes.h:25
#define KSEVENT_TYPE_TOPOLOGY
Definition: ks.h:1796
#define KSEVENT_TYPE_ENABLE
Definition: ks.h:1789
#define IOCTL_KS_ENABLE_EVENT
Definition: ks.h:130
@ KSEVENT_CONTROL_CHANGE
Definition: ksmedia.h:1120
#define KSEVENTSETID_AudioControlChange
Definition: ksmedia.h:1117
@ MM_STATUS_NO_MEMORY
Definition: mmixer.h:12
@ MM_STATUS_SUCCESS
Definition: mmixer.h:5
struct EVENT_NOTIFICATION_ENTRY * PEVENT_NOTIFICATION_ENTRY
Definition: precomp.h:169
PVOID MixerEventContext
Definition: precomp.h:171
LIST_ENTRY Entry
Definition: precomp.h:170
PMIXER_EVENT MixerEventRoutine
Definition: precomp.h:172
Definition: ks.h:2074
PMIXER_DEVICE_CONTROL Control
Definition: mmixer.h:95
PMIXER_FREE_EVENT_DATA FreeEventData
Definition: mmixer.h:104
PMIXER_ALLOC Alloc
Definition: mmixer.h:94
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_ ULONG _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesReturned
Definition: wdfiotarget.h:1052

Referenced by MMixerOpen().

◆ MMixerAddMixerControl()

MIXER_STATUS MMixerAddMixerControl ( IN PMIXER_CONTEXT  MixerContext,
IN LPMIXER_INFO  MixerInfo,
IN HANDLE  hMixer,
IN PTOPOLOGY  Topology,
IN ULONG  NodeIndex,
IN LPMIXERLINE_EXT  MixerLine,
IN ULONG  MaxChannels 
)

Definition at line 35 of file controls.c.

43{
49 LPMIXERCONTROL_EXT MixerControl;
50
51 /* allocate mixer control */
52 MixerControl = MixerContext->Alloc(sizeof(MIXERCONTROL_EXT));
53 if (!MixerControl)
54 {
55 /* no memory */
57 }
58
59
60 /* initialize mixer control */
61 MixerControl->hDevice = hMixer;
62 MixerControl->NodeID = NodeIndex;
63 MixerControl->ExtraData = NULL;
64
65 MixerControl->Control.cbStruct = sizeof(MIXERCONTROLW);
66 MixerControl->Control.dwControlID = MixerInfo->ControlId;
67
68 /* get node type */
69 NodeType = MMixerGetNodeTypeFromTopology(Topology, NodeIndex);
70 /* store control type */
72
73 MixerControl->Control.fdwControl = (MaxChannels > 1 ? 0 : MIXERCONTROL_CONTROLF_UNIFORM);
74 MixerControl->Control.cMultipleItems = 0;
75
76 /* setup request to retrieve name */
77 Node.NodeId = NodeIndex;
78 Node.Property.Id = KSPROPERTY_TOPOLOGY_NAME;
79 Node.Property.Flags = KSPROPERTY_TYPE_GET;
80 Node.Property.Set = KSPROPSETID_Topology;
81 Node.Reserved = 0;
82
83 /* get node name size */
85
87 {
90 if (!Name)
91 {
92 /* not enough memory */
94 }
95
96 /* get node name */
98
100 {
102 MixerControl->Control.szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
103
104 MixerContext->Copy(MixerControl->Control.szName, Name, (min(MIXER_LONG_NAME_CHARS, wcslen(Name)+1)) * sizeof(WCHAR));
105 MixerControl->Control.szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
106 }
107
108 /* free name buffer */
110 }
111
112 /* increment control count */
113 MixerInfo->ControlId++;
114
115 /* insert control */
116 InsertTailList(&MixerLine->ControlsList, &MixerControl->Entry);
117
119 {
120 ULONG NodesCount;
121 PULONG Nodes;
122
123 /* allocate topology nodes array */
125
127 {
128 /* out of memory */
129 return STATUS_NO_MEMORY;
130 }
131
132 /* get connected node count */
133 MMixerGetNextNodesFromNodeIndex(MixerContext, Topology, NodeIndex, TRUE, &NodesCount, Nodes);
134
135 /* TODO */
136 MixerContext->Free(Nodes);
137
138 /* setup mux bounds */
139 MixerControl->Control.Bounds.dwMinimum = 0;
140 MixerControl->Control.Bounds.dwMaximum = NodesCount - 1;
141 MixerControl->Control.Metrics.dwReserved[0] = NodesCount;
142 MixerControl->Control.cMultipleItems = NodesCount;
144 }
145 else if (MixerControl->Control.dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
146 {
147 MixerControl->Control.Bounds.dwMinimum = 0;
148 MixerControl->Control.Bounds.dwMaximum = 1;
149 }
150 else if (MixerControl->Control.dwControlType == MIXERCONTROL_CONTROLTYPE_ONOFF)
151 {
152 /* only needs to set bounds */
153 MixerControl->Control.Bounds.dwMinimum = 0;
154 MixerControl->Control.Bounds.dwMaximum = 1;
155 }
156 else if (MixerControl->Control.dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
157 {
163
164 MixerControl->Control.Bounds.dwMinimum = 0;
165 MixerControl->Control.Bounds.dwMaximum = 0xFFFF;
166 MixerControl->Control.Metrics.cSteps = 0xC0; /* FIXME */
167
170 ASSERT(Desc);
171
172 /* setup the request */
174
175 Property.NodeProperty.NodeId = NodeIndex;
178 Property.NodeProperty.Property.Set = KSPROPSETID_Audio;
179
180 /* get node volume level info */
182
184 {
185 LPMIXERVOLUME_DATA VolumeData;
186 ULONG Steps, MaxRange, Index;
187 LONG Value;
188
189 Members = (PKSPROPERTY_MEMBERSHEADER)(Desc + 1);
190 Range = (PKSPROPERTY_STEPPING_LONG)(Members + 1);
191
192 DPRINT("NodeIndex %u Range Min %d Max %d Steps %x UMin %x UMax %x\n", NodeIndex, Range->Bounds.SignedMinimum, Range->Bounds.SignedMaximum, Range->SteppingDelta, Range->Bounds.UnsignedMinimum, Range->Bounds.UnsignedMaximum);
193
194 MaxRange = Range->Bounds.UnsignedMaximum - Range->Bounds.UnsignedMinimum;
195
196 if (MaxRange)
197 {
198 ASSERT(MaxRange);
200 if (!VolumeData)
201 return MM_STATUS_NO_MEMORY;
202
203 Steps = MaxRange / Range->SteppingDelta + 1;
204
205 /* store mixer control info there */
206 VolumeData->Header.dwControlID = MixerControl->Control.dwControlID;
207 VolumeData->SignedMaximum = Range->Bounds.SignedMaximum;
208 VolumeData->SignedMinimum = Range->Bounds.SignedMinimum;
209 VolumeData->SteppingDelta = Range->SteppingDelta;
210 VolumeData->ValuesCount = Steps;
211 VolumeData->InputSteppingDelta = 0x10000 / Steps;
212
213 VolumeData->Values = (PLONG)MixerContext->Alloc(sizeof(LONG) * Steps);
214 if (!VolumeData->Values)
215 {
216 MixerContext->Free(Desc);
217 MixerContext->Free(VolumeData);
218 return MM_STATUS_NO_MEMORY;
219 }
220
221 Value = Range->Bounds.SignedMinimum;
222 for(Index = 0; Index < Steps; Index++)
223 {
224 VolumeData->Values[Index] = Value;
225 Value += Range->SteppingDelta;
226 }
227 MixerControl->ExtraData = VolumeData;
228 }
229 }
230 MixerContext->Free(Desc);
231 }
232
233 DPRINT("Status %x Name %S\n", Status, MixerControl->Control.szName);
234 return MM_STATUS_SUCCESS;
235}
NodeType
Definition: Node.h:6
struct NameRec_ * Name
Definition: cdprocs.h:460
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
union node Node
Definition: types.h:1255
#define NodeType(P)
Definition: nodetype.h:51
#define KSPROPERTY_TYPE_TOPOLOGY
Definition: dmksctrl.h:53
#define KSPROPERTY_TYPE_BASICSUPPORT
Definition: dmksctrl.h:45
#define KSPROPERTY_TYPE_GET
Definition: dmksctrl.h:42
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define IOCTL_KS_PROPERTY
Definition: ks.h:127
@ KSPROPERTY_TOPOLOGY_NAME
Definition: ks.h:848
struct KSPROPERTY_STEPPING_LONG * PKSPROPERTY_STEPPING_LONG
#define KSPROPSETID_Topology
Definition: ks.h:842
struct KSPROPERTY_DESCRIPTION * PKSPROPERTY_DESCRIPTION
struct KSPROPERTY_MEMBERSHEADER * PKSPROPERTY_MEMBERSHEADER
@ KSPROPERTY_AUDIO_VOLUMELEVEL
Definition: ksmedia.h:1057
#define KSPROPSETID_Audio
Definition: ksmedia.h:1051
MIXER_STATUS
Definition: mmixer.h:4
@ MM_STATUS_MORE_ENTRIES
Definition: mmixer.h:9
#define MIXERCONTROL_CONTROLF_UNIFORM
Definition: mmsystem.h:350
#define MIXERCONTROL_CONTROLTYPE_ONOFF
Definition: mmsystem.h:383
#define MIXERCONTROL_CONTROLTYPE_MUX
Definition: mmsystem.h:403
struct tagMIXERCONTROLW MIXERCONTROLW
#define MIXERCONTROL_CONTROLF_MULTIPLE
Definition: mmsystem.h:351
#define MIXERCONTROL_CONTROLTYPE_VOLUME
Definition: mmsystem.h:398
#define MIXER_LONG_NAME_CHARS
Definition: mmsystem.h:294
#define MIXER_SHORT_NAME_CHARS
Definition: mmsystem.h:293
#define MIXERCONTROL_CONTROLTYPE_MUTE
Definition: mmsystem.h:384
#define ASSERT(a)
Definition: mode.c:44
HMIXER hMixer
Definition: test.c:10
#define min(a, b)
Definition: monoChain.cc:55
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
struct tagRange Range
ULONG MMixerGetControlTypeFromTopologyNode(IN LPGUID NodeType)
Definition: filter.c:139
struct MIXERVOLUME_DATA * LPMIXERVOLUME_DATA
LPGUID MMixerGetNodeTypeFromTopology(IN PTOPOLOGY Topology, IN ULONG NodeIndex)
Definition: topology.c:1191
MIXER_STATUS MMixerAllocateTopologyNodeArray(IN PMIXER_CONTEXT MixerContext, IN PTOPOLOGY Topology, OUT PULONG *OutPins)
Definition: topology.c:1052
VOID MMixerGetNextNodesFromNodeIndex(IN PMIXER_CONTEXT MixerContext, IN PTOPOLOGY Topology, IN ULONG NodeIndex, IN ULONG bUpStream, OUT PULONG OutNodesCount, OUT PULONG OutNodes)
Definition: topology.c:972
#define DPRINT
Definition: sndvol32.h:71
ULONG dwControlID
Definition: precomp.h:97
HANDLE hDevice
Definition: precomp.h:81
MIXERCONTROLW Control
Definition: precomp.h:79
PVOID ExtraData
Definition: precomp.h:82
ULONG NodeID
Definition: precomp.h:80
LIST_ENTRY Entry
Definition: precomp.h:78
MIXERCONTROL_DATA Header
Definition: precomp.h:102
LONG SignedMinimum
Definition: precomp.h:103
ULONG ValuesCount
Definition: precomp.h:107
ULONG InputSteppingDelta
Definition: precomp.h:106
LONG SignedMaximum
Definition: precomp.h:104
LONG SteppingDelta
Definition: precomp.h:105
PMIXER_COPY Copy
Definition: mmixer.h:99
PMIXER_FREE Free
Definition: mmixer.h:96
Property(long _type, long _tag, INREAL _value)
Definition: reader.h:125
WCHAR szName[MIXER_LONG_NAME_CHARS]
Definition: mmsystem.h:1310
DWORD dwControlType
Definition: mmsystem.h:1306
DWORD cMultipleItems
Definition: mmsystem.h:1308
union tagMIXERCONTROLW::@3026 Bounds
union tagMIXERCONTROLW::@3027 Metrics
WCHAR szShortName[MIXER_SHORT_NAME_CHARS]
Definition: mmsystem.h:1309
DWORD dwReserved[6]
Definition: mmsystem.h:1320
Definition: range.c:39
uint32_t * PULONG
Definition: typedefs.h:59
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
int32_t * PLONG
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
Definition: dlist.c:348
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by MMixerAddMixerControlsToMixerLineByNodeIndexArray().

◆ MMixerAddMixerControlsToDestinationLine()

MIXER_STATUS MMixerAddMixerControlsToDestinationLine ( IN PMIXER_CONTEXT  MixerContext,
IN OUT LPMIXER_INFO  MixerInfo,
IN HANDLE  hMixer,
IN PTOPOLOGY  Topology,
IN ULONG  PinId,
IN ULONG  bInput,
IN ULONG  DestinationLineId,
OUT PULONG  OutLineTerminator 
)

Definition at line 1168 of file controls.c.

1177{
1178 PULONG Nodes;
1179 ULONG NodesCount, LineTerminator;
1181 LPMIXERLINE_EXT DstLine;
1182
1183 /* allocate nodes index array */
1185
1186 /* check for success */
1188 {
1189 /* out of memory */
1190 return Status;
1191 }
1192
1193 /* get all destination line controls */
1194 Status = MMixerCountMixerControls(MixerContext, Topology, PinId, bInput, TRUE, &NodesCount, Nodes, &LineTerminator);
1195
1196 /* check for success */
1198 {
1199 /* failed to count controls */
1200 MixerContext->Free(Nodes);
1201 return Status;
1202 }
1203
1204 /* get destination mixer line */
1205 DstLine = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineId);
1206
1207 /* sanity check */
1208 ASSERT(DstLine);
1209
1210 if (NodesCount > 0)
1211 {
1212 /* add all nodes as mixer controls to the destination line */
1213 Status = MMixerAddMixerControlsToMixerLineByNodeIndexArray(MixerContext, MixerInfo, hMixer, Topology, DstLine, NodesCount, Nodes);
1215 {
1216 /* failed to add controls */
1217 MixerContext->Free(Nodes);
1218 return Status;
1219 }
1220 }
1221
1222 /* store result */
1223 *OutLineTerminator = LineTerminator;
1224
1225 /* return result */
1226 return Status;
1227}
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, IN PULONG Nodes)
Definition: controls.c:675
MIXER_STATUS MMixerCountMixerControls(IN PMIXER_CONTEXT MixerContext, IN PTOPOLOGY Topology, IN ULONG PinId, IN ULONG bInputMixer, IN ULONG bUpStream, OUT PULONG OutNodesCount, OUT PULONG OutNodes, OUT PULONG OutLineTerminator)
Definition: controls.c:445
LPMIXERLINE_EXT MMixerGetSourceMixerLineByLineId(LPMIXER_INFO MixerInfo, DWORD dwLineID)
Definition: sup.c:221

Referenced by MMixerHandleAlternativeMixers(), MMixerHandlePhysicalConnection(), and MMixerHandleTopologyFilter().

◆ MMixerAddMixerControlsToMixerLineByNodeIndexArray()

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,
IN PULONG  Nodes 
)

Definition at line 675 of file controls.c.

683{
684 ULONG Index, Count, bReserved;
687 ULONG MaxChannels;
688
689 /* initialize control count */
690 Count = 0;
691
692 for(Index = 0; Index < NodesCount; Index++)
693 {
694 /* check if the node has already been reserved to a line */
695 MMixerIsTopologyNodeReserved(Topology, Nodes[Index], &bReserved);
696#if 0 /* MS lies */
697 if (bReserved)
698 {
699 /* node is already used, skip it */
700 continue;
701 }
702#endif
703 /* set node status as used */
704 MMixerSetTopologyNodeReserved(Topology, Nodes[Index]);
705
706 /* query node type */
707 NodeType = MMixerGetNodeTypeFromTopology(Topology, Nodes[Index]);
708
710 {
711 /* calculate maximum channel count for node */
712 MMixerGetMaxChannelsForNode(MixerContext, MixerInfo, hMixer, Nodes[Index], &MaxChannels);
713
714 DPRINT("NodeId %lu MaxChannels %lu Line %S Id %lu\n", Nodes[Index], MaxChannels, DstLine->Line.szName, DstLine->Line.dwLineID);
715 /* calculate maximum channels */
716 DstLine->Line.cChannels = min(DstLine->Line.cChannels, MaxChannels);
717 }
718 else
719 {
720 /* use default of one channel */
721 MaxChannels = 1;
722 }
723
724 /* now add the mixer control */
725 Status = MMixerAddMixerControl(MixerContext, MixerInfo, hMixer, Topology, Nodes[Index], DstLine, MaxChannels);
726
728 {
729 /* increment control count */
730 Count++;
731 }
732 }
733
734 /* store control count */
735 DstLine->Line.cControls = Count;
736
737 /* done */
738 return MM_STATUS_SUCCESS;
739}
VOID MMixerGetMaxChannelsForNode(IN PMIXER_CONTEXT MixerContext, IN LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN ULONG NodeId, OUT PULONG MaxChannels)
Definition: controls.c:655
MIXER_STATUS MMixerAddMixerControl(IN PMIXER_CONTEXT MixerContext, IN LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN PTOPOLOGY Topology, IN ULONG NodeIndex, IN LPMIXERLINE_EXT MixerLine, IN ULONG MaxChannels)
Definition: controls.c:35
#define KSNODETYPE_VOLUME
Definition: ksmedia.h:338
int Count
Definition: noreturn.cpp:7
VOID MMixerIsTopologyNodeReserved(IN PTOPOLOGY Topology, IN ULONG NodeIndex, OUT PULONG bReserved)
Definition: topology.c:1239
VOID MMixerSetTopologyNodeReserved(IN PTOPOLOGY Topology, IN ULONG NodeIndex)
Definition: topology.c:1227
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:235

Referenced by MMixerAddMixerControlsToDestinationLine(), and MMixerBuildMixerSourceLine().

◆ MMixerAddMixerSourceLines()

MIXER_STATUS MMixerAddMixerSourceLines ( IN PMIXER_CONTEXT  MixerContext,
IN OUT LPMIXER_INFO  MixerInfo,
IN HANDLE  hMixer,
IN PTOPOLOGY  Topology,
IN ULONG  DestinationLineID,
IN ULONG  LineTerminator 
)

Definition at line 1034 of file controls.c.

1041{
1042 PULONG AllNodes, AllPins, AllPinNodes;
1043 ULONG AllNodesCount, AllPinsCount, AllPinNodesCount;
1044 ULONG Index, SubIndex, PinId, CurNode, bConnected;
1046 LPMIXERLINE_EXT DstLine, SrcLine;
1047
1048 /* get destination line */
1049 DstLine = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
1050 ASSERT(DstLine);
1051
1052 /* allocate an array to store all nodes which are upstream of the line terminator */
1053 Status = MMixerAllocateTopologyNodeArray(MixerContext, Topology, &AllNodes);
1054
1055 /* check for success */
1057 {
1058 /* out of memory */
1059 return MM_STATUS_NO_MEMORY;
1060 }
1061
1062 /* allocate an array to store all nodes which are downstream of a particular pin */
1063 Status = MMixerAllocateTopologyNodeArray(MixerContext, Topology, &AllPinNodes);
1064
1065 /* allocate an array to store all pins which are upstream of this pin */
1066 Status = MMixerAllocateTopologyPinArray(MixerContext, Topology, &AllPins);
1067
1068 /* check for success */
1070 {
1071 /* out of memory */
1072 MixerContext->Free(AllNodes);
1073 return MM_STATUS_NO_MEMORY;
1074 }
1075
1076 /* get all nodes which indirectly / directly connect to this node */
1077 AllNodesCount = 0;
1078 MMixerGetAllUpOrDownstreamNodesFromNodeIndex(MixerContext, Topology, LineTerminator, TRUE, &AllNodesCount, AllNodes);
1079
1080 /* get all pins which indirectly / directly connect to this node */
1081 AllPinsCount = 0;
1082 MMixerGetAllUpOrDownstreamPinsFromNodeIndex(MixerContext, Topology, LineTerminator, TRUE, &AllPinsCount, AllPins);
1083
1084 DPRINT("LineTerminator %lu\n", LineTerminator);
1085 DPRINT("PinCount %lu\n", AllPinsCount);
1086 DPRINT("AllNodesCount %lu\n", AllNodesCount);
1087
1088 /* now construct the source lines which are attached to the destination line */
1089 Index = AllPinsCount;
1090
1091 do
1092 {
1093 /* get current pin id */
1094 PinId = AllPins[Index - 1];
1095
1096 /* reset nodes count */
1097 AllPinNodesCount = 0;
1098
1099 /* now scan all nodes and add them to AllPinNodes array when they are connected to this pin */
1100 for(SubIndex = 0; SubIndex < AllNodesCount; SubIndex++)
1101 {
1102 /* get current node index */
1103 CurNode = AllNodes[SubIndex];
1104
1105 if (CurNode != MAXULONG && CurNode != LineTerminator)
1106 {
1107 /* check if that node is connected in some way to the current pin */
1108 Status = MMixerIsNodeConnectedToPin(MixerContext, Topology, CurNode, PinId, TRUE, &bConnected);
1109
1111 break;
1112
1113 if (bConnected)
1114 {
1115 /* it is connected */
1116 AllPinNodes[AllPinNodesCount] = CurNode;
1117 AllPinNodesCount++;
1118
1119 /* clear current index */
1120 AllNodes[SubIndex] = MAXULONG;
1121 }
1122 }
1123 }
1124
1125 /* decrement pin index */
1126 Index--;
1127
1128 if (AllPinNodesCount)
1129 {
1130#ifdef MMIXER_DEBUG
1131 ULONG TempIndex;
1132#endif
1133 /* now build the mixer source line */
1134 Status = MMixerBuildMixerSourceLine(MixerContext, MixerInfo, hMixer, Topology, PinId, AllPinNodesCount, AllPinNodes, DestinationLineID, &SrcLine);
1135
1137 {
1138 /* insert into line list */
1139 InsertTailList(&MixerInfo->LineList, &SrcLine->Entry);
1140
1141 /* increment destination line count */
1142 DstLine->Line.cConnections++;
1143
1144 /* mark pin as reserved */
1145 MMixerSetTopologyPinReserved(Topology, PinId);
1146
1147#ifdef MMIXER_DEBUG
1148 DPRINT1("Adding PinId %lu AllPinNodesCount %lu to DestinationLine %lu\n", PinId, AllPinNodesCount, DestinationLineID);
1149 for(TempIndex = 0; TempIndex < AllPinNodesCount; TempIndex++)
1150 DPRINT1("NodeIndex %lu\n", AllPinNodes[TempIndex]);
1151#endif
1152 }
1153 }
1154 else
1155 {
1156#ifdef MMIXER_DEBUG
1157 DPRINT1("Discarding DestinationLineID %lu PinId %lu NO NODES!\n", DestinationLineID, PinId);
1158#endif
1159 }
1160
1161 }while(Index != 0);
1162
1163 return MM_STATUS_SUCCESS;
1164}
#define DPRINT1
Definition: precomp.h:8
MIXER_STATUS MMixerBuildMixerSourceLine(IN PMIXER_CONTEXT MixerContext, IN OUT LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN PTOPOLOGY Topology, IN ULONG PinId, IN ULONG NodesCount, IN PULONG Nodes, IN ULONG DestinationLineID, OUT LPMIXERLINE_EXT *OutSrcLine)
Definition: controls.c:941
BOOL bConnected
Definition: fdebug.c:27
VOID MMixerSetTopologyPinReserved(IN PTOPOLOGY Topology, IN ULONG PinId)
Definition: topology.c:1202
MIXER_STATUS MMixerGetAllUpOrDownstreamNodesFromNodeIndex(IN PMIXER_CONTEXT MixerContext, IN PTOPOLOGY Topology, IN ULONG NodeIndex, IN ULONG bUpStream, OUT PULONG OutNodesCount, OUT PULONG OutNodes)
Definition: topology.c:785
VOID MMixerGetAllUpOrDownstreamPinsFromNodeIndex(IN PMIXER_CONTEXT MixerContext, IN PTOPOLOGY Topology, IN ULONG NodeIndex, IN ULONG bUpStream, OUT PULONG OutPinsCount, OUT PULONG OutPins)
Definition: topology.c:713
MIXER_STATUS MMixerIsNodeConnectedToPin(IN PMIXER_CONTEXT MixerContext, IN PTOPOLOGY Topology, IN ULONG NodeIndex, IN ULONG PinId, IN ULONG bUpStream, OUT PULONG bConnected)
Definition: topology.c:1119
MIXER_STATUS MMixerAllocateTopologyPinArray(IN PMIXER_CONTEXT MixerContext, IN PTOPOLOGY Topology, OUT PULONG *OutPins)
Definition: topology.c:1020
MIXERLINEW Line
Definition: precomp.h:89
LIST_ENTRY Entry
Definition: precomp.h:87
DWORD cConnections
Definition: mmsystem.h:1263
#define MAXULONG
Definition: typedefs.h:251

Referenced by MMixerHandleAlternativeMixers(), MMixerHandlePhysicalConnection(), and MMixerHandleTopologyFilter().

◆ MMixerApplyOutputFilterHack()

VOID MMixerApplyOutputFilterHack ( IN PMIXER_CONTEXT  MixerContext,
IN LPMIXER_DATA  MixerData,
IN HANDLE  hMixer,
IN OUT PULONG  PinsCount,
IN OUT PULONG  Pins 
)

Definition at line 1230 of file controls.c.

1236{
1237 ULONG Count = 0, Index;
1239 PKSPIN_PHYSICALCONNECTION Connection;
1240
1241 for(Index = 0; Index < *PinsCount; Index++)
1242 {
1243 /* check if it has a physical connection */
1245
1247 {
1248 /* remove pin */
1249 MixerContext->Copy(&Pins[Index], &Pins[Index + 1], (*PinsCount - (Index + 1)) * sizeof(ULONG));
1250
1251 /* free physical connection */
1252 MixerContext->Free(Connection);
1253
1254 /* decrement index */
1255 Index--;
1256
1257 /* decrement pin count */
1258 (*PinsCount)--;
1259 }
1260 else
1261 {
1262 /* simple pin */
1263 Count++;
1264 }
1265 }
1266
1267 /* store result */
1268 *PinsCount = Count;
1269}
MIXER_STATUS MMixerGetPhysicalConnection(IN PMIXER_CONTEXT MixerContext, IN HANDLE hMixer, IN ULONG PinId, OUT PKSPIN_PHYSICALCONNECTION *OutConnection)
Definition: filter.c:91

Referenced by MMixerHandlePhysicalConnection(), and MMixerHandleTopologyFilter().

◆ MMixerBuildMixerDestinationLine()

MIXER_STATUS MMixerBuildMixerDestinationLine ( IN PMIXER_CONTEXT  MixerContext,
IN OUT LPMIXER_INFO  MixerInfo,
IN HANDLE  hMixer,
IN ULONG  PinId,
IN ULONG  bInput 
)

Definition at line 352 of file controls.c.

358{
359 LPWSTR PinName;
361
362 /* try get pin name */
363 Status = MMixerGetPinName(MixerContext, MixerInfo, hMixer, PinId, &PinName);
365 {
366 /* create mixer destination line */
367
368 Status = MMixerCreateDestinationLine(MixerContext, MixerInfo, bInput, PinName);
369
370 /* free pin name */
371 MixerContext->Free(PinName);
372 }
373 else
374 {
375 /* create mixer destination line unlocalized */
376 Status = MMixerCreateDestinationLine(MixerContext, MixerInfo, bInput, L"No Name");
377 }
378
379 return Status;
380}
MIXER_STATUS MMixerGetPinName(IN PMIXER_CONTEXT MixerContext, IN LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN ULONG PinId, IN OUT LPWSTR *OutBuffer)
Definition: controls.c:300
MIXER_STATUS MMixerCreateDestinationLine(IN PMIXER_CONTEXT MixerContext, IN LPMIXER_INFO MixerInfo, IN ULONG bInputMixer, IN LPWSTR LineName)
Definition: controls.c:238

Referenced by MMixerHandleAlternativeMixers(), MMixerHandlePhysicalConnection(), MMixerHandleTopologyFilter(), and MMixerInitializeFilter().

◆ MMixerBuildMixerSourceLine()

MIXER_STATUS MMixerBuildMixerSourceLine ( IN PMIXER_CONTEXT  MixerContext,
IN OUT LPMIXER_INFO  MixerInfo,
IN HANDLE  hMixer,
IN PTOPOLOGY  Topology,
IN ULONG  PinId,
IN ULONG  NodesCount,
IN PULONG  Nodes,
IN ULONG  DestinationLineID,
OUT LPMIXERLINE_EXT OutSrcLine 
)

Definition at line 941 of file controls.c.

951{
952 LPMIXERLINE_EXT SrcLine, DstLine;
953 LPWSTR PinName;
955 ULONG ComponentType, TargetType;
956
957 /* get component and target type */
958 Status = MMixerGetComponentAndTargetType(MixerContext, MixerInfo, hMixer, PinId, &ComponentType, &TargetType);
960 {
961 /* failed to get component status */
964 }
965
966 /* construct source line */
967 SrcLine = (LPMIXERLINE_EXT)MixerContext->Alloc(sizeof(MIXERLINE_EXT));
968
969 if (!SrcLine)
970 {
971 /* no memory */
972 return MM_STATUS_NO_MEMORY;
973 }
974
975 /* get destination line */
976 DstLine = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
977 ASSERT(DstLine);
978
979 /* initialize mixer src line */
980 SrcLine->PinId = PinId;
981
982 /* initialize mixer line */
983 SrcLine->Line.cbStruct = sizeof(MIXERLINEW);
984 SrcLine->Line.dwDestination = MixerInfo->MixCaps.cDestinations-1;
985 SrcLine->Line.dwSource = DstLine->Line.cConnections;
986 SrcLine->Line.dwLineID = (DstLine->Line.cConnections * SOURCE_LINE)+ (MixerInfo->MixCaps.cDestinations-1);
988 SrcLine->Line.dwComponentType = ComponentType;
989 SrcLine->Line.dwUser = 0;
990 SrcLine->Line.cChannels = DstLine->Line.cChannels;
991 SrcLine->Line.cConnections = 0;
992 SrcLine->Line.Target.dwType = TargetType;
993 SrcLine->Line.Target.dwDeviceID = DstLine->Line.Target.dwDeviceID;
994 SrcLine->Line.Target.wMid = MixerInfo->MixCaps.wMid;
995 SrcLine->Line.Target.wPid = MixerInfo->MixCaps.wPid;
996 SrcLine->Line.Target.vDriverVersion = MixerInfo->MixCaps.vDriverVersion;
998
999 /* copy name */
1000 ASSERT(MixerInfo->MixCaps.szPname[MAXPNAMELEN-1] == L'\0');
1001 wcscpy(SrcLine->Line.Target.szPname, MixerInfo->MixCaps.szPname);
1002
1003 /* get pin name */
1004 Status = MMixerGetPinName(MixerContext, MixerInfo, hMixer, PinId, &PinName);
1005
1007 {
1008 /* store pin name as line name */
1009 MixerContext->Copy(SrcLine->Line.szShortName, PinName, (min(MIXER_SHORT_NAME_CHARS, wcslen(PinName)+1)) * sizeof(WCHAR));
1010 SrcLine->Line.szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
1011
1012 MixerContext->Copy(SrcLine->Line.szName, PinName, (min(MIXER_LONG_NAME_CHARS, wcslen(PinName)+1)) * sizeof(WCHAR));
1013 SrcLine->Line.szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
1014
1015 /* free pin name buffer */
1016 MixerContext->Free(PinName);
1017 }
1018
1019 /* add the controls to mixer line */
1020 Status = MMixerAddMixerControlsToMixerLineByNodeIndexArray(MixerContext, MixerInfo, hMixer, Topology, SrcLine, NodesCount, Nodes);
1022 {
1023 /* failed */
1024 return Status;
1025 }
1026
1027 /* store result */
1028 *OutSrcLine = SrcLine;
1029
1030 return MM_STATUS_SUCCESS;
1031}
MIXER_STATUS MMixerGetComponentAndTargetType(IN PMIXER_CONTEXT MixerContext, IN OUT LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN ULONG PinId, OUT PULONG ComponentType, OUT PULONG TargetType)
Definition: controls.c:742
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define MIXERLINE_COMPONENTTYPE_DST_UNDEFINED
Definition: mmsystem.h:315
#define MAXPNAMELEN
Definition: mmsystem.h:24
#define MIXERLINE_LINEF_ACTIVE
Definition: mmsystem.h:311
#define MIXERLINE_TARGETTYPE_UNDEFINED
Definition: mmsystem.h:338
struct tagMIXERLINEW MIXERLINEW
#define MIXERLINE_LINEF_SOURCE
Definition: mmsystem.h:313
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
struct MIXERLINE_EXT * LPMIXERLINE_EXT
#define SOURCE_LINE
Definition: precomp.h:177
LIST_ENTRY ControlsList
Definition: precomp.h:90
ULONG PinId
Definition: precomp.h:88
DWORD fdwLine
Definition: mmsystem.h:1259
DWORD dwDestination
Definition: mmsystem.h:1256
DWORD dwSource
Definition: mmsystem.h:1257
DWORD dwLineID
Definition: mmsystem.h:1258
WCHAR szName[MIXER_LONG_NAME_CHARS]
Definition: mmsystem.h:1266
DWORD cChannels
Definition: mmsystem.h:1262
DWORD_PTR dwUser
Definition: mmsystem.h:1260
struct tagMIXERLINEW::@3021 Target
DWORD cbStruct
Definition: mmsystem.h:1255
DWORD dwComponentType
Definition: mmsystem.h:1261
WCHAR szShortName[MIXER_SHORT_NAME_CHARS]
Definition: mmsystem.h:1265

Referenced by MMixerAddMixerSourceLines().

◆ MMixerBuildTopology()

MIXER_STATUS MMixerBuildTopology ( IN PMIXER_CONTEXT  MixerContext,
IN LPMIXER_DATA  MixerData,
OUT PTOPOLOGY OutTopology 
)

Definition at line 383 of file controls.c.

387{
388 ULONG PinsCount;
389 PKSMULTIPLE_ITEM NodeTypes = NULL;
390 PKSMULTIPLE_ITEM NodeConnections = NULL;
392
393 if (MixerData->Topology)
394 {
395 /* re-use existing topology */
396 *OutTopology = MixerData->Topology;
397
398 return MM_STATUS_SUCCESS;
399 }
400
401 /* get connected filter pin count */
402 PinsCount = MMixerGetFilterPinCount(MixerContext, MixerData->hDevice);
403
404 if (!PinsCount)
405 {
406 /* referenced filter does not have any pins */
408 }
409
410 /* get topology node types */
413 {
414 /* failed to get topology node types */
415 return Status;
416 }
417
418 /* get topology connections */
421 {
422 /* failed to get topology connections */
423 MixerContext->Free(NodeTypes);
424 return Status;
425 }
426
427 /* create a topology */
428 Status = MMixerCreateTopology(MixerContext, PinsCount, NodeConnections, NodeTypes, OutTopology);
429
430 /* free node types & connections */
431 MixerContext->Free(NodeConnections);
432 MixerContext->Free(NodeTypes);
433
435 {
436 /* store topology object */
437 MixerData->Topology = *OutTopology;
438 }
439
440 /* done */
441 return Status;
442}
@ KSPROPERTY_TOPOLOGY_NODES
Definition: ks.h:846
@ KSPROPERTY_TOPOLOGY_CONNECTIONS
Definition: ks.h:847
@ MM_STATUS_UNSUCCESSFUL
Definition: mmixer.h:11
ULONG MMixerGetFilterPinCount(IN PMIXER_CONTEXT MixerContext, IN HANDLE hMixer)
Definition: filter.c:15
MIXER_STATUS MMixerGetFilterTopologyProperty(IN PMIXER_CONTEXT MixerContext, IN HANDLE hMixer, IN ULONG PropertyId, OUT PKSMULTIPLE_ITEM *OutMultipleItem)
Definition: filter.c:39
MIXER_STATUS MMixerCreateTopology(IN PMIXER_CONTEXT MixerContext, IN ULONG PinCount, IN PKSMULTIPLE_ITEM NodeConnections, IN PKSMULTIPLE_ITEM NodeTypes, OUT PTOPOLOGY *OutTopology)
Definition: topology.c:1253

Referenced by MMixerHandlePhysicalConnection(), and MMixerSetupFilter().

◆ MMixerCountMixerControls()

MIXER_STATUS MMixerCountMixerControls ( IN PMIXER_CONTEXT  MixerContext,
IN PTOPOLOGY  Topology,
IN ULONG  PinId,
IN ULONG  bInputMixer,
IN ULONG  bUpStream,
OUT PULONG  OutNodesCount,
OUT PULONG  OutNodes,
OUT PULONG  OutLineTerminator 
)

Definition at line 445 of file controls.c.

454{
455 PULONG Nodes;
456 ULONG NodesCount, NodeIndex, Count, bTerminator;
458
459 /* allocate an array to store all nodes which are upstream of this pin */
461
463 {
464 /* out of memory */
465 return STATUS_NO_MEMORY;
466 }
467
468 /* mark result array as zero */
469 *OutNodesCount = 0;
470
471 /* get next nodes */
472 MMixerGetNextNodesFromPinIndex(MixerContext, Topology, PinId, bUpStream, &NodesCount, Nodes);
473
474 if (NodesCount == 0)
475 {
476 /* a pin which is not connected from any node
477 * a) it is a topology bug (driver bug)
478 * b) the request is from an alternative mixer
479 alternative mixer code scans all pins which have not been used and tries to build lines
480 */
481 DPRINT1("MMixerCountMixerControls PinId %lu is not connected by any node\n", PinId);
482 MMixerPrintTopology(Topology);
484 }
485
486 /* assume no topology split before getting line terminator */
487 ASSERT(NodesCount == 1);
488
489 /* get first node */
490 NodeIndex = Nodes[0];
491 Count = 0;
492
493 do
494 {
495 /* check if the node is a terminator */
496 MMixerIsNodeTerminator(Topology, NodeIndex, &bTerminator);
497
498 if (bTerminator)
499 {
500 /* found terminator */
501 if (bInputMixer)
502 {
503 /* add mux source for source destination line */
504 OutNodes[Count] = NodeIndex;
505 Count++;
506 }
507 break;
508 }
509
510 /* store node id */
511 OutNodes[Count] = NodeIndex;
512
513 /* increment node count */
514 Count++;
515
516 /* get next nodes upstream */
517 MMixerGetNextNodesFromNodeIndex(MixerContext, Topology, NodeIndex, bUpStream, &NodesCount, Nodes);
518
519 if (NodesCount != 1)
520 {
521 DPRINT("PinId %lu bInputMixer %lu bUpStream %lu NodeIndex %lu is not connected", PinId, bInputMixer, bUpStream, NodeIndex);
522 break;
523 }
524
525 ASSERT(NodesCount == 1);
526
527 /* use first index */
528 NodeIndex = Nodes[0];
529
530 }while(TRUE);
531
532 /* free node index */
533 MixerContext->Free(Nodes);
534
535 /* store nodes count */
536 *OutNodesCount = Count;
537
538 /* store line terminator */
539 *OutLineTerminator = NodeIndex;
540
541 /* done */
542 return MM_STATUS_SUCCESS;
543}
VOID MMixerGetNextNodesFromPinIndex(IN PMIXER_CONTEXT MixerContext, IN PTOPOLOGY Topology, IN ULONG PinIndex, IN ULONG bUpStream, OUT PULONG OutNodesCount, OUT PULONG OutNodes)
Definition: topology.c:929
VOID MMixerIsNodeTerminator(IN PTOPOLOGY Topology, IN ULONG NodeIndex, OUT ULONG *bTerminator)
Definition: topology.c:1084
VOID MMixerPrintTopology()

Referenced by MMixerAddMixerControlsToDestinationLine().

◆ MMixerCreateDestinationLine()

MIXER_STATUS MMixerCreateDestinationLine ( IN PMIXER_CONTEXT  MixerContext,
IN LPMIXER_INFO  MixerInfo,
IN ULONG  bInputMixer,
IN LPWSTR  LineName 
)

Definition at line 238 of file controls.c.

243{
244 LPMIXERLINE_EXT DestinationLine;
245
246 /* allocate a mixer destination line */
247 DestinationLine = (LPMIXERLINE_EXT) MixerContext->Alloc(sizeof(MIXERLINE_EXT));
248 if (!MixerInfo)
249 {
250 /* no memory */
251 return MM_STATUS_NO_MEMORY;
252 }
253
254 /* initialize mixer destination line */
255 DestinationLine->Line.cbStruct = sizeof(MIXERLINEW);
256 DestinationLine->Line.cChannels = 2; /* FIXME */
257 DestinationLine->Line.cConnections = 0;
258 DestinationLine->Line.cControls = 0;
260 DestinationLine->Line.dwDestination = MixerInfo->MixCaps.cDestinations;
261 DestinationLine->Line.dwLineID = MixerInfo->MixCaps.cDestinations + DESTINATION_LINE;
262 DestinationLine->Line.dwSource = MAXULONG;
263 DestinationLine->Line.dwUser = 0;
264 DestinationLine->Line.fdwLine = MIXERLINE_LINEF_ACTIVE;
265
266
267 if (LineName)
268 {
269 MixerContext->Copy(DestinationLine->Line.szShortName, LineName, (min(MIXER_SHORT_NAME_CHARS, wcslen(LineName)+1)) * sizeof(WCHAR));
270 DestinationLine->Line.szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
271
272 MixerContext->Copy(DestinationLine->Line.szName, LineName, (min(MIXER_LONG_NAME_CHARS, wcslen(LineName)+1)) * sizeof(WCHAR));
273 DestinationLine->Line.szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
274
275 }
276
277 DestinationLine->Line.Target.dwType = (bInputMixer == 0 ? MIXERLINE_TARGETTYPE_WAVEOUT : MIXERLINE_TARGETTYPE_WAVEIN);
278 DestinationLine->Line.Target.dwDeviceID = 0; //FIXME
279 DestinationLine->Line.Target.wMid = MixerInfo->MixCaps.wMid;
280 DestinationLine->Line.Target.wPid = MixerInfo->MixCaps.wPid;
281 DestinationLine->Line.Target.vDriverVersion = MixerInfo->MixCaps.vDriverVersion;
282
283 ASSERT(MixerInfo->MixCaps.szPname[MAXPNAMELEN-1] == 0);
284 wcscpy(DestinationLine->Line.Target.szPname, MixerInfo->MixCaps.szPname);
285
286 /* initialize extra line */
287 InitializeListHead(&DestinationLine->ControlsList);
288
289 /* insert into mixer info */
290 InsertTailList(&MixerInfo->LineList, &DestinationLine->Entry);
291
292 /* increment destination count */
293 MixerInfo->MixCaps.cDestinations++;
294
295 /* done */
296 return MM_STATUS_SUCCESS;
297}
#define MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
Definition: mmsystem.h:319
#define MIXERLINE_TARGETTYPE_WAVEOUT
Definition: mmsystem.h:339
#define MIXERLINE_TARGETTYPE_WAVEIN
Definition: mmsystem.h:340
#define MIXERLINE_COMPONENTTYPE_DST_WAVEIN
Definition: mmsystem.h:322
#define DESTINATION_LINE
Definition: precomp.h:176
DWORD cControls
Definition: mmsystem.h:1264

Referenced by MMixerBuildMixerDestinationLine().

◆ MMixerGetChannelCountEnhanced()

MIXER_STATUS MMixerGetChannelCountEnhanced ( IN PMIXER_CONTEXT  MixerContext,
IN LPMIXER_INFO  MixerInfo,
IN HANDLE  hMixer,
IN ULONG  NodeId,
OUT PULONG  MaxChannels 
)

Definition at line 546 of file controls.c.

552{
554 PKSPROPERTY_DESCRIPTION NewDescription;
559
560 /* try #1 obtain it via description */
561 Request.NodeId = NodeId;
562 Request.Reserved = 0;
563 Request.Property.Set = KSPROPSETID_Audio;
566
567
568 /* get description */
571 {
572 if (Description.DescriptionSize >= sizeof(KSPROPERTY_DESCRIPTION) + sizeof(KSPROPERTY_MEMBERSHEADER) && (Description.MembersListCount > 0))
573 {
574 /* allocate new description */
575 NewDescription = MixerContext->Alloc(Description.DescriptionSize);
576
577 if (!NewDescription)
578 {
579 /* not enough memory */
580 return MM_STATUS_NO_MEMORY;
581 }
582
583 /* get description */
584 Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSP_NODE), (PVOID)NewDescription, Description.DescriptionSize, &BytesReturned);
586 {
587 /* get header */
588 Header = (PKSPROPERTY_MEMBERSHEADER)(NewDescription + 1);
589
591 {
592 /* found enhanced flag */
593 ASSERT(Header->MembersCount > 1);
594
595 /* store channel count */
596 *MaxChannels = Header->MembersCount;
597
598 /* free description */
599 MixerContext->Free(NewDescription);
600
601 /* done */
602 return MM_STATUS_SUCCESS;
603 }
604 }
605
606 /* free description */
607 MixerContext->Free(NewDescription);
608 }
609 }
610
611 /* failed to get channel count enhanced */
613}
Definition: Header.h:9
static const WCHAR Description[]
Definition: oid.c:1266
#define KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL
Definition: ks.h:1564
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547

Referenced by MMixerGetMaxChannelsForNode().

◆ MMixerGetChannelCountLegacy()

VOID MMixerGetChannelCountLegacy ( IN PMIXER_CONTEXT  MixerContext,
IN LPMIXER_INFO  MixerInfo,
IN HANDLE  hMixer,
IN ULONG  NodeId,
OUT PULONG  MaxChannels 
)

Definition at line 616 of file controls.c.

622{
626 LONG Volume;
627
628 /* setup request */
629 Channel.Reserved = 0;
630 Channel.NodeProperty.NodeId = NodeId;
631 Channel.NodeProperty.Reserved = 0;
634 Channel.Channel = 0;
636
637 do
638 {
639 /* get channel volume */
642 break;
643
644 /* increment channel count */
645 Channel.Channel++;
646
647 }while(TRUE);
648
649 /* store channel count */
650 *MaxChannels = Channel.Channel;
651
652}
UNICODE_STRING Volume
Definition: fltkernel.h:1172
ULONG Id
Definition: dmksctrl.h:77
ULONG Flags
Definition: dmksctrl.h:78
GUID Set
Definition: dmksctrl.h:76
KSNODEPROPERTY NodeProperty
Definition: ksmedia.h:1240
ULONG NodeId
Definition: ksmedia.h:1234
KSPROPERTY Property
Definition: ksmedia.h:1233
ULONG Reserved
Definition: ksmedia.h:1235

Referenced by MMixerGetMaxChannelsForNode().

◆ MMixerGetComponentAndTargetType()

MIXER_STATUS MMixerGetComponentAndTargetType ( IN PMIXER_CONTEXT  MixerContext,
IN OUT LPMIXER_INFO  MixerInfo,
IN HANDLE  hMixer,
IN ULONG  PinId,
OUT PULONG  ComponentType,
OUT PULONG  TargetType 
)

Definition at line 742 of file controls.c.

749{
751 KSPIN_COMMUNICATION Communication;
755 GUID Guid;
756 BOOLEAN BridgePin = FALSE;
757 PKSPIN_PHYSICALCONNECTION Connection;
758
759 /* first dataflow type */
761
763 {
764 /* failed to get dataflow */
765 return Status;
766 }
767
768 /* now get pin category guid */
769 Request.PinId = PinId;
770 Request.Reserved = 0;
771 Request.Property.Flags = KSPROPERTY_TYPE_GET;
772 Request.Property.Set = KSPROPSETID_Pin;
773 Request.Property.Id = KSPROPERTY_PIN_CATEGORY;
774
775
776 /* get pin category */
779 {
780 /* failed to get dataflow */
781 return Status;
782 }
783
784 /* check if it has a physical connection */
787 {
788 /* pin is a brige pin */
789 BridgePin = TRUE;
790
791 /* free physical connection */
792 MixerContext->Free(Connection);
793 }
794
796 {
799 {
800 /* type microphone */
801 *TargetType = MIXERLINE_TARGETTYPE_WAVEIN;
803 }
807 {
808 /* type waveout */
809 *TargetType = MIXERLINE_TARGETTYPE_WAVEOUT;
811 }
813 {
814 /* type cd player */
815 *TargetType = MIXERLINE_TARGETTYPE_UNDEFINED;
817 }
819 {
820 /* type synthesizer */
821 *TargetType = MIXERLINE_TARGETTYPE_MIDIOUT;
823 }
825 {
826 /* type line */
827 *TargetType = MIXERLINE_TARGETTYPE_UNDEFINED;
828 *ComponentType = MIXERLINE_COMPONENTTYPE_SRC_LINE;
829 }
833 {
834 /* type telephone */
835 *TargetType = MIXERLINE_TARGETTYPE_UNDEFINED;
837 }
839 {
840 /* type analog */
841 if (BridgePin)
842 *TargetType = MIXERLINE_TARGETTYPE_WAVEIN;
843 else
844 *TargetType = MIXERLINE_TARGETTYPE_WAVEOUT;
845
846 *ComponentType = MIXERLINE_COMPONENTTYPE_SRC_ANALOG;
847 }
849 {
850 /* type analog */
851 if (BridgePin)
852 *TargetType = MIXERLINE_TARGETTYPE_WAVEIN;
853 else
854 *TargetType = MIXERLINE_TARGETTYPE_WAVEOUT;
855
857 }
858 else
859 {
860 /* unknown type */
861 *TargetType = MIXERLINE_TARGETTYPE_UNDEFINED;
863 DPRINT1("Unknown Category for PinId %lu BridgePin %lu\n", PinId, BridgePin);
864 }
865 }
866 else
867 {
872 {
873 /* type waveout */
874 *TargetType = MIXERLINE_TARGETTYPE_WAVEOUT;
876 }
879 {
880 /* type wavein */
881 *TargetType = MIXERLINE_TARGETTYPE_WAVEIN;
882 *ComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
883 }
886 {
887 /* type head phones */
888 *TargetType = MIXERLINE_TARGETTYPE_WAVEOUT;
890 }
894 {
895 /* type waveout */
896 *TargetType = MIXERLINE_TARGETTYPE_UNDEFINED;
898 }
900 {
901 /* type analog */
902 if (BridgePin)
903 {
904 *TargetType = MIXERLINE_TARGETTYPE_WAVEOUT;
906 }
907 else
908 {
909 *TargetType = MIXERLINE_TARGETTYPE_WAVEIN;
910 *ComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
911 }
912 }
914 {
915 /* type spdif */
916 if (BridgePin)
917 {
918 *TargetType = MIXERLINE_TARGETTYPE_WAVEOUT;
920 }
921 else
922 {
923 *TargetType = MIXERLINE_TARGETTYPE_WAVEIN;
924 *ComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
925 }
926 }
927 else
928 {
929 /* unknown type */
930 *TargetType = MIXERLINE_TARGETTYPE_UNDEFINED;
932 DPRINT1("Unknown Category for PinId %lu BridgePin %lu\n", PinId, BridgePin);
933 }
934 }
935
936 /* done */
937 return MM_STATUS_SUCCESS;
938}
unsigned char BOOLEAN
const GUID KSNODETYPE_PHONE_LINE
Definition: controls.c:17
const GUID KSNODETYPE_ROOM_SPEAKER
Definition: controls.c:20
const GUID KSNODETYPE_SPEAKER
Definition: controls.c:28
const GUID KSNODETYPE_HEADPHONES
Definition: controls.c:22
const GUID KSNODETYPE_COMMUNICATION_SPEAKER
Definition: controls.c:21
const GUID KSNODETYPE_DESKTOP_SPEAKER
Definition: controls.c:19
const GUID KSNODETYPE_LEGACY_AUDIO_CONNECTOR
Definition: controls.c:15
const GUID KSNODETYPE_DOWN_LINE_PHONE
Definition: controls.c:18
const GUID KSNODETYPE_TELEPHONE
Definition: controls.c:16
const GUID KSNODETYPE_LINE_CONNECTOR
Definition: controls.c:31
const GUID KSNODETYPE_MICROPHONE
Definition: controls.c:24
const GUID KSNODETYPE_ANALOG_CONNECTOR
Definition: controls.c:27
const GUID KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO
Definition: controls.c:23
const GUID KSNODETYPE_SYNTHESIZER
Definition: controls.c:30
const GUID KSCATEGORY_AUDIO
Definition: controls.c:25
const GUID KSNODETYPE_DESKTOP_MICROPHONE
Definition: controls.c:14
const GUID KSNODETYPE_CD_PLAYER
Definition: controls.c:29
const GUID KSNODETYPE_SPDIF_INTERFACE
Definition: controls.c:26
DataFlow
#define FALSE
Definition: types.h:117
#define KSPROPSETID_Pin
Definition: ks.h:617
@ KSPROPERTY_PIN_CATEGORY
Definition: ks.h:636
KSPIN_DATAFLOW
Definition: ks.h:1248
@ KSPIN_DATAFLOW_IN
Definition: ks.h:1249
KSPIN_COMMUNICATION
Definition: ks.h:1253
#define PINNAME_CAPTURE
Definition: ksmedia.h:147
#define MIXERLINE_COMPONENTTYPE_DST_TELEPHONE
Definition: mmsystem.h:321
#define MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED
Definition: mmsystem.h:326
#define MIXERLINE_COMPONENTTYPE_SRC_DIGITAL
Definition: mmsystem.h:327
#define MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE
Definition: mmsystem.h:329
#define MIXERLINE_TARGETTYPE_MIDIOUT
Definition: mmsystem.h:341
#define MIXERLINE_COMPONENTTYPE_DST_HEADPHONES
Definition: mmsystem.h:320
#define MIXERLINE_COMPONENTTYPE_SRC_ANALOG
Definition: mmsystem.h:336
#define MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER
Definition: mmsystem.h:330
#define MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT
Definition: mmsystem.h:334
#define MIXERLINE_COMPONENTTYPE_SRC_LINE
Definition: mmsystem.h:328
#define MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE
Definition: mmsystem.h:332
#define MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC
Definition: mmsystem.h:331
MIXER_STATUS MMixerGetPinDataFlowAndCommunication(IN PMIXER_CONTEXT MixerContext, IN HANDLE hDevice, IN ULONG PinId, OUT PKSPIN_DATAFLOW DataFlow, OUT PKSPIN_COMMUNICATION Communication)
Definition: midi.c:15
Definition: ks.h:642
_Must_inspect_result_ _In_ WDFOBJECT _In_ CONST GUID * Guid
Definition: wdfobject.h:762

Referenced by MMixerBuildMixerSourceLine().

◆ MMixerGetMaxChannelsForNode()

VOID MMixerGetMaxChannelsForNode ( IN PMIXER_CONTEXT  MixerContext,
IN LPMIXER_INFO  MixerInfo,
IN HANDLE  hMixer,
IN ULONG  NodeId,
OUT PULONG  MaxChannels 
)

Definition at line 655 of file controls.c.

661{
663
664 /* try to get it enhanced */
665 Status = MMixerGetChannelCountEnhanced(MixerContext, MixerInfo, hMixer, NodeId, MaxChannels);
666
668 {
669 /* get it old-fashioned way */
670 MMixerGetChannelCountLegacy(MixerContext, MixerInfo, hMixer, NodeId, MaxChannels);
671 }
672}
MIXER_STATUS MMixerGetChannelCountEnhanced(IN PMIXER_CONTEXT MixerContext, IN LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN ULONG NodeId, OUT PULONG MaxChannels)
Definition: controls.c:546
VOID MMixerGetChannelCountLegacy(IN PMIXER_CONTEXT MixerContext, IN LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN ULONG NodeId, OUT PULONG MaxChannels)
Definition: controls.c:616

Referenced by MMixerAddMixerControlsToMixerLineByNodeIndexArray().

◆ MMixerGetPinName()

MIXER_STATUS MMixerGetPinName ( IN PMIXER_CONTEXT  MixerContext,
IN LPMIXER_INFO  MixerInfo,
IN HANDLE  hMixer,
IN ULONG  PinId,
IN OUT LPWSTR OutBuffer 
)

Definition at line 300 of file controls.c.

306{
307 KSP_PIN Pin;
311
312 /* prepare pin */
313 Pin.PinId = PinId;
314 Pin.Reserved = 0;
315 Pin.Property.Flags = KSPROPERTY_TYPE_GET;
316 Pin.Property.Set = KSPROPSETID_Pin;
317 Pin.Property.Id = KSPROPERTY_PIN_NAME;
318
319 /* try get pin name size */
321
322 /* check if buffer overflowed */
324 {
325 /* allocate buffer */
327 if (!Buffer)
328 {
329 /* out of memory */
330 return MM_STATUS_NO_MEMORY;
331 }
332
333 /* try get pin name */
336 {
337 /* failed to get pin name */
339 return Status;
340 }
341
342 /* successfully obtained pin name */
343 *OutBuffer = Buffer;
344 return MM_STATUS_SUCCESS;
345 }
346
347 /* failed to get pin name */
348 return Status;
349}
Definition: bufpool.h:45
IN PDCB IN VBO IN ULONG IN BOOLEAN Pin
Definition: fatprocs.h:427
@ KSPROPERTY_PIN_NAME
Definition: ks.h:637
_In_ UCHAR _In_ ULONG _Out_ PUCHAR _Outptr_result_bytebuffer_ OutBufferLength PVOID * OutBuffer
Definition: scsi.h:4071
ULONG Flags
Definition: ntfs.h:536

Referenced by MMixerBuildMixerDestinationLine(), and MMixerBuildMixerSourceLine().

◆ MMixerHandleAlternativeMixers()

VOID MMixerHandleAlternativeMixers ( IN PMIXER_CONTEXT  MixerContext,
IN PMIXER_LIST  MixerList,
IN LPMIXER_DATA  MixerData,
IN PTOPOLOGY  Topology 
)

Definition at line 1682 of file controls.c.

1687{
1690 ULONG DestinationLineID, LineTerminator;
1691 LPMIXERLINE_EXT DstLine;
1692
1693 DPRINT("DeviceName %S\n", MixerData->DeviceName);
1694
1695 /* get topology pin count */
1697
1698 for(Index = 0; Index < PinCount; Index++)
1699 {
1701
1702 /* check if it has already been reserved */
1703 if (Reserved)
1704 {
1705 /* pin has already been reserved */
1706 continue;
1707 }
1708
1709 DPRINT("MixerName %S Available PinID %lu\n", MixerData->DeviceName, Index);
1710
1711 /* sanity check */
1712 //ASSERT(MixerData->MixerInfo);
1713
1714 if (!MixerData->MixerInfo)
1715 {
1716 DPRINT1("Expected mixer info\n");
1717 continue;
1718 }
1719
1720 /* build the destination line */
1721 Status = MMixerBuildMixerDestinationLine(MixerContext, MixerData->MixerInfo, MixerData->hDevice, Index, TRUE);
1723 {
1724 /* failed to build destination line */
1725 continue;
1726 }
1727
1728 /* calculate destination line id */
1729 DestinationLineID = (DESTINATION_LINE + MixerData->MixerInfo->MixCaps.cDestinations-1);
1730
1731 /* add mixer controls to destination line */
1732 Status = MMixerAddMixerControlsToDestinationLine(MixerContext, MixerData->MixerInfo, MixerData->hDevice, MixerData->Topology, Index, TRUE, DestinationLineID, &LineTerminator);
1734 {
1735 /* now add the rest of the source lines */
1736 Status = MMixerAddMixerSourceLines(MixerContext, MixerData->MixerInfo, MixerData->hDevice, MixerData->Topology, DestinationLineID, LineTerminator);
1737 }
1738
1739 /* mark pin as consumed */
1741
1742 /* now grab destination line */
1743 DstLine = MMixerGetSourceMixerLineByLineId(MixerData->MixerInfo, DestinationLineID);
1744
1745 /* set type and target as undefined */
1747 DstLine->Line.Target.dwType = MIXERLINE_TARGETTYPE_UNDEFINED;
1748 DstLine->Line.Target.vDriverVersion = 0;
1749 DstLine->Line.Target.wMid = 0;
1750 DstLine->Line.Target.wPid = 0;
1751 }
1752}
MIXER_STATUS MMixerAddMixerSourceLines(IN PMIXER_CONTEXT MixerContext, IN OUT LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN PTOPOLOGY Topology, IN ULONG DestinationLineID, IN ULONG LineTerminator)
Definition: controls.c:1034
MIXER_STATUS MMixerAddMixerControlsToDestinationLine(IN PMIXER_CONTEXT MixerContext, IN OUT LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN PTOPOLOGY Topology, IN ULONG PinId, IN ULONG bInput, IN ULONG DestinationLineId, OUT PULONG OutLineTerminator)
Definition: controls.c:1168
MIXER_STATUS MMixerBuildMixerDestinationLine(IN PMIXER_CONTEXT MixerContext, IN OUT LPMIXER_INFO MixerInfo, IN HANDLE hMixer, IN ULONG PinId, IN ULONG bInput)
Definition: controls.c:352
VOID MMixerGetTopologyPinCount(IN PTOPOLOGY Topology, OUT PULONG PinCount)
Definition: topology.c:1011
VOID MMixerIsTopologyPinReserved(IN PTOPOLOGY Topology, IN ULONG PinId, OUT PULONG bReserved)
Definition: topology.c:1214
_In_ const GUID _In_ ULONG PinCount
Definition: strmini.h:505
_Reserved_ PVOID Reserved
Definition: winddi.h:3974

Referenced by MMixerInitialize().

◆ MMixerHandlePhysicalConnection()

MIXER_STATUS MMixerHandlePhysicalConnection ( IN PMIXER_CONTEXT  MixerContext,
IN PMIXER_LIST  MixerList,
IN LPMIXER_DATA  MixerData,
IN OUT LPMIXER_INFO  MixerInfo,
IN ULONG  bInput,
IN PKSPIN_PHYSICALCONNECTION  OutConnection 
)

Definition at line 1376 of file controls.c.

1383{
1385 ULONG PinsCount, LineTerminator, DestinationLineID;
1386 PULONG Pins;
1387 PTOPOLOGY Topology;
1388
1389 /* first try to open the connected filter */
1390 OutConnection->SymbolicLinkName[1] = L'\\';
1391 MixerData = MMixerGetDataByDeviceName(MixerList, OutConnection->SymbolicLinkName);
1392
1393 /* check if the linked connection is found */
1394 if (!MixerData)
1395 {
1396 /* filter references invalid physical connection */
1398 }
1399
1400 DPRINT("Name %S, Pin %lu bInput %lu\n", OutConnection->SymbolicLinkName, OutConnection->Pin, bInput);
1401
1402 /* sanity check */
1403 ASSERT(MixerData->MixerInfo == NULL || MixerData->MixerInfo == MixerInfo);
1404
1405 /* associate with mixer */
1406 MixerData->MixerInfo = MixerInfo;
1407
1408 if (MixerData->Topology == NULL)
1409 {
1410 /* construct new topology */
1411 Status = MMixerBuildTopology(MixerContext, MixerData, &Topology);
1413 {
1414 /* failed to create topology */
1415 return Status;
1416 }
1417
1418 /* store topology */
1419 MixerData->Topology = Topology;
1420 }
1421 else
1422 {
1423 /* re-use existing topology */
1424 Topology = MixerData->Topology;
1425 }
1426
1427 /* mark pin as consumed */
1428 MMixerSetTopologyPinReserved(Topology, OutConnection->Pin);
1429
1430 if (!bInput)
1431 {
1432 /* allocate pin index array which will hold all referenced pins */
1435 {
1436 /* failed to create topology */
1437 return Status;
1438 }
1439
1440 /* the mixer is an output mixer
1441 * find end pin of the node path
1442 */
1443 PinsCount = 0;
1444 Status = MMixerGetAllUpOrDownstreamPinsFromPinIndex(MixerContext, Topology, OutConnection->Pin, FALSE, &PinsCount, Pins);
1445
1446 /* check for success */
1448 {
1449 /* failed to get end pin */
1450 MixerContext->Free(Pins);
1451 //MMixerFreeTopology(Topology);
1452
1453 /* return error code */
1454 return Status;
1455 }
1456 /* HACK:
1457 * some topologies do not have strict boundaries
1458 * WorkArround: remove all pin ids which have a physical connection
1459 * because bridge pins may belong to different render paths
1460 */
1461 MMixerApplyOutputFilterHack(MixerContext, MixerData, MixerData->hDevice, &PinsCount, Pins);
1462
1463 /* sanity checks */
1464 ASSERT(PinsCount != 0);
1465 if (PinsCount != 1)
1466 {
1467 DPRINT1("MMixerHandlePhysicalConnection Expected 1 pin but got %lu\n", PinsCount);
1468 }
1469
1470 /* create destination line */
1471 Status = MMixerBuildMixerDestinationLine(MixerContext, MixerInfo, MixerData->hDevice, Pins[0], bInput);
1472
1473 /* calculate destination line id */
1474 DestinationLineID = (DESTINATION_LINE + MixerInfo->MixCaps.cDestinations-1);
1475
1477 {
1478 /* failed to build destination line */
1479 MixerContext->Free(Pins);
1480
1481 /* return error code */
1482 return Status;
1483 }
1484
1485 /* add mixer controls to destination line */
1486 Status = MMixerAddMixerControlsToDestinationLine(MixerContext, MixerInfo, MixerData->hDevice, Topology, Pins[0], bInput, DestinationLineID, &LineTerminator);
1487
1489 {
1490 /* now add the rest of the source lines */
1491 Status = MMixerAddMixerSourceLines(MixerContext, MixerInfo, MixerData->hDevice, Topology, DestinationLineID, LineTerminator);
1492 }
1493
1494 /* mark pin as consumed */
1495 MMixerSetTopologyPinReserved(Topology, Pins[0]);
1496
1497 /* free topology pin array */
1498 MixerContext->Free(Pins);
1499 }
1500 else
1501 {
1502 /* calculate destination line id */
1503 DestinationLineID = (DESTINATION_LINE + MixerInfo->MixCaps.cDestinations-1);
1504
1505 /* add mixer controls */
1506 Status = MMixerAddMixerControlsToDestinationLine(MixerContext, MixerInfo, MixerData->hDevice, Topology, OutConnection->Pin, bInput, DestinationLineID, &LineTerminator);
1507
1509 {
1510 /* now add the rest of the source lines */
1511 Status = MMixerAddMixerSourceLines(MixerContext, MixerInfo, MixerData->hDevice, Topology, DestinationLineID, LineTerminator);
1512 }
1513 }
1514
1515 return Status;
1516}
MIXER_STATUS MMixerBuildTopology(IN PMIXER_CONTEXT MixerContext, IN LPMIXER_DATA MixerData, OUT PTOPOLOGY *OutTopology)
Definition: controls.c:383
VOID MMixerApplyOutputFilterHack(IN PMIXER_CONTEXT MixerContext, IN LPMIXER_DATA MixerData, IN HANDLE hMixer, IN OUT PULONG PinsCount, IN OUT PULONG Pins)
Definition: controls.c:1230
LPMIXER_DATA MMixerGetDataByDeviceName(IN PMIXER_LIST MixerList, IN LPWSTR DeviceName)
Definition: sup.c:759
MIXER_STATUS MMixerGetAllUpOrDownstreamPinsFromPinIndex(IN PMIXER_CONTEXT MixerContext, IN PTOPOLOGY Topology, IN ULONG PinIndex, IN ULONG bUpStream, OUT PULONG OutPinsCount, OUT PULONG OutPins)
Definition: topology.c:813

Referenced by MMixerInitializeFilter().

◆ MMixerHandleTopologyFilter()

MIXER_STATUS MMixerHandleTopologyFilter ( IN PMIXER_CONTEXT  MixerContext,
IN PMIXER_LIST  MixerList,
IN LPMIXER_DATA  MixerData,
IN OUT LPMIXER_INFO  MixerInfo,
IN ULONG  bInput,
IN ULONG  Pin 
)

Definition at line 1272 of file controls.c.

1279{
1281 ULONG PinsCount, LineTerminator, DestinationLineID;
1282 PULONG Pins;
1283 PTOPOLOGY Topology;
1284
1285 /* re-use existing topology */
1286 Topology = MixerData->Topology;
1287
1288 if (!bInput)
1289 {
1290 /* allocate pin index array which will hold all referenced pins */
1293 {
1294 /* failed to create topology */
1295 return Status;
1296 }
1297
1298 /* the mixer is an output mixer
1299 * find end pin of the node path
1300 */
1301 PinsCount = 0;
1303
1304 /* check for success */
1306 {
1307 /* failed to get end pin */
1308 MixerContext->Free(Pins);
1309 //MMixerFreeTopology(Topology);
1310
1311 /* return error code */
1312 return Status;
1313 }
1314 /* HACK:
1315 * some topologies do not have strict boundaries
1316 * WorkArround: remove all pin ids which have a physical connection
1317 * because bridge pins may belong to different render paths
1318 */
1319 MMixerApplyOutputFilterHack(MixerContext, MixerData, MixerData->hDevice, &PinsCount, Pins);
1320
1321 /* sanity checks */
1322 ASSERT(PinsCount != 0);
1323 if (PinsCount != 1)
1324 {
1325 DPRINT1("MMixerHandlePhysicalConnection Expected 1 pin but got %lu\n", PinsCount);
1326 }
1327
1328 /* create destination line */
1329 Status = MMixerBuildMixerDestinationLine(MixerContext, MixerInfo, MixerData->hDevice, Pins[0], bInput);
1330
1331 /* calculate destination line id */
1332 DestinationLineID = (DESTINATION_LINE + MixerInfo->MixCaps.cDestinations - 1);
1333
1335 {
1336 /* failed to build destination line */
1337 MixerContext->Free(Pins);
1338
1339 /* return error code */
1340 return Status;
1341 }
1342
1343 /* add mixer controls to destination line */
1344 Status = MMixerAddMixerControlsToDestinationLine(MixerContext, MixerInfo, MixerData->hDevice, Topology, Pins[0], bInput, DestinationLineID, &LineTerminator);
1345
1347 {
1348 /* now add the rest of the source lines */
1349 Status = MMixerAddMixerSourceLines(MixerContext, MixerInfo, MixerData->hDevice, Topology, DestinationLineID, LineTerminator);
1350 }
1351
1352 /* mark pin as consumed */
1353 MMixerSetTopologyPinReserved(Topology, Pins[0]);
1354
1355 /* free topology pin array */
1356 MixerContext->Free(Pins);
1357 }
1358 else
1359 {
1360 /* calculate destination line id */
1361 DestinationLineID = (DESTINATION_LINE + MixerInfo->MixCaps.cDestinations - 1);
1362
1363 /* add mixer controls */
1364 Status = MMixerAddMixerControlsToDestinationLine(MixerContext, MixerInfo, MixerData->hDevice, Topology, Pin, bInput, DestinationLineID, &LineTerminator);
1365
1367 {
1368 /* now add the rest of the source lines */
1369 Status = MMixerAddMixerSourceLines(MixerContext, MixerInfo, MixerData->hDevice, Topology, DestinationLineID, LineTerminator);
1370 }
1371 }
1372 return Status;
1373}

Referenced by MMixerInitializeFilter().

◆ MMixerInitializeFilter()

MIXER_STATUS MMixerInitializeFilter ( IN PMIXER_CONTEXT  MixerContext,
IN PMIXER_LIST  MixerList,
IN LPMIXER_DATA  MixerData,
IN LPMIXER_INFO  MixerInfo,
IN PTOPOLOGY  Topology,
IN ULONG  NodeIndex,
IN ULONG  bInputMixer,
IN OUT LPMIXER_INFO OutMixerInfo 
)

Definition at line 1519 of file controls.c.

1528{
1529 ULONG Index;
1531 PKSPIN_PHYSICALCONNECTION OutConnection;
1532 ULONG * Pins;
1533 ULONG PinsFound;
1534 ULONG NewMixerInfo = FALSE;
1535
1536 if (MixerInfo == NULL)
1537 {
1538 /* allocate a mixer info struct */
1539 MixerInfo = (LPMIXER_INFO) MixerContext->Alloc(sizeof(MIXER_INFO));
1540 if (!MixerInfo)
1541 {
1542 /* no memory */
1543 return MM_STATUS_NO_MEMORY;
1544 }
1545
1546 /* new mixer info */
1547 NewMixerInfo = TRUE;
1548
1549 /* intialize mixer caps */
1550 MixerInfo->MixCaps.wMid = MM_MICROSOFT; /* FIXME */
1551 MixerInfo->MixCaps.wPid = MM_PID_UNMAPPED; /* FIXME */
1552 MixerInfo->MixCaps.vDriverVersion = 1; /* FIXME */
1553 MixerInfo->MixCaps.fdwSupport = 0;
1554 MixerInfo->MixCaps.cDestinations = 0;
1555
1556 /* get mixer name */
1557 Status = MMixerGetDeviceName(MixerContext, MixerInfo->MixCaps.szPname, MixerData->hDeviceInterfaceKey);
1559 {
1560 /* try get name with component id */
1561 Status = MMixerGetDeviceNameWithComponentId(MixerContext, MixerData->hDevice, MixerInfo->MixCaps.szPname);
1563 {
1564 MixerInfo->MixCaps.szPname[0] = L'\0';
1565 }
1566 }
1567
1568 /* initialize line list */
1569 InitializeListHead(&MixerInfo->LineList);
1570 InitializeListHead(&MixerInfo->EventList);
1571
1572 /* associate with mixer data */
1573 MixerData->MixerInfo = MixerInfo;
1574 }
1575
1576 /* store mixer info */
1577 *OutMixerInfo = MixerInfo;
1578
1579 /* now allocate an array which will receive the indices of the pin
1580 * which has a ADC / DAC nodetype in its path
1581 */
1584
1585 PinsFound = 0;
1586
1587 /* now get all sink / source pins, which are attached to the ADC / DAC node
1588 * For sink pins (wave out) search up stream
1589 * For source pins (wave in) search down stream
1590 * The search direction is always the opposite of the current mixer type
1591 */
1592 PinsFound = 0;
1593 MMixerGetAllUpOrDownstreamPinsFromNodeIndex(MixerContext, Topology, NodeIndex, !bInputMixer, &PinsFound, Pins);
1594
1595 /* if there is no pin found, we have a broken topology */
1596 ASSERT(PinsFound != 0);
1597
1598 /* now create a wave info struct */
1599 Status = MMixerInitializeWaveInfo(MixerContext, MixerList, MixerData, MixerInfo->MixCaps.szPname, bInputMixer, PinsFound, Pins);
1601 {
1602 /* failed to create wave info struct */
1603 MixerContext->Free(MixerInfo);
1604 MixerContext->Free(Pins);
1605 return Status;
1606 }
1607
1608 /* mark all found pins as reserved */
1609 for(Index = 0; Index < PinsFound; Index++)
1610 {
1611 MMixerSetTopologyPinReserved(Topology, Pins[Index]);
1612 }
1613
1614 if (bInputMixer)
1615 {
1616 /* pre create the mixer destination line for input mixers */
1617 Status = MMixerBuildMixerDestinationLine(MixerContext, MixerInfo, MixerData->hDevice, Pins[0], bInputMixer);
1618
1620 {
1621 /* failed to create mixer destination line */
1622 return Status;
1623 }
1624 }
1625
1626
1627 /* now get the bridge pin which is at the end of node path
1628 * For sink pins (wave out) search down stream
1629 * For source pins (wave in) search up stream
1630 */
1631 MixerContext->Free(Pins);
1634
1635 PinsFound = 0;
1636 MMixerGetAllUpOrDownstreamPinsFromNodeIndex(MixerContext, Topology, NodeIndex, bInputMixer, &PinsFound, Pins);
1637
1638 /* if there is no pin found, we have a broken topology */
1639 ASSERT(PinsFound != 0);
1640
1641 /* there should be exactly one bridge pin */
1642 ASSERT(PinsFound == 1);
1643
1644 DPRINT("BridgePin %lu bInputMixer %lu\n", Pins[0], bInputMixer);
1645
1646 /* does the pin have a physical connection */
1647 Status = MMixerGetPhysicalConnection(MixerContext, MixerData->hDevice, Pins[0], &OutConnection);
1648
1650 {
1651 /* mark pin as reserved */
1652 MMixerSetTopologyPinReserved(Topology, Pins[0]);
1653
1654 /* topology on the topoloy filter */
1655 Status = MMixerHandlePhysicalConnection(MixerContext, MixerList, MixerData, MixerInfo, bInputMixer, OutConnection);
1656
1657 /* free physical connection data */
1658 MixerContext->Free(OutConnection);
1659 }
1660 else
1661 {
1662 /* topology is on the same filter */
1663 Status = MMixerHandleTopologyFilter(MixerContext, MixerList, MixerData, MixerInfo, bInputMixer, Pins[0]);
1664 }
1665
1666 /* free pins */
1667 MixerContext->Free(Pins);
1668
1669 if (NewMixerInfo)
1670 {
1671 /* insert mixer */
1672 InsertHeadList(&MixerList->MixerList, &MixerInfo->Entry);
1673 /* increment mixer count */
1674 MixerList->MixerListCount++;
1675 }
1676
1677 /* done */
1678 return Status;
1679}
MIXER_STATUS MMixerHandlePhysicalConnection(IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, IN LPMIXER_DATA MixerData, IN OUT LPMIXER_INFO MixerInfo, IN ULONG bInput, IN PKSPIN_PHYSICALCONNECTION OutConnection)
Definition: controls.c:1376
MIXER_STATUS MMixerHandleTopologyFilter(IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, IN LPMIXER_DATA MixerData, IN OUT LPMIXER_INFO MixerInfo, IN ULONG bInput, IN ULONG Pin)
Definition: controls.c:1272
#define InsertHeadList(ListHead, Entry)
#define MM_PID_UNMAPPED
Definition: mmreg.h:141
#define MM_MICROSOFT
Definition: mmreg.h:144
MIXER_STATUS MMixerGetDeviceName(IN PMIXER_CONTEXT MixerContext, OUT LPWSTR DeviceName, IN HANDLE hKey)
Definition: sup.c:855
MIXER_STATUS MMixerInitializeWaveInfo(IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, IN LPMIXER_DATA MixerData, IN LPWSTR DeviceName, IN ULONG bWaveIn, IN ULONG PinCount, IN PULONG Pins)
Definition: wave.c:330
struct MIXER_INFO * LPMIXER_INFO
MIXER_STATUS MMixerGetDeviceNameWithComponentId(IN PMIXER_CONTEXT MixerContext, IN HANDLE hMixer, OUT LPWSTR DeviceName)
Definition: sup.c:807

Referenced by MMixerSetupFilter().

◆ MMixerRemoveEvent()

MIXER_STATUS MMixerRemoveEvent ( IN PMIXER_CONTEXT  MixerContext,
IN OUT LPMIXER_INFO  MixerInfo,
IN PVOID  MixerEventContext,
IN PMIXER_EVENT  MixerEventRoutine 
)

Definition at line 1882 of file controls.c.

1887{
1888 PLIST_ENTRY EventList;
1890
1891 /* Lookup through mixers */
1892 EventList = MixerInfo->EventList.Flink;
1893 while(EventList != &MixerInfo->EventList)
1894 {
1896 EventList = EventList->Flink;
1897 /* TODO: find a better way to identify an event ? */
1898 if(NotificationEntry->MixerEventRoutine == MixerEventRoutine &&
1899 NotificationEntry->MixerEventContext == MixerEventContext)
1900 {
1901 DPRINT1("Freeing entry %p\n", NotificationEntry);
1902 /* We found the event to remove */
1905 }
1906 }
1907 return MM_STATUS_SUCCESS;
1908}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
_In_ ULONG _In_opt_ PVOID _In_ PDRIVER_OBJECT _In_ PDRIVER_NOTIFICATION_CALLBACK_ROUTINE _Inout_opt_ __drv_aliasesMem PVOID _Outptr_result_nullonfailure_ _At_ * NotificationEntry(return==0, __drv_allocatesMem(Mem))) PVOID *NotificationEntry

Referenced by MMixerClose().

◆ MMixerSetupFilter()

MIXER_STATUS MMixerSetupFilter ( IN PMIXER_CONTEXT  MixerContext,
IN PMIXER_LIST  MixerList,
IN LPMIXER_DATA  MixerData,
IN PULONG  DeviceCount 
)

Definition at line 1755 of file controls.c.

1760{
1762 PTOPOLOGY Topology;
1763 ULONG NodeIndex;
1764 LPMIXER_INFO MixerInfo = NULL;
1765
1766 /* check if topology has already been built */
1767 if (MixerData->Topology == NULL)
1768 {
1769 /* build topology */
1770 Status = MMixerBuildTopology(MixerContext, MixerData, &Topology);
1771
1773 {
1774 /* failed to build topology */
1775 return Status;
1776 }
1777
1778 /* store topology */
1779 MixerData->Topology = Topology;
1780 }
1781 else
1782 {
1783 /* re-use topology */
1784 Topology = MixerData->Topology;
1785 }
1786
1787 /* check if the filter has an wave out node */
1788 NodeIndex = MMixerGetNodeIndexFromGuid(Topology, &KSNODETYPE_DAC);
1789 if (NodeIndex != MAXULONG)
1790 {
1791 /* it has */
1792 Status = MMixerInitializeFilter(MixerContext, MixerList, MixerData, NULL, Topology, NodeIndex, FALSE, &MixerInfo);
1793
1794 /* check for success */
1796 {
1797 /* increment mixer count */
1798 (*DeviceCount)++;
1799 }
1800 else
1801 {
1802 /* reset mixer info in case of error */
1803 MixerInfo = NULL;
1804 }
1805 }
1806
1807 /* check if the filter has an wave in node */
1808 NodeIndex = MMixerGetNodeIndexFromGuid(Topology, &KSNODETYPE_ADC);
1809 if (NodeIndex != MAXULONG)
1810 {
1811 /* it has */
1812 Status = MMixerInitializeFilter(MixerContext, MixerList, MixerData, MixerInfo, Topology, NodeIndex, TRUE, &MixerInfo);
1813
1814 /* check for success */
1816 {
1817 /* increment mixer count */
1818 (*DeviceCount)++;
1819 }
1820
1821 }
1822
1823 /* TODO: apply hacks for Wave source line */
1824
1825 /* activate midi devices */
1826 //MMixerInitializeMidiForFilter(MixerContext, MixerList, MixerData, Topology);
1827
1828 /* done */
1829 return Status;
1830}
MIXER_STATUS MMixerInitializeFilter(IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, IN LPMIXER_DATA MixerData, IN LPMIXER_INFO MixerInfo, IN PTOPOLOGY Topology, IN ULONG NodeIndex, IN ULONG bInputMixer, IN OUT LPMIXER_INFO *OutMixerInfo)
Definition: controls.c:1519
#define KSNODETYPE_ADC
Definition: ksmedia.h:262
#define KSNODETYPE_DAC
Definition: ksmedia.h:287
ULONG MMixerGetNodeIndexFromGuid(IN PTOPOLOGY Topology, IN const GUID *NodeType)
Definition: topology.c:694

Referenced by MMixerInitialize().

Variable Documentation

◆ KSCATEGORY_AUDIO

const GUID KSCATEGORY_AUDIO = {0x6994AD04L, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}

Definition at line 25 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ KSNODETYPE_ANALOG_CONNECTOR

const GUID KSNODETYPE_ANALOG_CONNECTOR = {0xDFF21FE1, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}

Definition at line 27 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ KSNODETYPE_CD_PLAYER

const GUID KSNODETYPE_CD_PLAYER = {0xDFF220E3, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}

Definition at line 29 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ KSNODETYPE_COMMUNICATION_SPEAKER

const GUID KSNODETYPE_COMMUNICATION_SPEAKER = {0xDFF21CE6, 0xF70F, 0x11D0, {0xB9,0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}

Definition at line 21 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ KSNODETYPE_DESKTOP_MICROPHONE

const GUID KSNODETYPE_DESKTOP_MICROPHONE = {0xDFF21BE2, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}

Definition at line 14 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ KSNODETYPE_DESKTOP_SPEAKER

const GUID KSNODETYPE_DESKTOP_SPEAKER = {0xDFF21CE4, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}

Definition at line 19 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ KSNODETYPE_DOWN_LINE_PHONE

const GUID KSNODETYPE_DOWN_LINE_PHONE = {0xDFF21EE3, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}

Definition at line 18 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO

const GUID KSNODETYPE_HEAD_MOUNTED_DISPLAY_AUDIO = {0xDFF21CE3, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}

Definition at line 23 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ KSNODETYPE_HEADPHONES

const GUID KSNODETYPE_HEADPHONES = {0xDFF21CE2, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}

Definition at line 22 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ KSNODETYPE_LEGACY_AUDIO_CONNECTOR

const GUID KSNODETYPE_LEGACY_AUDIO_CONNECTOR = {0xDFF21FE4, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}

Definition at line 15 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ KSNODETYPE_LINE_CONNECTOR

const GUID KSNODETYPE_LINE_CONNECTOR = {0xDFF21FE3, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0,0xC9, 0x22, 0x31, 0x96}}

Definition at line 31 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ KSNODETYPE_MICROPHONE

const GUID KSNODETYPE_MICROPHONE = {0xDFF21BE1, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9,0x22, 0x31, 0x96}}

Definition at line 24 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ KSNODETYPE_PHONE_LINE

const GUID KSNODETYPE_PHONE_LINE = {0xDFF21EE1, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}

Definition at line 17 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ KSNODETYPE_ROOM_SPEAKER

const GUID KSNODETYPE_ROOM_SPEAKER = {0xDFF21CE5, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}

Definition at line 20 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ KSNODETYPE_SPDIF_INTERFACE

const GUID KSNODETYPE_SPDIF_INTERFACE = {0xDFF21FE5, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}

Definition at line 26 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ KSNODETYPE_SPEAKER

const GUID KSNODETYPE_SPEAKER = {0xDFF21CE1, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}

Definition at line 28 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ KSNODETYPE_SYNTHESIZER

const GUID KSNODETYPE_SYNTHESIZER = {0xDFF220F3, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}

Definition at line 30 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ KSNODETYPE_TELEPHONE

const GUID KSNODETYPE_TELEPHONE = {0xDFF21EE2, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}

Definition at line 16 of file controls.c.

Referenced by MMixerGetComponentAndTargetType().

◆ PINNAME_VIDEO_CAPTURE

const GUID PINNAME_VIDEO_CAPTURE = {0xfb6c4281, 0x353, 0x11d1, {0x90, 0x5f, 0x0, 0x0, 0xc0, 0xcc, 0x16, 0xba}}

Definition at line 32 of file controls.c.