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::path_from_region_name (DataType type, string name, string identifier)
1836 char buf[PATH_MAX+1];
1838 SessionDirectory sdir(get_best_session_directory_for_new_source());
1839 std::string source_dir = ((type == DataType::AUDIO)
1840 ? sdir.sound_path() : sdir.midi_path());
1842 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1844 for (n = 0; n < 999999; ++n) {
1845 if (identifier.length()) {
1846 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1847 identifier.c_str(), n, ext.c_str());
1849 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1853 std::string source_path = Glib::build_filename (source_dir, buf);
1855 if (!Glib::file_test (source_path, Glib::FILE_TEST_EXISTS)) {
1860 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1869 Session::load_sources (const XMLNode& node)
1872 XMLNodeConstIterator niter;
1873 boost::shared_ptr<Source> source;
1875 nlist = node.children();
1879 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1882 if ((source = XMLSourceFactory (**niter)) == 0) {
1883 error << _("Session: cannot create Source from XML description.") << endmsg;
1886 } catch (MissingSource& err) {
1890 if (!no_questions_about_missing_files) {
1891 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1896 switch (user_choice) {
1898 /* user added a new search location, so try again */
1903 /* user asked to quit the entire session load
1908 no_questions_about_missing_files = true;
1912 no_questions_about_missing_files = true;
1917 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1918 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1927 boost::shared_ptr<Source>
1928 Session::XMLSourceFactory (const XMLNode& node)
1930 if (node.name() != "Source") {
1931 return boost::shared_ptr<Source>();
1935 /* note: do peak building in another thread when loading session state */
1936 return SourceFactory::create (*this, node, true);
1939 catch (failed_constructor& err) {
1940 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1941 return boost::shared_ptr<Source>();
1946 Session::save_template (string template_name)
1950 if (_state_of_the_state & CannotSave) {
1954 std::string user_template_dir(user_template_directory());
1956 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
1957 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
1958 user_template_dir, g_strerror (errno)) << endmsg;
1962 tree.set_root (&get_template());
1964 std::string template_dir_path(user_template_dir);
1966 /* directory to put the template in */
1967 template_dir_path = Glib::build_filename (template_dir_path, template_name);
1969 if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
1970 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1971 template_dir_path) << endmsg;
1975 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
1976 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
1977 template_dir_path, g_strerror (errno)) << endmsg;
1982 std::string template_file_path(template_dir_path);
1983 template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
1985 if (!tree.write (template_file_path)) {
1986 error << _("template not saved") << endmsg;
1990 /* copy plugin state directory */
1992 std::string template_plugin_state_path(template_dir_path);
1993 template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
1995 if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
1996 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
1997 template_plugin_state_path, g_strerror (errno)) << endmsg;
2001 copy_files (plugins_dir(), template_plugin_state_path);
2007 Session::refresh_disk_space ()
2009 #if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
2011 Glib::Threads::Mutex::Lock lm (space_lock);
2013 /* get freespace on every FS that is part of the session path */
2015 _total_free_4k_blocks = 0;
2016 _total_free_4k_blocks_uncertain = false;
2018 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2020 struct statfs statfsbuf;
2021 statfs (i->path.c_str(), &statfsbuf);
2023 double const scale = statfsbuf.f_bsize / 4096.0;
2025 /* See if this filesystem is read-only */
2026 struct statvfs statvfsbuf;
2027 statvfs (i->path.c_str(), &statvfsbuf);
2029 /* f_bavail can be 0 if it is undefined for whatever
2030 filesystem we are looking at; Samba shares mounted
2031 via GVFS are an example of this.
2033 if (statfsbuf.f_bavail == 0) {
2034 /* block count unknown */
2036 i->blocks_unknown = true;
2037 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2038 /* read-only filesystem */
2040 i->blocks_unknown = false;
2042 /* read/write filesystem with known space */
2043 i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2044 i->blocks_unknown = false;
2047 _total_free_4k_blocks += i->blocks;
2048 if (i->blocks_unknown) {
2049 _total_free_4k_blocks_uncertain = true;
2056 Session::get_best_session_directory_for_new_source ()
2058 vector<space_and_path>::iterator i;
2059 string result = _session_dir->root_path();
2061 /* handle common case without system calls */
2063 if (session_dirs.size() == 1) {
2067 /* OK, here's the algorithm we're following here:
2069 We want to select which directory to use for
2070 the next file source to be created. Ideally,
2071 we'd like to use a round-robin process so as to
2072 get maximum performance benefits from splitting
2073 the files across multiple disks.
2075 However, in situations without much diskspace, an
2076 RR approach may end up filling up a filesystem
2077 with new files while others still have space.
2078 Its therefore important to pay some attention to
2079 the freespace in the filesystem holding each
2080 directory as well. However, if we did that by
2081 itself, we'd keep creating new files in the file
2082 system with the most space until it was as full
2083 as all others, thus negating any performance
2084 benefits of this RAID-1 like approach.
2086 So, we use a user-configurable space threshold. If
2087 there are at least 2 filesystems with more than this
2088 much space available, we use RR selection between them.
2089 If not, then we pick the filesystem with the most space.
2091 This gets a good balance between the two
2095 refresh_disk_space ();
2097 int free_enough = 0;
2099 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2100 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2105 if (free_enough >= 2) {
2106 /* use RR selection process, ensuring that the one
2110 i = last_rr_session_dir;
2113 if (++i == session_dirs.end()) {
2114 i = session_dirs.begin();
2117 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2118 SessionDirectory sdir(i->path);
2119 if (sdir.create ()) {
2121 last_rr_session_dir = i;
2126 } while (i != last_rr_session_dir);
2130 /* pick FS with the most freespace (and that
2131 seems to actually work ...)
2134 vector<space_and_path> sorted;
2135 space_and_path_ascending_cmp cmp;
2137 sorted = session_dirs;
2138 sort (sorted.begin(), sorted.end(), cmp);
2140 for (i = sorted.begin(); i != sorted.end(); ++i) {
2141 SessionDirectory sdir(i->path);
2142 if (sdir.create ()) {
2144 last_rr_session_dir = i;
2154 Session::automation_dir () const
2156 return Glib::build_filename (_path, "automation");
2160 Session::analysis_dir () const
2162 return Glib::build_filename (_path, "analysis");
2166 Session::plugins_dir () const
2168 return Glib::build_filename (_path, "plugins");
2172 Session::externals_dir () const
2174 return Glib::build_filename (_path, "externals");
2178 Session::load_bundles (XMLNode const & node)
2180 XMLNodeList nlist = node.children();
2181 XMLNodeConstIterator niter;
2185 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2186 if ((*niter)->name() == "InputBundle") {
2187 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2188 } else if ((*niter)->name() == "OutputBundle") {
2189 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2191 error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2200 Session::load_route_groups (const XMLNode& node, int version)
2202 XMLNodeList nlist = node.children();
2203 XMLNodeConstIterator niter;
2207 if (version >= 3000) {
2209 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2210 if ((*niter)->name() == "RouteGroup") {
2211 RouteGroup* rg = new RouteGroup (*this, "");
2212 add_route_group (rg);
2213 rg->set_state (**niter, version);
2217 } else if (version < 3000) {
2219 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2220 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2221 RouteGroup* rg = new RouteGroup (*this, "");
2222 add_route_group (rg);
2223 rg->set_state (**niter, version);
2232 Session::auto_save()
2234 save_state (_current_snapshot_name);
2238 state_file_filter (const string &str, void */*arg*/)
2240 return (str.length() > strlen(statefile_suffix) &&
2241 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2245 bool operator()(const string* a, const string* b) {
2251 remove_end(string* state)
2253 string statename(*state);
2255 string::size_type start,end;
2256 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2257 statename = statename.substr (start+1);
2260 if ((end = statename.rfind(".ardour")) == string::npos) {
2261 end = statename.length();
2264 return new string(statename.substr (0, end));
2268 Session::possible_states (string path)
2270 PathScanner scanner;
2271 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2273 transform(states->begin(), states->end(), states->begin(), remove_end);
2276 sort (states->begin(), states->end(), cmp);
2282 Session::possible_states () const
2284 return possible_states(_path);
2288 Session::add_route_group (RouteGroup* g)
2290 _route_groups.push_back (g);
2291 route_group_added (g); /* EMIT SIGNAL */
2293 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2294 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2295 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2301 Session::remove_route_group (RouteGroup& rg)
2303 list<RouteGroup*>::iterator i;
2305 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2306 _route_groups.erase (i);
2309 route_group_removed (); /* EMIT SIGNAL */
2313 /** Set a new order for our route groups, without adding or removing any.
2314 * @param groups Route group list in the new order.
2317 Session::reorder_route_groups (list<RouteGroup*> groups)
2319 _route_groups = groups;
2321 route_groups_reordered (); /* EMIT SIGNAL */
2327 Session::route_group_by_name (string name)
2329 list<RouteGroup *>::iterator i;
2331 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2332 if ((*i)->name() == name) {
2340 Session::all_route_group() const
2342 return *_all_route_group;
2346 Session::add_commands (vector<Command*> const & cmds)
2348 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2354 Session::begin_reversible_command (const string& name)
2356 begin_reversible_command (g_quark_from_string (name.c_str ()));
2359 /** Begin a reversible command using a GQuark to identify it.
2360 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2361 * but there must be as many begin...()s as there are commit...()s.
2364 Session::begin_reversible_command (GQuark q)
2366 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2367 to hold all the commands that are committed. This keeps the order of
2368 commands correct in the history.
2371 if (_current_trans == 0) {
2372 /* start a new transaction */
2373 assert (_current_trans_quarks.empty ());
2374 _current_trans = new UndoTransaction();
2375 _current_trans->set_name (g_quark_to_string (q));
2378 _current_trans_quarks.push_front (q);
2382 Session::commit_reversible_command (Command *cmd)
2384 assert (_current_trans);
2385 assert (!_current_trans_quarks.empty ());
2390 _current_trans->add_command (cmd);
2393 _current_trans_quarks.pop_front ();
2395 if (!_current_trans_quarks.empty ()) {
2396 /* the transaction we're committing is not the top-level one */
2400 if (_current_trans->empty()) {
2401 /* no commands were added to the transaction, so just get rid of it */
2402 delete _current_trans;
2407 gettimeofday (&now, 0);
2408 _current_trans->set_timestamp (now);
2410 _history.add (_current_trans);
2415 accept_all_audio_files (const string& path, void */*arg*/)
2417 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2421 if (!AudioFileSource::safe_audio_file_extension (path)) {
2429 accept_all_midi_files (const string& path, void */*arg*/)
2431 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2435 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2436 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2437 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2441 accept_all_state_files (const string& path, void */*arg*/)
2443 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2447 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2451 Session::find_all_sources (string path, set<string>& result)
2456 if (!tree.read (path)) {
2460 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2465 XMLNodeConstIterator niter;
2467 nlist = node->children();
2471 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2475 if ((prop = (*niter)->property (X_("type"))) == 0) {
2479 DataType type (prop->value());
2481 if ((prop = (*niter)->property (X_("name"))) == 0) {
2485 if (Glib::path_is_absolute (prop->value())) {
2486 /* external file, ignore */
2494 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2495 result.insert (found_path);
2503 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2505 PathScanner scanner;
2506 vector<string*>* state_files;
2508 string this_snapshot_path;
2514 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2515 ripped = ripped.substr (0, ripped.length() - 1);
2518 state_files = scanner (ripped, accept_all_state_files, (void *) 0, true, true);
2520 if (state_files == 0) {
2525 this_snapshot_path = _path;
2526 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2527 this_snapshot_path += statefile_suffix;
2529 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2531 if (exclude_this_snapshot && **i == this_snapshot_path) {
2535 if (find_all_sources (**i, result) < 0) {
2543 struct RegionCounter {
2544 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2545 AudioSourceList::iterator iter;
2546 boost::shared_ptr<Region> region;
2549 RegionCounter() : count (0) {}
2553 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2555 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2556 return r.get_value_or (1);
2560 Session::cleanup_regions ()
2562 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2564 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2566 uint32_t used = playlists->region_use_count (i->second);
2568 if (used == 0 && !i->second->automatic ()) {
2569 RegionFactory::map_remove (i->second);
2573 /* dump the history list */
2580 Session::cleanup_sources (CleanupReport& rep)
2582 // FIXME: needs adaptation to midi
2584 vector<boost::shared_ptr<Source> > dead_sources;
2585 PathScanner scanner;
2588 vector<space_and_path>::iterator i;
2589 vector<space_and_path>::iterator nexti;
2590 vector<string*>* candidates;
2591 vector<string*>* candidates2;
2592 vector<string> unused;
2593 set<string> all_sources;
2598 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2600 /* consider deleting all unused playlists */
2602 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2607 /* sync the "all regions" property of each playlist with its current state
2610 playlists->sync_all_regions_with_regions ();
2612 /* find all un-used sources */
2617 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2619 SourceMap::iterator tmp;
2624 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2628 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2629 dead_sources.push_back (i->second);
2630 i->second->drop_references ();
2636 /* build a list of all the possible audio directories for the session */
2638 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2643 SessionDirectory sdir ((*i).path);
2644 audio_path += sdir.sound_path();
2646 if (nexti != session_dirs.end()) {
2654 /* build a list of all the possible midi directories for the session */
2656 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2661 SessionDirectory sdir ((*i).path);
2662 midi_path += sdir.midi_path();
2664 if (nexti != session_dirs.end()) {
2671 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2672 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2678 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2679 candidates->push_back (*i);
2684 candidates = candidates2; // might still be null
2687 /* find all sources, but don't use this snapshot because the
2688 state file on disk still references sources we may have already
2692 find_all_sources_across_snapshots (all_sources, true);
2694 /* add our current source list
2697 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2698 boost::shared_ptr<FileSource> fs;
2699 SourceMap::iterator tmp = i;
2702 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2704 if (!fs->is_stub()) {
2706 if (playlists->source_use_count (fs) != 0) {
2707 all_sources.insert (fs->path());
2710 /* we might not remove this source from disk, because it may be used
2711 by other snapshots, but its not being used in this version
2712 so lets get rid of it now, along with any representative regions
2716 RegionFactory::remove_regions_using_source (i->second);
2725 char tmppath1[PATH_MAX+1];
2726 char tmppath2[PATH_MAX+1];
2729 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2734 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2736 if (realpath(spath.c_str(), tmppath1) == 0) {
2737 error << string_compose (_("Cannot expand path %1 (%2)"),
2738 spath, strerror (errno)) << endmsg;
2742 if (realpath((*i).c_str(), tmppath2) == 0) {
2743 error << string_compose (_("Cannot expand path %1 (%2)"),
2744 (*i), strerror (errno)) << endmsg;
2748 if (strcmp(tmppath1, tmppath2) == 0) {
2755 unused.push_back (spath);
2764 /* now try to move all unused files into the "dead" directory(ies) */
2766 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2767 struct stat statbuf;
2771 /* don't move the file across filesystems, just
2772 stick it in the `dead_dir_name' directory
2773 on whichever filesystem it was already on.
2776 if ((*x).find ("/sounds/") != string::npos) {
2778 /* old school, go up 1 level */
2780 newpath = Glib::path_get_dirname (*x); // "sounds"
2781 newpath = Glib::path_get_dirname (newpath); // "session-name"
2785 /* new school, go up 4 levels */
2787 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2788 newpath = Glib::path_get_dirname (newpath); // "session-name"
2789 newpath = Glib::path_get_dirname (newpath); // "interchange"
2790 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2793 newpath = Glib::build_filename (newpath, dead_dir_name);
2795 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2796 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2800 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2802 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2804 /* the new path already exists, try versioning */
2806 char buf[PATH_MAX+1];
2810 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2813 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2814 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2818 if (version == 999) {
2819 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2823 newpath = newpath_v;
2828 /* it doesn't exist, or we can't read it or something */
2832 stat ((*x).c_str(), &statbuf);
2834 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2835 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2836 (*x), newpath, strerror (errno))
2841 /* see if there an easy to find peakfile for this file, and remove it.
2844 string base = basename_nosuffix (*x);
2845 base += "%A"; /* this is what we add for the channel suffix of all native files,
2846 or for the first channel of embedded files. it will miss
2847 some peakfiles for other channels
2849 string peakpath = peak_path (base);
2851 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2852 if (::unlink (peakpath.c_str()) != 0) {
2853 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2854 peakpath, _path, strerror (errno))
2856 /* try to back out */
2857 ::rename (newpath.c_str(), _path.c_str());
2862 rep.paths.push_back (*x);
2863 rep.space += statbuf.st_size;
2866 /* dump the history list */
2870 /* save state so we don't end up a session file
2871 referring to non-existent sources.
2878 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2884 Session::cleanup_trash_sources (CleanupReport& rep)
2886 // FIXME: needs adaptation for MIDI
2888 vector<space_and_path>::iterator i;
2894 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2896 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2898 clear_directory (dead_dir, &rep.space, &rep.paths);
2905 Session::set_dirty ()
2907 bool was_dirty = dirty();
2909 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2913 DirtyChanged(); /* EMIT SIGNAL */
2919 Session::set_clean ()
2921 bool was_dirty = dirty();
2923 _state_of_the_state = Clean;
2927 DirtyChanged(); /* EMIT SIGNAL */
2932 Session::set_deletion_in_progress ()
2934 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2938 Session::clear_deletion_in_progress ()
2940 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2944 Session::add_controllable (boost::shared_ptr<Controllable> c)
2946 /* this adds a controllable to the list managed by the Session.
2947 this is a subset of those managed by the Controllable class
2948 itself, and represents the only ones whose state will be saved
2949 as part of the session.
2952 Glib::Threads::Mutex::Lock lm (controllables_lock);
2953 controllables.insert (c);
2956 struct null_deleter { void operator()(void const *) const {} };
2959 Session::remove_controllable (Controllable* c)
2961 if (_state_of_the_state & Deletion) {
2965 Glib::Threads::Mutex::Lock lm (controllables_lock);
2967 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2969 if (x != controllables.end()) {
2970 controllables.erase (x);
2974 boost::shared_ptr<Controllable>
2975 Session::controllable_by_id (const PBD::ID& id)
2977 Glib::Threads::Mutex::Lock lm (controllables_lock);
2979 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2980 if ((*i)->id() == id) {
2985 return boost::shared_ptr<Controllable>();
2988 boost::shared_ptr<Controllable>
2989 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2991 boost::shared_ptr<Controllable> c;
2992 boost::shared_ptr<Route> r;
2994 switch (desc.top_level_type()) {
2995 case ControllableDescriptor::NamedRoute:
2997 std::string str = desc.top_level_name();
2998 if (str == "master") {
3000 } else if (str == "control" || str == "listen") {
3003 r = route_by_name (desc.top_level_name());
3008 case ControllableDescriptor::RemoteControlID:
3009 r = route_by_remote_id (desc.rid());
3017 switch (desc.subtype()) {
3018 case ControllableDescriptor::Gain:
3019 c = r->gain_control ();
3022 case ControllableDescriptor::Solo:
3023 c = r->solo_control();
3026 case ControllableDescriptor::Mute:
3027 c = r->mute_control();
3030 case ControllableDescriptor::Recenable:
3032 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3035 c = t->rec_enable_control ();
3040 case ControllableDescriptor::PanDirection:
3042 c = r->pannable()->pan_azimuth_control;
3046 case ControllableDescriptor::PanWidth:
3048 c = r->pannable()->pan_width_control;
3052 case ControllableDescriptor::PanElevation:
3054 c = r->pannable()->pan_elevation_control;
3058 case ControllableDescriptor::Balance:
3059 /* XXX simple pan control */
3062 case ControllableDescriptor::PluginParameter:
3064 uint32_t plugin = desc.target (0);
3065 uint32_t parameter_index = desc.target (1);
3067 /* revert to zero based counting */
3073 if (parameter_index > 0) {
3077 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3080 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3081 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3086 case ControllableDescriptor::SendGain:
3088 uint32_t send = desc.target (0);
3090 /* revert to zero-based counting */
3096 boost::shared_ptr<Processor> p = r->nth_send (send);
3099 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3100 boost::shared_ptr<Amp> a = s->amp();
3103 c = s->amp()->gain_control();
3110 /* relax and return a null pointer */
3118 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3121 Stateful::add_instant_xml (node, _path);
3124 if (write_to_config) {
3125 Config->add_instant_xml (node);
3130 Session::instant_xml (const string& node_name)
3132 return Stateful::instant_xml (node_name, _path);
3136 Session::save_history (string snapshot_name)
3144 if (snapshot_name.empty()) {
3145 snapshot_name = _current_snapshot_name;
3148 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3149 const string backup_filename = history_filename + backup_suffix;
3150 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3151 const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3153 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3154 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3155 error << _("could not backup old history file, current history not saved") << endmsg;
3160 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3164 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3166 if (!tree.write (xml_path))
3168 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3170 if (g_remove (xml_path.c_str()) != 0) {
3171 error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3172 xml_path, g_strerror (errno)) << endmsg;
3174 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3175 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3176 backup_path, g_strerror (errno)) << endmsg;
3186 Session::restore_history (string snapshot_name)
3190 if (snapshot_name.empty()) {
3191 snapshot_name = _current_snapshot_name;
3194 const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3195 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3197 info << "Loading history from " << xml_path << endmsg;
3199 if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3200 info << string_compose (_("%1: no history file \"%2\" for this session."),
3201 _name, xml_path) << endmsg;
3205 if (!tree.read (xml_path)) {
3206 error << string_compose (_("Could not understand session history file \"%1\""),
3207 xml_path) << endmsg;
3214 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3217 UndoTransaction* ut = new UndoTransaction ();
3220 ut->set_name(t->property("name")->value());
3221 stringstream ss(t->property("tv-sec")->value());
3223 ss.str(t->property("tv-usec")->value());
3225 ut->set_timestamp(tv);
3227 for (XMLNodeConstIterator child_it = t->children().begin();
3228 child_it != t->children().end(); child_it++)
3230 XMLNode *n = *child_it;
3233 if (n->name() == "MementoCommand" ||
3234 n->name() == "MementoUndoCommand" ||
3235 n->name() == "MementoRedoCommand") {
3237 if ((c = memento_command_factory(n))) {
3241 } else if (n->name() == "NoteDiffCommand") {
3242 PBD::ID id (n->property("midi-source")->value());
3243 boost::shared_ptr<MidiSource> midi_source =
3244 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3246 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3248 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3251 } else if (n->name() == "SysExDiffCommand") {
3253 PBD::ID id (n->property("midi-source")->value());
3254 boost::shared_ptr<MidiSource> midi_source =
3255 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3257 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3259 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3262 } else if (n->name() == "PatchChangeDiffCommand") {
3264 PBD::ID id (n->property("midi-source")->value());
3265 boost::shared_ptr<MidiSource> midi_source =
3266 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3268 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3270 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3273 } else if (n->name() == "StatefulDiffCommand") {
3274 if ((c = stateful_diff_command_factory (n))) {
3275 ut->add_command (c);
3278 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3289 Session::config_changed (std::string p, bool ours)
3295 if (p == "seamless-loop") {
3297 } else if (p == "rf-speed") {
3299 } else if (p == "auto-loop") {
3301 } else if (p == "auto-input") {
3303 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3304 /* auto-input only makes a difference if we're rolling */
3305 set_track_monitor_input_status (!config.get_auto_input());
3308 } else if (p == "punch-in") {
3312 if ((location = _locations->auto_punch_location()) != 0) {
3314 if (config.get_punch_in ()) {
3315 replace_event (SessionEvent::PunchIn, location->start());
3317 remove_event (location->start(), SessionEvent::PunchIn);
3321 } else if (p == "punch-out") {
3325 if ((location = _locations->auto_punch_location()) != 0) {
3327 if (config.get_punch_out()) {
3328 replace_event (SessionEvent::PunchOut, location->end());
3330 clear_events (SessionEvent::PunchOut);
3334 } else if (p == "edit-mode") {
3336 Glib::Threads::Mutex::Lock lm (playlists->lock);
3338 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3339 (*i)->set_edit_mode (Config->get_edit_mode ());
3342 } else if (p == "use-video-sync") {
3344 waiting_for_sync_offset = config.get_use_video_sync();
3346 } else if (p == "mmc-control") {
3348 //poke_midi_thread ();
3350 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3352 _mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3354 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3356 _mmc->set_send_device_id (Config->get_mmc_send_device_id());
3358 } else if (p == "midi-control") {
3360 //poke_midi_thread ();
3362 } else if (p == "raid-path") {
3364 setup_raid_path (config.get_raid_path());
3366 } else if (p == "timecode-format") {
3370 } else if (p == "video-pullup") {
3374 } else if (p == "seamless-loop") {
3376 if (play_loop && transport_rolling()) {
3377 // to reset diskstreams etc
3378 request_play_loop (true);
3381 } else if (p == "rf-speed") {
3383 cumulative_rf_motion = 0;
3386 } else if (p == "click-sound") {
3388 setup_click_sounds (1);
3390 } else if (p == "click-emphasis-sound") {
3392 setup_click_sounds (-1);
3394 } else if (p == "clicking") {
3396 if (Config->get_clicking()) {
3397 if (_click_io && click_data) { // don't require emphasis data
3404 } else if (p == "click-gain") {
3407 _click_gain->set_gain (Config->get_click_gain(), this);
3410 } else if (p == "send-mtc") {
3412 if (Config->get_send_mtc ()) {
3413 /* mark us ready to send */
3414 next_quarter_frame_to_send = 0;
3417 } else if (p == "send-mmc") {
3419 _mmc->enable_send (Config->get_send_mmc ());
3421 } else if (p == "midi-feedback") {
3423 session_midi_feedback = Config->get_midi_feedback();
3425 } else if (p == "jack-time-master") {
3427 engine().reset_timebase ();
3429 } else if (p == "native-file-header-format") {
3431 if (!first_file_header_format_reset) {
3432 reset_native_file_format ();
3435 first_file_header_format_reset = false;
3437 } else if (p == "native-file-data-format") {
3439 if (!first_file_data_format_reset) {
3440 reset_native_file_format ();
3443 first_file_data_format_reset = false;
3445 } else if (p == "external-sync") {
3446 if (!config.get_external_sync()) {
3447 drop_sync_source ();
3449 switch_to_sync_source (Config->get_sync_source());
3451 } else if (p == "denormal-model") {
3453 } else if (p == "history-depth") {
3454 set_history_depth (Config->get_history_depth());
3455 } else if (p == "remote-model") {
3456 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3459 } else if (p == "initial-program-change") {
3461 if (_mmc->output_port() && Config->get_initial_program_change() >= 0) {
3464 buf[0] = MIDI::program; // channel zero by default
3465 buf[1] = (Config->get_initial_program_change() & 0x7f);
3467 _mmc->output_port()->midimsg (buf, sizeof (buf), 0);
3469 } else if (p == "solo-mute-override") {
3470 // catch_up_on_solo_mute_override ();
3471 } else if (p == "listen-position" || p == "pfl-position") {
3472 listen_position_changed ();
3473 } else if (p == "solo-control-is-listen-control") {
3474 solo_control_mode_changed ();
3475 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3476 last_timecode_valid = false;
3477 } else if (p == "playback-buffer-seconds") {
3478 AudioSource::allocate_working_buffers (frame_rate());
3479 } else if (p == "automation-thinning-factor") {
3480 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3481 } else if (p == "ltc-source-port") {
3482 reconnect_ltc_input ();
3483 } else if (p == "ltc-sink-port") {
3484 reconnect_ltc_output ();
3485 } else if (p == "timecode-generator-offset") {
3486 ltc_tx_parse_offset();
3493 Session::set_history_depth (uint32_t d)
3495 _history.set_depth (d);
3499 Session::load_diskstreams_2X (XMLNode const & node, int)
3502 XMLNodeConstIterator citer;
3504 clist = node.children();
3506 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3509 /* diskstreams added automatically by DiskstreamCreated handler */
3510 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3511 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3512 _diskstreams_2X.push_back (dsp);
3514 error << _("Session: unknown diskstream type in XML") << endmsg;
3518 catch (failed_constructor& err) {
3519 error << _("Session: could not load diskstream via XML state") << endmsg;
3527 /** Connect things to the MMC object */
3529 Session::setup_midi_machine_control ()
3531 _mmc = new MIDI::MachineControl;
3532 _mmc->set_ports (_midi_ports->mmc_input_port(), _midi_ports->mmc_output_port());
3534 _mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3535 _mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3536 _mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3537 _mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3538 _mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3539 _mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3540 _mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3541 _mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3542 _mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3543 _mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3544 _mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3545 _mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3546 _mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3548 /* also handle MIDI SPP because its so common */
3550 _mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3551 _mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3552 _mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3555 boost::shared_ptr<Controllable>
3556 Session::solo_cut_control() const
3558 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3559 controls in Ardour that currently get presented to the user in the GUI that require
3560 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3562 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3563 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3567 return _solo_cut_control;
3571 Session::rename (const std::string& new_name)
3573 string legal_name = legalize_for_path (new_name);
3579 string const old_sources_root = _session_dir->sources_root();
3581 #define RENAME ::rename
3586 * interchange subdirectory
3590 * Backup files are left unchanged and not renamed.
3593 /* pass one: not 100% safe check that the new directory names don't
3597 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3602 /* this is a stupid hack because Glib::path_get_dirname() is
3603 * lexical-only, and so passing it /a/b/c/ gives a different
3604 * result than passing it /a/b/c ...
3607 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3608 oldstr = oldstr.substr (0, oldstr.length() - 1);
3611 string base = Glib::path_get_dirname (oldstr);
3612 string p = Glib::path_get_basename (oldstr);
3614 newstr = Glib::build_filename (base, legal_name);
3616 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3623 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3628 /* this is a stupid hack because Glib::path_get_dirname() is
3629 * lexical-only, and so passing it /a/b/c/ gives a different
3630 * result than passing it /a/b/c ...
3633 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3634 oldstr = oldstr.substr (0, oldstr.length() - 1);
3637 string base = Glib::path_get_dirname (oldstr);
3638 string p = Glib::path_get_basename (oldstr);
3640 newstr = Glib::build_filename (base, legal_name);
3642 cerr << "Rename " << oldstr << " => " << newstr << endl;
3644 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3649 (*_session_dir) = newstr;
3654 /* directory below interchange */
3656 v.push_back (newstr);
3657 v.push_back (interchange_dir_name);
3660 oldstr = Glib::build_filename (v);
3663 v.push_back (newstr);
3664 v.push_back (interchange_dir_name);
3665 v.push_back (legal_name);
3667 newstr = Glib::build_filename (v);
3669 cerr << "Rename " << oldstr << " => " << newstr << endl;
3671 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3678 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3679 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3681 cerr << "Rename " << oldstr << " => " << newstr << endl;
3683 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3690 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3692 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3693 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3695 cerr << "Rename " << oldstr << " => " << newstr << endl;
3697 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3702 /* update file source paths */
3704 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3705 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3707 string p = fs->path ();
3708 boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3713 /* remove old name from recent sessions */
3715 remove_recent_sessions (_path);
3718 _current_snapshot_name = new_name;
3723 /* save state again to get everything just right */
3725 save_state (_current_snapshot_name);
3728 /* add to recent sessions */
3730 store_recent_sessions (new_name, _path);
3738 Session::get_session_info_from_path (XMLTree& tree, const string& xmlpath)
3740 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3744 if (!tree.read (xmlpath)) {
3752 Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format)
3755 bool found_sr = false;
3756 bool found_data_format = false;
3758 if (get_session_info_from_path (tree, xmlpath)) {
3764 const XMLProperty* prop;
3765 if ((prop = tree.root()->property (X_("sample-rate"))) != 0) {
3766 sample_rate = atoi (prop->value());
3770 const XMLNodeList& children (tree.root()->children());
3771 for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
3772 const XMLNode* child = *c;
3773 if (child->name() == "Config") {
3774 const XMLNodeList& options (child->children());
3775 for (XMLNodeList::const_iterator oc = options.begin(); oc != options.end(); ++oc) {
3776 const XMLNode* option = *oc;
3777 const XMLProperty* name = option->property("name");
3783 if (name->value() == "native-file-data-format") {
3784 const XMLProperty* value = option->property ("value");
3786 SampleFormat fmt = (SampleFormat) string_2_enum (option->property ("value")->value(), fmt);
3788 found_data_format = true;
3794 if (found_data_format) {
3799 return !(found_sr && found_data_format); // zero if they are both found