note: land the programmed capture-signal model — division ladder, tempo resolution, anchored offsets, one record and one resolver

This commit is contained in:
2026-07-30 19:44:15 -04:00
parent 7bd911d58b
commit 834a6ddcc7
12 changed files with 1098 additions and 0 deletions
+37
View File
@@ -0,0 +1,37 @@
// tempo — a validated project tempo and every beats <-> seconds <-> ms conversion a
// beat-denominated capture value resolves through.
//
// A BEAT IS A QUARTER NOTE — REAPER states project tempo in quarter notes per minute
// regardless of time signature, so a division resolves without one.
#pragma once
#include <optional>
namespace reasampler::instrument::note {
inline constexpr double kMsPerSecond = 1000.0;
constexpr double msToSeconds(double ms) { return ms / kMsPerSecond; }
constexpr double secondsToMs(double seconds) { return seconds * kMsPerSecond; }
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.
static std::optional<Tempo> fromBpm(double beatsPerMinute);
double bpm() const { return bpm_; }
double secondsPerBeat() const;
double beatsToSeconds(double beats) const;
double secondsToBeats(double seconds) const;
double beatsToMs(double beats) const;
double msToBeats(double ms) const;
private:
explicit Tempo(double beatsPerMinute) : bpm_(beatsPerMinute) {}
double bpm_;
};
} // namespace reasampler::instrument::note