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 mixer_test_controlA(HMIXER mix
, LPMIXERCONTROLA control
)
181 if ((control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_VOLUME
) ||
182 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_UNSIGNED
)) {
183 MIXERCONTROLDETAILS details
;
184 MIXERCONTROLDETAILS_UNSIGNED value
;
186 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
187 details
.dwControlID
= control
->dwControlID
;
188 details
.cChannels
= 1;
189 U(details
).cMultipleItems
= 0;
190 details
.paDetails
= &value
;
191 details
.cbDetails
= sizeof(value
);
193 /* read the current control value */
194 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_GETCONTROLDETAILSF_VALUE
);
195 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
196 "MMSYSERR_NOERROR expected, got %s\n",
198 if (rc
==MMSYSERR_NOERROR
&& winetest_interactive
) {
199 MIXERCONTROLDETAILS new_details
;
200 MIXERCONTROLDETAILS_UNSIGNED new_value
;
202 trace(" Value=%d\n",value
.dwValue
);
204 if (value
.dwValue
+ control
->Metrics
.cSteps
< S1(control
->Bounds
).dwMaximum
)
205 new_value
.dwValue
= value
.dwValue
+ control
->Metrics
.cSteps
;
207 new_value
.dwValue
= value
.dwValue
- control
->Metrics
.cSteps
;
209 new_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
210 new_details
.dwControlID
= control
->dwControlID
;
211 new_details
.cChannels
= 1;
212 U(new_details
).cMultipleItems
= 0;
213 new_details
.paDetails
= &new_value
;
214 new_details
.cbDetails
= sizeof(new_value
);
216 /* change the control value by one step */
217 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&new_details
,MIXER_SETCONTROLDETAILSF_VALUE
);
218 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
219 "MMSYSERR_NOERROR expected, got %s\n",
221 if (rc
==MMSYSERR_NOERROR
) {
222 MIXERCONTROLDETAILS ret_details
;
223 MIXERCONTROLDETAILS_UNSIGNED ret_value
;
225 ret_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
226 ret_details
.dwControlID
= control
->dwControlID
;
227 ret_details
.cChannels
= 1;
228 U(ret_details
).cMultipleItems
= 0;
229 ret_details
.paDetails
= &ret_value
;
230 ret_details
.cbDetails
= sizeof(ret_value
);
232 /* read back the new control value */
233 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&ret_details
,MIXER_GETCONTROLDETAILSF_VALUE
);
234 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
235 "MMSYSERR_NOERROR expected, got %s\n",
237 if (rc
==MMSYSERR_NOERROR
) {
238 /* result may not match exactly because of rounding */
239 ok(abs(ret_value
.dwValue
-new_value
.dwValue
)<=1,
240 "Couldn't change value from %d to %d, returned %d\n",
241 value
.dwValue
,new_value
.dwValue
,ret_value
.dwValue
);
243 if (abs(ret_value
.dwValue
-new_value
.dwValue
)<=1) {
244 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
245 details
.dwControlID
= control
->dwControlID
;
246 details
.cChannels
= 1;
247 U(details
).cMultipleItems
= 0;
248 details
.paDetails
= &value
;
249 details
.cbDetails
= sizeof(value
);
251 /* restore original value */
252 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_SETCONTROLDETAILSF_VALUE
);
253 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
254 "MMSYSERR_NOERROR expected, got %s\n",
260 } else if ((control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_MUTE
) ||
261 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_BOOLEAN
) ||
262 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_BUTTON
)) {
263 MIXERCONTROLDETAILS details
;
264 MIXERCONTROLDETAILS_BOOLEAN value
;
266 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
267 details
.dwControlID
= control
->dwControlID
;
268 details
.cChannels
= 1;
269 U(details
).cMultipleItems
= 0;
270 details
.paDetails
= &value
;
271 details
.cbDetails
= sizeof(value
);
273 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_GETCONTROLDETAILSF_VALUE
);
274 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
275 "MMSYSERR_NOERROR expected, got %s\n",
277 if (rc
==MMSYSERR_NOERROR
&& winetest_interactive
) {
278 MIXERCONTROLDETAILS new_details
;
279 MIXERCONTROLDETAILS_BOOLEAN new_value
;
281 trace(" Value=%d\n",value
.fValue
);
283 if (value
.fValue
== FALSE
)
284 new_value
.fValue
= TRUE
;
286 new_value
.fValue
= FALSE
;
288 new_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
289 new_details
.dwControlID
= control
->dwControlID
;
290 new_details
.cChannels
= 1;
291 U(new_details
).cMultipleItems
= 0;
292 new_details
.paDetails
= &new_value
;
293 new_details
.cbDetails
= sizeof(new_value
);
295 /* change the control value by one step */
296 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&new_details
,MIXER_SETCONTROLDETAILSF_VALUE
);
297 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
298 "MMSYSERR_NOERROR expected, got %s\n",
300 if (rc
==MMSYSERR_NOERROR
) {
301 MIXERCONTROLDETAILS ret_details
;
302 MIXERCONTROLDETAILS_BOOLEAN ret_value
;
304 ret_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
305 ret_details
.dwControlID
= control
->dwControlID
;
306 ret_details
.cChannels
= 1;
307 U(ret_details
).cMultipleItems
= 0;
308 ret_details
.paDetails
= &ret_value
;
309 ret_details
.cbDetails
= sizeof(ret_value
);
311 /* read back the new control value */
312 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&ret_details
,MIXER_GETCONTROLDETAILSF_VALUE
);
313 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
314 "MMSYSERR_NOERROR expected, got %s\n",
316 if (rc
==MMSYSERR_NOERROR
) {
317 /* result may not match exactly because of rounding */
318 ok(ret_value
.fValue
==new_value
.fValue
,
319 "Couldn't change value from %d to %d, returned %d\n",
320 value
.fValue
,new_value
.fValue
,ret_value
.fValue
);
322 if (ret_value
.fValue
==new_value
.fValue
) {
323 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
324 details
.dwControlID
= control
->dwControlID
;
325 details
.cChannels
= 1;
326 U(details
).cMultipleItems
= 0;
327 details
.paDetails
= &value
;
328 details
.cbDetails
= sizeof(value
);
330 /* restore original value */
331 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_SETCONTROLDETAILSF_VALUE
);
332 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
333 "MMSYSERR_NOERROR expected, got %s\n",
344 static void mixer_test_deviceA(int device
)
351 rc
=mixerGetDevCapsA(device
,0,sizeof(capsA
));
352 ok(rc
==MMSYSERR_INVALPARAM
,
353 "mixerGetDevCapsA: MMSYSERR_INVALPARAM expected, got %s\n",
356 rc
=mixerGetDevCapsA(device
,&capsA
,4);
357 ok(rc
==MMSYSERR_NOERROR
,
358 "mixerGetDevCapsA: MMSYSERR_NOERROR expected, got %s\n",
361 rc
=mixerGetDevCapsA(device
,&capsA
,sizeof(capsA
));
362 ok(rc
==MMSYSERR_NOERROR
,
363 "mixerGetDevCapsA: MMSYSERR_NOERROR expected, got %s\n",
366 if (winetest_interactive
) {
367 trace(" %d: \"%s\" %d.%d (%d:%d) destinations=%d\n", device
,
368 capsA
.szPname
, capsA
.vDriverVersion
>> 8,
369 capsA
.vDriverVersion
& 0xff,capsA
.wMid
,capsA
.wPid
,
370 capsA
.cDestinations
);
372 trace(" %d: \"%s\" %d.%d (%d:%d)\n", device
,
373 capsA
.szPname
, capsA
.vDriverVersion
>> 8,
374 capsA
.vDriverVersion
& 0xff,capsA
.wMid
,capsA
.wPid
);
377 rc
=mixerOpen(&mix
, device
, 0, 0, 0);
378 ok(rc
==MMSYSERR_NOERROR
,
379 "mixerOpen: MMSYSERR_NOERROR expected, got %s\n",mmsys_error(rc
));
380 if (rc
==MMSYSERR_NOERROR
) {
381 rc
=mixerOpen(&mix
, device
, 0, 0, CALLBACK_FUNCTION
);
382 ok(rc
==MMSYSERR_INVALFLAG
383 || rc
==MMSYSERR_NOTSUPPORTED
, /* 98/ME */
384 "mixerOpen: MMSYSERR_INVALFLAG or MMSYSERR_NOTSUPPORTED expected, got %s\n", mmsys_error(rc
));
386 for (d
=0;d
<capsA
.cDestinations
;d
++) {
387 MIXERLINEA mixerlineA
;
388 mixerlineA
.cbStruct
= 0;
389 mixerlineA
.dwDestination
=d
;
390 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,
391 MIXER_GETLINEINFOF_DESTINATION
);
392 ok(rc
==MMSYSERR_INVALPARAM
,
393 "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
394 "MMSYSERR_INVALPARAM expected, got %s\n",
397 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
398 mixerlineA
.dwDestination
=capsA
.cDestinations
;
399 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,
400 MIXER_GETLINEINFOF_DESTINATION
);
401 ok(rc
==MMSYSERR_INVALPARAM
||rc
==MIXERR_INVALLINE
,
402 "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
403 "MMSYSERR_INVALPARAM or MIXERR_INVALLINE expected, got %s\n",
406 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
407 mixerlineA
.dwDestination
=d
;
408 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,0,
409 MIXER_GETLINEINFOF_DESTINATION
);
410 ok(rc
==MMSYSERR_INVALPARAM
,
411 "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
412 "MMSYSERR_INVALPARAM expected, got %s\n",
415 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
416 mixerlineA
.dwDestination
=d
;
417 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,-1);
418 ok(rc
==MMSYSERR_INVALFLAG
,
419 "mixerGetLineInfoA(-1): MMSYSERR_INVALFLAG expected, got %s\n",
422 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
423 mixerlineA
.dwDestination
=d
;
424 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,
425 MIXER_GETLINEINFOF_DESTINATION
);
426 ok(rc
==MMSYSERR_NOERROR
||rc
==MMSYSERR_NODRIVER
,
427 "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
428 "MMSYSERR_NOERROR expected, got %s\n",
430 if (rc
==MMSYSERR_NODRIVER
)
431 trace(" No Driver\n");
432 else if (rc
==MMSYSERR_NOERROR
) {
433 if (winetest_interactive
) {
434 trace(" %d: \"%s\" (%s) Destination=%d Source=%d\n",
435 d
,mixerlineA
.szShortName
, mixerlineA
.szName
,
436 mixerlineA
.dwDestination
,mixerlineA
.dwSource
);
437 trace(" LineID=%08x Channels=%d "
438 "Connections=%d Controls=%d\n",
439 mixerlineA
.dwLineID
,mixerlineA
.cChannels
,
440 mixerlineA
.cConnections
,mixerlineA
.cControls
);
441 trace(" State=0x%08x(%s)\n",
442 mixerlineA
.fdwLine
,line_flags(mixerlineA
.fdwLine
));
443 trace(" ComponentType=%s\n",
444 component_type(mixerlineA
.dwComponentType
));
446 target_type(mixerlineA
.Target
.dwType
));
447 trace(" Device=%d (%s) %d.%d (%d:%d)\n",
448 mixerlineA
.Target
.dwDeviceID
,
449 mixerlineA
.Target
.szPname
,
450 mixerlineA
.Target
.vDriverVersion
>> 8,
451 mixerlineA
.Target
.vDriverVersion
& 0xff,
452 mixerlineA
.Target
.wMid
, mixerlineA
.Target
.wPid
);
454 ns
=mixerlineA
.cConnections
;
456 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
457 mixerlineA
.dwDestination
=d
;
458 mixerlineA
.dwSource
=s
;
459 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,
460 MIXER_GETLINEINFOF_SOURCE
);
461 ok(rc
==MMSYSERR_NOERROR
||rc
==MMSYSERR_NODRIVER
,
462 "mixerGetLineInfoA(MIXER_GETLINEINFOF_SOURCE): "
463 "MMSYSERR_NOERROR expected, got %s\n",
465 if (rc
==MMSYSERR_NODRIVER
)
466 trace(" No Driver\n");
467 else if (rc
==MMSYSERR_NOERROR
) {
468 LPMIXERCONTROLA array
;
469 MIXERLINECONTROLSA controls
;
470 if (winetest_interactive
) {
471 trace(" %d: \"%s\" (%s) Destination=%d Source=%d\n",
472 s
,mixerlineA
.szShortName
, mixerlineA
.szName
,
473 mixerlineA
.dwDestination
,mixerlineA
.dwSource
);
474 trace(" LineID=%08x Channels=%d "
475 "Connections=%d Controls=%d\n",
476 mixerlineA
.dwLineID
,mixerlineA
.cChannels
,
477 mixerlineA
.cConnections
,mixerlineA
.cControls
);
478 trace(" State=0x%08x(%s)\n",
479 mixerlineA
.fdwLine
,line_flags(mixerlineA
.fdwLine
));
480 trace(" ComponentType=%s\n",
481 component_type(mixerlineA
.dwComponentType
));
483 target_type(mixerlineA
.Target
.dwType
));
484 trace(" Device=%d (%s) %d.%d (%d:%d)\n",
485 mixerlineA
.Target
.dwDeviceID
,
486 mixerlineA
.Target
.szPname
,
487 mixerlineA
.Target
.vDriverVersion
>> 8,
488 mixerlineA
.Target
.vDriverVersion
& 0xff,
489 mixerlineA
.Target
.wMid
, mixerlineA
.Target
.wPid
);
491 if (mixerlineA
.cControls
) {
492 array
=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
493 mixerlineA
.cControls
*sizeof(MIXERCONTROLA
));
495 memset(&controls
, 0, sizeof(controls
));
497 rc
=mixerGetLineControlsA((HMIXEROBJ
)mix
,0,
498 MIXER_GETLINECONTROLSF_ALL
);
499 ok(rc
==MMSYSERR_INVALPARAM
,
500 "mixerGetLineControlsA(MIXER_GETLINECONTROLSF_ALL): "
501 "MMSYSERR_INVALPARAM expected, got %s\n",
504 rc
=mixerGetLineControlsA((HMIXEROBJ
)mix
,&controls
,-1);
505 ok(rc
==MMSYSERR_INVALFLAG
||rc
==MMSYSERR_INVALPARAM
,
506 "mixerGetLineControlsA(-1): "
507 "MMSYSERR_INVALFLAG or MMSYSERR_INVALPARAM expected, got %s\n",
510 controls
.cbStruct
= sizeof(MIXERLINECONTROLSA
);
511 controls
.cControls
= mixerlineA
.cControls
;
512 controls
.dwLineID
= mixerlineA
.dwLineID
;
513 controls
.pamxctrl
= array
;
514 controls
.cbmxctrl
= sizeof(MIXERCONTROLA
);
516 /* FIXME: do MIXER_GETLINECONTROLSF_ONEBYID
517 * and MIXER_GETLINECONTROLSF_ONEBYTYPE
519 rc
=mixerGetLineControlsA((HMIXEROBJ
)mix
,&controls
,
520 MIXER_GETLINECONTROLSF_ALL
);
521 ok(rc
==MMSYSERR_NOERROR
,
522 "mixerGetLineControlsA(MIXER_GETLINECONTROLSF_ALL): "
523 "MMSYSERR_NOERROR expected, got %s\n",
525 if (rc
==MMSYSERR_NOERROR
) {
526 for(nc
=0;nc
<mixerlineA
.cControls
;nc
++) {
527 if (winetest_interactive
) {
528 trace(" %d: \"%s\" (%s) ControlID=%d\n", nc
,
529 array
[nc
].szShortName
,
530 array
[nc
].szName
, array
[nc
].dwControlID
);
531 trace(" ControlType=%s\n",
532 control_type(array
[nc
].dwControlType
));
533 trace(" Control=0x%08x(%s)\n",
534 array
[nc
].fdwControl
,
535 control_flags(array
[nc
].fdwControl
));
536 trace(" Items=%d Min=%d Max=%d Step=%d\n",
537 array
[nc
].cMultipleItems
,
538 S1(array
[nc
].Bounds
).dwMinimum
,
539 S1(array
[nc
].Bounds
).dwMaximum
,
540 array
[nc
].Metrics
.cSteps
);
543 mixer_test_controlA(mix
, &array
[nc
]);
547 HeapFree(GetProcessHeap(),0,array
);
555 ok(rc
==MMSYSERR_NOERROR
|| rc
==MMSYSERR_INVALHANDLE
,
556 "mixerClose: MMSYSERR_NOERROR or MMSYSERR_INVALHANDLE expected, got %s\n",
561 static void mixer_test_controlW(HMIXER mix
, LPMIXERCONTROLW control
)
565 if ((control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_VOLUME
) ||
566 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_UNSIGNED
)) {
567 MIXERCONTROLDETAILS details
;
568 MIXERCONTROLDETAILS_UNSIGNED value
;
570 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
571 details
.dwControlID
= control
->dwControlID
;
572 details
.cChannels
= 1;
573 U(details
).cMultipleItems
= 0;
574 details
.paDetails
= &value
;
575 details
.cbDetails
= sizeof(value
);
577 /* read the current control value */
578 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_GETCONTROLDETAILSF_VALUE
);
579 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
580 "MMSYSERR_NOERROR expected, got %s\n",
582 if (rc
==MMSYSERR_NOERROR
&& winetest_interactive
) {
583 MIXERCONTROLDETAILS new_details
;
584 MIXERCONTROLDETAILS_UNSIGNED new_value
;
586 trace(" Value=%d\n",value
.dwValue
);
588 if (value
.dwValue
+ control
->Metrics
.cSteps
< S1(control
->Bounds
).dwMaximum
)
589 new_value
.dwValue
= value
.dwValue
+ control
->Metrics
.cSteps
;
591 new_value
.dwValue
= value
.dwValue
- control
->Metrics
.cSteps
;
593 new_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
594 new_details
.dwControlID
= control
->dwControlID
;
595 new_details
.cChannels
= 1;
596 U(new_details
).cMultipleItems
= 0;
597 new_details
.paDetails
= &new_value
;
598 new_details
.cbDetails
= sizeof(new_value
);
600 /* change the control value by one step */
601 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&new_details
,MIXER_SETCONTROLDETAILSF_VALUE
);
602 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
603 "MMSYSERR_NOERROR expected, got %s\n",
605 if (rc
==MMSYSERR_NOERROR
) {
606 MIXERCONTROLDETAILS ret_details
;
607 MIXERCONTROLDETAILS_UNSIGNED ret_value
;
609 ret_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
610 ret_details
.dwControlID
= control
->dwControlID
;
611 ret_details
.cChannels
= 1;
612 U(ret_details
).cMultipleItems
= 0;
613 ret_details
.paDetails
= &ret_value
;
614 ret_details
.cbDetails
= sizeof(ret_value
);
616 /* read back the new control value */
617 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&ret_details
,MIXER_GETCONTROLDETAILSF_VALUE
);
618 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
619 "MMSYSERR_NOERROR expected, got %s\n",
621 if (rc
==MMSYSERR_NOERROR
) {
622 /* result may not match exactly because of rounding */
623 ok(abs(ret_value
.dwValue
-new_value
.dwValue
)<=1,
624 "Couldn't change value from %d to %d, returned %d\n",
625 value
.dwValue
,new_value
.dwValue
,ret_value
.dwValue
);
627 if (abs(ret_value
.dwValue
-new_value
.dwValue
)<=1) {
628 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
629 details
.dwControlID
= control
->dwControlID
;
630 details
.cChannels
= 1;
631 U(details
).cMultipleItems
= 0;
632 details
.paDetails
= &value
;
633 details
.cbDetails
= sizeof(value
);
635 /* restore original value */
636 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_SETCONTROLDETAILSF_VALUE
);
637 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
638 "MMSYSERR_NOERROR expected, got %s\n",
644 } else if ((control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_MUTE
) ||
645 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_BOOLEAN
) ||
646 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_BUTTON
)) {
647 MIXERCONTROLDETAILS details
;
648 MIXERCONTROLDETAILS_BOOLEAN value
;
650 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
651 details
.dwControlID
= control
->dwControlID
;
652 details
.cChannels
= 1;
653 U(details
).cMultipleItems
= 0;
654 details
.paDetails
= &value
;
655 details
.cbDetails
= sizeof(value
);
657 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_GETCONTROLDETAILSF_VALUE
);
658 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
659 "MMSYSERR_NOERROR expected, got %s\n",
661 if (rc
==MMSYSERR_NOERROR
&& winetest_interactive
) {
662 MIXERCONTROLDETAILS new_details
;
663 MIXERCONTROLDETAILS_BOOLEAN new_value
;
665 trace(" Value=%d\n",value
.fValue
);
667 if (value
.fValue
== FALSE
)
668 new_value
.fValue
= TRUE
;
670 new_value
.fValue
= FALSE
;
672 new_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
673 new_details
.dwControlID
= control
->dwControlID
;
674 new_details
.cChannels
= 1;
675 U(new_details
).cMultipleItems
= 0;
676 new_details
.paDetails
= &new_value
;
677 new_details
.cbDetails
= sizeof(new_value
);
679 /* change the control value by one step */
680 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&new_details
,MIXER_SETCONTROLDETAILSF_VALUE
);
681 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
682 "MMSYSERR_NOERROR expected, got %s\n",
684 if (rc
==MMSYSERR_NOERROR
) {
685 MIXERCONTROLDETAILS ret_details
;
686 MIXERCONTROLDETAILS_BOOLEAN ret_value
;
688 ret_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
689 ret_details
.dwControlID
= control
->dwControlID
;
690 ret_details
.cChannels
= 1;
691 U(ret_details
).cMultipleItems
= 0;
692 ret_details
.paDetails
= &ret_value
;
693 ret_details
.cbDetails
= sizeof(ret_value
);
695 /* read back the new control value */
696 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&ret_details
,MIXER_GETCONTROLDETAILSF_VALUE
);
697 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
698 "MMSYSERR_NOERROR expected, got %s\n",
700 if (rc
==MMSYSERR_NOERROR
) {
701 /* result may not match exactly because of rounding */
702 ok(ret_value
.fValue
==new_value
.fValue
,
703 "Couldn't change value from %d to %d, returned %d\n",
704 value
.fValue
,new_value
.fValue
,ret_value
.fValue
);
706 if (ret_value
.fValue
==new_value
.fValue
) {
707 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
708 details
.dwControlID
= control
->dwControlID
;
709 details
.cChannels
= 1;
710 U(details
).cMultipleItems
= 0;
711 details
.paDetails
= &value
;
712 details
.cbDetails
= sizeof(value
);
714 /* restore original value */
715 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_SETCONTROLDETAILSF_VALUE
);
716 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
717 "MMSYSERR_NOERROR expected, got %s\n",
728 static void mixer_test_deviceW(int device
)
734 char szShortName
[MIXER_SHORT_NAME_CHARS
];
735 char szName
[MIXER_LONG_NAME_CHARS
];
736 char szPname
[MAXPNAMELEN
];
738 rc
=mixerGetDevCapsW(device
,0,sizeof(capsW
));
739 ok(rc
==MMSYSERR_INVALPARAM
,
740 "mixerGetDevCapsW: MMSYSERR_INVALPARAM expected, got %s\n",
743 rc
=mixerGetDevCapsW(device
,&capsW
,4);
744 ok(rc
==MMSYSERR_NOERROR
||
745 rc
==MMSYSERR_INVALPARAM
, /* Vista and W2K8 */
746 "mixerGetDevCapsW: MMSYSERR_NOERROR or MMSYSERR_INVALPARAM expected, got %s\n",
749 rc
=mixerGetDevCapsW(device
,&capsW
,sizeof(capsW
));
750 ok(rc
==MMSYSERR_NOERROR
,
751 "mixerGetDevCapsW: MMSYSERR_NOERROR expected, got %s\n",
754 WideCharToMultiByte(CP_ACP
,0,capsW
.szPname
, MAXPNAMELEN
,szPname
,
755 MAXPNAMELEN
,NULL
,NULL
);
756 if (winetest_interactive
) {
757 trace(" %d: \"%s\" %d.%d (%d:%d) destinations=%d\n", device
,
758 szPname
, capsW
.vDriverVersion
>> 8,
759 capsW
.vDriverVersion
& 0xff,capsW
.wMid
,capsW
.wPid
,
760 capsW
.cDestinations
);
762 trace(" %d: \"%s\" %d.%d (%d:%d)\n", device
,
763 szPname
, capsW
.vDriverVersion
>> 8,
764 capsW
.vDriverVersion
& 0xff,capsW
.wMid
,capsW
.wPid
);
768 rc
=mixerOpen(&mix
, device
, 0, 0, 0);
769 ok(rc
==MMSYSERR_NOERROR
,
770 "mixerOpen: MMSYSERR_BADDEVICEID expected, got %s\n",mmsys_error(rc
));
771 if (rc
==MMSYSERR_NOERROR
) {
772 rc
=mixerOpen(&mix
, device
, 0, 0, CALLBACK_FUNCTION
);
773 ok(rc
==MMSYSERR_INVALFLAG
,
774 "mixerOpen: MMSYSERR_INVALFLAG expected, got %s\n", mmsys_error(rc
));
776 for (d
=0;d
<capsW
.cDestinations
;d
++) {
777 MIXERLINEW mixerlineW
;
778 mixerlineW
.cbStruct
= 0;
779 mixerlineW
.dwDestination
=d
;
780 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,&mixerlineW
,
781 MIXER_GETLINEINFOF_DESTINATION
);
782 ok(rc
==MMSYSERR_INVALPARAM
,
783 "mixerGetLineInfoW(MIXER_GETLINEINFOF_DESTINATION): "
784 "MMSYSERR_INVALPARAM expected, got %s\n",
787 mixerlineW
.cbStruct
= sizeof(mixerlineW
);
788 mixerlineW
.dwDestination
=capsW
.cDestinations
;
789 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,&mixerlineW
,
790 MIXER_GETLINEINFOF_DESTINATION
);
791 ok(rc
==MMSYSERR_INVALPARAM
||rc
==MIXERR_INVALLINE
,
792 "mixerGetLineInfoW(MIXER_GETLINEINFOF_DESTINATION): "
793 "MMSYSERR_INVALPARAM or MIXERR_INVALLINE expected, got %s\n",
796 mixerlineW
.cbStruct
= sizeof(mixerlineW
);
797 mixerlineW
.dwDestination
=d
;
798 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,0,
799 MIXER_GETLINEINFOF_DESTINATION
);
800 ok(rc
==MMSYSERR_INVALPARAM
,
801 "mixerGetLineInfoW(MIXER_GETLINEINFOF_DESTINATION): "
802 "MMSYSERR_INVALPARAM expected, got %s\n",
805 mixerlineW
.cbStruct
= sizeof(mixerlineW
);
806 mixerlineW
.dwDestination
=d
;
807 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,&mixerlineW
,-1);
808 ok(rc
==MMSYSERR_INVALFLAG
,
809 "mixerGetLineInfoW(-1): MMSYSERR_INVALFLAG expected, got %s\n",
812 mixerlineW
.cbStruct
= sizeof(mixerlineW
);
813 mixerlineW
.dwDestination
=d
;
814 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,&mixerlineW
,
815 MIXER_GETLINEINFOF_DESTINATION
);
816 ok(rc
==MMSYSERR_NOERROR
||rc
==MMSYSERR_NODRIVER
,
817 "mixerGetLineInfoW(MIXER_GETLINEINFOF_DESTINATION): "
818 "MMSYSERR_NOERROR expected, got %s\n",
820 if (rc
==MMSYSERR_NODRIVER
)
821 trace(" No Driver\n");
822 else if (rc
==MMSYSERR_NOERROR
&& winetest_interactive
) {
823 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.szShortName
,
824 MIXER_SHORT_NAME_CHARS
,szShortName
,
825 MIXER_SHORT_NAME_CHARS
,NULL
,NULL
);
826 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.szName
,
827 MIXER_LONG_NAME_CHARS
,szName
,
828 MIXER_LONG_NAME_CHARS
,NULL
,NULL
);
829 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.Target
.szPname
,
831 MAXPNAMELEN
,NULL
, NULL
);
832 trace(" %d: \"%s\" (%s) Destination=%d Source=%d\n",
833 d
,szShortName
,szName
,
834 mixerlineW
.dwDestination
,mixerlineW
.dwSource
);
835 trace(" LineID=%08x Channels=%d "
836 "Connections=%d Controls=%d\n",
837 mixerlineW
.dwLineID
,mixerlineW
.cChannels
,
838 mixerlineW
.cConnections
,mixerlineW
.cControls
);
839 trace(" State=0x%08x(%s)\n",
840 mixerlineW
.fdwLine
,line_flags(mixerlineW
.fdwLine
));
841 trace(" ComponentType=%s\n",
842 component_type(mixerlineW
.dwComponentType
));
844 target_type(mixerlineW
.Target
.dwType
));
845 trace(" Device=%d (%s) %d.%d (%d:%d)\n",
846 mixerlineW
.Target
.dwDeviceID
,szPname
,
847 mixerlineW
.Target
.vDriverVersion
>> 8,
848 mixerlineW
.Target
.vDriverVersion
& 0xff,
849 mixerlineW
.Target
.wMid
, mixerlineW
.Target
.wPid
);
851 ns
=mixerlineW
.cConnections
;
853 mixerlineW
.cbStruct
= sizeof(mixerlineW
);
854 mixerlineW
.dwDestination
=d
;
855 mixerlineW
.dwSource
=s
;
856 rc
=mixerGetLineInfoW((HMIXEROBJ
)mix
,&mixerlineW
,
857 MIXER_GETLINEINFOF_SOURCE
);
858 ok(rc
==MMSYSERR_NOERROR
||rc
==MMSYSERR_NODRIVER
,
859 "mixerGetLineInfoW(MIXER_GETLINEINFOF_SOURCE): "
860 "MMSYSERR_NOERROR expected, got %s\n",
862 if (rc
==MMSYSERR_NODRIVER
)
863 trace(" No Driver\n");
864 else if (rc
==MMSYSERR_NOERROR
) {
865 LPMIXERCONTROLW array
;
866 MIXERLINECONTROLSW controls
;
867 if (winetest_interactive
) {
868 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.szShortName
,
869 MIXER_SHORT_NAME_CHARS
,szShortName
,
870 MIXER_SHORT_NAME_CHARS
,NULL
,NULL
);
871 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.szName
,
872 MIXER_LONG_NAME_CHARS
,szName
,
873 MIXER_LONG_NAME_CHARS
,NULL
,NULL
);
874 WideCharToMultiByte(CP_ACP
,0,mixerlineW
.Target
.szPname
,
876 MAXPNAMELEN
,NULL
, NULL
);
877 trace(" %d: \"%s\" (%s) Destination=%d Source=%d\n",
878 s
,szShortName
,szName
,
879 mixerlineW
.dwDestination
,mixerlineW
.dwSource
);
880 trace(" LineID=%08x Channels=%d "
881 "Connections=%d Controls=%d\n",
882 mixerlineW
.dwLineID
,mixerlineW
.cChannels
,
883 mixerlineW
.cConnections
,mixerlineW
.cControls
);
884 trace(" State=0x%08x(%s)\n",
885 mixerlineW
.fdwLine
,line_flags(mixerlineW
.fdwLine
));
886 trace(" ComponentType=%s\n",
887 component_type(mixerlineW
.dwComponentType
));
889 target_type(mixerlineW
.Target
.dwType
));
890 trace(" Device=%d (%s) %d.%d (%d:%d)\n",
891 mixerlineW
.Target
.dwDeviceID
,szPname
,
892 mixerlineW
.Target
.vDriverVersion
>> 8,
893 mixerlineW
.Target
.vDriverVersion
& 0xff,
894 mixerlineW
.Target
.wMid
, mixerlineW
.Target
.wPid
);
896 if (mixerlineW
.cControls
) {
897 array
=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
898 mixerlineW
.cControls
*sizeof(MIXERCONTROLW
));
900 rc
=mixerGetLineControlsW((HMIXEROBJ
)mix
,0,
901 MIXER_GETLINECONTROLSF_ALL
);
902 ok(rc
==MMSYSERR_INVALPARAM
,
903 "mixerGetLineControlsW(MIXER_GETLINECONTROLSF_ALL): "
904 "MMSYSERR_INVALPARAM expected, got %s\n",
906 rc
=mixerGetLineControlsW((HMIXEROBJ
)mix
,&controls
,
908 ok(rc
==MMSYSERR_INVALFLAG
||rc
==MMSYSERR_INVALPARAM
,
909 "mixerGetLineControlsA(-1): "
910 "MMSYSERR_INVALFLAG or MMSYSERR_INVALPARAM expected, got %s\n",
913 controls
.cbStruct
= sizeof(MIXERLINECONTROLSW
);
914 controls
.cControls
= mixerlineW
.cControls
;
915 controls
.dwLineID
= mixerlineW
.dwLineID
;
916 controls
.pamxctrl
= array
;
917 controls
.cbmxctrl
= sizeof(MIXERCONTROLW
);
919 /* FIXME: do MIXER_GETLINECONTROLSF_ONEBYID
920 * and MIXER_GETLINECONTROLSF_ONEBYTYPE
922 rc
=mixerGetLineControlsW((HMIXEROBJ
)mix
,&controls
,
923 MIXER_GETLINECONTROLSF_ALL
);
924 ok(rc
==MMSYSERR_NOERROR
,
925 "mixerGetLineControlsW(MIXER_GETLINECONTROLSF_ALL): "
926 "MMSYSERR_NOERROR expected, got %s\n",
928 if (rc
==MMSYSERR_NOERROR
) {
929 for(nc
=0;nc
<mixerlineW
.cControls
;nc
++) {
930 if (winetest_interactive
) {
931 WideCharToMultiByte(CP_ACP
,0,array
[nc
].szShortName
,
932 MIXER_SHORT_NAME_CHARS
,szShortName
,
933 MIXER_SHORT_NAME_CHARS
,NULL
,NULL
);
934 WideCharToMultiByte(CP_ACP
,0,array
[nc
].szName
,
935 MIXER_LONG_NAME_CHARS
,szName
,
936 MIXER_LONG_NAME_CHARS
,NULL
,NULL
);
937 trace(" %d: \"%s\" (%s) ControlID=%d\n", nc
,
938 szShortName
, szName
, array
[nc
].dwControlID
);
939 trace(" ControlType=%s\n",
940 control_type(array
[nc
].dwControlType
));
941 trace(" Control=0x%08x(%s)\n",
942 array
[nc
].fdwControl
,
943 control_flags(array
[nc
].fdwControl
));
944 trace(" Items=%d Min=%d Max=%d Step=%d\n",
945 array
[nc
].cMultipleItems
,
946 S1(array
[nc
].Bounds
).dwMinimum
,
947 S1(array
[nc
].Bounds
).dwMaximum
,
948 array
[nc
].Metrics
.cSteps
);
950 mixer_test_controlW(mix
, &array
[nc
]);
954 HeapFree(GetProcessHeap(),0,array
);
961 ok(rc
==MMSYSERR_NOERROR
|| rc
==MMSYSERR_INVALHANDLE
,
962 "mixerClose: MMSYSERR_NOERROR or MMSYSERR_INVALHANDLE expected, got %s\n",
967 static void mixer_testsA(void)
974 trace("--- Testing ASCII functions ---\n");
976 ndev
=mixerGetNumDevs();
977 trace("found %d Mixer devices\n",ndev
);
979 rc
=mixerGetDevCapsA(ndev
+1,&capsA
,sizeof(capsA
));
980 ok(rc
==MMSYSERR_BADDEVICEID
,
981 "mixerGetDevCapsA: MMSYSERR_BADDEVICEID expected, got %s\n",
984 rc
=mixerOpen(&mix
, ndev
+1, 0, 0, 0);
985 ok(rc
==MMSYSERR_BADDEVICEID
,
986 "mixerOpen: MMSYSERR_BADDEVICEID expected, got %s\n",
990 mixer_test_deviceA(d
);
993 static void mixer_testsW(void)
1000 trace("--- Testing WCHAR functions ---\n");
1002 ndev
=mixerGetNumDevs();
1003 trace("found %d Mixer devices\n",ndev
);
1005 rc
=mixerGetDevCapsW(ndev
+1,&capsW
,sizeof(capsW
));
1006 ok(rc
==MMSYSERR_BADDEVICEID
||rc
==MMSYSERR_NOTSUPPORTED
,
1007 "mixerGetDevCapsW: MMSYSERR_BADDEVICEID or MMSYSERR_NOTSUPPORTED "
1008 "expected, got %s\n", mmsys_error(rc
));
1009 if (rc
==MMSYSERR_NOTSUPPORTED
)
1012 rc
=mixerOpen(&mix
, ndev
+1, 0, 0, 0);
1013 ok(rc
==MMSYSERR_BADDEVICEID
,
1014 "mixerOpen: MMSYSERR_BADDEVICEID expected, got %s\n",
1017 for (d
=0;d
<ndev
;d
++)
1018 mixer_test_deviceW(d
);