136 phase_ = wrap_unit(
phase);
145 scan(increment, 0.0, 1.0);
160 int advance_synced(
double increment,
double sync_frac,
double sync_phase = 0.0) {
164 const double f = clamp_unit(sync_frac);
165 scan(increment * f, 0.0, f);
167 const double target = wrap_unit(sync_phase);
171 scan(increment * (1.0 - f), f, 1.0 - f);
176 double phase()
const {
return phase_; }
179 std::span<const PhaseEvent>
events()
const {
180 return {events_.data(),
static_cast<std::size_t
>(count_)};
195 void scan(
double delta,
double t0,
double span) {
204 if (!std::isfinite(delta)) {
209 const double p0 = phase_;
210 const double raw = p0 + delta;
211 const double n = std::floor(raw);
216 double wrapped = raw - n;
217 if (!(wrapped >= 0.0 && wrapped < 1.0))
221 const double magnitude = std::fabs(n);
225 }
else if (magnitude >= 1.0) {
226 events =
static_cast<int>(magnitude);
233 for (
int k = 0; k <
events; ++k) {
234 const double level =
forward ?
static_cast<double>(k + 1)
235 : -static_cast<double>(k);
236 const double t = (level - p0) / delta;
247 void emit(
double frac,
double before,
double after,
PhaseEventKind kind) {
252 events_[
static_cast<std::size_t
>(count_++)] = PhaseEvent{frac, before, after, kind};
256 static double wrap_unit(
double x) {
257 double w =
x - std::floor(x);
258 if (!(w >= 0.0 && w < 1.0))
264 static double clamp_unit(
double x) {
265 if (!(x > 0.0))
return 0.0;
266 if (x > 1.0)
return 1.0;
271 std::array<PhaseEvent, max_events_per_sample> events_{};
273 bool truncated_ =
false;
Phase accumulator over the unit circle [0, 1), suitable as the clock for through-zero FM,...
Definition phase.hpp:129
int advance_synced(double increment, double sync_frac, double sync_phase=0.0)
Advance one sample by increment cycles, forcing the phase to sync_phase at sub-sample position sync_f...
Definition phase.hpp:160
double phase() const
Current phase, always in [0, 1).
Definition phase.hpp:176
static constexpr int max_events_per_sample
Event capacity of a single advance. See the truncation note above.
Definition phase.hpp:132
int advance(double increment)
Advance one sample by increment cycles. Returns the number of events.
Definition phase.hpp:142
bool truncated() const
Whether the last advance dropped events past max_events_per_sample.
Definition phase.hpp:184
std::span< const PhaseEvent > events() const
Events from the last advance, in chronological order.
Definition phase.hpp:179
void reset(double phase=0.0)
Set the phase, wrapped into [0, 1). Clears any reported events.
Definition phase.hpp:135
Definition child_process_manager.hpp:18
PhaseEventKind
What produced a phase discontinuity.
Definition phase.hpp:11
@ wrap_backward
Phase left 0 downward and wrapped to 1 (increment < 0).
Definition phase.hpp:13
@ wrap_forward
Phase reached 1 and wrapped to 0 (increment > 0).
Definition phase.hpp:12
@ sync
Phase was forced by advance_synced().
Definition phase.hpp:14
@ forward
(s + 1) mod N.
Definition stage_sequencer.hpp:18
@ x
Definition input_events.hpp:41
@ w
Definition input_events.hpp:41
A single phase discontinuity within one sample period.
Definition phase.hpp:28
PhaseEventKind kind
Definition phase.hpp:34
double phase_after
Definition phase.hpp:33
double phase_before
Definition phase.hpp:32
double frac
Sub-sample position of the discontinuity, relative to the start of the sample being advanced.
Definition phase.hpp:31