32 std::expected<RealType, std::string> besselI0(
const RealType x)
38 return std::unexpected(
"Modified Bessel approximation only valid for x > 0");
45 t * (3.5156229 + t * (3.0899424 + t * (1.2067492 + t * (0.2659732 + t * (0.0360768 + t * 0.0045813)))));
57 t * (-0.02057706 + t * (0.02635537 + t * (-0.01647633 + t * 0.00392377)))))));
58 return i0 * std::exp(x) / std::sqrt(x);
72 if (x < 0 || x > _alpha * 2)
76 auto bessel = besselI0(_beta * std::sqrt(1 - std::pow((x - _alpha) / _alpha, 2)));
79 return *bessel / _bessel_beta;
82 return std::unexpected(bessel.error());
87 auto kaiser = kaiserWinCompute(x + _alpha);
90 return *kaiser * sinc(x);
93 return std::unexpected(kaiser.error());
96 InterpFilter::InterpFilter()
99 _table_filters = 1000;
100 _filter_table = std::vector<RealType>(_table_filters * _length);
102 _alpha = std::floor(
static_cast<RealType>(_length) / 2.0);
103 if (
auto bessel = besselI0(_beta); bessel)
105 _bessel_beta = *bessel;
109 LOG(Level::FATAL,
"Bessel function calculation failed: {}", bessel.error());
110 throw std::runtime_error(
"Bessel function calculation failed");
113 const auto hfilt =
static_cast<std::ptrdiff_t
>(_table_filters / 2);
114 const auto alpha_offset =
static_cast<std::ptrdiff_t
>(_alpha);
116 LOG(Level::DEBUG,
"Building table of {} filters", _table_filters);
118 for (std::ptrdiff_t i = -hfilt; i < hfilt; ++i)
121 for (std::ptrdiff_t j = -alpha_offset; j < alpha_offset; ++j)
125 const auto filter_index =
126 static_cast<std::size_t
>(i + hfilt) * _length +
static_cast<std::size_t
>(j + alpha_offset);
127 _filter_table[filter_index] = *
interp;
131 LOG(Level::FATAL,
"Interpolation filter calculation failed: {}",
interp.error());
132 throw std::runtime_error(
"Interpolation filter calculation failed");
137 LOG(Level::DEBUG,
"Filter table complete");
142 if (delay < -1 || delay > 1)
144 LOG(Level::FATAL,
"Requested delay filter value out of range: {}", delay);
145 throw std::runtime_error(
"Requested delay filter value out of range");
149 std::min(
static_cast<std::size_t
>((delay + 1.0) * (
static_cast<RealType>(_table_filters) / 2.0)),
151 return std::span{_filter_table.data() + filt * _length, _length};
Provides methods to generate interpolation filters using Kaiser windows.
static InterpFilter & getInstance() noexcept
Retrieves the singleton instance of the InterpFilter class.
std::span< const RealType > getFilter(RealType delay) const
Retrieves a span of precomputed filter values for a given delay.
std::expected< RealType, std::string > kaiserWinCompute(RealType x) const noexcept
Computes the Kaiser window function for a given input.
std::expected< RealType, std::string > interpFilter(RealType x) const noexcept
Computes the interpolation filter value for a given input.
double RealType
Type for real numbers.
Interpolation filter implementation using Kaiser windowing.
Header file for the logging system.
unsigned renderFilterLength() noexcept
Get the render filter length.
Defines the Parameters struct and provides methods for managing simulation parameters.