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