2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: lib/drivers/sound/mmixer/mmixer.c
5 * PURPOSE: Mixer Handling Functions
6 * PROGRAMMER: Johannes Anderwald
15 IN PMIXER_CONTEXT MixerContext
)
17 PMIXER_LIST MixerList
;
20 /* verify mixer context */
21 Status
= MMixerVerifyContext(MixerContext
);
23 if (Status
!= MM_STATUS_SUCCESS
)
25 /* invalid context passed */
30 MixerList
= (PMIXER_LIST
)MixerContext
->MixerContext
;
32 // return number of mixers
33 return MixerList
->MixerListCount
;
37 MMixerGetCapabilities(
38 IN PMIXER_CONTEXT MixerContext
,
40 OUT LPMIXERCAPSW MixerCaps
)
43 LPMIXER_INFO MixerInfo
;
45 /* verify mixer context */
46 Status
= MMixerVerifyContext(MixerContext
);
48 if (Status
!= MM_STATUS_SUCCESS
)
50 /* invalid context passed */
55 MixerInfo
= MMixerGetMixerInfoByIndex(MixerContext
, MixerIndex
);
59 // invalid device index
60 return MM_STATUS_INVALID_PARAMETER
;
63 MixerCaps
->wMid
= MixerInfo
->MixCaps
.wMid
;
64 MixerCaps
->wPid
= MixerInfo
->MixCaps
.wPid
;
65 MixerCaps
->vDriverVersion
= MixerInfo
->MixCaps
.vDriverVersion
;
66 MixerCaps
->fdwSupport
= MixerInfo
->MixCaps
.fdwSupport
;
67 MixerCaps
->cDestinations
= MixerInfo
->MixCaps
.cDestinations
;
69 ASSERT(MixerInfo
->MixCaps
.szPname
[MAXPNAMELEN
-1] == 0);
70 wcscpy(MixerCaps
->szPname
, MixerInfo
->MixCaps
.szPname
);
72 return MM_STATUS_SUCCESS
;
77 IN PMIXER_CONTEXT MixerContext
,
79 IN PVOID MixerEventContext
,
80 IN PMIXER_EVENT MixerEventRoutine
,
81 OUT PHANDLE MixerHandle
)
84 LPMIXER_INFO MixerInfo
;
86 /* verify mixer context */
87 Status
= MMixerVerifyContext(MixerContext
);
89 if (Status
!= MM_STATUS_SUCCESS
)
91 /* invalid context passed */
92 DPRINT1("invalid context\n");
97 MixerInfo
= (LPMIXER_INFO
)MMixerGetMixerInfoByIndex(MixerContext
, MixerId
);
100 /* invalid mixer id */
101 DPRINT1("invalid mixer id %lu\n", MixerId
);
102 return MM_STATUS_INVALID_PARAMETER
;
106 Status
= MMixerAddEvent(MixerContext
, MixerInfo
, MixerEventContext
, MixerEventRoutine
);
110 *MixerHandle
= (HANDLE
)MixerInfo
;
111 return MM_STATUS_SUCCESS
;
116 IN PMIXER_CONTEXT MixerContext
,
117 IN HANDLE MixerHandle
,
120 OUT LPMIXERLINEW MixerLine
)
123 LPMIXER_INFO MixerInfo
;
124 LPMIXERLINE_EXT MixerLineSrc
;
125 ULONG DestinationLineID
;
127 /* verify mixer context */
128 Status
= MMixerVerifyContext(MixerContext
);
130 if (Status
!= MM_STATUS_SUCCESS
)
132 /* invalid context passed */
135 if ((Flags
& (MIXER_OBJECTF_MIXER
| MIXER_OBJECTF_HMIXER
)) == MIXER_OBJECTF_MIXER
)
137 /* caller passed mixer id */
138 MixerHandle
= (HANDLE
)MMixerGetMixerInfoByIndex(MixerContext
, MixerId
);
142 /* invalid parameter */
143 return MM_STATUS_INVALID_PARAMETER
;
147 if (MixerLine
->cbStruct
!= sizeof(MIXERLINEW
))
149 DPRINT1("MixerLine Expected %lu but got %lu\n", sizeof(MIXERLINEW
), MixerLine
->cbStruct
);
150 return MM_STATUS_INVALID_PARAMETER
;
153 /* clear hmixer from flags */
154 Flags
&=~MIXER_OBJECTF_HMIXER
;
156 DPRINT("MMixerGetLineInfo MixerId %lu Flags %lu\n", MixerId
, Flags
);
158 if (Flags
== MIXER_GETLINEINFOF_DESTINATION
)
160 /* cast to mixer info */
161 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
163 /* calculate destination line id */
164 DestinationLineID
= (MixerLine
->dwDestination
+ DESTINATION_LINE
);
166 /* get destination line */
167 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, DestinationLineID
);
169 if (MixerLineSrc
== NULL
)
171 DPRINT1("MixerCaps Name %S DestinationLineCount %lu dwDestination %lu not found\n", MixerInfo
->MixCaps
.szPname
, MixerInfo
->MixCaps
.cDestinations
, MixerLine
->dwDestination
);
172 return MM_STATUS_UNSUCCESSFUL
;
174 /* copy mixer line */
175 MixerContext
->Copy(MixerLine
, &MixerLineSrc
->Line
, sizeof(MIXERLINEW
));
177 /* make sure it is null terminated */
178 MixerLine
->szName
[MIXER_LONG_NAME_CHARS
-1] = L
'\0';
179 MixerLine
->szShortName
[MIXER_SHORT_NAME_CHARS
-1] = L
'\0';
180 MixerLine
->Target
.szPname
[MAXPNAMELEN
-1] = L
'\0';
183 return MM_STATUS_SUCCESS
;
185 else if (Flags
== MIXER_GETLINEINFOF_SOURCE
)
187 /* cast to mixer info */
188 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
190 /* calculate destination line id */
191 DestinationLineID
= (MixerLine
->dwDestination
+ DESTINATION_LINE
);
193 /* get destination line */
194 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, DestinationLineID
);
196 if (MixerLineSrc
== NULL
)
198 DPRINT1("MixerCaps Name %S DestinationLineCount %lu dwDestination %lu not found\n", MixerInfo
->MixCaps
.szPname
, MixerInfo
->MixCaps
.cDestinations
, MixerLine
->dwDestination
);
199 return MM_STATUS_UNSUCCESSFUL
;
202 /* check if dwSource is out of bounds */
203 if (MixerLine
->dwSource
>= MixerLineSrc
->Line
.cConnections
)
205 DPRINT1("MixerCaps Name %S MixerLineName %S Connections %lu dwSource %lu not found\n", MixerInfo
->MixCaps
.szPname
, MixerLineSrc
->Line
.szName
, MixerLineSrc
->Line
.cConnections
, MixerLine
->dwSource
);
206 return MM_STATUS_UNSUCCESSFUL
;
209 /* calculate destination line id */
210 DestinationLineID
= (MixerLine
->dwSource
* SOURCE_LINE
) + MixerLine
->dwDestination
;
212 DPRINT("MixerName %S cDestinations %lu MixerLineName %S cConnections %lu dwSource %lu dwDestination %lu ID %lx\n", MixerInfo
->MixCaps
.szPname
, MixerInfo
->MixCaps
.cDestinations
,
213 MixerLineSrc
->Line
.szName
, MixerLineSrc
->Line
.cConnections
,
214 MixerLine
->dwSource
, MixerLine
->dwDestination
,
216 /* get target destination line id */
217 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, DestinationLineID
);
220 ASSERT(MixerLineSrc
);
222 DPRINT("Line %u Name %S\n", MixerLineSrc
->Line
.dwSource
, MixerLineSrc
->Line
.szName
);
224 /* copy mixer line */
225 MixerContext
->Copy(MixerLine
, &MixerLineSrc
->Line
, sizeof(MIXERLINEW
));
227 /* make sure it is null terminated */
228 MixerLine
->szName
[MIXER_LONG_NAME_CHARS
-1] = L
'\0';
229 MixerLine
->szShortName
[MIXER_SHORT_NAME_CHARS
-1] = L
'\0';
230 MixerLine
->Target
.szPname
[MAXPNAMELEN
-1] = L
'\0';
233 return MM_STATUS_SUCCESS
;
235 else if (Flags
== MIXER_GETLINEINFOF_LINEID
)
237 /* cast to mixer info */
238 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
240 /* try to find line */
241 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, MixerLine
->dwLineID
);
244 /* invalid parameter */
245 DPRINT1("MMixerGetLineInfo: MixerName %S Line not found 0x%lx\n", MixerInfo
->MixCaps
.szPname
, MixerLine
->dwLineID
);
246 return MM_STATUS_INVALID_PARAMETER
;
249 DPRINT("Line %u Name %S\n", MixerLineSrc
->Line
.dwSource
, MixerLineSrc
->Line
.szName
);
252 MixerContext
->Copy(MixerLine
, &MixerLineSrc
->Line
, sizeof(MIXERLINEW
));
254 /* make sure it is null terminated */
255 MixerLine
->szName
[MIXER_LONG_NAME_CHARS
-1] = L
'\0';
256 MixerLine
->szShortName
[MIXER_SHORT_NAME_CHARS
-1] = L
'\0';
257 MixerLine
->Target
.szPname
[MAXPNAMELEN
-1] = L
'\0';
259 return MM_STATUS_SUCCESS
;
261 else if (Flags
== MIXER_GETLINEINFOF_COMPONENTTYPE
)
263 /* cast to mixer info */
264 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
266 /* find mixer line by component type */
267 MixerLineSrc
= MMixerGetSourceMixerLineByComponentType(MixerInfo
, MixerLine
->dwComponentType
);
270 DPRINT1("Failed to find component type %x\n", MixerLine
->dwComponentType
);
271 return MM_STATUS_UNSUCCESSFUL
;
274 /* copy mixer line */
275 MixerContext
->Copy(MixerLine
, &MixerLineSrc
->Line
, sizeof(MIXERLINEW
));
277 /* make sure it is null terminated */
278 MixerLine
->szName
[MIXER_LONG_NAME_CHARS
-1] = L
'\0';
279 MixerLine
->szShortName
[MIXER_SHORT_NAME_CHARS
-1] = L
'\0';
280 MixerLine
->Target
.szPname
[MAXPNAMELEN
-1] = L
'\0';
283 return MM_STATUS_SUCCESS
;
285 else if (Flags
== MIXER_GETLINEINFOF_TARGETTYPE
)
287 DPRINT1("MIXER_GETLINEINFOF_TARGETTYPE handling is unimplemented\n");
291 DPRINT1("Unknown Flags %lx handling is unimplemented\n", Flags
);
294 return MM_STATUS_NOT_IMPLEMENTED
;
298 MMixerGetLineControls(
299 IN PMIXER_CONTEXT MixerContext
,
300 IN HANDLE MixerHandle
,
303 OUT LPMIXERLINECONTROLSW MixerLineControls
)
305 LPMIXER_INFO MixerInfo
;
306 LPMIXERLINE_EXT MixerLineSrc
;
307 LPMIXERCONTROL_EXT MixerControl
;
312 /* verify mixer context */
313 Status
= MMixerVerifyContext(MixerContext
);
315 if (Status
!= MM_STATUS_SUCCESS
)
317 /* invalid context passed */
321 if (MixerLineControls
->cbStruct
!= sizeof(MIXERLINECONTROLSW
))
323 DPRINT1("Invalid MixerLineControls cbStruct passed %lu expected %lu\n", MixerLineControls
->cbStruct
, sizeof(MIXERLINECONTROLSW
));
324 /* invalid parameter */
325 return MM_STATUS_INVALID_PARAMETER
;
328 if (MixerLineControls
->cbmxctrl
!= sizeof(MIXERCONTROLW
))
330 DPRINT1("Invalid MixerLineControls cbmxctrl passed %lu expected %lu\n", MixerLineControls
->cbStruct
, sizeof(MIXERLINECONTROLSW
));
331 /* invalid parameter */
332 return MM_STATUS_INVALID_PARAMETER
;
335 if ((Flags
& (MIXER_OBJECTF_MIXER
| MIXER_OBJECTF_HMIXER
)) == MIXER_OBJECTF_MIXER
)
337 /* caller passed mixer id */
338 MixerHandle
= (HANDLE
)MMixerGetMixerInfoByIndex(MixerContext
, MixerId
);
342 /* invalid parameter */
343 return MM_STATUS_INVALID_PARAMETER
;
347 Flags
&= ~MIXER_OBJECTF_HMIXER
;
349 DPRINT("MMixerGetLineControls MixerId %lu Flags %lu\n", MixerId
, Flags
);
351 if (Flags
== MIXER_GETLINECONTROLSF_ALL
)
353 /* cast to mixer info */
354 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
357 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, MixerLineControls
->dwLineID
);
361 /* invalid line id */
362 DPRINT("MMixerGetLineControls Line not found %lx\n", MixerLineControls
->dwLineID
);
363 return MM_STATUS_INVALID_PARAMETER
;
366 if (MixerLineSrc
->Line
.cControls
!= MixerLineControls
->cControls
)
368 /* invalid parameter */
369 DPRINT1("Invalid control count %lu expected %lu\n", MixerLineControls
->cControls
, MixerLineSrc
->Line
.cControls
);
370 return MM_STATUS_INVALID_PARAMETER
;
373 /* copy line control(s) */
374 Entry
= MixerLineSrc
->ControlsList
.Flink
;
376 while(Entry
!= &MixerLineSrc
->ControlsList
)
378 /* get mixer control */
379 MixerControl
= (LPMIXERCONTROL_EXT
)CONTAINING_RECORD(Entry
, MIXERCONTROL_EXT
, Entry
);
381 /* copy mixer control */
382 MixerContext
->Copy(&MixerLineControls
->pamxctrl
[Index
], &MixerControl
->Control
, sizeof(MIXERCONTROLW
));
385 Entry
= Entry
->Flink
;
387 /* increment mixer control offset */
390 return MM_STATUS_SUCCESS
;
392 else if (Flags
== MIXER_GETLINECONTROLSF_ONEBYTYPE
)
394 /* cast to mixer info */
395 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
398 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, MixerLineControls
->dwLineID
);
402 /* invalid line id */
403 DPRINT1("MMixerGetLineControls Line not found %lx\n", MixerLineControls
->dwLineID
);
404 return MM_STATUS_INVALID_PARAMETER
;
408 ASSERT(MixerLineControls
->cControls
== 1);
409 ASSERT(MixerLineControls
->cbmxctrl
== sizeof(MIXERCONTROLW
));
410 ASSERT(MixerLineControls
->pamxctrl
!= NULL
);
412 Entry
= MixerLineSrc
->ControlsList
.Flink
;
413 while(Entry
!= &MixerLineSrc
->ControlsList
)
415 MixerControl
= (LPMIXERCONTROL_EXT
)CONTAINING_RECORD(Entry
, MIXERCONTROL_EXT
, Entry
);
416 if (MixerLineControls
->dwControlType
== MixerControl
->Control
.dwControlType
)
418 /* found a control with that type */
419 MixerContext
->Copy(MixerLineControls
->pamxctrl
, &MixerControl
->Control
, sizeof(MIXERCONTROLW
));
420 return MM_STATUS_SUCCESS
;
423 /* move to next entry */
424 Entry
= Entry
->Flink
;
427 DPRINT("DeviceInfo->u.MixControls.dwControlType %x not found in Line %x cControls %u \n", MixerLineControls
->dwControlType
, MixerLineControls
->dwLineID
, MixerLineSrc
->Line
.cControls
);
428 return MM_STATUS_UNSUCCESSFUL
;
430 else if (Flags
== MIXER_GETLINECONTROLSF_ONEBYID
)
432 /* cast to mixer info */
433 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
435 Status
= MMixerGetMixerControlById(MixerInfo
, MixerLineControls
->dwControlID
, NULL
, &MixerControl
, NULL
);
437 if (Status
!= MM_STATUS_SUCCESS
)
439 /* invalid parameter */
440 DPRINT("MMixerGetLineControls ControlID not found %lx\n", MixerLineControls
->dwLineID
);
441 return MM_STATUS_INVALID_PARAMETER
;
444 ASSERT(MixerLineControls
->cControls
== 1);
445 ASSERT(MixerLineControls
->cbmxctrl
== sizeof(MIXERCONTROLW
));
446 ASSERT(MixerLineControls
->pamxctrl
!= NULL
);
448 DPRINT("MMixerGetLineControls ControlID %lx ControlType %lx Name %S\n", MixerControl
->Control
.dwControlID
, MixerControl
->Control
.dwControlType
, MixerControl
->Control
.szName
);
450 /* copy the controls */
451 MixerContext
->Copy(MixerLineControls
->pamxctrl
, &MixerControl
->Control
, sizeof(MIXERCONTROLW
));
452 MixerLineControls
->pamxctrl
->szName
[MIXER_LONG_NAME_CHARS
-1] = L
'\0';
453 MixerLineControls
->pamxctrl
->szShortName
[MIXER_SHORT_NAME_CHARS
-1] = L
'\0';
455 return MM_STATUS_SUCCESS
;
458 return MM_STATUS_NOT_IMPLEMENTED
;
462 MMixerSetControlDetails(
463 IN PMIXER_CONTEXT MixerContext
,
464 IN HANDLE MixerHandle
,
467 OUT LPMIXERCONTROLDETAILS MixerControlDetails
)
471 LPMIXER_INFO MixerInfo
;
472 LPMIXERLINE_EXT MixerLine
;
473 LPMIXERCONTROL_EXT MixerControl
;
475 /* verify mixer context */
476 Status
= MMixerVerifyContext(MixerContext
);
478 if (Status
!= MM_STATUS_SUCCESS
)
480 /* invalid context passed */
481 DPRINT1("invalid context\n");
485 if ((Flags
& (MIXER_OBJECTF_MIXER
| MIXER_OBJECTF_HMIXER
)) == MIXER_OBJECTF_MIXER
)
487 /* caller passed mixer id */
488 MixerHandle
= (HANDLE
)MMixerGetMixerInfoByIndex(MixerContext
, MixerId
);
492 /* invalid parameter */
493 DPRINT1("invalid handle\n");
494 return MM_STATUS_INVALID_PARAMETER
;
499 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
501 /* get mixer control */
502 Status
= MMixerGetMixerControlById(MixerInfo
, MixerControlDetails
->dwControlID
, &MixerLine
, &MixerControl
, &NodeId
);
504 /* check for success */
505 if (Status
!= MM_STATUS_SUCCESS
)
507 /* failed to find control id */
508 DPRINT1("invalid control id %lu\n", MixerControlDetails
->dwControlID
);
509 return MM_STATUS_INVALID_PARAMETER
;
512 DPRINT("MMixerSetControlDetails ControlType %lx MixerControlName %S MixerLineName %S NodeID %lu\n", MixerControl
->Control
.dwControlType
, MixerControl
->Control
.szName
, MixerLine
->Line
.szName
, NodeId
);
513 switch(MixerControl
->Control
.dwControlType
)
515 case MIXERCONTROL_CONTROLTYPE_MUTE
:
516 Status
= MMixerSetGetMuteControlDetails(MixerContext
, MixerInfo
, MixerControl
, MixerLine
->Line
.dwLineID
, MixerControlDetails
, TRUE
);
518 case MIXERCONTROL_CONTROLTYPE_VOLUME
:
519 Status
= MMixerSetGetVolumeControlDetails(MixerContext
, MixerInfo
, NodeId
, TRUE
, MixerControl
, MixerControlDetails
, MixerLine
);
521 case MIXERCONTROL_CONTROLTYPE_MUX
:
522 Status
= MMixerSetGetMuxControlDetails(MixerContext
, MixerInfo
, NodeId
, TRUE
, Flags
, MixerControl
, MixerControlDetails
, MixerLine
);
525 Status
= MM_STATUS_NOT_IMPLEMENTED
;
532 MMixerGetControlDetails(
533 IN PMIXER_CONTEXT MixerContext
,
534 IN HANDLE MixerHandle
,
537 OUT LPMIXERCONTROLDETAILS MixerControlDetails
)
541 LPMIXER_INFO MixerInfo
;
542 LPMIXERLINE_EXT MixerLine
;
543 LPMIXERCONTROL_EXT MixerControl
;
545 /* verify mixer context */
546 Status
= MMixerVerifyContext(MixerContext
);
548 if (Status
!= MM_STATUS_SUCCESS
)
550 /* invalid context passed */
554 if ((Flags
& (MIXER_OBJECTF_MIXER
| MIXER_OBJECTF_HMIXER
)) == MIXER_OBJECTF_MIXER
)
556 /* caller passed mixer id */
557 MixerHandle
= (HANDLE
)MMixerGetMixerInfoByIndex(MixerContext
, MixerId
);
561 /* invalid parameter */
562 return MM_STATUS_INVALID_PARAMETER
;
567 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
569 /* get mixer control */
570 Status
= MMixerGetMixerControlById(MixerInfo
, MixerControlDetails
->dwControlID
, &MixerLine
, &MixerControl
, &NodeId
);
572 /* check for success */
573 if (Status
!= MM_STATUS_SUCCESS
)
575 /* failed to find control id */
576 return MM_STATUS_INVALID_PARAMETER
;
579 switch(MixerControl
->Control
.dwControlType
)
581 case MIXERCONTROL_CONTROLTYPE_MUTE
:
582 Status
= MMixerSetGetMuteControlDetails(MixerContext
, MixerInfo
, MixerControl
, MixerLine
->Line
.dwLineID
, MixerControlDetails
, FALSE
);
584 case MIXERCONTROL_CONTROLTYPE_VOLUME
:
585 Status
= MMixerSetGetVolumeControlDetails(MixerContext
, MixerInfo
, NodeId
, FALSE
, MixerControl
, MixerControlDetails
, MixerLine
);
587 case MIXERCONTROL_CONTROLTYPE_ONOFF
:
588 DPRINT1("Not Implemented MIXERCONTROL_CONTROLTYPE_ONOFF\n");
590 case MIXERCONTROL_CONTROLTYPE_MUX
:
591 Status
= MMixerSetGetMuxControlDetails(MixerContext
, MixerInfo
, NodeId
, FALSE
, Flags
, MixerControl
, MixerControlDetails
, MixerLine
);
595 Status
= MM_STATUS_NOT_IMPLEMENTED
;
596 DPRINT1("ControlType %lx not implemented\n", MixerControl
->Control
.dwControlType
);
603 MMixerPrintMixerLineControls(
604 IN LPMIXERLINE_EXT MixerLine
)
607 LPMIXERCONTROL_EXT MixerControl
;
610 Entry
= MixerLine
->ControlsList
.Flink
;
611 while(Entry
!= &MixerLine
->ControlsList
)
613 MixerControl
= (LPMIXERCONTROL_EXT
)CONTAINING_RECORD(Entry
, MIXERCONTROL_EXT
, Entry
);
616 DPRINT1("Control Index: %lu\n", Index
);
618 DPRINT1("cbStruct %u\n", MixerControl
->Control
.cbStruct
);
619 DPRINT1("dwControlID %lu\n", MixerControl
->Control
.dwControlID
);
620 DPRINT1("dwControlType %lx\n", MixerControl
->Control
.dwControlType
);
621 DPRINT1("fdwControl %lu\n", MixerControl
->Control
.fdwControl
);
622 DPRINT1("cMultipleItems %lu\n", MixerControl
->Control
.cMultipleItems
);
623 DPRINT1("szShortName %S\n", MixerControl
->Control
.szShortName
);
624 DPRINT1("szName %S\n", MixerControl
->Control
.szName
);
625 DPRINT1("Bounds.dwMinimum %lu\n", MixerControl
->Control
.Bounds
.dwMinimum
);
626 DPRINT1("Bounds.dwMaximum %lu\n", MixerControl
->Control
.Bounds
.dwMaximum
);
628 DPRINT1("Metrics.Reserved[0] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[0]);
629 DPRINT1("Metrics.Reserved[1] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[1]);
630 DPRINT1("Metrics.Reserved[2] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[2]);
631 DPRINT1("Metrics.Reserved[3] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[3]);
632 DPRINT1("Metrics.Reserved[4] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[4]);
633 DPRINT1("Metrics.Reserved[5] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[5]);
635 Entry
= Entry
->Flink
;
642 IN PMIXER_CONTEXT MixerContext
,
643 IN PMIXER_LIST MixerList
)
645 ULONG Index
, SubIndex
, DestinationLineID
, SrcIndex
;
646 LPMIXER_INFO MixerInfo
;
647 LPMIXERLINE_EXT DstMixerLine
, SrcMixerLine
;
649 DPRINT1("MixerList %p\n", MixerList
);
650 DPRINT1("MidiInCount %lu\n", MixerList
->MidiInListCount
);
651 DPRINT1("MidiOutCount %lu\n", MixerList
->MidiOutListCount
);
652 DPRINT1("WaveInCount %lu\n", MixerList
->WaveInListCount
);
653 DPRINT1("WaveOutCount %lu\n", MixerList
->WaveOutListCount
);
654 DPRINT1("MixerCount %p\n", MixerList
->MixerListCount
);
657 for(Index
= 0; Index
< MixerList
->MixerListCount
; Index
++)
660 MixerInfo
= MMixerGetMixerInfoByIndex(MixerContext
, Index
);
664 DPRINT1("Name :%S\n", MixerInfo
->MixCaps
.szPname
);
665 DPRINT1("cDestinations: %lu\n", MixerInfo
->MixCaps
.cDestinations
);
666 DPRINT1("fdwSupport %lu\n", MixerInfo
->MixCaps
.fdwSupport
);
667 DPRINT1("vDriverVersion %lx\n", MixerInfo
->MixCaps
.vDriverVersion
);
668 DPRINT1("wMid %lx\n", MixerInfo
->MixCaps
.wMid
);
669 DPRINT1("wPid %lx\n", MixerInfo
->MixCaps
.wPid
);
671 for(SubIndex
= 0; SubIndex
< MixerInfo
->MixCaps
.cDestinations
; SubIndex
++)
673 /* calculate destination line id */
674 DestinationLineID
= (SubIndex
+ DESTINATION_LINE
);
676 /* get destination line */
677 DstMixerLine
= MMixerGetSourceMixerLineByLineId(MixerInfo
, DestinationLineID
);
678 DPRINT1("//----------------------------------------------------------------------------------------------\n");
680 DPRINT1("Destination Index %lu\n", SubIndex
);
682 DPRINT1("cChannels %lu\n", DstMixerLine
->Line
.cChannels
);
683 DPRINT1("cConnections %lu\n", DstMixerLine
->Line
.cConnections
);
684 DPRINT1("cControls %lu\n", DstMixerLine
->Line
.cControls
);
685 DPRINT1("dwComponentType %lx\n", DstMixerLine
->Line
.dwComponentType
);
686 DPRINT1("dwDestination %lu\n", DstMixerLine
->Line
.dwDestination
);
687 DPRINT1("dwLineID %lx\n", DstMixerLine
->Line
.dwLineID
);
688 DPRINT1("dwSource %lx\n", DstMixerLine
->Line
.dwSource
);
689 DPRINT1("dwUser %lu\n", DstMixerLine
->Line
.dwUser
);
690 DPRINT1("fdwLine %lu\n", DstMixerLine
->Line
.fdwLine
);
691 DPRINT1("szName %S\n", DstMixerLine
->Line
.szName
);
692 DPRINT1("szShortName %S\n", DstMixerLine
->Line
.szShortName
);
693 DPRINT1("Target.dwDeviceId %lu\n", DstMixerLine
->Line
.Target
.dwDeviceID
);
694 DPRINT1("Target.dwType %lu\n", DstMixerLine
->Line
.Target
.dwType
);
695 DPRINT1("Target.szName %S\n", DstMixerLine
->Line
.Target
.szPname
);
696 DPRINT1("Target.vDriverVersion %lx\n", DstMixerLine
->Line
.Target
.vDriverVersion
);
697 DPRINT1("Target.wMid %lx\n", DstMixerLine
->Line
.Target
.wMid
);
698 DPRINT1("Target.wPid %lx\n", DstMixerLine
->Line
.Target
.wPid
);
699 MMixerPrintMixerLineControls(DstMixerLine
);
701 for(SrcIndex
= 0; SrcIndex
< DstMixerLine
->Line
.cConnections
; SrcIndex
++)
703 /* calculate destination line id */
704 DestinationLineID
= (SOURCE_LINE
* SrcIndex
) + SubIndex
;
706 /* get source line */
707 SrcMixerLine
= MMixerGetSourceMixerLineByLineId(MixerInfo
, DestinationLineID
);
708 DPRINT1("//==============================================================================================\n");
710 DPRINT1("SrcLineIndex : %lu\n", SrcIndex
);
712 DPRINT1("cChannels %lu\n", SrcMixerLine
->Line
.cChannels
);
713 DPRINT1("cConnections %lu\n", SrcMixerLine
->Line
.cConnections
);
714 DPRINT1("cControls %lu\n", SrcMixerLine
->Line
.cControls
);
715 DPRINT1("dwComponentType %lx\n", SrcMixerLine
->Line
.dwComponentType
);
716 DPRINT1("dwDestination %lu\n", SrcMixerLine
->Line
.dwDestination
);
717 DPRINT1("dwLineID %lx\n", SrcMixerLine
->Line
.dwLineID
);
718 DPRINT1("dwSource %lx\n", SrcMixerLine
->Line
.dwSource
);
719 DPRINT1("dwUser %lu\n", SrcMixerLine
->Line
.dwUser
);
720 DPRINT1("fdwLine %lu\n", SrcMixerLine
->Line
.fdwLine
);
721 DPRINT1("szName %S\n", SrcMixerLine
->Line
.szName
);
722 DPRINT1("szShortName %S\n", SrcMixerLine
->Line
.szShortName
);
723 DPRINT1("Target.dwDeviceId %lu\n", SrcMixerLine
->Line
.Target
.dwDeviceID
);
724 DPRINT1("Target.dwType %lu\n", SrcMixerLine
->Line
.Target
.dwType
);
725 DPRINT1("Target.szName %S\n", SrcMixerLine
->Line
.Target
.szPname
);
726 DPRINT1("Target.vDriverVersion %lx\n", SrcMixerLine
->Line
.Target
.vDriverVersion
);
727 DPRINT1("Target.wMid %lx\n", SrcMixerLine
->Line
.Target
.wMid
);
728 DPRINT1("Target.wPid %lx\n", SrcMixerLine
->Line
.Target
.wPid
);
729 MMixerPrintMixerLineControls(SrcMixerLine
);
737 IN PMIXER_CONTEXT MixerContext
,
738 IN PMIXER_ENUM EnumFunction
,
739 IN PVOID EnumContext
)
743 ULONG DeviceIndex
, Count
;
745 LPMIXER_DATA MixerData
;
746 PMIXER_LIST MixerList
;
749 if (!MixerContext
|| !EnumFunction
|| !EnumContext
)
751 /* invalid parameter */
752 return MM_STATUS_INVALID_PARAMETER
;
755 if (!MixerContext
->Alloc
|| !MixerContext
->Control
|| !MixerContext
->Free
|| !MixerContext
->Open
||
756 !MixerContext
->AllocEventData
|| !MixerContext
->FreeEventData
||
757 !MixerContext
->Close
|| !MixerContext
->OpenKey
|| !MixerContext
->QueryKeyValue
|| !MixerContext
->CloseKey
)
759 /* invalid parameter */
760 return MM_STATUS_INVALID_PARAMETER
;
763 /* allocate a mixer list */
764 MixerList
= (PMIXER_LIST
)MixerContext
->Alloc(sizeof(MIXER_LIST
));
768 return MM_STATUS_NO_MEMORY
;
771 /* initialize mixer list */
772 MixerList
->MixerListCount
= 0;
773 MixerList
->MixerDataCount
= 0;
774 MixerList
->WaveInListCount
= 0;
775 MixerList
->WaveOutListCount
= 0;
776 MixerList
->MidiInListCount
= 0;
777 MixerList
->MidiOutListCount
= 0;
778 InitializeListHead(&MixerList
->MixerList
);
779 InitializeListHead(&MixerList
->MixerData
);
780 InitializeListHead(&MixerList
->WaveInList
);
781 InitializeListHead(&MixerList
->WaveOutList
);
782 InitializeListHead(&MixerList
->MidiInList
);
783 InitializeListHead(&MixerList
->MidiOutList
);
785 /* store mixer list */
786 MixerContext
->MixerContext
= (PVOID
)MixerList
;
788 /* start enumerating all available devices */
794 /* enumerate a device */
795 Status
= EnumFunction(EnumContext
, DeviceIndex
, &DeviceName
, &hMixer
, &hKey
);
797 if (Status
!= MM_STATUS_SUCCESS
)
799 /* check error code */
800 if (Status
== MM_STATUS_NO_MORE_DEVICES
)
802 /* enumeration has finished */
807 DPRINT1("Failed to enumerate device %lu\n", DeviceIndex
);
815 /* create a mixer data entry */
816 Status
= MMixerCreateMixerData(MixerContext
, MixerList
, DeviceIndex
, DeviceName
, hMixer
, hKey
);
817 if (Status
!= MM_STATUS_SUCCESS
)
821 /* increment device index */
825 /* now all filters have been pre-opened
826 * lets enumerate the filters
828 Entry
= MixerList
->MixerData
.Flink
;
829 while(Entry
!= &MixerList
->MixerData
)
831 MixerData
= (LPMIXER_DATA
)CONTAINING_RECORD(Entry
, MIXER_DATA
, Entry
);
832 MMixerSetupFilter(MixerContext
, MixerList
, MixerData
, &Count
);
833 Entry
= Entry
->Flink
;
836 Entry
= MixerList
->MixerData
.Flink
;
837 while(Entry
!= &MixerList
->MixerData
)
839 MixerData
= (LPMIXER_DATA
)CONTAINING_RECORD(Entry
, MIXER_DATA
, Entry
);
841 /* now handle alternative mixer types */
842 MMixerHandleAlternativeMixers(MixerContext
, MixerList
, MixerData
, MixerData
->Topology
);
843 Entry
= Entry
->Flink
;
846 //MMixerPrintMixers(MixerContext, MixerList);
849 return MM_STATUS_SUCCESS
;