4 * Copyright (C) 1998 Patrick Stridvall
5 * Copyright (C) 1999 Eric Pouech
7 * Originally distributed under LPGL 2.1 (or later) by the Wine project.
9 * Modified for use with MPlayer, detailed CVS changelog at
10 * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
12 * File now distributed as part of VLC media player with no modifications.
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
29 /**************************************************************************
32 This file will contain an interface to ACM drivers.
33 Its content will be based mainly on wine/dlls/msacm32
34 actually, for audio decompression only the following functions
37 acmStreamOpen ( takes formats of src and dest, returns stream handle )
38 acmStreamPrepareHeader ( takes stream handler and info on data )
39 acmStreamConvert ( the same as PrepareHeader )
40 acmStreamUnprepareHeader
45 In future I'll also add functions for format enumeration,
48 Modified for use with MPlayer, detailed CVS changelog at
49 http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
51 ***************************************************************************/
54 #include "wine/winbase.h"
55 #include "wine/windef.h"
56 #include "wine/winuser.h"
58 #include "wine/winestring.h"
59 #include "wine/driver.h"
60 #include "wine/winerror.h"
61 #include "wine/msacm.h"
62 #include "wine/msacmdrv.h"
73 #define OpenDriverA DrvOpen
74 #define CloseDriver DrvClose
76 static inline PWINE_ACMSTREAM
ACM_GetStream(HACMSTREAM has
)
78 return (PWINE_ACMSTREAM
)has
;
81 /***********************************************************************
82 * acmDriverAddA (MSACM32.2)
84 MMRESULT WINAPI
acmDriverAddA(PHACMDRIVERID phadid
, HINSTANCE hinstModule
,
85 LPARAM lParam
, DWORD dwPriority
, DWORD fdwAdd
)
88 return MMSYSERR_INVALPARAM
;
90 /* Check if any unknown flags */
92 ~(ACM_DRIVERADDF_FUNCTION
|ACM_DRIVERADDF_NOTIFYHWND
|
93 ACM_DRIVERADDF_GLOBAL
))
94 return MMSYSERR_INVALFLAG
;
96 /* Check if any incompatible flags */
97 if ((fdwAdd
& ACM_DRIVERADDF_FUNCTION
) &&
98 (fdwAdd
& ACM_DRIVERADDF_NOTIFYHWND
))
99 return MMSYSERR_INVALFLAG
;
101 /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a
102 * LoadDriver on it, to be sure we can call SendDriverMessage on the
105 *phadid
= (HACMDRIVERID
) MSACM_RegisterDriver(NULL
, 0, hinstModule
);
107 /* FIXME: lParam, dwPriority and fdwAdd ignored */
109 return MMSYSERR_NOERROR
;
112 /***********************************************************************
113 * acmDriverClose (MSACM32.4)
115 MMRESULT WINAPI
acmDriverClose(HACMDRIVER had
, DWORD fdwClose
)
121 return MMSYSERR_INVALFLAG
;
123 p
= MSACM_GetDriver(had
);
125 return MMSYSERR_INVALHANDLE
;
127 for (tp
= &(p
->obj
.pACMDriverID
->pACMDriverList
); *tp
; *tp
= (*tp
)->pNextACMDriver
) {
129 *tp
= (*tp
)->pNextACMDriver
;
134 if (p
->hDrvr
&& !p
->obj
.pACMDriverID
->pACMDriverList
)
135 CloseDriver(p
->hDrvr
);
137 HeapFree(MSACM_hHeap
, 0, p
);
139 return MMSYSERR_NOERROR
;
142 /***********************************************************************
143 * acmDriverEnum (MSACM32.7)
145 MMRESULT WINAPI
acmDriverEnum(ACMDRIVERENUMCB fnCallback
, DWORD dwInstance
, DWORD fdwEnum
)
151 return MMSYSERR_INVALPARAM
;
154 if (fdwEnum
&& ~(ACM_DRIVERENUMF_NOLOCAL
|ACM_DRIVERENUMF_DISABLED
)) {
155 return MMSYSERR_INVALFLAG
;
158 for (p
= MSACM_pFirstACMDriverID
; p
; p
= p
->pNextACMDriverID
) {
159 fdwSupport
= ACMDRIVERDETAILS_SUPPORTF_CODEC
;
161 if (fdwEnum
& ACM_DRIVERENUMF_DISABLED
)
162 fdwSupport
|= ACMDRIVERDETAILS_SUPPORTF_DISABLED
;
166 (*fnCallback
)((HACMDRIVERID
) p
, dwInstance
, fdwSupport
);
169 return MMSYSERR_NOERROR
;
172 /***********************************************************************
173 * acmDriverID (MSACM32.8)
175 MMRESULT WINAPI
acmDriverID(HACMOBJ hao
, PHACMDRIVERID phadid
, DWORD fdwDriverID
)
179 pao
= MSACM_GetObj(hao
);
181 return MMSYSERR_INVALHANDLE
;
184 return MMSYSERR_INVALPARAM
;
187 return MMSYSERR_INVALFLAG
;
189 *phadid
= (HACMDRIVERID
) pao
->pACMDriverID
;
191 return MMSYSERR_NOERROR
;
194 /***********************************************************************
195 * acmDriverMessage (MSACM32.9)
199 LRESULT WINAPI
acmDriverMessage(HACMDRIVER had
, UINT uMsg
, LPARAM lParam1
, LPARAM lParam2
)
201 PWINE_ACMDRIVER pad
= MSACM_GetDriver(had
);
203 return MMSYSERR_INVALPARAM
;
205 /* FIXME: Check if uMsg legal */
207 if (!SendDriverMessage(pad
->hDrvr
, uMsg
, lParam1
, lParam2
))
208 return MMSYSERR_NOTSUPPORTED
;
210 return MMSYSERR_NOERROR
;
214 /***********************************************************************
215 * acmDriverOpen (MSACM32.10)
217 MMRESULT WINAPI
acmDriverOpen(PHACMDRIVER phad
, HACMDRIVERID hadid
, DWORD fdwOpen
)
219 PWINE_ACMDRIVERID padid
;
225 TRACE("(%p, %x, %08lu)\n", phad
, hadid
, fdwOpen
);
228 return MMSYSERR_INVALPARAM
;
230 padid
= MSACM_GetDriverID(hadid
);
232 return MMSYSERR_INVALHANDLE
;
235 return MMSYSERR_INVALFLAG
;
237 pad
= (PWINE_ACMDRIVER
) HeapAlloc(MSACM_hHeap
, 0, sizeof(WINE_ACMDRIVER
));
239 return MMSYSERR_NOMEM
;
241 pad
->obj
.pACMDriverID
= padid
;
242 icopen
.fccType
= mmioFOURCC('a', 'u', 'd', 'c');
243 icopen
.fccHandler
= (long)padid
->pszFileName
;
244 icopen
.dwSize
= sizeof(ICOPEN
);
247 icopen
.pV1Reserved
= padid
->pszFileName
;
248 if (!padid
->hInstModule
)
249 pad
->hDrvr
= OpenDriverA((long)&icopen
);
251 pad
->hDrvr
= padid
->hInstModule
;
254 HeapFree(MSACM_hHeap
, 0, pad
);
255 return MMSYSERR_ERROR
;
258 pad
->pfnDriverProc
= GetProcAddress(pad
->hDrvr
, "DriverProc");
260 /* insert new pad at beg of list */
261 pad
->pNextACMDriver
= padid
->pACMDriverList
;
262 padid
->pACMDriverList
= pad
;
264 /* FIXME: Create a WINE_ACMDRIVER32 */
265 *phad
= (HACMDRIVER
)pad
;
267 return MMSYSERR_NOERROR
;
270 /***********************************************************************
271 * acmDriverRemove (MSACM32.12)
273 MMRESULT WINAPI
acmDriverRemove(HACMDRIVERID hadid
, DWORD fdwRemove
)
275 PWINE_ACMDRIVERID padid
;
277 padid
= MSACM_GetDriverID(hadid
);
279 return MMSYSERR_INVALHANDLE
;
282 return MMSYSERR_INVALFLAG
;
284 MSACM_UnregisterDriver(padid
);
286 return MMSYSERR_NOERROR
;
291 /**********************************************************************/
293 HANDLE MSACM_hHeap
= (HANDLE
) NULL
;
294 PWINE_ACMDRIVERID MSACM_pFirstACMDriverID
= NULL
;
295 PWINE_ACMDRIVERID MSACM_pLastACMDriverID
= NULL
;
297 /***********************************************************************
298 * MSACM_RegisterDriver32()
300 PWINE_ACMDRIVERID
MSACM_RegisterDriver(const char* pszFileName
,
302 HINSTANCE hinstModule
)
304 PWINE_ACMDRIVERID padid
;
306 TRACE("('%s', '%x', 0x%08x)\n", pszFileName
, wFormatTag
, hinstModule
);
309 MSACM_hHeap
= GetProcessHeap();
311 padid
= (PWINE_ACMDRIVERID
) HeapAlloc(MSACM_hHeap
, 0, sizeof(WINE_ACMDRIVERID
));
312 padid
->pszFileName
= (char*)malloc(strlen(pszFileName
)+1);
313 strcpy(padid
->pszFileName
, pszFileName
);
314 // 1~strdup(pszDriverAlias);
315 padid
->wFormatTag
= wFormatTag
;
316 padid
->hInstModule
= hinstModule
;
317 padid
->bEnabled
= TRUE
;
318 padid
->pACMDriverList
= NULL
;
319 padid
->pNextACMDriverID
= NULL
;
320 padid
->pPrevACMDriverID
= MSACM_pLastACMDriverID
;
321 if (MSACM_pLastACMDriverID
)
322 MSACM_pLastACMDriverID
->pNextACMDriverID
= padid
;
323 MSACM_pLastACMDriverID
= padid
;
324 if (!MSACM_pFirstACMDriverID
)
325 MSACM_pFirstACMDriverID
= padid
;
331 /***********************************************************************
332 * MSACM_UnregisterDriver32()
334 PWINE_ACMDRIVERID
MSACM_UnregisterDriver(PWINE_ACMDRIVERID p
)
336 PWINE_ACMDRIVERID pNextACMDriverID
;
338 while (p
->pACMDriverList
)
339 acmDriverClose((HACMDRIVER
) p
->pACMDriverList
, 0);
342 free(p
->pszFileName
);
344 if (p
== MSACM_pFirstACMDriverID
)
345 MSACM_pFirstACMDriverID
= p
->pNextACMDriverID
;
346 if (p
== MSACM_pLastACMDriverID
)
347 MSACM_pLastACMDriverID
= p
->pPrevACMDriverID
;
349 if (p
->pPrevACMDriverID
)
350 p
->pPrevACMDriverID
->pNextACMDriverID
= p
->pNextACMDriverID
;
351 if (p
->pNextACMDriverID
)
352 p
->pNextACMDriverID
->pPrevACMDriverID
= p
->pPrevACMDriverID
;
354 pNextACMDriverID
= p
->pNextACMDriverID
;
356 HeapFree(MSACM_hHeap
, 0, p
);
358 return pNextACMDriverID
;
361 /***********************************************************************
362 * MSACM_UnregisterAllDrivers32()
364 * Where should this function be called?
366 void MSACM_UnregisterAllDrivers(void)
370 for (p
= MSACM_pFirstACMDriverID
; p
; p
= MSACM_UnregisterDriver(p
));
373 /***********************************************************************
374 * MSACM_GetDriverID32()
376 PWINE_ACMDRIVERID
MSACM_GetDriverID(HACMDRIVERID hDriverID
)
378 return (PWINE_ACMDRIVERID
)hDriverID
;
381 /***********************************************************************
382 * MSACM_GetDriver32()
384 PWINE_ACMDRIVER
MSACM_GetDriver(HACMDRIVER hDriver
)
386 return (PWINE_ACMDRIVER
)hDriver
;
389 /***********************************************************************
392 PWINE_ACMOBJ
MSACM_GetObj(HACMOBJ hObj
)
394 return (PWINE_ACMOBJ
)hObj
;
399 /***********************************************************************
400 * acmStreamOpen (MSACM32.40)
402 MMRESULT WINAPI
acmStreamOpen(PHACMSTREAM phas
, HACMDRIVER had
, PWAVEFORMATEX pwfxSrc
,
403 PWAVEFORMATEX pwfxDst
, PWAVEFILTER pwfltr
, DWORD dwCallback
,
404 DWORD dwInstance
, DWORD fdwOpen
)
412 TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n",
413 phas
, had
, pwfxSrc
, pwfxDst
, pwfltr
, dwCallback
, dwInstance
, fdwOpen
);
415 TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
416 pwfxSrc
->wFormatTag
, pwfxSrc
->nChannels
, pwfxSrc
->nSamplesPerSec
, pwfxSrc
->nAvgBytesPerSec
,
417 pwfxSrc
->nBlockAlign
, pwfxSrc
->wBitsPerSample
, pwfxSrc
->cbSize
);
419 TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
420 pwfxDst
->wFormatTag
, pwfxDst
->nChannels
, pwfxDst
->nSamplesPerSec
, pwfxDst
->nAvgBytesPerSec
,
421 pwfxDst
->nBlockAlign
, pwfxDst
->wBitsPerSample
, pwfxDst
->cbSize
);
423 #define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
424 wfxSrcSize
= SIZEOF_WFX(pwfxSrc
);
425 wfxDstSize
= SIZEOF_WFX(pwfxDst
);
428 was
= (PWINE_ACMSTREAM
) HeapAlloc(MSACM_hHeap
, 0, sizeof(*was
) + wfxSrcSize
+ wfxDstSize
+ ((pwfltr
) ? sizeof(WAVEFILTER
) : 0));
430 return MMSYSERR_NOMEM
;
431 was
->drvInst
.cbStruct
= sizeof(was
->drvInst
);
432 was
->drvInst
.pwfxSrc
= (PWAVEFORMATEX
)((LPSTR
)was
+ sizeof(*was
));
433 memcpy(was
->drvInst
.pwfxSrc
, pwfxSrc
, wfxSrcSize
);
434 // LHACM is checking for 0x1
435 // but if this will not help
436 // was->drvInst.pwfxSrc->wFormatTag = 1;
437 was
->drvInst
.pwfxDst
= (PWAVEFORMATEX
)((LPSTR
)was
+ sizeof(*was
) + wfxSrcSize
);
438 memcpy(was
->drvInst
.pwfxDst
, pwfxDst
, wfxDstSize
);
440 was
->drvInst
.pwfltr
= (PWAVEFILTER
)((LPSTR
)was
+ sizeof(*was
) + wfxSrcSize
+ wfxDstSize
);
441 memcpy(was
->drvInst
.pwfltr
, pwfltr
, sizeof(WAVEFILTER
));
443 was
->drvInst
.pwfltr
= NULL
;
445 was
->drvInst
.dwCallback
= dwCallback
;
446 was
->drvInst
.dwInstance
= dwInstance
;
447 was
->drvInst
.fdwOpen
= fdwOpen
;
448 was
->drvInst
.fdwDriver
= 0L;
449 was
->drvInst
.dwDriver
= 0L;
450 was
->drvInst
.has
= (HACMSTREAM
)was
;
453 if (!(wad
= MSACM_GetDriver(had
))) {
454 ret
= MMSYSERR_INVALPARAM
;
458 was
->obj
.pACMDriverID
= wad
->obj
.pACMDriverID
;
460 was
->hAcmDriver
= 0; /* not to close it in acmStreamClose */
462 ret
= SendDriverMessage(wad
->hDrvr
, ACMDM_STREAM_OPEN
, (DWORD
)&was
->drvInst
, 0L);
463 if (ret
!= MMSYSERR_NOERROR
)
466 PWINE_ACMDRIVERID wadi
;
468 ret
= ACMERR_NOTPOSSIBLE
;
469 /* if(pwfxSrc->wFormatTag==1)//compression
470 drv_tag=pwfxDst->wFormatTag;
472 if(pwfxDst->wFormatTag==1)//decompression
473 drv_tag=pwfxSrc->wFormatTag;
477 ret=acmDriverOpen2(drv_tag);
478 if (ret == MMSYSERR_NOERROR) {
479 if ((wad = MSACM_GetDriver(had)) != 0) {
480 was->obj.pACMDriverID = wad->obj.pACMDriverID;
482 was->hAcmDriver = had;
484 ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
485 if (ret == MMSYSERR_NOERROR) {
486 if (fdwOpen & ACM_STREAMOPENF_QUERY) {
487 acmDriverClose(had, 0L);
492 acmDriverClose(had, 0L);*/
493 //if(MSACM_pFirstACMDriverID==NULL)
494 // MSACM_RegisterAllDrivers();
496 for (wadi
= MSACM_pFirstACMDriverID
; wadi
; wadi
= wadi
->pNextACMDriverID
)
499 if ((int)wadi
->wFormatTag
!= (int)pwfxSrc
->wFormatTag
) continue;
501 ret
= acmDriverOpen(&had
, (HACMDRIVERID
)wadi
, 0L);
502 if (ret
== MMSYSERR_NOERROR
) {
503 if ((wad
= MSACM_GetDriver(had
)) != 0) {
504 was
->obj
.pACMDriverID
= wad
->obj
.pACMDriverID
;
506 was
->hAcmDriver
= had
;
508 ret
= SendDriverMessage(wad
->hDrvr
, ACMDM_STREAM_OPEN
, (DWORD
)&was
->drvInst
, 0L);
509 //lhacm - crash printf("RETOPEN %d\n", ret);
511 if (ret
== MMSYSERR_NOERROR
) {
512 if (fdwOpen
& ACM_STREAMOPENF_QUERY
) {
513 acmDriverClose(had
, 0L);
518 // no match, close this acm driver and try next one
519 acmDriverClose(had
, 0L);
522 if (ret
!= MMSYSERR_NOERROR
) {
523 ret
= ACMERR_NOTPOSSIBLE
;
527 ret
= MMSYSERR_NOERROR
;
528 if (!(fdwOpen
& ACM_STREAMOPENF_QUERY
)) {
530 *phas
= (HACMSTREAM
)was
;
531 TRACE("=> (%d)\n", ret
);
539 *phas
= (HACMSTREAM
)0;
540 HeapFree(MSACM_hHeap
, 0, was
);
541 TRACE("=> (%d)\n", ret
);
546 MMRESULT WINAPI
acmStreamClose(HACMSTREAM has
, DWORD fdwClose
)
551 TRACE("(0x%08x, %ld)\n", has
, fdwClose
);
553 if ((was
= ACM_GetStream(has
)) == NULL
) {
554 return MMSYSERR_INVALHANDLE
;
556 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_CLOSE
, (DWORD
)&was
->drvInst
, 0);
557 if (ret
== MMSYSERR_NOERROR
) {
559 acmDriverClose(was
->hAcmDriver
, 0L);
560 HeapFree(MSACM_hHeap
, 0, was
);
565 TRACE("=> (%d)\n", ret
);
569 /***********************************************************************
570 * acmStreamConvert (MSACM32.38)
572 MMRESULT WINAPI
acmStreamConvert(HACMSTREAM has
, PACMSTREAMHEADER pash
,
576 MMRESULT ret
= MMSYSERR_NOERROR
;
577 PACMDRVSTREAMHEADER padsh
;
579 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwConvert
);
581 if ((was
= ACM_GetStream(has
)) == NULL
)
582 return MMSYSERR_INVALHANDLE
;
583 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
584 return MMSYSERR_INVALPARAM
;
586 if (!(pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_PREPARED
))
587 return ACMERR_UNPREPARED
;
589 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
590 * size. some fields are private to msacm internals, and are exposed
591 * in ACMSTREAMHEADER in the dwReservedDriver array
593 padsh
= (PACMDRVSTREAMHEADER
)pash
;
595 /* check that pointers have not been modified */
596 if (padsh
->pbPreparedSrc
!= padsh
->pbSrc
||
597 padsh
->cbPreparedSrcLength
< padsh
->cbSrcLength
||
598 padsh
->pbPreparedDst
!= padsh
->pbDst
||
599 padsh
->cbPreparedDstLength
< padsh
->cbDstLength
) {
600 return MMSYSERR_INVALPARAM
;
603 padsh
->fdwConvert
= fdwConvert
;
605 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_CONVERT
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
606 if (ret
== MMSYSERR_NOERROR
) {
607 padsh
->fdwStatus
|= ACMSTREAMHEADER_STATUSF_DONE
;
609 TRACE("=> (%d)\n", ret
);
614 /***********************************************************************
615 * acmStreamPrepareHeader (MSACM32.41)
617 MMRESULT WINAPI
acmStreamPrepareHeader(HACMSTREAM has
, PACMSTREAMHEADER pash
,
621 MMRESULT ret
= MMSYSERR_NOERROR
;
622 PACMDRVSTREAMHEADER padsh
;
624 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwPrepare
);
626 if ((was
= ACM_GetStream(has
)) == NULL
)
627 return MMSYSERR_INVALHANDLE
;
628 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
629 return MMSYSERR_INVALPARAM
;
631 ret
= MMSYSERR_INVALFLAG
;
633 if (pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_DONE
)
634 return MMSYSERR_NOERROR
;
636 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
637 * size. some fields are private to msacm internals, and are exposed
638 * in ACMSTREAMHEADER in the dwReservedDriver array
640 padsh
= (PACMDRVSTREAMHEADER
)pash
;
642 padsh
->fdwConvert
= fdwPrepare
;
643 padsh
->padshNext
= NULL
;
644 padsh
->fdwDriver
= padsh
->dwDriver
= 0L;
646 padsh
->fdwPrepared
= 0;
647 padsh
->dwPrepared
= 0;
648 padsh
->pbPreparedSrc
= 0;
649 padsh
->cbPreparedSrcLength
= 0;
650 padsh
->pbPreparedDst
= 0;
651 padsh
->cbPreparedDstLength
= 0;
653 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_PREPARE
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
654 if (ret
== MMSYSERR_NOERROR
|| ret
== MMSYSERR_NOTSUPPORTED
) {
655 ret
= MMSYSERR_NOERROR
;
656 padsh
->fdwStatus
&= ~(ACMSTREAMHEADER_STATUSF_DONE
|ACMSTREAMHEADER_STATUSF_INQUEUE
);
657 padsh
->fdwStatus
|= ACMSTREAMHEADER_STATUSF_PREPARED
;
658 padsh
->fdwPrepared
= padsh
->fdwStatus
;
659 padsh
->dwPrepared
= 0;
660 padsh
->pbPreparedSrc
= padsh
->pbSrc
;
661 padsh
->cbPreparedSrcLength
= padsh
->cbSrcLength
;
662 padsh
->pbPreparedDst
= padsh
->pbDst
;
663 padsh
->cbPreparedDstLength
= padsh
->cbDstLength
;
665 padsh
->fdwPrepared
= 0;
666 padsh
->dwPrepared
= 0;
667 padsh
->pbPreparedSrc
= 0;
668 padsh
->cbPreparedSrcLength
= 0;
669 padsh
->pbPreparedDst
= 0;
670 padsh
->cbPreparedDstLength
= 0;
672 TRACE("=> (%d)\n", ret
);
676 /***********************************************************************
677 * acmStreamReset (MSACM32.42)
679 MMRESULT WINAPI
acmStreamReset(HACMSTREAM has
, DWORD fdwReset
)
682 MMRESULT ret
= MMSYSERR_NOERROR
;
684 TRACE("(0x%08x, %ld)\n", has
, fdwReset
);
687 ret
= MMSYSERR_INVALFLAG
;
688 } else if ((was
= ACM_GetStream(has
)) == NULL
) {
689 return MMSYSERR_INVALHANDLE
;
690 } else if (was
->drvInst
.fdwOpen
& ACM_STREAMOPENF_ASYNC
) {
691 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_RESET
, (DWORD
)&was
->drvInst
, 0);
693 TRACE("=> (%d)\n", ret
);
697 /***********************************************************************
698 * acmStreamSize (MSACM32.43)
700 MMRESULT WINAPI
acmStreamSize(HACMSTREAM has
, DWORD cbInput
,
701 LPDWORD pdwOutputBytes
, DWORD fdwSize
)
704 ACMDRVSTREAMSIZE adss
;
707 TRACE("(0x%08x, %ld, %p, %ld)\n", has
, cbInput
, pdwOutputBytes
, fdwSize
);
709 if ((was
= ACM_GetStream(has
)) == NULL
) {
710 return MMSYSERR_INVALHANDLE
;
712 if ((fdwSize
& ~ACM_STREAMSIZEF_QUERYMASK
) != 0) {
713 return MMSYSERR_INVALFLAG
;
716 *pdwOutputBytes
= 0L;
718 switch (fdwSize
& ACM_STREAMSIZEF_QUERYMASK
) {
719 case ACM_STREAMSIZEF_DESTINATION
:
720 adss
.cbDstLength
= cbInput
;
721 adss
.cbSrcLength
= 0;
723 case ACM_STREAMSIZEF_SOURCE
:
724 adss
.cbSrcLength
= cbInput
;
725 adss
.cbDstLength
= 0;
728 return MMSYSERR_INVALFLAG
;
731 adss
.cbStruct
= sizeof(adss
);
732 adss
.fdwSize
= fdwSize
;
733 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_SIZE
,
734 (DWORD
)&was
->drvInst
, (DWORD
)&adss
);
735 if (ret
== MMSYSERR_NOERROR
) {
736 switch (fdwSize
& ACM_STREAMSIZEF_QUERYMASK
) {
737 case ACM_STREAMSIZEF_DESTINATION
:
738 *pdwOutputBytes
= adss
.cbSrcLength
;
740 case ACM_STREAMSIZEF_SOURCE
:
741 *pdwOutputBytes
= adss
.cbDstLength
;
745 TRACE("=> (%d) [%lu]\n", ret
, *pdwOutputBytes
);
749 /***********************************************************************
750 * acmStreamUnprepareHeader (MSACM32.44)
752 MMRESULT WINAPI
acmStreamUnprepareHeader(HACMSTREAM has
, PACMSTREAMHEADER pash
,
756 MMRESULT ret
= MMSYSERR_NOERROR
;
757 PACMDRVSTREAMHEADER padsh
;
759 TRACE("(0x%08x, %p, %ld)\n", has
, pash
, fdwUnprepare
);
761 if ((was
= ACM_GetStream(has
)) == NULL
)
762 return MMSYSERR_INVALHANDLE
;
763 if (!pash
|| pash
->cbStruct
< sizeof(ACMSTREAMHEADER
))
764 return MMSYSERR_INVALPARAM
;
766 if (!(pash
->fdwStatus
& ACMSTREAMHEADER_STATUSF_PREPARED
))
767 return ACMERR_UNPREPARED
;
769 /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
770 * size. some fields are private to msacm internals, and are exposed
771 * in ACMSTREAMHEADER in the dwReservedDriver array
773 padsh
= (PACMDRVSTREAMHEADER
)pash
;
775 /* check that pointers have not been modified */
776 if (padsh
->pbPreparedSrc
!= padsh
->pbSrc
||
777 padsh
->cbPreparedSrcLength
< padsh
->cbSrcLength
||
778 padsh
->pbPreparedDst
!= padsh
->pbDst
||
779 padsh
->cbPreparedDstLength
< padsh
->cbDstLength
) {
780 return MMSYSERR_INVALPARAM
;
783 padsh
->fdwConvert
= fdwUnprepare
;
785 ret
= SendDriverMessage(was
->pDrv
->hDrvr
, ACMDM_STREAM_UNPREPARE
, (DWORD
)&was
->drvInst
, (DWORD
)padsh
);
786 if (ret
== MMSYSERR_NOERROR
|| ret
== MMSYSERR_NOTSUPPORTED
) {
787 ret
= MMSYSERR_NOERROR
;
788 padsh
->fdwStatus
&= ~(ACMSTREAMHEADER_STATUSF_DONE
|ACMSTREAMHEADER_STATUSF_INQUEUE
|ACMSTREAMHEADER_STATUSF_PREPARED
);
790 TRACE("=> (%d)\n", ret
);