Merged DirectSound dropout fix from SDL 1.2 SDL-1.3
authorSam Lantinga <slouken@libsdl.org>
Fri, 23 Jun 2006 08:48:24 +0000
branchSDL-1.3
changeset 1701 442248d4e738
parent 1700 21184e1d04c3
child 1702 a7ad7081b977
Merged DirectSound dropout fix from SDL 1.2
src/audio/windx5/SDL_dx5audio.c
src/audio/windx5/SDL_dx5audio.h
--- a/src/audio/windx5/SDL_dx5audio.c	Fri Jun 23 08:40:46 2006 +0000
+++ b/src/audio/windx5/SDL_dx5audio.c	Fri Jun 23 08:48:24 2006 +0000
@@ -263,7 +263,7 @@
     /* Semi-busy wait, since we have no way of getting play notification
        on a primary mixing buffer located in hardware (DirectX 5.0)
      */
-    result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &cursor, &junk);
+    result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &junk, &cursor);
     if (result != DS_OK) {
         if (result == DSERR_BUFFERLOST) {
             IDirectSoundBuffer_Restore(mixbuf);
@@ -273,11 +273,10 @@
 #endif
         return;
     }
-    cursor /= mixlen;
 
-    while (cursor == playing) {
+    while ((cursor / mixlen) == lastchunk) {
         /* FIXME: find out how much time is left and sleep that long */
-        SDL_Delay(10);
+        SDL_Delay(1);
 
         /* Try to restore a lost sound buffer */
         IDirectSoundBuffer_GetStatus(mixbuf, &status);
@@ -301,12 +300,11 @@
 
         /* Find out where we are playing */
         result = IDirectSoundBuffer_GetCurrentPosition(mixbuf,
-                                                       &cursor, &junk);
+                                                       &junk, &cursor);
         if (result != DS_OK) {
             SetDSerror("DirectSound GetCurrentPosition", result);
             return;
         }
-        cursor /= mixlen;
     }
 }
 
@@ -358,18 +356,31 @@
 
     /* Figure out which blocks to fill next */
     locked_buf = NULL;
-    result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &cursor, &junk);
+    result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &junk, &cursor);
     if (result == DSERR_BUFFERLOST) {
         IDirectSoundBuffer_Restore(mixbuf);
         result = IDirectSoundBuffer_GetCurrentPosition(mixbuf,
-                                                       &cursor, &junk);
+                                                       &junk, &cursor);
     }
     if (result != DS_OK) {
         SetDSerror("DirectSound GetCurrentPosition", result);
         return (NULL);
     }
     cursor /= mixlen;
-    playing = cursor;
+#ifdef DEBUG_SOUND
+    /* Detect audio dropouts */
+    {
+        DWORD spot = cursor;
+        if (spot < lastchunk) {
+            spot += NUM_BUFFERS;
+        }
+        if (spot > lastchunk + 1) {
+            fprintf(stderr, "Audio dropout, missed %d fragments\n",
+                    (spot - (lastchunk + 1)));
+        }
+    }
+#endif
+    lastchunk = cursor;
     cursor = (cursor + 1) % NUM_BUFFERS;
     cursor *= mixlen;
 
@@ -511,7 +522,7 @@
                 LPDIRECTSOUNDBUFFER * sndbuf, WAVEFORMATEX * wavefmt,
                 Uint32 chunksize)
 {
-    const int numchunks = 2;
+    const int numchunks = 8;
     HRESULT result;
     DSBUFFERDESC format;
     LPVOID pvAudioPtr1, pvAudioPtr2;
@@ -563,10 +574,9 @@
 
     /* Silence the initial audio buffer */
     result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes,
-                                     (LPVOID *) & pvAudioPtr1,
-                                     &dwAudioBytes1,
-                                     (LPVOID *) & pvAudioPtr2,
-                                     &dwAudioBytes2, DSBLOCK_ENTIREBUFFER);
+                                     (LPVOID *) & pvAudioPtr1, &dwAudioBytes1,
+                                     (LPVOID *) & pvAudioPtr2, &dwAudioBytes2,
+                                     DSBLOCK_ENTIREBUFFER);
     if (result == DS_OK) {
         if (wavefmt->wBitsPerSample == 8) {
             SDL_memset(pvAudioPtr1, 0x80, dwAudioBytes1);
@@ -706,7 +716,7 @@
 #endif
 
     /* The buffer will auto-start playing in DX5_WaitAudio() */
-    playing = 0;
+    lastchunk = 0;
     mixlen = spec->size;
 
 #ifdef USE_POSITION_NOTIFY
--- a/src/audio/windx5/SDL_dx5audio.h	Fri Jun 23 08:40:46 2006 +0000
+++ b/src/audio/windx5/SDL_dx5audio.h	Fri Jun 23 08:48:24 2006 +0000
@@ -38,7 +38,7 @@
     LPDIRECTSOUNDBUFFER mixbuf;
     int NUM_BUFFERS;
     int mixlen, silence;
-    DWORD playing;
+    DWORD lastchunk;
     Uint8 *locked_buf;
     HANDLE audio_event;
 };
@@ -49,9 +49,10 @@
 #define NUM_BUFFERS		(this->hidden->NUM_BUFFERS)
 #define mixlen			(this->hidden->mixlen)
 #define silence			(this->hidden->silence)
-#define playing			(this->hidden->playing)
+#define lastchunk		(this->hidden->lastchunk)
 #define locked_buf		(this->hidden->locked_buf)
 #define audio_event		(this->hidden->audio_event)
 
 #endif /* _SDL_lowaudio_h */
+
 /* vi: set ts=4 sw=4 expandtab: */