From 5653f5d5711d68a43c3f003f86e899ac17663f39 Mon Sep 17 00:00:00 2001 From: Moros Smith Date: Sat, 26 Sep 2026 20:48:10 -0400 Subject: [PATCH 1/8] [ext][miniaudio] fix implementation macro --- extensions/miniaudio/olcPGEX3_Miniaudio.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/miniaudio/olcPGEX3_Miniaudio.h b/extensions/miniaudio/olcPGEX3_Miniaudio.h index 7d1145c..d4edf1f 100644 --- a/extensions/miniaudio/olcPGEX3_Miniaudio.h +++ b/extensions/miniaudio/olcPGEX3_Miniaudio.h @@ -59,9 +59,10 @@ #ifdef OLC_PGEX3_MINIAUDIO #define MINIAUDIO_IMPLEMENTATION -#include "miniaudio.h" #endif +#include "miniaudio.h" + #include #include #include From b1de8a46f11922e7c43a7e94bd48a3d1012f7782 Mon Sep 17 00:00:00 2001 From: Moros Smith Date: Sat, 26 Sep 2026 20:48:59 -0400 Subject: [PATCH 2/8] [ext][miniaudio] fix copy/move semantics, delete copy, allow move. --- extensions/miniaudio/olcPGEX3_Miniaudio.h | 49 +++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/extensions/miniaudio/olcPGEX3_Miniaudio.h b/extensions/miniaudio/olcPGEX3_Miniaudio.h index d4edf1f..9807967 100644 --- a/extensions/miniaudio/olcPGEX3_Miniaudio.h +++ b/extensions/miniaudio/olcPGEX3_Miniaudio.h @@ -82,6 +82,10 @@ namespace olc::ext::Miniaudio public: Sound() = default; ~Sound(); + Sound(const Sound&) = delete; + Sound& operator=(const Sound&) = delete; + Sound(Sound&& other) noexcept; + Sound& operator=(Sound&& other) noexcept; public: // Loaders // Create an image resource based on an image file asset on disk @@ -334,7 +338,52 @@ namespace olc::ext::Miniaudio #pragma region Sound uint32_t Sound::m_id_tracker = 0; + Sound::Sound(Sound&& other) noexcept + : m_pgex(other.m_pgex), + m_buffer(std::move(other.m_buffer)), + m_base_sound(other.m_base_sound), + m_voices(std::move(other.m_voices)), + m_id(other.m_id), + m_virtual_path(std::move(other.m_virtual_path)), + m_is_loaded(other.m_is_loaded), + m_is_paused(other.m_is_paused), + m_num_voices(other.m_num_voices), + m_current_voice(other.m_current_voice), + m_length_in_pcm_frames(other.m_length_in_pcm_frames), + m_length_in_seconds(other.m_length_in_seconds) + { + other.m_pgex = nullptr; + other.m_base_sound = {0}; + other.m_is_loaded = false; + other.m_id = 0; + }; + Sound& Sound::operator=(Sound&& other) noexcept + { + if(this != &other) + { + DestroySound(); + m_pgex = other.m_pgex; + m_buffer = std::move(other.m_buffer); + m_base_sound = other.m_base_sound; + m_voices = std::move(other.m_voices); + m_id = other.m_id; + m_virtual_path = std::move(other.m_virtual_path); + m_is_loaded = other.m_is_loaded; + m_is_paused = other.m_is_paused; + m_num_voices = other.m_num_voices; + m_current_voice = other.m_current_voice; + m_length_in_pcm_frames = other.m_length_in_pcm_frames; + m_length_in_seconds = other.m_length_in_seconds; + + other.m_pgex = nullptr; + other.m_base_sound = {0}; + other.m_is_loaded = false; + other.m_id = 0; + } + return *this; + } + Sound::~Sound() { DestroySound(); From 7d037caac80235838d1a6e56b4ac2e63c2325c42 Mon Sep 17 00:00:00 2001 From: Moros Smith Date: Sat, 26 Sep 2026 20:50:16 -0400 Subject: [PATCH 3/8] [ext][miniaudio] allow per-voice tweaking of volume, pan, and pitch at Play() --- extensions/miniaudio/olcPGEX3_Miniaudio.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/extensions/miniaudio/olcPGEX3_Miniaudio.h b/extensions/miniaudio/olcPGEX3_Miniaudio.h index 9807967..b9ad5ba 100644 --- a/extensions/miniaudio/olcPGEX3_Miniaudio.h +++ b/extensions/miniaudio/olcPGEX3_Miniaudio.h @@ -104,7 +104,7 @@ namespace olc::ext::Miniaudio public: // playback routines // plays a sound, can be set to loop - void Play(const bool looping = false); + void Play(const bool looping = false, const float volume = 1.0f, const float pan = 0.0f, const float pitch = 1.0f); // stops a sound, rewinds to beginning void Stop(); // pauses a sound, does not change position @@ -529,11 +529,14 @@ namespace olc::ext::Miniaudio } // plays a sound, can be set to loop - void Sound::Play(const bool looping) + void Sound::Play(const bool looping, const float volume, const float pan, const float pitch) { if(!m_is_paused) m_current_voice = (m_current_voice + 1) % m_num_voices; + ma_sound_set_volume(&m_voices[m_current_voice], std::clamp(volume, 0.0f, 1.0f)); + ma_sound_set_pan(&m_voices[m_current_voice], std::clamp(pan, -1.0f, 1.0f)); + ma_sound_set_pitch(&m_voices[m_current_voice], std::max({0.0f, pitch})); ma_sound_set_looping(&m_voices[m_current_voice], looping); ma_sound_seek_to_pcm_frame(&m_voices[m_current_voice], 0); ma_sound_start(&m_voices[m_current_voice]); From 23a9e93118e20d4e543a77b30e75b019b32c1296 Mon Sep 17 00:00:00 2001 From: Moros Smith Date: Sat, 26 Sep 2026 20:54:58 -0400 Subject: [PATCH 4/8] [ext][miniaudio] allow engine to continue processing when not focused, regardless of background playback. --- extensions/miniaudio/olcPGEX3_Miniaudio.h | 26 ++++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/extensions/miniaudio/olcPGEX3_Miniaudio.h b/extensions/miniaudio/olcPGEX3_Miniaudio.h index b9ad5ba..8949765 100644 --- a/extensions/miniaudio/olcPGEX3_Miniaudio.h +++ b/extensions/miniaudio/olcPGEX3_Miniaudio.h @@ -835,9 +835,6 @@ namespace olc::ext::Miniaudio if(ma == nullptr) throw std::runtime_error{"unable to access miniaudio pgex instance from data_callback"}; - if(!ma->m_cfg.BackgroundPlay && !ma->m_pge->IsFocused()) - return; - // with great power comes... if(ma->m_data_callback) { @@ -845,8 +842,10 @@ namespace olc::ext::Miniaudio return; } + const bool audioShouldPlay = !(!ma->m_cfg.BackgroundPlay && !ma->m_pge->IsFocused()); + std::span engineBuffer((float*)pOutput, frameCount * ma->GetDeviceChannels()); - ma_engine_read_pcm_frames(&ma->m_engine, engineBuffer.data(), frameCount, NULL); + ma_engine_read_pcm_frames(&ma->m_engine, engineBuffer.data(), frameCount, NULL); // resize, if required. frameCount is not guaranteed not to change. if(ma->m_waveform_buffer.size() != (frameCount * ma->GetDeviceChannels())) @@ -860,9 +859,12 @@ namespace olc::ext::Miniaudio if (!waveform->IsPlaying()) continue; - ma_waveform_read_pcm_frames(&waveform->m_waveform, ma->m_waveform_buffer.data(), frameCount, NULL); + // if audio shouldn't play, move on here. + if(!audioShouldPlay) + continue; + for(int frame = 0; frame < frameCount; ++frame) { // Ramp gain toward target one step per frame @@ -886,9 +888,11 @@ namespace olc::ext::Miniaudio { float left, right; ma->m_synth_callback(left, right, 1.0f / ma->GetDeviceSampleRate()); - - engineBuffer[(i * ma->GetDeviceChannels())] += left; - engineBuffer[(i * ma->GetDeviceChannels()) + 1] += right; + if(audioShouldPlay) + { + engineBuffer[(i * ma->GetDeviceChannels())] += left; + engineBuffer[(i * ma->GetDeviceChannels()) + 1] += right; + } } } @@ -897,6 +901,12 @@ namespace olc::ext::Miniaudio for(int i = 0; i < engineBuffer.size(); i++) { + if(!audioShouldPlay) + { + engineBuffer[i] = 0.0f; + continue; + } + float peak = fabsf(engineBuffer[i]); if (peak > 1.0f) From 1d990527748bc85e2fb9e631a7a930bd37e5f9a4 Mon Sep 17 00:00:00 2001 From: Moros Smith Date: Sun, 27 Sep 2026 12:09:02 -0400 Subject: [PATCH 5/8] [ext][miniaudio] fetch only the header for miniaudio --- extensions/miniaudio/CMakeLists.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/extensions/miniaudio/CMakeLists.txt b/extensions/miniaudio/CMakeLists.txt index f678d58..8846aeb 100644 --- a/extensions/miniaudio/CMakeLists.txt +++ b/extensions/miniaudio/CMakeLists.txt @@ -1,14 +1,15 @@ # Fetch 3rd Party miniaudio library +# Fetch miniaudio.h FetchContent_Declare( miniaudio - GIT_REPOSITORY https://github.com/mackron/miniaudio.git - GIT_TAG 0.11.25 + URL "https://raw.githubusercontent.com/mackron/miniaudio/0.11.25/miniaudio.h" + DOWNLOAD_NO_EXTRACT ON + SOURCE_DIR "${CMAKE_BINARY_DIR}/_deps/miniaudio-src" ) FetchContent_MakeAvailable(miniaudio) add_example(ext_demo_Miniaudio demo_Miniaudio.cpp) -target_include_directories(ext_demo_Miniaudio PRIVATE ${miniaudio_SOURCE_DIR}) - +target_include_directories(ext_demo_Miniaudio PRIVATE "${CMAKE_BINARY_DIR}/_deps/miniaudio-src") handle_assets(ext_demo_Miniaudio ${CMAKE_CURRENT_SOURCE_DIR}/assets) From 96cdc9a2dff029fbb0b824acff020df3d5522704 Mon Sep 17 00:00:00 2001 From: Moros Smith Date: Sun, 27 Sep 2026 12:09:29 -0400 Subject: [PATCH 6/8] [ext][miniaudio] add note about additional arguments to Sound::Play --- extensions/miniaudio/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extensions/miniaudio/README.md b/extensions/miniaudio/README.md index c1e1526..13baacc 100644 --- a/extensions/miniaudio/README.md +++ b/extensions/miniaudio/README.md @@ -133,6 +133,8 @@ mySound.Play(); mySound.Play(true); // Loops continuously ``` +> **Note For Advanced Users:** the `olc::ext::Miniaudio::Sound` has a pool of voices, the `Play` function has several optional arguments to allow you to set the **volume**, **pan**, and **pitch** of an individual voice at the moment playback begins. + #### Stop ```cpp // Stop and rewind to beginning From 608edbf45b90ec82ab01771d60bc0d884a906f82 Mon Sep 17 00:00:00 2001 From: Moros Smith Date: Sun, 27 Sep 2026 12:10:09 -0400 Subject: [PATCH 7/8] [ext][miniaudio] set Sound::Play default values out of range to detect if they've been explicitly set --- extensions/miniaudio/olcPGEX3_Miniaudio.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/extensions/miniaudio/olcPGEX3_Miniaudio.h b/extensions/miniaudio/olcPGEX3_Miniaudio.h index 8949765..2a488eb 100644 --- a/extensions/miniaudio/olcPGEX3_Miniaudio.h +++ b/extensions/miniaudio/olcPGEX3_Miniaudio.h @@ -103,8 +103,8 @@ namespace olc::ext::Miniaudio public: // playback routines - // plays a sound, can be set to loop - void Play(const bool looping = false, const float volume = 1.0f, const float pan = 0.0f, const float pitch = 1.0f); + // plays a sound, can set looping, volume, pan, or pitch (note: default values are out of range deliberately) + void Play(const bool looping = false, const float volume = 2.0f, const float pan = 2.0f, const float pitch = 2.0f); // stops a sound, rewinds to beginning void Stop(); // pauses a sound, does not change position @@ -534,9 +534,15 @@ namespace olc::ext::Miniaudio if(!m_is_paused) m_current_voice = (m_current_voice + 1) % m_num_voices; - ma_sound_set_volume(&m_voices[m_current_voice], std::clamp(volume, 0.0f, 1.0f)); - ma_sound_set_pan(&m_voices[m_current_voice], std::clamp(pan, -1.0f, 1.0f)); - ma_sound_set_pitch(&m_voices[m_current_voice], std::max({0.0f, pitch})); + if(volume != 2.0f) + ma_sound_set_volume(&m_voices[m_current_voice], std::clamp(volume, 0.0f, 1.0f)); + + if(pan != 2.0f) + ma_sound_set_pan(&m_voices[m_current_voice], std::clamp(pan, -1.0f, 1.0f)); + + if(pitch != 2.0f) + ma_sound_set_pitch(&m_voices[m_current_voice], std::max({0.0f, pitch})); + ma_sound_set_looping(&m_voices[m_current_voice], looping); ma_sound_seek_to_pcm_frame(&m_voices[m_current_voice], 0); ma_sound_start(&m_voices[m_current_voice]); From 6e023bc9ad16c3ad0bbc2cd3a40bec6f6ba88e8b Mon Sep 17 00:00:00 2001 From: Moros Smith Date: Thu, 1 Oct 2026 06:17:36 -0400 Subject: [PATCH 8/8] [ext][miniaudio] fix bad memcpy assumptions, Thanks Linh --- extensions/miniaudio/olcPGEX3_Miniaudio.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/extensions/miniaudio/olcPGEX3_Miniaudio.h b/extensions/miniaudio/olcPGEX3_Miniaudio.h index 2a488eb..d904d82 100644 --- a/extensions/miniaudio/olcPGEX3_Miniaudio.h +++ b/extensions/miniaudio/olcPGEX3_Miniaudio.h @@ -421,13 +421,18 @@ namespace olc::ext::Miniaudio bool Sound::CreateSoundFromMemory(const uint8_t* data, const size_t bytes, AudioEngine* pgex, uint32_t nNumVoices) { - if(!data) return false; - if(bytes <= 0) return false; + if(!data || bytes <= 0) return false; - m_buffer.resize(bytes); - uint8_t* result = reinterpret_cast(std::memcpy(m_buffer.data(), data, m_buffer.size())); - if(result == m_buffer.data()) + // Thanks Linh + try + { + m_buffer.assign(data, data + bytes); + } + catch (const std::exception&) + { + m_buffer.clear(); return false; + } m_pgex = pgex; m_num_voices = nNumVoices;