4 * Copyright (c) 2004 Robert Reif
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * add interactive tests
31 #include "wine/test.h"
37 #include "winmm_test.h"
39 static const char * line_flags(DWORD fdwLine
)
41 static char flags
[100];
44 if (fdwLine
&MIXERLINE_LINEF_ACTIVE
) {
45 strcat(flags
,"MIXERLINE_LINEF_ACTIVE");
48 if (fdwLine
&MIXERLINE_LINEF_DISCONNECTED
) {
52 strcat(flags
,"MIXERLINE_LINEF_DISCONNECTED");
56 if (fdwLine
&MIXERLINE_LINEF_SOURCE
) {
60 strcat(flags
,"MIXERLINE_LINEF_SOURCE");
66 static const char * component_type(DWORD dwComponentType
)
68 #define TYPE_TO_STR(x) case x: return #x
69 switch (dwComponentType
) {
70 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_UNDEFINED
);
71 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_DIGITAL
);
72 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_LINE
);
73 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_MONITOR
);
74 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
);
75 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_HEADPHONES
);
76 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_TELEPHONE
);
77 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_WAVEIN
);
78 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_VOICEIN
);
79 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED
);
80 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_DIGITAL
);
81 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_LINE
);
82 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE
);
83 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER
);
84 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC
);
85 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE
);
86 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER
);
87 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT
);
88 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY
);
89 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_ANALOG
);
95 static const char * target_type(DWORD dwType
)
97 #define TYPE_TO_STR(x) case x: return #x
99 TYPE_TO_STR(MIXERLINE_TARGETTYPE_UNDEFINED
);
100 TYPE_TO_STR(MIXERLINE_TARGETTYPE_WAVEOUT
);
101 TYPE_TO_STR(MIXERLINE_TARGETTYPE_WAVEIN
);
102 TYPE_TO_STR(MIXERLINE_TARGETTYPE_MIDIOUT
);
103 TYPE_TO_STR(MIXERLINE_TARGETTYPE_MIDIIN
);
104 TYPE_TO_STR(MIXERLINE_TARGETTYPE_AUX
);
110 static const char * control_type(DWORD dwControlType
)
112 #define TYPE_TO_STR(x) case x: return #x
113 switch (dwControlType
) {
114 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_CUSTOM
);
115 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BOOLEANMETER
);
116 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SIGNEDMETER
);
117 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_PEAKMETER
);
118 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER
);
119 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BOOLEAN
);
120 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_ONOFF
);
121 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MUTE
);
122 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MONO
);
123 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_LOUDNESS
);
124 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_STEREOENH
);
125 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BASS_BOOST
);
126 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BUTTON
);
127 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_DECIBELS
);
128 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SIGNED
);
129 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_UNSIGNED
);
130 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_PERCENT
);
131 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SLIDER
);
132 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_PAN
);
133 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_QSOUNDPAN
);
134 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_FADER
);
135 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_VOLUME
);
136 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BASS
);
137 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_TREBLE
);
138 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_EQUALIZER
);
139 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SINGLESELECT
);
140 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MUX
);
141 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT
);
142 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MIXER
);
143 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MICROTIME
);
144 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MILLITIME
);
150 static const char * control_flags(DWORD fdwControl
)
152 static char flags
[100];
155 if (fdwControl
&MIXERCONTROL_CONTROLF_UNIFORM
) {
156 strcat(flags
,"MIXERCONTROL_CONTROLF_UNIFORM");
159 if (fdwControl
&MIXERCONTROL_CONTROLF_MULTIPLE
) {
163 strcat(flags
,"MIXERCONTROL_CONTROLF_MULTIPLE");
167 if (fdwControl
&MIXERCONTROL_CONTROLF_DISABLED
) {
171 strcat(flags
,"MIXERCONTROL_CONTROLF_DISABLED");
177 static void test_mixerClose(HMIXER mix
)
181 rc
= mixerClose(mix
);
182 ok(rc
== MMSYSERR_NOERROR
|| rc
== MMSYSERR_INVALHANDLE
,
183 "mixerClose: MMSYSERR_NOERROR or MMSYSERR_INVALHANDLE expected, got %s\n",
187 static void mixer_test_controlA(HMIXER mix
, LPMIXERCONTROLA control
)
191 if ((control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_VOLUME
) ||
192 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_UNSIGNED
)) {
193 MIXERCONTROLDETAILS details
;
194 MIXERCONTROLDETAILS_UNSIGNED value
;
196 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
197 details
.dwControlID
= control
->dwControlID
;
198 details
.cChannels
= 1;
199 U(details
).cMultipleItems
= 0;
200 details
.paDetails
= &value
;
201 details
.cbDetails
= sizeof(value
);
203 /* read the current control value */
204 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_GETCONTROLDETAILSF_VALUE
);
205 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
206 "MMSYSERR_NOERROR expected, got %s\n",
208 if (rc
==MMSYSERR_NOERROR
&& winetest_interactive
) {
209 MIXERCONTROLDETAILS new_details
;
210 MIXERCONTROLDETAILS_UNSIGNED new_value
;
212 trace(" Value=%d\n",value
.dwValue
);
214 if (value
.dwValue
+ control
->Metrics
.cSteps
< S1(control
->Bounds
).dwMaximum
)
215 new_value
.dwValue
= value
.dwValue
+ control
->Metrics
.cSteps
;
217 new_value
.dwValue
= value
.dwValue
- control
->Metrics
.cSteps
;
219 new_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
220 new_details
.dwControlID
= control
->dwControlID
;
221 new_details
.cChannels
= 1;
222 U(new_details
).cMultipleItems
= 0;
223 new_details
.paDetails
= &new_value
;
224 new_details
.cbDetails
= sizeof(new_value
);
226 /* change the control value by one step */
227 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&new_details
,MIXER_SETCONTROLDETAILSF_VALUE
);
228 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
229 "MMSYSERR_NOERROR expected, got %s\n",
231 if (rc
==MMSYSERR_NOERROR
) {
232 MIXERCONTROLDETAILS ret_details
;
233 MIXERCONTROLDETAILS_UNSIGNED ret_value
;
235 ret_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
236 ret_details
.dwControlID
= control
->dwControlID
;
237 ret_details
.cChannels
= 1;
238 U(ret_details
).cMultipleItems
= 0;
239 ret_details
.paDetails
= &ret_value
;
240 ret_details
.cbDetails
= sizeof(ret_value
);
242 /* read back the new control value */
243 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&ret_details
,MIXER_GETCONTROLDETAILSF_VALUE
);
244 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
245 "MMSYSERR_NOERROR expected, got %s\n",
247 if (rc
==MMSYSERR_NOERROR
) {
248 /* result may not match exactly because of rounding */
249 ok(abs(ret_value
.dwValue
-new_value
.dwValue
)<=1,
250 "Couldn't change value from %d to %d, returned %d\n",
251 value
.dwValue
,new_value
.dwValue
,ret_value
.dwValue
);
253 if (abs(ret_value
.dwValue
-new_value
.dwValue
)<=1) {
254 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
255 details
.dwControlID
= control
->dwControlID
;
256 details
.cChannels
= 1;
257 U(details
).cMultipleItems
= 0;
258 details
.paDetails
= &value
;
259 details
.cbDetails
= sizeof(value
);
261 /* restore original value */
262 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_SETCONTROLDETAILSF_VALUE
);
263 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
264 "MMSYSERR_NOERROR expected, got %s\n",
270 } else if ((control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_MUTE
) ||
271 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_BOOLEAN
) ||
272 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_BUTTON
)) {
273 MIXERCONTROLDETAILS details
;
274 MIXERCONTROLDETAILS_BOOLEAN value
;
276 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
277 details
.dwControlID
= control
->dwControlID
;
278 details
.cChannels
= 1;
279 U(details
).cMultipleItems
= 0;
280 details
.paDetails
= &value
;
281 details
.cbDetails
= sizeof(value
);
283 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_GETCONTROLDETAILSF_VALUE
);
284 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
285 "MMSYSERR_NOERROR expected, got %s\n",
287 if (rc
==MMSYSERR_NOERROR
&& winetest_interactive
) {
288 MIXERCONTROLDETAILS new_details
;
289 MIXERCONTROLDETAILS_BOOLEAN new_value
;
291 trace(" Value=%d\n",value
.fValue
);
293 if (value
.fValue
== FALSE
)
294 new_value
.fValue
= TRUE
;
296 new_value
.fValue
= FALSE
;
298 new_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
299 new_details
.dwControlID
= control
->dwControlID
;
300 new_details
.cChannels
= 1;
301 U(new_details
).cMultipleItems
= 0;
302 new_details
.paDetails
= &new_value
;
303 new_details
.cbDetails
= sizeof(new_value
);
305 /* change the control value by one step */
306 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&new_details
,MIXER_SETCONTROLDETAILSF_VALUE
);
307 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
308 "MMSYSERR_NOERROR expected, got %s\n",
310 if (rc
==MMSYSERR_NOERROR
) {
311 MIXERCONTROLDETAILS ret_details
;
312 MIXERCONTROLDETAILS_BOOLEAN ret_value
;
314 ret_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
315 ret_details
.dwControlID
= control
->dwControlID
;
316 ret_details
.cChannels
= 1;
317 U(ret_details
).cMultipleItems
= 0;
318 ret_details
.paDetails
= &ret_value
;
319 ret_details
.cbDetails
= sizeof(ret_value
);
321 /* read back the new control value */
322 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&ret_details
,MIXER_GETCONTROLDETAILSF_VALUE
);
323 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
324 "MMSYSERR_NOERROR expected, got %s\n",
326 if (rc
==MMSYSERR_NOERROR
) {
327 /* result may not match exactly because of rounding */
328 ok(ret_value
.fValue
==new_value
.fValue
,
329 "Couldn't change value from %d to %d, returned %d\n",
330 value
.fValue
,new_value
.fValue
,ret_value
.fValue
);
332 if (ret_value
.fValue
==new_value
.fValue
) {
333 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
334 details
.dwControlID
= control
->dwControlID
;
335 details
.cChannels
= 1;
336 U(details
).cMultipleItems
= 0;
337 details
.paDetails
= &value
;
338 details
.cbDetails
= sizeof(value
);
340 /* restore original value */
341 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_SETCONTROLDETAILSF_VALUE
);
342 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
343 "MMSYSERR_NOERROR expected, got %s\n",
354 static void mixer_test_deviceA(int device
)
361 rc
=mixerGetDevCapsA(device
,0,sizeof(capsA
));
362 ok(rc
==MMSYSERR_INVALPARAM
,
363 "mixerGetDevCapsA: MMSYSERR_INVALPARAM expected, got %s\n",
366 rc
=mixerGetDevCapsA(device
,&capsA
,4);
367 ok(rc
==MMSYSERR_NOERROR
,
368 "mixerGetDevCapsA: MMSYSERR_NOERROR expected, got %s\n",
371 rc
=mixerGetDevCapsA(device
,&capsA
,sizeof(capsA
));
372 ok(rc
==MMSYSERR_NOERROR
,
373 "mixerGetDevCapsA: MMSYSERR_NOERROR expected, got %s\n",
376 if (winetest_interactive
) {
377 trace(" %d: \"%s\" %d.%d (%d:%d) destinations=%d\n", device
,
378 capsA
.szPname
, capsA
.vDriverVersion
>> 8,
379 capsA
.vDriverVersion
& 0xff,capsA
.wMid
,capsA
.wPid
,
380 capsA
.cDestinations
);
382 trace(" %d: \"%s\" %d.%d (%d:%d)\n", device
,
383 capsA
.szPname
, capsA
.vDriverVersion
>> 8,
384 capsA
.vDriverVersion
& 0xff,capsA
.wMid
,capsA
.wPid
);
387 rc
=mixerOpen(&mix
, device
, 0, 0, 0);
388 ok(rc
==MMSYSERR_NOERROR
,
389 "mixerOpen: MMSYSERR_NOERROR expected, got %s\n",mmsys_error(rc
));
390 if (rc
==MMSYSERR_NOERROR
) {
391 for (d
=0;d
<capsA
.cDestinations
;d
++) {
392 MIXERLINEA mixerlineA
;
393 mixerlineA
.cbStruct
= 0;
394 mixerlineA
.dwDestination
=d
;
395 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,
396 MIXER_GETLINEINFOF_DESTINATION
);
397 ok(rc
==MMSYSERR_INVALPARAM
,
398 "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
399 "MMSYSERR_INVALPARAM expected, got %s\n",
402 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
403 mixerlineA
.dwDestination
=capsA
.cDestinations
;
404 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,
405 MIXER_GETLINEINFOF_DESTINATION
);
406 ok(rc
==MMSYSERR_INVALPARAM
||rc
==MIXERR_INVALLINE
,
407 "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
408 "MMSYSERR_INVALPARAM or MIXERR_INVALLINE expected, got %s\n",
411 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
412 mixerlineA
.dwDestination
=d
;
413 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,0,
414 MIXER_GETLINEINFOF_DESTINATION
);
415 ok(rc
==MMSYSERR_INVALPARAM
,
416 "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
417 "MMSYSERR_INVALPARAM expected, got %s\n",
420 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
421 mixerlineA
.dwDestination
=d
;
422 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,-1);
423 ok(rc
==MMSYSERR_INVALFLAG
,
424 "mixerGetLineInfoA(-1): MMSYSERR_INVALFLAG expected, got %s\n",
427 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
428 mixerlineA
.dwDestination
=d
;
429 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,
430 MIXER_GETLINEINFOF_DESTINATION
);
431 ok(rc
==MMSYSERR_NOERROR
||rc
==MMSYSERR_NODRIVER
,
432 "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
433 "MMSYSERR_NOERROR expected, got %s\n",
435 if (rc
==MMSYSERR_NODRIVER
)
436 trace(" No Driver\n");
437 else if (rc
==MMSYSERR_NOERROR
) {
438 if (winetest_interactive
) {
439 trace(" %d: \"%s\" (%s) Destination=%d Source=%d\n",
440 d
,mixerlineA
.szShortName
, mixerlineA
.szName
,
441 mixerlineA
.dwDestination
,mixerlineA
.dwSource
);
442 trace(" LineID=%08x Channels=%d "
443 "Connections=%d Controls=%d\n",
444 mixerlineA
.dwLineID
,mixerlineA
.cChannels
,
445 mixerlineA
.cConnections
,mixerlineA
.cControls
);
446 trace(" State=0x%08x(%s)\n",
447 mixerlineA
.fdwLine
,line_flags(mixerlineA
.fdwLine
));
448 trace(" ComponentType=%s\n",
449 component_type(mixerlineA
.dwComponentType
));
451 target_type(mixerlineA
.Target
.dwType
));
452 trace(" Device=%d (%s) %d.%d (%d:%d)\n",
453 mixerlineA
.Target
.dwDeviceID
,
454 mixerlineA
.Target
.szPname
,
455 mixerlineA
.Target
.vDriverVersion
>> 8,
456 mixerlineA
.Target
.vDriverVersion
& 0xff,
457 mixerlineA
.Target
.wMid
, mixerlineA
.Target
.wPid
);
459 ns
=mixerlineA
.cConnections
;
461 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
462 mixerlineA
.dwDestination
=d
;
463 mixerlineA
.dwSource
=s
;
464 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,
465 MIXER_GETLINEINFOF_SOURCE
);
466 ok(rc
==MMSYSERR_NOERROR
||rc
==MMSYSERR_NODRIVER
,
467 "mixerGetLineInfoA(MIXER_GETLINEINFOF_SOURCE): "
468 "MMSYSERR_NOERROR expected, got %s\n",
470 if (rc
==MMSYSERR_NODRIVER
)
471 trace(" No Driver\n");
472 else if (rc
==MMSYSERR_NOERROR
) {
473 LPMIXERCONTROLA array
;
474 MIXERLINECONTROLSA controls
;
475 if (winetest_interactive
) {
476 trace(" %d: \"%s\" (%s) Destination=%d Source=%d\n",
477 s
,mixerlineA
.szShortName
, mixerlineA
.szName
,
478 mixerlineA
.dwDestination
,mixerlineA
.dwSource
);
479 trace(" LineID=%08x Channels=%d "
480 "Connections=%d Controls=%d\n",
481 mixerlineA
.dwLineID
,mixerlineA
.cChannels
,
482 mixerlineA
.cConnections
,mixerlineA
.cControls
);
483 trace(" State=0x%08x(%s)\n",
484 mixerlineA
.fdwLine
,line_flags(mixerlineA
.fdwLine
));
485 trace(" ComponentType=%s\n",
486 component_type(mixerlineA
.dwComponentType
));
488 target_type(mixerlineA
.Target
.dwType
));
489 trace(" Device=%d (%s) %d.%d (%d:%d)\n",
490 mixerlineA
.Target
.dwDeviceID
,
491 mixerlineA
.Target
.szPname
,
492 mixerlineA
.Target
.vDriverVersion
>> 8,
493 mixerlineA
.Target
.vDriverVersion
& 0xff,
494 mixerlineA
.Target
.wMid
, mixerlineA
.Target
.wPid
);
496 if (mixerlineA
.cControls
) {
497 array
=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
498 mixerlineA
.cControls
*sizeof(MIXERCONTROLA
));
500 memset(&controls
, 0, sizeof(controls
));
502 rc
=mixerGetLineControlsA((HMIXEROBJ
)mix
,0,
503 MIXER_GETLINECONTROLSF_ALL
);
504 ok(rc
==MMSYSERR_INVALPARAM
,
505 "mixerGetLineControlsA(MIXER_GETLINECONTROLSF_ALL): "
506 "MMSYSERR_INVALPARAM expected, got %s\n",
509 rc
=mixerGetLineControlsA((HMIXEROBJ
)mix
,&controls
,-1);
510 ok(rc
==MMSYSERR_INVALFLAG
||rc
==MMSYSERR_INVALPARAM
,
511 "mixerGetLineControlsA(-1): "
512 "MMSYSERR_INVALFLAG or MMSYSERR_INVALPARAM expected, got %s\n",
515 controls
.cbStruct
= sizeof(MIXERLINECONTROLSA
);
516 controls
.cControls
= mixerlineA
.cControls
;
517 controls
.dwLineID
= mixerlineA
.dwLineID
;
518 controls
.pamxctrl
= array
;
519 controls
.cbmxctrl
= sizeof(MIXERCONTROLA
);
521 /* FIXME: do MIXER_GETLINECONTROLSF_ONEBYID
522 * and MIXER_GETLINECONTROLSF_ONEBYTYPE
524 rc
=mixerGetLineControlsA((HMIXEROBJ
)mix
,&controls
,
525 MIXER_GETLINECONTROLSF_ALL
);
526 ok(rc
==MMSYSERR_NOERROR
,
527 "mixerGetLineControlsA(MIXER_GETLINECONTROLSF_ALL): "
528 "MMSYSERR_NOERROR expected, got %s\n",
530 if (rc
==MMSYSERR_NOERROR
) {
531 for(nc
=0;nc
<mixerlineA
.cControls
;nc
++) {
532 if (winetest_interactive
) {
533 trace(" %d: \"%s\" (%s) ControlID=%d\n", nc
,
534 array
[nc
].szShortName
,
535 array
[nc
].szName
, array
[nc
].dwControlID
);
536 trace(" ControlType=%s\n",
537 control_type(array
[nc
].dwControlType
));
538 trace(" Control=0x%08x(%s)\n",
539 array
[nc
].fdwControl
,
540 control_flags(array
[nc
].fdwControl
));
541 trace(" Items=%d Min=%d Max=%d Step=%d\n",
542 array
[nc
].cMultipleItems
,
543 S1(array
[nc
].Bounds
).dwMinimum
,
544 S1(array
[nc
].Bounds
).dwMaximum
,
545 array
[nc
].Metrics
.cSteps
);
548 mixer_test_controlA(mix
, &array
[nc
]);
552 HeapFree(GetProcessHeap(),0,array
);
559 test_mixerClose(mix
);
563 static void mixer_test_controlW(HMIXER mix
, LPMIXERCONTROLW control
)
567 if ((control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_VOLUME
) ||
568 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_UNSIGNED
)) {
569 MIXERCONTROLDETAILS details
;
570 MIXERCONTROLDETAILS_UNSIGNED value
;
572 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
573 details
.dwControlID
= control
->dwControlID
;
574 details
.cChannels
= 1;
575 U(details
).cMultipleItems
= 0;
576 details
.paDetails
= &value
;
577 details
.cbDetails
= sizeof(value
);
579 /* read the current control value */
580 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_GETCONTROLDETAILSF_VALUE
);
581 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
582 "MMSYSERR_NOERROR expected, got %s\n",
584 if (rc
==MMSYSERR_NOERROR
&& winetest_interactive
) {
585 MIXERCONTROLDETAILS new_details
;
586 MIXERCONTROLDETAILS_UNSIGNED new_value
;
588 trace(" Value=%d\n",value
.dwValue
);
590 if (value
.dwValue
+ control
->Metrics
.cSteps
< S1(control
->Bounds
).dwMaximum
)
591 new_value
.dwValue
= value
.dwValue
+ control
->Metrics
.cSteps
;
593 new_value
.dwValue
= value
.dwValue
- control
->Metrics
.cSteps
;
595 new_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
596 new_details
.dwControlID
= control
->dwControlID
;
597 new_details
.cChannels
= 1;
598 U(new_details
).cMultipleItems
= 0;
599 new_details
.paDetails
= &new_value
;
600 new_details
.cbDetails
= sizeof(new_value
);
602 /* change the control value by one step */
603 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&new_details
,MIXER_SETCONTROLDETAILSF_VALUE
);
604 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
605 "MMSYSERR_NOERROR expected, got %s\n",
607 if (rc
==MMSYSERR_NOERROR
) {
608 MIXERCONTROLDETAILS ret_details
;
609 MIXERCONTROLDETAILS_UNSIGNED ret_value
;
611 ret_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
612 ret_details
.dwControlID
= control
->dwControlID
;
613 ret_details
.cChannels
= 1;
614 U(ret_details
).cMultipleItems
= 0;
615 ret_details
.paDetails
= &ret_value
;
616 ret_details
.cbDetails
= sizeof(ret_value
);
618 /* read back the new control value */
619 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&ret_details
,MIXER_GETCONTROLDETAILSF_VALUE
);
620 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
621 "MMSYSERR_NOERROR expected, got %s\n",
623 if (rc
==MMSYSERR_NOERROR
) {
624 /* result may not match exactly because of rounding */
625 ok(abs(ret_value
.dwValue
-new_value
.dwValue
)<=1,
626 "Couldn't change value from %d to %d, returned %d\n",
627 value
.dwValue
,new_value
.dwValue
,ret_value
.dwValue
);
629 if (abs(ret_value
.dwValue
-new_value
.dwValue
)<=1) {
630 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
631 details
.dwControlID
= control
->dwControlID
;
632 details
.cChannels
= 1;
633 U(details
).cMultipleItems
= 0;
634 details
.paDetails
= &value
;
635 details
.cbDetails
= sizeof(value
);
637 /* restore original value */
638 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_SETCONTROLDETAILSF_VALUE
);
639 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
640 "MMSYSERR_NOERROR expected, got %s\n",
646 } else if ((control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_MUTE
) ||
647 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_BOOLEAN
) ||
648 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_BUTTON
)) {
649 MIXERCONTROLDETAILS details
;
650 MIXERCONTROLDETAILS_BOOLEAN value
;
652 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
653 details
.dwControlID
= control
->dwControlID
;
654 details
.cChannels
= 1;
655 U(details
).cMultipleItems
= 0;
656 details
.paDetails
= &value
;
657 details
.cbDetails
= sizeof(value
);
659 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_GETCONTROLDETAILSF_VALUE
);
660 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
661 "MMSYSERR_NOERROR expected, got %s\n",
663 if (rc
==MMSYSERR_NOERROR
&& winetest_interactive
) {
664 MIXERCONTROLDETAILS new_details
;
665 MIXERCONTROLDETAILS_BOOLEAN new_value
;
667 trace(" Value=%d\n",value
.fValue
);
669 if (value
.fValue
== FALSE
)
670 new_value
.fValue
= TRUE
;
672 new_value
.fValue
= FALSE
;
674 new_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
675 new_details
.dwControlID
= control
->dwControlID
;
676 new_details
.cChannels
= 1;
677 U(new_details
).cMultipleItems
= 0;
678 new_details
.paDetails
= &new_value
;
679 new_details
.cbDetails
= sizeof(new_value
);
681 /* change the control value by one step */
682 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&new_details
,MIXER_SETCONTROLDETAILSF_VALUE
);
683 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
684 "MMSYSERR_NOERROR expected, got %s\n",
686 if (rc
==MMSYSERR_NOERROR
) {
687 MIXERCONTROLDETAILS ret_details
;
688 MIXERCONTROLDETAILS_BOOLEAN ret_value
;
690 ret_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
691 ret_details
.dwControlID
= control
->dwControlID
;
692 ret_details
.cChannels
= 1;
693 U(ret_details
).cMultipleItems
= 0;
694 ret_details
.paDetails
= &ret_value
;
695 ret_details
.cbDetails
= sizeof(ret_value
);
697 /* read back the new control value */
698 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&ret_details
,MIXER_GETCONTROLDETAILSF_VALUE
);
699 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
700 "MMSYSERR_NOERROR expected, got %s\n",
702 if (rc
==MMSYSERR_NOERROR
) {
703 /* result may not match exactly because of rounding */
704 ok(ret_value
.fValue
==new_value
.fValue
,
705 "Couldn't change value from %d to %d, returned %d\n",
706 value
.fValue
,new_value
.fValue
,ret_value
.fValue
);
708 if (ret_value
.fValue
==new_value
.fValue
) {
709 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
710 details
.dwControlID
= control
->dwControlID
;
711 details
.cChannels
= 1;
712 U(details
).cMultipleItems
= 0;
713 details
.paDetails
= &value
;
714 details
.cbDetails
= sizeof(value
);
716 /* restore original value */
717 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_SETCONTROLDETAILSF_VALUE
);
718 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
719 "MMSYSERR_NOERROR expected, got %s\n",
730 static void mixer_test_deviceW(int device
)
736 char szShortName
[MIXER_SHORT_NAME_CHARS
];
737 char szName
[MIXER_LONG_NAME_CHARS
];
738 char szPname
[MAXPNAMELEN
];
740 rc
=mixerGetDevCapsW(device
,0,sizeof(capsW
));
741 ok(rc
==MMSYSERR_INVALPARAM
,
742 "mixerGetDevCapsW: MMSYSERR_INVALPARAM expected, got %s\n",
745 rc
=mixerGetDevCapsW(device
,&capsW
,4);
746 ok(rc
==MMSYSERR_NOERROR
||
747 rc
==MMSYSERR_INVALPARAM
, /* Vista and W2K8 */
748 "mixerGetDevCapsW: MMSYSERR_NOERROR or MMSYSERR_INVALPARAM expected, got %s\n",
751 rc
=mixerGetDevCapsW(device
,&capsW
,sizeof(capsW
));
752 ok(rc
==MMSYSERR_NOERROR
,
753 "mixerGetDevCapsW: MMSYSERR_NOERROR expected, got %s\n",
756 WideCharToMultiByte(CP_ACP
,0,capsW
.szPname
, MAXPNAMELEN
,szPname
,
757 MAXPNAMELEN
,NULL
,NULL
);
758 if (winetest_interactive
) {
759 trace(" %d: \"%s\" %d.%d (%d:%d) destinations=%d\n", device
,
760 szPname
, capsW
.vDriverVersion
>> 8,
761 capsW
.vDriverVersion
& 0xff,capsW
.wMid
,capsW
.wPid
,
762 capsW
.cDestinations
);
764 trace(" %d: \"%s\" %d.%d (%d:%d)\n", device
,
765 szPname
, capsW
.vDriverVersion
>> 8,
766 capsW
.vDriverVersion
& 0xff,capsW
.wMid
,capsW
.wPid
);
770 rc
=mixerOpen(&mix
, device
, 0, 0, 0);
771 ok(rc
==MMSYSERR_NOERROR
,
772 "mixerOpen: MMSYSERR_NOERROR expected, got %s\n",mmsys_error(rc
));
773 if (rc
==MMSYSERR_NOERROR
) {
774 for (d
=0;d
<capsW
.cDestinations
;d
++) {
775 MIXERLINEW mixerlineW
;
776 mixerlineW
.cbStruct
= 0;
777 mixerlineW
.dwDestination
=d
;
778 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,&mixerlineW
,
779 MIXER_GETLINEINFOF_DESTINATION
);
780 ok(rc
==MMSYSERR_INVALPARAM
,
781 "mixerGetLineInfoW(MIXER_GETLINEINFOF_DESTINATION): "
782 "MMSYSERR_INVALPARAM expected, got %s\n",
785 mixerlineW
.cbStruct
= sizeof(mixerlineW
);
786 mixerlineW
.dwDestination
=capsW
.cDestinations
;
787 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,&mixerlineW
,
788 MIXER_GETLINEINFOF_DESTINATION
);
789 ok(rc
==MMSYSERR_INVALPARAM
||rc
==MIXERR_INVALLINE
,
790 "mixerGetLineInfoW(MIXER_GETLINEINFOF_DESTINATION): "
791 "MMSYSERR_INVALPARAM or MIXERR_INVALLINE expected, got %s\n",
794 mixerlineW
.cbStruct
= sizeof(mixerlineW
);
795 mixerlineW
.dwDestination
=d
;
796 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,0,
797 MIXER_GETLINEINFOF_DESTINATION
);
798 ok(rc
==MMSYSERR_INVALPARAM
,
799 "mixerGetLineInfoW(MIXER_GETLINEINFOF_DESTINATION): "
800 "MMSYSERR_INVALPARAM expected, got %s\n",
803 mixerlineW
.cbStruct
= sizeof(mixerlineW
);
804 mixerlineW
.dwDestination
=d
;
805 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,&mixerlineW
,-1);
806 ok(rc
==MMSYSERR_INVALFLAG
,
807 "mixerGetLineInfoW(-1): MMSYSERR_INVALFLAG expected, got %s\n",
810 mixerlineW
.cbStruct
= sizeof(mixerlineW
);
811 mixerlineW
.dwDestination
=d
;
812 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,&mixerlineW
,
813 MIXER_GETLINEINFOF_DESTINATION
);
814 ok(rc
==MMSYSERR_NOERROR
||rc
==MMSYSERR_NODRIVER
,
815 "mixerGetLineInfoW(MIXER_GETLINEINFOF_DESTINATION): "
816 "MMSYSERR_NOERROR expected, got %s\n",
818 if (rc
==MMSYSERR_NODRIVER
)
819 trace(" No Driver\n");
820 else if (rc
==MMSYSERR_NOERROR
&& winetest_interactive
) {
821 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.szShortName
,
822 MIXER_SHORT_NAME_CHARS
,szShortName
,
823 MIXER_SHORT_NAME_CHARS
,NULL
,NULL
);
824 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.szName
,
825 MIXER_LONG_NAME_CHARS
,szName
,
826 MIXER_LONG_NAME_CHARS
,NULL
,NULL
);
827 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.Target
.szPname
,
829 MAXPNAMELEN
,NULL
, NULL
);
830 trace(" %d: \"%s\" (%s) Destination=%d Source=%d\n",
831 d
,szShortName
,szName
,
832 mixerlineW
.dwDestination
,mixerlineW
.dwSource
);
833 trace(" LineID=%08x Channels=%d "
834 "Connections=%d Controls=%d\n",
835 mixerlineW
.dwLineID
,mixerlineW
.cChannels
,
836 mixerlineW
.cConnections
,mixerlineW
.cControls
);
837 trace(" State=0x%08x(%s)\n",
838 mixerlineW
.fdwLine
,line_flags(mixerlineW
.fdwLine
));
839 trace(" ComponentType=%s\n",
840 component_type(mixerlineW
.dwComponentType
));
842 target_type(mixerlineW
.Target
.dwType
));
843 trace(" Device=%d (%s) %d.%d (%d:%d)\n",
844 mixerlineW
.Target
.dwDeviceID
,szPname
,
845 mixerlineW
.Target
.vDriverVersion
>> 8,
846 mixerlineW
.Target
.vDriverVersion
& 0xff,
847 mixerlineW
.Target
.wMid
, mixerlineW
.Target
.wPid
);
849 ns
=mixerlineW
.cConnections
;
851 mixerlineW
.cbStruct
= sizeof(mixerlineW
);
852 mixerlineW
.dwDestination
=d
;
853 mixerlineW
.dwSource
=s
;
854 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,&mixerlineW
,
855 MIXER_GETLINEINFOF_SOURCE
);
856 ok(rc
==MMSYSERR_NOERROR
||rc
==MMSYSERR_NODRIVER
,
857 "mixerGetLineInfoW(MIXER_GETLINEINFOF_SOURCE): "
858 "MMSYSERR_NOERROR expected, got %s\n",
860 if (rc
==MMSYSERR_NODRIVER
)
861 trace(" No Driver\n");
862 else if (rc
==MMSYSERR_NOERROR
) {
863 LPMIXERCONTROLW array
;
864 MIXERLINECONTROLSW controls
;
865 if (winetest_interactive
) {
866 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.szShortName
,
867 MIXER_SHORT_NAME_CHARS
,szShortName
,
868 MIXER_SHORT_NAME_CHARS
,NULL
,NULL
);
869 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.szName
,
870 MIXER_LONG_NAME_CHARS
,szName
,
871 MIXER_LONG_NAME_CHARS
,NULL
,NULL
);
872 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.Target
.szPname
,
874 MAXPNAMELEN
,NULL
, NULL
);
875 trace(" %d: \"%s\" (%s) Destination=%d Source=%d\n",
876 s
,szShortName
,szName
,
877 mixerlineW
.dwDestination
,mixerlineW
.dwSource
);
878 trace(" LineID=%08x Channels=%d "
879 "Connections=%d Controls=%d\n",
880 mixerlineW
.dwLineID
,mixerlineW
.cChannels
,
881 mixerlineW
.cConnections
,mixerlineW
.cControls
);
882 trace(" State=0x%08x(%s)\n",
883 mixerlineW
.fdwLine
,line_flags(mixerlineW
.fdwLine
));
884 trace(" ComponentType=%s\n",
885 component_type(mixerlineW
.dwComponentType
));
887 target_type(mixerlineW
.Target
.dwType
));
888 trace(" Device=%d (%s) %d.%d (%d:%d)\n",
889 mixerlineW
.Target
.dwDeviceID
,szPname
,
890 mixerlineW
.Target
.vDriverVersion
>> 8,
891 mixerlineW
.Target
.vDriverVersion
& 0xff,
892 mixerlineW
.Target
.wMid
, mixerlineW
.Target
.wPid
);
894 if (mixerlineW
.cControls
) {
895 array
=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
896 mixerlineW
.cControls
*sizeof(MIXERCONTROLW
));
898 rc
=mixerGetLineControlsW((HMIXEROBJ
)mix
,0,
899 MIXER_GETLINECONTROLSF_ALL
);
900 ok(rc
==MMSYSERR_INVALPARAM
,
901 "mixerGetLineControlsW(MIXER_GETLINECONTROLSF_ALL): "
902 "MMSYSERR_INVALPARAM expected, got %s\n",
904 rc
=mixerGetLineControlsW((HMIXEROBJ
)mix
,&controls
,
906 ok(rc
==MMSYSERR_INVALFLAG
||rc
==MMSYSERR_INVALPARAM
,
907 "mixerGetLineControlsA(-1): "
908 "MMSYSERR_INVALFLAG or MMSYSERR_INVALPARAM expected, got %s\n",
911 controls
.cbStruct
= sizeof(MIXERLINECONTROLSW
);
912 controls
.cControls
= mixerlineW
.cControls
;
913 controls
.dwLineID
= mixerlineW
.dwLineID
;
914 controls
.pamxctrl
= array
;
915 controls
.cbmxctrl
= sizeof(MIXERCONTROLW
);
917 /* FIXME: do MIXER_GETLINECONTROLSF_ONEBYID
918 * and MIXER_GETLINECONTROLSF_ONEBYTYPE
920 rc
=mixerGetLineControlsW((HMIXEROBJ
)mix
,&controls
,
921 MIXER_GETLINECONTROLSF_ALL
);
922 ok(rc
==MMSYSERR_NOERROR
,
923 "mixerGetLineControlsW(MIXER_GETLINECONTROLSF_ALL): "
924 "MMSYSERR_NOERROR expected, got %s\n",
926 if (rc
==MMSYSERR_NOERROR
) {
927 for(nc
=0;nc
<mixerlineW
.cControls
;nc
++) {
928 if (winetest_interactive
) {
929 WideCharToMultiByte(CP_ACP
,0,array
[nc
].szShortName
,
930 MIXER_SHORT_NAME_CHARS
,szShortName
,
931 MIXER_SHORT_NAME_CHARS
,NULL
,NULL
);
932 WideCharToMultiByte(CP_ACP
,0,array
[nc
].szName
,
933 MIXER_LONG_NAME_CHARS
,szName
,
934 MIXER_LONG_NAME_CHARS
,NULL
,NULL
);
935 trace(" %d: \"%s\" (%s) ControlID=%d\n", nc
,
936 szShortName
, szName
, array
[nc
].dwControlID
);
937 trace(" ControlType=%s\n",
938 control_type(array
[nc
].dwControlType
));
939 trace(" Control=0x%08x(%s)\n",
940 array
[nc
].fdwControl
,
941 control_flags(array
[nc
].fdwControl
));
942 trace(" Items=%d Min=%d Max=%d Step=%d\n",
943 array
[nc
].cMultipleItems
,
944 S1(array
[nc
].Bounds
).dwMinimum
,
945 S1(array
[nc
].Bounds
).dwMaximum
,
946 array
[nc
].Metrics
.cSteps
);
948 mixer_test_controlW(mix
, &array
[nc
]);
952 HeapFree(GetProcessHeap(),0,array
);
958 test_mixerClose(mix
);
962 static void mixer_testsA(void)
968 trace("--- Testing ASCII functions ---\n");
970 ndev
=mixerGetNumDevs();
971 trace("found %d Mixer devices\n",ndev
);
973 rc
=mixerGetDevCapsA(ndev
+1,&capsA
,sizeof(capsA
));
974 ok(rc
==MMSYSERR_BADDEVICEID
,
975 "mixerGetDevCapsA: MMSYSERR_BADDEVICEID expected, got %s\n",
979 mixer_test_deviceA(d
);
982 static void mixer_testsW(void)
988 trace("--- Testing WCHAR functions ---\n");
990 ndev
=mixerGetNumDevs();
991 trace("found %d Mixer devices\n",ndev
);
993 rc
=mixerGetDevCapsW(ndev
+1,&capsW
,sizeof(capsW
));
994 ok(rc
==MMSYSERR_BADDEVICEID
||rc
==MMSYSERR_NOTSUPPORTED
,
995 "mixerGetDevCapsW: MMSYSERR_BADDEVICEID or MMSYSERR_NOTSUPPORTED "
996 "expected, got %s\n", mmsys_error(rc
));
997 if (rc
==MMSYSERR_NOTSUPPORTED
)
1000 for (d
=0;d
<ndev
;d
++)
1001 mixer_test_deviceW(d
);
1004 static void test_mixerOpen(void)
1010 ndev
= mixerGetNumDevs();
1012 /* Test mixerOpen with invalid device ID values. */
1013 rc
= mixerOpen(&mix
, ndev
+ 1, 0, 0, 0);
1014 ok(rc
== MMSYSERR_BADDEVICEID
,
1015 "mixerOpen: MMSYSERR_BADDEVICEID expected, got %s\n",
1018 rc
= mixerOpen(&mix
, -1, 0, 0, 0);
1019 ok(rc
== MMSYSERR_BADDEVICEID
||
1020 rc
== MMSYSERR_INVALHANDLE
, /* NT4/W2K */
1021 "mixerOpen: MMSYSERR_BADDEVICEID or MMSYSERR_INVALHANDLE expected, got %s\n",
1024 for (d
= 0; d
< ndev
; d
++) {
1025 /* Test mixerOpen with valid device ID values and invalid parameters. */
1026 rc
= mixerOpen(&mix
, d
, 0, 0, CALLBACK_FUNCTION
);
1027 ok(rc
== MMSYSERR_INVALFLAG
1028 || rc
== MMSYSERR_NOTSUPPORTED
, /* 98/ME */
1029 "mixerOpen: MMSYSERR_INVALFLAG expected, got %s\n",
1032 rc
= mixerOpen(&mix
, d
, 0xdeadbeef, 0, CALLBACK_WINDOW
);
1033 ok(rc
== MMSYSERR_INVALPARAM
||
1034 rc
== MMSYSERR_NOERROR
, /* 98 */
1035 "mixerOpen: MMSYSERR_INVALPARAM expected, got %s\n",
1037 if (rc
== MMSYSERR_NOERROR
)
1038 test_mixerClose(mix
);
1040 /* Test mixerOpen with a NULL dwCallback and CALLBACK_WINDOW flag. */
1041 rc
= mixerOpen(&mix
, d
, 0, 0, CALLBACK_WINDOW
);
1042 ok(rc
== MMSYSERR_NOERROR
,
1043 "mixerOpen: MMSYSERR_NOERROR expected, got %s\n",
1046 if (rc
== MMSYSERR_NOERROR
)
1047 test_mixerClose(mix
);
1049 /* Test mixerOpen with normal parameters. */
1050 rc
= mixerOpen(&mix
, d
, 0, 0, 0);
1051 ok(rc
== MMSYSERR_NOERROR
,
1052 "mixerOpen: MMSYSERR_NOERROR expected, got %s\n",
1055 if (rc
== MMSYSERR_NOERROR
)
1056 test_mixerClose(mix
);