diff --git a/engine/MUNGA/AUDCMP.cpp b/engine/MUNGA/AUDCMP.cpp index 9c2c3b9..6f2db9c 100644 --- a/engine/MUNGA/AUDCMP.cpp +++ b/engine/MUNGA/AUDCMP.cpp @@ -1,4 +1,5 @@ #include +#include // (BT411) the 28Hz smoother-intake clock (cadence census item 3) #include "munga.h" #pragma hdrstop @@ -958,7 +959,54 @@ void if (control_ID == controlID) { - audioControlAverage.Add(control_value); + // (BT411 cadence census item 3, gotcha 32) SAMPLE INTAKE AT 28 Hz: + // the authored olympic windows (N=30/15, fill 0) are SIZED for one + // sample per POD frame (28 Hz -- AUDWTHR.h:457); the port's watcher + // poll feeds one per RENDER frame (~59), which halves the smoothing + // window in wall time and feeds a noisier operand. Clock ONLY the + // Add (the smoother's own intake) on a per-instance 28 Hz wall + // clock; the forward below still runs EVERY poll with the held + // average, so downstream watcher semantics are untouched. During a + // hitch the pod would have taken ~28 samples/s of the stalled + // value -- catch-up repeats the current sample, capped at the + // largest authored window (30), heat.cpp #119 pattern. + // BT_AUD_SMOOTH_HZ= overrides (=0 restores per-poll intake). + { + static Scalar s_hz = -2.0f; + if (s_hz < -1.0f) + { + const char *hz = getenv("BT_AUD_SMOOTH_HZ"); + s_hz = (hz != 0 && *hz != '\0') ? (Scalar)atof(hz) : 28.0f; + } + if (s_hz > 0.0f) + { + static std::map s_nextMs; + const DWORD now = GetTickCount(); + const DWORD tick = (DWORD)(1000.0f / s_hz); // 35 ms at 28 + DWORD &next = s_nextMs[this]; + if (next == 0) + { + audioControlAverage.Add(control_value); + next = now + tick; + } + else if ((long)(now - next) >= 0) + { + int added = 0; + while ((long)(now - next) >= 0 && ++added <= 30) + { + audioControlAverage.Add(control_value); + next += tick; + } + if ((long)(now - next) >= 0) + next = now + tick; // hitch: resync + } + // else: off-tick poll -- hold; the average is forwarded below + } + else + { + audioControlAverage.Add(control_value); // legacy per-poll + } + } if (getenv("BT_AUDIO_SPATIAL")) { static int s_sa=0; if ((controlID == 100 || controlID == 101) && s_sa++ < 3000)