From 725a65c1f7eff77e5632b6a7d7fdb11c47ee0c3f Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 6 Oct 2018 21:44:40 +0100 Subject: [PATCH 1/5] Call SDL_RWclose after an SDL_RWFromMem call to close the RWops. --- src/sdl/mixer_sound.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 5211efe0..e835a55c 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -387,7 +387,15 @@ void *I_GetSfx(sfxinfo_t *sfx) #endif // Try to load it as a WAVE or OGG using Mixer. - return Mix_LoadWAV_RW(SDL_RWFromMem(lump, sfx->length), 1); + SDL_RWops *rw = SDL_RWFromMem(lump, sfx->length); + if (rw != NULL) + { + Mix_Chunk *chunk = Mix_LoadWAV_RW(rw, 1); + SDL_RWclose(rw); + return chunk; + } + + return NULL; // haven't been able to get anything } void I_FreeSfx(sfxinfo_t *sfx) @@ -635,7 +643,12 @@ boolean I_StartDigSong(const char *musicname, boolean looping) } #endif - music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len), SDL_FALSE); + SDL_RWops *rw = SDL_RWFromMem(data, len); + if (rw != NULL) + { + music = Mix_LoadMUS_RW(rw, SDL_FALSE); + SDL_RWclose(rw); + } if (!music) { CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError()); @@ -798,7 +811,12 @@ void I_SetMIDIMusicVolume(UINT8 volume) INT32 I_RegisterSong(void *data, size_t len) { - music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len), SDL_FALSE); + SDL_RWops *rw = SDL_RWFromMem(data, len); + if (rw != NULL) + { + music = Mix_LoadMUS_RW(rw, SDL_FALSE); + SDL_RWclose(rw); + } if (!music) { CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError()); From 7b417b573c61eeaeb325366196d78ace780f1b5a Mon Sep 17 00:00:00 2001 From: Sryder Date: Sat, 6 Oct 2018 23:59:39 +0100 Subject: [PATCH 2/5] Mix_QuickLoad_RAW sets a flag in the Mix_Chunk so that Mix_FreeChunk doesn't actually Free the sound. Checks for the flag when freeing, and if it's 0, we free the data manually after Mix_FreeChunk. I went back to Z_Malloc and Z_Free for this because they still work after this. --- src/sdl/mixer_sound.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index e835a55c..15f1595c 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -178,7 +178,7 @@ static Mix_Chunk *ds2chunk(void *stream) return NULL; // would and/or did wrap, can't store. break; } - sound = malloc(newsamples<<2); // samples * frequency shift * bytes per sample * channels + sound = Z_Malloc(newsamples<<2, PU_SOUND, 0); // samples * frequency shift * bytes per sample * channels s = (SINT8 *)stream; d = (INT16 *)sound; @@ -401,7 +401,22 @@ void *I_GetSfx(sfxinfo_t *sfx) void I_FreeSfx(sfxinfo_t *sfx) { if (sfx->data) + { + Mix_Chunk *chunk = (Mix_Chunk*)sfx->data; + UINT8 *abufdata = NULL; + if (chunk->allocated == 0) + { + // We allocated the data in this chunk, so get the abuf from mixer, then let it free the chunk, THEN we free the data + // I believe this should ensure the sound is not playing when we free it + abufdata = chunk->abuf; + } Mix_FreeChunk(sfx->data); + if (abufdata) + { + // I'm going to assume we used Z_Malloc to allocate this data. + Z_Free(abufdata); + } + } sfx->data = NULL; sfx->lumpnum = LUMPERROR; } From d072dd27254596c7c8925b4f6d08c151e57535f2 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 7 Oct 2018 00:22:23 +0100 Subject: [PATCH 3/5] I think that should be NULL, not 0 actually. --- src/sdl/mixer_sound.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 15f1595c..9fef1646 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -178,7 +178,7 @@ static Mix_Chunk *ds2chunk(void *stream) return NULL; // would and/or did wrap, can't store. break; } - sound = Z_Malloc(newsamples<<2, PU_SOUND, 0); // samples * frequency shift * bytes per sample * channels + sound = Z_Malloc(newsamples<<2, PU_SOUND, NULL); // samples * frequency shift * bytes per sample * channels s = (SINT8 *)stream; d = (INT16 *)sound; From 02597e0bf923c76cb1aed2bd15c285371bdd71ff Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 7 Oct 2018 09:26:18 +0100 Subject: [PATCH 4/5] Fix compiler warnings. --- src/sdl/mixer_sound.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 9fef1646..ed15fcda 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -246,6 +246,7 @@ void *I_GetSfx(sfxinfo_t *sfx) { void *lump; Mix_Chunk *chunk; + SDL_RWops *rw; #ifdef HAVE_LIBGME Music_Emu *emu; gme_info_t *info; @@ -387,10 +388,10 @@ void *I_GetSfx(sfxinfo_t *sfx) #endif // Try to load it as a WAVE or OGG using Mixer. - SDL_RWops *rw = SDL_RWFromMem(lump, sfx->length); + rw = SDL_RWFromMem(lump, sfx->length); if (rw != NULL) { - Mix_Chunk *chunk = Mix_LoadWAV_RW(rw, 1); + chunk = Mix_LoadWAV_RW(rw, 1); SDL_RWclose(rw); return chunk; } @@ -547,6 +548,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping) char *data; size_t len; lumpnum_t lumpnum = W_CheckNumForName(va("O_%s",musicname)); + SDL_RWops *rw; I_Assert(!music); #ifdef HAVE_LIBGME @@ -658,7 +660,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping) } #endif - SDL_RWops *rw = SDL_RWFromMem(data, len); + rw = SDL_RWFromMem(data, len); if (rw != NULL) { music = Mix_LoadMUS_RW(rw, SDL_FALSE); From fb6c3298702e76ee8a167264cc7dc0e86936f862 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 7 Oct 2018 10:37:45 +0100 Subject: [PATCH 5/5] Fix the crashing bug hopefully A value of 1 in freesrc for Mix_LoadWAV_RW and Mix_LoadMus_RW calls SDL_RWclose on the RWops anyway. For Mix_LoadWAV_RW the RWops is freed right after the data is loaded (because it makes a copy of the data in memory) For Mix_LoadMUS_RW the RWops is freed when Mix_FreeMusic is called (because the data is not a copy) So setting 1 on freesrc doesn't actually free the RWops immediately on Mix_LoadMus_RW *unless* it failed to load any music. --- src/sdl/mixer_sound.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index ed15fcda..53a767df 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -392,7 +392,6 @@ void *I_GetSfx(sfxinfo_t *sfx) if (rw != NULL) { chunk = Mix_LoadWAV_RW(rw, 1); - SDL_RWclose(rw); return chunk; } @@ -663,8 +662,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping) rw = SDL_RWFromMem(data, len); if (rw != NULL) { - music = Mix_LoadMUS_RW(rw, SDL_FALSE); - SDL_RWclose(rw); + music = Mix_LoadMUS_RW(rw, 1); } if (!music) { @@ -831,8 +829,7 @@ INT32 I_RegisterSong(void *data, size_t len) SDL_RWops *rw = SDL_RWFromMem(data, len); if (rw != NULL) { - music = Mix_LoadMUS_RW(rw, SDL_FALSE); - SDL_RWclose(rw); + music = Mix_LoadMUS_RW(rw, 1); } if (!music) {