ReactOS  0.4.15-dev-1070-ge1a01de
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_MCIWAVEWAVE_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;
432  return MCIERR_FILE_NOT_FOUND;
433  }
434 
435  *pszTmpFileName = HeapAlloc(GetProcessHeap(),
437  MAX_PATH * sizeof(WCHAR));
438  if (!GetTempFileNameW(szTmpPath, szPrefix, 0, *pszTmpFileName)) {
439  WARN("can't retrieve temp file name!\n");
440  HeapFree(GetProcessHeap(), 0, *pszTmpFileName);
441  return MCIERR_FILE_NOT_FOUND;
442  }
443 
444  TRACE("%s!\n", debugstr_w(*pszTmpFileName));
445 
446  if (*pszTmpFileName && (*pszTmpFileName)[0]) {
447 
448  *hFile = mmioOpenW(*pszTmpFileName, NULL,
450 
451  if (*hFile == 0) {
452  WARN("can't create file=%s!\n", debugstr_w(*pszTmpFileName));
453  /* temporary file could not be created. clean filename. */
454  HeapFree(GetProcessHeap(), 0, *pszTmpFileName);
455  dwRet = MCIERR_FILE_NOT_FOUND;
456  }
457  }
458  return dwRet;
459 }
#define MMIO_ALLOCBUF
Definition: mmsystem.h:532
#define MMIO_READWRITE
Definition: mmsystem.h:537
#define WARN(fmt,...)
Definition: debug.h:112
HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO *lpmmioinfo, DWORD dwOpenFlags)
Definition: mmio.c:669
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2079
#define debugstr_w
Definition: kernel32.h:32
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define GetProcessHeap()
Definition: compat.h:484
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_PATH
Definition: compat.h:34
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
_In_ HANDLE hFile
Definition: mswsock.h:90
#define MCIERR_FILE_NOT_FOUND
Definition: mmsystem.h:585
#define ARRAY_SIZE(a)
Definition: main.h:24
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define MMIO_CREATE
Definition: mmsystem.h:528
#define HeapFree(x, y, z)
Definition: compat.h:483

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,%08lx,%08lx)\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,%08lx,%08lx)\n",
91  sca->wDevID, sca->dwParam1, sca->dwParam2);
92  HeapFree(GetProcessHeap(), 0, sca);
93  return ret;
94 }
Definition: mciwave.c:71
#define MCI_WAIT
Definition: mmsystem.h:730
HANDLE evt
Definition: mciwave.c:73
async_cmd cmd
Definition: mciwave.c:72
#define TRACE(s)
Definition: solgame.cpp:4
DWORD_PTR dwParam2
Definition: mciwave.c:76
#define GetProcessHeap()
Definition: compat.h:484
unsigned long DWORD
Definition: ntddk_ex.h:95
int ret
DWORD_PTR dwParam1
Definition: mciwave.c:75
UINT wDevID
Definition: mciwave.c:74
#define HeapFree(x, y, z)
Definition: compat.h:483

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 = HeapAlloc(GetProcessHeap(), 0, sizeof(struct SCA) + size);
104 
105  if (sca == 0)
106  return MCIERR_OUT_OF_MEMORY;
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  */
136  CloseHandle(handles[0]);
137  CloseHandle(handles[1]);
138  return 0;
139 }
Definition: mciwave.c:71
#define CloseHandle
Definition: compat.h:487
static struct object_header ** handles
Definition: handle.c:45
#define DWORD_PTR
Definition: treelist.c:76
#define WARN(fmt,...)
Definition: debug.h:112
HANDLE evt
Definition: mciwave.c:73
char * cmd
Definition: vfdcmd.c:85
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
async_cmd cmd
Definition: mciwave.c:72
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
#define FALSE
Definition: types.h:117
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:136
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:699
#define MCIERR_OUT_OF_MEMORY
Definition: mmsystem.h:574
GLsizeiptr size
Definition: glext.h:5919
DWORD_PTR dwParam2
Definition: mciwave.c:76
#define GetProcessHeap()
Definition: compat.h:484
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define THREAD_PRIORITY_TIME_CRITICAL
Definition: winbase.h:278
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
DWORD_PTR dwParam1
Definition: mciwave.c:75
UINT wDevID
Definition: mciwave.c:74
static DWORD CALLBACK MCI_SCAStarter(LPVOID arg)
Definition: mciwave.c:82
#define INFINITE
Definition: serial.h:102

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 1716 of file mciwave.c.

1718 {
1719  TRACE("(%08lX, %p, %08X, %08lX, %08lX)\n",
1720  dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1721 
1722  switch (wMsg) {
1723  case DRV_LOAD: return 1;
1724  case DRV_FREE: return 1;
1726  case DRV_CLOSE: return WAVE_drvClose(dwDevID);
1727  case DRV_ENABLE: return 1;
1728  case DRV_DISABLE: return 1;
1729  case DRV_QUERYCONFIGURE: return 1;
1730  case DRV_CONFIGURE: MessageBoxA(0, "MCI waveaudio Driver !", "Wine Driver", MB_OK); return 1;
1731  case DRV_INSTALL: return DRVCNF_RESTART;
1732  case DRV_REMOVE: return DRVCNF_RESTART;
1733  }
1734 
1735  if (dwDevID == 0xFFFFFFFF) return MCIERR_UNSUPPORTED_FUNCTION;
1736 
1737  switch (wMsg) {
1740  case MCI_CUE: return WAVE_mciCue (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1741  case MCI_PLAY: return WAVE_mciPlay (dwDevID, dwParam1, dwParam2, NULL);
1742  case MCI_RECORD: return WAVE_mciRecord (dwDevID, dwParam1, dwParam2, NULL);
1743  case MCI_STOP: return WAVE_mciStop (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1744  case MCI_SET: return WAVE_mciSet (dwDevID, dwParam1, (LPMCI_WAVE_SET_PARMS) dwParam2);
1745  case MCI_PAUSE: return WAVE_mciPause (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1746  case MCI_RESUME: return WAVE_mciResume (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1747  case MCI_STATUS: return WAVE_mciStatus (dwDevID, dwParam1, (LPMCI_STATUS_PARMS) dwParam2);
1749  case MCI_INFO: return WAVE_mciInfo (dwDevID, dwParam1, (LPMCI_INFO_PARMSW) dwParam2);
1750  case MCI_SEEK: return WAVE_mciSeek (dwDevID, dwParam1, (LPMCI_SEEK_PARMS) dwParam2);
1751  case MCI_SAVE: return WAVE_mciSave (dwDevID, dwParam1, (LPMCI_SAVE_PARMSW) dwParam2);
1752  /* commands that should be supported */
1753  case MCI_LOAD:
1754  case MCI_FREEZE:
1755  case MCI_PUT:
1756  case MCI_REALIZE:
1757  case MCI_UNFREEZE:
1758  case MCI_UPDATE:
1759  case MCI_WHERE:
1760  case MCI_STEP:
1761  case MCI_SPIN:
1762  case MCI_ESCAPE:
1763  case MCI_COPY:
1764  case MCI_CUT:
1765  case MCI_DELETE:
1766  case MCI_PASTE:
1767  FIXME("Unsupported command [%u]\n", wMsg);
1768  break;
1769  case MCI_WINDOW:
1770  TRACE("Unsupported command [%u]\n", wMsg);
1771  break;
1772  /* option which can be silenced */
1773  case MCI_CONFIGURE:
1774  return 0;
1775  case MCI_OPEN:
1776  case MCI_CLOSE:
1777  ERR("Shouldn't receive a MCI_OPEN or CLOSE message\n");
1778  break;
1779  default:
1780  FIXME("is probably wrong msg [%u]\n", wMsg);
1781  return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1782  }
1784 }
#define DRV_DISABLE
Definition: mmsystem.h:123
#define MCI_UNFREEZE
Definition: mmsystem.h:669
#define MCI_ESCAPE
Definition: mmsystem.h:648
static DWORD WAVE_mciPlay(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE hEvent)
Definition: mciwave.c:739
#define MCI_COPY
Definition: mmsystem.h:672
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define MCIERR_UNSUPPORTED_FUNCTION
Definition: mmsystem.h:584
static DWORD WAVE_mciSave(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SAVE_PARMSW lpParms)
Definition: mciwave.c:1419
#define MCI_STEP
Definition: mmsystem.h:657
#define MCI_PASTE
Definition: mmsystem.h:673
static DWORD WAVE_mciPause(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:1166
#define MCI_PLAY
Definition: mmsystem.h:649
#define DRV_CLOSE
Definition: mmsystem.h:122
#define MCI_RESUME
Definition: mmsystem.h:675
#define MCI_FREEZE
Definition: mmsystem.h:668
#define MCI_CUE
Definition: mmsystem.h:663
#define MCI_SAVE
Definition: mmsystem.h:661
#define DRV_QUERYCONFIGURE
Definition: mmsystem.h:126
#define DRV_OPEN
Definition: mmsystem.h:121
#define MCI_STOP
Definition: mmsystem.h:651
#define MCI_WINDOW
Definition: mmsystem.h:665
int WINAPI MessageBoxA(_In_opt_ HWND, _In_opt_ LPCSTR, _In_opt_ LPCSTR, _In_ UINT)
#define MCI_SET
Definition: mmsystem.h:656
#define MCI_RECORD
Definition: mmsystem.h:658
#define FIXME(fmt,...)
Definition: debug.h:111
static LRESULT WAVE_drvClose(MCIDEVICEID dwDevID)
Definition: mciwave.c:180
#define MCI_WHERE
Definition: mmsystem.h:667
smooth NULL
Definition: ftsmooth.c:416
#define DRV_LOAD(x)
#define MCI_OPEN
Definition: mmsystem.h:646
static DWORD WAVE_mciCue(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:581
#define DRVCNF_RESTART
Definition: mmsystem.h:135
#define DRV_REMOVE
Definition: mmsystem.h:128
#define MCI_INFO
Definition: mmsystem.h:653
#define MCI_CONFIGURE
Definition: digitalv.h:45
#define MCI_OPEN_DRIVER
Definition: mmddk.h:338
#define MCI_STATUS
Definition: mmsystem.h:662
#define TRACE(s)
Definition: solgame.cpp:4
DWORD_PTR dwParam2
Definition: mciwave.c:76
#define DRV_CONFIGURE
Definition: mmsystem.h:125
static DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:1206
static LRESULT WAVE_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp)
Definition: mciwave.c:150
#define MCI_REALIZE
Definition: mmsystem.h:664
#define DRV_FREE
Definition: mmsystem.h:124
static DWORD WAVE_mciRecord(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE hEvent)
Definition: mciwave.c:1000
#define MCI_LOAD
Definition: mmsystem.h:670
#define MCI_CUT
Definition: mmsystem.h:671
#define MCI_CLOSE_DRIVER
Definition: mmddk.h:339
#define DRV_ENABLE
Definition: mmsystem.h:120
#define ERR(fmt,...)
Definition: debug.h:110
static DWORD WAVE_mciSeek(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
Definition: mciwave.c:1249
static DWORD WAVE_mciStop(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:618
#define MCI_PUT
Definition: mmsystem.h:666
static DWORD WAVE_mciStatus(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
Definition: mciwave.c:1471
static LRESULT WAVE_mciOpen(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_PARMSW lpOpenParms)
Definition: mciwave.c:514
DWORD_PTR dwParam1
Definition: mciwave.c:75
#define MB_OK
Definition: winuser.h:784
#define MCI_CLOSE
Definition: mmsystem.h:647
#define MCI_GETDEVCAPS
Definition: mmsystem.h:654
static DWORD WAVE_mciGetDevCaps(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms)
Definition: mciwave.c:1599
#define MCIERR_UNRECOGNIZED_COMMAND
Definition: mmsystem.h:571
#define MCI_PAUSE
Definition: mmsystem.h:652
static DWORD WAVE_mciInfo(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_INFO_PARMSW lpParms)
Definition: mciwave.c:1670
#define DRV_INSTALL
Definition: mmsystem.h:127
LRESULT WINAPI DefDriverProc(DWORD_PTR dwDriverIdentifier, HDRVR hDrv, UINT Msg, LPARAM lParam1, LPARAM lParam2)
Definition: driver.c:554
#define MCI_SPIN
Definition: mmsystem.h:655
#define MCI_UPDATE
Definition: mmsystem.h:674
#define MCI_SEEK
Definition: mmsystem.h:650
#define MCI_DELETE
Definition: mmsystem.h:676
static DWORD WAVE_mciClose(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:660
static DWORD WAVE_mciSet(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_WAVE_SET_PARMS lpParms)
Definition: mciwave.c:1293

◆ 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) {
233  ret = MulDiv(val,1000,wmw->lpWaveFormat->nAvgBytesPerSec);
234  break;
235  case MCI_FORMAT_BYTES:
236  ret = val;
237  break;
238  case MCI_FORMAT_SAMPLES:
240  break;
241  default:
242  WARN("Bad time format %u!\n", wmw->dwMciTimeFormat);
243  }
244  TRACE("val=%u=0x%08x [tf=%u] => ret=%u\n", val, val, wmw->dwMciTimeFormat, ret);
245  return ret;
246 }
#define MCI_FORMAT_SAMPLES
Definition: mmsystem.h:710
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
#define WARN(fmt,...)
Definition: debug.h:112
#define MCI_FORMAT_MILLISECONDS
Definition: mmsystem.h:701
GLuint GLfloat * val
Definition: glext.h:7180
#define TRACE(s)
Definition: solgame.cpp:4
LPWAVEFORMATEX lpWaveFormat
Definition: mciwave.c:47
unsigned long DWORD
Definition: ntddk_ex.h:95
int ret
DWORD dwMciTimeFormat
Definition: mciwave.c:52
DWORD nSamplesPerSec
Definition: mmreg.h:80
#define MCI_FORMAT_BYTES
Definition: mmsystem.h:709
#define MulDiv(x, y, z)
Definition: gdifloat.h:86

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) {
257  ret = MulDiv(val,wmw->lpWaveFormat->nAvgBytesPerSec,1000);
258  if (ret > wmw->ckWaveData.cksize &&
260  ret = wmw->ckWaveData.cksize;
261  break;
262  case MCI_FORMAT_BYTES:
263  ret = val;
264  break;
265  case MCI_FORMAT_SAMPLES:
267  break;
268  default:
269  WARN("Bad time format %u!\n", wmw->dwMciTimeFormat);
270  }
271  TRACE("val=%u=0x%08x [tf=%u] => ret=%u\n", val, val, wmw->dwMciTimeFormat, ret);
272  return ret;
273 }
#define MCI_FORMAT_SAMPLES
Definition: mmsystem.h:710
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
#define WARN(fmt,...)
Definition: debug.h:112
static DWORD WAVE_ConvertByteToTimeFormat(WINE_MCIWAVE *wmw, DWORD val)
Definition: mciwave.c:227
#define MCI_FORMAT_MILLISECONDS
Definition: mmsystem.h:701
GLuint GLfloat * val
Definition: glext.h:7180
#define TRACE(s)
Definition: solgame.cpp:4
LPWAVEFORMATEX lpWaveFormat
Definition: mciwave.c:47
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD cksize
Definition: mmsystem.h:1508
int ret
MMCKINFO ckWaveData
Definition: mciwave.c:57
DWORD dwMciTimeFormat
Definition: mciwave.c:52
DWORD nSamplesPerSec
Definition: mmreg.h:80
#define MCI_FORMAT_BYTES
Definition: mmsystem.h:709
#define MulDiv(x, y, z)
Definition: gdifloat.h:86

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 {
182  WINE_MCIWAVE* wmw = (WINE_MCIWAVE*)mciGetDriverData(dwDevID);
183 
184  if (wmw) {
185  HeapFree(GetProcessHeap(), 0, 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:2066
#define GetProcessHeap()
Definition: compat.h:484
#define HeapFree(x, y, z)
Definition: compat.h:483

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;
162  mciSetDriverData(wmw->wDevID, (DWORD_PTR)wmw);
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 }
BOOL WINAPI mciSetDriverData(UINT uDeviceID, DWORD dwData)
#define MCI_NO_COMMAND_TABLE
Definition: mmddk.h:375
#define WAVE_FORMAT_PCM
Definition: constants.h:425
UINT wCustomCommandTable
Definition: mmddk.h:438
WAVEFORMATEX wfxRef
Definition: mciwave.c:46
WORD wBitsPerSample
Definition: audioclient.idl:45
smooth NULL
Definition: ftsmooth.c:416
DWORD nSamplesPerSec
Definition: audioclient.idl:42
#define GetProcessHeap()
Definition: compat.h:484
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
UINT wDevID
Definition: mciwave.c:39
uint32_t DWORD_PTR
Definition: typedefs.h:65
DWORD nAvgBytesPerSec
Definition: audioclient.idl:43
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define MCI_DEVTYPE_WAVEFORM_AUDIO
Definition: mmsystem.h:689

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciClose()

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

Definition at line 660 of file mciwave.c.

661 {
662  DWORD dwRet = 0;
664 
665  TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);
666 
667  if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
668 
669  if (wmw->dwStatus != MCI_MODE_STOP) {
670  /* mciStop handles MCI_NOTIFY_ABORTED */
671  dwRet = WAVE_mciStop(wDevID, MCI_WAIT, lpParms);
672  }
673 
674  wmw->nUseCount--;
675 
676  if (wmw->nUseCount == 0) {
677  if (wmw->hFile != 0) {
678  mmioClose(wmw->hFile, 0);
679  wmw->hFile = 0;
680  }
681  }
682 
683  if (wmw->lpWaveFormat != &wmw->wfxRef)
685  wmw->lpWaveFormat = &wmw->wfxRef;
686  HeapFree(GetProcessHeap(), 0, wmw->lpFileName);
687  wmw->lpFileName = NULL;
688 
689  if ((dwFlags & MCI_NOTIFY) && lpParms) {
690  WAVE_mciNotify(lpParms->dwCallback, wmw,
691  (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE);
692  }
693 
694  return 0;
695 }
#define MCI_MODE_STOP
Definition: mmsystem.h:695
#define MCI_WAIT
Definition: mmsystem.h:730
static void WAVE_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIWAVE *wmw, UINT wStatus)
Definition: mciwave.c:213
HMMIO hFile
Definition: mciwave.c:42
MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
Definition: mmio.c:701
volatile WORD dwStatus
Definition: mciwave.c:51
WAVEFORMATEX wfxRef
Definition: mciwave.c:46
smooth NULL
Definition: ftsmooth.c:416
#define MCI_NOTIFY_FAILURE
Definition: mmsystem.h:728
#define TRACE(s)
Definition: solgame.cpp:4
LPWSTR lpFileName
Definition: mciwave.c:45
#define GetProcessHeap()
Definition: compat.h:484
LPWAVEFORMATEX lpWaveFormat
Definition: mciwave.c:47
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
static WINE_MCIWAVE * WAVE_mciGetOpenDev(MCIDEVICEID wDevID)
Definition: mciwave.c:195
static DWORD WAVE_mciStop(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:618
DWORD_PTR dwCallback
Definition: mmsystem.h:1517
UINT wDevID
Definition: mciwave.c:74
int nUseCount
Definition: mciwave.c:41
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define HeapFree(x, y, z)
Definition: compat.h:483

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 
356  if (MMSYSERR_NOERROR != mmioCreateChunk(wmw->hFile, lpckRIFF, MMIO_CREATERIFF))
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. */
366  if (wmw->lpWaveFormat->wFormatTag == WAVE_FORMAT_PCM) {
367  if (wmw->lpWaveFormat->nBlockAlign !=
369  WORD size = wmw->lpWaveFormat->nChannels *
371  WARN("Incorrect nBlockAlign (%d), setting it to %d\n",
372  wmw->lpWaveFormat->nBlockAlign, size);
373  wmw->lpWaveFormat->nBlockAlign = size;
374  }
375  if (wmw->lpWaveFormat->nAvgBytesPerSec !=
377  DWORD speed = wmw->lpWaveFormat->nSamplesPerSec *
379  WARN("Incorrect nAvgBytesPerSec (%d), setting it to %d\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 
413 err:
414  /* mciClose takes care of wmw->lpWaveFormat. */
415  return MCIERR_INVALID_FILE;
416 }
#define MCIERR_INVALID_FILE
Definition: mmsystem.h:604
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
MMRESULT WINAPI mmioAscend(HMMIO hmmio, LPMMCKINFO lpck, UINT uFlags)
Definition: mmio.c:1204
WORD nChannels
Definition: mmreg.h:79
#define WARN(fmt,...)
Definition: debug.h:112
HMMIO hFile
Definition: mciwave.c:42
#define assert(x)
Definition: debug.h:53
struct pcmwaveformat_tag PCMWAVEFORMAT
#define WAVE_FORMAT_PCM
Definition: constants.h:425
WAVEFORMATEX wfxRef
Definition: mciwave.c:46
LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
Definition: mmio.c:781
FOURCC fccType
Definition: mmsystem.h:1509
#define MCIERR_OUT_OF_MEMORY
Definition: mmsystem.h:574
GLsizeiptr size
Definition: glext.h:5919
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define GetProcessHeap()
Definition: compat.h:484
LPWAVEFORMATEX lpWaveFormat
Definition: mciwave.c:47
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD cksize
Definition: mmsystem.h:1508
WORD wFormatTag
Definition: mmreg.h:78
#define FOURCC_RIFF
Definition: mmsystem.h:564
MMRESULT WINAPI mmioCreateChunk(HMMIO hmmio, MMCKINFO *lpck, UINT uFlags)
Definition: mmio.c:1238
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
#define err(...)
#define MMIO_CREATERIFF
Definition: mmsystem.h:554
MMCKINFO ckWaveData
Definition: mciwave.c:57
MMCKINFO ckMainRIFF
Definition: mciwave.c:56
FOURCC ckid
Definition: mmsystem.h:1507
WORD cbSize
Definition: mmreg.h:84
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nBlockAlign
Definition: mmreg.h:82
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 581 of file mciwave.c.

582 {
584 
585  TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);
586 
587  /* Tests on systems without sound drivers show that Cue, like
588  * Record and Play, opens winmm, returning MCIERR_WAVE_xyPUTSUNSUITABLE.
589  * The first Cue Notify does not immediately return the
590  * notification, as if a player or recorder thread is started.
591  * PAUSE mode is reported when successful, but this mode is
592  * different from the normal Pause, because a) Pause then returns
593  * NONAPPLICABLE_FUNCTION instead of 0 and b) Set Channels etc. is
594  * still accepted, returning the original notification as ABORTED.
595  * I.e. Cue allows subsequent format changes, unlike Record or
596  * Open file, closes winmm if the format changes and stops this
597  * thread.
598  * Wine creates one player or recorder thread per async. Play or
599  * Record command. Notification behaviour suggests that MS-W*
600  * reuses a single thread to improve response times. Having Cue
601  * start this thread early helps to improve Play/Record's initial
602  * response time. In effect, Cue is a performance hint, which
603  * justifies our almost no-op implementation.
604  */
605 
606  if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
608 
609  if ((dwFlags & MCI_NOTIFY) && lpParms)
611 
612  return MMSYSERR_NOERROR;
613 }
#define MCIERR_NONAPPLICABLE_FUNCTION
Definition: mmsystem.h:610
#define MCI_MODE_STOP
Definition: mmsystem.h:695
static void WAVE_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIWAVE *wmw, UINT wStatus)
Definition: mciwave.c:213
volatile WORD dwStatus
Definition: mciwave.c:51
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
static WINE_MCIWAVE * WAVE_mciGetOpenDev(MCIDEVICEID wDevID)
Definition: mciwave.c:195
DWORD_PTR dwCallback
Definition: mmsystem.h:1517
UINT wDevID
Definition: mciwave.c:74
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_NOTIFY
Definition: mmsystem.h:729

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;
339  wmw->lpWaveFormat->wBitsPerSample = 8;
340  wmw->lpWaveFormat->cbSize = 0;
341 }
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
WORD nChannels
Definition: mmreg.h:79
#define WAVE_FORMAT_PCM
Definition: constants.h:425
WAVEFORMATEX wfxRef
Definition: mciwave.c:46
LPWAVEFORMATEX lpWaveFormat
Definition: mciwave.c:47
WORD wFormatTag
Definition: mmreg.h:78
WORD cbSize
Definition: mmreg.h:84
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nBlockAlign
Definition: mmreg.h:82
WORD wBitsPerSample
Definition: mmreg.h:83

Referenced by WAVE_mciOpen().

◆ WAVE_mciGetDevCaps()

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

Definition at line 1599 of file mciwave.c.

1601 {
1603  DWORD ret = 0;
1604 
1605  TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);
1606 
1607  if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1608  if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
1609 
1610  if (dwFlags & MCI_GETDEVCAPS_ITEM) {
1611  switch(lpParms->dwItem) {
1615  break;
1617  lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
1619  break;
1621  lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
1623  break;
1625  lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
1627  break;
1629  lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
1631  break;
1633  lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
1635  break;
1637  lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
1639  break;
1641  lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
1643  break;
1645  lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
1647  break;
1649  lpParms->dwReturn = waveInGetNumDevs();
1650  break;
1652  lpParms->dwReturn = waveOutGetNumDevs();
1653  break;
1654  default:
1655  FIXME("Unknown capability (%08x) !\n", lpParms->dwItem);
1657  }
1658  } else {
1659  WARN("No GetDevCaps-Item !\n");
1661  }
1662  if ((dwFlags & MCI_NOTIFY) && HRESULT_CODE(ret)==0)
1664  return ret;
1665 }
#define MCI_WAVE_GETDEVCAPS_INPUTS
Definition: mmsystem.h:839
static void WAVE_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIWAVE *wmw, UINT wStatus)
Definition: mciwave.c:213
#define TRUE
Definition: types.h:120
#define MCI_GETDEVCAPS_CAN_SAVE
Definition: mmsystem.h:767
#define WARN(fmt,...)
Definition: debug.h:112
#define MCI_GETDEVCAPS_COMPOUND_DEVICE
Definition: mmsystem.h:764
#define MCI_RESOURCE_RETURNED
Definition: mmddk.h:369
#define MCI_GETDEVCAPS_CAN_RECORD
Definition: mmsystem.h:759
#define MAKEMCIRESOURCE(wRet, wRes)
Definition: mmddk.h:388
#define MCI_GETDEVCAPS_USES_FILES
Definition: mmsystem.h:763
#define FALSE
Definition: types.h:117
#define FIXME(fmt,...)
Definition: debug.h:111
#define MCI_GETDEVCAPS_DEVICE_TYPE
Definition: mmsystem.h:762
smooth NULL
Definition: ftsmooth.c:416
UINT WINAPI waveOutGetNumDevs(void)
Definition: winmm.c:2140
#define MCI_GETDEVCAPS_HAS_VIDEO
Definition: mmsystem.h:761
#define TRACE(s)
Definition: solgame.cpp:4
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
int ret
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define MCI_GETDEVCAPS_HAS_AUDIO
Definition: mmsystem.h:760
static WINE_MCIWAVE * WAVE_mciGetOpenDev(MCIDEVICEID wDevID)
Definition: mciwave.c:195
#define MCI_GETDEVCAPS_ITEM
Definition: mmsystem.h:758
#define MCI_FALSE
Definition: mmddk.h:340
#define MCI_TRUE
Definition: mmddk.h:341
UINT wDevID
Definition: mciwave.c:74
#define MCIERR_UNRECOGNIZED_COMMAND
Definition: mmsystem.h:571
#define HRESULT_CODE(hr)
Definition: winerror.h:76
#define MCI_GETDEVCAPS_CAN_EJECT
Definition: mmsystem.h:765
#define MCI_DEVTYPE_WAVEFORM_AUDIO
Definition: mmsystem.h:689
UINT WINAPI waveInGetNumDevs(void)
Definition: winmm.c:2568
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define MCI_WAVE_GETDEVCAPS_OUTPUTS
Definition: mmsystem.h:840
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605
#define MCI_GETDEVCAPS_CAN_PLAY
Definition: mmsystem.h:766

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 }
DWORD WINAPI mciGetDriverData(UINT uDeviceID)
Definition: mci.c:2066
#define WARN(fmt,...)
Definition: debug.h:112
smooth NULL
Definition: ftsmooth.c:416
UINT wDevID
Definition: mciwave.c:74
int nUseCount
Definition: mciwave.c:41

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 1670 of file mciwave.c.

1671 {
1672  DWORD ret = 0;
1673  LPCWSTR str = 0;
1675 
1676  TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);
1677 
1678  if (!lpParms || !lpParms->lpstrReturn)
1680 
1681  TRACE("buf=%p, len=%u\n", lpParms->lpstrReturn, lpParms->dwRetSize);
1682 
1683  if (wmw == NULL) {
1685  } else {
1686  static const WCHAR wszAudio [] = {'W','i','n','e','\'','s',' ','a','u','d','i','o',' ','p','l','a','y','e','r',0};
1687  static const WCHAR wszWaveIn [] = {'W','i','n','e',' ','W','a','v','e',' ','I','n',0};
1688  static const WCHAR wszWaveOut[] = {'W','i','n','e',' ','W','a','v','e',' ','O','u','t',0};
1689 
1690  switch (dwFlags & ~(MCI_WAIT|MCI_NOTIFY)) {
1691  case MCI_INFO_PRODUCT: str = wszAudio; break;
1692  case MCI_INFO_FILE: str = wmw->lpFileName; break;
1693  case MCI_WAVE_INPUT: str = wszWaveIn; break;
1694  case MCI_WAVE_OUTPUT: str = wszWaveOut; break;
1695  default:
1696  WARN("Don't know this info command (%u)\n", dwFlags);
1698  }
1699  }
1700  if (!ret) {
1701  if (lpParms->dwRetSize) {
1702  WCHAR zero = 0;
1703  /* FIXME? Since NT, mciwave, mciseq and mcicda set dwRetSize
1704  * to the number of characters written, excluding \0. */
1705  lstrcpynW(lpParms->lpstrReturn, str ? str : &zero, lpParms->dwRetSize);
1706  } else ret = MCIERR_PARAM_OVERFLOW;
1707  }
1708  if (MMSYSERR_NOERROR==ret && (dwFlags & MCI_NOTIFY))
1710  return ret;
1711 }
#define MCI_INFO_PRODUCT
Definition: mmsystem.h:752
#define MCI_WAIT
Definition: mmsystem.h:730
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static void WAVE_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIWAVE *wmw, UINT wStatus)
Definition: mciwave.c:213
#define MCI_WAVE_INPUT
Definition: mmsystem.h:828
#define WARN(fmt,...)
Definition: debug.h:112
#define lstrcpynW
Definition: compat.h:486
const WCHAR * str
#define MCI_INFO_FILE
Definition: mmsystem.h:753
#define MCI_WAVE_OUTPUT
Definition: mmsystem.h:829
smooth NULL
Definition: ftsmooth.c:416
DWORD_PTR dwCallback
Definition: mmsystem.h:1579
#define MCIERR_PARAM_OVERFLOW
Definition: mmsystem.h:578
#define TRACE(s)
Definition: solgame.cpp:4
LPWSTR lpFileName
Definition: mciwave.c:45
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
static double zero
Definition: j0_y0.c:96
int ret
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
static WINE_MCIWAVE * WAVE_mciGetOpenDev(MCIDEVICEID wDevID)
Definition: mciwave.c:195
#define MCIERR_UNRECOGNIZED_KEYWORD
Definition: mmsystem.h:570
UINT wDevID
Definition: mciwave.c:74
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605

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  */
221  mciDriverNotify(HWND_32(LOWORD(hWndCallBack)), wDevID, wStatus);
222 }
HANDLE hCallback
Definition: mciwave.c:44
BOOL WINAPI mciDriverNotify(HWND hwndCallback, UINT uDeviceID, UINT uStatus)
Definition: mci.c:2056
smooth NULL
Definition: ftsmooth.c:416
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
MCIDEVICEID wNotifyDeviceID
Definition: mciwave.c:43
#define HWND_32(h16)
Definition: wownt32.h:29
#define MCI_NOTIFY_SUPERSEDED
Definition: mmsystem.h:726
UINT wDevID
Definition: mciwave.c:74
UINT MCIDEVICEID
Definition: mmsystem.h:959
#define LOWORD(l)
Definition: pedump.c:82

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 514 of file mciwave.c.

515 {
516  DWORD dwRet = 0;
518 
519  TRACE("(%04X, %08X, %p)\n", wDevID, dwFlags, lpOpenParms);
520  if (lpOpenParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
521  if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
522 
525 
526  if (wmw->nUseCount > 0) {
527  /* The driver is already opened on this channel
528  * Wave driver cannot be shared
529  */
530  return MCIERR_DEVICE_OPEN;
531  }
532 
533  wmw->nUseCount++;
534 
535  wmw->wInput = wmw->wOutput = WAVE_MAPPER;
536  wmw->fInput = FALSE;
537  wmw->hWave = 0;
539  wmw->hFile = 0;
540  wmw->lpFileName = NULL; /* will be set by WAVE_mciOpenFile */
541  wmw->hCallback = NULL;
542  WAVE_mciDefaultFmt(wmw);
543 
544  TRACE("wDevID=%04X (lpParams->wDeviceID=%08X)\n", wDevID, lpOpenParms->wDeviceID);
545  /* Logs show the native winmm calls us with 0 still in lpOpenParms.wDeviceID */
546  wmw->wNotifyDeviceID = wDevID;
547 
548  if (dwFlags & MCI_OPEN_ELEMENT) {
550  /* could it be that (DWORD)lpOpenParms->lpstrElementName
551  * contains the hFile value ?
552  */
554  } else {
555  dwRet = WAVE_mciOpenFile(wmw, lpOpenParms->lpstrElementName);
556  }
557  }
558  TRACE("hFile=%p\n", wmw->hFile);
559 
560  if (dwRet == 0) {
561  wmw->dwPosition = 0;
562 
563  wmw->dwStatus = MCI_MODE_STOP;
564 
565  if (dwFlags & MCI_NOTIFY)
566  WAVE_mciNotify(lpOpenParms->dwCallback, wmw, MCI_NOTIFY_SUCCESSFUL);
567  } else {
568  wmw->nUseCount--;
569  if (wmw->hFile != 0)
570  mmioClose(wmw->hFile, 0);
571  wmw->hFile = 0;
572  HeapFree(GetProcessHeap(), 0, wmw->lpFileName);
573  wmw->lpFileName = NULL;
574  }
575  return dwRet;
576 }
#define MCI_MODE_STOP
Definition: mmsystem.h:695
DWORD WINAPI mciGetDriverData(UINT uDeviceID)
Definition: mci.c:2066
static void WAVE_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIWAVE *wmw, UINT wStatus)
Definition: mciwave.c:213
#define MCIERR_UNSUPPORTED_FUNCTION
Definition: mmsystem.h:584
HMMIO hFile
Definition: mciwave.c:42
MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
Definition: mmio.c:701
HANDLE hCallback
Definition: mciwave.c:44
static LRESULT WAVE_mciOpenFile(WINE_MCIWAVE *wmw, LPCWSTR filename)
Definition: mciwave.c:461
volatile WORD dwStatus
Definition: mciwave.c:51
DWORD dwPosition
Definition: mciwave.c:53
#define MCI_OPEN_ELEMENT_ID
Definition: mmsystem.h:737
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:416
BOOL fInput
Definition: mciwave.c:48
WORD wOutput
Definition: mciwave.c:50
#define TRACE(s)
Definition: solgame.cpp:4
LPWSTR lpFileName
Definition: mciwave.c:45
#define WAVE_MAPPER
Definition: mmsystem.h:187
#define GetProcessHeap()
Definition: compat.h:484
#define MCI_OPEN_SHAREABLE
Definition: mmsystem.h:734
MCIDEVICEID wNotifyDeviceID
Definition: mciwave.c:43
WORD wInput
Definition: mciwave.c:49
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
static void WAVE_mciDefaultFmt(WINE_MCIWAVE *wmw)
Definition: mciwave.c:331
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define MCI_MODE_NOT_READY
Definition: mmsystem.h:694
MCIDEVICEID wDeviceID
Definition: mmsystem.h:1677
#define MCI_OPEN_ELEMENT
Definition: mmsystem.h:735
HANDLE hWave
Definition: mciwave.c:40
UINT wDevID
Definition: mciwave.c:74
#define MCIERR_UNRECOGNIZED_COMMAND
Definition: mmsystem.h:571
#define MCIERR_DEVICE_OPEN
Definition: mmsystem.h:575
int nUseCount
Definition: mciwave.c:41
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605
#define HeapFree(x, y, z)
Definition: compat.h:483

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciOpenFile()

static LRESULT WAVE_mciOpenFile ( WINE_MCIWAVE wmw,
LPCWSTR  filename 
)
static

Definition at line 461 of file mciwave.c.

462 {
463  LRESULT dwRet = MMSYSERR_NOERROR;
464  LPWSTR fn;
465 
466  fn = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1) * sizeof(WCHAR));
467  if (!fn) return MCIERR_OUT_OF_MEMORY;
468  lstrcpyW(fn, filename);
469  HeapFree(GetProcessHeap(), 0, wmw->lpFileName);
470  wmw->lpFileName = fn;
471 
472  if (filename[0]) {
473  /* FIXME : what should be done if wmw->hFile is already != 0, or the driver is playin' */
474  TRACE("MCI_OPEN_ELEMENT %s!\n", debugstr_w(filename));
475 
478 
479  if (wmw->hFile == 0) {
480  WARN("can't find file=%s!\n", debugstr_w(filename));
481  dwRet = MCIERR_FILE_NOT_FOUND;
482  }
483  else
484  {
485  LPMMCKINFO lpckMainRIFF = &wmw->ckMainRIFF;
486 
487  /* make sure we're at the beginning of the file */
488  mmioSeek(wmw->hFile, 0, SEEK_SET);
489 
490  /* first reading of this file. read the waveformat chunk */
491  if (mmioDescend(wmw->hFile, lpckMainRIFF, NULL, 0) != 0) {
492  dwRet = MCIERR_INVALID_FILE;
493  } else {
494  TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08X\n",
495  (LPSTR)&(lpckMainRIFF->ckid),
496  (LPSTR) &(lpckMainRIFF->fccType),
497  (lpckMainRIFF->cksize));
498 
499  if ((lpckMainRIFF->ckid != FOURCC_RIFF) ||
500  lpckMainRIFF->fccType != mmioFOURCC('W', 'A', 'V', 'E')) {
501  dwRet = MCIERR_INVALID_FILE;
502  } else {
503  dwRet = WAVE_mciReadFmt(wmw, lpckMainRIFF);
504  }
505  }
506  }
507  }
508  return dwRet;
509 }
#define MMIO_ALLOCBUF
Definition: mmsystem.h:532
#define MCIERR_INVALID_FILE
Definition: mmsystem.h:604
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
#define WARN(fmt,...)
Definition: debug.h:112
HMMIO hFile
Definition: mciwave.c:42
HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO *lpmmioinfo, DWORD dwOpenFlags)
Definition: mmio.c:669
#define MMIO_DENYWRITE
Definition: mmsystem.h:540
char * LPSTR
Definition: xmlstorage.h:182
const char * filename
Definition: ioapi.h:135
#define lstrlenW
Definition: compat.h:498
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
Definition: mmio.c:835
#define debugstr_w
Definition: kernel32.h:32
smooth NULL
Definition: ftsmooth.c:416
FOURCC fccType
Definition: mmsystem.h:1509
#define MMIO_READ
Definition: mmsystem.h:535
#define MCIERR_OUT_OF_MEMORY
Definition: mmsystem.h:574
#define SEEK_SET
Definition: jmemansi.c:26
#define TRACE(s)
Definition: solgame.cpp:4
LPWSTR lpFileName
Definition: mciwave.c:45
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define GetProcessHeap()
Definition: compat.h:484
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
DWORD cksize
Definition: mmsystem.h:1508
#define FOURCC_RIFF
Definition: mmsystem.h:564
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
static DWORD WAVE_mciReadFmt(WINE_MCIWAVE *wmw, const MMCKINFO *pckMainRIFF)
Definition: mciwave.c:278
MMCKINFO ckMainRIFF
Definition: mciwave.c:56
#define MCIERR_FILE_NOT_FOUND
Definition: mmsystem.h:585
#define lstrcpyW
Definition: compat.h:497
FOURCC ckid
Definition: mmsystem.h:1507
MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck, const MMCKINFO *lpckParent, UINT uFlags)
Definition: mmio.c:1106
WCHAR * LPWSTR
Definition: xmlstorage.h:184
LONG_PTR LRESULT
Definition: windef.h:209
#define HeapFree(x, y, z)
Definition: compat.h:483

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 1166 of file mciwave.c.

1167 {
1168  DWORD dwRet;
1170 
1171  TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);
1172 
1173  if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
1174 
1175  switch (wmw->dwStatus) {
1176  case MCI_MODE_PLAY:
1177  dwRet = waveOutPause(wmw->hWave);
1178  if (dwRet==MMSYSERR_NOERROR) wmw->dwStatus = MCI_MODE_PAUSE;
1179  else { /* When playthread was not started yet, winmm not opened, error 5 MMSYSERR_INVALHANDLE */
1180  ERR("waveOutPause error %d\n",dwRet);
1181  dwRet = MCIERR_INTERNAL;
1182  }
1183  break;
1184  case MCI_MODE_RECORD:
1185  dwRet = waveInStop(wmw->hWave);
1186  if (dwRet==MMSYSERR_NOERROR) wmw->dwStatus = MCI_MODE_PAUSE;
1187  else {
1188  ERR("waveInStop error %d\n",dwRet);
1189  dwRet = MCIERR_INTERNAL;
1190  }
1191  break;
1192  case MCI_MODE_PAUSE:
1193  dwRet = MMSYSERR_NOERROR;
1194  break;
1195  default:
1197  }
1198  if (MMSYSERR_NOERROR==dwRet && (dwFlags & MCI_NOTIFY) && lpParms)
1200  return dwRet;
1201 }
#define MCIERR_NONAPPLICABLE_FUNCTION
Definition: mmsystem.h:610
static void WAVE_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIWAVE *wmw, UINT wStatus)
Definition: mciwave.c:213
volatile WORD dwStatus
Definition: mciwave.c:51
#define MCI_MODE_RECORD
Definition: mmsystem.h:697
#define MCI_MODE_PLAY
Definition: mmsystem.h:696
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
Definition: winmm.c:2374
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
static WINE_MCIWAVE * WAVE_mciGetOpenDev(MCIDEVICEID wDevID)
Definition: mciwave.c:195
#define MCIERR_INTERNAL
Definition: mmsystem.h:587
#define ERR(fmt,...)
Definition: debug.h:110
UINT WINAPI waveInStop(HWAVEIN hWaveIn)
Definition: winmm.c:2767
DWORD_PTR dwCallback
Definition: mmsystem.h:1517
HANDLE hWave
Definition: mciwave.c:40
UINT wDevID
Definition: mciwave.c:74
#define MCI_MODE_PAUSE
Definition: mmsystem.h:699
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_NOTIFY
Definition: mmsystem.h:729

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 739 of file mciwave.c.

740 {
741  LPMCI_PLAY_PARMS lpParms = (void*)pmt;
742  DWORD end;
744  DWORD dwRet;
745  LPWAVEHDR waveHdr = NULL;
747  HANDLE oldcb;
748  int whidx;
749 
750  TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
751 
752  if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
753  if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
754 
755  if (wmw->hFile == 0) {
756  WARN("Can't play: no file=%s!\n", debugstr_w(wmw->lpFileName));
757  return MCIERR_FILE_NOT_FOUND;
758  }
759 
760  if (wmw->dwStatus == MCI_MODE_PAUSE && !wmw->fInput && !(dwFlags & (MCI_FROM | MCI_TO))) {
761  /* FIXME: notification is different with Resume than Play */
763  }
764 
769  if ( !(wmw->dwStatus == MCI_MODE_STOP) &&
770  !((wmw->dwStatus == MCI_MODE_PLAY) && (dwFlags & MCI_WAIT) && !wmw->hWave)) {
771  /* FIXME: Check FROM/TO parameters first. */
772  /* FIXME: Play; Play [notify|wait] must hook into the running player. */
773  dwRet = WAVE_mciStop(wDevID, MCI_WAIT, NULL);
774  if (dwRet) return dwRet;
775  }
776 
777  if (wmw->lpWaveFormat->wFormatTag == WAVE_FORMAT_PCM) {
778  if (wmw->lpWaveFormat->nBlockAlign !=
780  WARN("Incorrect nBlockAlign (%d), setting it to %d\n",
782  wmw->lpWaveFormat->nChannels *
783  wmw->lpWaveFormat->wBitsPerSample/8);
784  wmw->lpWaveFormat->nBlockAlign =
785  wmw->lpWaveFormat->nChannels *
787  }
788  if (wmw->lpWaveFormat->nAvgBytesPerSec !=
790  WARN("Incorrect nAvgBytesPerSec (%d), setting it to %d\n",
793  wmw->lpWaveFormat->nBlockAlign);
797  }
798  }
799 
800  end = wmw->ckWaveData.cksize;
801  if (dwFlags & MCI_TO) {
802  DWORD position = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwTo);
803  if (position > end) return MCIERR_OUTOFRANGE;
804  end = position;
805  }
806  if (dwFlags & MCI_FROM) {
807  DWORD position = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwFrom);
808  if (position > end) return MCIERR_OUTOFRANGE;
809  /* Seek rounds down, so do we. */
810  position /= wmw->lpWaveFormat->nBlockAlign;
811  position *= wmw->lpWaveFormat->nBlockAlign;
812  wmw->dwPosition = position;
813  }
814  if (end < wmw->dwPosition) return MCIERR_OUTOFRANGE;
815  left = end - wmw->dwPosition;
816  if (0==left) return MMSYSERR_NOERROR; /* FIXME: NOTIFY */
817 
818  wmw->fInput = FALSE; /* FIXME: waveInOpen may have been called. */
819  wmw->dwStatus = MCI_MODE_PLAY;
820 
821  if (!(dwFlags & MCI_WAIT)) {
823  (DWORD_PTR)lpParms, sizeof(MCI_PLAY_PARMS));
824  }
825 
826  TRACE("Playing from byte=%u to byte=%u\n", wmw->dwPosition, end);
827 
829  (dwFlags & MCI_NOTIFY) ? HWND_32(LOWORD(lpParms->dwCallback)) : NULL);
830  if (oldcb) mciDriverNotify(oldcb, wDevID, MCI_NOTIFY_ABORTED);
831  oldcb = NULL;
832 
833 #define WAVE_ALIGN_ON_BLOCK(wmw,v) \
834 ((((v) + (wmw)->lpWaveFormat->nBlockAlign - 1) / (wmw)->lpWaveFormat->nBlockAlign) * (wmw)->lpWaveFormat->nBlockAlign)
835 
836  /* go back to beginning of chunk plus the requested position */
837  /* FIXME: I'm not sure this is correct, notably because some data linked to
838  * the decompression state machine will not be correctly initialized.
839  * try it this way (other way would be to decompress from 0 up to dwPosition
840  * and to start sending to hWave when dwPosition is reached)
841  */
842  mmioSeek(wmw->hFile, wmw->ckWaveData.dwDataOffset + wmw->dwPosition, SEEK_SET); /* >= 0 */
843 
844  dwRet = waveOutOpen((HWAVEOUT *)&wmw->hWave, wmw->wOutput, wmw->lpWaveFormat,
846 
847  if (dwRet != 0) {
848  TRACE("Can't open low level audio device %d\n", dwRet);
849  dwRet = MCIERR_DEVICE_OPEN;
850  wmw->hWave = 0;
851  goto cleanUp;
852  }
853 
854  /* make it so that 3 buffers per second are needed */
856 
857  waveHdr = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(WAVEHDR) + 2 * bufsize);
858  waveHdr[0].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR);
859  waveHdr[1].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR) + bufsize;
860  waveHdr[0].dwUser = waveHdr[1].dwUser = 0L;
861  waveHdr[0].dwLoops = waveHdr[1].dwLoops = 0L;
862  waveHdr[0].dwFlags = waveHdr[1].dwFlags = 0L;
863  waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize;
864  if (waveOutPrepareHeader(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
865  waveOutPrepareHeader(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR))) {
866  dwRet = MCIERR_INTERNAL;
867  goto cleanUp;
868  }
869 
870  whidx = 0;
871  wmw->hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
872  if (!wmw->hEvent) {
873  dwRet = MCIERR_OUT_OF_MEMORY;
874  goto cleanUp;
875  }
876  wmw->dwEventCount = 1L; /* for first buffer */
877 
878  TRACE("Playing (normalized) from byte=%u for %u bytes\n", wmw->dwPosition, left);
879  if (hEvent) SetEvent(hEvent);
880 
881  /* FIXME: this doesn't work if wmw->dwPosition != 0 */
882  while (left > 0 && wmw->dwStatus != MCI_MODE_STOP && wmw->dwStatus != MCI_MODE_NOT_READY) {
883  count = mmioRead(wmw->hFile, waveHdr[whidx].lpData, min(bufsize, left));
884  TRACE("mmioRead bufsize=%d count=%d\n", bufsize, count);
885  if (count < 1)
886  break;
887  /* count is always <= bufsize, so this is correct regarding the
888  * waveOutPrepareHeader function
889  */
890  waveHdr[whidx].dwBufferLength = count;
891  waveHdr[whidx].dwFlags &= ~WHDR_DONE;
892  TRACE("before WODM_WRITE lpWaveHdr=%p dwBufferLength=%u\n",
893  &waveHdr[whidx], waveHdr[whidx].dwBufferLength);
894  dwRet = waveOutWrite(wmw->hWave, &waveHdr[whidx], sizeof(WAVEHDR));
895  if (dwRet) {
896  ERR("Aborting play loop, WODM_WRITE error %d\n", dwRet);
897  dwRet = MCIERR_HARDWARE;
898  break;
899  }
900  left -= count;
901  wmw->dwPosition += count;
902  TRACE("after WODM_WRITE dwPosition=%u\n", wmw->dwPosition);
903  /* InterlockedDecrement if and only if waveOutWrite is successful */
905  whidx ^= 1;
906  }
907 
908  WAVE_mciPlayWaitDone(wmw); /* to balance first buffer */
909 
910  /* just to get rid of some race conditions between play, stop and pause */
911  waveOutReset(wmw->hWave);
912 
913  waveOutUnprepareHeader(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR));
914  waveOutUnprepareHeader(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR));
915 
916 cleanUp:
917  if (dwFlags & MCI_NOTIFY)
918  oldcb = InterlockedExchangePointer(&wmw->hCallback, NULL);
919 
920  HeapFree(GetProcessHeap(), 0, waveHdr);
921 
922  if (wmw->hWave) {
923  waveOutClose(wmw->hWave);
924  wmw->hWave = 0;
925  }
926  CloseHandle(wmw->hEvent);
927  wmw->hEvent = NULL;
928 
929  wmw->dwStatus = MCI_MODE_STOP;
930 
931  /* Let the potentially asynchronous commands support FAILURE notification. */
932  if (oldcb) mciDriverNotify(oldcb, wDevID,
934 
935  return dwRet;
936 }
#define MCI_MODE_STOP
Definition: mmsystem.h:695
static void CALLBACK WAVE_mciPlayCallback(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, LPARAM dwParam1, LPARAM dwParam2)
Definition: mciwave.c:700
#define CloseHandle
Definition: compat.h:487
static DWORD WAVE_mciPlay(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE hEvent)
Definition: mciwave.c:739
#define MCI_WAIT
Definition: mmsystem.h:730
GLuint GLuint GLsizei count
Definition: gl.h:1545
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
WORD nChannels
Definition: mmreg.h:79
#define WARN(fmt,...)
Definition: debug.h:112
DWORD dwDataOffset
Definition: mmsystem.h:1510
HMMIO hFile
Definition: mciwave.c:42
DWORD_PTR dwCallback
Definition: mmsystem.h:1537
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
LPSTR lpData
Definition: mmsystem.h:1014
GLuint GLuint end
Definition: gl.h:1545
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
Definition: mmio.c:835
#define MCI_NOTIFY_ABORTED
Definition: mmsystem.h:727
HANDLE hCallback
Definition: mciwave.c:44
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut, WAVEHDR *lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2280
static HANDLE hEvent
Definition: comm.c:54
DWORD dwLoops
Definition: mmsystem.h:1019
BOOL WINAPI mciDriverNotify(HWND hwndCallback, UINT uDeviceID, UINT uStatus)
Definition: mci.c:2056
volatile WORD dwStatus
Definition: mciwave.c:51
DWORD dwPosition
Definition: mciwave.c:53
#define WAVE_FORMAT_PCM
Definition: constants.h:425
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
#define CALLBACK_FUNCTION
Definition: mmsystem.h:150
DWORD dwFlags
Definition: mmsystem.h:1018
#define debugstr_w
Definition: kernel32.h:32
#define MCI_MODE_PLAY
Definition: mmsystem.h:696
smooth NULL
Definition: ftsmooth.c:416
static void WAVE_mciPlayWaitDone(WINE_MCIWAVE *wmw)
Definition: mciwave.c:723
BOOL fInput
Definition: mciwave.c:48
WORD wOutput
Definition: mciwave.c:50
#define MCI_NOTIFY_FAILURE
Definition: mmsystem.h:728
#define MCIERR_OUT_OF_MEMORY
Definition: mmsystem.h:574
#define SEEK_SET
Definition: jmemansi.c:26
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
LPWSTR lpFileName
Definition: mciwave.c:45
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define GetProcessHeap()
Definition: compat.h:484
LPWAVEFORMATEX lpWaveFormat
Definition: mciwave.c:47
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:1206
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint left
Definition: glext.h:7726
DWORD cksize
Definition: mmsystem.h:1508
UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2344
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
WORD wFormatTag
Definition: mmreg.h:78
static DWORD MCI_SendCommandAsync(UINT wDevID, async_cmd cmd, DWORD_PTR dwParam1, DWORD_PTR dwParam2, UINT size)
Definition: mciwave.c:99
static const WCHAR L[]
Definition: oid.c:1250
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
static WINE_MCIWAVE * WAVE_mciGetOpenDev(MCIDEVICEID wDevID)
Definition: mciwave.c:195
DWORD dwBufferLength
Definition: mmsystem.h:1015
#define MCIERR_INTERNAL
Definition: mmsystem.h:587
#define MCIERR_OUTOFRANGE
Definition: mmsystem.h:592
uint32_t DWORD_PTR
Definition: typedefs.h:65
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2310
#define ERR(fmt,...)
Definition: debug.h:110
MMCKINFO ckWaveData
Definition: mciwave.c:57
#define HWND_32(h16)
Definition: wownt32.h:29
static DWORD WAVE_mciStop(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:618
#define MCIERR_FILE_NOT_FOUND
Definition: mmsystem.h:585
#define MCI_MODE_NOT_READY
Definition: mmsystem.h:694
MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2249
#define min(a, b)
Definition: monoChain.cc:55
UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
Definition: winmm.c:2260
HANDLE hEvent
Definition: mciwave.c:54
HANDLE hWave
Definition: mciwave.c:40
DWORD_PTR dwUser
Definition: mmsystem.h:1017
UINT wDevID
Definition: mciwave.c:74
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nBlockAlign
Definition: mmreg.h:82
#define MCIERR_HARDWARE
Definition: mmsystem.h:572
WORD wBitsPerSample
Definition: mmreg.h:83
#define MCI_MODE_PAUSE
Definition: mmsystem.h:699
#define MCI_FROM
Definition: mmsystem.h:731
#define WHDR_DONE
Definition: mmsystem.h:193
#define MCIERR_DEVICE_OPEN
Definition: mmsystem.h:575
static DWORD WAVE_ConvertTimeFormatToByte(WINE_MCIWAVE *wmw, DWORD val)
Definition: mciwave.c:251
#define WAVE_ALIGN_ON_BLOCK(wmw, v)
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_NOTIFY
Definition: mmsystem.h:729
void cleanUp()
Definition: main.cpp:472
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605
LONG dwEventCount
Definition: mciwave.c:55
UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
Definition: winmm.c:2388
#define LOWORD(l)
Definition: pedump.c:82
#define HeapFree(x, y, z)
Definition: compat.h:483
#define MCI_TO
Definition: mmsystem.h:732
LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
Definition: mmio.c:732

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciPlayCallback()

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

Definition at line 700 of file mciwave.c.

703 {
704  WINE_MCIWAVE* wmw = (WINE_MCIWAVE*)dwInstance;
705 
706  switch (uMsg) {
707  case WOM_OPEN:
708  case WOM_CLOSE:
709  break;
710  case WOM_DONE:
712  TRACE("Returning waveHdr=%lx\n", dwParam1);
713  SetEvent(wmw->hEvent);
714  break;
715  default:
716  ERR("Unknown uMsg=%d\n", uMsg);
717  }
718 }
#define WOM_DONE
Definition: mmsystem.h:183
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
#define WOM_OPEN
Definition: mmsystem.h:181
#define WOM_CLOSE
Definition: mmsystem.h:182
#define TRACE(s)
Definition: solgame.cpp:4
#define ERR(fmt,...)
Definition: debug.h:110
#define InterlockedIncrement
Definition: armddk.h:53
DWORD_PTR dwParam1
Definition: mciwave.c:75
HANDLE hEvent
Definition: mciwave.c:54
LONG dwEventCount
Definition: mciwave.c:55

Referenced by WAVE_mciPlay().

◆ WAVE_mciPlayWaitDone()

static void WAVE_mciPlayWaitDone ( WINE_MCIWAVE wmw)
static

Definition at line 723 of file mciwave.c.

724 {
725  for (;;) {
726  ResetEvent(wmw->hEvent);
727  if (InterlockedDecrement(&wmw->dwEventCount) >= 0) {
728  break;
729  }
731 
733  }
734 }
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define InterlockedDecrement
Definition: armddk.h:52
#define InterlockedIncrement
Definition: armddk.h:53
HANDLE hEvent
Definition: mciwave.c:54
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
#define INFINITE
Definition: serial.h:102
LONG dwEventCount
Definition: mciwave.c:55

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=%08X\n",
288  (LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
289 
290  pwfx = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize);
291  if (!pwfx) return MCIERR_OUT_OF_MEMORY;
292 
293  r = mmioRead(wmw->hFile, (HPSTR)pwfx, mmckInfo.cksize);
294  if (r < sizeof(PCMWAVEFORMAT)) {
295  HeapFree(GetProcessHeap(), 0, pwfx);
296  return MCIERR_INVALID_FILE;
297  }
298  TRACE("wFormatTag=%04X !\n", pwfx->wFormatTag);
299  TRACE("nChannels=%d\n", pwfx->nChannels);
300  TRACE("nSamplesPerSec=%d\n", pwfx->nSamplesPerSec);
301  TRACE("nAvgBytesPerSec=%d\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  HeapFree(GetProcessHeap(), 0, 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=%08X\n",
321  return 0;
322 }
#define MCIERR_INVALID_FILE
Definition: mmsystem.h:604
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
MMRESULT WINAPI mmioAscend(HMMIO hmmio, LPMMCKINFO lpck, UINT uFlags)
Definition: mmio.c:1204
WORD nChannels
Definition: mmreg.h:79
HMMIO hFile
Definition: mciwave.c:42
char * LPSTR
Definition: xmlstorage.h:182
#define WAVE_FORMAT_PCM
Definition: constants.h:425
long LONG
Definition: pedump.c:60
#define MMIO_FINDCHUNK
Definition: mmsystem.h:551
FOURCC fccType
Definition: mmsystem.h:1509
#define MCIERR_OUT_OF_MEMORY
Definition: mmsystem.h:574
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:484
LPWAVEFORMATEX lpWaveFormat
Definition: mciwave.c:47
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD cksize
Definition: mmsystem.h:1508
WORD wFormatTag
Definition: mmreg.h:78
char * HPSTR
Definition: mmsystem.h:1477
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
MMCKINFO ckWaveData
Definition: mciwave.c:57
FOURCC ckid
Definition: mmsystem.h:1507
MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck, const MMCKINFO *lpckParent, UINT uFlags)
Definition: mmio.c:1106
WORD cbSize
Definition: mmreg.h:84
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nBlockAlign
Definition: mmreg.h:82
WORD wBitsPerSample
Definition: mmreg.h:83
#define HeapFree(x, y, z)
Definition: compat.h:483
LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
Definition: mmio.c:732

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 1000 of file mciwave.c.

1001 {
1002  LPMCI_RECORD_PARMS lpParms = (void*)pmt;
1003  DWORD end;
1004  DWORD dwRet = MMSYSERR_NOERROR;
1005  LONG bufsize;
1006  LPWAVEHDR waveHdr = NULL;
1008  HANDLE oldcb;
1009 
1010  TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
1011 
1012  if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
1013  if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1014 
1015  if (wmw->dwStatus == MCI_MODE_PAUSE && wmw->fInput) {
1016  /* FIXME: parameters (start/end) in lpParams may not be used */
1017  return WAVE_mciResume(wDevID, dwFlags, (LPMCI_GENERIC_PARMS)lpParms);
1018  }
1019 
1024  if ( !(wmw->dwStatus == MCI_MODE_STOP) &&
1025  !((wmw->dwStatus == MCI_MODE_RECORD) && (dwFlags & MCI_WAIT) && !wmw->hWave)) {
1026  return MCIERR_INTERNAL;
1027  }
1028 
1029  wmw->fInput = TRUE; /* FIXME: waveOutOpen may have been called. */
1030  wmw->dwStatus = MCI_MODE_RECORD;
1031 
1032  if (!(dwFlags & MCI_WAIT)) {
1034  (DWORD_PTR)lpParms, sizeof(MCI_RECORD_PARMS));
1035  }
1036 
1037  /* FIXME: we only re-create the RIFF structure from an existing file (if any)
1038  * we don't modify the wave part of an existing file (ie. we always erase an
1039  * existing content, we don't overwrite)
1040  */
1041  HeapFree(GetProcessHeap(), 0, wmw->lpFileName);
1042  dwRet = create_tmp_file(&wmw->hFile, (WCHAR**)&wmw->lpFileName);
1043  if (dwRet != 0) return dwRet;
1044 
1045  /* new RIFF file, lpWaveFormat now valid */
1046  dwRet = WAVE_mciCreateRIFFSkeleton(wmw);
1047  if (dwRet != 0) return dwRet;
1048 
1049  if (dwFlags & MCI_TO) {
1050  end = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwTo);
1051  } else end = 0xFFFFFFFF;
1052  if (dwFlags & MCI_FROM) {
1053  DWORD position = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwFrom);
1054  if (wmw->ckWaveData.cksize < position) return MCIERR_OUTOFRANGE;
1055  /* Seek rounds down, so do we. */
1056  position /= wmw->lpWaveFormat->nBlockAlign;
1057  position *= wmw->lpWaveFormat->nBlockAlign;
1058  wmw->dwPosition = position;
1059  }
1060  if (end==wmw->dwPosition) return MMSYSERR_NOERROR; /* FIXME: NOTIFY */
1061 
1062  TRACE("Recording from byte=%u to byte=%u\n", wmw->dwPosition, end);
1063 
1064  oldcb = InterlockedExchangePointer(&wmw->hCallback,
1065  (dwFlags & MCI_NOTIFY) ? HWND_32(LOWORD(lpParms->dwCallback)) : NULL);
1066  if (oldcb) mciDriverNotify(oldcb, wDevID, MCI_NOTIFY_ABORTED);
1067  oldcb = NULL;
1068 
1069 #define WAVE_ALIGN_ON_BLOCK(wmw,v) \
1070 ((((v) + (wmw)->lpWaveFormat->nBlockAlign - 1) / (wmw)->lpWaveFormat->nBlockAlign) * (wmw)->lpWaveFormat->nBlockAlign)
1071 
1073 
1074  /* Go back to the beginning of the chunk plus the requested position */
1075  /* FIXME: I'm not sure this is correct, notably because some data linked to
1076  * the decompression state machine will not be correctly initialized.
1077  * Try it this way (other way would be to decompress from 0 up to dwPosition
1078  * and to start sending to hWave when dwPosition is reached).
1079  */
1080  mmioSeek(wmw->hFile, wmw->ckWaveData.dwDataOffset + wmw->dwPosition, SEEK_SET); /* >= 0 */
1081 
1082  dwRet = waveInOpen((HWAVEIN*)&wmw->hWave, wmw->wInput, wmw->lpWaveFormat,
1084 
1085  if (dwRet != MMSYSERR_NOERROR) {
1086  TRACE("Can't open low level audio device %d\n", dwRet);
1087  dwRet = MCIERR_DEVICE_OPEN;
1088  wmw->hWave = 0;
1089  goto cleanUp;
1090  }
1091 
1092  /* make it so that 3 buffers per second are needed */
1094 
1095  waveHdr = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(WAVEHDR) + 2 * bufsize);
1096  waveHdr[0].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR);
1097  waveHdr[1].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR) + bufsize;
1098  waveHdr[0].dwUser = waveHdr[1].dwUser = 0L;
1099  waveHdr[0].dwLoops = waveHdr[1].dwLoops = 0L;
1100  waveHdr[0].dwFlags = waveHdr[1].dwFlags = 0L;
1101  waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize;
1102 
1103  if (waveInPrepareHeader(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
1104  waveInPrepareHeader(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR))) {
1105  dwRet = MCIERR_INTERNAL;
1106  goto cleanUp;
1107  }
1108 
1109  if (waveInAddBuffer(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
1110  waveInAddBuffer(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR))) {
1111  dwRet = MCIERR_INTERNAL;
1112  goto cleanUp;
1113  }
1114 
1115  wmw->hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
1116  wmw->dwEventCount = 1L; /* for first buffer */
1117 
1118  TRACE("Recording (normalized) from byte=%u for %u bytes\n", wmw->dwPosition, end - wmw->dwPosition);
1119 
1120  waveInStart(wmw->hWave);
1121 
1122  if (hEvent) SetEvent(hEvent);
1123 
1124  while (wmw->dwPosition < end && wmw->dwStatus != MCI_MODE_STOP && wmw->dwStatus != MCI_MODE_NOT_READY) {
1126  }
1127  /* Grab callback before another thread kicks in after we change dwStatus. */
1128  if (dwFlags & MCI_NOTIFY) {
1129  oldcb = InterlockedExchangePointer(&wmw->hCallback, NULL);
1130  dwFlags &= ~MCI_NOTIFY;
1131  }
1132  /* needed so that the callback above won't add again the buffers returned by the reset */
1133  wmw->dwStatus = MCI_MODE_STOP;
1134 
1135  waveInReset(wmw->hWave);
1136 
1137  waveInUnprepareHeader(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR));
1138  waveInUnprepareHeader(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR));
1139 
1140  dwRet = 0;
1141 
1142 cleanUp:
1143  if (dwFlags & MCI_NOTIFY)
1144  oldcb = InterlockedExchangePointer(&wmw->hCallback, NULL);
1145 
1146  HeapFree(GetProcessHeap(), 0, waveHdr);
1147 
1148  if (wmw->hWave) {
1149  waveInClose(wmw->hWave);
1150  wmw->hWave = 0;
1151  }
1152  CloseHandle(wmw->hEvent);
1153 
1154  wmw->dwStatus = MCI_MODE_STOP;
1155 
1156  if (oldcb) mciDriverNotify(oldcb, wDevID,
1158 
1159  return dwRet;
1160 
1161 }
#define MCI_MODE_STOP
Definition: mmsystem.h:695
UINT WINAPI waveInClose(HWAVEIN hWaveIn)
Definition: winmm.c:2637
#define CloseHandle
Definition: compat.h:487
#define MCI_WAIT
Definition: mmsystem.h:730
MMRESULT WINAPI waveInOpen(HWAVEIN *lphWaveIn, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2626
#define TRUE
Definition: types.h:120
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
DWORD dwDataOffset
Definition: mmsystem.h:1510
HMMIO hFile
Definition: mciwave.c:42
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
LPSTR lpData
Definition: mmsystem.h:1014
GLuint GLuint end
Definition: gl.h:1545
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
UINT WINAPI waveInPrepareHeader(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2656
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
Definition: mmio.c:835
#define MCI_NOTIFY_ABORTED
Definition: mmsystem.h:727
HANDLE hCallback
Definition: mciwave.c:44
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
static HANDLE hEvent
Definition: comm.c:54
DWORD dwLoops
Definition: mmsystem.h:1019
BOOL WINAPI mciDriverNotify(HWND hwndCallback, UINT uDeviceID, UINT uStatus)
Definition: mci.c:2056
volatile WORD dwStatus
Definition: mciwave.c:51
#define MCI_MODE_RECORD
Definition: mmsystem.h:697
DWORD dwPosition
Definition: mciwave.c:53
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
#define CALLBACK_FUNCTION
Definition: mmsystem.h:150
DWORD dwFlags
Definition: mmsystem.h:1018
UINT WINAPI waveInUnprepareHeader(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2687
smooth NULL
Definition: ftsmooth.c:416
BOOL fInput
Definition: mciwave.c:48
#define MCI_NOTIFY_FAILURE
Definition: mmsystem.h:728
#define SEEK_SET
Definition: jmemansi.c:26
static DWORD WAVE_mciCreateRIFFSkeleton(WINE_MCIWAVE *wmw)
Definition: mciwave.c:346
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
LPWSTR lpFileName
Definition: mciwave.c:45
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define GetProcessHeap()
Definition: compat.h:484
LPWAVEFORMATEX lpWaveFormat
Definition: mciwave.c:47
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
static DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:1206
WORD wInput
Definition: mciwave.c:49
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD cksize
Definition: mmsystem.h:1508
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
static DWORD MCI_SendCommandAsync(UINT wDevID, async_cmd cmd, DWORD_PTR dwParam1, DWORD_PTR dwParam2, UINT size)
Definition: mciwave.c:99
static DWORD WAVE_mciRecord(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE hEvent)
Definition: mciwave.c:1000
static const WCHAR L[]
Definition: oid.c:1250
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
UINT WINAPI waveInAddBuffer(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2720
static WINE_MCIWAVE * WAVE_mciGetOpenDev(MCIDEVICEID wDevID)
Definition: mciwave.c:195
DWORD dwBufferLength
Definition: mmsystem.h:1015
#define MCIERR_INTERNAL
Definition: mmsystem.h:587
#define MCIERR_OUTOFRANGE
Definition: mmsystem.h:592
static void WAVE_mciRecordWaitDone(WINE_MCIWAVE *wmw)
Definition: mciwave.c:984
uint32_t DWORD_PTR
Definition: typedefs.h:65
static void CALLBACK WAVE_mciRecordCallback(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, LPARAM dwParam1, LPARAM dwParam2)
Definition: mciwave.c:941
UINT WINAPI waveInStart(HWAVEIN hWaveIn)
Definition: winmm.c:2752
UINT WINAPI waveInReset(HWAVEIN hWaveIn)
Definition: winmm.c:2737
MMCKINFO ckWaveData
Definition: mciwave.c:57
#define HWND_32(h16)
Definition: wownt32.h:29
#define MCI_MODE_NOT_READY
Definition: mmsystem.h:694
static DWORD create_tmp_file(HMMIO *hFile, LPWSTR *pszTmpFileName)
Definition: mciwave.c:418
HANDLE hEvent
Definition: mciwave.c:54
HANDLE hWave
Definition: mciwave.c:40
DWORD_PTR dwUser
Definition: mmsystem.h:1017
UINT wDevID
Definition: mciwave.c:74
WORD nBlockAlign
Definition: mmreg.h:82
DWORD_PTR dwCallback
Definition: mmsystem.h:1639
#define MCI_MODE_PAUSE
Definition: mmsystem.h:699
#define MCI_FROM
Definition: mmsystem.h:731
#define MCIERR_DEVICE_OPEN
Definition: mmsystem.h:575
static DWORD WAVE_ConvertTimeFormatToByte(WINE_MCIWAVE *wmw, DWORD val)
Definition: mciwave.c:251
#define WAVE_ALIGN_ON_BLOCK(wmw, v)
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_NOTIFY
Definition: mmsystem.h:729
void cleanUp()
Definition: main.cpp:472
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605
LONG dwEventCount
Definition: mciwave.c:55
#define LOWORD(l)
Definition: pedump.c:82
#define HeapFree(x, y, z)
Definition: compat.h:483
#define MCI_TO
Definition: mmsystem.h:732

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciRecordCallback()

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

Definition at line 941 of file mciwave.c.

944 {
945  WINE_MCIWAVE* wmw = (WINE_MCIWAVE*)dwInstance;
946  LPWAVEHDR lpWaveHdr;
947  LONG count = 0;
948 
949  switch (uMsg) {
950  case WIM_OPEN:
951  case WIM_CLOSE:
952  break;
953  case WIM_DATA:
954  lpWaveHdr = (LPWAVEHDR) dwParam1;
955 
957 
958  count = mmioWrite(wmw->hFile, lpWaveHdr->lpData, lpWaveHdr->dwBytesRecorded);
959 
960  lpWaveHdr->dwFlags &= ~WHDR_DONE;
961  if (count > 0)
962  wmw->dwPosition += count;
963  /* else error reporting ?? */
964  if (wmw->dwStatus == MCI_MODE_RECORD)
965  {
966  /* Only queue up another buffer if we are recording. We could receive this
967  message also when waveInReset() is called, since it notifies on all wave
968  buffers that are outstanding. Queueing up more sometimes causes waveInClose
969  to fail. */
970  waveInAddBuffer(wmw->hWave, lpWaveHdr, sizeof(*lpWaveHdr));
971  TRACE("after mmioWrite dwPosition=%u\n", wmw->dwPosition);
972  }
973 
974  SetEvent(wmw->hEvent);
975  break;
976  default:
977  ERR("Unknown uMsg=%d\n", uMsg);
978  }
979 }
struct wavehdr_tag * LPWAVEHDR
GLuint GLuint GLsizei count
Definition: gl.h:1545
HMMIO hFile
Definition: mciwave.c:42
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
LPSTR lpData
Definition: mmsystem.h:1014
volatile WORD dwStatus
Definition: mciwave.c:51
#define MCI_MODE_RECORD
Definition: mmsystem.h:697
DWORD dwPosition
Definition: mciwave.c:53
#define WIM_CLOSE
Definition: mmsystem.h:185
long LONG
Definition: pedump.c:60
DWORD dwFlags
Definition: mmsystem.h:1018
LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
Definition: mmio.c:781
#define WIM_OPEN
Definition: mmsystem.h:184
#define TRACE(s)
Definition: solgame.cpp:4
UINT WINAPI waveInAddBuffer(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2720
#define ERR(fmt,...)
Definition: debug.h:110
#define InterlockedIncrement
Definition: armddk.h:53
DWORD_PTR dwParam1
Definition: mciwave.c:75
HANDLE hEvent
Definition: mciwave.c:54
HANDLE hWave
Definition: mciwave.c:40
#define WHDR_DONE
Definition: mmsystem.h:193
#define WIM_DATA
Definition: mmsystem.h:186
LONG dwEventCount
Definition: mciwave.c:55
DWORD dwBytesRecorded
Definition: mmsystem.h:1016

Referenced by WAVE_mciRecord().

◆ WAVE_mciRecordWaitDone()

static void WAVE_mciRecordWaitDone ( WINE_MCIWAVE wmw)
static

Definition at line 984 of file mciwave.c.

985 {
986  for (;;) {
987  ResetEvent(wmw->hEvent);
988  if (InterlockedDecrement(&wmw->dwEventCount) >= 0) {
989  break;
990  }
992 
994  }
995 }
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define InterlockedDecrement
Definition: armddk.h:52
#define InterlockedIncrement
Definition: armddk.h:53
HANDLE hEvent
Definition: mciwave.c:54
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
#define INFINITE
Definition: serial.h:102
LONG dwEventCount
Definition: mciwave.c:55

Referenced by WAVE_mciRecord().

◆ WAVE_mciResume()

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

Definition at line 1206 of file mciwave.c.

1207 {
1209  DWORD dwRet;
1210 
1211  TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);
1212 
1213  if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
1214 
1215  switch (wmw->dwStatus) {
1216  case MCI_MODE_PAUSE:
1217  /* Only update dwStatus if wave* succeeds and will exchange buffers buffers. */
1218  if (wmw->fInput) {
1219  dwRet = waveInStart(wmw->hWave);
1220  if (dwRet==MMSYSERR_NOERROR) wmw->dwStatus = MCI_MODE_RECORD;
1221  else {
1222  ERR("waveInStart error %d\n",dwRet);
1223  dwRet = MCIERR_INTERNAL;
1224  }
1225  } else {
1226  dwRet = waveOutRestart(wmw->hWave);
1227  if (dwRet==MMSYSERR_NOERROR) wmw->dwStatus = MCI_MODE_PLAY;
1228  else {
1229  ERR("waveOutRestart error %d\n",dwRet);
1230  dwRet = MCIERR_INTERNAL;
1231  }
1232  }
1233  break;
1234  case MCI_MODE_PLAY:
1235  case MCI_MODE_RECORD:
1236  dwRet = MMSYSERR_NOERROR;
1237  break;
1238  default:
1240  }
1241  if (MMSYSERR_NOERROR==dwRet && (dwFlags & MCI_NOTIFY) && lpParms)
1243  return dwRet;
1244 }
#define MCIERR_NONAPPLICABLE_FUNCTION
Definition: mmsystem.h:610
static void WAVE_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIWAVE *wmw, UINT wStatus)
Definition: mciwave.c:213
volatile WORD dwStatus
Definition: mciwave.c:51
#define MCI_MODE_RECORD
Definition: mmsystem.h:697
#define MCI_MODE_PLAY
Definition: mmsystem.h:696
smooth NULL
Definition: ftsmooth.c:416
BOOL fInput
Definition: mciwave.c:48
#define TRACE(s)
Definition: solgame.cpp:4
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
static WINE_MCIWAVE * WAVE_mciGetOpenDev(MCIDEVICEID wDevID)
Definition: mciwave.c:195
#define MCIERR_INTERNAL
Definition: mmsystem.h:587
UINT WINAPI waveInStart(HWAVEIN hWaveIn)
Definition: winmm.c:2752
#define ERR(fmt,...)
Definition: debug.h:110
DWORD_PTR dwCallback
Definition: mmsystem.h:1517
HANDLE hWave
Definition: mciwave.c:40
UINT wDevID
Definition: mciwave.c:74
UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
Definition: winmm.c:2402
#define MCI_MODE_PAUSE
Definition: mmsystem.h:699
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_NOTIFY
Definition: mmsystem.h:729

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 1419 of file mciwave.c.

1420 {
1422  DWORD ret = MCIERR_FILE_NOT_SAVED, tmpRet;
1423 
1424  TRACE("%d, %08X, %p);\n", wDevID, dwFlags, lpParms);
1425  if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1426  if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
1427 
1428  if (dwFlags & MCI_WAIT)
1429  {
1430  FIXME("MCI_WAIT not implemented\n");
1431  }
1432  WAVE_mciStop(wDevID, 0, NULL);
1433 
1434  ret = mmioAscend(wmw->hFile, &wmw->ckWaveData, 0);
1435  ret = mmioAscend(wmw->hFile, &wmw->ckMainRIFF, 0);
1436 
1437  ret = mmioClose(wmw->hFile, 0);
1438  wmw->hFile = 0;
1439 
1440  /*
1441  If the destination file already exists, it has to be overwritten. (Behaviour
1442  verified in Windows (2000)). If it doesn't overwrite, it is breaking one of
1443  my applications. We are making use of mmioRename, which WILL NOT overwrite
1444  the destination file (which is what Windows does, also verified in Win2K)
1445  So, lets delete the destination file before calling mmioRename. If the
1446  destination file DOESN'T exist, the delete will fail silently. Let's also be
1447  careful not to lose our previous error code.
1448  */
1449  tmpRet = GetLastError();
1450  DeleteFileW (lpParms->lpfilename);
1451  SetLastError(tmpRet);
1452 
1453  /* FIXME: Open file.wav; Save; must not rename the original file.
1454  * Nor must Save a.wav; Save b.wav rename a. */
1455  if (0 == mmioRenameW(wmw->lpFileName, lpParms->lpfilename, 0, 0 )) {
1457  }
1458 
1459  if (MMSYSERR_NOERROR==ret && (dwFlags & MCI_NOTIFY))
1461 
1462  if (ret == MMSYSERR_NOERROR)
1463  ret = WAVE_mciOpenFile(wmw, lpParms->lpfilename);
1464 
1465  return ret;
1466 }
#define MCI_WAIT
Definition: mmsystem.h:730
DWORD_PTR dwCallback
Definition: mmsystem.h:1624
static void WAVE_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIWAVE *wmw, UINT wStatus)
Definition: mciwave.c:213
LPCWSTR lpfilename
Definition: mmsystem.h:1625
MMRESULT WINAPI mmioAscend(HMMIO hmmio, LPMMCKINFO lpck, UINT uFlags)
Definition: mmio.c:1204
HMMIO hFile
Definition: mciwave.c:42
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
Definition: mmio.c:701
static LRESULT WAVE_mciOpenFile(WINE_MCIWAVE *wmw, LPCWSTR filename)
Definition: mciwave.c:461
#define MCIERR_FILE_NOT_SAVED
Definition: mmsystem.h:594
#define FIXME(fmt,...)
Definition: debug.h:111
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
smooth NULL
Definition: ftsmooth.c:416
#define TRACE(s)
Definition: solgame.cpp:4
LPWSTR lpFileName
Definition: mciwave.c:45
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:500
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
int ret
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
static WINE_MCIWAVE * WAVE_mciGetOpenDev(MCIDEVICEID wDevID)
Definition: mciwave.c:195
MMCKINFO ckWaveData
Definition: mciwave.c:57
static DWORD WAVE_mciStop(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:618
MMCKINFO ckMainRIFF
Definition: mciwave.c:56
UINT wDevID
Definition: mciwave.c:74
MMRESULT WINAPI mmioRenameW(LPCWSTR szFileName, LPCWSTR szNewFileName, const MMIOINFO *lpmmioinfo, DWORD dwFlags)
Definition: mmio.c:1319
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciSeek()

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

Definition at line 1249 of file mciwave.c.

1250 {
1252  DWORD position, dwRet;
1253 
1254  TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms);
1255 
1256  if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1257  if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
1258 
1260  if (!position) return MCIERR_MISSING_PARAMETER;
1261  if (position&(position-1)) return MCIERR_FLAGS_NOT_COMPATIBLE;
1262 
1263  /* Stop sends MCI_NOTIFY_ABORTED when needed */
1264  dwRet = WAVE_mciStop(wDevID, MCI_WAIT, 0);
1265  if (dwRet != MMSYSERR_NOERROR) return dwRet;
1266 
1267  if (dwFlags & MCI_TO) {
1268  position = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwTo);
1269  if (position > wmw->ckWaveData.cksize)
1270  return MCIERR_OUTOFRANGE;
1271  } else if (dwFlags & MCI_SEEK_TO_START) {
1272  position = 0;
1273  } else {
1274  position = wmw->ckWaveData.cksize;
1275  }
1276  /* Seek rounds down, unless at end */
1277  if (position != wmw->ckWaveData.cksize) {
1278  position /= wmw->lpWaveFormat->nBlockAlign;
1279  position *= wmw->lpWaveFormat->nBlockAlign;
1280  }
1281  wmw->dwPosition = position;
1282  TRACE("Seeking to position=%u bytes\n", position);
1283 
1284  if (dwFlags & MCI_NOTIFY)
1286 
1287  return MMSYSERR_NOERROR;
1288 }
#define MCI_WAIT
Definition: mmsystem.h:730
static void WAVE_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIWAVE *wmw, UINT wStatus)
Definition: mciwave.c:213
DWORD dwPosition
Definition: mciwave.c:53
#define MCIERR_FLAGS_NOT_COMPATIBLE
Definition: mmsystem.h:593
smooth NULL
Definition: ftsmooth.c:416
#define MCIERR_MISSING_PARAMETER
Definition: mmsystem.h:583
#define TRACE(s)
Definition: solgame.cpp:4
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
LPWAVEFORMATEX lpWaveFormat
Definition: mciwave.c:47
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD cksize
Definition: mmsystem.h:1508
DWORD_PTR dwCallback
Definition: mmsystem.h:1543
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
static WINE_MCIWAVE * WAVE_mciGetOpenDev(MCIDEVICEID wDevID)
Definition: mciwave.c:195
#define MCI_SEEK_TO_END
Definition: mmsystem.h:741
#define MCIERR_OUTOFRANGE
Definition: mmsystem.h:592
#define MCI_SEEK_TO_START
Definition: mmsystem.h:740
MMCKINFO ckWaveData
Definition: mciwave.c:57
static DWORD WAVE_mciStop(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:618
UINT wDevID
Definition: mciwave.c:74
WORD nBlockAlign
Definition: mmreg.h:82
static DWORD WAVE_ConvertTimeFormatToByte(WINE_MCIWAVE *wmw, DWORD val)
Definition: mciwave.c:251
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605
#define MCI_TO
Definition: mmsystem.h:732

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciSet()

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

Definition at line 1293 of file mciwave.c.

1294 {
1296 
1297  TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);
1298 
1299  if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1300  if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
1301 
1302  if (dwFlags & MCI_SET_TIME_FORMAT) {
1303  switch (lpParms->dwTimeFormat) {
1305  TRACE("MCI_FORMAT_MILLISECONDS !\n");
1307  break;
1308  case MCI_FORMAT_BYTES:
1309  TRACE("MCI_FORMAT_BYTES !\n");
1311  break;
1312  case MCI_FORMAT_SAMPLES:
1313  TRACE("MCI_FORMAT_SAMPLES !\n");
1315  break;
1316  default:
1317  WARN("Bad time format %u!\n", lpParms->dwTimeFormat);
1318  return MCIERR_BAD_TIME_FORMAT;
1319  }
1320  }
1321  if (dwFlags & MCI_SET_VIDEO) {
1322  TRACE("No support for video !\n");
1324  }
1325  if (dwFlags & MCI_SET_DOOR_OPEN) {
1326  TRACE("No support for door open !\n");
1328  }
1329  if (dwFlags & MCI_SET_DOOR_CLOSED) {
1330  TRACE("No support for door close !\n");
1332  }
1333  if (dwFlags & MCI_SET_AUDIO) {
1334  if (dwFlags & MCI_SET_ON) {
1335  TRACE("MCI_SET_ON audio !\n");
1336  } else if (dwFlags & MCI_SET_OFF) {
1337  TRACE("MCI_SET_OFF audio !\n");
1338  } else {
1339  WARN("MCI_SET_AUDIO without SET_ON or SET_OFF\n");
1340  return MCIERR_BAD_INTEGER;
1341  }
1342 
1343  switch (lpParms->dwAudio)
1344  {
1345  case MCI_SET_AUDIO_ALL: TRACE("MCI_SET_AUDIO_ALL !\n"); break;
1346  case MCI_SET_AUDIO_LEFT: TRACE("MCI_SET_AUDIO_LEFT !\n"); break;
1347  case MCI_SET_AUDIO_RIGHT: TRACE("MCI_SET_AUDIO_RIGHT !\n"); break;
1348  default: WARN("Unknown audio channel %u\n", lpParms->dwAudio); break;
1349  }
1350  }
1351  if (dwFlags & MCI_WAVE_INPUT) {
1352  TRACE("MCI_WAVE_INPUT = %d\n", lpParms->wInput);
1353  if (lpParms->wInput >= waveInGetNumDevs())
1354  return MCIERR_OUTOFRANGE;
1355  if (wmw->wInput != (WORD)lpParms->wInput)
1357  wmw->wInput = lpParms->wInput;
1358  }
1359  if (dwFlags & MCI_WAVE_OUTPUT) {
1360  TRACE("MCI_WAVE_OUTPUT = %d\n", lpParms->wOutput);
1361  if (lpParms->wOutput >= waveOutGetNumDevs())
1362  return MCIERR_OUTOFRANGE;
1363  if (wmw->wOutput != (WORD)lpParms->wOutput)
1365  wmw->wOutput = lpParms->wOutput;
1366  }
1368  TRACE("MCI_WAVE_SET_ANYINPUT\n");
1369  if (wmw->wInput != (WORD)lpParms->wInput)
1371  wmw->wInput = WAVE_MAPPER;
1372  }
1374  TRACE("MCI_WAVE_SET_ANYOUTPUT\n");
1375  if (wmw->wOutput != (WORD)lpParms->wOutput)
1377  wmw->wOutput = WAVE_MAPPER;
1378  }
1379  /* Set wave format parameters is refused after Open or Record.*/
1381  TRACE("MCI_WAVE_SET_FORMATTAG = %d\n", lpParms->wFormatTag);
1382  if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
1383  if (lpParms->wFormatTag != WAVE_FORMAT_PCM)
1384  return MCIERR_OUTOFRANGE;
1385  }
1387  if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
1388  wmw->wfxRef.nAvgBytesPerSec = lpParms->nAvgBytesPerSec;
1389  TRACE("MCI_WAVE_SET_AVGBYTESPERSEC = %d\n", wmw->wfxRef.nAvgBytesPerSec);
1390  }
1392  if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
1393  wmw->wfxRef.wBitsPerSample = lpParms->wBitsPerSample;
1394  TRACE("MCI_WAVE_SET_BITSPERSAMPLE = %d\n", wmw->wfxRef.wBitsPerSample);
1395  }
1397  if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
1398  wmw->wfxRef.nBlockAlign = lpParms->nBlockAlign;
1399  TRACE("MCI_WAVE_SET_BLOCKALIGN = %d\n", wmw->wfxRef.nBlockAlign);
1400  }
1402  if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
1403  wmw->wfxRef.nChannels = lpParms->nChannels;
1404  TRACE("MCI_WAVE_SET_CHANNELS = %d\n", wmw->wfxRef.nChannels);
1405  }
1407  if (wmw->lpWaveFormat != &wmw->wfxRef) return MCIERR_NONAPPLICABLE_FUNCTION;
1408  wmw->wfxRef.nSamplesPerSec = lpParms->nSamplesPerSec;
1409  TRACE("MCI_WAVE_SET_SAMPLESPERSEC = %d\n", wmw->wfxRef.nSamplesPerSec);
1410  }
1411  if (dwFlags & MCI_NOTIFY)
1413  return 0;
1414 }
#define MCI_FORMAT_SAMPLES
Definition: mmsystem.h:710
#define MCIERR_NONAPPLICABLE_FUNCTION
Definition: mmsystem.h:610
DWORD_PTR dwCallback
Definition: mmsystem.h:1691
#define MCI_WAVE_SET_CHANNELS
Definition: mmsystem.h:823
#define MCI_WAIT
Definition: mmsystem.h:730
static void WAVE_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIWAVE *wmw, UINT wStatus)
Definition: mciwave.c:213
#define MCI_WAVE_INPUT
Definition: mmsystem.h:828
#define MCIERR_UNSUPPORTED_FUNCTION
Definition: mmsystem.h:584
#define WARN(fmt,...)
Definition: debug.h:112
#define MCI_SET_OFF
Definition: mmsystem.h:778
#define MCI_WAVE_SET_FORMATTAG
Definition: mmsystem.h:822
#define MCI_SET_AUDIO
Definition: mmsystem.h:775
#define MCI_SET_DOOR_CLOSED
Definition: mmsystem.h:773
#define WAVE_FORMAT_PCM
Definition: constants.h:425
#define MCI_FORMAT_MILLISECONDS
Definition: mmsystem.h:701
WAVEFORMATEX wfxRef
Definition: mciwave.c:46
WORD wBitsPerSample
Definition: audioclient.idl:45
#define MCI_WAVE_SET_SAMPLESPERSEC
Definition: mmsystem.h:824
#define MCI_WAVE_OUTPUT
Definition: mmsystem.h:829
smooth NULL
Definition: ftsmooth.c:416
#define MCI_WAVE_SET_ANYOUTPUT
Definition: mmsystem.h:838
UINT WINAPI waveOutGetNumDevs(void)
Definition: winmm.c:2140
WORD wOutput
Definition: mciwave.c:50
DWORD nSamplesPerSec
Definition: audioclient.idl:42
#define TRACE(s)
Definition: solgame.cpp:4
#define MCI_SET_ON
Definition: mmsystem.h:777
#define WAVE_MAPPER
Definition: mmsystem.h:187
LPWAVEFORMATEX lpWaveFormat
Definition: mciwave.c:47
#define MCIERR_BAD_INTEGER
Definition: mmsystem.h:580
#define MCI_SET_TIME_FORMAT
Definition: mmsystem.h:774
#define MCI_SET_AUDIO_LEFT
Definition: mmsystem.h:780
#define MCIERR_BAD_TIME_FORMAT
Definition: mmsystem.h:601
WORD wInput
Definition: mciwave.c:49
unsigned short WORD
Definition: ntddk_ex.h:93
#define MCI_WAVE_SET_AVGBYTESPERSEC
Definition: mmsystem.h:825
#define MCI_WAVE_SET_ANYINPUT
Definition: mmsystem.h:837
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
#define MCI_SET_AUDIO_RIGHT
Definition: mmsystem.h:781
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
static WINE_MCIWAVE * WAVE_mciGetOpenDev(MCIDEVICEID wDevID)
Definition: mciwave.c:195
#define MCIERR_OUTOFRANGE
Definition: mmsystem.h:592
static DWORD WAVE_mciStop(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:618
#define MCI_WAVE_SET_BITSPERSAMPLE
Definition: mmsystem.h:827
#define MCI_SET_VIDEO
Definition: mmsystem.h:776
DWORD nAvgBytesPerSec
Definition: audioclient.idl:43
UINT wDevID
Definition: mciwave.c:74
DWORD dwMciTimeFormat
Definition: mciwave.c:52
UINT WINAPI waveInGetNumDevs(void)
Definition: winmm.c:2568
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_SET_AUDIO_ALL
Definition: mmsystem.h:779
#define MCI_FORMAT_BYTES
Definition: mmsystem.h:709
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605
#define MCI_WAVE_SET_BLOCKALIGN
Definition: mmsystem.h:826
#define MCI_SET_DOOR_OPEN
Definition: mmsystem.h:772

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciStatus()

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

Definition at line 1471 of file mciwave.c.

1472 {
1474  DWORD ret = 0;
1475 
1476  TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);
1477  if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1478  if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
1480 
1481  if (dwFlags & MCI_STATUS_ITEM) {
1482  switch (lpParms->dwItem) {
1484  lpParms->dwReturn = 1;
1485  TRACE("MCI_STATUS_CURRENT_TRACK => %lu\n", lpParms->dwReturn);
1486  break;
1487  case MCI_STATUS_LENGTH:
1488  if (!wmw->hFile) {
1489  lpParms->dwReturn = 0;
1491  }
1492  /* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
1494  TRACE("MCI_STATUS_LENGTH => %lu\n", lpParms->dwReturn);
1495  break;
1496  case MCI_STATUS_MODE:
1497  TRACE("MCI_STATUS_MODE => %u\n", wmw->dwStatus);
1498  lpParms->dwReturn = MAKEMCIRESOURCE(wmw->dwStatus, wmw->dwStatus);
1500  break;
1502  TRACE("MCI_STATUS_MEDIA_PRESENT => TRUE!\n");
1503  lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
1505  break;
1507  /* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
1508  lpParms->dwReturn = 1;
1509  TRACE("MCI_STATUS_NUMBER_OF_TRACKS => %lu\n", lpParms->dwReturn);
1510  break;
1511  case MCI_STATUS_POSITION:
1512  if (!wmw->hFile) {
1513  lpParms->dwReturn = 0;
1515  }
1516  /* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
1517  lpParms->dwReturn = WAVE_ConvertByteToTimeFormat(wmw,
1518  (dwFlags & MCI_STATUS_START) ? 0 : wmw->dwPosition);
1519  TRACE("MCI_STATUS_POSITION %s => %lu\n",
1520  (dwFlags & MCI_STATUS_START) ? "start" : "current", lpParms->dwReturn);
1521  break;
1522  case MCI_STATUS_READY:
1523  lpParms->dwReturn = (wmw->dwStatus == MCI_MODE_NOT_READY) ?
1525  TRACE("MCI_STATUS_READY => %u!\n", LOWORD(lpParms->dwReturn));
1527  break;
1530  TRACE("MCI_STATUS_TIME_FORMAT => %lu\n", lpParms->dwReturn);
1532  break;
1533  case MCI_WAVE_INPUT:
1534  if (wmw->wInput != (WORD)WAVE_MAPPER)
1535  lpParms->dwReturn = wmw->wInput;
1536  else {
1539  }
1540  TRACE("MCI_WAVE_INPUT => %d\n", (signed)wmw->wInput);
1541  break;
1542  case MCI_WAVE_OUTPUT:
1543  if (wmw->wOutput != (WORD)WAVE_MAPPER)
1544  lpParms->dwReturn = wmw->wOutput;
1545  else {
1548  }
1549  TRACE("MCI_WAVE_OUTPUT => %d\n", (signed)wmw->wOutput);
1550  break;
1551  /* It is always ok to query wave format parameters,
1552  * except on auto-open yield MCIERR_UNSUPPORTED_FUNCTION. */
1555  lpParms->dwReturn = wmw->lpWaveFormat->wFormatTag;
1556  else {
1559  }
1560  TRACE("MCI_WAVE_FORMATTAG => %lu\n", lpParms->dwReturn);
1561  break;
1563  lpParms->dwReturn = wmw->lpWaveFormat->nAvgBytesPerSec;
1564  TRACE("MCI_WAVE_STATUS_AVGBYTESPERSEC => %lu\n", lpParms->dwReturn);
1565  break;
1567  lpParms->dwReturn = wmw->lpWaveFormat->wBitsPerSample;
1568  TRACE("MCI_WAVE_STATUS_BITSPERSAMPLE => %lu\n", lpParms->dwReturn);
1569  break;
1571  lpParms->dwReturn = wmw->lpWaveFormat->nBlockAlign;
1572  TRACE("MCI_WAVE_STATUS_BLOCKALIGN => %lu\n", lpParms->dwReturn);
1573  break;
1575  lpParms->dwReturn = wmw->lpWaveFormat->nChannels;
1576  TRACE("MCI_WAVE_STATUS_CHANNELS => %lu\n", lpParms->dwReturn);
1577  break;
1579  lpParms->dwReturn = wmw->lpWaveFormat->nSamplesPerSec;
1580  TRACE("MCI_WAVE_STATUS_SAMPLESPERSEC => %lu\n", lpParms->dwReturn);
1581  break;
1582  case MCI_WAVE_STATUS_LEVEL:
1583  TRACE("MCI_WAVE_STATUS_LEVEL !\n");
1584  lpParms->dwReturn = 0xAAAA5555;
1585  break;
1586  default:
1587  WARN("unknown command %08X !\n", lpParms->dwItem);
1589  }
1590  }
1591  if ((dwFlags & MCI_NOTIFY) && HRESULT_CODE(ret)==0)
1593  return ret;
1594 }
#define WAVE_FORMAT_PCM_S
Definition: mmddk.h:358
#define MCI_WAVE_STATUS_BITSPERSAMPLE
Definition: mmsystem.h:835
#define MCI_WAVE_STATUS_SAMPLESPERSEC
Definition: mmsystem.h:832
#define MCI_STATUS_ITEM
Definition: mmsystem.h:742
static void WAVE_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIWAVE *wmw, UINT wStatus)
Definition: mciwave.c:213
#define TRUE
Definition: types.h:120
#define MCI_WAVE_INPUT
Definition: mmsystem.h:828
#define MCI_STATUS_NUMBER_OF_TRACKS
Definition: mmsystem.h:746
#define MCI_WAVE_STATUS_CHANNELS
Definition: mmsystem.h:831
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
WORD nChannels
Definition: mmreg.h:79
#define MCIERR_UNSUPPORTED_FUNCTION
Definition: mmsystem.h:584
#define WARN(fmt,...)
Definition: debug.h:112
HMMIO hFile
Definition: mciwave.c:42
#define WAVE_MAPPER_S
Definition: mmddk.h:359
static DWORD WAVE_ConvertByteToTimeFormat(WINE_MCIWAVE *wmw, DWORD val)
Definition: mciwave.c:227
#define MCI_WAVE_STATUS_FORMATTAG
Definition: mmsystem.h:830
#define MCI_WAVE_STATUS_BLOCKALIGN
Definition: mmsystem.h:834
#define MCI_RESOURCE_RETURNED
Definition: mmddk.h:369
#define MAKEMCIRESOURCE(wRet, wRes)
Definition: mmddk.h:388
#define MCI_STATUS_POSITION
Definition: mmsystem.h:745
DWORD_PTR dwReturn
Definition: mmsystem.h:1567
volatile WORD dwStatus
Definition: mciwave.c:51
DWORD dwPosition
Definition: mciwave.c:53
#define WAVE_FORMAT_PCM
Definition: constants.h:425
#define FALSE
Definition: types.h:117
#define MCI_WAVE_STATUS_LEVEL
Definition: mmsystem.h:836
#define MCI_WAVE_OUTPUT
Definition: mmsystem.h:829
smooth NULL
Definition: ftsmooth.c:416
#define MCIERR_MISSING_PARAMETER
Definition: mmsystem.h:583
WORD wOutput
Definition: mciwave.c:50
#define TRACE(s)
Definition: solgame.cpp:4
#define WAVE_MAPPER
Definition: mmsystem.h:187
LPWAVEFORMATEX lpWaveFormat
Definition: mciwave.c:47
#define MCI_STATUS_LENGTH
Definition: mmsystem.h:744
WORD wInput
Definition: mciwave.c:49
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD cksize
Definition: mmsystem.h:1508
#define MCI_STATUS_MODE
Definition: mmsystem.h:747
#define MCI_STATUS_START
Definition: mmsystem.h:743
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
WORD wFormatTag
Definition: mmreg.h:78
int ret
#define MCI_WAVE_STATUS_AVGBYTESPERSEC
Definition: mmsystem.h:833
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
static WINE_MCIWAVE * WAVE_mciGetOpenDev(MCIDEVICEID wDevID)
Definition: mciwave.c:195
#define MCI_STATUS_CURRENT_TRACK
Definition: mmsystem.h:751
#define MCI_FALSE
Definition: mmddk.h:340
DWORD_PTR dwCallback
Definition: mmsystem.h:1566
MMCKINFO ckWaveData
Definition: mciwave.c:57
#define MCI_MODE_NOT_READY
Definition: mmsystem.h:694
#define MCI_TRUE
Definition: mmddk.h:341
UINT wDevID
Definition: mciwave.c:74
DWORD dwMciTimeFormat
Definition: mciwave.c:52
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nBlockAlign
Definition: mmreg.h:82
#define HRESULT_CODE(hr)
Definition: winerror.h:76
WORD wBitsPerSample
Definition: mmreg.h:83
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_STATUS_TIME_FORMAT
Definition: mmsystem.h:749
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define MCI_STATUS_MEDIA_PRESENT
Definition: mmsystem.h:748
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605
#define LOWORD(l)
Definition: pedump.c:82
#define MCI_FORMAT_RETURN_BASE
Definition: mmddk.h:343
#define MCI_STATUS_READY
Definition: mmsystem.h:750

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciStop()

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

Definition at line 618 of file mciwave.c.

619 {
620  DWORD dwRet = 0;
622 
623  TRACE("(%u, %08X, %p);\n", wDevID, dwFlags, lpParms);
624 
625  if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
626 
627  if (wmw->dwStatus != MCI_MODE_STOP) {
629  if (old) mciDriverNotify(old, wDevID, MCI_NOTIFY_ABORTED);
630  }
631 
632  /* wait for playback thread (if any) to exit before processing further */
633  switch (wmw->dwStatus) {
634  case MCI_MODE_PAUSE:
635  case MCI_MODE_PLAY:
636  case MCI_MODE_RECORD:
637  {
638  int oldStat = wmw->dwStatus;
640  if (oldStat == MCI_MODE_PAUSE)
641  dwRet = (wmw->fInput) ? waveInReset(wmw->hWave) : waveOutReset(wmw->hWave);
642  }
643  while (wmw->dwStatus != MCI_MODE_STOP)
644  Sleep(10);
645  break;
646  }
647 
648  /* sanity resets */
649  wmw->dwStatus = MCI_MODE_STOP;
650 
651  if ((dwFlags & MCI_NOTIFY) && lpParms && MMSYSERR_NOERROR==dwRet)
653 
654  return dwRet;
655 }
#define MCI_MODE_STOP
Definition: mmsystem.h:695
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
static void WAVE_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIWAVE *wmw, UINT wStatus)
Definition: mciwave.c:213
#define MCI_NOTIFY_ABORTED
Definition: mmsystem.h:727
HANDLE hCallback
Definition: mciwave.c:44
BOOL WINAPI mciDriverNotify(HWND hwndCallback, UINT uDeviceID, UINT uStatus)
Definition: mci.c:2056
volatile WORD dwStatus
Definition: mciwave.c:51
#define MCI_MODE_RECORD
Definition: mmsystem.h:697
#define MCI_MODE_PLAY
Definition: mmsystem.h:696
smooth NULL
Definition: ftsmooth.c:416
BOOL fInput
Definition: mciwave.c:48
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
static WINE_MCIWAVE * WAVE_mciGetOpenDev(MCIDEVICEID wDevID)
Definition: mciwave.c:195
UINT WINAPI waveInReset(HWAVEIN hWaveIn)
Definition: winmm.c:2737
#define MCI_MODE_NOT_READY
Definition: mmsystem.h:694
DWORD_PTR dwCallback
Definition: mmsystem.h:1517
HANDLE hWave
Definition: mciwave.c:40
UINT wDevID
Definition: mciwave.c:74
#define MCI_MODE_PAUSE
Definition: mmsystem.h:699
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_NOTIFY
Definition: mmsystem.h:729
UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
Definition: winmm.c:2388

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

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( mciwave  )