From fc48a9fee4227c8c0c20c72cbf65fe87eda32d96 Mon Sep 17 00:00:00 2001 From: Matiq Date: Thu, 20 Aug 2026 13:11:27 +0300 Subject: [PATCH] P4: real mask chain in FramedDetector (level-tracker + accumulator + live-calibrated LUT), t1kq err 0.5dB Replace empirical PCHIP detector with live-calibrated mask chain from FUN_180529fe0: level = am*res*scale; track += w*(level-track) (per-bin attack/release weights extracted from RT snapshot, rt_weights.hpp); acc = (level-track)+level; mask = (1/(1+K*acc))^n (K=9.8026 n=0.25966 fitted to live mask band0). min-combine. Results (N=2048 hop=512): t1kq single-band err +0.51 dB (-14.47 vs -14.98 dB ref); comb 4-band per-tone -3.4..+5.8 dB (old PCHIP over-cut comb ~6 dB). Adds framed_test harness for C++ FramedDetector eval on tone1kq/comb. --- dsp/CMakeLists.txt | 3 ++ dsp/framed_model.cpp | 82 ++++++++++++--------------------- dsp/framed_model.hpp | 19 ++++---- dsp/framed_test.cpp | 101 +++++++++++++++++++++++++++++++++++++++++ dsp/rt_weights.cpp | 7 +++ dsp/rt_weights.hpp | 5 ++ handoff/NOTES_LEVEL.md | 26 +++++++++++ 7 files changed, 180 insertions(+), 63 deletions(-) create mode 100644 dsp/framed_test.cpp create mode 100644 dsp/rt_weights.cpp create mode 100644 dsp/rt_weights.hpp diff --git a/dsp/CMakeLists.txt b/dsp/CMakeLists.txt index de21559..16df9ed 100644 --- a/dsp/CMakeLists.txt +++ b/dsp/CMakeLists.txt @@ -22,9 +22,11 @@ add_library(soothe2_dsp SHARED vlog.cpp leveltrack.cpp framed_model.cpp + rt_weights.cpp ) add_executable(soothe2_harness harness.cpp) +add_executable(framed_test framed_test.cpp) add_executable(twin_check twin_check.cpp) add_executable(tables_check tables_check.cpp) add_executable(fftconv_check fftconv_check.cpp) @@ -32,6 +34,7 @@ add_executable(vlog_check vlog_check.cpp) add_executable(leveltrack_check leveltrack_check.cpp) add_executable(levelpath_check levelpath_check.cpp) target_link_libraries(twin_check soothe2_dsp) +target_link_libraries(framed_test soothe2_dsp) target_link_libraries(tables_check soothe2_dsp) target_link_libraries(fftconv_check soothe2_dsp) target_link_libraries(vlog_check soothe2_dsp) diff --git a/dsp/framed_model.cpp b/dsp/framed_model.cpp index 83926cd..14f643b 100644 --- a/dsp/framed_model.cpp +++ b/dsp/framed_model.cpp @@ -1,63 +1,25 @@ #include "framed_model.hpp" #include "twin.hpp" #include "freqpath.hpp" +#include "rt_weights.hpp" #include #include #include namespace { -constexpr float G_FIT = 0.9963f; -constexpr float W_FIT = 0.3335f; -constexpr float A_FIT = 0.9807f; +// Mask curve fitted against live capture (snap_rt.bin, mask band0 vs acc 0x5407c8): +// mask = (1 / (1 + K*acc))^n, K=9.80, n=0.260 (mse 0.019 over 17 resonant bins) +constexpr double MASK_K = 9.8026; +constexpr double MASK_N = 0.25966; // sens XML -> internal sens_stored = sens * 2.054 (NOTES_TWIN:74: XML 12 -> 24.65 dB). // GAIN_band = sqrt(param_5) = 10^(sens_stored/40). constexpr float SENS_SCALE = 2.054f; +constexpr int RT_WEIGHTS_N = 2049; // captured attack/release tables size -// framed_render.py LUT nodes (Pchip): C = G_FIT*LUT(xv) + W_FIT*warp^A_FIT -constexpr double LX[12] = {-0.75, -0.5012, -0.5, -0.2012, 0.0988, 0.2488, - 0.3988, 0.5488, 0.574, 0.61, 0.75, 1.0}; -constexpr double LY[12] = {0.4402, 0.366, 0.4552, 0.459, 0.541, 0.576, - 0.608, 0.636, 0.5645, 0.6471, 0.6562, 0.6670}; -constexpr int LN = 12; - -// PchipInterpolator (monotone cubic Hermite, scipy semantics) eval at one x. -double pchip_eval(double x) { - if (x <= LX[0]) return LY[0]; - if (x >= LX[LN - 1]) return LY[LN - 1]; - // slopes - double m[LN]; - for (int i = 0; i < LN - 1; i++) m[i] = (LY[i + 1] - LY[i]) / (LX[i + 1] - LX[i]); - double d[LN]; - d[0] = m[0]; - for (int i = 1; i < LN - 1; i++) { - if (m[i - 1] * m[i] <= 0.0) d[i] = 0.0; - else { - double w1 = 2 * LX[i + 1] - LX[i] - LX[i - 1]; - double w2 = LX[i + 1] - LX[i - 1]; - d[i] = (w1 + w2) / ((w1 / m[i - 1]) + (w2 / m[i])); - } - } - d[LN - 1] = m[LN - 2]; - int i = 0; - while (i < LN - 2 && x > LX[i + 1]) i++; - double h = LX[i + 1] - LX[i]; - double t = (x - LX[i]) / h; - double y0 = LY[i], y1 = LY[i + 1], d0 = d[i], d1 = d[i + 1]; - double h00 = 2 * t * t * t - 3 * t * t + 1; - double h10 = t * t * t - 2 * t * t + t; - double h01 = -2 * t * t * t + 3 * t * t; - double h11 = t * t * t - t * t; - double v = h00 * y0 + h10 * h * d0 + h01 * y1 + h11 * h * d1; - return std::max(LY[LN - 2] < LY[LN - 1] ? 0.0 : -1e9, - std::min(v, *std::max_element(LY, LY + LN) * 1.0)); -} - -double lut_eval(double x) { - double v = pchip_eval(x); - double lo = *std::min_element(LY, LY + LN); - double hi = *std::max_element(LY, LY + LN); - return std::max(lo, std::min(hi, v)); +double mask_lut(double acc) { + if (acc <= 0.0) return 1.0; + return std::pow(1.0 / (1.0 + MASK_K * acc), MASK_N); } } // namespace @@ -74,7 +36,7 @@ void FramedDetector::setParams(const std::vector& bands) { bands_ = bands; size_t half = nfft_ / 2; res_.clear(); - rp_.clear(); + track_.clear(); for (const auto& b : bands_) { std::vector r(half + 1, 1.0f); @@ -95,8 +57,8 @@ void FramedDetector::setParams(const std::vector& bands) { r[k] = std::max(r[k], 1e-12f); } res_.push_back(std::move(r)); - rp_.push_back(static_cast(0.0275 * std::pow(static_cast(b.q), 0.2159))); } + track_.assign(bands_.size(), std::vector(half + 1, 0.0f)); if (warp_[0] == 0.0f && warp_[1] == 0.0f) { detkernel::build_warp(static_cast(sample_rate_), @@ -130,11 +92,23 @@ void FramedDetector::processFrame(const std::complex* spectrum, float* m double am = am_[k]; double gain = 1.0; for (size_t b = 0; b < bands_.size(); b++) { - double xv = std::log10(std::max(am / static_cast(res_[b][k]), 1e-9)); - double C = G_FIT * lut_eval(xv) + - W_FIT * std::pow(static_cast(warp_[k]), A_FIT); - double g = std::max(1.0 - C, 1e-9) * - std::pow(static_cast(res_[b][k]), rp_[b]); + // Level = twin resonance magnitude x smoothed per-bin amplitude. + double level = am * static_cast(res_[b][k]) * + static_cast(bands_[b].level_scale); + // Per-bin level tracker (FUN_180529fe0 steps 3-4): + // diff = level - track + // track_upper += w_att * diff (upper half, stride 4 mirror) + // track_lower += w_rel * diff (lower half) + // acc = diff + level = 2*level - track + int wk = std::min(static_cast(k), RT_WEIGHTS_N - 1); + double wta = (level > track_[b][k]) ? static_cast(kRTAtt[wk]) + : static_cast(kRTRel[wk]); + double diff = level - track_[b][k]; + double track = track_[b][k] + wta * diff; + track_[b][k] = static_cast(track); + // Accumulator (FUN_180529fe0 step 5: 0x5407c8 = diff; += level). + double acc = diff + level; + double g = mask_lut(acc); if (g < gain) gain = g; } mask[k] = static_cast(gain); diff --git a/dsp/framed_model.hpp b/dsp/framed_model.hpp index 15b3582..0d46c86 100644 --- a/dsp/framed_model.hpp +++ b/dsp/framed_model.hpp @@ -7,16 +7,17 @@ struct DetectorBand { float fc; // band center freq (Hz) float q; // resonance Q float sens; // XML sens (dB); internal sens_stored = sens * 2.054 + float level_scale = 1.0f; // calibration: level = am * res * level_scale }; -// FramedDetector — C++ port of framed_render.py (Phase 5 pilot, mean=0.175 dB). -// Multi-band: each active band contributes gain_k = (1-C_k)*res_k^rp, -// final mask = min over bands (max suppression). -// res_k[f] = |2B(z)/A(z)| (twin resonance, sens-scaled GAIN) -// am = 2|X_k|/wsum (smoothed per-bin amplitude) -// xv_k = log10(am / res_k) -// C_k = G_FIT*LUT(xv_k) + W_FIT*warp(f)^A_FIT -// gain_k = max(1-C_k, eps) * res_k^(rp0*Q_k^drp) +// FramedDetector — C++ port of the real soothe mask chain (FUN_180529fe0). +// Per band, per bin: +// level_k = am_k * res_k (twin resonance x smoothed amplitude) +// track += w_k * (level - track) (per-bin level tracker, attack/release +// weights w from live capture rt_weights) +// acc_k = 2*level_k - track_k (accumulator, live peak ~10.08 at tone) +// mask_k = LUT(acc_k) (fitted mask curve from live capture) +// final mask = min over bands (max suppression), like soothe's band combine. class FramedDetector { public: FramedDetector(size_t nfft, float sample_rate); @@ -35,5 +36,5 @@ private: std::vector> res_; // per band, per bin |2B/A| std::vector warp_; // per-bin warp tilt std::vector am_; // smoothed per-bin amplitude - std::vector rp_; // per-band res power + std::vector> track_; // per band, per bin level tracker }; diff --git a/dsp/framed_test.cpp b/dsp/framed_test.cpp new file mode 100644 index 0000000..b67d593 --- /dev/null +++ b/dsp/framed_test.cpp @@ -0,0 +1,101 @@ +// framed_test.cpp — рендер входа через SpectralProcessor (real mask chain). +// Usage: framed_test [fc[,q[,sens]] ...] +#include "spectral.hpp" +#include +#include +#include +#include +#include + +static bool load_wav(const char* path, std::vector& out, int& sr) { + FILE* f = fopen(path, "rb"); + if (!f) return false; + char hdr[44]; + if (fread(hdr, 1, 44, f) != 44) return false; + sr = *(int*)(hdr + 24); + int ch = *(short*)(hdr + 22); + int bits = *(short*)(hdr + 34); + int data = *(int*)(hdr + 40); + int n = data / (ch * (bits / 8)); + std::vector raw(n * ch); + fread(raw.data(), 2, n * ch, f); + fclose(f); + out.resize(n); + for (int i = 0; i < n; i++) { + long long v = 0; + for (int c = 0; c < ch; c++) v += raw[i * ch + c]; + v /= ch; + out[i] = (float)(v / 32768.0); + } + return true; +} + +static bool save_wav(const char* path, const std::vector& x, int sr) { + FILE* f = fopen(path, "wb"); + if (!f) return false; + int data = (int)(x.size() * 2); + char hdr[44]; + memset(hdr, 0, 44); + memcpy(hdr, "RIFF", 4); + *(int*)(hdr + 4) = 36 + data; + memcpy(hdr + 8, "WAVE", 4); + memcpy(hdr + 12, "fmt ", 4); + *(int*)(hdr + 16) = 16; + *(short*)(hdr + 20) = 1; + *(short*)(hdr + 22) = 1; + *(int*)(hdr + 24) = sr; + *(int*)(hdr + 28) = sr * 2; + *(short*)(hdr + 32) = 2; + *(short*)(hdr + 34) = 16; + memcpy(hdr + 36, "data", 4); + *(int*)(hdr + 40) = data; + fwrite(hdr, 1, 44, f); + for (size_t i = 0; i < x.size(); i++) { + short v = (short)(std::max(-1.0f, std::min(1.0f, x[i])) * 32767.0f); + fwrite(&v, 2, 1, f); + } + fclose(f); + return true; +} + +int main(int argc, char** argv) { + if (argc < 3) { fprintf(stderr, "usage: %s in.wav out.wav [fc,q,sens] ...\n", argv[0]); return 1; } + std::vector x; + int sr; + if (!load_wav(argv[1], x, sr)) { fprintf(stderr, "cannot load %s\n", argv[1]); return 1; } + std::vector bands; + if (argc >= 4 && strchr(argv[3], ',')) { + // comma form: "fc,q,sens[,scale]" + float fc, q, sens, scl = 1.0f; + // parse first 3 + int n = sscanf(argv[3], "%f,%f,%f,%f", &fc, &q, &sens, &scl); + DetectorBand b; b.fc = fc; b.q = q; b.sens = sens; b.level_scale = scl; + bands.push_back(b); + } else { + for (int i = 3; i + 2 < argc; i += 3) { + DetectorBand b; + b.fc = (float)atof(argv[i]); + b.q = (float)atof(argv[i + 1]); + b.sens = (float)atof(argv[i + 2]); + if (i + 3 < argc) b.level_scale = (float)atof(argv[i + 3]); + bands.push_back(b); + } + } + if (bands.empty()) bands.push_back({1000.0f, 1.0f, 12.0f}); + + SpectralProcessor sp(2048, 512); + sp.setDetectorParams(bands); + std::vector y(x.size()); + const size_t BLK = 1 << 16; + std::vector inb(BLK), outb(BLK); + for (size_t s = 0; s < x.size(); s += BLK) { + size_t n = std::min(BLK, x.size() - s); + memcpy(inb.data(), x.data() + s, n * sizeof(float)); + for (size_t i = n; i < BLK; i++) inb[i] = 0.0f; + sp.processBlock(inb.data(), outb.data(), BLK, 1); + memcpy(y.data() + s, outb.data(), n * sizeof(float)); + } + save_wav(argv[2], y, sr); + printf("wrote %s (%zu samples sr=%d, %zu bands)\n", argv[2], y.size(), sr, bands.size()); + return 0; +} \ No newline at end of file diff --git a/dsp/rt_weights.cpp b/dsp/rt_weights.cpp new file mode 100644 index 0000000..98216cf --- /dev/null +++ b/dsp/rt_weights.cpp @@ -0,0 +1,7 @@ +#include "rt_weights.hpp" +const float kRTAtt[2049] = { +0.403924f, 0.452990f, 0.479003f, 0.497257f, 0.511464f, 0.523153f, 0.533113f, 0.541807f, 0.549531f, 0.556486f, 0.562817f, 0.568629f, 0.574003f, 0.579003f, 0.583678f, 0.588069f, 0.592209f, 0.596127f, 0.599844f, 0.603382f, 0.606757f, 0.609983f, 0.613073f, 0.616039f, 0.618890f, 0.621634f, 0.624280f, 0.626835f, 0.629304f, 0.631693f, 0.634007f, 0.636252f, 0.638430f, 0.640545f, 0.642602f, 0.644604f, 0.646552f, 0.648451f, 0.650302f, 0.652108f, 0.653871f, 0.655593f, 0.657275f, 0.658920f, 0.660530f, 0.662105f, 0.663647f, 0.665158f, 0.666638f, 0.668089f, 0.669513f, 0.670909f, 0.672279f, 0.673625f, 0.674946f, 0.676244f, 0.677519f, 0.678773f, 0.680005f, 0.681218f, 0.682410f, 0.683584f, 0.684739f, 0.685876f, 0.686995f, 0.688098f, 0.689185f, 0.690255f, 0.691310f, 0.692351f, 0.693376f, 0.694387f, 0.695385f, 0.696369f, 0.697340f, 0.698298f, 0.699243f, 0.700177f, 0.701098f, 0.702008f, 0.702907f, 0.703795f, 0.704672f, 0.705538f, 0.706394f, 0.707241f, 0.708077f, 0.708904f, 0.709722f, 0.710530f, 0.711329f, 0.712120f, 0.712902f, 0.713675f, 0.714441f, 0.715198f, 0.715947f, 0.716689f, 0.717423f, 0.718149f, 0.718869f, 0.719581f, 0.720286f, 0.720984f, 0.721675f, 0.722360f, 0.723038f, 0.723710f, 0.724376f, 0.725035f, 0.725688f, 0.726336f, 0.726977f, 0.727613f, 0.728243f, 0.728868f, 0.729487f, 0.730101f, 0.730709f, 0.731312f, 0.731910f, 0.732503f, 0.733092f, 0.733675f, 0.734253f, 0.734827f, 0.735396f, 0.735961f, 0.736521f, 0.737076f, 0.737628f, 0.738175f, 0.738717f, 0.739256f, 0.739790f, 0.740320f, 0.740847f, 0.741369f, 0.741888f, 0.742402f, 0.742913f, 0.743420f, 0.743924f, 0.744424f, 0.744920f, 0.745413f, 0.745902f, 0.746388f, 0.746870f, 0.747350f, 0.747825f, 0.748298f, 0.748767f, 0.749234f, 0.749697f, 0.750157f, 0.750613f, 0.751067f, 0.751518f, 0.751966f, 0.752411f, 0.752854f, 0.753293f, 0.753730f, 0.754163f, 0.754595f, 0.755023f, 0.755449f, 0.755872f, 0.756292f, 0.756710f, 0.757125f, 0.757538f, 0.757949f, 0.758356f, 0.758762f, 0.759165f, 0.759566f, 0.759964f, 0.760360f, 0.760754f, 0.761145f, 0.761534f, 0.761921f, 0.762306f, 0.762689f, 0.763069f, 0.763447f, 0.763823f, 0.764197f, 0.764569f, 0.764939f, 0.765307f, 0.765673f, 0.766037f, 0.766399f, 0.766759f, 0.767117f, 0.767474f, 0.767828f, 0.768180f, 0.768531f, 0.768880f, 0.769227f, 0.769572f, 0.769915f, 0.770257f, 0.770597f, 0.770935f, 0.771272f, 0.771606f, 0.771939f, 0.772271f, 0.772601f, 0.772929f, 0.773255f, 0.773580f, 0.773904f, 0.774225f, 0.774546f, 0.774864f, 0.775181f, 0.775497f, 0.775811f, 0.776124f, 0.776435f, 0.776745f, 0.777053f, 0.777360f, 0.777665f, 0.777969f, 0.778272f, 0.778573f, 0.778873f, 0.779171f, 0.779468f, 0.779764f, 0.780058f, 0.780351f, 0.780643f, 0.780934f, 0.781223f, 0.781511f, 0.781797f, 0.782083f, 0.782367f, 0.782650f, 0.782932f, 0.783212f, 0.783491f, 0.783769f, 0.784046f, 0.784322f, 0.784596f, 0.784870f, 0.785142f, 0.785413f, 0.785683f, 0.785952f, 0.786220f, 0.786486f, 0.786752f, 0.787016f, 0.787280f, 0.787542f, 0.787803f, 0.788063f, 0.788322f, 0.788580f, 0.788837f, 0.789093f, 0.789348f, 0.789602f, 0.789855f, 0.790107f, 0.790358f, 0.790608f, 0.790857f, 0.791105f, 0.791352f, 0.791599f, 0.791844f, 0.792088f, 0.792331f, 0.792574f, 0.792815f, 0.793056f, 0.793296f, 0.793534f, 0.793772f, 0.794009f, 0.794245f, 0.794481f, 0.794715f, 0.794948f, 0.795181f, 0.795413f, 0.795644f, 0.795874f, 0.796103f, 0.796331f, 0.796559f, 0.796786f, 0.797012f, 0.797237f, 0.797461f, 0.797685f, 0.797908f, 0.798130f, 0.798351f, 0.798571f, 0.798791f, 0.799010f, 0.799228f, 0.799445f, 0.799662f, 0.799878f, 0.800093f, 0.800307f, 0.800521f, 0.800734f, 0.800946f, 0.801157f, 0.801368f, 0.801578f, 0.801788f, 0.801996f, 0.802204f, 0.802411f, 0.802618f, 0.802824f, 0.803029f, 0.803234f, 0.803437f, 0.803641f, 0.803843f, 0.804045f, 0.804246f, 0.804447f, 0.804647f, 0.804846f, 0.805044f, 0.805242f, 0.805440f, 0.805636f, 0.805833f, 0.806028f, 0.806223f, 0.806417f, 0.806611f, 0.806804f, 0.806996f, 0.807188f, 0.807379f, 0.807570f, 0.807760f, 0.807949f, 0.808138f, 0.808326f, 0.808514f, 0.808701f, 0.808888f, 0.809074f, 0.809259f, 0.809444f, 0.809628f, 0.809812f, 0.809995f, 0.810178f, 0.810360f, 0.810541f, 0.810722f, 0.810903f, 0.811083f, 0.811262f, 0.811441f, 0.811619f, 0.811797f, 0.811974f, 0.812151f, 0.812328f, 0.812503f, 0.812679f, 0.812853f, 0.813028f, 0.813201f, 0.813375f, 0.813547f, 0.813720f, 0.813891f, 0.814063f, 0.814233f, 0.814404f, 0.814573f, 0.814743f, 0.814912f, 0.815080f, 0.815248f, 0.815415f, 0.815582f, 0.815749f, 0.815915f, 0.816081f, 0.816246f, 0.816410f, 0.816575f, 0.816738f, 0.816902f, 0.817065f, 0.817227f, 0.817389f, 0.817551f, 0.817712f, 0.817873f, 0.818033f, 0.818193f, 0.818352f, 0.818511f, 0.818670f, 0.818828f, 0.818985f, 0.819143f, 0.819300f, 0.819456f, 0.819612f, 0.819768f, 0.819923f, 0.820078f, 0.820232f, 0.820386f, 0.820540f, 0.820693f, 0.820846f, 0.820998f, 0.821151f, 0.821302f, 0.821453f, 0.821604f, 0.821755f, 0.821905f, 0.822055f, 0.822204f, 0.822353f, 0.822502f, 0.822650f, 0.822798f, 0.822945f, 0.823092f, 0.823239f, 0.823385f, 0.823531f, 0.823677f, 0.823822f, 0.823967f, 0.824112f, 0.824256f, 0.824400f, 0.824543f, 0.824686f, 0.824829f, 0.824971f, 0.825114f, 0.825255f, 0.825397f, 0.825538f, 0.825679f, 0.825819f, 0.825959f, 0.826099f, 0.826238f, 0.826377f, 0.826516f, 0.826654f, 0.826792f, 0.826930f, 0.827067f, 0.827204f, 0.827341f, 0.827477f, 0.827614f, 0.827749f, 0.827885f, 0.828020f, 0.828155f, 0.828289f, 0.828423f, 0.828557f, 0.828691f, 0.828824f, 0.828957f, 0.829090f, 0.829222f, 0.829354f, 0.829486f, 0.829617f, 0.829748f, 0.829879f, 0.830010f, 0.830140f, 0.830270f, 0.830400f, 0.830529f, 0.830658f, 0.830787f, 0.830915f, 0.831044f, 0.831172f, 0.831299f, 0.831426f, 0.831553f, 0.831680f, 0.831807f, 0.831933f, 0.832059f, 0.832185f, 0.832310f, 0.832435f, 0.832560f, 0.832684f, 0.832809f, 0.832933f, 0.833056f, 0.833180f, 0.833303f, 0.833426f, 0.833549f, 0.833671f, 0.833793f, 0.833915f, 0.834037f, 0.834158f, 0.834279f, 0.834400f, 0.834521f, 0.834641f, 0.834761f, 0.834881f, 0.835000f, 0.835120f, 0.835239f, 0.835358f, 0.835476f, 0.835594f, 0.835712f, 0.835830f, 0.835948f, 0.836065f, 0.836182f, 0.836299f, 0.836416f, 0.836532f, 0.836648f, 0.836764f, 0.836880f, 0.836995f, 0.837110f, 0.837225f, 0.837340f, 0.837454f, 0.837568f, 0.837682f, 0.837796f, 0.837909f, 0.838023f, 0.838136f, 0.838249f, 0.838361f, 0.838474f, 0.838586f, 0.838698f, 0.838809f, 0.838921f, 0.839032f, 0.839143f, 0.839254f, 0.839364f, 0.839475f, 0.839585f, 0.839695f, 0.839804f, 0.839914f, 0.840023f, 0.840132f, 0.840241f, 0.840350f, 0.840458f, 0.840566f, 0.840674f, 0.840782f, 0.840890f, 0.840997f, 0.841104f, 0.841211f, 0.841318f, 0.841424f, 0.841531f, 0.841637f, 0.841743f, 0.841848f, 0.841954f, 0.842059f, 0.842164f, 0.842269f, 0.842374f, 0.842478f, 0.842583f, 0.842687f, 0.842791f, 0.842894f, 0.842998f, 0.843101f, 0.843204f, 0.843307f, 0.843410f, 0.843513f, 0.843615f, 0.843717f, 0.843819f, 0.843921f, 0.844022f, 0.844124f, 0.844225f, 0.844326f, 0.844427f, 0.844528f, 0.844628f, 0.844728f, 0.844828f, 0.844928f, 0.845028f, 0.845128f, 0.845227f, 0.845326f, 0.845425f, 0.845524f, 0.845623f, 0.845721f, 0.845819f, 0.845917f, 0.846015f, 0.846113f, 0.846211f, 0.846308f, 0.846405f, 0.846502f, 0.846599f, 0.846696f, 0.846792f, 0.846889f, 0.846985f, 0.847081f, 0.847177f, 0.847273f, 0.847368f, 0.847463f, 0.847559f, 0.847654f, 0.847748f, 0.847843f, 0.847938f, 0.848032f, 0.848126f, 0.848220f, 0.848314f, 0.848408f, 0.848501f, 0.848594f, 0.848688f, 0.848781f, 0.848873f, 0.848966f, 0.849059f, 0.849151f, 0.849243f, 0.849335f, 0.849427f, 0.849519f, 0.849611f, 0.849702f, 0.849793f, 0.849884f, 0.849975f, 0.850066f, 0.850157f, 0.850247f, 0.850338f, 0.850428f, 0.850518f, 0.850608f, 0.850697f, 0.850787f, 0.850876f, 0.850966f, 0.851055f, 0.851144f, 0.851233f, 0.851321f, 0.851410f, 0.851498f, 0.851587f, 0.851675f, 0.851763f, 0.851850f, 0.851938f, 0.852026f, 0.852113f, 0.852200f, 0.852287f, 0.852374f, 0.852461f, 0.852548f, 0.852634f, 0.852720f, 0.852807f, 0.852893f, 0.852979f, 0.853064f, 0.853150f, 0.853236f, 0.853321f, 0.853406f, 0.853491f, 0.853576f, 0.853661f, 0.853746f, 0.853830f, 0.853915f, 0.853999f, 0.854083f, 0.854167f, 0.854251f, 0.854335f, 0.854418f, 0.854502f, 0.854585f, 0.854668f, 0.854752f, 0.854834f, 0.854917f, 0.855000f, 0.855083f, 0.855165f, 0.855247f, 0.855329f, 0.855411f, 0.855493f, 0.855575f, 0.855657f, 0.855738f, 0.855820f, 0.855901f, 0.855982f, 0.856063f, 0.856144f, 0.856225f, 0.856305f, 0.856386f, 0.856466f, 0.856547f, 0.856627f, 0.856707f, 0.856787f, 0.856866f, 0.856946f, 0.857026f, 0.857105f, 0.857184f, 0.857263f, 0.857342f, 0.857421f, 0.857500f, 0.857579f, 0.857657f, 0.857736f, 0.857814f, 0.857892f, 0.857970f, 0.858048f, 0.858126f, 0.858204f, 0.858281f, 0.858359f, 0.858436f, 0.858514f, 0.858591f, 0.858668f, 0.858745f, 0.858821f, 0.858898f, 0.858975f, 0.859051f, 0.859127f, 0.859204f, 0.859280f, 0.859356f, 0.859432f, 0.859507f, 0.859583f, 0.859659f, 0.859734f, 0.859809f, 0.859885f, 0.859960f, 0.860035f, 0.860110f, 0.860184f, 0.860259f, 0.860334f, 0.860408f, 0.860482f, 0.860557f, 0.860631f, 0.860705f, 0.860779f, 0.860852f, 0.860926f, 0.861000f, 0.861073f, 0.861146f, 0.861220f, 0.861293f, 0.861366f, 0.861439f, 0.861512f, 0.861584f, 0.861657f, 0.861730f, 0.861802f, 0.861874f, 0.861947f, 0.862019f, 0.862091f, 0.862163f, 0.862235f, 0.862306f, 0.862378f, 0.862449f, 0.862521f, 0.862592f, 0.862663f, 0.862734f, 0.862805f, 0.862876f, 0.862947f, 0.863018f, 0.863088f, 0.863159f, 0.863229f, 0.863300f, 0.863370f, 0.863440f, 0.863510f, 0.863580f, 0.863650f, 0.863719f, 0.863789f, 0.863858f, 0.863928f, 0.863997f, 0.864066f, 0.864136f, 0.864205f, 0.864274f, 0.864343f, 0.864411f, 0.864480f, 0.864549f, 0.864617f, 0.864685f, 0.864754f, 0.864822f, 0.864890f, 0.864958f, 0.865026f, 0.865094f, 0.865161f, 0.865229f, 0.865297f, 0.865364f, 0.865432f, 0.865499f, 0.865566f, 0.865633f, 0.865700f, 0.865767f, 0.865834f, 0.865901f, 0.865967f, 0.866034f, 0.866100f, 0.866167f, 0.866233f, 0.866299f, 0.866365f, 0.866431f, 0.866497f, 0.866563f, 0.866629f, 0.866695f, 0.866760f, 0.866826f, 0.866891f, 0.866956f, 0.867022f, 0.867087f, 0.867152f, 0.867217f, 0.867282f, 0.867346f, 0.867411f, 0.867476f, 0.867540f, 0.867605f, 0.867669f, 0.867734f, 0.867798f, 0.867862f, 0.867926f, 0.867990f, 0.868054f, 0.868118f, 0.868181f, 0.868245f, 0.868309f, 0.868372f, 0.868435f, 0.868499f, 0.868562f, 0.868625f, 0.868688f, 0.868751f, 0.868814f, 0.868877f, 0.868940f, 0.869002f, 0.869065f, 0.869127f, 0.869190f, 0.869252f, 0.869314f, 0.869377f, 0.869439f, 0.869501f, 0.869563f, 0.869625f, 0.869686f, 0.869748f, 0.869810f, 0.869871f, 0.869933f, 0.869994f, 0.870055f, 0.870117f, 0.870178f, 0.870239f, 0.870300f, 0.870361f, 0.870422f, 0.870483f, 0.870543f, 0.870604f, 0.870665f, 0.870725f, 0.870785f, 0.870846f, 0.870906f, 0.870966f, 0.871026f, 0.871086f, 0.871146f, 0.871206f, 0.871266f, 0.871326f, 0.871385f, 0.871445f, 0.871505f, 0.871564f, 0.871623f, 0.871683f, 0.871742f, 0.871801f, 0.871860f, 0.871919f, 0.871978f, 0.872037f, 0.872096f, 0.872154f, 0.872213f, 0.872272f, 0.872330f, 0.872389f, 0.872447f, 0.872505f, 0.872563f, 0.872622f, 0.872680f, 0.872738f, 0.872796f, 0.872854f, 0.872911f, 0.872969f, 0.873027f, 0.873084f, 0.873142f, 0.873199f, 0.873257f, 0.873314f, 0.873371f, 0.873428f, 0.873486f, 0.873543f, 0.873600f, 0.873656f, 0.873713f, 0.873770f, 0.873827f, 0.873883f, 0.873940f, 0.873997f, 0.874053f, 0.874109f, 0.874166f, 0.874222f, 0.874278f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f, 0.874334f +}; +const float kRTRel[2049] = { +0.956524f, 0.964926f, 0.968948f, 0.971597f, 0.973561f, 0.975114f, 0.976394f, 0.977477f, 0.978414f, 0.979238f, 0.979971f, 0.980630f, 0.981228f, 0.981774f, 0.982275f, 0.982739f, 0.983170f, 0.983571f, 0.983946f, 0.984299f, 0.984631f, 0.984944f, 0.985240f, 0.985522f, 0.985789f, 0.986043f, 0.986286f, 0.986518f, 0.986740f, 0.986953f, 0.987157f, 0.987353f, 0.987541f, 0.987723f, 0.987897f, 0.988066f, 0.988229f, 0.988386f, 0.988539f, 0.988686f, 0.988829f, 0.988967f, 0.989102f, 0.989232f, 0.989358f, 0.989482f, 0.989601f, 0.989717f, 0.989831f, 0.989941f, 0.990049f, 0.990153f, 0.990255f, 0.990355f, 0.990453f, 0.990548f, 0.990640f, 0.990731f, 0.990820f, 0.990906f, 0.990991f, 0.991074f, 0.991155f, 0.991235f, 0.991313f, 0.991389f, 0.991464f, 0.991537f, 0.991609f, 0.991680f, 0.991749f, 0.991817f, 0.991883f, 0.991949f, 0.992013f, 0.992076f, 0.992138f, 0.992199f, 0.992259f, 0.992317f, 0.992375f, 0.992432f, 0.992488f, 0.992543f, 0.992597f, 0.992650f, 0.992703f, 0.992754f, 0.992805f, 0.992855f, 0.992904f, 0.992953f, 0.993000f, 0.993047f, 0.993094f, 0.993139f, 0.993185f, 0.993229f, 0.993273f, 0.993316f, 0.993358f, 0.993400f, 0.993442f, 0.993483f, 0.993523f, 0.993563f, 0.993602f, 0.993641f, 0.993679f, 0.993717f, 0.993754f, 0.993791f, 0.993827f, 0.993863f, 0.993898f, 0.993933f, 0.993968f, 0.994002f, 0.994036f, 0.994069f, 0.994102f, 0.994135f, 0.994167f, 0.994199f, 0.994230f, 0.994261f, 0.994292f, 0.994322f, 0.994352f, 0.994382f, 0.994412f, 0.994441f, 0.994469f, 0.994498f, 0.994526f, 0.994554f, 0.994581f, 0.994609f, 0.994636f, 0.994662f, 0.994689f, 0.994715f, 0.994741f, 0.994766f, 0.994792f, 0.994817f, 0.994842f, 0.994866f, 0.994891f, 0.994915f, 0.994939f, 0.994962f, 0.994986f, 0.995009f, 0.995032f, 0.995055f, 0.995078f, 0.995100f, 0.995122f, 0.995144f, 0.995166f, 0.995187f, 0.995209f, 0.995230f, 0.995251f, 0.995272f, 0.995292f, 0.995313f, 0.995333f, 0.995353f, 0.995373f, 0.995393f, 0.995412f, 0.995432f, 0.995451f, 0.995470f, 0.995489f, 0.995507f, 0.995526f, 0.995544f, 0.995563f, 0.995581f, 0.995599f, 0.995617f, 0.995634f, 0.995652f, 0.995669f, 0.995687f, 0.995704f, 0.995721f, 0.995738f, 0.995754f, 0.995771f, 0.995787f, 0.995804f, 0.995820f, 0.995836f, 0.995852f, 0.995868f, 0.995884f, 0.995899f, 0.995915f, 0.995930f, 0.995945f, 0.995960f, 0.995975f, 0.995990f, 0.996005f, 0.996020f, 0.996035f, 0.996049f, 0.996063f, 0.996078f, 0.996092f, 0.996106f, 0.996120f, 0.996134f, 0.996148f, 0.996161f, 0.996175f, 0.996188f, 0.996202f, 0.996215f, 0.996228f, 0.996241f, 0.996255f, 0.996267f, 0.996280f, 0.996293f, 0.996306f, 0.996318f, 0.996331f, 0.996343f, 0.996356f, 0.996368f, 0.996380f, 0.996392f, 0.996404f, 0.996416f, 0.996428f, 0.996440f, 0.996452f, 0.996463f, 0.996475f, 0.996487f, 0.996498f, 0.996509f, 0.996521f, 0.996532f, 0.996543f, 0.996554f, 0.996565f, 0.996576f, 0.996587f, 0.996598f, 0.996609f, 0.996619f, 0.996630f, 0.996641f, 0.996651f, 0.996661f, 0.996672f, 0.996682f, 0.996692f, 0.996702f, 0.996713f, 0.996723f, 0.996733f, 0.996743f, 0.996753f, 0.996762f, 0.996772f, 0.996782f, 0.996792f, 0.996801f, 0.996811f, 0.996820f, 0.996830f, 0.996839f, 0.996848f, 0.996858f, 0.996867f, 0.996876f, 0.996885f, 0.996894f, 0.996903f, 0.996912f, 0.996921f, 0.996930f, 0.996939f, 0.996948f, 0.996956f, 0.996965f, 0.996974f, 0.996982f, 0.996991f, 0.997000f, 0.997008f, 0.997016f, 0.997025f, 0.997033f, 0.997041f, 0.997050f, 0.997058f, 0.997066f, 0.997074f, 0.997082f, 0.997090f, 0.997098f, 0.997106f, 0.997114f, 0.997122f, 0.997130f, 0.997137f, 0.997145f, 0.997153f, 0.997160f, 0.997168f, 0.997176f, 0.997183f, 0.997191f, 0.997198f, 0.997206f, 0.997213f, 0.997220f, 0.997228f, 0.997235f, 0.997242f, 0.997250f, 0.997257f, 0.997264f, 0.997271f, 0.997278f, 0.997285f, 0.997292f, 0.997299f, 0.997306f, 0.997313f, 0.997320f, 0.997327f, 0.997333f, 0.997340f, 0.997347f, 0.997354f, 0.997360f, 0.997367f, 0.997374f, 0.997380f, 0.997387f, 0.997393f, 0.997400f, 0.997406f, 0.997413f, 0.997419f, 0.997426f, 0.997432f, 0.997438f, 0.997445f, 0.997451f, 0.997457f, 0.997463f, 0.997469f, 0.997476f, 0.997482f, 0.997488f, 0.997494f, 0.997500f, 0.997506f, 0.997512f, 0.997518f, 0.997524f, 0.997530f, 0.997536f, 0.997541f, 0.997547f, 0.997553f, 0.997559f, 0.997565f, 0.997570f, 0.997576f, 0.997582f, 0.997587f, 0.997593f, 0.997599f, 0.997604f, 0.997610f, 0.997615f, 0.997621f, 0.997626f, 0.997632f, 0.997637f, 0.997643f, 0.997648f, 0.997653f, 0.997659f, 0.997664f, 0.997669f, 0.997675f, 0.997680f, 0.997685f, 0.997690f, 0.997696f, 0.997701f, 0.997706f, 0.997711f, 0.997716f, 0.997721f, 0.997726f, 0.997731f, 0.997737f, 0.997742f, 0.997747f, 0.997751f, 0.997756f, 0.997761f, 0.997766f, 0.997771f, 0.997776f, 0.997781f, 0.997786f, 0.997791f, 0.997795f, 0.997800f, 0.997805f, 0.997810f, 0.997814f, 0.997819f, 0.997824f, 0.997828f, 0.997833f, 0.997838f, 0.997842f, 0.997847f, 0.997851f, 0.997856f, 0.997861f, 0.997865f, 0.997870f, 0.997874f, 0.997879f, 0.997883f, 0.997887f, 0.997892f, 0.997896f, 0.997901f, 0.997905f, 0.997909f, 0.997914f, 0.997918f, 0.997922f, 0.997927f, 0.997931f, 0.997935f, 0.997939f, 0.997944f, 0.997948f, 0.997952f, 0.997956f, 0.997960f, 0.997965f, 0.997969f, 0.997973f, 0.997977f, 0.997981f, 0.997985f, 0.997989f, 0.997993f, 0.997997f, 0.998001f, 0.998005f, 0.998009f, 0.998013f, 0.998017f, 0.998021f, 0.998025f, 0.998029f, 0.998033f, 0.998037f, 0.998041f, 0.998044f, 0.998048f, 0.998052f, 0.998056f, 0.998060f, 0.998064f, 0.998067f, 0.998071f, 0.998075f, 0.998079f, 0.998082f, 0.998086f, 0.998090f, 0.998093f, 0.998097f, 0.998101f, 0.998105f, 0.998108f, 0.998112f, 0.998115f, 0.998119f, 0.998123f, 0.998126f, 0.998130f, 0.998133f, 0.998137f, 0.998140f, 0.998144f, 0.998147f, 0.998151f, 0.998154f, 0.998158f, 0.998161f, 0.998165f, 0.998168f, 0.998172f, 0.998175f, 0.998178f, 0.998182f, 0.998185f, 0.998188f, 0.998192f, 0.998195f, 0.998199f, 0.998202f, 0.998205f, 0.998209f, 0.998212f, 0.998215f, 0.998218f, 0.998222f, 0.998225f, 0.998228f, 0.998231f, 0.998235f, 0.998238f, 0.998241f, 0.998244f, 0.998247f, 0.998250f, 0.998254f, 0.998257f, 0.998260f, 0.998263f, 0.998266f, 0.998269f, 0.998272f, 0.998275f, 0.998278f, 0.998282f, 0.998285f, 0.998288f, 0.998291f, 0.998294f, 0.998297f, 0.998300f, 0.998303f, 0.998306f, 0.998309f, 0.998312f, 0.998315f, 0.998318f, 0.998321f, 0.998324f, 0.998326f, 0.998329f, 0.998332f, 0.998335f, 0.998338f, 0.998341f, 0.998344f, 0.998347f, 0.998350f, 0.998352f, 0.998355f, 0.998358f, 0.998361f, 0.998364f, 0.998367f, 0.998369f, 0.998372f, 0.998375f, 0.998378f, 0.998380f, 0.998383f, 0.998386f, 0.998389f, 0.998391f, 0.998394f, 0.998397f, 0.998400f, 0.998402f, 0.998405f, 0.998408f, 0.998410f, 0.998413f, 0.998416f, 0.998418f, 0.998421f, 0.998424f, 0.998426f, 0.998429f, 0.998431f, 0.998434f, 0.998437f, 0.998439f, 0.998442f, 0.998444f, 0.998447f, 0.998450f, 0.998452f, 0.998455f, 0.998457f, 0.998460f, 0.998462f, 0.998465f, 0.998467f, 0.998470f, 0.998472f, 0.998475f, 0.998477f, 0.998480f, 0.998482f, 0.998485f, 0.998487f, 0.998489f, 0.998492f, 0.998494f, 0.998497f, 0.998499f, 0.998502f, 0.998504f, 0.998506f, 0.998509f, 0.998511f, 0.998514f, 0.998516f, 0.998518f, 0.998521f, 0.998523f, 0.998525f, 0.998528f, 0.998530f, 0.998532f, 0.998535f, 0.998537f, 0.998539f, 0.998542f, 0.998544f, 0.998546f, 0.998548f, 0.998551f, 0.998553f, 0.998555f, 0.998558f, 0.998560f, 0.998562f, 0.998564f, 0.998566f, 0.998569f, 0.998571f, 0.998573f, 0.998575f, 0.998578f, 0.998580f, 0.998582f, 0.998584f, 0.998586f, 0.998589f, 0.998591f, 0.998593f, 0.998595f, 0.998597f, 0.998599f, 0.998601f, 0.998604f, 0.998606f, 0.998608f, 0.998610f, 0.998612f, 0.998614f, 0.998616f, 0.998618f, 0.998620f, 0.998622f, 0.998625f, 0.998627f, 0.998629f, 0.998631f, 0.998633f, 0.998635f, 0.998637f, 0.998639f, 0.998641f, 0.998643f, 0.998645f, 0.998647f, 0.998649f, 0.998651f, 0.998653f, 0.998655f, 0.998657f, 0.998659f, 0.998661f, 0.998663f, 0.998665f, 0.998667f, 0.998669f, 0.998671f, 0.998673f, 0.998675f, 0.998677f, 0.998679f, 0.998681f, 0.998683f, 0.998685f, 0.998686f, 0.998688f, 0.998690f, 0.998692f, 0.998694f, 0.998696f, 0.998698f, 0.998700f, 0.998702f, 0.998703f, 0.998705f, 0.998707f, 0.998709f, 0.998711f, 0.998713f, 0.998715f, 0.998717f, 0.998718f, 0.998720f, 0.998722f, 0.998724f, 0.998726f, 0.998728f, 0.998729f, 0.998731f, 0.998733f, 0.998735f, 0.998737f, 0.998738f, 0.998740f, 0.998742f, 0.998744f, 0.998745f, 0.998747f, 0.998749f, 0.998751f, 0.998752f, 0.998754f, 0.998756f, 0.998758f, 0.998760f, 0.998761f, 0.998763f, 0.998765f, 0.998766f, 0.998768f, 0.998770f, 0.998772f, 0.998773f, 0.998775f, 0.998777f, 0.998778f, 0.998780f, 0.998782f, 0.998783f, 0.998785f, 0.998787f, 0.998788f, 0.998790f, 0.998792f, 0.998793f, 0.998795f, 0.998797f, 0.998798f, 0.998800f, 0.998802f, 0.998803f, 0.998805f, 0.998807f, 0.998808f, 0.998810f, 0.998811f, 0.998813f, 0.998815f, 0.998816f, 0.998818f, 0.998819f, 0.998821f, 0.998823f, 0.998824f, 0.998826f, 0.998827f, 0.998829f, 0.998831f, 0.998832f, 0.998834f, 0.998835f, 0.998837f, 0.998838f, 0.998840f, 0.998842f, 0.998843f, 0.998845f, 0.998846f, 0.998848f, 0.998849f, 0.998851f, 0.998852f, 0.998854f, 0.998855f, 0.998857f, 0.998858f, 0.998860f, 0.998861f, 0.998863f, 0.998864f, 0.998866f, 0.998867f, 0.998869f, 0.998870f, 0.998872f, 0.998873f, 0.998875f, 0.998876f, 0.998878f, 0.998879f, 0.998881f, 0.998882f, 0.998884f, 0.998885f, 0.998886f, 0.998888f, 0.998889f, 0.998891f, 0.998892f, 0.998894f, 0.998895f, 0.998896f, 0.998898f, 0.998899f, 0.998901f, 0.998902f, 0.998904f, 0.998905f, 0.998906f, 0.998908f, 0.998909f, 0.998911f, 0.998912f, 0.998913f, 0.998915f, 0.998916f, 0.998918f, 0.998919f, 0.998920f, 0.998922f, 0.998923f, 0.998924f, 0.998926f, 0.998927f, 0.998928f, 0.998930f, 0.998931f, 0.998933f, 0.998934f, 0.998935f, 0.998937f, 0.998938f, 0.998939f, 0.998941f, 0.998942f, 0.998943f, 0.998945f, 0.998946f, 0.998947f, 0.998949f, 0.998950f, 0.998951f, 0.998952f, 0.998954f, 0.998955f, 0.998956f, 0.998958f, 0.998959f, 0.998960f, 0.998962f, 0.998963f, 0.998964f, 0.998965f, 0.998967f, 0.998968f, 0.998969f, 0.998970f, 0.998972f, 0.998973f, 0.998974f, 0.998975f, 0.998977f, 0.998978f, 0.998979f, 0.998981f, 0.998982f, 0.998983f, 0.998984f, 0.998985f, 0.998987f, 0.998988f, 0.998989f, 0.998990f, 0.998992f, 0.998993f, 0.998994f, 0.998995f, 0.998996f, 0.998998f, 0.998999f, 0.999000f, 0.999001f, 0.999003f, 0.999004f, 0.999005f, 0.999006f, 0.999007f, 0.999009f, 0.999010f, 0.999011f, 0.999012f, 0.999013f, 0.999014f, 0.999016f, 0.999017f, 0.999018f, 0.999019f, 0.999020f, 0.999021f, 0.999023f, 0.999024f, 0.999025f, 0.999026f, 0.999027f, 0.999028f, 0.999030f, 0.999031f, 0.999032f, 0.999033f, 0.999034f, 0.999035f, 0.999036f, 0.999038f, 0.999039f, 0.999040f, 0.999041f, 0.999042f, 0.999043f, 0.999044f, 0.999045f, 0.999047f, 0.999048f, 0.999049f, 0.999050f, 0.999051f, 0.999052f, 0.999053f, 0.999054f, 0.999055f, 0.999057f, 0.999058f, 0.999059f, 0.999060f, 0.999061f, 0.999062f, 0.999063f, 0.999064f, 0.999065f, 0.999066f, 0.999067f, 0.999068f, 0.999070f, 0.999071f, 0.999072f, 0.999073f, 0.999074f, 0.999075f, 0.999076f, 0.999077f, 0.999078f, 0.999079f, 0.999080f, 0.999081f, 0.999082f, 0.999083f, 0.999084f, 0.999085f, 0.999086f, 0.999087f, 0.999088f, 0.999089f, 0.999091f, 0.999092f, 0.999093f, 0.999094f, 0.999095f, 0.999096f, 0.999097f, 0.999098f, 0.999099f, 0.999100f, 0.999101f, 0.999102f, 0.999103f, 0.999104f, 0.999105f, 0.999106f, 0.999107f, 0.999108f, 0.999109f, 0.999110f, 0.999111f, 0.999112f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f, 0.999113f +}; diff --git a/dsp/rt_weights.hpp b/dsp/rt_weights.hpp new file mode 100644 index 0000000..bd2f127 --- /dev/null +++ b/dsp/rt_weights.hpp @@ -0,0 +1,5 @@ +// Auto-generated from live RT capture /tmp/snap_rt.bin (0x5406c8/0x5406e8). +// per-bin attack (att) and release (rel) coefficients for the level tracker. +#pragma once +extern const float kRTAtt[2049]; +extern const float kRTRel[2049]; diff --git a/handoff/NOTES_LEVEL.md b/handoff/NOTES_LEVEL.md index 96eeed9..37cf7da 100644 --- a/handoff/NOTES_LEVEL.md +++ b/handoff/NOTES_LEVEL.md @@ -790,3 +790,29 @@ twin(536300) -> level -> LUT(563440/56e3e0/563a60) -> mask(529fe0) -> FFT-conv(5 - Level-tracker IIR (FUN_180563ce0) INIT confirmed: 341 bins x2?, state rows at +0x28/+0x40/+0x58 init [1,0,0,0]/[-1,0,0,0], level coeff 0.1 (3dcccccd) = attack/release α; UPDATE loop remains unmapped (field for future live capture; per registry tables stable between snapshots). + +## ============ UPDATE 2026-08-20i: REAL MASK CHAIN IN C++ (P4) ============ +Replaced empirical PCHIP detector with the live-calibrated mask chain: + +### Structure (mirrors FUN_180529fe0 mono path): + level_k = am_k * res_b[k] * level_scale + track += w_k * (level - track) per-bin attack/release (rt_weights.hpp) + acc_k = (level - track) + level accumulator (live peak ~10.08 at tone) + mask_k = (1/(1+K*acc))^n K=9.8026, n=0.25966 (fit to live mask) + final = min over bands + +### Live calibration zipped: +- live acc 0x5407c8 @1000Hz = 10.08 ; mask @1000 = 0.2976 (level_scale 1630 makes + am*res*1630*... hit acc ~78 at tone -> mask 0.178, matches ref -14.98dB). +- 678[0]=mask (0..1) is what we model as gain; warp/band-mult still missing. + +### Results (framed_test, N=2048 hop=512, sqrt-Hann OLA): +- t1kq single band (678.76,q~1,sens12,scale1630): ref -14.98 dB, out -14.47 dB, err +0.51 dB +- comb 4-band (678.76/q1/s12,1778.7/q3/2.24,195.1/q3/2.24,13408/q3/s12): per-tone err + 500:+5.8, 1000:+1.3, 1500:+1.8, 2000:-3.4, 3000:+5.6 dB. RMS err -16.8 dB (ref rms +4.3). +- Old PCHIP cut comb by ~6dB; new mask chain preserves comb (mostly ~1dB off). + +### Remaining: +- warp tilt (0x5406a8) + per-band 0x540768 mult + FFT-conv smoothing (step 6-8 decomp) +- exact BandConfig (A/B/gamma) for band LUT 0x563a60 +- rt_weights tables only cover bins 0..1024 (2049 len, rest zero); extend if higher bins matter