2 Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
4 This file is part of libdcp.
6 libdcp is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 libdcp is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with libdcp. If not, see <http://www.gnu.org/licenses/>.
21 /** @file src/dcp_time.cc
25 #include "raw_convert.h"
27 #include "exceptions.h"
28 #include <boost/algorithm/string.hpp>
34 using namespace boost;
37 Time::Time (int frame, double frames_per_second, int tcr_)
39 set (double (frame) / frames_per_second, tcr_);
42 /** Construct a Time from a number of seconds and a timecode rate.
44 * @param seconds A number of seconds.
45 * @param tcr_ Timecode rate.
47 Time::Time (double seconds, int tcr_)
52 /** Construct a Time with specified timecode rate and using the supplied
55 * @param seconds A number of seconds.
56 * @param tcr_ Timecode rate to use.
59 Time::set (double seconds, int tcr_)
64 e = int (round ((seconds - s) * tcr));
81 /** @param time String of the form HH:MM:SS:EE[E] */
82 Time::Time (string time, int tcr_)
86 split (b, time, is_any_of (":"));
88 boost::throw_exception (DCPReadError ("unrecognised time specification"));
91 h = raw_convert<int> (b[0]);
92 m = raw_convert<int> (b[1]);
93 s = raw_convert<int> (b[2]);
94 e = raw_convert<int> (b[3]);
98 dcp::operator== (Time const & a, Time const & b)
100 return (a.h == b.h && a.m == b.m && a.s == b.s && (a.e * b.tcr) == (b.e * a.tcr));
104 dcp::operator!= (Time const & a, Time const & b)
110 dcp::operator<= (Time const & a, Time const & b)
112 return a < b || a == b;
116 dcp::operator>= (Time const & a, Time const & b)
118 return a > b || a == b;
122 dcp::operator< (Time const & a, Time const & b)
136 if ((a.e * b.tcr) != (b.e * a.tcr)) {
137 return (a.e * b.tcr) < (b.e * a.tcr);
144 dcp::operator> (Time const & a, Time const & b)
158 if ((a.e * b.tcr) != (b.e * a.tcr)) {
159 return (a.e * b.tcr) > (b.e * a.tcr);
166 dcp::operator<< (ostream& s, Time const & t)
168 s << t.h << ":" << t.m << ":" << t.s << "." << t.e;
173 dcp::operator+ (Time a, Time b)
177 /* Make sure we have a common tcr */
178 if (a.tcr != b.tcr) {
181 r.tcr = a.tcr * b.tcr;
210 dcp::operator- (Time a, Time b)
214 /* Make sure we have a common tcr */
215 if (a.tcr != b.tcr) {
218 r.tcr = a.tcr * b.tcr;
247 dcp::operator/ (Time a, Time const & b)
249 int64_t const at = a.h * 3600 + a.m * 60 + a.s * float (a.e) / a.tcr;
250 int64_t const bt = b.h * 3600 + b.m * 60 + b.s * float (b.e) / b.tcr;
251 return float (at) / bt;
254 /** @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) */
256 Time::as_string (Standard standard) const
259 str << setw(2) << setfill('0') << h << ":"
260 << setw(2) << setfill('0') << m << ":"
261 << setw(2) << setfill('0') << s << ":";
263 if (standard == SMPTE) {
264 str << setw(2) << setfill('0') << e;
266 str << setw(3) << setfill('0') << e;
272 /** @param tcr_ Timecode rate with which the return value should be counted.
273 * @return the total number of editable units that this time consists of at the specified timecode rate, rounded up
274 * to the nearest editable unit. For example, as_editable_units (24) returns the total time in frames at 24fps.
277 Time::as_editable_units (int tcr_) const
279 return ceil (int64_t(e) * double (tcr_) / tcr) + int64_t(s) * tcr_ + int64_t(m) * 60 * tcr_ + int64_t(h) * 60 * 60 * tcr_;
282 /** @return the total number of seconds that this time consists of */
284 Time::as_seconds () const
286 return h * 3600 + m * 60 + s + double(e) / tcr;
289 /** @param tcr_ New timecode rate.
290 * @return A new Time which is this time at the spcified new timecode rate.
293 Time::rebase (int tcr_) const
295 return Time (h, m, s, floor (float (e) * tcr_ / tcr), tcr_);