ReactOS  0.4.14-dev-52-g6116262
msacm.c
Go to the documentation of this file.
1 /*
2  * Unit tests for msacm functions
3  *
4  * Copyright (c) 2004 Robert Reif
5  *
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.
10  *
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.
15  *
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
19  */
20 
21 #include <stdarg.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <math.h>
25 
26 #include "wine/test.h"
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winnls.h"
30 #include "mmsystem.h"
31 #define NOBITMAP
32 #include "mmreg.h"
33 #include "msacm.h"
34 #include "wine/msacmdrv.h"
35 
36 static BOOL CALLBACK FormatTagEnumProc(HACMDRIVERID hadid,
38  DWORD_PTR dwInstance,
39  DWORD fdwSupport)
40 {
41  MMRESULT rc;
42  HACMDRIVER had;
43 
45  trace(" Format 0x%04x: %s\n", paftd->dwFormatTag, paftd->szFormatTag);
46 
47  rc = acmDriverOpen(&had, hadid, 0);
48  ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NODRIVER,
49  "acmDriverOpen(): rc = %08x, should be %08x\n",
50  rc, MMSYSERR_NOERROR);
51 
52  if (rc == MMSYSERR_NOERROR)
53  {
54  ACMFORMATDETAILSA fd = {0};
55  WAVEFORMATEX *pwfx, dst;
56  ACMFORMATTAGDETAILSA aftd_pcm = {0};
57  DWORD dwSize, dwSizeMax;
58  DWORD i;
59 
60  fd.cbStruct = sizeof(fd);
61  if (paftd->cbFormatSize < sizeof(WAVEFORMATEX))
63  else
65  fd.pwfx = pwfx;
66  fd.cbwfx = paftd->cbFormatSize;
67  fd.dwFormatTag = paftd->dwFormatTag;
68 
69  /* try bad pwfx */
70  fd.pwfx = NULL;
72  ok(rc == MMSYSERR_INVALPARAM,
73  "acmFormatDetailsA(): rc = %08x, should be %08x\n",
75  fd.pwfx = pwfx;
76 
77  /* try bad wFormatTag */
78  fd.pwfx->wFormatTag = WAVE_FORMAT_UNKNOWN;
80  ok(rc == MMSYSERR_INVALPARAM,
81  "acmFormatDetailsA(): rc = %08x, should be %08x\n",
83  fd.pwfx->wFormatTag = paftd->dwFormatTag;
84 
85  /* try bad fdwSupport */
86  fd.fdwSupport = 0xdeadbeef;
88  ok(rc == MMSYSERR_INVALPARAM,
89  "acmFormatDetailsA(): rc = %08x, should be %08x\n",
91  fd.fdwSupport = 0;
92 
93  /* try bad pwfx structure size */
94  fd.cbwfx = sizeof(PCMWAVEFORMAT)-1;
96  ok(rc == MMSYSERR_INVALPARAM,
97  "acmFormatDetailsA(): rc = %08x, should be %08x\n",
99  fd.cbwfx = paftd->cbFormatSize;
100 
101  /* test bad parameters (all zero) */
103  ok(rc == ACMERR_NOTPOSSIBLE,
104  "acmFormatDetailsA(): rc = %08x, should be %08x\n",
105  rc, ACMERR_NOTPOSSIBLE);
106 
107  /* test acmFormatSuggest */
108 
109  /* if we don't specify a format, we must give at least the driver's maximum size for any format */
111  rc = acmFormatSuggest(had, pwfx, &dst, dwSize-1, 0);
112  ok(rc == MMSYSERR_INVALPARAM,
113  "acmFormatSuggest(): rc = %08x, should be %08x\n",
114  rc, MMSYSERR_INVALPARAM);
115 
116  rc = acmFormatSuggest(had, pwfx, &dst, dwSize, 0);
117  ok(rc == ACMERR_NOTPOSSIBLE,
118  "acmFormatSuggest(): rc = %08x, should be %08x\n",
119  rc, ACMERR_NOTPOSSIBLE);
120 
121  /* if we do specify a format, we must give at least the driver's maximum size for that format */
122  aftd_pcm.cbStruct = sizeof(aftd_pcm);
123  aftd_pcm.dwFormatTag = WAVE_FORMAT_PCM;
125  ok(rc == MMSYSERR_NOERROR, "returned %08x\n", rc);
126 
127  dst.wFormatTag = WAVE_FORMAT_PCM;
128  rc = acmFormatSuggest(had, pwfx, &dst, aftd_pcm.cbFormatSize-1, ACM_FORMATSUGGESTF_WFORMATTAG);
129  ok(rc == MMSYSERR_INVALPARAM,
130  "acmFormatSuggest(): rc = %08x, should be %08x\n",
131  rc, MMSYSERR_INVALPARAM);
132 
133  rc = acmFormatSuggest(had, pwfx, &dst, aftd_pcm.cbFormatSize, ACM_FORMATSUGGESTF_WFORMATTAG);
134  ok(rc == ACMERR_NOTPOSSIBLE,
135  "acmFormatSuggest(): rc = %08x, should be %08x\n",
136  rc, ACMERR_NOTPOSSIBLE);
137 
138  /* test nonexistent format */
139  dst.wFormatTag = 0xbeef;
140  rc = acmFormatSuggest(had, pwfx, &dst, 0, ACM_FORMATSUGGESTF_WFORMATTAG);
142  "acmFormatSuggest(): rc = %08x, should be %08x\n",
143  rc, ACMERR_NOTPOSSIBLE);
144 
145  /* if the driver is NULL, we must give at least the maximum size for any driver */
147  rc = acmFormatSuggest(NULL, pwfx, &dst, dwSizeMax-1, 0);
148  ok(rc == MMSYSERR_INVALPARAM,
149  "acmFormatSuggest(): rc = %08x, should be %08x\n",
150  rc, MMSYSERR_INVALPARAM);
151 
152  if (paftd->dwFormatTag != WAVE_FORMAT_PCM)
153  {
154  rc = acmFormatSuggest(NULL, pwfx, &dst, dwSizeMax, 0);
155  ok(rc == ACMERR_NOTPOSSIBLE,
156  "acmFormatSuggest(): rc = %08x, should be %08x\n",
157  rc, ACMERR_NOTPOSSIBLE);
158  }
159 
160  /* if we specify a dst format, we must give the maximum size for that format */
161  dst.wFormatTag = WAVE_FORMAT_PCM;
163  ok(rc == MMSYSERR_INVALPARAM || broken (rc == ACMERR_NOTPOSSIBLE), /* WinXP */
164  "acmFormatSuggest(): rc = %08x, should be %08x\n",
165  rc, MMSYSERR_INVALPARAM);
166 
168  ok(rc == ACMERR_NOTPOSSIBLE,
169  "acmFormatSuggest(): rc = %08x, should be %08x\n",
170  rc, ACMERR_NOTPOSSIBLE);
171 
172  dst.wFormatTag = paftd->dwFormatTag;
174  ok(rc == MMSYSERR_INVALPARAM || broken (rc == ACMERR_NOTPOSSIBLE), /* WinXP */
175  "acmFormatSuggest(): rc = %08x, should be %08x\n",
176  rc, MMSYSERR_INVALPARAM);
177 
179  ok(rc == ACMERR_NOTPOSSIBLE,
180  "acmFormatSuggest(): rc = %08x, should be %08x\n",
181  rc, ACMERR_NOTPOSSIBLE);
182 
183  /* test nonexistent format */
184  dst.wFormatTag = 0xbeef;
187  "acmFormatSuggest(): rc = %08x, should be %08x\n",
188  rc, ACMERR_NOTPOSSIBLE);
189 
190  /* test index */
191  for (i = 0; i < paftd->cStandardFormats; i++)
192  {
193  fd.dwFormatIndex = i;
194 
195  fd.fdwSupport = 0;
196  fd.cbwfx = paftd->cbFormatSize;
197  fd.pwfx->cbSize = 0xbeef;
199  ok(rc == MMSYSERR_NOERROR,
200  "acmFormatDetailsA(): rc = %08x, should be %08x\n",
201  rc, MMSYSERR_NOERROR);
202 
203  /* Windows will write cbSize (and other data) even if the
204  * given cbwfx is not large enough */
205  fd.fdwSupport = 0;
206  fd.cbwfx = sizeof(PCMWAVEFORMAT);
207  fd.pwfx->cbSize = 0xbeef;
209  todo_wine_if(rc != MMSYSERR_NOERROR) /* remove when fixed */
210  ok(rc == MMSYSERR_NOERROR,
211  "acmFormatDetailsA(): rc = %08x, should be %08x\n",
212  rc, MMSYSERR_NOERROR);
213  if (paftd->dwFormatTag != WAVE_FORMAT_PCM)
214  todo_wine_if(fd.pwfx->cbSize != paftd->cbFormatSize - sizeof(WAVEFORMATEX)) /* remove when fixed */
215  ok(fd.pwfx->cbSize == paftd->cbFormatSize - sizeof(WAVEFORMATEX),
216  "got %d\n", fd.pwfx->cbSize);
217  }
218 
219  /* one more */
220  fd.dwFormatIndex = paftd->cStandardFormats;
221  fd.fdwSupport = 0;
223  ok(rc == MMSYSERR_INVALPARAM,
224  "acmFormatDetailsA(): rc = %08x, should be %08x\n",
225  rc, MMSYSERR_INVALPARAM);
226 
227  HeapFree(GetProcessHeap(), 0, pwfx);
228  }
229  return TRUE;
230 }
231 
232 static BOOL CALLBACK FormatEnumProc(HACMDRIVERID hadid,
233  LPACMFORMATDETAILSA pafd,
234  DWORD_PTR dwInstance,
235  DWORD fd)
236 {
237  MMRESULT rc;
238  HACMDRIVER had;
239  WAVEFORMATEX *dst, *dstMax;
240  DWORD dwSize, dwSizeMax;
241  DWORD fdwSupport;
242 
243  acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_SUPPORT, &fdwSupport);
244 
246  trace(" 0x%04x, %s\n", pafd->dwFormatTag, pafd->szFormat);
247 
248  acmDriverOpen(&had, hadid, 0);
249  dwSize = pafd->cbwfx;
251 
252  /* test acmFormatSuggest with valid src format */
253  if (pafd->dwFormatTag == WAVE_FORMAT_PCM)
254  {
255  rc = acmFormatSuggest(had, pafd->pwfx, dst, dwSize, 0);
256  /* this fails on some decode-only drivers */
257  ok(rc == MMSYSERR_NOERROR || rc == ACMERR_NOTPOSSIBLE,
258  "acmFormatSuggest(): rc = %08x, should be %08x\n",
259  rc, MMSYSERR_NOERROR);
260  if (rc == MMSYSERR_NOERROR)
261  {
262  if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC) /* supports different conversions */
263  ok(dst->wFormatTag != WAVE_FORMAT_PCM, "expected different format\n");
264  else
265  ok(dst->wFormatTag == WAVE_FORMAT_PCM,
266  "expected %d, got %d\n", WAVE_FORMAT_PCM, dst->wFormatTag);
267  }
268  }
269  else
270  {
271  rc = acmFormatSuggest(had, pafd->pwfx, dst, dwSize, 0);
272  ok(rc == MMSYSERR_NOERROR,
273  "acmFormatSuggest(): rc = %08x, should be %08x\n",
274  rc, MMSYSERR_NOERROR);
275  ok(dst->wFormatTag == WAVE_FORMAT_PCM,
276  "expected %d, got %d\n", WAVE_FORMAT_PCM, dst->wFormatTag);
277  ok(dst->nChannels == pafd->pwfx->nChannels,
278  "expected %d, got %d\n", pafd->pwfx->nChannels, dst->nChannels);
279  if (pafd->dwFormatTag != 0x42) /* codec 0x0042 returns a different sample rate */
280  ok(dst->nSamplesPerSec == pafd->pwfx->nSamplesPerSec,
281  "expected %d, got %d\n", pafd->pwfx->nSamplesPerSec, dst->nSamplesPerSec);
282  ok(dst->wBitsPerSample == 16,
283  "expected %d, got %d\n", 16, dst->wBitsPerSample);
284  ok(dst->nBlockAlign == 2*pafd->pwfx->nChannels,
285  "expected %d, got %d\n", 2*pafd->pwfx->nChannels, dst->nBlockAlign);
286 
287  /* test with NULL driver */
289  dstMax = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSizeMax);
290  rc = acmFormatSuggest(NULL, pafd->pwfx, dstMax, dwSizeMax, 0);
291  ok(rc == MMSYSERR_NOERROR,
292  "acmFormatSuggest(): rc = %08x, should be %08x\n",
293  rc, MMSYSERR_NOERROR);
294 
295  HeapFree(GetProcessHeap(), 0, dstMax);
296  }
297 
299  dst->wFormatTag = pafd->pwfx->wFormatTag;
301  if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CONVERTER) /* supports same conversions */
302  ok(rc == MMSYSERR_NOERROR,
303  "acmFormatSuggest(): rc = %08x, should be %08x\n",
304  rc, MMSYSERR_NOERROR);
305  else
307  ok(rc == ACMERR_NOTPOSSIBLE,
308  "acmFormatSuggest(): rc = %08x, should be %08x\n",
309  rc, ACMERR_NOTPOSSIBLE);
310 
311  HeapFree(GetProcessHeap(), 0, dst);
312  acmDriverClose(had, 0);
313 
314  return TRUE;
315 }
316 
317 static BOOL CALLBACK DriverEnumProc(HACMDRIVERID hadid,
318  DWORD_PTR dwInstance,
319  DWORD fdwSupport)
320 {
321  MMRESULT rc;
323  HACMDRIVER had;
324 
325  DWORD dwDriverPriority;
326  DWORD dwDriverSupport;
327 
328  if (winetest_interactive) {
329  trace("id: %p\n", hadid);
330  trace(" Supports:\n");
331  if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_ASYNC)
332  trace(" async conversions\n");
333  if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC)
334  trace(" different format conversions\n");
335  if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CONVERTER)
336  trace(" same format conversions\n");
337  if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_FILTER)
338  trace(" filtering\n");
339  }
340 
341  /* try an invalid pointer */
342  rc = acmDriverDetailsA(hadid, 0, 0);
343  ok(rc == MMSYSERR_INVALPARAM,
344  "acmDriverDetailsA(): rc = %08x, should be %08x\n",
345  rc, MMSYSERR_INVALPARAM);
346 
347  /* try an invalid structure size */
348  ZeroMemory(&dd, sizeof(dd));
349  rc = acmDriverDetailsA(hadid, &dd, 0);
350  ok(rc == MMSYSERR_INVALPARAM,
351  "acmDriverDetailsA(): rc = %08x, should be %08x\n",
352  rc, MMSYSERR_INVALPARAM);
353 
354  /* MSDN says this should fail but it doesn't in practice */
355  dd.cbStruct = 4;
356  rc = acmDriverDetailsA(hadid, &dd, 0);
358  "acmDriverDetailsA(): rc = %08x, should be %08x\n",
359  rc, MMSYSERR_NOERROR);
360 
361  /* try an invalid handle */
362  dd.cbStruct = sizeof(dd);
363  rc = acmDriverDetailsA((HACMDRIVERID)1, &dd, 0);
364  ok(rc == MMSYSERR_INVALHANDLE,
365  "acmDriverDetailsA(): rc = %08x, should be %08x\n",
367 
368  /* try an invalid handle and pointer */
369  rc = acmDriverDetailsA((HACMDRIVERID)1, 0, 0);
370  ok(rc == MMSYSERR_INVALPARAM,
371  "acmDriverDetailsA(): rc = %08x, should be %08x\n",
372  rc, MMSYSERR_INVALPARAM);
373 
374  /* try invalid details */
375  rc = acmDriverDetailsA(hadid, &dd, -1);
376  ok(rc == MMSYSERR_INVALFLAG,
377  "acmDriverDetailsA(): rc = %08x, should be %08x\n",
378  rc, MMSYSERR_INVALFLAG);
379 
380  /* try valid parameters */
381  rc = acmDriverDetailsA(hadid, &dd, 0);
383  "acmDriverDetailsA(): rc = %08x, should be %08x\n",
384  rc, MMSYSERR_NOERROR);
385 
386  /* cbStruct should contain size of returned data (at most sizeof(dd))
387  TODO: should it be *exactly* sizeof(dd), as tested here?
388  */
389  if (rc == MMSYSERR_NOERROR) {
390  static const struct {
391  const char *shortname;
392  WORD mid;
393  WORD pid;
394  WORD pid_alt;
395  } *iter, expected_ids[] = {
396  { "Microsoft IMA ADPCM", MM_MICROSOFT, MM_MSFT_ACM_IMAADPCM },
397  { "MS-ADPCM", MM_MICROSOFT, MM_MSFT_ACM_MSADPCM },
398  { "Microsoft CCITT G.711", MM_MICROSOFT, MM_MSFT_ACM_G711},
400  { "MS-PCM", MM_MICROSOFT, MM_MSFT_ACM_PCM },
401  { 0 }
402  };
403 
404  ok(dd.cbStruct == sizeof(dd),
405  "acmDriverDetailsA(): cbStruct = %08x\n", dd.cbStruct);
406 
407  for (iter = expected_ids; iter->shortname; ++iter) {
408  if (!strcmp(iter->shortname, dd.szShortName)) {
409  /* try alternative product id on mismatch */
410  if (iter->pid_alt && iter->pid != dd.wPid)
411  ok(iter->mid == dd.wMid && iter->pid_alt == dd.wPid,
412  "Got wrong manufacturer (0x%x vs 0x%x) or product (0x%x vs 0x%x)\n",
413  dd.wMid, iter->mid,
414  dd.wPid, iter->pid_alt);
415  else
416  ok(iter->mid == dd.wMid && iter->pid == dd.wPid,
417  "Got wrong manufacturer (0x%x vs 0x%x) or product (0x%x vs 0x%x)\n",
418  dd.wMid, iter->mid,
419  dd.wPid, iter->pid);
420  }
421  }
422  }
423 
424  if (rc == MMSYSERR_NOERROR && winetest_interactive) {
425  trace(" Short name: %s\n", dd.szShortName);
426  trace(" Long name: %s\n", dd.szLongName);
427  trace(" Copyright: %s\n", dd.szCopyright);
428  trace(" Licensing: %s\n", dd.szLicensing);
429  trace(" Features: %s\n", dd.szFeatures);
430  trace(" Supports %u formats\n", dd.cFormatTags);
431  trace(" Supports %u filter formats\n", dd.cFilterTags);
432  trace(" Mid: 0x%x\n", dd.wMid);
433  trace(" Pid: 0x%x\n", dd.wPid);
434  }
435 
436  /* try bad pointer */
437  rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_PRIORITY, 0);
438  ok(rc == MMSYSERR_INVALPARAM,
439  "acmMetrics(): rc = %08x, should be %08x\n",
440  rc, MMSYSERR_INVALPARAM);
441 
442  /* try bad handle */
443  rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_PRIORITY, &dwDriverPriority);
444  ok(rc == MMSYSERR_INVALHANDLE,
445  "acmMetrics(): rc = %08x, should be %08x\n",
447 
448  /* try bad pointer and handle */
449  rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_PRIORITY, 0);
450  ok(rc == MMSYSERR_INVALHANDLE,
451  "acmMetrics(): rc = %08x, should be %08x\n",
453 
454  /* try valid parameters */
455  rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_PRIORITY, &dwDriverSupport);
456  ok(rc == MMSYSERR_NOERROR,
457  "acmMetrics(): rc = %08x, should be %08x\n",
458  rc, MMSYSERR_NOERROR);
459 
460  /* try bad pointer */
461  rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_SUPPORT, 0);
462  ok(rc == MMSYSERR_INVALPARAM,
463  "acmMetrics(): rc = %08x, should be %08x\n",
464  rc, MMSYSERR_INVALPARAM);
465 
466  /* try bad handle */
467  rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_SUPPORT, &dwDriverSupport);
468  ok(rc == MMSYSERR_INVALHANDLE,
469  "acmMetrics(): rc = %08x, should be %08x\n",
471 
472  /* try bad pointer and handle */
473  rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_SUPPORT, 0);
474  ok(rc == MMSYSERR_INVALHANDLE,
475  "acmMetrics(): rc = %08x, should be %08x\n",
477 
478  /* try valid parameters */
479  rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_SUPPORT, &dwDriverSupport);
480  ok(rc == MMSYSERR_NOERROR,
481  "acmMetrics(): rc = %08x, should be %08x\n",
482  rc, MMSYSERR_NOERROR);
483 
484  /* try invalid pointer */
485  rc = acmDriverOpen(0, hadid, 0);
486  ok(rc == MMSYSERR_INVALPARAM,
487  "acmDriverOpen(): rc = %08x, should be %08x\n",
488  rc, MMSYSERR_INVALPARAM);
489 
490  /* try invalid handle */
491  rc = acmDriverOpen(&had, (HACMDRIVERID)1, 0);
492  ok(rc == MMSYSERR_INVALHANDLE,
493  "acmDriverOpen(): rc = %08x, should be %08x\n",
495 
496  /* try invalid open */
497  rc = acmDriverOpen(&had, hadid, -1);
498  ok(rc == MMSYSERR_INVALFLAG,
499  "acmDriverOpen(): rc = %08x, should be %08x\n",
500  rc, MMSYSERR_INVALFLAG);
501 
502  /* try valid parameters */
503  rc = acmDriverOpen(&had, hadid, 0);
504  ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NODRIVER,
505  "acmDriverOpen(): rc = %08x, should be %08x\n",
506  rc, MMSYSERR_NOERROR);
507 
508  if (rc == MMSYSERR_NOERROR) {
509  DWORD dwSize;
510  HACMDRIVERID hid;
511 
512  /* try bad pointer */
513  rc = acmDriverID((HACMOBJ)had, 0, 0);
514  ok(rc == MMSYSERR_INVALPARAM,
515  "acmDriverID(): rc = %08x, should be %08x\n",
516  rc, MMSYSERR_INVALPARAM);
517 
518  /* try bad handle */
519  rc = acmDriverID((HACMOBJ)1, &hid, 0);
520  ok(rc == MMSYSERR_INVALHANDLE,
521  "acmDriverID(): rc = %08x, should be %08x\n",
523 
524  /* try bad handle and pointer */
525  rc = acmDriverID((HACMOBJ)1, 0, 0);
526  ok(rc == MMSYSERR_INVALHANDLE,
527  "acmDriverID(): rc = %08x, should be %08x\n",
529 
530  /* try bad flag */
531  rc = acmDriverID((HACMOBJ)had, &hid, 1);
532  ok(rc == MMSYSERR_INVALFLAG,
533  "acmDriverID(): rc = %08x, should be %08x\n",
534  rc, MMSYSERR_INVALFLAG);
535 
536  /* try valid parameters */
537  rc = acmDriverID((HACMOBJ)had, &hid, 0);
538  ok(rc == MMSYSERR_NOERROR,
539  "acmDriverID(): rc = %08x, should be %08x\n",
540  rc, MMSYSERR_NOERROR);
541  ok(hid == hadid,
542  "acmDriverID() returned ID %p doesn't equal %p\n",
543  hid, hadid);
544 
545  /* try bad pointer */
546  rc = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, 0);
547  ok(rc == MMSYSERR_INVALPARAM,
548  "acmMetrics(): rc = %08x, should be %08x\n",
549  rc, MMSYSERR_INVALPARAM);
550 
551  /* try bad handle */
552  rc = acmMetrics((HACMOBJ)1, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize);
553  ok(rc == MMSYSERR_INVALHANDLE,
554  "acmMetrics(): rc = %08x, should be %08x\n",
556 
557  /* try bad pointer and handle */
558  rc = acmMetrics((HACMOBJ)1, ACM_METRIC_MAX_SIZE_FORMAT, 0);
559  ok(rc == MMSYSERR_INVALHANDLE,
560  "acmMetrics(): rc = %08x, should be %08x\n",
562 
563  /* try valid parameters */
564  rc = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize);
565  ok(rc == MMSYSERR_NOERROR,
566  "acmMetrics(): rc = %08x, should be %08x\n",
567  rc, MMSYSERR_NOERROR);
568  if (rc == MMSYSERR_NOERROR) {
570  WAVEFORMATEX * pwfx;
572 
573  /* try bad pointer */
574  rc = acmFormatEnumA(had, 0, FormatEnumProc, 0, 0);
575  ok(rc == MMSYSERR_INVALPARAM,
576  "acmFormatEnumA(): rc = %08x, should be %08x\n",
577  rc, MMSYSERR_INVALPARAM);
578 
579  /* try bad structure size */
580  ZeroMemory(&fd, sizeof(fd));
581  rc = acmFormatEnumA(had, &fd, FormatEnumProc, 0, 0);
582  ok(rc == MMSYSERR_INVALPARAM,
583  "acmFormatEnumA(): rc = %08x, should be %08x\n",
584  rc, MMSYSERR_INVALPARAM);
585 
586  fd.cbStruct = sizeof(fd) - 1;
587  rc = acmFormatEnumA(had, &fd, FormatEnumProc, 0, 0);
588  ok(rc == MMSYSERR_INVALPARAM,
589  "acmFormatEnumA(): rc = %08x, should be %08x\n",
590  rc, MMSYSERR_INVALPARAM);
591 
593 
594  if (dwSize >= sizeof(WAVEFORMATEX))
595  pwfx->cbSize = LOWORD(dwSize) - sizeof(WAVEFORMATEX);
597 
598  fd.cbStruct = sizeof(fd);
599  fd.pwfx = pwfx;
600  fd.cbwfx = dwSize;
601  fd.dwFormatTag = WAVE_FORMAT_UNKNOWN;
602 
603  /* try bad callback */
604  rc = acmFormatEnumA(had, &fd, NULL, 0, 0);
605  ok(rc == MMSYSERR_INVALPARAM,
606  "acmFormatEnumA(): rc = %08x, should be %08x\n",
607  rc, MMSYSERR_INVALPARAM);
608 
609  /* try bad pwfx */
610  fd.pwfx = NULL;
611  rc = acmFormatEnumA(had, &fd, FormatEnumProc, 0, 0);
612  ok(rc == MMSYSERR_INVALPARAM,
613  "acmFormatEnumA(): rc = %08x, should be %08x\n",
614  rc, MMSYSERR_INVALPARAM);
615  fd.pwfx = pwfx;
616 
617  /* fdwSupport must be zero */
618  fd.fdwSupport = 0xdeadbeef;
619  rc = acmFormatEnumA(had, &fd, FormatEnumProc, 0, 0);
620  ok(rc == MMSYSERR_INVALPARAM,
621  "acmFormatEnumA(): rc = %08x, should be %08x\n",
622  rc, MMSYSERR_INVALPARAM);
623  fd.fdwSupport = 0;
624 
625  /* try bad pwfx structure size */
626  fd.cbwfx = dwSize-1;
627  rc = acmFormatEnumA(had, &fd, FormatEnumProc, 0, 0);
628  ok(rc == MMSYSERR_INVALPARAM,
629  "acmFormatEnumA(): rc = %08x, should be %08x\n",
630  rc, MMSYSERR_INVALPARAM);
631  fd.cbwfx = dwSize;
632 
633  /* try valid parameters */
634  rc = acmFormatEnumA(had, &fd, FormatEnumProc, 0, 0);
635  ok(rc == MMSYSERR_NOERROR,
636  "acmFormatEnumA(): rc = %08x, should be %08x\n",
637  rc, MMSYSERR_NOERROR);
638 
639  /* try bad pointer */
640  rc = acmFormatTagEnumA(had, 0, FormatTagEnumProc, 0, 0);
641  ok(rc == MMSYSERR_INVALPARAM,
642  "acmFormatTagEnumA(): rc = %08x, should be %08x\n",
643  rc, MMSYSERR_INVALPARAM);
644 
645  /* try bad structure size */
646  ZeroMemory(&aftd, sizeof(aftd));
647  rc = acmFormatTagEnumA(had, &aftd, FormatTagEnumProc, 0, 0);
648  ok(rc == MMSYSERR_INVALPARAM,
649  "acmFormatTagEnumA(): rc = %08x, should be %08x\n",
650  rc, MMSYSERR_INVALPARAM);
651 
652  aftd.cbStruct = sizeof(aftd) - 1;
653  rc = acmFormatTagEnumA(had, &aftd, FormatTagEnumProc, 0, 0);
654  ok(rc == MMSYSERR_INVALPARAM,
655  "acmFormatTagEnumA(): rc = %08x, should be %08x\n",
656  rc, MMSYSERR_INVALPARAM);
657 
658  aftd.cbStruct = sizeof(aftd);
660 
661  /* try bad flag */
662  rc = acmFormatTagEnumA(had, &aftd, FormatTagEnumProc, 0, 1);
663  ok(rc == MMSYSERR_INVALFLAG,
664  "acmFormatTagEnumA(): rc = %08x, should be %08x\n",
665  rc, MMSYSERR_INVALFLAG);
666 
667  /* try valid parameters */
668  rc = acmFormatTagEnumA(had, &aftd, FormatTagEnumProc, 0, 0);
669  ok(rc == MMSYSERR_NOERROR,
670  "acmFormatTagEnumA(): rc = %08x, should be %08x\n",
671  rc, MMSYSERR_NOERROR);
672 
673  /* try bad pointer */
675  ok(rc == MMSYSERR_INVALPARAM,
676  "acmFormatDetailsA(): rc = %08x, should be %08x\n",
677  rc, MMSYSERR_INVALPARAM);
678 
679  /* try bad structure size */
680  ZeroMemory(&fd, sizeof(fd));
682  ok(rc == MMSYSERR_INVALPARAM,
683  "acmFormatDetailsA(): rc = %08x, should be %08x\n",
684  rc, MMSYSERR_INVALPARAM);
685 
686  fd.cbStruct = sizeof(fd) - 1;
688  ok(rc == MMSYSERR_INVALPARAM,
689  "acmFormatDetailsA(): rc = %08x, should be %08x\n",
690  rc, MMSYSERR_INVALPARAM);
691 
692  fd.cbStruct = sizeof(fd);
693  fd.pwfx = pwfx;
694  ZeroMemory(fd.pwfx, dwSize);
695  fd.cbwfx = dwSize;
696  fd.dwFormatTag = WAVE_FORMAT_UNKNOWN;
697 
698  /* try WAVE_FORMAT_UNKNOWN */
700  ok(rc == MMSYSERR_INVALPARAM,
701  "acmFormatDetailsA(): rc = %08x, should be %08x\n",
702  rc, MMSYSERR_INVALPARAM);
703 
704  HeapFree(GetProcessHeap(), 0, pwfx);
705 
706  /* try invalid handle */
707  rc = acmDriverClose((HACMDRIVER)1, 0);
708  ok(rc == MMSYSERR_INVALHANDLE,
709  "acmDriverClose(): rc = %08x, should be %08x\n",
711 
712  /* try invalid flag */
713  rc = acmDriverClose(had, 1);
714  ok(rc == MMSYSERR_INVALFLAG,
715  "acmDriverClose(): rc = %08x, should be %08x\n",
716  rc, MMSYSERR_INVALFLAG);
717 
718  /* try valid parameters */
719  rc = acmDriverClose(had, 0);
720  ok(rc == MMSYSERR_NOERROR,
721  "acmDriverClose(): rc = %08x, should be %08x\n",
722  rc, MMSYSERR_NOERROR);
723 
724  /* try closing again */
725  rc = acmDriverClose(had, 0);
726  ok(rc == MMSYSERR_INVALHANDLE,
727  "acmDriverClose(): rc = %08x, should be %08x\n",
729  }
730  }
731 
732  return TRUE;
733 }
734 
735 static const char * get_metric(UINT uMetric)
736 {
737  switch (uMetric) {
739  return "ACM_METRIC_COUNT_CODECS";
741  return "ACM_METRIC_COUNT_CONVERTERS";
743  return "ACM_METRIC_COUNT_DISABLED";
745  return "ACM_METRIC_COUNT_DRIVERS";
747  return "ACM_METRIC_COUNT_FILTERS";
749  return "ACM_METRIC_COUNT_HARDWARE";
751  return "ACM_METRIC_COUNT_LOCAL_CODECS";
753  return "ACM_METRIC_COUNT_LOCAL_CONVERTERS";
755  return "ACM_METRIC_COUNT_LOCAL_DISABLED";
757  return "ACM_METRIC_COUNT_LOCAL_DRIVERS";
759  return "ACM_METRIC_COUNT_LOCAL_FILTERS";
761  return "ACM_METRIC_DRIVER_PRIORITY";
763  return "ACM_METRIC_DRIVER_SUPPORT";
765  return "ACM_METRIC_HARDWARE_WAVE_INPUT";
767  return "ACM_METRIC_HARDWARE_WAVE_OUTPUT";
769  return "ACM_METRIC_MAX_SIZE_FILTER";
771  return "ACM_METRIC_MAX_SIZE_FORMAT";
772  }
773 
774  return "UNKNOWN";
775 }
776 
777 static void check_count(UINT uMetric)
778 {
779  DWORD dwMetric;
780  MMRESULT rc;
781 
782  /* try invalid result pointer */
783  rc = acmMetrics(NULL, uMetric, 0);
784  ok(rc == MMSYSERR_INVALPARAM,
785  "acmMetrics(NULL, %s, 0): rc = 0x%08x, should be 0x%08x\n",
786  get_metric(uMetric), rc, MMSYSERR_INVALPARAM);
787 
788  /* try invalid handle */
789  rc = acmMetrics((HACMOBJ)1, uMetric, &dwMetric);
790  ok(rc == MMSYSERR_INVALHANDLE,
791  "acmMetrics(1, %s, %p): rc = 0x%08x, should be 0x%08x\n",
792  get_metric(uMetric), &dwMetric, rc, MMSYSERR_INVALHANDLE);
793 
794  /* try invalid result pointer and handle */
795  rc = acmMetrics((HACMOBJ)1, uMetric, 0);
796  ok(rc == MMSYSERR_INVALHANDLE,
797  "acmMetrics(1, %s, 0): rc = 0x%08x, should be 0x%08x\n",
798  get_metric(uMetric), rc, MMSYSERR_INVALHANDLE);
799 
800  /* try valid parameters */
801  rc = acmMetrics(NULL, uMetric, &dwMetric);
802  ok(rc == MMSYSERR_NOERROR, "acmMetrics() failed: rc = 0x%08x\n", rc);
803 
805  trace("%s: %u\n", get_metric(uMetric), dwMetric);
806 }
807 
808 static void driver_tests(void)
809 {
810  MMRESULT rc;
811  DWORD dwACMVersion = acmGetVersion();
812 
813  if (winetest_interactive) {
814  trace("ACM version = %u.%02u build %u%s\n",
815  HIWORD(dwACMVersion) >> 8,
816  HIWORD(dwACMVersion) & 0xff,
817  LOWORD(dwACMVersion),
818  LOWORD(dwACMVersion) == 0 ? " (Retail)" : "");
819  }
820 
832 
834  trace("enabled drivers:\n");
835 
836  rc = acmDriverEnum(DriverEnumProc, 0, 0);
837  ok(rc == MMSYSERR_NOERROR,
838  "acmDriverEnum() failed, rc=%08x, should be 0x%08x\n",
839  rc, MMSYSERR_NOERROR);
840 }
841 
842 static void test_prepareheader(void)
843 {
844  HACMSTREAM has;
847  MMRESULT mr;
849  BYTE buf[sizeof(WAVEFORMATEX) + 32], pcm[2048], input[512];
850  ADPCMCOEFSET *coef;
851 
852  src = (ADPCMWAVEFORMAT*)buf;
853  coef = src->aCoef;
854  src->wfx.cbSize = 32;
855  src->wfx.wFormatTag = WAVE_FORMAT_ADPCM;
856  src->wfx.nSamplesPerSec = 22050;
857  src->wfx.wBitsPerSample = 4;
858  src->wfx.nChannels = 1;
859  src->wfx.nBlockAlign = 512;
860  src->wfx.nAvgBytesPerSec = 11025;
861  src->wSamplesPerBlock = 0x3f4;
862  src->wNumCoef = 7;
863  coef[0].iCoef1 = 0x0100;
864  coef[0].iCoef2 = 0x0000;
865  coef[1].iCoef1 = 0x0200;
866  coef[1].iCoef2 = 0xff00;
867  coef[2].iCoef1 = 0x0000;
868  coef[2].iCoef2 = 0x0000;
869  coef[3].iCoef1 = 0x00c0;
870  coef[3].iCoef2 = 0x0040;
871  coef[4].iCoef1 = 0x00f0;
872  coef[4].iCoef2 = 0x0000;
873  coef[5].iCoef1 = 0x01cc;
874  coef[5].iCoef2 = 0xff30;
875  coef[6].iCoef1 = 0x0188;
876  coef[6].iCoef2 = 0xff18;
877 
878  dst.cbSize = 0;
879  dst.wFormatTag = WAVE_FORMAT_PCM;
880  dst.nSamplesPerSec = 22050;
881  dst.wBitsPerSample = 8;
882  dst.nChannels = 1;
883  dst.nBlockAlign = dst.wBitsPerSample * dst.nChannels / 8;
884  dst.nAvgBytesPerSec = dst.nSamplesPerSec * dst.nBlockAlign;
885 
886  mr = acmStreamOpen(&has, NULL, (WAVEFORMATEX*)src, &dst, NULL, 0, 0, 0);
887  ok(mr == MMSYSERR_NOERROR, "open failed: 0x%x\n", mr);
888 
889  memset(input, 0, sizeof(input));
890  memset(&hdr, 0, sizeof(hdr));
891  hdr.cbStruct = sizeof(hdr);
892  hdr.pbSrc = input;
893  hdr.cbSrcLength = sizeof(input);
894  hdr.pbDst = pcm;
895  hdr.cbDstLength = sizeof(pcm);
896 
897  mr = acmStreamPrepareHeader(has, &hdr, 0);
898  ok(mr == MMSYSERR_NOERROR, "prepare failed: 0x%x\n", mr);
899  ok(hdr.fdwStatus == ACMSTREAMHEADER_STATUSF_PREPARED, "header wasn't prepared: 0x%x\n", hdr.fdwStatus);
900 
901  mr = acmStreamUnprepareHeader(has, &hdr, 0);
902  ok(mr == MMSYSERR_NOERROR, "unprepare failed: 0x%x\n", mr);
903  ok(hdr.fdwStatus == 0, "header wasn't unprepared: 0x%x\n", hdr.fdwStatus);
904 
905  memset(&hdr, 0, sizeof(hdr));
906  hdr.cbStruct = sizeof(hdr);
907  hdr.pbSrc = input;
908  hdr.cbSrcLength = 0; /* invalid source length */
909  hdr.pbDst = pcm;
910  hdr.cbDstLength = sizeof(pcm);
911 
912  mr = acmStreamPrepareHeader(has, &hdr, 0);
913  ok(mr == MMSYSERR_INVALPARAM, "expected 0x0b, got 0x%x\n", mr);
914 
915  hdr.cbSrcLength = src->wfx.nBlockAlign - 1; /* less than block align */
916  mr = acmStreamPrepareHeader(has, &hdr, 0);
917  ok(mr == ACMERR_NOTPOSSIBLE, "expected 0x200, got 0x%x\n", mr);
918 
919  hdr.cbSrcLength = src->wfx.nBlockAlign + 1; /* more than block align */
920  mr = acmStreamPrepareHeader(has, &hdr, 0);
921  ok(mr == MMSYSERR_NOERROR, "prepare failed: 0x%x\n", mr);
922 
923  mr = acmStreamUnprepareHeader(has, &hdr, 0);
924  ok(mr == MMSYSERR_NOERROR, "unprepare failed: 0x%x\n", mr);
925 
926  hdr.cbSrcLength = src->wfx.nBlockAlign;
927  mr = acmStreamPrepareHeader(has, &hdr, 1); /* invalid use of reserved parameter */
928  ok(mr == MMSYSERR_INVALFLAG, "expected 0x0a, got 0x%x\n", mr);
929 
930  mr = acmStreamPrepareHeader(has, &hdr, 0);
931  ok(mr == MMSYSERR_NOERROR, "prepare failed: 0x%x\n", mr);
932 
933  mr = acmStreamUnprepareHeader(has, &hdr, 0);
934  ok(mr == MMSYSERR_NOERROR, "unprepare failed: 0x%x\n", mr);
935 
936  memset(&hdr, 0, sizeof(hdr));
937  hdr.cbStruct = sizeof(hdr);
938  hdr.pbSrc = input;
939  hdr.cbSrcLength = sizeof(input);
940  hdr.pbDst = pcm;
941  hdr.cbDstLength = sizeof(pcm);
942  hdr.fdwStatus = ACMSTREAMHEADER_STATUSF_DONE;
943 
944  mr = acmStreamPrepareHeader(has, &hdr, 0);
945  ok(mr == MMSYSERR_NOERROR, "prepare failed: 0x%x\n", mr);
946  ok(hdr.fdwStatus == (ACMSTREAMHEADER_STATUSF_PREPARED | ACMSTREAMHEADER_STATUSF_DONE), "header wasn't prepared: 0x%x\n", hdr.fdwStatus);
947 
948  hdr.cbSrcLengthUsed = 12345;
949  hdr.cbDstLengthUsed = 12345;
950  hdr.fdwStatus &= ~ACMSTREAMHEADER_STATUSF_DONE;
952  ok(mr == MMSYSERR_NOERROR, "convert failed: 0x%x\n", mr);
953  ok(hdr.fdwStatus & ACMSTREAMHEADER_STATUSF_DONE, "conversion was not done: 0x%x\n", hdr.fdwStatus);
954  ok(hdr.cbSrcLengthUsed == hdr.cbSrcLength, "expected %d, got %d\n", hdr.cbSrcLength, hdr.cbSrcLengthUsed);
955 todo_wine
956  ok(hdr.cbDstLengthUsed == 1010, "expected 1010, got %d\n", hdr.cbDstLengthUsed);
957 
958  mr = acmStreamUnprepareHeader(has, &hdr, 0);
959  ok(mr == MMSYSERR_NOERROR, "unprepare failed: 0x%x\n", mr);
960  ok(hdr.fdwStatus == ACMSTREAMHEADER_STATUSF_DONE, "header wasn't unprepared: 0x%x\n", hdr.fdwStatus);
961 
962  /* The 2 next tests are related to Lost Horizon (bug 24723) */
963  memset(&hdr, 0, sizeof(hdr));
964  hdr.cbStruct = sizeof(hdr);
965  hdr.pbSrc = input;
966  hdr.cbSrcLength = sizeof(input);
967  hdr.pbDst = pcm;
968  hdr.cbDstLength = -4;
969 
970  mr = acmStreamPrepareHeader(has, &hdr, 0);
971  if (sizeof(void *) == 4) /* 64 bit fails on this test */
972  {
973  ok(mr == MMSYSERR_NOERROR, "prepare failed: 0x%x\n", mr);
974  ok(hdr.fdwStatus == ACMSTREAMHEADER_STATUSF_PREPARED, "header wasn't prepared: 0x%x\n", hdr.fdwStatus);
975 
976  hdr.cbSrcLengthUsed = 12345;
977  hdr.cbDstLengthUsed = 12345;
978  hdr.fdwStatus &= ~ACMSTREAMHEADER_STATUSF_DONE;
980  ok(mr == MMSYSERR_NOERROR, "convert failed: 0x%x\n", mr);
981  ok(hdr.fdwStatus & ACMSTREAMHEADER_STATUSF_DONE, "conversion was not done: 0x%x\n", hdr.fdwStatus);
982  ok(hdr.cbSrcLengthUsed == hdr.cbSrcLength, "expected %d, got %d\n", hdr.cbSrcLength, hdr.cbSrcLengthUsed);
983 todo_wine
984  ok(hdr.cbDstLengthUsed == 1010, "expected 1010, got %d\n", hdr.cbDstLengthUsed);
985 
986  mr = acmStreamUnprepareHeader(has, &hdr, 0);
987  ok(mr == MMSYSERR_NOERROR, "unprepare failed: 0x%x\n", mr);
988  ok(hdr.fdwStatus == ACMSTREAMHEADER_STATUSF_DONE, "header wasn't unprepared: 0x%x\n", hdr.fdwStatus);
989  }
990  else
991 todo_wine
992  ok(mr == MMSYSERR_INVALPARAM, "expected 0x0b, got 0x%x\n", mr);
993 
994  memset(&hdr, 0, sizeof(hdr));
995  hdr.cbStruct = sizeof(hdr);
996  hdr.pbSrc = input;
997  hdr.cbSrcLength = 24;
998  hdr.pbDst = pcm;
999  hdr.cbDstLength = -4;
1000  mr = acmStreamPrepareHeader(has, &hdr, 0);
1001  ok(mr == ACMERR_NOTPOSSIBLE, "expected 0x200, got 0x%x\n", mr);
1002  ok(hdr.fdwStatus == 0, "expected 0, got 0x%x\n", hdr.fdwStatus);
1003 
1004  hdr.cbSrcLengthUsed = 12345;
1005  hdr.cbDstLengthUsed = 12345;
1007  ok(mr == ACMERR_UNPREPARED, "expected 0x202, got 0x%x\n", mr);
1008  ok(hdr.cbSrcLengthUsed == 12345, "expected 12345, got %d\n", hdr.cbSrcLengthUsed);
1009  ok(hdr.cbDstLengthUsed == 12345, "expected 12345, got %d\n", hdr.cbDstLengthUsed);
1010 
1011  mr = acmStreamUnprepareHeader(has, &hdr, 0);
1012  ok(mr == ACMERR_UNPREPARED, "expected 0x202, got 0x%x\n", mr);
1013 
1014  /* Less output space than required */
1015  memset(&hdr, 0, sizeof(hdr));
1016  hdr.cbStruct = sizeof(hdr);
1017  hdr.pbSrc = input;
1018  hdr.cbSrcLength = sizeof(input);
1019  hdr.pbDst = pcm;
1020  hdr.cbDstLength = 32;
1021 
1022  mr = acmStreamPrepareHeader(has, &hdr, 0);
1023  ok(mr == MMSYSERR_NOERROR, "prepare failed: 0x%x\n", mr);
1024  ok(hdr.fdwStatus == ACMSTREAMHEADER_STATUSF_PREPARED, "header wasn't prepared: 0x%x\n", hdr.fdwStatus);
1025 
1026  hdr.cbSrcLengthUsed = 12345;
1027  hdr.cbDstLengthUsed = 12345;
1028  hdr.fdwStatus &= ~ACMSTREAMHEADER_STATUSF_DONE;
1030  ok(mr == MMSYSERR_NOERROR, "convert failed: 0x%x\n", mr);
1031  ok(hdr.fdwStatus & ACMSTREAMHEADER_STATUSF_DONE, "conversion was not done: 0x%x\n", hdr.fdwStatus);
1032 todo_wine
1033  ok(hdr.cbSrcLengthUsed == hdr.cbSrcLength, "expected %d, got %d\n", hdr.cbSrcLength, hdr.cbSrcLengthUsed);
1034 todo_wine
1035  ok(hdr.cbDstLengthUsed == hdr.cbDstLength, "expected %d, got %d\n", hdr.cbDstLength, hdr.cbDstLengthUsed);
1036 
1037  mr = acmStreamUnprepareHeader(has, &hdr, 0);
1038  ok(mr == MMSYSERR_NOERROR, "unprepare failed: 0x%x\n", mr);
1039  ok(hdr.fdwStatus == ACMSTREAMHEADER_STATUSF_DONE, "header wasn't unprepared: 0x%x\n", hdr.fdwStatus);
1040 
1041  mr = acmStreamClose(has, 0);
1042  ok(mr == MMSYSERR_NOERROR, "close failed: 0x%x\n", mr);
1043 }
1044 
1045 static const BYTE input[64] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63};
1046 
1048 {
1051  BYTE output[256];
1054 };
1055 
1056 static const struct stream_output expected_output[] = {
1057  /* #0: Identical conversion */
1058  {{WAVE_FORMAT_PCM, 1, 8000, 8000, 1, 8}, {WAVE_FORMAT_PCM, 1, 8000, 8000, 1, 8}, {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}, 64, FALSE},
1059 
1060  /* #1: 1 -> 2 channels */
1061  {{WAVE_FORMAT_PCM, 1, 8000, 8000, 1, 8}, {WAVE_FORMAT_PCM, 2, 8000, 16000, 2, 8}, {0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,49,49,50,50,51,51,52,52,53,53,54,54,55,55,56,56,57,57,58,58,59,59,60,60,61,61,62,62,63,63}, 128, FALSE},
1062 
1063  /* #2: 2 -> 1 channels: all of the audio underflows due to addition */
1064  {{WAVE_FORMAT_PCM, 2, 8000, 16000, 2, 8}, {WAVE_FORMAT_PCM, 1, 8000, 8000, 1, 8}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 32, FALSE},
1065 
1066  /* #3: 2 -> 2 channels */
1067  {{WAVE_FORMAT_PCM, 2, 8000, 16000, 2, 8}, {WAVE_FORMAT_PCM, 2, 8000, 16000, 2, 8}, {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}, 64, FALSE},
1068 
1069  /* #4: 8 -> 16 bits per sample */
1070  {{WAVE_FORMAT_PCM, 1, 8000, 8000, 1, 8}, {WAVE_FORMAT_PCM, 1, 8000, 16000, 2, 16}, {0,128,0,129,0,130,0,131,0,132,0,133,0,134,0,135,0,136,0,137,0,138,0,139,0,140,0,141,0,142,0,143,0,144,0,145,0,146,0,147,0,148,0,149,0,150,0,151,0,152,0,153,0,154,0,155,0,156,0,157,0,158,0,159,0,160,0,161,0,162,0,163,0,164,0,165,0,166,0,167,0,168,0,169,0,170,0,171,0,172,0,173,0,174,0,175,0,176,0,177,0,178,0,179,0,180,0,181,0,182,0,183,0,184,0,185,0,186,0,187,0,188,0,189,0,190,0,191}, 128, FALSE},
1071 
1072  /* #5: 16 -> 8 bits per sample */
1073  {{WAVE_FORMAT_PCM, 1, 8000, 16000, 2, 16}, {WAVE_FORMAT_PCM, 1, 8000, 8000, 1, 8}, {129,131,133,135,137,139,141,143,145,147,149,151,153,155,157,159,161,163,165,167,169,171,173,175,177,179,181,183,185,187,189,191}, 32, FALSE},
1074 
1075  /* #6: 16 bits per sample, 2 -> 1 channels */
1076  {{WAVE_FORMAT_PCM, 2, 8000, 32000, 4, 16}, {WAVE_FORMAT_PCM, 1, 8000, 16000, 2, 16}, {2,4,10,12,18,20,26,28,34,36,42,44,50,52,58,60,66,68,74,76,82,84,90,92,98,100,106,108,114,116,122,124}, 32, FALSE},
1077 
1078  /* #7: 8000 -> 11025 sample rate */
1079  /* FIXME: upsampling is slightly off on wine - the algorithm is wrong whenever error > (srcrate + dstrate) / 2 */
1080  {{WAVE_FORMAT_PCM, 1, 8000, 8000, 1, 8}, {WAVE_FORMAT_PCM, 1, 11025, 11025, 1, 8}, {0,1,1,2,3,4,4,5,6,7,7,8,9,9,10,11,12,12,13,14,15,15,16,17,17,18,19,20,20,21,22,22,23,24,25,25,26,27,28,28,29,30,30,31,32,33,33,34,35,36,36,37,38,38,39,40,41,41,42,43,44,44,45,46,46,47,48,49,49,50,51,52,52,53,54,54,55,56,57,57,58,59,60,60,61,62,62,63}, 88, TRUE},
1081 
1082  /* #8: 8000 -> 22050 sample rate */
1083  {{WAVE_FORMAT_PCM, 1, 8000, 8000, 1, 8}, {WAVE_FORMAT_PCM, 1, 22050, 22050, 1, 8}, {0,0,1,1,1,2,2,3,3,3,4,4,4,5,5,5,6,6,7,7,7,8,8,8,9,9,9,10,10,11,11,11,12,12,12,13,13,13,14,14,15,15,15,16,16,16,17,17,17,18,18,19,19,19,20,20,20,21,21,21,22,22,22,23,23,24,24,24,25,25,25,26,26,26,27,27,28,28,28,29,29,29,30,30,30,31,31,32,32,32,33,33,33,34,34,34,35,35,36,36,36,37,37,37,38,38,38,39,39,40,40,40,41,41,41,42,42,42,43,43,44,44,44,45,45,45,46,46,46,47,47,48,48,48,49,49,49,50,50,50,51,51,52,52,52,53,53,53,54,54,54,55,55,56,56,56,57,57,57,58,58,58,59,59,60,60,60,61,61,61,62,62,62,63,63,63}, 176, TRUE},
1084 
1085  /* #9: 11025 -> 22050 sample rate */
1086  {{WAVE_FORMAT_PCM, 1, 11025, 11025, 1, 8}, {WAVE_FORMAT_PCM, 1, 22050, 22050, 1, 8}, {0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,49,49,50,50,51,51,52,52,53,53,54,54,55,55,56,56,57,57,58,58,59,59,60,60,61,61,62,62,63,63}, 128, FALSE},
1087 
1088  /* #10: 22050 -> 11025 sample rate */
1089  {{WAVE_FORMAT_PCM, 1, 22050, 22050, 1, 8}, {WAVE_FORMAT_PCM, 1, 11025, 11025, 1, 8}, {1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63}, 32, FALSE},
1090 
1091  /* #11: 11025 -> 8000 sample rate */
1092  {{WAVE_FORMAT_PCM, 1, 11025, 11025, 1, 8}, {WAVE_FORMAT_PCM, 1, 8000, 8000, 1, 8}, {0,2,3,4,6,7,8,10,11,13,14,15,17,18,19,21,22,24,25,26,28,29,31,32,33,35,36,37,39,40,42,43,44,46,47,48,50,51,53,54,55,57,58,59,61,62}, 46, FALSE},
1093 
1094  /* #12: 22050 -> 8000 sample rate */
1095  {{WAVE_FORMAT_PCM, 1, 22050, 22050, 1, 8}, {WAVE_FORMAT_PCM, 1, 8000, 8000, 1, 8}, {1,4,6,9,12,15,17,20,23,26,28,31,34,37,39,42,45,48,50,53,56,59,62}, 23, FALSE},
1096 
1097  /* #13: 44100 -> 8000 sample rate */
1098  {{WAVE_FORMAT_PCM, 1, 44100, 44100, 1, 8}, {WAVE_FORMAT_PCM, 1, 8000, 8000, 1, 8}, {2,8,13,19,24,30,35,41,46,52,57,63}, 12, FALSE},
1099 };
1100 
1101 static void test_convert(void)
1102 {
1103  HACMSTREAM has;
1104  ACMSTREAMHEADER hdr = {0};
1105  BYTE output[256];
1106  MMRESULT mmr;
1107  unsigned i;
1108 
1109  for (i = 0; i < sizeof(expected_output)/sizeof(struct stream_output); i++)
1110  {
1112  ok(mmr == MMSYSERR_NOERROR, "#%d: open failed: 0x%x\n", i, mmr);
1113 
1114  memset(&hdr, 0, sizeof(hdr));
1115  hdr.cbStruct = sizeof(hdr);
1116  hdr.pbSrc = (BYTE *)input;
1117  hdr.cbSrcLength = sizeof(input);
1118  hdr.pbDst = output;
1119  hdr.cbDstLength = sizeof(output);
1120 
1121  mmr = acmStreamPrepareHeader(has, &hdr, 0);
1122  ok(mmr == MMSYSERR_NOERROR, "#%d: prepare failed: 0x%x\n", i, mmr);
1123  ok(hdr.fdwStatus == ACMSTREAMHEADER_STATUSF_PREPARED, "#%d: header wasn't prepared: 0x%x\n", i, hdr.fdwStatus);
1124 
1125  memset(&output, 0, sizeof(output));
1127  ok(mmr == MMSYSERR_NOERROR, "#%d: convert failed: 0x%x\n", i, mmr);
1128  ok(hdr.fdwStatus & ACMSTREAMHEADER_STATUSF_DONE, "#%d: conversion was not done: 0x%x\n", i, hdr.fdwStatus);
1129  ok(hdr.cbSrcLengthUsed == hdr.cbSrcLength, "#%d: expected %d, got %d\n", i, hdr.cbSrcLength, hdr.cbSrcLengthUsed);
1130  ok(hdr.cbDstLengthUsed == expected_output[i].dst_used, "#%d: expected %d, got %d\n", i, expected_output[i].dst_used, hdr.cbDstLengthUsed);
1132  ok(!memcmp(expected_output[i].output, output, hdr.cbDstLengthUsed), "#%d: output does not match\n", i);
1133 
1134  mmr = acmStreamUnprepareHeader(has, &hdr, 0);
1135  ok(mmr == MMSYSERR_NOERROR, "#%d: unprepare failed: 0x%x\n", i, mmr);
1136  ok(hdr.fdwStatus == ACMSTREAMHEADER_STATUSF_DONE, "#%d: header wasn't unprepared: 0x%x\n", i, hdr.fdwStatus);
1137 
1138  mmr = acmStreamClose(has, 0);
1139  ok(mmr == MMSYSERR_NOERROR, "#%d: close failed: 0x%x\n", i, mmr);
1140  }
1141 }
1142 
1143 static void test_acmFormatSuggest(void)
1144 {
1145  WAVEFORMATEX src, dst;
1146  DWORD suggest;
1147  MMRESULT rc;
1148  DWORD sizeMax;
1149 
1151 
1152  /* Test a valid PCM format */
1153  src.wFormatTag = WAVE_FORMAT_PCM;
1154  src.nChannels = 1;
1155  src.nSamplesPerSec = 8000;
1156  src.nAvgBytesPerSec = 16000;
1157  src.nBlockAlign = 2;
1158  src.wBitsPerSample = 16;
1159  src.cbSize = 0;
1160  suggest = 0;
1161  memset(&dst, 0, sizeof(dst));
1162  rc = acmFormatSuggest(NULL, &src, &dst, sizeof(PCMWAVEFORMAT), suggest);
1163  ok(rc == MMSYSERR_NOERROR, "failed with error 0x%x\n", rc);
1164  ok(src.wFormatTag == dst.wFormatTag, "expected %d, got %d\n", src.wFormatTag, dst.wFormatTag);
1165  ok(src.nChannels == dst.nChannels, "expected %d, got %d\n", src.nChannels, dst.nChannels);
1166  ok(src.nSamplesPerSec == dst.nSamplesPerSec, "expected %d, got %d\n", src.nSamplesPerSec, dst.nSamplesPerSec);
1167  ok(src.nAvgBytesPerSec == dst.nAvgBytesPerSec, "expected %d, got %d\n", src.nAvgBytesPerSec, dst.nAvgBytesPerSec);
1168  ok(src.nBlockAlign == dst.nBlockAlign, "expected %d, got %d\n", src.nBlockAlign, dst.nBlockAlign);
1169  ok(src.wBitsPerSample == dst.wBitsPerSample, "expected %d, got %d\n", src.wBitsPerSample, dst.wBitsPerSample);
1170 
1171  /* All parameters from destination are valid */
1176  dst = src;
1177  rc = acmFormatSuggest(NULL, &src, &dst, sizeof(PCMWAVEFORMAT), suggest);
1178  ok(rc == MMSYSERR_NOERROR, "failed with error 0x%x\n", rc);
1179  ok(src.wFormatTag == dst.wFormatTag, "expected %d, got %d\n", src.wFormatTag, dst.wFormatTag);
1180  ok(src.nChannels == dst.nChannels, "expected %d, got %d\n", src.nChannels, dst.nChannels);
1181  ok(src.nSamplesPerSec == dst.nSamplesPerSec, "expected %d, got %d\n", src.nSamplesPerSec, dst.nSamplesPerSec);
1182  ok(src.nAvgBytesPerSec == dst.nAvgBytesPerSec, "expected %d, got %d\n", src.nAvgBytesPerSec, dst.nAvgBytesPerSec);
1183  ok(src.nBlockAlign == dst.nBlockAlign, "expected %d, got %d\n", src.nBlockAlign, dst.nBlockAlign);
1184  ok(src.wBitsPerSample == dst.wBitsPerSample, "expected %d, got %d\n", src.wBitsPerSample, dst.wBitsPerSample);
1185 
1186  /* Test an invalid PCM format */
1187  ZeroMemory(&dst, sizeof(dst));
1188  src.nSamplesPerSec = 0xdeadbeef;
1189  suggest = 0;
1190  rc = acmFormatSuggest(NULL, &src, &dst, sizeMax, suggest);
1191  todo_wine {
1192  ok(rc == MMSYSERR_NOERROR, "failed with error 0x%x\n", rc);
1193  ok(dst.wFormatTag == WAVE_FORMAT_PCM, "expected %d, got %d\n", WAVE_FORMAT_PCM, dst.wFormatTag);
1194  ok(dst.nSamplesPerSec == 0xdeadbeef, "expected %d, got %d\n", 0xdeadbeef, dst.nSamplesPerSec);
1195  }
1196  src.nSamplesPerSec = 8000;
1197 
1198  /* Test a nonexistent format */
1199  src.wFormatTag = 0xbeef;
1200  rc = acmFormatSuggest(NULL, &src, &dst, sizeMax-1, suggest);
1201  ok(rc == MMSYSERR_INVALPARAM, "failed with error 0x%x\n", rc);
1202 
1203  rc = acmFormatSuggest(NULL, &src, &dst, sizeMax, suggest);
1204  todo_wine
1205  ok(rc == MMSYSERR_NODRIVER, "failed with error 0x%x\n", rc);
1206 
1207  /* Test converting between two known but incompatible formats */
1208  src.wFormatTag = WAVE_FORMAT_ALAW;
1209  src.nChannels = 1;
1210  src.nSamplesPerSec = 8000;
1211  src.nAvgBytesPerSec = 8000;
1212  src.nBlockAlign = 1;
1213  src.wBitsPerSample = 8;
1214  src.cbSize = 0;
1216  dst.wFormatTag = WAVE_FORMAT_IMA_ADPCM;
1217  rc = acmFormatSuggest(NULL, &src, &dst, sizeof(IMAADPCMWAVEFORMAT)-1, suggest);
1218  ok(rc == MMSYSERR_INVALPARAM, "failed with error 0x%x\n", rc);
1219 
1220  rc = acmFormatSuggest(NULL, &src, &dst, sizeof(IMAADPCMWAVEFORMAT), suggest);
1221  todo_wine
1222  ok(rc == MMSYSERR_NODRIVER, "failed with error 0x%x\n", rc);
1223 
1224  /* Invalid suggest flags */
1225  src.wFormatTag = WAVE_FORMAT_PCM;
1226  suggest = 0xFFFFFFFF;
1227  rc = acmFormatSuggest(NULL, &src, &dst, sizeof(dst), suggest);
1228  ok(rc == MMSYSERR_INVALFLAG, "failed with error 0x%x\n", rc);
1229 
1230  /* Invalid source and destination */
1231  suggest = 0;
1232  rc = acmFormatSuggest(NULL, NULL, &dst, sizeof(dst), suggest);
1233  ok(rc == MMSYSERR_INVALPARAM, "failed with error 0x%x\n", rc);
1234  rc = acmFormatSuggest(NULL, &src, NULL, sizeof(dst), suggest);
1235  ok(rc == MMSYSERR_INVALPARAM, "failed with error 0x%x\n", rc);
1236  rc = acmFormatSuggest(NULL, NULL, NULL, sizeof(dst), suggest);
1237  ok(rc == MMSYSERR_INVALPARAM, "failed with error 0x%x\n", rc);
1238 }
1239 
1240 static void test_acmFormatTagDetails(void)
1241 {
1242  ACMFORMATTAGDETAILSW aftd = {0};
1243  MMRESULT rc;
1244 
1245  aftd.cbStruct = sizeof(aftd);
1248  if (rc == MMSYSERR_NOERROR)
1249  ok(aftd.cbFormatSize == sizeof(MPEGLAYER3WAVEFORMAT), "got %d\n", aftd.cbFormatSize);
1250 }
1251 
1252 static void test_acmFormatChoose(void)
1253 {
1254  ACMFORMATCHOOSEW afc = {0};
1255  WAVEFORMATEX *pwfx;
1256  DWORD sizeMax;
1257  MMRESULT rc;
1258 
1260  pwfx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeMax);
1261 
1262  afc.cbStruct = sizeof(afc);
1263  afc.pwfx = pwfx;
1264 
1265  /* test invalid struct size */
1266  afc.cbStruct = sizeof(afc)-1;
1267  rc = acmFormatChooseW(&afc);
1268  ok(rc == MMSYSERR_INVALPARAM, "expected 0xb, got 0x%x\n", rc);
1269  afc.cbStruct = sizeof(afc);
1270 
1271  afc.pwfx = NULL;
1272  rc = acmFormatChooseW(&afc);
1273  ok(rc == MMSYSERR_INVALPARAM, "expected 0xb, got 0x%x\n", rc);
1274  afc.pwfx = pwfx;
1275 
1276  HeapFree(GetProcessHeap(), 0, pwfx);
1277 }
1278 
1279 static void test_mp3(void)
1280 {
1282  WAVEFORMATEX dst;
1283  HACMSTREAM has;
1284  DWORD output;
1285  MMRESULT mr;
1286 
1287  src.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
1288  src.wfx.nSamplesPerSec = 11025;
1289  src.wfx.wBitsPerSample = 0;
1290  src.wfx.nChannels = 1;
1291  src.wfx.nBlockAlign = 576;
1292  src.wfx.nAvgBytesPerSec = 2000;
1293 
1294  src.wID = MPEGLAYER3_ID_MPEG;
1295  src.fdwFlags = 0;
1296  src.nBlockSize = 576;
1297  src.nFramesPerBlock = 1;
1298  src.nCodecDelay = 0;
1299 
1300  dst.cbSize = 0;
1301  dst.wFormatTag = WAVE_FORMAT_PCM;
1302  dst.nSamplesPerSec = 11025;
1303  dst.wBitsPerSample = 16;
1304  dst.nChannels = 1;
1305  dst.nBlockAlign = dst.wBitsPerSample * dst.nChannels / 8;
1306  dst.nAvgBytesPerSec = dst.nSamplesPerSec * dst.nBlockAlign;
1307 
1308  src.wfx.cbSize = 0;
1309 
1310  mr = acmStreamOpen(&has, NULL, (WAVEFORMATEX*)&src, &dst, NULL, 0, 0, 0);
1311  ok(mr == ACMERR_NOTPOSSIBLE, "expected error ACMERR_NOTPOSSIBLE, got 0x%x\n", mr);
1312  if (mr == MMSYSERR_NOERROR) acmStreamClose(has, 0);
1313 
1314  src.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
1315  src.wID = 0;
1316 
1317  mr = acmStreamOpen(&has, NULL, (WAVEFORMATEX*)&src, &dst, NULL, 0, 0, 0);
1318  ok(mr == ACMERR_NOTPOSSIBLE, "expected error ACMERR_NOTPOSSIBLE, got 0x%x\n", mr);
1319  if (mr == MMSYSERR_NOERROR) acmStreamClose(has, 0);
1320 
1321  src.wID = MPEGLAYER3_ID_MPEG;
1322  src.nBlockSize = 0;
1323 
1324  mr = acmStreamOpen(&has, NULL, (WAVEFORMATEX*)&src, &dst, NULL, 0, 0, 0);
1325  ok(mr == MMSYSERR_NOERROR, "failed with error 0x%x\n", mr);
1326  mr = acmStreamClose(has, 0);
1327  ok(mr == MMSYSERR_NOERROR, "failed with error 0x%x\n", mr);
1328 
1329  src.nBlockSize = 576;
1330  src.wfx.nAvgBytesPerSec = 0;
1331 
1332  mr = acmStreamOpen(&has, NULL, (WAVEFORMATEX*)&src, &dst, NULL, 0, 0, 0);
1333  ok(mr == MMSYSERR_NOERROR, "failed with error 0x%x\n", mr);
1334  /* causes a division by zero exception */
1335  if (0) acmStreamSize(has, 4000, &output, ACM_STREAMSIZEF_SOURCE);
1336  mr = acmStreamClose(has, 0);
1337  ok(mr == MMSYSERR_NOERROR, "failed with error 0x%x\n", mr);
1338 
1339  src.wfx.nAvgBytesPerSec = 2000;
1340 
1341  mr = acmStreamOpen(&has, NULL, (WAVEFORMATEX*)&src, &dst, NULL, 0, 0, 0);
1342  ok(mr == MMSYSERR_NOERROR, "failed with error 0x%x\n", mr);
1343  mr = acmStreamSize(has, 4000, &output, ACM_STREAMSIZEF_SOURCE);
1344  ok(mr == MMSYSERR_NOERROR, "failed with error 0x%x\n", mr);
1345  mr = acmStreamClose(has, 0);
1346  ok(mr == MMSYSERR_NOERROR, "failed with error 0x%x\n", mr);
1347 }
1348 
1349 static struct
1350 {
1351  struct
1352  {
1355  } driver;
1356  struct
1357  {
1359  } format;
1360  struct
1361  {
1363  } stream;
1364  int other;
1365 } driver_calls;
1366 
1368 {
1369  switch (msg)
1370  {
1371  /* Driver messages */
1372  case DRV_LOAD:
1373  driver_calls.driver.load++;
1374  return 1;
1375  case DRV_FREE:
1376  driver_calls.driver.free++;
1377  return 1;
1378  case DRV_OPEN:
1379  driver_calls.driver.open++;
1380  return 1;
1381  case DRV_CLOSE:
1382  driver_calls.driver.close++;
1383  return 1;
1384  case DRV_ENABLE:
1385  driver_calls.driver.enable++;
1386  return 1;
1387  case DRV_DISABLE:
1388  driver_calls.driver.disable++;
1389  return 1;
1390  case DRV_QUERYCONFIGURE:
1391  driver_calls.driver.querycfg++;
1392  return 1;
1393  case DRV_INSTALL:
1394  driver_calls.driver.install++;
1395  return DRVCNF_RESTART;
1396  case DRV_REMOVE:
1397  driver_calls.driver.remove++;
1398  return DRVCNF_RESTART;
1399  case ACMDM_DRIVER_ABOUT:
1400  driver_calls.driver.about++;
1401  return MMSYSERR_NOTSUPPORTED;
1402  case ACMDM_DRIVER_DETAILS:
1403  {
1405 
1406  /* copied from pcmconverter.c */
1409  ptr->wMid = MM_MICROSOFT;
1410  ptr->wPid = MM_MSFT_ACM_PCM;
1411  ptr->vdwACM = 0x01000000;
1412  ptr->vdwDriver = 0x01000000;
1414  ptr->cFormatTags = 1;
1415  ptr->cFilterTags = 0;
1416  ptr->hicon = NULL;
1417  strcpy(ptr->szShortName, "TEST-CODEC");
1418  strcpy(ptr->szLongName, "Wine Test Codec");
1419  strcpy(ptr->szCopyright, "Brought to you by the Wine team...");
1420  strcpy(ptr->szLicensing, "Refer to LICENSE file");
1421  ptr->szFeatures[0] = 0;
1422 
1423  driver_calls.driver.details++;
1424  break;
1425  }
1426  case ACMDM_DRIVER_NOTIFY:
1427  driver_calls.driver.notify++;
1428  return MMSYSERR_NOTSUPPORTED;
1429 
1430  /* Format messages */
1432  driver_calls.format.tag_details++;
1433  break;
1434  case ACMDM_FORMAT_DETAILS:
1435  driver_calls.format.details++;
1436  break;
1437  case ACMDM_FORMAT_SUGGEST:
1438  driver_calls.format.suggest++;
1439  break;
1440 
1441  /* Stream messages */
1442  case ACMDM_STREAM_OPEN:
1443  driver_calls.stream.open++;
1444  break;
1445  case ACMDM_STREAM_CLOSE:
1446  driver_calls.stream.close++;
1447  break;
1448  case ACMDM_STREAM_SIZE:
1449  driver_calls.stream.size++;
1450  break;
1451  case ACMDM_STREAM_CONVERT:
1452  driver_calls.stream.convert++;
1453  break;
1454  case ACMDM_STREAM_RESET:
1455  driver_calls.stream.reset++;
1456  return MMSYSERR_NOTSUPPORTED;
1457  case ACMDM_STREAM_PREPARE:
1458  driver_calls.stream.prepare++;
1459  break;
1461  driver_calls.stream.unprepare++;
1462  break;
1463 
1464  default:
1465  driver_calls.other++;
1466  return DefDriverProc(id, handle, msg, param1, param2);
1467  }
1468  return MMSYSERR_NOERROR;
1469 }
1470 
1471 static void test_acmDriverAdd(void)
1472 {
1473  MMRESULT res;
1474  HACMDRIVERID drvid;
1475  union
1476  {
1477  ACMDRIVERDETAILSA drv_details;
1478  } acm;
1479 
1480  /* Driver load steps:
1481  * - acmDriverAdd checks the passed parameters
1482  * - DRV_LOAD message is sent - required
1483  * - DRV_ENABLE message is sent - required
1484  * - DRV_OPEN message is sent - required
1485  * - DRV_DETAILS message is sent - required
1486  * - ACMDM_FORMATTAG_DETAILS message is sent - optional
1487  * - DRV_QUERYCONFIGURE message is sent - optional
1488  * - ACMDM_DRIVER_ABOUT message is sent - optional
1489  */
1490 
1492  ok(res == MMSYSERR_NOERROR, "Expected 0, got %d\n", res);
1493 todo_wine
1494  ok(driver_calls.driver.open == 1, "Expected 1, got %d\n", driver_calls.driver.open);
1495  ok(driver_calls.driver.details == 1, "Expected 1, got %d\n", driver_calls.driver.details);
1496 
1497  memset(&acm, 0, sizeof(acm));
1498  res = acmDriverDetailsA(drvid, &acm.drv_details, 0);
1499  ok(res == MMSYSERR_INVALPARAM, "Expected 11, got %d\n", res);
1500 
1501  acm.drv_details.cbStruct = sizeof(acm.drv_details);
1502  res = acmDriverDetailsA(drvid, &acm.drv_details, 0);
1503  ok(res == MMSYSERR_NOERROR, "Expected 0, got %d\n", res);
1504 todo_wine
1505  ok(driver_calls.driver.open == 1, "Expected 1, got %d\n", driver_calls.driver.open);
1506  ok(driver_calls.driver.details == 2, "Expected 2, got %d\n", driver_calls.driver.details);
1507 todo_wine
1508  ok(driver_calls.driver.close == 0, "Expected 0, got %d\n", driver_calls.driver.close);
1509 }
1510 
1512 {
1513  driver_tests();
1515  test_convert();
1519  test_mp3();
1520  /* Test acmDriverAdd in the end as it may conflict
1521  * with other tests due to codec lookup order */
1523 }
#define DRV_DISABLE
Definition: mmsystem.h:123
#define WAVE_FORMAT_UNKNOWN
Definition: mmreg.h:95
static BOOL CALLBACK DriverEnumProc(HACMDRIVERID hadid, DWORD_PTR dwInstance, DWORD fdwSupport)
Definition: msacm.c:317
#define ACM_METRIC_COUNT_HARDWARE
Definition: msacm.h:192
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3835
#define TRUE
Definition: types.h:120
DWORD cFilterTags
Definition: msacm.h:285
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
#define ACM_METRIC_DRIVER_SUPPORT
Definition: msacm.h:202
char hdr[14]
Definition: iptest.cpp:33
static LRESULT CALLBACK acm_driver_func(DWORD_PTR id, HDRVR handle, UINT msg, LPARAM param1, LPARAM param2)
Definition: msacm.c:1367
#define ACM_FORMATSUGGESTF_NSAMPLESPERSEC
Definition: msacm.h:176
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
WAVEFORMATEX dst
Definition: msacm.c:1050
#define ACMERR_UNPREPARED
Definition: msacm.h:38
#define MM_MSFT_ACM_MSADPCM
Definition: mmreg.h:146
static struct @1605 driver_calls
CHAR szFeatures[ACMDRIVERDETAILS_FEATURES_CHARS]
Definition: msacm.h:293
static void test_mp3(void)
Definition: msacm.c:1279
#define ACM_STREAMCONVERTF_BLOCKALIGN
Definition: msacm.h:205
int install
Definition: msacm.c:1353
static void test_acmFormatChoose(void)
Definition: msacm.c:1252
int tag_details
Definition: msacm.c:1358
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
DWORD cbStruct
Definition: msacm.h:462
#define ACM_METRIC_COUNT_DRIVERS
Definition: msacm.h:187
#define MM_FHGIIS_MPEGLAYER3_DECODE
Definition: mmreg.h:153
#define MPEGLAYER3_WFX_EXTRA_BYTES
Definition: mmreg.h:439
#define ACM_METRIC_COUNT_LOCAL_CODECS
Definition: msacm.h:194
CHAR szLongName[ACMDRIVERDETAILS_LONGNAME_CHARS]
Definition: msacm.h:290
int other
Definition: msacm.c:1364
#define ACM_METRIC_HARDWARE_WAVE_INPUT
Definition: msacm.h:198
WORD nChannels
Definition: mmreg.h:79
int notify
Definition: msacm.c:1353
#define ACMDRIVERDETAILS_SUPPORTF_CODEC
Definition: msacm.h:61
int size
Definition: msacm.c:1362
#define ACMDM_STREAM_RESET
Definition: msacmdrv.h:62
#define CALLBACK
Definition: compat.h:27
BOOL todo
Definition: filedlg.c:313
static BOOL CALLBACK FormatEnumProc(HACMDRIVERID hadid, LPACMFORMATDETAILSA pafd, DWORD_PTR dwInstance, DWORD fd)
Definition: msacm.c:232
#define ACM_FORMATSUGGESTF_WFORMATTAG
Definition: msacm.h:174
MMRESULT WINAPI acmFormatTagEnumA(HACMDRIVER had, PACMFORMATTAGDETAILSA paftda, ACMFORMATTAGENUMCBA fnCallback, DWORD_PTR dwInstance, DWORD fdwEnum)
Definition: format.c:968
MMRESULT WINAPI acmFormatChooseW(PACMFORMATCHOOSEW pafmtc)
Definition: format.c:379
#define ZeroMemory
Definition: winbase.h:1635
UINT MMRESULT
Definition: mmsystem.h:962
#define DRV_CLOSE
Definition: mmsystem.h:122
static int fd
Definition: io.c:51
struct tWAVEFORMATEX WAVEFORMATEX
Definition: austream.idl:23
int suggest
Definition: msacm.c:1358
#define ACM_METRIC_COUNT_LOCAL_FILTERS
Definition: msacm.h:196
#define MMSYSERR_INVALHANDLE
Definition: mmsystem.h:101
int unprepare
Definition: msacm.c:1362
CHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]
Definition: msacm.h:524
MMRESULT WINAPI acmFormatDetailsA(HACMDRIVER had, PACMFORMATDETAILSA pafd, DWORD fdwDetails)
Definition: format.c:402
int winetest_interactive
static void test_acmFormatSuggest(void)
Definition: msacm.c:1143
#define ACMDM_STREAM_OPEN
Definition: msacmdrv.h:58
#define ACMDM_FORMATTAG_DETAILS
Definition: msacmdrv.h:51
#define ACMDM_STREAM_PREPARE
Definition: msacmdrv.h:63
struct pcmwaveformat_tag PCMWAVEFORMAT
START_TEST(msacm)
Definition: msacm.c:1511
#define ACMSTREAMHEADER_STATUSF_DONE
Definition: msacm.h:209
CHAR szLicensing[ACMDRIVERDETAILS_LICENSING_CHARS]
Definition: msacm.h:292
#define ACM_METRIC_COUNT_CONVERTERS
Definition: msacm.h:189
#define ACMDM_STREAM_CLOSE
Definition: msacmdrv.h:59
#define DRV_QUERYCONFIGURE
Definition: mmsystem.h:126
#define ACMDRIVERDETAILS_SUPPORTF_ASYNC
Definition: msacm.h:65
#define DRV_OPEN
Definition: mmsystem.h:121
#define ACMDM_DRIVER_NOTIFY
Definition: msacmdrv.h:45
#define ACMDM_FORMAT_SUGGEST
Definition: msacmdrv.h:53
MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose)
Definition: driver.c:182
#define ACM_METRIC_COUNT_LOCAL_DRIVERS
Definition: msacm.h:193
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define WAVE_FORMAT_PCM
Definition: constants.h:425
static void driver_tests(void)
Definition: msacm.c:808
struct @1605::@1607 format
#define MMSYSERR_NODRIVER
Definition: mmsystem.h:102
int open
Definition: msacm.c:1353
PWAVEFORMATEX pwfx
Definition: msacm.h:496
#define ACM_FORMATDETAILSF_FORMAT
Definition: msacm.h:161
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ACMDM_DRIVER_DETAILS
Definition: msacmdrv.h:46
MMRESULT WINAPI acmFormatTagDetailsA(HACMDRIVER had, PACMFORMATTAGDETAILSA paftda, DWORD fdwDetails)
Definition: format.c:826
#define MM_FHGIIS_MPEGLAYER3_PROFESSIONAL
Definition: mmreg.h:154
#define ACMDRIVERDETAILS_SUPPORTF_FILTER
Definition: msacm.h:63
PWAVEFORMATEX pwfx
Definition: msacm.h:467
#define ACMDM_STREAM_CONVERT
Definition: msacmdrv.h:61
DWORD cbStruct
Definition: msacm.h:272
#define ACM_METRIC_HARDWARE_WAVE_OUTPUT
Definition: msacm.h:199
static PVOID ptr
Definition: dispmode.c:27
static void test_convert(void)
Definition: msacm.c:1101
struct @1605::@1606 driver
int enable
Definition: msacm.c:1353
MMRESULT WINAPI acmMetrics(HACMOBJ hao, UINT uMetric, LPVOID pMetric)
Definition: msacm32_main.c:106
#define MM_MSFT_ACM_G711
Definition: mmreg.h:149
#define ACMDRIVERDETAILS_FCCCOMP_UNDEFINED
Definition: msacm.h:59
#define ACM_METRIC_COUNT_DISABLED
Definition: msacm.h:191
smooth NULL
Definition: ftsmooth.c:416
MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwUnprepare)
Definition: stream.c:449
LONG_PTR LPARAM
Definition: windef.h:208
#define ACM_FORMATSUGGESTF_NCHANNELS
Definition: msacm.h:175
#define DRV_LOAD(x)
#define ACM_METRIC_DRIVER_PRIORITY
Definition: msacm.h:203
#define ACM_METRIC_COUNT_FILTERS
Definition: msacm.h:190
DWORD dst_used
Definition: msacm.c:1052
#define DRVCNF_RESTART
Definition: mmsystem.h:135
int reset
Definition: msacm.c:1362
#define DRV_REMOVE
Definition: mmsystem.h:128
#define ACM_METRIC_COUNT_LOCAL_DISABLED
Definition: msacm.h:197
#define MPEGLAYER3_ID_MPEG
Definition: mmreg.h:442
#define todo_wine_if(is_todo)
Definition: test.h:155
MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID)
Definition: driver.c:355
int querycfg
Definition: msacm.c:1353
static BOOL CALLBACK FormatTagEnumProc(HACMDRIVERID hadid, PACMFORMATTAGDETAILSA paftd, DWORD_PTR dwInstance, DWORD fdwSupport)
Definition: msacm.c:36
static const char * get_metric(UINT uMetric)
Definition: msacm.c:735
#define ACM_FORMATTAGDETAILSF_FORMATTAG
Definition: msacm.h:183
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define GetProcessHeap()
Definition: compat.h:395
#define trace
Definition: atltest.h:70
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
int convert
Definition: msacm.c:1362
#define WAVE_FORMAT_IMA_ADPCM
Definition: mmreg.h:103
#define ACM_STREAMSIZEF_SOURCE
Definition: msacm.h:217
MMRESULT WINAPI acmFormatTagDetailsW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd, DWORD fdwDetails)
Definition: format.c:853
DWORD WINAPI acmGetVersion(void)
Definition: msacm32_main.c:76
static const BYTE input[64]
Definition: msacm.c:1045
#define ACM_METRIC_COUNT_LOCAL_CONVERTERS
Definition: msacm.h:195
#define MM_FRAUNHOFER_IIS
Definition: mmreg.h:152
BYTE output[256]
Definition: msacm.c:1051
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MMSYSERR_INVALFLAG
Definition: mmsystem.h:106
#define ACMDRIVERDETAILS_SUPPORTF_CONVERTER
Definition: msacm.h:62
#define DRV_FREE
Definition: mmsystem.h:124
MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)
Definition: driver.c:494
DWORD cFormatTags
Definition: msacm.h:284
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
BOOL todo
Definition: msacm.c:1053
int free
Definition: msacm.c:1353
MMRESULT WINAPI acmDriverDetailsA(HACMDRIVERID hadid, PACMDRIVERDETAILSA padd, DWORD fdwDetails)
Definition: driver.c:226
static void test_prepareheader(void)
Definition: msacm.c:842
#define MM_MSFT_ACM_IMAADPCM
Definition: mmreg.h:147
WORD wFormatTag
Definition: mmreg.h:78
static void test_acmDriverAdd(void)
Definition: msacm.c:1471
#define todo_wine
Definition: test.h:154
#define MM_MICROSOFT
Definition: mmreg.h:144
DWORD cStandardFormats
Definition: msacm.h:523
#define WAVE_FORMAT_MPEGLAYER3
Definition: mmreg.h:127
struct @1605::@1608 stream
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
unsigned char BYTE
Definition: mem.h:68
#define ACM_FORMATTAGDETAILSF_LARGESTSIZE
Definition: msacm.h:184
CHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]
Definition: msacm.h:498
GLenum src
Definition: glext.h:6340
uint32_t DWORD_PTR
Definition: typedefs.h:63
DWORD dwFormatTag
Definition: msacm.h:494
#define ACM_METRIC_MAX_SIZE_FILTER
Definition: msacm.h:201
#define ACMERR_NOTPOSSIBLE
Definition: msacm.h:36
#define ACMDM_STREAM_UNPREPARE
Definition: msacmdrv.h:64
#define WAVE_FORMAT_ADPCM
Definition: constants.h:426
#define broken(x)
Definition: _sntprintf.h:21
#define DRV_ENABLE
Definition: mmsystem.h:120
CHAR szCopyright[ACMDRIVERDETAILS_COPYRIGHT_CHARS]
Definition: msacm.h:291
MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule, LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
Definition: driver.c:48
int prepare
Definition: msacm.c:1362
MMRESULT WINAPI acmFormatEnumA(HACMDRIVER had, PACMFORMATDETAILSA pafda, ACMFORMATENUMCBA fnCallback, DWORD_PTR dwInstance, DWORD fdwEnum)
Definition: format.c:543
GLenum GLenum GLenum input
Definition: glext.h:9031
#define ACM_DRIVERADDF_FUNCTION
Definition: msacm.h:46
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
MMRESULT WINAPI acmFormatSuggest(HACMDRIVER had, PWAVEFORMATEX pwfxSrc, PWAVEFORMATEX pwfxDst, DWORD cbwfxDst, DWORD fdwSuggest)
Definition: format.c:747
#define ok(value,...)
Definition: atltest.h:57
GLenum GLenum dst
Definition: glext.h:6340
unsigned int UINT
Definition: ndis.h:50
#define ACM_METRIC_COUNT_CODECS
Definition: msacm.h:188
int close
Definition: msacm.c:1353
MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc, PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
Definition: stream.c:149
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
WAVEFORMATEX src
Definition: msacm.c:1049
MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwPrepare)
Definition: stream.c:299
#define WAVE_FORMAT_ALAW
Definition: constants.h:427
DWORD nSamplesPerSec
Definition: mmreg.h:80
#define msg(x)
Definition: auth_time.c:54
#define ACM_FORMATDETAILSF_INDEX
Definition: msacm.h:160
MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput, LPDWORD pdwOutputBytes, DWORD fdwSize)
Definition: stream.c:394
GLuint res
Definition: glext.h:9613
int disable
Definition: msacm.c:1353
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define ACMSTREAMHEADER_STATUSF_PREPARED
Definition: msacm.h:210
#define HIWORD(l)
Definition: typedefs.h:246
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int details
Definition: msacm.c:1353
#define DRV_INSTALL
Definition: mmsystem.h:127
LRESULT WINAPI DefDriverProc(DWORD_PTR dwDriverIdentifier, HDRVR hDrv, UINT Msg, LPARAM lParam1, LPARAM lParam2)
Definition: driver.c:554
static void check_count(UINT uMetric)
Definition: msacm.c:777
MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD_PTR dwInstance, DWORD fdwEnum)
Definition: driver.c:318
int load
Definition: msacm.c:1353
CHAR szShortName[ACMDRIVERDETAILS_SHORTNAME_CHARS]
Definition: msacm.h:289
int about
Definition: msacm.c:1353
#define MM_MSFT_ACM_PCM
Definition: mmreg.h:150
static void test_acmFormatTagDetails(void)
Definition: msacm.c:1240
LONG_PTR LRESULT
Definition: windef.h:209
int remove
Definition: msacm.c:1353
#define memset(x, y, z)
Definition: compat.h:39
#define ACM_METRIC_MAX_SIZE_FORMAT
Definition: msacm.h:200
#define LOWORD(l)
Definition: pedump.c:82
#define HeapFree(x, y, z)
Definition: compat.h:394
#define ACM_FORMATSUGGESTF_WBITSPERSAMPLE
Definition: msacm.h:177
MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwConvert)
Definition: stream.c:89
MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose)
Definition: stream.c:65
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
#define ACMDM_DRIVER_ABOUT
Definition: msacm.h:227
#define ACMDM_FORMAT_DETAILS
Definition: msacmdrv.h:52
#define ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC
Definition: msacm.h:58
#define ACMDM_STREAM_SIZE
Definition: msacmdrv.h:60
static const struct stream_output expected_output[]
Definition: msacm.c:1056