43 #include "compose.hpp"
45 #include <boost/algorithm/string.hpp>
46 #include <boost/optional.hpp>
53 using namespace boost;
57 Time::Time (
int frame,
double frames_per_second,
int tcr_)
59 set (
double (frame) / frames_per_second, tcr_);
63 Time::Time (
double seconds,
int tcr_)
76 Time::set (
double seconds,
int tcr_)
81 e = int (round ((seconds - s) * tcr));
99 Time::Time (
string time, optional<int> tcr_)
102 split (b, time, is_any_of (
":"));
104 if (b.size() < 3 || b[0].empty() || b[1].empty() || b[0].length() > 2 || b[1].length() > 2) {
105 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1", time)));
113 split (bs, b[2], is_any_of (
"."));
114 if (bs.size() != 2) {
115 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1", time)));
118 h = raw_convert<int> (b[0]);
119 m = raw_convert<int> (b[1]);
120 if (bs[0].empty() || bs[0].length() > 2) {
121 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1; %2 has bad length", time, bs[0])));
123 s = raw_convert<int> (bs[0]);
124 if (bs[1].empty() || bs[1].length() > 3) {
125 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1; %2 has bad length", time, bs[1])));
127 e = raw_convert<int> (bs[1]);
129 }
else if (b.size() == 4) {
131 h = raw_convert<int> (b[0]);
132 m = raw_convert<int> (b[1]);
133 if (b[2].empty() || b[2].length() > 2) {
134 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1; %2 has bad length", time, b[2])));
136 s = raw_convert<int> (b[2]);
137 if (b[3].empty() || b[3].length() > 3) {
138 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1; %2 has bad length", time, b[3])));
140 e = raw_convert<int> (b[3]);
143 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1", time)));
148 split (b, time, is_any_of (
":"));
150 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1; does not have 4 parts", time)));
153 h = raw_convert<int> (b[0]);
154 m = raw_convert<int> (b[1]);
155 if (b[2].empty() || b[2].length() > 2) {
156 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1; %2 has bad length", time, b[2])));
158 s = raw_convert<int> (b[2]);
159 if (b[3].empty() || b[3].length() > 2) {
160 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1; %2 has bad length", time, b[3])));
162 e = raw_convert<int> (b[3]);
169 dcp::operator== (
Time const & a,
Time const & b)
171 return (a.
h == b.
h && a.
m == b.
m && a.
s == b.
s && (a.
e * b.
tcr) == (b.
e * a.
tcr));
176 dcp::operator!= (
Time const & a,
Time const & b)
183 dcp::operator<= (
Time const & a,
Time const & b)
185 return a < b || a == b;
190 dcp::operator>= (
Time const & a,
Time const & b)
192 return a > b || a == b;
197 dcp::operator< (
Time const & a,
Time const & b)
211 return (a.
e * b.
tcr) < (b.
e * a.
tcr);
216 dcp::operator> (
Time const & a,
Time const & b)
230 return (a.
e * b.
tcr) > (b.
e * a.
tcr);
235 dcp::operator<< (ostream& s,
Time const & t)
237 s << t.
h <<
":" << t.
m <<
":" << t.
s <<
"." << t.
e;
319 dcp::operator/ (
Time a,
Time const & b)
321 int64_t
const at = a.
h * 3600 + a.
m * 60 + a.
s * float (a.
e) / a.
tcr;
322 int64_t
const bt = b.
h * 3600 + b.
m * 60 + b.
s * float (b.
e) / b.
tcr;
323 return float (at) / bt;
328 Time::as_string (Standard standard)
const
332 if (standard == Standard::SMPTE) {
333 snprintf (buffer,
sizeof(buffer),
"%02d:%02d:%02d:%02d", h, m, s, e);
335 snprintf (buffer,
sizeof(buffer),
"%02d:%02d:%02d:%03d", h, m, s, e);
343 Time::as_editable_units_floor (
int tcr_)
const
345 return floor(int64_t(e) *
double(tcr_) / tcr) + int64_t(s) * tcr_ + int64_t(m) * 60 * tcr_ + int64_t(h) * 60 * 60 * tcr_;
350 Time::as_editable_units_ceil (
int tcr_)
const
352 return ceil(int64_t(e) *
double(tcr_) / tcr) + int64_t(s) * tcr_ + int64_t(m) * 60 * tcr_ + int64_t(h) * 60 * 60 * tcr_;
357 Time::as_seconds ()
const
359 return h * 3600 + m * 60 + s + double(e) / tcr;
364 Time::rebase (
int tcr_)
const
366 long int e_ = lrintf (
float (e) * tcr_ / tcr);
383 return Time (h_, m_, s_, e_, tcr_);
Any error that occurs when reading data from a DCP.
A representation of time within a DCP.
int e
editable units (where 1 editable unit is 1 / tcr_ seconds)
int tcr
timecode rate: the number of editable units per second.
Exceptions thrown by libdcp.
Namespace for everything in libdcp.
Methods for conversion to/from string.