Program Listing for File fft.hpp¶
↰ Return to documentation for file (ear/fft.hpp)
#pragma once
#include <complex>
#include <memory>
namespace ear {
/// \file
/// Interface for performing c2r and r2c FFTs with pluggable implementations.
/// temporary buffers needed to perform an FFT; allocated by calling
/// FFTPlan::alloc_workbuf.
///
/// As this contains data which is mutated by the transform functions, this
/// must not be shared between threads.
class FFTWorkBuf {
public:
virtual ~FFTWorkBuf() = 0;
};
inline FFTWorkBuf::~FFTWorkBuf() {}
/// Plan for performing an FFT of a particular size/layout/type; allocated by
/// calling FFTImpl::plan
///
/// This is not mutated when transform_* are called, so one plan may be shared
/// between threads.
template <typename Real>
class FFTPlan {
public:
using Complex = std::complex<Real>;
/// Execute an r2c forwards transform.
/// \param input n_fft input samples
/// \param output n_fft/2+1 output samples containing the first half of the
/// complex frequency components without any packing.
/// \param workbuf temporary buffers allocated with alloc_workbuf
virtual void transform_forward(Real *input, Complex *output,
FFTWorkBuf &workbuf) const = 0;
/// Execute an c2r inverse transform.
/// \param input n_fft/2+1 input samples, in the same format as given by
/// transform_forward
/// \param output n_fft output samples
/// \param workbuf temporary buffers allocated with alloc_workbuf
virtual void transform_reverse(Complex *input, Real *output,
FFTWorkBuf &workbuf) const = 0;
/// allocate temporary buffers to be used with transform_*
virtual std::unique_ptr<FFTWorkBuf> alloc_workbuf() const = 0;
virtual ~FFTPlan() {}
};
/// An FFT implementation.
template <typename Real>
class FFTImpl {
public:
/// Plan to execute an r2c/c2r FFT using this implementation.
/// \param n_fft number of points in the real parts; i.e. the input to
/// transform_forward and the output of transform_reverse. Must be even.
virtual std::shared_ptr<FFTPlan<Real>> plan(size_t n_fft) const = 0;
virtual ~FFTImpl() {}
};
/// Get a KISS FFT implementation for a particular type. This is always
/// available.
template <typename Real>
FFTImpl<Real> &get_fft_kiss();
} // namespace ear