13#include "../FIRFilter.h"
14#include "ContinuousClip.h"
15#include "ContinuousStereoColor.h"
16#include "ConvolutionRate.h"
17#include "RetimedDcBlock.h"
30 std::array<double, 64> dry_{}, pad_{};
31 int delay_, padding_, latency_, dryWrite_ = 0, padWrite_ = 0;
34 [[nodiscard]]
static int latencyFor(
int factor,
int sourceFactor)
noexcept
38 return 256 + 2 * 64 + (delay + factor - 1) / factor;
40 [[nodiscard]]
static std::size_t
allocationBound(
int factor,
int sourceFactor)
noexcept
42 const std::size_t order = factor <= 2 ? 18 : 10, taps = 2 * order + 1;
43 const auto construction = (6 * (order + 1) + (order + 2) * taps) *
sizeof(
double);
44 const auto filter = taps * (
sizeof(std::atomic<double>) + 4 *
sizeof(
double)) +
sizeof(
int);
50 : rate_(factor, {256, 64, 18.5, .475},
false), dc_(factor, sourceFactor),
51 delay_(7 + (factor <= 2 ? 18 : 10)),
52 padding_((factor - (delay_ + dc_.
latency()) % factor) % factor),
53 latency_(rate_.
latency() + (delay_ + dc_.
latency() + padding_) / factor)
57 eq_.
prepare(
static_cast<int>(coefficients.size()), 1);
62 [[nodiscard]]
int latency() const noexcept
75 dryWrite_ = padWrite_ = 0;
80 auto high = rate_.upsample(input);
81 auto *values = high.getChannel(0);
82 for (
int i = 0; i < high.getNumSamples(); ++i)
84 const double sample = values[i];
86 result += dry_[dryWrite_];
87 dry_[dryWrite_] = sample;
88 dryWrite_ = (dryWrite_ + 1) % delay_;
92 const double old = pad_[padWrite_];
93 pad_[padWrite_] = result;
94 padWrite_ = (padWrite_ + 1) % padding_;
99 rate_.downsample(input);
106 std::unique_ptr<ContinuousStereoColor<C>> continuous_;
107 std::unique_ptr<OversampledStereoColor<C>> oversampled_;
110 [[nodiscard]]
static int latencyFor(
int factor,
int sourceFactor)
noexcept
115 [[nodiscard]]
static std::size_t
allocationBound(
int factor,
int sourceFactor)
noexcept
124 continuous_ = std::make_unique<ContinuousStereoColor<C>>(sourceFactor);
126 oversampled_ = std::make_unique<OversampledStereoColor<C>>(factor, sourceFactor);
130 return continuous_ ? continuous_->latency() : oversampled_->latency();
134 if (continuous_) continuous_->reset();
135 else oversampled_->reset();
139 if (continuous_) continuous_->process(input);
140 else oversampled_->process(input);
Non-owning view over audio channel data.
FIR filter using direct-form convolution with a mirrored delay line.
void reset() noexcept
Resets all delay lines to zero, clearing the filter's memory.
void prepare(int maxTaps, int numChannels)
Pre-allocates memory and initializes the delay lines.
T processSample(T input, int channel) noexcept
Processes a single sample through the FIR filter.
void setCoefficients(std::span< const T > coeffs) noexcept
Sets the filter coefficients asynchronously.
static constexpr int latency() noexcept
static std::size_t allocationBound(int factor, Settings settings, bool withReference) noexcept
OversampledStereoColor(int factor, int sourceFactor)
static int latencyFor(int factor, int sourceFactor) noexcept
static std::size_t allocationBound(int factor, int sourceFactor) noexcept
int latency() const noexcept
void process(AudioBufferView< double > input) noexcept
double process(double x) noexcept
static std::size_t allocationBound(int factor, int sourceFactor) noexcept
static int filterLength(int factor, int sourceFactor) noexcept
static std::size_t allocationBound(int factor, int sourceFactor) noexcept
void process(AudioBufferView< double > input) noexcept
int latency() const noexcept
static int latencyFor(int factor, int sourceFactor) noexcept
StereoColor(int factor, int sourceFactor)
Streaming cubic B-spline moments of a reconstructed clipping residual.
double process(double x) noexcept
Processes one high-rate sample, returning its integrated residual.
void reset(double ceiling) noexcept
Resets reconstruction history and sets the positive finite ceiling.
std::vector< double > inverseBoxPower(int order)