Add methods for plugin APIs to obtsin quarter pulses ('beats' for AU) from the tempo...
[ardour.git] / libs / ardour / ardour / tempo.h
index a04f1bb072b19033f68f10d7b304a962ae0b0a74..c134f450fb5f3bd610b40b3ea6f9c72cea1e6727 100644 (file)
@@ -37,6 +37,7 @@
 
 class BBTTest;
 class FrameposPlusBeatsTest;
+class FrameposMinusBeatsTest;
 class TempoTest;
 class XMLNode;
 
@@ -105,8 +106,8 @@ class LIBARDOUR_API Meter {
 /** A section of timeline with a certain Tempo or Meter. */
 class LIBARDOUR_API MetricSection {
   public:
-       MetricSection (double pulse, framepos_t frame, PositionLockStyle pls)
-               : _pulse (pulse), _frame (frame), _movable (true), _position_lock_style (pls) {}
+       MetricSection (double pulse, framepos_t frame, PositionLockStyle pls, bool is_tempo)
+               : _pulse (pulse), _frame (frame), _movable (true), _position_lock_style (pls), _is_tempo (is_tempo) {}
 
        virtual ~MetricSection() {}
 
@@ -129,19 +130,21 @@ class LIBARDOUR_API MetricSection {
 
        PositionLockStyle position_lock_style () const { return _position_lock_style; }
        void set_position_lock_style (PositionLockStyle ps) { _position_lock_style = ps; }
+       bool is_tempo () const { return _is_tempo; }
 
 private:
        double             _pulse;
        framepos_t         _frame;
        bool               _movable;
        PositionLockStyle  _position_lock_style;
+       const bool         _is_tempo;
 };
 
 /** A section of timeline with a certain Meter. */
 class LIBARDOUR_API MeterSection : public MetricSection, public Meter {
   public:
        MeterSection (double pulse, framepos_t frame, double beat, const Timecode::BBT_Time& bbt, double bpb, double note_type, PositionLockStyle pls)
-               : MetricSection (pulse, frame, pls), Meter (bpb, note_type), _bbt (bbt),  _beat (beat) {}
+               : MetricSection (pulse, frame, pls, false), Meter (bpb, note_type), _bbt (bbt),  _beat (beat) {}
 
        MeterSection (const XMLNode&);
 
@@ -172,7 +175,7 @@ class LIBARDOUR_API TempoSection : public MetricSection, public Tempo {
        };
 
        TempoSection (const double& pulse, const framepos_t& frame, double qpm, double note_type, Type tempo_type, PositionLockStyle pls)
-               : MetricSection (pulse, frame, pls), Tempo (qpm, note_type), _type (tempo_type), _c_func (0.0), _active (true), _locked_to_meter (false)  {}
+               : MetricSection (pulse, frame, pls, true), Tempo (qpm, note_type), _type (tempo_type), _c_func (0.0), _active (true), _locked_to_meter (false)  {}
 
        TempoSection (const XMLNode&);
 
@@ -198,8 +201,8 @@ class LIBARDOUR_API TempoSection : public MetricSection, public Tempo {
        double tempo_at_pulse (const double& pulse) const;
        double pulse_at_tempo (const double& ppm, const framepos_t& frame, const framecnt_t& frame_rate) const;
 
-       double pulse_at_frame (const framepos_t& frame, const framecnt_t& frame_rate) const;
-       frameoffset_t frame_at_pulse (const double& pulse, const framecnt_t& frame_rate) const;
+       double pulse_at_frame (const framepos_t& frame, const framepos_t& frame_rate) const;
+       framepos_t frame_at_pulse (const double& pulse, const framecnt_t& frame_rate) const;
 
        double compute_c_func_pulse (const double& end_bpm, const double& end_pulse, const framecnt_t& frame_rate);
        double compute_c_func_frame (const double& end_bpm, const framepos_t& end_frame, const framecnt_t& frame_rate) const;
@@ -334,7 +337,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
        const MeterSection& meter_section_at_frame (framepos_t frame) const;
        const MeterSection& meter_section_at_beat (double beat) const;
 
-       /** add a tempo section locked to pls. ignored values will be set in recompute_tempos()
+       /** add a tempo section locked to pls. ignored values will be set in recompute_tempi()
         * @param pulse pulse position of new section. ignored if pls == AudioTime
         * @param frame frame position of new section. ignored if pls == MusicTime
         * @param type type of new tempo section (Ramp, Constant)
@@ -401,7 +404,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
        */
 
        double beat_at_frame (const framecnt_t& frame) const;
-       framecnt_t frame_at_beat (const double& beat) const;
+       framepos_t frame_at_beat (const double& beat) const;
 
        Tempo tempo_at_frame (const framepos_t& frame) const;
        framepos_t frame_at_tempo (const Tempo& tempo) const;
@@ -415,7 +418,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
        double beat_at_pulse (const double& pulse) const;
 
        double pulse_at_frame (const framecnt_t& frame) const;
-       framecnt_t frame_at_pulse (const double& pulse) const;
+       framepos_t frame_at_pulse (const double& pulse) const;
 
        /* bbt - it's nearly always better to use beats.*/
        Timecode::BBT_Time bbt_at_frame (framepos_t when);
@@ -426,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);
@@ -445,11 +449,17 @@ 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;
 
-       void gui_move_tempo (TempoSection*, const framepos_t& frame);
+       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);
        void gui_dilate_tempo (TempoSection* tempo, const framepos_t& frame, const framepos_t& end_frame, const double& pulse);
 
+       double exact_beat_at_frame (const framepos_t& frame, const int32_t sub_num);
+
        std::pair<double, framepos_t> predict_tempo_position (TempoSection* section, const Timecode::BBT_Time& bbt);
        bool can_solve_bbt (TempoSection* section, const Timecode::BBT_Time& bbt);
 
@@ -459,13 +469,13 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
 private:
 
        double beat_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const;
-       framecnt_t frame_at_beat_locked (const Metrics& metrics, const double& beat) const;
+       framepos_t frame_at_beat_locked (const Metrics& metrics, const double& beat) const;
 
        double pulse_at_beat_locked (const Metrics& metrics, const double& beat) const;
        double beat_at_pulse_locked (const Metrics& metrics, const double& pulse) const;
 
-       double pulse_at_frame_locked (const Metrics& metrics, const framecnt_t& frame) const;
-       framecnt_t frame_at_pulse_locked (const Metrics& metrics, const double& pulse) const;
+       double pulse_at_frame_locked (const Metrics& metrics, const framepos_t& frame) const;
+       framepos_t frame_at_pulse_locked (const Metrics& metrics, const double& pulse) const;
 
        Tempo tempo_at_frame_locked (const Metrics& metrics, const framepos_t& frame) const;
        framepos_t frame_at_tempo_locked (const Metrics& metrics, const Tempo& tempo) const;
@@ -493,8 +503,11 @@ private:
        bool solve_map_frame (Metrics& metrics, MeterSection* section, const framepos_t& frame);
        bool solve_map_bbt (Metrics& metrics, MeterSection* section, const Timecode::BBT_Time& bbt);
 
+       double exact_beat_at_frame_locked (const Metrics& metrics, const framepos_t& frame, const int32_t sub_num);
+
        friend class ::BBTTest;
        friend class ::FrameposPlusBeatsTest;
+       friend class ::FrameposMinusBeatsTest;
        friend class ::TempoTest;
 
        static Tempo    _default_tempo;
@@ -504,7 +517,7 @@ private:
        framecnt_t                    _frame_rate;
        mutable Glib::Threads::RWLock lock;
 
-       void recompute_tempos (Metrics& metrics);
+       void recompute_tempi (Metrics& metrics);
        void recompute_meters (Metrics& metrics);
        void recompute_map (Metrics& metrics, framepos_t end = -1);