c++11 tidying.
[libsub.git] / src / sub_time.cc
index e304310677b4b6dc42542dbcbafa2481e52c72f2..763b4e44aba4e1389f118ba401fd3a0670bf3031 100644 (file)
 */
 
 #include "sub_time.h"
+#include "sub_assert.h"
 #include "exceptions.h"
 #include <cmath>
 #include <iomanip>
+#include <iostream>
 
 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));
 }
 
@@ -152,3 +154,43 @@ 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
+{
+       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());
+}