#ifndef DCPOMATIC_TIME_H
#define DCPOMATIC_TIME_H
+#include "frame_rate_change.h"
+#include "safe_stringstream.h"
+#include "dcpomatic_assert.h"
+#include <stdint.h>
#include <cmath>
#include <ostream>
-#include <stdint.h>
-#include "frame_rate_change.h"
+#include <sstream>
+#include <iomanip>
class dcpomatic_round_up_test;
: _t (0)
{}
- explicit Time (int64_t t)
+ typedef int64_t Type;
+
+ explicit Time (Type t)
: _t (t)
{}
virtual ~Time () {}
- int64_t get () const {
+ Type get () const {
return _t;
}
return rint (_t * r / HZ);
}
+ /** @param r Frames per second */
+ template <typename T>
+ void split (T r, int& h, int& m, int& s, int& f) const
+ {
+ /* Do this calculation with frames so that we can round
+ to a frame boundary at the start rather than the end.
+ */
+ int64_t ff = frames (r);
+
+ h = ff / (3600 * r);
+ ff -= h * 3600 * r;
+ m = ff / (60 * r);
+ ff -= m * 60 * r;
+ s = ff / r;
+ ff -= s * r;
+
+ f = static_cast<int> (ff);
+ }
+
+ template <typename T>
+ std::string timecode (T r) const {
+ int h;
+ int m;
+ int s;
+ int f;
+ split (r, h, m, s, f);
+
+ SafeStringStream o;
+ o.width (2);
+ o.fill ('0');
+ o << std::setw(2) << std::setfill('0') << h << ":"
+ << std::setw(2) << std::setfill('0') << m << ":"
+ << std::setw(2) << std::setfill('0') << s << ":"
+ << std::setw(2) << std::setfill('0') << f;
+ return o.str ();
+ }
+
protected:
- friend class dcptime_round_up_test;
+ friend struct dcptime_round_up_test;
- int64_t _t;
+ Type _t;
static const int HZ = 96000;
};
{
public:
ContentTime () : Time () {}
- explicit ContentTime (int64_t t) : Time (t) {}
- ContentTime (int64_t n, int64_t d) : Time (n * HZ / d) {}
+ 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 {
* @param r Sampling rate.
*/
ContentTime round_up (float r) {
- int64_t const n = rint (HZ / r);
- int64_t const a = _t + n - 1;
+ Type const n = rint (HZ / r);
+ Type const a = _t + n - 1;
return ContentTime (a - (a % n));
}
template <class T>
static ContentTime from_frames (int64_t f, T r) {
- assert (r > 0);
+ DCPOMATIC_ASSERT (r > 0);
return ContentTime (f * HZ / r);
}
ContentTime from;
ContentTime to;
+
+ ContentTimePeriod operator+ (ContentTime const & o) const {
+ return ContentTimePeriod (from + o, to + o);
+ }
+
+ bool overlaps (ContentTimePeriod const & o) const;
+ bool contains (ContentTime const & o) const;
};
class DCPTime : public Time
{
public:
DCPTime () : Time () {}
- explicit DCPTime (int64_t t) : Time (t) {}
+ explicit DCPTime (Type t) : Time (t) {}
DCPTime (ContentTime t, FrameRateChange c) : Time (rint (t.get() / c.speed_up)) {}
bool operator< (DCPTime const & o) const {
* @param r Sampling rate.
*/
DCPTime round_up (float r) {
- int64_t const n = rint (HZ / r);
- int64_t const a = _t + n - 1;
+ Type const n = rint (HZ / r);
+ Type const a = _t + n - 1;
return DCPTime (a - (a % n));
}
template <class T>
static DCPTime from_frames (int64_t f, T r) {
- assert (r > 0);
+ DCPOMATIC_ASSERT (r > 0);
return DCPTime (f * HZ / r);
}