allow for fractional scaling of time durations
implemented as extension to the linear combinations. I decided to use the same "always floor" rule as employed for time quantisation. Moreover, we don't support floating point, only rationals
This commit is contained in:
parent
22322dfec4
commit
9aec2a9806
3 changed files with 51 additions and 7 deletions
|
|
@ -23,12 +23,14 @@
|
|||
|
||||
#include "lib/time/timevalue.hpp"
|
||||
#include "lib/time.h"
|
||||
#include "lib/util-quant.hpp"
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <boost/rational.hpp>
|
||||
|
||||
using std::string;
|
||||
using util::floordiv;
|
||||
|
||||
|
||||
namespace lib {
|
||||
|
|
@ -122,6 +124,16 @@ namespace time {
|
|||
}
|
||||
|
||||
|
||||
Offset
|
||||
operator* (boost::rational<int64_t> factor, Offset const& o)
|
||||
{
|
||||
boost::rational<int64_t> distance (_raw(o));
|
||||
distance *= factor;
|
||||
gavl_time_t microTicks = floordiv (distance.numerator(), distance.denominator());
|
||||
return Offset(TimeValue(microTicks));
|
||||
}
|
||||
|
||||
|
||||
/** offset by the given number of frames. */
|
||||
Offset::Offset (int64_t count, FrameRate const& fps)
|
||||
: TimeValue (count? (count<0? -1:+1) * lumiera_framecount_to_time (::abs(count), fps)
|
||||
|
|
|
|||
|
|
@ -223,6 +223,13 @@ namespace time {
|
|||
return Offset(distance);
|
||||
}
|
||||
|
||||
template<typename INT>
|
||||
inline Offset
|
||||
operator* (Offset const& distance, INT factor)
|
||||
{
|
||||
return factor*distance;
|
||||
}
|
||||
|
||||
inline Offset
|
||||
operator* (int factor, Offset const& o)
|
||||
{
|
||||
|
|
@ -231,12 +238,12 @@ namespace time {
|
|||
return Offset(distance);
|
||||
}
|
||||
|
||||
inline Offset
|
||||
operator* (Offset const& distance, int factor)
|
||||
{
|
||||
return factor*distance;
|
||||
}
|
||||
/** stretch offset by a possibly fractional factor */
|
||||
Offset
|
||||
operator* (boost::rational<int64_t> factor, Offset const& o);
|
||||
|
||||
|
||||
/** flip offset direction */
|
||||
inline Offset
|
||||
Offset::operator- () const
|
||||
{
|
||||
|
|
@ -365,14 +372,16 @@ namespace time {
|
|||
return Offset(base) + Offset(toAdd);
|
||||
}
|
||||
|
||||
template<typename INT>
|
||||
inline Offset
|
||||
operator* (int factor, Duration const& dur)
|
||||
operator* (INT factor, Duration const& dur)
|
||||
{
|
||||
return factor * Offset(dur);
|
||||
}
|
||||
|
||||
template<typename INT>
|
||||
inline Offset
|
||||
operator* (Duration const& dur, int factor)
|
||||
operator* (Duration const& dur, INT factor)
|
||||
{
|
||||
return factor*dur;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ namespace test{
|
|||
buildTimeSpan (ref);
|
||||
compareTimeSpan (Time(ref));
|
||||
relateTimeIntervals (ref);
|
||||
verify_fractionalOffset();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -286,6 +287,28 @@ namespace test{
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
verify_fractionalOffset ()
|
||||
{
|
||||
typedef boost::rational<int64_t> Frac;
|
||||
|
||||
Duration three (TimeValue(3)); // three micro seconds
|
||||
|
||||
Offset o1 = Frac(1,2) * three;
|
||||
CHECK (o1 > Time::ZERO);
|
||||
CHECK (o1 == TimeValue(1)); // bias towards the next lower micro grid position
|
||||
|
||||
Offset o2 = -Frac(1,2) * three;
|
||||
CHECK (o2 < Time::ZERO);
|
||||
CHECK (o2 == TimeValue(-2));
|
||||
|
||||
CHECK (three * Frac(1,2) * 2 != three);
|
||||
CHECK (three *(Frac(1,2) * 2) == three);
|
||||
// integral arithmetics is precise,
|
||||
// but not necessarily exact!
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
buildTimeSpan (TimeValue org)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue