Added asynchronous recording in MCI layer.
This commit is contained in:
parent
d747b76cb6
commit
3732965c15
|
@ -4,12 +4,10 @@
|
||||||
*
|
*
|
||||||
* Copyright 1994 Martin Ayotte
|
* Copyright 1994 Martin Ayotte
|
||||||
* 1999 Eric Pouech
|
* 1999 Eric Pouech
|
||||||
*/
|
* 2000 Francois Jacques
|
||||||
/*
|
|
||||||
* FIXME:
|
|
||||||
* - record/play should and must be done asynchronous
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "winerror.h"
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
|
@ -31,11 +29,13 @@ typedef struct {
|
||||||
BOOL fInput; /* FALSE = Output, TRUE = Input */
|
BOOL fInput; /* FALSE = Output, TRUE = Input */
|
||||||
volatile WORD dwStatus; /* one from MCI_MODE_xxxx */
|
volatile WORD dwStatus; /* one from MCI_MODE_xxxx */
|
||||||
DWORD dwMciTimeFormat;/* One of the supported MCI_FORMAT_xxxx */
|
DWORD dwMciTimeFormat;/* One of the supported MCI_FORMAT_xxxx */
|
||||||
DWORD dwFileOffset; /* Offset of chunk in mmio file */
|
DWORD dwRemaining; /* remaining bytes to play or record */
|
||||||
DWORD dwLength; /* number of bytes in chunk for playing */
|
DWORD dwPosition; /* position in bytes in chunk */
|
||||||
DWORD dwPosition; /* position in bytes in chunk for playing */
|
|
||||||
HANDLE hEvent; /* for synchronization */
|
HANDLE hEvent; /* for synchronization */
|
||||||
DWORD dwEventCount; /* for synchronization */
|
DWORD dwEventCount; /* for synchronization */
|
||||||
|
BOOL bTemporaryFile; /* temporary file (MCI_RECORD) */
|
||||||
|
MMCKINFO ckMainRIFF; /* main RIFF chunk */
|
||||||
|
MMCKINFO ckWaveData; /* data chunk */
|
||||||
} WINE_MCIWAVE;
|
} WINE_MCIWAVE;
|
||||||
|
|
||||||
/* ===================================================================
|
/* ===================================================================
|
||||||
|
@ -172,8 +172,8 @@ static WINE_MCIWAVE* WAVE_mciGetOpenDev(UINT wDevID)
|
||||||
*/
|
*/
|
||||||
static DWORD WAVE_ConvertByteToTimeFormat(WINE_MCIWAVE* wmw, DWORD val, LPDWORD lpRet)
|
static DWORD WAVE_ConvertByteToTimeFormat(WINE_MCIWAVE* wmw, DWORD val, LPDWORD lpRet)
|
||||||
{
|
{
|
||||||
DWORD ret = 0;
|
DWORD ret = 0;
|
||||||
|
|
||||||
switch (wmw->dwMciTimeFormat) {
|
switch (wmw->dwMciTimeFormat) {
|
||||||
case MCI_FORMAT_MILLISECONDS:
|
case MCI_FORMAT_MILLISECONDS:
|
||||||
ret = (val * 1000) / wmw->lpWaveFormat->nAvgBytesPerSec;
|
ret = (val * 1000) / wmw->lpWaveFormat->nAvgBytesPerSec;
|
||||||
|
@ -245,20 +245,84 @@ static DWORD WAVE_mciReadFmt(WINE_MCIWAVE* wmw, MMCKINFO* pckMainRIFF)
|
||||||
TRACE("cbSize=%u !\n", wmw->lpWaveFormat->cbSize);
|
TRACE("cbSize=%u !\n", wmw->lpWaveFormat->cbSize);
|
||||||
|
|
||||||
mmioAscend(wmw->hFile, &mmckInfo, 0);
|
mmioAscend(wmw->hFile, &mmckInfo, 0);
|
||||||
mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
|
wmw->ckWaveData.ckid = mmioFOURCC('d', 'a', 't', 'a');
|
||||||
if (mmioDescend(wmw->hFile, &mmckInfo, pckMainRIFF, MMIO_FINDCHUNK) != 0) {
|
if (mmioDescend(wmw->hFile, &wmw->ckWaveData, pckMainRIFF, MMIO_FINDCHUNK) != 0) {
|
||||||
TRACE("can't find data chunk\n");
|
TRACE("can't find data chunk\n");
|
||||||
return MCIERR_INVALID_FILE;
|
return MCIERR_INVALID_FILE;
|
||||||
}
|
}
|
||||||
TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
|
TRACE("Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
|
||||||
(LPSTR)&mmckInfo.ckid, (LPSTR)&mmckInfo.fccType, mmckInfo.cksize);
|
(LPSTR)&wmw->ckWaveData.ckid, (LPSTR)&wmw->ckWaveData.fccType, wmw->ckWaveData.cksize);
|
||||||
TRACE("nChannels=%d nSamplesPerSec=%ld\n",
|
TRACE("nChannels=%d nSamplesPerSec=%ld\n",
|
||||||
wmw->lpWaveFormat->nChannels, wmw->lpWaveFormat->nSamplesPerSec);
|
wmw->lpWaveFormat->nChannels, wmw->lpWaveFormat->nSamplesPerSec);
|
||||||
wmw->dwLength = mmckInfo.cksize;
|
|
||||||
wmw->dwFileOffset = mmckInfo.dwDataOffset;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* WAVE_mciCreateRIFFSkeleton [internal]
|
||||||
|
*/
|
||||||
|
static DWORD WAVE_mciCreateRIFFSkeleton(WINE_MCIWAVE* wmw)
|
||||||
|
{
|
||||||
|
MMCKINFO ckWaveFormat;
|
||||||
|
|
||||||
|
LPMMCKINFO lpckRIFF = &(wmw->ckMainRIFF);
|
||||||
|
LPMMCKINFO lpckWaveData = &(wmw->ckWaveData);
|
||||||
|
LPWAVEFORMATEX lpWaveFormat = wmw->lpWaveFormat;
|
||||||
|
|
||||||
|
|
||||||
|
HMMIO hmmio = wmw->hFile;
|
||||||
|
|
||||||
|
lpckRIFF->ckid = FOURCC_RIFF;
|
||||||
|
lpckRIFF->fccType = mmioFOURCC('W', 'A', 'V', 'E');
|
||||||
|
lpckRIFF->cksize = 0;
|
||||||
|
|
||||||
|
if (MMSYSERR_NOERROR != mmioCreateChunk(hmmio, lpckRIFF, MMIO_CREATERIFF))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
ckWaveFormat.fccType = 0;
|
||||||
|
ckWaveFormat.ckid = mmioFOURCC('f', 'm', 't', ' ');
|
||||||
|
ckWaveFormat.cksize = 16;
|
||||||
|
|
||||||
|
if (!lpWaveFormat)
|
||||||
|
{
|
||||||
|
TRACE("allocating waveformat with default waveformat 11khz/8bit/mono \n");
|
||||||
|
|
||||||
|
lpWaveFormat = wmw->lpWaveFormat = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*lpWaveFormat));
|
||||||
|
|
||||||
|
lpWaveFormat->wFormatTag = WAVE_FORMAT_PCM;
|
||||||
|
lpWaveFormat->nChannels = 1; /* MONO */
|
||||||
|
lpWaveFormat->nSamplesPerSec = 11025;
|
||||||
|
lpWaveFormat->nAvgBytesPerSec = 11025;
|
||||||
|
lpWaveFormat->nBlockAlign = 1;
|
||||||
|
lpWaveFormat->wBitsPerSample = 8;
|
||||||
|
lpWaveFormat->cbSize = 0; /* don't care */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MMSYSERR_NOERROR != mmioCreateChunk(hmmio, &ckWaveFormat, 0))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/* only the first 16 bytes are serialized */
|
||||||
|
if (-1 == mmioWrite(hmmio, (HPCSTR) lpWaveFormat, 16))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (MMSYSERR_NOERROR != mmioAscend(hmmio, &ckWaveFormat, 0))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
lpckWaveData->cksize = 0;
|
||||||
|
lpckWaveData->fccType = 0;
|
||||||
|
lpckWaveData->ckid = mmioFOURCC('d', 'a', 't', 'a');
|
||||||
|
|
||||||
|
/* create data chunk */
|
||||||
|
if (MMSYSERR_NOERROR != mmioCreateChunk(hmmio, lpckWaveData, 0))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
HeapFree(GetProcessHeap(), 0, wmw->lpWaveFormat);
|
||||||
|
return MCIERR_INVALID_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* WAVE_mciOpen [internal]
|
* WAVE_mciOpen [internal]
|
||||||
*/
|
*/
|
||||||
|
@ -267,6 +331,7 @@ static DWORD WAVE_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_PARMSA lpO
|
||||||
DWORD dwRet = 0;
|
DWORD dwRet = 0;
|
||||||
DWORD dwDeviceID;
|
DWORD dwDeviceID;
|
||||||
WINE_MCIWAVE* wmw = (WINE_MCIWAVE*)mciGetDriverData(wDevID);
|
WINE_MCIWAVE* wmw = (WINE_MCIWAVE*)mciGetDriverData(wDevID);
|
||||||
|
CHAR* pszTmpFileName = 0;
|
||||||
|
|
||||||
TRACE("(%04X, %08lX, %p)\n", wDevID, dwFlags, lpOpenParms);
|
TRACE("(%04X, %08lX, %p)\n", wDevID, dwFlags, lpOpenParms);
|
||||||
if (lpOpenParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
|
if (lpOpenParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
|
||||||
|
@ -281,12 +346,14 @@ static DWORD WAVE_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_PARMSA lpO
|
||||||
*/
|
*/
|
||||||
return MCIERR_DEVICE_OPEN;
|
return MCIERR_DEVICE_OPEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
wmw->nUseCount++;
|
wmw->nUseCount++;
|
||||||
|
|
||||||
dwDeviceID = lpOpenParms->wDeviceID;
|
dwDeviceID = lpOpenParms->wDeviceID;
|
||||||
|
|
||||||
wmw->fInput = FALSE;
|
wmw->fInput = FALSE;
|
||||||
wmw->hWave = 0;
|
wmw->hWave = 0;
|
||||||
|
wmw->dwStatus = MCI_MODE_NOT_READY;
|
||||||
|
|
||||||
TRACE("wDevID=%04X (lpParams->wDeviceID=%08lX)\n", wDevID, dwDeviceID);
|
TRACE("wDevID=%04X (lpParams->wDeviceID=%08lX)\n", wDevID, dwDeviceID);
|
||||||
|
|
||||||
|
@ -297,46 +364,101 @@ static DWORD WAVE_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_WAVE_OPEN_PARMSA lpO
|
||||||
*/
|
*/
|
||||||
dwRet = MCIERR_UNRECOGNIZED_COMMAND;
|
dwRet = MCIERR_UNRECOGNIZED_COMMAND;
|
||||||
} else {
|
} else {
|
||||||
LPCSTR lpstrElementName = lpOpenParms->lpstrElementName;
|
if (strlen(lpOpenParms->lpstrElementName) > 0) {
|
||||||
|
lpOpenParms->lpstrElementName = lpOpenParms->lpstrElementName;
|
||||||
/*FIXME : what should be done id wmw->hFile is already != 0, or the driver is playin' */
|
|
||||||
TRACE("MCI_OPEN_ELEMENT '%s' !\n", lpstrElementName);
|
/* FIXME : what should be done id wmw->hFile is already != 0, or the driver is playin' */
|
||||||
if (lpstrElementName && (strlen(lpstrElementName) > 0)) {
|
TRACE("MCI_OPEN_ELEMENT '%s' !\n", lpOpenParms->lpstrElementName);
|
||||||
wmw->hFile = mmioOpenA((LPSTR)lpstrElementName, NULL,
|
|
||||||
MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
|
if (lpOpenParms->lpstrElementName && (strlen(lpOpenParms->lpstrElementName) > 0)) {
|
||||||
if (wmw->hFile == 0) {
|
wmw->hFile = mmioOpenA((LPSTR)lpOpenParms->lpstrElementName, NULL,
|
||||||
WARN("can't find file='%s' !\n", lpstrElementName);
|
MMIO_ALLOCBUF | MMIO_DENYWRITE | MMIO_READWRITE);
|
||||||
dwRet = MCIERR_FILE_NOT_FOUND;
|
|
||||||
|
if (wmw->hFile == 0) {
|
||||||
|
WARN("can't find file='%s' !\n", lpOpenParms->lpstrElementName);
|
||||||
|
dwRet = MCIERR_FILE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LPMMCKINFO lpckMainRIFF = &wmw->ckMainRIFF;
|
||||||
|
|
||||||
|
/* make sure we're are the beginning of the file */
|
||||||
|
mmioSeek(wmw->hFile, 0, SEEK_SET);
|
||||||
|
|
||||||
|
/* first reading of this file. read the waveformat chunk */
|
||||||
|
if (mmioDescend(wmw->hFile, lpckMainRIFF, NULL, 0) != 0) {
|
||||||
|
dwRet = MCIERR_INVALID_FILE;
|
||||||
|
} else {
|
||||||
|
TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
|
||||||
|
(LPSTR)&(lpckMainRIFF->ckid),
|
||||||
|
(LPSTR) &(lpckMainRIFF->fccType),
|
||||||
|
(lpckMainRIFF->cksize));
|
||||||
|
|
||||||
|
if ((lpckMainRIFF->ckid != FOURCC_RIFF) ||
|
||||||
|
lpckMainRIFF->fccType != mmioFOURCC('W', 'A', 'V', 'E')) {
|
||||||
|
dwRet = MCIERR_INVALID_FILE;
|
||||||
|
} else {
|
||||||
|
dwRet = WAVE_mciReadFmt(wmw, lpckMainRIFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wmw->hFile = 0;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
wmw->hFile = 0;
|
else {
|
||||||
}
|
CHAR szTmpPath[MAX_PATH];
|
||||||
|
CHAR szPrefix[4] = "TMP\0";
|
||||||
|
|
||||||
|
pszTmpFileName = HeapAlloc(GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
MAX_PATH * sizeof(*pszTmpFileName));
|
||||||
|
|
||||||
|
if (!GetTempPathA(sizeof(szTmpPath), szTmpPath)) {
|
||||||
|
WARN("can't retrieve temp path!\n");
|
||||||
|
HeapFree(GetProcessHeap(), 0, pszTmpFileName);
|
||||||
|
return MCIERR_FILE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTempFileNameA(szTmpPath, szPrefix, 0, pszTmpFileName)) {
|
||||||
|
WARN("can't retrieve temp file name!\n");
|
||||||
|
HeapFree(GetProcessHeap(), 0, pszTmpFileName);
|
||||||
|
return MCIERR_FILE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
wmw->bTemporaryFile = TRUE;
|
||||||
|
|
||||||
|
TRACE("MCI_OPEN_ELEMENT '%s' !\n", pszTmpFileName);
|
||||||
|
|
||||||
|
if (pszTmpFileName && (strlen(pszTmpFileName) > 0)) {
|
||||||
|
|
||||||
|
wmw->hFile = mmioOpenA(pszTmpFileName, NULL,
|
||||||
|
MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_CREATE);
|
||||||
|
|
||||||
|
if (wmw->hFile == 0) {
|
||||||
|
/* temporary file could not be created. clean filename. */
|
||||||
|
HeapFree(GetProcessHeap(), 0, pszTmpFileName);
|
||||||
|
WARN("can't create file='%s' !\n", pszTmpFileName);
|
||||||
|
dwRet = MCIERR_FILE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("hFile=%u\n", wmw->hFile);
|
TRACE("hFile=%u\n", wmw->hFile);
|
||||||
|
|
||||||
memcpy(&wmw->openParms, lpOpenParms, sizeof(MCI_WAVE_OPEN_PARMSA));
|
memcpy(&wmw->openParms, lpOpenParms, sizeof(MCI_WAVE_OPEN_PARMSA));
|
||||||
wmw->wNotifyDeviceID = dwDeviceID;
|
|
||||||
wmw->dwStatus = MCI_MODE_NOT_READY; /* while loading file contents */
|
if (wmw->bTemporaryFile == TRUE)
|
||||||
|
{
|
||||||
if (dwRet == 0 && wmw->hFile != 0) {
|
/* Additional openParms is temporary file's name */
|
||||||
MMCKINFO ckMainRIFF;
|
wmw->openParms.lpstrElementName = pszTmpFileName;
|
||||||
|
|
||||||
if (mmioDescend(wmw->hFile, &ckMainRIFF, NULL, 0) != 0) {
|
|
||||||
dwRet = MCIERR_INVALID_FILE;
|
|
||||||
} else {
|
|
||||||
TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
|
|
||||||
(LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType, ckMainRIFF.cksize);
|
|
||||||
if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
|
|
||||||
(ckMainRIFF.fccType != mmioFOURCC('W', 'A', 'V', 'E'))) {
|
|
||||||
dwRet = MCIERR_INVALID_FILE;
|
|
||||||
} else {
|
|
||||||
dwRet = WAVE_mciReadFmt(wmw, &ckMainRIFF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
wmw->dwLength = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wmw->wNotifyDeviceID = dwDeviceID;
|
||||||
|
|
||||||
if (dwRet == 0) {
|
if (dwRet == 0) {
|
||||||
if (wmw->lpWaveFormat) {
|
if (wmw->lpWaveFormat) {
|
||||||
switch (wmw->lpWaveFormat->wFormatTag) {
|
switch (wmw->lpWaveFormat->wFormatTag) {
|
||||||
|
@ -475,6 +597,16 @@ static DWORD WAVE_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPar
|
||||||
wmw->hFile = 0;
|
wmw->hFile = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* That string got allocated in mciOpen because no filename was specified
|
||||||
|
* in MCI_OPEN_PARMS stucture. Cast-away const from string since it was
|
||||||
|
* allocated by mciOpen, *NOT* the application.
|
||||||
|
*/
|
||||||
|
if (wmw->bTemporaryFile)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, (CHAR*) wmw->openParms.lpstrElementName);
|
||||||
|
wmw->openParms.lpstrElementName = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, wmw->lpWaveFormat);
|
HeapFree(GetProcessHeap(), 0, wmw->lpWaveFormat);
|
||||||
wmw->lpWaveFormat = NULL;
|
wmw->lpWaveFormat = NULL;
|
||||||
|
@ -535,26 +667,31 @@ static DWORD WAVE_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
|
||||||
LPWAVEHDR waveHdr = NULL;
|
LPWAVEHDR waveHdr = NULL;
|
||||||
WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
|
WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
|
||||||
int whidx;
|
int whidx;
|
||||||
|
|
||||||
TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
|
TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
|
||||||
|
|
||||||
if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
|
if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
|
||||||
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
|
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
|
||||||
|
|
||||||
|
/* FIXME : since there is no way to determine in which mode the device is
|
||||||
|
* open (recording/playback) automatically switch from a mode to another
|
||||||
|
*/
|
||||||
|
wmw->fInput = FALSE;
|
||||||
|
|
||||||
if (wmw->fInput) {
|
if (wmw->fInput) {
|
||||||
WARN("cannot play on input device\n");
|
WARN("cannot play on input device\n");
|
||||||
return MCIERR_NONAPPLICABLE_FUNCTION;
|
return MCIERR_NONAPPLICABLE_FUNCTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wmw->hFile == 0) {
|
if (wmw->hFile == 0) {
|
||||||
WARN("Can't play: no file='%s' !\n", wmw->openParms.lpstrElementName);
|
WARN("Can't play: no file='%s' !\n", wmw->openParms.lpstrElementName);
|
||||||
return MCIERR_FILE_NOT_FOUND;
|
return MCIERR_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wmw->dwStatus == MCI_MODE_PAUSE) {
|
if (wmw->dwStatus == MCI_MODE_PAUSE) {
|
||||||
/* FIXME: parameters (start/end) in lpParams may not be used */
|
/* FIXME: parameters (start/end) in lpParams may not be used */
|
||||||
return WAVE_mciResume(wDevID, dwFlags, (LPMCI_GENERIC_PARMS)lpParms);
|
return WAVE_mciResume(wDevID, dwFlags, (LPMCI_GENERIC_PARMS)lpParms);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This function will be called again by a thread when async is used.
|
/** 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
|
* We have to set MCI_MODE_PLAY before we do this so that the app can spin
|
||||||
|
@ -584,18 +721,43 @@ static DWORD WAVE_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
|
||||||
if (end <= wmw->dwPosition)
|
if (end <= wmw->dwPosition)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
|
||||||
#define WAVE_ALIGN_ON_BLOCK(wmw,v) \
|
#define WAVE_ALIGN_ON_BLOCK(wmw,v) \
|
||||||
((((v) + (wmw)->lpWaveFormat->nBlockAlign - 1) / (wmw)->lpWaveFormat->nBlockAlign) * (wmw)->lpWaveFormat->nBlockAlign)
|
((((v) + (wmw)->lpWaveFormat->nBlockAlign - 1) / (wmw)->lpWaveFormat->nBlockAlign) * (wmw)->lpWaveFormat->nBlockAlign)
|
||||||
|
|
||||||
wmw->dwPosition = WAVE_ALIGN_ON_BLOCK(wmw, wmw->dwPosition);
|
wmw->dwPosition = WAVE_ALIGN_ON_BLOCK(wmw, wmw->dwPosition);
|
||||||
wmw->dwLength = WAVE_ALIGN_ON_BLOCK(wmw, wmw->dwLength);
|
wmw->ckWaveData.cksize = WAVE_ALIGN_ON_BLOCK(wmw, wmw->ckWaveData.cksize);
|
||||||
|
|
||||||
|
if (dwRet == 0) {
|
||||||
|
if (wmw->lpWaveFormat) {
|
||||||
|
switch (wmw->lpWaveFormat->wFormatTag) {
|
||||||
|
case WAVE_FORMAT_PCM:
|
||||||
|
if (wmw->lpWaveFormat->nAvgBytesPerSec !=
|
||||||
|
wmw->lpWaveFormat->nSamplesPerSec * wmw->lpWaveFormat->nBlockAlign) {
|
||||||
|
WARN("Incorrect nAvgBytesPerSec (%ld), setting it to %ld\n",
|
||||||
|
wmw->lpWaveFormat->nAvgBytesPerSec,
|
||||||
|
wmw->lpWaveFormat->nSamplesPerSec *
|
||||||
|
wmw->lpWaveFormat->nBlockAlign);
|
||||||
|
wmw->lpWaveFormat->nAvgBytesPerSec =
|
||||||
|
wmw->lpWaveFormat->nSamplesPerSec *
|
||||||
|
wmw->lpWaveFormat->nBlockAlign;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TRACE("can't retrieve wave format %ld\n", dwRet);
|
||||||
|
goto cleanUp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* go back to begining of chunk plus the requested position */
|
/* go back to begining of chunk plus the requested position */
|
||||||
/* FIXME: I'm not sure this is correct, notably because some data linked to
|
/* FIXME: I'm not sure this is correct, notably because some data linked to
|
||||||
* the decompression state machine will not be correcly initialized.
|
* the decompression state machine will not be correcly initialized.
|
||||||
* try it this way (other way would be to decompress from 0 up to dwPosition
|
* try it this way (other way would be to decompress from 0 up to dwPosition
|
||||||
* and to start sending to hWave when dwPosition is reached)
|
* and to start sending to hWave when dwPosition is reached)
|
||||||
*/
|
*/
|
||||||
mmioSeek(wmw->hFile, wmw->dwFileOffset + wmw->dwPosition, SEEK_SET); /* >= 0 */
|
mmioSeek(wmw->hFile, wmw->ckWaveData.dwDataOffset + wmw->dwPosition, SEEK_SET); /* >= 0 */
|
||||||
|
|
||||||
/* By default the device will be opened for output, the MCI_CUE function is there to
|
/* By default the device will be opened for output, the MCI_CUE function is there to
|
||||||
* change from output to input and back
|
* change from output to input and back
|
||||||
|
@ -628,7 +790,7 @@ static DWORD WAVE_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
|
||||||
}
|
}
|
||||||
|
|
||||||
whidx = 0;
|
whidx = 0;
|
||||||
left = min(wmw->dwLength, end - wmw->dwPosition);
|
left = min(wmw->ckWaveData.cksize, end - wmw->dwPosition);
|
||||||
wmw->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
|
wmw->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||||
wmw->dwEventCount = 1L; /* for first buffer */
|
wmw->dwEventCount = 1L; /* for first buffer */
|
||||||
|
|
||||||
|
@ -687,64 +849,212 @@ cleanUp:
|
||||||
return dwRet;
|
return dwRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* WAVE_mciPlayCallback [internal]
|
||||||
|
*/
|
||||||
|
static void CALLBACK WAVE_mciRecordCallback(HWAVEOUT hwo, UINT uMsg,
|
||||||
|
DWORD dwInstance,
|
||||||
|
DWORD dwParam1, DWORD dwParam2)
|
||||||
|
{
|
||||||
|
WINE_MCIWAVE* wmw = (WINE_MCIWAVE*)dwInstance;
|
||||||
|
LPWAVEHDR lpWaveHdr = NULL;
|
||||||
|
LONG count = 0;
|
||||||
|
switch (uMsg) {
|
||||||
|
case WIM_OPEN:
|
||||||
|
case WIM_CLOSE:
|
||||||
|
break;
|
||||||
|
case WIM_DATA:
|
||||||
|
lpWaveHdr = (LPWAVEHDR) dwParam1;
|
||||||
|
|
||||||
|
InterlockedIncrement(&wmw->dwEventCount);
|
||||||
|
|
||||||
|
count = mmioWrite(wmw->hFile, lpWaveHdr->lpData, lpWaveHdr->dwBytesRecorded);
|
||||||
|
|
||||||
|
lpWaveHdr->dwFlags &= ~WHDR_DONE;
|
||||||
|
wmw->dwPosition += count;
|
||||||
|
wmw->dwRemaining -= count;
|
||||||
|
|
||||||
|
waveInAddBuffer(wmw->hWave, lpWaveHdr, sizeof(*lpWaveHdr));
|
||||||
|
TRACE("after mmioWrite dwPosition=%lu\n", wmw->dwPosition);
|
||||||
|
|
||||||
|
SetEvent(wmw->hEvent);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ERR("Unknown uMsg=%d\n", uMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WAVE_mciRecordWaitDone(WINE_MCIWAVE* wmw)
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
ResetEvent(wmw->hEvent);
|
||||||
|
if (InterlockedDecrement(&wmw->dwEventCount) >= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
InterlockedIncrement(&wmw->dwEventCount);
|
||||||
|
|
||||||
|
WaitForSingleObject(wmw->hEvent, INFINITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* WAVE_mciRecord [internal]
|
* WAVE_mciRecord [internal]
|
||||||
*/
|
*/
|
||||||
static DWORD WAVE_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
|
static DWORD WAVE_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
|
||||||
{
|
{
|
||||||
int start, end;
|
DWORD end;
|
||||||
LONG bufsize;
|
DWORD dwRet = 0;
|
||||||
WAVEHDR waveHdr;
|
LONG bufsize;
|
||||||
DWORD dwRet;
|
LPWAVEHDR waveHdr = NULL;
|
||||||
WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
|
WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
|
||||||
|
|
||||||
|
|
||||||
TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
|
TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);
|
||||||
|
|
||||||
if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
|
if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
|
||||||
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
|
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
|
||||||
|
|
||||||
|
/* FIXME : since there is no way to determine in which mode the device is
|
||||||
|
* open (recording/playback) automatically switch from a mode to another
|
||||||
|
*/
|
||||||
|
wmw->fInput = TRUE;
|
||||||
|
|
||||||
if (!wmw->fInput) {
|
if (!wmw->fInput) {
|
||||||
WARN("cannot record on output device\n");
|
WARN("cannot record on output device\n");
|
||||||
return MCIERR_NONAPPLICABLE_FUNCTION;
|
return MCIERR_NONAPPLICABLE_FUNCTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wmw->dwStatus == MCI_MODE_PAUSE) {
|
||||||
|
/* FIXME: parameters (start/end) in lpParams may not be used */
|
||||||
|
return WAVE_mciResume(wDevID, dwFlags, (LPMCI_GENERIC_PARMS)lpParms);
|
||||||
|
}
|
||||||
|
|
||||||
if (wmw->hFile == 0) {
|
/** This function will be called again by a thread when async is used.
|
||||||
WARN("can't find file='%s' !\n",
|
* We have to set MCI_MODE_PLAY before we do this so that the app can spin
|
||||||
wmw->openParms.lpstrElementName);
|
* on MCI_STATUS, so we have to allow it here if we're not going to start this thread.
|
||||||
return MCIERR_FILE_NOT_FOUND;
|
*/
|
||||||
|
if ((wmw->dwStatus != MCI_MODE_STOP) && ((wmw->dwStatus != MCI_MODE_RECORD) && (dwFlags & MCI_WAIT))) {
|
||||||
|
return MCIERR_INTERNAL;
|
||||||
}
|
}
|
||||||
start = 1; end = 99999;
|
|
||||||
if (dwFlags & MCI_FROM) {
|
|
||||||
start = lpParms->dwFrom;
|
|
||||||
TRACE("MCI_FROM=%d \n", start);
|
|
||||||
}
|
|
||||||
if (dwFlags & MCI_TO) {
|
|
||||||
end = lpParms->dwTo;
|
|
||||||
TRACE("MCI_TO=%d \n", end);
|
|
||||||
}
|
|
||||||
bufsize = 64000;
|
|
||||||
waveHdr.lpData = HeapAlloc(GetProcessHeap(), 0, bufsize);
|
|
||||||
waveHdr.dwBufferLength = bufsize;
|
|
||||||
waveHdr.dwUser = 0L;
|
|
||||||
waveHdr.dwFlags = 0L;
|
|
||||||
waveHdr.dwLoops = 0L;
|
|
||||||
dwRet = waveInPrepareHeader(wmw->hWave, &waveHdr, sizeof(WAVEHDR));
|
|
||||||
|
|
||||||
for (;;) { /* FIXME: I don't see any waveInAddBuffer ? */
|
wmw->dwStatus = MCI_MODE_RECORD;
|
||||||
waveHdr.dwBytesRecorded = 0;
|
|
||||||
dwRet = waveInStart(wmw->hWave);
|
if (!(dwFlags & MCI_WAIT)) {
|
||||||
TRACE("waveInStart => lpWaveHdr=%p dwBytesRecorded=%lu\n",
|
return MCI_SendCommandAsync(wmw->wNotifyDeviceID, MCI_RECORD, dwFlags,
|
||||||
&waveHdr, waveHdr.dwBytesRecorded);
|
(DWORD)lpParms, sizeof(MCI_RECORD_PARMS));
|
||||||
if (waveHdr.dwBytesRecorded == 0) break;
|
|
||||||
}
|
}
|
||||||
dwRet = waveInUnprepareHeader(wmw->hWave, &waveHdr, sizeof(WAVEHDR));
|
|
||||||
HeapFree(GetProcessHeap(), 0, waveHdr.lpData);
|
|
||||||
|
|
||||||
if (dwFlags & MCI_NOTIFY) {
|
if (!wmw->lpWaveFormat)
|
||||||
|
{
|
||||||
|
/* new RIFF file */
|
||||||
|
dwRet = WAVE_mciCreateRIFFSkeleton(wmw);
|
||||||
|
}
|
||||||
|
|
||||||
|
end = 0xFFFFFFFF;
|
||||||
|
if (lpParms && (dwFlags & MCI_FROM)) {
|
||||||
|
wmw->dwPosition = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwFrom);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpParms && (dwFlags & MCI_TO)) {
|
||||||
|
end = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("Recording from byte=%lu to byte=%lu\n", wmw->dwPosition, end);
|
||||||
|
|
||||||
|
if (end <= wmw->dwPosition)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WAVE_ALIGN_ON_BLOCK(wmw,v) \
|
||||||
|
((((v) + (wmw)->lpWaveFormat->nBlockAlign - 1) / (wmw)->lpWaveFormat->nBlockAlign) * (wmw)->lpWaveFormat->nBlockAlign)
|
||||||
|
|
||||||
|
wmw->dwPosition = WAVE_ALIGN_ON_BLOCK(wmw, wmw->dwPosition);
|
||||||
|
wmw->ckWaveData.cksize = WAVE_ALIGN_ON_BLOCK(wmw, wmw->ckWaveData.cksize);
|
||||||
|
|
||||||
|
/* go back to begining of chunk plus the requested position */
|
||||||
|
/* FIXME: I'm not sure this is correct, notably because some data linked to
|
||||||
|
* the decompression state machine will not be correcly initialized.
|
||||||
|
* try it this way (other way would be to decompress from 0 up to dwPosition
|
||||||
|
* and to start sending to hWave when dwPosition is reached)
|
||||||
|
*/
|
||||||
|
mmioSeek(wmw->hFile, wmw->ckWaveData.dwDataOffset + wmw->dwPosition, SEEK_SET); /* >= 0 */
|
||||||
|
|
||||||
|
/* By default the device will be opened for output, the MCI_CUE function is there to
|
||||||
|
* change from output to input and back
|
||||||
|
*/
|
||||||
|
/* FIXME: how to choose between several output channels ? here mapper is forced */
|
||||||
|
dwRet = waveInOpen(&wmw->hWave, WAVE_MAPPER, wmw->lpWaveFormat,
|
||||||
|
(DWORD)WAVE_mciRecordCallback, (DWORD)wmw, CALLBACK_FUNCTION);
|
||||||
|
|
||||||
|
if (dwRet != 0) {
|
||||||
|
TRACE("Can't open low level audio device %ld\n", dwRet);
|
||||||
|
dwRet = MCIERR_DEVICE_OPEN;
|
||||||
|
wmw->hWave = 0;
|
||||||
|
goto cleanUp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make it so that 3 buffers per second are needed */
|
||||||
|
bufsize = WAVE_ALIGN_ON_BLOCK(wmw, wmw->lpWaveFormat->nAvgBytesPerSec / 3);
|
||||||
|
|
||||||
|
waveHdr = HeapAlloc(GetProcessHeap(), 0, 2 * sizeof(WAVEHDR) + 2 * bufsize);
|
||||||
|
waveHdr[0].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR);
|
||||||
|
waveHdr[1].lpData = (char*)waveHdr + 2 * sizeof(WAVEHDR) + bufsize;
|
||||||
|
waveHdr[0].dwUser = waveHdr[1].dwUser = 0L;
|
||||||
|
waveHdr[0].dwLoops = waveHdr[1].dwLoops = 0L;
|
||||||
|
waveHdr[0].dwFlags = waveHdr[1].dwFlags = 0L;
|
||||||
|
waveHdr[0].dwBufferLength = waveHdr[1].dwBufferLength = bufsize;
|
||||||
|
|
||||||
|
if (waveInPrepareHeader(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
|
||||||
|
waveInPrepareHeader(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR))) {
|
||||||
|
dwRet = MCIERR_INTERNAL;
|
||||||
|
goto cleanUp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (waveInAddBuffer(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR)) ||
|
||||||
|
waveInAddBuffer(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR))) {
|
||||||
|
dwRet = MCIERR_INTERNAL;
|
||||||
|
goto cleanUp;
|
||||||
|
}
|
||||||
|
|
||||||
|
wmw->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||||
|
wmw->dwEventCount = 1L; /* for first buffer */
|
||||||
|
|
||||||
|
wmw->dwRemaining = end - wmw->dwPosition;
|
||||||
|
|
||||||
|
TRACE("Recording (normalized) from byte=%lu for %lu bytes\n", wmw->dwPosition, wmw->dwRemaining);
|
||||||
|
|
||||||
|
dwRet = waveInStart(wmw->hWave);
|
||||||
|
|
||||||
|
while ( wmw->dwRemaining > 0 && wmw->dwStatus != MCI_MODE_STOP && wmw->dwStatus != MCI_MODE_NOT_READY) {
|
||||||
|
WAVE_mciRecordWaitDone(wmw);
|
||||||
|
}
|
||||||
|
|
||||||
|
waveInReset(wmw->hWave);
|
||||||
|
waveInUnprepareHeader(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR));
|
||||||
|
waveInUnprepareHeader(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR));
|
||||||
|
|
||||||
|
dwRet = 0;
|
||||||
|
|
||||||
|
cleanUp:
|
||||||
|
HeapFree(GetProcessHeap(), 0, waveHdr);
|
||||||
|
|
||||||
|
if (wmw->hWave) {
|
||||||
|
waveInClose(wmw->hWave);
|
||||||
|
wmw->hWave = 0;
|
||||||
|
}
|
||||||
|
CloseHandle(wmw->hEvent);
|
||||||
|
|
||||||
|
if (lpParms && (dwFlags & MCI_NOTIFY)) {
|
||||||
mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
|
mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
|
||||||
wmw->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
|
wmw->wNotifyDeviceID,
|
||||||
|
dwRet ? MCI_NOTIFY_FAILURE : MCI_NOTIFY_SUCCESSFUL);
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
wmw->dwStatus = MCI_MODE_STOP;
|
||||||
|
|
||||||
|
return dwRet;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -811,7 +1121,7 @@ static DWORD WAVE_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
|
||||||
if (dwFlags & MCI_SEEK_TO_START) {
|
if (dwFlags & MCI_SEEK_TO_START) {
|
||||||
wmw->dwPosition = 0;
|
wmw->dwPosition = 0;
|
||||||
} else if (dwFlags & MCI_SEEK_TO_END) {
|
} else if (dwFlags & MCI_SEEK_TO_END) {
|
||||||
wmw->dwPosition = wmw->dwLength;
|
wmw->dwPosition = wmw->ckWaveData.cksize;
|
||||||
} else if (dwFlags & MCI_TO) {
|
} else if (dwFlags & MCI_TO) {
|
||||||
wmw->dwPosition = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwTo);
|
wmw->dwPosition = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwTo);
|
||||||
} else {
|
} else {
|
||||||
|
@ -912,6 +1222,45 @@ static DWORD WAVE_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* WAVE_mciSave [internal]
|
||||||
|
*/
|
||||||
|
static DWORD WAVE_mciSave(UINT wDevID, DWORD dwFlags, LPMCI_SAVE_PARMS lpParms)
|
||||||
|
{
|
||||||
|
WINE_MCIWAVE* wmw = WAVE_mciGetOpenDev(wDevID);
|
||||||
|
DWORD ret = MCIERR_FILE_NOT_SAVED;
|
||||||
|
WPARAM wparam = MCI_NOTIFY_FAILURE;
|
||||||
|
|
||||||
|
TRACE("%d, %08lX, %p);\n", wDevID, dwFlags, lpParms);
|
||||||
|
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
|
||||||
|
if (wmw == NULL) return MCIERR_INVALID_DEVICE_ID;
|
||||||
|
|
||||||
|
if (dwFlags & MCI_WAIT)
|
||||||
|
{
|
||||||
|
FIXME("MCI_WAIT not implemented\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = mmioAscend(wmw->hFile, &wmw->ckWaveData, 0);
|
||||||
|
ret = mmioAscend(wmw->hFile, &wmw->ckMainRIFF, 0);
|
||||||
|
|
||||||
|
|
||||||
|
ret = mmioClose(wmw->hFile, 0);
|
||||||
|
|
||||||
|
if (0 == mmioRenameA(wmw->openParms.lpstrElementName, lpParms->lpfilename, 0, 0 )) {
|
||||||
|
ret = ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dwFlags & MCI_NOTIFY) {
|
||||||
|
if (ret == ERROR_SUCCESS) wparam = MCI_NOTIFY_SUCCESSFUL;
|
||||||
|
|
||||||
|
mciDriverNotify( (HWND) LOWORD(lpParms->dwCallback),
|
||||||
|
wmw->wNotifyDeviceID,
|
||||||
|
wparam);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* WAVE_mciStatus [internal]
|
* WAVE_mciStatus [internal]
|
||||||
*/
|
*/
|
||||||
|
@ -936,7 +1285,7 @@ static DWORD WAVE_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpPar
|
||||||
return MCIERR_UNSUPPORTED_FUNCTION;
|
return MCIERR_UNSUPPORTED_FUNCTION;
|
||||||
}
|
}
|
||||||
/* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
|
/* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
|
||||||
lpParms->dwReturn = WAVE_ConvertByteToTimeFormat(wmw, wmw->dwLength, &ret);
|
lpParms->dwReturn = WAVE_ConvertByteToTimeFormat(wmw, wmw->ckWaveData.cksize, &ret);
|
||||||
TRACE("MCI_STATUS_LENGTH => %lu\n", lpParms->dwReturn);
|
TRACE("MCI_STATUS_LENGTH => %lu\n", lpParms->dwReturn);
|
||||||
break;
|
break;
|
||||||
case MCI_STATUS_MODE:
|
case MCI_STATUS_MODE:
|
||||||
|
@ -1209,9 +1558,9 @@ LONG CALLBACK MCIWAVE_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg,
|
||||||
case MCI_GETDEVCAPS: return WAVE_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS) dwParam2);
|
case MCI_GETDEVCAPS: return WAVE_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS) dwParam2);
|
||||||
case MCI_INFO: return WAVE_mciInfo (dwDevID, dwParam1, (LPMCI_INFO_PARMSA) dwParam2);
|
case MCI_INFO: return WAVE_mciInfo (dwDevID, dwParam1, (LPMCI_INFO_PARMSA) dwParam2);
|
||||||
case MCI_SEEK: return WAVE_mciSeek (dwDevID, dwParam1, (LPMCI_SEEK_PARMS) dwParam2);
|
case MCI_SEEK: return WAVE_mciSeek (dwDevID, dwParam1, (LPMCI_SEEK_PARMS) dwParam2);
|
||||||
|
case MCI_SAVE: return WAVE_mciSave (dwDevID, dwParam1, (LPMCI_SAVE_PARMS) dwParam2);
|
||||||
/* commands that should be supported */
|
/* commands that should be supported */
|
||||||
case MCI_LOAD:
|
case MCI_LOAD:
|
||||||
case MCI_SAVE:
|
|
||||||
case MCI_FREEZE:
|
case MCI_FREEZE:
|
||||||
case MCI_PUT:
|
case MCI_PUT:
|
||||||
case MCI_REALIZE:
|
case MCI_REALIZE:
|
||||||
|
|
Loading…
Reference in New Issue