Merge branch 'export-dialog' into cairocanvas
[ardour.git] / libs / ardour / ardour / tempo.h
index 65e488d9a5506d2eea9f7e42861806597a846c68..8fa5ed45a0242104f51d9fe78bafee09ae3d687f 100644 (file)
@@ -45,7 +45,7 @@ class Meter;
 class TempoMap;
 
 /** Tempo, the speed at which musical time progresses (BPM). */
-class Tempo {
+class LIBARDOUR_API Tempo {
   public:
        Tempo (double bpm, double type=4.0) // defaulting to quarter note
                : _beats_per_minute (bpm), _note_type(type) {}
@@ -62,7 +62,7 @@ class Tempo {
 };
 
 /** Meter, or time signature (beats per bar, and which note type is a beat). */
-class Meter {
+class LIBARDOUR_API Meter {
   public:
        Meter (double dpb, double bt)
                : _divisions_per_bar (dpb), _note_type (bt) {}
@@ -87,7 +87,7 @@ class Meter {
 };
 
 /** A section of timeline with a certain Tempo or Meter. */
-class MetricSection {
+class LIBARDOUR_API MetricSection {
   public:
        MetricSection (const Timecode::BBT_Time& start)
                : _start (start), _frame (0), _movable (true) {}
@@ -123,7 +123,7 @@ class MetricSection {
 };
 
 /** A section of timeline with a certain Meter. */
-class MeterSection : public MetricSection, public Meter {
+class LIBARDOUR_API MeterSection : public MetricSection, public Meter {
   public:
        MeterSection (const Timecode::BBT_Time& start, double bpb, double note_type)
                : MetricSection (start), Meter (bpb, note_type) {}
@@ -137,7 +137,7 @@ class MeterSection : public MetricSection, public Meter {
 };
 
 /** A section of timeline with a certain Tempo. */
-class TempoSection : public MetricSection, public Tempo {
+class LIBARDOUR_API TempoSection : public MetricSection, public Tempo {
   public:
        TempoSection (const Timecode::BBT_Time& start, double qpm, double note_type)
                : MetricSection (start), Tempo (qpm, note_type), _bar_offset (-1.0)  {}
@@ -170,7 +170,7 @@ typedef std::list<MetricSection*> Metrics;
 /** Helper class to keep track of the Meter *AND* Tempo in effect
     at a given point in time.
 */
-class TempoMetric {
+class LIBARDOUR_API TempoMetric {
   public:
        TempoMetric (const Meter& m, const Tempo& t)
                : _meter (&m), _tempo (&t), _frame (0) {}
@@ -180,6 +180,19 @@ class TempoMetric {
        void set_frame (framepos_t f)                { _frame = f; }
        void set_start (const Timecode::BBT_Time& t) { _start = t; }
 
+       void set_metric (const MetricSection* section) {
+               const MeterSection* meter;
+               const TempoSection* tempo;
+               if ((meter = dynamic_cast<const MeterSection*>(section))) {
+                       set_meter(*meter);
+               } else if ((tempo = dynamic_cast<const TempoSection*>(section))) {
+                       set_tempo(*tempo);
+               }
+
+               set_frame(section->frame());
+               set_start(section->start());
+       }
+
        const Meter&              meter() const { return *_meter; }
        const Tempo&              tempo() const { return *_tempo; }
        framepos_t                frame() const { return _frame; }
@@ -192,7 +205,7 @@ class TempoMetric {
        Timecode::BBT_Time _start;
 };
 
-class TempoMap : public PBD::StatefulDestructible
+class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
 {
   public:
        TempoMap (framecnt_t frame_rate);
@@ -298,7 +311,13 @@ class TempoMap : public PBD::StatefulDestructible
        void clear ();
 
        TempoMetric metric_at (Timecode::BBT_Time bbt) const;
-       TempoMetric metric_at (framepos_t) const;
+
+       /** Return the TempoMetric at frame @p t, and point @p last to the latest
+        * metric change <= t, if it is non-NULL.
+        */
+       TempoMetric metric_at (framepos_t, Metrics::const_iterator* last=NULL) const;
+
+       Metrics::const_iterator metrics_end() { return metrics.end(); }
 
        void change_existing_tempo_at (framepos_t, double bpm, double note_type);
        void change_initial_tempo (double bpm, double note_type);