From 9884773eea9764b6dacd3ade6a1d49cf389fe398 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 6 Dec 2012 19:56:33 +0000 Subject: [PATCH] various fixes for exporting, including correct handling of errors during export which previously would hang when using jack1 because jack_set_freewheel() was called from inside a process() callback; use shared_ptr in parts of export code that weren't using them before; fix up generation of export filenames so that Glib::build_filename() is used and non-existent folders are ignored git-svn-id: svn://localhost/ardour2/branches/3.0@13610 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/export_channel_selector.cc | 27 ++++++++++++-------------- gtk2_ardour/export_channel_selector.h | 6 +++--- gtk2_ardour/export_dialog.cc | 11 +++++++---- gtk2_ardour/export_dialog.h | 1 - libs/ardour/ardour/export_channel.h | 6 +++--- libs/ardour/ardour/export_status.h | 3 ++- libs/ardour/ardour/session.h | 3 ++- libs/ardour/audioengine.cc | 13 +++++-------- libs/ardour/export_channel.cc | 6 +++--- libs/ardour/export_filename.cc | 24 ++++++++++++++++------- libs/ardour/export_status.cc | 5 +++-- libs/ardour/session_export.cc | 23 +++++++++++----------- 12 files changed, 69 insertions(+), 59 deletions(-) diff --git a/gtk2_ardour/export_channel_selector.cc b/gtk2_ardour/export_channel_selector.cc index 27e6ffaa50..6b90f7a36c 100644 --- a/gtk2_ardour/export_channel_selector.cc +++ b/gtk2_ardour/export_channel_selector.cc @@ -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(route)) { + if (!boost::dynamic_pointer_cast(*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(route)) { - add_track(route); + if (boost::dynamic_pointer_cast(*it)) { + add_track (*it); } } } void -TrackExportChannelSelector::add_track(Route * route) +TrackExportChannelSelector::add_track (boost::shared_ptr 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 = 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 (channel.get()); pec->add_port(port); @@ -630,9 +627,9 @@ TrackExportChannelSelector::update_config() */ std::list 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 (); diff --git a/gtk2_ardour/export_channel_selector.h b/gtk2_ardour/export_channel_selector.h index 4cb9902ed0..79e943a569 100644 --- a/gtk2_ardour/export_channel_selector.h +++ b/gtk2_ardour/export_channel_selector.h @@ -235,7 +235,7 @@ class TrackExportChannelSelector : public ExportChannelSelector private: void fill_list(); - void add_track(ARDOUR::Route * route); + void add_track (boost::shared_ptr route); void update_config(); ChannelConfigList configs; @@ -243,11 +243,11 @@ class TrackExportChannelSelector : public ExportChannelSelector struct TrackCols : public Gtk::TreeModelColumnRecord { public: - Gtk::TreeModelColumn track; + Gtk::TreeModelColumn > route; Gtk::TreeModelColumn label; Gtk::TreeModelColumn selected; - TrackCols () { add (track); add(label); add(selected); } + TrackCols () { add (route); add(label); add(selected); } }; TrackCols track_cols; diff --git a/gtk2_ardour/export_dialog.cc b/gtk2_ardour/export_dialog.cc index 9d707678cf..5e6812429a 100644 --- a/gtk2_ardour/export_dialog.cc +++ b/gtk2_ardour/export_dialog.cc @@ -21,6 +21,8 @@ #include +#include + #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 diff --git a/gtk2_ardour/export_dialog.h b/gtk2_ardour/export_dialog.h index 9507d8b2d9..066b594812 100644 --- a/gtk2_ardour/export_dialog.h +++ b/gtk2_ardour/export_dialog.h @@ -111,7 +111,6 @@ class ExportDialog : public ArdourDialog { PublicEditor & editor; StatusPtr status; - PBD::ScopedConnection abort_connection; /*** GUI components ***/ diff --git a/libs/ardour/ardour/export_channel.h b/libs/ardour/ardour/export_channel.h index 6f9682018c..f3244095a3 100644 --- a/libs/ardour/ardour/export_channel.h +++ b/libs/ardour/ardour/export_channel.h @@ -161,7 +161,7 @@ class RouteExportChannel : public ExportChannel boost::shared_ptr remover); ~RouteExportChannel(); - static void create_from_route(std::list & result, Route & route); + static void create_from_route(std::list & result, boost::shared_ptr 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 processor) + ProcessorRemover (boost::shared_ptr route, boost::shared_ptr processor) : route (route), processor (processor) {} ~ProcessorRemover(); private: - Route & route; + boost::shared_ptr route; boost::shared_ptr processor; }; diff --git a/libs/ardour/ardour/export_status.h b/libs/ardour/ardour/export_status.h index cb24cb55f5..31027269f8 100644 --- a/libs/ardour/ardour/export_status.h +++ b/libs/ardour/ardour/export_status.h @@ -40,7 +40,6 @@ class ExportStatus { volatile bool stop; volatile bool running; - PBD::Signal0 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; diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 5e75b4980b..b2a077162c 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -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; diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 90ff62f2a1..dffd65556a 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -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 r = Freewheel (nframes); - if (r.get_value_or (0)) { - jack_set_freewheel (_priv_jack, false); - } + + Freewheel (nframes); } else { MIDI::Manager::instance()->cycle_start(nframes); diff --git a/libs/ardour/export_channel.cc b/libs/ardour/export_channel.cc index 8deb31956d..9b3f50e85d 100644 --- a/libs/ardour/export_channel.cc +++ b/libs/ardour/export_channel.cc @@ -214,9 +214,9 @@ RouteExportChannel::~RouteExportChannel() } void -RouteExportChannel::create_from_route(std::list & result, Route & route) +RouteExportChannel::create_from_route(std::list & result, boost::shared_ptr route) { - boost::shared_ptr processor = route.add_export_point(); + boost::shared_ptr processor = route->add_export_point(); uint32_t channels = processor->input_streams().n_audio(); boost::shared_ptr 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); } diff --git a/libs/ardour/export_filename.cc b/libs/ardour/export_filename.cc index 3b8c27bc07..d00b0147a7 100644 --- a/libs/ardour/export_filename.cc +++ b/libs/ardour/export_filename.cc @@ -21,6 +21,9 @@ #include #include "ardour/export_filename.h" +#include +#include + #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 diff --git a/libs/ardour/export_status.cc b/libs/ardour/export_status.cc index 70ce8dd27e..0f7938bb7f 100644 --- a/libs/ardour/export_status.cc +++ b/libs/ardour/export_status.cc @@ -18,6 +18,8 @@ */ +#include + #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 diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc index 969f4bb609..d1ee5d8122 100644 --- a/libs/ardour/session_export.cc +++ b/libs/ardour/session_export.cc @@ -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);