From 7b8d36e01d413031665dfd1a8df1618a848cecca Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 19 May 2025 15:31:18 -0700 Subject: [PATCH] Add `MxMiniaudio` wrapper to fix resource issues --- LEGO1/lego/legoomni/include/lego3dsound.h | 3 +- LEGO1/lego/legoomni/include/legocachsound.h | 4 +- .../lego/legoomni/src/audio/legocachsound.cpp | 12 +++--- LEGO1/omni/include/mxminiaudio.h | 38 +++++++++++++++++++ LEGO1/omni/include/mxsoundmanager.h | 4 +- LEGO1/omni/include/mxwavepresenter.h | 9 ++--- LEGO1/omni/src/audio/mxsoundmanager.cpp | 4 +- LEGO1/omni/src/audio/mxwavepresenter.cpp | 22 +++++------ 8 files changed, 66 insertions(+), 30 deletions(-) create mode 100644 LEGO1/omni/include/mxminiaudio.h diff --git a/LEGO1/lego/legoomni/include/lego3dsound.h b/LEGO1/lego/legoomni/include/lego3dsound.h index ddf34782..9e70e2aa 100644 --- a/LEGO1/lego/legoomni/include/lego3dsound.h +++ b/LEGO1/lego/legoomni/include/lego3dsound.h @@ -2,10 +2,9 @@ #define LEGO3DSOUND_H #include "decomp.h" +#include "mxminiaudio.h" #include "mxtypes.h" -#include - class LegoActor; class LegoROI; diff --git a/LEGO1/lego/legoomni/include/legocachsound.h b/LEGO1/lego/legoomni/include/legocachsound.h index c0fe05d4..fd9df5b0 100644 --- a/LEGO1/lego/legoomni/include/legocachsound.h +++ b/LEGO1/lego/legoomni/include/legocachsound.h @@ -62,8 +62,8 @@ class LegoCacheSound : public MxCore { // [library:audio] WAVE_FORMAT_PCM (audio in .SI files only used this format) static const MxU32 g_supportedFormatTag = 1; - ma_audio_buffer m_buffer; - ma_sound m_cacheSound; + MxMiniaudio m_buffer; + MxMiniaudio m_cacheSound; undefined m_unk0x0c[4]; // 0x0c Lego3DSound m_sound; // 0x10 MxU8* m_data; // 0x40 diff --git a/LEGO1/lego/legoomni/src/audio/legocachsound.cpp b/LEGO1/lego/legoomni/src/audio/legocachsound.cpp index 1d4a5d11..42223113 100644 --- a/LEGO1/lego/legoomni/src/audio/legocachsound.cpp +++ b/LEGO1/lego/legoomni/src/audio/legocachsound.cpp @@ -63,16 +63,16 @@ MxResult LegoCacheSound::Create( ma_audio_buffer_config_init(format, p_pwfx.m_channels, bufferSizeInFrames, m_data, NULL); config.sampleRate = p_pwfx.m_samplesPerSec; - if (ma_audio_buffer_init(&config, &m_buffer) != MA_SUCCESS) { + if (m_buffer.Init(ma_audio_buffer_init, &config) != MA_SUCCESS) { return FAILURE; } - if (ma_sound_init_from_data_source( + if (m_cacheSound.Init( + ma_sound_init_from_data_source, SoundManager()->GetEngine(), &m_buffer, MxOmni::IsSound3D() ? 0 : MA_SOUND_FLAG_NO_SPATIALIZATION, - NULL, - &m_cacheSound + nullptr ) != MA_SUCCESS) { return FAILURE; } @@ -108,8 +108,8 @@ void LegoCacheSound::CopyData(MxU8* p_data, MxU32 p_dataSize) // FUNCTION: BETA10 0x1006685b void LegoCacheSound::Destroy() { - ma_sound_uninit(&m_cacheSound); - ma_audio_buffer_uninit(&m_buffer); + m_cacheSound.Destroy(ma_sound_uninit); + m_buffer.Destroy(ma_audio_buffer_uninit); delete[] m_data; Init(); diff --git a/LEGO1/omni/include/mxminiaudio.h b/LEGO1/omni/include/mxminiaudio.h new file mode 100644 index 00000000..c7e55cb9 --- /dev/null +++ b/LEGO1/omni/include/mxminiaudio.h @@ -0,0 +1,38 @@ +#ifndef MXMINIAUDIO_H +#define MXMINIAUDIO_H + +#include "mxtypes.h" + +#include +#include + +template +class MxMiniaudio : public T { +public: + MxMiniaudio() : m_initialized(false) {} + + template + ma_result Init(Fn ma_init, Args&&... args) + { + ma_result result = ma_init(std::forward(args)..., this); + if (result == MA_SUCCESS) { + m_initialized = true; + } + + return result; + } + + template + void Destroy(Fn ma_uninit) + { + if (m_initialized) { + ma_uninit(this); + m_initialized = false; + } + } + +private: + bool m_initialized; +}; + +#endif // MXMINIAUDIO_H diff --git a/LEGO1/omni/include/mxsoundmanager.h b/LEGO1/omni/include/mxsoundmanager.h index e926cb1c..8f92aa41 100644 --- a/LEGO1/omni/include/mxsoundmanager.h +++ b/LEGO1/omni/include/mxsoundmanager.h @@ -4,9 +4,9 @@ #include "decomp.h" #include "mxatom.h" #include "mxaudiomanager.h" +#include "mxminiaudio.h" #include -#include // VTABLE: LEGO1 0x100dc128 // VTABLE: BETA10 0x101c1ce8 @@ -44,7 +44,7 @@ class MxSoundManager : public MxAudioManager { int p_totalAmount ); - ma_engine m_engine; + MxMiniaudio m_engine; SDL_AudioStream* m_stream; undefined m_unk0x38[4]; }; diff --git a/LEGO1/omni/include/mxwavepresenter.h b/LEGO1/omni/include/mxwavepresenter.h index a543da35..f53cb0a3 100644 --- a/LEGO1/omni/include/mxwavepresenter.h +++ b/LEGO1/omni/include/mxwavepresenter.h @@ -2,10 +2,9 @@ #define MXWAVEPRESENTER_H #include "decomp.h" +#include "mxminiaudio.h" #include "mxsoundpresenter.h" -#include - // VTABLE: LEGO1 0x100d49a8 // SIZE 0x6c class MxWavePresenter : public MxSoundPresenter { @@ -92,15 +91,15 @@ class MxWavePresenter : public MxSoundPresenter { // [library:audio] // If MxDSAction::looping is set, we keep the entire audio in memory and use `m_ab`. // In (most) other cases, data is streamed through the ring buffer `m_rb`. - ma_pcm_rb m_rb; + MxMiniaudio m_rb; struct { - ma_audio_buffer m_buffer; + MxMiniaudio m_buffer; MxU8* m_data; MxU32 m_length; MxU32 m_offset; } m_ab; - ma_sound m_sound; + MxMiniaudio m_sound; MxU32 m_chunkLength; // 0x5c MxBool m_started; // 0x65 MxBool m_is3d; // 0x66 diff --git a/LEGO1/omni/src/audio/mxsoundmanager.cpp b/LEGO1/omni/src/audio/mxsoundmanager.cpp index 0d14343c..f2f8f26f 100644 --- a/LEGO1/omni/src/audio/mxsoundmanager.cpp +++ b/LEGO1/omni/src/audio/mxsoundmanager.cpp @@ -58,7 +58,7 @@ void MxSoundManager::Destroy(MxBool p_fromDestructor) SDL_DestroyAudioStream(m_stream); } - ma_engine_uninit(&m_engine); + m_engine.Destroy(ma_engine_uninit); Init(); m_criticalSection.Leave(); @@ -88,7 +88,7 @@ MxResult MxSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) engineConfig.channels = MxOmni::IsSound3D() ? 2 : 1; engineConfig.sampleRate = g_sampleRate; - if (ma_engine_init(&engineConfig, &m_engine) != MA_SUCCESS) { + if (m_engine.Init(ma_engine_init, &engineConfig) != MA_SUCCESS) { goto done; } diff --git a/LEGO1/omni/src/audio/mxwavepresenter.cpp b/LEGO1/omni/src/audio/mxwavepresenter.cpp index 81161898..a0f4d8ab 100644 --- a/LEGO1/omni/src/audio/mxwavepresenter.cpp +++ b/LEGO1/omni/src/audio/mxwavepresenter.cpp @@ -40,9 +40,9 @@ MxResult MxWavePresenter::AddToManager() // FUNCTION: LEGO1 0x100b1b10 void MxWavePresenter::Destroy(MxBool p_fromDestructor) { - ma_sound_uninit(&m_sound); - ma_pcm_rb_uninit(&m_rb); - ma_audio_buffer_uninit(&m_ab.m_buffer); + m_sound.Destroy(ma_sound_uninit); + m_rb.Destroy(ma_pcm_rb_uninit); + m_ab.m_buffer.Destroy(ma_audio_buffer_uninit); delete[] m_ab.m_data; if (m_waveFormat) { @@ -145,18 +145,18 @@ void MxWavePresenter::StartingTickle() ma_audio_buffer_config_init(format, channels, sizeInFrames, m_ab.m_data, NULL); config.sampleRate = sampleRate; - if (ma_audio_buffer_init(&config, &m_ab.m_buffer) != MA_SUCCESS) { + if (m_ab.m_buffer.Init(ma_audio_buffer_init, &config) != MA_SUCCESS) { goto done; } } else { - if (ma_pcm_rb_init( + if (m_rb.Init( + ma_pcm_rb_init, format, channels, ma_calculate_buffer_size_in_frames_from_milliseconds(g_rbSizeInMilliseconds, sampleRate), - NULL, - NULL, - &m_rb + nullptr, + nullptr ) != MA_SUCCESS) { goto done; } @@ -164,12 +164,12 @@ void MxWavePresenter::StartingTickle() ma_pcm_rb_set_sample_rate(&m_rb, sampleRate); } - if (ma_sound_init_from_data_source( + if (m_sound.Init( + ma_sound_init_from_data_source, MSoundManager()->GetEngine(), m_action->IsLooping() ? (ma_data_source*) &m_ab.m_buffer : (ma_data_source*) &m_rb, m_is3d ? 0 : MA_SOUND_FLAG_NO_SPATIALIZATION, - NULL, - &m_sound + nullptr ) != MA_SUCCESS) { goto done; }