Runs.
[dcpomatic.git] / src / lib / util.cc
index 892a7fd8647520a575c24203508391a5666656f3..0247408679f172a3ae29b5737083e8e625b0debc 100644 (file)
@@ -235,8 +235,6 @@ seconds (struct timeval t)
 void
 dvdomatic_setup ()
 {
-       bindtextdomain ("libdvdomatic", LOCALE_DIR);
-       
        avfilter_register_all ();
        
        Format::setup_formats ();
@@ -248,6 +246,50 @@ dvdomatic_setup ()
        ui_thread = this_thread::get_id ();
 }
 
+#ifdef DVDOMATIC_WINDOWS
+boost::filesystem::path
+mo_path ()
+{
+       wchar_t buffer[512];
+       GetModuleFileName (0, buffer, 512 * sizeof(wchar_t));
+       boost::filesystem::path p (buffer);
+       p = p.parent_path ();
+       p = p.parent_path ();
+       p /= "locale";
+       return p;
+}
+#endif
+
+void
+dvdomatic_setup_i18n (string lang)
+{
+#ifdef DVDOMATIC_POSIX
+       lang += ".UTF8";
+#endif
+
+       if (!lang.empty ()) {
+               /* Override our environment language; this is essential on
+                  Windows.
+               */
+               char cmd[64];
+               snprintf (cmd, sizeof(cmd), "LANGUAGE=%s", lang.c_str ());
+               putenv (cmd);
+               snprintf (cmd, sizeof(cmd), "LANG=%s", lang.c_str ());
+               putenv (cmd);
+       }
+
+       setlocale (LC_ALL, "");
+       textdomain ("libdvdomatic");
+
+#ifdef DVDOMATIC_WINDOWS
+       bindtextdomain ("libdvdomatic", mo_path().string().c_str());
+#endif 
+
+#ifdef DVDOMATIC_POSIX
+       bindtextdomain ("libdvdomatic", POSIX_LOCALE_PREFIX);
+#endif
+}
+
 /** @param start Start position for the crop within the image.
  *  @param size Size of the cropped area.
  *  @return FFmpeg crop filter string.
@@ -305,11 +347,11 @@ md5_digest (void const * data, int size)
  *  @return MD5 digest of file's contents.
  */
 string
-md5_digest (string file)
+md5_digest (boost::filesystem::path file)
 {
-       ifstream f (file.c_str(), ios::binary);
+       ifstream f (file.string().c_str(), ios::binary);
        if (!f.good ()) {
-               throw OpenFileError (file);
+               throw OpenFileError (file.string());
        }
        
        f.seekg (0, ios::end);
@@ -374,21 +416,12 @@ public:
                , dcp (dcp_)
        {}
 
-       bool skip () const {
-               return !about_equal (source, dcp) && source > dcp;
-       }
-
-       bool repeat () const {
-               return !about_equal (source, dcp) && source < dcp;
-       }
-
        float source;
        int dcp;
 };
 
-/** @param fps Arbitrary source frames-per-second value */
-/** XXX: this could be slow-ish */
-DCPFrameRate::DCPFrameRate (float source_fps)
+int
+best_dcp_frame_rate (float source_fps)
 {
        list<int> const allowed_dcp_frame_rates = Config::instance()->allowed_dcp_frame_rates ();
 
@@ -426,14 +459,8 @@ DCPFrameRate::DCPFrameRate (float source_fps)
                ++i;
        }
 
-       if (!best) {
-               throw EncodeError (_("cannot find a suitable DCP frame rate for this source"));
-       }
-
-       frames_per_second = best->dcp;
-       skip = best->skip ();
-       repeat = best->repeat ();
-       change_speed = !about_equal (source_fps * factor(), frames_per_second);
+       assert (best);
+       return best->dcp;
 }
 
 /** @param An arbitrary sampling rate.
@@ -449,19 +476,6 @@ dcp_audio_sample_rate (int fs)
        return 96000;
 }
 
-int
-dcp_audio_channels (int f)
-{
-       if (f == 1) {
-               /* The source is mono, so to put the mono channel into
-                  the centre we need to generate a 5.1 soundtrack.
-               */
-               return 6;
-       }
-
-       return f;
-}
-
 bool operator== (Crop const & a, Crop const & b)
 {
        return (a.left == b.left && a.right == b.right && a.top == b.top && a.bottom == b.bottom);
@@ -902,3 +916,104 @@ cpu_info ()
 
        return info;
 }
+
+string
+audio_channel_name (int c)
+{
+       assert (MAX_AUDIO_CHANNELS == 6);
+
+       /* TRANSLATORS: these are the names of audio channels; Lfe (sub) is the low-frequency
+          enhancement channel (sub-woofer)./
+       */
+       string const channels[] = {
+               _("Left"),
+               _("Right"),
+               _("Centre"),
+               _("Lfe (sub)"),
+               _("Left surround"),
+               _("Right surround"),
+       };
+
+       return channels[c];
+}
+
+AudioMapping::AudioMapping (int c)
+       : _source_channels (c)
+{
+
+}
+
+optional<libdcp::Channel>
+AudioMapping::source_to_dcp (int c) const
+{
+       if (c >= _source_channels) {
+               return optional<libdcp::Channel> ();
+       }
+
+       if (_source_channels == 1) {
+               /* mono sources to centre */
+               return libdcp::CENTRE;
+       }
+       
+       return static_cast<libdcp::Channel> (c);
+}
+
+optional<int>
+AudioMapping::dcp_to_source (libdcp::Channel c) const
+{
+       if (_source_channels == 1) {
+               if (c == libdcp::CENTRE) {
+                       return 0;
+               } else {
+                       return optional<int> ();
+               }
+       }
+
+       if (static_cast<int> (c) >= _source_channels) {
+               return optional<int> ();
+       }
+       
+       return static_cast<int> (c);
+}
+
+int
+AudioMapping::dcp_channels () const
+{
+       if (_source_channels == 1) {
+               /* The source is mono, so to put the mono channel into
+                  the centre we need to generate a 5.1 soundtrack.
+               */
+               return 6;
+       }
+
+       return _source_channels;
+}
+
+FrameRateConversion::FrameRateConversion (float source, int dcp)
+       : skip (false)
+       , repeat (false)
+       , change_speed (false)
+{
+       if (fabs (source / 2.0 - dcp) < (fabs (source - dcp))) {
+               skip = true;
+       } else if (fabs (source * 2 - dcp) < fabs (source - dcp)) {
+               repeat = true;
+       }
+
+       change_speed = !about_equal (source * factor(), dcp);
+
+       if (!skip && !repeat && !change_speed) {
+               description = _("DCP and source have the same rate.\n");
+       } else {
+               if (skip) {
+                       description = _("DCP will use every other frame of the source.\n");
+               } else if (repeat) {
+                       description = _("Each source frame will be doubled in the DCP.\n");
+               }
+
+               if (change_speed) {
+                       float const pc = dcp * 100 / (source * factor());
+                       description += String::compose (_("DCP will run at %1%% of the source speed."), pc);
+               }
+       }
+}