audio cut out in firefights because nobody ever asked OpenAL for more than 256 voices

Field report from 2026-07-23 was "audio cutting in and out toward the end of the
match". The night-5 logs say it precisely: 2017 ACQUIRE FAILED lines in a single
match, and every last one of them at live=256.

It is not a leak, which is where I started and where the code comments still
pointed. The source census sits at a healthy 45-60 live, spikes during
firefights, and drains right back down afterwards -- 226 back to 42 in one
window -- so the engine's priority steal loop is doing exactly what it should:
AudioSourceStop/SuspendMaintenance -> ReleaseChannels -> ReleaseSourceSet ->
alDeleteSources, with the live counter following it down. The 2026-07-23 fix
(a999e5c, deleting sources one at a time instead of the spec-atomic bulk call)
was real and is what makes that drain work. It just was not the ceiling.

The ceiling was ours. MakeAudioRenderer called alcCreateContext(device, NULL) --
no attribute list at all -- so OpenAL Soft applied its default budget of 256
mono sources. That number has nothing to do with the 1995 audio hardware; it is
just what you get for not asking. Meanwhile a busy match logs about 7200
explosions, each spawning three DPLIndependantEffect voices, so the pool pins at
the cap and every acquire during that window fails outright and drops its sound.
The peak we actually observed was 226 against a 256 cap, i.e. the bursts were
already scraping the ceiling.

So ask. ALC_MONO_SOURCES at 1024 by default, BT_AUDIO_SOURCES to override for
A/B testing, and read back what the driver GRANTED rather than assuming the
request was honoured. That last part earns its keep: asking for 64 grants 240,
because OpenAL Soft has a floor of its own -- which is also the reason the NULL
default landed on 256 in the first place.

  requested 1024 -> granted 1024
  requested 2048 -> granted 2048
  requested   64 -> granted  240   (driver floor)

Costs mixing headroom, not hardware voices -- OpenAL Soft mixes in software and
only touches voices that are actually sounding.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Joe DiPrima
2026-07-28 16:24:50 -05:00
co-authored by Claude Fable 5
parent 819772f974
commit 7e57816d39
2 changed files with 55 additions and 1 deletions
+15
View File
@@ -16,6 +16,21 @@ on top of it. Full detail: `docs/PROGRESS_LOG.md §5b, §8`.
## What WinTesla already did (do NOT rebuild)
- **Renderer bypass: DONE** — `MUNGA_L4/L4D3D.cpp` + `DXUtils` replace libDPL / the IG board with
Direct3D9. No `libdpl.lib` in the tree. (The early from-scratch D3D9 viewer was retired and removed.) [T1]
- **Audio SOURCE BUDGET — dropouts in heavy combat, FIXED 2026-07-28** [T2]. Field report "audio
cutting in and out toward the end of the match"; night-5 logs carried **2017 `ACQUIRE FAILED` lines in
a single match, every one at `live=256`**. It is **NOT a leak** — the census sits at a healthy 45-60
live, spikes during firefights, and drains straight back, so the engine's priority steal loop
(`AudioSourceStop`/`SuspendMaintenance``ReleaseChannels``ReleaseSourceSet`
`alDeleteSources`) works. The cause: `L4AudioRenderer` called `alcCreateContext(device, NULL)` with
**no attribute list**, so OpenAL Soft applied its DEFAULT budget of 256 mono sources — an OpenAL
default, unrelated to the 1995 audio hardware. A busy match logs ~7200 explosions × 3
`DPLIndependantEffect` voices each; while the pool is pinned every acquire fails and that sound is
dropped outright. FIX: pass `ALC_MONO_SOURCES` (default **1024**, `BT_AUDIO_SOURCES` overrides) and
**read back what was granted** — a request is not a promise. Measured: 1024→1024, 2048→2048, and
64→**240** (OpenAL Soft's own floor, which is why the NULL default landed at 256). Observed bursts
peaked at 226 against the old 256 cap, i.e. they were clipping the ceiling. Note the earlier
2026-07-23 fix (`a999e5c`, per-source delete instead of the spec-atomic bulk `alDeleteSources`) was
real and is still needed — it is what makes the pool drain; it just was not the ceiling problem.
- **Audio: BACKEND now REAL + soundbank loaded; only game-triggering remains** [T2, updated
2026-07-15]. OpenAL replaces the HMI "SOS" engine and the renderer→device→buffer→source→play chain
IS all implemented (`L4AUDRND`/`L4AUDRES`/`L4AUDLVL`; `PatchLevelOfDetail::PlayNote` really calls