Tempo ramps - fix many problems wrt dragging tempos over each other.
[ardour.git] / libs / ardour / ardour / tempo.h
index 9a2248414224f1e778109ead4f039a4cdee0eb95..e8f40e4236b65eafb36ce6b415bf0d7b8311d265 100644 (file)
@@ -27,6 +27,7 @@
 #include <glibmm/threads.h>
 
 #include "pbd/undo.h"
+
 #include "pbd/stateful.h"
 #include "pbd/statefuldestructible.h"
 
@@ -54,7 +55,8 @@ class LIBARDOUR_API Tempo {
        Tempo (double bpm, double type=4.0) // defaulting to quarter note
                : _beats_per_minute (bpm), _note_type(type) {}
 
-       double beats_per_minute () const { return _beats_per_minute;}
+       double beats_per_minute () const { return _beats_per_minute; }
+
        double ticks_per_minute () const { return _beats_per_minute * Timecode::BBT_Time::ticks_per_beat;}
        double note_type () const { return _note_type;}
        /** audio samples per beat
@@ -98,9 +100,9 @@ class LIBARDOUR_API Meter {
 class LIBARDOUR_API MetricSection {
   public:
        MetricSection (const Timecode::BBT_Time& start)
-               : _start (start), _frame (0), _movable (true) {}
+               : _start (start), _frame (0), _movable (true), _position_lock_style (MusicTime) {}
        MetricSection (framepos_t start)
-               : _frame (start), _movable (true) {}
+               : _frame (start), _movable (true), _position_lock_style (MusicTime) {}
 
        virtual ~MetricSection() {}
 
@@ -123,11 +125,15 @@ class LIBARDOUR_API MetricSection {
           XML state information.
        */
        virtual XMLNode& get_state() const = 0;
+       PositionLockStyle position_lock_style () const { return _position_lock_style; }
+       void set_position_lock_style (PositionLockStyle ps) { _position_lock_style = ps; }
+
+private:
 
-  private:
        Timecode::BBT_Time _start;
        framepos_t         _frame;
        bool               _movable;
+       PositionLockStyle  _position_lock_style;
 };
 
 /** A section of timeline with a certain Meter. */
@@ -147,14 +153,14 @@ class LIBARDOUR_API MeterSection : public MetricSection, public Meter {
 /** A section of timeline with a certain Tempo. */
 class LIBARDOUR_API TempoSection : public MetricSection, public Tempo {
   public:
-       enum TempoSectionType {
+       enum Type {
                Ramp,
                Constant,
        };
 
-       TempoSection (const Timecode::BBT_Time& start, double qpm, double note_type, TempoSectionType tempo_type)
+       TempoSection (const Timecode::BBT_Time& start, double qpm, double note_type, Type tempo_type)
                : MetricSection (start), Tempo (qpm, note_type), _bar_offset (-1.0), _type (tempo_type)  {}
-       TempoSection (framepos_t start, double qpm, double note_type, TempoSectionType tempo_type)
+       TempoSection (framepos_t start, double qpm, double note_type, Type tempo_type)
                : MetricSection (start), Tempo (qpm, note_type), _bar_offset (-1.0), _type (tempo_type) {}
        TempoSection (const XMLNode&);
 
@@ -166,8 +172,8 @@ class LIBARDOUR_API TempoSection : public MetricSection, public Tempo {
        void update_bbt_time_from_bar_offset (const Meter&);
        double bar_offset() const { return _bar_offset; }
 
-       void set_type (TempoSectionType type);
-       TempoSectionType type () const { return _type; }
+       void set_type (Type type);
+       Type type () const { return _type; }
 
        double tempo_at_frame (framepos_t frame, double end_bpm, framepos_t end_frame, framecnt_t frame_rate) const;
        framepos_t frame_at_tempo (double tempo, double end_bpm, framepos_t end_frame, framecnt_t frame_rate) const;
@@ -210,7 +216,7 @@ class LIBARDOUR_API TempoSection : public MetricSection, public Tempo {
           position within the bar if/when the meter changes.
        */
        double _bar_offset;
-       TempoSectionType _type;
+       Type _type;
 };
 
 typedef std::list<MetricSection*> Metrics;
@@ -343,13 +349,14 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
        TempoSection* tempo_section_after (framepos_t) const;
        const MeterSection& meter_section_at (framepos_t) const;
 
-       void add_tempo (const Tempo&, Timecode::BBT_Time where, TempoSection::TempoSectionType type);
+       void add_tempo (const Tempo&, Timecode::BBT_Time where, TempoSection::Type type);
        void add_meter (const Meter&, Timecode::BBT_Time where);
 
        void remove_tempo (const TempoSection&, bool send_signal);
        void remove_meter (const MeterSection&, bool send_signal);
 
-       void replace_tempo (const TempoSection&, const Tempo&, const Timecode::BBT_Time& where, TempoSection::TempoSectionType type);
+       void replace_tempo (const TempoSection&, const Tempo&, const Timecode::BBT_Time& where, TempoSection::Type type);
+       void gui_set_tempo_frame (TempoSection&, framepos_t where);
        void replace_meter (const MeterSection&, const Meter&, const Timecode::BBT_Time& where);
 
        framepos_t round_to_bar  (framepos_t frame, RoundMode dir);
@@ -384,7 +391,9 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
 
        framecnt_t frame_rate () const { return _frame_rate; }
 
-  private:
+       PBD::Signal0<void> MetricPositionChanged;
+
+private:
 
        friend class ::BBTTest;
        friend class ::FrameposPlusBeatsTest;
@@ -415,7 +424,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
 
        void do_insert (MetricSection* section);
 
-       void add_tempo_locked (const Tempo&, Timecode::BBT_Time where, bool recompute, TempoSection::TempoSectionType type);
+       void add_tempo_locked (const Tempo&, Timecode::BBT_Time where, bool recompute, TempoSection::Type type);
        void add_meter_locked (const Meter&, Timecode::BBT_Time where, bool recompute);
 
        bool remove_tempo_locked (const TempoSection&);