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

📄 wavemap.c

📁 Wine-20031016
💻 C
📖 第 1 页 / 共 3 页
字号:
    ash->dwUser = (DWORD)lpWaveHdrSrc;    ash->pbSrc = lpWaveHdrSrc->lpData;    ash->cbSrcLength = lpWaveHdrSrc->dwBufferLength;    /* ash->cbSrcLengthUsed */    ash->dwSrcUser = lpWaveHdrSrc->dwUser; /* FIXME ? */    ash->pbDst = (LPSTR)ash + sizeof(ACMSTREAMHEADER) + sizeof(WAVEHDR);    ash->cbDstLength = size;    /* ash->cbDstLengthUsed */    ash->dwDstUser = 0; /* FIXME ? */    dwRet = acmStreamPrepareHeader(wom->hAcmStream, ash, 0L);    if (dwRet != MMSYSERR_NOERROR)	goto errCleanUp;    lpWaveHdrDst = (LPWAVEHDR)((LPSTR)ash + sizeof(ACMSTREAMHEADER));    lpWaveHdrDst->lpData = ash->pbDst;    lpWaveHdrDst->dwBufferLength = size; /* conversion is not done yet */    lpWaveHdrDst->dwFlags = 0;    lpWaveHdrDst->dwLoops = 0;    dwRet = waveOutPrepareHeader(wom->u.out.hInnerWave, lpWaveHdrDst, sizeof(*lpWaveHdrDst));    if (dwRet != MMSYSERR_NOERROR)	goto errCleanUp;    lpWaveHdrSrc->reserved = (DWORD)ash;    lpWaveHdrSrc->dwFlags = WHDR_PREPARED;    TRACE("=> (0)\n");    return MMSYSERR_NOERROR;errCleanUp:    TRACE("=> (%ld)\n", dwRet);    HeapFree(GetProcessHeap(), 0, ash);    return dwRet;}static	DWORD	wodUnprepare(WAVEMAPDATA* wom, LPWAVEHDR lpWaveHdrSrc, DWORD dwParam2){    PACMSTREAMHEADER	ash;    LPWAVEHDR		lpWaveHdrDst;    DWORD		dwRet1, dwRet2;    if (!wom->hAcmStream) {	return waveOutUnprepareHeader(wom->u.out.hInnerWave, lpWaveHdrSrc, dwParam2);    }    ash = (PACMSTREAMHEADER)lpWaveHdrSrc->reserved;    dwRet1 = acmStreamUnprepareHeader(wom->hAcmStream, ash, 0L);    lpWaveHdrDst = (LPWAVEHDR)((LPSTR)ash + sizeof(ACMSTREAMHEADER));    dwRet2 = waveOutUnprepareHeader(wom->u.out.hInnerWave, lpWaveHdrDst, sizeof(*lpWaveHdrDst));    HeapFree(GetProcessHeap(), 0, ash);    lpWaveHdrSrc->dwFlags &= ~WHDR_PREPARED;    return (dwRet1 == MMSYSERR_NOERROR) ? dwRet2 : dwRet1;}static	DWORD	wodGetPosition(WAVEMAPDATA* wom, LPMMTIME lpTime, DWORD dwParam2){    DWORD       val = waveOutGetPosition(wom->u.out.hInnerWave, lpTime, dwParam2);    if (lpTime->wType == TIME_BYTES)        lpTime->u.cb = MulDiv(lpTime->u.cb, wom->avgSpeedOuter, wom->avgSpeedInner);    /* other time types don't require conversion */    return val;}static	DWORD	wodGetDevCaps(UINT wDevID, WAVEMAPDATA* wom, LPWAVEOUTCAPSA lpWaveCaps, DWORD dwParam2){    /* if opened low driver, forward message */    if (WAVEMAP_IsData(wom))	return waveOutGetDevCapsA((UINT)wom->u.out.hInnerWave, lpWaveCaps, dwParam2);    /* otherwise, return caps of mapper itself */    if (wDevID == (UINT)-1 || wDevID == (UINT16)-1) {	lpWaveCaps->wMid = 0x00FF;	lpWaveCaps->wPid = 0x0001;	lpWaveCaps->vDriverVersion = 0x0100;	strcpy(lpWaveCaps->szPname, "Wine wave out mapper");	lpWaveCaps->dwFormats =	    WAVE_FORMAT_4M08 | WAVE_FORMAT_4S08 | WAVE_FORMAT_4M16 | WAVE_FORMAT_4S16 |	    WAVE_FORMAT_2M08 | WAVE_FORMAT_2S08 | WAVE_FORMAT_2M16 | WAVE_FORMAT_2S16 |	    WAVE_FORMAT_1M08 | WAVE_FORMAT_1S08 | WAVE_FORMAT_1M16 | WAVE_FORMAT_1S16;	lpWaveCaps->wChannels = 2;	lpWaveCaps->dwSupport = WAVECAPS_VOLUME | WAVECAPS_LRVOLUME;	return MMSYSERR_NOERROR;    }    ERR("This shouldn't happen\n");    return MMSYSERR_ERROR;}static	DWORD	wodGetVolume(UINT wDevID, WAVEMAPDATA* wom, LPDWORD lpVol){    if (WAVEMAP_IsData(wom))	return waveOutGetVolume(wom->u.out.hInnerWave, lpVol);    return MMSYSERR_NOERROR;}static	DWORD	wodSetVolume(UINT wDevID, WAVEMAPDATA* wom, DWORD vol){    if (WAVEMAP_IsData(wom))	return waveOutSetVolume(wom->u.out.hInnerWave, vol);    return MMSYSERR_NOERROR;}static	DWORD	wodPause(WAVEMAPDATA* wom){    return waveOutPause(wom->u.out.hInnerWave);}static	DWORD	wodRestart(WAVEMAPDATA* wom){    return waveOutRestart(wom->u.out.hInnerWave);}static	DWORD	wodReset(WAVEMAPDATA* wom){    return waveOutReset(wom->u.out.hInnerWave);}static	DWORD	wodBreakLoop(WAVEMAPDATA* wom){    return waveOutBreakLoop(wom->u.out.hInnerWave);}static  DWORD	wodMapperStatus(WAVEMAPDATA* wom, DWORD flags, LPVOID ptr){    UINT	id;    DWORD	ret = MMSYSERR_NOTSUPPORTED;    switch (flags) {    case WAVEOUT_MAPPER_STATUS_DEVICE:	ret = waveOutGetID(wom->u.out.hInnerWave, &id);	*(LPDWORD)ptr = id;	break;    case WAVEOUT_MAPPER_STATUS_MAPPED:	FIXME("Unsupported flag=%ld\n", flags);	*(LPDWORD)ptr = 0; /* FIXME ?? */	break;    case WAVEOUT_MAPPER_STATUS_FORMAT:	FIXME("Unsupported flag=%ld\n", flags);	/* ptr points to a WAVEFORMATEX struct - before or after streaming ? */	*(LPDWORD)ptr = 0;	break;    default:	FIXME("Unsupported flag=%ld\n", flags);	*(LPDWORD)ptr = 0;	break;    }    return ret;}/************************************************************************** * 				wodMessage (MSACM.@) */DWORD WINAPI WAVEMAP_wodMessage(UINT wDevID, UINT wMsg, DWORD dwUser,				DWORD dwParam1, DWORD dwParam2){    TRACE("(%u, %04X, %08lX, %08lX, %08lX);\n",	  wDevID, wMsg, dwUser, dwParam1, dwParam2);    switch (wMsg) {    case DRVM_INIT:    case DRVM_EXIT:    case DRVM_ENABLE:    case DRVM_DISABLE:	/* FIXME: Pretend this is supported */	return 0;    case WODM_OPEN:	 	return wodOpen		((LPDWORD)dwUser,      (LPWAVEOPENDESC)dwParam1,dwParam2);    case WODM_CLOSE:	 	return wodClose		((WAVEMAPDATA*)dwUser);    case WODM_WRITE:	 	return wodWrite		((WAVEMAPDATA*)dwUser, (LPWAVEHDR)dwParam1,	dwParam2);    case WODM_PAUSE:	 	return wodPause		((WAVEMAPDATA*)dwUser);    case WODM_GETPOS:	 	return wodGetPosition	((WAVEMAPDATA*)dwUser, (LPMMTIME)dwParam1, 	dwParam2);    case WODM_BREAKLOOP: 	return wodBreakLoop	((WAVEMAPDATA*)dwUser);    case WODM_PREPARE:	 	return wodPrepare	((WAVEMAPDATA*)dwUser, (LPWAVEHDR)dwParam1, 	dwParam2);    case WODM_UNPREPARE: 	return wodUnprepare	((WAVEMAPDATA*)dwUser, (LPWAVEHDR)dwParam1, 	dwParam2);    case WODM_GETDEVCAPS:	return wodGetDevCaps	(wDevID, (WAVEMAPDATA*)dwUser, (LPWAVEOUTCAPSA)dwParam1,dwParam2);    case WODM_GETNUMDEVS:	return 1;    case WODM_GETPITCH:	 	return MMSYSERR_NOTSUPPORTED;    case WODM_SETPITCH:	 	return MMSYSERR_NOTSUPPORTED;    case WODM_GETPLAYBACKRATE:	return MMSYSERR_NOTSUPPORTED;    case WODM_SETPLAYBACKRATE:	return MMSYSERR_NOTSUPPORTED;    case WODM_GETVOLUME:	return wodGetVolume	(wDevID, (WAVEMAPDATA*)dwUser, (LPDWORD)dwParam1);    case WODM_SETVOLUME:	return wodSetVolume	(wDevID, (WAVEMAPDATA*)dwUser, dwParam1);    case WODM_RESTART:		return wodRestart	((WAVEMAPDATA*)dwUser);    case WODM_RESET:		return wodReset		((WAVEMAPDATA*)dwUser);    case WODM_MAPPER_STATUS:	return wodMapperStatus  ((WAVEMAPDATA*)dwUser, dwParam1, (LPVOID)dwParam2);    default:	FIXME("unknown message %d!\n", wMsg);    }    return MMSYSERR_NOTSUPPORTED;}/*======================================================================* *                  WAVE IN part                                        * *======================================================================*/static void	CALLBACK widCallback(HWAVEIN hWave, UINT uMsg, DWORD dwInstance,				     DWORD dwParam1, DWORD dwParam2){    WAVEMAPDATA*	wim = (WAVEMAPDATA*)dwInstance;    TRACE("(%p %u %ld %lx %lx);\n", hWave, uMsg, dwInstance, dwParam1, dwParam2);    if (!WAVEMAP_IsData(wim)) {	ERR("Bad data\n");	return;    }    if (hWave != wim->u.in.hInnerWave && uMsg != WIM_OPEN)	ERR("Shouldn't happen (%p %p)\n", hWave, wim->u.in.hInnerWave);    switch (uMsg) {    case WIM_OPEN:    case WIM_CLOSE:	/* dwParam1 & dwParam2 are supposed to be 0, nothing to do */	break;    case WIM_DATA:	if (wim->hAcmStream) {	    LPWAVEHDR		lpWaveHdrSrc = (LPWAVEHDR)dwParam1;	    PACMSTREAMHEADER	ash = (PACMSTREAMHEADER)((LPSTR)lpWaveHdrSrc - sizeof(ACMSTREAMHEADER));	    LPWAVEHDR		lpWaveHdrDst = (LPWAVEHDR)ash->dwUser;	    /* convert data just gotten from waveIn into requested format */	    if (acmStreamConvert(wim->hAcmStream, ash, 0L) != MMSYSERR_NOERROR) {		ERR("ACM conversion failed\n");		return;	    } else {		TRACE("Converted %ld bytes into %ld\n", ash->cbSrcLengthUsed, ash->cbDstLengthUsed);	    }	    /* and setup the wavehdr to return accordingly */	    lpWaveHdrDst->dwFlags &= ~WHDR_INQUEUE;	    lpWaveHdrDst->dwFlags |= WHDR_DONE;	    lpWaveHdrDst->dwBytesRecorded = ash->cbDstLengthUsed;	    dwParam1 = (DWORD)lpWaveHdrDst;	}	break;    default:	ERR("Unknown msg %u\n", uMsg);    }    DriverCallback(wim->dwCallback, HIWORD(wim->dwFlags), (HDRVR)wim->u.in.hOuterWave,		   uMsg, wim->dwClientInstance, dwParam1, dwParam2);}static	DWORD	widOpenHelper(WAVEMAPDATA* wim, UINT idx,			      LPWAVEOPENDESC lpDesc, LPWAVEFORMATEX lpwfx,			      DWORD dwFlags){    DWORD	ret;    /* source is always PCM, so the formulas below apply */    lpwfx->nBlockAlign = (lpwfx->nChannels * lpwfx->wBitsPerSample) / 8;    lpwfx->nAvgBytesPerSec = lpwfx->nSamplesPerSec * lpwfx->nBlockAlign;    if (dwFlags & WAVE_FORMAT_QUERY) {	ret = acmStreamOpen(NULL, 0, lpwfx, lpDesc->lpFormat, NULL, 0L, 0L, ACM_STREAMOPENF_QUERY);    } else {	ret = acmStreamOpen(&wim->hAcmStream, 0, lpwfx, lpDesc->lpFormat, NULL, 0L, 0L, 0L);    }    if (ret == MMSYSERR_NOERROR) {	ret = waveInOpen(&wim->u.in.hInnerWave, idx, lpwfx, (DWORD)widCallback,			 (DWORD)wim, (dwFlags & ~CALLBACK_TYPEMASK) | CALLBACK_FUNCTION);	if (ret != MMSYSERR_NOERROR && !(dwFlags & WAVE_FORMAT_QUERY)) {	    acmStreamClose(wim->hAcmStream, 0);	    wim->hAcmStream = 0;	}    }    return ret;}static	DWORD	widOpen(LPDWORD lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags){    UINT 		ndlo, ndhi;    UINT		i;    WAVEMAPDATA*	wim = HeapAlloc(GetProcessHeap(), 0, sizeof(WAVEMAPDATA));    TRACE("(%p %p %08lx)\n", lpdwUser, lpDesc, dwFlags);    if (!wim)	return MMSYSERR_NOMEM;    wim->self = wim;    wim->dwCallback = lpDesc->dwCallback;    wim->dwFlags = dwFlags;    wim->dwClientInstance = lpDesc->dwInstance;    wim->u.in.hOuterWave = (HWAVEIN)lpDesc->hWave;    ndhi = waveInGetNumDevs();    if (dwFlags & WAVE_MAPPED) {	if (lpDesc->uMappedDeviceID >= ndhi) return MMSYSERR_INVALPARAM;	ndlo = lpDesc->uMappedDeviceID;	ndhi = ndlo + 1;	dwFlags &= ~WAVE_MAPPED;    } else {	ndlo = 0;    }    wim->avgSpeedOuter = wim->avgSpeedInner = lpDesc->lpFormat->nAvgBytesPerSec;    for (i = ndlo; i < ndhi; i++) {	if (waveInOpen(&wim->u.in.hInnerWave, i, lpDesc->lpFormat, (DWORD)widCallback,                       (DWORD)wim, (dwFlags & ~CALLBACK_TYPEMASK) | CALLBACK_FUNCTION | WAVE_FORMAT_DIRECT) == MMSYSERR_NOERROR) {	    wim->hAcmStream = 0;	    goto found;	}    }    if ((dwFlags & WAVE_FORMAT_DIRECT) == 0)    {        WAVEFORMATEX	wfx;        wfx.wFormatTag = WAVE_FORMAT_PCM;        wfx.cbSize = 0; /* normally, this field is not used for PCM format, just in case */        /* try some ACM stuff */        #define	TRY(sps,bps)    wfx.nSamplesPerSec = (sps); wfx.wBitsPerSample = (bps); \                        switch (widOpenHelper(wim, i, lpDesc, &wfx, dwFlags | WAVE_FORMAT_DIRECT)) { \                        case MMSYSERR_NOERROR: wim->avgSpeedInner = wfx.nAvgBytesPerSec; goto found; \                        case WAVERR_BADFORMAT: break; \                        default: goto error; \                        }                for (i = ndlo; i < ndhi; i++) {	    wfx.nSamplesPerSec=lpDesc->lpFormat->nSamplesPerSec;            /* first try with same stereo/mono option as source */            wfx.nChannels = lpDesc->lpFormat->nChannels;			TRY(wfx.nSamplesPerSec, 16);			TRY(wfx.nSamplesPerSec, 8);			wfx.nChannels ^= 3;			TRY(wfx.nSamplesPerSec, 16);			TRY(wfx.nSamplesPerSec, 8);

⌨️ 快捷键说明

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