From f9346add79a78fa19a310dc311412df10de641e5 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Thu, 16 Apr 2026 10:02:55 +0200 Subject: [PATCH] =?UTF-8?q?refactor:=20jail=5Faudio=20RAII=20polish=20?= =?UTF-8?q?=E2=80=94=20JA=5FMusic=5Ft=20amb=20vector/string=20+=20e?= =?UTF-8?q?limina=20overload=20i=20camp=20morts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/core/jail/jail_audio.hpp | 83 ++++++++++++--------------------- 1 file changed, 29 insertions(+), 54 deletions(-) diff --git a/source/core/jail/jail_audio.hpp b/source/core/jail/jail_audio.hpp index 6cbbf85..0d35c0d 100644 --- a/source/core/jail/jail_audio.hpp +++ b/source/core/jail/jail_audio.hpp @@ -7,6 +7,9 @@ #include #include +#include +#include + #define STB_VORBIS_HEADER_ONLY #include "external/stb_vorbis.h" @@ -48,13 +51,15 @@ struct JA_Channel_t { struct JA_Music_t { SDL_AudioSpec spec{SDL_AUDIO_S16, 2, 48000}; - // OGG comprimit en memòria. Propietat nostra; es copia des del fitxer una - // sola vegada en JA_LoadMusic i es descomprimix en chunks per streaming. - Uint8* ogg_data{nullptr}; - Uint32 ogg_length{0}; + // OGG comprimit en memòria. Propietat nostra; es copia des del buffer + // d'entrada una sola vegada en JA_LoadMusic i es descomprimix en chunks + // per streaming. Com que stb_vorbis guarda un punter persistent al + // `.data()` d'aquest vector, no el podem resize'jar un cop establert + // (una reallocation invalidaria el punter que el decoder conserva). + std::vector ogg_data; stb_vorbis* vorbis{nullptr}; // handle del decoder, viu tot el cicle del JA_Music_t - char* filename{nullptr}; + std::string filename; int times{0}; // loops restants (-1 = infinit, 0 = un sol play) SDL_AudioStream* stream{nullptr}; @@ -200,26 +205,23 @@ inline void JA_Quit() { inline JA_Music_t* JA_LoadMusic(const Uint8* buffer, Uint32 length) { if (!buffer || length == 0) return nullptr; - // Còpia del OGG comprimit: stb_vorbis llig de forma persistent aquesta - // memòria mentre el handle estiga viu, així que hem de posseir-la nosaltres. - Uint8* ogg_copy = static_cast(SDL_malloc(length)); - if (!ogg_copy) return nullptr; - SDL_memcpy(ogg_copy, buffer, length); + // Allocem el JA_Music_t primer per aprofitar el seu `std::vector` + // com a propietari del OGG comprimit. stb_vorbis guarda un punter + // persistent al buffer; com que ací no el resize'jem, el .data() és + // estable durant tot el cicle de vida del music. + auto* music = new JA_Music_t(); + music->ogg_data.assign(buffer, buffer + length); int error = 0; - stb_vorbis* vorbis = stb_vorbis_open_memory(ogg_copy, static_cast(length), &error, nullptr); - if (!vorbis) { - SDL_free(ogg_copy); + music->vorbis = stb_vorbis_open_memory(music->ogg_data.data(), + static_cast(length), &error, nullptr); + if (!music->vorbis) { SDL_Log("JA_LoadMusic: stb_vorbis_open_memory failed (error %d)", error); + delete music; return nullptr; } - auto* music = new JA_Music_t(); - music->ogg_data = ogg_copy; - music->ogg_length = length; - music->vorbis = vorbis; - - const stb_vorbis_info info = stb_vorbis_get_info(vorbis); + const stb_vorbis_info info = stb_vorbis_get_info(music->vorbis); music->spec.channels = info.channels; music->spec.freq = static_cast(info.sample_rate); music->spec.format = SDL_AUDIO_S16; @@ -228,38 +230,11 @@ inline JA_Music_t* JA_LoadMusic(const Uint8* buffer, Uint32 length) { return music; } -// Overload de compatibilitat: accepta filename per a no trencar els call -// sites existents que passaven el nom del fitxer junt amb el buffer. +// Overload amb filename — els callers l'usen per poder comparar la música +// en curs amb JA_GetMusicFilename() i no rearrancar-la si ja és la mateixa. inline JA_Music_t* JA_LoadMusic(Uint8* buffer, Uint32 length, const char* filename) { JA_Music_t* music = JA_LoadMusic(static_cast(buffer), length); - if (music && filename) { - music->filename = static_cast(malloc(strlen(filename) + 1)); - if (music->filename) strcpy(music->filename, filename); - } - return music; -} - -inline JA_Music_t* JA_LoadMusic(const char* filename) { - FILE* f = fopen(filename, "rb"); - if (!f) return nullptr; - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - auto* buffer = static_cast(malloc(fsize + 1)); - if (!buffer) { - fclose(f); - return nullptr; - } - if (fread(buffer, fsize, 1, f) != 1) { - fclose(f); - free(buffer); - return nullptr; - } - fclose(f); - - JA_Music_t* music = JA_LoadMusic(buffer, static_cast(fsize), filename); - free(buffer); - + if (music && filename) music->filename = filename; return music; } @@ -290,10 +265,10 @@ inline void JA_PlayMusic(JA_Music_t* music, const int loop = -1) { if (!SDL_BindAudioStream(sdlAudioDevice, current_music->stream)) printf("[ERROR] SDL_BindAudioStream failed!\n"); } -inline char* JA_GetMusicFilename(JA_Music_t* music = nullptr) { +inline const char* JA_GetMusicFilename(JA_Music_t* music = nullptr) { if (!music) music = current_music; - if (!music) return nullptr; - return music->filename; + if (!music || music->filename.empty()) return nullptr; + return music->filename.c_str(); } inline void JA_PauseMusic() { @@ -352,8 +327,8 @@ inline void JA_DeleteMusic(JA_Music_t* music) { } if (music->stream) SDL_DestroyAudioStream(music->stream); if (music->vorbis) stb_vorbis_close(music->vorbis); - SDL_free(music->ogg_data); - free(music->filename); + // ogg_data (std::vector) i filename (std::string) s'alliberen sols + // al destructor de JA_Music_t. delete music; }