Merge master; fix destruction of Server; some test cleanups.
[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 <stdint.h>
26 #include "frame_rate_change.h"
27
28 class dcpomatic_round_up_test;
29
30 class Time;
31
32 /** A time in seconds, expressed as a number scaled up by Time::HZ. */
33 class Time
34 {
35 public:
36         Time ()
37                 : _t (0)
38         {}
39
40         explicit Time (int64_t t)
41                 : _t (t)
42         {}
43
44         virtual ~Time () {}
45
46         int64_t get () const {
47                 return _t;
48         }
49
50         double seconds () const {
51                 return double (_t) / HZ;
52         }
53
54         template <typename T>
55         int64_t frames (T r) const {
56                 return rint (_t * r / HZ);
57         }
58
59 protected:
60         friend class dcptime_round_up_test;
61         
62         int64_t _t;
63         static const int HZ = 96000;
64 };
65
66 class DCPTime;
67
68 class ContentTime : public Time
69 {
70 public:
71         ContentTime () : Time () {}
72         explicit ContentTime (int64_t t) : Time (t) {}
73         ContentTime (int64_t n, int64_t d) : Time (n * HZ / d) {}
74         ContentTime (DCPTime d, FrameRateChange f);
75
76         bool operator< (ContentTime const & o) const {
77                 return _t < o._t;
78         }
79
80         bool operator<= (ContentTime const & o) const {
81                 return _t <= o._t;
82         }
83
84         bool operator== (ContentTime const & o) const {
85                 return _t == o._t;
86         }
87
88         bool operator!= (ContentTime const & o) const {
89                 return _t != o._t;
90         }
91
92         bool operator>= (ContentTime const & o) const {
93                 return _t >= o._t;
94         }
95
96         bool operator> (ContentTime const & o) const {
97                 return _t > o._t;
98         }
99
100         ContentTime operator+ (ContentTime const & o) const {
101                 return ContentTime (_t + o._t);
102         }
103
104         ContentTime & operator+= (ContentTime const & o) {
105                 _t += o._t;
106                 return *this;
107         }
108
109         ContentTime operator- () const {
110                 return ContentTime (-_t);
111         }
112
113         ContentTime operator- (ContentTime const & o) const {
114                 return ContentTime (_t - o._t);
115         }
116
117         ContentTime & operator-= (ContentTime const & o) {
118                 _t -= o._t;
119                 return *this;
120         }
121
122         /** Round up to the nearest sampling interval
123          *  at some sampling rate.
124          *  @param r Sampling rate.
125          */
126         ContentTime round_up (float r) {
127                 int64_t const n = rint (HZ / r);
128                 int64_t const a = _t + n - 1;
129                 return ContentTime (a - (a % n));
130         }
131
132         static ContentTime from_seconds (double s) {
133                 return ContentTime (s * HZ);
134         }
135
136         template <class T>
137         static ContentTime from_frames (int64_t f, T r) {
138                 assert (r > 0);
139                 return ContentTime (f * HZ / r);
140         }
141
142         static ContentTime max () {
143                 return ContentTime (INT64_MAX);
144         }
145 };
146
147 std::ostream& operator<< (std::ostream& s, ContentTime t);
148
149 class ContentTimePeriod
150 {
151 public:
152         ContentTimePeriod () {}
153         ContentTimePeriod (ContentTime f, ContentTime t)
154                 : from (f)
155                 , to (t)
156         {}
157
158         ContentTime from;
159         ContentTime to;
160
161         ContentTimePeriod operator+ (ContentTime const & o) const {
162                 return ContentTimePeriod (from + o, to + o);
163         }
164
165         bool overlaps (ContentTimePeriod const & o) const;
166 };
167
168 class DCPTime : public Time
169 {
170 public:
171         DCPTime () : Time () {}
172         explicit DCPTime (int64_t t) : Time (t) {}
173         DCPTime (ContentTime t, FrameRateChange c) : Time (rint (t.get() / c.speed_up)) {}
174
175         bool operator< (DCPTime const & o) const {
176                 return _t < o._t;
177         }
178
179         bool operator<= (DCPTime const & o) const {
180                 return _t <= o._t;
181         }
182
183         bool operator== (DCPTime const & o) const {
184                 return _t == o._t;
185         }
186
187         bool operator!= (DCPTime const & o) const {
188                 return _t != o._t;
189         }
190
191         bool operator>= (DCPTime const & o) const {
192                 return _t >= o._t;
193         }
194
195         bool operator> (DCPTime const & o) const {
196                 return _t > o._t;
197         }
198
199         DCPTime operator+ (DCPTime const & o) const {
200                 return DCPTime (_t + o._t);
201         }
202
203         DCPTime & operator+= (DCPTime const & o) {
204                 _t += o._t;
205                 return *this;
206         }
207
208         DCPTime operator- () const {
209                 return DCPTime (-_t);
210         }
211
212         DCPTime operator- (DCPTime const & o) const {
213                 return DCPTime (_t - o._t);
214         }
215
216         DCPTime & operator-= (DCPTime const & o) {
217                 _t -= o._t;
218                 return *this;
219         }
220
221         /** Round up to the nearest sampling interval
222          *  at some sampling rate.
223          *  @param r Sampling rate.
224          */
225         DCPTime round_up (float r) {
226                 int64_t const n = rint (HZ / r);
227                 int64_t const a = _t + n - 1;
228                 return DCPTime (a - (a % n));
229         }
230
231         DCPTime abs () const {
232                 return DCPTime (std::abs (_t));
233         }
234
235         static DCPTime from_seconds (double s) {
236                 return DCPTime (s * HZ);
237         }
238
239         template <class T>
240         static DCPTime from_frames (int64_t f, T r) {
241                 assert (r > 0);
242                 return DCPTime (f * HZ / r);
243         }
244
245         static DCPTime delta () {
246                 return DCPTime (1);
247         }
248
249         static DCPTime max () {
250                 return DCPTime (INT64_MAX);
251         }
252 };
253
254 DCPTime min (DCPTime a, DCPTime b);
255 std::ostream& operator<< (std::ostream& s, DCPTime t);
256
257 #endif