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
24 struct MSACM_FillFormatData
{
26 #define WINE_ACMFF_TAG 0
27 #define WINE_ACMFF_FORMAT 1
28 #define WINE_ACMFF_WFX 2
30 WCHAR szFormatTag
[ACMFORMATTAGDETAILS_FORMATTAG_CHARS
];
31 PACMFORMATCHOOSEW afc
;
35 static BOOL CALLBACK
MSACM_FillFormatTagsCB(HACMDRIVERID hadid
,
36 PACMFORMATTAGDETAILSW paftd
,
40 struct MSACM_FillFormatData
* affd
= (struct MSACM_FillFormatData
*)dwInstance
;
44 if (paftd
->cStandardFormats
> 0)
46 if (SendDlgItemMessageW(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
47 CB_FINDSTRINGEXACT
, -1,
48 (LPARAM
)paftd
->szFormatTag
) == CB_ERR
)
50 int index
= SendDlgItemMessageW(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
51 CB_ADDSTRING
, 0, (LPARAM
)paftd
->szFormatTag
);
52 if (((affd
->afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT
) &&
53 (paftd
->dwFormatTag
== affd
->afc
->pwfx
->wFormatTag
)) ||
54 (!(affd
->afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT
) &&
55 (paftd
->dwFormatTag
== WAVE_FORMAT_PCM
)))
56 SendDlgItemMessageW(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
57 CB_SETCURSEL
, index
, 0);
61 case WINE_ACMFF_FORMAT
:
62 if (strcmpW(affd
->szFormatTag
, paftd
->szFormatTag
) == 0) {
65 if (acmDriverOpen(&had
, hadid
, 0) == MMSYSERR_NOERROR
) {
66 ACMFORMATDETAILSW afd
= {0};
69 WCHAR buffer
[ACMFORMATDETAILS_FORMAT_CHARS
+16];
71 afd
.cbStruct
= sizeof(afd
);
72 afd
.dwFormatTag
= paftd
->dwFormatTag
;
73 afd
.pwfx
= HeapAlloc(MSACM_hHeap
, 0, paftd
->cbFormatSize
);
74 if (!afd
.pwfx
) return FALSE
;
75 afd
.pwfx
->wFormatTag
= paftd
->dwFormatTag
;
76 if (paftd
->dwFormatTag
!= WAVE_FORMAT_PCM
)
77 afd
.pwfx
->cbSize
= paftd
->cbFormatSize
- sizeof(WAVEFORMATEX
);
78 afd
.cbwfx
= paftd
->cbFormatSize
;
80 for (i
= 0; i
< paftd
->cStandardFormats
; i
++) {
81 static const WCHAR fmtW
[] = {'%','d',' ','K','o','/','s','\0'};
84 afd
.dwFormatIndex
= i
;
86 mmr
= acmFormatDetailsW(had
, &afd
, ACM_FORMATDETAILSF_INDEX
);
87 if (mmr
== MMSYSERR_NOERROR
) {
88 lstrcpynW(buffer
, afd
.szFormat
, ACMFORMATTAGDETAILS_FORMATTAG_CHARS
+ 1);
89 len
= strlenW(buffer
);
90 for (j
= len
; j
< ACMFORMATTAGDETAILS_FORMATTAG_CHARS
; j
++)
92 wsprintfW(buffer
+ ACMFORMATTAGDETAILS_FORMATTAG_CHARS
,
93 fmtW
, (afd
.pwfx
->nAvgBytesPerSec
+ 512) / 1024);
94 index
= SendDlgItemMessageW(affd
->hWnd
,
95 IDD_ACMFORMATCHOOSE_CMB_FORMAT
,
96 CB_ADDSTRING
, 0, (LPARAM
)buffer
);
97 if ((affd
->afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT
) &&
98 affd
->afc
->cbwfx
>= paftd
->cbFormatSize
&&
99 !memcmp(afd
.pwfx
, affd
->afc
->pwfx
, paftd
->cbFormatSize
))
100 SendDlgItemMessageW(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
,
101 CB_SETCURSEL
, index
, 0);
104 acmDriverClose(had
, 0);
105 HeapFree(MSACM_hHeap
, 0, afd
.pwfx
);
110 if (strcmpW(affd
->szFormatTag
, paftd
->szFormatTag
) == 0) {
113 if (acmDriverOpen(&had
, hadid
, 0) == MMSYSERR_NOERROR
) {
114 ACMFORMATDETAILSW afd
= {0};
116 afd
.cbStruct
= sizeof(afd
);
117 afd
.dwFormatTag
= paftd
->dwFormatTag
;
118 afd
.pwfx
= affd
->afc
->pwfx
;
119 afd
.cbwfx
= affd
->afc
->cbwfx
;
121 afd
.dwFormatIndex
= SendDlgItemMessageW(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
,
123 affd
->ret
= acmFormatDetailsW(had
, &afd
, ACM_FORMATDETAILSF_INDEX
);
124 acmDriverClose(had
, 0);
130 FIXME("Unknown mode (%d)\n", affd
->mode
);
136 static BOOL
MSACM_FillFormatTags(HWND hWnd
, PACMFORMATCHOOSEW afc
)
138 ACMFORMATTAGDETAILSW aftd
;
139 struct MSACM_FillFormatData affd
;
141 memset(&aftd
, 0, sizeof(aftd
));
142 aftd
.cbStruct
= sizeof(aftd
);
145 affd
.mode
= WINE_ACMFF_TAG
;
148 acmFormatTagEnumW(NULL
, &aftd
, MSACM_FillFormatTagsCB
, (DWORD_PTR
)&affd
, 0);
149 if (SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
, CB_GETCURSEL
, 0, 0) == CB_ERR
)
150 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
, CB_SETCURSEL
, 0, 0);
154 static BOOL
MSACM_FillFormat(HWND hWnd
, PACMFORMATCHOOSEW afc
)
156 ACMFORMATTAGDETAILSW aftd
;
157 struct MSACM_FillFormatData affd
;
159 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
, CB_RESETCONTENT
, 0, 0);
161 memset(&aftd
, 0, sizeof(aftd
));
162 aftd
.cbStruct
= sizeof(aftd
);
165 affd
.mode
= WINE_ACMFF_FORMAT
;
167 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
169 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
171 (LPARAM
)affd
.szFormatTag
);
173 acmFormatTagEnumW(NULL
, &aftd
, MSACM_FillFormatTagsCB
, (DWORD_PTR
)&affd
, 0);
174 if (SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
, CB_GETCURSEL
, 0, 0) == CB_ERR
)
175 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
, CB_SETCURSEL
, 0, 0);
179 static MMRESULT
MSACM_GetWFX(HWND hWnd
, PACMFORMATCHOOSEW afc
)
181 ACMFORMATTAGDETAILSW aftd
;
182 struct MSACM_FillFormatData affd
;
184 memset(&aftd
, 0, sizeof(aftd
));
185 aftd
.cbStruct
= sizeof(aftd
);
188 affd
.mode
= WINE_ACMFF_WFX
;
190 affd
.ret
= MMSYSERR_NOERROR
;
191 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
193 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
195 (LPARAM
)affd
.szFormatTag
);
197 acmFormatTagEnumW(NULL
, &aftd
, MSACM_FillFormatTagsCB
, (DWORD_PTR
)&affd
, 0);
201 static const WCHAR fmt_prop
[] = {'a','c','m','p','r','o','p','\0'};
203 static INT_PTR CALLBACK
FormatChooseDlgProc(HWND hWnd
, UINT msg
,
204 WPARAM wParam
, LPARAM lParam
)
206 PACMFORMATCHOOSEW afc
= (PACMFORMATCHOOSEW
)GetPropW(hWnd
, fmt_prop
);
208 TRACE("hwnd=%p msg=%i 0x%08lx 0x%08lx\n", hWnd
, msg
, wParam
, lParam
);
212 afc
= (PACMFORMATCHOOSEW
)lParam
;
213 SetPropW(hWnd
, fmt_prop
, (HANDLE
)afc
);
214 MSACM_FillFormatTags(hWnd
, afc
);
215 MSACM_FillFormat(hWnd
, afc
);
216 if ((afc
->fdwStyle
& ~(ACMFORMATCHOOSE_STYLEF_CONTEXTHELP
|
217 ACMFORMATCHOOSE_STYLEF_SHOWHELP
|
218 ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT
|
219 ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATEHANDLE
|
220 ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATE
)) != 0)
221 FIXME("Unsupported style %08x\n", afc
->fdwStyle
);
222 if (!(afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_SHOWHELP
))
223 ShowWindow(GetDlgItem(hWnd
, IDD_ACMFORMATCHOOSE_BTN_HELP
), SW_HIDE
);
227 switch (LOWORD(wParam
)) {
229 EndDialog(hWnd
, MSACM_GetWFX(hWnd
, afc
));
232 EndDialog(hWnd
, ACMERR_CANCELED
);
234 case IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
:
235 switch (HIWORD(wParam
)) {
237 MSACM_FillFormat(hWnd
, afc
);
240 TRACE("Dropped dlgNotif (fmtTag): 0x%08x 0x%08lx\n",
241 HIWORD(wParam
), lParam
);
245 case IDD_ACMFORMATCHOOSE_BTN_HELP
:
246 if (afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_SHOWHELP
)
247 SendMessageW(afc
->hwndOwner
,
248 RegisterWindowMessageW(ACMHELPMSGSTRINGW
), 0L, 0L);
252 TRACE("Dropped dlgCmd: ctl=%d ntf=0x%04x 0x%08lx\n",
253 LOWORD(wParam
), HIWORD(wParam
), lParam
);
258 if (afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_CONTEXTHELP
)
259 SendMessageW(afc
->hwndOwner
,
260 RegisterWindowMessageW(ACMHELPMSGCONTEXTMENUW
),
263 #if defined(WM_CONTEXTHELP)
265 if (afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_CONTEXTHELP
)
266 SendMessageW(afc
->hwndOwner
,
267 RegisterWindowMessageW(ACMHELPMSGCONTEXTHELPW
),
272 TRACE("Dropped dlgMsg: hwnd=%p msg=%i 0x%08lx 0x%08lx\n",
273 hWnd
, msg
, wParam
, lParam
);
279 /***********************************************************************
280 * acmFormatChooseA (MSACM32.@)
282 MMRESULT WINAPI
acmFormatChooseA(PACMFORMATCHOOSEA pafmtc
)
284 ACMFORMATCHOOSEW afcw
;
291 if (pafmtc
->cbStruct
< sizeof(ACMFORMATCHOOSEA
))
292 return MMSYSERR_INVALPARAM
;
294 afcw
.cbStruct
= sizeof(afcw
);
295 afcw
.fdwStyle
= pafmtc
->fdwStyle
;
296 afcw
.hwndOwner
= pafmtc
->hwndOwner
;
297 afcw
.pwfx
= pafmtc
->pwfx
;
298 afcw
.cbwfx
= pafmtc
->cbwfx
;
299 if (pafmtc
->pszTitle
)
301 sz
= MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszTitle
, -1, NULL
, 0);
302 if (!(title
= HeapAlloc(GetProcessHeap(), 0, sz
* sizeof(WCHAR
))))
304 ret
= MMSYSERR_NOMEM
;
307 MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszTitle
, -1, title
, sz
);
309 afcw
.pszTitle
= title
;
312 sz
= MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszName
, -1, NULL
, 0);
313 if (!(name
= HeapAlloc(GetProcessHeap(), 0, sz
* sizeof(WCHAR
))))
315 ret
= MMSYSERR_NOMEM
;
318 MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszName
, -1, name
, sz
);
321 afcw
.cchName
= pafmtc
->cchName
;
322 afcw
.fdwEnum
= pafmtc
->fdwEnum
;
323 afcw
.pwfxEnum
= pafmtc
->pwfxEnum
;
324 afcw
.hInstance
= pafmtc
->hInstance
;
325 if (pafmtc
->pszTemplateName
)
327 sz
= MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszTemplateName
, -1, NULL
, 0);
328 if (!(templ
= HeapAlloc(GetProcessHeap(), 0, sz
* sizeof(WCHAR
))))
330 ret
= MMSYSERR_NOMEM
;
333 MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszTemplateName
, -1, templ
, sz
);
335 afcw
.pszTemplateName
= templ
;
336 /* FIXME: hook procs not supported yet */
339 FIXME("Unsupported hook procs\n");
340 ret
= MMSYSERR_NOTSUPPORTED
;
343 ret
= acmFormatChooseW(&afcw
);
344 if (ret
== MMSYSERR_NOERROR
)
346 WideCharToMultiByte(CP_ACP
, 0, afcw
.szFormatTag
, -1, pafmtc
->szFormatTag
, sizeof(pafmtc
->szFormatTag
),
348 WideCharToMultiByte(CP_ACP
, 0, afcw
.szFormat
, -1, pafmtc
->szFormat
, sizeof(pafmtc
->szFormat
),
351 WideCharToMultiByte(CP_ACP
, 0, afcw
.pszName
, -1, pafmtc
->pszName
, pafmtc
->cchName
, NULL
, NULL
);
354 HeapFree(GetProcessHeap(), 0, title
);
355 HeapFree(GetProcessHeap(), 0, name
);
356 HeapFree(GetProcessHeap(), 0, templ
);
360 /***********************************************************************
361 * acmFormatChooseW (MSACM32.@)
363 MMRESULT WINAPI
acmFormatChooseW(PACMFORMATCHOOSEW pafmtc
)
365 if (pafmtc
->cbStruct
< sizeof(ACMFORMATCHOOSEW
))
366 return MMSYSERR_INVALPARAM
;
369 return MMSYSERR_INVALPARAM
;
371 if (pafmtc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATEHANDLE
)
372 return DialogBoxIndirectParamW(MSACM_hInstance32
, (LPCDLGTEMPLATEW
)pafmtc
->hInstance
,
373 pafmtc
->hwndOwner
, FormatChooseDlgProc
, (LPARAM
)pafmtc
);
375 if (pafmtc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATE
)
376 return DialogBoxParamW(pafmtc
->hInstance
, pafmtc
->pszTemplateName
,
377 pafmtc
->hwndOwner
, FormatChooseDlgProc
, (LPARAM
)pafmtc
);
379 return DialogBoxParamW(MSACM_hInstance32
, MAKEINTRESOURCEW(DLG_ACMFORMATCHOOSE_ID
),
380 pafmtc
->hwndOwner
, FormatChooseDlgProc
, (LPARAM
)pafmtc
);
383 /***********************************************************************
384 * acmFormatDetailsA (MSACM32.@)
386 MMRESULT WINAPI
acmFormatDetailsA(HACMDRIVER had
, PACMFORMATDETAILSA pafd
,
389 ACMFORMATDETAILSW afdw
;
393 return MMSYSERR_INVALPARAM
;
395 memset(&afdw
, 0, sizeof(afdw
));
396 afdw
.cbStruct
= sizeof(afdw
);
397 afdw
.dwFormatIndex
= pafd
->dwFormatIndex
;
398 afdw
.dwFormatTag
= pafd
->dwFormatTag
;
399 afdw
.fdwSupport
= pafd
->fdwSupport
;
400 afdw
.pwfx
= pafd
->pwfx
;
401 afdw
.cbwfx
= pafd
->cbwfx
;
403 mmr
= acmFormatDetailsW(had
, &afdw
, fdwDetails
);
404 if (mmr
== MMSYSERR_NOERROR
) {
405 pafd
->dwFormatTag
= afdw
.dwFormatTag
;
406 pafd
->fdwSupport
= afdw
.fdwSupport
;
407 WideCharToMultiByte( CP_ACP
, 0, afdw
.szFormat
, -1,
408 pafd
->szFormat
, sizeof(pafd
->szFormat
), NULL
, NULL
);
413 /***********************************************************************
414 * acmFormatDetailsW (MSACM32.@)
416 MMRESULT WINAPI
acmFormatDetailsW(HACMDRIVER had
, PACMFORMATDETAILSW pafd
, DWORD fdwDetails
)
419 static const WCHAR fmt1
[] = {'%','d',' ','H','z',0};
420 static const WCHAR fmt2
[] = {';',' ','%','d',' ','b','i','t','s',0};
421 ACMFORMATTAGDETAILSW aftd
= {0};
423 TRACE("(%p, %p, %d)\n", had
, pafd
, fdwDetails
);
426 return MMSYSERR_INVALPARAM
;
428 if (pafd
->cbStruct
< sizeof(*pafd
)) return MMSYSERR_INVALPARAM
;
431 return MMSYSERR_INVALPARAM
;
433 if (pafd
->cbwfx
< sizeof(PCMWAVEFORMAT
))
434 return MMSYSERR_INVALPARAM
;
436 if (pafd
->fdwSupport
)
437 return MMSYSERR_INVALPARAM
;
439 if (pafd
->dwFormatTag
== WAVE_FORMAT_UNKNOWN
)
440 return MMSYSERR_INVALPARAM
;
442 switch (fdwDetails
) {
443 case ACM_FORMATDETAILSF_FORMAT
:
444 if (pafd
->dwFormatTag
!= pafd
->pwfx
->wFormatTag
) {
445 mmr
= MMSYSERR_INVALPARAM
;
449 PWINE_ACMDRIVERID padid
;
451 mmr
= ACMERR_NOTPOSSIBLE
;
452 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
453 /* should check for codec only */
454 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
455 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
456 mmr
= MSACM_Message(had
, ACMDM_FORMAT_DETAILS
, (LPARAM
)pafd
, fdwDetails
);
457 acmDriverClose(had
, 0);
458 if (mmr
== MMSYSERR_NOERROR
) break;
462 mmr
= MSACM_Message(had
, ACMDM_FORMAT_DETAILS
, (LPARAM
)pafd
, fdwDetails
);
465 case ACM_FORMATDETAILSF_INDEX
:
466 aftd
.cbStruct
= sizeof(aftd
);
467 aftd
.dwFormatTag
= pafd
->dwFormatTag
;
468 mmr
= acmFormatTagDetailsW(had
, &aftd
, ACM_FORMATTAGDETAILSF_FORMATTAG
);
469 if (mmr
!= MMSYSERR_NOERROR
)
471 if (pafd
->dwFormatIndex
>= aftd
.cStandardFormats
)
473 mmr
= MMSYSERR_INVALPARAM
;
476 mmr
= MSACM_Message(had
, ACMDM_FORMAT_DETAILS
, (LPARAM
)pafd
, fdwDetails
);
479 WARN("Unknown fdwDetails %08x\n", fdwDetails
);
480 mmr
= MMSYSERR_INVALFLAG
;
484 if (mmr
== MMSYSERR_NOERROR
&& pafd
->szFormat
[0] == 0) {
485 wsprintfW(pafd
->szFormat
, fmt1
, pafd
->pwfx
->nSamplesPerSec
);
486 if (pafd
->pwfx
->wBitsPerSample
) {
487 wsprintfW(pafd
->szFormat
+ lstrlenW(pafd
->szFormat
), fmt2
,
488 pafd
->pwfx
->wBitsPerSample
);
490 MultiByteToWideChar( CP_ACP
, 0, (pafd
->pwfx
->nChannels
== 1) ? "; Mono" : "; Stereo", -1,
491 pafd
->szFormat
+ strlenW(pafd
->szFormat
),
492 sizeof(pafd
->szFormat
)/sizeof(WCHAR
) - strlenW(pafd
->szFormat
) );
495 TRACE("=> %d\n", mmr
);
499 struct MSACM_FormatEnumWtoA_Instance
{
500 PACMFORMATDETAILSA pafda
;
501 DWORD_PTR dwInstance
;
502 ACMFORMATENUMCBA fnCallback
;
505 static BOOL CALLBACK
MSACM_FormatEnumCallbackWtoA(HACMDRIVERID hadid
,
506 PACMFORMATDETAILSW pafdw
,
507 DWORD_PTR dwInstance
,
510 struct MSACM_FormatEnumWtoA_Instance
* pafei
;
512 pafei
= (struct MSACM_FormatEnumWtoA_Instance
*)dwInstance
;
514 pafei
->pafda
->dwFormatIndex
= pafdw
->dwFormatIndex
;
515 pafei
->pafda
->dwFormatTag
= pafdw
->dwFormatTag
;
516 pafei
->pafda
->fdwSupport
= pafdw
->fdwSupport
;
517 WideCharToMultiByte( CP_ACP
, 0, pafdw
->szFormat
, -1,
518 pafei
->pafda
->szFormat
, sizeof(pafei
->pafda
->szFormat
), NULL
, NULL
);
520 return (pafei
->fnCallback
)(hadid
, pafei
->pafda
,
521 pafei
->dwInstance
, fdwSupport
);
524 /***********************************************************************
525 * acmFormatEnumA (MSACM32.@)
527 MMRESULT WINAPI
acmFormatEnumA(HACMDRIVER had
, PACMFORMATDETAILSA pafda
,
528 ACMFORMATENUMCBA fnCallback
,
529 DWORD_PTR dwInstance
, DWORD fdwEnum
)
531 ACMFORMATDETAILSW afdw
;
532 struct MSACM_FormatEnumWtoA_Instance afei
;
535 return MMSYSERR_INVALPARAM
;
538 return MMSYSERR_INVALPARAM
;
540 if (pafda
->cbStruct
< sizeof(*pafda
))
541 return MMSYSERR_INVALPARAM
;
543 memset(&afdw
, 0, sizeof(afdw
));
544 afdw
.cbStruct
= sizeof(afdw
);
545 afdw
.dwFormatIndex
= pafda
->dwFormatIndex
;
546 afdw
.dwFormatTag
= pafda
->dwFormatTag
;
547 afdw
.fdwSupport
= pafda
->fdwSupport
;
548 afdw
.pwfx
= pafda
->pwfx
;
549 afdw
.cbwfx
= pafda
->cbwfx
;
552 afei
.dwInstance
= dwInstance
;
553 afei
.fnCallback
= fnCallback
;
555 return acmFormatEnumW(had
, &afdw
, MSACM_FormatEnumCallbackWtoA
,
556 (DWORD_PTR
)&afei
, fdwEnum
);
559 /***********************************************************************
560 * acmFormatEnumW (MSACM32.@)
562 static BOOL
MSACM_FormatEnumHelper(PWINE_ACMDRIVERID padid
, HACMDRIVER had
,
563 PACMFORMATDETAILSW pafd
, PWAVEFORMATEX pwfxRef
,
564 ACMFORMATENUMCBW fnCallback
,
565 DWORD_PTR dwInstance
, DWORD fdwEnum
)
567 ACMFORMATTAGDETAILSW aftd
;
570 if (fdwEnum
& ACM_FORMATENUMF_SUGGEST
) {
572 ACMDRVFORMATSUGGEST adfs
;
573 pafd
->dwFormatIndex
= 0;
574 memset(&aftd
, 0, sizeof(aftd
));
575 aftd
.cbStruct
= sizeof(aftd
);
576 memset(&adfs
, 0, sizeof(adfs
));
577 adfs
.cbStruct
= sizeof(adfs
);
579 for (i
= 0; i
< padid
->cFormatTags
; i
++) {
580 aftd
.dwFormatTag
= i
;
581 pafd
->dwFormatTag
= aftd
.dwFormatTag
;
582 pafd
->pwfx
->wFormatTag
= pafd
->dwFormatTag
;
584 if (acmFormatTagDetailsW(had
, &aftd
, ACM_FORMATTAGDETAILSF_INDEX
) != MMSYSERR_NOERROR
)
587 adfs
.cbwfxSrc
= aftd
.cbFormatSize
;
588 adfs
.cbwfxDst
= aftd
.cbFormatSize
;
589 adfs
.pwfxSrc
= pwfxRef
;
590 adfs
.pwfxDst
= pafd
->pwfx
;
591 pafd
->fdwSupport
= padid
->fdwSupport
;
593 if ((fdwEnum
& ACM_FORMATENUMF_WFORMATTAG
) &&
594 aftd
.dwFormatTag
!= pwfxRef
->wFormatTag
)
597 if ((fdwEnum
& ACM_FORMATENUMF_HARDWARE
) &&
598 !(pafd
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_HARDWARE
))
601 hdrvr
= OpenDriver(padid
->pszFileName
,0,0);
602 SendDriverMessage(hdrvr
,ACMDM_FORMAT_SUGGEST
,(LPARAM
)&adfs
,(fdwEnum
& 0x000000FFL
));
604 if (acmFormatDetailsW(had
, pafd
, ACM_FORMATDETAILSF_FORMAT
) != MMSYSERR_NOERROR
)
607 pafd
->cbwfx
= sizeof(*(pafd
->pwfx
));
609 if (!(fnCallback
)((HACMDRIVERID
)padid
, pafd
, dwInstance
, padid
->fdwSupport
))
613 for (i
= 0; i
< padid
->cFormatTags
; i
++) {
614 memset(&aftd
, 0, sizeof(aftd
));
615 aftd
.cbStruct
= sizeof(aftd
);
616 aftd
.dwFormatTagIndex
= i
;
617 if (acmFormatTagDetailsW(had
, &aftd
, ACM_FORMATTAGDETAILSF_INDEX
) != MMSYSERR_NOERROR
)
620 if ((fdwEnum
& ACM_FORMATENUMF_WFORMATTAG
) && aftd
.dwFormatTag
!= pwfxRef
->wFormatTag
)
623 for (j
= 0; j
< aftd
.cStandardFormats
; j
++) {
624 pafd
->dwFormatIndex
= j
;
625 pafd
->dwFormatTag
= aftd
.dwFormatTag
;
626 pafd
->fdwSupport
= 0;
627 if (acmFormatDetailsW(had
, pafd
, ACM_FORMATDETAILSF_INDEX
) != MMSYSERR_NOERROR
)
630 if ((fdwEnum
& ACM_FORMATENUMF_NCHANNELS
) &&
631 pafd
->pwfx
->nChannels
!= pwfxRef
->nChannels
)
633 if ((fdwEnum
& ACM_FORMATENUMF_NSAMPLESPERSEC
) &&
634 pafd
->pwfx
->nSamplesPerSec
!= pwfxRef
->nSamplesPerSec
)
636 if ((fdwEnum
& ACM_FORMATENUMF_WBITSPERSAMPLE
) &&
637 pafd
->pwfx
->wBitsPerSample
!= pwfxRef
->wBitsPerSample
)
639 if ((fdwEnum
& ACM_FORMATENUMF_HARDWARE
) &&
640 !(pafd
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_HARDWARE
))
643 /* more checks to be done on fdwEnum */
645 if (!(fnCallback
)((HACMDRIVERID
)padid
, pafd
, dwInstance
, padid
->fdwSupport
))
648 /* the "formats" used by the filters are also reported */
654 /**********************************************************************/
656 MMRESULT WINAPI
acmFormatEnumW(HACMDRIVER had
, PACMFORMATDETAILSW pafd
,
657 ACMFORMATENUMCBW fnCallback
,
658 DWORD_PTR dwInstance
, DWORD fdwEnum
)
660 PWINE_ACMDRIVERID padid
;
666 TRACE("(%p, %p, %p, %ld, %d)\n",
667 had
, pafd
, fnCallback
, dwInstance
, fdwEnum
);
670 return MMSYSERR_INVALPARAM
;
673 return MMSYSERR_INVALPARAM
;
675 if (pafd
->cbStruct
< sizeof(*pafd
))
676 return MMSYSERR_INVALPARAM
;
678 if (pafd
->fdwSupport
)
679 return MMSYSERR_INVALPARAM
;
682 return MMSYSERR_INVALPARAM
;
684 if (fdwEnum
& (ACM_FORMATENUMF_WFORMATTAG
|ACM_FORMATENUMF_NCHANNELS
|
685 ACM_FORMATENUMF_NSAMPLESPERSEC
|ACM_FORMATENUMF_WBITSPERSAMPLE
|
686 ACM_FORMATENUMF_CONVERT
|ACM_FORMATENUMF_SUGGEST
))
687 wfxRef
= *pafd
->pwfx
;
689 if ((fdwEnum
& ACM_FORMATENUMF_HARDWARE
) &&
690 !(fdwEnum
& (ACM_FORMATENUMF_INPUT
|ACM_FORMATENUMF_OUTPUT
)))
691 return MMSYSERR_INVALPARAM
;
693 if ((fdwEnum
& ACM_FORMATENUMF_WFORMATTAG
) &&
694 (pafd
->dwFormatTag
!= pafd
->pwfx
->wFormatTag
))
695 return MMSYSERR_INVALPARAM
;
697 if (fdwEnum
& (ACM_FORMATENUMF_CONVERT
|ACM_FORMATENUMF_INPUT
|ACM_FORMATENUMF_OUTPUT
))
698 FIXME("Unsupported fdwEnum values %08x\n", fdwEnum
);
700 mmr
= acmMetrics((HACMOBJ
)had
, ACM_METRIC_MAX_SIZE_FORMAT
, &cbwfxMax
);
701 if (mmr
!= MMSYSERR_NOERROR
)
703 if (pafd
->cbwfx
< cbwfxMax
)
704 return MMSYSERR_INVALPARAM
;
709 if (acmDriverID((HACMOBJ
)had
, &hadid
, 0) != MMSYSERR_NOERROR
)
710 return MMSYSERR_INVALHANDLE
;
711 MSACM_FormatEnumHelper(MSACM_GetDriverID(hadid
), had
, pafd
, &wfxRef
,
712 fnCallback
, dwInstance
, fdwEnum
);
713 return MMSYSERR_NOERROR
;
715 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
716 /* should check for codec only */
717 if ((padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) ||
718 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) != MMSYSERR_NOERROR
)
720 ret
= MSACM_FormatEnumHelper(padid
, had
, pafd
, &wfxRef
,
721 fnCallback
, dwInstance
, fdwEnum
);
722 acmDriverClose(had
, 0);
725 return MMSYSERR_NOERROR
;
728 /***********************************************************************
729 * acmFormatSuggest (MSACM32.@)
731 MMRESULT WINAPI
acmFormatSuggest(HACMDRIVER had
, PWAVEFORMATEX pwfxSrc
,
732 PWAVEFORMATEX pwfxDst
, DWORD cbwfxDst
, DWORD fdwSuggest
)
734 ACMFORMATTAGDETAILSW aftd
= {0};
735 ACMDRVFORMATSUGGEST adfg
;
738 TRACE("(%p, %p, %p, %d, %d)\n",
739 had
, pwfxSrc
, pwfxDst
, cbwfxDst
, fdwSuggest
);
741 if (!pwfxSrc
|| !pwfxDst
)
742 return MMSYSERR_INVALPARAM
;
744 if (fdwSuggest
& ~(ACM_FORMATSUGGESTF_NCHANNELS
|ACM_FORMATSUGGESTF_NSAMPLESPERSEC
|
745 ACM_FORMATSUGGESTF_WBITSPERSAMPLE
|ACM_FORMATSUGGESTF_WFORMATTAG
))
746 return MMSYSERR_INVALFLAG
;
748 /* if we were given PCM, try to convert to PCM */
749 if (pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
&& !had
&&
750 !(fdwSuggest
& ACM_FORMATSUGGESTF_WFORMATTAG
))
752 ACMFORMATDETAILSW afd
= {0};
753 afd
.cbStruct
= sizeof(afd
);
754 afd
.dwFormatTag
= WAVE_FORMAT_PCM
;
756 afd
.cbwfx
= sizeof(PCMWAVEFORMAT
);
757 if (!acmFormatDetailsW(had
, &afd
, ACM_FORMATDETAILSF_FORMAT
))
759 memcpy(pwfxDst
, pwfxSrc
, sizeof(PCMWAVEFORMAT
));
760 return MMSYSERR_NOERROR
;
764 aftd
.cbStruct
= sizeof(aftd
);
765 if (fdwSuggest
& ACM_FORMATSUGGESTF_WFORMATTAG
)
766 aftd
.dwFormatTag
= pwfxDst
->wFormatTag
;
767 mmr
= acmFormatTagDetailsW(had
, &aftd
, ACM_FORMATTAGDETAILSF_LARGESTSIZE
);
768 if ((fdwSuggest
& ACM_FORMATSUGGESTF_WFORMATTAG
) && mmr
== ACMERR_NOTPOSSIBLE
)
769 return ACMERR_NOTPOSSIBLE
;
771 if (cbwfxDst
< aftd
.cbFormatSize
)
772 return MMSYSERR_INVALPARAM
;
774 adfg
.cbStruct
= sizeof(adfg
);
775 adfg
.fdwSuggest
= fdwSuggest
;
776 adfg
.pwfxSrc
= pwfxSrc
;
777 adfg
.cbwfxSrc
= (pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
) ?
778 sizeof(WAVEFORMATEX
) : (sizeof(WAVEFORMATEX
) + pwfxSrc
->cbSize
);
779 adfg
.pwfxDst
= pwfxDst
;
780 adfg
.cbwfxDst
= cbwfxDst
;
783 PWINE_ACMDRIVERID padid
;
785 /* MS doc says: ACM finds the best suggestion.
786 * Well, first found will be the "best"
788 mmr
= ACMERR_NOTPOSSIBLE
;
789 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
790 /* should check for codec only */
791 if ((padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) ||
792 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) != MMSYSERR_NOERROR
)
795 if (MSACM_Message(had
, ACMDM_FORMAT_SUGGEST
, (LPARAM
)&adfg
, 0L) == MMSYSERR_NOERROR
) {
796 mmr
= MMSYSERR_NOERROR
;
799 acmDriverClose(had
, 0);
802 mmr
= MSACM_Message(had
, ACMDM_FORMAT_SUGGEST
, (LPARAM
)&adfg
, 0L);
807 /***********************************************************************
808 * acmFormatTagDetailsA (MSACM32.@)
810 MMRESULT WINAPI
acmFormatTagDetailsA(HACMDRIVER had
, PACMFORMATTAGDETAILSA paftda
,
813 ACMFORMATTAGDETAILSW aftdw
;
816 memset(&aftdw
, 0, sizeof(aftdw
));
817 aftdw
.cbStruct
= sizeof(aftdw
);
818 aftdw
.dwFormatTagIndex
= paftda
->dwFormatTagIndex
;
819 aftdw
.dwFormatTag
= paftda
->dwFormatTag
;
821 mmr
= acmFormatTagDetailsW(had
, &aftdw
, fdwDetails
);
822 if (mmr
== MMSYSERR_NOERROR
) {
823 paftda
->dwFormatTag
= aftdw
.dwFormatTag
;
824 paftda
->dwFormatTagIndex
= aftdw
.dwFormatTagIndex
;
825 paftda
->cbFormatSize
= aftdw
.cbFormatSize
;
826 paftda
->fdwSupport
= aftdw
.fdwSupport
;
827 paftda
->cStandardFormats
= aftdw
.cStandardFormats
;
828 WideCharToMultiByte( CP_ACP
, 0, aftdw
.szFormatTag
, -1, paftda
->szFormatTag
,
829 sizeof(paftda
->szFormatTag
), NULL
, NULL
);
834 /***********************************************************************
835 * acmFormatTagDetailsW (MSACM32.@)
837 MMRESULT WINAPI
acmFormatTagDetailsW(HACMDRIVER had
, PACMFORMATTAGDETAILSW paftd
,
840 PWINE_ACMDRIVERID padid
;
841 MMRESULT mmr
= ACMERR_NOTPOSSIBLE
;
843 TRACE("(%p, %p, %d)\n", had
, paftd
, fdwDetails
);
845 if (fdwDetails
& ~(ACM_FORMATTAGDETAILSF_FORMATTAG
|ACM_FORMATTAGDETAILSF_INDEX
|
846 ACM_FORMATTAGDETAILSF_LARGESTSIZE
))
847 return MMSYSERR_INVALFLAG
;
849 switch (fdwDetails
) {
850 case ACM_FORMATTAGDETAILSF_FORMATTAG
:
852 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
853 /* should check for codec only */
854 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
855 MSACM_FindFormatTagInCache(padid
, paftd
->dwFormatTag
, NULL
) &&
856 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
857 mmr
= MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
858 acmDriverClose(had
, 0);
859 if (mmr
== MMSYSERR_NOERROR
) break;
863 PWINE_ACMDRIVER pad
= MSACM_GetDriver(had
);
865 if (pad
&& MSACM_FindFormatTagInCache(pad
->obj
.pACMDriverID
, paftd
->dwFormatTag
, NULL
))
866 mmr
= MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
870 case ACM_FORMATTAGDETAILSF_INDEX
:
872 PWINE_ACMDRIVER pad
= MSACM_GetDriver(had
);
874 if (pad
&& paftd
->dwFormatTagIndex
< pad
->obj
.pACMDriverID
->cFormatTags
)
875 mmr
= MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
879 case ACM_FORMATTAGDETAILSF_LARGESTSIZE
:
881 ACMFORMATTAGDETAILSW tmp
;
882 DWORD ft
= paftd
->dwFormatTag
;
884 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
885 /* should check for codec only */
886 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
887 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
889 memset(&tmp
, 0, sizeof(tmp
));
890 tmp
.cbStruct
= sizeof(tmp
);
891 tmp
.dwFormatTag
= ft
;
893 if (MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
,
894 (LPARAM
)&tmp
, fdwDetails
) == MMSYSERR_NOERROR
) {
895 if (mmr
== ACMERR_NOTPOSSIBLE
||
896 paftd
->cbFormatSize
< tmp
.cbFormatSize
) {
898 mmr
= MMSYSERR_NOERROR
;
901 acmDriverClose(had
, 0);
905 mmr
= MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
910 WARN("Unsupported fdwDetails=%08x\n", fdwDetails
);
911 mmr
= MMSYSERR_ERROR
;
914 if (mmr
== MMSYSERR_NOERROR
&&
915 paftd
->dwFormatTag
== WAVE_FORMAT_PCM
&& paftd
->szFormatTag
[0] == 0)
916 MultiByteToWideChar( CP_ACP
, 0, "PCM", -1, paftd
->szFormatTag
,
917 sizeof(paftd
->szFormatTag
)/sizeof(WCHAR
) );
922 struct MSACM_FormatTagEnumWtoA_Instance
{
923 PACMFORMATTAGDETAILSA paftda
;
924 DWORD_PTR dwInstance
;
925 ACMFORMATTAGENUMCBA fnCallback
;
928 static BOOL CALLBACK
MSACM_FormatTagEnumCallbackWtoA(HACMDRIVERID hadid
,
929 PACMFORMATTAGDETAILSW paftdw
,
930 DWORD_PTR dwInstance
,
933 struct MSACM_FormatTagEnumWtoA_Instance
* paftei
;
935 paftei
= (struct MSACM_FormatTagEnumWtoA_Instance
*)dwInstance
;
937 paftei
->paftda
->dwFormatTagIndex
= paftdw
->dwFormatTagIndex
;
938 paftei
->paftda
->dwFormatTag
= paftdw
->dwFormatTag
;
939 paftei
->paftda
->cbFormatSize
= paftdw
->cbFormatSize
;
940 paftei
->paftda
->fdwSupport
= paftdw
->fdwSupport
;
941 paftei
->paftda
->cStandardFormats
= paftdw
->cStandardFormats
;
942 WideCharToMultiByte( CP_ACP
, 0, paftdw
->szFormatTag
, -1, paftei
->paftda
->szFormatTag
,
943 sizeof(paftei
->paftda
->szFormatTag
), NULL
, NULL
);
945 return (paftei
->fnCallback
)(hadid
, paftei
->paftda
,
946 paftei
->dwInstance
, fdwSupport
);
949 /***********************************************************************
950 * acmFormatTagEnumA (MSACM32.@)
952 MMRESULT WINAPI
acmFormatTagEnumA(HACMDRIVER had
, PACMFORMATTAGDETAILSA paftda
,
953 ACMFORMATTAGENUMCBA fnCallback
,
954 DWORD_PTR dwInstance
, DWORD fdwEnum
)
956 ACMFORMATTAGDETAILSW aftdw
;
957 struct MSACM_FormatTagEnumWtoA_Instance aftei
;
960 return MMSYSERR_INVALPARAM
;
962 if (paftda
->cbStruct
< sizeof(*paftda
))
963 return MMSYSERR_INVALPARAM
;
966 return MMSYSERR_INVALFLAG
;
968 memset(&aftdw
, 0, sizeof(aftdw
));
969 aftdw
.cbStruct
= sizeof(aftdw
);
970 aftdw
.dwFormatTagIndex
= paftda
->dwFormatTagIndex
;
971 aftdw
.dwFormatTag
= paftda
->dwFormatTag
;
973 aftei
.paftda
= paftda
;
974 aftei
.dwInstance
= dwInstance
;
975 aftei
.fnCallback
= fnCallback
;
977 return acmFormatTagEnumW(had
, &aftdw
, MSACM_FormatTagEnumCallbackWtoA
,
978 (DWORD_PTR
)&aftei
, fdwEnum
);
981 /***********************************************************************
982 * acmFormatTagEnumW (MSACM32.@)
984 MMRESULT WINAPI
acmFormatTagEnumW(HACMDRIVER had
, PACMFORMATTAGDETAILSW paftd
,
985 ACMFORMATTAGENUMCBW fnCallback
,
986 DWORD_PTR dwInstance
, DWORD fdwEnum
)
988 PWINE_ACMDRIVERID padid
;
990 BOOL bPcmDone
= FALSE
;
992 TRACE("(%p, %p, %p, %ld, %d)\n",
993 had
, paftd
, fnCallback
, dwInstance
, fdwEnum
);
996 return MMSYSERR_INVALPARAM
;
998 if (paftd
->cbStruct
< sizeof(*paftd
))
999 return MMSYSERR_INVALPARAM
;
1002 return MMSYSERR_INVALFLAG
;
1004 /* (WS) MSDN info page says that if had != 0, then we should find
1005 * the specific driver to get its tags from. Therefore I'm removing
1006 * the FIXME call and adding a search block below. It also seems
1007 * that the lack of this functionality was the responsible for
1008 * codecs to be multiply and incorrectly listed.
1011 /* if (had) FIXME("had != NULL, not supported\n"); */
1014 if (acmDriverID((HACMOBJ
)had
, (HACMDRIVERID
*)&padid
, 0) != MMSYSERR_NOERROR
)
1015 return MMSYSERR_INVALHANDLE
;
1017 for (i
= 0; i
< padid
->cFormatTags
; i
++) {
1018 paftd
->dwFormatTagIndex
= i
;
1019 if (MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
,
1020 (LPARAM
)paftd
, ACM_FORMATTAGDETAILSF_INDEX
) == MMSYSERR_NOERROR
) {
1021 if (paftd
->dwFormatTag
== WAVE_FORMAT_PCM
) {
1022 if (paftd
->szFormatTag
[0] == 0)
1023 MultiByteToWideChar( CP_ACP
, 0, "PCM", -1, paftd
->szFormatTag
,
1024 sizeof(paftd
->szFormatTag
)/sizeof(WCHAR
) );
1025 /* (WS) I'm preserving this PCM hack since it seems to be
1026 * correct. Please notice this block was borrowed from
1029 if (bPcmDone
) continue;
1032 if (!(fnCallback
)((HACMDRIVERID
)padid
, paftd
, dwInstance
, padid
->fdwSupport
))
1033 return MMSYSERR_NOERROR
;
1037 /* if had==0 then search for the first suitable driver */
1039 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
1040 /* should check for codec only */
1041 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
1042 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == MMSYSERR_NOERROR
) {
1043 for (i
= 0; i
< padid
->cFormatTags
; i
++) {
1044 paftd
->dwFormatTagIndex
= i
;
1045 if (MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
,
1046 (LPARAM
)paftd
, ACM_FORMATTAGDETAILSF_INDEX
) == MMSYSERR_NOERROR
) {
1047 if (paftd
->dwFormatTag
== WAVE_FORMAT_PCM
) {
1048 if (paftd
->szFormatTag
[0] == 0)
1049 MultiByteToWideChar( CP_ACP
, 0, "PCM", -1, paftd
->szFormatTag
,
1050 sizeof(paftd
->szFormatTag
)/sizeof(WCHAR
) );
1051 /* FIXME (EPP): I'm not sure this is the correct
1052 * algorithm (should make more sense to apply the same
1053 * for all already loaded formats, but this will do
1056 if (bPcmDone
) continue;
1059 if (!(fnCallback
)((HACMDRIVERID
)padid
, paftd
, dwInstance
, padid
->fdwSupport
)) {
1060 acmDriverClose(had
, 0);
1061 return MMSYSERR_NOERROR
;
1065 acmDriverClose(had
, 0);
1069 return MMSYSERR_NOERROR
;