2 Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 /** @file src/dcp_time.cc
24 #include "raw_convert.h"
26 #include "exceptions.h"
27 #include <boost/algorithm/string.hpp>
33 using namespace boost;
36 Time::Time (int frame, int frames_per_second, int tcr_)
38 set (double (frame) / frames_per_second, tcr_);
41 /** Construct a Time with a timecode rate of 24 and using the supplied
44 * @param seconds A number of seconds.
46 Time::Time (double seconds)
51 /** Construct a Time with specified timecode rate and using the supplied
54 * @param seconds A number of seconds.
55 * @param tcr_ Timecode rate to use.
58 Time::set (double seconds, int tcr_)
63 e = int (round ((seconds - s) * tcr));
80 /** @param time String of the form HH:MM:SS:EE[E] */
81 Time::Time (string time, int tcr_)
85 split (b, time, is_any_of (":"));
87 boost::throw_exception (DCPReadError ("unrecognised time specification"));
90 h = raw_convert<int> (b[0]);
91 m = raw_convert<int> (b[1]);
92 s = raw_convert<int> (b[2]);
93 e = raw_convert<int> (b[3]);
97 dcp::operator== (Time const & a, Time const & b)
99 return (a.h == b.h && a.m == b.m && a.s == b.s && (a.e * b.tcr) == (b.e * a.tcr));
103 dcp::operator!= (Time const & a, Time const & b)
109 dcp::operator<= (Time const & a, Time const & b)
111 return a < b || a == b;
115 dcp::operator>= (Time const & a, Time const & b)
117 return a > b || a == b;
121 dcp::operator< (Time const & a, Time const & b)
135 if ((a.e * b.tcr) != (b.e * a.tcr)) {
136 return (a.e * b.tcr) < (b.e * a.tcr);
143 dcp::operator> (Time const & a, Time const & b)
157 if ((a.e * b.tcr) != (b.e * a.tcr)) {
158 return (a.e * b.tcr) > (b.e * a.tcr);
165 dcp::operator<< (ostream& s, Time const & t)
167 s << t.h << ":" << t.m << ":" << t.s << "." << t.e;
172 dcp::operator+ (Time a, Time b)
176 /* Make sure we have a common tcr */
177 if (a.tcr != b.tcr) {
180 r.tcr = a.tcr * b.tcr;
209 dcp::operator- (Time a, Time b)
213 /* Make sure we have a common tcr */
214 if (a.tcr != b.tcr) {
217 r.tcr = a.tcr * b.tcr;
246 dcp::operator/ (Time a, Time const & b)
248 int64_t const at = a.h * 3600 + a.m * 60 + a.s * float (a.e) / a.tcr;
249 int64_t const bt = b.h * 3600 + b.m * 60 + b.s * float (b.e) / b.tcr;
250 return float (at) / bt;
253 /** @return A string of the form h:m:s:e padded as in 00:00:00:000 */
255 Time::as_string () const
258 str << setw(2) << setfill('0') << h << ":"
259 << setw(2) << setfill('0') << m << ":"
260 << setw(2) << setfill('0') << s << ":"
261 << setw(3) << setfill('0') << e;
265 /** @param tcr_ Timecode rate with which the return value should be counted.
266 * @return the total number of editable units that this time consists of at the specified timecode rate.
267 * For example, as_editable_units (24) returns the total time in frames at 24fps.
270 Time::as_editable_units (int tcr_) const
272 return (int64_t(e) * float (tcr_ / tcr)) + int64_t(s) * tcr_ + int64_t(m) * 60 * tcr_ + int64_t(h) * 60 * 60 * tcr_;
275 /** @return the total number of seconds that this time consists of */
277 Time::as_seconds () const
279 return h * 3600 + m * 60 + s + double(e) / tcr;
282 /** @param tcr_ New timecode rate.
283 * @return A new Time which is this time at the spcified new timecode rate.
286 Time::rebase (int tcr_) const
288 return Time (h, m, s, rint (float (e) * tcr_ / tcr), tcr_);