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:
Fischlurch 2012-03-17 00:49:58 +01:00
parent 22322dfec4
commit 9aec2a9806
3 changed files with 51 additions and 7 deletions

View file

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

View file

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

View file

@ -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)
{