media/libsydneyaudio/bug564734-win32-drain.patch
author Chris Lord <chrislord.net@gmail.com>
Fri, 17 Jun 2011 08:57:46 -0700
changeset 71278 0839c57106a8351290736b54f22b416942e96d28
parent 42253 3cf79d49588ef1a0f88a73ec0efe1a8444d76a66
permissions -rw-r--r--
Bug 664996 - After quitting the application by tapping the Home button, re-entering it will show a white. Regression from bug 661843. r=dougt

diff --git a/media/libsydneyaudio/src/sydney_audio_waveapi.c b/media/libsydneyaudio/src/sydney_audio_waveapi.c
--- a/media/libsydneyaudio/src/sydney_audio_waveapi.c
+++ b/media/libsydneyaudio/src/sydney_audio_waveapi.c
@@ -121,16 +121,17 @@ struct sa_stream {
 };
 
 
 /** Forward definitions of audio api specific functions */
 int allocateBlocks(int size, int count, WAVEHDR** blocks);
 int freeBlocks(WAVEHDR* blocks);
 int openAudio(sa_stream_t *s);
 int closeAudio(sa_stream_t * s);
+int writeBlock(sa_stream_t *s, WAVEHDR* current);
 int writeAudio(sa_stream_t *s, LPSTR data, int bytes);
 int getSAErrorCode(int waveErrorCode);
 
 void CALLBACK waveOutProc(HWAVEOUT hWaveOut, UINT uMsg, 
     DWORD dwInstance, DWORD dwParam1, DWORD dwParam2);
 
 /** Normal way to open a PCM device */
 int sa_stream_create_pcm(sa_stream_t **s, 
@@ -320,20 +321,32 @@ int sa_stream_pause(sa_stream_t *s) {
   
   status = waveOutPause(s->hWaveOut);
   HANDLE_WAVE_ERROR(status, "resuming audio playback");
 
   s->playing = 0;
 
   return SA_SUCCESS;
 }
+
 /** Block until all audio has been played */
 int sa_stream_drain(sa_stream_t *s) {
+  int status;
+  WAVEHDR* current;
+
   ERROR_IF_NO_INIT(s);
-  
+
+  current = &(s->waveBlocks[s->waveCurrentBlock]);
+  if (current->dwUser) {
+    /* We've got pending audio which hasn't been written, we must write it to
+       the hardware, else it will never be played. */
+    status = writeBlock(s, current);
+    HANDLE_WAVE_ERROR(status, "writing audio to audio device");
+  }
+
   if (!s->playing) {
     return SA_ERROR_INVALID;
   }
 
   /* wait for all blocks to complete */
   EnterCriticalSection(&(s->waveCriticalSection));
   while(s->waveFreeBlockCount < BLOCK_COUNT) {
     LeaveCriticalSection(&(s->waveCriticalSection));
@@ -502,16 +515,48 @@ int closeAudio(sa_stream_t * s) {
 
   s->playing = 0;
 
   DeleteCriticalSection(&(s->waveCriticalSection));
   CloseHandle(s->callbackEvent);
   
   return result;
 }
+
+/**
+ * \brief - writes a WAVEHDR block of PCM audio samples to hardware.
+ * \param s - valid handle to opened sydney stream
+ * \param current - pointer to WAVEHDR storing audio samples to be played
+ * \return - completion status
+ */
+int writeBlock(sa_stream_t *s, WAVEHDR* current) {
+  int status;
+  ERROR_IF_NO_INIT(s);
+
+  current->dwBufferLength = current->dwUser;
+  /* write to audio device */
+  waveOutPrepareHeader(s->hWaveOut, current, sizeof(WAVEHDR));
+  status = waveOutWrite(s->hWaveOut, current, sizeof(WAVEHDR));      
+  HANDLE_WAVE_ERROR(status, "writing audio to audio device");
+    
+  EnterCriticalSection(&(s->waveCriticalSection));
+  s->waveFreeBlockCount--;
+  LeaveCriticalSection(&(s->waveCriticalSection));
+
+  /*
+   * point to the next block
+   */
+  (s->waveCurrentBlock)++;
+  (s->waveCurrentBlock) %= BLOCK_COUNT;		
+
+  s->playing = 1;
+
+  return SA_SUCCESS;
+}
+
 /**
  * \brief - writes PCM audio samples to audio device
  * \param s - valid handle to opened sydney stream
  * \param data - pointer to memory storing audio samples to be played
  * \param nsamples - number of samples in the memory pointed by previous parameter
  * \return - completion status
  */
 int writeAudio(sa_stream_t *s, LPSTR data, int bytes) {    
@@ -536,40 +581,27 @@ int writeAudio(sa_stream_t *s, LPSTR dat
 		  
     if(bytes < (int)(BLOCK_SIZE - current->dwUser)) {							  	    
 		  memcpy(current->lpData + current->dwUser, data, bytes);
       current->dwUser += bytes;
       break;
     }
 
     /* remain is even as BLOCK_SIZE and dwUser are even too */
-    remain = BLOCK_SIZE - current->dwUser;      
+    remain = BLOCK_SIZE - current->dwUser;
   	memcpy(current->lpData + current->dwUser, data, remain);
+    current->dwUser += remain;
     bytes -= remain;
     data += remain;
-	  current->dwBufferLength = BLOCK_SIZE;
-	  /* write to audio device */
-    waveOutPrepareHeader(s->hWaveOut, current, sizeof(WAVEHDR));
-	  status = waveOutWrite(s->hWaveOut, current, sizeof(WAVEHDR));      
+
+    status = writeBlock(s, current);
     HANDLE_WAVE_ERROR(status, "writing audio to audio device");
-      
-    EnterCriticalSection(&(s->waveCriticalSection));
-    s->waveFreeBlockCount--;
-    LeaveCriticalSection(&(s->waveCriticalSection));
-
-    /*
-     * point to the next block
-     */
-    (s->waveCurrentBlock)++;
-    (s->waveCurrentBlock) %= BLOCK_COUNT;		
 
     current = &(s->waveBlocks[s->waveCurrentBlock]);
     current->dwUser = 0;
-
-    s->playing = 1;
   }
   return SA_SUCCESS;
 }
 
 /**
  * \brief - audio callback function called when next WAVE header is played by audio device
  */
 void CALLBACK waveOutProc(