4 * Copyright 1998 Patrik Stridvall
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msacm
);
39 struct MSACM_FillFormatData
{
41 #define WINE_ACMFF_TAG 0
42 #define WINE_ACMFF_FORMAT 1
43 #define WINE_ACMFF_WFX 2
45 WCHAR szFormatTag
[ACMFORMATTAGDETAILS_FORMATTAG_CHARS
];
46 PACMFORMATCHOOSEW afc
;
50 static BOOL CALLBACK
MSACM_FillFormatTagsCB(HACMDRIVERID hadid
,
51 PACMFORMATTAGDETAILSW paftd
,
55 struct MSACM_FillFormatData
* affd
= (struct MSACM_FillFormatData
*)dwInstance
;
59 if (paftd
->cStandardFormats
> 0)
61 if (SendDlgItemMessageW(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
62 CB_FINDSTRINGEXACT
, -1,
63 (LPARAM
)paftd
->szFormatTag
) == CB_ERR
)
65 int index
= SendDlgItemMessageW(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
66 CB_ADDSTRING
, 0, (LPARAM
)paftd
->szFormatTag
);
67 if (((affd
->afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT
) &&
68 (paftd
->dwFormatTag
== affd
->afc
->pwfx
->wFormatTag
)) ||
69 (!(affd
->afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT
) &&
70 (paftd
->dwFormatTag
== WAVE_FORMAT_PCM
)))
71 SendDlgItemMessageW(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
72 CB_SETCURSEL
, index
, 0);
76 case WINE_ACMFF_FORMAT
:
77 if (lstrcmpW(affd
->szFormatTag
, paftd
->szFormatTag
) == 0) {
80 if (acmDriverOpen(&had
, hadid
, 0) == MMSYSERR_NOERROR
) {
81 ACMFORMATDETAILSW afd
= {0};
84 WCHAR buffer
[ACMFORMATDETAILS_FORMAT_CHARS
+16];
86 afd
.cbStruct
= sizeof(afd
);
87 afd
.dwFormatTag
= paftd
->dwFormatTag
;
88 afd
.pwfx
= HeapAlloc(MSACM_hHeap
, 0, paftd
->cbFormatSize
);
89 if (!afd
.pwfx
) return FALSE
;
90 afd
.pwfx
->wFormatTag
= paftd
->dwFormatTag
;
91 if (paftd
->dwFormatTag
!= WAVE_FORMAT_PCM
)
92 afd
.pwfx
->cbSize
= paftd
->cbFormatSize
- sizeof(WAVEFORMATEX
);
93 afd
.cbwfx
= paftd
->cbFormatSize
;
95 for (i
= 0; i
< paftd
->cStandardFormats
; i
++) {
98 afd
.dwFormatIndex
= i
;
100 mmr
= acmFormatDetailsW(had
, &afd
, ACM_FORMATDETAILSF_INDEX
);
101 if (mmr
== MMSYSERR_NOERROR
) {
102 lstrcpynW(buffer
, afd
.szFormat
, ACMFORMATTAGDETAILS_FORMATTAG_CHARS
+ 1);
103 len
= lstrlenW(buffer
);
104 for (j
= len
; j
< ACMFORMATTAGDETAILS_FORMATTAG_CHARS
; j
++)
106 wsprintfW(buffer
+ ACMFORMATTAGDETAILS_FORMATTAG_CHARS
,
107 L
"%d Ko/s", (afd
.pwfx
->nAvgBytesPerSec
+ 512) / 1024);
108 index
= SendDlgItemMessageW(affd
->hWnd
,
109 IDD_ACMFORMATCHOOSE_CMB_FORMAT
,
110 CB_ADDSTRING
, 0, (LPARAM
)buffer
);
111 if ((affd
->afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT
) &&
112 affd
->afc
->cbwfx
>= paftd
->cbFormatSize
&&
113 !memcmp(afd
.pwfx
, affd
->afc
->pwfx
, paftd
->cbFormatSize
))
114 SendDlgItemMessageW(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
,
115 CB_SETCURSEL
, index
, 0);
118 acmDriverClose(had
, 0);
119 HeapFree(MSACM_hHeap
, 0, afd
.pwfx
);
124 if (lstrcmpW(affd
->szFormatTag
, paftd
->szFormatTag
) == 0) {
127 if (acmDriverOpen(&had
, hadid
, 0) == MMSYSERR_NOERROR
) {
128 ACMFORMATDETAILSW afd
= {0};
130 afd
.cbStruct
= sizeof(afd
);
131 afd
.dwFormatTag
= paftd
->dwFormatTag
;
132 afd
.pwfx
= affd
->afc
->pwfx
;
133 afd
.cbwfx
= affd
->afc
->cbwfx
;
135 afd
.dwFormatIndex
= SendDlgItemMessageW(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
,
137 affd
->ret
= acmFormatDetailsW(had
, &afd
, ACM_FORMATDETAILSF_INDEX
);
138 acmDriverClose(had
, 0);
144 FIXME("Unknown mode (%d)\n", affd
->mode
);
150 static BOOL
MSACM_FillFormatTags(HWND hWnd
, PACMFORMATCHOOSEW afc
)
152 ACMFORMATTAGDETAILSW aftd
;
153 struct MSACM_FillFormatData affd
;
155 memset(&aftd
, 0, sizeof(aftd
));
156 aftd
.cbStruct
= sizeof(aftd
);
159 affd
.mode
= WINE_ACMFF_TAG
;
162 acmFormatTagEnumW(NULL
, &aftd
, MSACM_FillFormatTagsCB
, (DWORD_PTR
)&affd
, 0);
163 if (SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
, CB_GETCURSEL
, 0, 0) == CB_ERR
)
164 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
, CB_SETCURSEL
, 0, 0);
168 static BOOL
MSACM_FillFormat(HWND hWnd
, PACMFORMATCHOOSEW afc
)
170 ACMFORMATTAGDETAILSW aftd
;
171 struct MSACM_FillFormatData affd
;
173 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
, CB_RESETCONTENT
, 0, 0);
175 memset(&aftd
, 0, sizeof(aftd
));
176 aftd
.cbStruct
= sizeof(aftd
);
179 affd
.mode
= WINE_ACMFF_FORMAT
;
181 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
183 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
185 (LPARAM
)affd
.szFormatTag
);
187 acmFormatTagEnumW(NULL
, &aftd
, MSACM_FillFormatTagsCB
, (DWORD_PTR
)&affd
, 0);
188 if (SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
, CB_GETCURSEL
, 0, 0) == CB_ERR
)
189 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
, CB_SETCURSEL
, 0, 0);
193 static MMRESULT
MSACM_GetWFX(HWND hWnd
, PACMFORMATCHOOSEW afc
)
195 ACMFORMATTAGDETAILSW aftd
;
196 struct MSACM_FillFormatData affd
;
198 memset(&aftd
, 0, sizeof(aftd
));
199 aftd
.cbStruct
= sizeof(aftd
);
202 affd
.mode
= WINE_ACMFF_WFX
;
204 affd
.ret
= MMSYSERR_NOERROR
;
205 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
207 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
209 (LPARAM
)affd
.szFormatTag
);
211 acmFormatTagEnumW(NULL
, &aftd
, MSACM_FillFormatTagsCB
, (DWORD_PTR
)&affd
, 0);
215 static INT_PTR CALLBACK
FormatChooseDlgProc(HWND hWnd
, UINT msg
,
216 WPARAM wParam
, LPARAM lParam
)
218 ACMFORMATCHOOSEW
*afc
= (ACMFORMATCHOOSEW
*)GetPropW(hWnd
, L
"acmprop");
220 TRACE("hwnd=%p msg=%i 0x%08lx 0x%08lx\n", hWnd
, msg
, wParam
, lParam
);
224 afc
= (PACMFORMATCHOOSEW
)lParam
;
225 SetPropW(hWnd
, L
"acmprop", (HANDLE
)afc
);
226 MSACM_FillFormatTags(hWnd
, afc
);
227 MSACM_FillFormat(hWnd
, afc
);
228 if ((afc
->fdwStyle
& ~(ACMFORMATCHOOSE_STYLEF_CONTEXTHELP
|
229 ACMFORMATCHOOSE_STYLEF_SHOWHELP
|
230 ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT
|
231 ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATEHANDLE
|
232 ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATE
)) != 0)
233 FIXME("Unsupported style %08x\n", afc
->fdwStyle
);
234 if (!(afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_SHOWHELP
))
235 ShowWindow(GetDlgItem(hWnd
, IDD_ACMFORMATCHOOSE_BTN_HELP
), SW_HIDE
);
239 switch (LOWORD(wParam
)) {
241 EndDialog(hWnd
, MSACM_GetWFX(hWnd
, afc
));
244 EndDialog(hWnd
, ACMERR_CANCELED
);
246 case IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
:
247 switch (HIWORD(wParam
)) {
249 MSACM_FillFormat(hWnd
, afc
);
252 TRACE("Dropped dlgNotif (fmtTag): 0x%08x 0x%08lx\n",
253 HIWORD(wParam
), lParam
);
257 case IDD_ACMFORMATCHOOSE_BTN_HELP
:
258 if (afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_SHOWHELP
)
259 SendMessageW(afc
->hwndOwner
,
260 RegisterWindowMessageW(ACMHELPMSGSTRINGW
), 0L, 0L);
264 TRACE("Dropped dlgCmd: ctl=%d ntf=0x%04x 0x%08lx\n",
265 LOWORD(wParam
), HIWORD(wParam
), lParam
);
270 if (afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_CONTEXTHELP
)
271 SendMessageW(afc
->hwndOwner
,
272 RegisterWindowMessageW(ACMHELPMSGCONTEXTMENUW
),
275 #if defined(WM_CONTEXTHELP)
277 if (afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_CONTEXTHELP
)
278 SendMessageW(afc
->hwndOwner
,
279 RegisterWindowMessageW(ACMHELPMSGCONTEXTHELPW
),
284 TRACE("Dropped dlgMsg: hwnd=%p msg=%i 0x%08lx 0x%08lx\n",
285 hWnd
, msg
, wParam
, lParam
);
291 /***********************************************************************
292 * acmFormatChooseA (MSACM32.@)
294 MMRESULT WINAPI
acmFormatChooseA(PACMFORMATCHOOSEA pafmtc
)
296 ACMFORMATCHOOSEW afcw
;
303 if (pafmtc
->cbStruct
< sizeof(ACMFORMATCHOOSEA
))
304 return MMSYSERR_INVALPARAM
;
306 afcw
.cbStruct
= sizeof(afcw
);
307 afcw
.fdwStyle
= pafmtc
->fdwStyle
;
308 afcw
.hwndOwner
= pafmtc
->hwndOwner
;
309 afcw
.pwfx
= pafmtc
->pwfx
;
310 afcw
.cbwfx
= pafmtc
->cbwfx
;
311 if (pafmtc
->pszTitle
)
313 sz
= MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszTitle
, -1, NULL
, 0);
314 if (!(title
= HeapAlloc(GetProcessHeap(), 0, sz
* sizeof(WCHAR
))))
316 ret
= MMSYSERR_NOMEM
;
319 MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszTitle
, -1, title
, sz
);
321 afcw
.pszTitle
= title
;
324 sz
= MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszName
, -1, NULL
, 0);
325 if (!(name
= HeapAlloc(GetProcessHeap(), 0, sz
* sizeof(WCHAR
))))
327 ret
= MMSYSERR_NOMEM
;
330 MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszName
, -1, name
, sz
);
333 afcw
.cchName
= pafmtc
->cchName
;
334 afcw
.fdwEnum
= pafmtc
->fdwEnum
;
335 afcw
.pwfxEnum
= pafmtc
->pwfxEnum
;
336 afcw
.hInstance
= pafmtc
->hInstance
;
337 if (pafmtc
->pszTemplateName
)
339 sz
= MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszTemplateName
, -1, NULL
, 0);
340 if (!(templ
= HeapAlloc(GetProcessHeap(), 0, sz
* sizeof(WCHAR
))))
342 ret
= MMSYSERR_NOMEM
;
345 MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszTemplateName
, -1, templ
, sz
);
347 afcw
.pszTemplateName
= templ
;
348 /* FIXME: hook procs not supported yet */
351 FIXME("Unsupported hook procs\n");
352 ret
= MMSYSERR_NOTSUPPORTED
;
355 ret
= acmFormatChooseW(&afcw
);
356 if (ret
== MMSYSERR_NOERROR
)
358 WideCharToMultiByte(CP_ACP
, 0, afcw
.szFormatTag
, -1, pafmtc
->szFormatTag
, sizeof(pafmtc
->szFormatTag
),
360 WideCharToMultiByte(CP_ACP
, 0, afcw
.szFormat
, -1, pafmtc
->szFormat
, sizeof(pafmtc
->szFormat
),
363 WideCharToMultiByte(CP_ACP
, 0, afcw
.pszName
, -1, pafmtc
->pszName
, pafmtc
->cchName
, NULL
, NULL
);
366 HeapFree(GetProcessHeap(), 0, title
);
367 HeapFree(GetProcessHeap(), 0, name
);
368 HeapFree(GetProcessHeap(), 0, templ
);
372 /***********************************************************************
373 * acmFormatChooseW (MSACM32.@)
375 MMRESULT WINAPI
acmFormatChooseW(PACMFORMATCHOOSEW pafmtc
)
377 if (pafmtc
->cbStruct
< sizeof(ACMFORMATCHOOSEW
))
378 return MMSYSERR_INVALPARAM
;
381 return MMSYSERR_INVALPARAM
;
383 if (pafmtc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATEHANDLE
)
384 return DialogBoxIndirectParamW(MSACM_hInstance32
, (LPCDLGTEMPLATEW
)pafmtc
->hInstance
,
385 pafmtc
->hwndOwner
, FormatChooseDlgProc
, (LPARAM
)pafmtc
);
387 if (pafmtc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATE
)
388 return DialogBoxParamW(pafmtc
->hInstance
, pafmtc
->pszTemplateName
,
389 pafmtc
->hwndOwner
, FormatChooseDlgProc
, (LPARAM
)pafmtc
);
391 return DialogBoxParamW(MSACM_hInstance32
, MAKEINTRESOURCEW(DLG_ACMFORMATCHOOSE_ID
),
392 pafmtc
->hwndOwner
, FormatChooseDlgProc
, (LPARAM
)pafmtc
);
395 /***********************************************************************
396 * acmFormatDetailsA (MSACM32.@)
398 MMRESULT WINAPI
acmFormatDetailsA(HACMDRIVER had
, PACMFORMATDETAILSA pafd
,
401 ACMFORMATDETAILSW afdw
;
405 return MMSYSERR_INVALPARAM
;
407 memset(&afdw
, 0, sizeof(afdw
));
408 afdw
.cbStruct
= sizeof(afdw
);
409 afdw
.dwFormatIndex
= pafd
->dwFormatIndex
;
410 afdw
.dwFormatTag
= pafd
->dwFormatTag
;
411 afdw
.fdwSupport
= pafd
->fdwSupport
;
412 afdw
.pwfx
= pafd
->pwfx
;
413 afdw
.cbwfx
= pafd
->cbwfx
;
415 mmr
= acmFormatDetailsW(had
, &afdw
, fdwDetails
);
416 if (mmr
== MMSYSERR_NOERROR
) {
417 pafd
->dwFormatTag
= afdw
.dwFormatTag
;
418 pafd
->fdwSupport
= afdw
.fdwSupport
;
419 WideCharToMultiByte( CP_ACP
, 0, afdw
.szFormat
, -1,
420 pafd
->szFormat
, sizeof(pafd
->szFormat
), NULL
, NULL
);
425 /***********************************************************************
426 * acmFormatDetailsW (MSACM32.@)
428 MMRESULT WINAPI
acmFormatDetailsW(HACMDRIVER had
, PACMFORMATDETAILSW pafd
, DWORD fdwDetails
)
431 ACMFORMATTAGDETAILSW aftd
= {0};
433 TRACE("(%p, %p, %d)\n", had
, pafd
, fdwDetails
);
436 return MMSYSERR_INVALPARAM
;
438 if (pafd
->cbStruct
< sizeof(*pafd
)) return MMSYSERR_INVALPARAM
;
441 return MMSYSERR_INVALPARAM
;
443 if (pafd
->cbwfx
< sizeof(PCMWAVEFORMAT
))
444 return MMSYSERR_INVALPARAM
;
446 if (pafd
->fdwSupport
)
447 return MMSYSERR_INVALPARAM
;
449 if (pafd
->dwFormatTag
== WAVE_FORMAT_UNKNOWN
)
450 return MMSYSERR_INVALPARAM
;
452 switch (fdwDetails
) {
453 case ACM_FORMATDETAILSF_FORMAT
:
454 if (pafd
->dwFormatTag
!= pafd
->pwfx
->wFormatTag
) {
455 mmr
= MMSYSERR_INVALPARAM
;
459 PWINE_ACMDRIVERID padid
;
461 mmr
= ACMERR_NOTPOSSIBLE
;
462 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
463 /* should check for codec only */
464 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
465 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
466 mmr
= MSACM_Message(had
, ACMDM_FORMAT_DETAILS
, (LPARAM
)pafd
, fdwDetails
);
467 acmDriverClose(had
, 0);
468 if (mmr
== MMSYSERR_NOERROR
) break;
472 mmr
= MSACM_Message(had
, ACMDM_FORMAT_DETAILS
, (LPARAM
)pafd
, fdwDetails
);
475 case ACM_FORMATDETAILSF_INDEX
:
476 aftd
.cbStruct
= sizeof(aftd
);
477 aftd
.dwFormatTag
= pafd
->dwFormatTag
;
478 mmr
= acmFormatTagDetailsW(had
, &aftd
, ACM_FORMATTAGDETAILSF_FORMATTAG
);
479 if (mmr
!= MMSYSERR_NOERROR
)
481 if (pafd
->dwFormatIndex
>= aftd
.cStandardFormats
)
483 mmr
= MMSYSERR_INVALPARAM
;
486 mmr
= MSACM_Message(had
, ACMDM_FORMAT_DETAILS
, (LPARAM
)pafd
, fdwDetails
);
489 WARN("Unknown fdwDetails %08x\n", fdwDetails
);
490 mmr
= MMSYSERR_INVALFLAG
;
494 if (mmr
== MMSYSERR_NOERROR
&& pafd
->szFormat
[0] == 0) {
495 wsprintfW(pafd
->szFormat
, L
"%d Hz", pafd
->pwfx
->nSamplesPerSec
);
496 if (pafd
->pwfx
->wBitsPerSample
) {
497 wsprintfW(pafd
->szFormat
+ lstrlenW(pafd
->szFormat
), L
"; %d bits",
498 pafd
->pwfx
->wBitsPerSample
);
500 MultiByteToWideChar(CP_ACP
, 0, (pafd
->pwfx
->nChannels
== 1) ? "; Mono" : "; Stereo", -1,
501 pafd
->szFormat
+ lstrlenW(pafd
->szFormat
),
502 ARRAY_SIZE(pafd
->szFormat
) - lstrlenW(pafd
->szFormat
));
505 TRACE("=> %d\n", mmr
);
509 struct MSACM_FormatEnumWtoA_Instance
{
510 PACMFORMATDETAILSA pafda
;
511 DWORD_PTR dwInstance
;
512 ACMFORMATENUMCBA fnCallback
;
515 static BOOL CALLBACK
MSACM_FormatEnumCallbackWtoA(HACMDRIVERID hadid
,
516 PACMFORMATDETAILSW pafdw
,
517 DWORD_PTR dwInstance
,
520 struct MSACM_FormatEnumWtoA_Instance
* pafei
;
522 pafei
= (struct MSACM_FormatEnumWtoA_Instance
*)dwInstance
;
524 pafei
->pafda
->dwFormatIndex
= pafdw
->dwFormatIndex
;
525 pafei
->pafda
->dwFormatTag
= pafdw
->dwFormatTag
;
526 pafei
->pafda
->fdwSupport
= pafdw
->fdwSupport
;
527 WideCharToMultiByte( CP_ACP
, 0, pafdw
->szFormat
, -1,
528 pafei
->pafda
->szFormat
, sizeof(pafei
->pafda
->szFormat
), NULL
, NULL
);
530 return (pafei
->fnCallback
)(hadid
, pafei
->pafda
,
531 pafei
->dwInstance
, fdwSupport
);
534 /***********************************************************************
535 * acmFormatEnumA (MSACM32.@)
537 MMRESULT WINAPI
acmFormatEnumA(HACMDRIVER had
, PACMFORMATDETAILSA pafda
,
538 ACMFORMATENUMCBA fnCallback
,
539 DWORD_PTR dwInstance
, DWORD fdwEnum
)
541 ACMFORMATDETAILSW afdw
;
542 struct MSACM_FormatEnumWtoA_Instance afei
;
545 return MMSYSERR_INVALPARAM
;
548 return MMSYSERR_INVALPARAM
;
550 if (pafda
->cbStruct
< sizeof(*pafda
))
551 return MMSYSERR_INVALPARAM
;
553 memset(&afdw
, 0, sizeof(afdw
));
554 afdw
.cbStruct
= sizeof(afdw
);
555 afdw
.dwFormatIndex
= pafda
->dwFormatIndex
;
556 afdw
.dwFormatTag
= pafda
->dwFormatTag
;
557 afdw
.fdwSupport
= pafda
->fdwSupport
;
558 afdw
.pwfx
= pafda
->pwfx
;
559 afdw
.cbwfx
= pafda
->cbwfx
;
562 afei
.dwInstance
= dwInstance
;
563 afei
.fnCallback
= fnCallback
;
565 return acmFormatEnumW(had
, &afdw
, MSACM_FormatEnumCallbackWtoA
,
566 (DWORD_PTR
)&afei
, fdwEnum
);
569 /***********************************************************************
570 * acmFormatEnumW (MSACM32.@)
572 static BOOL
MSACM_FormatEnumHelper(PWINE_ACMDRIVERID padid
, HACMDRIVER had
,
573 PACMFORMATDETAILSW pafd
, PWAVEFORMATEX pwfxRef
,
574 ACMFORMATENUMCBW fnCallback
,
575 DWORD_PTR dwInstance
, DWORD fdwEnum
)
577 ACMFORMATTAGDETAILSW aftd
;
580 if (fdwEnum
& ACM_FORMATENUMF_SUGGEST
) {
582 ACMDRVFORMATSUGGEST adfs
;
583 pafd
->dwFormatIndex
= 0;
584 memset(&aftd
, 0, sizeof(aftd
));
585 aftd
.cbStruct
= sizeof(aftd
);
586 memset(&adfs
, 0, sizeof(adfs
));
587 adfs
.cbStruct
= sizeof(adfs
);
589 for (i
= 0; i
< padid
->cFormatTags
; i
++) {
590 aftd
.dwFormatTag
= i
;
591 pafd
->dwFormatTag
= aftd
.dwFormatTag
;
592 pafd
->pwfx
->wFormatTag
= pafd
->dwFormatTag
;
594 if (acmFormatTagDetailsW(had
, &aftd
, ACM_FORMATTAGDETAILSF_INDEX
) != MMSYSERR_NOERROR
)
597 adfs
.cbwfxSrc
= aftd
.cbFormatSize
;
598 adfs
.cbwfxDst
= aftd
.cbFormatSize
;
599 adfs
.pwfxSrc
= pwfxRef
;
600 adfs
.pwfxDst
= pafd
->pwfx
;
601 pafd
->fdwSupport
= padid
->fdwSupport
;
603 if ((fdwEnum
& ACM_FORMATENUMF_WFORMATTAG
) &&
604 aftd
.dwFormatTag
!= pwfxRef
->wFormatTag
)
607 if ((fdwEnum
& ACM_FORMATENUMF_HARDWARE
) &&
608 !(pafd
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_HARDWARE
))
611 hdrvr
= OpenDriver(padid
->pszFileName
,0,0);
612 SendDriverMessage(hdrvr
,ACMDM_FORMAT_SUGGEST
,(LPARAM
)&adfs
,(fdwEnum
& 0x000000FFL
));
614 if (acmFormatDetailsW(had
, pafd
, ACM_FORMATDETAILSF_FORMAT
) != MMSYSERR_NOERROR
)
617 pafd
->cbwfx
= sizeof(*(pafd
->pwfx
));
619 if (!(fnCallback
)((HACMDRIVERID
)padid
, pafd
, dwInstance
, padid
->fdwSupport
))
623 for (i
= 0; i
< padid
->cFormatTags
; i
++) {
624 memset(&aftd
, 0, sizeof(aftd
));
625 aftd
.cbStruct
= sizeof(aftd
);
626 aftd
.dwFormatTagIndex
= i
;
627 if (acmFormatTagDetailsW(had
, &aftd
, ACM_FORMATTAGDETAILSF_INDEX
) != MMSYSERR_NOERROR
)
630 if ((fdwEnum
& ACM_FORMATENUMF_WFORMATTAG
) && aftd
.dwFormatTag
!= pwfxRef
->wFormatTag
)
633 for (j
= 0; j
< aftd
.cStandardFormats
; j
++) {
634 pafd
->dwFormatIndex
= j
;
635 pafd
->dwFormatTag
= aftd
.dwFormatTag
;
636 pafd
->fdwSupport
= 0;
637 if (acmFormatDetailsW(had
, pafd
, ACM_FORMATDETAILSF_INDEX
) != MMSYSERR_NOERROR
)
640 if ((fdwEnum
& ACM_FORMATENUMF_NCHANNELS
) &&
641 pafd
->pwfx
->nChannels
!= pwfxRef
->nChannels
)
643 if ((fdwEnum
& ACM_FORMATENUMF_NSAMPLESPERSEC
) &&
644 pafd
->pwfx
->nSamplesPerSec
!= pwfxRef
->nSamplesPerSec
)
646 if ((fdwEnum
& ACM_FORMATENUMF_WBITSPERSAMPLE
) &&
647 pafd
->pwfx
->wBitsPerSample
!= pwfxRef
->wBitsPerSample
)
649 if ((fdwEnum
& ACM_FORMATENUMF_HARDWARE
) &&
650 !(pafd
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_HARDWARE
))
653 /* more checks to be done on fdwEnum */
655 if (!(fnCallback
)((HACMDRIVERID
)padid
, pafd
, dwInstance
, padid
->fdwSupport
))
658 /* the "formats" used by the filters are also reported */
664 /**********************************************************************/
666 MMRESULT WINAPI
acmFormatEnumW(HACMDRIVER had
, PACMFORMATDETAILSW pafd
,
667 ACMFORMATENUMCBW fnCallback
,
668 DWORD_PTR dwInstance
, DWORD fdwEnum
)
670 PWINE_ACMDRIVERID padid
;
676 TRACE("(%p, %p, %p, %ld, %d)\n",
677 had
, pafd
, fnCallback
, dwInstance
, fdwEnum
);
680 return MMSYSERR_INVALPARAM
;
683 return MMSYSERR_INVALPARAM
;
685 if (pafd
->cbStruct
< sizeof(*pafd
))
686 return MMSYSERR_INVALPARAM
;
688 if (pafd
->fdwSupport
)
689 return MMSYSERR_INVALPARAM
;
692 return MMSYSERR_INVALPARAM
;
694 if (fdwEnum
& (ACM_FORMATENUMF_WFORMATTAG
|ACM_FORMATENUMF_NCHANNELS
|
695 ACM_FORMATENUMF_NSAMPLESPERSEC
|ACM_FORMATENUMF_WBITSPERSAMPLE
|
696 ACM_FORMATENUMF_CONVERT
|ACM_FORMATENUMF_SUGGEST
))
697 wfxRef
= *pafd
->pwfx
;
699 if ((fdwEnum
& ACM_FORMATENUMF_HARDWARE
) &&
700 !(fdwEnum
& (ACM_FORMATENUMF_INPUT
|ACM_FORMATENUMF_OUTPUT
)))
701 return MMSYSERR_INVALPARAM
;
703 if ((fdwEnum
& ACM_FORMATENUMF_WFORMATTAG
) &&
704 (pafd
->dwFormatTag
!= pafd
->pwfx
->wFormatTag
))
705 return MMSYSERR_INVALPARAM
;
707 if (fdwEnum
& (ACM_FORMATENUMF_CONVERT
|ACM_FORMATENUMF_INPUT
|ACM_FORMATENUMF_OUTPUT
))
708 FIXME("Unsupported fdwEnum values %08x\n", fdwEnum
);
710 mmr
= acmMetrics((HACMOBJ
)had
, ACM_METRIC_MAX_SIZE_FORMAT
, &cbwfxMax
);
711 if (mmr
!= MMSYSERR_NOERROR
)
713 if (pafd
->cbwfx
< cbwfxMax
)
714 return MMSYSERR_INVALPARAM
;
719 if (acmDriverID((HACMOBJ
)had
, &hadid
, 0) != MMSYSERR_NOERROR
)
720 return MMSYSERR_INVALHANDLE
;
721 MSACM_FormatEnumHelper(MSACM_GetDriverID(hadid
), had
, pafd
, &wfxRef
,
722 fnCallback
, dwInstance
, fdwEnum
);
723 return MMSYSERR_NOERROR
;
725 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
726 /* should check for codec only */
727 if ((padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) ||
728 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) != MMSYSERR_NOERROR
)
730 ret
= MSACM_FormatEnumHelper(padid
, had
, pafd
, &wfxRef
,
731 fnCallback
, dwInstance
, fdwEnum
);
732 acmDriverClose(had
, 0);
735 return MMSYSERR_NOERROR
;
738 /***********************************************************************
739 * acmFormatSuggest (MSACM32.@)
741 MMRESULT WINAPI
acmFormatSuggest(HACMDRIVER had
, PWAVEFORMATEX pwfxSrc
,
742 PWAVEFORMATEX pwfxDst
, DWORD cbwfxDst
, DWORD fdwSuggest
)
744 ACMFORMATTAGDETAILSW aftd
= {0};
745 ACMDRVFORMATSUGGEST adfg
;
748 TRACE("(%p, %p, %p, %d, %d)\n",
749 had
, pwfxSrc
, pwfxDst
, cbwfxDst
, fdwSuggest
);
751 if (!pwfxSrc
|| !pwfxDst
)
752 return MMSYSERR_INVALPARAM
;
754 if (fdwSuggest
& ~(ACM_FORMATSUGGESTF_NCHANNELS
|ACM_FORMATSUGGESTF_NSAMPLESPERSEC
|
755 ACM_FORMATSUGGESTF_WBITSPERSAMPLE
|ACM_FORMATSUGGESTF_WFORMATTAG
))
756 return MMSYSERR_INVALFLAG
;
758 /* if we were given PCM, try to convert to PCM */
759 if (pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
&& !had
&&
760 !(fdwSuggest
& ACM_FORMATSUGGESTF_WFORMATTAG
))
762 ACMFORMATDETAILSW afd
= {0};
763 afd
.cbStruct
= sizeof(afd
);
764 afd
.dwFormatTag
= WAVE_FORMAT_PCM
;
766 afd
.cbwfx
= sizeof(PCMWAVEFORMAT
);
767 if (!acmFormatDetailsW(had
, &afd
, ACM_FORMATDETAILSF_FORMAT
))
769 memcpy(pwfxDst
, pwfxSrc
, sizeof(PCMWAVEFORMAT
));
770 return MMSYSERR_NOERROR
;
774 aftd
.cbStruct
= sizeof(aftd
);
775 if (fdwSuggest
& ACM_FORMATSUGGESTF_WFORMATTAG
)
776 aftd
.dwFormatTag
= pwfxDst
->wFormatTag
;
777 mmr
= acmFormatTagDetailsW(had
, &aftd
, ACM_FORMATTAGDETAILSF_LARGESTSIZE
);
778 if ((fdwSuggest
& ACM_FORMATSUGGESTF_WFORMATTAG
) && mmr
== ACMERR_NOTPOSSIBLE
)
779 return ACMERR_NOTPOSSIBLE
;
781 if (cbwfxDst
< aftd
.cbFormatSize
)
782 return MMSYSERR_INVALPARAM
;
784 adfg
.cbStruct
= sizeof(adfg
);
785 adfg
.fdwSuggest
= fdwSuggest
;
786 adfg
.pwfxSrc
= pwfxSrc
;
787 adfg
.cbwfxSrc
= (pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
) ?
788 sizeof(WAVEFORMATEX
) : (sizeof(WAVEFORMATEX
) + pwfxSrc
->cbSize
);
789 adfg
.pwfxDst
= pwfxDst
;
790 adfg
.cbwfxDst
= cbwfxDst
;
793 PWINE_ACMDRIVERID padid
;
795 /* MS doc says: ACM finds the best suggestion.
796 * Well, first found will be the "best"
798 mmr
= ACMERR_NOTPOSSIBLE
;
799 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
800 /* should check for codec only */
801 if ((padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) ||
802 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) != MMSYSERR_NOERROR
)
805 if (MSACM_Message(had
, ACMDM_FORMAT_SUGGEST
, (LPARAM
)&adfg
, 0L) == MMSYSERR_NOERROR
) {
806 mmr
= MMSYSERR_NOERROR
;
809 acmDriverClose(had
, 0);
812 mmr
= MSACM_Message(had
, ACMDM_FORMAT_SUGGEST
, (LPARAM
)&adfg
, 0L);
817 /***********************************************************************
818 * acmFormatTagDetailsA (MSACM32.@)
820 MMRESULT WINAPI
acmFormatTagDetailsA(HACMDRIVER had
, PACMFORMATTAGDETAILSA paftda
,
823 ACMFORMATTAGDETAILSW aftdw
;
826 memset(&aftdw
, 0, sizeof(aftdw
));
827 aftdw
.cbStruct
= sizeof(aftdw
);
828 aftdw
.dwFormatTagIndex
= paftda
->dwFormatTagIndex
;
829 aftdw
.dwFormatTag
= paftda
->dwFormatTag
;
831 mmr
= acmFormatTagDetailsW(had
, &aftdw
, fdwDetails
);
832 if (mmr
== MMSYSERR_NOERROR
) {
833 paftda
->dwFormatTag
= aftdw
.dwFormatTag
;
834 paftda
->dwFormatTagIndex
= aftdw
.dwFormatTagIndex
;
835 paftda
->cbFormatSize
= aftdw
.cbFormatSize
;
836 paftda
->fdwSupport
= aftdw
.fdwSupport
;
837 paftda
->cStandardFormats
= aftdw
.cStandardFormats
;
838 WideCharToMultiByte( CP_ACP
, 0, aftdw
.szFormatTag
, -1, paftda
->szFormatTag
,
839 sizeof(paftda
->szFormatTag
), NULL
, NULL
);
844 /***********************************************************************
845 * acmFormatTagDetailsW (MSACM32.@)
847 MMRESULT WINAPI
acmFormatTagDetailsW(HACMDRIVER had
, PACMFORMATTAGDETAILSW paftd
,
850 PWINE_ACMDRIVERID padid
;
851 MMRESULT mmr
= ACMERR_NOTPOSSIBLE
;
853 TRACE("(%p, %p, %d)\n", had
, paftd
, fdwDetails
);
855 if (fdwDetails
& ~(ACM_FORMATTAGDETAILSF_FORMATTAG
|ACM_FORMATTAGDETAILSF_INDEX
|
856 ACM_FORMATTAGDETAILSF_LARGESTSIZE
))
857 return MMSYSERR_INVALFLAG
;
859 switch (fdwDetails
) {
860 case ACM_FORMATTAGDETAILSF_FORMATTAG
:
862 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
863 /* should check for codec only */
864 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
865 MSACM_FindFormatTagInCache(padid
, paftd
->dwFormatTag
, NULL
) &&
866 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
867 mmr
= MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
868 acmDriverClose(had
, 0);
869 if (mmr
== MMSYSERR_NOERROR
) break;
873 PWINE_ACMDRIVER pad
= MSACM_GetDriver(had
);
875 if (pad
&& MSACM_FindFormatTagInCache(pad
->obj
.pACMDriverID
, paftd
->dwFormatTag
, NULL
))
876 mmr
= MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
880 case ACM_FORMATTAGDETAILSF_INDEX
:
882 PWINE_ACMDRIVER pad
= MSACM_GetDriver(had
);
884 if (pad
&& paftd
->dwFormatTagIndex
< pad
->obj
.pACMDriverID
->cFormatTags
)
885 mmr
= MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
889 case ACM_FORMATTAGDETAILSF_LARGESTSIZE
:
891 ACMFORMATTAGDETAILSW tmp
;
892 DWORD ft
= paftd
->dwFormatTag
;
894 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
895 /* should check for codec only */
896 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
897 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
899 memset(&tmp
, 0, sizeof(tmp
));
900 tmp
.cbStruct
= sizeof(tmp
);
901 tmp
.dwFormatTag
= ft
;
903 if (MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
,
904 (LPARAM
)&tmp
, fdwDetails
) == MMSYSERR_NOERROR
) {
905 if (mmr
== ACMERR_NOTPOSSIBLE
||
906 paftd
->cbFormatSize
< tmp
.cbFormatSize
) {
908 mmr
= MMSYSERR_NOERROR
;
911 acmDriverClose(had
, 0);
915 mmr
= MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
920 WARN("Unsupported fdwDetails=%08x\n", fdwDetails
);
921 mmr
= MMSYSERR_ERROR
;
924 if (mmr
== MMSYSERR_NOERROR
&&
925 paftd
->dwFormatTag
== WAVE_FORMAT_PCM
&& paftd
->szFormatTag
[0] == 0)
926 MultiByteToWideChar(CP_ACP
, 0, "PCM", -1, paftd
->szFormatTag
,
927 ARRAY_SIZE(paftd
->szFormatTag
));
932 struct MSACM_FormatTagEnumWtoA_Instance
{
933 PACMFORMATTAGDETAILSA paftda
;
934 DWORD_PTR dwInstance
;
935 ACMFORMATTAGENUMCBA fnCallback
;
938 static BOOL CALLBACK
MSACM_FormatTagEnumCallbackWtoA(HACMDRIVERID hadid
,
939 PACMFORMATTAGDETAILSW paftdw
,
940 DWORD_PTR dwInstance
,
943 struct MSACM_FormatTagEnumWtoA_Instance
* paftei
;
945 paftei
= (struct MSACM_FormatTagEnumWtoA_Instance
*)dwInstance
;
947 paftei
->paftda
->dwFormatTagIndex
= paftdw
->dwFormatTagIndex
;
948 paftei
->paftda
->dwFormatTag
= paftdw
->dwFormatTag
;
949 paftei
->paftda
->cbFormatSize
= paftdw
->cbFormatSize
;
950 paftei
->paftda
->fdwSupport
= paftdw
->fdwSupport
;
951 paftei
->paftda
->cStandardFormats
= paftdw
->cStandardFormats
;
952 WideCharToMultiByte( CP_ACP
, 0, paftdw
->szFormatTag
, -1, paftei
->paftda
->szFormatTag
,
953 sizeof(paftei
->paftda
->szFormatTag
), NULL
, NULL
);
955 return (paftei
->fnCallback
)(hadid
, paftei
->paftda
,
956 paftei
->dwInstance
, fdwSupport
);
959 /***********************************************************************
960 * acmFormatTagEnumA (MSACM32.@)
962 MMRESULT WINAPI
acmFormatTagEnumA(HACMDRIVER had
, PACMFORMATTAGDETAILSA paftda
,
963 ACMFORMATTAGENUMCBA fnCallback
,
964 DWORD_PTR dwInstance
, DWORD fdwEnum
)
966 ACMFORMATTAGDETAILSW aftdw
;
967 struct MSACM_FormatTagEnumWtoA_Instance aftei
;
970 return MMSYSERR_INVALPARAM
;
972 if (paftda
->cbStruct
< sizeof(*paftda
))
973 return MMSYSERR_INVALPARAM
;
976 return MMSYSERR_INVALFLAG
;
978 memset(&aftdw
, 0, sizeof(aftdw
));
979 aftdw
.cbStruct
= sizeof(aftdw
);
980 aftdw
.dwFormatTagIndex
= paftda
->dwFormatTagIndex
;
981 aftdw
.dwFormatTag
= paftda
->dwFormatTag
;
983 aftei
.paftda
= paftda
;
984 aftei
.dwInstance
= dwInstance
;
985 aftei
.fnCallback
= fnCallback
;
987 return acmFormatTagEnumW(had
, &aftdw
, MSACM_FormatTagEnumCallbackWtoA
,
988 (DWORD_PTR
)&aftei
, fdwEnum
);
991 /***********************************************************************
992 * acmFormatTagEnumW (MSACM32.@)
994 MMRESULT WINAPI
acmFormatTagEnumW(HACMDRIVER had
, PACMFORMATTAGDETAILSW paftd
,
995 ACMFORMATTAGENUMCBW fnCallback
,
996 DWORD_PTR dwInstance
, DWORD fdwEnum
)
998 PWINE_ACMDRIVERID padid
;
1000 BOOL bPcmDone
= FALSE
;
1002 TRACE("(%p, %p, %p, %ld, %d)\n",
1003 had
, paftd
, fnCallback
, dwInstance
, fdwEnum
);
1006 return MMSYSERR_INVALPARAM
;
1008 if (paftd
->cbStruct
< sizeof(*paftd
))
1009 return MMSYSERR_INVALPARAM
;
1012 return MMSYSERR_INVALFLAG
;
1014 /* (WS) MSDN info page says that if had != 0, then we should find
1015 * the specific driver to get its tags from. Therefore I'm removing
1016 * the FIXME call and adding a search block below. It also seems
1017 * that the lack of this functionality was the responsible for
1018 * codecs to be multiply and incorrectly listed.
1021 /* if (had) FIXME("had != NULL, not supported\n"); */
1024 if (acmDriverID((HACMOBJ
)had
, (HACMDRIVERID
*)&padid
, 0) != MMSYSERR_NOERROR
)
1025 return MMSYSERR_INVALHANDLE
;
1027 for (i
= 0; i
< padid
->cFormatTags
; i
++) {
1028 paftd
->dwFormatTagIndex
= i
;
1029 if (MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
,
1030 (LPARAM
)paftd
, ACM_FORMATTAGDETAILSF_INDEX
) == MMSYSERR_NOERROR
) {
1031 if (paftd
->dwFormatTag
== WAVE_FORMAT_PCM
) {
1032 if (paftd
->szFormatTag
[0] == 0)
1033 MultiByteToWideChar(CP_ACP
, 0, "PCM", -1, paftd
->szFormatTag
,
1034 ARRAY_SIZE(paftd
->szFormatTag
));
1035 /* (WS) I'm preserving this PCM hack since it seems to be
1036 * correct. Please notice this block was borrowed from
1039 if (bPcmDone
) continue;
1042 if (!(fnCallback
)((HACMDRIVERID
)padid
, paftd
, dwInstance
, padid
->fdwSupport
))
1043 return MMSYSERR_NOERROR
;
1047 /* if had==0 then search for the first suitable driver */
1049 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
1050 /* should check for codec only */
1051 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
1052 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == MMSYSERR_NOERROR
) {
1053 for (i
= 0; i
< padid
->cFormatTags
; i
++) {
1054 paftd
->dwFormatTagIndex
= i
;
1055 if (MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
,
1056 (LPARAM
)paftd
, ACM_FORMATTAGDETAILSF_INDEX
) == MMSYSERR_NOERROR
) {
1057 if (paftd
->dwFormatTag
== WAVE_FORMAT_PCM
) {
1058 if (paftd
->szFormatTag
[0] == 0)
1059 MultiByteToWideChar(CP_ACP
, 0, "PCM", -1, paftd
->szFormatTag
,
1060 ARRAY_SIZE(paftd
->szFormatTag
));
1061 /* FIXME (EPP): I'm not sure this is the correct
1062 * algorithm (should make more sense to apply the same
1063 * for all already loaded formats, but this will do
1066 if (bPcmDone
) continue;
1069 if (!(fnCallback
)((HACMDRIVERID
)padid
, paftd
, dwInstance
, padid
->fdwSupport
)) {
1070 acmDriverClose(had
, 0);
1071 return MMSYSERR_NOERROR
;
1075 acmDriverClose(had
, 0);
1079 return MMSYSERR_NOERROR
;