Skip to content

Commit 07841cb

Browse files
authored
fix(audio): correct sample limit tracking and source leaks (#182)
Fixed a bug in OpenALAudioManager and MiniAudioManager where the engines would continuously allocate new hardware sources without terminating lower priority sounds, eventually exhausting all available physical sources. Also corrected the sample count logic in MiniAudioManager to only evaluate 2D and 3D sample types rather than all playing sounds.
1 parent 7e3ea1d commit 07841cb

3 files changed

Lines changed: 29 additions & 6 deletions

File tree

Core/GameEngineDevice/Source/MiniAudioDevice/MiniAudioManager.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,7 +1052,10 @@ Bool MiniAudioManager::isPlayingLowerPriority(AudioEventRTS *event) const
10521052
for (auto it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) {
10531053
if (!(*it)->m_audioEventRTS) continue;
10541054
const AudioEventInfo *info = (*it)->m_audioEventRTS->getAudioEventInfo();
1055-
if (info && info->m_priority < priority) return true;
1055+
if (info && info->m_priority < priority) {
1056+
event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle());
1057+
return true;
1058+
}
10561059
}
10571060
return false;
10581061
}
@@ -1573,15 +1576,25 @@ UnsignedInt MiniAudioManager::getNumAvailable2DSamples() const
15731576
{
15741577
// GeneralsX @bugfix Mr. Meeseeks 27/06/2026 Fix available samples calculation to prevent voicelines culling
15751578
UnsignedInt max2D = getAudioSettings()->m_sampleCount2D;
1576-
UnsignedInt playing = (UnsignedInt)m_playingSounds.size();
1579+
UnsignedInt playing = 0;
1580+
for (auto it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) {
1581+
if ((*it) && (*it)->m_type == PAT_Sample) {
1582+
playing++;
1583+
}
1584+
}
15771585
return (max2D > playing) ? (max2D - playing) : 0;
15781586
}
15791587

15801588
//-------------------------------------------------------------------------------------------------
15811589
UnsignedInt MiniAudioManager::getNumAvailable3DSamples() const
15821590
{
1583-
// GeneralsX @bugfix Mr. Meeseeks 27/06/2026 Fix available samples calculation to prevent voicelines culling
1591+
// GeneralsX @bugfix Mr. Meeseeks 01/07/2026 Fix available samples calculation to only count 3D samples
15841592
UnsignedInt max3D = getAudioSettings()->m_sampleCount3D;
1585-
UnsignedInt playing = (UnsignedInt)m_playingSounds.size();
1593+
UnsignedInt playing = 0;
1594+
for (auto it = m_playingSounds.begin(); it != m_playingSounds.end(); ++it) {
1595+
if ((*it) && (*it)->m_type == PAT_3DSample) {
1596+
playing++;
1597+
}
1598+
}
15861599
return (max3D > playing) ? (max3D - playing) : 0;
15871600
}

Core/GameEngineDevice/Source/OpenALAudioDevice/OpenALAudioManager.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,7 +2131,7 @@ Bool OpenALAudioManager::isPlayingLowerPriority(AudioEventRTS* event) const
21312131
if (!(*it)->m_audioEventRTS) continue; // GeneralsX @bugfix BenderAI 11/03/2026
21322132
const AudioEventInfo* info = (*it)->m_audioEventRTS->getAudioEventInfo();
21332133
if (info && info->m_priority < priority) {
2134-
//event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle());
2134+
event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle());
21352135
return true;
21362136
}
21372137
}
@@ -2142,7 +2142,7 @@ Bool OpenALAudioManager::isPlayingLowerPriority(AudioEventRTS* event) const
21422142
if (!(*it)->m_audioEventRTS) continue; // GeneralsX @bugfix BenderAI 11/03/2026
21432143
const AudioEventInfo* info = (*it)->m_audioEventRTS->getAudioEventInfo();
21442144
if (info && info->m_priority < priority) {
2145-
//event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle());
2145+
event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle());
21462146
return true;
21472147
}
21482148
}

docs/DEV_BLOG/2026-07-DIARY.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# July 2026
2+
3+
## 02/07/2026
4+
### Audio Fix: Missing Voiceovers
5+
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.
6+
The issue stemmed from two places:
7+
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.
8+
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.
9+
10+
Both issues have been resolved by adding proper counting filters in MiniAudio and uncommenting `event->setHandleToKill` in both audio managers' priority checks.

0 commit comments

Comments
 (0)