diff --git a/libs/temporal/tempo.cc b/libs/temporal/tempo.cc index 05bc4f205d..a72ae13417 100644 --- a/libs/temporal/tempo.cc +++ b/libs/temporal/tempo.cc @@ -2263,7 +2263,7 @@ TempoMap::full_duration_at (timepos_t const & pos, timecnt_t const & duration, T break; case AudioTime: /* Determine beats at sc pos, so that we can add beats */ - p = metric_at (pos).quarters_at (pos.superclocks()); + p = timepos_t (metric_at (pos).quarters_at (pos.superclocks())); break; } /* add beats */ @@ -2287,7 +2287,7 @@ TempoMap::full_duration_at (timepos_t const & pos, timecnt_t const & duration, T break; case BeatTime: /* determined sc at beat position so we can add superclocks */ - p = metric_at (pos).superclock_at (pos.beats()); + p = timepos_t (metric_at (pos).sample_at (pos.beats())); break; } /* add superclocks */ diff --git a/libs/temporal/temporal/tempo.h b/libs/temporal/temporal/tempo.h index 79c7a85542..bbaad10589 100644 --- a/libs/temporal/temporal/tempo.h +++ b/libs/temporal/temporal/tempo.h @@ -374,14 +374,16 @@ class LIBTEMPORAL_API TempoPoint : public Tempo, public Point return *this; } + /* Given that this tempo point controls tempo for the time indicated by + * the argument of the following 4 functions, return information about + * that time. The first 3 return convert between domains (with + * ::sample_at() just being a convenience function); the fourth returns + * information about the tempo at that time. + */ + superclock_t superclock_at (Beats const & qn) const; - - void compute_omega (samplecnt_t sr, superclock_t end_superclocks_per_note_type, Beats const & duration); - - bool actually_ramped () const { return Tempo::ramped() && (_omega != 0); } - - Beats quarters_at (superclock_t sc) const; - + samplepos_t sample_at (Beats const & qn) const { return Temporal::superclock_to_samples (superclock_at (qn), _thread_sample_rate); } + Beats quarters_at (superclock_t sc) const; superclock_t superclocks_per_note_type_at (timepos_t const &) const; /* This method should be used only for display purposes, and even @@ -393,6 +395,10 @@ class LIBTEMPORAL_API TempoPoint : public Tempo, public Point return (superclock_ticks_per_second * 60.0) / superclocks_per_note_type_at (pos); } + double omega() const { return _omega; } + void compute_omega (samplecnt_t sr, superclock_t end_superclocks_per_note_type, Beats const & duration); + bool actually_ramped () const { return Tempo::ramped() && (_omega != 0); } + XMLNode& get_state () const; int set_state (XMLNode const&, int version); @@ -403,8 +409,6 @@ class LIBTEMPORAL_API TempoPoint : public Tempo, public Point return Tempo::operator!= (other) || Point::operator!= (other); } - double omega() const { return _omega; } - boost::intrusive::list_member_hook<> _tempo_hook; private: @@ -439,9 +443,10 @@ class LIBTEMPORAL_API TempoMetric { */ superclock_t superclock_at (Beats const & qn) const { return _tempo->superclock_at (qn); } - Beats quarters_at (superclock_t sc) const { return _tempo->quarters_at (sc); } - Beats quarters_at (BBT_Time const & bbt) const { return _meter->quarters_at (bbt); } - BBT_Time bbt_at (Beats const & beats) const { return _meter->bbt_at (beats); } + samplepos_t sample_at (Beats const & qn) const { return _tempo->sample_at (qn); } + Beats quarters_at (superclock_t sc) const { return _tempo->quarters_at (sc); } + Beats quarters_at (BBT_Time const & bbt) const { return _meter->quarters_at (bbt); } + BBT_Time bbt_at (Beats const & beats) const { return _meter->bbt_at (beats); } superclock_t superclocks_per_note_type () const { return _tempo->superclocks_per_note_type (); } superclock_t end_superclocks_per_note_type () const {return _tempo->end_superclocks_per_note_type (); } diff --git a/libs/temporal/temporal/timeline.h b/libs/temporal/temporal/timeline.h index 0eb52d0ca9..37266e153a 100644 --- a/libs/temporal/temporal/timeline.h +++ b/libs/temporal/temporal/timeline.h @@ -51,9 +51,10 @@ class LIBTEMPORAL_API timepos_t : public int62_t { /* for now (Sept2020) do not allow implicit type conversions */ explicit timepos_t (samplepos_t s) : int62_t (false, samples_to_superclock (s, _thread_sample_rate)) {} - explicit timepos_t (timecnt_t const &); /* will throw() if val is negative */ explicit timepos_t (Temporal::Beats const & b) : int62_t (false, b.to_ticks()) {} + explicit timepos_t (timecnt_t const &); /* will throw() if val is negative */ + /* superclock_t and samplepos_t are the same underlying primitive type, * which means we cannot use polymorphism to differentiate them. But it * turns out that we more or less never construct timepos_t from an @@ -75,13 +76,11 @@ class LIBTEMPORAL_API timepos_t : public int62_t { Temporal::TimeDomain time_domain () const { if (flagged()) return Temporal::BeatTime; return Temporal::AudioTime; } superclock_t superclocks() const { if (is_superclock()) return val(); return _superclocks (); } - int64_t samples() const { return superclock_to_samples (superclocks(), _thread_sample_rate); } - int64_t ticks() const { if (is_beats()) return val(); return _ticks (); } - Beats beats() const { if (is_beats()) return Beats::ticks (val()); return _beats (); } + int64_t samples() const { return superclock_to_samples (superclocks(), _thread_sample_rate); } + int64_t ticks() const { if (is_beats()) return val(); return _ticks (); } + Beats beats() const { if (is_beats()) return Beats::ticks (val()); return _beats (); } timepos_t & operator= (timecnt_t const & t); /* will throw() if val is negative */ - timepos_t & operator= (superclock_t s) { v = s; return *this; } - timepos_t & operator= (Temporal::Beats const & b) { operator= (build (true, b.to_ticks())); return *this; } timepos_t operator-() const { return timepos_t (int62_t::operator-()); } @@ -101,8 +100,7 @@ class LIBTEMPORAL_API timepos_t : public int62_t { bool operator>= (timepos_t const & other) const { if (is_beats() == other.is_beats()) return val() >= other.val(); return expensive_gte (other); } timepos_t operator+(timecnt_t const & d) const; - 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); } - timepos_t operator+(Temporal::Beats const &b ) const { if (is_beats()) return timepos_t (true, ticks() + b.to_ticks()); return expensive_add (b); } + 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); } /* donn't provide operator+(samplepos_t) or operator+(superclock_t) * because the compiler can't disambiguate them and neither can we. @@ -151,19 +149,18 @@ class LIBTEMPORAL_API timepos_t : public int62_t { */ timecnt_t distance (timecnt_t const & p) const; - timecnt_t distance (Temporal::Beats const & b) const; timecnt_t distance (timepos_t const & p) const; /* computes a new position value that is @param d earlier than this */ timepos_t earlier (timepos_t const & d) const; /* treat d as distance measured from timeline origin */ timepos_t earlier (timecnt_t const & d) const; - timepos_t earlier (Beats const & d) const; + timepos_t earlier (BBT_Offset const & d) const; /* like ::earlier() but changes this. loosely equivalent to operator-= */ timepos_t & shift_earlier (timepos_t const & d); timepos_t & shift_earlier (timecnt_t const & d); - timepos_t & shift_earlier (Temporal::Beats const &); + timepos_t & shift_earlier (Temporal::BBT_Offset const &); /* given the absence of operator- and thus also operator--, return a @@ -179,7 +176,7 @@ class LIBTEMPORAL_API timepos_t : public int62_t { timepos_t & operator+=(timecnt_t const & d); timepos_t & operator+=(timepos_t const & d); - timepos_t & operator+=(Temporal::Beats const &); + timepos_t & operator+=(Temporal::BBT_Offset const &); timepos_t operator% (timecnt_t const &) const; @@ -190,22 +187,22 @@ class LIBTEMPORAL_API timepos_t : public int62_t { * along the x (time) axis. */ - timepos_t operator/(ratio_t const & n) const; - timepos_t operator*(ratio_t const & n) const; - timepos_t & operator/=(ratio_t const & n); - timepos_t & operator*=(ratio_t const & n); + timepos_t operator/ (ratio_t const & n) const; + timepos_t operator* (ratio_t const & n) const; + timepos_t & operator/= (ratio_t const & n); + timepos_t & operator*= (ratio_t const & n); - bool operator< (superclock_t s) { return v < s; } + bool operator< (samplepos_t s) { return samples() < s; } bool operator< (Temporal::Beats const & b) { return beats() < b; } - bool operator<= (superclock_t s) { return v <= s; } + bool operator<= (samplepos_t s) { return samples() <= s; } bool operator<= (Temporal::Beats const & b) { return beats() <= b; } - bool operator> (superclock_t s) { return v > s; } + bool operator> (samplepos_t s) { return samples() > s; } bool operator> (Temporal::Beats const & b) { return beats() > b; } - bool operator>= (superclock_t s) { return v >= s; } + bool operator>= (samplepos_t s) { return samples() >= s; } bool operator>= (Temporal::Beats const & b) { return beats() >= b; } - bool operator== (superclock_t s) { return v == s; } + bool operator== (samplepos_t s) { return samples() == s; } bool operator== (Temporal::Beats const & b) { return beats() == b; } - bool operator!= (superclock_t s) { return v != s; } + bool operator!= (samplepos_t s) { return samples() != s; } bool operator!= (Temporal::Beats const & b) { return beats() != b; } void set_superclock (superclock_t s); @@ -230,16 +227,15 @@ class LIBTEMPORAL_API timepos_t : public int62_t { * when this is using the audio time doamin */ - superclock_t _superclocks() const; - - /* these two methods are to be called ONLY when we have already that + /* these three methods are to be called ONLY when we have already that * the time domain of this timepos_t does not match the desired return * type, and so we will need to go to the tempo map to convert * between domains, which could be expensive. */ - int64_t _ticks() const; - Beats _beats() const; + superclock_t _superclocks() const; + int64_t _ticks() const; + Beats _beats() const; bool expensive_lt (timepos_t const &) const; bool expensive_lte (timepos_t const &) const; @@ -251,12 +247,9 @@ class LIBTEMPORAL_API timepos_t : public int62_t { bool expensive_gt (timecnt_t const &) const; bool expensive_gte(timecnt_t const &) const; - /* used to compute distance when time domains do not match */ + /* used to compute stuff when time domains do not match */ timecnt_t expensive_distance (timepos_t const & p) const; - timecnt_t expensive_distance (Beats const &) const; - - timepos_t expensive_add (Temporal::Beats const &) const; timepos_t expensive_add (timepos_t const & s) const; int62_t operator- (int62_t) const { assert (0); } diff --git a/libs/temporal/timeline.cc b/libs/temporal/timeline.cc index c791a8c894..1e08dd5c69 100644 --- a/libs/temporal/timeline.cc +++ b/libs/temporal/timeline.cc @@ -487,23 +487,22 @@ timepos_t::operator*=(ratio_t const & n) } timepos_t -timepos_t::expensive_add (Beats const & b) const +timepos_t::expensive_add (timepos_t const & other) const { - assert (!is_beats()); + /* Called when other's time domain does not match our own, requiring us + to call either ::beats() or ::superclocks() on other to convert it to + our time domain. + */ - return timepos_t (beats() + b); -} - -timepos_t -timepos_t::expensive_add (timepos_t const & t) const -{ - assert (is_beats() != t.is_beats ()); + assert (is_beats() != other.is_beats ()); if (is_beats()) { - return timepos_t (beats() + t.beats()); + /* we are known to use music time, so val() is in ticks */ + return timepos_t::from_ticks (val() + other.ticks()); } - return timepos_t::from_superclock (superclocks() + t.superclocks()); + /* we are known to use audio time, so val() is in superclocks */ + return timepos_t::from_superclock (val() + other.superclocks()); } /* */ @@ -512,16 +511,6 @@ timepos_t::expensive_add (timepos_t const & t) const * thus returns a positive value if this condition is satisfied. */ -timecnt_t -timepos_t::distance (Beats const & b) const -{ - if (is_beats()) { - return timecnt_t (b - _beats(), *this); - } - - return expensive_distance (b); -} - timecnt_t timepos_t::distance (timepos_t const & other) const { @@ -532,13 +521,6 @@ timepos_t::distance (timepos_t const & other) const return expensive_distance (other); } -timecnt_t -timepos_t::expensive_distance (Temporal::Beats const & b) const -{ - return timecnt_t (b - beats(), *this); -} - - timecnt_t timepos_t::expensive_distance (timepos_t const & other) const { @@ -546,6 +528,9 @@ timepos_t::expensive_distance (timepos_t const & other) const to call either ::beats() or ::superclocks() on other to convert it to our time domain. */ + + assert (is_beats() != other.is_beats ()); + if (is_beats()) { /* we are known to use beat time: val() is ticks */ return timecnt_t::from_ticks (other.ticks() - val(), *this); @@ -556,21 +541,6 @@ timepos_t::expensive_distance (timepos_t const & other) const /* */ -timepos_t -timepos_t::earlier (Temporal::Beats const & b) const -{ - Beats bb; - - if (is_superclock()) { - TempoMap::SharedPtr tm (TempoMap::use()); - bb = tm->quarter_note_at (superclocks()); - } else { - bb = beats (); - } - - return timepos_t (bb - b); -} - timepos_t timepos_t::earlier (Temporal::BBT_Offset const & offset) const { @@ -670,23 +640,6 @@ timepos_t::shift_earlier (timecnt_t const & d) return *this; } -timepos_t & -timepos_t::shift_earlier (Temporal::Beats const & b) -{ - Beats bb; - - if (is_superclock()) { - TempoMap::SharedPtr tm (TempoMap::use()); - bb = tm->quarter_note_at (val()); - } else { - bb = beats (); - } - - v = (bb - b).to_ticks(); - - return *this; -} - timepos_t & timepos_t::shift_earlier (Temporal::BBT_Offset const & offset) { @@ -716,19 +669,6 @@ timepos_t::operator+= (Temporal::BBT_Offset const & offset) return *this; } -timepos_t & -timepos_t::operator+=(Temporal::Beats const & b) -{ - if (is_beats()) { - v += build (true, b.to_ticks()); - } else { - TempoMap::SharedPtr tm (TempoMap::use()); - v = tm->superclock_plus_quarters_as_superclock (val(), b); - } - - return *this; -} - /* */ timepos_t @@ -738,7 +678,7 @@ timepos_t::operator+(timecnt_t const & d) const return operator+ (timepos_t::from_superclock (d.superclocks())); } - return operator+ (d.beats()); + return operator+ (timepos_t::from_ticks (d.ticks())); } timepos_t & @@ -747,7 +687,7 @@ timepos_t::operator+=(timecnt_t const & d) if (d.time_domain() == AudioTime) { return operator+= (timepos_t::from_superclock (d.superclocks())); } - return operator+= (d.beats()); + return operator+= (timepos_t::from_ticks (d.ticks())); } /* */