From d9c54aecc18a4bc70131d685c44b0767446c0e98 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 23 Jun 2006 08:15:47 +0000 Subject: [PATCH] Fixed bug #69 Hopefully this takes care of most of the audio dropouts in Windows --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401882 --- src/audio/windx5/SDL_dx5audio.c | 32 +++++++++++++++++++++----------- src/audio/windx5/SDL_dx5audio.h | 4 ++-- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/audio/windx5/SDL_dx5audio.c b/src/audio/windx5/SDL_dx5audio.c index 48714dd11..26bd2e8f6 100644 --- a/src/audio/windx5/SDL_dx5audio.c +++ b/src/audio/windx5/SDL_dx5audio.c @@ -254,7 +254,7 @@ static void DX5_WaitAudio_BusyWait(_THIS) /* 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 @@ static void DX5_WaitAudio_BusyWait(_THIS) #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 @@ static void DX5_WaitAudio_BusyWait(_THIS) /* 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 @@ static Uint8 *DX5_GetAudioBuf(_THIS) /* 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 CreatePrimary(LPDIRECTSOUND sndObj, HWND focus, 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 @@ static int DX5_OpenAudio(_THIS, SDL_AudioSpec *spec) #endif /* The buffer will auto-start playing in DX5_WaitAudio() */ - playing = 0; + lastchunk = 0; mixlen = spec->size; #ifdef USE_POSITION_NOTIFY diff --git a/src/audio/windx5/SDL_dx5audio.h b/src/audio/windx5/SDL_dx5audio.h index 52cec130e..eebdf6d66 100644 --- a/src/audio/windx5/SDL_dx5audio.h +++ b/src/audio/windx5/SDL_dx5audio.h @@ -37,7 +37,7 @@ struct SDL_PrivateAudioData { LPDIRECTSOUNDBUFFER mixbuf; int NUM_BUFFERS; int mixlen, silence; - DWORD playing; + DWORD lastchunk; Uint8 *locked_buf; HANDLE audio_event; }; @@ -48,7 +48,7 @@ struct SDL_PrivateAudioData { #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)