31 static constexpr int unity = 0x38000;
41 explicit PitchRamp(std::span<const std::int32_t> ramp_exp) noexcept : table_(ramp_exp) {}
47 [[nodiscard]]
static int domain_of(
double ratio)
noexcept
53 return std::clamp(
static_cast<int>(std::lround(units)), 0,
domain_max) & ~1;
65 const auto index =
static_cast<std::size_t
>((value >> 6) & 0xFF);
66 const int fraction = value & 0x3F;
67 const std::int64_t interpolated =
68 (
static_cast<std::int64_t
>(table_[index]) * (0x40 - fraction))
69 + (
static_cast<std::int64_t
>(table_[index + 1]) * fraction);
70 const std::int64_t rounded = (interpolated + ((interpolated >> 63) & 0x3F)) >> 6;
71 return static_cast<std::int32_t
>(rounded >> (0xF - ((value >> 0xE) & 0xF)));
80 void arm(
double from_ratio,
double to_ratio)
noexcept
84 const auto delta =
static_cast<std::int64_t
>(target_) - current_;
85 step_ =
static_cast<int>((delta * max_rate) >> 13);
86 if (step_ == 0 && current_ < target_) {
89 active_ = current_ != target_ && step_ != 0;
93 [[nodiscard]]
bool is_active() const noexcept {
return active_; }
102 current_ = step_ < 0 ? std::max(target_, current_ + step_)
103 : std::min(target_, current_ + step_);
104 if (current_ == target_) {
113 static constexpr int max_rate = 0xFFF;
115 std::span<const std::int32_t> table_;
116 int current_ =
unity;
119 bool active_ =
false;
static constexpr int milli_semitone_divisor
Definition pitch_ramp.hpp:35
PitchRamp(std::span< const std::int32_t > ramp_exp) noexcept
Creates a ramp over the shared exponential table, which must outlive it.
Definition pitch_ramp.hpp:41
std::int32_t increment_of(int value) const noexcept
The 16.16 sampler increment a domain value decodes to.
Definition pitch_ramp.hpp:60
std::int32_t next_slot() noexcept
Advances one slot and returns the increment that serves the next eight samples.
Definition pitch_ramp.hpp:96
static constexpr int unity
The ramp domain's value for unity rate.
Definition pitch_ramp.hpp:31
static constexpr int units_per_octave
Units per octave, and the divisor that puts milli-semitones into them.
Definition pitch_ramp.hpp:34
void arm(double from_ratio, double to_ratio) noexcept
Arms the ramp to glide from one ratio to another across the coming block.
Definition pitch_ramp.hpp:80
static constexpr int samples_per_slot
Samples one increment serves; the engine writes four of these per 32-sample chunk.
Definition pitch_ramp.hpp:28
static int domain_of(double ratio) noexcept
Converts a playback ratio into the ramp domain.
Definition pitch_ramp.hpp:47
bool is_active() const noexcept
Whether the ramp still has ground to cover.
Definition pitch_ramp.hpp:93
static constexpr int domain_max
Largest value the exponential decode accepts.
Definition pitch_ramp.hpp:38
Definition control_decode.hpp:7