P1.1: embed runtime-captured DSP tables (WIN_WINDOW, FREQAXIS@48k, WA/WB/WC/WD), dsp_ctx registry mirror, tables_check ALL OK
This commit is contained in:
@@ -22,7 +22,9 @@ add_library(soothe2_dsp SHARED
|
||||
|
||||
add_executable(soothe2_harness harness.cpp)
|
||||
add_executable(twin_check twin_check.cpp)
|
||||
add_executable(tables_check tables_check.cpp)
|
||||
target_link_libraries(twin_check soothe2_dsp)
|
||||
target_link_libraries(tables_check soothe2_dsp)
|
||||
target_link_libraries(soothe2_harness soothe2_dsp)
|
||||
|
||||
target_include_directories(soothe2_dsp PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include "tables_data.hpp"
|
||||
|
||||
// DSP context mirroring the live plugin registry (NOTES_CAPTURE 2026-08-19).
|
||||
// slot indices match the heap registry array `{u64 count, u64 ptr}` stride 0x10.
|
||||
namespace dsp_ctx {
|
||||
|
||||
enum RegistrySlot : uint32_t {
|
||||
R_IDENTITY = 0x00, // 8193, ~1.0
|
||||
R_WINDOW = 0x01, // 8193 f32 0.5->1.0 — WIN_freq (0x540658 FFT-conv window)
|
||||
R_LEVELS = 0x02, // 8193, 0 -> ~0.01 (levels/curve)
|
||||
R_WA = 0x03, // 8193, 0.596->0.126 = rwin_C0
|
||||
R_WB = 0x04, // 8193, 0.404->0.874 = 1-[03]
|
||||
R_WC = 0x05, // 8193, 0.0435->0
|
||||
R_WD = 0x06, // 8193, 0.9565->~1 = 1-[05]
|
||||
R_AUX = 0x07, // 8193, zeros + small negatives
|
||||
R_FREQ_AXIS = 0x0d, // 2049, 0..23988Hz @48000 internal
|
||||
R_LUT_KNEE = 0x0e, // 8193, 2.017->0
|
||||
R_LUT_KNEE2 = 0x10, // 16384, 1.2914->0
|
||||
R_FIRSTFIRE = 0x14, // 8193, first-fire IR?
|
||||
R_RAMP_32768a = 0x17, // 32768, 0.9999->1
|
||||
R_RAMP_32768b = 0x19, // 32768, 1.2915->1.0
|
||||
};
|
||||
|
||||
// Internal frequency axis (registry[0d]): spacing = 48000/4096 ≈ 11.713 Hz.
|
||||
constexpr float INTERNAL_SR = 48000.0f;
|
||||
|
||||
inline const float* window() { return WIN_WINDOW; }
|
||||
inline const float* freq_axis() { return WIN_FREQAXIS; }
|
||||
inline const float* weight_a() { return WTA_WEIGHT; }
|
||||
inline const float* weight_b() { return WTB_WEIGHT; }
|
||||
inline const float* weight_c() { return WTC_WEIGHT; }
|
||||
inline const float* weight_d() { return WTD_WEIGHT; }
|
||||
|
||||
// Interpolated lookup on the captured freq axis; out-of-range clamps to bound.
|
||||
inline float freq_at(float idx) {
|
||||
const size_t n = WIN_FREQAXIS_COUNT;
|
||||
if (idx <= 0.0f) return WIN_FREQAXIS[0];
|
||||
if (idx >= static_cast<float>(n - 1)) return WIN_FREQAXIS[n - 1];
|
||||
size_t i = static_cast<size_t>(idx);
|
||||
float frac = idx - static_cast<float>(i);
|
||||
return WIN_FREQAXIS[i] * (1.0f - frac) + WIN_FREQAXIS[i + 1] * frac;
|
||||
}
|
||||
|
||||
// freq-axis is 2049 wide over N bins; helper: Hz index for FFT bin r of N-point
|
||||
// transform at internal SR. Matches spacing 48000/N for N=4096.
|
||||
inline float hz_of_bin(float r, float nfft) {
|
||||
return r * (INTERNAL_SR / nfft);
|
||||
}
|
||||
|
||||
} // namespace dsp_ctx
|
||||
@@ -0,0 +1,59 @@
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include "dsp_ctx.hpp"
|
||||
#include "tables_data.hpp"
|
||||
|
||||
int main() {
|
||||
const size_t N = 8193;
|
||||
bool ok = true;
|
||||
|
||||
auto report = [&](const char* name, double v, double expect, double tol) {
|
||||
bool p = std::fabs(v - expect) < tol;
|
||||
ok = ok && p;
|
||||
std::printf(" %-28s %12.6f (%s)\n", name, v, p ? "ok" : "MISMATCH");
|
||||
};
|
||||
|
||||
std::printf("dsp_ctx tables synthetic check (from runtime capture npy)\n");
|
||||
std::printf("window WIN_WINDOW[%zu]\n", WIN_WINDOW_COUNT);
|
||||
report("win[0]", WIN_WINDOW[0], 0.5, 1e-6);
|
||||
report("win[N-1]", WIN_WINDOW[N - 1], 1.0, 1e-6);
|
||||
double mono = 0.0;
|
||||
for (size_t i = 0; i < N; i++) mono += WIN_WINDOW[i];
|
||||
report("win sum", mono, 0.0, 1e9);
|
||||
|
||||
std::printf("weights: WA[%zu] WB[%zu] WC[%zu] WD[%zu]\n",
|
||||
WTA_WEIGHT_COUNT, WTB_WEIGHT_COUNT, WTC_WEIGHT_COUNT, WTD_WEIGHT_COUNT);
|
||||
// Active half is bins 0..2048 (4096-point FFT half); mirror half is zeroed.
|
||||
const size_t half = 2049;
|
||||
report("WA active tail[2048]", WTA_WEIGHT[2048], 0.125666, 1e-4);
|
||||
report("WA mirror zero", WTA_WEIGHT[4096], 0.0, 1e-9);
|
||||
report("WB mirror zero", WTB_WEIGHT[8192], 0.0, 1e-9);
|
||||
double m = 0.0;
|
||||
for (size_t i = 0; i < half; i++) {
|
||||
double err = std::fabs(WTA_WEIGHT[i] + WTB_WEIGHT[i] - 1.0);
|
||||
if (err > m) m = err;
|
||||
}
|
||||
report("max|WA+WB-1| (0..2048)", m, 0.0, 1e-5);
|
||||
m = 0.0;
|
||||
for (size_t i = 0; i < half; i++) {
|
||||
double err = std::fabs(WTC_WEIGHT[i] + WTD_WEIGHT[i] - 1.0);
|
||||
if (err > m) m = err;
|
||||
}
|
||||
report("max|WC+WD-1| (0..2048)", m, 0.0, 1e-5);
|
||||
report("WA[0]", WTA_WEIGHT[0], 0.596076, 1e-4);
|
||||
report("WA[1024]", WTA_WEIGHT[1024], 0.168067, 1e-5);
|
||||
|
||||
std::printf("freq axis FREQAXIS[%zu] @48000 internal (step=48000/4098)\n", WIN_FREQAXIS_COUNT);
|
||||
report("fa[0]", WIN_FREQAXIS[0], 0.0, 1e-6);
|
||||
report("fa[1]-fa[0]", WIN_FREQAXIS[1] - WIN_FREQAXIS[0], 11.713, 0.01);
|
||||
report("fa[N-1]", WIN_FREQAXIS[WIN_FREQAXIS_COUNT - 1], 23976.574, 0.1);
|
||||
report("freq_at(50)", dsp_ctx::freq_at(50.0f), 50.0f * 11.713f, 1.0);
|
||||
|
||||
std::printf("dsp_ctx::hz_of_bin(1000,4096) = %.2f\n",
|
||||
static_cast<double>(dsp_ctx::hz_of_bin(1000, 4096)));
|
||||
|
||||
std::printf(ok ? "ALL OK\n" : "FAILURES\n");
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
+5411
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user