1 #include <windows.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <setupapi.h>
5 #include <ks.h>
6 #include <ksmedia.h>
7 #include <mmsystem.h>
8 #include <mmreg.h>
9 
10 HMIXER hMixer;
11 HANDLE hThread;
12 HWND hwnd;
13 
14 DWORD
15 WINAPI
16 MixerThread(LPVOID Parameter)
17 {
18 
19     MSG msg;
20 
21 	printf("hMixer %p\n", hMixer);
22 
23 	while(GetMessage(&msg, NULL, 0, 0))
24 	{
25 			if (msg.message == MM_MIXM_CONTROL_CHANGE)
26 				printf("got MM_MIXM_CONTROL_CHANGE wParam %Ix lParam %Ix\n", msg.wParam, msg.lParam);
27 			else if (msg.message == MM_MIXM_LINE_CHANGE)
28 				printf("got MM_MIXM_LINE_CHANGE wParam %Ix lParam %Ix\n", msg.wParam, msg.lParam);
29 	}
30 	return 1;
31 }
32 
33 VOID
34 test()
35 {
36 
37 
38     hwnd = CreateWindowExA(0, "static", "winmm test", WS_POPUP, 0,0,100,100,
39                            0, 0, 0, NULL);
40 
41 
42 	if (!hwnd) {
43 		printf("failed to create window\n");
44 		exit(-1);
45 	}
46 
47 	printf("window created\n");
48 
49 	if (mixerOpen(&hMixer, 0, (DWORD_PTR)hwnd, 0, CALLBACK_WINDOW | MIXER_OBJECTF_MIXER) != MMSYSERR_NOERROR)
50 	{
51 		printf("failed to create mixer\n");
52 		exit(-2);
53 	}
54 
55 	hThread = CreateThread(NULL, 0, MixerThread, NULL, 0, NULL);
56 
57 	if (hThread == NULL)
58 	{
59 		printf("failed to create thread\n");
60 		exit(-3);
61 	}
62 }
63 
64 
65 
66 
67 
68 
69 void
70 printMixerLine(LPMIXERLINEW MixerLine, IN ULONG MixerIndex)
71 {
72     MIXERLINECONTROLSW MixerLineControls;
73     LPMIXERCONTROLDETAILS_LISTTEXTW ListText;
74     MIXERCONTROLDETAILS MixerControlDetails;
75     ULONG Index, SubIndex;
76     MMRESULT Result;
77 
78     printf("\n");
79     printf("cChannels %lu\n", MixerLine->cChannels);
80     printf("cConnections %lu\n", MixerLine->cConnections);
81     printf("cControls %lu\n", MixerLine->cControls);
82     printf("dwComponentType %lx\n", MixerLine->dwComponentType);
83     printf("dwDestination %lu\n", MixerLine->dwDestination);
84     printf("dwLineID %lx\n", MixerLine->dwLineID);
85     printf("dwSource %lx\n", MixerLine->dwSource);
86     printf("dwUser %Iu\n", MixerLine->dwUser);
87     printf("fdwLine %lu\n", MixerLine->fdwLine);
88     printf("szName %S\n", MixerLine->szName);
89     printf("szShortName %S\n", MixerLine->szShortName);
90     printf("Target.dwDeviceId %lu\n", MixerLine->Target.dwDeviceID);
91     printf("Target.dwType %lu\n", MixerLine->Target.dwType);
92     printf("Target.szName %S\n", MixerLine->Target.szPname);
93     printf("Target.vDriverVersion %x\n", MixerLine->Target.vDriverVersion);
94     printf("Target.wMid %x\n", MixerLine->Target.wMid );
95     printf("Target.wPid %x\n", MixerLine->Target.wPid);
96 
97     MixerLineControls.cbStruct = sizeof(MixerLineControls);
98     MixerLineControls.dwLineID = MixerLine->dwLineID;
99     MixerLineControls.cControls = MixerLine->cControls;
100     MixerLineControls.cbmxctrl= sizeof(MIXERCONTROLW);
101     MixerLineControls.pamxctrl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MixerLineControls.cControls * sizeof(MIXERCONTROLW));
102 
103     Result = mixerGetLineControlsW((HMIXEROBJ)UlongToHandle(MixerIndex), &MixerLineControls, MIXER_GETLINECONTROLSF_ALL | MIXER_OBJECTF_MIXER);
104 
105     printf("Result %u\n", Result);
106 
107     for(Index = 0; Index < MixerLine->cControls; Index++)
108     {
109         printf("\n");
110         printf("Control Index: %lu\n", Index);
111         printf("\n");
112         printf("cbStruct %lu\n", MixerLineControls.pamxctrl[Index].cbStruct);
113         printf("dwControlID %lu\n", MixerLineControls.pamxctrl[Index].dwControlID);
114         printf("dwControlType %lx\n", MixerLineControls.pamxctrl[Index].dwControlType);
115         printf("fdwControl %lu\n", MixerLineControls.pamxctrl[Index].fdwControl);
116         printf("cMultipleItems %lu\n", MixerLineControls.pamxctrl[Index].cMultipleItems);
117         printf("szShortName %S\n", MixerLineControls.pamxctrl[Index].szShortName);
118         printf("szName %S\n", MixerLineControls.pamxctrl[Index].szName);
119         printf("Bounds.dwMinimum %lu\n", MixerLineControls.pamxctrl[Index].Bounds.dwMinimum);
120         printf("Bounds.dwMaximum %lu\n", MixerLineControls.pamxctrl[Index].Bounds.dwMaximum);
121 
122         printf("Metrics.Reserved[0] %lu\n", MixerLineControls.pamxctrl[Index].Metrics.dwReserved[0]);
123         printf("Metrics.Reserved[1] %lu\n", MixerLineControls.pamxctrl[Index].Metrics.dwReserved[1]);
124         printf("Metrics.Reserved[2] %lu\n", MixerLineControls.pamxctrl[Index].Metrics.dwReserved[2]);
125         printf("Metrics.Reserved[3] %lu\n", MixerLineControls.pamxctrl[Index].Metrics.dwReserved[3]);
126         printf("Metrics.Reserved[4] %lu\n", MixerLineControls.pamxctrl[Index].Metrics.dwReserved[4]);
127         printf("Metrics.Reserved[5] %lu\n", MixerLineControls.pamxctrl[Index].Metrics.dwReserved[5]);
128 
129         if (MixerLineControls.pamxctrl[Index].dwControlType == MIXERCONTROL_CONTROLTYPE_MUX)
130         {
131             ZeroMemory(&MixerControlDetails, sizeof(MixerControlDetails));
132             MixerControlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
133             MixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXTW);
134             MixerControlDetails.cChannels = 1;
135             MixerControlDetails.cMultipleItems = MixerLineControls.pamxctrl[Index].Metrics.dwReserved[0];
136             MixerControlDetails.dwControlID = MixerLineControls.pamxctrl[Index].dwControlID;
137             MixerControlDetails.paDetails = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MixerControlDetails.cbDetails * MixerControlDetails.cChannels * MixerControlDetails.cMultipleItems);
138 
139             Result = mixerGetControlDetailsW((HMIXEROBJ)UlongToHandle(MixerIndex), &MixerControlDetails, MIXER_GETCONTROLDETAILSF_LISTTEXT | MIXER_OBJECTF_MIXER);
140 
141             printf("Result %x\n", Result);
142             ListText = (LPMIXERCONTROLDETAILS_LISTTEXTW)MixerControlDetails.paDetails;
143             for(SubIndex = 0; SubIndex < MixerControlDetails.cMultipleItems; SubIndex++)
144             {
145                 printf("dwParam1 %lx\n", ListText[SubIndex].dwParam1);
146                 printf("dwParam1 %lx\n", ListText[SubIndex].dwParam2);
147                 printf("szName %S\n", ListText[SubIndex].szName);
148             }
149 
150 			MixerControlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
151 			MixerControlDetails.paDetails = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MIXERCONTROLDETAILS_BOOLEAN) * MixerControlDetails.cMultipleItems);
152              ((LPMIXERCONTROLDETAILS_BOOLEAN)MixerControlDetails.paDetails)->fValue = TRUE;
153 
154 			Result = mixerSetControlDetails((HMIXEROBJ)hMixer, &MixerControlDetails, MIXER_SETCONTROLDETAILSF_VALUE | MIXER_OBJECTF_HANDLE);
155 			printf("Result %x hMixer %p\n", Result, hMixer);
156         }
157     }
158 }
159 
160 int main(int argc, char**argv)
161 {
162     DWORD MixerCount, MixerIndex, DestinationIndex, SrcIndex;
163     MIXERCAPSW MixerCaps;
164     MIXERLINEW DstMixerLine, SrcLine;
165     MMRESULT Result;
166 
167 
168 test();
169 
170     MixerCount = mixerGetNumDevs();
171 
172     printf("MixerCount %lu\n", MixerCount);
173 
174     for(MixerIndex = 0; MixerIndex < MixerCount; MixerIndex++)
175     {
176         Result = mixerGetDevCapsW((UINT_PTR)MixerIndex, &MixerCaps, sizeof(MixerCaps));
177 
178         printf("\n");
179         printf("Index %lu Result %x\n", MixerIndex, Result);
180         printf("Name :%S\n", MixerCaps.szPname);
181         printf("cDestinations: %lu\n", MixerCaps.cDestinations);
182         printf("fdwSupport %lx\n", MixerCaps.fdwSupport);
183         printf("vDriverVersion %x\n", MixerCaps.vDriverVersion);
184         printf("wMid %x\n", MixerCaps.wMid);
185         printf("wPid %x\n", MixerCaps.wPid);
186 
187         for(DestinationIndex = 0; DestinationIndex < MixerCaps.cDestinations; DestinationIndex++)
188         {
189             ZeroMemory(&DstMixerLine, sizeof(DstMixerLine));
190             DstMixerLine.dwDestination = DestinationIndex;
191             DstMixerLine.cbStruct = sizeof(DstMixerLine);
192 
193             Result = mixerGetLineInfoW((HMIXEROBJ)UlongToHandle(MixerIndex), &DstMixerLine, MIXER_GETLINEINFOF_DESTINATION | MIXER_OBJECTF_MIXER);
194             printf("\n");
195             printf("Destination Index %lu\n", DestinationIndex);
196             printMixerLine(&DstMixerLine, MixerIndex);
197             for(SrcIndex = 0; SrcIndex < DstMixerLine.cConnections; SrcIndex++)
198             {
199                 ZeroMemory(&SrcLine, sizeof(SrcLine));
200                 SrcLine.dwDestination = DestinationIndex;
201                 SrcLine.dwSource = SrcIndex;
202                 SrcLine.cbStruct = sizeof(SrcLine);
203 
204                 Result = mixerGetLineInfoW((HMIXEROBJ)UlongToHandle(MixerIndex), &SrcLine, MIXER_GETLINEINFOF_SOURCE  | MIXER_OBJECTF_MIXER);
205 
206                 if (Result == MMSYSERR_NOERROR)
207                 {
208                     printf("\n");
209                     printf("SrcLineIndex %lu\n", SrcIndex);
210                     printMixerLine(&SrcLine, MixerIndex);
211                 }
212             }
213         }
214     }
215 WaitForSingleObject(hThread, INFINITE);
216 CloseHandle(hThread);
217 
218     return 0;
219 }
220