From 194615b5f673214b1e4fc4211364f95eeb96af15 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 20 Jun 2014 11:55:46 +0100 Subject: [PATCH] Add timecode methods to Time --- src/lib/dcpomatic_time.h | 38 ++++++++++++++++++++++++++++++++++++++ src/wx/timecode.cc | 18 ++++++------------ test/util_test.cc | 6 ++++++ 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 #include +#include +#include #include #include "frame_rate_change.h" @@ -56,6 +58,42 @@ public: return rint (_t * r / HZ); } + template + 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 (ff); + } + + template + 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 (h)); checked_set (_minutes, lexical_cast (m)); checked_set (_seconds, lexical_cast (s)); checked_set (_frames, lexical_cast (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"); +} -- 2.30.2