Author: silverblade
Date: Mon Jul 14 17:06:03 2008
New Revision: 34509
URL:
http://svn.reactos.org/svn/reactos?rev=34509&view=rev
Log:
Implemented support for buffer looping (WHDR_BEGINLOOP and WHDR_ENDLOOP of the
WAVEHDR structure.) I had a feeling this was going to be very nasty to
implement, but it was actually very easy. Resolved infinite loop where the same
buffer is used for the beginning and end, tested with varying numbers of loops.
Not sure if dwLoops=1 means play buffer twice as dwLoops=0 means play once through.
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/wave/streaming.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] Mon Jul 14
17:06:03 2008
@@ -184,11 +184,12 @@
POPUP("Click for WODM_WRITE test");
WaveHeaders[0].lpData = (PVOID) Buffer;
WaveHeaders[0].dwBufferLength = 1000000;
- WaveHeaders[0].dwFlags = WHDR_PREPARED;
+ WaveHeaders[0].dwFlags = WHDR_PREPARED | WHDR_BEGINLOOP;
+ WaveHeaders[0].dwLoops = 0;
WaveHeaders[1].lpData = (PVOID) ((PCHAR)Buffer + 1000000);
WaveHeaders[1].dwBufferLength = 1000000;
- WaveHeaders[1].dwFlags = WHDR_PREPARED;
+ WaveHeaders[1].dwFlags = WHDR_PREPARED | WHDR_ENDLOOP;
WaveHeaders[2].lpData = (PVOID) ((PCHAR)Buffer + (1000000 *2));
WaveHeaders[2].dwBufferLength = 1000000;
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] Mon Jul
14 17:06:03 2008
@@ -269,9 +269,12 @@
/* The buffer currently being processed */
PWAVEHDR CurrentBuffer;
/* How far into the current buffer we've gone */
- //DWORD BufferOffset;
+ DWORD BufferOffset;
/* How many I/O operations have been submitted */
DWORD BuffersOutstanding;
+ /* Looping */
+ PWAVEHDR LoopHead;
+ DWORD LoopsRemaining;
} WAVE_STREAM_INFO, *PWAVE_STREAM_INFO;
Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/streaming.c
URL:
http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/s…
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/streaming.c [iso-8859-1]
(original)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/streaming.c [iso-8859-1]
Mon Jul 14 17:06:03 2008
@@ -9,6 +9,10 @@
* PROGRAMMERS: Andrew Greenwood (silverblade(a)reactos.org)
*/
+/*
+ TODO: If loops == 0 do we play once, and loops == 1 play twice?
+*/
+
#include <windows.h>
#include <mmsystem.h>
@@ -90,14 +94,26 @@
return 0;
}
+ /* Is this the beginning of a loop? */
+ if ( StreamInfo->CurrentBuffer->dwFlags & WHDR_BEGINLOOP )
+ {
+ /* Avoid infinite looping where the beginning and end are the same */
+ if ( StreamInfo->LoopHead != StreamInfo->CurrentBuffer )
+ {
+ TRACE_("Beginning of loop\n");
+ StreamInfo->LoopHead = StreamInfo->CurrentBuffer;
+ StreamInfo->LoopsRemaining = StreamInfo->CurrentBuffer->dwLoops;
+ }
+ }
+
/* Work out how much buffer can be submitted */
BytesToStream = MinimumOf(StreamInfo->CurrentBuffer->dwBufferLength -
- StreamInfo->CurrentBuffer->reserved,
+ StreamInfo->BufferOffset,
MAX_SOUND_BUFFER_SIZE);
TRACE_("Writing %p + %d (%d bytes) - buffer length is %d bytes\n",
StreamInfo->CurrentBuffer->lpData,
- (int) StreamInfo->CurrentBuffer->reserved,
+ (int) StreamInfo->BufferOffset,
(int) BytesToStream,
(int) StreamInfo->CurrentBuffer->dwBufferLength);
@@ -105,7 +121,7 @@
Result = OverlappedSoundDeviceIo(
SoundDeviceInstance,
(PCHAR) StreamInfo->CurrentBuffer->lpData +
- StreamInfo->CurrentBuffer->reserved,
+ StreamInfo->BufferOffset,
BytesToStream,
CompleteWaveBuffer,
(PVOID) StreamInfo->CurrentBuffer);
@@ -137,14 +153,30 @@
BytesStreamed = BytesToStream;
/* Advance the offset */
- StreamInfo->CurrentBuffer->reserved += BytesStreamed;
+ StreamInfo->BufferOffset += BytesStreamed;
/* If we've hit the end of the buffer, move to the next one */
- if ( StreamInfo->CurrentBuffer->reserved ==
+ if ( StreamInfo->BufferOffset ==
StreamInfo->CurrentBuffer->dwBufferLength )
{
TRACE_("Advancing to next buffer\n");
- StreamInfo->CurrentBuffer = StreamInfo->CurrentBuffer->lpNext;
+
+ if ( ( StreamInfo->CurrentBuffer->dwFlags & WHDR_ENDLOOP ) &&
+ ( StreamInfo->LoopHead ) &&
+ ( StreamInfo->LoopsRemaining > 0 ) )
+ {
+ /* Loop back to the head */
+ StreamInfo->CurrentBuffer = StreamInfo->LoopHead;
+ -- StreamInfo->LoopsRemaining;
+ TRACE_("Now %d loops remaining\n", (int)
StreamInfo->LoopsRemaining);
+ }
+ else
+ {
+ /* Either not looping, or looping expired */
+ StreamInfo->CurrentBuffer = StreamInfo->CurrentBuffer->lpNext;
+ }
+
+ StreamInfo->BufferOffset = 0;
}
/* Increase the number of outstanding buffers */
@@ -238,9 +270,12 @@
StreamInfo->CurrentBuffer = WaveHeader;
/* Initialise the stream state */
- //StreamInfo->BufferOffset = 0;
+ StreamInfo->BufferOffset = 0;
//StreamInfo->BytesOutstanding = 0;
StreamInfo->BuffersOutstanding = 0;
+
+ StreamInfo->LoopHead = NULL;
+ StreamInfo->LoopsRemaining = 0;
/* Get the streaming started */
StreamWaveBuffers(SoundDeviceInstance);