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;
172 SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
174 SendDlgItemMessageA(hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
176 (DWORD)affd.szFormatTag);
178 acmFormatTagEnumA((HACMDRIVER)0, &aftd, MSACM_FillFormatTagsCB, (DWORD)&affd, 0);
182 static BOOL WINAPI FormatChooseDlgProc(HWND hWnd, UINT msg,
183 WPARAM wParam, LPARAM lParam)
186 TRACE("hwnd=%i msg=%i 0x%08x 0x%08lx\n", hWnd, msg, wParam, lParam );
190 afc = (PACMFORMATCHOOSEA)lParam;
191 MSACM_FillFormatTags(hWnd);
192 MSACM_FillFormat(hWnd);
193 if ((afc->fdwStyle & ~(ACMFORMATCHOOSE_STYLEF_CONTEXTHELP|
194 ACMFORMATCHOOSE_STYLEF_SHOWHELP)) != 0)
195 FIXME("Unsupported style %08lx\n", ((PACMFORMATCHOOSEA)lParam)->fdwStyle);
196 if (!(afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_SHOWHELP))
197 ShowWindow(GetDlgItem(hWnd, IDD_ACMFORMATCHOOSE_BTN_HELP), SW_HIDE);
201 switch (LOWORD(wParam)) {
203 EndDialog(hWnd, MSACM_GetWFX(hWnd, afc));
206 EndDialog(hWnd, ACMERR_CANCELED);
208 case IDD_ACMFORMATCHOOSE_CMB_FORMATTAG:
209 switch (HIWORD(wParam)) {
211 MSACM_FillFormat(hWnd);
214 TRACE("Dropped dlgNotif (fmtTag): 0x%08x 0x%08lx\n",
215 HIWORD(wParam), lParam);
219 case IDD_ACMFORMATCHOOSE_BTN_HELP:
220 if (afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_SHOWHELP)
221 SendMessageA(afc->hwndOwner,
222 RegisterWindowMessageA(ACMHELPMSGSTRINGA), 0L, 0L);
226 TRACE("Dropped dlgCmd: ctl=%d ntf=0x%04x 0x%08lx\n",
227 LOWORD(wParam), HIWORD(wParam), lParam);
232 if (afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_CONTEXTHELP)
233 SendMessageA(afc->hwndOwner,
234 RegisterWindowMessageA(ACMHELPMSGCONTEXTMENUA),
237 #if defined(WM_CONTEXTHELP)
239 if (afc->fdwStyle & ACMFORMATCHOOSE_STYLEF_CONTEXTHELP)
240 SendMessageA(afc->hwndOwner,
241 RegisterWindowMessageA(ACMHELPMSGCONTEXTHELPA),
246 TRACE("Dropped dlgMsg: hwnd=%i msg=%i 0x%08x 0x%08lx\n",
247 hWnd, msg, wParam, lParam );
253 /***********************************************************************
254 * acmFormatChooseA (MSACM32.@)
256 MMRESULT WINAPI acmFormatChooseA(PACMFORMATCHOOSEA pafmtc)
258 return DialogBoxParamA(MSACM_hInstance32, MAKEINTRESOURCEA(DLG_ACMFORMATCHOOSE_ID),
259 pafmtc->hwndOwner, FormatChooseDlgProc, (INT)pafmtc);
262 /***********************************************************************
263 * acmFormatChooseW (MSACM32.@)
265 MMRESULT WINAPI acmFormatChooseW(PACMFORMATCHOOSEW pafmtc)
267 FIXME("(%p): stub\n", pafmtc);
268 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
269 return MMSYSERR_ERROR;
272 /***********************************************************************
273 * acmFormatDetailsA (MSACM32.@)
275 MMRESULT WINAPI acmFormatDetailsA(HACMDRIVER had, PACMFORMATDETAILSA pafd,
278 ACMFORMATDETAILSW afdw;
281 memset(&afdw, 0, sizeof(afdw));
282 afdw.cbStruct = sizeof(afdw);
283 afdw.dwFormatIndex = pafd->dwFormatIndex;
284 afdw.dwFormatTag = pafd->dwFormatTag;
285 afdw.pwfx = pafd->pwfx;
286 afdw.cbwfx = pafd->cbwfx;
288 mmr = acmFormatDetailsW(had, &afdw, fdwDetails);
289 if (mmr == MMSYSERR_NOERROR) {
290 pafd->dwFormatTag = afdw.dwFormatTag;
291 pafd->fdwSupport = afdw.fdwSupport;
292 WideCharToMultiByte( CP_ACP, 0, afdw.szFormat, -1,
293 pafd->szFormat, sizeof(pafd->szFormat), NULL, NULL );
298 /***********************************************************************
299 * acmFormatDetailsW (MSACM32.@)
301 MMRESULT WINAPI acmFormatDetailsW(HACMDRIVER had, PACMFORMATDETAILSW pafd, DWORD fdwDetails)
304 static WCHAR fmt1[] = {'%','d',' ','H','z',0};
305 static WCHAR fmt2[] = {';',' ','%','d',' ','b','i','t','s',0};
306 ACMFORMATTAGDETAILSA aftd;
308 TRACE("(0x%08x, %p, %ld)\n", had, pafd, fdwDetails);
310 memset(&aftd, 0, sizeof(aftd));
311 aftd.cbStruct = sizeof(aftd);
313 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
315 switch (fdwDetails) {
316 case ACM_FORMATDETAILSF_FORMAT:
317 if (pafd->dwFormatTag != pafd->pwfx->wFormatTag) {
318 mmr = MMSYSERR_INVALPARAM;
321 if (had == (HACMDRIVER)NULL) {
322 PWINE_ACMDRIVERID padid;
324 mmr = ACMERR_NOTPOSSIBLE;
325 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
326 /* should check for codec only */
327 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
328 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
329 mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails);
330 acmDriverClose(had, 0);
331 if (mmr == MMSYSERR_NOERROR) break;
335 mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails);
338 case ACM_FORMATDETAILSF_INDEX:
339 /* should check pafd->dwFormatIndex < aftd->cStandardFormats */
340 mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails);
343 WARN("Unknown fdwDetails %08lx\n", fdwDetails);
344 mmr = MMSYSERR_INVALFLAG;
348 if (mmr == MMSYSERR_NOERROR && pafd->szFormat[0] == (WCHAR)0) {
349 wsprintfW(pafd->szFormat, fmt1, pafd->pwfx->nSamplesPerSec);
350 if (pafd->pwfx->wBitsPerSample) {
351 wsprintfW(pafd->szFormat + lstrlenW(pafd->szFormat), fmt2,
352 pafd->pwfx->wBitsPerSample);
354 MultiByteToWideChar( CP_ACP, 0, (pafd->pwfx->nChannels == 1) ? "; Mono" : "; Stereo", -1,
355 pafd->szFormat + strlenW(pafd->szFormat),
356 sizeof(pafd->szFormat)/sizeof(WCHAR) - strlenW(pafd->szFormat) );
359 TRACE("=> %d\n", mmr);
363 struct MSACM_FormatEnumWtoA_Instance {
364 PACMFORMATDETAILSA pafda;
366 ACMFORMATENUMCBA fnCallback;
369 static BOOL CALLBACK MSACM_FormatEnumCallbackWtoA(HACMDRIVERID hadid,
370 PACMFORMATDETAILSW pafdw,
374 struct MSACM_FormatEnumWtoA_Instance* pafei;
376 pafei = (struct MSACM_FormatEnumWtoA_Instance*)dwInstance;
378 pafei->pafda->dwFormatIndex = pafdw->dwFormatIndex;
379 pafei->pafda->dwFormatTag = pafdw->dwFormatTag;
380 pafei->pafda->fdwSupport = pafdw->fdwSupport;
381 WideCharToMultiByte( CP_ACP, 0, pafdw->szFormat, -1,
382 pafei->pafda->szFormat, sizeof(pafei->pafda->szFormat), NULL, NULL );
384 return (pafei->fnCallback)(hadid, pafei->pafda,
385 pafei->dwInstance, fdwSupport);
388 /***********************************************************************
389 * acmFormatEnumA (MSACM32.@)
391 MMRESULT WINAPI acmFormatEnumA(HACMDRIVER had, PACMFORMATDETAILSA pafda,
392 ACMFORMATENUMCBA fnCallback, DWORD dwInstance,
395 ACMFORMATDETAILSW afdw;
396 struct MSACM_FormatEnumWtoA_Instance afei;
398 memset(&afdw, 0, sizeof(afdw));
399 afdw.cbStruct = sizeof(afdw);
400 afdw.dwFormatIndex = pafda->dwFormatIndex;
401 afdw.dwFormatTag = pafda->dwFormatTag;
402 afdw.pwfx = pafda->pwfx;
403 afdw.cbwfx = pafda->cbwfx;
406 afei.dwInstance = dwInstance;
407 afei.fnCallback = fnCallback;
409 return acmFormatEnumW(had, &afdw, MSACM_FormatEnumCallbackWtoA,
410 (DWORD)&afei, fdwEnum);
413 /***********************************************************************
414 * acmFormatEnumW (MSACM32.@)
416 static BOOL MSACM_FormatEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had,
417 PACMFORMATDETAILSW pafd, PWAVEFORMATEX pwfxRef,
418 ACMFORMATENUMCBW fnCallback, DWORD dwInstance,
421 ACMFORMATTAGDETAILSW aftd;
424 for (i = 0; i < padid->cFormatTags; i++) {
425 memset(&aftd, 0, sizeof(aftd));
426 aftd.cbStruct = sizeof(aftd);
427 aftd.dwFormatTagIndex = i;
428 if (acmFormatTagDetailsW(had, &aftd, ACM_FORMATTAGDETAILSF_INDEX) != MMSYSERR_NOERROR)
431 if ((fdwEnum & ACM_FORMATENUMF_WFORMATTAG) && aftd.dwFormatTag != pwfxRef->wFormatTag)
434 for (j = 0; j < aftd.cStandardFormats; j++) {
435 pafd->dwFormatIndex = j;
436 pafd->dwFormatTag = aftd.dwFormatTag;
437 if (acmFormatDetailsW(had, pafd, ACM_FORMATDETAILSF_INDEX) != MMSYSERR_NOERROR)
440 if ((fdwEnum & ACM_FORMATENUMF_NCHANNELS) &&
441 pafd->pwfx->nChannels != pwfxRef->nChannels)
443 if ((fdwEnum & ACM_FORMATENUMF_NSAMPLESPERSEC) &&
444 pafd->pwfx->nSamplesPerSec != pwfxRef->nSamplesPerSec)
446 if ((fdwEnum & ACM_FORMATENUMF_WBITSPERSAMPLE) &&
447 pafd->pwfx->wBitsPerSample != pwfxRef->wBitsPerSample)
449 if ((fdwEnum & ACM_FORMATENUMF_HARDWARE) &&
450 !(pafd->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_HARDWARE))
453 /* more checks to be done on fdwEnum */
455 if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, padid->fdwSupport))
458 /* the "formats" used by the filters are also reported */
463 /**********************************************************************/
465 MMRESULT WINAPI acmFormatEnumW(HACMDRIVER had, PACMFORMATDETAILSW pafd,
466 ACMFORMATENUMCBW fnCallback, DWORD dwInstance,
469 PWINE_ACMDRIVERID padid;
473 TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
474 had, pafd, fnCallback, dwInstance, fdwEnum);
476 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
478 if (fdwEnum & (ACM_FORMATENUMF_WFORMATTAG|ACM_FORMATENUMF_NCHANNELS|
479 ACM_FORMATENUMF_NSAMPLESPERSEC|ACM_FORMATENUMF_WBITSPERSAMPLE|
480 ACM_FORMATENUMF_CONVERT|ACM_FORMATENUMF_SUGGEST))
481 wfxRef = *pafd->pwfx;
483 if ((fdwEnum & ACM_FORMATENUMF_HARDWARE) &&
484 !(fdwEnum & (ACM_FORMATENUMF_INPUT|ACM_FORMATENUMF_OUTPUT)))
485 return MMSYSERR_INVALPARAM;
487 if ((fdwEnum & ACM_FORMATENUMF_WFORMATTAG) &&
488 (pafd->dwFormatTag != pafd->pwfx->wFormatTag))
489 return MMSYSERR_INVALPARAM;
491 if (fdwEnum & (ACM_FORMATENUMF_CONVERT|ACM_FORMATENUMF_SUGGEST|
492 ACM_FORMATENUMF_INPUT|ACM_FORMATENUMF_OUTPUT))
493 FIXME("Unsupported fdwEnum values %08lx\n", fdwEnum);
498 if (acmDriverID(had, &hadid, 0) != MMSYSERR_NOERROR)
499 return MMSYSERR_INVALHANDLE;
500 MSACM_FormatEnumHelper(MSACM_GetDriverID(hadid), had, pafd, &wfxRef,
501 fnCallback, dwInstance, fdwEnum);
502 return MMSYSERR_NOERROR;
504 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
505 /* should check for codec only */
506 if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) ||
507 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
509 ret = MSACM_FormatEnumHelper(padid, had, pafd, &wfxRef,
510 fnCallback, dwInstance, fdwEnum);
511 acmDriverClose(had, 0);
514 return MMSYSERR_NOERROR;
517 /***********************************************************************
518 * acmFormatSuggest (MSACM32.@)
520 MMRESULT WINAPI acmFormatSuggest(HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
521 PWAVEFORMATEX pwfxDst, DWORD cbwfxDst, DWORD fdwSuggest)
523 ACMDRVFORMATSUGGEST adfg;
526 TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
527 had, pwfxSrc, pwfxDst, cbwfxDst, fdwSuggest);
529 if (fdwSuggest & ~(ACM_FORMATSUGGESTF_NCHANNELS|ACM_FORMATSUGGESTF_NSAMPLESPERSEC|
530 ACM_FORMATSUGGESTF_WBITSPERSAMPLE|ACM_FORMATSUGGESTF_WFORMATTAG))
531 return MMSYSERR_INVALFLAG;
533 adfg.cbStruct = sizeof(adfg);
534 adfg.fdwSuggest = fdwSuggest;
535 adfg.pwfxSrc = pwfxSrc;
536 adfg.cbwfxSrc = (pwfxSrc->wFormatTag == WAVE_FORMAT_PCM) ?
537 sizeof(WAVEFORMATEX) : pwfxSrc->cbSize;
538 adfg.pwfxDst = pwfxDst;
539 adfg.cbwfxDst = cbwfxDst;
541 if (had == (HACMDRIVER)NULL) {
542 PWINE_ACMDRIVERID padid;
544 /* MS doc says: ACM finds the best suggestion.
545 * Well, first found will be the "best"
547 mmr = ACMERR_NOTPOSSIBLE;
548 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
549 /* should check for codec only */
550 if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) ||
551 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
554 if (MSACM_Message(had, ACMDM_FORMAT_SUGGEST, (LPARAM)&adfg, 0L) == MMSYSERR_NOERROR) {
555 mmr = MMSYSERR_NOERROR;
558 acmDriverClose(had, 0);
561 mmr = MSACM_Message(had, ACMDM_FORMAT_SUGGEST, (LPARAM)&adfg, 0L);
566 /***********************************************************************
567 * acmFormatTagDetailsA (MSACM32.@)
569 MMRESULT WINAPI acmFormatTagDetailsA(HACMDRIVER had, PACMFORMATTAGDETAILSA paftda,
572 ACMFORMATTAGDETAILSW aftdw;
575 memset(&aftdw, 0, sizeof(aftdw));
576 aftdw.cbStruct = sizeof(aftdw);
577 aftdw.dwFormatTagIndex = paftda->dwFormatTagIndex;
578 aftdw.dwFormatTag = paftda->dwFormatTag;
580 mmr = acmFormatTagDetailsW(had, &aftdw, fdwDetails);
581 if (mmr == MMSYSERR_NOERROR) {
582 paftda->dwFormatTag = aftdw.dwFormatTag;
583 paftda->dwFormatTagIndex = aftdw.dwFormatTagIndex;
584 paftda->cbFormatSize = aftdw.cbFormatSize;
585 paftda->fdwSupport = aftdw.fdwSupport;
586 paftda->cStandardFormats = aftdw.cStandardFormats;
587 WideCharToMultiByte( CP_ACP, 0, aftdw.szFormatTag, -1, paftda->szFormatTag,
588 sizeof(paftda->szFormatTag), NULL, NULL );
593 /***********************************************************************
594 * acmFormatTagDetailsW (MSACM32.@)
596 MMRESULT WINAPI acmFormatTagDetailsW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd,
599 PWINE_ACMDRIVERID padid;
600 MMRESULT mmr = ACMERR_NOTPOSSIBLE;
602 TRACE("(0x%08x, %p, %ld)\n", had, paftd, fdwDetails);
604 if (fdwDetails & ~(ACM_FORMATTAGDETAILSF_FORMATTAG|ACM_FORMATTAGDETAILSF_INDEX|
605 ACM_FORMATTAGDETAILSF_LARGESTSIZE))
606 return MMSYSERR_INVALFLAG;
608 switch (fdwDetails) {
609 case ACM_FORMATTAGDETAILSF_FORMATTAG:
610 if (had == (HACMDRIVER)NULL) {
611 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
612 /* should check for codec only */
613 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
614 MSACM_FindFormatTagInCache(padid, paftd->dwFormatTag, NULL) &&
615 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
616 mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails);
617 acmDriverClose(had, 0);
618 if (mmr == MMSYSERR_NOERROR) break;
622 PWINE_ACMDRIVER pad = MSACM_GetDriver(had);
624 if (pad && MSACM_FindFormatTagInCache(pad->obj.pACMDriverID, paftd->dwFormatTag, NULL))
625 mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails);
629 case ACM_FORMATTAGDETAILSF_INDEX:
630 if (had != (HACMDRIVER)NULL) {
631 PWINE_ACMDRIVER pad = MSACM_GetDriver(had);
633 if (pad && paftd->dwFormatTagIndex < pad->obj.pACMDriverID->cFormatTags)
634 mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails);
638 case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
639 if (had == (HACMDRIVER)NULL) {
640 ACMFORMATTAGDETAILSW tmp;
641 DWORD ft = paftd->dwFormatTag;
643 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
644 /* should check for codec only */
645 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
646 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
648 memset(&tmp, 0, sizeof(tmp));
649 tmp.cbStruct = sizeof(tmp);
650 tmp.dwFormatTag = ft;
652 if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS,
653 (LPARAM)&tmp, fdwDetails) == MMSYSERR_NOERROR) {
654 if (mmr == ACMERR_NOTPOSSIBLE ||
655 paftd->cbFormatSize < tmp.cbFormatSize) {
657 mmr = MMSYSERR_NOERROR;
660 acmDriverClose(had, 0);
664 mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails);
669 WARN("Unsupported fdwDetails=%08lx\n", fdwDetails);
670 mmr = MMSYSERR_ERROR;
673 if (mmr == MMSYSERR_NOERROR &&
674 paftd->dwFormatTag == WAVE_FORMAT_PCM && paftd->szFormatTag[0] == 0)
675 MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag,
676 sizeof(paftd->szFormatTag)/sizeof(WCHAR) );
681 struct MSACM_FormatTagEnumWtoA_Instance {
682 PACMFORMATTAGDETAILSA paftda;
684 ACMFORMATTAGENUMCBA fnCallback;
687 static BOOL CALLBACK MSACM_FormatTagEnumCallbackWtoA(HACMDRIVERID hadid,
688 PACMFORMATTAGDETAILSW paftdw,
692 struct MSACM_FormatTagEnumWtoA_Instance* paftei;
694 paftei = (struct MSACM_FormatTagEnumWtoA_Instance*)dwInstance;
696 paftei->paftda->dwFormatTagIndex = paftdw->dwFormatTagIndex;
697 paftei->paftda->dwFormatTag = paftdw->dwFormatTag;
698 paftei->paftda->cbFormatSize = paftdw->cbFormatSize;
699 paftei->paftda->fdwSupport = paftdw->fdwSupport;
700 paftei->paftda->cStandardFormats = paftdw->cStandardFormats;
701 WideCharToMultiByte( CP_ACP, 0, paftdw->szFormatTag, -1, paftei->paftda->szFormatTag,
702 sizeof(paftei->paftda->szFormatTag), NULL, NULL );
704 return (paftei->fnCallback)(hadid, paftei->paftda,
705 paftei->dwInstance, fdwSupport);
708 /***********************************************************************
709 * acmFormatTagEnumA (MSACM32.@)
711 MMRESULT WINAPI acmFormatTagEnumA(HACMDRIVER had, PACMFORMATTAGDETAILSA paftda,
712 ACMFORMATTAGENUMCBA fnCallback, DWORD dwInstance,
715 ACMFORMATTAGDETAILSW aftdw;
716 struct MSACM_FormatTagEnumWtoA_Instance aftei;
718 memset(&aftdw, 0, sizeof(aftdw));
719 aftdw.cbStruct = sizeof(aftdw);
720 aftdw.dwFormatTagIndex = paftda->dwFormatTagIndex;
721 aftdw.dwFormatTag = paftda->dwFormatTag;
723 aftei.paftda = paftda;
724 aftei.dwInstance = dwInstance;
725 aftei.fnCallback = fnCallback;
727 return acmFormatTagEnumW(had, &aftdw, MSACM_FormatTagEnumCallbackWtoA,
728 (DWORD)&aftei, fdwEnum);
731 /***********************************************************************
732 * acmFormatTagEnumW (MSACM32.@)
734 MMRESULT WINAPI acmFormatTagEnumW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd,
735 ACMFORMATTAGENUMCBW fnCallback, DWORD dwInstance,
738 PWINE_ACMDRIVERID padid;
740 BOOL bPcmDone = FALSE;
742 TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
743 had, paftd, fnCallback, dwInstance, fdwEnum);
745 if (paftd->cbStruct < sizeof(*paftd)) return MMSYSERR_INVALPARAM;
747 if (had) FIXME("had != NULL, not supported\n");
749 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
750 /* should check for codec only */
751 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
752 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) {
753 for (i = 0; i < padid->cFormatTags; i++) {
754 paftd->dwFormatTagIndex = i;
755 if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS,
756 (LPARAM)paftd, ACM_FORMATTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
757 if (paftd->dwFormatTag == WAVE_FORMAT_PCM) {
758 if (paftd->szFormatTag[0] == 0)
759 MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag,
760 sizeof(paftd->szFormatTag)/sizeof(WCHAR) );
761 /* FIXME (EPP): I'm not sure this is the correct
762 * algorithm (should make more sense to apply the same
763 * for all already loaded formats, but this will do
766 if (bPcmDone) continue;
769 if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) {
770 padid = NULL; /* to exist the two nested for loops */
776 acmDriverClose(had, 0);
778 return MMSYSERR_NOERROR;