Optimize automation-event process splitting
[ardour.git] / nutemp / t.h
1 #ifndef __ardour_tempo_h__
2 #define __ardour_tempo_h__
3
4 #include <list>
5 #include <string>
6 #include <vector>
7 #include <cmath>
8 #include <exception>
9
10 #include <glibmm/threads.h>
11
12 #include "pbd/signals.h"
13
14 #include "temporal/beats.h"
15
16 #include "ardour/ardour.h"
17 #include "ardour/superclock.h"
18
19 #include "temporal/bbt_time.h"
20
21 namespace ARDOUR {
22
23 class Meter;
24 class TempoMap;
25
26 /** Tempo, the speed at which musical time progresses (BPM).
27  */
28
29 class LIBARDOUR_API Tempo {
30   public:
31         /**
32          * @param npm Note Types per minute
33          * @param type Note Type (default `4': quarter note)
34          */
35         Tempo (double npm, int type = 4) : _superclocks_per_note_type (double_npm_to_sc (npm)), _note_type (type) {}
36
37         /* these two methods should only be used to show and collect information to the user (for whom
38          * bpm as a floating point number is the obvious representation)
39          */
40         double note_types_per_minute () const { return (superclock_ticks_per_second * 60.0) / _superclocks_per_note_type; }
41         void set_note_types_per_minute (double npm) { _superclocks_per_note_type = double_npm_to_sc (npm); }
42
43         int note_type () const { return _note_type; }
44
45         superclock_t superclocks_per_note_type () const {
46                 return _superclocks_per_note_type;
47         }
48         superclock_t superclocks_per_note_type (int note_type) const {
49                 return (_superclocks_per_note_type * _note_type) / note_type;
50         }
51         superclock_t superclocks_per_quarter_note () const {
52                 return superclocks_per_note_type (4);
53         }
54
55         Tempo& operator=(Tempo const& other) {
56                 if (&other != this) {
57                         _superclocks_per_note_type = other._superclocks_per_note_type;
58                         _note_type = other._note_type;
59                 }
60                 return *this;
61         }
62
63   protected:
64         superclock_t _superclocks_per_note_type;
65         int8_t       _note_type;
66
67         static inline double       sc_to_double_npm (superclock_t sc) { return (superclock_ticks_per_second * 60.0) / sc; }
68         static inline superclock_t double_npm_to_sc (double npm) { return llrint ((superclock_ticks_per_second / npm) * 60.0); }
69 };
70
71 /** Meter, or time signature (subdivisions per bar, and which note type is a single subdivision). */
72 class LIBARDOUR_API Meter {
73   public:
74         Meter (int8_t dpb, int8_t nv) : _note_value (nv), _divisions_per_bar (dpb) {}
75
76         int divisions_per_bar () const { return _divisions_per_bar; }
77         int note_value() const { return _note_value; }
78
79         inline bool operator==(const Meter& other) { return _divisions_per_bar == other.divisions_per_bar() && _note_value == other.note_value(); }
80         inline bool operator!=(const Meter& other) { return _divisions_per_bar != other.divisions_per_bar() || _note_value != other.note_value(); }
81
82         Meter& operator=(Meter const & other) {
83                 if (&other != this) {
84                         _divisions_per_bar = other._divisions_per_bar;
85                         _note_value = other._note_value;
86                 }
87                 return *this;
88         }
89
90         Timecode::BBT_Time   bbt_add (Timecode::BBT_Time const & bbt, Timecode::BBT_Offset const & add) const;
91         Timecode::BBT_Time   bbt_subtract (Timecode::BBT_Time const & bbt, Timecode::BBT_Offset const & sub) const;
92         Timecode::BBT_Offset bbt_delta (Timecode::BBT_Time const & bbt, Timecode::BBT_Time const & sub) const;
93
94         Timecode::BBT_Time round_up_to_bar (Timecode::BBT_Time const &) const;
95         Timecode::BBT_Time round_down_to_bar (Timecode::BBT_Time const &) const;
96         Timecode::BBT_Time round_to_bar (Timecode::BBT_Time const &) const;
97
98         Temporal::Beats to_quarters (Timecode::BBT_Offset const &) const;
99
100   protected:
101         /** The type of "note" that a division represents.  For example, 4 is
102             a quarter (crotchet) note, 8 is an eighth (quaver) note, etc.
103         */
104         int8_t _note_value;
105         /* how many of '_note_value' make up a bar or measure */
106         int8_t _divisions_per_bar;
107 };
108
109 /** Helper class to keep track of the Meter *AND* Tempo in effect
110     at a given point in time.
111 */
112 class LIBARDOUR_API TempoMetric : public Tempo, public Meter {
113   public:
114         TempoMetric (Tempo const & t, Meter const & m, bool ramp) : Tempo (t), Meter (m), _c_per_quarter (0.0), _c_per_superclock (0.0), _ramped (ramp) {}
115         ~TempoMetric () {}
116
117         double c_per_superclock () const { return _c_per_superclock; }
118         double c_per_quarter () const { return _c_per_quarter; }
119
120         void compute_c_superclock (samplecnt_t sr, superclock_t end_superclocks_per_note_type, superclock_t duration);
121         void compute_c_quarters (samplecnt_t sr, superclock_t end_superclocks_per_note_type, Temporal::Beats const & duration);
122
123         superclock_t superclocks_per_bar (samplecnt_t sr) const;
124         superclock_t superclocks_per_grid (samplecnt_t sr) const;
125
126         superclock_t superclock_at_qn (Temporal::Beats const & qn) const;
127         superclock_t superclock_per_note_type_at_superclock (superclock_t) const;
128
129         bool ramped () const { return _ramped; }
130         void set_ramped (bool yn) { _ramped = yn; } /* caller must mark something dirty to force recompute */
131
132   private:
133         double _c_per_quarter;
134         double _c_per_superclock;
135         bool   _ramped;
136 };
137
138 /** Tempo Map - mapping of timecode to musical time.
139  * convert audio-samples, sample-rate to Bar/Beat/Tick, Meter/Tempo
140  */
141
142 /* TempoMap concepts
143
144    we have several different ways of talking about time:
145
146    * PULSE : whole notes, just because. These are linearly related to any other
147              note type, so if you know a number of pulses (whole notes), you
148              know the corresponding number of any other note type (e.g. quarter
149              notes).
150
151    * QUARTER NOTES : just what the name says. A lot of MIDI software and
152                      concepts assume that a "beat" is a quarter-note.
153
154    * BEAT : a fraction of a PULSE. Defined by the meter in effect, so requires
155             meter (time signature) information to convert to/from PULSE or QUARTER NOTES.
156             In a 5/8 time, a BEAT is 1/8th note. In a 4/4 time, a beat is quarter note.
157             This means that measuring time in BEATS is potentially non-linear (if
158             the time signature changes, there will be a different number of BEATS
159             corresponding to a given time in any other unit).
160
161    * SUPERCLOCK : a very high resolution clock whose frequency
162                   has as factors all common sample rates and all common note
163                   type divisors. Related to MINUTES or SAMPLES only when a
164                   sample rate is known. Related to PULSE or QUARTER NOTES only
165                   when a tempo is known.
166
167    * MINUTES : wallclock time measurement. related to SAMPLES or SUPERCLOCK
168                only when a sample rate is known.
169
170
171    * SAMPLES : audio time measurement. Related to MINUTES or SUPERCLOCK only
172                when a sample rate is known
173
174    * BBT : bars|beats|ticks ... linearly related to BEATS but with the added
175            semantics of bars ("measures") added, in which beats are broken up
176            into groups of bars ("measures"). Requires meter (time signature)
177            information to compute to/from a given BEATS value. Contains no
178            additional time information compared to BEATS, but does have
179            additional semantic information.
180
181   Nick sez: not every note onset is on a tick
182   Paul wonders: if it's 8 samples off, does it matter?
183   Nick sez: it should not phase with existing audio
184
185  */
186
187 class LIBARDOUR_API TempoMapPoint
188 {
189   public:
190         enum Flag {
191                 ExplicitTempo = 0x1,
192                 ExplicitMeter = 0x2,
193         };
194
195         TempoMapPoint (Flag f, Tempo const& t, Meter const& m, superclock_t sc, Temporal::Beats const & q, Timecode::BBT_Time const & bbt, PositionLockStyle psl, bool ramp = false)
196                 : _flags (f), _explicit (t, m, psl, ramp), _sclock (sc), _quarters (q), _bbt (bbt), _dirty (true), _map (0) {}
197         TempoMapPoint (TempoMapPoint const & tmp, superclock_t sc, Temporal::Beats const & q, Timecode::BBT_Time const & bbt)
198                 : _flags (Flag (0)), _reference (&tmp), _sclock (sc), _quarters (q), _bbt (bbt), _dirty (true), _map (0) {}
199         ~TempoMapPoint () {}
200
201         void set_map (TempoMap* m);
202
203         Flag flags() const       { return _flags; }
204         bool is_explicit() const { return _flags != Flag (0); }
205         bool is_implicit() const { return _flags == Flag (0); }
206
207         superclock_t superclocks_per_note_type (int8_t note_type) const {
208                 if (is_explicit()) {
209                         return _explicit.metric.superclocks_per_note_type (note_type);
210                 }
211                 return _reference->superclocks_per_note_type (note_type);
212         }
213
214         struct BadTempoMetricLookup : public std::exception {
215                 virtual const char* what() const throw() { return "cannot obtain non-const Metric from implicit map point"; }
216         };
217
218         bool                dirty()  const { return _dirty; }
219
220         superclock_t        sclock() const      { return _sclock; }
221         Temporal::Beats const & quarters() const  { return _quarters; }
222         Timecode::BBT_Time  const & bbt() const { return _bbt; }
223         bool                ramped() const      { return metric().ramped(); }
224         TempoMetric const & metric() const      { return is_explicit() ? _explicit.metric : _reference->metric(); }
225         PositionLockStyle   lock_style() const  { return is_explicit() ? _explicit.lock_style : _reference->lock_style(); }
226
227         void compute_c_superclock (samplecnt_t sr, superclock_t end_superclocks_per_note_type, superclock_t duration) { if (is_explicit()) { _explicit.metric.compute_c_superclock (sr, end_superclocks_per_note_type, duration); } }
228         void compute_c_quarters (samplecnt_t sr, superclock_t end_superclocks_per_note_type, Temporal::Beats const & duration) { if (is_explicit()) { _explicit.metric.compute_c_quarters (sr, end_superclocks_per_note_type, duration); } }
229
230         /* None of these properties can be set for an Implicit point, because
231          * they are determined by the TempoMapPoint pointed to by _reference.
232          */
233
234         void set_sclock (superclock_t  sc) { if (is_explicit()) { _sclock = sc; _dirty = true; } }
235         void set_quarters (Temporal::Beats const & q) { if (is_explicit()) { _quarters = q; _dirty = true;  } }
236         void set_bbt (Timecode::BBT_Time const & bbt) {  if (is_explicit()) { _bbt = bbt; _dirty = true;  } }
237         void set_dirty (bool yn);
238         void set_lock_style (PositionLockStyle psl) {  if (is_explicit()) { _explicit.lock_style = psl; _dirty = true; } }
239
240         void make_explicit (Flag f) {
241                 _flags = Flag (_flags|f);
242                 /* since _metric and _reference are part of an anonymous union,
243                    avoid possible compiler glitches by copying to a stack
244                    variable first, then assign.
245                 */
246                 TempoMetric tm (_explicit.metric);
247                 _explicit.metric = tm;
248                 _dirty = true;
249         }
250
251         void make_implicit (TempoMapPoint & tmp) { _flags = Flag (0); _reference = &tmp; }
252
253         Temporal::Beats quarters_at (superclock_t sc) const;
254         Temporal::Beats quarters_at (Timecode::BBT_Time const &) const;
255
256         Timecode::BBT_Time bbt_at (Temporal::Beats const &) const;
257
258 #if 0
259         XMLNode& get_state() const;
260         int set_state (XMLNode const&, int version);
261 #endif
262
263         struct SuperClockComparator {
264                 bool operator() (TempoMapPoint const & a, TempoMapPoint const & b) const { return a.sclock() < b.sclock(); }
265         };
266
267         struct QuarterComparator {
268                 bool operator() (TempoMapPoint const & a, TempoMapPoint const & b) const { return a.quarters() < b.quarters(); }
269         };
270
271         struct BBTComparator {
272                 bool operator() (TempoMapPoint const & a, TempoMapPoint const & b) const { return a.bbt() < b.bbt(); }
273         };
274
275   protected:
276         friend class TempoMap;
277         void map_reset_set_sclock_for_sr_change (superclock_t sc) { _sclock = sc; }
278
279   private:
280         struct ExplicitInfo {
281                 ExplicitInfo (Tempo const & t, Meter const & m, PositionLockStyle psl, bool ramp) : metric (t, m, ramp), lock_style (psl) {}
282
283                 TempoMetric       metric;
284                 PositionLockStyle lock_style;
285         };
286
287         Flag                  _flags;
288         union {
289                 TempoMapPoint const * _reference;
290                 ExplicitInfo          _explicit;
291         };
292         superclock_t          _sclock;
293         Temporal::Beats       _quarters;
294         Timecode::BBT_Time    _bbt;
295         bool                  _dirty;
296         TempoMap*             _map;
297 };
298
299 typedef std::list<TempoMapPoint> TempoMapPoints;
300
301 class LIBARDOUR_API TempoMap
302 {
303    public:
304         TempoMap (Tempo const & initial_tempo, Meter const & initial_meter, samplecnt_t sr);
305
306         void set_dirty (bool yn);
307
308         void set_sample_rate (samplecnt_t sr);
309         samplecnt_t sample_rate() const { return _sample_rate; }
310
311         void remove_explicit_point (superclock_t);
312
313         bool move_to (superclock_t current, superclock_t destination, bool push = false);
314
315         bool set_tempo_and_meter (Tempo const &, Meter const &, superclock_t, bool ramp, bool flexible);
316
317         bool set_tempo (Tempo const &, Timecode::BBT_Time const &, bool ramp = false);
318         bool set_tempo (Tempo const &, superclock_t, bool ramp = false);
319
320         bool set_meter (Meter const &, Timecode::BBT_Time const &);
321         bool set_meter (Meter const &, superclock_t);
322
323         Meter const & meter_at (superclock_t sc) const;
324         Meter const & meter_at (Temporal::Beats const & b) const;
325         Meter const & meter_at (Timecode::BBT_Time const & bbt) const;
326         Tempo const & tempo_at (superclock_t sc) const;
327         Tempo const & tempo_at (Temporal::Beats const &b) const;
328         Tempo const & tempo_at (Timecode::BBT_Time const & bbt) const;
329
330         Timecode::BBT_Time bbt_at (superclock_t sc) const;
331         Timecode::BBT_Time bbt_at (Temporal::Beats const &) const;
332         Temporal::Beats quarter_note_at (superclock_t sc) const;
333         Temporal::Beats quarter_note_at (Timecode::BBT_Time const &) const;
334         superclock_t superclock_at (Temporal::Beats const &) const;
335         superclock_t superclock_at (Timecode::BBT_Time const &) const;
336
337         TempoMapPoint const & const_point_at (superclock_t sc) const { return *const_iterator_at (sc); }
338         TempoMapPoint const & const_point_at (Temporal::Beats const & b) const { return *const_iterator_at (b); }
339         TempoMapPoint const & const_point_at (Timecode::BBT_Time const & bbt) const { return *const_iterator_at (bbt); }
340
341         TempoMapPoint const & const_point_after (superclock_t sc) const;
342         TempoMapPoint const & const_point_after (Temporal::Beats const & b) const;
343         TempoMapPoint const & const_point_after (Timecode::BBT_Time const & bbt) const;
344
345         /* If resolution == Temporal::Beats() (i.e. zero), then the grid that is
346            returned will contain a mixture of implicit and explicit points,
347            and will only be valid as long as this map remains unchanged
348            (because the implicit points may reference explicit points in the
349            map.
350
351            If resolution != Temporal::Beats() (i.e. non-zero), then the in-out @param
352            grid will contain only explicit points that do not reference this
353            map in anyway.
354         */
355         void get_grid (TempoMapPoints& points, superclock_t start, superclock_t end, Temporal::Beats const & resolution);
356
357         void get_bar_grid (TempoMapPoints& points, superclock_t start, superclock_t end, int32_t bar_gap);
358
359         struct EmptyTempoMapException : public std::exception {
360                 virtual const char* what() const throw() { return "TempoMap is empty"; }
361         };
362
363         void dump (std::ostream&);
364         void rebuild (superclock_t limit);
365
366         PBD::Signal2<void,superclock_t,superclock_t> Changed;
367
368    private:
369         TempoMapPoints _points;
370         samplecnt_t     _sample_rate;
371         mutable Glib::Threads::RWLock _lock;
372         bool _dirty;
373
374         /* these return an iterator that refers to the TempoMapPoint at or most immediately preceding the given position.
375          *
376          * Conceptually, these could be const methods, but C++ prevents them returning a non-const iterator in that case.
377          *
378          * Note that they cannot return an invalid iterator (e.g. _points.end()) because:
379          *
380          *    - if the map is empty, an exception is thrown
381          *    - if the given time is before the first map entry, _points.begin() is returned
382          *    - if the given time is after the last map entry, the equivalent of _points.rbegin() is returned
383          *    - if the given time is within the map entries, a valid iterator will be returned
384          */
385
386         TempoMapPoints::iterator iterator_at (superclock_t sc);
387         TempoMapPoints::iterator iterator_at (Temporal::Beats const &);
388         TempoMapPoints::iterator iterator_at (Timecode::BBT_Time const &);
389
390         TempoMapPoints::const_iterator const_iterator_at (superclock_t sc) const { return const_cast<TempoMap*>(this)->iterator_at (sc); }
391         TempoMapPoints::const_iterator const_iterator_at (Temporal::Beats const & b) const { return const_cast<TempoMap*>(this)->iterator_at (b); }
392         TempoMapPoints::const_iterator const_iterator_at (Timecode::BBT_Time const & bbt) const { return const_cast<TempoMap*>(this)->iterator_at (bbt); }
393
394         /* Returns the TempoMapPoint at or most immediately preceding the given time. If the given time is
395          * before the first map entry, then the first map entry will be returned, which underlies the semantics
396          * that the first map entry's values propagate backwards in time if not at absolute zero.
397          *
398          * As for iterator_at(), define both const+const and non-const variants, because C++ won't let us return a non-const iterator
399            from a const method (which is a bit silly, but presumably aids compiler reasoning).
400         */
401
402         TempoMapPoint & point_at (superclock_t sc) { return *iterator_at (sc); }
403         TempoMapPoint & point_at (Temporal::Beats const & b) { return *iterator_at (b); }
404         TempoMapPoint & point_at (Timecode::BBT_Time const & bbt) { return *iterator_at (bbt); }
405
406         Meter const & meter_at_locked (superclock_t sc) const { return const_point_at (sc).metric(); }
407         Meter const & meter_at_locked (Temporal::Beats const & b) const { return const_point_at (b).metric(); }
408         Meter const & meter_at_locked (Timecode::BBT_Time const & bbt) const { return const_point_at (bbt).metric(); }
409         Tempo const & tempo_at_locked (superclock_t sc) const { return const_point_at (sc).metric(); }
410         Tempo const & tempo_at_locked (Temporal::Beats const &b) const { return const_point_at (b).metric(); }
411         Tempo const & tempo_at_locked (Timecode::BBT_Time const & bbt) const { return const_point_at (bbt).metric(); }
412         Timecode::BBT_Time bbt_at_locked (superclock_t sc) const;
413         Timecode::BBT_Time bbt_at_locked (Temporal::Beats const &) const;
414         Temporal::Beats quarter_note_at_locked (superclock_t sc) const;
415         Temporal::Beats quarter_note_at_locked (Timecode::BBT_Time const &) const;
416         superclock_t superclock_at_locked (Temporal::Beats const &) const;
417         superclock_t superclock_at_locked (Timecode::BBT_Time const &) const;
418
419         void rebuild_locked (superclock_t limit);
420         void dump_locked (std::ostream&);
421 };
422
423 }
424
425 std::ostream& operator<<(std::ostream&, ARDOUR::TempoMapPoint const &);
426 std::ostream& operator<<(std::ostream&, ARDOUR::Tempo const &);
427 std::ostream& operator<<(std::ostream&, ARDOUR::Meter const &);
428
429 #endif /* __ardour_tempo_h__ */