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/snd…
==============================================================================
--- 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/react…
==============================================================================
--- 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/s…
==============================================================================
--- 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/s…
==============================================================================
--- 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/s…
==============================================================================
--- 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/s…
==============================================================================
--- 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/s…
==============================================================================
--- 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;
+}