Issue #26: runtime master volume (-/= keys, persisted)

The game audio plays hot with no in-game control -- testers couldn't
hear voice chat without the Windows mixer (playtest night).  The -/=
keys now step the OpenAL listener gain (the master scale every source
inherits) in 5% steps, clamped 0..150%, edge-detected in the per-frame
poll with a foreground guard; the value persists to content\volume.cfg
and reloads at boot (BT_AUDIO_VOLUME env still wins when set; default
stays 0.6).  README updated.

Verified: volume.cfg 0.25 -> boot log "master gain=0.25"; key stepping
needs a live focused session (awaiting live verification).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-23 00:53:07 -05:00
co-authored by Claude Opus 4.8
parent 44f7c39ee1
commit 4e0fcbf328
3 changed files with 61 additions and 1 deletions
+42 -1
View File
@@ -383,9 +383,22 @@ void
ALCcontext *context = alcCreateContext(device,NULL);
alcMakeContextCurrent(context);
// Master volume: AL_GAIN on the listener scales EVERY source. Default 0.6
// (the raw samples are hot); override with BT_AUDIO_VOLUME=<0.0..1.0+>.
// (the raw samples are hot). Priority: BT_AUDIO_VOLUME env >
// content\volume.cfg (written by the runtime -/+ keys, issue #26) > 0.6.
float masterVol = 0.6f;
{
FILE *cfg = fopen("volume.cfg", "rt");
if (cfg != NULL)
{
float f = -1.0f;
if (fscanf(cfg, "%f", &f) == 1 && f >= 0.0f && f <= 1.5f)
masterVol = f;
fclose(cfg);
}
}
if (const char *v = getenv("BT_AUDIO_VOLUME")) { float f = (float)atof(v); if (f >= 0.0f) masterVol = f; }
extern float gBTMasterVolume;
gBTMasterVolume = masterVol;
alListenerf(AL_GAIN, masterVol);
if (getenv("BT_AUDIO_LOG")) DEBUG_STREAM << "[audio] OpenAL device OPENED + context current; master gain=" << masterVol << "\n" << std::flush;
// (task #50, AUDIO_FIDELITY F9/F11) EFX bridge: the authored lowpass
@@ -1442,3 +1455,31 @@ void L4AudioRenderer::ReleaseSourceSet(SourceSet &sourceSet)
#if defined(TRACE_AUDIO_RENDERER_DORMANT_SOURCES)
BitTrace Audio_Renderer_Dormant_Sources("Audio Renderer Dormant Sources");
#endif
//
//#############################################################################
// Master-volume runtime control (issue #26, 2026-07-23). The pod had a
// physical volume knob on the operator side; desktop players had NO way to
// duck the (hot) game audio under voice chat short of the Windows mixer.
// The -/= keys step the OpenAL listener gain (the master scale for every
// source); the value persists in content\volume.cfg (CWD) and reloads at
// the next boot (BT_AUDIO_VOLUME env still wins when set).
//#############################################################################
//
float gBTMasterVolume = 0.6f;
void BTAudioMasterVolumeStep(int direction)
{
gBTMasterVolume += (direction > 0) ? 0.05f : -0.05f;
if (gBTMasterVolume < 0.0f) gBTMasterVolume = 0.0f;
if (gBTMasterVolume > 1.5f) gBTMasterVolume = 1.5f;
alListenerf(AL_GAIN, gBTMasterVolume);
FILE *cfg = fopen("volume.cfg", "wt");
if (cfg != NULL)
{
fprintf(cfg, "%.2f\n", gBTMasterVolume);
fclose(cfg);
}
DEBUG_STREAM << "[audio] master volume "
<< (int)(gBTMasterVolume * 100.0f + 0.5f) << "%" << std::endl << std::flush;
}