35 std::span<const GrooveKernelStep>
steps{};
91 if (input.swing_grid.value < 0 ||
99 if ((input.table_grid.value != 0) != !input.steps.empty() || input.table_grid.value < 0 ||
107 for (
const auto& step : input.steps) {
112 if (step.timing_offset.value <= -input.table_grid.value ||
113 step.timing_offset.value >= input.table_grid.value)
114 return runtime::Err(InlineGrooveError::InvalidTable);
115 if (step.velocity_scale < 0 || step.velocity_scale > kMaximumGrooveKernelVelocityScale)
116 return runtime::Err(InlineGrooveError::InvalidVelocityScale);
130 constexpr std::span<const GrooveKernelStep>
steps() const noexcept {
131 return {steps_.data(), size_};
134 return timing_strength_;
137 return velocity_strength_;
142 return swing_grid_.value == 0 && size_ == 0;
158 std::int64_t displacement = 0;
159 if (swing_grid_.value != 0)
160 displacement = scaled_by_strength(
162 if (
const auto* step = step_at(authored))
163 displacement += scaled_by_strength(step->timing_offset.value, timing_strength_);
164 std::int64_t transformed = 0;
165 if (!checked_add(authored.value, displacement, transformed))
172 const auto* step = step_at(authored);
175 const auto deviation =
178 scaled_by_strength(deviation, velocity_strength_));
183 : swing_grid_(input.swing_grid), swing_(input.swing), table_grid_(input.table_grid),
184 size_(input.steps.size()), timing_strength_(input.timing_strength),
185 velocity_strength_(input.velocity_strength) {
186 for (std::size_t index = 0; index < size_; ++index)
187 steps_[index] = input.steps[index];
190 static constexpr bool checked_add(std::int64_t lhs, std::int64_t rhs,
191 std::int64_t& result)
noexcept {
192 constexpr auto min = std::numeric_limits<std::int64_t>::min();
193 constexpr auto max = std::numeric_limits<std::int64_t>::max();
194 if ((rhs > 0 && lhs > max - rhs) || (rhs < 0 && lhs < min - rhs))
211 static constexpr std::int64_t scaled_by_strength(std::int64_t value,
212 std::int32_t strength)
noexcept {
213 const auto magnitude = value < 0 ? -value : value;
216 return value < 0 ? -scaled : scaled;
222 constexpr const GrooveKernelStep* step_at(TickPosition authored)
const noexcept {
223 if (size_ == 0 || table_grid_.value <= 0)
225 auto index = authored.value / table_grid_.value;
226 if (authored.value % table_grid_.value < 0)
228 auto slot =
index %
static_cast<std::int64_t
>(size_);
230 slot +=
static_cast<std::int64_t
>(size_);
231 return &steps_[
static_cast<std::size_t
>(slot)];
234 TickDuration swing_grid_{};
236 TickDuration table_grid_{};
237 std::array<GrooveKernelStep, kMaximumInlineGrooveSteps> steps_{};
238 std::size_t size_ = 0;
247static_assert(std::is_trivially_copyable_v<InlineGrooveProjector>);
Wrap a value as a failure result.
Definition result.hpp:58
Wrap a value as a success result.
Definition result.hpp:42
Result<T, E> — either holds a T or an E, never both.
Definition result.hpp:76
static runtime::Result< InlineGrooveProjector, InlineGrooveError > create(InlineGrooveInput input) noexcept
Definition inline_groove_projector.hpp:90
constexpr TickDuration table_grid() const noexcept
Definition inline_groove_projector.hpp:127
constexpr std::int32_t velocity_scale_at(TickPosition authored) const noexcept
Definition inline_groove_projector.hpp:171
constexpr std::span< const GrooveKernelStep > steps() const noexcept
Definition inline_groove_projector.hpp:130
constexpr bool states_no_feel() const noexcept
Definition inline_groove_projector.hpp:141
constexpr SwingRatio swing() const noexcept
Definition inline_groove_projector.hpp:124
constexpr std::int32_t timing_strength() const noexcept
Definition inline_groove_projector.hpp:133
runtime::Result< TickPosition, InlineGrooveError > apply_timing(TickPosition authored) const noexcept
Definition inline_groove_projector.hpp:157
constexpr InlineGrooveProjector() noexcept=default
constexpr std::int32_t velocity_strength() const noexcept
Definition inline_groove_projector.hpp:136
constexpr TickDuration swing_grid() const noexcept
Definition inline_groove_projector.hpp:121
@ index
Definition gpu_pass.hpp:140
Definition generated_event_source.hpp:33
@ Ok
No error; bytes is authoritative.
Definition stream.hpp:32
Definition beat_division.hpp:11
constexpr bool valid_swing_ratio(SwingRatio ratio) noexcept
Definition quantize.hpp:79
constexpr bool valid_swing_grid(TickDuration grid) noexcept
Definition quantize.hpp:72
TickDuration swing_displacement(TickPosition position, TickDuration grid, SwingRatio ratio) noexcept
Definition quantize.hpp:114
@ InvalidSwing
Definition groove_kernel.hpp:43
@ InvalidTable
Definition groove_kernel.hpp:44
@ TooManySteps
Definition groove_kernel.hpp:45
@ InvalidStrength
Definition groove_kernel.hpp:46
@ InvalidSwingGrid
Definition groove_kernel.hpp:42
@ InvalidVelocityScale
Definition groove_kernel.hpp:47
constexpr std::size_t kMaximumInlineGrooveSteps
Definition inline_groove_projector.hpp:23
constexpr std::int64_t kMaxSwingGridTicks
Definition quantize.hpp:69
@ RangeExceeded
Definition beat_division.hpp:49
InlineGrooveError
Definition inline_groove_projector.hpp:40
@ InvalidSwing
Definition inline_groove_projector.hpp:43
@ InvalidTable
Definition inline_groove_projector.hpp:44
@ TooManySteps
Definition inline_groove_projector.hpp:45
@ RangeExceeded
Definition inline_groove_projector.hpp:48
@ InvalidStrength
Definition inline_groove_projector.hpp:46
@ InvalidSwingGrid
Definition inline_groove_projector.hpp:42
@ None
Definition grid_projection.hpp:97
constexpr std::int32_t kGrooveKernelUnitScale
Definition groove_kernel.hpp:18
constexpr SwingRatio kStraightSwing
Definition quantize.hpp:61
Result<T, E> — success / failure union for fallible operations.
Definition quantize.hpp:53