refactor: jail_audio RAII polish — JA_Music_t amb vector<Uint8>/string + elimina overload i camp morts
This commit is contained in:
@@ -7,6 +7,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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<Uint8> 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<Uint8*>(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<Uint8>`
|
||||
// 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<int>(length), &error, nullptr);
|
||||
if (!vorbis) {
|
||||
SDL_free(ogg_copy);
|
||||
music->vorbis = stb_vorbis_open_memory(music->ogg_data.data(),
|
||||
static_cast<int>(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<int>(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<const Uint8*>(buffer), length);
|
||||
if (music && filename) {
|
||||
music->filename = static_cast<char*>(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<Uint8*>(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<Uint32>(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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user