Force specification of timecode rate when creating a Time from seconds.
[libdcp.git] / src / dcp_time.cc
index 8e152ad28ca51e9c23bfce229afbbda11e941d8c..4e7ab6f2fa0cac106c840dbebc45ed093e1a34b2 100644 (file)
@@ -38,17 +38,28 @@ Time::Time (int frame, int frames_per_second, int tcr_)
        set (double (frame) / frames_per_second, tcr_);
 }
 
-Time::Time (double seconds)
+/** Construct a Time from a number of seconds and a timecode rate.
+ *
+ *  @param seconds A number of seconds.
+ *  @param tcr_ Timecode rate.
+ */
+Time::Time (double seconds, int tcr_)
 {
-       set (seconds, 24);
+       set (seconds, tcr_);
 }
 
+/** Construct a Time with specified timecode rate and using the supplied
+ *  number of seconds.
+ *
+ *  @param seconds A number of seconds.
+ *  @param tcr_ Timecode rate to use.
+ */
 void
 Time::set (double seconds, int tcr_)
 {
        s = floor (seconds);
        tcr = tcr_;
-       
+
        e = int (round ((seconds - s) * tcr));
 
        if (s >= 60) {
@@ -66,6 +77,7 @@ Time::set (double seconds, int tcr_)
        }
 }
 
+/** @param time String of the form HH:MM:SS:EE[E] */
 Time::Time (string time, int tcr_)
        : tcr (tcr_)
 {
@@ -74,7 +86,7 @@ Time::Time (string time, int tcr_)
        if (b.size() != 4) {
                boost::throw_exception (DCPReadError ("unrecognised time specification"));
        }
-       
+
        h = raw_convert<int> (b[0]);
        m = raw_convert<int> (b[1]);
        s = raw_convert<int> (b[2]);
@@ -206,7 +218,7 @@ dcp::operator- (Time a, Time b)
        } else {
                r.tcr = a.tcr;
        }
-       
+
        r.e = a.e - b.e;
        if (r.e < 0) {
                r.e += r.tcr;
@@ -238,32 +250,46 @@ dcp::operator/ (Time a, Time const & b)
        return float (at) / bt;
 }
 
-/** @return A string of the form h:m:s:e padded as in 00:00:00:000 */
+/** @return A string of the form h:m:s:e padded as in 00:00:00:000 (for Interop) or 00:00:00:00 (for SMPTE) */
 string
-Time::to_string () const
+Time::as_string (Standard standard) const
 {
        stringstream str;
        str << setw(2) << setfill('0') << h << ":"
            << setw(2) << setfill('0') << m << ":"
-           << setw(2) << setfill('0') << s << ":"
-           << setw(3) << setfill('0') << e;
+           << setw(2) << setfill('0') << s << ":";
+
+       if (standard == SMPTE) {
+               str << setw(2) << setfill('0') << e;
+       } else {
+               str << setw(3) << setfill('0') << e;
+       }
+
        return str.str ();
 }
 
+/** @param tcr_ Timecode rate with which the return value should be counted.
+ *  @return the total number of editable units that this time consists of at the specified timecode rate, rounded up
+ *  to the nearest editable unit. For example, as_editable_units (24) returns the total time in frames at 24fps.
+ */
 int64_t
-Time::to_editable_units (int tcr_) const
+Time::as_editable_units (int tcr_) const
 {
-       return (int64_t(e) * float (tcr_ / tcr)) + int64_t(s) * tcr_ + int64_t(m) * 60 * tcr_ + int64_t(h) * 60 * 60 * tcr_;
+       return ceil (int64_t(e) * double (tcr_) / tcr) + int64_t(s) * tcr_ + int64_t(m) * 60 * tcr_ + int64_t(h) * 60 * 60 * tcr_;
 }
 
+/** @return the total number of seconds that this time consists of */
 double
-Time::to_seconds () const
+Time::as_seconds () const
 {
        return h * 3600 + m * 60 + s + double(e) / tcr;
 }
 
+/** @param tcr_ New timecode rate.
+ *  @return A new Time which is this time at the spcified new timecode rate.
+ */
 Time
 Time::rebase (int tcr_) const
 {
-       return Time (h, m, s, rint (float (e) * tcr_ / tcr), tcr_);
+       return Time (h, m, s, floor (float (e) * tcr_ / tcr), tcr_);
 }