windows-nt/Source/XPSP1/NT/multimedia/media/midimap/cookmap.c
2020-09-26 16:20:57 +08:00

129 lines
3.6 KiB
C

/**********************************************************************
Copyright (c) 1992-1998 Microsoft Corporation
cookmap.c
DESCRIPTION:
Non-fixed code for doing cooked-mode output mapping.
HISTORY:
03/04/94 [jimge] created.
*********************************************************************/
#include "preclude.h"
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <mmddk.h>
#include "idf.h"
#include <memory.h>
#include "midimap.h"
#include "debug.h"
/***************************************************************************
@doc internal
@api int | MapCookedBuffer | Perform output mapping of a polymsg buffer.
@parm PINSTANCE | pinstance | Instance owning the polymsg buffer.
@parm LPMIDIHDR | lpmh | The buffer to map.
@comm
Map this buffer (which may allocate more channels to us).
Build array of used ports and physical channels used on each port.
Acquire shadow buffers and a sync object and set them up.
Queue the sync object and send it if there isn't anything playing.
@rdesc | MMSYSERR_xxx.
***************************************************************************/
#define SKIP_BYTES(x,s) \
{ \
if (cbBuffer < (x)) \
{ \
DPF(1, TEXT ("MapCookedBuffer: ran off end of polymsg buffer in parse! %ls"), (LPTSTR)(s)); \
mmRet = MMSYSERR_INVALPARAM; \
goto CLEANUP; \
} \
((LPBYTE)lpdwBuffer) += (x); \
cbBuffer -= (x); \
}
MMRESULT FNGLOBAL MapCookedBuffer(
PINSTANCE pinstance,
LPMIDIHDR lpmhParent)
{
LPDWORD lpdwBuffer;
DWORD cbBuffer;
BYTE bEventType;
DWORD dwEvent;
DWORD dwStreamID = 0;
MMRESULT mmRet;
LPMIDIHDR lpmh;
PSHADOWBLOCK psb;
mmRet = MMSYSERR_NOERROR;
psb = (PSHADOWBLOCK)(UINT_PTR)lpmhParent->dwReserved[MH_SHADOW];
lpmh = psb->lpmhShadow;
DPF(2, TEXT ("Map: pinstance %04X lpmh %p"), (WORD)pinstance, lpmh);
lpmh->reserved = lpmhParent->reserved;
lpmh->dwBytesRecorded = lpmhParent->dwBytesRecorded;
lpmh->dwReserved[MH_MAPINST] = (DWORD_PTR)pinstance;
// In-place map the buffer. Run through it, mapping all of the
// short events.
//
lpdwBuffer = (LPDWORD)lpmh->lpData;
cbBuffer = lpmh->dwBytesRecorded;
while (cbBuffer)
{
SKIP_BYTES(sizeof(DWORD), TEXT ("d-time"));
if (cbBuffer < 2*sizeof(DWORD))
return MMSYSERR_INVALPARAM;
bEventType = MEVT_EVENTTYPE(lpdwBuffer[1]);
dwEvent = MEVT_EVENTPARM(lpdwBuffer[1]);
if (bEventType == MEVT_SHORTMSG)
{
dwEvent = MapSingleEvent(pinstance,
dwEvent,
MSE_F_RETURNEVENT,
(DWORD BSTACK *)&dwStreamID);
lpdwBuffer[0] = dwStreamID;
lpdwBuffer[1] = dwEvent;
}
SKIP_BYTES(sizeof(DWORD), TEXT ("stream-id"));
SKIP_BYTES(sizeof(DWORD), TEXT ("event type"));
if (bEventType & (MEVT_F_LONG >> 24))
{
dwEvent = (dwEvent+3)&~3;
SKIP_BYTES(dwEvent, TEXT ("long event data"));
}
}
mmRet = midiStreamOut(ghMidiStrm, lpmh, sizeof(MIDIHDR));
CLEANUP:
return mmRet;
}