2 * Unit tests for msacm functions
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
26 #include "wine/test.h"
35 static BOOL CALLBACK
FormatTagEnumProc(HACMDRIVERID hadid
,
36 PACMFORMATTAGDETAILSA paftd
,
40 if (winetest_interactive
)
41 trace(" Format 0x%04x: %s\n", paftd
->dwFormatTag
, paftd
->szFormatTag
);
46 static BOOL CALLBACK
FormatEnumProc(HACMDRIVERID hadid
,
47 LPACMFORMATDETAILSA pafd
,
51 if (winetest_interactive
)
52 trace(" 0x%04x, %s\n", pafd
->dwFormatTag
, pafd
->szFormat
);
57 static BOOL CALLBACK
DriverEnumProc(HACMDRIVERID hadid
,
65 DWORD dwDriverPriority
;
66 DWORD dwDriverSupport
;
68 if (winetest_interactive
) {
69 trace("id: %p\n", hadid
);
70 trace(" Supports:\n");
71 if (fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_ASYNC
)
72 trace(" async conversions\n");
73 if (fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_CODEC
)
74 trace(" different format conversions\n");
75 if (fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_CONVERTER
)
76 trace(" same format conversions\n");
77 if (fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_FILTER
)
78 trace(" filtering\n");
81 /* try an invalid pointer */
82 rc
= acmDriverDetailsA(hadid
, 0, 0);
83 ok(rc
== MMSYSERR_INVALPARAM
,
84 "acmDriverDetailsA(): rc = %08x, should be %08x\n",
85 rc
, MMSYSERR_INVALPARAM
);
87 /* try an invalid structure size */
88 ZeroMemory(&dd
, sizeof(dd
));
89 rc
= acmDriverDetailsA(hadid
, &dd
, 0);
90 ok(rc
== MMSYSERR_INVALPARAM
,
91 "acmDriverDetailsA(): rc = %08x, should be %08x\n",
92 rc
, MMSYSERR_INVALPARAM
);
94 /* MSDN says this should fail but it doesn't in practice */
96 rc
= acmDriverDetailsA(hadid
, &dd
, 0);
97 ok(rc
== MMSYSERR_NOERROR
|| rc
== MMSYSERR_NOTSUPPORTED
,
98 "acmDriverDetailsA(): rc = %08x, should be %08x\n",
99 rc
, MMSYSERR_NOERROR
);
101 /* try an invalid handle */
102 dd
.cbStruct
= sizeof(dd
);
103 rc
= acmDriverDetailsA((HACMDRIVERID
)1, &dd
, 0);
104 ok(rc
== MMSYSERR_INVALHANDLE
,
105 "acmDriverDetailsA(): rc = %08x, should be %08x\n",
106 rc
, MMSYSERR_INVALHANDLE
);
108 /* try an invalid handle and pointer */
109 rc
= acmDriverDetailsA((HACMDRIVERID
)1, 0, 0);
110 ok(rc
== MMSYSERR_INVALPARAM
,
111 "acmDriverDetailsA(): rc = %08x, should be %08x\n",
112 rc
, MMSYSERR_INVALPARAM
);
114 /* try invalid details */
115 rc
= acmDriverDetailsA(hadid
, &dd
, -1);
116 ok(rc
== MMSYSERR_INVALFLAG
,
117 "acmDriverDetailsA(): rc = %08x, should be %08x\n",
118 rc
, MMSYSERR_INVALFLAG
);
120 /* try valid parameters */
121 rc
= acmDriverDetailsA(hadid
, &dd
, 0);
122 ok(rc
== MMSYSERR_NOERROR
|| rc
== MMSYSERR_NOTSUPPORTED
,
123 "acmDriverDetailsA(): rc = %08x, should be %08x\n",
124 rc
, MMSYSERR_NOERROR
);
126 /* cbStruct should contain size of returned data (at most sizeof(dd))
127 TODO: should it be *exactly* sizeof(dd), as tested here?
129 if (rc
== MMSYSERR_NOERROR
) {
130 static const struct {
131 const char *shortname
;
135 } *iter
, expected_ids
[] = {
136 { "Microsoft IMA ADPCM", MM_MICROSOFT
, MM_MSFT_ACM_IMAADPCM
},
137 { "MS-ADPCM", MM_MICROSOFT
, MM_MSFT_ACM_MSADPCM
},
138 { "Microsoft CCITT G.711", MM_MICROSOFT
, MM_MSFT_ACM_G711
},
139 { "MPEG Layer-3 Codec", MM_FRAUNHOFER_IIS
, MM_FHGIIS_MPEGLAYER3_DECODE
, MM_FHGIIS_MPEGLAYER3_PROFESSIONAL
},
140 { "MS-PCM", MM_MICROSOFT
, MM_MSFT_ACM_PCM
},
144 ok(dd
.cbStruct
== sizeof(dd
),
145 "acmDriverDetailsA(): cbStruct = %08x\n", dd
.cbStruct
);
147 for (iter
= expected_ids
; iter
->shortname
; ++iter
) {
148 if (!strcmp(iter
->shortname
, dd
.szShortName
)) {
149 /* try alternative product id on mismatch */
150 if (iter
->pid_alt
&& iter
->pid
!= dd
.wPid
)
151 ok(iter
->mid
== dd
.wMid
&& iter
->pid_alt
== dd
.wPid
,
152 "Got wrong manufacturer (0x%x vs 0x%x) or product (0x%x vs 0x%x)\n",
154 dd
.wPid
, iter
->pid_alt
);
156 ok(iter
->mid
== dd
.wMid
&& iter
->pid
== dd
.wPid
,
157 "Got wrong manufacturer (0x%x vs 0x%x) or product (0x%x vs 0x%x)\n",
164 if (rc
== MMSYSERR_NOERROR
&& winetest_interactive
) {
165 trace(" Short name: %s\n", dd
.szShortName
);
166 trace(" Long name: %s\n", dd
.szLongName
);
167 trace(" Copyright: %s\n", dd
.szCopyright
);
168 trace(" Licensing: %s\n", dd
.szLicensing
);
169 trace(" Features: %s\n", dd
.szFeatures
);
170 trace(" Supports %u formats\n", dd
.cFormatTags
);
171 trace(" Supports %u filter formats\n", dd
.cFilterTags
);
172 trace(" Mid: 0x%x\n", dd
.wMid
);
173 trace(" Pid: 0x%x\n", dd
.wPid
);
176 /* try bad pointer */
177 rc
= acmMetrics((HACMOBJ
)hadid
, ACM_METRIC_DRIVER_PRIORITY
, 0);
178 ok(rc
== MMSYSERR_INVALPARAM
,
179 "acmMetrics(): rc = %08x, should be %08x\n",
180 rc
, MMSYSERR_INVALPARAM
);
183 rc
= acmMetrics((HACMOBJ
)1, ACM_METRIC_DRIVER_PRIORITY
, &dwDriverPriority
);
184 ok(rc
== MMSYSERR_INVALHANDLE
,
185 "acmMetrics(): rc = %08x, should be %08x\n",
186 rc
, MMSYSERR_INVALHANDLE
);
188 /* try bad pointer and handle */
189 rc
= acmMetrics((HACMOBJ
)1, ACM_METRIC_DRIVER_PRIORITY
, 0);
190 ok(rc
== MMSYSERR_INVALHANDLE
,
191 "acmMetrics(): rc = %08x, should be %08x\n",
192 rc
, MMSYSERR_INVALHANDLE
);
194 /* try valid parameters */
195 rc
= acmMetrics((HACMOBJ
)hadid
, ACM_METRIC_DRIVER_PRIORITY
, &dwDriverSupport
);
196 ok(rc
== MMSYSERR_NOERROR
,
197 "acmMetrics(): rc = %08x, should be %08x\n",
198 rc
, MMSYSERR_NOERROR
);
200 /* try bad pointer */
201 rc
= acmMetrics((HACMOBJ
)hadid
, ACM_METRIC_DRIVER_SUPPORT
, 0);
202 ok(rc
== MMSYSERR_INVALPARAM
,
203 "acmMetrics(): rc = %08x, should be %08x\n",
204 rc
, MMSYSERR_INVALPARAM
);
207 rc
= acmMetrics((HACMOBJ
)1, ACM_METRIC_DRIVER_SUPPORT
, &dwDriverSupport
);
208 ok(rc
== MMSYSERR_INVALHANDLE
,
209 "acmMetrics(): rc = %08x, should be %08x\n",
210 rc
, MMSYSERR_INVALHANDLE
);
212 /* try bad pointer and handle */
213 rc
= acmMetrics((HACMOBJ
)1, ACM_METRIC_DRIVER_SUPPORT
, 0);
214 ok(rc
== MMSYSERR_INVALHANDLE
,
215 "acmMetrics(): rc = %08x, should be %08x\n",
216 rc
, MMSYSERR_INVALHANDLE
);
218 /* try valid parameters */
219 rc
= acmMetrics((HACMOBJ
)hadid
, ACM_METRIC_DRIVER_SUPPORT
, &dwDriverSupport
);
220 ok(rc
== MMSYSERR_NOERROR
,
221 "acmMetrics(): rc = %08x, should be %08x\n",
222 rc
, MMSYSERR_NOERROR
);
224 /* try invalid pointer */
225 rc
= acmDriverOpen(0, hadid
, 0);
226 ok(rc
== MMSYSERR_INVALPARAM
,
227 "acmDriverOpen(): rc = %08x, should be %08x\n",
228 rc
, MMSYSERR_INVALPARAM
);
230 /* try invalid handle */
231 rc
= acmDriverOpen(&had
, (HACMDRIVERID
)1, 0);
232 ok(rc
== MMSYSERR_INVALHANDLE
,
233 "acmDriverOpen(): rc = %08x, should be %08x\n",
234 rc
, MMSYSERR_INVALHANDLE
);
236 /* try invalid open */
237 rc
= acmDriverOpen(&had
, hadid
, -1);
238 ok(rc
== MMSYSERR_INVALFLAG
,
239 "acmDriverOpen(): rc = %08x, should be %08x\n",
240 rc
, MMSYSERR_INVALFLAG
);
242 /* try valid parameters */
243 rc
= acmDriverOpen(&had
, hadid
, 0);
244 ok(rc
== MMSYSERR_NOERROR
|| rc
== MMSYSERR_NODRIVER
,
245 "acmDriverOpen(): rc = %08x, should be %08x\n",
246 rc
, MMSYSERR_NOERROR
);
248 if (rc
== MMSYSERR_NOERROR
) {
252 /* try bad pointer */
253 rc
= acmDriverID((HACMOBJ
)had
, 0, 0);
254 ok(rc
== MMSYSERR_INVALPARAM
,
255 "acmDriverID(): rc = %08x, should be %08x\n",
256 rc
, MMSYSERR_INVALPARAM
);
259 rc
= acmDriverID((HACMOBJ
)1, &hid
, 0);
260 ok(rc
== MMSYSERR_INVALHANDLE
,
261 "acmDriverID(): rc = %08x, should be %08x\n",
262 rc
, MMSYSERR_INVALHANDLE
);
264 /* try bad handle and pointer */
265 rc
= acmDriverID((HACMOBJ
)1, 0, 0);
266 ok(rc
== MMSYSERR_INVALHANDLE
,
267 "acmDriverID(): rc = %08x, should be %08x\n",
268 rc
, MMSYSERR_INVALHANDLE
);
271 rc
= acmDriverID((HACMOBJ
)had
, &hid
, 1);
272 ok(rc
== MMSYSERR_INVALFLAG
,
273 "acmDriverID(): rc = %08x, should be %08x\n",
274 rc
, MMSYSERR_INVALFLAG
);
276 /* try valid parameters */
277 rc
= acmDriverID((HACMOBJ
)had
, &hid
, 0);
278 ok(rc
== MMSYSERR_NOERROR
,
279 "acmDriverID(): rc = %08x, should be %08x\n",
280 rc
, MMSYSERR_NOERROR
);
282 "acmDriverID() returned ID %p doesn't equal %p\n",
285 /* try bad pointer */
286 rc
= acmMetrics((HACMOBJ
)had
, ACM_METRIC_MAX_SIZE_FORMAT
, 0);
287 ok(rc
== MMSYSERR_INVALPARAM
,
288 "acmMetrics(): rc = %08x, should be %08x\n",
289 rc
, MMSYSERR_INVALPARAM
);
292 rc
= acmMetrics((HACMOBJ
)1, ACM_METRIC_MAX_SIZE_FORMAT
, &dwSize
);
293 ok(rc
== MMSYSERR_INVALHANDLE
,
294 "acmMetrics(): rc = %08x, should be %08x\n",
295 rc
, MMSYSERR_INVALHANDLE
);
297 /* try bad pointer and handle */
298 rc
= acmMetrics((HACMOBJ
)1, ACM_METRIC_MAX_SIZE_FORMAT
, 0);
299 ok(rc
== MMSYSERR_INVALHANDLE
,
300 "acmMetrics(): rc = %08x, should be %08x\n",
301 rc
, MMSYSERR_INVALHANDLE
);
303 /* try valid parameters */
304 rc
= acmMetrics((HACMOBJ
)had
, ACM_METRIC_MAX_SIZE_FORMAT
, &dwSize
);
305 ok(rc
== MMSYSERR_NOERROR
,
306 "acmMetrics(): rc = %08x, should be %08x\n",
307 rc
, MMSYSERR_NOERROR
);
308 if (rc
== MMSYSERR_NOERROR
) {
309 ACMFORMATDETAILSA fd
;
311 ACMFORMATTAGDETAILSA aftd
;
313 /* try bad pointer */
314 rc
= acmFormatEnumA(had
, 0, FormatEnumProc
, 0, 0);
315 ok(rc
== MMSYSERR_INVALPARAM
,
316 "acmFormatEnumA(): rc = %08x, should be %08x\n",
317 rc
, MMSYSERR_INVALPARAM
);
319 /* try bad structure size */
320 ZeroMemory(&fd
, sizeof(fd
));
321 rc
= acmFormatEnumA(had
, &fd
, FormatEnumProc
, 0, 0);
322 ok(rc
== MMSYSERR_INVALPARAM
,
323 "acmFormatEnumA(): rc = %08x, should be %08x\n",
324 rc
, MMSYSERR_INVALPARAM
);
326 fd
.cbStruct
= sizeof(fd
) - 1;
327 rc
= acmFormatEnumA(had
, &fd
, FormatEnumProc
, 0, 0);
328 ok(rc
== MMSYSERR_INVALPARAM
,
329 "acmFormatEnumA(): rc = %08x, should be %08x\n",
330 rc
, MMSYSERR_INVALPARAM
);
332 if (dwSize
< sizeof(WAVEFORMATEX
))
333 dwSize
= sizeof(WAVEFORMATEX
);
335 pwfx
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwSize
);
337 pwfx
->cbSize
= LOWORD(dwSize
) - sizeof(WAVEFORMATEX
);
338 pwfx
->wFormatTag
= WAVE_FORMAT_UNKNOWN
;
340 fd
.cbStruct
= sizeof(fd
);
343 fd
.dwFormatTag
= WAVE_FORMAT_UNKNOWN
;
345 /* try valid parameters */
346 rc
= acmFormatEnumA(had
, &fd
, FormatEnumProc
, 0, 0);
347 ok(rc
== MMSYSERR_NOERROR
,
348 "acmFormatEnumA(): rc = %08x, should be %08x\n",
349 rc
, MMSYSERR_NOERROR
);
351 /* try bad pointer */
352 rc
= acmFormatTagEnumA(had
, 0, FormatTagEnumProc
, 0, 0);
353 ok(rc
== MMSYSERR_INVALPARAM
,
354 "acmFormatTagEnumA(): rc = %08x, should be %08x\n",
355 rc
, MMSYSERR_INVALPARAM
);
357 /* try bad structure size */
358 ZeroMemory(&aftd
, sizeof(aftd
));
359 rc
= acmFormatTagEnumA(had
, &aftd
, FormatTagEnumProc
, 0, 0);
360 ok(rc
== MMSYSERR_INVALPARAM
,
361 "acmFormatTagEnumA(): rc = %08x, should be %08x\n",
362 rc
, MMSYSERR_INVALPARAM
);
364 aftd
.cbStruct
= sizeof(aftd
) - 1;
365 rc
= acmFormatTagEnumA(had
, &aftd
, FormatTagEnumProc
, 0, 0);
366 ok(rc
== MMSYSERR_INVALPARAM
,
367 "acmFormatTagEnumA(): rc = %08x, should be %08x\n",
368 rc
, MMSYSERR_INVALPARAM
);
370 aftd
.cbStruct
= sizeof(aftd
);
371 aftd
.dwFormatTag
= WAVE_FORMAT_UNKNOWN
;
374 rc
= acmFormatTagEnumA(had
, &aftd
, FormatTagEnumProc
, 0, 1);
375 ok(rc
== MMSYSERR_INVALFLAG
,
376 "acmFormatTagEnumA(): rc = %08x, should be %08x\n",
377 rc
, MMSYSERR_INVALFLAG
);
379 /* try valid parameters */
380 rc
= acmFormatTagEnumA(had
, &aftd
, FormatTagEnumProc
, 0, 0);
381 ok(rc
== MMSYSERR_NOERROR
,
382 "acmFormatTagEnumA(): rc = %08x, should be %08x\n",
383 rc
, MMSYSERR_NOERROR
);
385 HeapFree(GetProcessHeap(), 0, pwfx
);
387 /* try invalid handle */
388 rc
= acmDriverClose((HACMDRIVER
)1, 0);
389 ok(rc
== MMSYSERR_INVALHANDLE
,
390 "acmDriverClose(): rc = %08x, should be %08x\n",
391 rc
, MMSYSERR_INVALHANDLE
);
393 /* try invalid flag */
394 rc
= acmDriverClose(had
, 1);
395 ok(rc
== MMSYSERR_INVALFLAG
,
396 "acmDriverClose(): rc = %08x, should be %08x\n",
397 rc
, MMSYSERR_INVALFLAG
);
399 /* try valid parameters */
400 rc
= acmDriverClose(had
, 0);
401 ok(rc
== MMSYSERR_NOERROR
,
402 "acmDriverClose(): rc = %08x, should be %08x\n",
403 rc
, MMSYSERR_NOERROR
);
405 /* try closing again */
406 rc
= acmDriverClose(had
, 0);
407 ok(rc
== MMSYSERR_INVALHANDLE
,
408 "acmDriverClose(): rc = %08x, should be %08x\n",
409 rc
, MMSYSERR_INVALHANDLE
);
416 static const char * get_metric(UINT uMetric
)
419 case ACM_METRIC_COUNT_CODECS
:
420 return "ACM_METRIC_COUNT_CODECS";
421 case ACM_METRIC_COUNT_CONVERTERS
:
422 return "ACM_METRIC_COUNT_CONVERTERS";
423 case ACM_METRIC_COUNT_DISABLED
:
424 return "ACM_METRIC_COUNT_DISABLED";
425 case ACM_METRIC_COUNT_DRIVERS
:
426 return "ACM_METRIC_COUNT_DRIVERS";
427 case ACM_METRIC_COUNT_FILTERS
:
428 return "ACM_METRIC_COUNT_FILTERS";
429 case ACM_METRIC_COUNT_HARDWARE
:
430 return "ACM_METRIC_COUNT_HARDWARE";
431 case ACM_METRIC_COUNT_LOCAL_CODECS
:
432 return "ACM_METRIC_COUNT_LOCAL_CODECS";
433 case ACM_METRIC_COUNT_LOCAL_CONVERTERS
:
434 return "ACM_METRIC_COUNT_LOCAL_CONVERTERS";
435 case ACM_METRIC_COUNT_LOCAL_DISABLED
:
436 return "ACM_METRIC_COUNT_LOCAL_DISABLED";
437 case ACM_METRIC_COUNT_LOCAL_DRIVERS
:
438 return "ACM_METRIC_COUNT_LOCAL_DRIVERS";
439 case ACM_METRIC_COUNT_LOCAL_FILTERS
:
440 return "ACM_METRIC_COUNT_LOCAL_FILTERS";
441 case ACM_METRIC_DRIVER_PRIORITY
:
442 return "ACM_METRIC_DRIVER_PRIORITY";
443 case ACM_METRIC_DRIVER_SUPPORT
:
444 return "ACM_METRIC_DRIVER_SUPPORT";
445 case ACM_METRIC_HARDWARE_WAVE_INPUT
:
446 return "ACM_METRIC_HARDWARE_WAVE_INPUT";
447 case ACM_METRIC_HARDWARE_WAVE_OUTPUT
:
448 return "ACM_METRIC_HARDWARE_WAVE_OUTPUT";
449 case ACM_METRIC_MAX_SIZE_FILTER
:
450 return "ACM_METRIC_MAX_SIZE_FILTER";
451 case ACM_METRIC_MAX_SIZE_FORMAT
:
452 return "ACM_METRIC_MAX_SIZE_FORMAT";
458 static void check_count(UINT uMetric
)
463 /* try invalid result pointer */
464 rc
= acmMetrics(NULL
, uMetric
, 0);
465 ok(rc
== MMSYSERR_INVALPARAM
,
466 "acmMetrics(NULL, %s, 0): rc = 0x%08x, should be 0x%08x\n",
467 get_metric(uMetric
), rc
, MMSYSERR_INVALPARAM
);
469 /* try invalid handle */
470 rc
= acmMetrics((HACMOBJ
)1, uMetric
, &dwMetric
);
471 ok(rc
== MMSYSERR_INVALHANDLE
,
472 "acmMetrics(1, %s, %p): rc = 0x%08x, should be 0x%08x\n",
473 get_metric(uMetric
), &dwMetric
, rc
, MMSYSERR_INVALHANDLE
);
475 /* try invalid result pointer and handle */
476 rc
= acmMetrics((HACMOBJ
)1, uMetric
, 0);
477 ok(rc
== MMSYSERR_INVALHANDLE
,
478 "acmMetrics(1, %s, 0): rc = 0x%08x, should be 0x%08x\n",
479 get_metric(uMetric
), rc
, MMSYSERR_INVALHANDLE
);
481 /* try valid parameters */
482 rc
= acmMetrics(NULL
, uMetric
, &dwMetric
);
483 ok(rc
== MMSYSERR_NOERROR
, "acmMetrics() failed: rc = 0x%08x\n", rc
);
485 if (rc
== MMSYSERR_NOERROR
&& winetest_interactive
)
486 trace("%s: %u\n", get_metric(uMetric
), dwMetric
);
489 static void driver_tests(void)
492 DWORD dwACMVersion
= acmGetVersion();
494 if (winetest_interactive
) {
495 trace("ACM version = %u.%02u build %u%s\n",
496 HIWORD(dwACMVersion
) >> 8,
497 HIWORD(dwACMVersion
) & 0xff,
498 LOWORD(dwACMVersion
),
499 LOWORD(dwACMVersion
) == 0 ? " (Retail)" : "");
502 check_count(ACM_METRIC_COUNT_CODECS
);
503 check_count(ACM_METRIC_COUNT_CONVERTERS
);
504 check_count(ACM_METRIC_COUNT_DISABLED
);
505 check_count(ACM_METRIC_COUNT_DRIVERS
);
506 check_count(ACM_METRIC_COUNT_FILTERS
);
507 check_count(ACM_METRIC_COUNT_HARDWARE
);
508 check_count(ACM_METRIC_COUNT_LOCAL_CODECS
);
509 check_count(ACM_METRIC_COUNT_LOCAL_CONVERTERS
);
510 check_count(ACM_METRIC_COUNT_LOCAL_DISABLED
);
511 check_count(ACM_METRIC_COUNT_LOCAL_DRIVERS
);
512 check_count(ACM_METRIC_COUNT_LOCAL_FILTERS
);
514 if (winetest_interactive
)
515 trace("enabled drivers:\n");
517 rc
= acmDriverEnum(DriverEnumProc
, 0, 0);
518 ok(rc
== MMSYSERR_NOERROR
,
519 "acmDriverEnum() failed, rc=%08x, should be 0x%08x\n",
520 rc
, MMSYSERR_NOERROR
);
523 static void test_prepareheader(void)
526 ADPCMWAVEFORMAT
*src
;
530 BYTE buf
[sizeof(WAVEFORMATEX
) + 32], pcm
[512], input
[512];
533 src
= (ADPCMWAVEFORMAT
*)buf
;
535 src
->wfx
.cbSize
= 32;
536 src
->wfx
.wFormatTag
= WAVE_FORMAT_ADPCM
;
537 src
->wfx
.nSamplesPerSec
= 22050;
538 src
->wfx
.wBitsPerSample
= 4;
539 src
->wfx
.nChannels
= 1;
540 src
->wfx
.nBlockAlign
= 512;
541 src
->wfx
.nAvgBytesPerSec
= 11025;
542 src
->wSamplesPerBlock
= 0x3f4;
544 coef
[0].iCoef1
= 0x0100;
545 coef
[0].iCoef2
= 0x0000;
546 coef
[1].iCoef1
= 0x0200;
547 coef
[1].iCoef2
= 0xff00;
548 coef
[2].iCoef1
= 0x0000;
549 coef
[2].iCoef2
= 0x0000;
550 coef
[3].iCoef1
= 0x00c0;
551 coef
[3].iCoef2
= 0x0040;
552 coef
[4].iCoef1
= 0x00f0;
553 coef
[4].iCoef2
= 0x0000;
554 coef
[5].iCoef1
= 0x01cc;
555 coef
[5].iCoef2
= 0xff30;
556 coef
[6].iCoef1
= 0x0188;
557 coef
[6].iCoef2
= 0xff18;
560 dst
.wFormatTag
= WAVE_FORMAT_PCM
;
561 dst
.nSamplesPerSec
= 22050;
562 dst
.wBitsPerSample
= 8;
564 dst
.nBlockAlign
= dst
.wBitsPerSample
* dst
.nChannels
/ 8;
565 dst
.nAvgBytesPerSec
= dst
.nSamplesPerSec
* dst
.nBlockAlign
;
567 mr
= acmStreamOpen(&has
, NULL
, (WAVEFORMATEX
*)src
, &dst
, NULL
, 0, 0, 0);
568 ok(mr
== MMSYSERR_NOERROR
, "open failed: 0x%x\n", mr
);
570 memset(&hdr
, 0, sizeof(hdr
));
571 hdr
.cbStruct
= sizeof(hdr
);
573 hdr
.cbSrcLength
= sizeof(input
);
575 hdr
.cbDstLength
= sizeof(pcm
);
577 mr
= acmStreamPrepareHeader(has
, &hdr
, 0);
578 ok(mr
== MMSYSERR_NOERROR
, "prepare failed: 0x%x\n", mr
);
579 ok(hdr
.fdwStatus
== ACMSTREAMHEADER_STATUSF_PREPARED
, "header wasn't prepared: 0x%x\n", hdr
.fdwStatus
);
581 mr
= acmStreamUnprepareHeader(has
, &hdr
, 0);
582 ok(mr
== MMSYSERR_NOERROR
, "unprepare failed: 0x%x\n", mr
);
583 ok(hdr
.fdwStatus
== 0, "header wasn't unprepared: 0x%x\n", hdr
.fdwStatus
);
585 memset(&hdr
, 0, sizeof(hdr
));
586 hdr
.cbStruct
= sizeof(hdr
);
588 hdr
.cbSrcLength
= sizeof(input
);
590 hdr
.cbDstLength
= sizeof(pcm
);
591 hdr
.fdwStatus
= ACMSTREAMHEADER_STATUSF_DONE
;
593 mr
= acmStreamPrepareHeader(has
, &hdr
, 0);
594 ok(mr
== MMSYSERR_NOERROR
, "prepare failed: 0x%x\n", mr
);
595 ok(hdr
.fdwStatus
== (ACMSTREAMHEADER_STATUSF_PREPARED
| ACMSTREAMHEADER_STATUSF_DONE
), "header wasn't prepared: 0x%x\n", hdr
.fdwStatus
);
597 mr
= acmStreamUnprepareHeader(has
, &hdr
, 0);
598 ok(mr
== MMSYSERR_NOERROR
, "unprepare failed: 0x%x\n", mr
);
599 ok(hdr
.fdwStatus
== ACMSTREAMHEADER_STATUSF_DONE
, "header wasn't unprepared: 0x%x\n", hdr
.fdwStatus
);
601 mr
= acmStreamClose(has
, 0);
602 ok(mr
== MMSYSERR_NOERROR
, "close failed: 0x%x\n", mr
);
605 static void test_acmFormatSuggest(void)
607 WAVEFORMATEX src
, dst
;
611 /* Test a valid PCM format */
612 src
.wFormatTag
= WAVE_FORMAT_PCM
;
614 src
.nSamplesPerSec
= 8000;
615 src
.nAvgBytesPerSec
= 16000;
617 src
.wBitsPerSample
= 16;
620 memset(&dst
, 0, sizeof(dst
));
621 rc
= acmFormatSuggest(NULL
, &src
, &dst
, sizeof(dst
), suggest
);
622 ok(rc
== MMSYSERR_NOERROR
, "failed with error 0x%x\n", rc
);
624 ok(src
.wFormatTag
== dst
.wFormatTag
, "expected %d, got %d\n", src
.wFormatTag
, dst
.wFormatTag
);
625 ok(src
.nChannels
== dst
.nChannels
, "expected %d, got %d\n", src
.nChannels
, dst
.nChannels
);
626 ok(src
.nSamplesPerSec
== dst
.nSamplesPerSec
, "expected %d, got %d\n", src
.nSamplesPerSec
, dst
.nSamplesPerSec
);
628 ok(src
.nAvgBytesPerSec
== dst
.nAvgBytesPerSec
, "expected %d, got %d\n", src
.nAvgBytesPerSec
, dst
.nAvgBytesPerSec
);
630 ok(src
.nBlockAlign
== dst
.nBlockAlign
, "expected %d, got %d\n", src
.nBlockAlign
, dst
.nBlockAlign
);
632 ok(src
.wBitsPerSample
== dst
.wBitsPerSample
, "expected %d, got %d\n", src
.wBitsPerSample
, dst
.wBitsPerSample
);
634 /* All parameters from destination are valid */
635 suggest
= ACM_FORMATSUGGESTF_NCHANNELS
636 | ACM_FORMATSUGGESTF_NSAMPLESPERSEC
637 | ACM_FORMATSUGGESTF_WBITSPERSAMPLE
638 | ACM_FORMATSUGGESTF_WFORMATTAG
;
640 rc
= acmFormatSuggest(NULL
, &src
, &dst
, sizeof(dst
), suggest
);
641 ok(rc
== MMSYSERR_NOERROR
, "failed with error 0x%x\n", rc
);
642 ok(src
.wFormatTag
== dst
.wFormatTag
, "expected %d, got %d\n", src
.wFormatTag
, dst
.wFormatTag
);
643 ok(src
.nChannels
== dst
.nChannels
, "expected %d, got %d\n", src
.nChannels
, dst
.nChannels
);
644 ok(src
.nSamplesPerSec
== dst
.nSamplesPerSec
, "expected %d, got %d\n", src
.nSamplesPerSec
, dst
.nSamplesPerSec
);
645 ok(src
.nAvgBytesPerSec
== dst
.nAvgBytesPerSec
, "expected %d, got %d\n", src
.nAvgBytesPerSec
, dst
.nAvgBytesPerSec
);
646 ok(src
.nBlockAlign
== dst
.nBlockAlign
, "expected %d, got %d\n", src
.nBlockAlign
, dst
.nBlockAlign
);
647 ok(src
.wBitsPerSample
== dst
.wBitsPerSample
, "expected %d, got %d\n", src
.wBitsPerSample
, dst
.wBitsPerSample
);
649 /* Test for WAVE_FORMAT_MSRT24 used in Monster Truck Madness 2 */
650 src
.wFormatTag
= WAVE_FORMAT_MSRT24
;
652 src
.nSamplesPerSec
= 8000;
653 src
.nAvgBytesPerSec
= 16000;
655 src
.wBitsPerSample
= 16;
658 suggest
= ACM_FORMATSUGGESTF_NCHANNELS
659 | ACM_FORMATSUGGESTF_NSAMPLESPERSEC
660 | ACM_FORMATSUGGESTF_WBITSPERSAMPLE
661 | ACM_FORMATSUGGESTF_WFORMATTAG
;
662 rc
= acmFormatSuggest(NULL
, &src
, &dst
, sizeof(dst
), suggest
);
663 ok(rc
== ACMERR_NOTPOSSIBLE
, "failed with error 0x%x\n", rc
);
664 memset(&dst
, 0, sizeof(dst
));
666 rc
= acmFormatSuggest(NULL
, &src
, &dst
, sizeof(dst
), suggest
);
668 ok(rc
== MMSYSERR_INVALPARAM
, "failed with error 0x%x\n", rc
);
670 /* Invalid struct size */
671 src
.wFormatTag
= WAVE_FORMAT_PCM
;
672 rc
= acmFormatSuggest(NULL
, &src
, &dst
, 0, suggest
);
674 ok(rc
== MMSYSERR_INVALPARAM
, "failed with error 0x%x\n", rc
);
675 rc
= acmFormatSuggest(NULL
, &src
, &dst
, sizeof(dst
) / 2, suggest
);
677 ok(rc
== MMSYSERR_INVALPARAM
, "failed with error 0x%x\n", rc
);
678 /* cbSize is the last parameter and not required for PCM */
679 rc
= acmFormatSuggest(NULL
, &src
, &dst
, sizeof(dst
) - 1, suggest
);
680 ok(rc
== MMSYSERR_NOERROR
, "failed with error 0x%x\n", rc
);
681 rc
= acmFormatSuggest(NULL
, &src
, &dst
, sizeof(dst
) - sizeof(dst
.cbSize
), suggest
);
682 ok(rc
== MMSYSERR_NOERROR
, "failed with error 0x%x\n", rc
);
683 rc
= acmFormatSuggest(NULL
, &src
, &dst
, sizeof(dst
) - sizeof(dst
.cbSize
) - 1, suggest
);
685 ok(rc
== MMSYSERR_INVALPARAM
, "failed with error 0x%x\n", rc
);
686 /* cbSize is required for others */
687 src
.wFormatTag
= WAVE_FORMAT_ADPCM
;
688 rc
= acmFormatSuggest(NULL
, &src
, &dst
, sizeof(dst
) - sizeof(dst
.cbSize
), suggest
);
690 ok(rc
== MMSYSERR_INVALPARAM
, "failed with error 0x%x\n", rc
);
691 rc
= acmFormatSuggest(NULL
, &src
, &dst
, sizeof(dst
) - 1, suggest
);
693 ok(rc
== MMSYSERR_INVALPARAM
, "failed with error 0x%x\n", rc
);
695 /* Invalid suggest flags */
696 src
.wFormatTag
= WAVE_FORMAT_PCM
;
697 suggest
= 0xFFFFFFFF;
698 rc
= acmFormatSuggest(NULL
, &src
, &dst
, sizeof(dst
), suggest
);
699 ok(rc
== MMSYSERR_INVALFLAG
, "failed with error 0x%x\n", rc
);
701 /* Invalid source and destination */
703 rc
= acmFormatSuggest(NULL
, NULL
, &dst
, sizeof(dst
), suggest
);
704 ok(rc
== MMSYSERR_INVALPARAM
, "failed with error 0x%x\n", rc
);
705 rc
= acmFormatSuggest(NULL
, &src
, NULL
, sizeof(dst
), suggest
);
706 ok(rc
== MMSYSERR_INVALPARAM
, "failed with error 0x%x\n", rc
);
707 rc
= acmFormatSuggest(NULL
, NULL
, NULL
, sizeof(dst
), suggest
);
708 ok(rc
== MMSYSERR_INVALPARAM
, "failed with error 0x%x\n", rc
);
714 test_prepareheader();
715 test_acmFormatSuggest();