From e454e97617ee3a0091c0b6fb11dabb935bd747c7 Mon Sep 17 00:00:00 2001 From: arcattack Date: Thu, 16 Jul 2026 07:54:36 -0500 Subject: [PATCH] Audio: fix step-broadcast misfire -- feed ONLY volume/brightness mix stages (task #50) The blind foot-plant broadcast hit every entity-registered component; mixers whose authored OUTPUT control is Start forwarded the send as a Start and fired their sound on every stride (the per-step ProgramButton 'chirp'). Added GetOutputControlID() to AudioControlMixer/Multiplier and the broadcast now feeds only stages outputting Volume(3)/Brightness(5) -- the footstep loudness inputs -- directly (mixers are entity-registered, no splitter hop needed). Verified: FootFallInt01 delivers on BOTH gaits now (11/run, walk input included); ProgramButton deliveries 188 -> 38 (the remainder are authored looped-sequence cockpit ambience, not the broadcast); stable 28s drive+fire. Co-Authored-By: Claude Opus 4.8 (1M context) --- engine/MUNGA/AUDCMP.h | 10 ++++++++++ game/reconstructed/mech2.cpp | 24 +++++++++++++++--------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/engine/MUNGA/AUDCMP.h b/engine/MUNGA/AUDCMP.h index 180aa68..0d27235 100644 --- a/engine/MUNGA/AUDCMP.h +++ b/engine/MUNGA/AUDCMP.h @@ -232,6 +232,11 @@ class AudioControlMixer: public AudioComponent { public: + // DIAG/game-facing: expose the authored output control so game-side control + // broadcasts (the foot-plant intensity send) can target only volume/brightness + // mix stages and never Start-outputting stages. + AudioControlID GetOutputControlID() const { return outputControlID; } + // //-------------------------------------------------------------------- // Construction, Destruction, Testing @@ -307,6 +312,11 @@ class AudioControlMultiplier: public AudioComponent { public: + // DIAG/game-facing: expose the authored output control so game-side control + // broadcasts (the foot-plant intensity send) can target only volume/brightness + // mix stages and never Start-outputting stages. + AudioControlID GetOutputControlID() const { return outputControlID; } + // //-------------------------------------------------------------------- // Construction, Destruction, Testing diff --git a/game/reconstructed/mech2.cpp b/game/reconstructed/mech2.cpp index 8b612c4..49f0162 100644 --- a/game/reconstructed/mech2.cpp +++ b/game/reconstructed/mech2.cpp @@ -289,15 +289,21 @@ void Component *c; while ((c = it.ReadAndNext()) != NULL) { - // Only the control-graph components (mixers/multipliers/splitters) - // accept the 100+ input-range ids; an AudioSource's ReceiveControl - // Fail()s on unknown ids, so skip the patch-source classes - // (Direct/Dynamic3D/Static3D -- VDATA L4 ids 1001/1002/1005). - { - int cid = (int)c->GetClassID(); - if (cid == 1001 || cid == 1002 || cid == 1005) - continue; - } + // Feed ONLY the volume/brightness MIX stages (the footstep loudness + // inputs). A blind broadcast misfires: mixers whose OUTPUT control + // is Start would forward the send as a Start and fire their sound + // per stride (the "chirp per step" bug -- ProgramButton clicked on + // every plant), and an AudioSource Fail()s on the 100+ input ids. + int cid = (int)c->GetClassID(); + AudioControlID out; + if (cid == (int)RegisteredClass::AudioControlMixerClassID) + out = ((AudioControlMixer *)c)->GetOutputControlID(); + else if (cid == (int)RegisteredClass::AudioControlMultiplierClassID) + out = ((AudioControlMultiplier *)c)->GetOutputControlID(); + else + continue; + if (out != VolumeAudioControlID && out != BrightnessAudioControlID) + continue; AudioComponent *ac = (AudioComponent *)c; ac->ReceiveControl((AudioControlID)(runFamily ? 101 : 100), intensity); ac->ReceiveControl((AudioControlID)(runFamily ? 100 : 101), 0.0f);