From 3192eb551a55a4fe7e5195c54b030e26b95f185c Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 19 May 2025 17:07:20 -0700 Subject: [PATCH] Add `MxMiniaudio` wrapper to fix resource issues (#131) * Add `MxMiniaudio` wrapper to fix resource issues * Fix naming * Updated wrapper * Use implicit cast --- LEGO1/lego/legoomni/include/lego3dsound.h | 3 +- LEGO1/lego/legoomni/include/legocachsound.h | 4 +- .../src/audio/lego3dwavepresenter.cpp | 6 +- .../lego/legoomni/src/audio/legocachsound.cpp | 46 ++++++------ .../legoomni/src/audio/legosoundmanager.cpp | 8 +- LEGO1/omni/include/mxminiaudio.h | 64 ++++++++++++++++ LEGO1/omni/include/mxsoundmanager.h | 6 +- LEGO1/omni/include/mxwavepresenter.h | 9 +-- LEGO1/omni/src/audio/mxsoundmanager.cpp | 12 +-- LEGO1/omni/src/audio/mxwavepresenter.cpp | 74 +++++++++---------- 10 files changed, 147 insertions(+), 85 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/lego3dwavepresenter.cpp b/LEGO1/lego/legoomni/src/audio/lego3dwavepresenter.cpp index 55412b22..38a418d4 100644 --- a/LEGO1/lego/legoomni/src/audio/lego3dwavepresenter.cpp +++ b/LEGO1/lego/legoomni/src/audio/lego3dwavepresenter.cpp @@ -40,7 +40,7 @@ void Lego3DWavePresenter::StartingTickle() MxWavePresenter::StartingTickle(); - if (ma_sound_get_engine(&(MxWavePresenter::m_sound))) { + if (MxWavePresenter::m_sound) { MxU16 extraLength; char* buff; m_action->GetExtra(extraLength, buff); @@ -49,7 +49,7 @@ void Lego3DWavePresenter::StartingTickle() m_compositePresenter->GetAction()->GetExtra(extraLength, buff); } - if (m_sound.Create(&(MxWavePresenter::m_sound), buff, m_volume) != SUCCESS) { + if (m_sound.Create(MxWavePresenter::m_sound, buff, m_volume) != SUCCESS) { EndAction(); } } @@ -60,5 +60,5 @@ void Lego3DWavePresenter::StartingTickle() void Lego3DWavePresenter::StreamingTickle() { MxWavePresenter::StreamingTickle(); - m_sound.UpdatePosition(&(MxWavePresenter::m_sound)); + m_sound.UpdatePosition(MxWavePresenter::m_sound); } diff --git a/LEGO1/lego/legoomni/src/audio/legocachsound.cpp b/LEGO1/lego/legoomni/src/audio/legocachsound.cpp index 1d4a5d11..864659da 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; } @@ -80,9 +80,9 @@ MxResult LegoCacheSound::Create( m_volume = p_volume; MxS32 volume = m_volume * SoundManager()->GetVolume() / 100; - ma_sound_set_volume(&m_cacheSound, SoundManager()->GetAttenuation(volume)); + ma_sound_set_volume(m_cacheSound, SoundManager()->GetAttenuation(volume)); - if (m_sound.Create(&m_cacheSound, NULL, m_volume) != SUCCESS) { + if (m_sound.Create(m_cacheSound, NULL, m_volume) != 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(); @@ -141,19 +141,19 @@ MxResult LegoCacheSound::Play(const char* p_name, MxBool p_looping) } m_unk0x6a = FALSE; - m_sound.FUN_10011a60(&m_cacheSound, p_name); + m_sound.FUN_10011a60(m_cacheSound, p_name); if (p_name != NULL) { m_unk0x74 = p_name; } - if (ma_sound_seek_to_pcm_frame(&m_cacheSound, 0) != MA_SUCCESS) { + if (ma_sound_seek_to_pcm_frame(m_cacheSound, 0) != MA_SUCCESS) { return FAILURE; } - ma_sound_set_looping(&m_cacheSound, p_looping); + ma_sound_set_looping(m_cacheSound, p_looping); - if (ma_sound_start(&m_cacheSound) != MA_SUCCESS) { + if (ma_sound_start(m_cacheSound) != MA_SUCCESS) { return FAILURE; } @@ -173,7 +173,7 @@ MxResult LegoCacheSound::Play(const char* p_name, MxBool p_looping) // FUNCTION: BETA10 0x10066ca3 void LegoCacheSound::Stop() { - ma_sound_stop(&m_cacheSound); + ma_sound_stop(m_cacheSound); m_unk0x58 = FALSE; m_unk0x6a = FALSE; @@ -190,15 +190,15 @@ void LegoCacheSound::FUN_10006be0() { if (!m_looping) { if (m_unk0x70) { - if (!ma_sound_is_playing(&m_cacheSound)) { + if (!ma_sound_is_playing(m_cacheSound)) { return; } m_unk0x70 = FALSE; } - if (!ma_sound_is_playing(&m_cacheSound)) { - ma_sound_stop(&m_cacheSound); + if (!ma_sound_is_playing(m_cacheSound)) { + ma_sound_stop(m_cacheSound); m_sound.Reset(); if (m_unk0x74.GetLength() != 0) { m_unk0x74 = ""; @@ -214,14 +214,14 @@ void LegoCacheSound::FUN_10006be0() } if (!m_muted) { - if (!m_sound.UpdatePosition(&m_cacheSound)) { + if (!m_sound.UpdatePosition(m_cacheSound)) { if (!m_unk0x6a) { - ma_sound_stop(&m_cacheSound); + ma_sound_stop(m_cacheSound); m_unk0x6a = TRUE; } } else if (m_unk0x6a) { - ma_sound_start(&m_cacheSound); + ma_sound_start(m_cacheSound); m_unk0x6a = FALSE; } } @@ -247,11 +247,11 @@ void LegoCacheSound::MuteSilence(MxBool p_muted) m_muted = p_muted; if (m_muted) { - ma_sound_set_volume(&m_cacheSound, ma_volume_db_to_linear(-3000.0f / 100.0f)); + ma_sound_set_volume(m_cacheSound, ma_volume_db_to_linear(-3000.0f / 100.0f)); } else { MxS32 volume = m_volume * SoundManager()->GetVolume() / 100; - ma_sound_set_volume(&m_cacheSound, SoundManager()->GetAttenuation(volume)); + ma_sound_set_volume(m_cacheSound, SoundManager()->GetAttenuation(volume)); } } } @@ -264,10 +264,10 @@ void LegoCacheSound::MuteStop(MxBool p_muted) m_muted = p_muted; if (m_muted) { - ma_sound_stop(&m_cacheSound); + ma_sound_stop(m_cacheSound); } else { - ma_sound_start(&m_cacheSound); + ma_sound_start(m_cacheSound); } } } diff --git a/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp b/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp index d7f2f53e..1d53e64d 100644 --- a/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp +++ b/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp @@ -96,16 +96,16 @@ void LegoSoundManager::UpdateListener( // uses DirectX' left-handed system. The Z-axis needs to be inverted. if (p_position != NULL) { - ma_engine_listener_set_position(&m_engine, 0, p_position[0], p_position[1], -p_position[2]); + ma_engine_listener_set_position(m_engine, 0, p_position[0], p_position[1], -p_position[2]); } if (p_direction != NULL && p_up != NULL) { - ma_engine_listener_set_direction(&m_engine, 0, p_direction[0], p_direction[1], -p_direction[2]); - ma_engine_listener_set_world_up(&m_engine, 0, p_up[0], p_up[1], -p_up[2]); + ma_engine_listener_set_direction(m_engine, 0, p_direction[0], p_direction[1], -p_direction[2]); + ma_engine_listener_set_world_up(m_engine, 0, p_up[0], p_up[1], -p_up[2]); } if (p_velocity != NULL) { - ma_engine_listener_set_velocity(&m_engine, 0, p_velocity[0], p_velocity[1], -p_velocity[2]); + ma_engine_listener_set_velocity(m_engine, 0, p_velocity[0], p_velocity[1], -p_velocity[2]); } } } diff --git a/LEGO1/omni/include/mxminiaudio.h b/LEGO1/omni/include/mxminiaudio.h new file mode 100644 index 00000000..41bae048 --- /dev/null +++ b/LEGO1/omni/include/mxminiaudio.h @@ -0,0 +1,64 @@ +#ifndef MXMINIAUDIO_H +#define MXMINIAUDIO_H + +#include "mxtypes.h" + +#include +#include +#include + +template +class MxMiniaudio { +public: + MxMiniaudio() : m_initialized(false) {} + + template + ma_result Init(Fn p_init, Args&&... p_args) + { + assert(!m_initialized); + + ma_result result = p_init(std::forward(p_args)..., &m_object); + if (result == MA_SUCCESS) { + m_initialized = true; + } + + return result; + } + + template + void Destroy(Fn p_uninit) + { + if (m_initialized) { + p_uninit(&m_object); + m_initialized = false; + } + } + + T* operator->() + { + assert(m_initialized); + if (m_initialized) { + return &m_object; + } + + return nullptr; + } + + operator T*() + { + assert(m_initialized); + if (m_initialized) { + return &m_object; + } + + return nullptr; + } + + explicit operator bool() { return m_initialized; } + +private: + T m_object; + bool m_initialized; +}; + +#endif // MXMINIAUDIO_H diff --git a/LEGO1/omni/include/mxsoundmanager.h b/LEGO1/omni/include/mxsoundmanager.h index e926cb1c..062d3839 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 @@ -22,7 +22,7 @@ class MxSoundManager : public MxAudioManager { virtual void Pause(); // vtable+0x34 virtual void Resume(); // vtable+0x38 - ma_engine* GetEngine() { return &m_engine; } + ma_engine* GetEngine() { return m_engine; } float GetAttenuation(MxU32 p_volume); @@ -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..afb9b21e 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,15 +88,15 @@ 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; } SDL_AudioSpec spec; SDL_zero(spec); - spec.freq = ma_engine_get_sample_rate(&m_engine); + spec.freq = ma_engine_get_sample_rate(m_engine); spec.format = SDL_AUDIO_F32; - spec.channels = ma_engine_get_channels(&m_engine); + spec.channels = ma_engine_get_channels(m_engine); if ((m_stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, &AudioStreamCallback, this)) == NULL) { @@ -140,11 +140,11 @@ void MxSoundManager::AudioStreamCallback( g_buffer.reserve(p_additionalAmount); MxSoundManager* manager = (MxSoundManager*) p_userdata; - ma_uint32 bytesPerFrame = ma_get_bytes_per_frame(ma_format_f32, ma_engine_get_channels(&manager->m_engine)); + ma_uint32 bytesPerFrame = ma_get_bytes_per_frame(ma_format_f32, ma_engine_get_channels(manager->m_engine)); ma_uint32 bufferSizeInFrames = (ma_uint32) p_additionalAmount / bytesPerFrame; ma_uint64 framesRead; - if (ma_engine_read_pcm_frames(&manager->m_engine, g_buffer.data(), bufferSizeInFrames, &framesRead) == MA_SUCCESS) { + if (ma_engine_read_pcm_frames(manager->m_engine, g_buffer.data(), bufferSizeInFrames, &framesRead) == MA_SUCCESS) { SDL_PutAudioStreamData(manager->m_stream, g_buffer.data(), framesRead * bytesPerFrame); } } diff --git a/LEGO1/omni/src/audio/mxwavepresenter.cpp b/LEGO1/omni/src/audio/mxwavepresenter.cpp index 81161898..600d9b37 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) { @@ -71,15 +71,15 @@ MxBool MxWavePresenter::WriteToSoundBuffer(void* p_audioPtr, MxU32 p_length) ma_uint32 acquiredFrames = requestedFrames; void* bufferOut; - ma_pcm_rb_acquire_write(&m_rb, &acquiredFrames, &bufferOut); + ma_pcm_rb_acquire_write(m_rb, &acquiredFrames, &bufferOut); // [library:audio] If there isn't enough space in the buffer for a full chunk, try again later. if (acquiredFrames != requestedFrames) { - ma_pcm_rb_commit_write(&m_rb, 0); + ma_pcm_rb_commit_write(m_rb, 0); return FALSE; } - ma_uint32 acquiredBytes = acquiredFrames * ma_get_bytes_per_frame(m_rb.format, m_rb.channels); + ma_uint32 acquiredBytes = acquiredFrames * ma_get_bytes_per_frame(m_rb->format, m_rb->channels); assert(p_length <= acquiredBytes); memcpy(bufferOut, p_audioPtr, p_length); @@ -89,7 +89,7 @@ MxBool MxWavePresenter::WriteToSoundBuffer(void* p_audioPtr, MxU32 p_length) memset((ma_uint8*) bufferOut + p_length, m_silenceData, acquiredBytes - p_length); } - ma_pcm_rb_commit_write(&m_rb, acquiredFrames); + ma_pcm_rb_commit_write(m_rb, acquiredFrames); return TRUE; } } @@ -145,31 +145,31 @@ 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; } - ma_pcm_rb_set_sample_rate(&m_rb, sampleRate); + 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_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; } @@ -178,8 +178,8 @@ void MxWavePresenter::StartingTickle() // There is an issue with certain spatialized sounds causing an audio glitch. // To temporarily resolve this, we can disable the Doppler effect. // More info: https://github.com/mackron/miniaudio/issues/885 - ma_sound_set_doppler_factor(&m_sound, 0.0f); - ma_sound_set_looping(&m_sound, m_action->IsLooping() ? m_action->GetLoopCount() > 1 : MA_TRUE); + ma_sound_set_doppler_factor(m_sound, 0.0f); + ma_sound_set_looping(m_sound, m_action->IsLooping() ? m_action->GetLoopCount() > 1 : MA_TRUE); SetVolume(((MxDSSound*) m_action)->GetVolume()); ProgressTickleState(e_streaming); @@ -222,8 +222,8 @@ void MxWavePresenter::StreamingTickle() // FUNCTION: LEGO1 0x100b20c0 void MxWavePresenter::DoneTickle() { - if (!ma_sound_get_engine(&m_sound) || m_action->GetFlags() & MxDSAction::c_bit7 || - m_action->GetFlags() & MxDSAction::c_looping || ma_pcm_rb_pointer_distance(&m_rb) == 0) { + if (!m_sound || m_action->GetFlags() & MxDSAction::c_bit7 || m_action->GetFlags() & MxDSAction::c_looping || + ma_pcm_rb_pointer_distance(m_rb) == 0) { MxMediaPresenter::DoneTickle(); } } @@ -251,7 +251,7 @@ MxResult MxWavePresenter::PutData() } if (!m_started) { - if (ma_sound_start(&m_sound) == MA_SUCCESS) { + if (ma_sound_start(m_sound) == MA_SUCCESS) { m_started = TRUE; } } @@ -261,10 +261,10 @@ MxResult MxWavePresenter::PutData() break; } - assert(!ma_sound_is_playing(&m_sound)); - ma_sound_seek_to_pcm_frame(&m_sound, 0); + assert(!ma_sound_is_playing(m_sound)); + ma_sound_seek_to_pcm_frame(m_sound, 0); - if (ma_sound_start(&m_sound) == MA_SUCCESS) { + if (ma_sound_start(m_sound) == MA_SUCCESS) { m_started = TRUE; } } @@ -280,8 +280,8 @@ void MxWavePresenter::EndAction() AUTOLOCK(m_criticalSection); MxMediaPresenter::EndAction(); - if (ma_sound_get_engine(&m_sound)) { - ma_sound_stop(&m_sound); + if (m_sound) { + ma_sound_stop(m_sound); } } } @@ -292,10 +292,10 @@ void MxWavePresenter::SetVolume(MxS32 p_volume) m_criticalSection.Enter(); m_volume = p_volume; - if (ma_sound_get_engine(&m_sound)) { + if (m_sound) { MxS32 volume = p_volume * MxOmni::GetInstance()->GetSoundManager()->GetVolume() / 100; float attenuation = MxOmni::GetInstance()->GetSoundManager()->GetAttenuation(volume); - ma_sound_set_volume(&m_sound, attenuation); + ma_sound_set_volume(m_sound, attenuation); } m_criticalSection.Leave(); @@ -310,8 +310,8 @@ void MxWavePresenter::Enable(MxBool p_enable) if (p_enable) { m_started = FALSE; } - else if (ma_sound_get_engine(&m_sound)) { - ma_sound_stop(&m_sound); + else if (m_sound) { + ma_sound_stop(m_sound); } } } @@ -343,8 +343,8 @@ void MxWavePresenter::ParseExtra() void MxWavePresenter::Pause() { if (!m_paused && m_started) { - if (ma_sound_get_engine(&m_sound)) { - ma_sound_stop(&m_sound); + if (m_sound) { + ma_sound_stop(m_sound); } m_paused = TRUE; } @@ -354,15 +354,15 @@ void MxWavePresenter::Pause() void MxWavePresenter::Resume() { if (m_paused) { - if (ma_sound_get_engine(&m_sound) && m_started) { + if (m_sound && m_started) { switch (m_currentTickleState) { case e_streaming: case e_repeating: - ma_sound_start(&m_sound); + ma_sound_start(m_sound); break; case e_done: - if (!ma_sound_at_end(&m_sound)) { - ma_sound_start(&m_sound); + if (!ma_sound_at_end(m_sound)) { + ma_sound_start(m_sound); } } }