From 8234fc42d97268738b4c93e17c1f81d9f1df6ea6 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sun, 7 Jun 2026 10:57:46 +0200 Subject: [PATCH 1/3] refactor(audio): Simplify available audio samples management --- Core/GameEngine/Include/Common/GameAudio.h | 2 + Core/GameEngine/Include/Common/GameSounds.h | 17 ----- .../Source/Common/Audio/GameSounds.cpp | 55 ++------------- .../MilesAudioDevice/MilesAudioManager.h | 8 ++- .../MilesAudioDevice/MilesAudioManager.cpp | 68 ++++++++++--------- 5 files changed, 48 insertions(+), 102 deletions(-) diff --git a/Core/GameEngine/Include/Common/GameAudio.h b/Core/GameEngine/Include/Common/GameAudio.h index cc9d6cf8338..1843898911c 100644 --- a/Core/GameEngine/Include/Common/GameAudio.h +++ b/Core/GameEngine/Include/Common/GameAudio.h @@ -219,6 +219,8 @@ class AudioManager : public SubsystemInterface virtual UnsignedInt getNum2DSamples() const = 0; virtual UnsignedInt getNum3DSamples() const = 0; virtual UnsignedInt getNumStreams() const = 0; + virtual UnsignedInt getAvailable2DSamples() const = 0; + virtual UnsignedInt getAvailable3DSamples() const = 0; // Device Dependent calls to determine sound prioritization info virtual Bool doesViolateLimit( AudioEventRTS *event ) const = 0; diff --git a/Core/GameEngine/Include/Common/GameSounds.h b/Core/GameEngine/Include/Common/GameSounds.h index 83c846957ac..f684f11edda 100644 --- a/Core/GameEngine/Include/Common/GameSounds.h +++ b/Core/GameEngine/Include/Common/GameSounds.h @@ -69,15 +69,6 @@ class SoundManager : public SubsystemInterface virtual void addAudioEvent(AudioEventRTS *&eventToAdd); // pre-copied - virtual void notifyOf2DSampleStart(); - virtual void notifyOf3DSampleStart(); - - virtual void notifyOf2DSampleCompletion(); - virtual void notifyOf3DSampleCompletion(); - - virtual Int getAvailableSamples(); - virtual Int getAvailable3DSamples(); - // empty string means that this sound wasn't found or some error occurred. CHECK FOR EMPTY STRING. virtual AsciiString getFilenameForPlayFromAudioEvent( const AudioEventRTS *eventToGetFrom ); @@ -87,12 +78,4 @@ class SoundManager : public SubsystemInterface protected: virtual Bool violatesVoice( AudioEventRTS *event ); virtual Bool isInterrupting( AudioEventRTS *event ); - - - protected: - UnsignedInt m_num2DSamples; - UnsignedInt m_num3DSamples; - - UnsignedInt m_numPlaying2DSamples; - UnsignedInt m_numPlaying3DSamples; }; diff --git a/Core/GameEngine/Source/Common/Audio/GameSounds.cpp b/Core/GameEngine/Source/Common/Audio/GameSounds.cpp index c1f1afeedfe..b1c90b1bd20 100644 --- a/Core/GameEngine/Source/Common/Audio/GameSounds.cpp +++ b/Core/GameEngine/Source/Common/Audio/GameSounds.cpp @@ -92,8 +92,7 @@ void SoundManager::update() //------------------------------------------------------------------------------------------------- void SoundManager::reset() { - m_numPlaying2DSamples = 0; - m_numPlaying3DSamples = 0; + } //------------------------------------------------------------------------------------------------- @@ -135,11 +134,6 @@ Real SoundManager::getCameraAudibleDistance() //------------------------------------------------------------------------------------------------- void SoundManager::addAudioEvent(AudioEventRTS *&eventToAdd) { - if (m_num2DSamples == 0 && m_num3DSamples == 0) { - m_num2DSamples = TheAudio->getNum2DSamples(); - m_num3DSamples = TheAudio->getNum3DSamples(); - } - if (canPlayNow(eventToAdd)) { #ifdef INTENSIVE_AUDIO_DEBUG DEBUG_LOG((" - appended to request list with handle '%d'.", (UnsignedInt) eventToAdd->getPlayingHandle())); @@ -153,46 +147,6 @@ void SoundManager::addAudioEvent(AudioEventRTS *&eventToAdd) } } -//------------------------------------------------------------------------------------------------- -void SoundManager::notifyOf2DSampleStart() -{ - ++m_numPlaying2DSamples; -} - -//------------------------------------------------------------------------------------------------- -void SoundManager::notifyOf3DSampleStart() -{ - ++m_numPlaying3DSamples; -} - -//------------------------------------------------------------------------------------------------- -void SoundManager::notifyOf2DSampleCompletion() -{ - if (m_numPlaying2DSamples > 0) { - --m_numPlaying2DSamples; - } -} - -//------------------------------------------------------------------------------------------------- -void SoundManager::notifyOf3DSampleCompletion() -{ - if (m_numPlaying3DSamples > 0) { - --m_numPlaying3DSamples; - } -} - -//------------------------------------------------------------------------------------------------- -Int SoundManager::getAvailableSamples() -{ - return (m_num2DSamples - m_numPlaying2DSamples); -} - -//------------------------------------------------------------------------------------------------- -Int SoundManager::getAvailable3DSamples() -{ - return (m_num3DSamples - m_numPlaying3DSamples); -} - //------------------------------------------------------------------------------------------------- AsciiString SoundManager::getFilenameForPlayFromAudioEvent( const AudioEventRTS *eventToGetFrom ) { @@ -272,18 +226,19 @@ Bool SoundManager::canPlayNow( AudioEventRTS *event ) if (event->isPositionalAudio()) { - if (m_numPlaying3DSamples < m_num3DSamples) + if (TheAudio->getAvailable3DSamples() > 0) { return true; } #ifdef INTENSIVE_AUDIO_DEBUG - DEBUG_LOG(("- %d samples playing, %d samples available", m_numPlaying3DSamples, m_num3DSamples)); + DEBUG_LOG(("- %d samples playing, %d samples available", + TheAudio->getNum3DSamples() - TheAudio->getAvailable3DSamples(), TheAudio->getNum3DSamples())); #endif } else { // its a UI sound (and thus, 2-D) - if (m_numPlaying2DSamples < m_num2DSamples) + if (TheAudio->getAvailable2DSamples() > 0) { return true; } diff --git a/Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h b/Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h index 6000d1c8f8b..71d0b43ed34 100644 --- a/Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h +++ b/Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h @@ -195,6 +195,8 @@ class MilesAudioManager : public AudioManager virtual UnsignedInt getNum2DSamples() const override; virtual UnsignedInt getNum3DSamples() const override; virtual UnsignedInt getNumStreams() const override; + virtual UnsignedInt getAvailable2DSamples() const override; + virtual UnsignedInt getAvailable3DSamples() const override; virtual Bool doesViolateLimit( AudioEventRTS *event ) const override; virtual Bool isPlayingLowerPriority( AudioEventRTS *event ) const override; @@ -301,8 +303,8 @@ class MilesAudioManager : public AudioManager // Available handles for play. Note that there aren't handles open in advance for // streaming things, only 2-D and 3-D sounds. - std::list m_availableSamples; - std::list m_available3DSamples; + std::vector m_availableSamples; + std::vector m_available3DSamples; // Currently Playing audio. Useful if we have to preempt it. // This should rarely if ever happen, as we mirror this in Sounds, and attempt to @@ -368,6 +370,8 @@ class MilesAudioManagerDummy : public MilesAudioManager virtual UnsignedInt getNum2DSamples() const override { return 0; } virtual UnsignedInt getNum3DSamples() const override { return 0; } virtual UnsignedInt getNumStreams() const override { return 0; } + virtual UnsignedInt getAvailable2DSamples() const override { return 0; } + virtual UnsignedInt getAvailable3DSamples() const override { return 0; } virtual Bool doesViolateLimit(AudioEventRTS* event) const override { return false; } virtual Bool isPlayingLowerPriority(AudioEventRTS* event) const override { return false; } virtual Bool isPlayingAlready(AudioEventRTS* event) const override { return false; } diff --git a/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp b/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp index b0730c73f4a..07f219db914 100644 --- a/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp +++ b/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp @@ -165,9 +165,8 @@ void MilesAudioManager::audioDebugDisplay(DebugDisplayInterface *dd, void *, FIL dd->printf("Speech: %s ", (isOn(AudioAffect_Speech) ? "Yes" : "No")); dd->printf("Music: %s\n", (isOn(AudioAffect_Music) ? "Yes" : "No")); dd->printf("Channels Available: "); - dd->printf("%d Sounds ", m_sound->getAvailableSamples()); - - dd->printf("%d(%d) 3D Sounds\n", m_sound->getAvailable3DSamples(), m_available3DSamples.size() ); + dd->printf("%u Sounds ", getAvailable2DSamples()); + dd->printf("%u 3D Sounds\n", getAvailable3DSamples()); dd->printf("Volume: "); dd->printf("Sound: %d ", REAL_TO_INT(m_soundVolume * 100.0f)); dd->printf("3DSound: %d ", REAL_TO_INT(m_sound3DVolume * 100.0f)); @@ -196,8 +195,8 @@ void MilesAudioManager::audioDebugDisplay(DebugDisplayInterface *dd, void *, FIL fprintf( fp, "Speech: %s ", (isOn(AudioAffect_Speech) ? "Yes" : "No") ); fprintf( fp, "Music: %s\n", (isOn(AudioAffect_Music) ? "Yes" : "No") ); fprintf( fp, "Channels Available: " ); - fprintf( fp, "%d Sounds ", m_sound->getAvailableSamples() ); - fprintf( fp, "%d 3D Sounds\n", m_sound->getAvailable3DSamples() ); + fprintf( fp, "%u Sounds ", getAvailable3DSamples() ); + fprintf( fp, "%u 3D Sounds\n", getAvailable3DSamples() ); fprintf( fp, "Volume: "); fprintf( fp, "Sound: %d ", REAL_TO_INT(m_soundVolume * 100.0f) ); fprintf( fp, "3DSound: %d ", REAL_TO_INT(m_sound3DVolume * 100.0f) ); @@ -740,7 +739,6 @@ void MilesAudioManager::playAudioEvent( AudioRequest* req ) if (sample3D) { audio->m_file = playSample3D(event, sample3D); - m_sound->notifyOf3DSampleStart(); } if( !audio->m_file ) @@ -807,7 +805,6 @@ void MilesAudioManager::playAudioEvent( AudioRequest* req ) if (sample) { audio->m_file = playSample(event, sample); - m_sound->notifyOf2DSampleStart(); } if (!audio->m_file) { @@ -1042,17 +1039,6 @@ void MilesAudioManager::stopPlayingAudio( PlayingAudio *release ) if (prevStatus != PS_Stopping) { return; } - if (release->m_audioEventRTS->getAudioEventInfo()->m_soundType == AT_SoundEffect) { - if (release->m_type == PAT_Sample) { - if (release->m_sample) { - m_sound->notifyOf2DSampleCompletion(); - } - } else { - if (release->m_3DSample) { - m_sound->notifyOf3DSampleCompletion(); - } - } - } releaseMilesHandles(release); } @@ -1175,20 +1161,22 @@ void MilesAudioManager::freeAllMilesHandles() stopAllAudioImmediately(); // Walks through the available 2-D and 3-D handles and releases them - std::list::iterator it; + std::vector::iterator it; for ( it = m_availableSamples.begin(); it != m_availableSamples.end(); ) { HSAMPLE sample = *it; AIL_release_sample_handle(sample); - it = m_availableSamples.erase(it); } + + m_availableSamples.clear(); m_num2DSamples = 0; - std::list::iterator it3D; + std::vector::iterator it3D; for ( it3D = m_available3DSamples.begin(); it3D != m_available3DSamples.end(); ) { H3DSAMPLE sample3D = *it3D; AIL_release_3D_sample_handle(sample3D); - it3D = m_available3DSamples.erase(it3D); } + + m_available3DSamples.clear(); m_num3DSamples = 0; m_numStreams = 0; } @@ -1196,27 +1184,26 @@ void MilesAudioManager::freeAllMilesHandles() //------------------------------------------------------------------------------------------------- HSAMPLE MilesAudioManager::getFirst2DSample( AudioEventRTS *event ) { - if (m_availableSamples.begin() != m_availableSamples.end()) { - HSAMPLE retSample = *m_availableSamples.begin(); - m_availableSamples.erase(m_availableSamples.begin()); - return (retSample); + if (!m_availableSamples.empty()) { + HSAMPLE retSample = m_availableSamples.back(); + m_availableSamples.pop_back(); + return retSample; } - // Find the first sample of lower priority than my augmented priority that is interruptable and take its handle - + // Find the first sample of lower priority than my augmented priority that is interruptible and take its handle return nullptr; } //------------------------------------------------------------------------------------------------- H3DSAMPLE MilesAudioManager::getFirst3DSample( AudioEventRTS *event ) { - if (m_available3DSamples.begin() != m_available3DSamples.end()) { - H3DSAMPLE retSample = *m_available3DSamples.begin(); - m_available3DSamples.erase(m_available3DSamples.begin()); - return (retSample); + if (!m_available3DSamples.empty()) { + H3DSAMPLE retSample = m_available3DSamples.back(); + m_available3DSamples.pop_back(); + return retSample; } - // Find the first sample of lower priority than my augmented priority that is interruptable and take its handle + // Find the first sample of lower priority than my augmented priority that is interruptible and take its handle return nullptr; } @@ -1755,6 +1742,18 @@ UnsignedInt MilesAudioManager::getNumStreams() const return m_numStreams; } +//------------------------------------------------------------------------------------------------- +UnsignedInt MilesAudioManager::getAvailable2DSamples() const +{ + return (UnsignedInt)m_availableSamples.size(); +} + +//------------------------------------------------------------------------------------------------- +UnsignedInt MilesAudioManager::getAvailable3DSamples() const +{ + return (UnsignedInt)m_available3DSamples.size(); +} + //------------------------------------------------------------------------------------------------- Bool MilesAudioManager::doesViolateLimit( AudioEventRTS *event ) const { @@ -2769,6 +2768,9 @@ void MilesAudioManager::initSamplePools() return; } + m_availableSamples.reserve(getAudioSettings()->m_sampleCount2D); + m_available3DSamples.reserve(getAudioSettings()->m_sampleCount3D); + int i = 0; for (i = 0; i < getAudioSettings()->m_sampleCount2D; ++i) { HSAMPLE sample = AIL_allocate_sample_handle(m_digitalHandle); From 5fa4945b8258f805cb236da0a2ee93b3ea318e6d Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sun, 7 Jun 2026 21:35:25 +0200 Subject: [PATCH 2/3] Fix loops --- .../Source/MilesAudioDevice/MilesAudioManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp b/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp index 07f219db914..39ed21e71c4 100644 --- a/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp +++ b/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp @@ -1162,7 +1162,7 @@ void MilesAudioManager::freeAllMilesHandles() // Walks through the available 2-D and 3-D handles and releases them std::vector::iterator it; - for ( it = m_availableSamples.begin(); it != m_availableSamples.end(); ) { + for ( it = m_availableSamples.begin(); it != m_availableSamples.end(); ++it ) { HSAMPLE sample = *it; AIL_release_sample_handle(sample); } @@ -1171,7 +1171,7 @@ void MilesAudioManager::freeAllMilesHandles() m_num2DSamples = 0; std::vector::iterator it3D; - for ( it3D = m_available3DSamples.begin(); it3D != m_available3DSamples.end(); ) { + for ( it3D = m_available3DSamples.begin(); it3D != m_available3DSamples.end(); ++it3D ) { H3DSAMPLE sample3D = *it3D; AIL_release_3D_sample_handle(sample3D); } From 8a9463a27e4af78fccfa8b74ece350d5e2268c6a Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sun, 7 Jun 2026 21:39:53 +0200 Subject: [PATCH 3/3] Fix wrong function call in debug draw --- .../Source/MilesAudioDevice/MilesAudioManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp b/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp index 39ed21e71c4..e5ecd4d532b 100644 --- a/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp +++ b/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp @@ -195,7 +195,7 @@ void MilesAudioManager::audioDebugDisplay(DebugDisplayInterface *dd, void *, FIL fprintf( fp, "Speech: %s ", (isOn(AudioAffect_Speech) ? "Yes" : "No") ); fprintf( fp, "Music: %s\n", (isOn(AudioAffect_Music) ? "Yes" : "No") ); fprintf( fp, "Channels Available: " ); - fprintf( fp, "%u Sounds ", getAvailable3DSamples() ); + fprintf( fp, "%u Sounds ", getAvailable2DSamples() ); fprintf( fp, "%u 3D Sounds\n", getAvailable3DSamples() ); fprintf( fp, "Volume: "); fprintf( fp, "Sound: %d ", REAL_TO_INT(m_soundVolume * 100.0f) );