#pragma once #include #include #include #include "fft_plan.hpp" namespace fft { void init_plan(FFTPlan* plan, uint32_t log2N); void build_twiddle(FFTPlan* plan, double* scratch); void execute(const FFTPlan* plan, std::complex* buf); void execute_inverse(const FFTPlan* plan, std::complex* buf); // Real RFFT: N real → N/2+1 complex (forward) // N/2+1 complex → N real (inverse) void execute_real_forward(const FFTPlan* plan, double* real_in, std::complex* complex_out); void execute_real_inverse(const FFTPlan* plan, std::complex* complex_in, double* real_out); // Bit-exact RFFT matching plugin's th1a90/th2180 (FMA-complex with buf548/mask598) // plan: FFTPlan with log2N=12 (N=4096) // buf548: cos/sin table (size N, 2*double per entry: cos, sin), scale=2^-12 // mask598: SIMD lane masks (size N/4 float: 8×1.0, 8×0.0 periodic) void execute_real_forward_exact(const FFTPlan* plan, double* real_in, std::complex* complex_out, const double* buf548, const float* mask598); void execute_real_inverse_exact(const FFTPlan* plan, std::complex* complex_in, double* real_out, const double* buf548, const float* mask598); // Build plugin's exact buf548 and mask598 tables void build_buf548(double* buf548, uint32_t N); void build_mask598(float* mask598, uint32_t N); }