34 static_assert(std::is_floating_point_v<SampleType>);
43 [[nodiscard]]
bool prepare(
double sample_rate,
45 if (!std::isfinite(sample_rate) || !(sample_rate > 0.0) ||
46 !std::isfinite(max_length_seconds) ||
51 const auto requested = std::ceil(sample_rate * max_length_seconds);
53 requested >=
static_cast<double>(std::numeric_limits<std::size_t>::max()))
56 const auto maximum_delay =
static_cast<std::size_t
>(requested);
59 if (!new_right_going.
prepare(maximum_delay) || !new_left_going.
prepare(maximum_delay))
62 right_going_ = std::move(new_right_going);
63 left_going_ = std::move(new_left_going);
64 sample_rate_ = sample_rate;
65 maximum_length_samples_ =
static_cast<double>(maximum_delay);
68 length_.set_immediate(target_length_samples_);
69 length_configured_ =
false;
75 if (!prepared_ || !std::isfinite(
static_cast<double>(length)))
78 maximum_length_samples_);
79 if (!length_configured_) {
80 length_.set_immediate(target_length_samples_);
81 length_configured_ =
true;
83 length_.set_target(target_length_samples_);
88 return static_cast<SampleType
>(target_length_samples_);
94 return static_cast<SampleType
>(prepared_ ? length_.current()
95 : target_length_samples_);
99 return prepared_ ? 2.0 * length_.current() / sample_rate_ : 0.0;
102 [[nodiscard]]
bool prepared() const noexcept {
return prepared_; }
110 void read_outputs(SampleType& left_out, SampleType& right_out)
const noexcept {
111 left_out = SampleType{};
112 right_out = SampleType{};
116 const auto delay = length_.current();
117 const auto at_right = right_going_.read_lagrange5_at(
delay);
118 const auto at_left = left_going_.read_lagrange5_at(
delay);
120 right_out = finite_cast(at_right.sample);
122 left_out = finite_cast(at_left.sample);
126 void push_inputs(SampleType left_in, SampleType right_in)
noexcept {
129 (void)right_going_.push(
static_cast<double>(left_in));
130 (void)left_going_.push(
static_cast<double>(right_in));
131 (void)length_.next();
139 void process(SampleType left_in, SampleType right_in, SampleType& left_out,
140 SampleType& right_out)
noexcept {
146 right_going_.reset();
148 length_.set_immediate(target_length_samples_);
152 return right_going_.retained_bytes() + left_going_.retained_bytes();
156 [[nodiscard]]
static SampleType finite_cast(
double value)
noexcept {
157 const auto limit =
static_cast<double>(std::numeric_limits<SampleType>::max());
158 if (!std::isfinite(value) || value > limit || value < -limit)
160 return static_cast<SampleType
>(value);
163 FractionalDelayHistoryT<double> right_going_{};
164 FractionalDelayHistoryT<double> left_going_{};
166 double sample_rate_ = 0.0;
167 double maximum_length_samples_ = 0.0;
169 bool length_configured_ =
false;
170 bool prepared_ =
false;
Prepared history shared by any number of stateless Lagrange read heads.
Definition fractional_delay.hpp:161
bool prepare(std::size_t maximum_delay_samples)
Definition fractional_delay.hpp:179
A passive bidirectional waveguide segment.
Definition waveguide_line.hpp:33
static constexpr double minimum_max_length_seconds
Definition waveguide_line.hpp:38
void set_length_samples(SampleType length) noexcept
Definition waveguide_line.hpp:74
bool prepared() const noexcept
Definition waveguide_line.hpp:102
void push_inputs(SampleType left_in, SampleType right_in) noexcept
Injects both boundary results and advances the retuning glide once.
Definition waveguide_line.hpp:126
void process(SampleType left_in, SampleType right_in, SampleType &left_out, SampleType &right_out) noexcept
Convenience step for feed-forward use: read, then push.
Definition waveguide_line.hpp:139
static constexpr double minimum_length_samples
Definition waveguide_line.hpp:37
static constexpr double maximum_max_length_seconds
Definition waveguide_line.hpp:39
bool prepare(double sample_rate, double max_length_seconds=default_max_length_seconds)
Definition waveguide_line.hpp:43
SampleType current_length_samples() const noexcept
Returns the delay head used by the next sample.
Definition waveguide_line.hpp:93
void reset() noexcept
Definition waveguide_line.hpp:145
static constexpr double default_max_length_seconds
Definition waveguide_line.hpp:40
static constexpr double retune_seconds
Definition waveguide_line.hpp:41
SampleType length_samples() const noexcept
Definition waveguide_line.hpp:87
std::size_t retained_bytes() const noexcept
Definition waveguide_line.hpp:151
double round_trip_seconds() const noexcept
Definition waveguide_line.hpp:98
void read_outputs(SampleType &left_out, SampleType &right_out) const noexcept
Reads both boundary arrivals without advancing either rail.
Definition waveguide_line.hpp:110
Prepared fractional-delay storage with Thiran-1 and Lagrange-3/5 reads.
Definition additive_bank.hpp:218
WaveguideLineT< float > WaveguideLine
Definition waveguide_line.hpp:173
@ delay
Definition envelope.hpp:57
WaveguideLineT< double > WaveguideLine64
Definition waveguide_line.hpp:174