Author: silverblade Date: Sun Jul 6 13:57:26 2008 New Revision: 34340
URL: http://svn.reactos.org/svn/reactos?rev=34340&view=rev Log: Some restructuring to avoid SOUND_DEVICE_INSTANCE containing members only relevant to the a wave device thread. Now there are separate structures for device, device instance, thread, and anything relevant to a wave thread. Extended overlapped I/O structure so that the completion routine can identify the device instance, completed wave buffer and thread-specific data. The completion routine re-submits the same buffer repeatedly at present.
Modified: branches/silverblade-audio/dll/win32/sndblst/sndblst.c branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h branches/silverblade-audio/lib/drivers/sound/mmebuddy/instances.c branches/silverblade-audio/lib/drivers/sound/mmebuddy/kernel.c branches/silverblade-audio/lib/drivers/sound/mmebuddy/mme/wodMessage.c branches/silverblade-audio/lib/drivers/sound/mmebuddy/thread.c branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wavethread.c
Modified: branches/silverblade-audio/dll/win32/sndblst/sndblst.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/dll/win32/sndb... ============================================================================== --- branches/silverblade-audio/dll/win32/sndblst/sndblst.c [iso-8859-1] (original) +++ branches/silverblade-audio/dll/win32/sndblst/sndblst.c [iso-8859-1] Sun Jul 6 13:57:26 2008 @@ -132,6 +132,10 @@ WAVEFORMATEX Format; MMRESULT Result; PVOID InstanceData; + int i; + + for ( i = 0; i < 65536; ++ i ) + Buffer[i] = rand();
/* DRV_LOAD */ DriverProc(0, 0, DRV_LOAD, 0, 0);
Modified: branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/include/reacto... ============================================================================== --- branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h [iso-8859-1] (original) +++ branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h [iso-8859-1] Sun Jul 6 13:57:26 2008 @@ -101,18 +101,17 @@ MMRESULT Result; } THREAD_REQUEST, *PTHREAD_REQUEST;
- -/* - Thread helper operations -*/ typedef MMRESULT (*SOUND_THREAD_REQUEST_HANDLER)( IN struct _SOUND_DEVICE_INSTANCE* Instance, + IN PVOID PrivateThreadData, IN DWORD RequestId, IN PVOID Data);
typedef struct _SOUND_THREAD { + /* Thread management */ HANDLE Handle; + PVOID PrivateData; BOOLEAN Running; SOUND_THREAD_REQUEST_HANDLER RequestHandler; HANDLE ReadyEvent; /* Thread waiting for a request */ @@ -123,8 +122,30 @@
/* + Wave thread +*/ + +typedef struct _WAVE_OVERLAPPED +{ + OVERLAPPED General; + struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance; + struct _WAVE_THREAD_DATA* ThreadData; + PWAVEHDR Header; +} WAVE_OVERLAPPED, *PWAVE_OVERLAPPED; + +typedef struct _WAVE_THREAD_DATA +{ + /* Wave thread specific */ + WAVE_OVERLAPPED Overlapped; + + DWORD BufferCount; + PWAVEHDR CurrentBuffer; + PWAVEHDR FirstBuffer; + PWAVEHDR LastBuffer; +} WAVE_THREAD_DATA, *PWAVE_THREAD_DATA; + +/* Audio device function table - TODO - create/destroy instance need to work */
typedef MMRESULT (*MMCREATEINSTANCE_FUNC)( @@ -193,20 +214,6 @@ { DWORD ClientCallback; } WinMM; - - /* Everything below this is used by the worker thread only */ - OVERLAPPED Overlapped; - - union - { - struct - { - DWORD BufferCount; - PWAVEHDR CurrentBuffer; - PWAVEHDR FirstBuffer; - PWAVEHDR LastBuffer; - } Wave; - }; } SOUND_DEVICE_INSTANCE, *PSOUND_DEVICE_INSTANCE;
@@ -359,7 +366,8 @@ IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN LPVOID Buffer, IN DWORD BufferSize, - IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine); + IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine, + LPOVERLAPPED Overlapped);
/* @@ -467,7 +475,8 @@ MMRESULT StartSoundThread( IN PSOUND_DEVICE_INSTANCE Instance, - IN SOUND_THREAD_REQUEST_HANDLER RequestHandler); + IN SOUND_THREAD_REQUEST_HANDLER RequestHandler, + IN PVOID Data);
MMRESULT StopSoundThread( @@ -478,6 +487,11 @@ IN PSOUND_DEVICE_INSTANCE Instance, IN DWORD RequestId, IN PVOID RequestData); + +MMRESULT +GetSoundThreadPrivateData( + IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, + OUT PVOID* PrivateData);
Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/instances.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/so... ============================================================================== --- branches/silverblade-audio/lib/drivers/sound/mmebuddy/instances.c [iso-8859-1] (original) +++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/instances.c [iso-8859-1] Sun Jul 6 13:57:26 2008 @@ -31,6 +31,7 @@ SoundDeviceInstance->Next = NULL; SoundDeviceInstance->Device = NULL; SoundDeviceInstance->Thread = NULL; + /* TODO: WinMM callback entry */ }
PSOUND_DEVICE_INSTANCE
Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/kernel.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/so... ============================================================================== --- branches/silverblade-audio/lib/drivers/sound/mmebuddy/kernel.c [iso-8859-1] (original) +++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/kernel.c [iso-8859-1] Sun Jul 6 13:57:26 2008 @@ -212,13 +212,12 @@ PSOUND_DEVICE_INSTANCE SoundDeviceInstance, LPVOID Buffer, DWORD BufferSize, - LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine) + LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine, + LPOVERLAPPED Overlapped) { WCHAR msg[128]; if ( ( ! SoundDeviceInstance ) || ( ! Buffer ) || ( BufferSize == 0 ) ) return MMSYSERR_INVALPARAM; - - ZeroMemory(&SoundDeviceInstance->Overlapped, sizeof(OVERLAPPED));
wsprintf(msg, L"Writing to handle %x", SoundDeviceInstance->Device->Handle); SOUND_DEBUG(msg); @@ -226,7 +225,7 @@ if ( ! WriteFileEx(SoundDeviceInstance->Device->Handle, Buffer, BufferSize, - &SoundDeviceInstance->Overlapped, + Overlapped, CompletionRoutine) ) { wsprintf(msg, L"Win32 Error %d", GetLastError());
Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/mme/wodMessage.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/so... ============================================================================== --- branches/silverblade-audio/lib/drivers/sound/mmebuddy/mme/wodMessage.c [iso-8859-1] (original) +++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/mme/wodMessage.c [iso-8859-1] Sun Jul 6 13:57:26 2008 @@ -124,6 +124,8 @@ Result = DestroySoundDeviceInstance(Instance); SOUND_DEBUG_HEX(Result);
+ /* TODO: When do we send the callback? */ + return Result; /* CloseSoundDevice() */ }
Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/thread.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/so... ============================================================================== --- branches/silverblade-audio/lib/drivers/sound/mmebuddy/thread.c [iso-8859-1] (original) +++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/thread.c [iso-8859-1] Sun Jul 6 13:57:26 2008 @@ -59,6 +59,7 @@ /* Do the work (request 0 kills the thread) */ Thread->Request.Result = Thread->RequestHandler(Instance, + Thread->PrivateData, Thread->Request.RequestId, Thread->Request.Data);
@@ -139,7 +140,8 @@ MMRESULT StartSoundThread( IN PSOUND_DEVICE_INSTANCE Instance, - IN SOUND_THREAD_REQUEST_HANDLER RequestHandler) + IN SOUND_THREAD_REQUEST_HANDLER RequestHandler, + IN LPVOID PrivateThreadData) { PSOUND_THREAD SoundThread = NULL;
@@ -161,6 +163,7 @@ return MMSYSERR_NOMEM;
/* Initialise */ + SoundThread->PrivateData = PrivateThreadData; SoundThread->Running = FALSE; SoundThread->Handle = INVALID_HANDLE_VALUE; SoundThread->RequestHandler = RequestHandler; @@ -239,35 +242,54 @@
MMRESULT CallSoundThread( - IN PSOUND_DEVICE_INSTANCE Instance, + IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN DWORD RequestId, IN PVOID RequestData) { MMRESULT Result;
- if ( ! Instance ) - return MMSYSERR_INVALPARAM; - - if ( ! Instance->Thread ) + if ( ! SoundDeviceInstance ) + return MMSYSERR_INVALPARAM; + + if ( ! SoundDeviceInstance->Thread ) return MMSYSERR_ERROR;
/* Wait for the thread to be ready */ - WaitForSingleObject(Instance->Thread->ReadyEvent, INFINITE); + WaitForSingleObject(SoundDeviceInstance->Thread->ReadyEvent, INFINITE);
/* Load the request */ - Instance->Thread->Request.DeviceInstance = Instance; - Instance->Thread->Request.RequestId = RequestId; - Instance->Thread->Request.Data = RequestData; - Instance->Thread->Request.Result = MMSYSERR_NOTSUPPORTED; + SoundDeviceInstance->Thread->Request.DeviceInstance = SoundDeviceInstance; + SoundDeviceInstance->Thread->Request.RequestId = RequestId; + SoundDeviceInstance->Thread->Request.Data = RequestData; + SoundDeviceInstance->Thread->Request.Result = MMSYSERR_NOTSUPPORTED;
/* Notify the thread that there's a request to be processed */ - SetEvent(Instance->Thread->RequestEvent); + SetEvent(SoundDeviceInstance->Thread->RequestEvent);
/* Wait for the thread to be ready (request complete) */ - WaitForSingleObject(Instance->Thread->DoneEvent, INFINITE); + WaitForSingleObject(SoundDeviceInstance->Thread->DoneEvent, INFINITE);
/* Grab the result */ - Result = Instance->Thread->Request.Result; + Result = SoundDeviceInstance->Thread->Request.Result;
return Result; } + +MMRESULT +GetSoundThreadPrivateData( + IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, + OUT PVOID* PrivateData) +{ + if ( ! SoundDeviceInstance ) + return MMSYSERR_INVALPARAM; + + if ( ! SoundDeviceInstance->Thread ) + return MMSYSERR_ERROR; + + if ( ! PrivateData ) + return MMSYSERR_INVALPARAM; + + *PrivateData = SoundDeviceInstance->Thread->PrivateData; + + return MMSYSERR_NOERROR; +}
Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wavethread.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/so... ============================================================================== --- branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wavethread.c [iso-8859-1] (original) +++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wavethread.c [iso-8859-1] Sun Jul 6 13:57:26 2008 @@ -19,6 +19,14 @@ #include <mmsystem.h>
#include <mmebuddy.h> + +MMRESULT +WriteWaveBufferToSoundDevice( + IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, + IN PWAVE_THREAD_DATA ThreadData, + IN PWAVEHDR WaveHeader); + +
VOID CALLBACK WaveBufferCompleted( @@ -26,47 +34,91 @@ IN DWORD dwNumberOfBytesTransferred, IN LPOVERLAPPED lpOverlapped) { - MessageBox(0, L"Job done!", L"File IO Callback", MB_OK | MB_TASKMODAL); -} + PWAVE_OVERLAPPED WaveOverlapped = (PWAVE_OVERLAPPED) lpOverlapped; + /*PWAVE_THREAD_DATA ThreadData = WaveOverlapped->ThreadData;*/ + WCHAR msg[1024]; + + wsprintf(msg, L"Buffer %x done\nWrote %d bytes\nErrCode %d", + WaveOverlapped->Header, + dwNumberOfBytesTransferred, + dwErrorCode); + + MessageBox(0, msg, L"File IO Callback", MB_OK | MB_TASKMODAL); + + WriteWaveBufferToSoundDevice(WaveOverlapped->SoundDeviceInstance, + WaveOverlapped->ThreadData, + WaveOverlapped->Header); +} + +MMRESULT +WriteWaveBufferToSoundDevice( + IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, + IN PWAVE_THREAD_DATA ThreadData, + IN PWAVEHDR WaveHeader) +{ + SOUND_ASSERT(SoundDeviceInstance); + SOUND_ASSERT(ThreadData); + SOUND_ASSERT(WaveHeader); + + /* Prepare our overlapped data */ + ZeroMemory(&ThreadData->Overlapped, sizeof(WAVE_OVERLAPPED)); + ThreadData->Overlapped.SoundDeviceInstance = SoundDeviceInstance; + ThreadData->Overlapped.ThreadData = ThreadData; + ThreadData->Overlapped.Header = WaveHeader; + + return WriteSoundDeviceBuffer(SoundDeviceInstance, + WaveHeader->lpData, + WaveHeader->dwBufferLength, + WaveBufferCompleted, + (LPOVERLAPPED) &ThreadData->Overlapped); +} +
/* Internal dispatch routines */
MMRESULT SubmitWaveBuffer( IN PSOUND_DEVICE_INSTANCE Instance, + IN PWAVE_THREAD_DATA ThreadData, IN PWAVEHDR Buffer) { - MMRESULT Result; - SOUND_ASSERT(Instance != NULL); SOUND_ASSERT(Buffer != NULL); + SOUND_ASSERT(Instance->Thread != NULL); + + /* Store the device instance */ + Buffer->reserved = (DWORD) Instance;
/* Set the head of the buffer list if this is the first buffer */ - if ( ! Instance->Wave.FirstBuffer ) - { - Instance->Wave.FirstBuffer = Buffer; + if ( ! ThreadData->FirstBuffer ) + { + ThreadData->FirstBuffer = Buffer; }
/* Attach the buffer to the end of the list, unless this is the first */ - if ( Instance->Wave.LastBuffer ) - { - Instance->Wave.LastBuffer->lpNext = Buffer; + if ( ThreadData->LastBuffer ) + { + ThreadData->LastBuffer->lpNext = Buffer; }
/* Update our record of the last buffer */ - Instance->Wave.LastBuffer = Buffer; + ThreadData->LastBuffer = Buffer;
/* Increment the number of buffers queued */ - ++ Instance->Wave.BufferCount; + ++ ThreadData->BufferCount;
/* HACK */ - Instance->Wave.CurrentBuffer = Instance->Wave.FirstBuffer; - + ThreadData->CurrentBuffer = ThreadData->FirstBuffer; + + WriteWaveBufferToSoundDevice(Instance, ThreadData, Buffer); + +/* Result = WriteSoundDeviceBuffer(Instance, - Instance->Wave.CurrentBuffer->lpData, - Instance->Wave.CurrentBuffer->dwBufferLength, - WaveBufferCompleted); - + ThreadData->CurrentBuffer->lpData, + ThreadData->CurrentBuffer->dwBufferLength, + WaveBufferCompleted, + (LPOVERLAPPED) &Thread->Wave.Overlapped); +*/ return MMSYSERR_NOERROR; }
@@ -76,9 +128,13 @@ MMRESULT ProcessWaveThreadRequest( IN PSOUND_DEVICE_INSTANCE Instance, + IN PVOID PrivateThreadData, IN DWORD RequestId, IN PVOID Data) { + PWAVE_THREAD_DATA WaveThreadData = + (PWAVE_THREAD_DATA) PrivateThreadData; + /* Just some temporary testing code for now */ WCHAR msg[128]; wsprintf(msg, L"Request %d received", RequestId); @@ -93,7 +149,7 @@ { PWAVEHDR Buffer = (PWAVEHDR) Data;
- return SubmitWaveBuffer(Instance, Buffer); + return SubmitWaveBuffer(Instance, WaveThreadData, Buffer); } }
@@ -105,20 +161,30 @@ IN PSOUND_DEVICE_INSTANCE Instance) { MMRESULT Result = MMSYSERR_NOERROR; + PWAVE_THREAD_DATA WaveThreadData = NULL;
if ( ! Instance ) return MMSYSERR_INVALPARAM;
+ WaveThreadData = AllocateMemoryFor(WAVE_THREAD_DATA); + + if ( ! WaveThreadData ) + return MMSYSERR_NOMEM; + /* Initialise our data */ - Instance->Wave.CurrentBuffer = NULL; - Instance->Wave.FirstBuffer = NULL; - Instance->Wave.LastBuffer = NULL; - Instance->Wave.BufferCount = 0; + WaveThreadData->CurrentBuffer = NULL; + WaveThreadData->FirstBuffer = NULL; + WaveThreadData->LastBuffer = NULL; + WaveThreadData->BufferCount = 0; + /* TODO: More */
/* Kick off the thread */ - Result = StartSoundThread(Instance, ProcessWaveThreadRequest); + Result = StartSoundThread(Instance, + ProcessWaveThreadRequest, + WaveThreadData); if ( Result != MMSYSERR_NOERROR ) { + FreeMemory(WaveThreadData); return Result; }
@@ -130,8 +196,20 @@ StopWaveThread( IN PSOUND_DEVICE_INSTANCE Instance) { + MMRESULT Result; + PWAVE_THREAD_DATA WaveThreadData = NULL; + if ( ! Instance ) return MMSYSERR_INVALPARAM;
- return StopSoundThread(Instance); -} + Result = GetSoundThreadPrivateData(Instance, (PVOID*) &WaveThreadData); + SOUND_ASSERT( Result == MMSYSERR_NOERROR ); + + /* This shouldn't fail... */ + Result = StopSoundThread(Instance); + SOUND_ASSERT( Result == MMSYSERR_NOERROR ); + + FreeMemory(WaveThreadData); + + return MMSYSERR_NOERROR; +}