P4: lock PRNG prologue + correct constants (DAT_*=1); scale via prng_fvar30
CRITICAL fix: soothe_mem.bin is VA-linear (offset=RVA). DAT_18262b5c8/b704/b700 are INT 1 (cvtdq2ps -> 1.0), NOT the 0.4552/0.6089/0.6070 read earlier via a bad section offset. Transcribed FUN_180529fe0 PRNG prologue into prng_fvar30(): fVar30=(int)(LUT[s+1]*LUT[s]+0.001). At live state 112 this is deterministically 1.0 over 300 frames, so scale level *= (1/2048)*440.95 is not randomized in practice. Scale coefficient now computed structurally; t1kq unchanged -0.43 dB.
This commit is contained in:
+36
-1
@@ -33,6 +33,37 @@ void iir_leaky(const double* A, const double* B, float* x, int n) {
|
||||
}
|
||||
}
|
||||
|
||||
// FUN_180529fe0 PRNG prologue (:515-583). LCG state advances by round offsets;
|
||||
// fVar30 (scale coeff) = (int)(LUT[s+1]*LUT[s]+0.001). CONSTANTS b5c8/b704/b700
|
||||
// resolve to 1 (VA-linear dump; the earlier 0.4552/0.6089/0.6070 came from a bad
|
||||
// file offset). Live state 112 => fVar30 == 1.0 deterministically over 300 frames.
|
||||
// Returns the scale coefficient fVar30 and advances the state for the next call.
|
||||
double prng_fvar30(int& state) {
|
||||
constexpr unsigned M = 0x8000007f;
|
||||
unsigned s = static_cast<unsigned>(state & 0xffffffff);
|
||||
auto fix = [](unsigned x) {
|
||||
x &= M;
|
||||
if (x & 0x80000000u) x = ((x - 1) | 0xffffff80u) + 1;
|
||||
return x;
|
||||
};
|
||||
s = fix(s + 0x3cdca); // line 515
|
||||
unsigned s0 = s;
|
||||
s = fix(s + 0x140236); // line 526 (s1 for iVar20 second term)
|
||||
s = fix(s + 0x10d56); // line 538 (s2 -> iVar19)
|
||||
s = fix(s + 0xdf6b6); // line 549 (s3 -> fVar30)
|
||||
unsigned s3 = s;
|
||||
(void)s0;
|
||||
// fVar30 line554 = (int)(f32(f32(LUT[s3+1])*f32(LUT[s3])) + 0.001f)
|
||||
int lu = static_cast<int>(s3 & 0x7f);
|
||||
float a = static_cast<float>(kPRNGLut[lu]);
|
||||
float b = static_cast<float>(kPRNGLut[(lu + 1) & 0x7f]);
|
||||
float prod = a * b + 0.001f;
|
||||
int fv = static_cast<int>(prod); // cvttss2si truncation
|
||||
state = static_cast<int>(s3);
|
||||
if (fv < 1) fv = 1; // guard (observed always >=1)
|
||||
return static_cast<double>(fv);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
FramedDetector::FramedDetector(size_t nfft, float sample_rate)
|
||||
@@ -93,6 +124,9 @@ void FramedDetector::processFrame(const std::complex<double>* spectrum, float* m
|
||||
am_[k] = static_cast<float>(am);
|
||||
}
|
||||
|
||||
// PRNG prologue: advance state once per frame; fVar30 -> scale coefficient.
|
||||
double fVar30 = prng_fvar30(prng_state_);
|
||||
|
||||
// Per-band mask chain (FUN_180529fe0 mono path, 0x5408b8==0).
|
||||
// 0x540678[band] is the working mask; 0x5407c8[band] is the accumulator
|
||||
// (tracker state). Transcribed per decomp /tmp/consumers_out.txt:638-1111.
|
||||
@@ -105,7 +139,8 @@ void FramedDetector::processFrame(const std::complex<double>* spectrum, float* m
|
||||
for (size_t k = 0; k <= half; k++) {
|
||||
double level = am_[k] * static_cast<double>(res_[b][k]) *
|
||||
static_cast<double>(bands_[b].level_scale);
|
||||
scratch[k] = static_cast<float>(level * C_0x540870 * C_0x54088c / C_0x1a0);
|
||||
scratch[k] = static_cast<float>(level * (fVar30 / C_0x1a0) *
|
||||
C_0x540870 * C_0x54088c);
|
||||
}
|
||||
int n = static_cast<int>(half) + 1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user