ReactOS 0.4.15-dev-7942-gd23573b
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;
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);
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 ARRAY_SIZE(A)
Definition: main.h:33
#define WARN(fmt,...)
Definition: debug.h:112
#define NULL
Definition: types.h:112
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2080
HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO *lpmmioinfo, DWORD dwOpenFlags)
Definition: mmio.c:670
UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName)
Definition: filename.c:84
unsigned long DWORD
Definition: ntddk_ex.h:95
#define debugstr_w
Definition: kernel32.h:32
#define MMIO_ALLOCBUF
Definition: mmsystem.h:532
#define MMIO_READWRITE
Definition: mmsystem.h:537
#define MCIERR_FILE_NOT_FOUND
Definition: mmsystem.h:585
#define MMIO_CREATE
Definition: mmsystem.h:528
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
_In_ HANDLE hFile
Definition: mswsock.h:90
#define TRACE(s)
Definition: solgame.cpp:4
__wchar_t WCHAR
Definition: xmlstorage.h:180

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}
#define MCI_WAIT
Definition: mmsystem.h:730
Definition: mciwave.c:71
UINT wDevID
Definition: mciwave.c:74
DWORD_PTR dwParam1
Definition: mciwave.c:75
HANDLE evt
Definition: mciwave.c:73
DWORD_PTR dwParam2
Definition: mciwave.c:76
async_cmd cmd
Definition: mciwave.c:72
int ret

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

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;
1725 case DRV_OPEN: return WAVE_drvOpen((LPCWSTR)dwParam1, (LPMCI_OPEN_DRIVER_PARMSW)dwParam2);
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) {
1738 case MCI_OPEN_DRIVER: return WAVE_mciOpen (dwDevID, dwParam1, (LPMCI_WAVE_OPEN_PARMSW) dwParam2);
1739 case MCI_CLOSE_DRIVER: return WAVE_mciClose (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
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);
1748 case MCI_GETDEVCAPS: return WAVE_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_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 FIXME(fmt,...)
Definition: debug.h:111
#define ERR(fmt,...)
Definition: debug.h:110
#define MCI_CONFIGURE
Definition: digitalv.h:45
LRESULT WINAPI DefDriverProc(DWORD_PTR dwDriverIdentifier, HDRVR hDrv, UINT Msg, LPARAM lParam1, LPARAM lParam2)
Definition: driver.c:554
#define DRV_LOAD(x)
static LRESULT WAVE_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp)
Definition: mciwave.c:150
static DWORD WAVE_mciStatus(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
Definition: mciwave.c:1471
static DWORD WAVE_mciGetDevCaps(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms)
Definition: mciwave.c:1599
static DWORD WAVE_mciPlay(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE hEvent)
Definition: mciwave.c:739
static DWORD WAVE_mciPause(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:1166
static DWORD WAVE_mciSet(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_WAVE_SET_PARMS lpParms)
Definition: mciwave.c:1293
static DWORD WAVE_mciClose(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:660
static DWORD WAVE_mciCue(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:581
static LRESULT WAVE_drvClose(MCIDEVICEID dwDevID)
Definition: mciwave.c:180
static LRESULT WAVE_mciOpen(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_PARMSW lpOpenParms)
Definition: mciwave.c:514
static DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:1206
static DWORD WAVE_mciSeek(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
Definition: mciwave.c:1249
static DWORD WAVE_mciRecord(MCIDEVICEID wDevID, DWORD_PTR dwFlags, DWORD_PTR pmt, HANDLE hEvent)
Definition: mciwave.c:1000
static DWORD WAVE_mciSave(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_SAVE_PARMSW lpParms)
Definition: mciwave.c:1419
static DWORD WAVE_mciInfo(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_INFO_PARMSW lpParms)
Definition: mciwave.c:1670
static DWORD WAVE_mciStop(MCIDEVICEID wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mciwave.c:618
#define MCI_CUT
Definition: mmsystem.h:671
#define MCI_SAVE
Definition: mmsystem.h:661
#define DRV_CLOSE
Definition: mmsystem.h:122
#define DRV_QUERYCONFIGURE
Definition: mmsystem.h:126
#define MCI_GETDEVCAPS
Definition: mmsystem.h:654
#define MCI_RESUME
Definition: mmsystem.h:675
#define MCI_DELETE
Definition: mmsystem.h:676
#define MCI_FREEZE
Definition: mmsystem.h:668
#define DRVCNF_RESTART
Definition: mmsystem.h:135
#define MCI_WINDOW
Definition: mmsystem.h:665
#define MCI_STATUS
Definition: mmsystem.h:662
#define MCI_COPY
Definition: mmsystem.h:672
#define MCI_ESCAPE
Definition: mmsystem.h:648
#define MCIERR_UNRECOGNIZED_COMMAND
Definition: mmsystem.h:571
#define MCI_SET
Definition: mmsystem.h:656
#define MCI_LOAD
Definition: mmsystem.h:670
#define MCI_UPDATE
Definition: mmsystem.h:674
#define DRV_REMOVE
Definition: mmsystem.h:128
#define DRV_ENABLE
Definition: mmsystem.h:120
#define MCI_STOP
Definition: mmsystem.h:651
#define MCI_CLOSE
Definition: mmsystem.h:647
#define MCI_SEEK
Definition: mmsystem.h:650
#define DRV_CONFIGURE
Definition: mmsystem.h:125
#define DRV_OPEN
Definition: mmsystem.h:121
#define MCI_WHERE
Definition: mmsystem.h:667
#define DRV_INSTALL
Definition: mmsystem.h:127
#define MCI_OPEN
Definition: mmsystem.h:646
#define MCI_UNFREEZE
Definition: mmsystem.h:669
#define MCI_PUT
Definition: mmsystem.h:666
#define MCI_SPIN
Definition: mmsystem.h:655
#define MCI_CUE
Definition: mmsystem.h:663
#define MCI_PAUSE
Definition: mmsystem.h:652
#define MCI_INFO
Definition: mmsystem.h:653
#define MCI_PASTE
Definition: mmsystem.h:673
#define DRV_FREE
Definition: mmsystem.h:124
#define MCIERR_UNSUPPORTED_FUNCTION
Definition: mmsystem.h:584
#define MCI_PLAY
Definition: mmsystem.h:649
#define MCI_STEP
Definition: mmsystem.h:657
#define MCI_REALIZE
Definition: mmsystem.h:664
#define MCI_RECORD
Definition: mmsystem.h:658
#define DRV_DISABLE
Definition: mmsystem.h:123
#define MCI_OPEN_DRIVER
Definition: mmddk.h:338
#define MCI_CLOSE_DRIVER
Definition: mmddk.h:339
int WINAPI MessageBoxA(_In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType)
#define MB_OK
Definition: winuser.h:790
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

◆ WAVE_ConvertByteToTimeFormat()

static DWORD WAVE_ConvertByteToTimeFormat ( WINE_MCIWAVE wmw,
DWORD  val 
)
static

Definition at line 227 of file mciwave.c.

228{
229 DWORD ret = 0;
230
231 switch (wmw->dwMciTimeFormat) {
234 break;
235 case MCI_FORMAT_BYTES:
236 ret = val;
237 break;
240 break;
241 default:
242 WARN("Bad time format %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}
GLuint GLfloat * val
Definition: glext.h:7180
#define MCI_FORMAT_SAMPLES
Definition: mmsystem.h:710
#define MCI_FORMAT_MILLISECONDS
Definition: mmsystem.h:701
#define MCI_FORMAT_BYTES
Definition: mmsystem.h:709
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
DWORD dwMciTimeFormat
Definition: mciwave.c:52
LPWAVEFORMATEX lpWaveFormat
Definition: mciwave.c:47
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
DWORD nSamplesPerSec
Definition: mmreg.h:80

Referenced by WAVE_ConvertTimeFormatToByte(), and WAVE_mciStatus().

◆ WAVE_ConvertTimeFormatToByte()

static DWORD WAVE_ConvertTimeFormatToByte ( WINE_MCIWAVE wmw,
DWORD  val 
)
static

Definition at line 251 of file mciwave.c.

252{
253 DWORD ret = 0;
254
255 switch (wmw->dwMciTimeFormat) {
258 if (ret > wmw->ckWaveData.cksize &&
260 ret = wmw->ckWaveData.cksize;
261 break;
262 case MCI_FORMAT_BYTES:
263 ret = val;
264 break;
267 break;
268 default:
269 WARN("Bad time format %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}
static DWORD WAVE_ConvertByteToTimeFormat(WINE_MCIWAVE *wmw, DWORD val)
Definition: mciwave.c:227
MMCKINFO ckWaveData
Definition: mciwave.c:57
DWORD cksize
Definition: mmsystem.h:1508

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

◆ WAVE_drvClose()

static LRESULT WAVE_drvClose ( MCIDEVICEID  dwDevID)
static

Definition at line 180 of file mciwave.c.

181{
183
184 if (wmw) {
185 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:2233

Referenced by MCIWAVE_DriverProc().

◆ WAVE_drvOpen()

static LRESULT WAVE_drvOpen ( LPCWSTR  str,
LPMCI_OPEN_DRIVER_PARMSW  modp 
)
static

Definition at line 150 of file mciwave.c.

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

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciClose()

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

Definition at line 660 of file mciwave.c.

661{
662 DWORD dwRet = 0;
663 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
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;
687 wmw->lpFileName = NULL;
688
689 if ((dwFlags & MCI_NOTIFY) && lpParms) {
690 WAVE_mciNotify(lpParms->dwCallback, wmw,
692 }
693
694 return 0;
695}
MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
Definition: mmio.c:702
static WINE_MCIWAVE * WAVE_mciGetOpenDev(MCIDEVICEID wDevID)
Definition: mciwave.c:195
static void WAVE_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIWAVE *wmw, UINT wStatus)
Definition: mciwave.c:213
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_MODE_STOP
Definition: mmsystem.h:695
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
#define MCI_NOTIFY_FAILURE
Definition: mmsystem.h:728
HMMIO hFile
Definition: mciwave.c:42
LPWSTR lpFileName
Definition: mciwave.c:45
int nUseCount
Definition: mciwave.c:41
volatile WORD dwStatus
Definition: mciwave.c:51
DWORD_PTR dwCallback
Definition: mmsystem.h:1517
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciCreateRIFFSkeleton()

static DWORD WAVE_mciCreateRIFFSkeleton ( WINE_MCIWAVE wmw)
static

Definition at line 346 of file mciwave.c.

347{
348 MMCKINFO ckWaveFormat;
349 LPMMCKINFO lpckRIFF = &(wmw->ckMainRIFF);
350 LPMMCKINFO lpckWaveData = &(wmw->ckWaveData);
351
352 lpckRIFF->ckid = FOURCC_RIFF;
353 lpckRIFF->fccType = mmioFOURCC('W', 'A', 'V', 'E');
354 lpckRIFF->cksize = 0;
355
357 goto err;
358
359 ckWaveFormat.fccType = 0;
360 ckWaveFormat.ckid = mmioFOURCC('f', 'm', 't', ' ');
361 ckWaveFormat.cksize = sizeof(PCMWAVEFORMAT);
362
363 /* Set wave format accepts PCM only, however open an
364 * existing ADPCM file, record into it and the MCI will
365 * happily save back in that format. */
367 if (wmw->lpWaveFormat->nBlockAlign !=
371 WARN("Incorrect nBlockAlign (%d), setting it to %d\n",
374 }
375 if (wmw->lpWaveFormat->nAvgBytesPerSec !=
377 DWORD speed = wmw->lpWaveFormat->nSamplesPerSec *
379 WARN("Incorrect nAvgBytesPerSec (%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
413err:
414 /* mciClose takes care of wmw->lpWaveFormat. */
415 return MCIERR_INVALID_FILE;
416}
MMRESULT WINAPI mmioAscend(HMMIO hmmio, LPMMCKINFO lpck, UINT uFlags)
Definition: mmio.c:1205
LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
Definition: mmio.c:782
MMRESULT WINAPI mmioCreateChunk(HMMIO hmmio, MMCKINFO *lpck, UINT uFlags)
Definition: mmio.c:1239
#define assert(x)
Definition: debug.h:53
unsigned short WORD
Definition: ntddk_ex.h:93
#define FOURCC_RIFF
Definition: mmsystem.h:564
#define MCIERR_INVALID_FILE
Definition: mmsystem.h:604
struct pcmwaveformat_tag PCMWAVEFORMAT
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
#define MMIO_CREATERIFF
Definition: mmsystem.h:554
#define err(...)
MMCKINFO ckMainRIFF
Definition: mciwave.c:56
FOURCC ckid
Definition: mmsystem.h:1507
FOURCC fccType
Definition: mmsystem.h:1509
WORD nBlockAlign
Definition: mmreg.h:82
WORD cbSize
Definition: mmreg.h:84
WORD nChannels
Definition: mmreg.h:79
WORD wFormatTag
Definition: mmreg.h:78
WORD wBitsPerSample
Definition: mmreg.h:83

Referenced by WAVE_mciRecord().

◆ WAVE_mciCue()

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

Definition at line 581 of file mciwave.c.

582{
583 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
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

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciDefaultFmt()

static void WAVE_mciDefaultFmt ( WINE_MCIWAVE wmw)
static

Definition at line 331 of file mciwave.c.

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

Referenced by WAVE_mciOpen().

◆ WAVE_mciGetDevCaps()

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

Definition at line 1599 of file mciwave.c.

1601{
1602 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
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
1611 switch(lpParms->dwItem) {
1615 break;
1619 break;
1623 break;
1627 break;
1631 break;
1635 break;
1639 break;
1643 break;
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 TRUE
Definition: types.h:120
#define MAKEMCIRESOURCE(wRet, wRes)
Definition: mmddk.h:388
#define MCI_FALSE
Definition: mmddk.h:340
#define MCI_TRUE
Definition: mmddk.h:341
#define MCI_RESOURCE_RETURNED
Definition: mmddk.h:369
#define MCI_GETDEVCAPS_CAN_SAVE
Definition: mmsystem.h:767
#define MCI_GETDEVCAPS_HAS_VIDEO
Definition: mmsystem.h:761
#define MCI_GETDEVCAPS_CAN_RECORD
Definition: mmsystem.h:759
#define MCI_GETDEVCAPS_DEVICE_TYPE
Definition: mmsystem.h:762
#define MCI_WAVE_GETDEVCAPS_OUTPUTS
Definition: mmsystem.h:840
#define MCI_GETDEVCAPS_COMPOUND_DEVICE
Definition: mmsystem.h:764
#define MCI_GETDEVCAPS_USES_FILES
Definition: mmsystem.h:763
#define MCI_GETDEVCAPS_CAN_PLAY
Definition: mmsystem.h:766
#define MCI_WAVE_GETDEVCAPS_INPUTS
Definition: mmsystem.h:839
#define MCI_GETDEVCAPS_CAN_EJECT
Definition: mmsystem.h:765
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605
#define MCI_GETDEVCAPS_ITEM
Definition: mmsystem.h:758
#define MCI_GETDEVCAPS_HAS_AUDIO
Definition: mmsystem.h:760
#define HRESULT_CODE(hr)
Definition: winerror.h:76
UINT WINAPI waveOutGetNumDevs(void)
Definition: winmm.c:2137
UINT WINAPI waveInGetNumDevs(void)
Definition: winmm.c:2565

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciGetOpenDev()

static WINE_MCIWAVE * WAVE_mciGetOpenDev ( MCIDEVICEID  wDevID)
static

Definition at line 195 of file mciwave.c.

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

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

◆ WAVE_mciInfo()

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

Definition at line 1670 of file mciwave.c.

1671{
1672 DWORD ret = 0;
1673 LPCWSTR str = 0;
1674 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
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 }
1710 return ret;
1711}
#define lstrcpynW
Definition: compat.h:738
#define MCI_INFO_PRODUCT
Definition: mmsystem.h:752
#define MCI_WAVE_OUTPUT
Definition: mmsystem.h:829
#define MCI_WAVE_INPUT
Definition: mmsystem.h:828
#define MCIERR_PARAM_OVERFLOW
Definition: mmsystem.h:578
#define MCI_INFO_FILE
Definition: mmsystem.h:753
#define MCIERR_UNRECOGNIZED_KEYWORD
Definition: mmsystem.h:570
const WCHAR * str
int zero
Definition: sehframes.cpp:29
DWORD_PTR dwCallback
Definition: mmsystem.h:1579

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciNotify()

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

Definition at line 213 of file mciwave.c.

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

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

◆ WAVE_mciOpen()

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

Definition at line 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;
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
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)
567 } else {
568 wmw->nUseCount--;
569 if (wmw->hFile != 0)
570 mmioClose(wmw->hFile, 0);
571 wmw->hFile = 0;
573 wmw->lpFileName = NULL;
574 }
575 return dwRet;
576}
static void WAVE_mciDefaultFmt(WINE_MCIWAVE *wmw)
Definition: mciwave.c:331
static LRESULT WAVE_mciOpenFile(WINE_MCIWAVE *wmw, LPCWSTR filename)
Definition: mciwave.c:461
#define MCI_OPEN_SHAREABLE
Definition: mmsystem.h:734
#define MCI_OPEN_ELEMENT_ID
Definition: mmsystem.h:737
#define MCI_OPEN_ELEMENT
Definition: mmsystem.h:735
#define WAVE_MAPPER
Definition: mmsystem.h:187
#define MCIERR_DEVICE_OPEN
Definition: mmsystem.h:575
#define MCI_MODE_NOT_READY
Definition: mmsystem.h:694
BOOL fInput
Definition: mciwave.c:48
WORD wInput
Definition: mciwave.c:49
DWORD dwPosition
Definition: mciwave.c:53
HANDLE hWave
Definition: mciwave.c:40
WORD wOutput
Definition: mciwave.c:50
MCIDEVICEID wDeviceID
Definition: mmsystem.h:1677

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{
464 LPWSTR fn;
465
466 fn = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1) * sizeof(WCHAR));
467 if (!fn) return MCIERR_OUT_OF_MEMORY;
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 lstrcpyW
Definition: compat.h:749
#define lstrlenW
Definition: compat.h:750
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
Definition: mmio.c:836
MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck, const MMCKINFO *lpckParent, UINT uFlags)
Definition: mmio.c:1107
const char * filename
Definition: ioapi.h:137
#define SEEK_SET
Definition: jmemansi.c:26
static DWORD WAVE_mciReadFmt(WINE_MCIWAVE *wmw, const MMCKINFO *pckMainRIFF)
Definition: mciwave.c:278
#define MMIO_DENYWRITE
Definition: mmsystem.h:540
#define MMIO_READ
Definition: mmsystem.h:535
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
LONG_PTR LRESULT
Definition: windef.h:209
char * LPSTR
Definition: xmlstorage.h:182
WCHAR * LPWSTR
Definition: xmlstorage.h:184

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;
1169 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
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 MCI_MODE_PLAY
Definition: mmsystem.h:696
#define MCIERR_INTERNAL
Definition: mmsystem.h:587
#define MCI_MODE_RECORD
Definition: mmsystem.h:697
#define MCI_MODE_PAUSE
Definition: mmsystem.h:699
UINT WINAPI waveInStop(HWAVEIN hWaveIn)
Definition: winmm.c:2764
UINT WINAPI waveOutPause(HWAVEOUT hWaveOut)
Definition: winmm.c:2371

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciPlay()

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

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

Definition at line 739 of file mciwave.c.

740{
741 LPMCI_PLAY_PARMS lpParms = (void*)pmt;
742 DWORD end;
744 DWORD dwRet;
745 LPWAVEHDR waveHdr = NULL;
746 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
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));
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 */
762 return WAVE_mciResume(wDevID, dwFlags, (LPMCI_GENERIC_PARMS)lpParms);
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
778 if (wmw->lpWaveFormat->nBlockAlign !=
780 WARN("Incorrect nBlockAlign (%d), setting it to %d\n",
782 wmw->lpWaveFormat->nChannels *
785 wmw->lpWaveFormat->nChannels *
787 }
788 if (wmw->lpWaveFormat->nAvgBytesPerSec !=
790 WARN("Incorrect nAvgBytesPerSec (%d), setting it to %d\n",
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;
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
916cleanUp:
917 if (dwFlags & MCI_NOTIFY)
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}
LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
Definition: mmio.c:733
void cleanUp()
Definition: main.cpp:469
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint left
Definition: glext.h:7726
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
#define WAVE_ALIGN_ON_BLOCK(wmw, v)
static void WAVE_mciPlayWaitDone(WINE_MCIWAVE *wmw)
Definition: mciwave.c:723
static void CALLBACK WAVE_mciPlayCallback(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, LPARAM dwParam1, LPARAM dwParam2)
Definition: mciwave.c:700
static DWORD MCI_SendCommandAsync(UINT wDevID, async_cmd cmd, DWORD_PTR dwParam1, DWORD_PTR dwParam2, UINT size)
Definition: mciwave.c:99
static DWORD WAVE_ConvertTimeFormatToByte(WINE_MCIWAVE *wmw, DWORD val)
Definition: mciwave.c:251
#define MCI_TO
Definition: mmsystem.h:732
#define MCIERR_HARDWARE
Definition: mmsystem.h:572
#define MCI_NOTIFY_ABORTED
Definition: mmsystem.h:727
#define MCIERR_OUTOFRANGE
Definition: mmsystem.h:592
#define CALLBACK_FUNCTION
Definition: mmsystem.h:150
#define MCI_FROM
Definition: mmsystem.h:731
static HANDLE hEvent
Definition: comm.c:54
#define min(a, b)
Definition: monoChain.cc:55
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
HANDLE hEvent
Definition: mciwave.c:54
LONG dwEventCount
Definition: mciwave.c:55
DWORD dwDataOffset
Definition: mmsystem.h:1510
DWORD_PTR dwCallback
Definition: mmsystem.h:1537
DWORD dwBufferLength
Definition: mmsystem.h:1015
DWORD dwLoops
Definition: mmsystem.h:1019
DWORD dwFlags
Definition: mmsystem.h:1018
DWORD_PTR dwUser
Definition: mmsystem.h:1017
LPSTR lpData
Definition: mmsystem.h:1014
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
UINT WINAPI waveOutReset(HWAVEOUT hWaveOut)
Definition: winmm.c:2385
UINT WINAPI waveOutWrite(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2341
UINT WINAPI waveOutUnprepareHeader(HWAVEOUT hWaveOut, LPWAVEHDR lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2307
MMRESULT WINAPI waveOutOpen(LPHWAVEOUT lphWaveOut, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2246
UINT WINAPI waveOutPrepareHeader(HWAVEOUT hWaveOut, WAVEHDR *lpWaveOutHdr, UINT uSize)
Definition: winmm.c:2277
UINT WINAPI waveOutClose(HWAVEOUT hWaveOut)
Definition: winmm.c:2257

Referenced by MCIWAVE_DriverProc(), and WAVE_mciPlay().

◆ WAVE_mciPlayCallback()

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

Definition at line 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 InterlockedIncrement
Definition: armddk.h:53
#define WOM_DONE
Definition: mmsystem.h:183
#define WOM_OPEN
Definition: mmsystem.h:181
#define WOM_CLOSE
Definition: mmsystem.h:182

Referenced by WAVE_mciPlay().

◆ WAVE_mciPlayWaitDone()

static void WAVE_mciPlayWaitDone ( WINE_MCIWAVE wmw)
static

Definition at line 723 of file mciwave.c.

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

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}
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define MMIO_FINDCHUNK
Definition: mmsystem.h:551
char * HPSTR
Definition: mmsystem.h:1477

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;
1007 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
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. */
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 */
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
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
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) {
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
1142cleanUp:
1143 if (dwFlags & MCI_NOTIFY)
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}
static DWORD create_tmp_file(HMMIO *hFile, LPWSTR *pszTmpFileName)
Definition: mciwave.c:418
static DWORD WAVE_mciCreateRIFFSkeleton(WINE_MCIWAVE *wmw)
Definition: mciwave.c:346
static void WAVE_mciRecordWaitDone(WINE_MCIWAVE *wmw)
Definition: mciwave.c:984
static void CALLBACK WAVE_mciRecordCallback(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, LPARAM dwParam1, LPARAM dwParam2)
Definition: mciwave.c:941
DWORD_PTR dwCallback
Definition: mmsystem.h:1639
UINT WINAPI waveInAddBuffer(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2717
UINT WINAPI waveInPrepareHeader(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2653
UINT WINAPI waveInUnprepareHeader(HWAVEIN hWaveIn, WAVEHDR *lpWaveInHdr, UINT uSize)
Definition: winmm.c:2684
UINT WINAPI waveInReset(HWAVEIN hWaveIn)
Definition: winmm.c:2734
MMRESULT WINAPI waveInOpen(HWAVEIN *lphWaveIn, UINT uDeviceID, LPCWAVEFORMATEX lpFormat, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:2623
UINT WINAPI waveInClose(HWAVEIN hWaveIn)
Definition: winmm.c:2634
UINT WINAPI waveInStart(HWAVEIN hWaveIn)
Definition: winmm.c:2749

Referenced by MCIWAVE_DriverProc(), and WAVE_mciRecord().

◆ WAVE_mciRecordCallback()

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

Definition at line 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
#define WIM_DATA
Definition: mmsystem.h:186
#define WIM_CLOSE
Definition: mmsystem.h:185
#define WIM_OPEN
Definition: mmsystem.h:184
DWORD dwBytesRecorded
Definition: mmsystem.h: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}

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{
1208 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
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}
UINT WINAPI waveOutRestart(HWAVEOUT hWaveOut)
Definition: winmm.c:2399

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

◆ WAVE_mciSave()

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

Definition at line 1419 of file mciwave.c.

1420{
1421 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
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
1461
1462 if (ret == MMSYSERR_NOERROR)
1463 ret = WAVE_mciOpenFile(wmw, lpParms->lpfilename);
1464
1465 return ret;
1466}
#define SetLastError(x)
Definition: compat.h:752
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
MMRESULT WINAPI mmioRenameW(LPCWSTR szFileName, LPCWSTR szNewFileName, const MMIOINFO *lpmmioinfo, DWORD dwFlags)
Definition: mmio.c:1320
#define MCIERR_FILE_NOT_SAVED
Definition: mmsystem.h:594
LPCWSTR lpfilename
Definition: mmsystem.h:1625
DWORD_PTR dwCallback
Definition: mmsystem.h:1624
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

Referenced by MCIWAVE_DriverProc().

◆ WAVE_mciSeek()

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

Definition at line 1249 of file mciwave.c.

1250{
1251 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
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 MCIERR_FLAGS_NOT_COMPATIBLE
Definition: mmsystem.h:593
#define MCI_SEEK_TO_END
Definition: mmsystem.h:741
#define MCIERR_MISSING_PARAMETER
Definition: mmsystem.h:583
#define MCI_SEEK_TO_START
Definition: mmsystem.h:740
DWORD_PTR dwCallback
Definition: mmsystem.h:1543

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{
1295 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
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
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);
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 }
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)
1356 WAVE_mciStop(wDevID, MCI_WAIT, NULL);
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)
1364 WAVE_mciStop(wDevID, MCI_WAIT, NULL);
1365 wmw->wOutput = lpParms->wOutput;
1366 }
1368 TRACE("MCI_WAVE_SET_ANYINPUT\n");
1369 if (wmw->wInput != (WORD)lpParms->wInput)
1370 WAVE_mciStop(wDevID, MCI_WAIT, NULL);
1371 wmw->wInput = WAVE_MAPPER;
1372 }
1374 TRACE("MCI_WAVE_SET_ANYOUTPUT\n");
1375 if (wmw->wOutput != (WORD)lpParms->wOutput)
1376 WAVE_mciStop(wDevID, MCI_WAIT, NULL);
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_SET_AUDIO
Definition: mmsystem.h:775
#define MCI_WAVE_SET_SAMPLESPERSEC
Definition: mmsystem.h:824
#define MCI_WAVE_SET_AVGBYTESPERSEC
Definition: mmsystem.h:825
#define MCI_WAVE_SET_ANYINPUT
Definition: mmsystem.h:837
#define MCIERR_BAD_INTEGER
Definition: mmsystem.h:580
#define MCI_SET_DOOR_OPEN
Definition: mmsystem.h:772
#define MCI_SET_TIME_FORMAT
Definition: mmsystem.h:774
#define MCI_SET_VIDEO
Definition: mmsystem.h:776
#define MCI_SET_AUDIO_RIGHT
Definition: mmsystem.h:781
#define MCI_SET_AUDIO_ALL
Definition: mmsystem.h:779
#define MCI_WAVE_SET_FORMATTAG
Definition: mmsystem.h:822
#define MCI_SET_DOOR_CLOSED
Definition: mmsystem.h:773
#define MCI_WAVE_SET_CHANNELS
Definition: mmsystem.h:823
#define MCI_SET_AUDIO_LEFT
Definition: mmsystem.h:780
#define MCI_SET_OFF
Definition: mmsystem.h:778
#define MCI_WAVE_SET_BITSPERSAMPLE
Definition: mmsystem.h:827
#define MCI_WAVE_SET_BLOCKALIGN
Definition: mmsystem.h:826
#define MCI_WAVE_SET_ANYOUTPUT
Definition: mmsystem.h:838
#define MCIERR_BAD_TIME_FORMAT
Definition: mmsystem.h:601
#define MCI_SET_ON
Definition: mmsystem.h:777
DWORD_PTR dwCallback
Definition: mmsystem.h:1691

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{
1473 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
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");
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;
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 */
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;
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 MCI_FORMAT_RETURN_BASE
Definition: mmddk.h:343
#define WAVE_MAPPER_S
Definition: mmddk.h:359
#define WAVE_FORMAT_PCM_S
Definition: mmddk.h:358
#define MCI_WAVE_STATUS_BITSPERSAMPLE
Definition: mmsystem.h:835
#define MCI_STATUS_POSITION
Definition: mmsystem.h:745
#define MCI_WAVE_STATUS_LEVEL
Definition: mmsystem.h:836
#define MCI_WAVE_STATUS_BLOCKALIGN
Definition: mmsystem.h:834
#define MCI_WAVE_STATUS_SAMPLESPERSEC
Definition: mmsystem.h:832
#define MCI_STATUS_START
Definition: mmsystem.h:743
#define MCI_WAVE_STATUS_FORMATTAG
Definition: mmsystem.h:830
#define MCI_STATUS_CURRENT_TRACK
Definition: mmsystem.h:751
#define MCI_STATUS_NUMBER_OF_TRACKS
Definition: mmsystem.h:746
#define MCI_WAVE_STATUS_AVGBYTESPERSEC
Definition: mmsystem.h:833
#define MCI_STATUS_LENGTH
Definition: mmsystem.h:744
#define MCI_STATUS_MODE
Definition: mmsystem.h:747
#define MCI_STATUS_MEDIA_PRESENT
Definition: mmsystem.h:748
#define MCI_STATUS_TIME_FORMAT
Definition: mmsystem.h:749
#define MCI_WAVE_STATUS_CHANNELS
Definition: mmsystem.h:831
#define MCI_STATUS_ITEM
Definition: mmsystem.h:742
#define MCI_STATUS_READY
Definition: mmsystem.h:750
DWORD_PTR dwReturn
Definition: mmsystem.h:1567
DWORD_PTR dwCallback
Definition: mmsystem.h:1566

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;
621 WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
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}
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790

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

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( mciwave  )