X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fdcpomatic_time.h;h=0b78c5390557f03024bfac43f0b012159d4da68e;hb=0a93237cb5e4642d3b698ff9b7d0cfae5401478c;hp=55476d5b52ad6d5752344dd9a23b70d5f3770fe8;hpb=f90d74f7a0382f0dc63eef81bd553d7a7b38edb2;p=dcpomatic.git diff --git a/src/lib/dcpomatic_time.h b/src/lib/dcpomatic_time.h index 55476d5b5..0b78c5390 100644 --- a/src/lib/dcpomatic_time.h +++ b/src/lib/dcpomatic_time.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Carl Hetherington + Copyright (C) 2014-2015 Carl Hetherington This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,22 +17,32 @@ */ +/** @file src/lib/dcpomatic_time.h + * @brief Types to describe time. + */ + #ifndef DCPOMATIC_TIME_H #define DCPOMATIC_TIME_H +#include "frame_rate_change.h" +#include "safe_stringstream.h" +#include "dcpomatic_assert.h" +#include #include #include #include #include -#include -#include "frame_rate_change.h" -#include "safe_stringstream.h" class dcpomatic_round_up_test; -class Time; - -/** A time in seconds, expressed as a number scaled up by Time::HZ. */ +/** A time in seconds, expressed as a number scaled up by Time::HZ. We want two different + * versions of this class, ContentTime and DCPTime, and we want it to be impossible to + * convert implicitly between the two. Hence there's this template hack. I'm not + * sure if it's the best way to do it. + * + * S is the name of `this' class and O is its opposite (see the typedefs below). + */ +template class Time { public: @@ -46,21 +56,87 @@ public: : _t (t) {} - virtual ~Time () {} + explicit Time (Type n, Type d) + : _t (n * HZ / d) + {} + /* Explicit conversion from type O */ + Time (Time d, FrameRateChange f); + Type get () const { return _t; } + bool operator< (Time const & o) const { + return _t < o._t; + } + + bool operator<= (Time const & o) const { + return _t <= o._t; + } + + bool operator== (Time const & o) const { + return _t == o._t; + } + + bool operator!= (Time const & o) const { + return _t != o._t; + } + + bool operator>= (Time const & o) const { + return _t >= o._t; + } + + bool operator> (Time const & o) const { + return _t > o._t; + } + + Time operator+ (Time const & o) const { + return Time (_t + o._t); + } + + Time & operator+= (Time const & o) { + _t += o._t; + return *this; + } + + Time operator- () const { + return Time (-_t); + } + + Time operator- (Time const & o) const { + return Time (_t - o._t); + } + + Time & operator-= (Time const & o) { + _t -= o._t; + return *this; + } + + /** Round up to the nearest sampling interval + * at some sampling rate. + * @param r Sampling rate. + */ + Time round_up (float r) { + Type const n = rint (HZ / r); + Type const a = _t + n - 1; + return Time (a - (a % n)); + } + double seconds () const { return double (_t) / HZ; } + Time abs () const { + return Time (std::abs (_t)); + } + template int64_t frames (T r) const { - return rint (_t * r / HZ); + return rint (double (_t) * r / HZ); } + /** @param r Frames per second */ template void split (T r, int& h, int& m, int& s, int& f) const { @@ -97,100 +173,57 @@ public: return o.str (); } -protected: - friend struct dcptime_round_up_test; - Type _t; - static const int HZ = 96000; -}; - -class DCPTime; - -class ContentTime : public Time -{ -public: - ContentTime () : Time () {} - explicit ContentTime (Type t) : Time (t) {} - ContentTime (Type n, Type d) : Time (n * HZ / d) {} - ContentTime (DCPTime d, FrameRateChange f); - - bool operator< (ContentTime const & o) const { - return _t < o._t; - } - - bool operator<= (ContentTime const & o) const { - return _t <= o._t; - } - - bool operator== (ContentTime const & o) const { - return _t == o._t; - } - - bool operator!= (ContentTime const & o) const { - return _t != o._t; + static Time from_seconds (double s) { + return Time (s * HZ); } - bool operator>= (ContentTime const & o) const { - return _t >= o._t; - } - - bool operator> (ContentTime const & o) const { - return _t > o._t; - } - - ContentTime operator+ (ContentTime const & o) const { - return ContentTime (_t + o._t); - } - - ContentTime & operator+= (ContentTime const & o) { - _t += o._t; - return *this; + template + static Time from_frames (int64_t f, T r) { + DCPOMATIC_ASSERT (r > 0); + return Time (f * HZ / r); } - ContentTime operator- () const { - return ContentTime (-_t); + static Time delta () { + return Time (1); } - ContentTime operator- (ContentTime const & o) const { - return ContentTime (_t - o._t); + static Time min () { + return Time (-INT64_MAX); } - - ContentTime & operator-= (ContentTime const & o) { - _t -= o._t; - return *this; + + static Time max () { + return Time (INT64_MAX); } + +private: + friend struct dcptime_round_up_test; + + Type _t; + static const int HZ = 96000; +}; - /** Round up to the nearest sampling interval - * at some sampling rate. - * @param r Sampling rate. - */ - ContentTime round_up (float r) { - Type const n = rint (HZ / r); - Type const a = _t + n - 1; - return ContentTime (a - (a % n)); - } +class ContentTimeDifferentiator {}; +class DCPTimeDifferentiator {}; - static ContentTime from_seconds (double s) { - return ContentTime (s * HZ); - } +/* Specializations for the two allowed explicit conversions */ - template - static ContentTime from_frames (int64_t f, T r) { - assert (r > 0); - return ContentTime (f * HZ / r); - } +template<> +Time::Time (Time d, FrameRateChange f); - static ContentTime max () { - return ContentTime (INT64_MAX); - } -}; +template<> +Time::Time (Time d, FrameRateChange f); -std::ostream& operator<< (std::ostream& s, ContentTime t); +/** Time relative to the start or position of a piece of content in its native frame rate */ +typedef Time ContentTime; +/** Time relative to the start of the output DCP in its frame rate */ +typedef Time DCPTime; class ContentTimePeriod { public: ContentTimePeriod () {} + ContentTimePeriod (ContentTime f, ContentTime t) : from (f) , to (t) @@ -207,93 +240,8 @@ public: bool contains (ContentTime const & o) const; }; -class DCPTime : public Time -{ -public: - DCPTime () : Time () {} - explicit DCPTime (Type t) : Time (t) {} - DCPTime (ContentTime t, FrameRateChange c) : Time (rint (t.get() / c.speed_up)) {} - - bool operator< (DCPTime const & o) const { - return _t < o._t; - } - - bool operator<= (DCPTime const & o) const { - return _t <= o._t; - } - - bool operator== (DCPTime const & o) const { - return _t == o._t; - } - - bool operator!= (DCPTime const & o) const { - return _t != o._t; - } - - bool operator>= (DCPTime const & o) const { - return _t >= o._t; - } - - bool operator> (DCPTime const & o) const { - return _t > o._t; - } - - DCPTime operator+ (DCPTime const & o) const { - return DCPTime (_t + o._t); - } - - DCPTime & operator+= (DCPTime const & o) { - _t += o._t; - return *this; - } - - DCPTime operator- () const { - return DCPTime (-_t); - } - - DCPTime operator- (DCPTime const & o) const { - return DCPTime (_t - o._t); - } - - DCPTime & operator-= (DCPTime const & o) { - _t -= o._t; - return *this; - } - - /** Round up to the nearest sampling interval - * at some sampling rate. - * @param r Sampling rate. - */ - DCPTime round_up (float r) { - Type const n = rint (HZ / r); - Type const a = _t + n - 1; - return DCPTime (a - (a % n)); - } - - DCPTime abs () const { - return DCPTime (std::abs (_t)); - } - - static DCPTime from_seconds (double s) { - return DCPTime (s * HZ); - } - - template - static DCPTime from_frames (int64_t f, T r) { - assert (r > 0); - return DCPTime (f * HZ / r); - } - - static DCPTime delta () { - return DCPTime (1); - } - - static DCPTime max () { - return DCPTime (INT64_MAX); - } -}; - DCPTime min (DCPTime a, DCPTime b); +std::ostream& operator<< (std::ostream& s, ContentTime t); std::ostream& operator<< (std::ostream& s, DCPTime t); #endif