From a5f31084d493e4fb94f733313c4f41a4ba4b00c4 Mon Sep 17 00:00:00 2001 From: Thilo Schulz Date: Fri, 17 Jun 2011 23:29:19 +0000 Subject: [PATCH] - Fix memory leak in DMA sound after S_Shutdown() - Make codec load use temp hunk memory instead of zone mem - Fix sound issues with direct sound and game_restart (#4526) --- code/client/cl_main.c | 9 +++++---- code/client/snd_codec_ogg.c | 4 ++-- code/client/snd_codec_wav.c | 2 +- code/client/snd_dma.c | 7 ++++--- code/client/snd_local.h | 1 + code/client/snd_mem.c | 8 +++++++- code/client/snd_openal.c | 16 +++++++++------- code/null/null_client.c | 2 +- code/qcommon/common.c | 6 +++--- code/qcommon/qcommon.h | 2 +- 10 files changed, 34 insertions(+), 23 deletions(-) diff --git a/code/client/cl_main.c b/code/client/cl_main.c index 6e6303a9..4f328b49 100644 --- a/code/client/cl_main.c +++ b/code/client/cl_main.c @@ -1776,10 +1776,10 @@ CL_Snd_Restart Restart the sound subsystem ================= */ -void CL_Snd_Restart(void) +void CL_Snd_Shutdown(void) { S_Shutdown(); - S_Init(); + cls.soundStarted = qfalse; } /* @@ -1793,7 +1793,8 @@ handles will be invalid */ void CL_Snd_Restart_f(void) { - CL_Snd_Restart(); + CL_Snd_Shutdown(); + // sound will be reinitialized by vid_restart CL_Vid_Restart_f(); } @@ -3350,7 +3351,7 @@ void CL_Shutdown( char *finalmsg ) { CL_Disconnect( qtrue ); - S_Shutdown(); + CL_Snd_Shutdown(); CL_ShutdownRef(); CL_ShutdownUI(); diff --git a/code/client/snd_codec_ogg.c b/code/client/snd_codec_ogg.c index 511de719..c424649f 100644 --- a/code/client/snd_codec_ogg.c +++ b/code/client/snd_codec_ogg.c @@ -450,7 +450,7 @@ void *S_OGG_CodecLoad(const char *filename, snd_info_t *info) // allocate a buffer // this buffer must be free-ed by the caller of this function - buffer = Z_Malloc(info->size); + buffer = Hunk_AllocateTempMemory(info->size); if(!buffer) { S_OGG_CodecCloseStream(stream); @@ -464,7 +464,7 @@ void *S_OGG_CodecLoad(const char *filename, snd_info_t *info) // we don't even have read a single byte if(bytesRead <= 0) { - Z_Free(buffer); + Hunk_FreeTempMemory(buffer); S_OGG_CodecCloseStream(stream); return NULL; diff --git a/code/client/snd_codec_wav.c b/code/client/snd_codec_wav.c index ef0e15e6..e5a08ae9 100644 --- a/code/client/snd_codec_wav.c +++ b/code/client/snd_codec_wav.c @@ -218,7 +218,7 @@ void *S_WAV_CodecLoad(const char *filename, snd_info_t *info) } // Allocate some memory - buffer = Z_Malloc(info->size); + buffer = Hunk_AllocateTempMemory(info->size); if(!buffer) { FS_FCloseFile(file); diff --git a/code/client/snd_dma.c b/code/client/snd_dma.c index c6bf492b..45cef4c6 100644 --- a/code/client/snd_dma.c +++ b/code/client/snd_dma.c @@ -391,9 +391,8 @@ void S_Base_BeginRegistration( void ) { if (s_numSfx == 0) { SND_setup(); - s_numSfx = 0; - Com_Memset( s_knownSfx, 0, sizeof( s_knownSfx ) ); - Com_Memset(sfxHash, 0, sizeof(sfx_t *)*LOOP_HASH); + Com_Memset(s_knownSfx, '\0', sizeof(s_knownSfx)); + Com_Memset(sfxHash, '\0', sizeof(sfx_t *) * LOOP_HASH); S_Base_RegisterSound("sound/feedback/hit.wav", qfalse); // changed to a sound in baseq3 } @@ -1467,8 +1466,10 @@ void S_Base_Shutdown( void ) { } SNDDMA_Shutdown(); + SND_shutdown(); s_soundStarted = 0; + s_numSfx = 0; Cmd_RemoveCommand("s_info"); } diff --git a/code/client/snd_local.h b/code/client/snd_local.h index 775e5764..dbdcc334 100644 --- a/code/client/snd_local.h +++ b/code/client/snd_local.h @@ -202,6 +202,7 @@ qboolean S_LoadSound( sfx_t *sfx ); void SND_free(sndBuffer *v); sndBuffer* SND_malloc( void ); void SND_setup( void ); +void SND_shutdown(void); void S_PaintChannels(int endtime); diff --git a/code/client/snd_mem.c b/code/client/snd_mem.c index 8c3f98e7..ee40a750 100644 --- a/code/client/snd_mem.c +++ b/code/client/snd_mem.c @@ -100,6 +100,12 @@ void SND_setup(void) { Com_Printf("Sound memory manager started\n"); } +void SND_shutdown(void) +{ + free(sfxScratchBuffer); + free(buffer); +} + /* ================ ResampleSfx @@ -255,7 +261,7 @@ qboolean S_LoadSound( sfx_t *sfx ) } Hunk_FreeTempMemory(samples); - Z_Free(data); + Hunk_FreeTempMemory(data); return qtrue; } diff --git a/code/client/snd_openal.c b/code/client/snd_openal.c index 49864a1e..aa6a8cb8 100644 --- a/code/client/snd_openal.c +++ b/code/client/snd_openal.c @@ -148,7 +148,7 @@ static qboolean alBuffersInitialised = qfalse; // Sound effect storage, data structures #define MAX_SFX 4096 static alSfx_t knownSfx[MAX_SFX]; -static int numSfx = 0; +static sfxHandle_t numSfx = 0; static sfxHandle_t default_sfx; @@ -332,7 +332,7 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache) if (!cache) { // Don't create AL cache - Z_Free(data); + Hunk_FreeTempMemory(data); return; } @@ -344,7 +344,7 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache) if((error = qalGetError()) != AL_NO_ERROR) { S_AL_BufferUseDefault(sfx); - Z_Free(data); + Hunk_FreeTempMemory(data); Com_Printf( S_COLOR_RED "ERROR: Can't create a sound buffer for %s - %s\n", curSfx->filename, S_AL_ErrorMsg(error)); return; @@ -369,7 +369,7 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache) if( !S_AL_BufferEvict( ) ) { S_AL_BufferUseDefault(sfx); - Z_Free(data); + Hunk_FreeTempMemory(data); Com_Printf( S_COLOR_RED "ERROR: Out of memory loading %s\n", curSfx->filename); return; } @@ -383,7 +383,7 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache) if(error != AL_NO_ERROR) { S_AL_BufferUseDefault(sfx); - Z_Free(data); + Hunk_FreeTempMemory(data); Com_Printf( S_COLOR_RED "ERROR: Can't fill sound buffer for %s - %s\n", curSfx->filename, S_AL_ErrorMsg(error)); return; @@ -392,7 +392,7 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache) curSfx->info = info; // Free the memory - Z_Free(data); + Hunk_FreeTempMemory(data); // Woo! curSfx->inMemory = qtrue; @@ -460,7 +460,7 @@ void S_AL_BufferShutdown( void ) S_AL_BufferUnload(i); // Clear the tables - memset(knownSfx, 0, sizeof(knownSfx)); + numSfx = 0; // All undone alBuffersInitialised = qfalse; @@ -2205,6 +2205,8 @@ S_AL_BeginRegistration static void S_AL_BeginRegistration( void ) { + if(!numSfx) + S_AL_BufferInit(); } /* diff --git a/code/null/null_client.c b/code/null/null_client.c index 66ead8a2..1e852482 100644 --- a/code/null/null_client.c +++ b/code/null/null_client.c @@ -85,7 +85,7 @@ void CL_FlushMemory( void ) { void CL_StartHunkUsers( qboolean rendererOnly ) { } -void CL_Snd_Restart(void) +void CL_Snd_Shutdown(void) { } diff --git a/code/qcommon/common.c b/code/qcommon/common.c index 35351e5c..804f9499 100644 --- a/code/qcommon/common.c +++ b/code/qcommon/common.c @@ -2408,10 +2408,10 @@ void Com_GameRestart(int checksumFeed, qboolean clientRestart) // Clean out any user and VM created cvars Cvar_Restart(qtrue); Com_ExecuteCfg(); - - // Restart sound subsystem so old handles are flushed - CL_Snd_Restart(); + // shut down sound system before restart + CL_Snd_Shutdown(); + if(clientRestart) CL_StartHunkUsers(qfalse); diff --git a/code/qcommon/qcommon.h b/code/qcommon/qcommon.h index 4c46b994..2f1c9172 100644 --- a/code/qcommon/qcommon.h +++ b/code/qcommon/qcommon.h @@ -996,7 +996,7 @@ void CL_FlushMemory( void ); void CL_StartHunkUsers( qboolean rendererOnly ); // start all the client stuff using the hunk -void CL_Snd_Restart(void); +void CL_Snd_Shutdown(void); // Restart sound subsystem void Key_KeynameCompletion( void(*callback)(const char *s) );