various fixes for exporting, including correct handling of errors during export which...
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 6 Dec 2012 19:56:33 +0000 (19:56 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 6 Dec 2012 19:56:33 +0000 (19:56 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@13610 d708f5d6-7413-0410-9779-e7cbd77b26cf

12 files changed:
gtk2_ardour/export_channel_selector.cc
gtk2_ardour/export_channel_selector.h
gtk2_ardour/export_dialog.cc
gtk2_ardour/export_dialog.h
libs/ardour/ardour/export_channel.h
libs/ardour/ardour/export_status.h
libs/ardour/ardour/session.h
libs/ardour/audioengine.cc
libs/ardour/export_channel.cc
libs/ardour/export_filename.cc
libs/ardour/export_status.cc
libs/ardour/session_export.cc

index 27e6ffaa502d194ab98e18ed436347d35a38f94f..6b90f7a36c12cabd65f74bdc98e47462fccc2b1c 100644 (file)
@@ -570,34 +570,31 @@ TrackExportChannelSelector::fill_list()
        RouteList routes = *_session->get_routes();
 
        for (RouteList::iterator it = routes.begin(); it != routes.end(); ++it) {
-               Route * route = it->get();
-               if(!dynamic_cast<Track *>(route)) {
+               if (!boost::dynamic_pointer_cast<Track>(*it)) {
                        // not a track, must be a bus
                        if ((*it)->is_master () || (*it)->is_monitor ()) {
                                continue;
                        }
                        // not monitor or master bus
-                                       
-                       add_track(route);
+                       add_track (*it);
                }
        }
        for (RouteList::iterator it = routes.begin(); it != routes.end(); ++it) {
-               Route * route = it->get();
-               if(dynamic_cast<AudioTrack *>(route)) {
-                       add_track(route);
+               if (boost::dynamic_pointer_cast<AudioTrack>(*it)) {
+                       add_track (*it);
                }
        }
 }
 
 void
-TrackExportChannelSelector::add_track(Route * route)
+TrackExportChannelSelector::add_track (boost::shared_ptr<Route> route)
 {
        Gtk::TreeModel::iterator iter = track_list->append();
        Gtk::TreeModel::Row row = *iter;
 
        row[track_cols.selected] = true;
        row[track_cols.label] = route->name();
-       row[track_cols.track] = route;
+       row[track_cols.route] = route;
 }
 
 void
@@ -614,13 +611,13 @@ TrackExportChannelSelector::update_config()
 
                ExportProfileManager::ChannelConfigStatePtr state = manager->add_channel_config();
 
-               Route * track = row[track_cols.track];
+               boost::shared_ptr<Route> route = row[track_cols.route];
 
                /* Output of track code. TODO make this an option also
-               uint32_t outs = track->n_ports().n_audio();
+               uint32_t outs = route->n_ports().n_audio();
                for (uint32_t i = 0; i < outs; ++i) {
-                       AudioPort * port = track->audio (i);
-                       if(port) {
+                       AudioPort * port = route->audio (i);
+                       if (port) {
                                ExportChannelPtr channel (new PortExportChannel ());
                                PortExportChannel * pec = static_cast<PortExportChannel *> (channel.get());
                                pec->add_port(port);
@@ -630,9 +627,9 @@ TrackExportChannelSelector::update_config()
                */
 
                std::list<ExportChannelPtr> list;
-               RouteExportChannel::create_from_route (list, *track);
+               RouteExportChannel::create_from_route (list, route);
                state->config->register_channels (list);
-               state->config->set_name(track->name());
+               state->config->set_name (route->name());
        }
 
        CriticalSelectionChanged ();
index 4cb9902ed08d6b31ae7cf14474633e34356573c8..79e943a569e5b4d7d0b66c147aaa00ae490ab0db 100644 (file)
@@ -235,7 +235,7 @@ class TrackExportChannelSelector : public ExportChannelSelector
   private:
 
        void fill_list();
-       void add_track(ARDOUR::Route * route);
+        void add_track (boost::shared_ptr<ARDOUR::Route> route);
        void update_config();
 
        ChannelConfigList configs;
@@ -243,11 +243,11 @@ class TrackExportChannelSelector : public ExportChannelSelector
        struct TrackCols : public Gtk::TreeModelColumnRecord
        {
          public:
-               Gtk::TreeModelColumn<ARDOUR::Route *> track;
+               Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Route> > route;
                Gtk::TreeModelColumn<std::string>     label;
                Gtk::TreeModelColumn<bool>            selected;
 
-               TrackCols () { add (track); add(label); add(selected); }
+               TrackCols () { add (route); add(label); add(selected); }
        };
        TrackCols                    track_cols;
 
index 9d707678cf3048ed49b99ebfca10ebb2a970c452..5e6812429a15ab6e093165c252cc2041f21ddc99 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <sigc++/signal.h>
 
+#include <gtkmm/messagedialog.h>
+
 #include "ardour/audioregion.h"
 #include "ardour/export_status.h"
 #include "ardour/export_handler.h"
@@ -94,8 +96,6 @@ ExportDialog::set_session (ARDOUR::Session* s)
        channel_selector->CriticalSelectionChanged.connect (sigc::mem_fun (*this, &ExportDialog::update_warnings_and_example_filename));
        file_notebook->CriticalSelectionChanged.connect (sigc::mem_fun (*this, &ExportDialog::update_warnings_and_example_filename));
 
-       status->Aborting.connect (abort_connection, invalidator (*this), boost::bind (&ExportDialog::notify_errors, this), gui_context());
-
        update_warnings_and_example_filename ();
 }
 
@@ -323,6 +323,7 @@ ExportDialog::show_progress ()
        progress_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ExportDialog::progress_timeout), 100);
 
        gtk_main_iteration ();
+
        while (status->running) {
                if (gtk_events_pending()) {
                        gtk_main_iteration ();
@@ -339,9 +340,11 @@ ExportDialog::show_progress ()
                        ns->nag ();
                        delete ns;
                }
-               
-               status->finish ();
+       } else {
+               notify_errors ();
        }
+
+       status->finish ();
 }
 
 gint
index 9507d8b2d9ab11657f115c6b65670443b92848f0..066b594812c735c70822e485ba96ab076ac23f30 100644 (file)
@@ -111,7 +111,6 @@ class ExportDialog : public ArdourDialog {
 
        PublicEditor &  editor;
        StatusPtr       status;
-       PBD::ScopedConnection abort_connection;
 
        /*** GUI components ***/
 
index 6f9682018c514095febe758fb44b3f799bb6d973..f3244095a3125cdb55b0aaee78bb54ee5d6aada1 100644 (file)
@@ -161,7 +161,7 @@ class RouteExportChannel : public ExportChannel
                           boost::shared_ptr<ProcessorRemover> remover);
        ~RouteExportChannel();
 
-       static void create_from_route(std::list<ExportChannelPtr> & result, Route & route);
+        static void create_from_route(std::list<ExportChannelPtr> & result, boost::shared_ptr<Route> route);
 
   public: // ExportChannel interface
        void set_max_buffer_size(framecnt_t frames);
@@ -179,11 +179,11 @@ class RouteExportChannel : public ExportChannel
        // Removes the processor from the track when deleted
        class ProcessorRemover {
          public:
-               ProcessorRemover (Route & route, boost::shared_ptr<CapturingProcessor> processor)
+                ProcessorRemover (boost::shared_ptr<Route> route, boost::shared_ptr<CapturingProcessor> processor)
                        : route (route), processor (processor) {}
                ~ProcessorRemover();
          private:
-               Route & route;
+                boost::shared_ptr<Route> route;
                boost::shared_ptr<CapturingProcessor> processor;
        };
 
index cb24cb55f514417aba2f6df905ce9c780fcdddf4..31027269f8ca376e9ccb9a886469f35ae7488b3a 100644 (file)
@@ -40,7 +40,6 @@ class ExportStatus {
        volatile bool           stop;
        volatile bool           running;
 
-       PBD::Signal0<void>      Aborting;
        void abort (bool error_occurred = false);
        bool aborted () const { return _aborted; }
        bool errors () const { return _errors; }
@@ -49,6 +48,8 @@ class ExportStatus {
        void finish ();
        bool finished () const { return _finished; }
 
+        void cleanup ();
+
        /* Progress info */
 
        volatile bool           normalizing;
index 5e75b4980bf76ed759830b57c56fa78f60864796..b2a077162cee0fc9de9910aba26f98c5f349b65c 100644 (file)
@@ -941,7 +941,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        void process_without_events (pframes_t);
        void process_with_events    (pframes_t);
        void process_audition       (pframes_t);
-       void process_export         (pframes_t);
+        int  process_export         (pframes_t);
        int  process_export_fw      (pframes_t);
 
        void block_processing() { g_atomic_int_set (&processing_prohibited, 1); }
@@ -983,6 +983,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        int  pre_export ();
        int  stop_audio_export ();
        void finalize_audio_export ();
+       void finalize_export_internal (bool stop_freewheel);
        bool _pre_export_mmc_enabled;
 
        PBD::ScopedConnection export_freewheel_connection;
index 90ff62f2a10e5f01cbe342857cf466469bc26e3c..dffd65556a3c48109705cdab95f521227ffe8b4c 100644 (file)
@@ -547,16 +547,13 @@ AudioEngine::process_callback (pframes_t nframes)
        }
 
        /* test if we are freewheeling and there are freewheel signals connected.
-           ardour should act normally even when freewheeling unless /it/ is exporting */
-
+           ardour should act normally even when freewheeling unless /it/ is
+           exporting 
+       */
 
        if (_freewheeling && !Freewheel.empty()) {
-               /* emit the Freewheel signal and stop freewheeling in the event of trouble
-                */
-                boost::optional<int> r = Freewheel (nframes);
-               if (r.get_value_or (0)) {
-                       jack_set_freewheel (_priv_jack, false);
-               }
+
+                Freewheel (nframes);
 
        } else {
                MIDI::Manager::instance()->cycle_start(nframes);
index 8deb31956dbedbb0c8afd1e486a77988caf16537..9b3f50e85d85906e728433fa51876bf39647283e 100644 (file)
@@ -214,9 +214,9 @@ RouteExportChannel::~RouteExportChannel()
 }
 
 void
-RouteExportChannel::create_from_route(std::list<ExportChannelPtr> & result, Route & route)
+RouteExportChannel::create_from_route(std::list<ExportChannelPtr> & result, boost::shared_ptr<Route> route)
 {
-       boost::shared_ptr<CapturingProcessor> processor = route.add_export_point();
+       boost::shared_ptr<CapturingProcessor> processor = route->add_export_point();
        uint32_t channels = processor->input_streams().n_audio();
 
        boost::shared_ptr<ProcessorRemover> remover (new ProcessorRemover (route, processor));
@@ -271,5 +271,5 @@ RouteExportChannel::operator< (ExportChannel const & other) const
 
 RouteExportChannel::ProcessorRemover::~ProcessorRemover()
 {
-       route.remove_processor (processor);
+       route->remove_processor (processor);
 }
index 3b8c27bc07d24c3433f9c2cc90f6c8327e718ccc..d00b0147a7bcd4bd7833947c34b34ada69cb73fa 100644 (file)
@@ -21,6 +21,9 @@
 #include <string>
 #include "ardour/export_filename.h"
 
+#include <glibmm/miscutils.h>
+#include <glibmm/fileutils.h>
+
 #include "pbd/xml++.h"
 #include "pbd/convert.h"
 #include "pbd/enumwriter.h"
@@ -101,15 +104,24 @@ ExportFilename::set_state (const XMLNode & node)
        folder = "";
 
        if ((prop = child->property ("relative"))) {
-               if (!prop->value().compare ("true")) {
+               if (string_is_affirmative (prop->value())) {
                        folder = session.session_directory().root_path();
                }
        }
 
        if ((prop = child->property ("path"))) {
-               folder += prop->value();
+               std::string tmp;
+               tmp = Glib::build_filename (folder, prop->value());
+               if (!Glib::file_test (tmp, Glib::FILE_TEST_EXISTS)) {
+                       warning << string_compose (_("Existing export folder for this session (%1) does not exist - ignored"), tmp) << endmsg;
+               } else {
+                       folder = tmp;
+               }
+       }
+       
+       if (folder.empty()) {
+               folder = session.session_directory().export_path();
        }
-
 
        pair = get_field (node, "label");
        include_label = pair.first;
@@ -140,11 +152,9 @@ ExportFilename::set_state (const XMLNode & node)
 string
 ExportFilename::get_path (ExportFormatSpecPtr format) const
 {
-       string path = folder;
+       string path;
        bool filename_empty = true;
 
-       path += "/";
-
        if (include_session) {
                path += filename_empty ? "" : "_";
                path += session.name();
@@ -198,7 +208,7 @@ ExportFilename::get_path (ExportFormatSpecPtr format) const
        path += ".";
        path += format->extension ();
 
-       return path;
+       return Glib::build_filename (folder, path);
 }
 
 string
index 70ce8dd27e96b286325d5bb3f77e0433403af032..0f7938bb7f2cb3d4a0ab31297cf96e862a882e86 100644 (file)
@@ -18,6 +18,8 @@
 
 */
 
+#include <pbd/stacktrace.h>
+
 #include "ardour/export_status.h"
 
 namespace ARDOUR
@@ -59,7 +61,6 @@ ExportStatus::abort (bool error_occurred)
        _finished = true;
        _errors = _errors || error_occurred;
        running = false;
-       Aborting ();
 }
 
 void
@@ -67,7 +68,7 @@ ExportStatus::finish ()
 {
        _finished = true;
        running = false;
-       Finished();
+       Finished(); /* EMIT SIGNAL */
 }
 
 } // namespace ARDOUR
index 969f4bb609d81d76ef970962b9faa5fae36e4c07..d1ee5d8122662a8eff6c6e3f0f23d1ce49caf246 100644 (file)
@@ -89,7 +89,6 @@ Session::pre_export ()
 
        _exporting = true;
        export_status->running = true;
-       export_status->Aborting.connect_same_thread (*this, boost::bind (&Session::stop_audio_export, this));
        export_status->Finished.connect_same_thread (*this, boost::bind (&Session::finalize_audio_export, this));
        
        /* disable MMC output early */
@@ -157,7 +156,7 @@ Session::start_audio_export (framepos_t position)
        return _engine.freewheel (true);
 }
 
-void
+int
 Session::process_export (pframes_t nframes)
 {
        if (_export_rolling && export_status->stop) {
@@ -183,25 +182,28 @@ Session::process_export (pframes_t nframes)
        } catch (std::exception & e) {
                error << string_compose (_("Export ended unexpectedly: %1"), e.what()) << endmsg;
                export_status->abort (true);
+               return -1;
        }
+
+       return 0;
 }
 
 int
 Session::process_export_fw (pframes_t nframes)
 {
-
        if (!_export_started) {
-               _export_started=true;
+               _export_started = true;
                set_transport_speed (1.0, false);
                butler_transport_work ();
                g_atomic_int_set (&_butler->should_do_transport_work, 0);
                post_transport ();
                return 0;
        }
-
+       
         _engine.main_thread()->get_buffers ();
        process_export (nframes);
         _engine.main_thread()->drop_buffers ();
+
        return 0;
 }
 
@@ -217,23 +219,22 @@ Session::stop_audio_export ()
        _export_rolling = false;
        _butler->schedule_transport_work ();
 
-       if (export_status->aborted()) {
-               finalize_audio_export ();
-       }
-
        return 0;
-
 }
 
 void
 Session::finalize_audio_export ()
 {
        _exporting = false;
-       _export_rolling = false;
+
+       if (_export_rolling) {
+               stop_audio_export ();
+       }
 
        /* Clean up */
 
        _engine.freewheel (false);
+
        export_freewheel_connection.disconnect();
        
        MIDI::Manager::instance()->mmc()->enable_send (_pre_export_mmc_enabled);