Audio: target the step-intensity send at FOOTSTEP sources only (task #50)
The output-filtered broadcast still fed EVERY volume/brightness mixer -- the
always-on ambience pulse's own volume mixer got cranked to step intensity on
every stride ('a stuck button', 3/s, loud). The send now identifies footstep
sources by authored patch (FootFallInt/Ext: bank2 37-39, bank1 106/107) through
mixer->GetTargetComponent() -> AudioSource -> PatchResource LOD bank/patch
(new accessors: GetTargetComponent, GetBankID/GetPatchID,
AudioResource::PeekAudioLevelOfDetail).
Also: step intensity curve raised (speed/25, floor 0.55 -- a mech stomp is
never subtle; it was firing at ~0.4 gain and masked under 0.9-gain layers,
heard as an unrecognizable 'orchestral hit').
Verified: FootFallInt at 0.78 gain in the live tape; the ambience pulse back
to its brief authored form (absent from 1/s snapshots).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
37d4554440
commit
847b9b85cd
@@ -236,6 +236,7 @@ public:
|
||||
// broadcasts (the foot-plant intensity send) can target only volume/brightness
|
||||
// mix stages and never Start-outputting stages.
|
||||
AudioControlID GetOutputControlID() const { return outputControlID; }
|
||||
AudioComponent *GetTargetComponent() { return audioComponentSocket.GetCurrent(); }
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------
|
||||
@@ -316,6 +317,7 @@ public:
|
||||
// broadcasts (the foot-plant intensity send) can target only volume/brightness
|
||||
// mix stages and never Start-outputting stages.
|
||||
AudioControlID GetOutputControlID() const { return outputControlID; }
|
||||
AudioComponent *GetTargetComponent() { return audioComponentSocket.GetCurrent(); }
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
@@ -162,6 +162,11 @@ protected:
|
||||
AudioLevelOfDetail*
|
||||
GetAudioLevelOfDetail();
|
||||
|
||||
public:
|
||||
// (task #50) public read of the active LOD -- the game-side footstep
|
||||
// intensity send identifies footstep sources by their patch bank/id.
|
||||
AudioLevelOfDetail* PeekAudioLevelOfDetail() { return GetAudioLevelOfDetail(); }
|
||||
|
||||
private:
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
@@ -69,6 +69,11 @@ public:
|
||||
GetVoiceCount()
|
||||
{return PRESET_getNumSamples(bankID,patchID);}
|
||||
|
||||
// (task #50) expose the authored bank/patch so the game-side footstep
|
||||
// intensity send can identify footstep sources precisely.
|
||||
int GetBankID() const { return (int)bankID; }
|
||||
int GetPatchID() const { return (int)patchID; }
|
||||
|
||||
//
|
||||
//-----------------------------------------------------------------------
|
||||
// BuildFromPage
|
||||
|
||||
@@ -91,6 +91,9 @@
|
||||
|
||||
#include <bt.hpp>
|
||||
#include <AUDCMP.hpp> // AudioComponent -- the foot-plant step-intensity broadcast
|
||||
#include <AUDSRC.hpp> // AudioSource -- footstep-source identification
|
||||
#include <AUDLVL.hpp> // AudioResource::GetAudioLevelOfDetail
|
||||
#include <L4AUDLVL.hpp> // PatchLevelOfDetail -- bank/patch of the target source
|
||||
#pragma hdrstop
|
||||
|
||||
#if !defined(MECH_HPP)
|
||||
@@ -281,29 +284,53 @@ void
|
||||
// by their own scales, so the broadcast cannot durably disturb them.
|
||||
{
|
||||
Scalar speed = localVelocity.linearMotion.Length();
|
||||
Scalar intensity = speed * (1.0f / 40.0f);
|
||||
Scalar intensity = speed * (1.0f / 25.0f); // full stomp by run speed (~25 u/s)
|
||||
if (intensity > 1.0f) intensity = 1.0f;
|
||||
if (intensity < 0.35f) intensity = 0.35f; // audible floor (> the 0.3 transient drop gate)
|
||||
if (intensity < 0.55f) intensity = 0.55f; // a mech step is never subtle; floor well over the 0.3 drop gate
|
||||
int runFamily = (state >= 0x0a && state <= 0x0f); // wrr/wrl/rrr/rrl/rwr/rwl
|
||||
Entity::AudioSocketIterator it(this);
|
||||
Component *c;
|
||||
while ((c = it.ReadAndNext()) != NULL)
|
||||
{
|
||||
// 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.
|
||||
// Feed ONLY the volume/brightness mix stages WHOSE TARGET IS A
|
||||
// FOOTSTEP SOURCE. Two earlier bugs shaped this filter: a blind
|
||||
// broadcast Start-fired sounds through Start-outputting mixers, and
|
||||
// an output-only filter still cranked OTHER sounds' volume mixers
|
||||
// (the always-on ambience pulsed to full step intensity -- the
|
||||
// 'stuck button'). Identify footstep sources by their authored
|
||||
// patch: FootFallInt/Ext live at bank2 patches 37/38/39 and bank1
|
||||
// 106/107 (audiopresets.cpp, from the AUDIO1/2.RES soundfonts).
|
||||
int cid = (int)c->GetClassID();
|
||||
AudioComponent *tgt;
|
||||
AudioControlID out;
|
||||
if (cid == (int)RegisteredClass::AudioControlMixerClassID)
|
||||
{
|
||||
out = ((AudioControlMixer *)c)->GetOutputControlID();
|
||||
tgt = ((AudioControlMixer *)c)->GetTargetComponent();
|
||||
}
|
||||
else if (cid == (int)RegisteredClass::AudioControlMultiplierClassID)
|
||||
{
|
||||
out = ((AudioControlMultiplier *)c)->GetOutputControlID();
|
||||
tgt = ((AudioControlMultiplier *)c)->GetTargetComponent();
|
||||
}
|
||||
else
|
||||
continue;
|
||||
if (out != VolumeAudioControlID && out != BrightnessAudioControlID)
|
||||
continue;
|
||||
if (tgt == 0)
|
||||
continue;
|
||||
int tcid = (int)tgt->GetClassID();
|
||||
if (tcid != 1001 && tcid != 1002 && tcid != 1005) // Direct/Dyn3D/Static3D patch sources
|
||||
continue;
|
||||
PatchLevelOfDetail *lod = Cast_Object(PatchLevelOfDetail*,
|
||||
((AudioSource *)tgt)->GetAudioResource()->PeekAudioLevelOfDetail());
|
||||
if (lod == 0)
|
||||
continue;
|
||||
int b = lod->GetBankID(), pp = lod->GetPatchID();
|
||||
Logical isFootfall =
|
||||
(b == 2 && pp >= 37 && pp <= 39) || (b == 1 && (pp == 106 || pp == 107));
|
||||
if (!isFootfall)
|
||||
continue;
|
||||
AudioComponent *ac = (AudioComponent *)c;
|
||||
ac->ReceiveControl((AudioControlID)(runFamily ? 101 : 100), intensity);
|
||||
ac->ReceiveControl((AudioControlID)(runFamily ? 100 : 101), 0.0f);
|
||||
|
||||
Reference in New Issue
Block a user