cadence census item 4: doppler velocity operand sample-and-held at 28Hz (gotcha 32) [T2 mechanism / T3 perceptual]. worldLinearVelocity is a raw per-render-frame position derivative; at ~59fps its gait-aliasing noise reached the doppler divisor directly. Fix is consumer-side only per the census: the relative WORLD velocity held per AudioLocation on a 28Hz wall clock; head-frame transform + geometry stay live per call; the mech4 producer untouched. BT_AUD_DOPPLER_HZ override (=0 per-call) + [doppler] receipt under BT_AUD_DOPPLER_LOG (cents/v/d/h/hm2). Measured: clock proven live (55% of calls held vs 0% in control), operand total-variation 67.8 -> 54.2 u/s-per-s (-20%) with std preserved (real stride oscillation kept). T3 flag: cents jitter only -11% on the solo rig because the loud sources ride the player's own entity at d~1 where live near-field geometry dominates -- the nearby-walking-mech warble needs an ear A/B or a 2-node rig. Bonus finding (pre-existing, receipt-exposed, NOT touched): sources linked to child entities of a moving mech read relative v = full ground speed (child worldLinearVelocity=0) -> cents ~ -200 on self-sounds; new census row.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016bw71WVsccjwW7uKRg4aWD
This commit is contained in:
co-authored by
Claude Fable 5
parent
b355844847
commit
f9546d254f
@@ -1,3 +1,5 @@
|
||||
#include <cstdlib> // (BT411) getenv -- the 28Hz doppler-operand clock (cadence census item 4)
|
||||
#include <map> // (BT411) per-instance sample-and-hold registry
|
||||
#include "munga.h"
|
||||
#pragma hdrstop
|
||||
|
||||
@@ -442,6 +444,45 @@ void
|
||||
);
|
||||
Check(&relative_velocity_temp);
|
||||
|
||||
//
|
||||
// (BT411 cadence census item 4, gotcha 32) 28 Hz SAMPLE-AND-HOLD on the
|
||||
// doppler velocity operand: worldLinearVelocity is a raw per-render-frame
|
||||
// position derivative (the mech4 producer feeds other consumers and is
|
||||
// NOT touched); at ~59 fps its gait-aliasing noise reaches this divisor
|
||||
// directly and warbles dopplerCents per stride. The pod computed this
|
||||
// once per 28 Hz frame. Hold the RELATIVE WORLD velocity per instance
|
||||
// on a 28 Hz wall clock; the head-frame transform below stays live per
|
||||
// call (geometry is smooth -- only the noisy operand is clocked).
|
||||
// BT_AUD_DOPPLER_HZ=<hz> overrides (=0 restores per-call sampling).
|
||||
//
|
||||
int dopplerFresh = -1; // receipt: -1 legacy / 1 sampled / 0 held
|
||||
{
|
||||
static Scalar s_dopHz = -2.0f;
|
||||
if (s_dopHz < -1.0f)
|
||||
{
|
||||
const char *hz = getenv("BT_AUD_DOPPLER_HZ");
|
||||
s_dopHz = (hz != 0 && *hz != '\0') ? (Scalar)atof(hz) : 28.0f;
|
||||
}
|
||||
if (s_dopHz > 0.0f)
|
||||
{
|
||||
struct DopplerHold { DWORD nextMs; Vector3D held; };
|
||||
static std::map<const void *, DopplerHold> s_dopHold;
|
||||
DopplerHold &h = s_dopHold[this];
|
||||
const DWORD now = GetTickCount();
|
||||
if (h.nextMs == 0 || (long)(now - h.nextMs) >= 0)
|
||||
{
|
||||
h.held = relative_velocity_temp;
|
||||
h.nextMs = now + (DWORD)(1000.0f / s_dopHz);
|
||||
dopplerFresh = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
relative_velocity_temp = h.held;
|
||||
dopplerFresh = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
relative_velocity.MultiplyByInverse(
|
||||
relative_velocity_temp,
|
||||
head_entity->localToWorld
|
||||
@@ -473,6 +514,19 @@ void
|
||||
{
|
||||
dopplerCents = cents;
|
||||
}
|
||||
|
||||
// (BT411) doppler receipt -- jitter A/B for the 28Hz operand clock.
|
||||
// hm2 = |held relative WORLD velocity|^2 (the clocked operand itself,
|
||||
// geometry-free); h = 1 fresh sample / 0 held / -1 legacy per-call.
|
||||
if (getenv("BT_AUD_DOPPLER_LOG")) { static int s_dl = 0; if (s_dl++ < 6000)
|
||||
DEBUG_STREAM << "[doppler] t=" << (GetTickCount() % 1000000)
|
||||
<< " this=" << (void *)this
|
||||
<< " cents=" << dopplerCents
|
||||
<< " v=" << speed_of_source
|
||||
<< " d=" << distanceToSource
|
||||
<< " h=" << dopplerFresh
|
||||
<< " hm2=" << relative_velocity_temp.LengthSquared()
|
||||
<< "\n" << std::flush; }
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user