2 Copyright (C) 2014 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 #ifndef DCPOMATIC_TIME_H
21 #define DCPOMATIC_TIME_H
23 #include "frame_rate_change.h"
24 #include "safe_stringstream.h"
25 #include "dcpomatic_assert.h"
32 class dcpomatic_round_up_test;
36 /** A time in seconds, expressed as a number scaled up by Time::HZ. */
46 explicit Time (Type t)
56 double seconds () const {
57 return double (_t) / HZ;
61 int64_t frames (T r) const {
62 return rint (_t * r / HZ);
65 /** @param r Frames per second */
67 void split (T r, int& h, int& m, int& s, int& f) const
69 /* Do this calculation with frames so that we can round
70 to a frame boundary at the start rather than the end.
72 int64_t ff = frames (r);
81 f = static_cast<int> (ff);
85 std::string timecode (T r) const {
90 split (r, h, m, s, f);
95 o << std::setw(2) << std::setfill('0') << h << ":"
96 << std::setw(2) << std::setfill('0') << m << ":"
97 << std::setw(2) << std::setfill('0') << s << ":"
98 << std::setw(2) << std::setfill('0') << f;
103 friend struct dcptime_round_up_test;
106 static const int HZ = 96000;
111 class ContentTime : public Time
114 ContentTime () : Time () {}
115 explicit ContentTime (Type t) : Time (t) {}
116 ContentTime (Type n, Type d) : Time (n * HZ / d) {}
117 ContentTime (DCPTime d, FrameRateChange f);
119 bool operator< (ContentTime const & o) const {
123 bool operator<= (ContentTime const & o) const {
127 bool operator== (ContentTime const & o) const {
131 bool operator!= (ContentTime const & o) const {
135 bool operator>= (ContentTime const & o) const {
139 bool operator> (ContentTime const & o) const {
143 ContentTime operator+ (ContentTime const & o) const {
144 return ContentTime (_t + o._t);
147 ContentTime & operator+= (ContentTime const & o) {
152 ContentTime operator- () const {
153 return ContentTime (-_t);
156 ContentTime operator- (ContentTime const & o) const {
157 return ContentTime (_t - o._t);
160 ContentTime & operator-= (ContentTime const & o) {
165 /** Round up to the nearest sampling interval
166 * at some sampling rate.
167 * @param r Sampling rate.
169 ContentTime round_up (float r) {
170 Type const n = rint (HZ / r);
171 Type const a = _t + n - 1;
172 return ContentTime (a - (a % n));
175 static ContentTime from_seconds (double s) {
176 return ContentTime (s * HZ);
180 static ContentTime from_frames (int64_t f, T r) {
181 DCPOMATIC_ASSERT (r > 0);
182 return ContentTime (f * HZ / r);
185 static ContentTime max () {
186 return ContentTime (INT64_MAX);
190 std::ostream& operator<< (std::ostream& s, ContentTime t);
192 class ContentTimePeriod
195 ContentTimePeriod () {}
196 ContentTimePeriod (ContentTime f, ContentTime t)
204 ContentTimePeriod operator+ (ContentTime const & o) const {
205 return ContentTimePeriod (from + o, to + o);
208 bool overlaps (ContentTimePeriod const & o) const;
209 bool contains (ContentTime const & o) const;
212 class DCPTime : public Time
215 DCPTime () : Time () {}
216 explicit DCPTime (Type t) : Time (t) {}
217 DCPTime (ContentTime t, FrameRateChange c) : Time (rint (t.get() / c.speed_up)) {}
219 bool operator< (DCPTime const & o) const {
223 bool operator<= (DCPTime const & o) const {
227 bool operator== (DCPTime const & o) const {
231 bool operator!= (DCPTime const & o) const {
235 bool operator>= (DCPTime const & o) const {
239 bool operator> (DCPTime const & o) const {
243 DCPTime operator+ (DCPTime const & o) const {
244 return DCPTime (_t + o._t);
247 DCPTime & operator+= (DCPTime const & o) {
252 DCPTime operator- () const {
253 return DCPTime (-_t);
256 DCPTime operator- (DCPTime const & o) const {
257 return DCPTime (_t - o._t);
260 DCPTime & operator-= (DCPTime const & o) {
265 /** Round up to the nearest sampling interval
266 * at some sampling rate.
267 * @param r Sampling rate.
269 DCPTime round_up (float r) {
270 Type const n = rint (HZ / r);
271 Type const a = _t + n - 1;
272 return DCPTime (a - (a % n));
275 DCPTime abs () const {
276 return DCPTime (std::abs (_t));
279 static DCPTime from_seconds (double s) {
280 return DCPTime (s * HZ);
284 static DCPTime from_frames (int64_t f, T r) {
285 DCPOMATIC_ASSERT (r > 0);
286 return DCPTime (f * HZ / r);
289 static DCPTime delta () {
293 static DCPTime max () {
294 return DCPTime (INT64_MAX);
298 DCPTime min (DCPTime a, DCPTime b);
299 std::ostream& operator<< (std::ostream& s, DCPTime t);