GUI and metadata for external audio.
authorCarl Hetherington <cth@carlh.net>
Wed, 7 Nov 2012 13:48:16 +0000 (13:48 +0000)
committerCarl Hetherington <cth@carlh.net>
Wed, 7 Nov 2012 13:48:16 +0000 (13:48 +0000)
src/lib/film.cc
src/lib/film.h
src/lib/util.h
src/wx/film_editor.cc
src/wx/film_editor.h
src/wx/wx_util.cc
src/wx/wx_util.h

index b335f8cc3e75223da839344ed9ffc32793efc556..cc5de0e7985f09bdaf8c6f0fca7c32a1a1ecdfcf 100644 (file)
@@ -86,6 +86,7 @@ Film::Film (string d, bool must_exist)
        , _dcp_trim_start (0)
        , _dcp_trim_end (0)
        , _dcp_ab (false)
+       , _use_source_audio (true)
        , _audio_stream (-1)
        , _audio_gain (0)
        , _audio_delay (0)
@@ -147,7 +148,9 @@ Film::Film (Film const & o)
        , _dcp_trim_start    (o._dcp_trim_start)
        , _dcp_trim_end      (o._dcp_trim_end)
        , _dcp_ab            (o._dcp_ab)
+       , _use_source_audio  (o._use_source_audio)
        , _audio_stream      (o._audio_stream)
+       , _external_audio    (o._external_audio)
        , _audio_gain        (o._audio_gain)
        , _audio_delay       (o._audio_delay)
        , _still_duration    (o._still_duration)
@@ -418,7 +421,11 @@ Film::write_metadata () const
        f << "dcp_trim_start " << _dcp_trim_start << "\n";
        f << "dcp_trim_end " << _dcp_trim_end << "\n";
        f << "dcp_ab " << (_dcp_ab ? "1" : "0") << "\n";
+       f << "use_source_audio " << (_use_source_audio ? "1" : "0") << "\n";
        f << "selected_audio_stream " << _audio_stream << "\n";
+       for (vector<string>::const_iterator i = _external_audio.begin(); i != _external_audio.end(); ++i) {
+               f << "external_audio " << *i << "\n";
+       }
        f << "audio_gain " << _audio_gain << "\n";
        f << "audio_delay " << _audio_delay << "\n";
        f << "still_duration " << _still_duration << "\n";
@@ -465,6 +472,11 @@ void
 Film::read_metadata ()
 {
        boost::mutex::scoped_lock lm (_state_mutex);
+
+       _external_audio.clear ();
+       _thumbs.clear ();
+       _audio_streams.clear ();
+       _subtitle_streams.clear ();
        
        ifstream f (file ("metadata").c_str());
        multimap<string, string> kv = read_key_value (f);
@@ -501,8 +513,12 @@ Film::read_metadata ()
                        _dcp_trim_end = atoi (v.c_str ());
                } else if (k == "dcp_ab") {
                        _dcp_ab = (v == "1");
+               } else if (k == "use_source_audio") {
+                       _use_source_audio = (v == "1");
                } else if (k == "selected_audio_stream") {
                        _audio_stream = atoi (v.c_str ());
+               } else if (k == "external_audio") {
+                       _external_audio.push_back (v);
                } else if (k == "audio_gain") {
                        _audio_gain = atof (v.c_str ());
                } else if (k == "audio_delay") {
@@ -723,11 +739,9 @@ Film::dcp_length () const
 string
 Film::dci_name () const
 {
-       boost::mutex::scoped_lock lm (_state_mutex);
-       
        stringstream d;
 
-       string fixed_name = to_upper_copy (_name);
+       string fixed_name = to_upper_copy (name());
        for (size_t i = 0; i < fixed_name.length(); ++i) {
                if (fixed_name[i] == ' ') {
                        fixed_name[i] = '-';
@@ -741,18 +755,18 @@ Film::dci_name () const
 
        d << fixed_name << "_";
 
-       if (_dcp_content_type) {
-               d << _dcp_content_type->dci_name() << "_";
+       if (dcp_content_type()) {
+               d << dcp_content_type()->dci_name() << "_";
        }
 
-       if (_format) {
-               d << _format->dci_name() << "_";
+       if (format()) {
+               d << format()->dci_name() << "_";
        }
 
-       if (!_audio_language.empty ()) {
-               d << _audio_language;
-               if (!_subtitle_language.empty() && _with_subtitles) {
-                       d << "-" << _subtitle_language;
+       if (!audio_language().empty ()) {
+               d << audio_language();
+               if (!subtitle_language().empty() && with_subtitles()) {
+                       d << "-" << subtitle_language();
                } else {
                        d << "-XX";
                }
@@ -760,15 +774,15 @@ Film::dci_name () const
                d << "_";
        }
 
-       if (!_territory.empty ()) {
-               d << _territory;
-               if (!_rating.empty ()) {
-                       d << "-" << _rating;
+       if (!territory().empty ()) {
+               d << territory();
+               if (!rating().empty ()) {
+                       d << "-" << rating();
                }
                d << "_";
        }
 
-       switch (_audio_streams[_audio_stream].channels()) {
+       switch (audio_channels()) {
        case 1:
                d << "10_";
                break;
@@ -785,18 +799,18 @@ Film::dci_name () const
 
        d << "2K_";
 
-       if (!_studio.empty ()) {
-               d << _studio << "_";
+       if (!studio().empty ()) {
+               d << studio() << "_";
        }
 
        d << boost::gregorian::to_iso_string (_dci_date) << "_";
 
-       if (!_facility.empty ()) {
-               d << _facility << "_";
+       if (!facility().empty ()) {
+               d << facility() << "_";
        }
 
-       if (!_package_type.empty ()) {
-               d << _package_type;
+       if (!package_type().empty ()) {
+               d << package_type();
        }
 
        return d.str ();
@@ -1054,6 +1068,16 @@ Film::set_dcp_ab (bool a)
        signal_changed (DCP_AB);
 }
 
+void
+Film::set_use_source_audio (bool s)
+{
+       {
+               boost::mutex::scoped_lock lm (_state_mutex);
+               _use_source_audio = s;
+       }
+       signal_changed (USE_SOURCE_AUDIO);
+}
+
 void
 Film::set_audio_stream (int s)
 {
@@ -1064,6 +1088,16 @@ Film::set_audio_stream (int s)
        signal_changed (AUDIO_STREAM);
 }
 
+void
+Film::set_external_audio (vector<string> a)
+{
+       {
+               boost::mutex::scoped_lock lm (_state_mutex);
+               _external_audio = a;
+       }
+       signal_changed (EXTERNAL_AUDIO);
+}
+
 void
 Film::set_audio_gain (float g)
 {
@@ -1321,11 +1355,23 @@ int
 Film::audio_channels () const
 {
        boost::mutex::scoped_lock lm (_state_mutex);
-       if (_audio_stream == -1) {
-               return 0;
-       }
        
-       return _audio_streams[_audio_stream].channels ();
+       if (_use_source_audio) {
+               if (_audio_stream >= 0) {
+                       return _audio_streams[_audio_stream].channels ();
+               }
+       } else {
+               int last_filled = -1;
+               for (size_t i = 0; i < _external_audio.size(); ++i) {
+                       if (!_external_audio[i].empty()) {
+                               last_filled = i;
+                       }
+               }
+               
+               return last_filled + 1;
+       }
+
+       return 0;
 }
 
 void
index 049af45e2ef2811d8d1605dbe52aad83ea351684..168a5e0b207ce3f350549ba61e3bfb6b6fb89015 100644 (file)
@@ -120,7 +120,9 @@ public:
                DCP_TRIM_START,
                DCP_TRIM_END,
                DCP_AB,
+               USE_SOURCE_AUDIO,
                AUDIO_STREAM,
+               EXTERNAL_AUDIO,
                AUDIO_GAIN,
                AUDIO_DELAY,
                STILL_DURATION,
@@ -202,6 +204,11 @@ public:
                return _dcp_ab;
        }
 
+       bool use_source_audio () const {
+               boost::mutex::scoped_lock lm (_state_mutex);
+               return _use_source_audio;
+       }
+
        int audio_stream_index () const {
                boost::mutex::scoped_lock lm (_state_mutex);
                return _audio_stream;
@@ -212,6 +219,11 @@ public:
                assert (_audio_stream < int (_audio_streams.size()));
                return _audio_streams[_audio_stream];
        }
+
+       std::vector<std::string> external_audio () const {
+               boost::mutex::scoped_lock lm (_state_mutex);
+               return _external_audio;
+       }
        
        float audio_gain () const {
                boost::mutex::scoped_lock lm (_state_mutex);
@@ -353,7 +365,9 @@ public:
        void set_dcp_trim_start (int);
        void set_dcp_trim_end (int);
        void set_dcp_ab (bool);
+       void set_use_source_audio (bool);
        void set_audio_stream (int);
+       void set_external_audio (std::vector<std::string>);
        void set_audio_gain (float);
        void set_audio_delay (int);
        void set_still_duration (int);
@@ -432,8 +446,10 @@ private:
            has the specified filters and post-processing.
        */
        bool _dcp_ab;
+       bool _use_source_audio;
        /** An index into our _audio_streams vector for the stream to use for audio, or -1 if there is none */
        int _audio_stream;
+       std::vector<std::string> _external_audio;
        /** Gain to apply to audio in dB */
        float _audio_gain;
        /** Delay to apply to audio (positive moves audio later) in milliseconds */
index 7aa9f25e14f01be88c0e4e43bda5b55bc0700b4b..577b9ba1bbf22c0c1a225f3de6b3692529de0360 100644 (file)
@@ -41,6 +41,8 @@ extern "C" {
 #define TIMING(...)
 #endif
 
+#define MAX_AUDIO_CHANNELS 6
+
 class Scaler;
 
 extern std::string seconds_to_hms (int);
index be96285e490995fe7b10543276df959401486af1..f2446c22afce7a479a2e73ac186823d229723af2 100644 (file)
@@ -192,6 +192,11 @@ FilmEditor::connect_to_widgets ()
        _audio_delay->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::audio_delay_changed), 0, this);
        _use_source_audio->Connect (wxID_ANY, wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler (FilmEditor::use_audio_changed), 0, this);
        _use_external_audio->Connect (wxID_ANY, wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler (FilmEditor::use_audio_changed), 0, this);
+       for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) {
+               _external_audio[i]->Connect (
+                       wxID_ANY, wxEVT_COMMAND_FILEPICKER_CHANGED, wxCommandEventHandler (FilmEditor::external_audio_changed), 0, this
+                       );
+       }
 }
 
 void
@@ -299,6 +304,8 @@ FilmEditor::make_audio_panel ()
        _audio_sizer->Add (video_control (_use_external_audio));
        _audio_sizer->AddSpacer (0);
 
+       assert (MAX_AUDIO_CHANNELS == 6);
+
        char const * channels[] = {
                "L",
                "R",
@@ -308,10 +315,10 @@ FilmEditor::make_audio_panel ()
                "Rs"
        };
 
-       for (int i = 0; i < 6; ++i) {
+       for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) {
                add_label_to_sizer (_audio_sizer, _audio_panel, channels[i]);
-               _external_audio_channel[i] = new wxFilePickerCtrl (_audio_panel, wxID_ANY, wxT (""), wxT ("Select Audio File"), wxT ("*.wav"));
-               _audio_sizer->Add (video_control (_external_audio_channel[i]), 1, wxEXPAND);
+               _external_audio[i] = new wxFilePickerCtrl (_audio_panel, wxID_ANY, wxT (""), wxT ("Select Audio File"), wxT ("*.wav"));
+               _audio_sizer->Add (video_control (_external_audio[i]), 1, wxEXPAND);
        }
 
        _audio_gain->SetRange (-60, 60);
@@ -602,6 +609,19 @@ FilmEditor::film_changed (Film::Property p)
        case Film::SUBTITLE_STREAM:
                checked_set (_subtitle_stream, _film->subtitle_stream_index ());
                break;
+       case Film::USE_SOURCE_AUDIO:
+               checked_set (_use_source_audio, _film->use_source_audio ());
+               checked_set (_use_external_audio, !_film->use_source_audio ());
+               setup_audio_control_sensitivity ();
+               break;
+       case Film::EXTERNAL_AUDIO:
+       {
+               vector<string> a = _film->external_audio ();
+               for (size_t i = 0; i < a.size() && i < MAX_AUDIO_CHANNELS; ++i) {
+                       checked_set (_external_audio[i], a[i]);
+               }
+               break;
+       }
        }
 }
 
@@ -661,6 +681,9 @@ FilmEditor::set_film (shared_ptr<Film> f)
        film_changed (Film::DCP_TRIM_START);
        film_changed (Film::DCP_TRIM_END);
        film_changed (Film::DCP_AB);
+       film_changed (Film::USE_SOURCE_AUDIO);
+       film_changed (Film::AUDIO_STREAM);
+       film_changed (Film::EXTERNAL_AUDIO);
        film_changed (Film::SIZE);
        film_changed (Film::LENGTH);
        film_changed (Film::FRAMES_PER_SECOND);
@@ -907,8 +930,8 @@ FilmEditor::setup_audio_control_sensitivity ()
        bool const external = _generally_sensitive && _use_external_audio->GetValue();
 
        _audio_stream->Enable (source);
-       for (int i = 0; i < 6; ++i) {
-               _external_audio_channel[i]->Enable (external);
+       for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) {
+               _external_audio[i]->Enable (external);
        }
 }
 
@@ -993,5 +1016,17 @@ FilmEditor::active_jobs_changed (bool a)
 void
 FilmEditor::use_audio_changed (wxCommandEvent &)
 {
+       _film->set_use_source_audio (_use_source_audio->GetValue ());
        setup_audio_control_sensitivity ();
 }
+
+void
+FilmEditor::external_audio_changed (wxCommandEvent &)
+{
+       vector<string> a;
+       for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) {
+               a.push_back (wx_to_std (_external_audio[i]->GetPath()));
+       }
+
+       _film->set_external_audio (a);
+}
index f0c1c6384b0157a38d9b0354258753c8e557cd55..2890df2441f6afa8be7706d84eff00e9977c072b 100644 (file)
@@ -77,6 +77,7 @@ private:
        void audio_stream_changed (wxCommandEvent &);
        void subtitle_stream_changed (wxCommandEvent &);
        void use_audio_changed (wxCommandEvent &);
+       void external_audio_changed (wxCommandEvent &);
 
        /* Handle changes to the model */
        void film_changed (Film::Property);
@@ -134,7 +135,7 @@ private:
        wxRadioButton* _use_source_audio;
        wxComboBox* _audio_stream;
        wxRadioButton* _use_external_audio;
-       wxFilePickerCtrl* _external_audio_channel[6];
+       wxFilePickerCtrl* _external_audio[MAX_AUDIO_CHANNELS];
        /** The Film's audio gain */
        wxSpinCtrl* _audio_gain;
        /** A button to open the gain calculation dialogue */
index a677fd9ac1057d171984aaf9659c7352521ee55b..d3bfa2702edb12607a7ae19143166c597d40ca0f 100644 (file)
@@ -148,3 +148,11 @@ checked_set (wxCheckBox* widget, bool value)
                widget->SetValue (value);
        }
 }
+
+void
+checked_set (wxRadioButton* widget, bool value)
+{
+       if (widget->GetValue() != value) {
+               widget->SetValue (value);
+       }
+}
index c2c3b6dde2ea3adde15bd838fdd26e83103bcf77..5cd3e5a7fcbee104c058dc8837486dc65aad2aa2 100644 (file)
@@ -59,3 +59,4 @@ extern void checked_set (wxSpinCtrl* widget, int value);
 extern void checked_set (wxComboBox* widget, int value);
 extern void checked_set (wxTextCtrl* widget, std::string value);
 extern void checked_set (wxCheckBox* widget, bool value);
+extern void checked_set (wxRadioButton* widget, bool value);