summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2014-06-20 11:55:46 +0100
committerCarl Hetherington <cth@carlh.net>2014-06-20 11:55:46 +0100
commit194615b5f673214b1e4fc4211364f95eeb96af15 (patch)
treeebdeee342e6a428dbe4657307c9e1ca39bf95895
parent2cdecbe2b56233b009f6edfa13033c6ec9d198bf (diff)
Add timecode methods to Time
-rw-r--r--src/lib/dcpomatic_time.h38
-rw-r--r--src/wx/timecode.cc18
-rw-r--r--test/util_test.cc6
3 files changed, 50 insertions, 12 deletions
diff --git a/src/lib/dcpomatic_time.h b/src/lib/dcpomatic_time.h
index 142104073..4afc9ab40 100644
--- a/src/lib/dcpomatic_time.h
+++ b/src/lib/dcpomatic_time.h
@@ -22,6 +22,8 @@
#include <cmath>
#include <ostream>
+#include <sstream>
+#include <iomanip>
#include <stdint.h>
#include "frame_rate_change.h"
@@ -56,6 +58,42 @@ public:
return rint (_t * r / HZ);
}
+ 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);
+
+ std::ostringstream 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;
diff --git a/src/wx/timecode.cc b/src/wx/timecode.cc
index 1ab4b590b..86e1997e9 100644
--- a/src/wx/timecode.cc
+++ b/src/wx/timecode.cc
@@ -85,24 +85,18 @@ Timecode::Timecode (wxWindow* parent)
void
Timecode::set (DCPTime t, int fps)
{
- /* Do this calculation with frames so that we can round
- to a frame boundary at the start rather than the end.
- */
- int64_t f = rint (t.seconds() * fps);
-
- int const h = f / (3600 * fps);
- f -= h * 3600 * fps;
- int const m = f / (60 * fps);
- f -= m * 60 * fps;
- int const s = f / fps;
- f -= s * fps;
+ int h;
+ int m;
+ int s;
+ int f;
+ t.split (fps, h, m, s, f);
checked_set (_hours, lexical_cast<string> (h));
checked_set (_minutes, lexical_cast<string> (m));
checked_set (_seconds, lexical_cast<string> (s));
checked_set (_frames, lexical_cast<string> (f));
- _fixed->SetLabel (wxString::Format ("%02d:%02d:%02d.%02" wxLongLongFmtSpec "d", h, m, s, f));
+ _fixed->SetLabel (std_to_wx (t.timecode (fps)));
}
DCPTime
diff --git a/test/util_test.cc b/test/util_test.cc
index 5eb3e27f1..39cc0e6bf 100644
--- a/test/util_test.cc
+++ b/test/util_test.cc
@@ -88,3 +88,9 @@ BOOST_AUTO_TEST_CASE (divide_with_round_test)
BOOST_CHECK_EQUAL (divide_with_round (1000, 500), 2);
}
+
+BOOST_AUTO_TEST_CASE (timecode_test)
+{
+ DCPTime t = DCPTime::from_seconds (2 * 60 * 60 + 4 * 60 + 31) + DCPTime::from_frames (19, 24);
+ BOOST_CHECK_EQUAL (t.timecode (24), "02:04:31:19");
+}