ReactOS 0.4.17-dev-934-g091855f
mciwave.c File Reference
#include <assert.h>
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "mmddk.h"
#include "wownt32.h"
#include "digitalv.h"
#include "wine/debug.h"
Include dependency graph for mciwave.c:

Go to the source code of this file.

Classes

struct  WINE_MCIWAVE
 
struct  SCA
 

Macros

#define WAVE_ALIGN_ON_BLOCK(wmw, v)   ((((v) + (wmw)->lpWaveFormat->nBlockAlign - 1) / (wmw)->lpWaveFormat->nBlockAlign) * (wmw)->lpWaveFormat->nBlockAlign)
 
#define WAVE_ALIGN_ON_BLOCK(wmw, v)   ((((v) + (wmw)->lpWaveFormat->nBlockAlign - 1) / (wmw)->lpWaveFormat->nBlockAlign) * (wmw)->lpWaveFormat->nBlockAlign)
 

Typedefs

typedef DWORD(* async_cmd) (MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE evt)
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (mciwave)
 
static DWORD CALLBACK MCI_SCAStarter (LPVOID arg)
 
static DWORD MCI_SendCommandAsync (UINT wDevID, async_cmd cmd, DWORD_PTR dwParam1, DWORD_PTR dwParam2, UINT size)
 
static DWORD WAVE_mciResume (UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 
static LRESULT WAVE_drvOpen (LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp)
 
static LRESULT WAVE_drvClose (MCIDEVICEID dwDevID)
 
static WINE_MCIWAVE * WAVE_mciGetOpenDev (MCIDEVICEID wDevID)
 
static void WAVE_mciNotify (DWORD_PTR hWndCallBack, WINE_MCIWAVE *wmw, UINT wStatus)
 
static DWORD WAVE_ConvertByteToTimeFormat (WINE_MCIWAVE *wmw, DWORD val)
 
static DWORD WAVE_ConvertTimeFormatToByte (WINE_MCIWAVE *wmw, DWORD val)
 
static DWORD WAVE_mciReadFmt (WINE_MCIWAVE *wmw, const MMCKINFO *pckMainRIFF)
 
static void WAVE_mciDefaultFmt (WINE_MCIWAVE *wmw)
 
static DWORD WAVE_mciCreateRIFFSkeleton (WINE_MCIWAVE *wmw)
 
static DWORD create_tmp_file (HMMIO *hFile, LPWSTR *pszTmpFileName)
 
static LRESULT WAVE_mciOpenFile (WINE_MCIWAVE *wmw, LPCWSTR filename)
 
static LRESULT WAVE_mciOpen (MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_PARMSW lpOpenParms)
 
static DWORD WAVE_mciCue (MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 
static DWORD WAVE_mciStop (MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 
static DWORD WAVE_mciClose (MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 
static void CALLBACK WAVE_mciPlayCallback (HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, LPARAM dwParam1, LPARAM dwParam2)
 
static void WAVE_mciPlayWaitDone (WINE_MCIWAVE *wmw)
 
static DWORD WAVE_mciPlay (MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE hEvent)
 
static void CALLBACK WAVE_mciRecordCallback (HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, LPARAM dwParam1, LPARAM dwParam2)
 
static void WAVE_mciRecordWaitDone (WINE_MCIWAVE *wmw)
 
static DWORD WAVE_mciRecord (MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE hEvent)
 
static DWORD WAVE_mciPause (MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 
static DWORD WAVE_mciSeek (MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
 
static DWORD WAVE_mciSet (MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_WAVE_SET_PARMS lpParms)
 
static DWORD WAVE_mciSave (MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SAVE_PARMSW lpParms)
 
static DWORD WAVE_mciStatus (MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
 
static DWORD WAVE_mciGetDevCaps (MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms)
 
static DWORD WAVE_mciInfo (MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_INFO_PARMSW lpParms)
 
LRESULT CALLBACK MCIWAVE_DriverProc (DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, LPARAM dwParam1, LPARAM dwParam2)
 

Macro Definition Documentation

◆ WAVE_ALIGN_ON_BLOCK [1/2]

#define WAVE_ALIGN_ON_BLOCK (   wmw,
  v 
)    ((((v) + (wmw)->lpWaveFormat->nBlockAlign - 1) / (wmw)->lpWaveFormat->nBlockAlign) * (wmw)->lpWaveFormat->nBlockAlign)

◆ WAVE_ALIGN_ON_BLOCK [2/2]

#define WAVE_ALIGN_ON_BLOCK (   wmw,
  v 
)    ((((v) + (wmw)->lpWaveFormat->nBlockAlign - 1) / (wmw)->lpWaveFormat->nBlockAlign) * (wmw)->lpWaveFormat->nBlockAlign)

Typedef Documentation

◆ async_cmd

typedef DWORD(* async_cmd) (MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE evt)

Definition at line 69 of file mciwave.c.

Function Documentation

◆ create_tmp_file()

static DWORD create_tmp_file ( HMMIO *  hFile,
LPWSTR *  pszTmpFileName 
)
static

Definition at line 418 of file mciwave.c.

419{
420 WCHAR szTmpPath[MAX_PATH];
421 WCHAR szPrefix[4];
422 DWORD dwRet = MMSYSERR_NOERROR;
423
424 szPrefix[0] = 'M';
425 szPrefix[1] = 'C';
426 szPrefix[2] = 'I';
427 szPrefix[3] = '\0';
428
429 if (!GetTempPathW(ARRAY_SIZE(szTmpPath), szTmpPath)) {
430 WARN("can't retrieve temp path!\n");
431 *pszTmpFileName = NULL;
433 }
434
435 *pszTmpFileName = calloc(1, MAX_PATH * sizeof(WCHAR));
436 if (!GetTempFileNameW(szTmpPath, szPrefix, 0, *pszTmpFileName)) {
437 WARN("can't retrieve temp file name!\n");
438 free(*pszTmpFileName);
440 }
441
442 TRACE("%s!\n", debugstr_w(*pszTmpFileName));
443
444 if (*pszTmpFileName && (*pszTmpFileName)[0]) {
445
446 *hFile = mmioOpenW(*pszTmpFileName, NULL,
448
449 if (*hFile == 0) {
450 WARN("can't create file=%s!\n", debugstr_w(*pszTmpFileName));
451 /* temporary file could not be created. clean filename. */
452 free(*pszTmpFileName);
453 dwRet = MCIERR_FILE_NOT_FOUND;
454 }
455 }
456 return dwRet;
457}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define WARN(fmt,...)
Definition: precomp.h:61
#define free
Definition: debug_ros.c:5
#define NULL
Definition: types.h:112
#define MAX_PATH
Definition: compat.h:34
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2098
HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO *lpmmioinfo, DWORD dwOpenFlags)
Definition: mmio.c:670
UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName)
Definition: filename.c:84
unsigned long DWORD
Definition: ntddk_ex.h:95
#define debugstr_w
Definition: kernel32.h:32
#define MMIO_ALLOCBUF
Definition: mmsystem.h:532
#define MMIO_READWRITE
Definition: mmsystem.h:537
#define MCIERR_FILE_NOT_FOUND
Definition: mmsystem.h:585
#define MMIO_CREATE
Definition: mmsystem.h:528
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
_In_ HANDLE hFile
Definition: mswsock.h:90
short WCHAR
Definition: pedump.c:58
#define calloc
Definition: rosglue.h:14
#define TRACE(s)
Definition: solgame.cpp:4

Referenced by WAVE_mciRecord().

◆ MCI_SCAStarter()

static DWORD CALLBACK MCI_SCAStarter ( LPVOID  arg)
static

Definition at line 82 of file mciwave.c.

83{
84 struct SCA* sca = (struct SCA*)arg;
85 DWORD ret;
86
87 TRACE("In thread before async command (%08x,%08Ix,%08Ix)\n",
88 sca->wDevID, sca->dwParam1, sca->dwParam2);
89 ret = sca->cmd(sca->wDevID, sca->dwParam1 | MCI_WAIT, sca->dwParam2, sca->evt);
90 TRACE("In thread after async command (%08x,%08Ix,%08Ix)\n",
91 sca->wDevID, sca->dwParam1, sca->dwParam2);
92 free(sca);
93 return ret;
94}
return ret
Definition: mutex.c:147
#define MCI_WAIT
Definition: mmsystem.h:730
Definition: mciwave.c:71
UINT wDevID
Definition: mciwave.c:74
DWORD_PTR dwParam1
Definition: mciwave.c:75
HANDLE evt
Definition: mciwave.c:73
DWORD_PTR dwParam2
Definition: mciwave.c:76
async_cmd cmd
Definition: mciwave.c:72

Referenced by MCI_SendCommandAsync().

◆ MCI_SendCommandAsync()

static DWORD MCI_SendCommandAsync ( UINT  wDevID,
async_cmd  cmd,
DWORD_PTR  dwParam1,
DWORD_PTR  dwParam2,
UINT  size 
)
static

Definition at line 99 of file mciwave.c.

101{
102 HANDLE handles[2];
103 struct SCA* sca = malloc(sizeof(struct SCA) + size);
104
105 if (sca == 0)
107
108 sca->wDevID = wDevID;
109 sca->cmd = cmd;
110 sca->dwParam1 = dwParam1;
111
112 if (size && dwParam2) {
113 sca->dwParam2 = (DWORD_PTR)sca + sizeof(struct SCA);
114 /* copy structure passed by program in dwParam2 to be sure
115 * we can still use it whatever the program does
116 */
118 } else {
119 sca->dwParam2 = dwParam2;
120 }
121
122 if ((sca->evt = handles[1] = CreateEventW(NULL, FALSE, FALSE, NULL)) == NULL ||
123 (handles[0] = CreateThread(NULL, 0, MCI_SCAStarter, sca, 0, NULL)) == 0) {
124 WARN("Couldn't allocate thread for async command handling, sending synchronously\n");
125 if (handles[1]) CloseHandle(handles[1]);
126 sca->evt = NULL;
127 return MCI_SCAStarter(sca);
128 }
129
131 /* wait until either:
132 * - the thread has finished (handles[0], likely an error)
133 * - init phase of async command is done (handles[1])
134 */
138 return 0;
139}
#define malloc
Definition: debug_ros.c:4
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:758
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
#define INFINITE
Definition: serial.h:102
GLsizeiptr size
Definition: glext.h:5919
static DWORD CALLBACK MCI_SCAStarter(LPVOID arg)
Definition: mciwave.c:82
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define MCIERR_OUT_OF_MEMORY
Definition: mmsystem.h:574
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:587
#define DWORD_PTR
Definition: treelist.c:76
static EFI_HANDLE * handles
Definition: uefidisk.c:66
#define THREAD_PRIORITY_TIME_CRITICAL
Definition: winbase.h:306

Referenced by WAVE_mciPlay(), and WAVE_mciRecord().

◆ MCIWAVE_DriverProc()

LRESULT CALLBACK MCIWAVE_DriverProc ( DWORD_PTR  dwDevID,
HDRVR  hDriv,
UINT  wMsg,
LPARAM  dwParam1,
LPARAM  dwParam2 
)

Definition at line 1704 of file mciwave.c.

1706{
1707 TRACE("(%08IX, %p, %08X, %08IX, %08IX)\n",
1708 dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1709
1710 switch (wMsg) {
1711 case DRV_LOAD: return 1;
1712 case DRV_FREE: return 1;
1713 case DRV_OPEN: return WAVE_drvOpen((LPCWSTR)dwParam1, (LPMCI_OPEN_DRIVER_PARMSW)dwParam2);
1714 case DRV_CLOSE: return WAVE_drvClose(dwDevID);
1715 case DRV_ENABLE: return 1;
1716 case DRV_DISABLE: return 1;
1717 case DRV_QUERYCONFIGURE: return 1;
1718 case DRV_CONFIGURE: MessageBoxA(0, "MCI waveaudio Driver !", "Wine Driver", MB_OK); return 1;
1719 case DRV_INSTALL: return DRVCNF_RESTART;
1720 case DRV_REMOVE: return DRVCNF_RESTART;
1721 }
1722
1723 if (dwDevID == 0xFFFFFFFF) return MCIERR_UNSUPPORTED_FUNCTION;
1724
1725 switch (wMsg) {
1726 case MCI_OPEN_DRIVER: return WAVE_mciOpen (dwDevID, dwParam1, (LPMCI_WAVE_OPEN_PARMSW) dwParam2);
1727 case MCI_CLOSE_DRIVER: return WAVE_mciClose (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1728 case MCI_CUE: return WAVE_mciCue (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1729 case MCI_PLAY: return WAVE_mciPlay (dwDevID, dwParam1, dwParam2, NULL);
1730 case MCI_RECORD: return WAVE_mciRecord (dwDevID, dwParam1, dwParam2, NULL);
1731 case MCI_STOP: return WAVE_mciStop (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1732 case MCI_SET: return WAVE_mciSet (dwDevID, dwParam1, (LPMCI_WAVE_SET_PARMS) dwParam2);
1733 case MCI_PAUSE: return WAVE_mciPause (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1734 case MCI_RESUME: return WAVE_mciResume (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1735 case MCI_STATUS: return WAVE_mciStatus (dwDevID, dwParam1, (LPMCI_STATUS_PARMS) dwParam2);
1736 case MCI_GETDEVCAPS: return WAVE_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS) dwParam2);
1737 case MCI_INFO: return WAVE_mciInfo (dwDevID, dwParam1, (LPMCI_INFO_PARMSW) dwParam2);
1738 case MCI_SEEK: return WAVE_mciSeek (dwDevID, dwParam1, (LPMCI_SEEK_PARMS) dwParam2);
1739 case MCI_SAVE: return WAVE_mciSave (dwDevID, dwParam1, (LPMCI_SAVE_PARMSW) dwParam2);
1740 /* commands that should be supported */
1741 case MCI_LOAD:
1742 case MCI_FREEZE:
1743 case MCI_PUT:
1744 case MCI_REALIZE:
1745 case MCI_UNFREEZE:
1746 case MCI_UPDATE:
1747 case MCI_WHERE:
1748 case MCI_STEP:
1749 case MCI_SPIN:
1750 case MCI_ESCAPE:
1751 case MCI_COPY:
1752 case MCI_CUT:
1753 case MCI_DELETE:
1754 case MCI_PASTE:
1755 FIXME("Unsupported command [%u]\n", wMsg);
1756 break;
1757 case MCI_WINDOW:
1758 TRACE("Unsupported command [%u]\n", wMsg);
1759 break;
1760 /* option which can be silenced */
1761 case MCI_CONFIGURE:
1762 return 0;
1763 case MCI_OPEN:
1764 case MCI_CLOSE:
1765 ERR("Shouldn't receive a MCI_OPEN or CLOSE message\n");
1766 break;
1767 default:
1768 FIXME("is probably wrong msg [%u]\n", wMsg);
1769 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1770 }
1772}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
#define MCI_CONFIGURE
Definition: digitalv.h:45
LRESULT WINAPI DefDriverProc(DWORD_PTR dwDriverIdentifier, HDRVR hDrv, UINT Msg, LPARAM lParam1, LPARAM lParam2)
Definition: driver.c:554
#define DRV_LOAD(x)
static LRESULT WAVE_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp)
Definition: mciwave.c:150
static DWORD WAVE_mciStatus(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
Definition: mciwave.c:1464
static DWORD WAVE_mciGetDevCaps(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms)
Definition: mciwave.c:1592
static DWORD WAVE_mciPlay(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE hEvent)
Definition: mciwave.c:732
static DWORD WAVE_mciPause(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:1159
static DWORD WAVE_mciSet(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_WAVE_SET_PARMS lpParms)
Definition: mciwave.c:1286
static DWORD WAVE_mciClose(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:653
static DWORD WAVE_mciCue(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:578
static LRESULT WAVE_drvClose(MCIDEVICEID dwDevID)
Definition: mciwave.c:180
static LRESULT WAVE_mciOpen(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_PARMSW lpOpenParms)
Definition: mciwave.c:511
static DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:1199
static DWORD WAVE_mciSeek(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
Definition: mciwave.c:1242
static DWORD WAVE_mciRecord(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE hEvent)
Definition: mciwave.c:993
static DWORD WAVE_mciSave(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SAVE_PARMSW lpParms)
Definition: mciwave.c:1412
static DWORD WAVE_mciInfo(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_INFO_PARMSW lpParms)
Definition: mciwave.c:1663
static DWORD WAVE_mciStop(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:615
#define MCI_CUT
Definition: mmsystem.h:671
#define MCI_SAVE
Definition: mmsystem.h:661
#define DRV_CLOSE
Definition: mmsystem.h:122
#define DRV_QUERYCONFIGURE
Definition: mmsystem.h:126
#define MCI_GETDEVCAPS
Definition: mmsystem.h:654
#define MCI_RESUME
Definition: mmsystem.h:675
#define MCI_DELETE
Definition: mmsystem.h:676
#define MCI_FREEZE
Definition: mmsystem.h:668
#define DRVCNF_RESTART
Definition: mmsystem.h:135
#define MCI_WINDOW
Definition: mmsystem.h:665
#define MCI_STATUS
Definition: mmsystem.h:662
#define MCI_COPY
Definition: mmsystem.h:672
#define MCI_ESCAPE
Definition: mmsystem.h:648
#define MCIERR_UNRECOGNIZED_COMMAND
Definition: mmsystem.h:571
#define MCI_SET
Definition: mmsystem.h:656
#define MCI_LOAD
Definition: mmsystem.h:670
#define MCI_UPDATE
Definition: mmsystem.h:674
#define DRV_REMOVE
Definition: mmsystem.h:128
#define DRV_ENABLE
Definition: mmsystem.h:120
#define MCI_STOP
Definition: mmsystem.h:651
#define MCI_CLOSE
Definition: mmsystem.h:647
#define MCI_SEEK
Definition: mmsystem.h:650
#define DRV_CONFIGURE
Definition: mmsystem.h:125
#define DRV_OPEN
Definition: mmsystem.h:121
#define MCI_WHERE
Definition: mmsystem.h:667
#define DRV_INSTALL
Definition: mmsystem.h:127
#define MCI_OPEN
Definition: mmsystem.h:646
#define MCI_UNFREEZE
Definition: mmsystem.h:669
#define MCI_PUT
Definition: mmsystem.h:666
#define MCI_SPIN
Definition: mmsystem.h:655
#define MCI_CUE
Definition: mmsystem.h:663
#define MCI_PAUSE
Definition: mmsystem.h:652
#define MCI_INFO
Definition: mmsystem.h:653
#define MCI_PASTE
Definition: mmsystem.h:673
#define DRV_FREE
Definition: mmsystem.h:124
#define MCIERR_UNSUPPORTED_FUNCTION
Definition: mmsystem.h:584
#define MCI_PLAY
Definition: mmsystem.h:649
#define MCI_STEP
Definition: mmsystem.h:657
#define MCI_REALIZE
Definition: mmsystem.h:664
#define MCI_RECORD
Definition: mmsystem.h:658
#define DRV_DISABLE
Definition: mmsystem.h:123
int WINAPI MessageBoxA(_In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType)
#define MB_OK
Definition: winuser.h:801
#define MCI_OPEN_DRIVER
Definition: mmddk.h:338
#define MCI_CLOSE_DRIVER
Definition: mmddk.h:339
const uint16_t * LPCWSTR
Definition: typedefs.h:57

◆ WAVE_ConvertByteToTimeFormat()

static DWORD WAVE_ConvertByteToTimeFormat ( WINE_MCIWAVE *  wmw,
DWORD  val 
)
static

Definition at line 227 of file mciwave.c.

228{
229 DWORD ret = 0;
230
231 switch (wmw->dwMciTimeFormat) {
234 break;
235 case MCI_FORMAT_BYTES:
236 ret = val;
237 break;
240 break;
241 default:
242 WARN("Bad time format %lu!\n", wmw->dwMciTimeFormat);
243 }
244 TRACE("val=%lu=0x%08lx [tf=%lu] => ret=%lu\n", val, val, wmw->dwMciTimeFormat, ret);
245 return ret;
246}
GLuint GLfloat * val
Definition: glext.h:7180
#define MCI_FORMAT_SAMPLES
Definition: mmsystem.h:710
#define MCI_FORMAT_MILLISECONDS
Definition: mmsystem.h:701
#define MCI_FORMAT_BYTES
Definition: mmsystem.h:709
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
DWORD dwMciTimeFormat
Definition: mciwave.c:52
LPWAVEFORMATEX lpWaveFormat
Definition: mciwave.c:47
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
DWORD nSamplesPerSec
Definition: mmreg.h:80

Referenced by WAVE_ConvertTimeFormatToByte(), and WAVE_mciStatus().

◆ WAVE_ConvertTimeFormatToByte()

static DWORD WAVE_ConvertTimeFormatToByte ( WINE_MCIWAVE *  wmw,
DWORD  val 
)
static

Definition at line 251 of file mciwave.c.

252{
253 DWORD ret = 0;
254
255 switch (wmw->dwMciTimeFormat) {
258 if (ret > wmw->ckWaveData.cksize &&
260 ret = wmw->ckWaveData.cksize;
261 break;
262 case MCI_FORMAT_BYTES:
263 ret = val;
264 break;
267 break;
268 default:
269 WARN("Bad time format %lu!\n", wmw->dwMciTimeFormat);
270 }
271 TRACE("val=%lu=0x%08lx [tf=%lu] => ret=%lu\n", val, val, wmw->dwMciTimeFormat, ret);
272 return ret;
273}
static DWORD WAVE_ConvertByteToTimeFormat(WINE_MCIWAVE *wmw, DWORD val)
Definition: mciwave.c:227
MMCKINFO ckWaveData
Definition: mciwave.c:57
DWORD cksize
Definition: mmsystem.h:1510

Referenced by WAVE_mciPlay(), WAVE_mciRecord(), and WAVE_mciSeek().

◆ WAVE_drvClose()

static LRESULT WAVE_drvClose ( MCIDEVICEID  dwDevID)
static

Definition at line 180 of file mciwave.c.

181{
183
184 if (wmw) {
185 free(wmw);
186 mciSetDriverData(dwDevID, 0);
187 return 1;
188 }
189 return (dwDevID == 0xFFFFFFFF) ? 1 : 0;
190}
BOOL WINAPI mciSetDriverData(UINT uDeviceID, DWORD dwData)
DWORD WINAPI mciGetDriverData(UINT uDeviceID)
Definition: mci.c:2233

Referenced by MCIWAVE_DriverProc().

◆ WAVE_drvOpen()

static LRESULT WAVE_drvOpen ( LPCWSTR  str,
LPMCI_OPEN_DRIVER_PARMSW  modp 
)
static

Definition at line 150 of file mciwave.c.

151{
152 WINE_MCIWAVE* wmw;
153
154 if (modp == NULL) return 0xFFFFFFFF;
155
157
158 if (!wmw)
159 return 0;
160
161 wmw->wDevID = modp->wDeviceID;
165
167 wmw->wfxRef.nChannels = 1; /* MONO */
168 wmw->wfxRef.nSamplesPerSec = 11025;
169 wmw->wfxRef.nAvgBytesPerSec = 11025;
170 wmw->wfxRef.nBlockAlign = 1;
171 wmw->wfxRef.wBitsPerSample = 8;
172 wmw->wfxRef.cbSize = 0; /* don't care */
173
174 return modp->wDeviceID;
175}
#define WAVE_FORMAT_PCM
Definition: constants.h:425
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define MCI_NO_COMMAND_TABLE
Definition: mmddk.h:375
#define MCI_DEVTYPE_WAVEFORM_AUDIO
Definition: mmsystem.h:689
UINT wCustomCommandTable
Definition: mmddk.h:438
DWORD nAvgBytesPerSec
Definition: audioclient.idl:43
WORD wBitsPerSample
Definition: audioclient.idl:45
DWORD nSamplesPerSec
Definition: audioclient.idl:42
WAVEFORMATEX wfxRef
Definition: mciwave.c:46
UINT wDevID
Definition: mciwave.c:39
uint32_t DWORD_PTR
Definition: typedefs.h:65

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciClose()

static DWORD WAVE_mciClose ( MCIDEVICEID  wDevID,
DWORD  dwFlags,
LPMCI_GENERIC_PARMS  lpParms 
)
static

Definition at line 653 of file mciwave.c.

654{
655 DWORD dwRet = 0;
656 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
657
658 TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
659
660 if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
661
662 if (wmw->dwStatus != MCI_MODE_STOP) {
663 /* mciStop handles MCI_NOTIFY_ABORTED */
664 dwRet = WAVE_mciStop(wDevID, MCI_WAIT, lpParms);
665 }
666
667 wmw->nUseCount--;
668
669 if (wmw->nUseCount == 0) {
670 if (wmw->hFile != 0) {
671 mmioClose(wmw->hFile, 0);
672 wmw->hFile = 0;
673 }
674 }
675
676 if (wmw->lpWaveFormat != &wmw->wfxRef)
677 free(wmw->lpWaveFormat);
678 wmw->lpWaveFormat = &wmw->wfxRef;
679 free(wmw->lpFileName);
680 wmw->lpFileName = NULL;
681
682 if ((dwFlags & MCI_NOTIFY) && lpParms) {
683 WAVE_mciNotify(lpParms->dwCallback, wmw,
685 }
686
687 return 0;
688}
MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
Definition: mmio.c:702
static WINE_MCIWAVE * WAVE_mciGetOpenDev(MCIDEVICEID wDevID)
Definition: mciwave.c:195
static void WAVE_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIWAVE *wmw, UINT wStatus)
Definition: mciwave.c:213
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_MODE_STOP
Definition: mmsystem.h:695
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
#define MCI_NOTIFY_FAILURE
Definition: mmsystem.h:728
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
HMMIO hFile
Definition: mciwave.c:42
LPWSTR lpFileName
Definition: mciwave.c:45
int nUseCount
Definition: mciwave.c:41
volatile WORD dwStatus
Definition: mciwave.c:51
DWORD_PTR dwCallback
Definition: mmsystem.h:1519

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciCreateRIFFSkeleton()

static DWORD WAVE_mciCreateRIFFSkeleton ( WINE_MCIWAVE *  wmw)
static

Definition at line 346 of file mciwave.c.

347{
348 MMCKINFO ckWaveFormat;
349 LPMMCKINFO lpckRIFF = &(wmw->ckMainRIFF);
350 LPMMCKINFO lpckWaveData = &(wmw->ckWaveData);
351
352 lpckRIFF->ckid = FOURCC_RIFF;
353 lpckRIFF->fccType = mmioFOURCC('W', 'A', 'V', 'E');
354 lpckRIFF->cksize = 0;
355
357 goto err;
358
359 ckWaveFormat.fccType = 0;
360 ckWaveFormat.ckid = mmioFOURCC('f', 'm', 't', ' ');
361 ckWaveFormat.cksize = sizeof(PCMWAVEFORMAT);
362
363 /* Set wave format accepts PCM only, however open an
364 * existing ADPCM file, record into it and the MCI will
365 * happily save back in that format. */
367 if (wmw->lpWaveFormat->nBlockAlign !=
371 WARN("Incorrect nBlockAlign (%d), setting it to %d\n",
374 }
375 if (wmw->lpWaveFormat->nAvgBytesPerSec !=
377 DWORD speed = wmw->lpWaveFormat->nSamplesPerSec *
379 WARN("Incorrect nAvgBytesPerSec (%ld), setting it to %ld\n",
380 wmw->lpWaveFormat->nAvgBytesPerSec, speed);
381 wmw->lpWaveFormat->nAvgBytesPerSec = speed;
382 }
383 }
384 if (wmw->lpWaveFormat == &wmw->wfxRef) {
386 if (!pwfx) return MCIERR_OUT_OF_MEMORY;
387 /* Set wave format accepts PCM only so the size is known. */
389 *pwfx = wmw->wfxRef;
390 wmw->lpWaveFormat = pwfx;
391 }
392
393 if (MMSYSERR_NOERROR != mmioCreateChunk(wmw->hFile, &ckWaveFormat, 0))
394 goto err;
395
396 if (-1 == mmioWrite(wmw->hFile, (HPCSTR)wmw->lpWaveFormat, (WAVE_FORMAT_PCM==wmw->lpWaveFormat->wFormatTag)
397 ? sizeof(PCMWAVEFORMAT) : sizeof(WAVEFORMATEX)+wmw->lpWaveFormat->cbSize))
398 goto err;
399
400 if (MMSYSERR_NOERROR != mmioAscend(wmw->hFile, &ckWaveFormat, 0))
401 goto err;
402
403 lpckWaveData->cksize = 0;
404 lpckWaveData->fccType = 0;
405 lpckWaveData->ckid = mmioFOURCC('d', 'a', 't', 'a');
406
407 /* create data chunk */
408 if (MMSYSERR_NOERROR != mmioCreateChunk(wmw->hFile, lpckWaveData, 0))
409 goto err;
410
411 return 0;
412
413err:
414 /* mciClose takes care of wmw->lpWaveFormat. */
415 return MCIERR_INVALID_FILE;
416}
#define assert(_expr)
Definition: assert.h:32
MMRESULT WINAPI mmioAscend(HMMIO hmmio, LPMMCKINFO lpck, UINT uFlags)
Definition: mmio.c:1205
LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
Definition: mmio.c:782
MMRESULT WINAPI mmioCreateChunk(HMMIO hmmio, MMCKINFO *lpck, UINT uFlags)
Definition: mmio.c:1239
unsigned short WORD
Definition: ntddk_ex.h:93
#define FOURCC_RIFF
Definition: mmsystem.h:564
#define MCIERR_INVALID_FILE
Definition: mmsystem.h:604
struct pcmwaveformat_tag PCMWAVEFORMAT
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
#define MMIO_CREATERIFF
Definition: mmsystem.h:554
#define err(...)
MMCKINFO ckMainRIFF
Definition: mciwave.c:56
FOURCC ckid
Definition: mmsystem.h:1509
FOURCC fccType
Definition: mmsystem.h:1511
WORD nBlockAlign
Definition: mmreg.h:82
WORD cbSize
Definition: mmreg.h:84
WORD nChannels
Definition: mmreg.h:79
WORD wFormatTag
Definition: mmreg.h:78
WORD wBitsPerSample
Definition: mmreg.h:83

Referenced by WAVE_mciRecord().

◆ WAVE_mciCue()

static DWORD WAVE_mciCue ( MCIDEVICEID  wDevID,
DWORD  dwFlags,
LPMCI_GENERIC_PARMS  lpParms 
)
static

Definition at line 578 of file mciwave.c.

579{
580 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
581
582 TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
583
584 /* Tests on systems without sound drivers show that Cue, like
585 * Record and Play, opens winmm, returning MCIERR_WAVE_xyPUTSUNSUITABLE.
586 * The first Cue Notify does not immediately return the
587 * notification, as if a player or recorder thread is started.
588 * PAUSE mode is reported when successful, but this mode is
589 * different from the normal Pause, because a) Pause then returns
590 * NONAPPLICABLE_FUNCTION instead of 0 and b) Set Channels etc. is
591 * still accepted, returning the original notification as ABORTED.
592 * I.e. Cue allows subsequent format changes, unlike Record or
593 * Open file, closes winmm if the format changes and stops this
594 * thread.
595 * Wine creates one player or recorder thread per async. Play or
596 * Record command. Notification behaviour suggests that MS-W*
597 * reuses a single thread to improve response times. Having Cue
598 * start this thread early helps to improve Play/Record's initial
599 * response time. In effect, Cue is a performance hint, which
600 * justifies our almost no-op implementation.
601 */
602
603 if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
605
606 if ((dwFlags & MCI_NOTIFY) && lpParms)
608
609 return MMSYSERR_NOERROR;
610}
#define MCIERR_NONAPPLICABLE_FUNCTION
Definition: mmsystem.h:610

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciDefaultFmt()

static void WAVE_mciDefaultFmt ( WINE_MCIWAVE *  wmw)
static

Definition at line 331 of file mciwave.c.

332{
333 wmw->lpWaveFormat = &wmw->wfxRef;
335 wmw->lpWaveFormat->nChannels = 1;
336 wmw->lpWaveFormat->nSamplesPerSec = 11025;
337 wmw->lpWaveFormat->nAvgBytesPerSec = 11025;
338 wmw->lpWaveFormat->nBlockAlign = 1;
340 wmw->lpWaveFormat->cbSize = 0;
341}

Referenced by WAVE_mciOpen().

◆ WAVE_mciGetDevCaps()

static DWORD WAVE_mciGetDevCaps ( MCIDEVICEID  wDevID,
DWORD  dwFlags,
LPMCI_GETDEVCAPS_PARMS  lpParms 
)
static

Definition at line 1592 of file mciwave.c.

1594{
1595 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
1596 DWORD ret = 0;
1597
1598 TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
1599
1600 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1601 if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
1602
1604 switch(lpParms->dwItem) {
1608 break;
1612 break;
1616 break;
1620 break;
1624 break;
1628 break;
1632 break;
1636 break;
1640 break;
1642 lpParms->dwReturn = waveInGetNumDevs();
1643 break;
1645 lpParms->dwReturn = waveOutGetNumDevs();
1646 break;
1647 default:
1648 FIXME("Unknown capability (%08lx) !\n", lpParms->dwItem);
1650 }
1651 } else {
1652 WARN("No GetDevCaps-Item !\n");
1654 }
1655 if ((dwFlags & MCI_NOTIFY) && HRESULT_CODE(ret)==0)
1657 return ret;
1658}
#define TRUE
Definition: types.h:120
#define MAKEMCIRESOURCE(wRet, wRes)
Definition: mmddk.h:388
#define MCI_FALSE
Definition: mmddk.h:340
#define MCI_TRUE
Definition: mmddk.h:341
#define MCI_RESOURCE_RETURNED
Definition: mmddk.h:369
#define MCI_GETDEVCAPS_CAN_SAVE
Definition: mmsystem.h:767
#define MCI_GETDEVCAPS_HAS_VIDEO
Definition: mmsystem.h:761
#define MCI_GETDEVCAPS_CAN_RECORD
Definition: mmsystem.h:759
#define MCI_GETDEVCAPS_DEVICE_TYPE
Definition: mmsystem.h:762
#define MCI_WAVE_GETDEVCAPS_OUTPUTS
Definition: mmsystem.h:840
#define MCI_GETDEVCAPS_COMPOUND_DEVICE
Definition: mmsystem.h:764
#define MCI_GETDEVCAPS_USES_FILES
Definition: mmsystem.h:763
#define MCI_GETDEVCAPS_CAN_PLAY
Definition: mmsystem.h:766
#define MCI_WAVE_GETDEVCAPS_INPUTS
Definition: mmsystem.h:839
#define MCI_GETDEVCAPS_CAN_EJECT
Definition: mmsystem.h:765
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605
#define MCI_GETDEVCAPS_ITEM
Definition: mmsystem.h:758
#define MCI_GETDEVCAPS_HAS_AUDIO
Definition: mmsystem.h:760
#define HRESULT_CODE(hr)
Definition: winerror.h:188
UINT WINAPI waveOutGetNumDevs(void)
Definition: winmm.c:2137
UINT WINAPI waveInGetNumDevs(void)
Definition: winmm.c:2565

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciGetOpenDev()

static WINE_MCIWAVE * WAVE_mciGetOpenDev ( MCIDEVICEID  wDevID)
static

Definition at line 195 of file mciwave.c.

196{
198
199 if (wmw == NULL || wmw->nUseCount == 0) {
200 WARN("Invalid wDevID=%u\n", wDevID);
201 return 0;
202 }
203 return wmw;
204}

Referenced by WAVE_mciClose(), WAVE_mciCue(), WAVE_mciGetDevCaps(), WAVE_mciInfo(), WAVE_mciPause(), WAVE_mciPlay(), WAVE_mciRecord(), WAVE_mciResume(), WAVE_mciSave(), WAVE_mciSeek(), WAVE_mciSet(), WAVE_mciStatus(), and WAVE_mciStop().

◆ WAVE_mciInfo()

static DWORD WAVE_mciInfo ( MCIDEVICEID  wDevID,
DWORD  dwFlags,
LPMCI_INFO_PARMSW  lpParms 
)
static

Definition at line 1663 of file mciwave.c.

1664{
1665 DWORD ret = 0;
1666 LPCWSTR str = 0;
1667 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
1668
1669 TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
1670
1671 if (!lpParms || !lpParms->lpstrReturn)
1673
1674 TRACE("buf=%p, len=%lu\n", lpParms->lpstrReturn, lpParms->dwRetSize);
1675
1676 if (wmw == NULL) {
1678 } else {
1679 switch (dwFlags & ~(MCI_WAIT|MCI_NOTIFY)) {
1680 case MCI_INFO_PRODUCT: str = L"Wine's audio player"; break;
1681 case MCI_INFO_FILE: str = wmw->lpFileName; break;
1682 case MCI_WAVE_INPUT: str = L"Wine Wave In"; break;
1683 case MCI_WAVE_OUTPUT: str = L"Wine Wave Out"; break;
1684 default:
1685 WARN("Don't know this info command (%lu)\n", dwFlags);
1687 }
1688 }
1689 if (!ret) {
1690 if (lpParms->dwRetSize) {
1691 /* FIXME? Since NT, mciwave, mciseq and mcicda set dwRetSize
1692 * to the number of characters written, excluding \0. */
1693 lstrcpynW(lpParms->lpstrReturn, str ? str : L"", lpParms->dwRetSize);
1694 } else ret = MCIERR_PARAM_OVERFLOW;
1695 }
1698 return ret;
1699}
#define lstrcpynW
Definition: compat.h:738
#define L(x)
Definition: resources.c:13
#define MCI_INFO_PRODUCT
Definition: mmsystem.h:752
#define MCI_WAVE_OUTPUT
Definition: mmsystem.h:829
#define MCI_WAVE_INPUT
Definition: mmsystem.h:828
#define MCIERR_PARAM_OVERFLOW
Definition: mmsystem.h:578
#define MCI_INFO_FILE
Definition: mmsystem.h:753
#define MCIERR_UNRECOGNIZED_KEYWORD
Definition: mmsystem.h:570
const WCHAR * str
DWORD_PTR dwCallback
Definition: mmsystem.h:1581

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciNotify()

static void WAVE_mciNotify ( DWORD_PTR  hWndCallBack,
WINE_MCIWAVE *  wmw,
UINT  wStatus 
)
static

Definition at line 213 of file mciwave.c.

214{
215 /* We simply save one parameter by not passing the wDevID local
216 * to the command. They are the same (via mciGetDriverData).
217 */
218 MCIDEVICEID wDevID = wmw->wNotifyDeviceID;
220 if (old) mciDriverNotify(old, wDevID, MCI_NOTIFY_SUPERSEDED);
221 mciDriverNotify(HWND_32(LOWORD(hWndCallBack)), wDevID, wStatus);
222}
BOOL WINAPI mciDriverNotify(HWND hwndCallback, UINT uDeviceID, UINT uStatus)
Definition: mci.c:2223
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define MCI_NOTIFY_SUPERSEDED
Definition: mmsystem.h:726
UINT MCIDEVICEID
Definition: mmsystem.h:961
#define LOWORD(l)
Definition: pedump.c:82
HANDLE hCallback
Definition: mciwave.c:44
MCIDEVICEID wNotifyDeviceID
Definition: mciwave.c:43
#define HWND_32(h16)
Definition: wownt32.h:29

Referenced by WAVE_mciClose(), WAVE_mciCue(), WAVE_mciGetDevCaps(), WAVE_mciInfo(), WAVE_mciOpen(), WAVE_mciPause(), WAVE_mciResume(), WAVE_mciSave(), WAVE_mciSeek(), WAVE_mciSet(), WAVE_mciStatus(), and WAVE_mciStop().

◆ WAVE_mciOpen()

static LRESULT WAVE_mciOpen ( MCIDEVICEID  wDevID,
DWORD  dwFlags,
LPMCI_WAVE_OPEN_PARMSW  lpOpenParms 
)
static

Definition at line 511 of file mciwave.c.

512{
513 DWORD dwRet = 0;
515
516 TRACE("(%04X, %08lX, %p)\n", wDevID, dwFlags, lpOpenParms);
517 if (lpOpenParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
518 if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
519
522
523 if (wmw->nUseCount > 0) {
524 /* The driver is already opened on this channel
525 * Wave driver cannot be shared
526 */
527 return MCIERR_DEVICE_OPEN;
528 }
529
530 wmw->nUseCount++;
531
532 wmw->wInput = wmw->wOutput = WAVE_MAPPER;
533 wmw->fInput = FALSE;
534 wmw->hWave = 0;
536 wmw->hFile = 0;
537 wmw->lpFileName = NULL; /* will be set by WAVE_mciOpenFile */
538 wmw->hCallback = NULL;
540
541 TRACE("wDevID=%04X (lpParams->wDeviceID=%08X)\n", wDevID, lpOpenParms->wDeviceID);
542 /* Logs show the native winmm calls us with 0 still in lpOpenParms.wDeviceID */
543 wmw->wNotifyDeviceID = wDevID;
544
547 /* could it be that (DWORD)lpOpenParms->lpstrElementName
548 * contains the hFile value ?
549 */
551 } else {
552 dwRet = WAVE_mciOpenFile(wmw, lpOpenParms->lpstrElementName);
553 }
554 }
555 TRACE("hFile=%p\n", wmw->hFile);
556
557 if (dwRet == 0) {
558 wmw->dwPosition = 0;
559
560 wmw->dwStatus = MCI_MODE_STOP;
561
562 if (dwFlags & MCI_NOTIFY)
564 } else {
565 wmw->nUseCount--;
566 if (wmw->hFile != 0)
567 mmioClose(wmw->hFile, 0);
568 wmw->hFile = 0;
569 free(wmw->lpFileName);
570 wmw->lpFileName = NULL;
571 }
572 return dwRet;
573}
static void WAVE_mciDefaultFmt(WINE_MCIWAVE *wmw)
Definition: mciwave.c:331
static LRESULT WAVE_mciOpenFile(WINE_MCIWAVE *wmw, LPCWSTR filename)
Definition: mciwave.c:459
#define MCI_OPEN_SHAREABLE
Definition: mmsystem.h:734
#define MCI_OPEN_ELEMENT_ID
Definition: mmsystem.h:737
#define MCI_OPEN_ELEMENT
Definition: mmsystem.h:735
#define WAVE_MAPPER
Definition: mmsystem.h:187
#define MCIERR_DEVICE_OPEN
Definition: mmsystem.h:575
#define MCI_MODE_NOT_READY
Definition: mmsystem.h:694
BOOL fInput
Definition: mciwave.c:48
WORD wInput
Definition: mciwave.c:49
DWORD dwPosition
Definition: mciwave.c:53
HANDLE hWave
Definition: mciwave.c:40
WORD wOutput
Definition: mciwave.c:50
MCIDEVICEID wDeviceID
Definition: mmsystem.h:1679

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciOpenFile()

static LRESULT WAVE_mciOpenFile ( WINE_MCIWAVE *  wmw,
LPCWSTR  filename 
)
static

Definition at line 459 of file mciwave.c.

460{
462 LPWSTR fn;
463
464 fn = wcsdup(filename);
465 if (!fn) return MCIERR_OUT_OF_MEMORY;
466 free(wmw->lpFileName);
467 wmw->lpFileName = fn;
468
469 if (filename[0]) {
470 /* FIXME : what should be done if wmw->hFile is already != 0, or the driver is playin' */
471 TRACE("MCI_OPEN_ELEMENT %s!\n", debugstr_w(filename));
472
475
476 if (wmw->hFile == 0) {
477 WARN("can't find file=%s!\n", debugstr_w(filename));
478 dwRet = MCIERR_FILE_NOT_FOUND;
479 }
480 else
481 {
482 LPMMCKINFO lpckMainRIFF = &wmw->ckMainRIFF;
483
484 /* make sure we're at the beginning of the file */
485 mmioSeek(wmw->hFile, 0, SEEK_SET);
486
487 /* first reading of this file. read the waveformat chunk */
488 if (mmioDescend(wmw->hFile, lpckMainRIFF, NULL, 0) != 0) {
489 dwRet = MCIERR_INVALID_FILE;
490 } else {
491 TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX\n",
492 (LPSTR)&(lpckMainRIFF->ckid),
493 (LPSTR) &(lpckMainRIFF->fccType),
494 (lpckMainRIFF->cksize));
495
496 if ((lpckMainRIFF->ckid != FOURCC_RIFF) ||
497 lpckMainRIFF->fccType != mmioFOURCC('W', 'A', 'V', 'E')) {
498 dwRet = MCIERR_INVALID_FILE;
499 } else {
500 dwRet = WAVE_mciReadFmt(wmw, lpckMainRIFF);
501 }
502 }
503 }
504 }
505 return dwRet;
506}
static wchar_t * wcsdup(const wchar_t *str)
Definition: string.h:94
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
Definition: mmio.c:836
MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck, const MMCKINFO *lpckParent, UINT uFlags)
Definition: mmio.c:1107
const char * filename
Definition: ioapi.h:137
#define SEEK_SET
Definition: jmemansi.c:26
static DWORD WAVE_mciReadFmt(WINE_MCIWAVE *wmw, const MMCKINFO *pckMainRIFF)
Definition: mciwave.c:278
LONG_PTR LRESULT
Definition: minwindef.h:176
#define MMIO_DENYWRITE
Definition: mmsystem.h:540
#define MMIO_READ
Definition: mmsystem.h:535
uint16_t * LPWSTR
Definition: typedefs.h:56
char * LPSTR
Definition: typedefs.h:51
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159

Referenced by WAVE_mciOpen(), and WAVE_mciSave().

◆ WAVE_mciPause()

static DWORD WAVE_mciPause ( MCIDEVICEID  wDevID,
DWORD  dwFlags,
LPMCI_GENERIC_PARMS  lpParms 
)
static

Definition at line 1159 of file mciwave.c.

1160{
1161 DWORD dwRet;
1162 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
1163
1164 TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
1165
1166 if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
1167
1168 switch (wmw->dwStatus) {
1169 case MCI_MODE_PLAY:
1170 dwRet = waveOutPause(wmw->hWave);
1171 if (dwRet==MMSYSERR_NOERROR) wmw->dwStatus = MCI_MODE_PAUSE;
1172 else { /* When playthread was not started yet, winmm not opened, error 5 MMSYSERR_INVALHANDLE */
1173 ERR("waveOutPause error %ld\n",dwRet);
1174 dwRet = MCIERR_INTERNAL;
1175 }
1176 break;
1177 case MCI_MODE_RECORD:
1178 dwRet = waveInStop(wmw->hWave);
1179 if (dwRet==MMSYSERR_NOERROR) wmw->dwStatus = MCI_MODE_PAUSE;
1180 else {
1181 ERR("waveInStop error %ld\n",dwRet);
1182 dwRet = MCIERR_INTERNAL;
1183 }
1184 break;
1185 case MCI_MODE_PAUSE:
1186 dwRet = MMSYSERR_NOERROR;
1187 break;
1188 default:
1190 }
1191 if (MMSYSERR_NOERROR==dwRet && (dwFlags & MCI_NOTIFY) && lpParms)
1193 return dwRet;
1194}
#define MCI_MODE_PLAY
Definition: mmsystem.h:696
#define MCIERR_INTERNAL
Definition: mmsystem.h:587
#define MCI_MODE_RECORD
Definition: mmsystem.h:697
#define MCI_MODE_PAUSE
Definition: mmsystem.h:699
UINT WINAPI waveInStop(HWAVEIN hWaveIn)
Definition: winmm.c:2764
UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
Definition: winmm.c:2371

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciPlay()

static DWORD WAVE_mciPlay ( MCIDEVICEID  wDevID,
DWORD_PTR  dwFlags,
DWORD_PTR  pmt,
HANDLE  hEvent 
)
static

This function will be called again by a thread when async is used. We have to set MCI_MODE_PLAY before we do this so that the app can spin on MCI_STATUS, so we have to allow it here if we're not going to start this thread.

Definition at line 732 of file mciwave.c.

733{
734 LPMCI_PLAY_PARMS lpParms = (void*)pmt;
735 DWORD end;
737 DWORD dwRet;
738 LPWAVEHDR waveHdr = NULL;
739 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
740 HANDLE oldcb;
741 int whidx;
742
743 TRACE("(%u, %08IX, %p);\n", wDevID, dwFlags, lpParms);
744
745 if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
746 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
747
748 if (wmw->hFile == 0) {
749 WARN("Can't play: no file=%s!\n", debugstr_w(wmw->lpFileName));
751 }
752
753 if (wmw->dwStatus == MCI_MODE_PAUSE && !wmw->fInput && !(dwFlags & (MCI_FROM | MCI_TO))) {
754 /* FIXME: notification is different with Resume than Play */
755 return WAVE_mciResume(wDevID, dwFlags, (LPMCI_GENERIC_PARMS)lpParms);
756 }
757
762 if ( !(wmw->dwStatus == MCI_MODE_STOP) &&
763 !((wmw->dwStatus == MCI_MODE_PLAY) && (dwFlags & MCI_WAIT) && !wmw->hWave)) {
764 /* FIXME: Check FROM/TO parameters first. */
765 /* FIXME: Play; Play [notify|wait] must hook into the running player. */
766 dwRet = WAVE_mciStop(wDevID, MCI_WAIT, NULL);
767 if (dwRet) return dwRet;
768 }
769
771 if (wmw->lpWaveFormat->nBlockAlign !=
773 WARN("Incorrect nBlockAlign (%d), setting it to %d\n",
775 wmw->lpWaveFormat->nChannels *
778 wmw->lpWaveFormat->nChannels *
780 }
781 if (wmw->lpWaveFormat->nAvgBytesPerSec !=
783 WARN("Incorrect nAvgBytesPerSec (%ld), setting it to %ld\n",
790 }
791 }
792
793 end = wmw->ckWaveData.cksize;
794 if (dwFlags & MCI_TO) {
795 DWORD position = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwTo);
796 if (position > end) return MCIERR_OUTOFRANGE;
797 end = position;
798 }
799 if (dwFlags & MCI_FROM) {
800 DWORD position = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwFrom);
801 if (position > end) return MCIERR_OUTOFRANGE;
802 /* Seek rounds down, so do we. */
803 position /= wmw->lpWaveFormat->nBlockAlign;
804 position *= wmw->lpWaveFormat->nBlockAlign;
805 wmw->dwPosition = position;
806 }
807 if (end < wmw->dwPosition) return MCIERR_OUTOFRANGE;
808 left = end - wmw->dwPosition;
809 if (0==left) return MMSYSERR_NOERROR; /* FIXME: NOTIFY */
810
811 wmw->fInput = FALSE; /* FIXME: waveInOpen may have been called. */
812 wmw->dwStatus = MCI_MODE_PLAY;
813
814 if (!(dwFlags & MCI_WAIT)) {
816 (DWORD_PTR)lpParms, sizeof(MCI_PLAY_PARMS));
817 }
818
819 TRACE("Playing from byte=%lu to byte=%lu\n", wmw->dwPosition, end);
820
822 (dwFlags & MCI_NOTIFY) ? HWND_32(LOWORD(lpParms->dwCallback)) : NULL);
823 if (oldcb) mciDriverNotify(oldcb, wDevID, MCI_NOTIFY_ABORTED);
824 oldcb = NULL;
825
826#define WAVE_ALIGN_ON_BLOCK(wmw,v) \
827((((v) + (wmw)->lpWaveFormat->nBlockAlign - 1) / (wmw)->lpWaveFormat->nBlockAlign) * (wmw)->lpWaveFormat->nBlockAlign)
828
829 /* go back to beginning of chunk plus the requested position */
830 /* FIXME: I'm not sure this is correct, notably because some data linked to
831 * the decompression state machine will not be correctly initialized.
832 * try it this way (other way would be to decompress from 0 up to dwPosition
833 * and to start sending to hWave when dwPosition is reached)
834 */
835 mmioSeek(wmw->hFile, wmw->ckWaveData.dwDataOffset + wmw->dwPosition, SEEK_SET); /* >= 0 */
836
837 dwRet = waveOutOpen((HWAVEOUT *)&wmw->hWave, wmw->wOutput, wmw->lpWaveFormat,
839
840 if (dwRet != 0) {
841 TRACE("Can't open low level audio device %ld\n", dwRet);
842 dwRet = MCIERR_DEVICE_OPEN;
843 wmw->hWave = 0;
844 goto cleanUp;
845 }
846
847 /* make it so that 3 buffers per second are needed */
849
850 waveHdr = malloc(2 * sizeof(WAVEHDR) + 2 * bufsize);
851 waveHdr[0].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR);
852 waveHdr[1].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR) + bufsize;
853 waveHdr[0].dwUser = waveHdr[1].dwUser = 0L;
854 waveHdr[0].dwLoops = waveHdr[1].dwLoops = 0L;
855 waveHdr[0].dwFlags = waveHdr[1].dwFlags = 0L;
856 waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize;
857 if (waveOutPrepareHeader(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
858 waveOutPrepareHeader(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR))) {
859 dwRet = MCIERR_INTERNAL;
860 goto cleanUp;
861 }
862
863 whidx = 0;
865 if (!wmw->hEvent) {
866 dwRet = MCIERR_OUT_OF_MEMORY;
867 goto cleanUp;
868 }
869 wmw->dwEventCount = 1L; /* for first buffer */
870
871 TRACE("Playing (normalized) from byte=%lu for %lu bytes\n", wmw->dwPosition, left);
872 if (hEvent) SetEvent(hEvent);
873
874 /* FIXME: this doesn't work if wmw->dwPosition != 0 */
875 while (left > 0 && wmw->dwStatus != MCI_MODE_STOP && wmw->dwStatus != MCI_MODE_NOT_READY) {
876 count = mmioRead(wmw->hFile, waveHdr[whidx].lpData, min(bufsize, left));
877 TRACE("mmioRead bufsize=%ld count=%ld\n", bufsize, count);
878 if (count < 1)
879 break;
880 /* count is always <= bufsize, so this is correct regarding the
881 * waveOutPrepareHeader function
882 */
883 waveHdr[whidx].dwBufferLength = count;
884 waveHdr[whidx].dwFlags &= ~WHDR_DONE;
885 TRACE("before WODM_WRITE lpWaveHdr=%p dwBufferLength=%lu\n",
886 &waveHdr[whidx], waveHdr[whidx].dwBufferLength);
887 dwRet = waveOutWrite(wmw->hWave, &waveHdr[whidx], sizeof(WAVEHDR));
888 if (dwRet) {
889 ERR("Aborting play loop, WODM_WRITE error %ld\n", dwRet);
890 dwRet = MCIERR_HARDWARE;
891 break;
892 }
893 left -= count;
894 wmw->dwPosition += count;
895 TRACE("after WODM_WRITE dwPosition=%lu\n", wmw->dwPosition);
896 /* InterlockedDecrement if and only if waveOutWrite is successful */
898 whidx ^= 1;
899 }
900
901 WAVE_mciPlayWaitDone(wmw); /* to balance first buffer */
902
903 /* just to get rid of some race conditions between play, stop and pause */
904 waveOutReset(wmw->hWave);
905
906 waveOutUnprepareHeader(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR));
907 waveOutUnprepareHeader(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR));
908
909cleanUp:
910 if (dwFlags & MCI_NOTIFY)
912
913 free(waveHdr);
914
915 if (wmw->hWave) {
916 waveOutClose(wmw->hWave);
917 wmw->hWave = 0;
918 }
919 CloseHandle(wmw->hEvent);
920 wmw->hEvent = NULL;
921
922 wmw->dwStatus = MCI_MODE_STOP;
923
924 /* Let the potentially asynchronous commands support FAILURE notification. */
925 if (oldcb) mciDriverNotify(oldcb, wDevID,
927
928 return dwRet;
929}
LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
Definition: mmio.c:733
void cleanUp()
Definition: main.cpp:469
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLint left
Definition: glext.h:7726
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
#define WAVE_ALIGN_ON_BLOCK(wmw, v)
static void WAVE_mciPlayWaitDone(WINE_MCIWAVE *wmw)
Definition: mciwave.c:716
static void CALLBACK WAVE_mciPlayCallback(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, LPARAM dwParam1, LPARAM dwParam2)
Definition: mciwave.c:693
static DWORD MCI_SendCommandAsync(UINT wDevID, async_cmd cmd, DWORD_PTR dwParam1, DWORD_PTR dwParam2, UINT size)
Definition: mciwave.c:99
static DWORD WAVE_ConvertTimeFormatToByte(WINE_MCIWAVE *wmw, DWORD val)
Definition: mciwave.c:251
#define MCI_TO
Definition: mmsystem.h:732
#define MCIERR_HARDWARE
Definition: mmsystem.h:572
#define MCI_NOTIFY_ABORTED
Definition: mmsystem.h:727
#define MCIERR_OUTOFRANGE
Definition: mmsystem.h:592
#define CALLBACK_FUNCTION
Definition: mmsystem.h:150
#define MCI_FROM
Definition: mmsystem.h:731
static HANDLE hEvent
Definition: comm.c:54
#define min(a, b)
Definition: monoChain.cc:55
long LONG
Definition: pedump.c:60
HANDLE hEvent
Definition: mciwave.c:54
LONG dwEventCount
Definition: mciwave.c:55
DWORD dwDataOffset
Definition: mmsystem.h:1512
DWORD_PTR dwCallback
Definition: mmsystem.h:1539
DWORD dwBufferLength
Definition: mmsystem.h:1017
DWORD dwLoops
Definition: mmsystem.h:1021
DWORD dwFlags
Definition: mmsystem.h:1020
DWORD_PTR dwUser
Definition: mmsystem.h:1019
LPSTR lpData
Definition: mmsystem.h:1016
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
Definition: winmm.c:2385
UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2341
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2307
MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2246
UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut, WAVEHDR *lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2277
UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
Definition: winmm.c:2257

Referenced by MCIWAVE_DriverProc(), and WAVE_mciPlay().

◆ WAVE_mciPlayCallback()

static void CALLBACK WAVE_mciPlayCallback ( HWAVEOUT  hwo,
UINT  uMsg,
DWORD_PTR  dwInstance,
LPARAM  dwParam1,
LPARAM  dwParam2 
)
static

Definition at line 693 of file mciwave.c.

696{
697 WINE_MCIWAVE* wmw = (WINE_MCIWAVE*)dwInstance;
698
699 switch (uMsg) {
700 case WOM_OPEN:
701 case WOM_CLOSE:
702 break;
703 case WOM_DONE:
705 TRACE("Returning waveHdr=%Ix\n", dwParam1);
706 SetEvent(wmw->hEvent);
707 break;
708 default:
709 ERR("Unknown uMsg=%d\n", uMsg);
710 }
711}
#define InterlockedIncrement
Definition: armddk.h:53
#define WOM_DONE
Definition: mmsystem.h:183
#define WOM_OPEN
Definition: mmsystem.h:181
#define WOM_CLOSE
Definition: mmsystem.h:182

Referenced by WAVE_mciPlay().

◆ WAVE_mciPlayWaitDone()

static void WAVE_mciPlayWaitDone ( WINE_MCIWAVE *  wmw)
static

Definition at line 716 of file mciwave.c.

717{
718 for (;;) {
719 ResetEvent(wmw->hEvent);
720 if (InterlockedDecrement(&wmw->dwEventCount) >= 0) {
721 break;
722 }
724
726 }
727}
#define InterlockedDecrement
Definition: armddk.h:52
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:650

Referenced by WAVE_mciPlay().

◆ WAVE_mciReadFmt()

static DWORD WAVE_mciReadFmt ( WINE_MCIWAVE *  wmw,
const MMCKINFO *  pckMainRIFF 
)
static

Definition at line 278 of file mciwave.c.

279{
280 MMCKINFO mmckInfo;
281 LONG r;
282 LPWAVEFORMATEX pwfx;
283
284 mmckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');
285 if (mmioDescend(wmw->hFile, &mmckInfo, pckMainRIFF, MMIO_FINDCHUNK) != 0)
286 return MCIERR_INVALID_FILE;
287 TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX\n",
288 (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
289
290 pwfx = malloc(mmckInfo.cksize);
291 if (!pwfx) return MCIERR_OUT_OF_MEMORY;
292
293 r = mmioRead(wmw->hFile, (HPSTR)pwfx, mmckInfo.cksize);
294 if (r < 0 || r < sizeof(PCMWAVEFORMAT)) {
295 free(pwfx);
296 return MCIERR_INVALID_FILE;
297 }
298 TRACE("wFormatTag=%04X !\n", pwfx->wFormatTag);
299 TRACE("nChannels=%d\n", pwfx->nChannels);
300 TRACE("nSamplesPerSec=%ld\n", pwfx->nSamplesPerSec);
301 TRACE("nAvgBytesPerSec=%ld\n", pwfx->nAvgBytesPerSec);
302 TRACE("nBlockAlign=%d\n", pwfx->nBlockAlign);
303 TRACE("wBitsPerSample=%u !\n", pwfx->wBitsPerSample);
304 if (r >= sizeof(WAVEFORMATEX))
305 TRACE("cbSize=%u !\n", pwfx->cbSize);
306 if ((pwfx->wFormatTag != WAVE_FORMAT_PCM)
307 && (r < sizeof(WAVEFORMATEX) || (r < sizeof(WAVEFORMATEX) + pwfx->cbSize))) {
308 free(pwfx);
309 return MCIERR_INVALID_FILE;
310 }
311 wmw->lpWaveFormat = pwfx;
312
313 mmioAscend(wmw->hFile, &mmckInfo, 0);
314 wmw->ckWaveData.ckid = mmioFOURCC('d', 'a', 't', 'a');
315 if (mmioDescend(wmw->hFile, &wmw->ckWaveData, pckMainRIFF, MMIO_FINDCHUNK) != 0) {
316 TRACE("can't find data chunk\n");
317 return MCIERR_INVALID_FILE;
318 }
319 TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX\n",
321 return 0;
322}
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define MMIO_FINDCHUNK
Definition: mmsystem.h:551
char * HPSTR
Definition: mmsystem.h:1479

Referenced by WAVE_mciOpenFile().

◆ WAVE_mciRecord()

static DWORD WAVE_mciRecord ( MCIDEVICEID  wDevID,
DWORD_PTR  dwFlags,
DWORD_PTR  pmt,
HANDLE  hEvent 
)
static

This function will be called again by a thread when async is used. We have to set MCI_MODE_RECORD before we do this so that the app can spin on MCI_STATUS, so we have to allow it here if we're not going to start this thread.

Definition at line 993 of file mciwave.c.

994{
995 LPMCI_RECORD_PARMS lpParms = (void*)pmt;
996 DWORD end;
997 DWORD dwRet = MMSYSERR_NOERROR;
999 LPWAVEHDR waveHdr = NULL;
1000 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
1001 HANDLE oldcb;
1002
1003 TRACE("(%u, %08IX, %p);\n", wDevID, dwFlags, lpParms);
1004
1005 if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
1006 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1007
1008 if (wmw->dwStatus == MCI_MODE_PAUSE && wmw->fInput) {
1009 /* FIXME: parameters (start/end) in lpParams may not be used */
1010 return WAVE_mciResume(wDevID, dwFlags, (LPMCI_GENERIC_PARMS)lpParms);
1011 }
1012
1017 if ( !(wmw->dwStatus == MCI_MODE_STOP) &&
1018 !((wmw->dwStatus == MCI_MODE_RECORD) && (dwFlags & MCI_WAIT) && !wmw->hWave)) {
1019 return MCIERR_INTERNAL;
1020 }
1021
1022 wmw->fInput = TRUE; /* FIXME: waveOutOpen may have been called. */
1024
1025 if (!(dwFlags & MCI_WAIT)) {
1027 (DWORD_PTR)lpParms, sizeof(MCI_RECORD_PARMS));
1028 }
1029
1030 /* FIXME: we only re-create the RIFF structure from an existing file (if any)
1031 * we don't modify the wave part of an existing file (ie. we always erase an
1032 * existing content, we don't overwrite)
1033 */
1034 free(wmw->lpFileName);
1035 dwRet = create_tmp_file(&wmw->hFile, (WCHAR**)&wmw->lpFileName);
1036 if (dwRet != 0) return dwRet;
1037
1038 /* new RIFF file, lpWaveFormat now valid */
1039 dwRet = WAVE_mciCreateRIFFSkeleton(wmw);
1040 if (dwRet != 0) return dwRet;
1041
1042 if (dwFlags & MCI_TO) {
1043 end = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwTo);
1044 } else end = 0xFFFFFFFF;
1045 if (dwFlags & MCI_FROM) {
1046 DWORD position = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwFrom);
1047 if (wmw->ckWaveData.cksize < position) return MCIERR_OUTOFRANGE;
1048 /* Seek rounds down, so do we. */
1049 position /= wmw->lpWaveFormat->nBlockAlign;
1050 position *= wmw->lpWaveFormat->nBlockAlign;
1051 wmw->dwPosition = position;
1052 }
1053 if (end==wmw->dwPosition) return MMSYSERR_NOERROR; /* FIXME: NOTIFY */
1054
1055 TRACE("Recording from byte=%lu to byte=%lu\n", wmw->dwPosition, end);
1056
1058 (dwFlags & MCI_NOTIFY) ? HWND_32(LOWORD(lpParms->dwCallback)) : NULL);
1059 if (oldcb) mciDriverNotify(oldcb, wDevID, MCI_NOTIFY_ABORTED);
1060 oldcb = NULL;
1061
1062#define WAVE_ALIGN_ON_BLOCK(wmw,v) \
1063((((v) + (wmw)->lpWaveFormat->nBlockAlign - 1) / (wmw)->lpWaveFormat->nBlockAlign) * (wmw)->lpWaveFormat->nBlockAlign)
1064
1066
1067 /* Go back to the beginning of the chunk plus the requested position */
1068 /* FIXME: I'm not sure this is correct, notably because some data linked to
1069 * the decompression state machine will not be correctly initialized.
1070 * Try it this way (other way would be to decompress from 0 up to dwPosition
1071 * and to start sending to hWave when dwPosition is reached).
1072 */
1073 mmioSeek(wmw->hFile, wmw->ckWaveData.dwDataOffset + wmw->dwPosition, SEEK_SET); /* >= 0 */
1074
1075 dwRet = waveInOpen((HWAVEIN*)&wmw->hWave, wmw->wInput, wmw->lpWaveFormat,
1077
1078 if (dwRet != MMSYSERR_NOERROR) {
1079 TRACE("Can't open low level audio device %ld\n", dwRet);
1080 dwRet = MCIERR_DEVICE_OPEN;
1081 wmw->hWave = 0;
1082 goto cleanUp;
1083 }
1084
1085 /* make it so that 3 buffers per second are needed */
1087
1088 waveHdr = malloc(2 * sizeof(WAVEHDR) + 2 * bufsize);
1089 waveHdr[0].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR);
1090 waveHdr[1].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR) + bufsize;
1091 waveHdr[0].dwUser = waveHdr[1].dwUser = 0L;
1092 waveHdr[0].dwLoops = waveHdr[1].dwLoops = 0L;
1093 waveHdr[0].dwFlags = waveHdr[1].dwFlags = 0L;
1094 waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize;
1095
1096 if (waveInPrepareHeader(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
1097 waveInPrepareHeader(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR))) {
1098 dwRet = MCIERR_INTERNAL;
1099 goto cleanUp;
1100 }
1101
1102 if (waveInAddBuffer(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
1103 waveInAddBuffer(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR))) {
1104 dwRet = MCIERR_INTERNAL;
1105 goto cleanUp;
1106 }
1107
1109 wmw->dwEventCount = 1L; /* for first buffer */
1110
1111 TRACE("Recording (normalized) from byte=%lu for %lu bytes\n", wmw->dwPosition, end - wmw->dwPosition);
1112
1113 waveInStart(wmw->hWave);
1114
1115 if (hEvent) SetEvent(hEvent);
1116
1117 while (wmw->dwPosition < end && wmw->dwStatus != MCI_MODE_STOP && wmw->dwStatus != MCI_MODE_NOT_READY) {
1119 }
1120 /* Grab callback before another thread kicks in after we change dwStatus. */
1121 if (dwFlags & MCI_NOTIFY) {
1123 dwFlags &= ~MCI_NOTIFY;
1124 }
1125 /* needed so that the callback above won't add again the buffers returned by the reset */
1126 wmw->dwStatus = MCI_MODE_STOP;
1127
1128 waveInReset(wmw->hWave);
1129
1130 waveInUnprepareHeader(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR));
1131 waveInUnprepareHeader(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR));
1132
1133 dwRet = 0;
1134
1135cleanUp:
1136 if (dwFlags & MCI_NOTIFY)
1138
1139 free(waveHdr);
1140
1141 if (wmw->hWave) {
1142 waveInClose(wmw->hWave);
1143 wmw->hWave = 0;
1144 }
1145 CloseHandle(wmw->hEvent);
1146
1147 wmw->dwStatus = MCI_MODE_STOP;
1148
1149 if (oldcb) mciDriverNotify(oldcb, wDevID,
1151
1152 return dwRet;
1153
1154}
static DWORD create_tmp_file(HMMIO *hFile, LPWSTR *pszTmpFileName)
Definition: mciwave.c:418
static DWORD WAVE_mciCreateRIFFSkeleton(WINE_MCIWAVE *wmw)
Definition: mciwave.c:346
static void WAVE_mciRecordWaitDone(WINE_MCIWAVE *wmw)
Definition: mciwave.c:977
static void CALLBACK WAVE_mciRecordCallback(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, LPARAM dwParam1, LPARAM dwParam2)
Definition: mciwave.c:934
DWORD_PTR dwCallback
Definition: mmsystem.h:1641
UINT WINAPI waveInAddBuffer(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2717
UINT WINAPI waveInPrepareHeader(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2653
UINT WINAPI waveInUnprepareHeader(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2684
UINT WINAPI waveInReset(HWAVEIN hWaveIn)
Definition: winmm.c:2734
MMRESULT WINAPI waveInOpen(HWAVEIN *lphWaveIn, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2623
UINT WINAPI waveInClose(HWAVEIN hWaveIn)
Definition: winmm.c:2634
UINT WINAPI waveInStart(HWAVEIN hWaveIn)
Definition: winmm.c:2749

Referenced by MCIWAVE_DriverProc(), and WAVE_mciRecord().

◆ WAVE_mciRecordCallback()

static void CALLBACK WAVE_mciRecordCallback ( HWAVEOUT  hwo,
UINT  uMsg,
DWORD_PTR  dwInstance,
LPARAM  dwParam1,
LPARAM  dwParam2 
)
static

Definition at line 934 of file mciwave.c.

937{
938 WINE_MCIWAVE* wmw = (WINE_MCIWAVE*)dwInstance;
939 LPWAVEHDR lpWaveHdr;
940 LONG count = 0;
941
942 switch (uMsg) {
943 case WIM_OPEN:
944 case WIM_CLOSE:
945 break;
946 case WIM_DATA:
947 lpWaveHdr = (LPWAVEHDR) dwParam1;
948
950
951 count = mmioWrite(wmw->hFile, lpWaveHdr->lpData, lpWaveHdr->dwBytesRecorded);
952
953 lpWaveHdr->dwFlags &= ~WHDR_DONE;
954 if (count > 0)
955 wmw->dwPosition += count;
956 /* else error reporting ?? */
957 if (wmw->dwStatus == MCI_MODE_RECORD)
958 {
959 /* Only queue up another buffer if we are recording. We could receive this
960 message also when waveInReset() is called, since it notifies on all wave
961 buffers that are outstanding. Queueing up more sometimes causes waveInClose
962 to fail. */
963 waveInAddBuffer(wmw->hWave, lpWaveHdr, sizeof(*lpWaveHdr));
964 TRACE("after mmioWrite dwPosition=%lu\n", wmw->dwPosition);
965 }
966
967 SetEvent(wmw->hEvent);
968 break;
969 default:
970 ERR("Unknown uMsg=%d\n", uMsg);
971 }
972}
struct wavehdr_tag * LPWAVEHDR
#define WIM_DATA
Definition: mmsystem.h:186
#define WIM_CLOSE
Definition: mmsystem.h:185
#define WIM_OPEN
Definition: mmsystem.h:184
DWORD dwBytesRecorded
Definition: mmsystem.h:1018

Referenced by WAVE_mciRecord().

◆ WAVE_mciRecordWaitDone()

static void WAVE_mciRecordWaitDone ( WINE_MCIWAVE *  wmw)
static

Definition at line 977 of file mciwave.c.

978{
979 for (;;) {
980 ResetEvent(wmw->hEvent);
981 if (InterlockedDecrement(&wmw->dwEventCount) >= 0) {
982 break;
983 }
985
987 }
988}

Referenced by WAVE_mciRecord().

◆ WAVE_mciResume()

static DWORD WAVE_mciResume ( UINT  wDevID,
DWORD  dwFlags,
LPMCI_GENERIC_PARMS  lpParms 
)
static

Definition at line 1199 of file mciwave.c.

1200{
1201 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
1202 DWORD dwRet;
1203
1204 TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
1205
1206 if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
1207
1208 switch (wmw->dwStatus) {
1209 case MCI_MODE_PAUSE:
1210 /* Only update dwStatus if wave* succeeds and will exchange buffers buffers. */
1211 if (wmw->fInput) {
1212 dwRet = waveInStart(wmw->hWave);
1213 if (dwRet==MMSYSERR_NOERROR) wmw->dwStatus = MCI_MODE_RECORD;
1214 else {
1215 ERR("waveInStart error %ld\n",dwRet);
1216 dwRet = MCIERR_INTERNAL;
1217 }
1218 } else {
1219 dwRet = waveOutRestart(wmw->hWave);
1220 if (dwRet==MMSYSERR_NOERROR) wmw->dwStatus = MCI_MODE_PLAY;
1221 else {
1222 ERR("waveOutRestart error %ld\n",dwRet);
1223 dwRet = MCIERR_INTERNAL;
1224 }
1225 }
1226 break;
1227 case MCI_MODE_PLAY:
1228 case MCI_MODE_RECORD:
1229 dwRet = MMSYSERR_NOERROR;
1230 break;
1231 default:
1233 }
1234 if (MMSYSERR_NOERROR==dwRet && (dwFlags & MCI_NOTIFY) && lpParms)
1236 return dwRet;
1237}
UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
Definition: winmm.c:2399

Referenced by MCIWAVE_DriverProc(), WAVE_mciPlay(), and WAVE_mciRecord().

◆ WAVE_mciSave()

static DWORD WAVE_mciSave ( MCIDEVICEID  wDevID,
DWORD  dwFlags,
LPMCI_SAVE_PARMSW  lpParms 
)
static

Definition at line 1412 of file mciwave.c.

1413{
1414 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
1416
1417 TRACE("%d, %08lX, %p);\n", wDevID, dwFlags, lpParms);
1418 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1419 if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
1420
1421 if (dwFlags & MCI_WAIT)
1422 {
1423 FIXME("MCI_WAIT not implemented\n");
1424 }
1425 WAVE_mciStop(wDevID, 0, NULL);
1426
1427 ret = mmioAscend(wmw->hFile, &wmw->ckWaveData, 0);
1428 ret = mmioAscend(wmw->hFile, &wmw->ckMainRIFF, 0);
1429
1430 ret = mmioClose(wmw->hFile, 0);
1431 wmw->hFile = 0;
1432
1433 /*
1434 If the destination file already exists, it has to be overwritten. (Behaviour
1435 verified in Windows (2000)). If it doesn't overwrite, it is breaking one of
1436 my applications. We are making use of mmioRename, which WILL NOT overwrite
1437 the destination file (which is what Windows does, also verified in Win2K)
1438 So, lets delete the destination file before calling mmioRename. If the
1439 destination file DOESN'T exist, the delete will fail silently. Let's also be
1440 careful not to lose our previous error code.
1441 */
1442 tmpRet = GetLastError();
1443 DeleteFileW (lpParms->lpfilename);
1444 SetLastError(tmpRet);
1445
1446 /* FIXME: Open file.wav; Save; must not rename the original file.
1447 * Nor must Save a.wav; Save b.wav rename a. */
1448 if (0 == mmioRenameW(wmw->lpFileName, lpParms->lpfilename, 0, 0 )) {
1450 }
1451
1454
1455 if (ret == MMSYSERR_NOERROR)
1456 ret = WAVE_mciOpenFile(wmw, lpParms->lpfilename);
1457
1458 return ret;
1459}
#define SetLastError(x)
Definition: compat.h:752
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
MMRESULT WINAPI mmioRenameW(LPCWSTR szFileName, LPCWSTR szNewFileName, const MMIOINFO *lpmmioinfo, DWORD dwFlags)
Definition: mmio.c:1320
#define MCIERR_FILE_NOT_SAVED
Definition: mmsystem.h:594
LPCWSTR lpfilename
Definition: mmsystem.h:1627
DWORD_PTR dwCallback
Definition: mmsystem.h:1626
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciSeek()

static DWORD WAVE_mciSeek ( MCIDEVICEID  wDevID,
DWORD  dwFlags,
LPMCI_SEEK_PARMS  lpParms 
)
static

Definition at line 1242 of file mciwave.c.

1243{
1244 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
1245 DWORD position, dwRet;
1246
1247 TRACE("(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
1248
1249 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1250 if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
1251
1253 if (!position) return MCIERR_MISSING_PARAMETER;
1254 if (position&(position-1)) return MCIERR_FLAGS_NOT_COMPATIBLE;
1255
1256 /* Stop sends MCI_NOTIFY_ABORTED when needed */
1257 dwRet = WAVE_mciStop(wDevID, MCI_WAIT, 0);
1258 if (dwRet != MMSYSERR_NOERROR) return dwRet;
1259
1260 if (dwFlags & MCI_TO) {
1261 position = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwTo);
1262 if (position > wmw->ckWaveData.cksize)
1263 return MCIERR_OUTOFRANGE;
1264 } else if (dwFlags & MCI_SEEK_TO_START) {
1265 position = 0;
1266 } else {
1267 position = wmw->ckWaveData.cksize;
1268 }
1269 /* Seek rounds down, unless at end */
1270 if (position != wmw->ckWaveData.cksize) {
1271 position /= wmw->lpWaveFormat->nBlockAlign;
1272 position *= wmw->lpWaveFormat->nBlockAlign;
1273 }
1274 wmw->dwPosition = position;
1275 TRACE("Seeking to position=%lu bytes\n", position);
1276
1277 if (dwFlags & MCI_NOTIFY)
1279
1280 return MMSYSERR_NOERROR;
1281}
#define MCIERR_FLAGS_NOT_COMPATIBLE
Definition: mmsystem.h:593
#define MCI_SEEK_TO_END
Definition: mmsystem.h:741
#define MCIERR_MISSING_PARAMETER
Definition: mmsystem.h:583
#define MCI_SEEK_TO_START
Definition: mmsystem.h:740
DWORD_PTR dwCallback
Definition: mmsystem.h:1545

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciSet()

static DWORD WAVE_mciSet ( MCIDEVICEID  wDevID,
DWORD  dwFlags,
LPMCI_WAVE_SET_PARMS  lpParms 
)
static

Definition at line 1286 of file mciwave.c.

1287{
1288 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
1289
1290 TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
1291
1292 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1293 if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
1294
1296 switch (lpParms->dwTimeFormat) {
1298 TRACE("MCI_FORMAT_MILLISECONDS !\n");
1300 break;
1301 case MCI_FORMAT_BYTES:
1302 TRACE("MCI_FORMAT_BYTES !\n");
1304 break;
1305 case MCI_FORMAT_SAMPLES:
1306 TRACE("MCI_FORMAT_SAMPLES !\n");
1308 break;
1309 default:
1310 WARN("Bad time format %lu!\n", lpParms->dwTimeFormat);
1312 }
1313 }
1314 if (dwFlags & MCI_SET_VIDEO) {
1315 TRACE("No support for video !\n");
1317 }
1318 if (dwFlags & MCI_SET_DOOR_OPEN) {
1319 TRACE("No support for door open !\n");
1321 }
1323 TRACE("No support for door close !\n");
1325 }
1326 if (dwFlags & MCI_SET_AUDIO) {
1327 if (dwFlags & MCI_SET_ON) {
1328 TRACE("MCI_SET_ON audio !\n");
1329 } else if (dwFlags & MCI_SET_OFF) {
1330 TRACE("MCI_SET_OFF audio !\n");
1331 } else {
1332 WARN("MCI_SET_AUDIO without SET_ON or SET_OFF\n");
1333 return MCIERR_BAD_INTEGER;
1334 }
1335
1336 switch (lpParms->dwAudio)
1337 {
1338 case MCI_SET_AUDIO_ALL: TRACE("MCI_SET_AUDIO_ALL !\n"); break;
1339 case MCI_SET_AUDIO_LEFT: TRACE("MCI_SET_AUDIO_LEFT !\n"); break;
1340 case MCI_SET_AUDIO_RIGHT: TRACE("MCI_SET_AUDIO_RIGHT !\n"); break;
1341 default: WARN("Unknown audio channel %lu\n", lpParms->dwAudio); break;
1342 }
1343 }
1344 if (dwFlags & MCI_WAVE_INPUT) {
1345 TRACE("MCI_WAVE_INPUT = %d\n", lpParms->wInput);
1346 if (lpParms->wInput >= waveInGetNumDevs())
1347 return MCIERR_OUTOFRANGE;
1348 if (wmw->wInput != (WORD)lpParms->wInput)
1349 WAVE_mciStop(wDevID, MCI_WAIT, NULL);
1350 wmw->wInput = lpParms->wInput;
1351 }
1352 if (dwFlags & MCI_WAVE_OUTPUT) {
1353 TRACE("MCI_WAVE_OUTPUT = %d\n", lpParms->wOutput);
1354 if (lpParms->wOutput >= waveOutGetNumDevs())
1355 return MCIERR_OUTOFRANGE;
1356 if (wmw->wOutput != (WORD)lpParms->wOutput)
1357 WAVE_mciStop(wDevID, MCI_WAIT, NULL);
1358 wmw->wOutput = lpParms->wOutput;
1359 }
1361 TRACE("MCI_WAVE_SET_ANYINPUT\n");
1362 if (wmw->wInput != (WORD)lpParms->wInput)
1363 WAVE_mciStop(wDevID, MCI_WAIT, NULL);
1364 wmw->wInput = WAVE_MAPPER;
1365 }
1367 TRACE("MCI_WAVE_SET_ANYOUTPUT\n");
1368 if (wmw->wOutput != (WORD)lpParms->wOutput)
1369 WAVE_mciStop(wDevID, MCI_WAIT, NULL);
1370 wmw->wOutput = WAVE_MAPPER;
1371 }
1372 /* Set wave format parameters is refused after Open or Record.*/
1374 TRACE("MCI_WAVE_SET_FORMATTAG = %d\n", lpParms->wFormatTag);
1375 if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
1376 if (lpParms->wFormatTag != WAVE_FORMAT_PCM)
1377 return MCIERR_OUTOFRANGE;
1378 }
1380 if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
1381 wmw->wfxRef.nAvgBytesPerSec = lpParms->nAvgBytesPerSec;
1382 TRACE("MCI_WAVE_SET_AVGBYTESPERSEC = %ld\n", wmw->wfxRef.nAvgBytesPerSec);
1383 }
1385 if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
1386 wmw->wfxRef.wBitsPerSample = lpParms->wBitsPerSample;
1387 TRACE("MCI_WAVE_SET_BITSPERSAMPLE = %d\n", wmw->wfxRef.wBitsPerSample);
1388 }
1390 if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
1391 wmw->wfxRef.nBlockAlign = lpParms->nBlockAlign;
1392 TRACE("MCI_WAVE_SET_BLOCKALIGN = %d\n", wmw->wfxRef.nBlockAlign);
1393 }
1395 if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
1396 wmw->wfxRef.nChannels = lpParms->nChannels;
1397 TRACE("MCI_WAVE_SET_CHANNELS = %d\n", wmw->wfxRef.nChannels);
1398 }
1400 if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
1401 wmw->wfxRef.nSamplesPerSec = lpParms->nSamplesPerSec;
1402 TRACE("MCI_WAVE_SET_SAMPLESPERSEC = %ld\n", wmw->wfxRef.nSamplesPerSec);
1403 }
1404 if (dwFlags & MCI_NOTIFY)
1406 return 0;
1407}
#define MCI_SET_AUDIO
Definition: mmsystem.h:775
#define MCI_WAVE_SET_SAMPLESPERSEC
Definition: mmsystem.h:824
#define MCI_WAVE_SET_AVGBYTESPERSEC
Definition: mmsystem.h:825
#define MCI_WAVE_SET_ANYINPUT
Definition: mmsystem.h:837
#define MCIERR_BAD_INTEGER
Definition: mmsystem.h:580
#define MCI_SET_DOOR_OPEN
Definition: mmsystem.h:772
#define MCI_SET_TIME_FORMAT
Definition: mmsystem.h:774
#define MCI_SET_VIDEO
Definition: mmsystem.h:776
#define MCI_SET_AUDIO_RIGHT
Definition: mmsystem.h:781
#define MCI_SET_AUDIO_ALL
Definition: mmsystem.h:779
#define MCI_WAVE_SET_FORMATTAG
Definition: mmsystem.h:822
#define MCI_SET_DOOR_CLOSED
Definition: mmsystem.h:773
#define MCI_WAVE_SET_CHANNELS
Definition: mmsystem.h:823
#define MCI_SET_AUDIO_LEFT
Definition: mmsystem.h:780
#define MCI_SET_OFF
Definition: mmsystem.h:778
#define MCI_WAVE_SET_BITSPERSAMPLE
Definition: mmsystem.h:827
#define MCI_WAVE_SET_BLOCKALIGN
Definition: mmsystem.h:826
#define MCI_WAVE_SET_ANYOUTPUT
Definition: mmsystem.h:838
#define MCIERR_BAD_TIME_FORMAT
Definition: mmsystem.h:601
#define MCI_SET_ON
Definition: mmsystem.h:777
DWORD_PTR dwCallback
Definition: mmsystem.h:1693

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciStatus()

static DWORD WAVE_mciStatus ( MCIDEVICEID  wDevID,
DWORD  dwFlags,
LPMCI_STATUS_PARMS  lpParms 
)
static

Definition at line 1464 of file mciwave.c.

1465{
1466 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
1467 DWORD ret = 0;
1468
1469 TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
1470 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1471 if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
1473
1474 if (dwFlags & MCI_STATUS_ITEM) {
1475 switch (lpParms->dwItem) {
1477 lpParms->dwReturn = 1;
1478 TRACE("MCI_STATUS_CURRENT_TRACK => %Iu\n", lpParms->dwReturn);
1479 break;
1480 case MCI_STATUS_LENGTH:
1481 if (!wmw->hFile) {
1482 lpParms->dwReturn = 0;
1484 }
1485 /* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
1487 TRACE("MCI_STATUS_LENGTH => %Iu\n", lpParms->dwReturn);
1488 break;
1489 case MCI_STATUS_MODE:
1490 TRACE("MCI_STATUS_MODE => %u\n", wmw->dwStatus);
1491 lpParms->dwReturn = MAKEMCIRESOURCE(wmw->dwStatus, wmw->dwStatus);
1493 break;
1495 TRACE("MCI_STATUS_MEDIA_PRESENT => TRUE!\n");
1498 break;
1500 /* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
1501 lpParms->dwReturn = 1;
1502 TRACE("MCI_STATUS_NUMBER_OF_TRACKS => %Iu\n", lpParms->dwReturn);
1503 break;
1505 if (!wmw->hFile) {
1506 lpParms->dwReturn = 0;
1508 }
1509 /* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
1511 (dwFlags & MCI_STATUS_START) ? 0 : wmw->dwPosition);
1512 TRACE("MCI_STATUS_POSITION %s => %Iu\n",
1513 (dwFlags & MCI_STATUS_START) ? "start" : "current", lpParms->dwReturn);
1514 break;
1515 case MCI_STATUS_READY:
1516 lpParms->dwReturn = (wmw->dwStatus == MCI_MODE_NOT_READY) ?
1518 TRACE("MCI_STATUS_READY => %u!\n", LOWORD(lpParms->dwReturn));
1520 break;
1523 TRACE("MCI_STATUS_TIME_FORMAT => %Iu\n", lpParms->dwReturn);
1525 break;
1526 case MCI_WAVE_INPUT:
1527 if (wmw->wInput != (WORD)WAVE_MAPPER)
1528 lpParms->dwReturn = wmw->wInput;
1529 else {
1532 }
1533 TRACE("MCI_WAVE_INPUT => %d\n", (signed)wmw->wInput);
1534 break;
1535 case MCI_WAVE_OUTPUT:
1536 if (wmw->wOutput != (WORD)WAVE_MAPPER)
1537 lpParms->dwReturn = wmw->wOutput;
1538 else {
1541 }
1542 TRACE("MCI_WAVE_OUTPUT => %d\n", (signed)wmw->wOutput);
1543 break;
1544 /* It is always ok to query wave format parameters,
1545 * except on auto-open yield MCIERR_UNSUPPORTED_FUNCTION. */
1548 lpParms->dwReturn = wmw->lpWaveFormat->wFormatTag;
1549 else {
1552 }
1553 TRACE("MCI_WAVE_FORMATTAG => %Iu\n", lpParms->dwReturn);
1554 break;
1556 lpParms->dwReturn = wmw->lpWaveFormat->nAvgBytesPerSec;
1557 TRACE("MCI_WAVE_STATUS_AVGBYTESPERSEC => %Iu\n", lpParms->dwReturn);
1558 break;
1560 lpParms->dwReturn = wmw->lpWaveFormat->wBitsPerSample;
1561 TRACE("MCI_WAVE_STATUS_BITSPERSAMPLE => %Iu\n", lpParms->dwReturn);
1562 break;
1564 lpParms->dwReturn = wmw->lpWaveFormat->nBlockAlign;
1565 TRACE("MCI_WAVE_STATUS_BLOCKALIGN => %Iu\n", lpParms->dwReturn);
1566 break;
1568 lpParms->dwReturn = wmw->lpWaveFormat->nChannels;
1569 TRACE("MCI_WAVE_STATUS_CHANNELS => %Iu\n", lpParms->dwReturn);
1570 break;
1572 lpParms->dwReturn = wmw->lpWaveFormat->nSamplesPerSec;
1573 TRACE("MCI_WAVE_STATUS_SAMPLESPERSEC => %Iu\n", lpParms->dwReturn);
1574 break;
1576 TRACE("MCI_WAVE_STATUS_LEVEL !\n");
1577 lpParms->dwReturn = 0xAAAA5555;
1578 break;
1579 default:
1580 WARN("unknown command %08lX !\n", lpParms->dwItem);
1582 }
1583 }
1584 if ((dwFlags & MCI_NOTIFY) && HRESULT_CODE(ret)==0)
1586 return ret;
1587}
#define MCI_FORMAT_RETURN_BASE
Definition: mmddk.h:343
#define WAVE_MAPPER_S
Definition: mmddk.h:359
#define WAVE_FORMAT_PCM_S
Definition: mmddk.h:358
#define MCI_WAVE_STATUS_BITSPERSAMPLE
Definition: mmsystem.h:835
#define MCI_STATUS_POSITION
Definition: mmsystem.h:745
#define MCI_WAVE_STATUS_LEVEL
Definition: mmsystem.h:836
#define MCI_WAVE_STATUS_BLOCKALIGN
Definition: mmsystem.h:834
#define MCI_WAVE_STATUS_SAMPLESPERSEC
Definition: mmsystem.h:832
#define MCI_STATUS_START
Definition: mmsystem.h:743
#define MCI_WAVE_STATUS_FORMATTAG
Definition: mmsystem.h:830
#define MCI_STATUS_CURRENT_TRACK
Definition: mmsystem.h:751
#define MCI_STATUS_NUMBER_OF_TRACKS
Definition: mmsystem.h:746
#define MCI_WAVE_STATUS_AVGBYTESPERSEC
Definition: mmsystem.h:833
#define MCI_STATUS_LENGTH
Definition: mmsystem.h:744
#define MCI_STATUS_MODE
Definition: mmsystem.h:747
#define MCI_STATUS_MEDIA_PRESENT
Definition: mmsystem.h:748
#define MCI_STATUS_TIME_FORMAT
Definition: mmsystem.h:749
#define MCI_WAVE_STATUS_CHANNELS
Definition: mmsystem.h:831
#define MCI_STATUS_ITEM
Definition: mmsystem.h:742
#define MCI_STATUS_READY
Definition: mmsystem.h:750
DWORD_PTR dwReturn
Definition: mmsystem.h:1569
DWORD_PTR dwCallback
Definition: mmsystem.h:1568

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciStop()

static DWORD WAVE_mciStop ( MCIDEVICEID  wDevID,
DWORD  dwFlags,
LPMCI_GENERIC_PARMS  lpParms 
)
static

Definition at line 615 of file mciwave.c.

616{
617 DWORD dwRet = 0;
618 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
619
620 TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
621
622 if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
623
624 if (wmw->dwStatus != MCI_MODE_STOP) {
626 if (old) mciDriverNotify(old, wDevID, MCI_NOTIFY_ABORTED);
627 }
628
629 /* wait for playback thread (if any) to exit before processing further */
630 switch (wmw->dwStatus) {
631 case MCI_MODE_PAUSE:
632 case MCI_MODE_PLAY:
633 case MCI_MODE_RECORD:
635 dwRet = (wmw->fInput) ? waveInReset(wmw->hWave) : waveOutReset(wmw->hWave);
636 while (wmw->dwStatus != MCI_MODE_STOP)
637 Sleep(10);
638 break;
639 }
640
641 /* sanity resets */
642 wmw->dwStatus = MCI_MODE_STOP;
643
644 if ((dwFlags & MCI_NOTIFY) && lpParms && MMSYSERR_NOERROR==dwRet)
646
647 return dwRet;
648}
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:726

Referenced by MCIWAVE_DriverProc(), WAVE_mciClose(), WAVE_mciPlay(), WAVE_mciSave(), WAVE_mciSeek(), and WAVE_mciSet().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( mciwave  )