namespace dcpomatic {
+
+class HMSF
+{
+public:
+ HMSF () {}
+
+ HMSF (int h_, int m_, int s_, int f_)
+ : h(h_)
+ , m(m_)
+ , s(s_)
+ , f(f_)
+ {}
+
+ int h = 0;
+ int m = 0;
+ int s = 0;
+ int f = 0;
+};
+
+
/** A time in seconds, expressed as a number scaled up by Time::HZ. We want two different
* versions of this class, dcpomatic::ContentTime and dcpomatic::DCPTime, and we want it to be impossible to
* convert implicitly between the two. Hence there's this template hack. I'm not
/* Explicit conversion from type O */
Time (Time<O, S> d, FrameRateChange f);
+ /** @param hmsf Hours, minutes, seconds, frames.
+ * @param fps Frame rate
+ */
+ Time (HMSF const& hmsf, float fps) {
+ *this = from_seconds (hmsf.h * 3600)
+ + from_seconds (hmsf.m * 60)
+ + from_seconds (hmsf.s)
+ + from_frames (hmsf.f, fps);
+ }
+
Type get () const {
return _t;
}
/** Split a time into hours, minutes, seconds and frames.
* @param r Frames per second.
- * @param h Returned hours.
- * @param m Returned minutes.
- * @param s Returned seconds.
- * @param f Returned frames.
+ * @return Split time.
*/
template <typename T>
- void split (T r, int& h, int& m, int& s, int& f) const
+ HMSF split (T r) 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_round (r);
+ auto ff = frames_round (r);
+ HMSF hmsf;
- h = ff / (3600 * r);
- ff -= h * 3600 * r;
- m = ff / (60 * r);
- ff -= m * 60 * r;
- s = ff / r;
- ff -= s * r;
+ hmsf.h = ff / (3600 * r);
+ ff -= hmsf.h * 3600 * r;
+ hmsf.m = ff / (60 * r);
+ ff -= hmsf.m * 60 * r;
+ hmsf.s = ff / r;
+ ff -= hmsf.s * r;
- f = static_cast<int> (ff);
+ hmsf.f = static_cast<int> (ff);
+ return hmsf;
}
template <typename T>
std::string timecode (T r) const {
- int h;
- int m;
- int s;
- int f;
- split (r, h, m, s, f);
+ auto hmsf = split (r);
char buffer[128];
- snprintf (buffer, sizeof (buffer), "%02d:%02d:%02d:%02d", h, m, s, f);
+ snprintf (buffer, sizeof(buffer), "%02d:%02d:%02d:%02d", hmsf.h, hmsf.m, hmsf.s, hmsf.f);
return buffer;
}
if (!reel_markers.empty ()) {
auto ma = make_shared<dcp::ReelMarkersAsset>(dcp::Fraction(film()->video_frame_rate(), 1), reel->duration(), 0);
for (auto const& i: reel_markers) {
- int h, m, s, f;
DCPTime relative = i.second - _period.from;
- relative.split (film()->video_frame_rate(), h, m, s, f);
- ma->set (i.first, dcp::Time(h, m, s, f, film()->video_frame_rate()));
+ auto hmsf = relative.split (film()->video_frame_rate());
+ ma->set (i.first, dcp::Time(hmsf.h, hmsf.m, hmsf.s, hmsf.f, film()->video_frame_rate()));
}
reel->add (ma);
}
}
boost::algorithm::replace_all (text, "$AUDIO", description);
- int h, m, s, fr;
- film()->length().split(film()->video_frame_rate(), h, m, s, fr);
+ auto const hmsf = film()->length().split(film()->video_frame_rate());
string length;
- if (h == 0 && m == 0) {
- length = String::compose("%1s", s);
- } else if (h == 0 && m > 0) {
- length = String::compose("%1m%2s", m, s);
- } else if (h > 0 && m > 0) {
- length = String::compose("%1h%2m%3s", h, m, s);
+ if (hmsf.h == 0 && hmsf.m == 0) {
+ length = String::compose("%1s", hmsf.s);
+ } else if (hmsf.h == 0 && hmsf.m > 0) {
+ length = String::compose("%1m%2s", hmsf.m, hmsf.s);
+ } else if (hmsf.h > 0 && hmsf.m > 0) {
+ length = String::compose("%1h%2m%3s", hmsf.h, hmsf.m, hmsf.s);
}
boost::algorithm::replace_all (text, "$LENGTH", length);
wxListItem it;
it.SetId(N);
it.SetColumn(0);
- DCPTime length = content->approximate_length ();
- int h, m, s, f;
- length.split (24, h, m, s, f);
- it.SetText(wxString::Format("%02d:%02d:%02d", h, m, s));
+ auto length = content->approximate_length ();
+ auto const hmsf = length.split (24);
+ it.SetText(wxString::Format("%02d:%02d:%02d", hmsf.h, hmsf.m, hmsf.s));
InsertItem(it);
- shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent>(content);
+ auto dcp = dynamic_pointer_cast<DCPContent>(content);
if (dcp && dcp->content_kind()) {
it.SetId(N);
it.SetColumn(1);
void set (T t, float fps)
{
- int h;
- int m;
- int s;
- int f;
- t.split (fps, h, m, s, f);
+ auto const hmsf = t.split (fps);
- checked_set (_hours, dcp::raw_convert<std::string>(h));
- checked_set (_minutes, dcp::raw_convert<std::string>(m));
- checked_set (_seconds, dcp::raw_convert<std::string>(s));
- checked_set (_frames, dcp::raw_convert<std::string>(f));
+ checked_set (_hours, dcp::raw_convert<std::string>(hmsf.h));
+ checked_set (_minutes, dcp::raw_convert<std::string>(hmsf.m));
+ checked_set (_seconds, dcp::raw_convert<std::string>(hmsf.s));
+ checked_set (_frames, dcp::raw_convert<std::string>(hmsf.f));
checked_set (_fixed, t.timecode (fps));
}
void set_hint (T t, float fps)
{
- int h;
- int m;
- int s;
- int f;
- t.split (fps, h, m, s, f);
-
- _hours->SetHint (std_to_wx(dcp::raw_convert<std::string>(h)));
- _minutes->SetHint (std_to_wx(dcp::raw_convert<std::string>(m)));
- _seconds->SetHint (std_to_wx(dcp::raw_convert<std::string>(s)));
- _frames->SetHint (std_to_wx(dcp::raw_convert<std::string>(f)));
+ auto hmsf = t.split (fps);
+
+ _hours->SetHint (std_to_wx(dcp::raw_convert<std::string>(hmsf.h)));
+ _minutes->SetHint (std_to_wx(dcp::raw_convert<std::string>(hmsf.m)));
+ _seconds->SetHint (std_to_wx(dcp::raw_convert<std::string>(hmsf.s)));
+ _frames->SetHint (std_to_wx(dcp::raw_convert<std::string>(hmsf.f)));
}
T get (float fps) const
{
- T t;
-
auto value_or_hint = [](wxTextCtrl const * t) {
- if (!t->GetValue().IsEmpty()) {
- return wx_to_std (t->GetValue());
- } else {
- return wx_to_std (t->GetHint());
+ auto s = wx_to_std (t->GetValue().IsEmpty() ? t->GetHint() : t->GetValue());
+ if (s.empty()) {
+ return 0;
}
+ return dcp::raw_convert<int>(s);
};
- std::string const h = value_or_hint (_hours);
- t += T::from_seconds (dcp::raw_convert<int>(h.empty() ? "0" : h) * 3600);
- std::string const m = value_or_hint (_minutes);
- t += T::from_seconds (dcp::raw_convert<int>(m.empty() ? "0" : m) * 60);
- std::string const s = value_or_hint (_seconds);
- t += T::from_seconds (dcp::raw_convert<int>(s.empty() ? "0" : s));
- std::string const f = value_or_hint (_frames);
- t += T::from_frames (dcp::raw_convert<int>(f.empty() ? "0" : f), fps);
-
- return t;
+ return T (
+ {
+ value_or_hint(_hours),
+ value_or_hint(_minutes),
+ value_or_hint(_seconds),
+ value_or_hint(_frames)
+ },
+ fps
+ );
}
};