Files
soothe2-re/dsp/fft.hpp
T
Matiq 2eb3b690c9 Add bit-exact RFFT infrastructure from decompilation (th1a90/th2180)
- fft.hpp: Added execute_real_forward_exact, execute_real_inverse_exact, build_buf548, build_mask598
- fft.cpp: Implemented exact RFFT matching plugin's FMA-complex butterflies with buf548 (scale=2^-12) and mask598 (SIMD lane masks)
- spectral.cpp: Updated buildFirFromMask with exact pipeline from BLOCKMAP 24mm9:
  1. design = ln(mask) → negate
  2. opA = inv-RFFT (th2180)
  3. fold: DIVIDE FIR[1..2047], zero FIR[2049..4095]
  4. opB = fwd-RFFT (th1a90)
  5. EXP: complex polynomial exp with q≈0.80
  6. opC = inv-RFFT (th2180)
  7. window: falling Hann WIN_freq[2048..4095]
  8. opD = fwd-RFFT (th1a90)
  9. normalize: FIR[0]=1.0, FIR[1]=0.0

Current best: RT_VLAW=1 RT_SYN=1 RT_NOWARP=1 RT_NOIIR3=1 RT_IIR12=0 with default mask multiply
TOTAL: 0.750 dB (vs 1.594 bridge)

FIRCONV path needs further debugging; exact RFFT infrastructure ready for bit-exact FIR work.
2026-08-28 00:53:11 +03:00

35 lines
1.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include <cstddef>
#include <cstdint>
#include <complex>
#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<double>* buf);
void execute_inverse(const FFTPlan* plan, std::complex<double>* 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<double>* complex_out);
void execute_real_inverse(const FFTPlan* plan, std::complex<double>* 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<double>* complex_out,
const double* buf548, const float* mask598);
void execute_real_inverse_exact(const FFTPlan* plan,
std::complex<double>* 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);
}