13
0

Update region delta-time API

This is the first step to fix various MIDI edit issues for sessions with
tempo-changes.

The old code, using .earlier returned an absolute position when
calculating a relative distance. This is only valid if the session has a
fixed tempo, and the origin is irrelevant when converting the timepos.

This resulted in follow up issues since there is a difference when
summing two positions (each with an origin) vs adding an offset to a
position.

Note: this API changes breaks compilation until the GUI is updated.
This commit is contained in:
Robin Gareus 2022-10-23 18:49:26 +02:00
parent 33348f6332
commit 0504db2a67
2 changed files with 34 additions and 36 deletions

View File

@ -126,8 +126,8 @@ public:
timepos_t nt_last() const { return end().decrement(); } timepos_t nt_last() const { return end().decrement(); }
timepos_t source_position () const; timepos_t source_position () const;
timepos_t source_relative_position (Temporal::timepos_t const &) const; timecnt_t source_relative_position (Temporal::timepos_t const &) const;
timepos_t region_relative_position (Temporal::timepos_t const &) const; timecnt_t region_relative_position (Temporal::timepos_t const &) const;
samplepos_t position_sample () const { return position().samples(); } samplepos_t position_sample () const { return position().samples(); }
samplecnt_t start_sample () const { return _start.val().samples(); } samplecnt_t start_sample () const { return _start.val().samples(); }
@ -311,9 +311,7 @@ public:
/** Convert a timestamp in absolute time to beats measured from source start*/ /** Convert a timestamp in absolute time to beats measured from source start*/
Temporal::Beats absolute_time_to_source_beats(Temporal::timepos_t const &) const; Temporal::Beats absolute_time_to_source_beats(Temporal::timepos_t const &) const;
Temporal::Beats absolute_time_to_region_beats (Temporal::timepos_t const & b) const { Temporal::Beats absolute_time_to_region_beats (Temporal::timepos_t const &) const;
return position().distance (b+start()).beats ();
}
int apply (Filter &, Progress* progress = 0); int apply (Filter &, Progress* progress = 0);

View File

@ -2071,6 +2071,12 @@ Region::source_beats_to_absolute_beats (Temporal::Beats beats) const
return source_position().beats() + beats; return source_position().beats() + beats;
} }
Temporal::Beats
Region::absolute_time_to_region_beats(timepos_t const & b) const
{
return (position().distance (b)).beats () + start().beats();;
}
Temporal::timepos_t Temporal::timepos_t
Region::region_beats_to_absolute_time (Temporal::Beats beats) const Region::region_beats_to_absolute_time (Temporal::Beats beats) const
{ {
@ -2087,47 +2093,41 @@ Region::source_beats_to_absolute_time (Temporal::Beats beats) const
return source_position() + timepos_t (beats); return source_position() + timepos_t (beats);
} }
Temporal::Beats /** Calculate (time - source_position) in Beats
Region::absolute_time_to_source_beats(timepos_t const & time) const *
{ * Measure the distance between the absolute time and the position of
/* measure the distance between the absolute time and the position of * the source start, in beats. The result is positive if time is later
the source start, in beats. positive if time is later than source * than source position.
position. *
* @param p is an absolute time
* @returns time offset from p to the region's source position as the origin in Beat units
*/ */
Temporal::Beats
return source_position().distance (time).beats(); Region::absolute_time_to_source_beats(timepos_t const& p) const
{
return source_position().distance (p).beats();
} }
timepos_t /** Calculate (pos - source-position)
*
* @param p is an absolute time
* @returns time offset from p to the region's source position as the origin.
*/
timecnt_t
Region::source_relative_position (timepos_t const & p) const Region::source_relative_position (timepos_t const & p) const
{ {
/* p is an absolute time, return the time with the source position as return source_position().distance (p);
the origin.
Note that conventionally we would return a timecnt_t, expressing a
distance from the source position. But we return timepos_t for which
the origin is implicit, and in this case, the origin is the region
position, not zero.
XXX this seems likely to cause problems.
*/
return p.earlier (source_position());
} }
timepos_t /** Calculate (p - region-position)
*
* @param p is an absolute time
* @returns the time offset using the region (timeline) position as origin
*/
timecnt_t
Region::region_relative_position (timepos_t const & p) const Region::region_relative_position (timepos_t const & p) const
{ {
/* p is an absolute time, return the time with the region position as return position().distance (p);
the origin.
Note that conventionally we would return a timecnt_t, expressing a
distance from the region position. But we return timepos_t for which
the origin is implicit, and in this case, the origin is the region
position, not zero.
XXX this seems likely to cause problems.
*/
return p.earlier (position());
} }
Temporal::TimeDomain Temporal::TimeDomain