Merge some cases to avoid duplicated logic
[ardour.git] / libs / ardour / ardour / tempo.h
index 08c2eec4dde30625c598ef6345301240f5632c67..5fce9ce384a8fe68ca78f91531b4ec9fa48623d1 100644 (file)
@@ -105,8 +105,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 +129,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&);
 
@@ -149,9 +151,6 @@ class LIBARDOUR_API MeterSection : public MetricSection, public Meter {
 
        XMLNode& get_state() const;
 
-       void set_pulse (double w) {
-               MetricSection::set_pulse (w);
-       }
        void set_beat (std::pair<double, Timecode::BBT_Time>& w) {
                _beat = w.first;
                _bbt = w.second;
@@ -175,7 +174,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&);
 
@@ -201,8 +200,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;
@@ -337,7 +336,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)
@@ -394,7 +393,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.
@@ -404,11 +403,13 @@ 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;
 
+       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 */
@@ -416,10 +417,11 @@ 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);
+       Timecode::BBT_Time bbt_at_frame_rt (framepos_t when);
        framepos_t frame_at_bbt (const Timecode::BBT_Time&);
 
        double beat_at_bbt (const Timecode::BBT_Time& bbt);
@@ -445,11 +447,13 @@ 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);
+       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 +463,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,6 +497,8 @@ 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 ::TempoTest;
@@ -504,7 +510,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);