X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fsub_time.cc;h=763b4e44aba4e1389f118ba401fd3a0670bf3031;hb=8f677948db6df82b73eaf42a2cc9f897a14c777d;hp=3f4d1e984788cbda4a7ebe47e9d86adadef13d27;hpb=e70f560b63aa5c17d2f7f102f232cf4d5cd4c807;p=libsub.git diff --git a/src/sub_time.cc b/src/sub_time.cc index 3f4d1e9..763b4e4 100644 --- a/src/sub_time.cc +++ b/src/sub_time.cc @@ -18,9 +18,11 @@ */ #include "sub_time.h" +#include "sub_assert.h" #include "exceptions.h" #include #include +#include using std::ostream; using std::cout; @@ -44,7 +46,7 @@ sub::operator< (sub::Time const & a, sub::Time const & b) if ((a._rate && !b._rate) || (!a._rate && b._rate)) { throw UnknownFrameRateError (); } - + return (a._frames * a._rate.get().numerator * b._rate.get().denominator) < (b._frames * b._rate.get().numerator * a._rate.get().denominator); } @@ -63,7 +65,7 @@ sub::operator> (sub::Time const & a, sub::Time const & b) if ((a._rate && !b._rate) || (!a._rate && b._rate)) { throw UnknownFrameRateError (); } - + return (a._frames * a._rate.get().numerator * b._rate.get().denominator) > (b._frames * b._rate.get().numerator * a._rate.get().denominator); } @@ -131,7 +133,7 @@ Time::frames_at (Rational rate) const if (!_rate) { throw UnknownFrameRateError (); } - + return rint (double (_frames) * _rate.get().denominator * rate.numerator / (_rate.get().numerator * rate.denominator)); } @@ -153,12 +155,42 @@ Time::from_hms (int h, int m, int s, int ms) return Time (h * 3600 + m * 60 + s, ms, Rational (1000, 1)); } +/** Create a Time from a number of frames. + * rate must be integer. + */ +Time +Time::from_frames (int f, Rational rate) +{ + SUB_ASSERT (rate.denominator != 0); + SUB_ASSERT (rate.integer ()); + return Time (f / rate.integer_fraction(), f % rate.integer_fraction(), rate); +} + double Time::all_as_seconds () const { - if (!_rate) { - throw UnknownFrameRateError (); - } - - return _seconds + double (_frames) / _rate.get().fraction (); + return _seconds + double(milliseconds()) / 1000; +} + +/** Add a time to this one. Both *this and t must have a specified _rate */ +void +Time::add (Time t) +{ + SUB_ASSERT (_rate); + SUB_ASSERT (t._rate); + + Rational result_rate = max (*_rate, *t._rate); + *this = Time::from_frames((all_as_seconds() + t.all_as_seconds()) * result_rate.fraction(), result_rate); +} + +void +Time::scale (float f) +{ + SUB_ASSERT (_rate); + SUB_ASSERT (_rate->denominator != 0); + SUB_ASSERT (_rate->integer ()); + + double const s = Time::all_as_seconds() * f; + _seconds = floor (s); + _frames = rint ((s - _seconds) * _rate->fraction()); }