Basic guessing of audio channels from filenames (#393).
[dcpomatic.git] / src / lib / film.cc
index 87a317e5769db7ab40c60e1a2dc3e6f14d9e68f6..64550556b39bd3d27104468a1573f7ab8b7fd6a7 100644 (file)
@@ -1,19 +1,20 @@
 /*
     Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
 
-    This program is free software; you can redistribute it and/or modify
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.
 
-    This program is distributed in the hope that it will be useful,
+    DCP-o-matic is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
     You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
 
 */
 
@@ -41,7 +42,7 @@
 #include "environment_info.h"
 #include "raw_convert.h"
 #include "audio_processor.h"
-#include "md5_digester.h"
+#include "digester.h"
 #include "compose.hpp"
 #include "screen.h"
 #include "audio_content.h"
@@ -61,6 +62,7 @@
 #include <boost/filesystem.hpp>
 #include <boost/algorithm/string.hpp>
 #include <boost/foreach.hpp>
+#include <boost/regex.hpp>
 #include <unistd.h>
 #include <stdexcept>
 #include <iostream>
@@ -107,8 +109,13 @@ using boost::is_any_of;
  *
  * 32 -> 33
  * Changed <Period> to <Subtitle> in FFmpegSubtitleStream
+ * 33 -> 34
+ * Content only contains audio/subtitle-related tags if those things
+ * are present.
+ * 34 -> 35
+ * VideoFrameType in VideoContent is a string rather than an integer.
  */
-int const Film::current_state_version = 33;
+int const Film::current_state_version = 35;
 
 /** Construct a Film object in a given directory.
  *
@@ -243,7 +250,7 @@ Film::audio_analysis_path (shared_ptr<const Playlist> playlist) const
 {
        boost::filesystem::path p = dir ("analysis");
 
-       MD5Digester digester;
+       Digester digester;
        BOOST_FOREACH (shared_ptr<Content> i, playlist->content ()) {
                if (!i->audio) {
                        continue;
@@ -887,7 +894,7 @@ Film::signal_changed (Property p)
 
        switch (p) {
        case Film::CONTENT:
-               set_video_frame_rate (_playlist->best_dcp_frame_rate ());
+               set_video_frame_rate (_playlist->best_video_frame_rate ());
                break;
        case Film::VIDEO_FRAME_RATE:
        case Film::SEQUENCE:
@@ -1082,7 +1089,7 @@ Film::length () const
 int
 Film::best_video_frame_rate () const
 {
-       return _playlist->best_dcp_frame_rate ();
+       return _playlist->best_video_frame_rate ();
 }
 
 FrameRateChange
@@ -1097,7 +1104,7 @@ Film::playlist_content_changed (weak_ptr<Content> c, int p, bool frequent)
        _dirty = true;
 
        if (p == ContentProperty::VIDEO_FRAME_RATE) {
-               set_video_frame_rate (_playlist->best_dcp_frame_rate ());
+               set_video_frame_rate (_playlist->best_video_frame_rate ());
        } else if (p == AudioContentProperty::STREAMS) {
                signal_changed (NAME);
        }
@@ -1286,18 +1293,44 @@ Film::subtitle_language () const
 
 /** Change the gains of the supplied AudioMapping to make it a default
  *  for this film.  The defaults are guessed based on what processor (if any)
- *  is in use and the number of input channels.
+ *  is in use, the number of input channels and any filename supplied.
  */
 void
-Film::make_audio_mapping_default (AudioMapping& mapping) const
+Film::make_audio_mapping_default (AudioMapping& mapping, optional<boost::filesystem::path> filename) const
 {
+       static string const regex[] = {
+               ".*[\\._-]L[\\._-].*",
+               ".*[\\._-]R[\\._-].*",
+               ".*[\\._-]C[\\._-].*",
+               ".*[\\._-]Lfe[\\._-].*",
+               ".*[\\._-]Ls[\\._-].*",
+               ".*[\\._-]Rs[\\._-].*"
+       };
+
+       static int const regexes = sizeof(regex) / sizeof(*regex);
+
        if (audio_processor ()) {
                audio_processor()->make_audio_mapping_default (mapping);
        } else {
                mapping.make_zero ();
                if (mapping.input_channels() == 1) {
-                       /* Mono -> Centre */
-                       mapping.set (0, static_cast<int> (dcp::CENTRE), 1);
+                       bool guessed = false;
+
+                       /* See if we can guess where this stream should go */
+                       if (filename) {
+                               for (int i = 0; i < regexes; ++i) {
+                                       boost::regex e (regex[i], boost::regex::icase);
+                                       if (boost::regex_match (filename->string(), e) && i < mapping.output_channels()) {
+                                               mapping.set (0, i, 1);
+                                               guessed = true;
+                                       }
+                               }
+                       }
+
+                       if (!guessed) {
+                               /* If we have no idea, just put it on centre */
+                               mapping.set (0, static_cast<int> (dcp::CENTRE), 1);
+                       }
                } else {
                        /* 1:1 mapping */
                        for (int i = 0; i < min (mapping.input_channels(), mapping.output_channels()); ++i) {