1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
6 * Copyright 1998 Patrik Stridvall
17 #include "wine/unicode.h"
18 #include "debugtools.h"
24 DEFAULT_DEBUG_CHANNEL(msacm
);
26 static PACMFORMATCHOOSEA afc
;
28 struct MSACM_FillFormatData
{
30 #define WINE_ACMFF_TAG 0
31 #define WINE_ACMFF_FORMAT 1
32 #define WINE_ACMFF_WFX 2
34 char szFormatTag
[ACMFORMATTAGDETAILS_FORMATTAG_CHARS
];
35 PACMFORMATCHOOSEA afc
;
39 static BOOL CALLBACK
MSACM_FillFormatTagsCB(HACMDRIVERID hadid
,
40 PACMFORMATTAGDETAILSA paftd
,
41 DWORD dwInstance
, DWORD fdwSupport
)
43 struct MSACM_FillFormatData
* affd
= (struct MSACM_FillFormatData
*)dwInstance
;
47 if (SendDlgItemMessageA(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
49 (WPARAM
)-1, (LPARAM
)paftd
->szFormatTag
) == CB_ERR
)
50 SendDlgItemMessageA(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
51 CB_ADDSTRING
, 0, (DWORD
)paftd
->szFormatTag
);
53 case WINE_ACMFF_FORMAT
:
54 if (strcmp(affd
->szFormatTag
, paftd
->szFormatTag
) == 0) {
57 if (acmDriverOpen(&had
, hadid
, 0) == MMSYSERR_NOERROR
) {
58 ACMFORMATDETAILSA afd
;
61 char buffer
[ACMFORMATDETAILS_FORMAT_CHARS
+16];
63 afd
.cbStruct
= sizeof(afd
);
64 afd
.dwFormatTag
= paftd
->dwFormatTag
;
65 afd
.pwfx
= HeapAlloc(MSACM_hHeap
, 0, paftd
->cbFormatSize
);
66 if (!afd
.pwfx
) return FALSE
;
67 afd
.pwfx
->wFormatTag
= paftd
->dwFormatTag
;
68 afd
.pwfx
->cbSize
= paftd
->cbFormatSize
;
69 afd
.cbwfx
= paftd
->cbFormatSize
;
71 for (i
= 0; i
< paftd
->cStandardFormats
; i
++) {
72 afd
.dwFormatIndex
= i
;
73 mmr
= acmFormatDetailsA(had
, &afd
, ACM_FORMATDETAILSF_INDEX
);
74 if (mmr
== MMSYSERR_NOERROR
) {
75 strncpy(buffer
, afd
.szFormat
, ACMFORMATTAGDETAILS_FORMATTAG_CHARS
);
76 for (idx
= strlen(buffer
);
77 idx
< ACMFORMATTAGDETAILS_FORMATTAG_CHARS
; idx
++)
79 wsprintfA(buffer
+ ACMFORMATTAGDETAILS_FORMATTAG_CHARS
,
81 (afd
.pwfx
->nAvgBytesPerSec
+ 512) / 1024);
82 SendDlgItemMessageA(affd
->hWnd
,
83 IDD_ACMFORMATCHOOSE_CMB_FORMAT
,
84 CB_ADDSTRING
, 0, (DWORD
)buffer
);
87 acmDriverClose(had
, 0);
88 SendDlgItemMessageA(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
,
90 HeapFree(MSACM_hHeap
, 0, afd
.pwfx
);
95 if (strcmp(affd
->szFormatTag
, paftd
->szFormatTag
) == 0) {
98 if (acmDriverOpen(&had
, hadid
, 0) == MMSYSERR_NOERROR
) {
99 ACMFORMATDETAILSA afd
;
101 afd
.cbStruct
= sizeof(afd
);
102 afd
.dwFormatTag
= paftd
->dwFormatTag
;
103 afd
.pwfx
= affd
->afc
->pwfx
;
104 afd
.cbwfx
= affd
->afc
->cbwfx
;
106 afd
.dwFormatIndex
= SendDlgItemMessageA(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
,
107 CB_GETCURSEL
, 0, 0);;
108 affd
->ret
= acmFormatDetailsA(had
, &afd
, ACM_FORMATDETAILSF_INDEX
);
109 acmDriverClose(had
, 0);
115 FIXME("Unknown mode (%d)\n", affd
->mode
);
121 static BOOL
MSACM_FillFormatTags(HWND hWnd
)
123 ACMFORMATTAGDETAILSA aftd
;
124 struct MSACM_FillFormatData affd
;
126 memset(&aftd
, 0, sizeof(aftd
));
127 aftd
.cbStruct
= sizeof(aftd
);
130 affd
.mode
= WINE_ACMFF_TAG
;
132 acmFormatTagEnumA((HACMDRIVER
)0, &aftd
, MSACM_FillFormatTagsCB
, (DWORD
)&affd
, 0);
133 SendDlgItemMessageA(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
, CB_SETCURSEL
, 0, 0);
137 static BOOL
MSACM_FillFormat(HWND hWnd
)
139 ACMFORMATTAGDETAILSA aftd
;
140 struct MSACM_FillFormatData affd
;
142 SendDlgItemMessageA(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
, CB_RESETCONTENT
, 0, 0);
144 memset(&aftd
, 0, sizeof(aftd
));
145 aftd
.cbStruct
= sizeof(aftd
);
148 affd
.mode
= WINE_ACMFF_FORMAT
;
149 SendDlgItemMessageA(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
151 SendDlgItemMessageA(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
153 (DWORD
)affd
.szFormatTag
);
155 acmFormatTagEnumA((HACMDRIVER
)0, &aftd
, MSACM_FillFormatTagsCB
, (DWORD
)&affd
, 0);
156 SendDlgItemMessageA(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
, CB_SETCURSEL
, 0, 0);
160 static MMRESULT
MSACM_GetWFX(HWND hWnd
, PACMFORMATCHOOSEA afc
)
162 ACMFORMATTAGDETAILSA aftd
;
163 struct MSACM_FillFormatData affd
;
165 memset(&aftd
, 0, sizeof(aftd
));
166 aftd
.cbStruct
= sizeof(aftd
);
169 affd
.mode
= WINE_ACMFF_WFX
;
171 affd
.ret
= MMSYSERR_NOERROR
;
173 acmFormatTagEnumA((HACMDRIVER
)0, &aftd
, MSACM_FillFormatTagsCB
, (DWORD
)&affd
, 0);
177 static BOOL WINAPI
FormatChooseDlgProc(HWND hWnd
, UINT msg
,
178 WPARAM wParam
, LPARAM lParam
)
181 TRACE("hwnd=%i msg=%i 0x%08x 0x%08lx\n", hWnd
, msg
, wParam
, lParam
);
185 afc
= (PACMFORMATCHOOSEA
)lParam
;
186 MSACM_FillFormatTags(hWnd
);
187 MSACM_FillFormat(hWnd
);
188 if ((afc
->fdwStyle
& ~(ACMFORMATCHOOSE_STYLEF_CONTEXTHELP
|
189 ACMFORMATCHOOSE_STYLEF_SHOWHELP
)) != 0)
190 FIXME("Unsupported style %08lx\n", ((PACMFORMATCHOOSEA
)lParam
)->fdwStyle
);
191 if (!(afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_SHOWHELP
))
192 ShowWindow(GetDlgItem(hWnd
, IDD_ACMFORMATCHOOSE_BTN_HELP
), SW_HIDE
);
196 switch (LOWORD(wParam
)) {
198 EndDialog(hWnd
, MSACM_GetWFX(hWnd
, afc
));
201 EndDialog(hWnd
, ACMERR_CANCELED
);
203 case IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
:
204 switch (HIWORD(wParam
)) {
206 MSACM_FillFormat(hWnd
);
209 TRACE("Dropped dlgNotif (fmtTag): 0x%08x 0x%08lx\n",
210 HIWORD(wParam
), lParam
);
214 case IDD_ACMFORMATCHOOSE_BTN_HELP
:
215 if (afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_SHOWHELP
)
216 SendMessageA(afc
->hwndOwner
,
217 RegisterWindowMessageA(ACMHELPMSGSTRINGA
), 0L, 0L);
221 TRACE("Dropped dlgCmd: ctl=%d ntf=0x%04x 0x%08lx\n",
222 LOWORD(wParam
), HIWORD(wParam
), lParam
);
227 if (afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_CONTEXTHELP
)
228 SendMessageA(afc
->hwndOwner
,
229 RegisterWindowMessageA(ACMHELPMSGCONTEXTMENUA
),
232 #if defined(WM_CONTEXTHELP)
234 if (afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_CONTEXTHELP
)
235 SendMessageA(afc
->hwndOwner
,
236 RegisterWindowMessageA(ACMHELPMSGCONTEXTHELPA
),
241 TRACE("Dropped dlgMsg: hwnd=%i msg=%i 0x%08x 0x%08lx\n",
242 hWnd
, msg
, wParam
, lParam
);
248 /***********************************************************************
249 * acmFormatChooseA (MSACM32.@)
251 MMRESULT WINAPI
acmFormatChooseA(PACMFORMATCHOOSEA pafmtc
)
253 return DialogBoxParamA(MSACM_hInstance32
, MAKEINTRESOURCEA(DLG_ACMFORMATCHOOSE_ID
),
254 pafmtc
->hwndOwner
, FormatChooseDlgProc
, (INT
)pafmtc
);
257 /***********************************************************************
258 * acmFormatChooseW (MSACM32.@)
260 MMRESULT WINAPI
acmFormatChooseW(PACMFORMATCHOOSEW pafmtc
)
262 FIXME("(%p): stub\n", pafmtc
);
263 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
264 return MMSYSERR_ERROR
;
267 /***********************************************************************
268 * acmFormatDetailsA (MSACM32.@)
270 MMRESULT WINAPI
acmFormatDetailsA(HACMDRIVER had
, PACMFORMATDETAILSA pafd
,
273 ACMFORMATDETAILSW afdw
;
276 memset(&afdw
, 0, sizeof(afdw
));
277 afdw
.cbStruct
= sizeof(afdw
);
278 afdw
.dwFormatIndex
= pafd
->dwFormatIndex
;
279 afdw
.dwFormatTag
= pafd
->dwFormatTag
;
280 afdw
.pwfx
= pafd
->pwfx
;
281 afdw
.cbwfx
= pafd
->cbwfx
;
283 mmr
= acmFormatDetailsW(had
, &afdw
, fdwDetails
);
284 if (mmr
== MMSYSERR_NOERROR
) {
285 pafd
->dwFormatTag
= afdw
.dwFormatTag
;
286 pafd
->fdwSupport
= afdw
.fdwSupport
;
287 WideCharToMultiByte( CP_ACP
, 0, afdw
.szFormat
, -1,
288 pafd
->szFormat
, sizeof(pafd
->szFormat
), NULL
, NULL
);
293 /***********************************************************************
294 * acmFormatDetailsW (MSACM32.@)
296 MMRESULT WINAPI
acmFormatDetailsW(HACMDRIVER had
, PACMFORMATDETAILSW pafd
, DWORD fdwDetails
)
299 static WCHAR fmt1
[] = {'%','d',' ','H','z',0};
300 static WCHAR fmt2
[] = {';',' ','%','d',' ','b','i','t','s',0};
301 ACMFORMATTAGDETAILSA aftd
;
303 TRACE("(0x%08x, %p, %ld)\n", had
, pafd
, fdwDetails
);
305 memset(&aftd
, 0, sizeof(aftd
));
306 aftd
.cbStruct
= sizeof(aftd
);
308 if (pafd
->cbStruct
< sizeof(*pafd
)) return MMSYSERR_INVALPARAM
;
310 switch (fdwDetails
) {
311 case ACM_FORMATDETAILSF_FORMAT
:
312 if (pafd
->dwFormatTag
!= pafd
->pwfx
->wFormatTag
) {
313 mmr
= MMSYSERR_INVALPARAM
;
316 if (had
== (HACMDRIVER
)NULL
) {
317 PWINE_ACMDRIVERID padid
;
319 mmr
= ACMERR_NOTPOSSIBLE
;
320 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
321 /* should check for codec only */
322 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
323 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
324 mmr
= MSACM_Message(had
, ACMDM_FORMAT_DETAILS
, (LPARAM
)pafd
, fdwDetails
);
325 acmDriverClose(had
, 0);
326 if (mmr
== MMSYSERR_NOERROR
) break;
330 mmr
= MSACM_Message(had
, ACMDM_FORMAT_DETAILS
, (LPARAM
)pafd
, fdwDetails
);
333 case ACM_FORMATDETAILSF_INDEX
:
334 /* should check pafd->dwFormatIndex < aftd->cStandardFormats */
335 mmr
= MSACM_Message(had
, ACMDM_FORMAT_DETAILS
, (LPARAM
)pafd
, fdwDetails
);
338 WARN("Unknown fdwDetails %08lx\n", fdwDetails
);
339 mmr
= MMSYSERR_INVALFLAG
;
343 if (mmr
== MMSYSERR_NOERROR
&& pafd
->szFormat
[0] == (WCHAR
)0) {
344 wsprintfW(pafd
->szFormat
, fmt1
, pafd
->pwfx
->nSamplesPerSec
);
345 if (pafd
->pwfx
->wBitsPerSample
) {
346 wsprintfW(pafd
->szFormat
+ lstrlenW(pafd
->szFormat
), fmt2
,
347 pafd
->pwfx
->wBitsPerSample
);
349 MultiByteToWideChar( CP_ACP
, 0, (pafd
->pwfx
->nChannels
== 1) ? "; Mono" : "; Stereo", -1,
350 pafd
->szFormat
+ strlenW(pafd
->szFormat
),
351 sizeof(pafd
->szFormat
)/sizeof(WCHAR
) - strlenW(pafd
->szFormat
) );
354 TRACE("=> %d\n", mmr
);
358 struct MSACM_FormatEnumWtoA_Instance
{
359 PACMFORMATDETAILSA pafda
;
361 ACMFORMATENUMCBA fnCallback
;
364 static BOOL CALLBACK
MSACM_FormatEnumCallbackWtoA(HACMDRIVERID hadid
,
365 PACMFORMATDETAILSW pafdw
,
369 struct MSACM_FormatEnumWtoA_Instance
* pafei
;
371 pafei
= (struct MSACM_FormatEnumWtoA_Instance
*)dwInstance
;
373 pafei
->pafda
->dwFormatIndex
= pafdw
->dwFormatIndex
;
374 pafei
->pafda
->dwFormatTag
= pafdw
->dwFormatTag
;
375 pafei
->pafda
->fdwSupport
= pafdw
->fdwSupport
;
376 WideCharToMultiByte( CP_ACP
, 0, pafdw
->szFormat
, -1,
377 pafei
->pafda
->szFormat
, sizeof(pafei
->pafda
->szFormat
), NULL
, NULL
);
379 return (pafei
->fnCallback
)(hadid
, pafei
->pafda
,
380 pafei
->dwInstance
, fdwSupport
);
383 /***********************************************************************
384 * acmFormatEnumA (MSACM32.@)
386 MMRESULT WINAPI
acmFormatEnumA(HACMDRIVER had
, PACMFORMATDETAILSA pafda
,
387 ACMFORMATENUMCBA fnCallback
, DWORD dwInstance
,
390 ACMFORMATDETAILSW afdw
;
391 struct MSACM_FormatEnumWtoA_Instance afei
;
393 memset(&afdw
, 0, sizeof(afdw
));
394 afdw
.cbStruct
= sizeof(afdw
);
395 afdw
.dwFormatIndex
= pafda
->dwFormatIndex
;
396 afdw
.dwFormatTag
= pafda
->dwFormatTag
;
397 afdw
.pwfx
= pafda
->pwfx
;
398 afdw
.cbwfx
= pafda
->cbwfx
;
401 afei
.dwInstance
= dwInstance
;
402 afei
.fnCallback
= fnCallback
;
404 return acmFormatEnumW(had
, &afdw
, MSACM_FormatEnumCallbackWtoA
,
405 (DWORD
)&afei
, fdwEnum
);
408 /***********************************************************************
409 * acmFormatEnumW (MSACM32.@)
411 static BOOL
MSACM_FormatEnumHelper(PWINE_ACMDRIVERID padid
, HACMDRIVER had
,
412 PACMFORMATDETAILSW pafd
, PWAVEFORMATEX pwfxRef
,
413 ACMFORMATENUMCBW fnCallback
, DWORD dwInstance
,
416 ACMFORMATTAGDETAILSW aftd
;
419 for (i
= 0; i
< padid
->cFormatTags
; i
++) {
420 memset(&aftd
, 0, sizeof(aftd
));
421 aftd
.cbStruct
= sizeof(aftd
);
422 aftd
.dwFormatTagIndex
= i
;
423 if (acmFormatTagDetailsW(had
, &aftd
, ACM_FORMATTAGDETAILSF_INDEX
) != MMSYSERR_NOERROR
)
426 if ((fdwEnum
& ACM_FORMATENUMF_WFORMATTAG
) && aftd
.dwFormatTag
!= pwfxRef
->wFormatTag
)
429 for (j
= 0; j
< aftd
.cStandardFormats
; j
++) {
430 pafd
->dwFormatIndex
= j
;
431 pafd
->dwFormatTag
= aftd
.dwFormatTag
;
432 if (acmFormatDetailsW(had
, pafd
, ACM_FORMATDETAILSF_INDEX
) != MMSYSERR_NOERROR
)
435 if ((fdwEnum
& ACM_FORMATENUMF_NCHANNELS
) &&
436 pafd
->pwfx
->nChannels
!= pwfxRef
->nChannels
)
438 if ((fdwEnum
& ACM_FORMATENUMF_NSAMPLESPERSEC
) &&
439 pafd
->pwfx
->nSamplesPerSec
!= pwfxRef
->nSamplesPerSec
)
441 if ((fdwEnum
& ACM_FORMATENUMF_WBITSPERSAMPLE
) &&
442 pafd
->pwfx
->wBitsPerSample
!= pwfxRef
->wBitsPerSample
)
444 if ((fdwEnum
& ACM_FORMATENUMF_HARDWARE
) &&
445 !(pafd
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_HARDWARE
))
448 /* more checks to be done on fdwEnum */
450 if (!(fnCallback
)((HACMDRIVERID
)padid
, pafd
, dwInstance
, padid
->fdwSupport
))
453 /* the "formats" used by the filters are also reported */
458 /**********************************************************************/
460 MMRESULT WINAPI
acmFormatEnumW(HACMDRIVER had
, PACMFORMATDETAILSW pafd
,
461 ACMFORMATENUMCBW fnCallback
, DWORD dwInstance
,
464 PWINE_ACMDRIVERID padid
;
468 TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
469 had
, pafd
, fnCallback
, dwInstance
, fdwEnum
);
471 if (pafd
->cbStruct
< sizeof(*pafd
)) return MMSYSERR_INVALPARAM
;
473 if (fdwEnum
& (ACM_FORMATENUMF_WFORMATTAG
|ACM_FORMATENUMF_NCHANNELS
|
474 ACM_FORMATENUMF_NSAMPLESPERSEC
|ACM_FORMATENUMF_WBITSPERSAMPLE
|
475 ACM_FORMATENUMF_CONVERT
|ACM_FORMATENUMF_SUGGEST
))
476 wfxRef
= *pafd
->pwfx
;
478 if ((fdwEnum
& ACM_FORMATENUMF_HARDWARE
) &&
479 !(fdwEnum
& (ACM_FORMATENUMF_INPUT
|ACM_FORMATENUMF_OUTPUT
)))
480 return MMSYSERR_INVALPARAM
;
482 if ((fdwEnum
& ACM_FORMATENUMF_WFORMATTAG
) &&
483 (pafd
->dwFormatTag
!= pafd
->pwfx
->wFormatTag
))
484 return MMSYSERR_INVALPARAM
;
486 if (fdwEnum
& (ACM_FORMATENUMF_CONVERT
|ACM_FORMATENUMF_SUGGEST
|
487 ACM_FORMATENUMF_INPUT
|ACM_FORMATENUMF_OUTPUT
))
488 FIXME("Unsupported fdwEnum values %08lx\n", fdwEnum
);
493 if (acmDriverID(had
, &hadid
, 0) != MMSYSERR_NOERROR
)
494 return MMSYSERR_INVALHANDLE
;
495 MSACM_FormatEnumHelper(MSACM_GetDriverID(hadid
), had
, pafd
, &wfxRef
,
496 fnCallback
, dwInstance
, fdwEnum
);
497 return MMSYSERR_NOERROR
;
499 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
500 /* should check for codec only */
501 if ((padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) ||
502 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) != MMSYSERR_NOERROR
)
504 ret
= MSACM_FormatEnumHelper(padid
, had
, pafd
, &wfxRef
,
505 fnCallback
, dwInstance
, fdwEnum
);
506 acmDriverClose(had
, 0);
509 return MMSYSERR_NOERROR
;
512 /***********************************************************************
513 * acmFormatSuggest (MSACM32.@)
515 MMRESULT WINAPI
acmFormatSuggest(HACMDRIVER had
, PWAVEFORMATEX pwfxSrc
,
516 PWAVEFORMATEX pwfxDst
, DWORD cbwfxDst
, DWORD fdwSuggest
)
518 ACMDRVFORMATSUGGEST adfg
;
521 TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
522 had
, pwfxSrc
, pwfxDst
, cbwfxDst
, fdwSuggest
);
524 if (fdwSuggest
& ~(ACM_FORMATSUGGESTF_NCHANNELS
|ACM_FORMATSUGGESTF_NSAMPLESPERSEC
|
525 ACM_FORMATSUGGESTF_WBITSPERSAMPLE
|ACM_FORMATSUGGESTF_WFORMATTAG
))
526 return MMSYSERR_INVALFLAG
;
528 adfg
.cbStruct
= sizeof(adfg
);
529 adfg
.fdwSuggest
= fdwSuggest
;
530 adfg
.pwfxSrc
= pwfxSrc
;
531 adfg
.cbwfxSrc
= (pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
) ?
532 sizeof(WAVEFORMATEX
) : pwfxSrc
->cbSize
;
533 adfg
.pwfxDst
= pwfxDst
;
534 adfg
.cbwfxDst
= cbwfxDst
;
536 if (had
== (HACMDRIVER
)NULL
) {
537 PWINE_ACMDRIVERID padid
;
539 /* MS doc says: ACM finds the best suggestion.
540 * Well, first found will be the "best"
542 mmr
= ACMERR_NOTPOSSIBLE
;
543 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
544 /* should check for codec only */
545 if ((padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) ||
546 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) != MMSYSERR_NOERROR
)
549 if (MSACM_Message(had
, ACMDM_FORMAT_SUGGEST
, (LPARAM
)&adfg
, 0L) == MMSYSERR_NOERROR
) {
550 mmr
= MMSYSERR_NOERROR
;
553 acmDriverClose(had
, 0);
556 mmr
= MSACM_Message(had
, ACMDM_FORMAT_SUGGEST
, (LPARAM
)&adfg
, 0L);
561 /***********************************************************************
562 * acmFormatTagDetailsA (MSACM32.@)
564 MMRESULT WINAPI
acmFormatTagDetailsA(HACMDRIVER had
, PACMFORMATTAGDETAILSA paftda
,
567 ACMFORMATTAGDETAILSW aftdw
;
570 memset(&aftdw
, 0, sizeof(aftdw
));
571 aftdw
.cbStruct
= sizeof(aftdw
);
572 aftdw
.dwFormatTagIndex
= paftda
->dwFormatTagIndex
;
573 aftdw
.dwFormatTag
= paftda
->dwFormatTag
;
575 mmr
= acmFormatTagDetailsW(had
, &aftdw
, fdwDetails
);
576 if (mmr
== MMSYSERR_NOERROR
) {
577 paftda
->dwFormatTag
= aftdw
.dwFormatTag
;
578 paftda
->dwFormatTagIndex
= aftdw
.dwFormatTagIndex
;
579 paftda
->cbFormatSize
= aftdw
.cbFormatSize
;
580 paftda
->fdwSupport
= aftdw
.fdwSupport
;
581 paftda
->cStandardFormats
= aftdw
.cStandardFormats
;
582 WideCharToMultiByte( CP_ACP
, 0, aftdw
.szFormatTag
, -1, paftda
->szFormatTag
,
583 sizeof(paftda
->szFormatTag
), NULL
, NULL
);
588 /***********************************************************************
589 * acmFormatTagDetailsW (MSACM32.@)
591 MMRESULT WINAPI
acmFormatTagDetailsW(HACMDRIVER had
, PACMFORMATTAGDETAILSW paftd
,
594 PWINE_ACMDRIVERID padid
;
595 MMRESULT mmr
= ACMERR_NOTPOSSIBLE
;
597 TRACE("(0x%08x, %p, %ld)\n", had
, paftd
, fdwDetails
);
599 if (fdwDetails
& ~(ACM_FORMATTAGDETAILSF_FORMATTAG
|ACM_FORMATTAGDETAILSF_INDEX
|
600 ACM_FORMATTAGDETAILSF_LARGESTSIZE
))
601 return MMSYSERR_INVALFLAG
;
603 switch (fdwDetails
) {
604 case ACM_FORMATTAGDETAILSF_FORMATTAG
:
605 if (had
== (HACMDRIVER
)NULL
) {
606 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
607 /* should check for codec only */
608 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
609 MSACM_FindFormatTagInCache(padid
, paftd
->dwFormatTag
, NULL
) &&
610 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
611 mmr
= MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
612 acmDriverClose(had
, 0);
613 if (mmr
== MMSYSERR_NOERROR
) break;
617 PWINE_ACMDRIVER pad
= MSACM_GetDriver(had
);
619 if (pad
&& MSACM_FindFormatTagInCache(pad
->obj
.pACMDriverID
, paftd
->dwFormatTag
, NULL
))
620 mmr
= MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
624 case ACM_FORMATTAGDETAILSF_INDEX
:
625 if (had
!= (HACMDRIVER
)NULL
) {
626 PWINE_ACMDRIVER pad
= MSACM_GetDriver(had
);
628 if (pad
&& paftd
->dwFormatTagIndex
< pad
->obj
.pACMDriverID
->cFormatTags
)
629 mmr
= MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
633 case ACM_FORMATTAGDETAILSF_LARGESTSIZE
:
634 if (had
== (HACMDRIVER
)NULL
) {
635 ACMFORMATTAGDETAILSW tmp
;
636 DWORD ft
= paftd
->dwFormatTag
;
638 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
639 /* should check for codec only */
640 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
641 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
643 memset(&tmp
, 0, sizeof(tmp
));
644 tmp
.cbStruct
= sizeof(tmp
);
645 tmp
.dwFormatTag
= ft
;
647 if (MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
,
648 (LPARAM
)&tmp
, fdwDetails
) == MMSYSERR_NOERROR
) {
649 if (mmr
== ACMERR_NOTPOSSIBLE
||
650 paftd
->cbFormatSize
< tmp
.cbFormatSize
) {
652 mmr
= MMSYSERR_NOERROR
;
655 acmDriverClose(had
, 0);
659 mmr
= MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
664 WARN("Unsupported fdwDetails=%08lx\n", fdwDetails
);
665 mmr
= MMSYSERR_ERROR
;
668 if (mmr
== MMSYSERR_NOERROR
&&
669 paftd
->dwFormatTag
== WAVE_FORMAT_PCM
&& paftd
->szFormatTag
[0] == 0)
670 MultiByteToWideChar( CP_ACP
, 0, "PCM", -1, paftd
->szFormatTag
,
671 sizeof(paftd
->szFormatTag
)/sizeof(WCHAR
) );
676 struct MSACM_FormatTagEnumWtoA_Instance
{
677 PACMFORMATTAGDETAILSA paftda
;
679 ACMFORMATTAGENUMCBA fnCallback
;
682 static BOOL CALLBACK
MSACM_FormatTagEnumCallbackWtoA(HACMDRIVERID hadid
,
683 PACMFORMATTAGDETAILSW paftdw
,
687 struct MSACM_FormatTagEnumWtoA_Instance
* paftei
;
689 paftei
= (struct MSACM_FormatTagEnumWtoA_Instance
*)dwInstance
;
691 paftei
->paftda
->dwFormatTagIndex
= paftdw
->dwFormatTagIndex
;
692 paftei
->paftda
->dwFormatTag
= paftdw
->dwFormatTag
;
693 paftei
->paftda
->cbFormatSize
= paftdw
->cbFormatSize
;
694 paftei
->paftda
->fdwSupport
= paftdw
->fdwSupport
;
695 paftei
->paftda
->cStandardFormats
= paftdw
->cStandardFormats
;
696 WideCharToMultiByte( CP_ACP
, 0, paftdw
->szFormatTag
, -1, paftei
->paftda
->szFormatTag
,
697 sizeof(paftei
->paftda
->szFormatTag
), NULL
, NULL
);
699 return (paftei
->fnCallback
)(hadid
, paftei
->paftda
,
700 paftei
->dwInstance
, fdwSupport
);
703 /***********************************************************************
704 * acmFormatTagEnumA (MSACM32.@)
706 MMRESULT WINAPI
acmFormatTagEnumA(HACMDRIVER had
, PACMFORMATTAGDETAILSA paftda
,
707 ACMFORMATTAGENUMCBA fnCallback
, DWORD dwInstance
,
710 ACMFORMATTAGDETAILSW aftdw
;
711 struct MSACM_FormatTagEnumWtoA_Instance aftei
;
713 memset(&aftdw
, 0, sizeof(aftdw
));
714 aftdw
.cbStruct
= sizeof(aftdw
);
715 aftdw
.dwFormatTagIndex
= paftda
->dwFormatTagIndex
;
716 aftdw
.dwFormatTag
= paftda
->dwFormatTag
;
718 aftei
.paftda
= paftda
;
719 aftei
.dwInstance
= dwInstance
;
720 aftei
.fnCallback
= fnCallback
;
722 return acmFormatTagEnumW(had
, &aftdw
, MSACM_FormatTagEnumCallbackWtoA
,
723 (DWORD
)&aftei
, fdwEnum
);
726 /***********************************************************************
727 * acmFormatTagEnumW (MSACM32.@)
729 MMRESULT WINAPI
acmFormatTagEnumW(HACMDRIVER had
, PACMFORMATTAGDETAILSW paftd
,
730 ACMFORMATTAGENUMCBW fnCallback
, DWORD dwInstance
,
733 PWINE_ACMDRIVERID padid
;
735 BOOL bPcmDone
= FALSE
;
737 TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
738 had
, paftd
, fnCallback
, dwInstance
, fdwEnum
);
740 if (paftd
->cbStruct
< sizeof(*paftd
)) return MMSYSERR_INVALPARAM
;
742 if (had
) FIXME("had != NULL, not supported\n");
744 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
745 /* should check for codec only */
746 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
747 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == MMSYSERR_NOERROR
) {
748 for (i
= 0; i
< padid
->cFormatTags
; i
++) {
749 paftd
->dwFormatTagIndex
= i
;
750 if (MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
,
751 (LPARAM
)paftd
, ACM_FORMATTAGDETAILSF_INDEX
) == MMSYSERR_NOERROR
) {
752 if (paftd
->dwFormatTag
== WAVE_FORMAT_PCM
) {
753 if (paftd
->szFormatTag
[0] == 0)
754 MultiByteToWideChar( CP_ACP
, 0, "PCM", -1, paftd
->szFormatTag
,
755 sizeof(paftd
->szFormatTag
)/sizeof(WCHAR
) );
756 /* FIXME (EPP): I'm not sure this is the correct
757 * algorithm (should make more sense to apply the same
758 * for all already loaded formats, but this will do
761 if (bPcmDone
) continue;
764 if (!(fnCallback
)((HACMDRIVERID
)padid
, paftd
, dwInstance
, padid
->fdwSupport
)) {
765 padid
= NULL
; /* to exist the two nested for loops */
771 acmDriverClose(had
, 0);
773 return MMSYSERR_NOERROR
;