Ardour  8.12
timeline.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2020 Paul Davis
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #ifndef __libtemporal_timeline_h__
20 #define __libtemporal_timeline_h__
21 
22 #include <ostream>
23 #include <exception>
24 #include <string>
25 #include <cassert>
26 #include <limits>
27 
28 #include "pbd/enumwriter.h"
29 #include "pbd/int62.h"
30 
31 #include "temporal/types.h"
32 #include "temporal/beats.h"
33 #include "temporal/bbt_time.h"
34 #include "temporal/superclock.h"
35 #include "temporal/visibility.h"
36 
37 namespace Temporal {
38 
39 class timecnt_t;
40 
41 void dump_stats (std::ostream&);
42 
43 /* A timepos_t designates an absolute position on the global timeline. It is
44  * measured since time zero, and it can thus only be positive. It is in one of
45  * two TimeDomains: AudioTime (wall time measured using superclock,
46  * proportional to sample count) or BeatTime (counting musical ticks, which are
47  * subdivided quarternotes or Beats). The ratio between these two is the tempo,
48  * which might change over time. Conversion between these time domains is thus
49  * non-trivial and will use the global TempoMap.
50  *
51  * Implemented using a 62 bit positional time value, a flag bit, and a sign bit.
52  * It is is intended to always be positive. If the flag bit is set (i.e. ::flagged() is true), the
53  * numerical value counts musical ticks; otherwise it counts superclocks.
54  */
55 
57  public:
58  timepos_t () : int62_t (false, 0) {}
60 
61  /* for now (Sept2020) do not allow implicit type conversions */
62 
63  explicit timepos_t (samplepos_t s);
64  explicit timepos_t (Temporal::Beats const & b) : int62_t (true, b.to_ticks()) {}
65 
66  explicit timepos_t (timecnt_t const &); /* will throw() if val is negative */
67 
68  /* ticks are int64_t, and superclock_t and samplepos_t are both typedefs of int64_t,
69  * which means we cannot use polymorphism to differentiate them. But it
70  * turns out that we more or less never construct timepos_t from an
71  * integer representing superclocks. So, there's a normal constructor
72  * for the samples case above, and ::from_superclock() here.
73  */
74  static timepos_t from_superclock (superclock_t s) { return timepos_t (false, s); }
75  static timepos_t from_ticks (int64_t t) { return timepos_t (true, t); }
76 
77  static timepos_t zero (bool is_beats) { return timepos_t (is_beats, 0); }
78 
79  bool is_beats() const { return flagged(); }
80  bool is_superclock() const { return !flagged(); }
81 
82  bool is_positive () const { return val() > 0; }
83  bool is_negative () const { return val() < 0; }
84  bool is_zero () const { return val() == 0; }
85  bool operator! () const { return val() == 0; }
86 
87  Temporal::TimeDomain time_domain () const { if (flagged()) return Temporal::BeatTime; return Temporal::AudioTime; }
89 
90  superclock_t superclocks() const { if (is_superclock()) return val(); return _superclocks (); }
91  int64_t samples() const { return superclock_to_samples (superclocks(), TEMPORAL_SAMPLE_RATE); }
92  int64_t ticks() const { if (is_beats()) return val(); return _ticks (); }
93  Beats beats() const { if (is_beats()) return Beats::ticks (val()); return _beats (); }
94 
95  timepos_t & operator= (timecnt_t const & t); /* will throw() if val is negative */
96  timepos_t & operator= (Beats const & b) { v.store (build (true, b.to_ticks())); return *this; }
97  timepos_t & operator= (samplepos_t const & s) { v.store (build (false, samples_to_superclock (s, TEMPORAL_SAMPLE_RATE))); return *this; }
98 
99  timepos_t operator-() const { return timepos_t (int62_t::operator-()); }
100 
101  /* if both values are zero, the time domain doesn't matter */
102  bool operator== (timepos_t const & other) const { return (val() == 0 && other.val() == 0) || (v == other.v); }
103  bool operator!= (timepos_t const & other) const { return (val() != 0 || other.val() != 0) && (v != other.v); }
104 
105 
106  bool operator< (timecnt_t const & other) const;
107  bool operator> (timecnt_t const & other) const;
108  bool operator<= (timecnt_t const & other) const;
109  bool operator>= (timecnt_t const & other) const;
110 
111  bool operator< (timepos_t const & other) const { if (is_beats() == other.is_beats()) return val() < other.val(); return expensive_lt (other); }
112  bool operator> (timepos_t const & other) const { if (is_beats() == other.is_beats()) return val() > other.val(); return expensive_gt (other); }
113  bool operator<= (timepos_t const & other) const { if (is_beats() == other.is_beats()) return val() <= other.val(); return expensive_lte (other); }
114  bool operator>= (timepos_t const & other) const { if (is_beats() == other.is_beats()) return val() >= other.val(); return expensive_gte (other); }
115 
116  timepos_t operator+(timecnt_t const & d) const;
117  timepos_t operator+(timepos_t const & d) const { if (is_beats() == d.is_beats()) return timepos_t (is_beats(), val() + d.val()); return expensive_add (d); }
118 
119  /* don't provide operator+(samplepos_t) or operator+(superclock_t)
120  * because the compiler can't disambiguate them and neither can we.
121  * to add such types, create a timepos_t and then add that.
122  */
123 
124  /* operator-() poses severe and thorny problems for a class that represents position on a timeline.
125  *
126  * If the value of the class is a simple scalar, then subtraction can be used for both:
127  *
128  * 1) movement backwards along the timeline
129  * 2) computing the distance between two positions
130  *
131  * But timepos_t is not a simple scalar, and neither is timecnt_t, and these two operations are quite different.
132  *
133  * 1) movement backwards along the timeline should result in another timepos_t
134  * 2) the distance between two positions is a timecnt_t
135  *
136  * so already we have a hint that we would need at least:
137  *
138  * timepos_t operator- (timecnt_t const &); ... compute new position
139  * timecnt_t operator- (timepos_t const &); ... compute distance
140  *
141  * But what happens we try to use more explicit types. What does this expression mean:
142  *
143  * timepos_t pos;
144  * pos - Beats (3);
145  *
146  * is this computing a new position 3 beats earlier than pos? or is it computing the distance between
147  * pos and the 3rd beat?
148  *
149  * For this reason, we do not provide any operator-() methods, but instead require the use of
150  * explicit methods with clear semantics.
151  */
152 
166  timecnt_t distance (timepos_t const & p) const;
167 
168  /* computes a new position value that is @p d earlier than this */
169  timepos_t earlier (timepos_t const & d) const; /* treat d as distance measured from timeline origin */
170  timepos_t earlier (timecnt_t const & d) const;
171 
172  timepos_t earlier (BBT_Offset const & d) const;
173 
174  /* like ::earlier() but changes this. loosely equivalent to operator-= */
177 
179 
180  /* audio time nominally uses superclocks as its canonical unit. However
181  * many things at a higher level only understand samples. If we
182  * increment or decrement a superclock value by 1, the vast majority of
183  * the time we will still get the same sample value after
184  * conversion. Thus to correctly alter an audio time by an amount
185  * that will manifest as 1 sample's difference, we have to use
186  * samples_to_superclock(1)
187  */
188 
189  /* given the absence of operator- and thus also operator--, return a
190  * timepos_t that is the previous (earlier) possible position given
191  * this one
192  */
193  timepos_t decrement () const { return timepos_t (flagged(),
194  is_beats() ?
195  (val() > 0 ? val() - 1 : 0) : /* reduce by 1 tick */
197 
198  /* purely for reasons of symmetry with ::decrement(), return a
199  * timepos_t that is the next (later) possible position given this one
200  */
201  timepos_t increment () const { return timepos_t (flagged(), (is_beats() ? (val() + 1) : (val() + samples_to_superclock (1, TEMPORAL_SAMPLE_RATE)))); }
202 
203 
206 
208 
209 #if 0 // not implemented, not used
210  timepos_t operator% (timecnt_t const &) const;
211  timepos_t & operator%=(timecnt_t const &);
212 #endif
213 
214  /* Although multiplication and division of positions seems unusual,
215  * these are used in Evoral::Curve when scaling a list of timed events
216  * along the x (time) axis.
217  */
218 
219  timepos_t scale (ratio_t const & n) const;
220 
221  bool operator< (samplepos_t s) { return samples() < s; }
222  bool operator< (Temporal::Beats const & b) { return beats() < b; }
223  bool operator<= (samplepos_t s) { return samples() <= s; }
224  bool operator<= (Temporal::Beats const & b) { return beats() <= b; }
225  bool operator> (samplepos_t s) { return samples() > s; }
226  bool operator> (Temporal::Beats const & b) { return beats() > b; }
227  bool operator>= (samplepos_t s) { return samples() >= s; }
228  bool operator>= (Temporal::Beats const & b) { return beats() >= b; }
229  bool operator== (samplepos_t s) { return samples() == s; }
230  bool operator== (Temporal::Beats const & b) { return beats() == b; }
231  bool operator!= (samplepos_t s) { return samples() != s; }
232  bool operator!= (Temporal::Beats const & b) { return beats() != b; }
233 
234  bool string_to (std::string const & str);
235  std::string str () const;
236 
237  /* note that the value returned if the time domain is audio is larger
238  than can be represented in musical time (for any realistic tempos).
239  */
240  static timepos_t max (TimeDomain td) { if (td == AudioTime) { return timepos_t (false, int62_t::max); } else { return timepos_t (std::numeric_limits<Beats>::max()); }}
241  static timepos_t smallest_step (TimeDomain td) { return timepos_t (td != AudioTime, 1); }
242 
243  private:
244  /* special private constructor for use when constructing timepos_t as a
245  return value using arithmetic ops
246  */
247  explicit timepos_t (bool b, int64_t v) : int62_t (b, v) {}
248  explicit timepos_t (int62_t const & v) : int62_t (v) {}
249 
250  /* these three methods are to be called ONLY when we have already that
251  * the time domain of this timepos_t does not match the desired return
252  * type, and so we will need to go to the tempo map to convert
253  * between domains, which could be expensive.
254  */
255 
257  int64_t _ticks() const;
258  Beats _beats() const;
259 
260  bool expensive_lt (timepos_t const &) const;
261  bool expensive_lte (timepos_t const &) const;
262  bool expensive_gt (timepos_t const &) const;
263  bool expensive_gte(timepos_t const &) const;
264 
265  bool expensive_lt (timecnt_t const &) const;
266  bool expensive_lte (timecnt_t const &) const;
267  bool expensive_gt (timecnt_t const &) const;
268  bool expensive_gte(timecnt_t const &) const;
269 
270  /* used to compute stuff when time domains do not match */
271 
273  timepos_t expensive_add (timepos_t const & s) const;
274 
275  int62_t operator- (int62_t) const { assert (0); return int62_t (false, 0); }
276  int62_t operator- (int64_t) const { assert (0); return int62_t (false, 0); }
277 
278  using int62_t::operator int64_t;
279  using int62_t::operator-=;
280 };
281 
282 
283 /* A timecnt_t (time count) designates a time distance (duration) with origin
284  * at a given absolute position on the global timeline (a timepos_t). It thus
285  * also designates an absolute end position. Both distance and position can
286  * independently be in one of two TimeDomains: AudioTime or BeatTime.
287  * Conversion between these time domains will use the global TempoMap.
288  *
289  * An important distinction between timepos_t and timecnt_t can be thought of
290  * this way: a timepos_t ALWAYS refers to a position relative to the origin of
291  * the timeline (technically, the origin in the tempo map used to translate
292  * between audio and musical domains). By contrast, a timecnt_t refers to a
293  * certain distance beyond some arbitrary (specified) origin. So, a timepos_t
294  * of "3 beats" always means "3 beats measured from the timeline origin". A
295  * timecnt_t of "3 beats" always come with a position, and so is really "3
296  * beats after <position>".
297  *
298  * The ambiguity surrounding operator-() that affects timepos_t does not exist
299  * for timecnt_t: all uses of operator-() are intended to compute the result of
300  * subtracting one timecnt_t from another which will always result in another
301  * timecnt_t of lesser value than the first operand.
302  */
303 
305  public:
306  /* default to zero superclocks @ zero */
307  timecnt_t () : _distance (false, 0), _position (AudioTime) {}
308  timecnt_t (TimeDomain td) : _distance (td != AudioTime, 0), _position (td) {}
309  timecnt_t (timecnt_t const &other) : _distance (other.distance()), _position (other.position()) {}
310 
311  /* construct from sample count (position doesn't matter due to linear nature of audio time) */
312  explicit timecnt_t (samplepos_t s, timepos_t const & pos);
313  explicit timecnt_t (samplepos_t s);
314 
315  /* construct from timeline types */
316  explicit timecnt_t (timepos_t const & d) : _distance (d), _position (timepos_t::zero (d.flagged())) {}
317  explicit timecnt_t (timepos_t const & d, timepos_t const & p) : _distance (d), _position (p) { }
318  explicit timecnt_t (timecnt_t const &, timepos_t const & pos);
319 
320  /* construct from int62_t (which will be flagged or not) and timepos_t */
321  explicit timecnt_t (int62_t d, timepos_t p) : _distance (d), _position (p) {}
322 
323  /* construct from beats */
324  explicit timecnt_t (Temporal::Beats const & b, timepos_t const & pos) : _distance (true, b.to_ticks()), _position (pos) {}
325 
326  static timecnt_t zero (TimeDomain td) { return timecnt_t (timepos_t::zero (td), timepos_t::zero (td)); }
327 
328  /* superclock_t and samplepos_t are the same underlying primitive type,
329  * See comments in timepos_t above.
330  */
331  static timecnt_t from_superclock (superclock_t s, timepos_t const & pos) { return timecnt_t (int62_t (false, s), pos); }
332  static timecnt_t from_ticks (int64_t ticks, timepos_t const & pos) { return timecnt_t (int62_t (true, ticks), pos); }
333 
334  /* Construct from just a distance value - position is assumed to be zero */
335  explicit timecnt_t (Temporal::Beats const & b) : _distance (true, b.to_ticks()), _position (Beats()) {}
338  static timecnt_t from_ticks (int64_t ticks) { return timecnt_t (int62_t (true, ticks), timepos_t::from_ticks (0)); }
339 
340  int64_t magnitude() const { return _distance.val(); }
341  int62_t const & distance() const { return _distance; }
342  timepos_t const & position() const { return _position; }
344  timepos_t end () const { return end (time_domain()); }
345 
346  void set_position (timepos_t const &pos);
347 
348  bool is_positive() const { return _distance.val() > 0; }
349  bool is_negative() const {return _distance.val() < 0; }
350  bool is_zero() const { return _distance.val() == 0; }
351 
352  static timecnt_t const & max() { return _max_timecnt; }
354 
355  timecnt_t abs() const;
356 
357  Temporal::TimeDomain time_domain () const { return _distance.flagged() ? BeatTime : AudioTime; }
359 
360  superclock_t superclocks() const { if (!_distance.flagged()) return _distance.val(); return compute_superclocks(); }
361  int64_t samples() const { return superclock_to_samples (superclocks(), TEMPORAL_SAMPLE_RATE); }
362  Temporal::Beats beats () const { if (_distance.flagged()) return Beats::ticks (_distance.val()); return compute_beats(); }
363  int64_t ticks () const { return beats().to_ticks(); }
364 
365  timecnt_t & operator= (Temporal::Beats const & b) { _distance = int62_t (true, b.to_ticks()); return *this; }
366 
367  /* return a timecnt_t that is the next/previous (earlier/later) possible position given
368  * this one
369  */
370  timecnt_t operator++ () { _distance += 1; return *this; }
371  timecnt_t operator-- () { _distance -= 1; return *this; }
372 
373  timecnt_t scale (ratio_t const &) const;
374 
375  ratio_t operator/ (timecnt_t const &) const;
376 
378  timecnt_t operator- (timecnt_t const & t) const;
379  timecnt_t operator+ (timecnt_t const & t) const;
380 
381  timecnt_t operator- (timepos_t const & t) const;
382  timecnt_t operator+ (timepos_t const & t) const;
383 
384  timecnt_t & operator-= (timecnt_t const & t);
385  timecnt_t & operator+= (timecnt_t const & t);
386 
387  /* audio time nominally uses superclocks as its canonical unit. However
388  * many things at a higher level only understand samples. If we
389  * increment or decrement a superclock value by 1, the vast majority of
390  * the time we will still get the same sample value after
391  * conversion. Thus to correctly alter an audio time by an amount
392  * that will manifest as 1 sample's difference, we have to use
393  * samples_to_superclock(1)
394  */
395 
396  timecnt_t decrement () const { return timecnt_t (_distance.flagged() ? _distance - 1 : _distance - samples_to_superclock (1, TEMPORAL_SAMPLE_RATE), _position); }
397  timecnt_t increment () const { return timecnt_t (_distance.flagged() ? _distance + 1 : _distance + samples_to_superclock (1, TEMPORAL_SAMPLE_RATE), _position); }
398 
399  //timecnt_t operator- (timepos_t const & t) const;
400  //timecnt_t operator+ (timepos_t const & t) const;
401  //timecnt_t & operator-= (timepos_t);
402  //timecnt_t & operator+= (timepos_t);
403 
404  bool operator> (timecnt_t const & other) const { if (_distance.flagged() == other.distance().flagged()) return _distance > other.distance (); else return expensive_gt (other); }
405  bool operator>= (timecnt_t const & other) const { if (_distance.flagged() == other.distance().flagged()) return _distance >= other.distance(); else return expensive_gte (other); }
406  bool operator< (timecnt_t const & other) const { if (_distance.flagged() == other.distance().flagged()) return _distance < other.distance(); else return expensive_lt (other); }
407  bool operator<= (timecnt_t const & other) const { if (_distance.flagged() == other.distance().flagged()) return _distance <= other.distance(); else return expensive_lte (other); }
408 
409  timecnt_t & operator= (timecnt_t const & other) {
410  if (this != &other) {
411  _distance = other.distance();
412  _position = other.position();
413  }
414  return *this;
415  }
416 
417  bool operator!= (timecnt_t const & other) const { return _distance != other.distance() || _position != other.position(); }
418  bool operator== (timecnt_t const & other) const { return _distance == other.distance() && _position == other.position(); }
419 
420  /* test for numerical equivalence with a timepos_T. This tests ONLY the
421  duration in the given domain, NOT position.
422  */
423  bool operator== (timepos_t const & other) const { return _distance == other; }
424 
425  bool operator< (Temporal::samplepos_t s) { return samples() < s; }
426  bool operator< (Temporal::Beats const & b) { return beats() < b; }
427  bool operator<= (Temporal::samplepos_t s) { return samples() <= s; }
428  bool operator<= (Temporal::Beats const & b) { return beats() <= b; }
429  bool operator> (Temporal::samplepos_t s) { return samples() > s; }
430  bool operator> (Temporal::Beats const & b) { return beats() > b; }
431  bool operator>= (Temporal::samplepos_t s) { return samples() >= s; }
432  bool operator>= (Temporal::Beats const & b) { return beats() >= b; }
433  bool operator== (Temporal::samplepos_t s) { return samples() == s; }
434  bool operator== (Temporal::Beats const & b) { return beats() == b; }
435  bool operator!= (Temporal::samplepos_t s) { return samples() != s; }
436  bool operator!= (Temporal::Beats const & b) { return beats() != b; }
437 
438  timecnt_t operator% (timecnt_t const &) const;
440 
441  bool string_to (std::string const & str);
442  std::string str () const;
443 
444  private:
445  int62_t _distance; /* aka "duration" */
446  timepos_t _position; /* aka "origin */
447 
449 
452 
453  bool expensive_lt (timecnt_t const & other) const;
454  bool expensive_lte (timecnt_t const & other) const;
455  bool expensive_gt (timecnt_t const & other) const;
456  bool expensive_gte (timecnt_t const & other) const;
457 };
458 
459 } /* end namespace Temporal */
460 
461 namespace std {
462 LIBTEMPORAL_API std::ostream& operator<< (std::ostream & o, Temporal::timecnt_t const & tc);
463 LIBTEMPORAL_API std::istream& operator>> (std::istream & o, Temporal::timecnt_t & tc);
464 LIBTEMPORAL_API std::ostream& operator<< (std::ostream & o, Temporal::timepos_t const & tp);
465 LIBTEMPORAL_API std::istream& operator>> (std::istream & o, Temporal::timepos_t & tp);
466 }
467 
468 #if 0
469 inline static bool operator< (Temporal::samplepos_t s, Temporal::timepos_t const & t) { return s < t.samples(); }
470 inline static bool operator< (Temporal::Beats const & b, Temporal::timepos_t const & t) { return b < t.beats(); }
471 
472 inline static bool operator<= (Temporal::samplepos_t s, Temporal::timepos_t const & t) { return s <= t.samples(); }
473 inline static bool operator<= (Temporal::Beats const & b, Temporal::timepos_t const & t) { return b <= t.beats(); }
474 
475 inline static bool operator> (Temporal::samplepos_t s, Temporal::timepos_t const & t) { return s > t.samples(); }
476 inline static bool operator> (Temporal::Beats const & b, Temporal::timepos_t const & t) { return b > t.beats(); }
477 
478 inline static bool operator>= (Temporal::samplepos_t s, Temporal::timepos_t const & t) { return s >= t.samples(); }
479 inline static bool operator>= (Temporal::Beats const & b, Temporal::timepos_t const & t) { return b >= t.beats(); }
480 
481 #ifdef TEMPORAL_DOMAIN_WARNING
482 #undef TEMPORAL_DOMAIN_WARNING
483 #endif
484 
485 #define TEMPORAL_DOMAIN_WARNING(d) if (t.time_domain() != (d)) std::cerr << "DOMAIN CONVERSION WARNING IN COMPARATOR with t.domain = " << enum_2_string (t.time_domain()) << " not " << enum_2_string (d) << std::endl;
486 
487 inline static bool operator< (Temporal::samplepos_t s, Temporal::timecnt_t const & t) { TEMPORAL_DOMAIN_WARNING (Temporal::AudioTime); return s < t.samples(); }
488 inline static bool operator< (Temporal::Beats const & b, Temporal::timecnt_t const & t) { TEMPORAL_DOMAIN_WARNING (Temporal::BeatTime); return b < t.beats(); }
489 
490 inline static bool operator<= (Temporal::samplepos_t s, Temporal::timecnt_t const & t) { TEMPORAL_DOMAIN_WARNING (Temporal::AudioTime); return s <= t.samples(); }
491 inline static bool operator<= (Temporal::Beats const & b, Temporal::timecnt_t const & t) { TEMPORAL_DOMAIN_WARNING (Temporal::BeatTime); return b <= t.beats(); }
492 
493 inline static bool operator> (Temporal::samplepos_t s, Temporal::timecnt_t const & t) { TEMPORAL_DOMAIN_WARNING (Temporal::AudioTime); return s > t.samples(); }
494 inline static bool operator> (Temporal::Beats const & b, Temporal::timecnt_t const & t) { TEMPORAL_DOMAIN_WARNING (Temporal::BeatTime); return b > t.beats(); }
495 
496 inline static bool operator>= (Temporal::samplepos_t s, Temporal::timecnt_t const & t) { TEMPORAL_DOMAIN_WARNING (Temporal::AudioTime); return s >= t.samples(); }
497 inline static bool operator>= (Temporal::Beats const & b, Temporal::timecnt_t const & t) { TEMPORAL_DOMAIN_WARNING (Temporal::BeatTime); return b >= t.beats(); }
498 #endif
499 
500 #undef TEMPORAL_DOMAIN_WARNING
501 
502 #endif /* __libtemporal_timeline_h__ */
bool operator<(const TextIter &lhs, const TextIter &rhs)
bool operator>=(const TextIter &lhs, const TextIter &rhs)
bool operator<=(const TextIter &lhs, const TextIter &rhs)
bool operator>(const TextIter &lhs, const TextIter &rhs)
static Beats ticks(int64_t ticks)
Definition: beats.h:88
int64_t to_ticks() const
Definition: beats.h:103
void set_position(timepos_t const &pos)
bool is_positive() const
Definition: timeline.h:348
Temporal::Beats beats() const
Definition: timeline.h:362
timecnt_t(samplepos_t s)
timecnt_t(timecnt_t const &other)
Definition: timeline.h:309
static timecnt_t max(Temporal::TimeDomain td)
Definition: timeline.h:353
static timecnt_t from_samples(samplepos_t s)
Definition: timeline.h:337
bool expensive_lte(timecnt_t const &other) const
Temporal::TimeDomain time_domain() const
Definition: timeline.h:357
void set_time_domain(Temporal::TimeDomain)
Beats compute_beats() const
bool expensive_lt(timecnt_t const &other) const
static timecnt_t from_superclock(superclock_t s)
Definition: timeline.h:336
timecnt_t(timepos_t const &d)
Definition: timeline.h:316
timecnt_t operator-() const
superclock_t compute_superclocks() const
int64_t ticks() const
Definition: timeline.h:363
bool is_negative() const
Definition: timeline.h:349
timepos_t const & position() const
Definition: timeline.h:342
timecnt_t decrement() const
Definition: timeline.h:396
bool expensive_gte(timecnt_t const &other) const
std::string str() const
timecnt_t(timepos_t const &d, timepos_t const &p)
Definition: timeline.h:317
static timecnt_t from_ticks(int64_t ticks)
Definition: timeline.h:338
static timecnt_t from_superclock(superclock_t s, timepos_t const &pos)
Definition: timeline.h:331
timepos_t end(TimeDomain) const
int64_t magnitude() const
Definition: timeline.h:340
timecnt_t(samplepos_t s, timepos_t const &pos)
timecnt_t & operator%=(timecnt_t const &)
bool string_to(std::string const &str)
timecnt_t(Temporal::Beats const &b)
Definition: timeline.h:335
timepos_t end() const
Definition: timeline.h:344
timecnt_t(Temporal::Beats const &b, timepos_t const &pos)
Definition: timeline.h:324
static timecnt_t zero(TimeDomain td)
Definition: timeline.h:326
bool expensive_gt(timecnt_t const &other) const
timecnt_t(timecnt_t const &, timepos_t const &pos)
timecnt_t scale(ratio_t const &) const
timecnt_t(int62_t d, timepos_t p)
Definition: timeline.h:321
int64_t samples() const
Definition: timeline.h:361
timecnt_t(TimeDomain td)
Definition: timeline.h:308
static timecnt_t from_ticks(int64_t ticks, timepos_t const &pos)
Definition: timeline.h:332
int62_t const & distance() const
Definition: timeline.h:341
superclock_t superclocks() const
Definition: timeline.h:360
timecnt_t increment() const
Definition: timeline.h:397
timecnt_t abs() const
bool is_zero() const
Definition: timeline.h:350
static timecnt_t const & max()
Definition: timeline.h:352
timepos_t _position
Definition: timeline.h:446
static timecnt_t _max_timecnt
Definition: timeline.h:448
timepos_t increment() const
Definition: timeline.h:201
int64_t ticks() const
Definition: timeline.h:92
superclock_t superclocks() const
Definition: timeline.h:90
timepos_t & shift_earlier(timecnt_t const &d)
timepos_t scale(ratio_t const &n) const
static timepos_t max(TimeDomain td)
Definition: timeline.h:240
timepos_t & shift_earlier(Temporal::BBT_Offset const &)
timepos_t earlier(BBT_Offset const &d) const
timepos_t(samplepos_t s)
timepos_t earlier(timepos_t const &d) const
timepos_t(timecnt_t const &)
timepos_t decrement() const
Definition: timeline.h:193
timepos_t & shift_earlier(timepos_t const &d)
static timepos_t from_ticks(int64_t t)
Definition: timeline.h:75
bool is_superclock() const
Definition: timeline.h:80
timepos_t operator-() const
Definition: timeline.h:99
bool is_beats() const
Definition: timeline.h:79
timepos_t & operator+=(timecnt_t const &d)
timepos_t(int62_t const &v)
Definition: timeline.h:248
timepos_t(Temporal::Beats const &b)
Definition: timeline.h:64
timepos_t expensive_add(timepos_t const &s) const
int64_t _ticks() const
timepos_t(bool b, int64_t v)
Definition: timeline.h:247
bool expensive_lt(timecnt_t const &) const
Beats beats() const
Definition: timeline.h:93
Temporal::TimeDomain time_domain() const
Definition: timeline.h:87
bool expensive_gt(timecnt_t const &) const
bool expensive_lt(timepos_t const &) const
bool is_zero() const
Definition: timeline.h:84
timepos_t & operator+=(timepos_t const &d)
bool expensive_lte(timecnt_t const &) const
static timepos_t zero(bool is_beats)
Definition: timeline.h:77
bool string_to(std::string const &str)
static timepos_t from_superclock(superclock_t s)
Definition: timeline.h:74
bool expensive_gte(timecnt_t const &) const
bool is_negative() const
Definition: timeline.h:83
bool is_positive() const
Definition: timeline.h:82
timepos_t operator+(timepos_t const &d) const
Definition: timeline.h:117
superclock_t _superclocks() const
timepos_t(TimeDomain d)
Definition: timeline.h:59
bool expensive_gte(timepos_t const &) const
bool expensive_lte(timepos_t const &) const
timepos_t & operator+=(Temporal::BBT_Offset const &)
std::string str() const
static timepos_t smallest_step(TimeDomain td)
Definition: timeline.h:241
void set_time_domain(Temporal::TimeDomain)
timecnt_t distance(timepos_t const &p) const
timecnt_t expensive_distance(timepos_t const &p) const
timepos_t earlier(timecnt_t const &d) const
bool expensive_gt(timepos_t const &) const
Beats _beats() const
timepos_t operator+(timecnt_t const &d) const
int64_t samples() const
Definition: timeline.h:91
Definition: int62.h:37
static bool flagged(int64_t v)
Definition: int62.h:54
static const int64_t max
Definition: int62.h:66
std::atomic< int64_t > v
Definition: int62.h:44
int64_t val() const
Definition: int62.h:70
PBD::PropertyDescriptor< Temporal::TimeDomain > time_domain
Temporal::timecnt_t timecnt_t
Temporal::timepos_t timepos_t
static superclock_t superclock_to_samples(superclock_t s, int sr)
Definition: superclock.h:49
static superclock_t samples_to_superclock(int64_t samples, int sr)
Definition: superclock.h:50
void dump_stats(std::ostream &)
int64_t superclock_t
Definition: superclock.h:35
bool operator==(const ProcessorSelection &a, const ProcessorSelection &b)
#define TEMPORAL_SAMPLE_RATE
Definition: superclock.h:59
#define LIBTEMPORAL_API