Fixed bug #69
authorSam Lantinga <slouken@libsdl.org>
Fri, 23 Jun 2006 08:15:47 +0000
changeset 1877 9b02a5b97f79
parent 1876 406b8325ee34
child 1878 d7c9d7f42881
Fixed bug #69 Hopefully this takes care of most of the audio dropouts in Windows
src/audio/windx5/SDL_dx5audio.c
src/audio/windx5/SDL_dx5audio.h
--- a/src/audio/windx5/SDL_dx5audio.c	Fri Jun 23 04:27:55 2006 +0000
+++ b/src/audio/windx5/SDL_dx5audio.c	Fri Jun 23 08:15:47 2006 +0000
@@ -254,7 +254,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);
@@ -264,11 +264,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);
@@ -292,12 +291,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;
 	}
 }
 
@@ -346,18 +344,30 @@
 
 	/* 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;
 
@@ -491,7 +501,7 @@
 static int CreateSecondary(LPDIRECTSOUND sndObj, HWND focus,
 	LPDIRECTSOUNDBUFFER *sndbuf, WAVEFORMATEX *wavefmt, Uint32 chunksize)
 {
-	const int numchunks = 2;
+	const int numchunks = 8;
 	HRESULT result;
 	DSBUFFERDESC format;
 	LPVOID pvAudioPtr1, pvAudioPtr2;
@@ -679,7 +689,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 04:27:55 2006 +0000
+++ b/src/audio/windx5/SDL_dx5audio.h	Fri Jun 23 08:15:47 2006 +0000
@@ -37,7 +37,7 @@
 	LPDIRECTSOUNDBUFFER mixbuf;
 	int NUM_BUFFERS;
 	int mixlen, silence;
-	DWORD playing;
+	DWORD lastchunk;
 	Uint8 *locked_buf;
 	HANDLE audio_event;
 };
@@ -48,7 +48,7 @@
 #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)