Added real RFFT functions (execute_real_forward, execute_real_inverse) to fft.hpp/cpp. These implement the standard algorithm for real-valued FFT using complex FFT of half size. Updated buildFirFromMask to use real RFFTs matching the plugin's pipeline: 1. log(mask) → negate 2. forward real RFFT (opB) 3. EXP in-place 4. inverse real RFFT (opC) 5. Window 6. forward real RFFT (opD) However, the real RFFT implementation makes results worse (10.377 dB vs 1.825 dB default). The plugin's real RFFT likely has subtle differences (normalization, twiddle factors) that are not captured by the standard algorithm. The default path (no FIRCONV) remains the best approach with 1.825 dB TOTAL error. Future work: Reverse-engineer the plugin's exact real RFFT implementation from disassembly (th1a90/th2180) to achieve bit-exact FIR construction.
20 lines
634 B
C++
20 lines
634 B
C++
#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);
|
|
|
|
}
|