feat(dsp): structural FUN_180529fe0 chain components + fn529fe0_check (step 1, module 1)
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include "fn529fe0.hpp"
|
||||
#include "rt_mask_tables.hpp"
|
||||
#include "rt_weights.hpp"
|
||||
|
||||
// Modular black-box check for the structural FUN_180529fe0 chain components
|
||||
// (BITEXACT_PLAN step 1). Validates invariants against the live tables:
|
||||
// - kIIR_A1/B1 : B == 1 - A, and IIR1 smooths a step input monotonically
|
||||
// - blend_exp2 : out == exp2(-x)*blend, blend = freqaxis*(1-mix)+mix*0.8
|
||||
// - combine_acc: subtract then add band/f6f8 contributions (exact)
|
||||
// - warp_mask : multiplies by kBand768*kWarp
|
||||
int main() {
|
||||
const size_t nbin = 2049; // internal N/2+1 grid used by the chain
|
||||
const size_t nfft = 4096;
|
||||
int fail = 0;
|
||||
|
||||
// --- IIR tables: B1 == 1 - A1 ---
|
||||
double maxB = 0.0;
|
||||
for (size_t i = 0; i < nbin; i++)
|
||||
maxB = std::fmax(maxB, std::fabs(kIIR_B1[i] - (1.0 - kIIR_A1[i])));
|
||||
std::printf("IIR: max|B1-(1-A1)| = %.3e (%s)\n", maxB, maxB < 1e-12 ? "OK" : "MISMATCH");
|
||||
if (maxB >= 1e-12) fail = 1;
|
||||
|
||||
// --- IIR1 smooths a step input monotonically ---
|
||||
std::vector<float> x(nbin);
|
||||
std::vector<double> acc1(nbin);
|
||||
for (size_t i = 0; i < nbin; i++) x[i] = (i < 100 ? 0.0f : 1.0f);
|
||||
std::vector<float> orig = x;
|
||||
fn529fe0::iir1(x.data(), kIIR_A1, kIIR_B1, nbin, 0.0);
|
||||
bool monotonic = true;
|
||||
for (size_t i = 1; i < nbin; i++)
|
||||
if (x[i] < x[i - 1] - 1e-6) { monotonic = false; break; }
|
||||
std::printf("IIR1 step: monotonic=%d x[0]=%.3f x[mid]=%.3f x[last]=%.3f\n",
|
||||
monotonic, x[0], x[nbin/2], x[nbin-1]);
|
||||
if (!monotonic || std::fabs(x[0] - 0.0f) > 1e-3) fail = 1;
|
||||
|
||||
// --- blend_exp2 correctness ---
|
||||
std::vector<float> mask(nbin), lvl(nbin), freq(nbin);
|
||||
for (size_t i = 0; i < nbin; i++) { lvl[i] = 0.5f * (1.0f + float(i) / nbin); freq[i] = 1.0f; }
|
||||
const float mix = 1.0f;
|
||||
fn529fe0::blend_exp2(mask.data(), lvl.data(), freq.data(), mix, nbin);
|
||||
double max_e = 0.0;
|
||||
for (size_t i = 0; i < nbin; i++) {
|
||||
double expect = std::exp2(-(double)lvl[i]) * 0.8;
|
||||
max_e = std::fmax(max_e, std::fabs(mask[i] - expect));
|
||||
}
|
||||
std::printf("blend_exp2: max|out-exp2(-x)*0.8| = %.3e (%s)\n",
|
||||
max_e, max_e < 1e-6 ? "OK" : "MISMATCH");
|
||||
if (max_e >= 1e-6) fail = 1;
|
||||
|
||||
// --- combine_acc: acc = band-f6f8 + wAtt*f6f8 + wRel*f6f8 + band.
|
||||
// With band=1, f6f8=0, weights=0: acc = band - 0 + 0 + 0 + band = 2 everywhere. ---
|
||||
std::vector<double> acc(nfft, 0.0);
|
||||
std::vector<float> band(nbin, 1.0f), f6f8(nbin, 0.0f), wA(nbin, 0.0f), wR(nbin, 0.0f);
|
||||
fn529fe0::combine_acc(acc.data(), band.data(), f6f8.data(), wA.data(), wR.data(), nfft);
|
||||
double max_c = 0.0;
|
||||
for (size_t i = 0; i < nfft; i++) max_c = std::fmax(max_c, std::fabs(acc[i] - 2.0));
|
||||
std::printf("combine: acc=2 for band=1,f6f8=0,w=0 max|d|=%.3e (%s)\n",
|
||||
max_c, max_c < 1e-12 ? "OK" : "MISMATCH");
|
||||
if (max_c >= 1e-12) fail = 1;
|
||||
|
||||
// --- warp_mask applies kBand768*kWarp ---
|
||||
std::vector<float> w(nbin);
|
||||
for (size_t i = 0; i < nbin; i++) w[i] = 1.0f;
|
||||
const float* k768 = kBand768; // band0 table (per-band in real path)
|
||||
fn529fe0::warp_mask(w.data(), k768, kWarp, nbin);
|
||||
double max_w = 0.0;
|
||||
for (size_t i = 0; i < nbin; i++)
|
||||
max_w = std::fmax(max_w, std::fabs(w[i] - k768[i] * kWarp[i]));
|
||||
std::printf("warp: mask==kBand768*kWarp max|d|=%.3e (%s)\n",
|
||||
max_w, max_w < 1e-6 ? "OK" : "MISMATCH");
|
||||
if (max_w >= 1e-6) fail = 1;
|
||||
|
||||
// --- live table ranges ---
|
||||
std::printf("live: kWarp[0]=%.3f kWarp[2048]=%.3f kBand768[0]=%.3f kBand768[2048]=%.3f\n",
|
||||
kWarp[0], kWarp[2048], k768[0], k768[2048]);
|
||||
|
||||
std::printf("fn529fe0 check %s\n", fail ? "FAIL" : "PASS");
|
||||
return fail;
|
||||
}
|
||||
Reference in New Issue
Block a user