Warning fixes.
[dcpomatic.git] / src / lib / dcpomatic_time.h
1 /*
2     Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
3
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.
8
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.
13
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.
17
18 */
19
20 #ifndef DCPOMATIC_TIME_H
21 #define DCPOMATIC_TIME_H
22
23 #include <cmath>
24 #include <ostream>
25 #include <sstream>
26 #include <iomanip>
27 #include <stdint.h>
28 #include "frame_rate_change.h"
29
30 class dcpomatic_round_up_test;
31
32 class Time;
33
34 /** A time in seconds, expressed as a number scaled up by Time::HZ. */
35 class Time
36 {
37 public:
38         Time ()
39                 : _t (0)
40         {}
41
42         typedef int64_t Type;
43
44         explicit Time (Type t)
45                 : _t (t)
46         {}
47
48         virtual ~Time () {}
49
50         Type get () const {
51                 return _t;
52         }
53
54         double seconds () const {
55                 return double (_t) / HZ;
56         }
57
58         template <typename T>
59         int64_t frames (T r) const {
60                 return rint (_t * r / HZ);
61         }
62
63         template <typename T>
64         void split (T r, int& h, int& m, int& s, int& f) const
65         {
66                 /* Do this calculation with frames so that we can round
67                    to a frame boundary at the start rather than the end.
68                 */
69                 int64_t ff = frames (r);
70                 
71                 h = ff / (3600 * r);
72                 ff -= h * 3600 * r;
73                 m = ff / (60 * r);
74                 ff -= m * 60 * r;
75                 s = ff / r;
76                 ff -= s * r;
77
78                 f = static_cast<int> (ff);
79         }
80
81         template <typename T>
82         std::string timecode (T r) const {
83                 int h;
84                 int m;
85                 int s;
86                 int f;
87                 split (r, h, m, s, f);
88
89                 std::ostringstream o;
90                 o.width (2);
91                 o.fill ('0');
92                 o << std::setw(2) << std::setfill('0') << h << ":"
93                   << std::setw(2) << std::setfill('0') << m << ":"
94                   << std::setw(2) << std::setfill('0') << s << ":"
95                   << std::setw(2) << std::setfill('0') << f;
96                 return o.str ();
97         }
98
99 protected:
100         friend struct dcptime_round_up_test;
101         
102         Type _t;
103         static const int HZ = 96000;
104 };
105
106 class DCPTime;
107
108 class ContentTime : public Time
109 {
110 public:
111         ContentTime () : Time () {}
112         explicit ContentTime (Type t) : Time (t) {}
113         ContentTime (Type n, Type d) : Time (n * HZ / d) {}
114         ContentTime (DCPTime d, FrameRateChange f);
115
116         bool operator< (ContentTime const & o) const {
117                 return _t < o._t;
118         }
119
120         bool operator<= (ContentTime const & o) const {
121                 return _t <= o._t;
122         }
123
124         bool operator== (ContentTime const & o) const {
125                 return _t == o._t;
126         }
127
128         bool operator!= (ContentTime const & o) const {
129                 return _t != o._t;
130         }
131
132         bool operator>= (ContentTime const & o) const {
133                 return _t >= o._t;
134         }
135
136         bool operator> (ContentTime const & o) const {
137                 return _t > o._t;
138         }
139
140         ContentTime operator+ (ContentTime const & o) const {
141                 return ContentTime (_t + o._t);
142         }
143
144         ContentTime & operator+= (ContentTime const & o) {
145                 _t += o._t;
146                 return *this;
147         }
148
149         ContentTime operator- () const {
150                 return ContentTime (-_t);
151         }
152
153         ContentTime operator- (ContentTime const & o) const {
154                 return ContentTime (_t - o._t);
155         }
156
157         ContentTime & operator-= (ContentTime const & o) {
158                 _t -= o._t;
159                 return *this;
160         }
161
162         /** Round up to the nearest sampling interval
163          *  at some sampling rate.
164          *  @param r Sampling rate.
165          */
166         ContentTime round_up (float r) {
167                 Type const n = rint (HZ / r);
168                 Type const a = _t + n - 1;
169                 return ContentTime (a - (a % n));
170         }
171
172         static ContentTime from_seconds (double s) {
173                 return ContentTime (s * HZ);
174         }
175
176         template <class T>
177         static ContentTime from_frames (int64_t f, T r) {
178                 assert (r > 0);
179                 return ContentTime (f * HZ / r);
180         }
181
182         static ContentTime max () {
183                 return ContentTime (INT64_MAX);
184         }
185 };
186
187 std::ostream& operator<< (std::ostream& s, ContentTime t);
188
189 class ContentTimePeriod
190 {
191 public:
192         ContentTimePeriod () {}
193         ContentTimePeriod (ContentTime f, ContentTime t)
194                 : from (f)
195                 , to (t)
196         {}
197
198         ContentTime from;
199         ContentTime to;
200
201         ContentTimePeriod operator+ (ContentTime const & o) const {
202                 return ContentTimePeriod (from + o, to + o);
203         }
204
205         bool overlaps (ContentTimePeriod const & o) const;
206         bool contains (ContentTime const & o) const;
207 };
208
209 class DCPTime : public Time
210 {
211 public:
212         DCPTime () : Time () {}
213         explicit DCPTime (Type t) : Time (t) {}
214         DCPTime (ContentTime t, FrameRateChange c) : Time (rint (t.get() / c.speed_up)) {}
215
216         bool operator< (DCPTime const & o) const {
217                 return _t < o._t;
218         }
219
220         bool operator<= (DCPTime const & o) const {
221                 return _t <= o._t;
222         }
223
224         bool operator== (DCPTime const & o) const {
225                 return _t == o._t;
226         }
227
228         bool operator!= (DCPTime const & o) const {
229                 return _t != o._t;
230         }
231
232         bool operator>= (DCPTime const & o) const {
233                 return _t >= o._t;
234         }
235
236         bool operator> (DCPTime const & o) const {
237                 return _t > o._t;
238         }
239
240         DCPTime operator+ (DCPTime const & o) const {
241                 return DCPTime (_t + o._t);
242         }
243
244         DCPTime & operator+= (DCPTime const & o) {
245                 _t += o._t;
246                 return *this;
247         }
248
249         DCPTime operator- () const {
250                 return DCPTime (-_t);
251         }
252
253         DCPTime operator- (DCPTime const & o) const {
254                 return DCPTime (_t - o._t);
255         }
256
257         DCPTime & operator-= (DCPTime const & o) {
258                 _t -= o._t;
259                 return *this;
260         }
261
262         /** Round up to the nearest sampling interval
263          *  at some sampling rate.
264          *  @param r Sampling rate.
265          */
266         DCPTime round_up (float r) {
267                 Type const n = rint (HZ / r);
268                 Type const a = _t + n - 1;
269                 return DCPTime (a - (a % n));
270         }
271
272         DCPTime abs () const {
273                 return DCPTime (std::abs (_t));
274         }
275
276         static DCPTime from_seconds (double s) {
277                 return DCPTime (s * HZ);
278         }
279
280         template <class T>
281         static DCPTime from_frames (int64_t f, T r) {
282                 assert (r > 0);
283                 return DCPTime (f * HZ / r);
284         }
285
286         static DCPTime delta () {
287                 return DCPTime (1);
288         }
289
290         static DCPTime max () {
291                 return DCPTime (INT64_MAX);
292         }
293 };
294
295 DCPTime min (DCPTime a, DCPTime b);
296 std::ostream& operator<< (std::ostream& s, DCPTime t);
297
298 #endif