note: close every value type's domain at construction, so resolveNote is finite for every constructible input
Division and OffsetAmount get single normalizing doors and private constructors; fromBpm validates by running the conversions rather than their reciprocal. Readers drop their re-clamps and default labels.
This commit is contained in:
@@ -16,10 +16,16 @@ inline constexpr double kMsPerSecond = 1000.0;
|
||||
constexpr double msToSeconds(double ms) { return ms / kMsPerSecond; }
|
||||
constexpr double secondsToMs(double seconds) { return seconds * kMsPerSecond; }
|
||||
|
||||
// The largest magnitude, in beats or in milliseconds, the conversions below are required to
|
||||
// keep finite. `fromBpm` validates against it and every caller caps its own domain to it, so
|
||||
// the two halves of the totality claim meet at one number. Astronomically above anything
|
||||
// musical — a billion milliseconds is eleven days — so nothing real is excluded.
|
||||
inline constexpr double kMaxConvertibleMagnitude = 1e9;
|
||||
|
||||
class Tempo {
|
||||
public:
|
||||
// The only place a bad BPM is rejected, which is what lets every conversion below be
|
||||
// total — no resolver downstream needs a failure path.
|
||||
// Rejects rather than clamps, alone among this module's doors: an unusable BPM has no
|
||||
// nearest usable one to fall to. See this directory's CLAUDE.md for the rule.
|
||||
static std::optional<Tempo> fromBpm(double beatsPerMinute);
|
||||
|
||||
double bpm() const { return bpm_; }
|
||||
|
||||
Reference in New Issue
Block a user