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
,
119 IN PVOID MixerEventContext
,
120 IN PMIXER_EVENT MixerEventRoutine
)
123 LPMIXER_INFO MixerInfo
;
125 /* verify mixer context */
126 Status
= MMixerVerifyContext(MixerContext
);
128 if (Status
!= MM_STATUS_SUCCESS
)
130 /* invalid context passed */
131 DPRINT1("invalid context\n");
136 MixerInfo
= MMixerGetMixerInfoByIndex(MixerContext
, MixerId
);
139 /* invalid mixer id */
140 DPRINT1("invalid mixer id %lu\n", MixerId
);
141 return MM_STATUS_INVALID_PARAMETER
;
144 /* remove event from list */
145 return MMixerRemoveEvent(MixerContext
, MixerInfo
, MixerEventContext
, MixerEventRoutine
);
150 IN PMIXER_CONTEXT MixerContext
,
151 IN HANDLE MixerHandle
,
154 OUT LPMIXERLINEW MixerLine
)
157 LPMIXER_INFO MixerInfo
;
158 LPMIXERLINE_EXT MixerLineSrc
;
159 ULONG DestinationLineID
;
161 /* verify mixer context */
162 Status
= MMixerVerifyContext(MixerContext
);
164 if (Status
!= MM_STATUS_SUCCESS
)
166 /* invalid context passed */
169 if ((Flags
& (MIXER_OBJECTF_MIXER
| MIXER_OBJECTF_HMIXER
)) == MIXER_OBJECTF_MIXER
)
171 /* caller passed mixer id */
172 MixerHandle
= (HANDLE
)MMixerGetMixerInfoByIndex(MixerContext
, MixerId
);
176 /* invalid parameter */
177 return MM_STATUS_INVALID_PARAMETER
;
181 if (MixerLine
->cbStruct
!= sizeof(MIXERLINEW
))
183 DPRINT1("MixerLine Expected %lu but got %lu\n", sizeof(MIXERLINEW
), MixerLine
->cbStruct
);
184 return MM_STATUS_INVALID_PARAMETER
;
187 /* clear hmixer from flags */
188 Flags
&=~MIXER_OBJECTF_HMIXER
;
190 DPRINT("MMixerGetLineInfo MixerId %lu Flags %lu\n", MixerId
, Flags
);
192 if (Flags
== MIXER_GETLINEINFOF_DESTINATION
)
194 /* cast to mixer info */
195 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
197 /* calculate destination line id */
198 DestinationLineID
= (MixerLine
->dwDestination
+ DESTINATION_LINE
);
200 /* get destination line */
201 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, DestinationLineID
);
203 if (MixerLineSrc
== NULL
)
205 DPRINT1("MixerCaps Name %S DestinationLineCount %lu dwDestination %lu not found\n", MixerInfo
->MixCaps
.szPname
, MixerInfo
->MixCaps
.cDestinations
, MixerLine
->dwDestination
);
206 return MM_STATUS_UNSUCCESSFUL
;
208 /* copy mixer line */
209 MixerContext
->Copy(MixerLine
, &MixerLineSrc
->Line
, sizeof(MIXERLINEW
));
211 /* make sure it is null terminated */
212 MixerLine
->szName
[MIXER_LONG_NAME_CHARS
-1] = L
'\0';
213 MixerLine
->szShortName
[MIXER_SHORT_NAME_CHARS
-1] = L
'\0';
214 MixerLine
->Target
.szPname
[MAXPNAMELEN
-1] = L
'\0';
217 return MM_STATUS_SUCCESS
;
219 else if (Flags
== MIXER_GETLINEINFOF_SOURCE
)
221 /* cast to mixer info */
222 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
224 /* calculate destination line id */
225 DestinationLineID
= (MixerLine
->dwDestination
+ DESTINATION_LINE
);
227 /* get destination line */
228 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, DestinationLineID
);
230 if (MixerLineSrc
== NULL
)
232 DPRINT1("MixerCaps Name %S DestinationLineCount %lu dwDestination %lu not found\n", MixerInfo
->MixCaps
.szPname
, MixerInfo
->MixCaps
.cDestinations
, MixerLine
->dwDestination
);
233 return MM_STATUS_UNSUCCESSFUL
;
236 /* check if dwSource is out of bounds */
237 if (MixerLine
->dwSource
>= MixerLineSrc
->Line
.cConnections
)
239 DPRINT1("MixerCaps Name %S MixerLineName %S Connections %lu dwSource %lu not found\n", MixerInfo
->MixCaps
.szPname
, MixerLineSrc
->Line
.szName
, MixerLineSrc
->Line
.cConnections
, MixerLine
->dwSource
);
240 return MM_STATUS_UNSUCCESSFUL
;
243 /* calculate destination line id */
244 DestinationLineID
= (MixerLine
->dwSource
* SOURCE_LINE
) + MixerLine
->dwDestination
;
246 DPRINT("MixerName %S cDestinations %lu MixerLineName %S cConnections %lu dwSource %lu dwDestination %lu ID %lx\n", MixerInfo
->MixCaps
.szPname
, MixerInfo
->MixCaps
.cDestinations
,
247 MixerLineSrc
->Line
.szName
, MixerLineSrc
->Line
.cConnections
,
248 MixerLine
->dwSource
, MixerLine
->dwDestination
,
250 /* get target destination line id */
251 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, DestinationLineID
);
254 ASSERT(MixerLineSrc
);
256 DPRINT("Line %u Name %S\n", MixerLineSrc
->Line
.dwSource
, MixerLineSrc
->Line
.szName
);
258 /* copy mixer line */
259 MixerContext
->Copy(MixerLine
, &MixerLineSrc
->Line
, sizeof(MIXERLINEW
));
261 /* make sure it is null terminated */
262 MixerLine
->szName
[MIXER_LONG_NAME_CHARS
-1] = L
'\0';
263 MixerLine
->szShortName
[MIXER_SHORT_NAME_CHARS
-1] = L
'\0';
264 MixerLine
->Target
.szPname
[MAXPNAMELEN
-1] = L
'\0';
267 return MM_STATUS_SUCCESS
;
269 else if (Flags
== MIXER_GETLINEINFOF_LINEID
)
271 /* cast to mixer info */
272 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
274 /* try to find line */
275 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, MixerLine
->dwLineID
);
278 /* invalid parameter */
279 DPRINT1("MMixerGetLineInfo: MixerName %S Line not found 0x%lx\n", MixerInfo
->MixCaps
.szPname
, MixerLine
->dwLineID
);
280 return MM_STATUS_INVALID_PARAMETER
;
283 DPRINT("Line %u Name %S\n", MixerLineSrc
->Line
.dwSource
, MixerLineSrc
->Line
.szName
);
286 MixerContext
->Copy(MixerLine
, &MixerLineSrc
->Line
, sizeof(MIXERLINEW
));
288 /* make sure it is null terminated */
289 MixerLine
->szName
[MIXER_LONG_NAME_CHARS
-1] = L
'\0';
290 MixerLine
->szShortName
[MIXER_SHORT_NAME_CHARS
-1] = L
'\0';
291 MixerLine
->Target
.szPname
[MAXPNAMELEN
-1] = L
'\0';
293 return MM_STATUS_SUCCESS
;
295 else if (Flags
== MIXER_GETLINEINFOF_COMPONENTTYPE
)
297 /* cast to mixer info */
298 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
300 /* find mixer line by component type */
301 MixerLineSrc
= MMixerGetSourceMixerLineByComponentType(MixerInfo
, MixerLine
->dwComponentType
);
304 DPRINT1("Failed to find component type %x\n", MixerLine
->dwComponentType
);
305 return MM_STATUS_UNSUCCESSFUL
;
308 /* copy mixer line */
309 MixerContext
->Copy(MixerLine
, &MixerLineSrc
->Line
, sizeof(MIXERLINEW
));
311 /* make sure it is null terminated */
312 MixerLine
->szName
[MIXER_LONG_NAME_CHARS
-1] = L
'\0';
313 MixerLine
->szShortName
[MIXER_SHORT_NAME_CHARS
-1] = L
'\0';
314 MixerLine
->Target
.szPname
[MAXPNAMELEN
-1] = L
'\0';
317 return MM_STATUS_SUCCESS
;
319 else if (Flags
== MIXER_GETLINEINFOF_TARGETTYPE
)
321 DPRINT1("MIXER_GETLINEINFOF_TARGETTYPE handling is unimplemented\n");
325 DPRINT1("Unknown Flags %lx handling is unimplemented\n", Flags
);
328 return MM_STATUS_NOT_IMPLEMENTED
;
332 MMixerGetLineControls(
333 IN PMIXER_CONTEXT MixerContext
,
334 IN HANDLE MixerHandle
,
337 OUT LPMIXERLINECONTROLSW MixerLineControls
)
339 LPMIXER_INFO MixerInfo
;
340 LPMIXERLINE_EXT MixerLineSrc
;
341 LPMIXERCONTROL_EXT MixerControl
;
346 /* verify mixer context */
347 Status
= MMixerVerifyContext(MixerContext
);
349 if (Status
!= MM_STATUS_SUCCESS
)
351 /* invalid context passed */
355 if (MixerLineControls
->cbStruct
!= sizeof(MIXERLINECONTROLSW
))
357 DPRINT1("Invalid MixerLineControls cbStruct passed %lu expected %lu\n", MixerLineControls
->cbStruct
, sizeof(MIXERLINECONTROLSW
));
358 /* invalid parameter */
359 return MM_STATUS_INVALID_PARAMETER
;
362 if (MixerLineControls
->cbmxctrl
!= sizeof(MIXERCONTROLW
))
364 DPRINT1("Invalid MixerLineControls cbmxctrl passed %lu expected %lu\n", MixerLineControls
->cbmxctrl
, sizeof(MIXERCONTROLW
));
365 /* invalid parameter */
366 return MM_STATUS_INVALID_PARAMETER
;
369 if ((Flags
& (MIXER_OBJECTF_MIXER
| MIXER_OBJECTF_HMIXER
)) == MIXER_OBJECTF_MIXER
)
371 /* caller passed mixer id */
372 MixerHandle
= (HANDLE
)MMixerGetMixerInfoByIndex(MixerContext
, MixerId
);
376 /* invalid parameter */
377 return MM_STATUS_INVALID_PARAMETER
;
381 Flags
&= ~MIXER_OBJECTF_HMIXER
;
383 DPRINT("MMixerGetLineControls MixerId %lu Flags %lu\n", MixerId
, Flags
);
385 if (Flags
== MIXER_GETLINECONTROLSF_ALL
)
387 /* cast to mixer info */
388 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
391 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, MixerLineControls
->dwLineID
);
395 /* invalid line id */
396 DPRINT("MMixerGetLineControls Line not found %lx\n", MixerLineControls
->dwLineID
);
397 return MM_STATUS_INVALID_PARAMETER
;
400 if (MixerLineSrc
->Line
.cControls
!= MixerLineControls
->cControls
)
402 /* invalid parameter */
403 DPRINT1("Invalid control count %lu expected %lu\n", MixerLineControls
->cControls
, MixerLineSrc
->Line
.cControls
);
404 return MM_STATUS_INVALID_PARAMETER
;
407 /* copy line control(s) */
408 Entry
= MixerLineSrc
->ControlsList
.Flink
;
410 while(Entry
!= &MixerLineSrc
->ControlsList
)
412 /* get mixer control */
413 MixerControl
= (LPMIXERCONTROL_EXT
)CONTAINING_RECORD(Entry
, MIXERCONTROL_EXT
, Entry
);
415 /* copy mixer control */
416 MixerContext
->Copy(&MixerLineControls
->pamxctrl
[Index
], &MixerControl
->Control
, sizeof(MIXERCONTROLW
));
419 Entry
= Entry
->Flink
;
421 /* increment mixer control offset */
424 return MM_STATUS_SUCCESS
;
426 else if (Flags
== MIXER_GETLINECONTROLSF_ONEBYTYPE
)
428 /* cast to mixer info */
429 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
432 MixerLineSrc
= MMixerGetSourceMixerLineByLineId(MixerInfo
, MixerLineControls
->dwLineID
);
436 /* invalid line id */
437 DPRINT1("MMixerGetLineControls Line not found %lx\n", MixerLineControls
->dwLineID
);
438 return MM_STATUS_INVALID_PARAMETER
;
442 ASSERT(MixerLineControls
->cControls
== 1);
443 ASSERT(MixerLineControls
->cbmxctrl
== sizeof(MIXERCONTROLW
));
444 ASSERT(MixerLineControls
->pamxctrl
!= NULL
);
446 Entry
= MixerLineSrc
->ControlsList
.Flink
;
447 while(Entry
!= &MixerLineSrc
->ControlsList
)
449 MixerControl
= (LPMIXERCONTROL_EXT
)CONTAINING_RECORD(Entry
, MIXERCONTROL_EXT
, Entry
);
450 if (MixerLineControls
->dwControlType
== MixerControl
->Control
.dwControlType
)
452 /* found a control with that type */
453 MixerContext
->Copy(MixerLineControls
->pamxctrl
, &MixerControl
->Control
, sizeof(MIXERCONTROLW
));
454 return MM_STATUS_SUCCESS
;
457 /* move to next entry */
458 Entry
= Entry
->Flink
;
461 DPRINT("DeviceInfo->u.MixControls.dwControlType %x not found in Line %x cControls %u \n", MixerLineControls
->dwControlType
, MixerLineControls
->dwLineID
, MixerLineSrc
->Line
.cControls
);
462 return MM_STATUS_UNSUCCESSFUL
;
464 else if (Flags
== MIXER_GETLINECONTROLSF_ONEBYID
)
466 /* cast to mixer info */
467 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
469 Status
= MMixerGetMixerControlById(MixerInfo
, MixerLineControls
->dwControlID
, NULL
, &MixerControl
, NULL
);
471 if (Status
!= MM_STATUS_SUCCESS
)
473 /* invalid parameter */
474 DPRINT("MMixerGetLineControls ControlID not found %lx\n", MixerLineControls
->dwLineID
);
475 return MM_STATUS_INVALID_PARAMETER
;
478 ASSERT(MixerLineControls
->cControls
== 1);
479 ASSERT(MixerLineControls
->cbmxctrl
== sizeof(MIXERCONTROLW
));
480 ASSERT(MixerLineControls
->pamxctrl
!= NULL
);
482 DPRINT("MMixerGetLineControls ControlID %lx ControlType %lx Name %S\n", MixerControl
->Control
.dwControlID
, MixerControl
->Control
.dwControlType
, MixerControl
->Control
.szName
);
484 /* copy the controls */
485 MixerContext
->Copy(MixerLineControls
->pamxctrl
, &MixerControl
->Control
, sizeof(MIXERCONTROLW
));
486 MixerLineControls
->pamxctrl
->szName
[MIXER_LONG_NAME_CHARS
-1] = L
'\0';
487 MixerLineControls
->pamxctrl
->szShortName
[MIXER_SHORT_NAME_CHARS
-1] = L
'\0';
489 return MM_STATUS_SUCCESS
;
492 return MM_STATUS_NOT_IMPLEMENTED
;
496 MMixerSetControlDetails(
497 IN PMIXER_CONTEXT MixerContext
,
498 IN HANDLE MixerHandle
,
501 OUT LPMIXERCONTROLDETAILS MixerControlDetails
)
505 LPMIXER_INFO MixerInfo
;
506 LPMIXERLINE_EXT MixerLine
;
507 LPMIXERCONTROL_EXT MixerControl
;
509 /* verify mixer context */
510 Status
= MMixerVerifyContext(MixerContext
);
512 if (Status
!= MM_STATUS_SUCCESS
)
514 /* invalid context passed */
515 DPRINT1("invalid context\n");
519 if ((Flags
& (MIXER_OBJECTF_MIXER
| MIXER_OBJECTF_HMIXER
)) == MIXER_OBJECTF_MIXER
)
521 /* caller passed mixer id */
522 MixerHandle
= (HANDLE
)MMixerGetMixerInfoByIndex(MixerContext
, MixerId
);
526 /* invalid parameter */
527 DPRINT1("invalid handle\n");
528 return MM_STATUS_INVALID_PARAMETER
;
533 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
535 /* get mixer control */
536 Status
= MMixerGetMixerControlById(MixerInfo
, MixerControlDetails
->dwControlID
, &MixerLine
, &MixerControl
, &NodeId
);
538 /* check for success */
539 if (Status
!= MM_STATUS_SUCCESS
)
541 /* failed to find control id */
542 DPRINT1("invalid control id %lu\n", MixerControlDetails
->dwControlID
);
543 return MM_STATUS_INVALID_PARAMETER
;
546 DPRINT("MMixerSetControlDetails ControlType %lx MixerControlName %S MixerLineName %S NodeID %lu\n", MixerControl
->Control
.dwControlType
, MixerControl
->Control
.szName
, MixerLine
->Line
.szName
, NodeId
);
547 switch(MixerControl
->Control
.dwControlType
)
549 case MIXERCONTROL_CONTROLTYPE_MUTE
:
550 Status
= MMixerSetGetMuteControlDetails(MixerContext
, MixerInfo
, MixerControl
, MixerLine
->Line
.dwLineID
, MixerControlDetails
, TRUE
);
552 case MIXERCONTROL_CONTROLTYPE_VOLUME
:
553 Status
= MMixerSetGetVolumeControlDetails(MixerContext
, MixerInfo
, NodeId
, TRUE
, MixerControl
, MixerControlDetails
, MixerLine
);
555 case MIXERCONTROL_CONTROLTYPE_MUX
:
556 Status
= MMixerSetGetMuxControlDetails(MixerContext
, MixerInfo
, NodeId
, TRUE
, Flags
, MixerControl
, MixerControlDetails
, MixerLine
);
559 Status
= MM_STATUS_NOT_IMPLEMENTED
;
566 MMixerGetControlDetails(
567 IN PMIXER_CONTEXT MixerContext
,
568 IN HANDLE MixerHandle
,
571 OUT LPMIXERCONTROLDETAILS MixerControlDetails
)
575 LPMIXER_INFO MixerInfo
;
576 LPMIXERLINE_EXT MixerLine
;
577 LPMIXERCONTROL_EXT MixerControl
;
579 /* verify mixer context */
580 Status
= MMixerVerifyContext(MixerContext
);
582 if (Status
!= MM_STATUS_SUCCESS
)
584 /* invalid context passed */
588 if ((Flags
& (MIXER_OBJECTF_MIXER
| MIXER_OBJECTF_HMIXER
)) == MIXER_OBJECTF_MIXER
)
590 /* caller passed mixer id */
591 MixerHandle
= (HANDLE
)MMixerGetMixerInfoByIndex(MixerContext
, MixerId
);
595 /* invalid parameter */
596 return MM_STATUS_INVALID_PARAMETER
;
601 MixerInfo
= (LPMIXER_INFO
)MixerHandle
;
603 /* get mixer control */
604 Status
= MMixerGetMixerControlById(MixerInfo
, MixerControlDetails
->dwControlID
, &MixerLine
, &MixerControl
, &NodeId
);
606 /* check for success */
607 if (Status
!= MM_STATUS_SUCCESS
)
609 /* failed to find control id */
610 return MM_STATUS_INVALID_PARAMETER
;
613 switch(MixerControl
->Control
.dwControlType
)
615 case MIXERCONTROL_CONTROLTYPE_MUTE
:
616 Status
= MMixerSetGetMuteControlDetails(MixerContext
, MixerInfo
, MixerControl
, MixerLine
->Line
.dwLineID
, MixerControlDetails
, FALSE
);
618 case MIXERCONTROL_CONTROLTYPE_VOLUME
:
619 Status
= MMixerSetGetVolumeControlDetails(MixerContext
, MixerInfo
, NodeId
, FALSE
, MixerControl
, MixerControlDetails
, MixerLine
);
621 case MIXERCONTROL_CONTROLTYPE_ONOFF
:
622 DPRINT1("Not Implemented MIXERCONTROL_CONTROLTYPE_ONOFF\n");
624 case MIXERCONTROL_CONTROLTYPE_MUX
:
625 Status
= MMixerSetGetMuxControlDetails(MixerContext
, MixerInfo
, NodeId
, FALSE
, Flags
, MixerControl
, MixerControlDetails
, MixerLine
);
629 Status
= MM_STATUS_NOT_IMPLEMENTED
;
630 DPRINT1("ControlType %lx not implemented\n", MixerControl
->Control
.dwControlType
);
637 MMixerPrintMixerLineControls(
638 IN LPMIXERLINE_EXT MixerLine
)
641 LPMIXERCONTROL_EXT MixerControl
;
644 Entry
= MixerLine
->ControlsList
.Flink
;
645 while(Entry
!= &MixerLine
->ControlsList
)
647 MixerControl
= (LPMIXERCONTROL_EXT
)CONTAINING_RECORD(Entry
, MIXERCONTROL_EXT
, Entry
);
650 DPRINT1("Control Index: %lu\n", Index
);
652 DPRINT1("cbStruct %u\n", MixerControl
->Control
.cbStruct
);
653 DPRINT1("dwControlID %lu\n", MixerControl
->Control
.dwControlID
);
654 DPRINT1("dwControlType %lx\n", MixerControl
->Control
.dwControlType
);
655 DPRINT1("fdwControl %lu\n", MixerControl
->Control
.fdwControl
);
656 DPRINT1("cMultipleItems %lu\n", MixerControl
->Control
.cMultipleItems
);
657 DPRINT1("szShortName %S\n", MixerControl
->Control
.szShortName
);
658 DPRINT1("szName %S\n", MixerControl
->Control
.szName
);
659 DPRINT1("Bounds.dwMinimum %lu\n", MixerControl
->Control
.Bounds
.dwMinimum
);
660 DPRINT1("Bounds.dwMaximum %lu\n", MixerControl
->Control
.Bounds
.dwMaximum
);
662 DPRINT1("Metrics.Reserved[0] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[0]);
663 DPRINT1("Metrics.Reserved[1] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[1]);
664 DPRINT1("Metrics.Reserved[2] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[2]);
665 DPRINT1("Metrics.Reserved[3] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[3]);
666 DPRINT1("Metrics.Reserved[4] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[4]);
667 DPRINT1("Metrics.Reserved[5] %lu\n", MixerControl
->Control
.Metrics
.dwReserved
[5]);
669 Entry
= Entry
->Flink
;
676 IN PMIXER_CONTEXT MixerContext
,
677 IN PMIXER_LIST MixerList
)
679 ULONG Index
, SubIndex
, DestinationLineID
, SrcIndex
;
680 LPMIXER_INFO MixerInfo
;
681 LPMIXERLINE_EXT DstMixerLine
, SrcMixerLine
;
683 DPRINT1("MixerList %p\n", MixerList
);
684 DPRINT1("MidiInCount %lu\n", MixerList
->MidiInListCount
);
685 DPRINT1("MidiOutCount %lu\n", MixerList
->MidiOutListCount
);
686 DPRINT1("WaveInCount %lu\n", MixerList
->WaveInListCount
);
687 DPRINT1("WaveOutCount %lu\n", MixerList
->WaveOutListCount
);
688 DPRINT1("MixerCount %p\n", MixerList
->MixerListCount
);
691 for(Index
= 0; Index
< MixerList
->MixerListCount
; Index
++)
694 MixerInfo
= MMixerGetMixerInfoByIndex(MixerContext
, Index
);
698 DPRINT1("Name :%S\n", MixerInfo
->MixCaps
.szPname
);
699 DPRINT1("cDestinations: %lu\n", MixerInfo
->MixCaps
.cDestinations
);
700 DPRINT1("fdwSupport %lu\n", MixerInfo
->MixCaps
.fdwSupport
);
701 DPRINT1("vDriverVersion %lx\n", MixerInfo
->MixCaps
.vDriverVersion
);
702 DPRINT1("wMid %lx\n", MixerInfo
->MixCaps
.wMid
);
703 DPRINT1("wPid %lx\n", MixerInfo
->MixCaps
.wPid
);
705 for(SubIndex
= 0; SubIndex
< MixerInfo
->MixCaps
.cDestinations
; SubIndex
++)
707 /* calculate destination line id */
708 DestinationLineID
= (SubIndex
+ DESTINATION_LINE
);
710 /* get destination line */
711 DstMixerLine
= MMixerGetSourceMixerLineByLineId(MixerInfo
, DestinationLineID
);
712 DPRINT1("//----------------------------------------------------------------------------------------------\n");
714 DPRINT1("Destination Index %lu\n", SubIndex
);
716 DPRINT1("cChannels %lu\n", DstMixerLine
->Line
.cChannels
);
717 DPRINT1("cConnections %lu\n", DstMixerLine
->Line
.cConnections
);
718 DPRINT1("cControls %lu\n", DstMixerLine
->Line
.cControls
);
719 DPRINT1("dwComponentType %lx\n", DstMixerLine
->Line
.dwComponentType
);
720 DPRINT1("dwDestination %lu\n", DstMixerLine
->Line
.dwDestination
);
721 DPRINT1("dwLineID %lx\n", DstMixerLine
->Line
.dwLineID
);
722 DPRINT1("dwSource %lx\n", DstMixerLine
->Line
.dwSource
);
723 DPRINT1("dwUser %lu\n", DstMixerLine
->Line
.dwUser
);
724 DPRINT1("fdwLine %lu\n", DstMixerLine
->Line
.fdwLine
);
725 DPRINT1("szName %S\n", DstMixerLine
->Line
.szName
);
726 DPRINT1("szShortName %S\n", DstMixerLine
->Line
.szShortName
);
727 DPRINT1("Target.dwDeviceId %lu\n", DstMixerLine
->Line
.Target
.dwDeviceID
);
728 DPRINT1("Target.dwType %lu\n", DstMixerLine
->Line
.Target
.dwType
);
729 DPRINT1("Target.szName %S\n", DstMixerLine
->Line
.Target
.szPname
);
730 DPRINT1("Target.vDriverVersion %lx\n", DstMixerLine
->Line
.Target
.vDriverVersion
);
731 DPRINT1("Target.wMid %lx\n", DstMixerLine
->Line
.Target
.wMid
);
732 DPRINT1("Target.wPid %lx\n", DstMixerLine
->Line
.Target
.wPid
);
733 MMixerPrintMixerLineControls(DstMixerLine
);
735 for(SrcIndex
= 0; SrcIndex
< DstMixerLine
->Line
.cConnections
; SrcIndex
++)
737 /* calculate destination line id */
738 DestinationLineID
= (SOURCE_LINE
* SrcIndex
) + SubIndex
;
740 /* get source line */
741 SrcMixerLine
= MMixerGetSourceMixerLineByLineId(MixerInfo
, DestinationLineID
);
742 DPRINT1("//==============================================================================================\n");
744 DPRINT1("SrcLineIndex : %lu\n", SrcIndex
);
746 DPRINT1("cChannels %lu\n", SrcMixerLine
->Line
.cChannels
);
747 DPRINT1("cConnections %lu\n", SrcMixerLine
->Line
.cConnections
);
748 DPRINT1("cControls %lu\n", SrcMixerLine
->Line
.cControls
);
749 DPRINT1("dwComponentType %lx\n", SrcMixerLine
->Line
.dwComponentType
);
750 DPRINT1("dwDestination %lu\n", SrcMixerLine
->Line
.dwDestination
);
751 DPRINT1("dwLineID %lx\n", SrcMixerLine
->Line
.dwLineID
);
752 DPRINT1("dwSource %lx\n", SrcMixerLine
->Line
.dwSource
);
753 DPRINT1("dwUser %lu\n", SrcMixerLine
->Line
.dwUser
);
754 DPRINT1("fdwLine %lu\n", SrcMixerLine
->Line
.fdwLine
);
755 DPRINT1("szName %S\n", SrcMixerLine
->Line
.szName
);
756 DPRINT1("szShortName %S\n", SrcMixerLine
->Line
.szShortName
);
757 DPRINT1("Target.dwDeviceId %lu\n", SrcMixerLine
->Line
.Target
.dwDeviceID
);
758 DPRINT1("Target.dwType %lu\n", SrcMixerLine
->Line
.Target
.dwType
);
759 DPRINT1("Target.szName %S\n", SrcMixerLine
->Line
.Target
.szPname
);
760 DPRINT1("Target.vDriverVersion %lx\n", SrcMixerLine
->Line
.Target
.vDriverVersion
);
761 DPRINT1("Target.wMid %lx\n", SrcMixerLine
->Line
.Target
.wMid
);
762 DPRINT1("Target.wPid %lx\n", SrcMixerLine
->Line
.Target
.wPid
);
763 MMixerPrintMixerLineControls(SrcMixerLine
);
771 IN PMIXER_CONTEXT MixerContext
,
772 IN PMIXER_ENUM EnumFunction
,
773 IN PVOID EnumContext
)
777 ULONG DeviceIndex
, Count
;
779 LPMIXER_DATA MixerData
;
780 PMIXER_LIST MixerList
;
783 if (!MixerContext
|| !EnumFunction
|| !EnumContext
)
785 /* invalid parameter */
786 return MM_STATUS_INVALID_PARAMETER
;
789 if (!MixerContext
->Alloc
|| !MixerContext
->Control
|| !MixerContext
->Free
|| !MixerContext
->Open
||
790 !MixerContext
->AllocEventData
|| !MixerContext
->FreeEventData
||
791 !MixerContext
->Close
|| !MixerContext
->OpenKey
|| !MixerContext
->QueryKeyValue
|| !MixerContext
->CloseKey
)
793 /* invalid parameter */
794 return MM_STATUS_INVALID_PARAMETER
;
797 /* allocate a mixer list */
798 MixerList
= (PMIXER_LIST
)MixerContext
->Alloc(sizeof(MIXER_LIST
));
802 return MM_STATUS_NO_MEMORY
;
805 /* initialize mixer list */
806 MixerList
->MixerListCount
= 0;
807 MixerList
->MixerDataCount
= 0;
808 MixerList
->WaveInListCount
= 0;
809 MixerList
->WaveOutListCount
= 0;
810 MixerList
->MidiInListCount
= 0;
811 MixerList
->MidiOutListCount
= 0;
812 InitializeListHead(&MixerList
->MixerList
);
813 InitializeListHead(&MixerList
->MixerData
);
814 InitializeListHead(&MixerList
->WaveInList
);
815 InitializeListHead(&MixerList
->WaveOutList
);
816 InitializeListHead(&MixerList
->MidiInList
);
817 InitializeListHead(&MixerList
->MidiOutList
);
819 /* store mixer list */
820 MixerContext
->MixerContext
= (PVOID
)MixerList
;
822 /* start enumerating all available devices */
828 /* enumerate a device */
829 Status
= EnumFunction(EnumContext
, DeviceIndex
, &DeviceName
, &hMixer
, &hKey
);
831 if (Status
!= MM_STATUS_SUCCESS
)
833 /* check error code */
834 if (Status
== MM_STATUS_NO_MORE_DEVICES
)
836 /* enumeration has finished */
841 DPRINT1("Failed to enumerate device %lu\n", DeviceIndex
);
849 /* create a mixer data entry */
850 Status
= MMixerCreateMixerData(MixerContext
, MixerList
, DeviceIndex
, DeviceName
, hMixer
, hKey
);
851 if (Status
!= MM_STATUS_SUCCESS
)
855 /* increment device index */
859 /* now all filters have been pre-opened
860 * lets enumerate the filters
862 Entry
= MixerList
->MixerData
.Flink
;
863 while(Entry
!= &MixerList
->MixerData
)
865 MixerData
= (LPMIXER_DATA
)CONTAINING_RECORD(Entry
, MIXER_DATA
, Entry
);
866 MMixerSetupFilter(MixerContext
, MixerList
, MixerData
, &Count
);
867 Entry
= Entry
->Flink
;
870 Entry
= MixerList
->MixerData
.Flink
;
871 while(Entry
!= &MixerList
->MixerData
)
873 MixerData
= (LPMIXER_DATA
)CONTAINING_RECORD(Entry
, MIXER_DATA
, Entry
);
875 /* now handle alternative mixer types */
876 MMixerHandleAlternativeMixers(MixerContext
, MixerList
, MixerData
, MixerData
->Topology
);
877 Entry
= Entry
->Flink
;
880 //MMixerPrintMixers(MixerContext, MixerList);
883 return MM_STATUS_SUCCESS
;