43 #include "compose.hpp"
45 #include <boost/algorithm/string.hpp>
46 #include <boost/optional.hpp>
55 using boost::is_any_of;
56 using boost::optional;
60 Time::Time (
int frame,
double frames_per_second,
int tcr_)
62 set (
double (frame) / frames_per_second, tcr_);
84 e = int (round ((seconds -
s) *
tcr));
105 split (b, time, is_any_of (
":"));
107 if (b.size() < 3 || b[0].empty() || b[1].empty() || b[0].length() > 2 || b[1].length() > 2) {
108 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1", time)));
116 split (bs, b[2], is_any_of (
"."));
117 if (bs.size() != 2) {
118 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1", time)));
121 h = raw_convert<int> (b[0]);
122 m = raw_convert<int> (b[1]);
123 if (bs[0].empty() || bs[0].length() > 2) {
124 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1; %2 has bad length", time, bs[0])));
126 s = raw_convert<int> (bs[0]);
127 if (bs[1].empty() || bs[1].length() > 3) {
128 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1; %2 has bad length", time, bs[1])));
130 e = raw_convert<int> (bs[1]);
132 }
else if (b.size() == 4) {
134 h = raw_convert<int> (b[0]);
135 m = raw_convert<int> (b[1]);
136 if (b[2].empty() || b[2].length() > 2) {
137 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1; %2 has bad length", time, b[2])));
139 s = raw_convert<int> (b[2]);
140 if (b[3].empty() || b[3].length() > 3) {
141 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1; %2 has bad length", time, b[3])));
143 e = raw_convert<int> (b[3]);
146 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1", time)));
152 split (b, time, is_any_of (
":"));
154 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1; does not have 4 parts", time)));
157 h = raw_convert<int> (b[0]);
158 m = raw_convert<int> (b[1]);
159 if (b[2].empty() || b[2].length() > 2) {
160 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1; %2 has bad length", time, b[2])));
162 s = raw_convert<int> (b[2]);
163 if (b[3].empty() || b[3].length() > 3) {
164 boost::throw_exception (
ReadError (String::compose (
"unrecognised time specification %1; %2 has bad length", time, b[3])));
166 e = raw_convert<int> (b[3]);
173 dcp::operator== (
Time const & a,
Time const & b)
175 return (a.
h == b.
h && a.
m == b.
m && a.
s == b.
s && (a.
e * b.
tcr) == (b.
e * a.
tcr));
180 dcp::operator!= (
Time const & a,
Time const & b)
187 dcp::operator<= (
Time const & a,
Time const & b)
189 return a < b || a == b;
194 dcp::operator>= (
Time const & a,
Time const & b)
196 return a > b || a == b;
201 dcp::operator< (
Time const & a,
Time const & b)
215 return (a.
e * b.
tcr) < (b.
e * a.
tcr);
220 dcp::operator> (
Time const & a,
Time const & b)
234 return (a.
e * b.
tcr) > (b.
e * a.
tcr);
239 dcp::operator<< (ostream& s,
Time const & t)
241 s << t.
h <<
":" << t.
m <<
":" << t.
s <<
"." << t.
e;
323 dcp::operator/ (
Time a,
Time const & b)
325 int64_t
const at = a.
h * 3600 + a.
m * 60 + a.
s * float (a.
e) / a.
tcr;
326 int64_t
const bt = b.
h * 3600 + b.
m * 60 + b.
s * float (b.
e) / b.
tcr;
327 return float (at) / bt;
336 if (standard == Standard::SMPTE) {
337 snprintf (buffer,
sizeof(buffer),
"%02d:%02d:%02d:%02d",
h,
m,
s,
e);
339 snprintf (buffer,
sizeof(buffer),
"%02d:%02d:%02d:%03d",
h,
m,
s,
e);
349 return floor(int64_t(
e) *
double(tcr_) /
tcr) + int64_t(
s) * tcr_ + int64_t(
m) * 60 * tcr_ + int64_t(
h) * 60 * 60 * tcr_;
356 return ceil(int64_t(
e) *
double(tcr_) /
tcr) + int64_t(
s) * tcr_ + int64_t(
m) * 60 * tcr_ + int64_t(
h) * 60 * 60 * tcr_;
363 return h * 3600 +
m * 60 +
s + double(
e) /
tcr;
370 long int e_ = lrintf (
float (
e) * tcr_ /
tcr);
387 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)
int64_t as_editable_units_ceil(int tcr_) const
int64_t as_editable_units_floor(int tcr_) const
double as_seconds() const
Time rebase(int tcr_) const
int tcr
timecode rate: the number of editable units per second.
void set(double seconds, int tcr)
std::string as_string(Standard standard) const
Exceptions thrown by libdcp.
Namespace for everything in libdcp.
Methods for conversion to/from string.