ReactOS 0.4.15-dev-7924-g5949c20
mixer.c
Go to the documentation of this file.
1/*
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
7 */
8
9#include "precomp.h"
10
11// #define NDEBUG
12#include <debug.h>
13
17{
18 PMIXER_LIST MixerList;
20
21 /* verify mixer context */
23
25 {
26 /* invalid context passed */
27 return Status;
28 }
29
30 /* grab mixer list */
32
33 // return number of mixers
34 return MixerList->MixerListCount;
35}
36
40 IN ULONG MixerIndex,
41 OUT LPMIXERCAPSW MixerCaps)
42{
44 LPMIXER_INFO MixerInfo;
45
46 /* verify mixer context */
48
50 {
51 /* invalid context passed */
52 return Status;
53 }
54
55 /* get mixer info */
56 MixerInfo = MMixerGetMixerInfoByIndex(MixerContext, MixerIndex);
57
58 if (!MixerInfo)
59 {
60 // invalid device index
62 }
63
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;
69
70 ASSERT(MixerInfo->MixCaps.szPname[MAXPNAMELEN-1] == 0);
71 wcscpy(MixerCaps->szPname, MixerInfo->MixCaps.szPname);
72
73 return MM_STATUS_SUCCESS;
74}
75
79 IN ULONG MixerId,
80 IN PVOID MixerEventContext,
81 IN PMIXER_EVENT MixerEventRoutine,
82 OUT PHANDLE MixerHandle)
83{
85 LPMIXER_INFO MixerInfo;
86
87 /* verify mixer context */
89
91 {
92 /* invalid context passed */
93 DPRINT1("invalid context\n");
94 return Status;
95 }
96
97 /* get mixer info */
99 if (!MixerInfo)
100 {
101 /* invalid mixer id */
102 DPRINT1("invalid mixer id %lu\n", MixerId);
104 }
105
106 /* add the event */
107 Status = MMixerAddEvent(MixerContext, MixerInfo, MixerEventContext, MixerEventRoutine);
108
109 /* store result */
110 *MixerHandle = (HANDLE)MixerInfo;
111 return MM_STATUS_SUCCESS;
112}
113
117 IN ULONG MixerId,
118 IN PVOID MixerEventContext,
119 IN PMIXER_EVENT MixerEventRoutine)
120{
122 LPMIXER_INFO MixerInfo;
123
124 /* verify mixer context */
126
128 {
129 /* invalid context passed */
130 DPRINT1("invalid context\n");
131 return Status;
132 }
133
134 /* get mixer info */
135 MixerInfo = MMixerGetMixerInfoByIndex(MixerContext, MixerId);
136 if (!MixerInfo)
137 {
138 /* invalid mixer id */
139 DPRINT1("invalid mixer id %lu\n", MixerId);
141 }
142
143 /* remove event from list */
144 return MMixerRemoveEvent(MixerContext, MixerInfo, MixerEventContext, MixerEventRoutine);
145}
146
150 IN HANDLE MixerHandle,
151 IN ULONG MixerId,
152 IN ULONG Flags,
153 OUT LPMIXERLINEW MixerLine)
154{
156 LPMIXER_INFO MixerInfo;
157 LPMIXERLINE_EXT MixerLineSrc;
158 ULONG DestinationLineID;
159
160 /* verify mixer context */
162
164 {
165 /* invalid context passed */
166 return Status;
167 }
169 {
170 /* caller passed mixer id */
171 MixerHandle = (HANDLE)MMixerGetMixerInfoByIndex(MixerContext, MixerId);
172
173 if (!MixerHandle)
174 {
175 /* invalid parameter */
177 }
178 }
179
180 if (MixerLine->cbStruct != sizeof(MIXERLINEW))
181 {
182 DPRINT1("MixerLine Expected %lu but got %lu\n", sizeof(MIXERLINEW), MixerLine->cbStruct);
184 }
185
186 /* clear hmixer from flags */
187 Flags &=~MIXER_OBJECTF_HMIXER;
188
189 DPRINT("MMixerGetLineInfo MixerId %lu Flags %lu\n", MixerId, Flags);
190
192 {
193 /* cast to mixer info */
194 MixerInfo = (LPMIXER_INFO)MixerHandle;
195
196 /* calculate destination line id */
197 DestinationLineID = (MixerLine->dwDestination + DESTINATION_LINE);
198
199 /* get destination line */
200 MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
201
202 if (MixerLineSrc == NULL)
203 {
204 DPRINT1("MixerCaps Name %S DestinationLineCount %lu dwDestination %lu not found\n", MixerInfo->MixCaps.szPname, MixerInfo->MixCaps.cDestinations, MixerLine->dwDestination);
206 }
207 /* copy mixer line */
208 MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW));
209
210 /* make sure it is null terminated */
211 MixerLine->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
212 MixerLine->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
213 MixerLine->Target.szPname[MAXPNAMELEN-1] = L'\0';
214
215 /* done */
216 return MM_STATUS_SUCCESS;
217 }
219 {
220 /* cast to mixer info */
221 MixerInfo = (LPMIXER_INFO)MixerHandle;
222
223 /* calculate destination line id */
224 DestinationLineID = (MixerLine->dwDestination + DESTINATION_LINE);
225
226 /* get destination line */
227 MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
228
229 if (MixerLineSrc == NULL)
230 {
231 DPRINT1("MixerCaps Name %S DestinationLineCount %lu dwDestination %lu not found\n", MixerInfo->MixCaps.szPname, MixerInfo->MixCaps.cDestinations, MixerLine->dwDestination);
233 }
234
235 /* check if dwSource is out of bounds */
236 if (MixerLine->dwSource >= MixerLineSrc->Line.cConnections)
237 {
238 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 }
241
242 /* calculate destination line id */
243 DestinationLineID = (MixerLine->dwSource * SOURCE_LINE) + MixerLine->dwDestination;
244
245 DPRINT("MixerName %S cDestinations %lu MixerLineName %S cConnections %lu dwSource %lu dwDestination %lu ID %lx\n", MixerInfo->MixCaps.szPname, MixerInfo->MixCaps.cDestinations,
246 MixerLineSrc->Line.szName, MixerLineSrc->Line.cConnections,
247 MixerLine->dwSource, MixerLine->dwDestination,
248 DestinationLineID);
249 /* get target destination line id */
250 MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
251
252 /* sanity check */
253 ASSERT(MixerLineSrc);
254
255 DPRINT("Line %u Name %S\n", MixerLineSrc->Line.dwSource, MixerLineSrc->Line.szName);
256
257 /* copy mixer line */
258 MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW));
259
260 /* make sure it is null terminated */
261 MixerLine->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
262 MixerLine->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
263 MixerLine->Target.szPname[MAXPNAMELEN-1] = L'\0';
264
265 /* done */
266 return MM_STATUS_SUCCESS;
267 }
269 {
270 /* cast to mixer info */
271 MixerInfo = (LPMIXER_INFO)MixerHandle;
272
273 /* try to find line */
274 MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLine->dwLineID);
275 if (!MixerLineSrc)
276 {
277 /* invalid parameter */
278 DPRINT1("MMixerGetLineInfo: MixerName %S Line not found 0x%lx\n", MixerInfo->MixCaps.szPname, MixerLine->dwLineID);
280 }
281
282 DPRINT("Line %u Name %S\n", MixerLineSrc->Line.dwSource, MixerLineSrc->Line.szName);
283
284 /* copy mixer line*/
285 MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW));
286
287 /* make sure it is null terminated */
288 MixerLine->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
289 MixerLine->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
290 MixerLine->Target.szPname[MAXPNAMELEN-1] = L'\0';
291
292 return MM_STATUS_SUCCESS;
293 }
295 {
296 /* cast to mixer info */
297 MixerInfo = (LPMIXER_INFO)MixerHandle;
298
299 /* find mixer line by component type */
300 MixerLineSrc = MMixerGetSourceMixerLineByComponentType(MixerInfo, MixerLine->dwComponentType);
301 if (!MixerLineSrc)
302 {
303 DPRINT1("Failed to find component type %x\n", MixerLine->dwComponentType);
305 }
306
307 /* copy mixer line */
308 MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW));
309
310 /* make sure it is null terminated */
311 MixerLine->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
312 MixerLine->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
313 MixerLine->Target.szPname[MAXPNAMELEN-1] = L'\0';
314
315 /* done */
316 return MM_STATUS_SUCCESS;
317 }
319 {
320 DPRINT1("MIXER_GETLINEINFOF_TARGETTYPE handling is unimplemented\n");
321 }
322 else
323 {
324 DPRINT1("Unknown Flags %lx handling is unimplemented\n", Flags);
325 }
326
328}
329
333 IN HANDLE MixerHandle,
334 IN ULONG MixerId,
335 IN ULONG Flags,
336 OUT LPMIXERLINECONTROLSW MixerLineControls)
337{
338 LPMIXER_INFO MixerInfo;
339 LPMIXERLINE_EXT MixerLineSrc;
340 LPMIXERCONTROL_EXT MixerControl;
343 ULONG Index;
344
345 /* verify mixer context */
347
349 {
350 /* invalid context passed */
351 return Status;
352 }
353
354 if (MixerLineControls->cbStruct != sizeof(MIXERLINECONTROLSW))
355 {
356 DPRINT1("Invalid MixerLineControls cbStruct passed %lu expected %lu\n", MixerLineControls->cbStruct, sizeof(MIXERLINECONTROLSW));
357 /* invalid parameter */
359 }
360
361 if (MixerLineControls->cbmxctrl != sizeof(MIXERCONTROLW))
362 {
363 DPRINT1("Invalid MixerLineControls cbmxctrl passed %lu expected %lu\n", MixerLineControls->cbmxctrl, sizeof(MIXERCONTROLW));
364 /* invalid parameter */
366 }
367
369 {
370 /* caller passed mixer id */
371 MixerHandle = (HANDLE)MMixerGetMixerInfoByIndex(MixerContext, MixerId);
372
373 if (!MixerHandle)
374 {
375 /* invalid parameter */
377 }
378 }
379
380 Flags &= ~MIXER_OBJECTF_HMIXER;
381
382 DPRINT("MMixerGetLineControls MixerId %lu Flags %lu\n", MixerId, Flags);
383
385 {
386 /* cast to mixer info */
387 MixerInfo = (LPMIXER_INFO)MixerHandle;
388
389 /* get mixer line */
390 MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLineControls->dwLineID);
391
392 if (!MixerLineSrc)
393 {
394 /* invalid line id */
395 DPRINT("MMixerGetLineControls Line not found %lx\n", MixerLineControls->dwLineID);
397 }
398
399 if (MixerLineSrc->Line.cControls != MixerLineControls->cControls)
400 {
401 /* invalid parameter */
402 DPRINT1("Invalid control count %lu expected %lu\n", MixerLineControls->cControls, MixerLineSrc->Line.cControls);
404 }
405
406 /* copy line control(s) */
407 Entry = MixerLineSrc->ControlsList.Flink;
408 Index = 0;
409 while(Entry != &MixerLineSrc->ControlsList)
410 {
411 /* get mixer control */
413
414 /* copy mixer control */
415 MixerContext->Copy(&MixerLineControls->pamxctrl[Index], &MixerControl->Control, sizeof(MIXERCONTROLW));
416
417 /* move to next */
418 Entry = Entry->Flink;
419
420 /* increment mixer control offset */
421 Index++;
422 }
423 return MM_STATUS_SUCCESS;
424 }
426 {
427 /* cast to mixer info */
428 MixerInfo = (LPMIXER_INFO)MixerHandle;
429
430 /* get mixer line */
431 MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLineControls->dwLineID);
432
433 if (!MixerLineSrc)
434 {
435 /* invalid line id */
436 DPRINT1("MMixerGetLineControls Line not found %lx\n", MixerLineControls->dwLineID);
438 }
439
440 /* sanity checks */
441 ASSERT(MixerLineControls->cControls == 1);
442 ASSERT(MixerLineControls->cbmxctrl == sizeof(MIXERCONTROLW));
443 ASSERT(MixerLineControls->pamxctrl != NULL);
444
445 Entry = MixerLineSrc->ControlsList.Flink;
446 while(Entry != &MixerLineSrc->ControlsList)
447 {
449 if (MixerLineControls->dwControlType == MixerControl->Control.dwControlType)
450 {
451 /* found a control with that type */
452 MixerContext->Copy(MixerLineControls->pamxctrl, &MixerControl->Control, sizeof(MIXERCONTROLW));
453 return MM_STATUS_SUCCESS;
454 }
455
456 /* move to next entry */
457 Entry = Entry->Flink;
458 }
459
460 DPRINT("DeviceInfo->u.MixControls.dwControlType %x not found in Line %x cControls %u \n", MixerLineControls->dwControlType, MixerLineControls->dwLineID, MixerLineSrc->Line.cControls);
462 }
464 {
465 /* cast to mixer info */
466 MixerInfo = (LPMIXER_INFO)MixerHandle;
467
468 Status = MMixerGetMixerControlById(MixerInfo, MixerLineControls->dwControlID, NULL, &MixerControl, NULL);
469
471 {
472 /* invalid parameter */
473 DPRINT("MMixerGetLineControls ControlID not found %lx\n", MixerLineControls->dwLineID);
475 }
476
477 ASSERT(MixerLineControls->cControls == 1);
478 ASSERT(MixerLineControls->cbmxctrl == sizeof(MIXERCONTROLW));
479 ASSERT(MixerLineControls->pamxctrl != NULL);
480
481 DPRINT("MMixerGetLineControls ControlID %lx ControlType %lx Name %S\n", MixerControl->Control.dwControlID, MixerControl->Control.dwControlType, MixerControl->Control.szName);
482
483 /* copy the controls */
484 MixerContext->Copy(MixerLineControls->pamxctrl, &MixerControl->Control, sizeof(MIXERCONTROLW));
485 MixerLineControls->pamxctrl->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
486 MixerLineControls->pamxctrl->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
487
488 return MM_STATUS_SUCCESS;
489 }
492}
493
497 IN HANDLE MixerHandle,
498 IN ULONG MixerId,
499 IN ULONG Flags,
500 OUT LPMIXERCONTROLDETAILS MixerControlDetails)
501{
503 ULONG NodeId;
504 LPMIXER_INFO MixerInfo;
505 LPMIXERLINE_EXT MixerLine;
506 LPMIXERCONTROL_EXT MixerControl;
507
508 /* verify mixer context */
510
512 {
513 /* invalid context passed */
514 DPRINT1("invalid context\n");
515 return Status;
516 }
517
519 {
520 /* caller passed mixer id */
521 MixerHandle = (HANDLE)MMixerGetMixerInfoByIndex(MixerContext, MixerId);
522
523 if (!MixerHandle)
524 {
525 /* invalid parameter */
526 DPRINT1("invalid handle\n");
528 }
529 }
530
531 /* get mixer info */
532 MixerInfo = (LPMIXER_INFO)MixerHandle;
533
534 /* get mixer control */
535 Status = MMixerGetMixerControlById(MixerInfo, MixerControlDetails->dwControlID, &MixerLine, &MixerControl, &NodeId);
536
537 /* check for success */
539 {
540 /* failed to find control id */
541 DPRINT1("invalid control id %lu\n", MixerControlDetails->dwControlID);
543 }
544
545 DPRINT("MMixerSetControlDetails ControlType %lx MixerControlName %S MixerLineName %S NodeID %lu\n", MixerControl->Control.dwControlType, MixerControl->Control.szName, MixerLine->Line.szName, NodeId);
546 switch(MixerControl->Control.dwControlType)
547 {
549 Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo, MixerControl, MixerLine->Line.dwLineID, MixerControlDetails, TRUE);
550 break;
552 Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo, NodeId, TRUE, MixerControl, MixerControlDetails, MixerLine);
553 break;
555 Status = MMixerSetGetMuxControlDetails(MixerContext, MixerInfo, NodeId, TRUE, Flags, MixerControl, MixerControlDetails, MixerLine);
556 break;
557 default:
559 }
560
561 return Status;
562}
563
567 IN HANDLE MixerHandle,
568 IN ULONG MixerId,
569 IN ULONG Flags,
570 OUT LPMIXERCONTROLDETAILS MixerControlDetails)
571{
573 ULONG NodeId;
574 LPMIXER_INFO MixerInfo;
575 LPMIXERLINE_EXT MixerLine;
576 LPMIXERCONTROL_EXT MixerControl;
577
578 /* verify mixer context */
580
582 {
583 /* invalid context passed */
584 return Status;
585 }
586
588 {
589 /* caller passed mixer id */
590 MixerHandle = (HANDLE)MMixerGetMixerInfoByIndex(MixerContext, MixerId);
591
592 if (!MixerHandle)
593 {
594 /* invalid parameter */
596 }
597 }
598
599 /* get mixer info */
600 MixerInfo = (LPMIXER_INFO)MixerHandle;
601
602 /* get mixer control */
603 Status = MMixerGetMixerControlById(MixerInfo, MixerControlDetails->dwControlID, &MixerLine, &MixerControl, &NodeId);
604
605 /* check for success */
607 {
608 /* failed to find control id */
610 }
611
612 switch(MixerControl->Control.dwControlType)
613 {
615 Status = MMixerSetGetMuteControlDetails(MixerContext, MixerInfo, MixerControl, MixerLine->Line.dwLineID, MixerControlDetails, FALSE);
616 break;
618 Status = MMixerSetGetVolumeControlDetails(MixerContext, MixerInfo, NodeId, FALSE, MixerControl, MixerControlDetails, MixerLine);
619 break;
621 DPRINT1("Not Implemented MIXERCONTROL_CONTROLTYPE_ONOFF\n");
622 break;
624 Status = MMixerSetGetMuxControlDetails(MixerContext, MixerInfo, NodeId, FALSE, Flags, MixerControl, MixerControlDetails, MixerLine);
625 break;
626
627 default:
629 DPRINT1("ControlType %lx not implemented\n", MixerControl->Control.dwControlType);
630 }
631
632 return Status;
633}
634
635VOID
637 IN LPMIXERLINE_EXT MixerLine)
638{
640 LPMIXERCONTROL_EXT MixerControl;
641 ULONG Index = 0;
642
643 Entry = MixerLine->ControlsList.Flink;
644 while(Entry != &MixerLine->ControlsList)
645 {
647
648 DPRINT1("\n");
649 DPRINT1("Control Index: %lu\n", Index);
650 DPRINT("\n");
651 DPRINT1("cbStruct %u\n", MixerControl->Control.cbStruct);
652 DPRINT1("dwControlID %lu\n", MixerControl->Control.dwControlID);
653 DPRINT1("dwControlType %lx\n", MixerControl->Control.dwControlType);
654 DPRINT1("fdwControl %lu\n", MixerControl->Control.fdwControl);
655 DPRINT1("cMultipleItems %lu\n", MixerControl->Control.cMultipleItems);
656 DPRINT1("szShortName %S\n", MixerControl->Control.szShortName);
657 DPRINT1("szName %S\n", MixerControl->Control.szName);
658 DPRINT1("Bounds.dwMinimum %lu\n", MixerControl->Control.Bounds.dwMinimum);
659 DPRINT1("Bounds.dwMaximum %lu\n", MixerControl->Control.Bounds.dwMaximum);
660
661 DPRINT1("Metrics.Reserved[0] %lu\n", MixerControl->Control.Metrics.dwReserved[0]);
662 DPRINT1("Metrics.Reserved[1] %lu\n", MixerControl->Control.Metrics.dwReserved[1]);
663 DPRINT1("Metrics.Reserved[2] %lu\n", MixerControl->Control.Metrics.dwReserved[2]);
664 DPRINT1("Metrics.Reserved[3] %lu\n", MixerControl->Control.Metrics.dwReserved[3]);
665 DPRINT1("Metrics.Reserved[4] %lu\n", MixerControl->Control.Metrics.dwReserved[4]);
666 DPRINT1("Metrics.Reserved[5] %lu\n", MixerControl->Control.Metrics.dwReserved[5]);
667
668 Entry = Entry->Flink;
669 Index++;
670 }
671}
672
673VOID
676 IN PMIXER_LIST MixerList)
677{
678 ULONG Index, SubIndex, DestinationLineID, SrcIndex;
679 LPMIXER_INFO MixerInfo;
680 LPMIXERLINE_EXT DstMixerLine, SrcMixerLine;
681
682 DPRINT1("MixerList %p\n", MixerList);
683 DPRINT1("MidiInCount %lu\n", MixerList->MidiInListCount);
684 DPRINT1("MidiOutCount %lu\n", MixerList->MidiOutListCount);
685 DPRINT1("WaveInCount %lu\n", MixerList->WaveInListCount);
686 DPRINT1("WaveOutCount %lu\n", MixerList->WaveOutListCount);
687 DPRINT1("MixerCount %p\n", MixerList->MixerListCount);
688
689 for(Index = 0; Index < MixerList->MixerListCount; Index++)
690 {
691 /* get mixer info */
693
694 ASSERT(MixerInfo);
695 DPRINT1("\n");
696 DPRINT1("Name :%S\n", MixerInfo->MixCaps.szPname);
697 DPRINT1("cDestinations: %lu\n", MixerInfo->MixCaps.cDestinations);
698 DPRINT1("fdwSupport %lu\n", MixerInfo->MixCaps.fdwSupport);
699 DPRINT1("vDriverVersion %lx\n", MixerInfo->MixCaps.vDriverVersion);
700 DPRINT1("wMid %lx\n", MixerInfo->MixCaps.wMid);
701 DPRINT1("wPid %lx\n", MixerInfo->MixCaps.wPid);
702
703 for(SubIndex = 0; SubIndex < MixerInfo->MixCaps.cDestinations; SubIndex++)
704 {
705 /* calculate destination line id */
706 DestinationLineID = (SubIndex + DESTINATION_LINE);
707
708 /* get destination line */
709 DstMixerLine = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
710 DPRINT1("//----------------------------------------------------------------------------------------------\n");
711 DPRINT1("\n");
712 DPRINT1("Destination Index %lu\n", SubIndex);
713 DPRINT1("\n");
714 DPRINT1("cChannels %lu\n", DstMixerLine->Line.cChannels);
715 DPRINT1("cConnections %lu\n", DstMixerLine->Line.cConnections);
716 DPRINT1("cControls %lu\n", DstMixerLine->Line.cControls);
717 DPRINT1("dwComponentType %lx\n", DstMixerLine->Line.dwComponentType);
718 DPRINT1("dwDestination %lu\n", DstMixerLine->Line.dwDestination);
719 DPRINT1("dwLineID %lx\n", DstMixerLine->Line.dwLineID);
720 DPRINT1("dwSource %lx\n", DstMixerLine->Line.dwSource);
721 DPRINT1("dwUser %lu\n", DstMixerLine->Line.dwUser);
722 DPRINT1("fdwLine %lu\n", DstMixerLine->Line.fdwLine);
723 DPRINT1("szName %S\n", DstMixerLine->Line.szName);
724 DPRINT1("szShortName %S\n", DstMixerLine->Line.szShortName);
725 DPRINT1("Target.dwDeviceId %lu\n", DstMixerLine->Line.Target.dwDeviceID);
726 DPRINT1("Target.dwType %lu\n", DstMixerLine->Line.Target.dwType);
727 DPRINT1("Target.szName %S\n", DstMixerLine->Line.Target.szPname);
728 DPRINT1("Target.vDriverVersion %lx\n", DstMixerLine->Line.Target.vDriverVersion);
729 DPRINT1("Target.wMid %lx\n", DstMixerLine->Line.Target.wMid );
730 DPRINT1("Target.wPid %lx\n", DstMixerLine->Line.Target.wPid);
731 MMixerPrintMixerLineControls(DstMixerLine);
732
733 for(SrcIndex = 0; SrcIndex < DstMixerLine->Line.cConnections; SrcIndex++)
734 {
735 /* calculate destination line id */
736 DestinationLineID = (SOURCE_LINE * SrcIndex) + SubIndex;
737
738 /* get source line */
739 SrcMixerLine = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
740 DPRINT1("//==============================================================================================\n");
741 DPRINT1("\n");
742 DPRINT1("SrcLineIndex : %lu\n", SrcIndex);
743 DPRINT1("\n");
744 DPRINT1("cChannels %lu\n", SrcMixerLine->Line.cChannels);
745 DPRINT1("cConnections %lu\n", SrcMixerLine->Line.cConnections);
746 DPRINT1("cControls %lu\n", SrcMixerLine->Line.cControls);
747 DPRINT1("dwComponentType %lx\n", SrcMixerLine->Line.dwComponentType);
748 DPRINT1("dwDestination %lu\n", SrcMixerLine->Line.dwDestination);
749 DPRINT1("dwLineID %lx\n", SrcMixerLine->Line.dwLineID);
750 DPRINT1("dwSource %lx\n", SrcMixerLine->Line.dwSource);
751 DPRINT1("dwUser %lu\n", SrcMixerLine->Line.dwUser);
752 DPRINT1("fdwLine %lu\n", SrcMixerLine->Line.fdwLine);
753 DPRINT1("szName %S\n", SrcMixerLine->Line.szName);
754 DPRINT1("szShortName %S\n", SrcMixerLine->Line.szShortName);
755 DPRINT1("Target.dwDeviceId %lu\n", SrcMixerLine->Line.Target.dwDeviceID);
756 DPRINT1("Target.dwType %lu\n", SrcMixerLine->Line.Target.dwType);
757 DPRINT1("Target.szName %S\n", SrcMixerLine->Line.Target.szPname);
758 DPRINT1("Target.vDriverVersion %lx\n", SrcMixerLine->Line.Target.vDriverVersion);
759 DPRINT1("Target.wMid %lx\n", SrcMixerLine->Line.Target.wMid );
760 DPRINT1("Target.wPid %lx\n", SrcMixerLine->Line.Target.wPid);
761 MMixerPrintMixerLineControls(SrcMixerLine);
762 }
763 }
764 }
765}
766
770 IN PMIXER_ENUM EnumFunction,
771 IN PVOID EnumContext)
772{
775 ULONG DeviceIndex, Count;
777 LPMIXER_DATA MixerData;
778 PMIXER_LIST MixerList;
780
781 if (!MixerContext || !EnumFunction || !EnumContext)
782 {
783 /* invalid parameter */
785 }
786
790 {
791 /* invalid parameter */
793 }
794
795 /* allocate a mixer list */
796 MixerList = (PMIXER_LIST)MixerContext->Alloc(sizeof(MIXER_LIST));
797 if (!MixerList)
798 {
799 /* no memory */
800 return MM_STATUS_NO_MEMORY;
801 }
802
803 /* initialize mixer list */
804 MixerList->MixerListCount = 0;
805 MixerList->MixerDataCount = 0;
806 MixerList->WaveInListCount = 0;
807 MixerList->WaveOutListCount = 0;
808 MixerList->MidiInListCount = 0;
809 MixerList->MidiOutListCount = 0;
810 InitializeListHead(&MixerList->MixerList);
811 InitializeListHead(&MixerList->MixerData);
812 InitializeListHead(&MixerList->WaveInList);
813 InitializeListHead(&MixerList->WaveOutList);
814 InitializeListHead(&MixerList->MidiInList);
815 InitializeListHead(&MixerList->MidiOutList);
816
817 /* store mixer list */
818 MixerContext->MixerContext = (PVOID)MixerList;
819
820 /* start enumerating all available devices */
821 Count = 0;
822 DeviceIndex = 0;
823
824 do
825 {
826 /* enumerate a device */
827 Status = EnumFunction(EnumContext, DeviceIndex, &DeviceName, &hMixer, &hKey);
828
830 {
831 /* check error code */
833 {
834 /* enumeration has finished */
835 break;
836 }
837 else
838 {
839 DPRINT1("Failed to enumerate device %lu\n", DeviceIndex);
840
841 /* TODO cleanup */
842 return Status;
843 }
844 }
845 else
846 {
847 /* create a mixer data entry */
848 Status = MMixerCreateMixerData(MixerContext, MixerList, DeviceIndex, DeviceName, hMixer, hKey);
850 break;
851 }
852
853 /* increment device index */
854 DeviceIndex++;
855 }while(TRUE);
856
857 /* now all filters have been pre-opened
858 * lets enumerate the filters
859 */
860 Entry = MixerList->MixerData.Flink;
861 while(Entry != &MixerList->MixerData)
862 {
864 MMixerSetupFilter(MixerContext, MixerList, MixerData, &Count);
865 Entry = Entry->Flink;
866 }
867
868 Entry = MixerList->MixerData.Flink;
869 while(Entry != &MixerList->MixerData)
870 {
872
873 /* now handle alternative mixer types */
874 MMixerHandleAlternativeMixers(MixerContext, MixerList, MixerData, MixerData->Topology);
875 Entry = Entry->Flink;
876 }
877
878 //MMixerPrintMixers(MixerContext, MixerList);
879
880 /* done */
881 return MM_STATUS_SUCCESS;
882}
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: debug.h:115
MIXER_STATUS MMixerAddEvent(IN PMIXER_CONTEXT MixerContext, IN OUT LPMIXER_INFO MixerInfo, IN PVOID MixerEventContext, IN PMIXER_EVENT MixerEventRoutine)
Definition: controls.c:1827
VOID MMixerHandleAlternativeMixers(IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, IN LPMIXER_DATA MixerData, IN PTOPOLOGY Topology)
Definition: controls.c:1676
MIXER_STATUS MMixerSetupFilter(IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, IN LPMIXER_DATA MixerData, IN PULONG DeviceCount)
Definition: controls.c:1749
MIXER_STATUS MMixerRemoveEvent(IN PMIXER_CONTEXT MixerContext, IN OUT LPMIXER_INFO MixerInfo, IN PVOID MixerEventContext, IN PMIXER_EVENT MixerEventRoutine)
Definition: controls.c:1875
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
MIXER_CONTEXT MixerContext
Definition: mmixer.c:41
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
FxAutoRegKey hKey
Status
Definition: gdiplustypes.h:25
VOID(CALLBACK * PMIXER_EVENT)(IN PVOID MixerEventContext, IN HANDLE hMixer, IN ULONG NotificationType, IN ULONG Value)
Definition: mmixer.h:50
MIXER_STATUS
Definition: mmixer.h:4
@ MM_STATUS_NOT_IMPLEMENTED
Definition: mmixer.h:7
@ MM_STATUS_UNSUCCESSFUL
Definition: mmixer.h:11
@ MM_STATUS_INVALID_PARAMETER
Definition: mmixer.h:10
@ MM_STATUS_NO_MEMORY
Definition: mmixer.h:12
@ MM_STATUS_SUCCESS
Definition: mmixer.h:5
@ MM_STATUS_NO_MORE_DEVICES
Definition: mmixer.h:8
MIXER_STATUS(* PMIXER_ENUM)(IN PVOID EnumContext, IN ULONG DeviceIndex, OUT LPWSTR *DeviceName, OUT PHANDLE OutHandle, OUT PHANDLE OutDevInterfaceKey)
Definition: mmixer.h:24
#define MIXER_OBJECTF_MIXER
Definition: mmsystem.h:300
#define MIXER_GETLINEINFOF_LINEID
Definition: mmsystem.h:346
#define MIXERCONTROL_CONTROLTYPE_ONOFF
Definition: mmsystem.h:383
#define MIXER_GETLINEINFOF_TARGETTYPE
Definition: mmsystem.h:348
#define MIXERCONTROL_CONTROLTYPE_MUX
Definition: mmsystem.h:403
#define MIXER_GETLINEINFOF_DESTINATION
Definition: mmsystem.h:344
#define MIXER_GETLINECONTROLSF_ONEBYID
Definition: mmsystem.h:409
#define MIXERCONTROL_CONTROLTYPE_VOLUME
Definition: mmsystem.h:398
#define MIXER_LONG_NAME_CHARS
Definition: mmsystem.h:294
#define MIXER_GETLINEINFOF_COMPONENTTYPE
Definition: mmsystem.h:347
#define MIXER_GETLINEINFOF_SOURCE
Definition: mmsystem.h:345
#define MIXER_GETLINECONTROLSF_ALL
Definition: mmsystem.h:408
#define MAXPNAMELEN
Definition: mmsystem.h:24
#define MIXER_GETLINECONTROLSF_ONEBYTYPE
Definition: mmsystem.h:410
#define MIXER_SHORT_NAME_CHARS
Definition: mmsystem.h:293
#define MIXER_OBJECTF_HMIXER
Definition: mmsystem.h:301
#define MIXERCONTROL_CONTROLTYPE_MUTE
Definition: mmsystem.h:384
#define ASSERT(a)
Definition: mode.c:44
HMIXER hMixer
Definition: test.c:10
int Count
Definition: noreturn.cpp:7
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define L(x)
Definition: ntvdm.h:50
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
MIXER_STATUS MMixerGetControlDetails(IN PMIXER_CONTEXT MixerContext, IN HANDLE MixerHandle, IN ULONG MixerId, IN ULONG Flags, OUT LPMIXERCONTROLDETAILS MixerControlDetails)
Definition: mixer.c:565
VOID MMixerPrintMixers(IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList)
Definition: mixer.c:674
MIXER_STATUS MMixerClose(IN PMIXER_CONTEXT MixerContext, IN ULONG MixerId, IN PVOID MixerEventContext, IN PMIXER_EVENT MixerEventRoutine)
Definition: mixer.c:115
VOID MMixerPrintMixerLineControls(IN LPMIXERLINE_EXT MixerLine)
Definition: mixer.c:636
MIXER_STATUS MMixerOpen(IN PMIXER_CONTEXT MixerContext, IN ULONG MixerId, IN PVOID MixerEventContext, IN PMIXER_EVENT MixerEventRoutine, OUT PHANDLE MixerHandle)
Definition: mixer.c:77
MIXER_STATUS MMixerGetLineControls(IN PMIXER_CONTEXT MixerContext, IN HANDLE MixerHandle, IN ULONG MixerId, IN ULONG Flags, OUT LPMIXERLINECONTROLSW MixerLineControls)
Definition: mixer.c:331
MIXER_STATUS MMixerSetControlDetails(IN PMIXER_CONTEXT MixerContext, IN HANDLE MixerHandle, IN ULONG MixerId, IN ULONG Flags, OUT LPMIXERCONTROLDETAILS MixerControlDetails)
Definition: mixer.c:495
MIXER_STATUS MMixerGetCapabilities(IN PMIXER_CONTEXT MixerContext, IN ULONG MixerIndex, OUT LPMIXERCAPSW MixerCaps)
Definition: mixer.c:38
ULONG MMixerGetCount(IN PMIXER_CONTEXT MixerContext)
Definition: mixer.c:15
MIXER_STATUS MMixerGetLineInfo(IN PMIXER_CONTEXT MixerContext, IN HANDLE MixerHandle, IN ULONG MixerId, IN ULONG Flags, OUT LPMIXERLINEW MixerLine)
Definition: mixer.c:148
MIXER_STATUS MMixerInitialize(IN PMIXER_CONTEXT MixerContext, IN PMIXER_ENUM EnumFunction, IN PVOID EnumContext)
Definition: mixer.c:768
MIXER_STATUS MMixerSetGetMuxControlDetails(IN PMIXER_CONTEXT MixerContext, IN LPMIXER_INFO MixerInfo, IN ULONG NodeId, IN ULONG bSet, IN ULONG Flags, LPMIXERCONTROL_EXT MixerControl, IN LPMIXERCONTROLDETAILS MixerControlDetails, LPMIXERLINE_EXT MixerLine)
MIXER_STATUS MMixerSetGetMuteControlDetails(IN PMIXER_CONTEXT MixerContext, IN LPMIXER_INFO MixerInfo, IN LPMIXERCONTROL_EXT MixerControl, IN ULONG dwLineID, IN LPMIXERCONTROLDETAILS MixerControlDetails, IN ULONG bSet)
Definition: sup.c:364
LPMIXER_INFO MMixerGetMixerInfoByIndex(IN PMIXER_CONTEXT MixerContext, IN ULONG MixerIndex)
Definition: sup.c:158
struct MIXER_DATA * LPMIXER_DATA
struct MIXERCONTROL_EXT * LPMIXERCONTROL_EXT
struct MIXER_LIST * PMIXER_LIST
MIXER_STATUS MMixerGetMixerControlById(LPMIXER_INFO MixerInfo, DWORD dwControlID, LPMIXERLINE_EXT *MixerLine, LPMIXERCONTROL_EXT *MixerControl, PULONG NodeId)
Definition: sup.c:278
MIXER_STATUS MMixerVerifyContext(IN PMIXER_CONTEXT MixerContext)
Definition: sup.c:40
LPMIXERLINE_EXT MMixerGetSourceMixerLineByComponentType(LPMIXER_INFO MixerInfo, DWORD dwComponentType)
Definition: sup.c:255
MIXER_STATUS MMixerSetGetVolumeControlDetails(IN PMIXER_CONTEXT MixerContext, IN LPMIXER_INFO MixerInfo, IN ULONG NodeId, IN ULONG bSet, LPMIXERCONTROL_EXT MixerControl, IN LPMIXERCONTROLDETAILS MixerControlDetails, LPMIXERLINE_EXT MixerLine)
Definition: sup.c:665
MIXER_STATUS MMixerCreateMixerData(IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, IN ULONG DeviceId, IN LPWSTR DeviceName, IN HANDLE hDevice, IN HANDLE hKey)
Definition: sup.c:778
#define DESTINATION_LINE
Definition: precomp.h:176
LPMIXERLINE_EXT MMixerGetSourceMixerLineByLineId(LPMIXER_INFO MixerInfo, DWORD dwLineID)
Definition: sup.c:218
#define SOURCE_LINE
Definition: precomp.h:177
struct MIXER_INFO * LPMIXER_INFO
#define DPRINT
Definition: sndvol32.h:71
base of all file and directory entries
Definition: entries.h:83
MIXERCONTROLW Control
Definition: precomp.h:79
MIXERLINEW Line
Definition: precomp.h:89
LIST_ENTRY ControlsList
Definition: precomp.h:90
PMIXER_ALLOC_EVENT_DATA AllocEventData
Definition: mmixer.h:103
PMIXER_OPEN_KEY OpenKey
Definition: mmixer.h:100
PMIXER_DEVICE_CONTROL Control
Definition: mmixer.h:95
PMIXER_CLOSE Close
Definition: mmixer.h:98
PMIXER_CLOSEKEY CloseKey
Definition: mmixer.h:102
PMIXER_COPY Copy
Definition: mmixer.h:99
PMIXER_QUERY_KEY_VALUE QueryKeyValue
Definition: mmixer.h:101
PMIXER_FREE_EVENT_DATA FreeEventData
Definition: mmixer.h:104
PVOID MixerContext
Definition: mmixer.h:92
PMIXER_OPEN Open
Definition: mmixer.h:97
PMIXER_FREE Free
Definition: mmixer.h:96
PMIXER_ALLOC Alloc
Definition: mmixer.h:94
PTOPOLOGY Topology
Definition: precomp.h:118
MIXERCAPSW MixCaps
Definition: precomp.h:70
ULONG MixerDataCount
Definition: precomp.h:152
ULONG MidiInListCount
Definition: precomp.h:161
LIST_ENTRY MidiOutList
Definition: precomp.h:165
LIST_ENTRY MidiInList
Definition: precomp.h:162
ULONG WaveOutListCount
Definition: precomp.h:158
LIST_ENTRY WaveInList
Definition: precomp.h:156
LIST_ENTRY MixerData
Definition: precomp.h:153
ULONG MixerListCount
Definition: precomp.h:149
LIST_ENTRY WaveOutList
Definition: precomp.h:159
ULONG WaveInListCount
Definition: precomp.h:155
ULONG MidiOutListCount
Definition: precomp.h:164
LIST_ENTRY MixerList
Definition: precomp.h:150
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
DWORD cDestinations
Definition: mmsystem.h:1228
MMVERSION vDriverVersion
Definition: mmsystem.h:1225
DWORD fdwSupport
Definition: mmsystem.h:1227
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1226
WCHAR szName[MIXER_LONG_NAME_CHARS]
Definition: mmsystem.h:1310
DWORD dwControlType
Definition: mmsystem.h:1306
DWORD cMultipleItems
Definition: mmsystem.h:1308
union tagMIXERCONTROLW::@3051 Bounds
WCHAR szShortName[MIXER_SHORT_NAME_CHARS]
Definition: mmsystem.h:1309
DWORD dwReserved[6]
Definition: mmsystem.h:1320
union tagMIXERCONTROLW::@3052 Metrics
struct tagMIXERLINEW::@3046 Target
DWORD fdwLine
Definition: mmsystem.h:1259
DWORD dwDestination
Definition: mmsystem.h:1256
DWORD cControls
Definition: mmsystem.h:1264
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 cConnections
Definition: mmsystem.h:1263
DWORD_PTR dwUser
Definition: mmsystem.h:1260
DWORD dwComponentType
Definition: mmsystem.h:1261
WCHAR szShortName[MIXER_SHORT_NAME_CHARS]
Definition: mmsystem.h:1265
void * PVOID
Definition: typedefs.h:50
PVOID HANDLE
Definition: typedefs.h:73
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
WCHAR * LPWSTR
Definition: xmlstorage.h:184