X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fdcp_time.cc;h=7d3111d270fbef814e05a7a398f8eadd9978023e;hb=30e2f6f873002d16aeae707879ea15c1c63a4323;hp=6af653adeabc43be623e9aab56a1745b9c10eb01;hpb=5130dd409e92a7cdb868b2af85797afd286d8afa;p=libdcp.git diff --git a/src/dcp_time.cc b/src/dcp_time.cc index 6af653ad..7d3111d2 100644 --- a/src/dcp_time.cc +++ b/src/dcp_time.cc @@ -17,18 +17,36 @@ */ +/** @file src/dcp_time.cc + * @brief A representation of time within a DCP. + */ + #include +#include +#include +#include #include #include "dcp_time.h" +#include "exceptions.h" using namespace std; +using namespace boost; using namespace libdcp; Time::Time (int frame, int frames_per_second) + : h (0) + , m (0) + , s (0) + , t (0) { - float sec_float = float (frame) / frames_per_second; - ms = int (sec_float * 1000) % 1000; - s = floor (sec_float); + set (double (frame) / frames_per_second); +} + +void +Time::set (double ss) +{ + t = (int (round (ss * 1000)) % 1000) / 4; + s = floor (ss); if (s > 60) { m = s / 60; @@ -41,10 +59,30 @@ Time::Time (int frame, int frames_per_second) } } +Time::Time (string time) +{ + vector b; + split (b, time, is_any_of (":")); + if (b.size() != 4) { + boost::throw_exception (DCPReadError ("unrecognised time specification")); + } + + h = lexical_cast (b[0]); + m = lexical_cast (b[1]); + s = lexical_cast (b[2]); + t = lexical_cast (b[3]); +} + bool libdcp::operator== (Time const & a, Time const & b) { - return (a.h == b.h && a.m == b.m && a.s == b.s && a.ms == b.ms); + return (a.h == b.h && a.m == b.m && a.s == b.s && a.t == b.t); +} + +bool +libdcp::operator!= (Time const & a, Time const & b) +{ + return !(a == b); } bool @@ -62,8 +100,52 @@ libdcp::operator<= (Time const & a, Time const & b) return a.s <= b.s; } - if (a.ms != b.ms) { - return a.ms <= b.ms; + if (a.t != b.t) { + return a.t <= b.t; + } + + return true; +} + +bool +libdcp::operator< (Time const & a, Time const & b) +{ + if (a.h != b.h) { + return a.h < b.h; + } + + if (a.m != b.m) { + return a.m < b.m; + } + + if (a.s != b.s) { + return a.s < b.s; + } + + if (a.t != b.t) { + return a.t < b.t; + } + + return true; +} + +bool +libdcp::operator> (Time const & a, Time const & b) +{ + if (a.h != b.h) { + return a.h > b.h; + } + + if (a.m != b.m) { + return a.m > b.m; + } + + if (a.s != b.s) { + return a.s > b.s; + } + + if (a.t != b.t) { + return a.t > b.t; } return true; @@ -72,6 +154,87 @@ libdcp::operator<= (Time const & a, Time const & b) ostream & libdcp::operator<< (ostream& s, Time const & t) { - s << t.h << ":" << t.m << ":" << t.s << "." << t.ms; + s << t.h << ":" << t.m << ":" << t.s << "." << t.t; return s; } + +libdcp::Time +libdcp::operator+ (Time a, Time const & b) +{ + Time r; + + r.t = a.t + b.t; + if (r.t >= 250) { + r.t -= 250; + r.s++; + } + + r.s += a.s + b.s; + if (r.s >= 60) { + r.s -= 60; + r.m++; + } + + r.m += a.m + b.m; + if (r.m >= 60) { + r.m -= 60; + r.h++; + } + + r.h += a.h + b.h; + + return r; +} + +libdcp::Time +libdcp::operator- (Time a, Time const & b) +{ + Time r; + + r.t = a.t - b.t; + if (r.t < 0) { + r.t += 250; + r.s--; + } + + r.s += (a.s - b.s); + if (r.s < 0) { + r.s += 60; + r.m--; + } + + r.m += (a.m - b.m); + if (r.m < 0) { + r.m += 60; + r.h--; + } + + r.h += (a.h - b.h); + + return r; +} + +float +libdcp::operator/ (Time a, Time const & b) +{ + int64_t const at = a.h * 3600 * 250 + a.m * 60 * 250 + a.s * 250 + a.t; + int64_t const bt = b.h * 3600 * 250 + b.m * 60 * 250 + b.s * 250 + b.t; + return float (at) / bt; +} + +/** @return A string of the form h:m:s:t */ +string +Time::to_string () const +{ + stringstream str; + str << h << ":" << m << ":" << s << ":" << t; + return str.str (); +} + +/** @return This time in ticks */ +int64_t +Time::to_ticks () const +{ + return t + s * 25 + m * 60 * 25 + h * 60 * 60 * 25; +} +