[ros-diffs] [silverblade] 34360: Wave buffers are now split up into chunks before being fed to the sound driver. Testing by writing 65, 536 bytes using an un-even block size of 16, 383. Results in 4 x 16, 383 byte blocks and 1 x 4 byte block, as expected. Completion of one buffer results in submission of the next. Doesn't handle multiple WAVEHDRs yet.

silverblade at svn.reactos.org silverblade at svn.reactos.org
Tue Jul 8 00:59:46 CEST 2008


Author: silverblade
Date: Mon Jul  7 17:59:45 2008
New Revision: 34360

URL: http://svn.reactos.org/svn/reactos?rev=34360&view=rev
Log:
Wave buffers are now split up into chunks before being fed to the sound driver.
Testing by writing 65,536 bytes using an un-even block size of 16,383. Results
in 4 x 16,383 byte blocks and 1 x 4 byte block, as expected. Completion of
one buffer results in submission of the next. Doesn't handle multiple WAVEHDRs
yet.


Modified:
    branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/thread.c
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wavethread.c

Modified: branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h?rev=34360&r1=34359&r2=34360&view=diff
==============================================================================
--- 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] Mon Jul  7 17:59:45 2008
@@ -169,7 +169,8 @@
     PWAVEHDR FirstBuffer;
     PWAVEHDR LastBuffer;
 
-    /*DWORD RemainingBytes;*/
+    /* How much data is waiting with the driver */
+    DWORD RemainingBytes;
 } WAVE_THREAD_DATA, *PWAVE_THREAD_DATA;
 
 /*

Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/thread.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/thread.c?rev=34360&r1=34359&r2=34360&view=diff
==============================================================================
--- 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] Mon Jul  7 17:59:45 2008
@@ -12,6 +12,11 @@
         4 July 2008 - Created
         5 July 2008 - Implemented basic request processing
         6 July 2008 - Added I/O completion handling
+
+    Possible improvements:
+        Spawn *one* thread to deal with requests and I/O completion, rather
+        than have a thread per sound device instance. This wouldn't be too
+        hard to do but not worth doing right now.
 */
 
 /*

Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wavethread.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wavethread.c?rev=34360&r1=34359&r2=34360&view=diff
==============================================================================
--- 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] Mon Jul  7 17:59:45 2008
@@ -23,23 +23,97 @@
 
 
 /*
-    Just a neat wrapper around the writing routine.
-*/
-
-MMRESULT
-WriteWaveBufferToSoundDevice(
+    How much we can feed to the driver at a time.
+    This is deliberately set low at the moment for testing purposes, and
+    intentionally set to be "one out" from 16384 so that writing 65536 bytes
+    results in 4x16383 byte buffers followed by 1x4 byte buffer.
+
+    Should it be configurable? Some sound drivers let you set buffer size...
+*/
+#define MAX_SOUND_BUFFER_SIZE   16383
+
+
+/*
+    Audio buffer I/O streaming handler. Slices 'n dices your buffers and
+    serves them up on a platter with a side dressing of your choice.
+
+    It's safe to update the buffer information post-submission within this
+    routine since any completion will be done in an APC for the same thread,
+    so we're not likely to be rudely interrupted by a completion routine
+    bursting through the door.
+*/
+MMRESULT
+StreamWaveData(
     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
-    IN  PWAVE_THREAD_DATA ThreadData,
-    IN  PWAVEHDR WaveHeader)
-{
-    SOUND_ASSERT(SoundDeviceInstance);
-    SOUND_ASSERT(ThreadData);
-    SOUND_ASSERT(WaveHeader);
-
-    return OverlappedWriteToSoundDevice(SoundDeviceInstance,
-                                        (PVOID) WaveHeader,
-                                        WaveHeader->lpData,
-                                        WaveHeader->dwBufferLength);
+    IN  PWAVE_THREAD_DATA ThreadData)
+{
+    PWAVEHDR Buffer = ThreadData->CurrentBuffer;
+    DWORD BufferOffset, BytesToStream, BytesAvailable;
+    MMRESULT Result;
+
+    SOUND_ASSERT(ThreadData->RemainingBytes <= MAX_SOUND_BUFFER_SIZE);
+    SOUND_ASSERT(Buffer);
+
+    /* The 'reserved' member of Buffer contains the offset */
+    BufferOffset = Buffer->reserved;
+
+    /* Work out how much data can be streamed with the driver */
+    BytesAvailable = MAX_SOUND_BUFFER_SIZE - ThreadData->RemainingBytes;
+
+    /*
+        If no space available, don't do anything. The routine will be revisited
+        as buffers complete, at which point the backlog will start being
+        dealt with.
+    */
+    if ( BytesAvailable == 0 )
+        return MMSYSERR_NOERROR;
+
+    /*
+        Adjust the amount of data to be streamed based on how much of the
+        current buffer has actually been dealt with already.
+    */
+    BytesToStream = Buffer->dwBufferLength - BufferOffset;
+
+    /*
+        No point in doing work unless we have to... This is, however, a
+        completed buffer, so it should be dealt with!!
+    */
+    if ( BytesToStream == 0 )
+    {
+        /* TODO */
+        return MMSYSERR_NOERROR;
+    }
+
+    /*
+        Now we know how much buffer is waiting to be provided to the driver,
+        we need to consider how much the driver can accept.
+    */
+    if ( BytesToStream > BytesAvailable )
+    {
+        /* Buffer can't fit entirely - fill the available space */
+        BytesToStream = BytesAvailable;
+    }
+
+    /*
+        Now the audio buffer sets sail on its merry way to the sound driver...
+        NOTE: Will need to implement a 'read' function, too.
+    */
+    Result = OverlappedWriteToSoundDevice(SoundDeviceInstance,
+                                          (PVOID) ThreadData,
+                                          Buffer->lpData + BufferOffset,
+                                          BytesToStream);
+
+    if ( Result != MMSYSERR_NOERROR )
+        return Result;
+
+    /* Update the offset ready for the next streaming operation */
+    BufferOffset += BytesToStream;
+    Buffer->reserved = BufferOffset;
+
+    /* More data has been sent to the driver, so this is updated, too */
+    ThreadData->RemainingBytes += BytesToStream;
+
+    return MMSYSERR_NOERROR;
 }
 
 
@@ -53,12 +127,15 @@
     IN  PWAVE_THREAD_DATA ThreadData,
     IN  PWAVEHDR Buffer)
 {
+/*    DWORD BytesSubmitted = 0;*/
+
     SOUND_ASSERT(Instance != NULL);
     SOUND_ASSERT(Buffer != NULL);
     SOUND_ASSERT(Instance->Thread != NULL);
 
-    /* Store the device instance */
-    Buffer->reserved = (DWORD) Instance;
+    /* This is used to mark the offset within the buffer */
+    Buffer->reserved = 0;
+    /* TODO: Clear completion flag */
 
     /* Set the head of the buffer list if this is the first buffer */
     if ( ! ThreadData->FirstBuffer )
@@ -78,18 +155,13 @@
     /* Increment the number of buffers queued */
     ++ ThreadData->BufferCount;
 
-    /* HACK */
-    ThreadData->CurrentBuffer = ThreadData->FirstBuffer;
-
-    WriteWaveBufferToSoundDevice(Instance, ThreadData, Buffer);
-
-/*
-    Result = WriteSoundDeviceBuffer(Instance,
-                                    ThreadData->CurrentBuffer->lpData,
-                                    ThreadData->CurrentBuffer->dwBufferLength,
-                                    WaveBufferCompleted,
-                                    (LPOVERLAPPED) &Thread->Wave.Overlapped);
-*/
+    /* If nothing is playing, we'll need to start things off */
+    if ( ThreadData->RemainingBytes == 0 )
+    {
+        ThreadData->CurrentBuffer = ThreadData->FirstBuffer;
+        StreamWaveData(Instance, ThreadData);
+    }
+
     return MMSYSERR_NOERROR;
 }
 
@@ -141,10 +213,12 @@
     IN  PVOID ContextData,
     IN  DWORD BytesTransferred)
 {
-    LPWAVEHDR WaveHeader = (LPWAVEHDR) ContextData;
-
-    SOUND_DEBUG(L"ProcessWaveIoCompletion called :)");
-    SOUND_DEBUG_HEX(WaveHeader);
+    PWAVE_THREAD_DATA ThreadData = (PWAVE_THREAD_DATA) ContextData;
+    SOUND_ASSERT(ThreadData);
+    WCHAR msg[1024];
+
+    /*SOUND_DEBUG(L"ProcessWaveIoCompletion called :)");*/
+    /*SOUND_DEBUG_HEX(WaveHeader);*/
 
     /*
         At this point we know:
@@ -164,6 +238,21 @@
         thread will wait for more requests from the client before
         it does anything else.
     */
+
+    /* Discount the amount of buffer which has been processed */
+    SOUND_ASSERT(BytesTransferred <= ThreadData->RemainingBytes);
+    ThreadData->RemainingBytes -= BytesTransferred;
+
+    wsprintf(msg, L"Wave header: %x\nOffset: %d\nTransferred: %d bytes\nRemaining: %d bytes",
+             ThreadData->CurrentBuffer,
+             ThreadData->CurrentBuffer->reserved,
+             BytesTransferred,
+             ThreadData->RemainingBytes);
+
+    MessageBox(0, msg, L"I/O COMPLETE", MB_OK | MB_TASKMODAL);
+
+    /* TODO: Check return value */
+    StreamWaveData(Instance, ThreadData);
 }
 
 



More information about the Ros-diffs mailing list