13
0

Temporal: clean up API for timepos_t to remove unneeded duplicates and remove ambiguity

This commit is contained in:
Paul Davis 2020-12-03 19:17:15 -07:00
parent 52ddf91e5b
commit c3d325b56a
4 changed files with 58 additions and 120 deletions

View File

@ -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 */

View File

@ -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 (); }

View File

@ -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); }

View File

@ -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()));
}
/* */