note: land the programmed capture-signal model — division ladder, tempo resolution, anchored offsets, one record and one resolver
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
// musical_division — the note-length ladder the capture signal is programmed from: 1/64
|
||||
// through 64/1, each straight, dotted, or triplet. Lengths are in BEATS only; the tempo
|
||||
// resolution belongs to `tempo`, which keeps this ladder provable without one.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace reasampler::instrument::note {
|
||||
|
||||
enum class DivisionModifier : std::uint8_t {
|
||||
Straight,
|
||||
Dotted, // x 3/2
|
||||
Triplet, // x 2/3
|
||||
};
|
||||
|
||||
// A rung of the ladder is the base-2 exponent of its length in quarter notes: -4 is 1/64,
|
||||
// 0 is 1/4, 2 is 1/1, 8 is 64/1. Holding the exponent rather than a table of literal beat
|
||||
// counts keeps every straight and dotted length exactly representable in double.
|
||||
inline constexpr int kMinQuarterExponent = -4;
|
||||
inline constexpr int kMaxQuarterExponent = 8;
|
||||
inline constexpr int kRungCount = kMaxQuarterExponent - kMinQuarterExponent + 1;
|
||||
inline constexpr int kModifierCount = 3;
|
||||
inline constexpr int kDivisionCount = kRungCount * kModifierCount;
|
||||
|
||||
struct Division {
|
||||
std::int8_t quarterExponent = 0; // 1/4
|
||||
DivisionModifier modifier = DivisionModifier::Straight;
|
||||
};
|
||||
|
||||
bool operator==(Division a, Division b);
|
||||
bool operator!=(Division a, Division b);
|
||||
|
||||
// Off-ladder exponents clamp rather than reject: the only ways to reach one are a corrupt
|
||||
// persisted record or a picker bug, and the nearest legal length beats a nonsense duration.
|
||||
Division makeDivision(int quarterExponent, DivisionModifier modifier);
|
||||
|
||||
// Length in beats (quarter notes). Always > 0.
|
||||
double divisionBeats(Division d);
|
||||
|
||||
// Picker order: shortest rung first, straight/dotted/triplet within each rung. Index is
|
||||
// presentation order only — see this directory's CLAUDE.md before persisting one.
|
||||
Division divisionAt(int index);
|
||||
int divisionIndex(Division d);
|
||||
|
||||
// The notation divisions are named in: "1/16", "1/8.", "1/4t", "4/1".
|
||||
std::string divisionLabel(Division d);
|
||||
|
||||
} // namespace reasampler::instrument::note
|
||||
Reference in New Issue
Block a user