Files
LlamaCasty/TASKS/task-12-master-limiter.md
gramps 87509bcf99 docs: restructure TASKS.md into a catalog — one file per task in TASKS/
TASKS.md is now the index (status table, open items, research pointer).
33 files: 32 task files + 1 research facts file. The full take-saga
narrative and all design decisions are preserved verbatim; the catalog
makes the queue readable without opening every task body. Schema and
AGENTS.md updated to reflect the new layout.
2026-09-05 16:31:46 -07:00

2.0 KiB
Raw Permalink Blame History

TASK 12 — Master limiter on the live mix (2026-08-15)

Catalog: TASKS.md — status and requirements live here.

Queued by the creator during the TRAX discussion: "should the soundtrack be limited to avoid squandering resources / should it cap at 20% / how do the three sound events balance?" Review conclusions (all three instincts checked out, only ONE real gap):

  • File size — no guard needed. MusicPlayer uses MediaFoundationReader, which streams from disk (progressive source): memory is flat (~a few MB) regardless of file size; CPU negligible.
  • 20% cap — already enforced by construction. MusicPlayer.MusicVolume = 0.20f + music rides the SAME WASAPI loopback (and therefore the same gain) as game audio, so music:game is always exactly 0.20:1 at any slider position — it literally cannot rise above 20% of the current desktop volume.
  • The gap: AudioMixer.FillAndMix summed mic + loopback with no output ceiling — mic 100% + loud game/music could pass 0 dBFS and clip the AAC encode.

Shipped:

  1. ✅ Services/Audio/MasterLimiter.cs (pure, unit-tested) — a −1 dBFS ceiling (Ceiling = 0.891), instant attack per frame (a hot frame is scaled exactly to the ceiling — no overshoot), smoothed release toward unity so loud passages don't pump; gain never exceeds 1 (no boosting). Applied at the end of AudioMixer.FillAndMix, right before the pipe write.
  2. ✅ Unit tests — over-ceiling frames trimmed to ≤ ceiling; sub-ceiling frames never boosted; gain recovers to unity after the loud frame ends.
  3. ✅ ONE integration test (MasterLimiter_CapsTheLiveMix_OnThePipe) — real mixer + pipe harness: a 0.95 loopback bed (hotter than the ceiling) is capped to exactly 0.891 on the wire while staying audible.
  4. ✅ Docs in the same commit — ai.md (go-live audio section), Services/index.md (new row).

No changes to MusicPlayer, the 0.20 cap, the ducker, or the meter zones. Build 0 warnings.