chain: wire IIR4 generator (RT_IIR4_GEN) + add chain smoke test
- iir4_bidir: env-gated generate_iir4_coefs (C/tau/p/mult/sr) vs proxy kIIR - fix exp sign: up=exp(-c*g*tau/mult) → down=1-up in 0..1 (was Inf) - fn529fe0_check: chain_9_19 smoke + generate_iir4 smoke (down0=1 up0=0 ok) - Gates: bridge 1.594, structural 2.689 (RT_CASC=0) unchanged
This commit is contained in:
+29
-6
@@ -196,13 +196,35 @@ void cascade_detect(
|
||||
|
||||
static inline void iir4_bidir_340510(float* x, size_t nbin) {
|
||||
// BLOCKMAP:52af09 IIR4×2 bidir log-domain base 0x340510
|
||||
// Uses DOUBLE precision (movsd/mulsd in disasm)
|
||||
// Coefficients from FUN_180533340 generator (frequency-dependent warp)
|
||||
// For now, use kIIR_A1/B1 as proxy (structure is correct)
|
||||
// Uses DOUBLE precision (movsd/mulsd/cvtpd2ps in disasm 1191-1201)
|
||||
// When RT_IIR4_GEN=1, generate via FUN_180533340 (freq-warp g=fc_norm/i|pow), else use proxy kIIR_A1/B1
|
||||
static std::vector<double> genDown, genUp;
|
||||
static int genN = 0;
|
||||
const double* A1;
|
||||
const double* B1;
|
||||
const double* A2;
|
||||
const double* B2;
|
||||
static const int useGen = getenv("RT_IIR4_GEN") ? atoi(getenv("RT_IIR4_GEN")) : 0;
|
||||
if (useGen) {
|
||||
if ((int)nbin != genN) {
|
||||
genDown.assign(nbin, 0.0); genUp.assign(nbin, 0.0);
|
||||
double C = getenv("RT_IIR4_C") ? atof(getenv("RT_IIR4_C")) : 1000.0;
|
||||
double tau = getenv("RT_IIR4_TAU") ? atof(getenv("RT_IIR4_TAU")) : 1200.0;
|
||||
double p = getenv("RT_IIR4_P") ? atof(getenv("RT_IIR4_P")) : 0.5;
|
||||
double mult = getenv("RT_IIR4_MULT") ? atof(getenv("RT_IIR4_MULT")) : 360.0;
|
||||
double sr = getenv("RT_IIR4_SR") ? atof(getenv("RT_IIR4_SR")) : 48000.0;
|
||||
generate_iir4_coefs(genDown.data(), genUp.data(), (int)nbin, C, tau, sr, p, mult);
|
||||
genN = (int)nbin;
|
||||
}
|
||||
// down=1-up, so A=down, B=up
|
||||
A1 = genDown.data(); B1 = genUp.data();
|
||||
A2 = genDown.data(); B2 = genUp.data();
|
||||
} else {
|
||||
extern const double kIIR_A1[]; extern const double kIIR_B1[];
|
||||
extern const double kIIR_A2[]; extern const double kIIR_B2[];
|
||||
const double* A1 = ::kIIR_A1; const double* B1 = ::kIIR_B1;
|
||||
const double* A2 = ::kIIR_A2; const double* B2 = ::kIIR_B2;
|
||||
A1 = ::kIIR_A1; B1 = ::kIIR_B1;
|
||||
A2 = ::kIIR_A2; B2 = ::kIIR_B2;
|
||||
}
|
||||
double acc = 0.0;
|
||||
for (size_t i = 0; i < nbin; i++) { double y = A1[i]*acc + B1[i]*x[i]; acc = y; x[i] = static_cast<float>(y); }
|
||||
acc = 0.0;
|
||||
@@ -223,7 +245,8 @@ void generate_iir4_coefs(double* downCoef, double* upCoef,
|
||||
for (int i = 1; i < n; i++) {
|
||||
double g = (i <= fc_norm) ? (fc_norm / i) : std::pow(fc_norm / i, p);
|
||||
double c = 1.0 / (g * tau / mult + 1.0);
|
||||
upCoef[i] = std::exp(c * g * tau * exp_scale);
|
||||
// state[2] ≈ mult per BLOCKMAP, so normalize: exp(-c*g*tau/state2) → 0..1
|
||||
upCoef[i] = std::exp(-c * g * tau / mult * exp_scale);
|
||||
downCoef[i] = 1.0 - upCoef[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,6 +195,26 @@ int main() {
|
||||
if (!ok) fail = 1;
|
||||
}
|
||||
|
||||
// --- chain_9_19: gated pipeline smoke (LOG#1→DIVIDE→dc40→FMA→EXP-1→*track→*warp→LOG#2→IIR4→FIR→EXP#2) ---
|
||||
{
|
||||
std::vector<float> bands(nbin, 0.5f), tmp(nbin, 0.1f), acc(nbin, 0.0f);
|
||||
std::vector<float> warp(nbin, 1.0f), att(nbin, 0.0f), rel(nbin, 0.0f);
|
||||
std::vector<float> bands0 = bands;
|
||||
fn529fe0::chain_9_19(bands.data(), tmp.data(), acc.data(), nullptr, warp.data(), att.data(), rel.data(), nbin);
|
||||
bool ok = true;
|
||||
for (size_t i = 0; i < nbin; i++) if (!std::isfinite(bands[i]) || bands[i] < 0.0f || bands[i] > 5.0f) ok = false;
|
||||
std::printf("chain_9_19 smoke: in0=%.3f out0=%.3f outmid=%.3f finite=%d (%s)\n",
|
||||
bands0[0], bands[0], bands[nbin/2], ok, ok ? "OK" : "MISMATCH");
|
||||
if (!ok) fail = 1;
|
||||
// IIR4 generator smoke
|
||||
std::vector<double> down(nbin), up(nbin);
|
||||
fn529fe0::generate_iir4_coefs(down.data(), up.data(), (int)nbin, 1000.0, 1200.0, 48000.0, 0.5, 360.0);
|
||||
bool gok = std::fabs(down[0]-1.0)<1e-9 && std::fabs(up[0])<1e-9 && down[1] < 1.0 && down[1] > 0.0;
|
||||
std::printf("generate_iir4: down0=%.3f up0=%.3f down1=%.4f up1=%.4f (%s)\n",
|
||||
down[0], up[0], down[1], up[1], gok ? "OK" : "MISMATCH");
|
||||
if (!gok) fail = 1;
|
||||
}
|
||||
|
||||
std::printf("fn529fe0 check %s\n", fail ? "FAIL" : "PASS");
|
||||
return fail;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user