|
|
//==========================================================================;
//
// wavein.c
//
// Copyright (c) 1992-1998 Microsoft Corporation
//
// Description:
//
//
// History:
// 9/18/93 cjp [curtisp]
//
//==========================================================================;
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <mmddk.h>
#include <mmreg.h>
#include <msacm.h>
#include <msacmdrv.h>
#include <memory.h>
#ifdef DEBUG
#include <stdlib.h>
#endif
#include "msacmmap.h"
#include "debug.h"
//--------------------------------------------------------------------------;
//
// LRESULT mapWaveInputConvertProc
//
// Description:
// Window Proc for hidden window...
//
// It should just recieve WIM_DATA messages from mapWaveDriverCallback
//
// Real driver has filled the shadow buffer
// Now convert it and call back the app/client.
//
// Arguments:
// DWORD dwInstance:
//
// Return (LONG):
//
// History:
// 11/15/92 gpd [geoffd]
// 08/02/93 cjp [curtisp] rewrote for new mapper
//
//--------------------------------------------------------------------------;
EXTERN_C LRESULT FNCALLBACK mapWaveInputConvertProc ( DWORD dwInstance ) { MMRESULT mmr; MSG msg; LPACMSTREAMHEADER pash; LPWAVEHDR pwh; LPWAVEHDR pwhShadow; LPMAPSTREAM pms;
#ifndef WIN32
DPF(1, "mapWaveInputConvertProc: creating htask=%.04Xh, dwInstance=%.08lXh", gpag->htaskInput, dwInstance); #endif // !WIN32
if (!SetMessageQueue(64)) { DPF(0, "!mapWaveInputConvertProc: SetMessageQueue() failed!"); return (0L); }
#ifdef WIN32
//
// Make sure we have a message queue for this thread and signal the
// caller when we're ready to go
//
GetDesktopWindow(); // Makes sure we've got a message queue
SetEvent(LongToHandle(dwInstance)); #endif
//
//
//
while (GetMessage(&msg, NULL, 0, 0)) { #ifdef DEBUG
if (gpag->fFaultAndDie) { if ((rand() & 0x7) == 0) { gpag->fFaultAndDie = (BOOL)*((LPBYTE)0);
DPF(1, "mapWaveInputConvertProc: fault was ignored...");
gpag->fFaultAndDie = TRUE; } } #endif
//
// if not a 'data' message, then translate and dispatch it...
//
if (msg.message != WIM_DATA) { DPF(1, "mapWaveInputConvertProc: ignoring message [%.04Xh]", msg.message);
TranslateMessage(&msg); DispatchMessage(&msg);
continue; }
//
// lParam is the waveheader of the shadow buffer
//
pwhShadow = (LPWAVEHDR)msg.lParam;
//
// client wave header is user data of shadow wave header
// the stream header for this client/shadow pair is in the client's
// 'reserved' member
//
// and finally, our stream header's dwUser member contains a
// reference to our mapping stream instance data.
//
pwh = (LPWAVEHDR)pwhShadow->dwUser; pash = (LPACMSTREAMHEADER)pwh->reserved; pms = (LPMAPSTREAM)pash->dwUser;
DPF(4, "mapWaveInputConvertProc: WIM_DATA htask=%.04Xh, pms=%.08lXh, pwh=%.08lXh, pwhShadow=%.08lXh", pms->htaskInput, pms, pwh, pwhShadow);
//
// do the conversion (if there is data in the input buffer)
//
pash->cbDstLengthUsed = 0L; if (0L != pwhShadow->dwBytesRecorded) { pash->pbSrc = pwhShadow->lpData; pash->cbSrcLength = pwhShadow->dwBytesRecorded; pash->pbDst = pwh->lpData; ////////////pash->cbDstLength = pwh->dwBufferLength;
mmr = acmStreamConvert(pms->has, pash, ACM_STREAMCONVERTF_BLOCKALIGN); if (MMSYSERR_NOERROR != mmr) { DPF(0, "!mapWaveInputConvertProc: conversion failed! mmr=%.04Xh, pms=%.08lXh", mmr, pms);
pash->cbDstLengthUsed = 0L; } else if (pash->cbSrcLength != pash->cbSrcLengthUsed) { DPF(1, "mapWaveInputConvertProc: discarding %lu bytes of input! pms=%.08lXh", pash->cbSrcLength - pash->cbSrcLengthUsed, pms); } }
if (0L == pash->cbDstLengthUsed) { DPF(1, "mapWaveInputConvertProc: nothing converted--no data in input buffer. pms=%.08lXh", pms); }
//
// update the 'real' header and send the WIM_DATA callback
//
//
pwh->dwBytesRecorded = pash->cbDstLengthUsed; pwh->dwFlags |= WHDR_DONE; pwh->dwFlags &= ~WHDR_INQUEUE;
mapWaveDriverCallback(pms, WIM_DATA, (DWORD_PTR)pwh, 0L); #ifdef WIN32
if (InterlockedDecrement((PLONG)&pms->nOutstanding) == 0) { SetEvent(pms->hStoppedEvent); } #endif // WIN32
}
#ifndef WIN32
DPF(1, "mapWaveInputConvertProc: being KILLED htask=%.04Xh", gpag->htaskInput); #endif // !WIN32
return (0L); } // mapWaveInputConvertProc()
//--------------------------------------------------------------------------;
//
// DWORD widmMapperStatus
//
// Description:
//
//
// Arguments:
// LPMAPSTREAM pms:
//
// DWORD dwStatus:
//
// LPDWORD pdw:
//
// Return (DWORD):
//
// History:
// 08/13/93 cjp [curtisp]
//
//--------------------------------------------------------------------------;
DWORD FNLOCAL widmMapperStatus ( LPMAPSTREAM pms, DWORD dwStatus, LPDWORD pdw ) { MMRESULT mmr;
// V_WPOINTER(pdw, sizeof(DWORD), MMSYSERR_INVALPARAM);
if ((NULL == pms) || (NULL == pdw)) { return (MMSYSERR_INVALPARAM); }
//
//
//
switch (dwStatus) { case WAVEIN_MAPPER_STATUS_DEVICE: { UINT uId = (UINT)(-1); // Invalid value
mmr = waveInGetID(pms->hwiReal, &uId); if (MMSYSERR_NOERROR != mmr) { return (mmr); }
*pdw = uId; return (MMSYSERR_NOERROR); }
case WAVEIN_MAPPER_STATUS_MAPPED: *pdw = (NULL != pms->has); return (MMSYSERR_NOERROR);
case WAVEIN_MAPPER_STATUS_FORMAT: if (NULL != pms->has) _fmemcpy(pdw, pms->pwfxReal, sizeof(PCMWAVEFORMAT)); else _fmemcpy(pdw, pms->pwfxClient, sizeof(PCMWAVEFORMAT));
((LPWAVEFORMATEX)pdw)->cbSize = 0; return (MMSYSERR_NOERROR); }
//
//
//
return (MMSYSERR_NOTSUPPORTED); } // widmMapperStatus()
//--------------------------------------------------------------------------;
//
// DWORD widMessage
//
// Description:
// This function conforms to the standard Wave Input driver message
// procedure (widMessage), which is documented in mmddk.d.
//
// Arguments:
// UINT uId:
//
// UINT uMsg:
//
// DWORD dwUser:
//
// DWORD dwParam1:
//
// DWORD dwParam2:
//
// Return (DWORD):
//
//
// History:
// 11/15/92 cjp [curtisp]
//
//--------------------------------------------------------------------------;
EXTERN_C DWORD FNEXPORT widMessage ( UINT uId, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2 ) { #ifndef WIN32 // Doesn't work for multithread
static short fSem = 0; #endif // !WIN32
LPMAPSTREAM pms; // pointer to per-instance info structure
DWORD dw;
if (!gpag->fEnabled) { DPF(1, "widMessage: called while disabled!"); return ((WIDM_GETNUMDEVS == uMsg) ? 0L : MMSYSERR_NOTENABLED); }
#ifndef WIN32
//
// we call back into the mmsystem wave APIs so protect ourself
// from being re-entered!
//
if (fSem) { DPF(0, "!widMessage(uMsg=%u, dwUser=%.08lXh) being reentered! fSem=%d", uMsg, dwUser, fSem); // return (MMSYSERR_NOTSUPPORTED);
} #endif // !WIN32
pms = (LPMAPSTREAM)dwUser;
switch (uMsg) { case WIDM_GETNUMDEVS: return (1L);
case WIDM_GETDEVCAPS: return mapWaveGetDevCaps(TRUE, (LPWAVEOUTCAPS)dwParam1, (UINT)dwParam2);
case WIDM_OPEN: #ifndef WIN32
fSem++;
DPF(1, "**** >> WIDM_OPEN(uMsg=%u, dwUser=%.08lXh, fSem=%d)", uMsg, dwUser, fSem);
#endif // !WIN32
//
// dwParam1 contains a pointer to a WAVEOPENDESC
// dwParam2 contains wave driver specific flags in the LOWORD
// and generic driver flags in the HIWORD
//
dw = mapWaveOpen(TRUE, uId, dwUser, (LPWAVEOPENDESC)dwParam1, (DWORD)(PtrToLong((PVOID)dwParam2)) );
#ifndef WIN32
fSem--;
DPF(1, "**** << WIDM_OPEN(uMsg=%u, dwUser=%.08lXh, *dwUser=%.08lXh, fSem=%d)", uMsg, dwUser, *(LPDWORD)dwUser, fSem); #endif // !WIN32
return (dw);
case WIDM_CLOSE: return (mapWaveClose(pms));
case WIDM_PREPARE: return (mapWavePrepareHeader(pms, (LPWAVEHDR)dwParam1));
case WIDM_UNPREPARE: return (mapWaveUnprepareHeader(pms, (LPWAVEHDR)dwParam1));
case WIDM_ADDBUFFER: return (mapWaveWriteBuffer(pms, (LPWAVEHDR)dwParam1));
case WIDM_START: DPF(4, "WIDM_START received..."); return waveInStart(pms->hwiReal);
case WIDM_STOP: DPF(4, "WIDM_STOP received.."); dw = waveInStop(pms->hwiReal);
#pragma message("----try to kill DirectedYield..")
//
// yield enough to get all input messages processed
//
if (pms->htaskInput) { #ifdef WIN32
ResetEvent(pms->hStoppedEvent); if (pms->nOutstanding != 0) { WaitForSingleObject(pms->hStoppedEvent, INFINITE); } #else
if (IsTask(pms->htaskInput)) { DirectedYield(pms->htaskInput); } else { DPF(0, "!WIDM_STOP: pms=%.08lXh, htask=%.04Xh is not valid!", pms, pms->htaskInput); pms->htaskInput = NULL; } #endif // !WIN32
} return (dw);
case WIDM_RESET: DPF(4, "WIDM_RESET received..."); dw = waveInReset(pms->hwiReal);
//
// yield enough to get all input messages processed
//
if (pms->htaskInput) { #ifdef WIN32
ResetEvent(pms->hStoppedEvent); if (pms->nOutstanding != 0) { WaitForSingleObject(pms->hStoppedEvent, INFINITE); } #else
if (IsTask(pms->htaskInput)) { DirectedYield(pms->htaskInput); } else { DPF(0, "!WIDM_RESET: pms=%.08lXh, htask=%.04Xh is not valid!", pms, pms->htaskInput); pms->htaskInput = NULL; } #endif // !WIN32
} return (dw);
case WIDM_GETPOS: return mapWaveGetPosition(pms, (LPMMTIME)dwParam1, (UINT)dwParam2);
case WIDM_MAPPER_STATUS: dw = widmMapperStatus(pms, (DWORD)(PtrToLong((PVOID)dwParam1)), (LPDWORD)dwParam2); return (dw);
#if (WINVER >= 0x0400)
case DRVM_MAPPER_RECONFIGURE: mapDriverDisable(NULL); mapDriverEnable(NULL); return (0); #endif
}
if (!pms || !pms->hwiReal) return (MMSYSERR_NOTSUPPORTED);
return waveInMessage(pms->hwiReal, uMsg, dwParam1, dwParam2); } // widMessage()
|