From b243af48c756813eda6af6f519e138447591cbde Mon Sep 17 00:00:00 2001 From: nick_m Date: Thu, 18 Aug 2016 05:36:24 +1000 Subject: [PATCH] Add methods for plugin APIs to obtsin quarter pulses ('beats' for AU) from the tempo map. --- libs/ardour/ardour/tempo.h | 5 ++++ libs/ardour/tempo.cc | 60 +++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h index 1db1f65149..c134f450fb 100644 --- a/libs/ardour/ardour/tempo.h +++ b/libs/ardour/ardour/tempo.h @@ -429,6 +429,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible Timecode::BBT_Time bbt_at_beat (const double& beats); double pulse_at_bbt (const Timecode::BBT_Time& bbt); + double pulse_at_bbt_rt (const Timecode::BBT_Time& bbt); Timecode::BBT_Time bbt_at_pulse (const double& pulse); framecnt_t bbt_duration_at (framepos_t, const Timecode::BBT_Time&, int dir); @@ -448,6 +449,10 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible framepos_t framepos_minus_beats (framepos_t, Evoral::Beats) const; Evoral::Beats framewalk_to_beats (framepos_t pos, framecnt_t distance) const; + double quarter_note_at_frame (const framepos_t frame); + double quarter_note_at_frame_rt (const framepos_t frame); + framepos_t frame_at_quarter_note (const double quarter_note); + void gui_move_tempo (TempoSection*, const framepos_t& frame, const int& sub_num); void gui_move_meter (MeterSection*, const framepos_t& frame); bool gui_change_tempo (TempoSection*, const Tempo& bpm); diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc index 754b60f249..d8db6a5616 100644 --- a/libs/ardour/tempo.cc +++ b/libs/ardour/tempo.cc @@ -1861,6 +1861,18 @@ TempoMap::pulse_at_bbt (const Timecode::BBT_Time& bbt) return pulse_at_bbt_locked (_metrics, bbt); } +double +TempoMap::pulse_at_bbt_rt (const Timecode::BBT_Time& bbt) +{ + Glib::Threads::RWLock::ReaderLock lm (lock); + + if (!lm.locked()) { + throw std::logic_error ("TempoMap::pulse_at_bbt_rt() could not lock tempo map"); + } + + return pulse_at_bbt_locked (_metrics, bbt); +} + double TempoMap::pulse_at_bbt_locked (const Metrics& metrics, const Timecode::BBT_Time& bbt) const { @@ -1975,7 +1987,7 @@ TempoMap::bbt_at_frame_rt (framepos_t frame) Glib::Threads::RWLock::ReaderLock lm (lock, Glib::Threads::TRY_LOCK); if (!lm.locked()) { - throw std::logic_error ("TempoMap::bbt_time_rt() could not lock tempo map"); + throw std::logic_error ("TempoMap::bbt_at_frame_rt() could not lock tempo map"); } return bbt_at_frame_locked (_metrics, frame); @@ -2077,6 +2089,52 @@ TempoMap::frame_at_bbt_locked (const Metrics& metrics, const BBT_Time& bbt) cons return ret; } +/** + * Returns the distance from 0 in quarter pulses at the supplied frame. + * + * Plugin APIs don't count ticks in the same way PROGRAM_NAME does. + * We use ticks per beat whereas the rest of the world uses ticks per quarter note. + * This is more or less the VST's ppqPos (a scalar you use to obtain tick position + * in whatever ppqn you're using). + * + * @param frame The distance in frames relative to session 0 whose quarter note distance you would like. + * @return The quarter note (quarter pulse) distance from session 0 to the supplied frame. Ignores meter. +*/ + +double +TempoMap::quarter_note_at_frame (const framepos_t frame) +{ + Glib::Threads::RWLock::ReaderLock lm (lock, Glib::Threads::TRY_LOCK); + + const double ret = pulse_at_frame_locked (_metrics, frame) * 4.0; + + return ret; +} + +double +TempoMap::quarter_note_at_frame_rt (const framepos_t frame) +{ + Glib::Threads::RWLock::ReaderLock lm (lock, Glib::Threads::TRY_LOCK); + + if (!lm.locked()) { + throw std::logic_error ("TempoMap::quarter_note_at_frame_rt() could not lock tempo map"); + } + + const double ret = pulse_at_frame_locked (_metrics, frame) * 4.0; + + return ret; +} + +framepos_t +TempoMap::frame_at_quarter_note (const double quarter_note) +{ + Glib::Threads::RWLock::ReaderLock lm (lock, Glib::Threads::TRY_LOCK); + + const framepos_t ret = frame_at_pulse_locked (_metrics, quarter_note / 4.0); + + return ret; +} + bool TempoMap::check_solved (const Metrics& metrics) const {