Added pow() forward.
[wine.git] / dlls / msacm / filter.c
blob54613be8f882b661b01474ece4e38d3895894f79
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
3 /*
4 * MSACM32 library
6 * Copyright 1998 Patrik Stridvall
7 */
9 #include "winbase.h"
10 #include "winerror.h"
11 #include "wine/winestring.h"
12 #include "mmsystem.h"
13 #include "msacm.h"
14 #include "msacmdrv.h"
15 #include "wineacm.h"
16 #include "debugtools.h"
18 DEFAULT_DEBUG_CHANNEL(msacm);
20 /***********************************************************************
21 * acmFilterChooseA (MSACM32.13)
23 MMRESULT WINAPI acmFilterChooseA(PACMFILTERCHOOSEA pafltrc)
25 FIXME("(%p): stub\n", pafltrc);
26 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
27 return MMSYSERR_ERROR;
30 /***********************************************************************
31 * acmFilterChooseW (MSACM32.14)
33 MMRESULT WINAPI acmFilterChooseW(PACMFILTERCHOOSEW pafltrc)
35 FIXME("(%p): stub\n", pafltrc);
36 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
37 return MMSYSERR_ERROR;
40 /***********************************************************************
41 * acmFilterDetailsA (MSACM32.15)
43 MMRESULT WINAPI acmFilterDetailsA(HACMDRIVER had, PACMFILTERDETAILSA pafd,
44 DWORD fdwDetails)
46 ACMFILTERDETAILSW afdw;
47 MMRESULT mmr;
49 memset(&afdw, 0, sizeof(afdw));
50 afdw.cbStruct = sizeof(afdw);
51 afdw.dwFilterIndex = pafd->dwFilterIndex;
52 afdw.dwFilterTag = pafd->dwFilterTag;
53 afdw.pwfltr = pafd->pwfltr;
54 afdw.cbwfltr = pafd->cbwfltr;
56 mmr = acmFilterDetailsW(had, &afdw, fdwDetails);
57 if (mmr == MMSYSERR_NOERROR) {
58 pafd->dwFilterTag = afdw.dwFilterTag;
59 pafd->fdwSupport = afdw.fdwSupport;
60 lstrcpyWtoA(pafd->szFilter, afdw.szFilter);
62 return mmr;
65 /***********************************************************************
66 * acmFilterDetailsW (MSACM32.16)
68 MMRESULT WINAPI acmFilterDetailsW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
69 DWORD fdwDetails)
71 MMRESULT mmr;
72 ACMFILTERTAGDETAILSA aftd;
74 TRACE("(0x%08x, %p, %ld)\n", had, pafd, fdwDetails);
76 memset(&aftd, 0, sizeof(aftd));
77 aftd.cbStruct = sizeof(aftd);
79 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
81 switch (fdwDetails) {
82 case ACM_FILTERDETAILSF_FILTER:
83 if (pafd->dwFilterTag != pafd->pwfltr->dwFilterTag) {
84 mmr = MMSYSERR_INVALPARAM;
85 break;
87 if (had == (HACMDRIVER)NULL) {
88 PWINE_ACMDRIVERID padid;
90 mmr = ACMERR_NOTPOSSIBLE;
91 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
92 /* should check for codec only */
93 if (padid->bEnabled &&
94 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
95 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
96 (LPARAM)pafd, (LPARAM)fdwDetails);
97 acmDriverClose(had, 0);
98 if (mmr == MMSYSERR_NOERROR) break;
101 } else {
102 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
103 (LPARAM)pafd, (LPARAM)fdwDetails);
105 break;
106 case ACM_FILTERDETAILSF_INDEX:
107 /* should check pafd->dwFilterIndex < aftd->cStandardFilters */
108 mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
109 (LPARAM)pafd, (LPARAM)fdwDetails);
110 break;
111 default:
112 WARN("Unknown fdwDetails %08lx\n", fdwDetails);
113 mmr = MMSYSERR_INVALFLAG;
114 break;
117 TRACE("=> %d\n", mmr);
118 return mmr;
121 struct MSACM_FilterEnumWtoA_Instance {
122 PACMFILTERDETAILSA pafda;
123 DWORD dwInstance;
124 ACMFILTERENUMCBA fnCallback;
127 static BOOL CALLBACK MSACM_FilterEnumCallbackWtoA(HACMDRIVERID hadid,
128 PACMFILTERDETAILSW pafdw,
129 DWORD dwInstance,
130 DWORD fdwSupport)
132 struct MSACM_FilterEnumWtoA_Instance* pafei;
134 pafei = (struct MSACM_FilterEnumWtoA_Instance*)dwInstance;
136 pafei->pafda->dwFilterIndex = pafdw->dwFilterIndex;
137 pafei->pafda->dwFilterTag = pafdw->dwFilterTag;
138 pafei->pafda->fdwSupport = pafdw->fdwSupport;
139 lstrcpyWtoA(pafei->pafda->szFilter, pafdw->szFilter);
141 return (pafei->fnCallback)(hadid, pafei->pafda,
142 pafei->dwInstance, fdwSupport);
145 /***********************************************************************
146 * acmFilterEnumA (MSACM32.17)
148 MMRESULT WINAPI acmFilterEnumA(HACMDRIVER had, PACMFILTERDETAILSA pafda,
149 ACMFILTERENUMCBA fnCallback, DWORD dwInstance,
150 DWORD fdwEnum)
152 ACMFILTERDETAILSW afdw;
153 struct MSACM_FilterEnumWtoA_Instance afei;
155 memset(&afdw, 0, sizeof(afdw));
156 afdw.cbStruct = sizeof(afdw);
157 afdw.dwFilterIndex = pafda->dwFilterIndex;
158 afdw.dwFilterTag = pafda->dwFilterTag;
159 afdw.pwfltr = pafda->pwfltr;
160 afdw.cbwfltr = pafda->cbwfltr;
162 afei.pafda = pafda;
163 afei.dwInstance = dwInstance;
164 afei.fnCallback = fnCallback;
166 return acmFilterEnumW(had, &afdw, MSACM_FilterEnumCallbackWtoA,
167 (DWORD)&afei, fdwEnum);
170 static BOOL MSACM_FilterEnumHelper(PWINE_ACMDRIVERID padid, HACMDRIVER had,
171 PACMFILTERDETAILSW pafd,
172 ACMFILTERENUMCBW fnCallback, DWORD dwInstance,
173 DWORD fdwEnum)
175 ACMDRIVERDETAILSW add;
176 ACMFILTERTAGDETAILSW aftd;
177 int i, j;
179 add.cbStruct = sizeof(add);
181 if (acmDriverDetailsW((HACMDRIVERID)padid, &add, 0) != MMSYSERR_NOERROR) return FALSE;
183 for (i = 0; i < add.cFilterTags; i++) {
184 memset(&aftd, 0, sizeof(aftd));
185 aftd.cbStruct = sizeof(aftd);
186 aftd.dwFilterTagIndex = i;
187 if (acmFilterTagDetailsW(had, &aftd, ACM_FILTERTAGDETAILSF_INDEX) != MMSYSERR_NOERROR)
188 continue;
190 if ((fdwEnum & ACM_FILTERENUMF_DWFILTERTAG) &&
191 aftd.dwFilterTag != pafd->pwfltr->dwFilterTag)
192 continue;
194 for (j = 0; j < aftd.cStandardFilters; j++) {
195 pafd->dwFilterIndex = j;
196 pafd->dwFilterTag = aftd.dwFilterTag;
197 if (acmFilterDetailsW(had, pafd, ACM_FILTERDETAILSF_INDEX) != MMSYSERR_NOERROR)
198 continue;
200 if (!(fnCallback)((HACMDRIVERID)padid, pafd, dwInstance, add.fdwSupport))
201 return FALSE;
204 return TRUE;
207 /***********************************************************************
208 * acmFilterEnumW (MSACM32.18)
210 MMRESULT WINAPI acmFilterEnumW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
211 ACMFILTERENUMCBW fnCallback, DWORD dwInstance,
212 DWORD fdwEnum)
214 PWINE_ACMDRIVERID padid;
215 BOOL ret;
217 TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
218 had, pafd, fnCallback, dwInstance, fdwEnum);
220 if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;
222 if (fdwEnum & ~(ACM_FILTERENUMF_DWFILTERTAG))
223 FIXME("Unsupported fdwEnum values\n");
225 if (had) {
226 HACMDRIVERID hadid;
228 if (acmDriverID(had, &hadid, 0) != MMSYSERR_NOERROR)
229 return MMSYSERR_INVALHANDLE;
230 return MSACM_FilterEnumHelper(MSACM_GetDriverID(hadid), had, pafd,
231 fnCallback, dwInstance, fdwEnum);
233 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
234 /* should check for codec only */
235 if (!padid->bEnabled || acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
236 continue;
237 ret = MSACM_FilterEnumHelper(padid, had, pafd,
238 fnCallback, dwInstance, fdwEnum);
239 acmDriverClose(had, 0);
240 if (!ret) break;
242 return MMSYSERR_NOERROR;
245 /***********************************************************************
246 * acmFilterTagDetailsA (MSACM32.19)
248 MMRESULT WINAPI acmFilterTagDetailsA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda,
249 DWORD fdwDetails)
251 ACMFILTERTAGDETAILSW aftdw;
252 MMRESULT mmr;
254 memset(&aftdw, 0, sizeof(aftdw));
255 aftdw.cbStruct = sizeof(aftdw);
256 aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
257 aftdw.dwFilterTag = paftda->dwFilterTag;
259 mmr = acmFilterTagDetailsW(had, &aftdw, fdwDetails);
260 if (mmr == MMSYSERR_NOERROR) {
261 paftda->dwFilterTag = aftdw.dwFilterTag;
262 paftda->dwFilterTagIndex = aftdw.dwFilterTagIndex;
263 paftda->cbFilterSize = aftdw.cbFilterSize;
264 paftda->fdwSupport = aftdw.fdwSupport;
265 paftda->cStandardFilters = aftdw.cStandardFilters;
266 lstrcpyWtoA(paftda->szFilterTag, aftdw.szFilterTag);
268 return mmr;
271 /***********************************************************************
272 * acmFilterTagDetailsW (MSACM32.20)
274 MMRESULT WINAPI acmFilterTagDetailsW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
275 DWORD fdwDetails)
277 PWINE_ACMDRIVERID padid;
278 MMRESULT mmr;
280 TRACE("(0x%08x, %p, %ld)\n", had, paftd, fdwDetails);
282 if (fdwDetails & ~(ACM_FILTERTAGDETAILSF_FILTERTAG|ACM_FILTERTAGDETAILSF_INDEX|
283 ACM_FILTERTAGDETAILSF_LARGESTSIZE))
284 return MMSYSERR_INVALFLAG;
286 switch (fdwDetails) {
287 case ACM_FILTERTAGDETAILSF_FILTERTAG:
288 if (had == (HACMDRIVER)NULL) {
289 mmr = ACMERR_NOTPOSSIBLE;
290 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
291 /* should check for codec only */
292 if (padid->bEnabled && acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
293 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
294 (LPARAM)paftd, (LPARAM)fdwDetails);
295 acmDriverClose(had, 0);
296 if (mmr == MMSYSERR_NOERROR) break;
299 } else {
300 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
301 (LPARAM)paftd, (LPARAM)fdwDetails);
303 break;
305 case ACM_FILTERTAGDETAILSF_INDEX:
306 /* FIXME should check paftd->dwFilterTagIndex < add.cFilterTags */
307 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
308 (LPARAM)paftd, (LPARAM)fdwDetails);
309 break;
311 case ACM_FILTERTAGDETAILSF_LARGESTSIZE:
312 if (had == (HACMDRIVER)NULL) {
313 ACMFILTERTAGDETAILSW tmp;
314 DWORD ft = paftd->dwFilterTag;
316 mmr = ACMERR_NOTPOSSIBLE;
317 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
318 /* should check for codec only */
319 if (padid->bEnabled &&
320 acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
322 memset(&tmp, 0, sizeof(tmp));
323 tmp.cbStruct = sizeof(tmp);
324 tmp.dwFilterTag = ft;
326 if (MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
327 (LPARAM)&tmp,
328 (LPARAM)fdwDetails) == MMSYSERR_NOERROR) {
329 if (mmr == ACMERR_NOTPOSSIBLE ||
330 paftd->cbFilterSize < tmp.cbFilterSize) {
331 *paftd = tmp;
332 mmr = MMSYSERR_NOERROR;
335 acmDriverClose(had, 0);
338 } else {
339 mmr = MSACM_Message(had, ACMDM_FILTERTAG_DETAILS,
340 (LPARAM)paftd, (LPARAM)fdwDetails);
342 break;
344 default:
345 WARN("Unsupported fdwDetails=%08lx\n", fdwDetails);
346 mmr = MMSYSERR_ERROR;
349 if (mmr == MMSYSERR_NOERROR &&
350 paftd->dwFilterTag == WAVE_FORMAT_PCM && paftd->szFilterTag[0] == 0)
351 lstrcpyAtoW(paftd->szFilterTag, "PCM");
353 return mmr;
356 struct MSACM_FilterTagEnumWtoA_Instance {
357 PACMFILTERTAGDETAILSA paftda;
358 DWORD dwInstance;
359 ACMFILTERTAGENUMCBA fnCallback;
362 static BOOL CALLBACK MSACM_FilterTagEnumCallbackWtoA(HACMDRIVERID hadid,
363 PACMFILTERTAGDETAILSW paftdw,
364 DWORD dwInstance,
365 DWORD fdwSupport)
367 struct MSACM_FilterTagEnumWtoA_Instance* paftei;
369 paftei = (struct MSACM_FilterTagEnumWtoA_Instance*)dwInstance;
371 paftei->paftda->dwFilterTagIndex = paftdw->dwFilterTagIndex;
372 paftei->paftda->dwFilterTag = paftdw->dwFilterTag;
373 paftei->paftda->cbFilterSize = paftdw->cbFilterSize;
374 paftei->paftda->fdwSupport = paftdw->fdwSupport;
375 paftei->paftda->cStandardFilters = paftdw->cStandardFilters;
376 lstrcpyWtoA(paftei->paftda->szFilterTag, paftdw->szFilterTag);
378 return (paftei->fnCallback)(hadid, paftei->paftda,
379 paftei->dwInstance, fdwSupport);
382 /***********************************************************************
383 * acmFilterTagEnumA (MSACM32.21)
385 MMRESULT WINAPI acmFilterTagEnumA(HACMDRIVER had, PACMFILTERTAGDETAILSA paftda,
386 ACMFILTERTAGENUMCBA fnCallback, DWORD dwInstance,
387 DWORD fdwEnum)
389 ACMFILTERTAGDETAILSW aftdw;
390 struct MSACM_FilterTagEnumWtoA_Instance aftei;
392 memset(&aftdw, 0, sizeof(aftdw));
393 aftdw.cbStruct = sizeof(aftdw);
394 aftdw.dwFilterTagIndex = paftda->dwFilterTagIndex;
395 aftdw.dwFilterTag = paftda->dwFilterTag;
397 aftei.paftda = paftda;
398 aftei.dwInstance = dwInstance;
399 aftei.fnCallback = fnCallback;
401 return acmFilterTagEnumW(had, &aftdw, MSACM_FilterTagEnumCallbackWtoA,
402 (DWORD)&aftei, fdwEnum);
405 /***********************************************************************
406 * acmFilterTagEnumW (MSACM32.22)
408 MMRESULT WINAPI acmFilterTagEnumW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
409 ACMFILTERTAGENUMCBW fnCallback, DWORD dwInstance,
410 DWORD fdwEnum)
412 PWINE_ACMDRIVERID padid;
413 ACMDRIVERDETAILSW add;
414 int i;
416 TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
417 had, paftd, fnCallback, dwInstance, fdwEnum);
419 if (paftd->cbStruct < sizeof(*paftd)) return MMSYSERR_INVALPARAM;
421 if (had) FIXME("had != NULL, not supported\n");
423 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
424 /* should check for codec only */
425 if (padid->bEnabled && acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) {
426 add.cbStruct = sizeof(add);
428 if (acmDriverDetailsW((HACMDRIVERID)padid, &add, 0) == MMSYSERR_NOERROR) {
429 for (i = 0; i < add.cFilterTags; i++) {
430 paftd->dwFilterTagIndex = i;
431 if (acmFilterTagDetailsW(had, paftd, ACM_FILTERTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
432 if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance,
433 add.fdwSupport)) {
434 padid = NULL;
435 break;
441 acmDriverClose(had, 0);
443 return MMSYSERR_NOERROR;