Skip to content

Commit

Permalink
[MMEBUDDY] Implement support for looped wave playback
Browse files Browse the repository at this point in the history
Fix playing wave header multiple times in case the caller requests to do it.
In Windows, it is supported by WHDR_BEGINLOOP and WHDR_ENDLOOP flags (specified together) and dwLoops member of WAVEHDR structure (ususally set to 0xFFFFFFFF (INFINITE constant)).
- Check whenther WHDR_BEGINLOOP | WHDR_ENDLOOP flags are set by the caller.
- If they are, get the amount of times to play the header from WAVEHDR.dwLoops.
- Perform wave header competion only when the loop count is equal to zero. Otherwise, don't do it.
- When the header is entirely committed, in case completion is not needed, reset committed bytes count to the starting value to allow the header play again.
- Decrement loop count in that case, to mark loop as played correctly. When this count becomes zero, the playback is finished.
- Do this only for WaveOut devices, since MSDN states it works only with output buffers. Hence, there is nothing changed for WaveIn.
- Update an appropriate statement about unimplemented functionality from mmebuddy notes.
TODO: probably handle the case when multiple headers are requested to be looped (WHDR_BEGINLOOP and WHDR_ENDLOOP are set separatedly: 1st flag - in the 1st header, and 2nd in the last header). Currently, only looping a single wave header is supported (if I'm not wrong here).
This fixes the playback in the apps those request looped wave playback of some audio data (e. g., BRD Demo app, which did play its sound only first 500 ms before, now it plays endlessly until closing it manually).
CORE-10118
  • Loading branch information
oleg-dubinskiy committed Apr 17, 2024
1 parent 6cb18bc commit 4f94a53
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 4 deletions.
2 changes: 1 addition & 1 deletion sdk/lib/drivers/sound/mmebuddy/readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Unsupported MME messages:
* Any not mentioned above

Notes/Bugs:
* WHDR_BEGINLOOP and WHDR_ENDLOOP are ignored
* WHDR_BEGINLOOP and WHDR_ENDLOOP are not working for looping multiple wave headers, only for a single header.
* Not possible to pause/restart playback


Expand Down
23 changes: 20 additions & 3 deletions sdk/lib/drivers/sound/mmebuddy/wave/streaming.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

#include "precomp.h"


/*
DoWaveStreaming
Check if there is streaming to be done, and if so, do it.
Expand Down Expand Up @@ -54,6 +53,14 @@ DoWaveStreaming(
return;
}

/* Do we need to loop a header? */
if ( Header->dwFlags & ( WHDR_BEGINLOOP | WHDR_ENDLOOP ) &&
DeviceType == WAVE_OUT_DEVICE_TYPE )
{
/* Yes, we do, so get the loops count */
SoundDeviceInstance->LoopsRemaining = Header->dwLoops;
}

while ( ( SoundDeviceInstance->OutstandingBuffers < SoundDeviceInstance->BufferCount ) &&
( Header ) && SoundDeviceInstance->ResetInProgress == FALSE)
{
Expand Down Expand Up @@ -107,8 +114,7 @@ DoWaveStreaming(
Overlap->Header = Header;

/* Don't complete this header if it's part of a loop */
Overlap->PerformCompletion = TRUE;
// ( SoundDeviceInstance->LoopsRemaining > 0 );
Overlap->PerformCompletion = SoundDeviceInstance->LoopsRemaining == 0;

/* Adjust the commit-related counters */
HeaderExtension->BytesCommitted += BytesToCommit;
Expand Down Expand Up @@ -206,6 +212,17 @@ CompleteIO(
/* Partially completed */
HdrExtension->BytesCompleted += dwNumberOfBytesTransferred;
SND_TRACE(L"%d/%d bytes of wavehdr completed\n", HdrExtension->BytesCompleted, WaveHdr->dwBufferLength);

/* Do we loop a header? */
if ( HdrExtension->BytesCommitted == WaveHdr->dwBufferLength &&
SoundOverlapped->PerformCompletion == FALSE )
{
/* Yes, reset amount of bytes and decrement loop count,
* to play the next iteration
*/
HdrExtension->BytesCommitted = 0;
-- SoundDeviceInstance->LoopsRemaining;
}
break;
}

Expand Down

0 comments on commit 4f94a53

Please sign in to comment.