diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h index 08c2eec4dd..4a2e5877b8 100644 --- a/libs/ardour/ardour/tempo.h +++ b/libs/ardour/ardour/tempo.h @@ -394,7 +394,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible /* TEMPO- AND METER-SENSITIVE FUNCTIONS - bbt_at_frame(), frame_at_bbt(), beat_at_frame(), frame_at_beat() + bbt_at_frame(), frame_at_bbt(), beat_at_frame(), frame_at_beat(), tempo_at_beat() and bbt_duration_at() are all sensitive to tempo and meter, and will give answers that align with the grid formed by tempo and meter sections. @@ -409,6 +409,8 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible Tempo tempo_at_frame (const framepos_t& frame) const; framepos_t frame_at_tempo (const Tempo& tempo) const; + Tempo tempo_at_beat (const double& beat) const; + const Meter& meter_at_frame (framepos_t) const; /* you probably only need to use pulses when moving tempos */ diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index f7aebeb0bc..d1d4ec0b99 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -1535,6 +1535,17 @@ TempoMap::frame_at_tempo_locked (const Metrics& metrics, const Tempo& tempo) con return prev_t->frame(); } +Tempo +TempoMap::tempo_at_beat (const double& beat) const +{ + Glib::Threads::RWLock::ReaderLock lm (lock); + const MeterSection* prev_m = &meter_section_at_beat_locked (_metrics, beat); + const TempoSection* prev_t = &tempo_section_at_beat_locked (_metrics, beat); + const double note_type = prev_t->note_type(); + + return Tempo (prev_t->tempo_at_pulse (((beat - prev_m->beat()) / prev_m->note_divisor()) + prev_m->pulse()) * note_type, note_type); +} + double TempoMap::pulse_at_beat (const double& beat) const {