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
16 IN PMIXER_CONTEXT MixerContext
)
18 PMIXER_LIST MixerList
;
21 /* verify mixer context */
22 Status
= MMixerVerifyContext(MixerContext
);
24 if (Status
!= MM_STATUS_SUCCESS
)
26 /* invalid context passed */
31 MixerList
= (PMIXER_LIST
)MixerContext
->MixerContext
;
33 // return number of mixers
34 return MixerList
->MixerListCount
;
38 MMixerGetCapabilities(
39 IN PMIXER_CONTEXT MixerContext
,
41 OUT LPMIXERCAPSW MixerCaps
)
44 LPMIXER_INFO MixerInfo
;
46 /* verify mixer context */
47 Status
= MMixerVerifyContext(MixerContext
);
49 if (Status
!= MM_STATUS_SUCCESS
)
51 /* invalid context passed */
56 MixerInfo
= MMixerGetMixerInfoByIndex(MixerContext
, MixerIndex
);
60 // invalid device index
61 return MM_STATUS_INVALID_PARAMETER
;
64 MixerCaps
->wMid
= MixerInfo
->MixCaps
.wMid
;
65 MixerCaps
->wPid
= MixerInfo
->MixCaps
.wPid
;
66 MixerCaps
->vDriverVersion
= MixerInfo
->MixCaps
.vDriverVersion
;
67 MixerCaps
->fdwSupport
= MixerInfo
->MixCaps
.fdwSupport
;
68 MixerCaps
->cDestinations
= MixerInfo
->MixCaps
.cDestinations
;
70 ASSERT(MixerInfo
->MixCaps
.szPname
[MAXPNAMELEN
-1] == 0);
71 wcscpy(MixerCaps
->szPname
, MixerInfo
->MixCaps
.szPname
);
73 return MM_STATUS_SUCCESS
;
78 IN PMIXER_CONTEXT MixerContext
,
80 IN PVOID MixerEventContext
,
81 IN PMIXER_EVENT MixerEventRoutine
,
82 OUT PHANDLE MixerHandle
)
85 LPMIXER_INFO MixerInfo
;
87 /* verify mixer context */
88 Status
= MMixerVerifyContext(MixerContext
);
90 if (Status
!= MM_STATUS_SUCCESS
)
92 /* invalid context passed */
93 DPRINT1("invalid context\n");
98 MixerInfo
= (LPMIXER_INFO
)MMixerGetMixerInfoByIndex(MixerContext
, MixerId
);
101 /* invalid mixer id */
102 DPRINT1("invalid mixer id %lu\n", MixerId
);
103 return MM_STATUS_INVALID_PARAMETER
;
107 Status
= MMixerAddEvent(MixerContext
, MixerInfo
, MixerEventContext
, MixerEventRoutine
);
111 *MixerHandle
= (HANDLE
)MixerInfo
;
112 return MM_STATUS_SUCCESS
;
117 IN PMIXER_CONTEXT MixerContext
,
118 IN HANDLE MixerHandle
,
121 OUT LPMIXERLINEW MixerLine
)
124 LPMIXER_INFO MixerInfo
;
125 LPMIXERLINE_EXT MixerLineSrc
;
126 ULONG DestinationLineID
;
128 /* verify mixer context */
129 Status
= MMixerVerifyContext(MixerContext
);
131 if (Status
!= MM_STATUS_SUCCESS
)
133 /* invalid context passed */
136 if ((Flags
& (MIXER_OBJECTF_MIXER
| MIXER_OBJECTF_HMIXER
)) == MIXER_OBJECTF_MIXER
)
138 /* caller passed mixer id */
139 MixerHandle
= (HANDLE
)MMixerGetMixerInfoByIndex(MixerContext
, MixerId
);
143 /* invalid parameter */
144 return MM_STATUS_INVALID_PARAMETER
;
148 if (MixerLine
->cbStruct
!= sizeof(MIXERLINEW
))
150 DPRINT1("MixerLine Expected %lu but got %lu\n", sizeof(MIXERLINEW
), MixerLine
->cbStruct
);
151 return MM_STATUS_INVALID_PARAMETER
;
154 /* clear hmixer from flags */
155 Flags
&=~MIXER_OBJECTF_HMIXER
;
157 DPRINT("MMixerGetLineInfo MixerId %lu Flags %lu\n", MixerId
, Flags
);
159 if (Flags
== MIXER_GETLINEINFOF_DESTINATION
)
161 /* cast to mixer info */
162 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
164 /* calculate destination line id */
165 DestinationLineID
= (MixerLine
->dwDestination
+ DESTINATION_LINE
);
167 /* get destination line */
168 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, DestinationLineID
);
170 if (MixerLineSrc
== NULL
)
172 DPRINT1("MixerCaps Name %S DestinationLineCount %lu dwDestination %lu not found\n", MixerInfo
->MixCaps
.szPname
, MixerInfo
->MixCaps
.cDestinations
, MixerLine
->dwDestination
);
173 return MM_STATUS_UNSUCCESSFUL
;
175 /* copy mixer line */
176 MixerContext
->Copy(MixerLine
, &MixerLineSrc
->Line
, sizeof(MIXERLINEW
));
178 /* make sure it is null terminated */
179 MixerLine
->szName
[MIXER_LONG_NAME_CHARS
-1] = L
'\0';
180 MixerLine
->szShortName
[MIXER_SHORT_NAME_CHARS
-1] = L
'\0';
181 MixerLine
->Target
.szPname
[MAXPNAMELEN
-1] = L
'\0';
184 return MM_STATUS_SUCCESS
;
186 else if (Flags
== MIXER_GETLINEINFOF_SOURCE
)
188 /* cast to mixer info */
189 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
191 /* calculate destination line id */
192 DestinationLineID
= (MixerLine
->dwDestination
+ DESTINATION_LINE
);
194 /* get destination line */
195 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, DestinationLineID
);
197 if (MixerLineSrc
== NULL
)
199 DPRINT1("MixerCaps Name %S DestinationLineCount %lu dwDestination %lu not found\n", MixerInfo
->MixCaps
.szPname
, MixerInfo
->MixCaps
.cDestinations
, MixerLine
->dwDestination
);
200 return MM_STATUS_UNSUCCESSFUL
;
203 /* check if dwSource is out of bounds */
204 if (MixerLine
->dwSource
>= MixerLineSrc
->Line
.cConnections
)
206 DPRINT1("MixerCaps Name %S MixerLineName %S Connections %lu dwSource %lu not found\n", MixerInfo
->MixCaps
.szPname
, MixerLineSrc
->Line
.szName
, MixerLineSrc
->Line
.cConnections
, MixerLine
->dwSource
);
207 return MM_STATUS_UNSUCCESSFUL
;
210 /* calculate destination line id */
211 DestinationLineID
= (MixerLine
->dwSource
* SOURCE_LINE
) + MixerLine
->dwDestination
;
213 DPRINT("MixerName %S cDestinations %lu MixerLineName %S cConnections %lu dwSource %lu dwDestination %lu ID %lx\n", MixerInfo
->MixCaps
.szPname
, MixerInfo
->MixCaps
.cDestinations
,
214 MixerLineSrc
->Line
.szName
, MixerLineSrc
->Line
.cConnections
,
215 MixerLine
->dwSource
, MixerLine
->dwDestination
,
217 /* get target destination line id */
218 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, DestinationLineID
);
221 ASSERT(MixerLineSrc
);
223 DPRINT("Line %u Name %S\n", MixerLineSrc
->Line
.dwSource
, MixerLineSrc
->Line
.szName
);
225 /* copy mixer line */
226 MixerContext
->Copy(MixerLine
, &MixerLineSrc
->Line
, sizeof(MIXERLINEW
));
228 /* make sure it is null terminated */
229 MixerLine
->szName
[MIXER_LONG_NAME_CHARS
-1] = L
'\0';
230 MixerLine
->szShortName
[MIXER_SHORT_NAME_CHARS
-1] = L
'\0';
231 MixerLine
->Target
.szPname
[MAXPNAMELEN
-1] = L
'\0';
234 return MM_STATUS_SUCCESS
;
236 else if (Flags
== MIXER_GETLINEINFOF_LINEID
)
238 /* cast to mixer info */
239 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
241 /* try to find line */
242 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, MixerLine
->dwLineID
);
245 /* invalid parameter */
246 DPRINT1("MMixerGetLineInfo: MixerName %S Line not found 0x%lx\n", MixerInfo
->MixCaps
.szPname
, MixerLine
->dwLineID
);
247 return MM_STATUS_INVALID_PARAMETER
;
250 DPRINT("Line %u Name %S\n", MixerLineSrc
->Line
.dwSource
, MixerLineSrc
->Line
.szName
);
253 MixerContext
->Copy(MixerLine
, &MixerLineSrc
->Line
, sizeof(MIXERLINEW
));
255 /* make sure it is null terminated */
256 MixerLine
->szName
[MIXER_LONG_NAME_CHARS
-1] = L
'\0';
257 MixerLine
->szShortName
[MIXER_SHORT_NAME_CHARS
-1] = L
'\0';
258 MixerLine
->Target
.szPname
[MAXPNAMELEN
-1] = L
'\0';
260 return MM_STATUS_SUCCESS
;
262 else if (Flags
== MIXER_GETLINEINFOF_COMPONENTTYPE
)
264 /* cast to mixer info */
265 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
267 /* find mixer line by component type */
268 MixerLineSrc
= MMixerGetSourceMixerLineByComponentType(MixerInfo
, MixerLine
->dwComponentType
);
271 DPRINT1("Failed to find component type %x\n", MixerLine
->dwComponentType
);
272 return MM_STATUS_UNSUCCESSFUL
;
275 /* copy mixer line */
276 MixerContext
->Copy(MixerLine
, &MixerLineSrc
->Line
, sizeof(MIXERLINEW
));
278 /* make sure it is null terminated */
279 MixerLine
->szName
[MIXER_LONG_NAME_CHARS
-1] = L
'\0';
280 MixerLine
->szShortName
[MIXER_SHORT_NAME_CHARS
-1] = L
'\0';
281 MixerLine
->Target
.szPname
[MAXPNAMELEN
-1] = L
'\0';
284 return MM_STATUS_SUCCESS
;
286 else if (Flags
== MIXER_GETLINEINFOF_TARGETTYPE
)
288 DPRINT1("MIXER_GETLINEINFOF_TARGETTYPE handling is unimplemented\n");
292 DPRINT1("Unknown Flags %lx handling is unimplemented\n", Flags
);
295 return MM_STATUS_NOT_IMPLEMENTED
;
299 MMixerGetLineControls(
300 IN PMIXER_CONTEXT MixerContext
,
301 IN HANDLE MixerHandle
,
304 OUT LPMIXERLINECONTROLSW MixerLineControls
)
306 LPMIXER_INFO MixerInfo
;
307 LPMIXERLINE_EXT MixerLineSrc
;
308 LPMIXERCONTROL_EXT MixerControl
;
313 /* verify mixer context */
314 Status
= MMixerVerifyContext(MixerContext
);
316 if (Status
!= MM_STATUS_SUCCESS
)
318 /* invalid context passed */
322 if (MixerLineControls
->cbStruct
!= sizeof(MIXERLINECONTROLSW
))
324 DPRINT1("Invalid MixerLineControls cbStruct passed %lu expected %lu\n", MixerLineControls
->cbStruct
, sizeof(MIXERLINECONTROLSW
));
325 /* invalid parameter */
326 return MM_STATUS_INVALID_PARAMETER
;
329 if (MixerLineControls
->cbmxctrl
!= sizeof(MIXERCONTROLW
))
331 DPRINT1("Invalid MixerLineControls cbmxctrl passed %lu expected %lu\n", MixerLineControls
->cbStruct
, sizeof(MIXERLINECONTROLSW
));
332 /* invalid parameter */
333 return MM_STATUS_INVALID_PARAMETER
;
336 if ((Flags
& (MIXER_OBJECTF_MIXER
| MIXER_OBJECTF_HMIXER
)) == MIXER_OBJECTF_MIXER
)
338 /* caller passed mixer id */
339 MixerHandle
= (HANDLE
)MMixerGetMixerInfoByIndex(MixerContext
, MixerId
);
343 /* invalid parameter */
344 return MM_STATUS_INVALID_PARAMETER
;
348 Flags
&= ~MIXER_OBJECTF_HMIXER
;
350 DPRINT("MMixerGetLineControls MixerId %lu Flags %lu\n", MixerId
, Flags
);
352 if (Flags
== MIXER_GETLINECONTROLSF_ALL
)
354 /* cast to mixer info */
355 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
358 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, MixerLineControls
->dwLineID
);
362 /* invalid line id */
363 DPRINT("MMixerGetLineControls Line not found %lx\n", MixerLineControls
->dwLineID
);
364 return MM_STATUS_INVALID_PARAMETER
;
367 if (MixerLineSrc
->Line
.cControls
!= MixerLineControls
->cControls
)
369 /* invalid parameter */
370 DPRINT1("Invalid control count %lu expected %lu\n", MixerLineControls
->cControls
, MixerLineSrc
->Line
.cControls
);
371 return MM_STATUS_INVALID_PARAMETER
;
374 /* copy line control(s) */
375 Entry
= MixerLineSrc
->ControlsList
.Flink
;
377 while(Entry
!= &MixerLineSrc
->ControlsList
)
379 /* get mixer control */
380 MixerControl
= (LPMIXERCONTROL_EXT
)CONTAINING_RECORD(Entry
, MIXERCONTROL_EXT
, Entry
);
382 /* copy mixer control */
383 MixerContext
->Copy(&MixerLineControls
->pamxctrl
[Index
], &MixerControl
->Control
, sizeof(MIXERCONTROLW
));
386 Entry
= Entry
->Flink
;
388 /* increment mixer control offset */
391 return MM_STATUS_SUCCESS
;
393 else if (Flags
== MIXER_GETLINECONTROLSF_ONEBYTYPE
)
395 /* cast to mixer info */
396 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
399 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, MixerLineControls
->dwLineID
);
403 /* invalid line id */
404 DPRINT1("MMixerGetLineControls Line not found %lx\n", MixerLineControls
->dwLineID
);
405 return MM_STATUS_INVALID_PARAMETER
;
409 ASSERT(MixerLineControls
->cControls
== 1);
410 ASSERT(MixerLineControls
->cbmxctrl
== sizeof(MIXERCONTROLW
));
411 ASSERT(MixerLineControls
->pamxctrl
!= NULL
);
413 Entry
= MixerLineSrc
->ControlsList
.Flink
;
414 while(Entry
!= &MixerLineSrc
->ControlsList
)
416 MixerControl
= (LPMIXERCONTROL_EXT
)CONTAINING_RECORD(Entry
, MIXERCONTROL_EXT
, Entry
);
417 if (MixerLineControls
->dwControlType
== MixerControl
->Control
.dwControlType
)
419 /* found a control with that type */
420 MixerContext
->Copy(MixerLineControls
->pamxctrl
, &MixerControl
->Control
, sizeof(MIXERCONTROLW
));
421 return MM_STATUS_SUCCESS
;
424 /* move to next entry */
425 Entry
= Entry
->Flink
;
428 DPRINT("DeviceInfo->u.MixControls.dwControlType %x not found in Line %x cControls %u \n", MixerLineControls
->dwControlType
, MixerLineControls
->dwLineID
, MixerLineSrc
->Line
.cControls
);
429 return MM_STATUS_UNSUCCESSFUL
;
431 else if (Flags
== MIXER_GETLINECONTROLSF_ONEBYID
)
433 /* cast to mixer info */
434 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
436 Status
= MMixerGetMixerControlById(MixerInfo
, MixerLineControls
->dwControlID
, NULL
, &MixerControl
, NULL
);
438 if (Status
!= MM_STATUS_SUCCESS
)
440 /* invalid parameter */
441 DPRINT("MMixerGetLineControls ControlID not found %lx\n", MixerLineControls
->dwLineID
);
442 return MM_STATUS_INVALID_PARAMETER
;
445 ASSERT(MixerLineControls
->cControls
== 1);
446 ASSERT(MixerLineControls
->cbmxctrl
== sizeof(MIXERCONTROLW
));
447 ASSERT(MixerLineControls
->pamxctrl
!= NULL
);
449 DPRINT("MMixerGetLineControls ControlID %lx ControlType %lx Name %S\n", MixerControl
->Control
.dwControlID
, MixerControl
->Control
.dwControlType
, MixerControl
->Control
.szName
);
451 /* copy the controls */
452 MixerContext
->Copy(MixerLineControls
->pamxctrl
, &MixerControl
->Control
, sizeof(MIXERCONTROLW
));
453 MixerLineControls
->pamxctrl
->szName
[MIXER_LONG_NAME_CHARS
-1] = L
'\0';
454 MixerLineControls
->pamxctrl
->szShortName
[MIXER_SHORT_NAME_CHARS
-1] = L
'\0';
456 return MM_STATUS_SUCCESS
;
459 return MM_STATUS_NOT_IMPLEMENTED
;
463 MMixerSetControlDetails(
464 IN PMIXER_CONTEXT MixerContext
,
465 IN HANDLE MixerHandle
,
468 OUT LPMIXERCONTROLDETAILS MixerControlDetails
)
472 LPMIXER_INFO MixerInfo
;
473 LPMIXERLINE_EXT MixerLine
;
474 LPMIXERCONTROL_EXT MixerControl
;
476 /* verify mixer context */
477 Status
= MMixerVerifyContext(MixerContext
);
479 if (Status
!= MM_STATUS_SUCCESS
)
481 /* invalid context passed */
482 DPRINT1("invalid context\n");
486 if ((Flags
& (MIXER_OBJECTF_MIXER
| MIXER_OBJECTF_HMIXER
)) == MIXER_OBJECTF_MIXER
)
488 /* caller passed mixer id */
489 MixerHandle
= (HANDLE
)MMixerGetMixerInfoByIndex(MixerContext
, MixerId
);
493 /* invalid parameter */
494 DPRINT1("invalid handle\n");
495 return MM_STATUS_INVALID_PARAMETER
;
500 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
502 /* get mixer control */
503 Status
= MMixerGetMixerControlById(MixerInfo
, MixerControlDetails
->dwControlID
, &MixerLine
, &MixerControl
, &NodeId
);
505 /* check for success */
506 if (Status
!= MM_STATUS_SUCCESS
)
508 /* failed to find control id */
509 DPRINT1("invalid control id %lu\n", MixerControlDetails
->dwControlID
);
510 return MM_STATUS_INVALID_PARAMETER
;
513 DPRINT("MMixerSetControlDetails ControlType %lx MixerControlName %S MixerLineName %S NodeID %lu\n", MixerControl
->Control
.dwControlType
, MixerControl
->Control
.szName
, MixerLine
->Line
.szName
, NodeId
);
514 switch(MixerControl
->Control
.dwControlType
)
516 case MIXERCONTROL_CONTROLTYPE_MUTE
:
517 Status
= MMixerSetGetMuteControlDetails(MixerContext
, MixerInfo
, MixerControl
, MixerLine
->Line
.dwLineID
, MixerControlDetails
, TRUE
);
519 case MIXERCONTROL_CONTROLTYPE_VOLUME
:
520 Status
= MMixerSetGetVolumeControlDetails(MixerContext
, MixerInfo
, NodeId
, TRUE
, MixerControl
, MixerControlDetails
, MixerLine
);
522 case MIXERCONTROL_CONTROLTYPE_MUX
:
523 Status
= MMixerSetGetMuxControlDetails(MixerContext
, MixerInfo
, NodeId
, TRUE
, Flags
, MixerControl
, MixerControlDetails
, MixerLine
);
526 Status
= MM_STATUS_NOT_IMPLEMENTED
;
533 MMixerGetControlDetails(
534 IN PMIXER_CONTEXT MixerContext
,
535 IN HANDLE MixerHandle
,
538 OUT LPMIXERCONTROLDETAILS MixerControlDetails
)
542 LPMIXER_INFO MixerInfo
;
543 LPMIXERLINE_EXT MixerLine
;
544 LPMIXERCONTROL_EXT MixerControl
;
546 /* verify mixer context */
547 Status
= MMixerVerifyContext(MixerContext
);
549 if (Status
!= MM_STATUS_SUCCESS
)
551 /* invalid context passed */
555 if ((Flags
& (MIXER_OBJECTF_MIXER
| MIXER_OBJECTF_HMIXER
)) == MIXER_OBJECTF_MIXER
)
557 /* caller passed mixer id */
558 MixerHandle
= (HANDLE
)MMixerGetMixerInfoByIndex(MixerContext
, MixerId
);
562 /* invalid parameter */
563 return MM_STATUS_INVALID_PARAMETER
;
568 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
570 /* get mixer control */
571 Status
= MMixerGetMixerControlById(MixerInfo
, MixerControlDetails
->dwControlID
, &MixerLine
, &MixerControl
, &NodeId
);
573 /* check for success */
574 if (Status
!= MM_STATUS_SUCCESS
)
576 /* failed to find control id */
577 return MM_STATUS_INVALID_PARAMETER
;
580 switch(MixerControl
->Control
.dwControlType
)
582 case MIXERCONTROL_CONTROLTYPE_MUTE
:
583 Status
= MMixerSetGetMuteControlDetails(MixerContext
, MixerInfo
, MixerControl
, MixerLine
->Line
.dwLineID
, MixerControlDetails
, FALSE
);
585 case MIXERCONTROL_CONTROLTYPE_VOLUME
:
586 Status
= MMixerSetGetVolumeControlDetails(MixerContext
, MixerInfo
, NodeId
, FALSE
, MixerControl
, MixerControlDetails
, MixerLine
);
588 case MIXERCONTROL_CONTROLTYPE_ONOFF
:
589 DPRINT1("Not Implemented MIXERCONTROL_CONTROLTYPE_ONOFF\n");
591 case MIXERCONTROL_CONTROLTYPE_MUX
:
592 Status
= MMixerSetGetMuxControlDetails(MixerContext
, MixerInfo
, NodeId
, FALSE
, Flags
, MixerControl
, MixerControlDetails
, MixerLine
);
596 Status
= MM_STATUS_NOT_IMPLEMENTED
;
597 DPRINT1("ControlType %lx not implemented\n", MixerControl
->Control
.dwControlType
);
604 MMixerPrintMixerLineControls(
605 IN LPMIXERLINE_EXT MixerLine
)
608 LPMIXERCONTROL_EXT MixerControl
;
611 Entry
= MixerLine
->ControlsList
.Flink
;
612 while(Entry
!= &MixerLine
->ControlsList
)
614 MixerControl
= (LPMIXERCONTROL_EXT
)CONTAINING_RECORD(Entry
, MIXERCONTROL_EXT
, Entry
);
617 DPRINT1("Control Index: %lu\n", Index
);
619 DPRINT1("cbStruct %u\n", MixerControl
->Control
.cbStruct
);
620 DPRINT1("dwControlID %lu\n", MixerControl
->Control
.dwControlID
);
621 DPRINT1("dwControlType %lx\n", MixerControl
->Control
.dwControlType
);
622 DPRINT1("fdwControl %lu\n", MixerControl
->Control
.fdwControl
);
623 DPRINT1("cMultipleItems %lu\n", MixerControl
->Control
.cMultipleItems
);
624 DPRINT1("szShortName %S\n", MixerControl
->Control
.szShortName
);
625 DPRINT1("szName %S\n", MixerControl
->Control
.szName
);
626 DPRINT1("Bounds.dwMinimum %lu\n", MixerControl
->Control
.Bounds
.dwMinimum
);
627 DPRINT1("Bounds.dwMaximum %lu\n", MixerControl
->Control
.Bounds
.dwMaximum
);
629 DPRINT1("Metrics.Reserved[0] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[0]);
630 DPRINT1("Metrics.Reserved[1] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[1]);
631 DPRINT1("Metrics.Reserved[2] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[2]);
632 DPRINT1("Metrics.Reserved[3] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[3]);
633 DPRINT1("Metrics.Reserved[4] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[4]);
634 DPRINT1("Metrics.Reserved[5] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[5]);
636 Entry
= Entry
->Flink
;
643 IN PMIXER_CONTEXT MixerContext
,
644 IN PMIXER_LIST MixerList
)
646 ULONG Index
, SubIndex
, DestinationLineID
, SrcIndex
;
647 LPMIXER_INFO MixerInfo
;
648 LPMIXERLINE_EXT DstMixerLine
, SrcMixerLine
;
650 DPRINT1("MixerList %p\n", MixerList
);
651 DPRINT1("MidiInCount %lu\n", MixerList
->MidiInListCount
);
652 DPRINT1("MidiOutCount %lu\n", MixerList
->MidiOutListCount
);
653 DPRINT1("WaveInCount %lu\n", MixerList
->WaveInListCount
);
654 DPRINT1("WaveOutCount %lu\n", MixerList
->WaveOutListCount
);
655 DPRINT1("MixerCount %p\n", MixerList
->MixerListCount
);
658 for(Index
= 0; Index
< MixerList
->MixerListCount
; Index
++)
661 MixerInfo
= MMixerGetMixerInfoByIndex(MixerContext
, Index
);
665 DPRINT1("Name :%S\n", MixerInfo
->MixCaps
.szPname
);
666 DPRINT1("cDestinations: %lu\n", MixerInfo
->MixCaps
.cDestinations
);
667 DPRINT1("fdwSupport %lu\n", MixerInfo
->MixCaps
.fdwSupport
);
668 DPRINT1("vDriverVersion %lx\n", MixerInfo
->MixCaps
.vDriverVersion
);
669 DPRINT1("wMid %lx\n", MixerInfo
->MixCaps
.wMid
);
670 DPRINT1("wPid %lx\n", MixerInfo
->MixCaps
.wPid
);
672 for(SubIndex
= 0; SubIndex
< MixerInfo
->MixCaps
.cDestinations
; SubIndex
++)
674 /* calculate destination line id */
675 DestinationLineID
= (SubIndex
+ DESTINATION_LINE
);
677 /* get destination line */
678 DstMixerLine
= MMixerGetSourceMixerLineByLineId(MixerInfo
, DestinationLineID
);
679 DPRINT1("//----------------------------------------------------------------------------------------------\n");
681 DPRINT1("Destination Index %lu\n", SubIndex
);
683 DPRINT1("cChannels %lu\n", DstMixerLine
->Line
.cChannels
);
684 DPRINT1("cConnections %lu\n", DstMixerLine
->Line
.cConnections
);
685 DPRINT1("cControls %lu\n", DstMixerLine
->Line
.cControls
);
686 DPRINT1("dwComponentType %lx\n", DstMixerLine
->Line
.dwComponentType
);
687 DPRINT1("dwDestination %lu\n", DstMixerLine
->Line
.dwDestination
);
688 DPRINT1("dwLineID %lx\n", DstMixerLine
->Line
.dwLineID
);
689 DPRINT1("dwSource %lx\n", DstMixerLine
->Line
.dwSource
);
690 DPRINT1("dwUser %lu\n", DstMixerLine
->Line
.dwUser
);
691 DPRINT1("fdwLine %lu\n", DstMixerLine
->Line
.fdwLine
);
692 DPRINT1("szName %S\n", DstMixerLine
->Line
.szName
);
693 DPRINT1("szShortName %S\n", DstMixerLine
->Line
.szShortName
);
694 DPRINT1("Target.dwDeviceId %lu\n", DstMixerLine
->Line
.Target
.dwDeviceID
);
695 DPRINT1("Target.dwType %lu\n", DstMixerLine
->Line
.Target
.dwType
);
696 DPRINT1("Target.szName %S\n", DstMixerLine
->Line
.Target
.szPname
);
697 DPRINT1("Target.vDriverVersion %lx\n", DstMixerLine
->Line
.Target
.vDriverVersion
);
698 DPRINT1("Target.wMid %lx\n", DstMixerLine
->Line
.Target
.wMid
);
699 DPRINT1("Target.wPid %lx\n", DstMixerLine
->Line
.Target
.wPid
);
700 MMixerPrintMixerLineControls(DstMixerLine
);
702 for(SrcIndex
= 0; SrcIndex
< DstMixerLine
->Line
.cConnections
; SrcIndex
++)
704 /* calculate destination line id */
705 DestinationLineID
= (SOURCE_LINE
* SrcIndex
) + SubIndex
;
707 /* get source line */
708 SrcMixerLine
= MMixerGetSourceMixerLineByLineId(MixerInfo
, DestinationLineID
);
709 DPRINT1("//==============================================================================================\n");
711 DPRINT1("SrcLineIndex : %lu\n", SrcIndex
);
713 DPRINT1("cChannels %lu\n", SrcMixerLine
->Line
.cChannels
);
714 DPRINT1("cConnections %lu\n", SrcMixerLine
->Line
.cConnections
);
715 DPRINT1("cControls %lu\n", SrcMixerLine
->Line
.cControls
);
716 DPRINT1("dwComponentType %lx\n", SrcMixerLine
->Line
.dwComponentType
);
717 DPRINT1("dwDestination %lu\n", SrcMixerLine
->Line
.dwDestination
);
718 DPRINT1("dwLineID %lx\n", SrcMixerLine
->Line
.dwLineID
);
719 DPRINT1("dwSource %lx\n", SrcMixerLine
->Line
.dwSource
);
720 DPRINT1("dwUser %lu\n", SrcMixerLine
->Line
.dwUser
);
721 DPRINT1("fdwLine %lu\n", SrcMixerLine
->Line
.fdwLine
);
722 DPRINT1("szName %S\n", SrcMixerLine
->Line
.szName
);
723 DPRINT1("szShortName %S\n", SrcMixerLine
->Line
.szShortName
);
724 DPRINT1("Target.dwDeviceId %lu\n", SrcMixerLine
->Line
.Target
.dwDeviceID
);
725 DPRINT1("Target.dwType %lu\n", SrcMixerLine
->Line
.Target
.dwType
);
726 DPRINT1("Target.szName %S\n", SrcMixerLine
->Line
.Target
.szPname
);
727 DPRINT1("Target.vDriverVersion %lx\n", SrcMixerLine
->Line
.Target
.vDriverVersion
);
728 DPRINT1("Target.wMid %lx\n", SrcMixerLine
->Line
.Target
.wMid
);
729 DPRINT1("Target.wPid %lx\n", SrcMixerLine
->Line
.Target
.wPid
);
730 MMixerPrintMixerLineControls(SrcMixerLine
);
738 IN PMIXER_CONTEXT MixerContext
,
739 IN PMIXER_ENUM EnumFunction
,
740 IN PVOID EnumContext
)
744 ULONG DeviceIndex
, Count
;
746 LPMIXER_DATA MixerData
;
747 PMIXER_LIST MixerList
;
750 if (!MixerContext
|| !EnumFunction
|| !EnumContext
)
752 /* invalid parameter */
753 return MM_STATUS_INVALID_PARAMETER
;
756 if (!MixerContext
->Alloc
|| !MixerContext
->Control
|| !MixerContext
->Free
|| !MixerContext
->Open
||
757 !MixerContext
->AllocEventData
|| !MixerContext
->FreeEventData
||
758 !MixerContext
->Close
|| !MixerContext
->OpenKey
|| !MixerContext
->QueryKeyValue
|| !MixerContext
->CloseKey
)
760 /* invalid parameter */
761 return MM_STATUS_INVALID_PARAMETER
;
764 /* allocate a mixer list */
765 MixerList
= (PMIXER_LIST
)MixerContext
->Alloc(sizeof(MIXER_LIST
));
769 return MM_STATUS_NO_MEMORY
;
772 /* initialize mixer list */
773 MixerList
->MixerListCount
= 0;
774 MixerList
->MixerDataCount
= 0;
775 MixerList
->WaveInListCount
= 0;
776 MixerList
->WaveOutListCount
= 0;
777 MixerList
->MidiInListCount
= 0;
778 MixerList
->MidiOutListCount
= 0;
779 InitializeListHead(&MixerList
->MixerList
);
780 InitializeListHead(&MixerList
->MixerData
);
781 InitializeListHead(&MixerList
->WaveInList
);
782 InitializeListHead(&MixerList
->WaveOutList
);
783 InitializeListHead(&MixerList
->MidiInList
);
784 InitializeListHead(&MixerList
->MidiOutList
);
786 /* store mixer list */
787 MixerContext
->MixerContext
= (PVOID
)MixerList
;
789 /* start enumerating all available devices */
795 /* enumerate a device */
796 Status
= EnumFunction(EnumContext
, DeviceIndex
, &DeviceName
, &hMixer
, &hKey
);
798 if (Status
!= MM_STATUS_SUCCESS
)
800 /* check error code */
801 if (Status
== MM_STATUS_NO_MORE_DEVICES
)
803 /* enumeration has finished */
808 DPRINT1("Failed to enumerate device %lu\n", DeviceIndex
);
816 /* create a mixer data entry */
817 Status
= MMixerCreateMixerData(MixerContext
, MixerList
, DeviceIndex
, DeviceName
, hMixer
, hKey
);
818 if (Status
!= MM_STATUS_SUCCESS
)
822 /* increment device index */
826 /* now all filters have been pre-opened
827 * lets enumerate the filters
829 Entry
= MixerList
->MixerData
.Flink
;
830 while(Entry
!= &MixerList
->MixerData
)
832 MixerData
= (LPMIXER_DATA
)CONTAINING_RECORD(Entry
, MIXER_DATA
, Entry
);
833 MMixerSetupFilter(MixerContext
, MixerList
, MixerData
, &Count
);
834 Entry
= Entry
->Flink
;
837 Entry
= MixerList
->MixerData
.Flink
;
838 while(Entry
!= &MixerList
->MixerData
)
840 MixerData
= (LPMIXER_DATA
)CONTAINING_RECORD(Entry
, MIXER_DATA
, Entry
);
842 /* now handle alternative mixer types */
843 MMixerHandleAlternativeMixers(MixerContext
, MixerList
, MixerData
, MixerData
->Topology
);
844 Entry
= Entry
->Flink
;
847 //MMixerPrintMixers(MixerContext, MixerList);
850 return MM_STATUS_SUCCESS
;