Committing my in-progress work with mmdrv, but it's still incomplete, and it still contains MS-specific things (in comments only!).

svn path=/trunk/; revision=8787
This commit is contained in:
Aleksey Bragin 2004-03-19 06:11:28 +00:00
parent 3398afcf63
commit f3eb637ea4
7 changed files with 332 additions and 237 deletions

View file

@ -17,6 +17,7 @@ TARGET_LFLAGS =
TARGET_SDKLIBS = winmm.a
TARGET_OBJECTS = \
auxil.o \
entry.o \
midi.o \
utils.o \

View file

@ -1,12 +1,14 @@
/*
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PROJECT: ReactOS Multimedia
* FILE: lib/mmdrv/entry.c
* PURPOSE: Multimedia User Mode Driver
* PROGRAMMER: Andrew Greenwood
* Aleksey Bragin
* UPDATE HISTORY:
* Jan 30, 2004: Imported into ReactOS tree
* Jan 30, 2004: Imported into ReactOS tree (Greenwood)
* Mar 16, 2004: Cleaned up a bit (Bragin)
*/
@ -129,67 +131,4 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
return TRUE;
}
/*
EXPORT DWORD midMessage(DWORD id, DWORD msg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
{
printf("midMessage\n");
switch (msg) {
case MIDM_GETNUMDEVS:
printf("MIDM_GETNUMDEVS");
return GetNumDevs(MidiInDevice);
case MIDM_GETDEVCAPS:
printf("MIDM_GETDEVCAPS");
return MMSYSERR_NOERROR;
case MIDM_OPEN:
printf("MIDM_OPEN");
return MMSYSERR_NOERROR;
case MIDM_CLOSE:
printf("MIDM_CLOSE");
return MMSYSERR_NOERROR;
case MIDM_ADDBUFFER:
printf("MIDM_ADDBUFFER");
return MMSYSERR_NOERROR;
case MIDM_STOP:
printf("MIDM_PAUSE");
return MMSYSERR_NOERROR;
case MIDM_START:
printf("MIDM_RESTART");
return MMSYSERR_NOERROR;
case MIDM_RESET:
printf("MIDM_RESET");
return MMSYSERR_NOERROR;
default:
return MMSYSERR_NOTSUPPORTED;
}
//
// Should not get here
//
return MMSYSERR_NOTSUPPORTED;
}
*/
APIENTRY DWORD auxMessage(UINT uDevice,
UINT uMsg,
DWORD dwUser,
DWORD dwParam1,
DWORD dwParam2)
{
printf("auxMessage\n");
return MMSYSERR_NOERROR;
}
/* EOF */

View file

@ -1,7 +1,7 @@
/*
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PROJECT: ReactOS Multimedia
* FILE: lib/mmdrv/midi.c
* PURPOSE: Multimedia User Mode Driver
* PROGRAMMER: Andrew Greenwood
@ -172,10 +172,51 @@ static int GetMidiLength(PMIDIALLOC pClient, BYTE b)
Exported functions
----------------------------------------------------------------------------- */
APIENTRY DWORD midMessage(DWORD ID, DWORD Message, DWORD User, DWORD Param1, DWORD Param2)
APIENTRY DWORD midMessage(DWORD dwId, DWORD dwMessage, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
{
printf("midMessage\n");
return MMSYSERR_NOERROR;
switch (dwMessage) {
case MIDM_GETNUMDEVS:
printf("MIDM_GETNUMDEVS");
return 0;
case MIDM_GETDEVCAPS:
printf("MIDM_GETDEVCAPS");
return MMSYSERR_NOERROR;
case MIDM_OPEN:
printf("MIDM_OPEN");
return MMSYSERR_NOERROR;
case MIDM_CLOSE:
printf("MIDM_CLOSE");
return MMSYSERR_NOERROR;
case MIDM_ADDBUFFER:
printf("MIDM_ADDBUFFER");
return MMSYSERR_NOERROR;
case MIDM_STOP:
printf("MIDM_PAUSE");
return MMSYSERR_NOERROR;
case MIDM_START:
printf("MIDM_RESTART");
return MMSYSERR_NOERROR;
case MIDM_RESET:
printf("MIDM_RESET");
return MMSYSERR_NOERROR;
default:
return MMSYSERR_NOTSUPPORTED;
}
// the function should never get to this point
//FIXME: Would it be wise to assert here?
return MMSYSERR_NOTSUPPORTED;
}
APIENTRY DWORD modMessage(DWORD ID, DWORD Message, DWORD User, DWORD Param1, DWORD Param2)

View file

@ -1,10 +1,11 @@
/*
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PROJECT: ReactOS Multimedia
* FILE: lib/mmdrv/mmdrv.h
* PURPOSE: Multimedia User Mode Driver (header)
* PROGRAMMER: Andrew Greenwood
* Aleksey Bragin
* UPDATE HISTORY:
* Jan 30, 2004: Imported into ReactOS tree
*/
@ -102,7 +103,6 @@ HANDLE Heap;
AuxDevice
};
MMRESULT OpenDevice(UINT DeviceType, DWORD ID, PHANDLE pDeviceHandle,
DWORD Access);

View file

@ -1,7 +1,7 @@
/*
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PROJECT: ReactOS Multimedia
* FILE: lib/mmdrv/utils.c
* PURPOSE: Multimedia User Mode Driver (utility functions)
* PROGRAMMER: Andrew Greenwood

View file

@ -1,16 +1,24 @@
/*
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PROJECT: ReactOS Multimedia
* FILE: lib/mmdrv/wave.c
* PURPOSE: Multimedia User Mode Driver
* PROGRAMMER: Andrew Greenwood
* Aleksey Bragin (aleksey at studiocerebral.com)
* UPDATE HISTORY:
* Jan 30, 2004: Imported into ReactOS tree
* Jan 30, 2004: Imported into ReactOS tree (Greenwood)
* Mar 16, 2004: Implemented some funcs (Bragin)
*/
#include "mmdrv.h"
#include "wave.h"
/* ============================
* INTERNAL
* functions start here
* ============================
*/
static MMRESULT GetDeviceCapabilities(DWORD ID, UINT DeviceType,
LPBYTE pCaps, DWORD Size)
@ -47,233 +55,259 @@ static MMRESULT GetDeviceCapabilities(DWORD ID, UINT DeviceType,
return Result;
}
APIENTRY DWORD wodMessage(DWORD ID, DWORD Message, DWORD User, DWORD Param1, DWORD Param2)
static MMRESULT OpenWaveDevice(UINT DeviceType,
DWORD id,
DWORD dwUser,
DWORD dwParam1,
DWORD dwParam2)
{
// PWAVEALLOC pOutClient;
MMRESULT Result;
// TODO: Implement
return MMSYSERR_NOERROR;
}
switch (Message) {
//FIXME: Params are MS-specific
static MMRESULT ThreadCallWaveDevice(WAVETHREADFUNCTION Function, PWAVEALLOC pClient)
{
return MMSYSERR_NOERROR;
}
//FIXME: Params are MS-specific
static void CallbackWaveDevice(PWAVEALLOC pWave, DWORD msg, DWORD dw1)
{
}
//FIXME: Params are MS-specific
static MMRESULT WriteWaveDevice(LPWAVEHDR pHdr, PWAVEALLOC pClient)
{
return MMSYSERR_NOERROR;
}
//FIXME: MS-specific code, except for name of the func!
MMRESULT GetPositionWaveDevice(PWAVEALLOC pClient, LPMMTIME lpmmt, DWORD dwSize)
{
/*
WAVE_DD_POSITION PositionData;
MMRESULT mErr;
if (dwSize < sizeof(MMTIME))
return MMSYSERR_ERROR;
//
// Get the current position from the driver
//
mErr = sndGetHandleData(pClient->hDev,
sizeof(PositionData),
&PositionData,
IOCTL_WAVE_GET_POSITION,
pClient->Event);
if (mErr == MMSYSERR_NOERROR) {
if (lpmmt->wType == TIME_BYTES) {
lpmmt->u.cb = PositionData.ByteCount;
}
// default is samples.
else {
lpmmt->wType = TIME_SAMPLES;
lpmmt->u.sample = PositionData.SampleCount;
}
}
return mErr;*/ return MMSYSERR_NOERROR;
}
//FIXME: Params are MS-specific
MMRESULT soundSetData(UINT DeviceType, UINT DeviceId, UINT Length, PBYTE Data,
ULONG Ioctl)
{
return MMSYSERR_NOERROR;
}
//FIXME: Params are MS-specific
MMRESULT soundGetData(UINT DeviceType, UINT DeviceId, UINT Length, PBYTE Data,
ULONG Ioctl)
{
return MMSYSERR_NOERROR;
}
/* ============================
* EXPORT
* functions start here
* ============================
*/
/*
* @implemented
*/
APIENTRY DWORD wodMessage(DWORD dwId, DWORD dwMessage, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
{
switch (dwMessage) {
case WODM_GETNUMDEVS:
printf(("WODM_GETNUMDEVS"));
printf("WODM_GETNUMDEVS");
return GetDeviceCount(WaveOutDevice);
case WODM_GETDEVCAPS:
printf(("WODM_GETDEVCAPS"));
return GetDeviceCapabilities(ID, WaveOutDevice, (LPBYTE)Param1,
(DWORD)Param2);
printf("WODM_GETDEVCAPS");
return GetDeviceCapabilities(dwId, WaveOutDevice, (LPBYTE)dwParam1,
(DWORD)dwParam2);
case WODM_OPEN:
printf(("WODM_OPEN"));
// return waveOpen(WaveOutDevice, id, dwUser, dwParam1, dwParam2);
printf("WODM_OPEN");
return OpenWaveDevice(WaveOutDevice, dwId, dwUser, dwParam1, dwParam2);
case WODM_CLOSE:
printf(("WODM_CLOSE"));
// pOutClient = (PWAVEALLOC)dwUser;
{
MMRESULT Result;
PWAVEALLOC pTask = (PWAVEALLOC)dwUser;
printf("WODM_CLOSE");
//
// Call our task to see if it's ready to complete
//
// Result = waveThreadCall(WaveThreadClose, pOutClient);
if (Result != MMSYSERR_NOERROR) {
return Result;
}
// 1. Check if the task is ready to complete
Result = ThreadCallWaveDevice(WaveThreadClose, pTask);
if (Result != MMSYSERR_NOERROR) {
return Result;
}
else
CallbackWaveDevice(pTask, WOM_CLOSE, 0L);
// 2. Close the device
if (pTask->hDev != INVALID_HANDLE_VALUE) {
CloseHandle(pTask->hDev);
// waveCallback(pOutClient, WOM_CLOSE, 0L);
EnterCriticalSection(&CS);
pTask->hDev = INVALID_HANDLE_VALUE;
LeaveCriticalSection(&CS);
}
//
// Close our device
//
// if (pOutClient->hDev != INVALID_HANDLE_VALUE) {
// CloseHandle(pOutClient->hDev);
EnterCriticalSection(&CS);
// pOutClient->hDev = INVALID_HANDLE_VALUE;
LeaveCriticalSection(&CS);
// }
return MMSYSERR_NOERROR;
return MMSYSERR_NOERROR;
};
case WODM_WRITE:
printf(("WODM_WRITE"));
/* WinAssert(dwParam1 != 0);
WinAssert(!(((LPWAVEHDR)dwParam1)->dwFlags &
~(WHDR_INQUEUE|WHDR_DONE|WHDR_PREPARED|
WHDR_BEGINLOOP|WHDR_ENDLOOP)));
{
LPWAVEHDR pWaveHdr = (LPWAVEHDR)dwParam1;
((LPWAVEHDR)dwParam1)->dwFlags &=
(WHDR_INQUEUE|WHDR_DONE|WHDR_PREPARED|
WHDR_BEGINLOOP|WHDR_ENDLOOP);
printf("WODM_WRITE");
WinAssert(((LPWAVEHDR)dwParam1)->dwFlags & WHDR_PREPARED);
if (dwParam1 != 0)
return MMSYSERR_INVALPARAM;
// check if it's been prepared
if (!(((LPWAVEHDR)dwParam1)->dwFlags & WHDR_PREPARED))
return WAVERR_UNPREPARED;
if ((pWaveHdr->dwFlags & ~(WHDR_INQUEUE|WHDR_DONE|WHDR_PREPARED|WHDR_BEGINLOOP|WHDR_ENDLOOP)))
return MMSYSERR_INVALPARAM;
WinAssert(!(((LPWAVEHDR)dwParam1)->dwFlags & WHDR_INQUEUE));
pWaveHdr->dwFlags &= (WHDR_INQUEUE|WHDR_DONE|WHDR_PREPARED|WHDR_BEGINLOOP|WHDR_ENDLOOP);
// if it is already in our Q, then we cannot do this
if ( ((LPWAVEHDR)dwParam1)->dwFlags & WHDR_INQUEUE )
return ( WAVERR_STILLPLAYING );
if ((pWaveHdr->dwFlags & WHDR_PREPARED) == 0)
return MMSYSERR_INVALPARAM;
// store the pointer to my WAVEALLOC structure in the wavehdr
pOutClient = (PWAVEALLOC)dwUser;
((LPWAVEHDR)dwParam1)->reserved = (DWORD)(LPSTR)pOutClient;
// Check, if the wave header is already prepared
if (!(pWaveHdr->dwFlags & WHDR_PREPARED))
return WAVERR_UNPREPARED;
// If it's already located in the queue, this op is impossible
if (pWaveHdr->dwFlags & WHDR_INQUEUE )
return ( WAVERR_STILLPLAYING );
// save WAVEALLOC pointer in the WaveHeader
pWaveHdr->reserved = dwUser;
return WriteWaveDevice(pWaveHdr, (PWAVEALLOC)dwUser);
}
return waveWrite((LPWAVEHDR)dwParam1, pOutClient);
*/
case WODM_PAUSE:
printf(("WODM_PAUSE"));
/*
pOutClient = (PWAVEALLOC)dwUser;
pOutClient->AuxParam.State = WAVE_DD_STOP;
return waveThreadCall(WaveThreadSetState, pOutClient);
*/
printf("WODM_PAUSE");
((PWAVEALLOC)dwUser)->AuxParam.State = WAVE_DD_STOP;
return ThreadCallWaveDevice(WaveThreadSetState, (PWAVEALLOC)dwUser);
case WODM_RESTART:
printf(("WODM_RESTART"));
/*
pOutClient = (PWAVEALLOC)dwUser;
pOutClient->AuxParam.State = WAVE_DD_PLAY;
return waveThreadCall(WaveThreadSetState, pOutClient);
*/
printf("WODM_RESTART");
((PWAVEALLOC)dwUser)->AuxParam.State = WAVE_DD_PLAY;
return ThreadCallWaveDevice(WaveThreadSetState, (PWAVEALLOC)dwUser);
case WODM_RESET:
printf(("WODM_RESET"));
/*
pOutClient = (PWAVEALLOC)dwUser;
pOutClient->AuxParam.State = WAVE_DD_RESET;
return waveThreadCall(WaveThreadSetState, pOutClient);
*/
printf("WODM_RESET");
((PWAVEALLOC)dwUser)->AuxParam.State = WAVE_DD_RESET;
return ThreadCallWaveDevice(WaveThreadSetState, (PWAVEALLOC)dwUser);
case WODM_BREAKLOOP:
/*
pOutClient = (PWAVEALLOC)dwUser;
printf(("WODM_BREAKLOOP"));
return waveThreadCall(WaveThreadBreakLoop, pOutClient);
*/
printf("WODM_BREAKLOOP");
return ThreadCallWaveDevice(WaveThreadBreakLoop, (PWAVEALLOC)dwUser);
case WODM_GETPOS:
printf(("WODM_GETPOS"));
/*
pOutClient = (PWAVEALLOC)dwUser;
return waveGetPos(pOutClient, (LPMMTIME)dwParam1, dwParam2);
*/
printf("WODM_GETPOS");
return GetPositionWaveDevice(((PWAVEALLOC)dwUser), (LPMMTIME)dwParam1, dwParam2);
case WODM_SETPITCH:
printf(("WODM_SETPITCH"));
/*
pOutClient = (PWAVEALLOC)dwUser;
pOutClient->AuxParam.GetSetData.pData = (PBYTE)&dwParam1;
pOutClient->AuxParam.GetSetData.DataLen = sizeof(DWORD);
pOutClient->AuxParam.GetSetData.Function = IOCTL_WAVE_SET_PITCH;
return waveThreadCall(WaveThreadSetData, pOutClient);
*/
printf("WODM_SETPITCH");
((PWAVEALLOC)dwUser)->AuxParam.GetSetData.pData = (PBYTE)&dwParam1;
((PWAVEALLOC)dwUser)->AuxParam.GetSetData.DataLen = sizeof(DWORD);
((PWAVEALLOC)dwUser)->AuxParam.GetSetData.Function = IOCTL_WAVE_SET_PITCH;
return ThreadCallWaveDevice(WaveThreadSetData, ((PWAVEALLOC)dwUser));
case WODM_SETVOLUME:
printf(("WODM_SETVOLUME"));// i didnt do this - AG
//pOutClient = (PWAVEALLOC)dwUser;
//pOutClient->AuxParam.GetSetData.pData = *(PBYTE *)&dwParam1;
//pOutClient->AuxParam.GetSetData.DataLen = sizeof(DWORD);
//pOutClient->AuxParam.GetSetData.Function = IOCTL_WAVE_SET_VOLUME;
//return waveThreadCall(WaveThreadSetData, pOutClient);
printf("WODM_SETVOLUME");
{
//
// Translate to device volume structure
//
WAVE_DD_VOLUME Vol;
Vol.Left = LOWORD(dwParam1) << 16;
Vol.Right = HIWORD(dwParam1) << 16;
// WAVE_DD_VOLUME Volume;
// Volume.Left = LOWORD(dwParam1) << 16;
// Volume.Right = HIWORD(dwParam1) << 16;
// return sndSetData(WaveOutDevice, id, sizeof(Volume),
// (PBYTE)&Volume, IOCTL_WAVE_SET_VOLUME);
return soundSetData(WaveOutDevice, dwId, sizeof(Vol),
(PBYTE)&Vol, IOCTL_WAVE_SET_VOLUME);
}
case WODM_SETPLAYBACKRATE:
/*
printf(("WODM_SETPLAYBACKRATE"));
pOutClient = (PWAVEALLOC)dwUser;
pOutClient->AuxParam.GetSetData.pData = (PBYTE)&dwParam1;
pOutClient->AuxParam.GetSetData.DataLen = sizeof(DWORD);
pOutClient->AuxParam.GetSetData.Function =
IOCTL_WAVE_SET_PLAYBACK_RATE;
return waveThreadCall(WaveThreadSetData, pOutClient);
*/
printf("WODM_SETPLAYBACKRATE");
((PWAVEALLOC)dwUser)->AuxParam.GetSetData.pData = (PBYTE)&dwParam1;
((PWAVEALLOC)dwUser)->AuxParam.GetSetData.DataLen = sizeof(DWORD);
((PWAVEALLOC)dwUser)->AuxParam.GetSetData.Function = IOCTL_WAVE_SET_PLAYBACK_RATE;
return ThreadCallWaveDevice(WaveThreadSetData, (PWAVEALLOC)dwUser);
case WODM_GETPITCH:
/*
printf(("WODM_GETPITCH"));
pOutClient = (PWAVEALLOC)dwUser;
pOutClient->AuxParam.GetSetData.pData = (PBYTE)dwParam1;
pOutClient->AuxParam.GetSetData.DataLen = sizeof(DWORD);
pOutClient->AuxParam.GetSetData.Function = IOCTL_WAVE_GET_PITCH;
return waveThreadCall(WaveThreadGetData, pOutClient);
*/
printf("WODM_GETPITCH");
((PWAVEALLOC)dwUser)->AuxParam.GetSetData.pData = (PBYTE)dwParam1;
((PWAVEALLOC)dwUser)->AuxParam.GetSetData.DataLen = sizeof(DWORD);
((PWAVEALLOC)dwUser)->AuxParam.GetSetData.Function = IOCTL_WAVE_GET_PITCH;
return ThreadCallWaveDevice(WaveThreadGetData, (PWAVEALLOC)dwUser);
case WODM_GETVOLUME:
printf(("WODM_GETVOLUME"));
//pOutClient = (PWAVEALLOC)dwUser;
//pOutClient->AuxParam.GetSetData.pData = *(PBYTE *)&dwParam1;
//pOutClient->AuxParam.GetSetData.DataLen = sizeof(DWORD);
//pOutClient->AuxParam.GetSetData.Function = IOCTL_WAVE_GET_VOLUME;
//return waveThreadCall(WaveThreadGetData, pOutClient);
printf("WODM_GETVOLUME");
{
//
// Translate to device volume structure
//
/*
WAVE_DD_VOLUME Volume;
DWORD rc;
WAVE_DD_VOLUME Vol;
DWORD res;
rc = sndGetData(WaveOutDevice, id, sizeof(Volume),
(PBYTE)&Volume, IOCTL_WAVE_GET_VOLUME);
res = soundGetData(WaveOutDevice, dwId, sizeof(Vol),
(PBYTE)&Vol, IOCTL_WAVE_GET_VOLUME);
if (rc == MMSYSERR_NOERROR) {
*(LPDWORD)dwParam1 =
(DWORD)MAKELONG(HIWORD(Volume.Left),
HIWORD(Volume.Right));
}
return rc;
*/
if (res == MMSYSERR_NOERROR)
*(LPDWORD)dwParam1 = (DWORD)MAKELONG(HIWORD(Vol.Left), HIWORD(Vol.Right));
return res;
}
case WODM_GETPLAYBACKRATE:
printf(("WODM_GETPLAYBACKRATE"));
/*
pOutClient = (PWAVEALLOC)dwUser;
pOutClient->AuxParam.GetSetData.pData = (PBYTE)dwParam1;
pOutClient->AuxParam.GetSetData.DataLen = sizeof(DWORD);
pOutClient->AuxParam.GetSetData.Function =
IOCTL_WAVE_GET_PLAYBACK_RATE;
return waveThreadCall(WaveThreadGetData, pOutClient);
*/
printf("WODM_GETPLAYBACKRATE");
((PWAVEALLOC)dwUser)->AuxParam.GetSetData.pData = (PBYTE)dwParam1;
((PWAVEALLOC)dwUser)->AuxParam.GetSetData.DataLen = sizeof(DWORD);
((PWAVEALLOC)dwUser)->AuxParam.GetSetData.Function = IOCTL_WAVE_GET_PLAYBACK_RATE;
return ThreadCallWaveDevice(WaveThreadGetData, (PWAVEALLOC)dwUser);
default:
return MMSYSERR_NOTSUPPORTED;
}
//
// Should not get here
//
// This point of execution should never be reached
return MMSYSERR_NOTSUPPORTED;
}
APIENTRY DWORD widMessage(DWORD id, DWORD msg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
/*
* @unimplemented
*/
APIENTRY DWORD widMessage(DWORD dwId, DWORD dwMessage, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
{
printf("widMessage\n");
switch (msg) {
switch (dwMessage) {
case WIDM_GETNUMDEVS:
return GetDeviceCount(WaveInDevice);
default :

80
reactos/lib/mmdrv/wave.h Normal file
View file

@ -0,0 +1,80 @@
// FIXME: Should be moved somewhere else?
typedef struct _WAVE_DD_VOLUME {
ULONG Left;
ULONG Right;
} WAVE_DD_VOLUME, *PWAVE_DD_VOLUME;
// driver
#define WAVE_DD_STOP 0x0001
#define WAVE_DD_PLAY 0x0002 // output devices only
#define WAVE_DD_RECORD 0x0003 // input devices only
#define WAVE_DD_RESET 0x0004
// ioctl
#define WAVE_DD_IDLE 0x0000
#define WAVE_DD_STOPPED 0x0001 // stopped
#define WAVE_DD_PLAYING 0x0002 // output devices only
#define WAVE_DD_RECORDING 0x0003 // input devices only
typedef enum {
WaveThreadInvalid,
WaveThreadAddBuffer,
WaveThreadSetState,
WaveThreadSetData,
WaveThreadGetData,
WaveThreadBreakLoop,
WaveThreadClose,
WaveThreadTerminate
} WAVETHREADFUNCTION;
// WARNING: MS code below!!
typedef struct {
OVERLAPPED Ovl;
LPWAVEHDR WaveHdr;
} WAVEOVL, *PWAVEOVL;
// WARNING: MS code below!!
// per allocation structure for wave
typedef struct tag_WAVEALLOC {
struct tag_WAVEALLOC *Next; // Chaining
UINT DeviceNumber; // Which device
UINT DeviceType; // WaveInput or WaveOutput
DWORD dwCallback; // client's callback
DWORD dwInstance; // client's instance data
DWORD dwFlags; // Open flags
HWAVE hWave; // handle for stream
HANDLE hDev; // Wave device handle
LPWAVEHDR DeviceQueue; // Buffers queued by application
LPWAVEHDR NextBuffer; // Next buffer to send to device
DWORD BufferPosition; // How far we're into a large buffer
DWORD BytesOutstanding;
// Bytes being processed by device
LPWAVEHDR LoopHead; // Start of loop if any
DWORD LoopCount; // Number more loops to go
WAVEOVL DummyWaveOvl; // For break loop
//
HANDLE Event; // Event for driver syncrhonization
// and notification of auxiliary
// task operation completion.
WAVETHREADFUNCTION AuxFunction; // Function for thread to perform
union {
LPWAVEHDR pHdr; // Buffer to pass in aux task
ULONG State; // State to set
struct {
ULONG Function; // IOCTL to use
PBYTE pData; // Data to set or get
ULONG DataLen; // Length of data
} GetSetData;
} AuxParam;
// 0 means terminate task.
HANDLE AuxEvent1; // Aux thread waits on this
HANDLE AuxEvent2; // Caller of Aux thread waits on this
HANDLE ThreadHandle; // Handle for thread termination ONLY
MMRESULT AuxReturnCode; // Return code from Aux task
}WAVEALLOC, *PWAVEALLOC;