diff --git a/Core/GameEngineDevice/Source/MiniAudioDevice/MiniAudioManager.cpp b/Core/GameEngineDevice/Source/MiniAudioDevice/MiniAudioManager.cpp index d886ccf56fc..4bbfdc6c91a 100644 --- a/Core/GameEngineDevice/Source/MiniAudioDevice/MiniAudioManager.cpp +++ b/Core/GameEngineDevice/Source/MiniAudioDevice/MiniAudioManager.cpp @@ -1052,7 +1052,10 @@ Bool MiniAudioManager::isPlayingLowerPriority(AudioEventRTS *event) const for (auto it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) { if (!(*it)->m_audioEventRTS) continue; const AudioEventInfo *info = (*it)->m_audioEventRTS->getAudioEventInfo(); - if (info && info->m_priority < priority) return true; + if (info && info->m_priority < priority) { + event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle()); + return true; + } } return false; } @@ -1573,15 +1576,25 @@ UnsignedInt MiniAudioManager::getNumAvailable2DSamples() const { // GeneralsX @bugfix Mr. Meeseeks 27/06/2026 Fix available samples calculation to prevent voicelines culling UnsignedInt max2D = getAudioSettings()->m_sampleCount2D; - UnsignedInt playing = (UnsignedInt)m_playingSounds.size(); + UnsignedInt playing = 0; + for (auto it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) { + if ((*it) && (*it)->m_type == PAT_Sample) { + playing++; + } + } return (max2D > playing) ? (max2D - playing) : 0; } //------------------------------------------------------------------------------------------------- UnsignedInt MiniAudioManager::getNumAvailable3DSamples() const { - // GeneralsX @bugfix Mr. Meeseeks 27/06/2026 Fix available samples calculation to prevent voicelines culling + // GeneralsX @bugfix Mr. Meeseeks 01/07/2026 Fix available samples calculation to only count 3D samples UnsignedInt max3D = getAudioSettings()->m_sampleCount3D; - UnsignedInt playing = (UnsignedInt)m_playingSounds.size(); + UnsignedInt playing = 0; + for (auto it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) { + if ((*it) && (*it)->m_type == PAT_3DSample) { + playing++; + } + } return (max3D > playing) ? (max3D - playing) : 0; } diff --git a/Core/GameEngineDevice/Source/OpenALAudioDevice/OpenALAudioManager.cpp b/Core/GameEngineDevice/Source/OpenALAudioDevice/OpenALAudioManager.cpp index aa7f91cc600..ca83ada7c42 100644 --- a/Core/GameEngineDevice/Source/OpenALAudioDevice/OpenALAudioManager.cpp +++ b/Core/GameEngineDevice/Source/OpenALAudioDevice/OpenALAudioManager.cpp @@ -2131,7 +2131,7 @@ Bool OpenALAudioManager::isPlayingLowerPriority(AudioEventRTS* event) const if (!(*it)->m_audioEventRTS) continue; // GeneralsX @bugfix BenderAI 11/03/2026 const AudioEventInfo* info = (*it)->m_audioEventRTS->getAudioEventInfo(); if (info && info->m_priority < priority) { - //event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle()); + event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle()); return true; } } @@ -2142,7 +2142,7 @@ Bool OpenALAudioManager::isPlayingLowerPriority(AudioEventRTS* event) const if (!(*it)->m_audioEventRTS) continue; // GeneralsX @bugfix BenderAI 11/03/2026 const AudioEventInfo* info = (*it)->m_audioEventRTS->getAudioEventInfo(); if (info && info->m_priority < priority) { - //event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle()); + event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle()); return true; } } diff --git a/docs/DEV_BLOG/2026-07-DIARY.md b/docs/DEV_BLOG/2026-07-DIARY.md new file mode 100644 index 00000000000..390701c51b2 --- /dev/null +++ b/docs/DEV_BLOG/2026-07-DIARY.md @@ -0,0 +1,10 @@ +# July 2026 + +## 02/07/2026 +### Audio Fix: Missing Voiceovers +Fixed a significant issue where in-game voiceovers (like "You are victorious" or General Challenge taunts) were not playing, especially during late-game or heavy combat scenarios. +The issue stemmed from two places: +1. **OpenAL and MiniAudio priority leaks:** When the maximum sample limits were hit (e.g., 64 2D sounds), the game would correctly attempt to cull lower priority sounds. However, `OpenALAudioManager` and `MiniAudioManager` were missing the logic to set the `handleToKill` inside `isPlayingLowerPriority()`. This resulted in the engines continuously generating new hardware sources without freeing older ones, eventually exhausting all physical sources (usually 256) and silently dropping new sounds. +2. **MiniAudio incorrect limits:** `MiniAudioManager::getNumAvailable2DSamples` was calculating available 2D samples against the size of the *entire* `m_playingSounds` list (which in MiniAudio includes 3D sounds and Streams/Music). This effectively kept the available samples at 0 at all times, making it always fall back to the broken priority handling. + +Both issues have been resolved by adding proper counting filters in MiniAudio and uncommenting `event->setHandleToKill` in both audio managers' priority checks.