2 Copyright (C) 1999-2013 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libardour-config.h"
31 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
49 #ifdef HAVE_SYS_STATVFS_H
50 #include <sys/statvfs.h>
54 #include <glib/gstdio.h>
57 #include <glibmm/threads.h>
59 #include <boost/algorithm/string.hpp>
61 #include "midi++/mmc.h"
62 #include "midi++/port.h"
64 #include "evoral/SMF.hpp"
66 #include "pbd/boost_debug.h"
67 #include "pbd/basename.h"
68 #include "pbd/controllable_descriptor.h"
69 #include "pbd/enumwriter.h"
70 #include "pbd/error.h"
71 #include "pbd/file_utils.h"
72 #include "pbd/pathscanner.h"
73 #include "pbd/pthread_utils.h"
74 #include "pbd/stacktrace.h"
75 #include "pbd/convert.h"
76 #include "pbd/clear_dir.h"
78 #include "ardour/amp.h"
79 #include "ardour/audio_diskstream.h"
80 #include "ardour/audio_track.h"
81 #include "ardour/audioengine.h"
82 #include "ardour/audiofilesource.h"
83 #include "ardour/audioregion.h"
84 #include "ardour/automation_control.h"
85 #include "ardour/butler.h"
86 #include "ardour/control_protocol_manager.h"
87 #include "ardour/directory_names.h"
88 #include "ardour/filename_extensions.h"
89 #include "ardour/graph.h"
90 #include "ardour/location.h"
91 #include "ardour/midi_model.h"
92 #include "ardour/midi_patch_manager.h"
93 #include "ardour/midi_region.h"
94 #include "ardour/midi_source.h"
95 #include "ardour/midi_track.h"
96 #include "ardour/pannable.h"
97 #include "ardour/playlist_factory.h"
98 #include "ardour/port.h"
99 #include "ardour/processor.h"
100 #include "ardour/proxy_controllable.h"
101 #include "ardour/recent_sessions.h"
102 #include "ardour/region_factory.h"
103 #include "ardour/route_group.h"
104 #include "ardour/send.h"
105 #include "ardour/session.h"
106 #include "ardour/session_directory.h"
107 #include "ardour/session_metadata.h"
108 #include "ardour/session_playlists.h"
109 #include "ardour/session_state_utils.h"
110 #include "ardour/silentfilesource.h"
111 #include "ardour/sndfilesource.h"
112 #include "ardour/source_factory.h"
113 #include "ardour/speakers.h"
114 #include "ardour/template_utils.h"
115 #include "ardour/tempo.h"
116 #include "ardour/ticker.h"
117 #include "ardour/user_bundle.h"
119 #include "control_protocol/control_protocol.h"
125 using namespace ARDOUR;
129 Session::pre_engine_init (string fullpath)
131 if (fullpath.empty()) {
133 throw failed_constructor();
136 /* discover canonical fullpath */
138 char buf[PATH_MAX+1];
140 if (!realpath (fullpath.c_str(), buf)) {
141 if (errno == ENOENT) {
142 /* fullpath does not exist yet, so realpath() returned
143 * ENOENT. Just use it as-is
147 error << string_compose(_("Could not use path %1 (%2)"), buf, strerror(errno)) << endmsg;
149 throw failed_constructor();
155 /* we require _path to end with a dir separator */
157 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
158 _path += G_DIR_SEPARATOR;
163 _is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
165 /* finish initialization that can't be done in a normal C++ constructor
169 timerclear (&last_mmc_step);
170 g_atomic_int_set (&processing_prohibited, 0);
171 g_atomic_int_set (&_record_status, Disabled);
172 g_atomic_int_set (&_playback_load, 100);
173 g_atomic_int_set (&_capture_load, 100);
175 _all_route_group->set_active (true, this);
176 interpolation.add_channel_to (0, 0);
178 if (config.get_use_video_sync()) {
179 waiting_for_sync_offset = true;
181 waiting_for_sync_offset = false;
184 last_rr_session_dir = session_dirs.begin();
186 set_history_depth (Config->get_history_depth());
188 /* default: assume simple stereo speaker configuration */
190 _speakers->setup_default_speakers (2);
192 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
193 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
194 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
195 add_controllable (_solo_cut_control);
197 /* These are all static "per-class" signals */
199 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
200 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
201 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
202 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
203 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
205 /* stop IO objects from doing stuff until we're ready for them */
207 Delivery::disable_panners ();
208 IO::disable_connecting ();
210 AudioFileSource::set_peak_dir (_session_dir->peak_path());
214 Session::post_engine_init ()
216 BootMessage (_("Set block size and sample rate"));
218 set_block_size (_engine.samples_per_cycle());
219 set_frame_rate (_engine.sample_rate());
221 BootMessage (_("Using configuration"));
223 _midi_ports = new MidiPortManager;
224 setup_midi_machine_control ();
226 if (_butler->start_thread()) {
230 if (start_midi_thread ()) {
234 setup_click_sounds (0);
235 setup_midi_control ();
237 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
238 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
241 /* tempo map requires sample rate knowledge */
243 _tempo_map = new TempoMap (_current_frame_rate);
244 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
246 /* MidiClock requires a tempo map */
248 midi_clock = new MidiClockTicker ();
249 midi_clock->set_session (this);
251 /* crossfades require sample rate knowledge */
253 SndFileSource::setup_standard_crossfades (*this, frame_rate());
254 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
256 AudioDiskstream::allocate_working_buffers();
257 refresh_disk_space ();
259 /* we're finally ready to call set_state() ... all objects have
260 * been created, the engine is running.
264 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
268 // set_state() will call setup_raid_path(), but if it's a new session we need
269 // to call setup_raid_path() here.
270 setup_raid_path (_path);
275 boost::function<void (std::string)> ff (boost::bind (&Session::config_changed, this, _1, false));
276 boost::function<void (std::string)> ft (boost::bind (&Session::config_changed, this, _1, true));
278 Config->map_parameters (ff);
279 config.map_parameters (ft);
281 /* Reset all panners */
283 Delivery::reset_panners ();
285 /* this will cause the CPM to instantiate any protocols that are in use
286 * (or mandatory), which will pass it this Session, and then call
287 * set_state() on each instantiated protocol to match stored state.
290 ControlProtocolManager::instance().set_session (this);
292 /* This must be done after the ControlProtocolManager set_session above,
293 as it will set states for ports which the ControlProtocolManager creates.
296 // XXX set state of MIDI::Port's
297 // MidiPortManager::instance()->set_port_states (Config->midi_port_states ());
299 /* And this must be done after the MIDI::Manager::set_port_states as
300 * it will try to make connections whose details are loaded by set_port_states.
305 /* Let control protocols know that we are now all connected, so they
306 * could start talking to surfaces if they want to.
309 ControlProtocolManager::instance().midi_connectivity_established ();
311 if (_is_new && !no_auto_connect()) {
312 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock());
313 auto_connect_master_bus ();
316 _state_of_the_state = StateOfTheState (_state_of_the_state & ~(CannotSave|Dirty));
318 /* update latencies */
320 initialize_latencies ();
322 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
323 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
325 } catch (AudioEngine::PortRegistrationFailure& err) {
326 /* handle this one in a different way than all others, so that its clear what happened */
327 error << err.what() << endmsg;
333 BootMessage (_("Reset Remote Controls"));
335 // send_full_time_code (0);
336 _engine.transport_locate (0);
338 _mmc->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
339 _mmc->send (MIDI::MachineControlCommand (Timecode::Time ()));
341 MIDI::Name::MidiPatchManager::instance().set_session (this);
344 /* initial program change will be delivered later; see ::config_changed() */
346 _state_of_the_state = Clean;
348 Port::set_connecting_blocked (false);
350 DirtyChanged (); /* EMIT SIGNAL */
354 } else if (state_was_pending) {
356 remove_pending_capture_state ();
357 state_was_pending = false;
364 Session::raid_path () const
366 SearchPath raid_search_path;
368 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
369 raid_search_path += (*i).path;
372 return raid_search_path.to_string ();
376 Session::setup_raid_path (string path)
385 session_dirs.clear ();
387 SearchPath search_path(path);
388 SearchPath sound_search_path;
389 SearchPath midi_search_path;
391 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
393 sp.blocks = 0; // not needed
394 session_dirs.push_back (sp);
396 SessionDirectory sdir(sp.path);
398 sound_search_path += sdir.sound_path ();
399 midi_search_path += sdir.midi_path ();
402 // reset the round-robin soundfile path thingie
403 last_rr_session_dir = session_dirs.begin();
407 Session::path_is_within_session (const std::string& path)
409 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
410 if (PBD::path_is_within (i->path, path)) {
418 Session::ensure_subdirs ()
422 dir = session_directory().peak_path();
424 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
425 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
429 dir = session_directory().sound_path();
431 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
432 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
436 dir = session_directory().midi_path();
438 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
439 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
443 dir = session_directory().dead_path();
445 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
446 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
450 dir = session_directory().export_path();
452 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
453 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
457 dir = analysis_dir ();
459 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
460 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
464 dir = plugins_dir ();
466 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
467 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471 dir = externals_dir ();
473 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
474 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
481 /** @param session_template directory containing session template, or empty.
482 * Caller must not hold process lock.
485 Session::create (const string& session_template, BusProfile* bus_profile)
487 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
488 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
492 if (ensure_subdirs ()) {
496 _writable = exists_and_writable (_path);
498 if (!session_template.empty()) {
499 std::string in_path = session_template_dir_to_file (session_template);
501 ifstream in(in_path.c_str());
504 /* no need to call legalize_for_path() since the string
505 * in session_template is already a legal path name
507 string out_path = Glib::build_filename (_session_dir->root_path(), _name + statefile_suffix);
509 ofstream out(out_path.c_str());
515 /* Copy plugin state files from template to new session */
516 std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
517 copy_files (template_plugins, plugins_dir ());
522 error << string_compose (_("Could not open %1 for writing session template"), out_path)
528 error << string_compose (_("Could not open session template %1 for reading"), in_path)
535 /* set initial start + end point */
537 _state_of_the_state = Clean;
539 /* set up Master Out and Control Out if necessary */
544 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
546 if (bus_profile->master_out_channels) {
547 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
551 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
552 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
555 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
556 r->input()->ensure_io (count, false, this);
557 r->output()->ensure_io (count, false, this);
563 /* prohibit auto-connect to master, because there isn't one */
564 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
568 add_routes (rl, false, false, false);
571 /* this allows the user to override settings with an environment variable.
574 if (no_auto_connect()) {
575 bus_profile->input_ac = AutoConnectOption (0);
576 bus_profile->output_ac = AutoConnectOption (0);
579 Config->set_input_auto_connect (bus_profile->input_ac);
580 Config->set_output_auto_connect (bus_profile->output_ac);
583 if (Config->get_use_monitor_bus() && bus_profile) {
584 add_monitor_section ();
591 Session::maybe_write_autosave()
593 if (dirty() && record_status() != Recording) {
594 save_state("", true);
599 Session::remove_pending_capture_state ()
601 std::string pending_state_file_path(_session_dir->root_path());
603 pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
605 if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
607 if (g_remove (pending_state_file_path.c_str()) != 0) {
608 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
609 pending_state_file_path, g_strerror (errno)) << endmsg;
613 /** Rename a state file.
614 * @param old_name Old snapshot name.
615 * @param new_name New snapshot name.
618 Session::rename_state (string old_name, string new_name)
620 if (old_name == _current_snapshot_name || old_name == _name) {
621 /* refuse to rename the current snapshot or the "main" one */
625 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
626 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
628 const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
629 const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
631 if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
632 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
633 old_name, new_name, g_strerror(errno)) << endmsg;
637 /** Remove a state file.
638 * @param snapshot_name Snapshot name.
641 Session::remove_state (string snapshot_name)
643 if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
644 // refuse to remove the current snapshot or the "main" one
648 std::string xml_path(_session_dir->root_path());
650 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
652 if (!create_backup_file (xml_path)) {
653 // don't remove it if a backup can't be made
654 // create_backup_file will log the error.
659 if (g_remove (xml_path.c_str()) != 0) {
660 error << string_compose(_("Could not remove session file at path \"%1\" (%2)"),
661 xml_path, g_strerror (errno)) << endmsg;
665 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
667 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
670 std::string xml_path(_session_dir->root_path());
672 if (!_writable || (_state_of_the_state & CannotSave)) {
676 if (!_engine.connected ()) {
677 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
683 /* tell sources we're saving first, in case they write out to a new file
684 * which should be saved with the state rather than the old one */
685 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
687 i->second->session_saved();
688 } catch (Evoral::SMF::FileError& e) {
689 error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
693 SaveSession (); /* EMIT SIGNAL */
695 tree.set_root (&get_state());
697 if (snapshot_name.empty()) {
698 snapshot_name = _current_snapshot_name;
699 } else if (switch_to_snapshot) {
700 _current_snapshot_name = snapshot_name;
705 /* proper save: use statefile_suffix (.ardour in English) */
707 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
709 /* make a backup copy of the old file */
711 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
712 // create_backup_file will log the error
718 /* pending save: use pending_suffix (.pending in English) */
719 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
722 std::string tmp_path(_session_dir->root_path());
723 tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
725 // cerr << "actually writing state to " << xml_path << endl;
727 if (!tree.write (tmp_path)) {
728 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
729 if (g_remove (tmp_path.c_str()) != 0) {
730 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
731 tmp_path, g_strerror (errno)) << endmsg;
737 if (::rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
738 error << string_compose (_("could not rename temporary session file %1 to %2"),
739 tmp_path, xml_path) << endmsg;
740 if (g_remove (tmp_path.c_str()) != 0) {
741 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
742 tmp_path, g_strerror (errno)) << endmsg;
750 save_history (snapshot_name);
752 bool was_dirty = dirty();
754 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
757 DirtyChanged (); /* EMIT SIGNAL */
760 StateSaved (snapshot_name); /* EMIT SIGNAL */
767 Session::restore_state (string snapshot_name)
769 if (load_state (snapshot_name) == 0) {
770 set_state (*state_tree->root(), Stateful::loading_state_version);
777 Session::load_state (string snapshot_name)
782 state_was_pending = false;
784 /* check for leftover pending state from a crashed capture attempt */
786 std::string xmlpath(_session_dir->root_path());
787 xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
789 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
791 /* there is pending state from a crashed capture attempt */
793 boost::optional<int> r = AskAboutPendingState();
794 if (r.get_value_or (1)) {
795 state_was_pending = true;
799 if (!state_was_pending) {
800 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
803 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
804 xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
805 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
806 error << string_compose(_("%1: session file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
811 state_tree = new XMLTree;
815 _writable = exists_and_writable (xmlpath);
817 if (!state_tree->read (xmlpath)) {
818 error << string_compose(_("Could not understand session file %1"), xmlpath) << endmsg;
824 XMLNode& root (*state_tree->root());
826 if (root.name() != X_("Session")) {
827 error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
833 const XMLProperty* prop;
835 if ((prop = root.property ("version")) == 0) {
836 /* no version implies very old version of Ardour */
837 Stateful::loading_state_version = 1000;
839 if (prop->value().find ('.') != string::npos) {
840 /* old school version format */
841 if (prop->value()[0] == '2') {
842 Stateful::loading_state_version = 2000;
844 Stateful::loading_state_version = 3000;
847 Stateful::loading_state_version = atoi (prop->value());
851 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
853 std::string backup_path(_session_dir->root_path());
854 std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
855 backup_path = Glib::build_filename (backup_path, backup_filename);
857 // only create a backup for a given statefile version once
859 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
861 VersionMismatch (xmlpath, backup_path);
863 if (!copy_file (xmlpath, backup_path)) {;
873 Session::load_options (const XMLNode& node)
875 LocaleGuard lg (X_("POSIX"));
876 config.set_variables (node);
887 Session::get_template()
889 /* if we don't disable rec-enable, diskstreams
890 will believe they need to store their capture
891 sources in their state node.
894 disable_record (false);
900 Session::state (bool full_state)
902 XMLNode* node = new XMLNode("Session");
906 snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
907 node->add_property("version", buf);
909 /* store configuration settings */
913 node->add_property ("name", _name);
914 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
915 node->add_property ("sample-rate", buf);
917 if (session_dirs.size() > 1) {
921 vector<space_and_path>::iterator i = session_dirs.begin();
922 vector<space_and_path>::iterator next;
924 ++i; /* skip the first one */
928 while (i != session_dirs.end()) {
932 if (next != session_dirs.end()) {
942 child = node->add_child ("Path");
943 child->add_content (p);
947 /* save the ID counter */
949 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
950 node->add_property ("id-counter", buf);
952 /* save the event ID counter */
954 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
955 node->add_property ("event-counter", buf);
957 /* various options */
959 list<XMLNode*> midi_port_nodes = _midi_ports->get_midi_port_states();
960 if (!midi_port_nodes.empty()) {
961 XMLNode* midi_port_stuff = new XMLNode ("MIDIPorts");
962 for (list<XMLNode*>::const_iterator n = midi_port_nodes.begin(); n != midi_port_nodes.end(); ++n) {
963 midi_port_stuff->add_child_nocopy (**n);
965 node->add_child_nocopy (*midi_port_stuff);
968 node->add_child_nocopy (config.get_variables ());
970 node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
972 child = node->add_child ("Sources");
975 Glib::Threads::Mutex::Lock sl (source_lock);
977 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
979 /* Don't save information about non-file Sources, or
980 * about non-destructive file sources that are empty
981 * and unused by any regions.
984 boost::shared_ptr<FileSource> fs;
986 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
988 if (!fs->destructive()) {
989 if (fs->empty() && !fs->used()) {
994 child->add_child_nocopy (siter->second->get_state());
999 child = node->add_child ("Regions");
1002 Glib::Threads::Mutex::Lock rl (region_lock);
1003 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1004 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1005 boost::shared_ptr<Region> r = i->second;
1006 /* only store regions not attached to playlists */
1007 if (r->playlist() == 0) {
1008 if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
1009 child->add_child_nocopy ((boost::dynamic_pointer_cast<AudioRegion>(r))->get_basic_state ());
1011 child->add_child_nocopy (r->get_state ());
1016 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1018 if (!cassocs.empty()) {
1019 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1021 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1023 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1024 i->first->id().print (buf, sizeof (buf));
1025 can->add_property (X_("copy"), buf);
1026 i->second->id().print (buf, sizeof (buf));
1027 can->add_property (X_("original"), buf);
1028 ca->add_child_nocopy (*can);
1034 node->add_child_nocopy (_locations->get_state());
1036 // for a template, just create a new Locations, populate it
1037 // with the default start and end, and get the state for that.
1038 Locations loc (*this);
1039 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1040 range->set (max_framepos, 0);
1042 node->add_child_nocopy (loc.get_state());
1045 child = node->add_child ("Bundles");
1047 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1048 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1049 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1051 child->add_child_nocopy (b->get_state());
1056 child = node->add_child ("Routes");
1058 boost::shared_ptr<RouteList> r = routes.reader ();
1060 RoutePublicOrderSorter cmp;
1061 RouteList public_order (*r);
1062 public_order.sort (cmp);
1064 /* the sort should have put control outs first */
1067 assert (_monitor_out == public_order.front());
1070 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1071 if (!(*i)->is_auditioner()) {
1073 child->add_child_nocopy ((*i)->get_state());
1075 child->add_child_nocopy ((*i)->get_template());
1081 playlists->add_state (node, full_state);
1083 child = node->add_child ("RouteGroups");
1084 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1085 child->add_child_nocopy ((*i)->get_state());
1089 XMLNode* gain_child = node->add_child ("Click");
1090 gain_child->add_child_nocopy (_click_io->state (full_state));
1091 gain_child->add_child_nocopy (_click_gain->state (full_state));
1095 XMLNode* ltc_input_child = node->add_child ("LTC-In");
1096 ltc_input_child->add_child_nocopy (_ltc_input->state (full_state));
1100 XMLNode* ltc_output_child = node->add_child ("LTC-Out");
1101 ltc_output_child->add_child_nocopy (_ltc_output->state (full_state));
1104 node->add_child_nocopy (_speakers->get_state());
1105 node->add_child_nocopy (_tempo_map->get_state());
1106 node->add_child_nocopy (get_control_protocol_state());
1109 node->add_child_copy (*_extra_xml);
1116 Session::get_control_protocol_state ()
1118 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1119 return cpm.get_state();
1123 Session::set_state (const XMLNode& node, int version)
1127 const XMLProperty* prop;
1130 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1132 if (node.name() != X_("Session")) {
1133 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1137 if ((prop = node.property ("name")) != 0) {
1138 _name = prop->value ();
1141 if ((prop = node.property (X_("sample-rate"))) != 0) {
1143 _nominal_frame_rate = atoi (prop->value());
1145 if (_nominal_frame_rate != _current_frame_rate) {
1146 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1147 if (r.get_value_or (0)) {
1153 setup_raid_path(_session_dir->root_path());
1155 if ((prop = node.property (X_("id-counter"))) != 0) {
1157 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1158 ID::init_counter (x);
1160 /* old sessions used a timebased counter, so fake
1161 the startup ID counter based on a standard
1166 ID::init_counter (now);
1169 if ((prop = node.property (X_("event-counter"))) != 0) {
1170 Evoral::init_event_id_counter (atoi (prop->value()));
1174 if ((child = find_named_node (node, "MIDIPorts")) != 0) {
1175 _midi_ports->set_midi_port_states (child->children());
1178 IO::disable_connecting ();
1180 Stateful::save_extra_xml (node);
1182 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1183 load_options (*child);
1184 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1185 load_options (*child);
1187 error << _("Session: XML state has no options section") << endmsg;
1190 if (version >= 3000) {
1191 if ((child = find_named_node (node, "Metadata")) == 0) {
1192 warning << _("Session: XML state has no metadata section") << endmsg;
1193 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1198 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1199 _speakers->set_state (*child, version);
1202 if ((child = find_named_node (node, "Sources")) == 0) {
1203 error << _("Session: XML state has no sources section") << endmsg;
1205 } else if (load_sources (*child)) {
1209 if ((child = find_named_node (node, "TempoMap")) == 0) {
1210 error << _("Session: XML state has no Tempo Map section") << endmsg;
1212 } else if (_tempo_map->set_state (*child, version)) {
1216 if ((child = find_named_node (node, "Locations")) == 0) {
1217 error << _("Session: XML state has no locations section") << endmsg;
1219 } else if (_locations->set_state (*child, version)) {
1225 if ((location = _locations->auto_loop_location()) != 0) {
1226 set_auto_loop_location (location);
1229 if ((location = _locations->auto_punch_location()) != 0) {
1230 set_auto_punch_location (location);
1233 if ((location = _locations->session_range_location()) != 0) {
1234 delete _session_range_location;
1235 _session_range_location = location;
1238 if (_session_range_location) {
1239 AudioFileSource::set_header_position_offset (_session_range_location->start());
1242 if ((child = find_named_node (node, "Regions")) == 0) {
1243 error << _("Session: XML state has no Regions section") << endmsg;
1245 } else if (load_regions (*child)) {
1249 if ((child = find_named_node (node, "Playlists")) == 0) {
1250 error << _("Session: XML state has no playlists section") << endmsg;
1252 } else if (playlists->load (*this, *child)) {
1256 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1258 } else if (playlists->load_unused (*this, *child)) {
1262 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1263 if (load_compounds (*child)) {
1268 if (version >= 3000) {
1269 if ((child = find_named_node (node, "Bundles")) == 0) {
1270 warning << _("Session: XML state has no bundles section") << endmsg;
1273 /* We can't load Bundles yet as they need to be able
1274 to convert from port names to Port objects, which can't happen until
1276 _bundle_xml_node = new XMLNode (*child);
1280 if (version < 3000) {
1281 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1282 error << _("Session: XML state has no diskstreams section") << endmsg;
1284 } else if (load_diskstreams_2X (*child, version)) {
1289 if ((child = find_named_node (node, "Routes")) == 0) {
1290 error << _("Session: XML state has no routes section") << endmsg;
1292 } else if (load_routes (*child, version)) {
1296 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1297 _diskstreams_2X.clear ();
1299 if (version >= 3000) {
1301 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1302 error << _("Session: XML state has no route groups section") << endmsg;
1304 } else if (load_route_groups (*child, version)) {
1308 } else if (version < 3000) {
1310 if ((child = find_named_node (node, "EditGroups")) == 0) {
1311 error << _("Session: XML state has no edit groups section") << endmsg;
1313 } else if (load_route_groups (*child, version)) {
1317 if ((child = find_named_node (node, "MixGroups")) == 0) {
1318 error << _("Session: XML state has no mix groups section") << endmsg;
1320 } else if (load_route_groups (*child, version)) {
1325 if ((child = find_named_node (node, "Click")) == 0) {
1326 warning << _("Session: XML state has no click section") << endmsg;
1327 } else if (_click_io) {
1328 setup_click_state (&node);
1331 if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
1332 ControlProtocolManager::instance().set_state (*child, version);
1335 update_have_rec_enabled_track ();
1337 /* here beginneth the second phase ... */
1339 StateReady (); /* EMIT SIGNAL */
1348 Session::load_routes (const XMLNode& node, int version)
1351 XMLNodeConstIterator niter;
1352 RouteList new_routes;
1354 nlist = node.children();
1358 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1360 boost::shared_ptr<Route> route;
1361 if (version < 3000) {
1362 route = XMLRouteFactory_2X (**niter, version);
1364 route = XMLRouteFactory (**niter, version);
1368 error << _("Session: cannot create Route from XML description.") << endmsg;
1372 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1374 new_routes.push_back (route);
1377 add_routes (new_routes, false, false, false);
1382 boost::shared_ptr<Route>
1383 Session::XMLRouteFactory (const XMLNode& node, int version)
1385 boost::shared_ptr<Route> ret;
1387 if (node.name() != "Route") {
1391 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1393 DataType type = DataType::AUDIO;
1394 const XMLProperty* prop = node.property("default-type");
1397 type = DataType (prop->value());
1400 assert (type != DataType::NIL);
1404 boost::shared_ptr<Track> track;
1406 if (type == DataType::AUDIO) {
1407 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1409 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1412 if (track->init()) {
1416 if (track->set_state (node, version)) {
1420 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1421 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1426 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1428 if (r->init () == 0 && r->set_state (node, version) == 0) {
1429 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1430 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1439 boost::shared_ptr<Route>
1440 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1442 boost::shared_ptr<Route> ret;
1444 if (node.name() != "Route") {
1448 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1450 ds_prop = node.property (X_("diskstream"));
1453 DataType type = DataType::AUDIO;
1454 const XMLProperty* prop = node.property("default-type");
1457 type = DataType (prop->value());
1460 assert (type != DataType::NIL);
1464 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1465 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1469 if (i == _diskstreams_2X.end()) {
1470 error << _("Could not find diskstream for route") << endmsg;
1471 return boost::shared_ptr<Route> ();
1474 boost::shared_ptr<Track> track;
1476 if (type == DataType::AUDIO) {
1477 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1479 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1482 if (track->init()) {
1486 if (track->set_state (node, version)) {
1490 track->set_diskstream (*i);
1492 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1493 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1498 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1500 if (r->init () == 0 && r->set_state (node, version) == 0) {
1501 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1502 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1512 Session::load_regions (const XMLNode& node)
1515 XMLNodeConstIterator niter;
1516 boost::shared_ptr<Region> region;
1518 nlist = node.children();
1522 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1523 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1524 error << _("Session: cannot create Region from XML description.");
1525 const XMLProperty *name = (**niter).property("name");
1528 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1539 Session::load_compounds (const XMLNode& node)
1541 XMLNodeList calist = node.children();
1542 XMLNodeConstIterator caiter;
1543 XMLProperty *caprop;
1545 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1546 XMLNode* ca = *caiter;
1550 if ((caprop = ca->property (X_("original"))) == 0) {
1553 orig_id = caprop->value();
1555 if ((caprop = ca->property (X_("copy"))) == 0) {
1558 copy_id = caprop->value();
1560 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1561 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1563 if (!orig || !copy) {
1564 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1570 RegionFactory::add_compound_association (orig, copy);
1577 Session::load_nested_sources (const XMLNode& node)
1580 XMLNodeConstIterator niter;
1582 nlist = node.children();
1584 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1585 if ((*niter)->name() == "Source") {
1587 /* it may already exist, so don't recreate it unnecessarily
1590 XMLProperty* prop = (*niter)->property (X_("id"));
1592 error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
1596 ID source_id (prop->value());
1598 if (!source_by_id (source_id)) {
1601 SourceFactory::create (*this, **niter, true);
1603 catch (failed_constructor& err) {
1604 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1611 boost::shared_ptr<Region>
1612 Session::XMLRegionFactory (const XMLNode& node, bool full)
1614 const XMLProperty* type = node.property("type");
1618 const XMLNodeList& nlist = node.children();
1620 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1621 XMLNode *child = (*niter);
1622 if (child->name() == "NestedSource") {
1623 load_nested_sources (*child);
1627 if (!type || type->value() == "audio") {
1628 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1629 } else if (type->value() == "midi") {
1630 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1633 } catch (failed_constructor& err) {
1634 return boost::shared_ptr<Region> ();
1637 return boost::shared_ptr<Region> ();
1640 boost::shared_ptr<AudioRegion>
1641 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1643 const XMLProperty* prop;
1644 boost::shared_ptr<Source> source;
1645 boost::shared_ptr<AudioSource> as;
1647 SourceList master_sources;
1648 uint32_t nchans = 1;
1651 if (node.name() != X_("Region")) {
1652 return boost::shared_ptr<AudioRegion>();
1655 if ((prop = node.property (X_("channels"))) != 0) {
1656 nchans = atoi (prop->value().c_str());
1659 if ((prop = node.property ("name")) == 0) {
1660 cerr << "no name for this region\n";
1664 if ((prop = node.property (X_("source-0"))) == 0) {
1665 if ((prop = node.property ("source")) == 0) {
1666 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1667 return boost::shared_ptr<AudioRegion>();
1671 PBD::ID s_id (prop->value());
1673 if ((source = source_by_id (s_id)) == 0) {
1674 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1675 return boost::shared_ptr<AudioRegion>();
1678 as = boost::dynamic_pointer_cast<AudioSource>(source);
1680 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1681 return boost::shared_ptr<AudioRegion>();
1684 sources.push_back (as);
1686 /* pickup other channels */
1688 for (uint32_t n=1; n < nchans; ++n) {
1689 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1690 if ((prop = node.property (buf)) != 0) {
1692 PBD::ID id2 (prop->value());
1694 if ((source = source_by_id (id2)) == 0) {
1695 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1696 return boost::shared_ptr<AudioRegion>();
1699 as = boost::dynamic_pointer_cast<AudioSource>(source);
1701 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1702 return boost::shared_ptr<AudioRegion>();
1704 sources.push_back (as);
1708 for (uint32_t n = 0; n < nchans; ++n) {
1709 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1710 if ((prop = node.property (buf)) != 0) {
1712 PBD::ID id2 (prop->value());
1714 if ((source = source_by_id (id2)) == 0) {
1715 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1716 return boost::shared_ptr<AudioRegion>();
1719 as = boost::dynamic_pointer_cast<AudioSource>(source);
1721 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1722 return boost::shared_ptr<AudioRegion>();
1724 master_sources.push_back (as);
1729 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1731 /* a final detail: this is the one and only place that we know how long missing files are */
1733 if (region->whole_file()) {
1734 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1735 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1737 sfp->set_length (region->length());
1742 if (!master_sources.empty()) {
1743 if (master_sources.size() != nchans) {
1744 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1746 region->set_master_sources (master_sources);
1754 catch (failed_constructor& err) {
1755 return boost::shared_ptr<AudioRegion>();
1759 boost::shared_ptr<MidiRegion>
1760 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1762 const XMLProperty* prop;
1763 boost::shared_ptr<Source> source;
1764 boost::shared_ptr<MidiSource> ms;
1767 if (node.name() != X_("Region")) {
1768 return boost::shared_ptr<MidiRegion>();
1771 if ((prop = node.property ("name")) == 0) {
1772 cerr << "no name for this region\n";
1776 if ((prop = node.property (X_("source-0"))) == 0) {
1777 if ((prop = node.property ("source")) == 0) {
1778 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1779 return boost::shared_ptr<MidiRegion>();
1783 PBD::ID s_id (prop->value());
1785 if ((source = source_by_id (s_id)) == 0) {
1786 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1787 return boost::shared_ptr<MidiRegion>();
1790 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1792 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1793 return boost::shared_ptr<MidiRegion>();
1796 sources.push_back (ms);
1799 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1800 /* a final detail: this is the one and only place that we know how long missing files are */
1802 if (region->whole_file()) {
1803 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1804 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1806 sfp->set_length (region->length());
1814 catch (failed_constructor& err) {
1815 return boost::shared_ptr<MidiRegion>();
1820 Session::get_sources_as_xml ()
1823 XMLNode* node = new XMLNode (X_("Sources"));
1824 Glib::Threads::Mutex::Lock lm (source_lock);
1826 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1827 node->add_child_nocopy (i->second->get_state());
1834 Session::load_sources (const XMLNode& node)
1837 XMLNodeConstIterator niter;
1838 boost::shared_ptr<Source> source;
1840 nlist = node.children();
1844 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1847 if ((source = XMLSourceFactory (**niter)) == 0) {
1848 error << _("Session: cannot create Source from XML description.") << endmsg;
1851 } catch (MissingSource& err) {
1855 if (!no_questions_about_missing_files) {
1856 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1861 switch (user_choice) {
1863 /* user added a new search location, so try again */
1868 /* user asked to quit the entire session load
1873 no_questions_about_missing_files = true;
1877 no_questions_about_missing_files = true;
1884 case DataType::AUDIO:
1885 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1886 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1889 case DataType::MIDI:
1890 warning << string_compose (_("A MIDI file is missing. %1 cannot currently recover from missing MIDI files"),
1891 PROGRAM_NAME) << endmsg;
1903 boost::shared_ptr<Source>
1904 Session::XMLSourceFactory (const XMLNode& node)
1906 if (node.name() != "Source") {
1907 return boost::shared_ptr<Source>();
1911 /* note: do peak building in another thread when loading session state */
1912 return SourceFactory::create (*this, node, true);
1915 catch (failed_constructor& err) {
1916 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1917 return boost::shared_ptr<Source>();
1922 Session::save_template (string template_name)
1926 if (_state_of_the_state & CannotSave) {
1930 std::string user_template_dir(user_template_directory());
1932 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
1933 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
1934 user_template_dir, g_strerror (errno)) << endmsg;
1938 tree.set_root (&get_template());
1940 std::string template_dir_path(user_template_dir);
1942 /* directory to put the template in */
1943 template_dir_path = Glib::build_filename (template_dir_path, template_name);
1945 if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
1946 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1947 template_dir_path) << endmsg;
1951 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
1952 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
1953 template_dir_path, g_strerror (errno)) << endmsg;
1958 std::string template_file_path(template_dir_path);
1959 template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
1961 if (!tree.write (template_file_path)) {
1962 error << _("template not saved") << endmsg;
1966 /* copy plugin state directory */
1968 std::string template_plugin_state_path(template_dir_path);
1969 template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
1971 if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
1972 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
1973 template_plugin_state_path, g_strerror (errno)) << endmsg;
1977 copy_files (plugins_dir(), template_plugin_state_path);
1983 Session::refresh_disk_space ()
1985 #if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
1987 Glib::Threads::Mutex::Lock lm (space_lock);
1989 /* get freespace on every FS that is part of the session path */
1991 _total_free_4k_blocks = 0;
1992 _total_free_4k_blocks_uncertain = false;
1994 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1996 struct statfs statfsbuf;
1997 statfs (i->path.c_str(), &statfsbuf);
1999 double const scale = statfsbuf.f_bsize / 4096.0;
2001 /* See if this filesystem is read-only */
2002 struct statvfs statvfsbuf;
2003 statvfs (i->path.c_str(), &statvfsbuf);
2005 /* f_bavail can be 0 if it is undefined for whatever
2006 filesystem we are looking at; Samba shares mounted
2007 via GVFS are an example of this.
2009 if (statfsbuf.f_bavail == 0) {
2010 /* block count unknown */
2012 i->blocks_unknown = true;
2013 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2014 /* read-only filesystem */
2016 i->blocks_unknown = false;
2018 /* read/write filesystem with known space */
2019 i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2020 i->blocks_unknown = false;
2023 _total_free_4k_blocks += i->blocks;
2024 if (i->blocks_unknown) {
2025 _total_free_4k_blocks_uncertain = true;
2032 Session::get_best_session_directory_for_new_audio ()
2034 vector<space_and_path>::iterator i;
2035 string result = _session_dir->root_path();
2037 /* handle common case without system calls */
2039 if (session_dirs.size() == 1) {
2043 /* OK, here's the algorithm we're following here:
2045 We want to select which directory to use for
2046 the next file source to be created. Ideally,
2047 we'd like to use a round-robin process so as to
2048 get maximum performance benefits from splitting
2049 the files across multiple disks.
2051 However, in situations without much diskspace, an
2052 RR approach may end up filling up a filesystem
2053 with new files while others still have space.
2054 Its therefore important to pay some attention to
2055 the freespace in the filesystem holding each
2056 directory as well. However, if we did that by
2057 itself, we'd keep creating new files in the file
2058 system with the most space until it was as full
2059 as all others, thus negating any performance
2060 benefits of this RAID-1 like approach.
2062 So, we use a user-configurable space threshold. If
2063 there are at least 2 filesystems with more than this
2064 much space available, we use RR selection between them.
2065 If not, then we pick the filesystem with the most space.
2067 This gets a good balance between the two
2071 refresh_disk_space ();
2073 int free_enough = 0;
2075 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2076 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2081 if (free_enough >= 2) {
2082 /* use RR selection process, ensuring that the one
2086 i = last_rr_session_dir;
2089 if (++i == session_dirs.end()) {
2090 i = session_dirs.begin();
2093 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2094 SessionDirectory sdir(i->path);
2095 if (sdir.create ()) {
2097 last_rr_session_dir = i;
2102 } while (i != last_rr_session_dir);
2106 /* pick FS with the most freespace (and that
2107 seems to actually work ...)
2110 vector<space_and_path> sorted;
2111 space_and_path_ascending_cmp cmp;
2113 sorted = session_dirs;
2114 sort (sorted.begin(), sorted.end(), cmp);
2116 for (i = sorted.begin(); i != sorted.end(); ++i) {
2117 SessionDirectory sdir(i->path);
2118 if (sdir.create ()) {
2120 last_rr_session_dir = i;
2130 Session::automation_dir () const
2132 return Glib::build_filename (_path, "automation");
2136 Session::analysis_dir () const
2138 return Glib::build_filename (_path, "analysis");
2142 Session::plugins_dir () const
2144 return Glib::build_filename (_path, "plugins");
2148 Session::externals_dir () const
2150 return Glib::build_filename (_path, "externals");
2154 Session::load_bundles (XMLNode const & node)
2156 XMLNodeList nlist = node.children();
2157 XMLNodeConstIterator niter;
2161 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2162 if ((*niter)->name() == "InputBundle") {
2163 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2164 } else if ((*niter)->name() == "OutputBundle") {
2165 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2167 error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2176 Session::load_route_groups (const XMLNode& node, int version)
2178 XMLNodeList nlist = node.children();
2179 XMLNodeConstIterator niter;
2183 if (version >= 3000) {
2185 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2186 if ((*niter)->name() == "RouteGroup") {
2187 RouteGroup* rg = new RouteGroup (*this, "");
2188 add_route_group (rg);
2189 rg->set_state (**niter, version);
2193 } else if (version < 3000) {
2195 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2196 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2197 RouteGroup* rg = new RouteGroup (*this, "");
2198 add_route_group (rg);
2199 rg->set_state (**niter, version);
2208 Session::auto_save()
2210 save_state (_current_snapshot_name);
2214 state_file_filter (const string &str, void */*arg*/)
2216 return (str.length() > strlen(statefile_suffix) &&
2217 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2221 bool operator()(const string* a, const string* b) {
2227 remove_end(string* state)
2229 string statename(*state);
2231 string::size_type start,end;
2232 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2233 statename = statename.substr (start+1);
2236 if ((end = statename.rfind(".ardour")) == string::npos) {
2237 end = statename.length();
2240 return new string(statename.substr (0, end));
2244 Session::possible_states (string path)
2246 PathScanner scanner;
2247 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2249 transform(states->begin(), states->end(), states->begin(), remove_end);
2252 sort (states->begin(), states->end(), cmp);
2258 Session::possible_states () const
2260 return possible_states(_path);
2264 Session::add_route_group (RouteGroup* g)
2266 _route_groups.push_back (g);
2267 route_group_added (g); /* EMIT SIGNAL */
2269 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2270 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2271 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2277 Session::remove_route_group (RouteGroup& rg)
2279 list<RouteGroup*>::iterator i;
2281 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2282 _route_groups.erase (i);
2285 route_group_removed (); /* EMIT SIGNAL */
2289 /** Set a new order for our route groups, without adding or removing any.
2290 * @param groups Route group list in the new order.
2293 Session::reorder_route_groups (list<RouteGroup*> groups)
2295 _route_groups = groups;
2297 route_groups_reordered (); /* EMIT SIGNAL */
2303 Session::route_group_by_name (string name)
2305 list<RouteGroup *>::iterator i;
2307 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2308 if ((*i)->name() == name) {
2316 Session::all_route_group() const
2318 return *_all_route_group;
2322 Session::add_commands (vector<Command*> const & cmds)
2324 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2330 Session::begin_reversible_command (const string& name)
2332 begin_reversible_command (g_quark_from_string (name.c_str ()));
2335 /** Begin a reversible command using a GQuark to identify it.
2336 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2337 * but there must be as many begin...()s as there are commit...()s.
2340 Session::begin_reversible_command (GQuark q)
2342 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2343 to hold all the commands that are committed. This keeps the order of
2344 commands correct in the history.
2347 if (_current_trans == 0) {
2348 /* start a new transaction */
2349 assert (_current_trans_quarks.empty ());
2350 _current_trans = new UndoTransaction();
2351 _current_trans->set_name (g_quark_to_string (q));
2354 _current_trans_quarks.push_front (q);
2358 Session::commit_reversible_command (Command *cmd)
2360 assert (_current_trans);
2361 assert (!_current_trans_quarks.empty ());
2366 _current_trans->add_command (cmd);
2369 _current_trans_quarks.pop_front ();
2371 if (!_current_trans_quarks.empty ()) {
2372 /* the transaction we're committing is not the top-level one */
2376 if (_current_trans->empty()) {
2377 /* no commands were added to the transaction, so just get rid of it */
2378 delete _current_trans;
2383 gettimeofday (&now, 0);
2384 _current_trans->set_timestamp (now);
2386 _history.add (_current_trans);
2391 accept_all_audio_files (const string& path, void */*arg*/)
2393 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2397 if (!AudioFileSource::safe_audio_file_extension (path)) {
2405 accept_all_midi_files (const string& path, void */*arg*/)
2407 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2411 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2412 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2413 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2417 accept_all_state_files (const string& path, void */*arg*/)
2419 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2423 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2427 Session::find_all_sources (string path, set<string>& result)
2432 if (!tree.read (path)) {
2436 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2441 XMLNodeConstIterator niter;
2443 nlist = node->children();
2447 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2451 if ((prop = (*niter)->property (X_("type"))) == 0) {
2455 DataType type (prop->value());
2457 if ((prop = (*niter)->property (X_("name"))) == 0) {
2461 if (Glib::path_is_absolute (prop->value())) {
2462 /* external file, ignore */
2470 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2471 result.insert (found_path);
2479 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2481 PathScanner scanner;
2482 vector<string*>* state_files;
2484 string this_snapshot_path;
2490 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2491 ripped = ripped.substr (0, ripped.length() - 1);
2494 state_files = scanner (ripped, accept_all_state_files, (void *) 0, true, true);
2496 if (state_files == 0) {
2501 this_snapshot_path = _path;
2502 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2503 this_snapshot_path += statefile_suffix;
2505 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2507 if (exclude_this_snapshot && **i == this_snapshot_path) {
2511 if (find_all_sources (**i, result) < 0) {
2519 struct RegionCounter {
2520 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2521 AudioSourceList::iterator iter;
2522 boost::shared_ptr<Region> region;
2525 RegionCounter() : count (0) {}
2529 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2531 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2532 return r.get_value_or (1);
2536 Session::cleanup_regions ()
2538 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2540 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2542 uint32_t used = playlists->region_use_count (i->second);
2544 if (used == 0 && !i->second->automatic ()) {
2545 RegionFactory::map_remove (i->second);
2549 /* dump the history list */
2556 Session::cleanup_sources (CleanupReport& rep)
2558 // FIXME: needs adaptation to midi
2560 vector<boost::shared_ptr<Source> > dead_sources;
2561 PathScanner scanner;
2564 vector<space_and_path>::iterator i;
2565 vector<space_and_path>::iterator nexti;
2566 vector<string*>* candidates;
2567 vector<string*>* candidates2;
2568 vector<string> unused;
2569 set<string> all_sources;
2574 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2576 /* consider deleting all unused playlists */
2578 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2583 /* sync the "all regions" property of each playlist with its current state
2586 playlists->sync_all_regions_with_regions ();
2588 /* find all un-used sources */
2593 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2595 SourceMap::iterator tmp;
2600 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2604 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2605 dead_sources.push_back (i->second);
2606 i->second->drop_references ();
2612 /* build a list of all the possible audio directories for the session */
2614 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2619 SessionDirectory sdir ((*i).path);
2620 audio_path += sdir.sound_path();
2622 if (nexti != session_dirs.end()) {
2630 /* build a list of all the possible midi directories for the session */
2632 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2637 SessionDirectory sdir ((*i).path);
2638 midi_path += sdir.midi_path();
2640 if (nexti != session_dirs.end()) {
2647 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2648 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2654 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2655 candidates->push_back (*i);
2660 candidates = candidates2; // might still be null
2663 /* find all sources, but don't use this snapshot because the
2664 state file on disk still references sources we may have already
2668 find_all_sources_across_snapshots (all_sources, true);
2670 /* add our current source list
2673 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2674 boost::shared_ptr<FileSource> fs;
2675 SourceMap::iterator tmp = i;
2678 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2680 if (!fs->is_stub()) {
2682 if (playlists->source_use_count (fs) != 0) {
2683 all_sources.insert (fs->path());
2686 /* we might not remove this source from disk, because it may be used
2687 by other snapshots, but its not being used in this version
2688 so lets get rid of it now, along with any representative regions
2692 RegionFactory::remove_regions_using_source (i->second);
2701 char tmppath1[PATH_MAX+1];
2702 char tmppath2[PATH_MAX+1];
2705 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2710 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2712 if (realpath(spath.c_str(), tmppath1) == 0) {
2713 error << string_compose (_("Cannot expand path %1 (%2)"),
2714 spath, strerror (errno)) << endmsg;
2718 if (realpath((*i).c_str(), tmppath2) == 0) {
2719 error << string_compose (_("Cannot expand path %1 (%2)"),
2720 (*i), strerror (errno)) << endmsg;
2724 if (strcmp(tmppath1, tmppath2) == 0) {
2731 unused.push_back (spath);
2740 /* now try to move all unused files into the "dead" directory(ies) */
2742 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2743 struct stat statbuf;
2747 /* don't move the file across filesystems, just
2748 stick it in the `dead_dir_name' directory
2749 on whichever filesystem it was already on.
2752 if ((*x).find ("/sounds/") != string::npos) {
2754 /* old school, go up 1 level */
2756 newpath = Glib::path_get_dirname (*x); // "sounds"
2757 newpath = Glib::path_get_dirname (newpath); // "session-name"
2761 /* new school, go up 4 levels */
2763 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2764 newpath = Glib::path_get_dirname (newpath); // "session-name"
2765 newpath = Glib::path_get_dirname (newpath); // "interchange"
2766 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2769 newpath = Glib::build_filename (newpath, dead_dir_name);
2771 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2772 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2776 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2778 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2780 /* the new path already exists, try versioning */
2782 char buf[PATH_MAX+1];
2786 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2789 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2790 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2794 if (version == 999) {
2795 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2799 newpath = newpath_v;
2804 /* it doesn't exist, or we can't read it or something */
2808 stat ((*x).c_str(), &statbuf);
2810 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2811 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2812 (*x), newpath, strerror (errno))
2817 /* see if there an easy to find peakfile for this file, and remove it.
2820 string base = basename_nosuffix (*x);
2821 base += "%A"; /* this is what we add for the channel suffix of all native files,
2822 or for the first channel of embedded files. it will miss
2823 some peakfiles for other channels
2825 string peakpath = peak_path (base);
2827 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2828 if (::unlink (peakpath.c_str()) != 0) {
2829 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2830 peakpath, _path, strerror (errno))
2832 /* try to back out */
2833 ::rename (newpath.c_str(), _path.c_str());
2838 rep.paths.push_back (*x);
2839 rep.space += statbuf.st_size;
2842 /* dump the history list */
2846 /* save state so we don't end up a session file
2847 referring to non-existent sources.
2854 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2860 Session::cleanup_trash_sources (CleanupReport& rep)
2862 // FIXME: needs adaptation for MIDI
2864 vector<space_and_path>::iterator i;
2870 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2872 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2874 clear_directory (dead_dir, &rep.space, &rep.paths);
2881 Session::set_dirty ()
2883 bool was_dirty = dirty();
2885 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2889 DirtyChanged(); /* EMIT SIGNAL */
2895 Session::set_clean ()
2897 bool was_dirty = dirty();
2899 _state_of_the_state = Clean;
2903 DirtyChanged(); /* EMIT SIGNAL */
2908 Session::set_deletion_in_progress ()
2910 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2914 Session::clear_deletion_in_progress ()
2916 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2920 Session::add_controllable (boost::shared_ptr<Controllable> c)
2922 /* this adds a controllable to the list managed by the Session.
2923 this is a subset of those managed by the Controllable class
2924 itself, and represents the only ones whose state will be saved
2925 as part of the session.
2928 Glib::Threads::Mutex::Lock lm (controllables_lock);
2929 controllables.insert (c);
2932 struct null_deleter { void operator()(void const *) const {} };
2935 Session::remove_controllable (Controllable* c)
2937 if (_state_of_the_state & Deletion) {
2941 Glib::Threads::Mutex::Lock lm (controllables_lock);
2943 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2945 if (x != controllables.end()) {
2946 controllables.erase (x);
2950 boost::shared_ptr<Controllable>
2951 Session::controllable_by_id (const PBD::ID& id)
2953 Glib::Threads::Mutex::Lock lm (controllables_lock);
2955 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2956 if ((*i)->id() == id) {
2961 return boost::shared_ptr<Controllable>();
2964 boost::shared_ptr<Controllable>
2965 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2967 boost::shared_ptr<Controllable> c;
2968 boost::shared_ptr<Route> r;
2970 switch (desc.top_level_type()) {
2971 case ControllableDescriptor::NamedRoute:
2973 std::string str = desc.top_level_name();
2974 if (str == "master") {
2976 } else if (str == "control" || str == "listen") {
2979 r = route_by_name (desc.top_level_name());
2984 case ControllableDescriptor::RemoteControlID:
2985 r = route_by_remote_id (desc.rid());
2993 switch (desc.subtype()) {
2994 case ControllableDescriptor::Gain:
2995 c = r->gain_control ();
2998 case ControllableDescriptor::Solo:
2999 c = r->solo_control();
3002 case ControllableDescriptor::Mute:
3003 c = r->mute_control();
3006 case ControllableDescriptor::Recenable:
3008 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3011 c = t->rec_enable_control ();
3016 case ControllableDescriptor::PanDirection:
3018 c = r->pannable()->pan_azimuth_control;
3022 case ControllableDescriptor::PanWidth:
3024 c = r->pannable()->pan_width_control;
3028 case ControllableDescriptor::PanElevation:
3030 c = r->pannable()->pan_elevation_control;
3034 case ControllableDescriptor::Balance:
3035 /* XXX simple pan control */
3038 case ControllableDescriptor::PluginParameter:
3040 uint32_t plugin = desc.target (0);
3041 uint32_t parameter_index = desc.target (1);
3043 /* revert to zero based counting */
3049 if (parameter_index > 0) {
3053 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3056 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3057 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3062 case ControllableDescriptor::SendGain:
3064 uint32_t send = desc.target (0);
3066 /* revert to zero-based counting */
3072 boost::shared_ptr<Processor> p = r->nth_send (send);
3075 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3076 boost::shared_ptr<Amp> a = s->amp();
3079 c = s->amp()->gain_control();
3086 /* relax and return a null pointer */
3094 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3097 Stateful::add_instant_xml (node, _path);
3100 if (write_to_config) {
3101 Config->add_instant_xml (node);
3106 Session::instant_xml (const string& node_name)
3108 return Stateful::instant_xml (node_name, _path);
3112 Session::save_history (string snapshot_name)
3120 if (snapshot_name.empty()) {
3121 snapshot_name = _current_snapshot_name;
3124 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3125 const string backup_filename = history_filename + backup_suffix;
3126 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3127 const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3129 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3130 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3131 error << _("could not backup old history file, current history not saved") << endmsg;
3136 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3140 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3142 if (!tree.write (xml_path))
3144 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3146 if (g_remove (xml_path.c_str()) != 0) {
3147 error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3148 xml_path, g_strerror (errno)) << endmsg;
3150 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3151 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3152 backup_path, g_strerror (errno)) << endmsg;
3162 Session::restore_history (string snapshot_name)
3166 if (snapshot_name.empty()) {
3167 snapshot_name = _current_snapshot_name;
3170 const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3171 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3173 info << "Loading history from " << xml_path << endmsg;
3175 if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3176 info << string_compose (_("%1: no history file \"%2\" for this session."),
3177 _name, xml_path) << endmsg;
3181 if (!tree.read (xml_path)) {
3182 error << string_compose (_("Could not understand session history file \"%1\""),
3183 xml_path) << endmsg;
3190 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3193 UndoTransaction* ut = new UndoTransaction ();
3196 ut->set_name(t->property("name")->value());
3197 stringstream ss(t->property("tv-sec")->value());
3199 ss.str(t->property("tv-usec")->value());
3201 ut->set_timestamp(tv);
3203 for (XMLNodeConstIterator child_it = t->children().begin();
3204 child_it != t->children().end(); child_it++)
3206 XMLNode *n = *child_it;
3209 if (n->name() == "MementoCommand" ||
3210 n->name() == "MementoUndoCommand" ||
3211 n->name() == "MementoRedoCommand") {
3213 if ((c = memento_command_factory(n))) {
3217 } else if (n->name() == "NoteDiffCommand") {
3218 PBD::ID id (n->property("midi-source")->value());
3219 boost::shared_ptr<MidiSource> midi_source =
3220 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3222 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3224 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3227 } else if (n->name() == "SysExDiffCommand") {
3229 PBD::ID id (n->property("midi-source")->value());
3230 boost::shared_ptr<MidiSource> midi_source =
3231 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3233 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3235 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3238 } else if (n->name() == "PatchChangeDiffCommand") {
3240 PBD::ID id (n->property("midi-source")->value());
3241 boost::shared_ptr<MidiSource> midi_source =
3242 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3244 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3246 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3249 } else if (n->name() == "StatefulDiffCommand") {
3250 if ((c = stateful_diff_command_factory (n))) {
3251 ut->add_command (c);
3254 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3265 Session::config_changed (std::string p, bool ours)
3271 if (p == "seamless-loop") {
3273 } else if (p == "rf-speed") {
3275 } else if (p == "auto-loop") {
3277 } else if (p == "auto-input") {
3279 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3280 /* auto-input only makes a difference if we're rolling */
3281 set_track_monitor_input_status (!config.get_auto_input());
3284 } else if (p == "punch-in") {
3288 if ((location = _locations->auto_punch_location()) != 0) {
3290 if (config.get_punch_in ()) {
3291 replace_event (SessionEvent::PunchIn, location->start());
3293 remove_event (location->start(), SessionEvent::PunchIn);
3297 } else if (p == "punch-out") {
3301 if ((location = _locations->auto_punch_location()) != 0) {
3303 if (config.get_punch_out()) {
3304 replace_event (SessionEvent::PunchOut, location->end());
3306 clear_events (SessionEvent::PunchOut);
3310 } else if (p == "edit-mode") {
3312 Glib::Threads::Mutex::Lock lm (playlists->lock);
3314 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3315 (*i)->set_edit_mode (Config->get_edit_mode ());
3318 } else if (p == "use-video-sync") {
3320 waiting_for_sync_offset = config.get_use_video_sync();
3322 } else if (p == "mmc-control") {
3324 //poke_midi_thread ();
3326 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3328 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3330 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3332 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
3334 } else if (p == "midi-control") {
3336 //poke_midi_thread ();
3338 } else if (p == "raid-path") {
3340 setup_raid_path (config.get_raid_path());
3342 } else if (p == "timecode-format") {
3346 } else if (p == "video-pullup") {
3350 } else if (p == "seamless-loop") {
3352 if (play_loop && transport_rolling()) {
3353 // to reset diskstreams etc
3354 request_play_loop (true);
3357 } else if (p == "rf-speed") {
3359 cumulative_rf_motion = 0;
3362 } else if (p == "click-sound") {
3364 setup_click_sounds (1);
3366 } else if (p == "click-emphasis-sound") {
3368 setup_click_sounds (-1);
3370 } else if (p == "clicking") {
3372 if (Config->get_clicking()) {
3373 if (_click_io && click_data) { // don't require emphasis data
3380 } else if (p == "click-gain") {
3383 _click_gain->set_gain (Config->get_click_gain(), this);
3386 } else if (p == "send-mtc") {
3388 if (Config->get_send_mtc ()) {
3389 /* mark us ready to send */
3390 next_quarter_frame_to_send = 0;
3393 } else if (p == "send-mmc") {
3395 _mmc->enable_send (Config->get_send_mmc ());
3397 } else if (p == "midi-feedback") {
3399 session_midi_feedback = Config->get_midi_feedback();
3401 } else if (p == "jack-time-master") {
3403 engine().reset_timebase ();
3405 } else if (p == "native-file-header-format") {
3407 if (!first_file_header_format_reset) {
3408 reset_native_file_format ();
3411 first_file_header_format_reset = false;
3413 } else if (p == "native-file-data-format") {
3415 if (!first_file_data_format_reset) {
3416 reset_native_file_format ();
3419 first_file_data_format_reset = false;
3421 } else if (p == "external-sync") {
3422 if (!config.get_external_sync()) {
3423 drop_sync_source ();
3425 switch_to_sync_source (Config->get_sync_source());
3427 } else if (p == "denormal-model") {
3429 } else if (p == "history-depth") {
3430 set_history_depth (Config->get_history_depth());
3431 } else if (p == "remote-model") {
3432 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3435 } else if (p == "initial-program-change") {
3437 if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
3440 buf[0] = MIDI::program; // channel zero by default
3441 buf[1] = (Config->get_initial_program_change() & 0x7f);
3443 _mmc->output_port()->midimsg (buf, sizeof (buf), 0);
3445 } else if (p == "solo-mute-override") {
3446 // catch_up_on_solo_mute_override ();
3447 } else if (p == "listen-position" || p == "pfl-position") {
3448 listen_position_changed ();
3449 } else if (p == "solo-control-is-listen-control") {
3450 solo_control_mode_changed ();
3451 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3452 last_timecode_valid = false;
3453 } else if (p == "playback-buffer-seconds") {
3454 AudioSource::allocate_working_buffers (frame_rate());
3455 } else if (p == "automation-thinning-factor") {
3456 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3457 } else if (p == "ltc-source-port") {
3458 reconnect_ltc_input ();
3459 } else if (p == "ltc-sink-port") {
3460 reconnect_ltc_output ();
3461 } else if (p == "timecode-generator-offset") {
3462 ltc_tx_parse_offset();
3469 Session::set_history_depth (uint32_t d)
3471 _history.set_depth (d);
3475 Session::load_diskstreams_2X (XMLNode const & node, int)
3478 XMLNodeConstIterator citer;
3480 clist = node.children();
3482 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3485 /* diskstreams added automatically by DiskstreamCreated handler */
3486 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3487 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3488 _diskstreams_2X.push_back (dsp);
3490 error << _("Session: unknown diskstream type in XML") << endmsg;
3494 catch (failed_constructor& err) {
3495 error << _("Session: could not load diskstream via XML state") << endmsg;
3503 /** Connect things to the MMC object */
3505 Session::setup_midi_machine_control ()
3507 _mmc = new MIDI::MachineControl;
3508 _mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
3510 _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3511 _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3512 _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3513 _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3514 _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3515 _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3516 _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3517 _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3518 _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3519 _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3520 _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3521 _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3522 _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3524 /* also handle MIDI SPP because its so common */
3526 _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3527 _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3528 _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3531 boost::shared_ptr<Controllable>
3532 Session::solo_cut_control() const
3534 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3535 controls in Ardour that currently get presented to the user in the GUI that require
3536 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3538 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3539 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3543 return _solo_cut_control;
3547 Session::rename (const std::string& new_name)
3549 string legal_name = legalize_for_path (new_name);
3555 string const old_sources_root = _session_dir->sources_root();
3557 #define RENAME ::rename
3562 * interchange subdirectory
3566 * Backup files are left unchanged and not renamed.
3569 /* pass one: not 100% safe check that the new directory names don't
3573 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3578 /* this is a stupid hack because Glib::path_get_dirname() is
3579 * lexical-only, and so passing it /a/b/c/ gives a different
3580 * result than passing it /a/b/c ...
3583 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3584 oldstr = oldstr.substr (0, oldstr.length() - 1);
3587 string base = Glib::path_get_dirname (oldstr);
3588 string p = Glib::path_get_basename (oldstr);
3590 newstr = Glib::build_filename (base, legal_name);
3592 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3599 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3604 /* this is a stupid hack because Glib::path_get_dirname() is
3605 * lexical-only, and so passing it /a/b/c/ gives a different
3606 * result than passing it /a/b/c ...
3609 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3610 oldstr = oldstr.substr (0, oldstr.length() - 1);
3613 string base = Glib::path_get_dirname (oldstr);
3614 string p = Glib::path_get_basename (oldstr);
3616 newstr = Glib::build_filename (base, legal_name);
3618 cerr << "Rename " << oldstr << " => " << newstr << endl;
3620 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3625 (*_session_dir) = newstr;
3630 /* directory below interchange */
3632 v.push_back (newstr);
3633 v.push_back (interchange_dir_name);
3636 oldstr = Glib::build_filename (v);
3639 v.push_back (newstr);
3640 v.push_back (interchange_dir_name);
3641 v.push_back (legal_name);
3643 newstr = Glib::build_filename (v);
3645 cerr << "Rename " << oldstr << " => " << newstr << endl;
3647 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3654 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3655 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3657 cerr << "Rename " << oldstr << " => " << newstr << endl;
3659 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3666 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3668 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3669 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3671 cerr << "Rename " << oldstr << " => " << newstr << endl;
3673 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3678 /* update file source paths */
3680 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3681 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3683 string p = fs->path ();
3684 boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3689 /* remove old name from recent sessions */
3691 remove_recent_sessions (_path);
3694 _current_snapshot_name = new_name;
3699 /* save state again to get everything just right */
3701 save_state (_current_snapshot_name);
3704 /* add to recent sessions */
3706 store_recent_sessions (new_name, _path);
3714 Session::get_session_info_from_path (XMLTree& tree, const string& xmlpath)
3716 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3720 if (!tree.read (xmlpath)) {
3728 Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
3731 bool found_sr = false;
3732 bool found_data_format = false;
3734 if (get_session_info_from_path (tree, xmlpath)) {
3740 const XMLProperty* prop;
3741 if ((prop = tree.root()->property (X_("sample-rate"))) != 0) {
3742 sample_rate = atoi (prop->value());
3746 const XMLNodeList& children (tree.root()->children());
3747 for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
3748 const XMLNode* child = *c;
3749 if (child->name() == "Config") {
3750 const XMLNodeList& options (child->children());
3751 for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
3752 const XMLNode* option = *oc;
3753 const XMLProperty* name = option->property("name");
3759 if (name->value() == "native-file-data-format") {
3760 const XMLProperty* value = option->property ("value");
3762 SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt);
3764 found_data_format = true;
3770 if (found_data_format) {
3775 return !(found_sr && found_data_format); // zero if they are both found