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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * add interactive tests
31 #include "wine/test.h"
37 #include "winmm_test.h"
39 #ifdef NONAMELESSSTRUCT
45 #ifdef NONAMELESSUNION
51 static const char * line_flags(DWORD fdwLine
)
53 static char flags
[100];
56 if (fdwLine
&MIXERLINE_LINEF_ACTIVE
) {
57 strcat(flags
,"MIXERLINE_LINEF_ACTIVE");
60 if (fdwLine
&MIXERLINE_LINEF_DISCONNECTED
) {
64 strcat(flags
,"MIXERLINE_LINEF_DISCONNECTED");
68 if (fdwLine
&MIXERLINE_LINEF_SOURCE
) {
72 strcat(flags
,"MIXERLINE_LINEF_SOURCE");
78 static const char * component_type(DWORD dwComponentType
)
80 #define TYPE_TO_STR(x) case x: return #x
81 switch (dwComponentType
) {
82 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_UNDEFINED
);
83 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_DIGITAL
);
84 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_LINE
);
85 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_MONITOR
);
86 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
);
87 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_HEADPHONES
);
88 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_TELEPHONE
);
89 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_WAVEIN
);
90 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_VOICEIN
);
91 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED
);
92 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_DIGITAL
);
93 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_LINE
);
94 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE
);
95 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER
);
96 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC
);
97 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE
);
98 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER
);
99 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT
);
100 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY
);
101 TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_ANALOG
);
107 static const char * target_type(DWORD dwType
)
109 #define TYPE_TO_STR(x) case x: return #x
111 TYPE_TO_STR(MIXERLINE_TARGETTYPE_UNDEFINED
);
112 TYPE_TO_STR(MIXERLINE_TARGETTYPE_WAVEOUT
);
113 TYPE_TO_STR(MIXERLINE_TARGETTYPE_WAVEIN
);
114 TYPE_TO_STR(MIXERLINE_TARGETTYPE_MIDIOUT
);
115 TYPE_TO_STR(MIXERLINE_TARGETTYPE_MIDIIN
);
116 TYPE_TO_STR(MIXERLINE_TARGETTYPE_AUX
);
122 static const char * control_type(DWORD dwControlType
)
124 #define TYPE_TO_STR(x) case x: return #x
125 switch (dwControlType
) {
126 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_CUSTOM
);
127 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BOOLEANMETER
);
128 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SIGNEDMETER
);
129 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_PEAKMETER
);
130 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER
);
131 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BOOLEAN
);
132 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_ONOFF
);
133 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MUTE
);
134 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MONO
);
135 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_LOUDNESS
);
136 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_STEREOENH
);
137 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BASS_BOOST
);
138 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BUTTON
);
139 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_DECIBELS
);
140 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SIGNED
);
141 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_UNSIGNED
);
142 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_PERCENT
);
143 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SLIDER
);
144 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_PAN
);
145 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_QSOUNDPAN
);
146 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_FADER
);
147 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_VOLUME
);
148 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BASS
);
149 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_TREBLE
);
150 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_EQUALIZER
);
151 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SINGLESELECT
);
152 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MUX
);
153 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT
);
154 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MIXER
);
155 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MICROTIME
);
156 TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MILLITIME
);
162 static const char * control_flags(DWORD fdwControl
)
164 static char flags
[100];
167 if (fdwControl
&MIXERCONTROL_CONTROLF_UNIFORM
) {
168 strcat(flags
,"MIXERCONTROL_CONTROLF_UNIFORM");
171 if (fdwControl
&MIXERCONTROL_CONTROLF_MULTIPLE
) {
175 strcat(flags
,"MIXERCONTROL_CONTROLF_MULTIPLE");
179 if (fdwControl
&MIXERCONTROL_CONTROLF_DISABLED
) {
183 strcat(flags
,"MIXERCONTROL_CONTROLF_DISABLED");
189 static void mixer_test_controlA(HMIXER mix
, LPMIXERCONTROLA control
)
193 if ((control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_VOLUME
) ||
194 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_UNSIGNED
)) {
195 MIXERCONTROLDETAILS details
;
196 MIXERCONTROLDETAILS_UNSIGNED value
;
198 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
199 details
.dwControlID
= control
->dwControlID
;
200 details
.cChannels
= 1;
201 U(details
).cMultipleItems
= 0;
202 details
.paDetails
= &value
;
203 details
.cbDetails
= sizeof(value
);
205 /* read the current control value */
206 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_GETCONTROLDETAILSF_VALUE
);
207 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
208 "MMSYSERR_NOERROR expected, got %s\n",
210 if (rc
==MMSYSERR_NOERROR
) {
211 MIXERCONTROLDETAILS new_details
;
212 MIXERCONTROLDETAILS_UNSIGNED new_value
;
214 if (winetest_interactive
)
215 trace(" Value=%ld\n",value
.dwValue
);
217 if (value
.dwValue
+ control
->Metrics
.cSteps
< S1(control
->Bounds
).dwMaximum
)
218 new_value
.dwValue
= value
.dwValue
+ control
->Metrics
.cSteps
;
220 new_value
.dwValue
= value
.dwValue
- control
->Metrics
.cSteps
;
222 new_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
223 new_details
.dwControlID
= control
->dwControlID
;
224 new_details
.cChannels
= 1;
225 U(new_details
).cMultipleItems
= 0;
226 new_details
.paDetails
= &new_value
;
227 new_details
.cbDetails
= sizeof(new_value
);
229 /* change the control value by one step */
230 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&new_details
,MIXER_SETCONTROLDETAILSF_VALUE
);
231 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
232 "MMSYSERR_NOERROR expected, got %s\n",
234 if (rc
==MMSYSERR_NOERROR
) {
235 MIXERCONTROLDETAILS ret_details
;
236 MIXERCONTROLDETAILS_UNSIGNED ret_value
;
238 ret_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
239 ret_details
.dwControlID
= control
->dwControlID
;
240 ret_details
.cChannels
= 1;
241 U(ret_details
).cMultipleItems
= 0;
242 ret_details
.paDetails
= &ret_value
;
243 ret_details
.cbDetails
= sizeof(ret_value
);
245 /* read back the new control value */
246 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&ret_details
,MIXER_GETCONTROLDETAILSF_VALUE
);
247 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
248 "MMSYSERR_NOERROR expected, got %s\n",
250 if (rc
==MMSYSERR_NOERROR
) {
251 /* result may not match exactly because of rounding */
252 ok(abs(ret_value
.dwValue
-new_value
.dwValue
)<=1,
253 "Couldn't change value from %ld to %ld, returned %ld\n",
254 value
.dwValue
,new_value
.dwValue
,ret_value
.dwValue
);
256 if (abs(ret_value
.dwValue
-new_value
.dwValue
)<=1) {
257 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
258 details
.dwControlID
= control
->dwControlID
;
259 details
.cChannels
= 1;
260 U(details
).cMultipleItems
= 0;
261 details
.paDetails
= &value
;
262 details
.cbDetails
= sizeof(value
);
264 /* restore original value */
265 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_SETCONTROLDETAILSF_VALUE
);
266 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
267 "MMSYSERR_NOERROR expected, got %s\n",
273 } else if ((control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_MUTE
) ||
274 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_BOOLEAN
) ||
275 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_BUTTON
)) {
276 MIXERCONTROLDETAILS details
;
277 MIXERCONTROLDETAILS_BOOLEAN value
;
279 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
280 details
.dwControlID
= control
->dwControlID
;
281 details
.cChannels
= 1;
282 U(details
).cMultipleItems
= 0;
283 details
.paDetails
= &value
;
284 details
.cbDetails
= sizeof(value
);
286 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_GETCONTROLDETAILSF_VALUE
);
287 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
288 "MMSYSERR_NOERROR expected, got %s\n",
290 if (rc
==MMSYSERR_NOERROR
) {
291 MIXERCONTROLDETAILS new_details
;
292 MIXERCONTROLDETAILS_BOOLEAN new_value
;
294 if (winetest_interactive
)
295 trace(" Value=%ld\n",value
.fValue
);
297 if (value
.fValue
== FALSE
)
298 new_value
.fValue
= TRUE
;
300 new_value
.fValue
= FALSE
;
302 new_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
303 new_details
.dwControlID
= control
->dwControlID
;
304 new_details
.cChannels
= 1;
305 U(new_details
).cMultipleItems
= 0;
306 new_details
.paDetails
= &new_value
;
307 new_details
.cbDetails
= sizeof(new_value
);
309 /* change the control value by one step */
310 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&new_details
,MIXER_SETCONTROLDETAILSF_VALUE
);
311 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
312 "MMSYSERR_NOERROR expected, got %s\n",
314 if (rc
==MMSYSERR_NOERROR
) {
315 MIXERCONTROLDETAILS ret_details
;
316 MIXERCONTROLDETAILS_BOOLEAN ret_value
;
318 ret_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
319 ret_details
.dwControlID
= control
->dwControlID
;
320 ret_details
.cChannels
= 1;
321 U(ret_details
).cMultipleItems
= 0;
322 ret_details
.paDetails
= &ret_value
;
323 ret_details
.cbDetails
= sizeof(ret_value
);
325 /* read back the new control value */
326 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&ret_details
,MIXER_GETCONTROLDETAILSF_VALUE
);
327 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
328 "MMSYSERR_NOERROR expected, got %s\n",
330 if (rc
==MMSYSERR_NOERROR
) {
331 /* result may not match exactly because of rounding */
332 ok(ret_value
.fValue
==new_value
.fValue
,
333 "Couldn't change value from %ld to %ld, returned %ld\n",
334 value
.fValue
,new_value
.fValue
,ret_value
.fValue
);
336 if (ret_value
.fValue
==new_value
.fValue
) {
337 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
338 details
.dwControlID
= control
->dwControlID
;
339 details
.cChannels
= 1;
340 U(details
).cMultipleItems
= 0;
341 details
.paDetails
= &value
;
342 details
.cbDetails
= sizeof(value
);
344 /* restore original value */
345 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_SETCONTROLDETAILSF_VALUE
);
346 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
347 "MMSYSERR_NOERROR expected, got %s\n",
358 void mixer_test_deviceA(int device
)
365 rc
=mixerGetDevCapsA(device
,0,sizeof(capsA
));
366 ok(rc
==MMSYSERR_INVALPARAM
,
367 "mixerGetDevCapsA: MMSYSERR_INVALPARAM expected, got %s\n",
370 rc
=mixerGetDevCapsA(device
,&capsA
,4);
371 ok(rc
==MMSYSERR_NOERROR
,
372 "mixerGetDevCapsA: MMSYSERR_NOERROR expected, got %s\n",
375 rc
=mixerGetDevCapsA(device
,&capsA
,sizeof(capsA
));
376 ok(rc
==MMSYSERR_NOERROR
,
377 "mixerGetDevCapsA: MMSYSERR_NOERROR expected, got %s\n",
380 if (winetest_interactive
) {
381 trace(" %d: \"%s\" %d.%d (%d:%d) destinations=%ld\n", device
,
382 capsA
.szPname
, capsA
.vDriverVersion
>> 8,
383 capsA
.vDriverVersion
& 0xff,capsA
.wMid
,capsA
.wPid
,
384 capsA
.cDestinations
);
386 trace(" %d: \"%s\" %d.%d (%d:%d)\n", device
,
387 capsA
.szPname
, capsA
.vDriverVersion
>> 8,
388 capsA
.vDriverVersion
& 0xff,capsA
.wMid
,capsA
.wPid
);
391 rc
=mixerOpen(&mix
, device
, 0, 0, 0);
392 ok(rc
==MMSYSERR_NOERROR
,
393 "mixerOpen: MMSYSERR_BADDEVICEID expected, got %s\n",mmsys_error(rc
));
394 if (rc
==MMSYSERR_NOERROR
) {
395 for (d
=0;d
<capsA
.cDestinations
;d
++) {
396 MIXERLINEA mixerlineA
;
397 mixerlineA
.cbStruct
= 0;
398 mixerlineA
.dwDestination
=d
;
399 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,
400 MIXER_GETLINEINFOF_DESTINATION
);
401 ok(rc
==MMSYSERR_INVALPARAM
,
402 "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
403 "MMSYSERR_INVALPARAM expected, got %s\n",
406 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
407 mixerlineA
.dwDestination
=capsA
.cDestinations
;
408 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,
409 MIXER_GETLINEINFOF_DESTINATION
);
410 ok(rc
==MMSYSERR_INVALPARAM
||rc
==MIXERR_INVALLINE
,
411 "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
412 "MMSYSERR_INVALPARAM or MIXERR_INVALLINE expected, got %s\n",
415 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
416 mixerlineA
.dwDestination
=d
;
417 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,0,
418 MIXER_GETLINEINFOF_DESTINATION
);
419 ok(rc
==MMSYSERR_INVALPARAM
,
420 "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
421 "MMSYSERR_INVALPARAM expected, got %s\n",
424 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
425 mixerlineA
.dwDestination
=d
;
426 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,-1);
427 ok(rc
==MMSYSERR_INVALFLAG
,
428 "mixerGetLineInfoA(-1): MMSYSERR_INVALFLAG expected, got %s\n",
431 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
432 mixerlineA
.dwDestination
=d
;
433 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,
434 MIXER_GETLINEINFOF_DESTINATION
);
435 ok(rc
==MMSYSERR_NOERROR
||rc
==MMSYSERR_NODRIVER
,
436 "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
437 "MMSYSERR_NOERROR expected, got %s\n",
439 if (rc
==MMSYSERR_NODRIVER
)
440 trace(" No Driver\n");
441 else if (rc
==MMSYSERR_NOERROR
&& winetest_interactive
) {
442 trace(" %ld: \"%s\" (%s) Destination=%ld Source=%ld\n",
443 d
,mixerlineA
.szShortName
, mixerlineA
.szName
,
444 mixerlineA
.dwDestination
,mixerlineA
.dwSource
);
445 trace(" LineID=%08lx Channels=%ld "
446 "Connections=%ld Controls=%ld \n",
447 mixerlineA
.dwLineID
,mixerlineA
.cChannels
,
448 mixerlineA
.cConnections
,mixerlineA
.cControls
);
449 trace(" State=0x%08lx(%s)\n",
450 mixerlineA
.fdwLine
,line_flags(mixerlineA
.fdwLine
));
451 trace(" ComponentType=%s\n",
452 component_type(mixerlineA
.dwComponentType
));
454 target_type(mixerlineA
.Target
.dwType
));
455 trace(" Device=%ld (%s) %d.%d (%d:%d)\n",
456 mixerlineA
.Target
.dwDeviceID
,
457 mixerlineA
.Target
.szPname
,
458 mixerlineA
.Target
.vDriverVersion
>> 8,
459 mixerlineA
.Target
.vDriverVersion
& 0xff,
460 mixerlineA
.Target
.wMid
, mixerlineA
.Target
.wPid
);
462 ns
=mixerlineA
.cConnections
;
464 mixerlineA
.cbStruct
= sizeof(mixerlineA
);
465 mixerlineA
.dwDestination
=d
;
466 mixerlineA
.dwSource
=s
;
467 rc
=mixerGetLineInfoA((HMIXEROBJ
)mix
,&mixerlineA
,
468 MIXER_GETLINEINFOF_SOURCE
);
469 ok(rc
==MMSYSERR_NOERROR
||rc
==MMSYSERR_NODRIVER
,
470 "mixerGetLineInfoA(MIXER_GETLINEINFOF_SOURCE): "
471 "MMSYSERR_NOERROR expected, got %s\n",
473 if (rc
==MMSYSERR_NODRIVER
)
474 trace(" No Driver\n");
475 else if (rc
==MMSYSERR_NOERROR
) {
476 LPMIXERCONTROLA array
;
477 MIXERLINECONTROLSA controls
;
478 if (winetest_interactive
) {
479 trace(" %ld: \"%s\" (%s) Destination=%ld Source=%ld\n",
480 s
,mixerlineA
.szShortName
, mixerlineA
.szName
,
481 mixerlineA
.dwDestination
,mixerlineA
.dwSource
);
482 trace(" LineID=%08lx Channels=%ld "
483 "Connections=%ld Controls=%ld \n",
484 mixerlineA
.dwLineID
,mixerlineA
.cChannels
,
485 mixerlineA
.cConnections
,mixerlineA
.cControls
);
486 trace(" State=0x%08lx(%s)\n",
487 mixerlineA
.fdwLine
,line_flags(mixerlineA
.fdwLine
));
488 trace(" ComponentType=%s\n",
489 component_type(mixerlineA
.dwComponentType
));
491 target_type(mixerlineA
.Target
.dwType
));
492 trace(" Device=%ld (%s) %d.%d (%d:%d)\n",
493 mixerlineA
.Target
.dwDeviceID
,
494 mixerlineA
.Target
.szPname
,
495 mixerlineA
.Target
.vDriverVersion
>> 8,
496 mixerlineA
.Target
.vDriverVersion
& 0xff,
497 mixerlineA
.Target
.wMid
, mixerlineA
.Target
.wPid
);
499 if (mixerlineA
.cControls
) {
500 array
=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
501 mixerlineA
.cControls
*sizeof(MIXERCONTROLA
));
503 rc
=mixerGetLineControlsA((HMIXEROBJ
)mix
,0,
504 MIXER_GETLINECONTROLSF_ALL
);
505 ok(rc
==MMSYSERR_INVALPARAM
,
506 "mixerGetLineControlsA(MIXER_GETLINECONTROLSF_ALL): "
507 "MMSYSERR_INVALPARAM expected, got %s\n",
510 rc
=mixerGetLineControlsA((HMIXEROBJ
)mix
,&controls
,-1);
511 ok(rc
==MMSYSERR_INVALFLAG
||rc
==MMSYSERR_INVALPARAM
,
512 "mixerGetLineControlsA(-1): "
513 "MMSYSERR_INVALFLAG or MMSYSERR_INVALPARAM expected, got %s\n",
516 controls
.cbStruct
= sizeof(MIXERLINECONTROLSA
);
517 controls
.cControls
= mixerlineA
.cControls
;
518 controls
.dwLineID
= mixerlineA
.dwLineID
;
519 controls
.pamxctrl
= array
;
520 controls
.cbmxctrl
= sizeof(MIXERCONTROLA
);
522 /* FIXME: do MIXER_GETLINECONTROLSF_ONEBYID
523 * and MIXER_GETLINECONTROLSF_ONEBYTYPE
525 rc
=mixerGetLineControlsA((HMIXEROBJ
)mix
,&controls
,
526 MIXER_GETLINECONTROLSF_ALL
);
527 ok(rc
==MMSYSERR_NOERROR
,
528 "mixerGetLineControlsA(MIXER_GETLINECONTROLSF_ALL): "
529 "MMSYSERR_NOERROR expected, got %s\n",
531 if (rc
==MMSYSERR_NOERROR
) {
532 for(nc
=0;nc
<mixerlineA
.cControls
;nc
++) {
533 if (winetest_interactive
) {
534 trace(" %ld: \"%s\" (%s) ControlID=%ld\n", nc
,
535 array
[nc
].szShortName
,
536 array
[nc
].szName
, array
[nc
].dwControlID
);
537 trace(" ControlType=%s\n",
538 control_type(array
[nc
].dwControlType
));
539 trace(" Control=0x%08lx(%s)\n",
540 array
[nc
].fdwControl
,
541 control_flags(array
[nc
].fdwControl
));
542 trace(" Items=%ld Min=%ld Max=%ld Step=%ld\n",
543 array
[nc
].cMultipleItems
,
544 S1(array
[nc
].Bounds
).dwMinimum
,
545 S1(array
[nc
].Bounds
).dwMaximum
,
546 array
[nc
].Metrics
.cSteps
);
549 mixer_test_controlA(mix
, &array
[nc
]);
553 HeapFree(GetProcessHeap(),0,array
);
560 ok(rc
==MMSYSERR_NOERROR
,
561 "mixerClose: MMSYSERR_BADDEVICEID expected, got %s\n",
566 static void mixer_test_controlW(HMIXER mix
, LPMIXERCONTROLW control
)
570 if ((control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_VOLUME
) ||
571 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_UNSIGNED
)) {
572 MIXERCONTROLDETAILS details
;
573 MIXERCONTROLDETAILS_UNSIGNED value
;
575 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
576 details
.dwControlID
= control
->dwControlID
;
577 details
.cChannels
= 1;
578 U(details
).cMultipleItems
= 0;
579 details
.paDetails
= &value
;
580 details
.cbDetails
= sizeof(value
);
582 /* read the current control value */
583 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_GETCONTROLDETAILSF_VALUE
);
584 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
585 "MMSYSERR_NOERROR expected, got %s\n",
587 if (rc
==MMSYSERR_NOERROR
) {
588 MIXERCONTROLDETAILS new_details
;
589 MIXERCONTROLDETAILS_UNSIGNED new_value
;
591 if (winetest_interactive
)
592 trace(" Value=%ld\n",value
.dwValue
);
594 if (value
.dwValue
+ control
->Metrics
.cSteps
< S1(control
->Bounds
).dwMaximum
)
595 new_value
.dwValue
= value
.dwValue
+ control
->Metrics
.cSteps
;
597 new_value
.dwValue
= value
.dwValue
- control
->Metrics
.cSteps
;
599 new_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
600 new_details
.dwControlID
= control
->dwControlID
;
601 new_details
.cChannels
= 1;
602 U(new_details
).cMultipleItems
= 0;
603 new_details
.paDetails
= &new_value
;
604 new_details
.cbDetails
= sizeof(new_value
);
606 /* change the control value by one step */
607 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&new_details
,MIXER_SETCONTROLDETAILSF_VALUE
);
608 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
609 "MMSYSERR_NOERROR expected, got %s\n",
611 if (rc
==MMSYSERR_NOERROR
) {
612 MIXERCONTROLDETAILS ret_details
;
613 MIXERCONTROLDETAILS_UNSIGNED ret_value
;
615 ret_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
616 ret_details
.dwControlID
= control
->dwControlID
;
617 ret_details
.cChannels
= 1;
618 U(ret_details
).cMultipleItems
= 0;
619 ret_details
.paDetails
= &ret_value
;
620 ret_details
.cbDetails
= sizeof(ret_value
);
622 /* read back the new control value */
623 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&ret_details
,MIXER_GETCONTROLDETAILSF_VALUE
);
624 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
625 "MMSYSERR_NOERROR expected, got %s\n",
627 if (rc
==MMSYSERR_NOERROR
) {
628 /* result may not match exactly because of rounding */
629 ok(abs(ret_value
.dwValue
-new_value
.dwValue
)<=1,
630 "Couldn't change value from %ld to %ld, returned %ld\n",
631 value
.dwValue
,new_value
.dwValue
,ret_value
.dwValue
);
633 if (abs(ret_value
.dwValue
-new_value
.dwValue
)<=1) {
634 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
635 details
.dwControlID
= control
->dwControlID
;
636 details
.cChannels
= 1;
637 U(details
).cMultipleItems
= 0;
638 details
.paDetails
= &value
;
639 details
.cbDetails
= sizeof(value
);
641 /* restore original value */
642 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_SETCONTROLDETAILSF_VALUE
);
643 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
644 "MMSYSERR_NOERROR expected, got %s\n",
650 } else if ((control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_MUTE
) ||
651 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_BOOLEAN
) ||
652 (control
->dwControlType
== MIXERCONTROL_CONTROLTYPE_BUTTON
)) {
653 MIXERCONTROLDETAILS details
;
654 MIXERCONTROLDETAILS_BOOLEAN value
;
656 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
657 details
.dwControlID
= control
->dwControlID
;
658 details
.cChannels
= 1;
659 U(details
).cMultipleItems
= 0;
660 details
.paDetails
= &value
;
661 details
.cbDetails
= sizeof(value
);
663 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_GETCONTROLDETAILSF_VALUE
);
664 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
665 "MMSYSERR_NOERROR expected, got %s\n",
667 if (rc
==MMSYSERR_NOERROR
) {
668 MIXERCONTROLDETAILS new_details
;
669 MIXERCONTROLDETAILS_BOOLEAN new_value
;
671 if (winetest_interactive
)
672 trace(" Value=%ld\n",value
.fValue
);
674 if (value
.fValue
== FALSE
)
675 new_value
.fValue
= TRUE
;
677 new_value
.fValue
= FALSE
;
679 new_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
680 new_details
.dwControlID
= control
->dwControlID
;
681 new_details
.cChannels
= 1;
682 U(new_details
).cMultipleItems
= 0;
683 new_details
.paDetails
= &new_value
;
684 new_details
.cbDetails
= sizeof(new_value
);
686 /* change the control value by one step */
687 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&new_details
,MIXER_SETCONTROLDETAILSF_VALUE
);
688 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
689 "MMSYSERR_NOERROR expected, got %s\n",
691 if (rc
==MMSYSERR_NOERROR
) {
692 MIXERCONTROLDETAILS ret_details
;
693 MIXERCONTROLDETAILS_BOOLEAN ret_value
;
695 ret_details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
696 ret_details
.dwControlID
= control
->dwControlID
;
697 ret_details
.cChannels
= 1;
698 U(ret_details
).cMultipleItems
= 0;
699 ret_details
.paDetails
= &ret_value
;
700 ret_details
.cbDetails
= sizeof(ret_value
);
702 /* read back the new control value */
703 rc
=mixerGetControlDetails((HMIXEROBJ
)mix
,&ret_details
,MIXER_GETCONTROLDETAILSF_VALUE
);
704 ok(rc
==MMSYSERR_NOERROR
,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
705 "MMSYSERR_NOERROR expected, got %s\n",
707 if (rc
==MMSYSERR_NOERROR
) {
708 /* result may not match exactly because of rounding */
709 ok(ret_value
.fValue
==new_value
.fValue
,
710 "Couldn't change value from %ld to %ld, returned %ld\n",
711 value
.fValue
,new_value
.fValue
,ret_value
.fValue
);
713 if (ret_value
.fValue
==new_value
.fValue
) {
714 details
.cbStruct
= sizeof(MIXERCONTROLDETAILS
);
715 details
.dwControlID
= control
->dwControlID
;
716 details
.cChannels
= 1;
717 U(details
).cMultipleItems
= 0;
718 details
.paDetails
= &value
;
719 details
.cbDetails
= sizeof(value
);
721 /* restore original value */
722 rc
=mixerSetControlDetails((HMIXEROBJ
)mix
,&details
,MIXER_SETCONTROLDETAILSF_VALUE
);
723 ok(rc
==MMSYSERR_NOERROR
,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
724 "MMSYSERR_NOERROR expected, got %s\n",
735 void mixer_test_deviceW(int device
)
741 char szShortName
[MIXER_SHORT_NAME_CHARS
];
742 char szName
[MIXER_LONG_NAME_CHARS
];
743 char szPname
[MAXPNAMELEN
];
745 rc
=mixerGetDevCapsW(device
,0,sizeof(capsW
));
746 ok(rc
==MMSYSERR_INVALPARAM
,
747 "mixerGetDevCapsW: MMSYSERR_INVALPARAM expected, got %s\n",
750 rc
=mixerGetDevCapsW(device
,&capsW
,4);
751 ok(rc
==MMSYSERR_NOERROR
,
752 "mixerGetDevCapsW: MMSYSERR_NOERROR expected, got %s\n",
755 rc
=mixerGetDevCapsW(device
,&capsW
,sizeof(capsW
));
756 ok(rc
==MMSYSERR_NOERROR
,
757 "mixerGetDevCapsW: MMSYSERR_NOERROR expected, got %s\n",
760 WideCharToMultiByte(CP_ACP
,0,capsW
.szPname
, MAXPNAMELEN
,szPname
,
761 MAXPNAMELEN
,NULL
,NULL
);
762 if (winetest_interactive
) {
763 trace(" %d: \"%s\" %d.%d (%d:%d) destinations=%ld\n", device
,
764 szPname
, capsW
.vDriverVersion
>> 8,
765 capsW
.vDriverVersion
& 0xff,capsW
.wMid
,capsW
.wPid
,
766 capsW
.cDestinations
);
768 trace(" %d: \"%s\" %d.%d (%d:%d)\n", device
,
769 szPname
, capsW
.vDriverVersion
>> 8,
770 capsW
.vDriverVersion
& 0xff,capsW
.wMid
,capsW
.wPid
);
772 rc
=mixerOpen(&mix
, device
, 0, 0, 0);
773 ok(rc
==MMSYSERR_NOERROR
,
774 "mixerOpen: MMSYSERR_BADDEVICEID expected, got %s\n",mmsys_error(rc
));
775 if (rc
==MMSYSERR_NOERROR
) {
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(" %ld: \"%s\" (%s) Destination=%ld Source=%ld\n",
833 d
,szShortName
,szName
,
834 mixerlineW
.dwDestination
,mixerlineW
.dwSource
);
835 trace(" LineID=%08lx Channels=%ld "
836 "Connections=%ld Controls=%ld \n",
837 mixerlineW
.dwLineID
,mixerlineW
.cChannels
,
838 mixerlineW
.cConnections
,mixerlineW
.cControls
);
839 trace(" State=0x%08lx(%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=%ld (%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(" %ld: \"%s\" (%s) Destination=%ld Source=%ld\n",
878 s
,szShortName
,szName
,
879 mixerlineW
.dwDestination
,mixerlineW
.dwSource
);
880 trace(" LineID=%08lx Channels=%ld "
881 "Connections=%ld Controls=%ld \n",
882 mixerlineW
.dwLineID
,mixerlineW
.cChannels
,
883 mixerlineW
.cConnections
,mixerlineW
.cControls
);
884 trace(" State=0x%08lx(%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=%ld (%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(" %ld: \"%s\" (%s) ControlID=%ld\n", nc
,
938 szShortName
, szName
, array
[nc
].dwControlID
);
939 trace(" ControlType=%s\n",
940 control_type(array
[nc
].dwControlType
));
941 trace(" Control=0x%08lx(%s)\n",
942 array
[nc
].fdwControl
,
943 control_flags(array
[nc
].fdwControl
));
944 trace(" Items=%ld Min=%ld Max=%ld Step=%ld\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
,
962 "mixerClose: MMSYSERR_BADDEVICEID expected, got %s\n",
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
);
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
);