add Meter::operator==.
[ardour.git] / libs / ardour / ardour / tempo.h
index a35e1b4fba41a23b24b7ab9cd986958fbc90da95..bd940f991a6fcbb871d0c853211d45d124316d92 100644 (file)
@@ -57,12 +57,12 @@ class LIBARDOUR_API Tempo {
                : _note_types_per_minute (npm), _note_type(type) {}
 
        double note_types_per_minute () const { return _note_types_per_minute; }
+       double note_types_per_minute (double note_type) const { return (_note_types_per_minute / _note_type) * note_type; }
        void set_note_types_per_minute (double npm) { _note_types_per_minute = npm; }
        double note_type () const { return _note_type; }
 
-       double note_divisions_per_minute (double note_type) const { return _note_types_per_minute * (note_type / _note_type); }
-       double quarter_notes_per_minute () const { return note_divisions_per_minute (4.0); }
-       double pulses_per_minute () const { return note_divisions_per_minute (1.0); }
+       double quarter_notes_per_minute () const { return note_types_per_minute (4.0); }
+       double pulses_per_minute () const { return note_types_per_minute (1.0); }
        /** audio samples per note type.
         * if you want an instantaneous value for this, use TempoMap::frames_per_quarter_note_at() instead.
         * @param sr samplerate
@@ -95,6 +95,9 @@ class LIBARDOUR_API Meter {
        double frames_per_bar (const Tempo&, framecnt_t sr) const;
        double frames_per_grid (const Tempo&, framecnt_t sr) const;
 
+       inline bool operator==(const Meter& other)
+       { return _divisions_per_bar == other.divisions_per_bar() && _note_type == other.note_divisor(); }
+
   protected:
        /** The number of divisions in a bar.  This is a floating point value because
            there are musical traditions on our planet that do not limit
@@ -112,7 +115,7 @@ class LIBARDOUR_API Meter {
 class LIBARDOUR_API MetricSection {
   public:
        MetricSection (double pulse, double minute, PositionLockStyle pls, bool is_tempo, framecnt_t sample_rate)
-               : _pulse (pulse), _minute (minute), _movable (true), _position_lock_style (pls), _is_tempo (is_tempo), _sample_rate (sample_rate) {}
+               : _pulse (pulse), _minute (minute), _initial (false), _position_lock_style (pls), _is_tempo (is_tempo), _sample_rate (sample_rate) {}
 
        virtual ~MetricSection() {}
 
@@ -126,8 +129,8 @@ class LIBARDOUR_API MetricSection {
 
        framepos_t frame () const { return frame_at_minute (_minute); }
 
-       void set_movable (bool yn) { _movable = yn; }
-       bool movable() const { return _movable; }
+       void set_initial (bool yn) { _initial = yn; }
+       bool initial() const { return _initial; }
 
        /* MeterSections are not stateful in the full sense,
           but we do want them to control their own
@@ -146,7 +149,7 @@ private:
 
        double             _pulse;
        double             _minute;
-       bool               _movable;
+       bool               _initial;
        PositionLockStyle  _position_lock_style;
        const bool         _is_tempo;
        framecnt_t         _sample_rate;
@@ -304,8 +307,11 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
 {
   public:
        TempoMap (framecnt_t frame_rate);
+       TempoMap (TempoMap const &);
        ~TempoMap();
 
+       TempoMap& operator= (TempoMap const &);
+
        /* measure-based stuff */
 
        enum BBTPointType {
@@ -356,12 +362,20 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
         */
        TempoSection* add_tempo (const Tempo&, const double& pulse, const framepos_t& frame, TempoSection::Type type, PositionLockStyle pls);
 
-       /** add an meter section locked to pls.. ignored values will be set in recompute_meters()
+       /** add a meter section locked to pls.. ignored values will be set in recompute_meters()
+        * @param meter the Meter to be added
         * @param beat beat position of new section
         * @param where bbt position of new section
         * @param frame frame position of new section. ignored if pls == MusicTime
+        * note that @frame may also be ignored if it would create an un-solvable map
+        * (previous audio-locked tempi may place the requested beat at an earlier time than frame)
+        * in which case the new meter will be placed at the specified BBT.
+        * @param  pls the position lock style
+        *
+        * adding an audio-locked meter will add a meter-locked tempo section at the meter position.
+        * the meter-locked tempo tempo will be the Tempo at @beat
         */
-       MeterSection* add_meter (const Meter&, const double& beat, const Timecode::BBT_Time& where, PositionLockStyle pls);
+       MeterSection* add_meter (const Meter& meter, const double& beat, const Timecode::BBT_Time& where, framepos_t frame, PositionLockStyle pls);
 
        void remove_tempo (const TempoSection&, bool send_signal);
        void remove_meter (const MeterSection&, bool send_signal);
@@ -369,7 +383,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
        void replace_tempo (const TempoSection&, const Tempo&, const double& pulse, const framepos_t& frame
                            , TempoSection::Type type, PositionLockStyle pls);
 
-       void replace_meter (const MeterSection&, const Meter&, const Timecode::BBT_Time& where, PositionLockStyle pls);
+       void replace_meter (const MeterSection&, const Meter&, const Timecode::BBT_Time& where, framepos_t frame, PositionLockStyle pls);
 
        framepos_t round_to_bar  (framepos_t frame, RoundMode dir);
        framepos_t round_to_beat (framepos_t frame, RoundMode dir);
@@ -381,7 +395,7 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
        XMLNode& get_state (void);
        int set_state (const XMLNode&, int version);
 
-       void dump (const Metrics& metrics, std::ostream&) const;
+       void dump (std::ostream&) const;
        void clear ();
 
        TempoMetric metric_at (Timecode::BBT_Time bbt) const;
@@ -460,22 +474,22 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
        framecnt_t frames_between_quarter_notes (const double start, const double end) const;
        double     quarter_notes_between_frames (const framecnt_t start, const framecnt_t end) const;
 
-       double quarter_note_at_beat (const double beat);
-       double beat_at_quarter_note (const double beat);
+       double quarter_note_at_beat (const double beat) const;
+       double beat_at_quarter_note (const double beat) const;
 
        /* obtain a musical subdivision via a frame position and magic note divisor.*/
-       double exact_qn_at_frame (const framepos_t& frame, const int32_t sub_num);
-       double exact_beat_at_frame (const framepos_t& frame, const int32_t sub_num);
+       double exact_qn_at_frame (const framepos_t& frame, const int32_t sub_num) const;
+       double exact_beat_at_frame (const framepos_t& frame, const int32_t sub_num) const;
 
        Tempo tempo_at_frame (const framepos_t& frame) const;
        framepos_t frame_at_tempo (const Tempo& tempo) const;
        Tempo tempo_at_quarter_note (const double& beat) const;
        double quarter_note_at_tempo (const Tempo& tempo) const;
 
-       void gui_move_tempo (TempoSection*, const framepos_t& frame, const int& sub_num);
-       void gui_move_meter (MeterSection*, const framepos_t& frame);
+       void gui_set_tempo_position (TempoSection*, const framepos_t& frame, const int& sub_num);
+       void gui_set_meter_position (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);
+       void gui_stretch_tempo (TempoSection* tempo, const framepos_t& frame, const framepos_t& end_frame);
 
        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);
@@ -525,15 +539,15 @@ private:
        const MeterSection& meter_section_at_beat_locked (const Metrics& metrics, const double& beat) const;
 
        bool check_solved (const Metrics& metrics) const;
-       bool set_active_tempos (const Metrics& metrics, const framepos_t& frame);
+       bool set_active_tempi (const Metrics& metrics, const framepos_t& frame);
 
        bool solve_map_minute (Metrics& metrics, TempoSection* section, const double& minute);
        bool solve_map_pulse (Metrics& metrics, TempoSection* section, const double& pulse);
        bool solve_map_minute (Metrics& metrics, MeterSection* section, const double& minute);
        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);
-       double exact_qn_at_frame_locked (const Metrics& metrics, const framepos_t& frame, const int32_t sub_num);
+       double exact_beat_at_frame_locked (const Metrics& metrics, const framepos_t& frame, const int32_t sub_num) const;
+       double exact_qn_at_frame_locked (const Metrics& metrics, const framepos_t& frame, const int32_t sub_num) const;
 
        double minute_at_frame (const framepos_t frame) const;
        framepos_t frame_at_minute (const double minute) const;
@@ -566,7 +580,7 @@ private:
        TempoSection* add_tempo_locked (const Tempo&, double pulse, double minute
                               , TempoSection::Type type, PositionLockStyle pls, bool recompute, bool locked_to_meter = false);
 
-       MeterSection* add_meter_locked (const Meter&, double beat, const Timecode::BBT_Time& where, PositionLockStyle pls, bool recompute);
+       MeterSection* add_meter_locked (const Meter&, double beat, const Timecode::BBT_Time& where, framepos_t frame, PositionLockStyle pls, bool recompute);
 
        bool remove_tempo_locked (const TempoSection&);
        bool remove_meter_locked (const MeterSection&);
@@ -577,8 +591,8 @@ private:
 
 }; /* namespace ARDOUR */
 
-std::ostream& operator<< (std::ostream&, const ARDOUR::Meter&);
-std::ostream& operator<< (std::ostream&, const ARDOUR::Tempo&);
-std::ostream& operator<< (std::ostream&, const ARDOUR::MetricSection&);
+LIBARDOUR_API std::ostream& operator<< (std::ostream&, const ARDOUR::Meter&);
+LIBARDOUR_API std::ostream& operator<< (std::ostream&, const ARDOUR::Tempo&);
+LIBARDOUR_API std::ostream& operator<< (std::ostream&, const ARDOUR::MetricSection&);
 
 #endif /* __ardour_tempo_h__ */