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/timevalue.hpp"
|
||||||
#include "lib/time.h"
|
#include "lib/time.h"
|
||||||
|
#include "lib/util-quant.hpp"
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/rational.hpp>
|
#include <boost/rational.hpp>
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
using util::floordiv;
|
||||||
|
|
||||||
|
|
||||||
namespace lib {
|
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 by the given number of frames. */
|
||||||
Offset::Offset (int64_t count, FrameRate const& fps)
|
Offset::Offset (int64_t count, FrameRate const& fps)
|
||||||
: TimeValue (count? (count<0? -1:+1) * lumiera_framecount_to_time (::abs(count), fps)
|
: TimeValue (count? (count<0? -1:+1) * lumiera_framecount_to_time (::abs(count), fps)
|
||||||
|
|
|
||||||
|
|
@ -223,6 +223,13 @@ namespace time {
|
||||||
return Offset(distance);
|
return Offset(distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename INT>
|
||||||
|
inline Offset
|
||||||
|
operator* (Offset const& distance, INT factor)
|
||||||
|
{
|
||||||
|
return factor*distance;
|
||||||
|
}
|
||||||
|
|
||||||
inline Offset
|
inline Offset
|
||||||
operator* (int factor, Offset const& o)
|
operator* (int factor, Offset const& o)
|
||||||
{
|
{
|
||||||
|
|
@ -231,12 +238,12 @@ namespace time {
|
||||||
return Offset(distance);
|
return Offset(distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Offset
|
/** stretch offset by a possibly fractional factor */
|
||||||
operator* (Offset const& distance, int factor)
|
Offset
|
||||||
{
|
operator* (boost::rational<int64_t> factor, Offset const& o);
|
||||||
return factor*distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
/** flip offset direction */
|
||||||
inline Offset
|
inline Offset
|
||||||
Offset::operator- () const
|
Offset::operator- () const
|
||||||
{
|
{
|
||||||
|
|
@ -365,14 +372,16 @@ namespace time {
|
||||||
return Offset(base) + Offset(toAdd);
|
return Offset(base) + Offset(toAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename INT>
|
||||||
inline Offset
|
inline Offset
|
||||||
operator* (int factor, Duration const& dur)
|
operator* (INT factor, Duration const& dur)
|
||||||
{
|
{
|
||||||
return factor * Offset(dur);
|
return factor * Offset(dur);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename INT>
|
||||||
inline Offset
|
inline Offset
|
||||||
operator* (Duration const& dur, int factor)
|
operator* (Duration const& dur, INT factor)
|
||||||
{
|
{
|
||||||
return factor*dur;
|
return factor*dur;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ namespace test{
|
||||||
buildTimeSpan (ref);
|
buildTimeSpan (ref);
|
||||||
compareTimeSpan (Time(ref));
|
compareTimeSpan (Time(ref));
|
||||||
relateTimeIntervals (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
|
void
|
||||||
buildTimeSpan (TimeValue org)
|
buildTimeSpan (TimeValue org)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue