⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mciwave.c

📁 Wine-20031016
💻 C
📖 第 1 页 / 共 4 页
字号:
	TRACE("after WODM_WRITE dwPosition=%lu\n", wmw->dwPosition);	WAVE_mciPlayWaitDone(wmw);	whidx ^= 1;    }    WAVE_mciPlayWaitDone(wmw); /* to balance first buffer */    /* just to get rid of some race conditions between play, stop and pause */    waveOutReset(wmw->hWave);    waveOutUnprepareHeader(wmw->hWave, &waveHdr[0], sizeof(WAVEHDR));    waveOutUnprepareHeader(wmw->hWave, &waveHdr[1], sizeof(WAVEHDR));    dwRet = 0;cleanUp:    HeapFree(GetProcessHeap(), 0, waveHdr);    if (wmw->hWave) {	waveOutClose(wmw->hWave);	wmw->hWave = 0;    }    CloseHandle(wmw->hEvent);    if (lpParms && (dwFlags & MCI_NOTIFY)) {	mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),			wmw->openParms.wDeviceID,			dwRet ? MCI_NOTIFY_FAILURE : MCI_NOTIFY_SUCCESSFUL);    }    wmw->dwStatus = MCI_MODE_STOP;    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;    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;        if (count > 0)            wmw->dwPosition  += count;        /* else error reporting ?? */        if (wmw->dwStatus == MCI_MODE_RECORD)        {           /* Only queue up another buffer if we are recording.  We could receive this              message also when waveInReset() is called, since it notifies on all wave              buffers that are outstanding.  Queueing up more sometimes causes waveInClose              to fail. */           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);    }}/****************************************************************** *		bWAVE_mciRecordWaitDone * */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] */static DWORD WAVE_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms){    DWORD		end;    DWORD		dwRet = MMSYSERR_NOERROR;    LONG		bufsize;    LPWAVEHDR		waveHdr = NULL;    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);    TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);    if (wmw == NULL)		return MCIERR_INVALID_DEVICE_ID;    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) {	WARN("cannot record on output device\n");	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);    }    /** 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.     */    if ((wmw->dwStatus != MCI_MODE_STOP) && ((wmw->dwStatus != MCI_MODE_RECORD) && (dwFlags & MCI_WAIT))) {	return MCIERR_INTERNAL;    }    wmw->dwStatus = MCI_MODE_RECORD;    if (!(dwFlags & MCI_WAIT)) {	return MCI_SendCommandAsync(wmw->openParms.wDeviceID, MCI_RECORD, dwFlags,				    (DWORD)lpParms, sizeof(MCI_RECORD_PARMS));    }    if (!wmw->lpWaveFormat) {        /* new RIFF file */        dwRet = WAVE_mciCreateRIFFSkeleton(wmw);    } else {	FIXME("Should descend into data chunk. Please report.\n");    }    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 beginning 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((HWAVEIN*)&wmw->hWave, WAVE_MAPPER, wmw->lpWaveFormat,			(DWORD)WAVE_mciRecordCallback, (DWORD)wmw, CALLBACK_FUNCTION);    if (dwRet != MMSYSERR_NOERROR) {	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 */    TRACE("Recording (normalized) from byte=%lu for %lu bytes\n", wmw->dwPosition, end - wmw->dwPosition);    dwRet = waveInStart(wmw->hWave);    while (wmw->dwPosition < end && wmw->dwStatus != MCI_MODE_STOP && wmw->dwStatus != MCI_MODE_NOT_READY) {	WAVE_mciRecordWaitDone(wmw);    }    /* needed so that the callback above won't add again the buffers returned by the reset */    wmw->dwStatus = MCI_MODE_STOP;    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);    /* need to update the size of the data chunk */    if (mmioAscend(wmw->hFile, &wmw->ckWaveData, 0) != MMSYSERR_NOERROR) {	TRACE("failed on ascend\n");    }    if (lpParms && (dwFlags & MCI_NOTIFY)) {	mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),			wmw->openParms.wDeviceID,			dwRet ? MCI_NOTIFY_FAILURE : MCI_NOTIFY_SUCCESSFUL);    }    wmw->dwStatus = MCI_MODE_STOP;    return dwRet;}/************************************************************************** * 				WAVE_mciPause			[internal] */static DWORD WAVE_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms){    DWORD 		dwRet;    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);    TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);    if (lpParms == NULL)	return MCIERR_NULL_PARAMETER_BLOCK;    if (wmw == NULL)		return MCIERR_INVALID_DEVICE_ID;    if (wmw->dwStatus == MCI_MODE_PLAY) {	wmw->dwStatus = MCI_MODE_PAUSE;    }    if (wmw->fInput)	dwRet = waveInStop(wmw->hWave);    else		dwRet = waveOutPause(wmw->hWave);    return (dwRet == MMSYSERR_NOERROR) ? 0 : MCIERR_INTERNAL;}/************************************************************************** * 				WAVE_mciResume			[internal] */static DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms){    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);    DWORD		dwRet = 0;    TRACE("(%u, %08lX, %p);\n", wDevID, dwFlags, lpParms);    if (wmw == NULL)		return MCIERR_INVALID_DEVICE_ID;    if (wmw->dwStatus == MCI_MODE_PAUSE) {	wmw->dwStatus = MCI_MODE_PLAY;    }    if (wmw->fInput)	dwRet = waveInStart(wmw->hWave);    else		dwRet = waveOutRestart(wmw->hWave);    return (dwRet == MMSYSERR_NOERROR) ? 0 : MCIERR_INTERNAL;}/************************************************************************** * 				WAVE_mciSeek			[internal] */static DWORD WAVE_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms){    DWORD		ret = 0;    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);    TRACE("(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);    if (lpParms == NULL) {	ret = MCIERR_NULL_PARAMETER_BLOCK;    } else if (wmw == NULL) {	ret = MCIERR_INVALID_DEVICE_ID;    } else {	WAVE_mciStop(wDevID, MCI_WAIT, 0);	if (dwFlags & MCI_SEEK_TO_START) {	    wmw->dwPosition = 0;	} else if (dwFlags & MCI_SEEK_TO_END) {	    wmw->dwPosition = wmw->ckWaveData.cksize;	} else if (dwFlags & MCI_TO) {	    wmw->dwPosition = WAVE_ConvertTimeFormatToByte(wmw, lpParms->dwTo);	} else {	    WARN("dwFlag doesn't tell where to seek to...\n");	    return MCIERR_MISSING_PARAMETER;	}	TRACE("Seeking to position=%lu bytes\n", wmw->dwPosition);	if (dwFlags & MCI_NOTIFY) {	    mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),			    wmw->openParms.wDeviceID, MCI_NOTIFY_SUCCESSFUL);	}    }    return ret;}/************************************************************************** * 				WAVE_mciSet			[internal] */static DWORD WAVE_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms){    WINE_MCIWAVE*	wmw = WAVE_mciGetOpenDev(wDevID);    TRACE("(%u, %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_SET_TIME_FORMAT) {	switch (lpParms->dwTimeFormat) {	case MCI_FORMAT_MILLISECONDS:	    TRACE("MCI_FORMAT_MILLISECONDS !\n");	    wmw->dwMciTimeFormat = MCI_FORMAT_MILLISECONDS;	    break;	case MCI_FORMAT_BYTES:	    TRACE("MCI_FORMAT_BYTES !\n");	    wmw->dwMciTimeFormat = MCI_FORMAT_BYTES;	    break;	case MCI_FORMAT_SAMPLES:	    TRACE("MCI_FORMAT_SAMPLES !\n");	    wmw->dwMciTimeFormat = MCI_FORMAT_SAMPLES;	    break;	default:	    WARN("Bad time format %lu!\n", lpParms->dwTimeFormat);	    return MCIERR_BAD_TIME_FORMAT;	}    }    if (dwFlags & MCI_SET_VIDEO) {	TRACE("No support for video !\n");	return MCIERR_UNSUPPORTED_FUNCTION;    }    if (dwFlags & MCI_SET_DOOR_OPEN) {	TRACE("No support for door open !\n");	return MCIERR_UNSUPPORTED_FUNCTION;    }    if (dwFlags & MCI_SET_DOOR_CLOSED) {	TRACE("No support for door close !\n");	return MCIERR_UNSUPPORTED_FUNCTION;    }    if (dwFlags & MCI_SET_AUDIO) {	if (dwFlags & MCI_SET_ON) {	    TRACE("MCI_SET_ON audio !\n");	} else if (dwFlags & MCI_SET_OFF) {	    TRACE("MCI_SET_OFF audio !\n");	} else {	    WARN("MCI_SET_AUDIO without SET_ON or SET_OFF\n");	    return MCIERR_BAD_INTEGER;	}	if (lpParms->dwAudio & MCI_SET_AUDIO_ALL)	    TRACE("MCI_SET_AUDIO_ALL !\n");	if (lpParms->dwAudio & MCI_SET_AUDIO_LEFT)	    TRACE("MCI_SET_AUDIO_LEFT !\n");	if (lpParms->dwAudio & MCI_SET_AUDIO_RIGHT)	    TRACE("MCI_SET_AUDIO_RIGHT !\n");    }    if (dwFlags & MCI_WAVE_INPUT)	TRACE("MCI_WAVE_INPUT !\n");    if (dwFlags & MCI_WAVE_OUTPUT)	TRACE("MCI_WAVE_OUTPUT !\n");    if (dwFlags & MCI_WAVE_SET_ANYINPUT)	TRACE("MCI_WAVE_SET_ANYINPUT !\n");    if (dwFlags & MCI_WAVE_SET_ANYOUTPUT)	TRACE("MCI_WAVE_SET_ANYOUTPUT !\n");    if (dwFlags & MCI_WAVE_SET_AVGBYTESPERSEC) {	wmw->wfxRef.nAvgBytesPerSec = ((LPMCI_WAVE_SET_PARMS)lpParms)->nAvgBytesPerSec;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -