31 constexpr explicit operator bool() const noexcept {
51 double beats_per_minute,
52 double sample_rate)
noexcept {
56 if (!std::isfinite(sample_rate) || !(sample_rate > 0.0) ||
63 const auto value = fraction.value();
64 if (value.numerator <= 0 || value.denominator <= 0)
67 const long double samples =
68 static_cast<long double>(value.numerator) * 60.0L *
static_cast<long double>(sample_rate) /
69 (
static_cast<long double>(value.denominator) *
static_cast<long double>(beats_per_minute));
70 constexpr long double maximum =
static_cast<long double>(std::numeric_limits<int>::max() - 1);
71 if (!std::isfinite(samples) || samples < 1.0L || samples >
maximum)
103 constexpr double maximum =
static_cast<double>(std::numeric_limits<int>::max() - 1);
111 transition_samples_ = transition_samples;
116 initialized_ =
false;
126 if (!std::isfinite(samples))
128 if (samples < 1.0 || samples > maximum_delay_samples_)
130 set_valid_target(samples);
137 double beats_per_minute)
noexcept {
146 [[nodiscard]]
double next() noexcept {
151 const std::uint32_t elapsed = transition_samples_ - remaining_ + 1U;
152 const double amount =
153 static_cast<double>(elapsed) /
static_cast<double>(transition_samples_);
154 current_ = start_ + (target_ - start_) * amount;
156 if (remaining_ == 0) {
163 void render(
double* output, std::size_t sample_count)
noexcept {
164 if (output ==
nullptr)
166 for (std::size_t
i = 0;
i < sample_count; ++
i)
171 if (!prepared_ || !initialized_)
185 return remaining_ != 0;
194 return maximum_delay_samples_;
197 return prepared_ ? current_ : 0.0;
200 return prepared_ ? target_ : 0.0;
203 return prepared_ ? std::max({start_, current_, target_}) : 0.0;
213 void set_valid_target(
double samples)
noexcept {
222 if (samples == target_)
224 if (samples == current_) {
232 remaining_ = transition_samples_;
233 if (remaining_ == 0) {
239 double sample_rate_ = 0.0;
240 double maximum_delay_samples_ = 0.0;
242 double current_ = 0.0;
243 double target_ = 0.0;
245 std::uint32_t remaining_ = 0;
246 bool prepared_ =
false;
247 bool initialized_ =
false;
Fixed-state controller for deterministic delay read-time modulation.
Definition tempo_delay.hpp:93
TempoDelayError prepare(double sample_rate, double maximum_delay_samples, std::uint32_t transition_samples=kDefaultTransitionSamples) noexcept
Definition tempo_delay.hpp:98
static constexpr int latency_samples() noexcept
Definition tempo_delay.hpp:205
bool initialized() const noexcept
Definition tempo_delay.hpp:181
double current_delay_samples() const noexcept
Definition tempo_delay.hpp:196
void reset() noexcept
Definition tempo_delay.hpp:170
double sample_rate() const noexcept
Definition tempo_delay.hpp:190
bool transition_active() const noexcept
Definition tempo_delay.hpp:184
double conservative_delay_samples() const noexcept
Definition tempo_delay.hpp:202
TempoDelayError set_delay_samples(double samples) noexcept
Adopt a direct fractional-sample target.
Definition tempo_delay.hpp:123
static constexpr std::uint32_t kDefaultTransitionSamples
Definition tempo_delay.hpp:95
double maximum_delay_samples() const noexcept
Definition tempo_delay.hpp:193
std::uint32_t remaining_transition_samples() const noexcept
Definition tempo_delay.hpp:187
static constexpr int tail_samples() noexcept
Definition tempo_delay.hpp:208
TempoDelayError set_tempo(timebase::BeatDivision division, double beats_per_minute) noexcept
Convert and adopt a musical target transactionally.
Definition tempo_delay.hpp:136
double target_delay_samples() const noexcept
Definition tempo_delay.hpp:199
bool prepared() const noexcept
Definition tempo_delay.hpp:178
double next() noexcept
Definition tempo_delay.hpp:146
void render(double *output, std::size_t sample_count) noexcept
Definition tempo_delay.hpp:163
Definition additive_bank.hpp:218
constexpr double kMaximumTempoDelayBpm
Definition tempo_delay.hpp:40
@ invalid_delay
Definition fractional_delay.hpp:38
@ not_prepared
Definition comb_filter.hpp:33
@ invalid_sample_rate
Definition auto_ducked_send.hpp:18
constexpr double kMaximumTempoDelaySampleRate
Definition tempo_delay.hpp:41
TempoDelayError
Definition tempo_delay.hpp:17
@ none
Definition tempo_delay.hpp:18
@ invalid_sample_rate
Definition tempo_delay.hpp:22
@ out_of_range
Definition tempo_delay.hpp:24
@ invalid_tempo
Definition tempo_delay.hpp:21
@ invalid_delay
Definition tempo_delay.hpp:23
@ invalid_division
Definition tempo_delay.hpp:20
@ not_prepared
Definition tempo_delay.hpp:19
@ maximum
Definition spectrum_trace.hpp:34
@ i
Definition formant_filter_bank.hpp:20
constexpr double kMinimumTempoDelayBpm
These bounds intentionally match TempoMap / CompiledTempoMap: a delay synchronized to a transport mus...
Definition tempo_delay.hpp:39
@ none
Definition dither.hpp:17
TempoDelayResult tempo_delay_samples(timebase::BeatDivision division, double beats_per_minute, double sample_rate) noexcept
Convert an exact persisted musical division to a fractional delay length.
Definition tempo_delay.hpp:50
@ out_of_range
Definition formant_filter_bank.hpp:27
constexpr std::uint32_t kMaximumCompiledSampleRate
Definition compiled_tempo_map.hpp:17
BeatDivision
Definition beat_division.hpp:15
runtime::Result< BeatFraction, BeatDivisionError > beat_fraction(BeatDivision division) noexcept
Definition beat_division.hpp:77
constexpr double kMinimumCompiledTempoBpm
Definition compiled_tempo_map.hpp:15
constexpr double kMaximumCompiledTempoBpm
Definition compiled_tempo_map.hpp:16
Definition tempo_delay.hpp:27
TempoDelayError error
Definition tempo_delay.hpp:28
double samples
Definition tempo_delay.hpp:29