2 Copyright (C) 1999-2002 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"
63 #include "midi++/manager.h"
65 #include "evoral/SMF.hpp"
67 #include "pbd/boost_debug.h"
68 #include "pbd/basename.h"
69 #include "pbd/controllable_descriptor.h"
70 #include "pbd/enumwriter.h"
71 #include "pbd/error.h"
72 #include "pbd/file_utils.h"
73 #include "pbd/pathscanner.h"
74 #include "pbd/pthread_utils.h"
75 #include "pbd/stacktrace.h"
76 #include "pbd/convert.h"
77 #include "pbd/clear_dir.h"
79 #include "ardour/amp.h"
80 #include "ardour/audio_diskstream.h"
81 #include "ardour/audio_track.h"
82 #include "ardour/audioengine.h"
83 #include "ardour/audiofilesource.h"
84 #include "ardour/audioregion.h"
85 #include "ardour/automation_control.h"
86 #include "ardour/butler.h"
87 #include "ardour/control_protocol_manager.h"
88 #include "ardour/directory_names.h"
89 #include "ardour/filename_extensions.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;
128 /** @param snapshot_name Snapshot name, without the .ardour prefix */
130 Session::first_stage_init (string fullpath, string snapshot_name)
132 if (fullpath.length() == 0) {
134 throw failed_constructor();
137 char buf[PATH_MAX+1];
138 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
139 error << string_compose(_("Could not use path %1 (%2)"), buf, strerror(errno)) << endmsg;
141 throw failed_constructor();
146 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
147 _path += G_DIR_SEPARATOR;
150 /* these two are just provisional settings. set_state()
151 will likely override them.
154 _name = _current_snapshot_name = snapshot_name;
156 set_history_depth (Config->get_history_depth());
158 _current_frame_rate = _engine.frame_rate ();
159 _nominal_frame_rate = _current_frame_rate;
160 _base_frame_rate = _current_frame_rate;
162 _tempo_map = new TempoMap (_current_frame_rate);
163 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
166 _non_soloed_outs_muted = false;
168 _solo_isolated_cnt = 0;
169 g_atomic_int_set (&processing_prohibited, 0);
170 _transport_speed = 0;
171 _default_transport_speed = 1.0;
172 _last_transport_speed = 0;
173 _target_transport_speed = 0;
174 auto_play_legal = false;
175 transport_sub_state = 0;
176 _transport_frame = 0;
177 _requested_return_frame = -1;
178 _session_range_location = 0;
179 g_atomic_int_set (&_record_status, Disabled);
180 loop_changing = false;
183 _last_roll_location = 0;
184 _last_roll_or_reversal_location = 0;
185 _last_record_location = 0;
186 pending_locate_frame = 0;
187 pending_locate_roll = false;
188 pending_locate_flush = false;
189 state_was_pending = false;
191 outbound_mtc_timecode_frame = 0;
192 next_quarter_frame_to_send = -1;
193 current_block_size = 0;
194 solo_update_disabled = false;
195 _have_captured = false;
196 _worst_output_latency = 0;
197 _worst_input_latency = 0;
198 _worst_track_latency = 0;
199 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
200 _was_seamless = Config->get_seamless_loop ();
202 _send_qf_mtc = false;
203 _pframes_since_last_mtc = 0;
204 g_atomic_int_set (&_playback_load, 100);
205 g_atomic_int_set (&_capture_load, 100);
208 pending_abort = false;
209 _adding_routes_in_progress = false;
210 destructive_index = 0;
211 first_file_data_format_reset = true;
212 first_file_header_format_reset = true;
213 post_export_sync = false;
216 no_questions_about_missing_files = false;
217 _speakers.reset (new Speakers);
219 ignore_route_processor_changes = false;
220 _pre_export_mmc_enabled = false;
222 AudioDiskstream::allocate_working_buffers();
224 /* default short fade = 15ms */
226 SndFileSource::setup_standard_crossfades (*this, frame_rate());
228 last_mmc_step.tv_sec = 0;
229 last_mmc_step.tv_usec = 0;
232 /* click sounds are unset by default, which causes us to internal
233 waveforms for clicks.
237 click_emphasis_length = 0;
240 process_function = &Session::process_with_events;
242 if (config.get_use_video_sync()) {
243 waiting_for_sync_offset = true;
245 waiting_for_sync_offset = false;
248 last_timecode_when = 0;
249 last_timecode_valid = false;
253 last_rr_session_dir = session_dirs.begin();
254 refresh_disk_space ();
256 /* default: assume simple stereo speaker configuration */
258 _speakers->setup_default_speakers (2);
262 average_slave_delta = 1800; // !!! why 1800 ????
263 have_first_delta_accumulator = false;
264 delta_accumulator_cnt = 0;
265 _slave_state = Stopped;
267 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
268 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
269 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
270 add_controllable (_solo_cut_control);
272 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
274 /* These are all static "per-class" signals */
276 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
277 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
278 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
279 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
280 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
282 /* stop IO objects from doing stuff until we're ready for them */
284 Delivery::disable_panners ();
285 IO::disable_connecting ();
289 Session::second_stage_init ()
291 AudioFileSource::set_peak_dir (_session_dir->peak_path());
294 if (load_state (_current_snapshot_name)) {
299 if (_butler->start_thread()) {
303 if (start_midi_thread ()) {
307 setup_midi_machine_control ();
309 // set_state() will call setup_raid_path(), but if it's a new session we need
310 // to call setup_raid_path() here.
313 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
317 setup_raid_path(_path);
320 /* we can't save till after ::when_engine_running() is called,
321 because otherwise we save state with no connections made.
322 therefore, we reset _state_of_the_state because ::set_state()
323 will have cleared it.
325 we also have to include Loading so that any events that get
326 generated between here and the end of ::when_engine_running()
327 will be processed directly rather than queued.
330 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
332 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
333 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
334 setup_click_sounds (0);
335 setup_midi_control ();
337 /* Pay attention ... */
339 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
340 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
342 midi_clock = new MidiClockTicker ();
343 midi_clock->set_session (this);
346 when_engine_running ();
349 /* handle this one in a different way than all others, so that its clear what happened */
351 catch (AudioEngine::PortRegistrationFailure& err) {
352 error << err.what() << endmsg;
360 BootMessage (_("Reset Remote Controls"));
362 send_full_time_code (0);
363 _engine.transport_locate (0);
365 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
366 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
368 MIDI::Name::MidiPatchManager::instance().set_session (this);
371 /* initial program change will be delivered later; see ::config_changed() */
373 _state_of_the_state = Clean;
375 Port::set_connecting_blocked (false);
377 DirtyChanged (); /* EMIT SIGNAL */
379 if (state_was_pending) {
380 save_state (_current_snapshot_name);
381 remove_pending_capture_state ();
382 state_was_pending = false;
385 BootMessage (_("Session loading complete"));
391 Session::raid_path () const
393 SearchPath raid_search_path;
395 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
396 raid_search_path += (*i).path;
399 return raid_search_path.to_string ();
403 Session::setup_raid_path (string path)
412 session_dirs.clear ();
414 SearchPath search_path(path);
415 SearchPath sound_search_path;
416 SearchPath midi_search_path;
418 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
420 sp.blocks = 0; // not needed
421 session_dirs.push_back (sp);
423 SessionDirectory sdir(sp.path);
425 sound_search_path += sdir.sound_path ();
426 midi_search_path += sdir.midi_path ();
429 // reset the round-robin soundfile path thingie
430 last_rr_session_dir = session_dirs.begin();
434 Session::path_is_within_session (const std::string& path)
436 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
437 if (PBD::path_is_within (i->path, path)) {
445 Session::ensure_subdirs ()
449 dir = session_directory().peak_path();
451 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
452 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
456 dir = session_directory().sound_path();
458 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
459 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
463 dir = session_directory().midi_path();
465 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
466 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
470 dir = session_directory().dead_path();
472 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
473 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
477 dir = session_directory().export_path();
479 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
480 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
484 dir = analysis_dir ();
486 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
487 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
491 dir = plugins_dir ();
493 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
494 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
498 dir = externals_dir ();
500 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
501 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
508 /** @param session_template directory containing session template, or empty.
509 * Caller must not hold process lock.
512 Session::create (const string& session_template, BusProfile* bus_profile)
514 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
515 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
519 if (ensure_subdirs ()) {
523 _writable = exists_and_writable (_path);
525 if (!session_template.empty()) {
526 std::string in_path = session_template_dir_to_file (session_template);
528 ifstream in(in_path.c_str());
531 string out_path = _path;
533 out_path += statefile_suffix;
535 ofstream out(out_path.c_str());
541 /* Copy plugin state files from template to new session */
542 std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
543 copy_files (template_plugins, plugins_dir ());
548 error << string_compose (_("Could not open %1 for writing session template"), out_path)
554 error << string_compose (_("Could not open session template %1 for reading"), in_path)
561 /* set initial start + end point */
563 _state_of_the_state = Clean;
565 /* set up Master Out and Control Out if necessary */
570 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
572 if (bus_profile->master_out_channels) {
573 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
577 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
578 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
581 Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
582 r->input()->ensure_io (count, false, this);
583 r->output()->ensure_io (count, false, this);
589 /* prohibit auto-connect to master, because there isn't one */
590 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
594 add_routes (rl, false, false, false);
597 /* this allows the user to override settings with an environment variable.
600 if (no_auto_connect()) {
601 bus_profile->input_ac = AutoConnectOption (0);
602 bus_profile->output_ac = AutoConnectOption (0);
605 Config->set_input_auto_connect (bus_profile->input_ac);
606 Config->set_output_auto_connect (bus_profile->output_ac);
609 if (Config->get_use_monitor_bus() && bus_profile) {
610 add_monitor_section ();
619 Session::maybe_write_autosave()
621 if (dirty() && record_status() != Recording) {
622 save_state("", true);
627 Session::remove_pending_capture_state ()
629 std::string pending_state_file_path(_session_dir->root_path());
631 pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
633 if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
635 if (g_remove (pending_state_file_path.c_str()) != 0) {
636 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
637 pending_state_file_path, g_strerror (errno)) << endmsg;
641 /** Rename a state file.
642 * @param old_name Old snapshot name.
643 * @param new_name New snapshot name.
646 Session::rename_state (string old_name, string new_name)
648 if (old_name == _current_snapshot_name || old_name == _name) {
649 /* refuse to rename the current snapshot or the "main" one */
653 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
654 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
656 const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
657 const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
659 if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
660 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
661 old_name, new_name, g_strerror(errno)) << endmsg;
665 /** Remove a state file.
666 * @param snapshot_name Snapshot name.
669 Session::remove_state (string snapshot_name)
671 if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
672 // refuse to remove the current snapshot or the "main" one
676 std::string xml_path(_session_dir->root_path());
678 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
680 if (!create_backup_file (xml_path)) {
681 // don't remove it if a backup can't be made
682 // create_backup_file will log the error.
687 if (g_remove (xml_path.c_str()) != 0) {
688 error << string_compose(_("Could not remove session file at path \"%1\" (%2)"),
689 xml_path, g_strerror (errno)) << endmsg;
693 #ifdef HAVE_JACK_SESSION
695 Session::jack_session_event (jack_session_event_t * event)
697 char timebuf[128], *tmp;
699 struct tm local_time;
702 localtime_r (&n, &local_time);
703 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
705 while ((tmp = strchr(timebuf, ':'))) { *tmp = '.'; }
707 if (event->type == JackSessionSaveTemplate)
709 if (save_template( timebuf )) {
710 event->flags = JackSessionSaveError;
712 string cmd ("ardour3 -P -U ");
713 cmd += event->client_uuid;
717 event->command_line = strdup (cmd.c_str());
722 if (save_state (timebuf)) {
723 event->flags = JackSessionSaveError;
725 std::string xml_path (_session_dir->root_path());
726 std::string legalized_filename = legalize_for_path (timebuf) + statefile_suffix;
727 xml_path = Glib::build_filename (xml_path, legalized_filename);
729 string cmd ("ardour3 -P -U ");
730 cmd += event->client_uuid;
735 event->command_line = strdup (cmd.c_str());
739 jack_session_reply (_engine.jack(), event);
741 if (event->type == JackSessionSaveAndQuit) {
742 Quit (); /* EMIT SIGNAL */
745 jack_session_event_free( event );
749 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
751 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
754 std::string xml_path(_session_dir->root_path());
756 if (!_writable || (_state_of_the_state & CannotSave)) {
760 if (!_engine.connected ()) {
761 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
767 /* tell sources we're saving first, in case they write out to a new file
768 * which should be saved with the state rather than the old one */
769 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
771 i->second->session_saved();
772 } catch (Evoral::SMF::FileError& e) {
773 error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
777 SaveSession (); /* EMIT SIGNAL */
779 tree.set_root (&get_state());
781 if (snapshot_name.empty()) {
782 snapshot_name = _current_snapshot_name;
783 } else if (switch_to_snapshot) {
784 _current_snapshot_name = snapshot_name;
789 /* proper save: use statefile_suffix (.ardour in English) */
791 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
793 /* make a backup copy of the old file */
795 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
796 // create_backup_file will log the error
802 /* pending save: use pending_suffix (.pending in English) */
803 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
806 std::string tmp_path(_session_dir->root_path());
807 tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
809 // cerr << "actually writing state to " << xml_path << endl;
811 if (!tree.write (tmp_path)) {
812 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
813 if (g_remove (tmp_path.c_str()) != 0) {
814 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
815 tmp_path, g_strerror (errno)) << endmsg;
821 if (::rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
822 error << string_compose (_("could not rename temporary session file %1 to %2"),
823 tmp_path, xml_path) << endmsg;
824 if (g_remove (tmp_path.c_str()) != 0) {
825 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
826 tmp_path, g_strerror (errno)) << endmsg;
834 save_history (snapshot_name);
836 bool was_dirty = dirty();
838 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
841 DirtyChanged (); /* EMIT SIGNAL */
844 StateSaved (snapshot_name); /* EMIT SIGNAL */
851 Session::restore_state (string snapshot_name)
853 if (load_state (snapshot_name) == 0) {
854 set_state (*state_tree->root(), Stateful::loading_state_version);
861 Session::load_state (string snapshot_name)
866 state_was_pending = false;
868 /* check for leftover pending state from a crashed capture attempt */
870 std::string xmlpath(_session_dir->root_path());
871 xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
873 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
875 /* there is pending state from a crashed capture attempt */
877 boost::optional<int> r = AskAboutPendingState();
878 if (r.get_value_or (1)) {
879 state_was_pending = true;
883 if (!state_was_pending) {
884 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
887 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
888 xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
889 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
890 error << string_compose(_("%1: session file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
895 state_tree = new XMLTree;
899 _writable = exists_and_writable (xmlpath);
901 if (!state_tree->read (xmlpath)) {
902 error << string_compose(_("Could not understand session file %1"), xmlpath) << endmsg;
908 XMLNode& root (*state_tree->root());
910 if (root.name() != X_("Session")) {
911 error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
917 const XMLProperty* prop;
919 if ((prop = root.property ("version")) == 0) {
920 /* no version implies very old version of Ardour */
921 Stateful::loading_state_version = 1000;
923 if (prop->value().find ('.') != string::npos) {
924 /* old school version format */
925 if (prop->value()[0] == '2') {
926 Stateful::loading_state_version = 2000;
928 Stateful::loading_state_version = 3000;
931 Stateful::loading_state_version = atoi (prop->value());
935 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
937 std::string backup_path(_session_dir->root_path());
938 std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
939 backup_path = Glib::build_filename (backup_path, backup_filename);
941 // only create a backup for a given statefile version once
943 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
945 VersionMismatch (xmlpath, backup_path);
947 if (!copy_file (xmlpath, backup_path)) {;
957 Session::load_options (const XMLNode& node)
959 LocaleGuard lg (X_("POSIX"));
960 config.set_variables (node);
971 Session::get_template()
973 /* if we don't disable rec-enable, diskstreams
974 will believe they need to store their capture
975 sources in their state node.
978 disable_record (false);
984 Session::state (bool full_state)
986 XMLNode* node = new XMLNode("Session");
990 snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
991 node->add_property("version", buf);
993 /* store configuration settings */
997 node->add_property ("name", _name);
998 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
999 node->add_property ("sample-rate", buf);
1001 if (session_dirs.size() > 1) {
1005 vector<space_and_path>::iterator i = session_dirs.begin();
1006 vector<space_and_path>::iterator next;
1008 ++i; /* skip the first one */
1012 while (i != session_dirs.end()) {
1016 if (next != session_dirs.end()) {
1026 child = node->add_child ("Path");
1027 child->add_content (p);
1031 /* save the ID counter */
1033 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1034 node->add_property ("id-counter", buf);
1036 /* save the event ID counter */
1038 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1039 node->add_property ("event-counter", buf);
1041 /* various options */
1043 node->add_child_nocopy (config.get_variables ());
1045 node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1047 child = node->add_child ("Sources");
1050 Glib::Threads::Mutex::Lock sl (source_lock);
1052 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1054 /* Don't save information about non-file Sources, or
1055 * about non-destructive file sources that are empty
1056 * and unused by any regions.
1059 boost::shared_ptr<FileSource> fs;
1061 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1063 if (!fs->destructive()) {
1064 if (fs->empty() && !fs->used()) {
1069 child->add_child_nocopy (siter->second->get_state());
1074 child = node->add_child ("Regions");
1077 Glib::Threads::Mutex::Lock rl (region_lock);
1078 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1079 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1080 boost::shared_ptr<Region> r = i->second;
1081 /* only store regions not attached to playlists */
1082 if (r->playlist() == 0) {
1083 if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
1084 child->add_child_nocopy ((boost::dynamic_pointer_cast<AudioRegion>(r))->get_basic_state ());
1086 child->add_child_nocopy (r->get_state ());
1091 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1093 if (!cassocs.empty()) {
1094 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1096 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1098 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1099 i->first->id().print (buf, sizeof (buf));
1100 can->add_property (X_("copy"), buf);
1101 i->second->id().print (buf, sizeof (buf));
1102 can->add_property (X_("original"), buf);
1103 ca->add_child_nocopy (*can);
1109 node->add_child_nocopy (_locations->get_state());
1111 // for a template, just create a new Locations, populate it
1112 // with the default start and end, and get the state for that.
1113 Locations loc (*this);
1114 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1115 range->set (max_framepos, 0);
1117 node->add_child_nocopy (loc.get_state());
1120 child = node->add_child ("Bundles");
1122 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1123 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1124 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1126 child->add_child_nocopy (b->get_state());
1131 child = node->add_child ("Routes");
1133 boost::shared_ptr<RouteList> r = routes.reader ();
1135 RoutePublicOrderSorter cmp;
1136 RouteList public_order (*r);
1137 public_order.sort (cmp);
1139 /* the sort should have put control outs first */
1142 assert (_monitor_out == public_order.front());
1145 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1146 if (!(*i)->is_auditioner()) {
1148 child->add_child_nocopy ((*i)->get_state());
1150 child->add_child_nocopy ((*i)->get_template());
1156 playlists->add_state (node, full_state);
1158 child = node->add_child ("RouteGroups");
1159 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1160 child->add_child_nocopy ((*i)->get_state());
1164 XMLNode* gain_child = node->add_child ("Click");
1165 gain_child->add_child_nocopy (_click_io->state (full_state));
1166 gain_child->add_child_nocopy (_click_gain->state (full_state));
1170 XMLNode* ltc_input_child = node->add_child ("LTC-In");
1171 ltc_input_child->add_child_nocopy (_ltc_input->state (full_state));
1175 XMLNode* ltc_output_child = node->add_child ("LTC-Out");
1176 ltc_output_child->add_child_nocopy (_ltc_output->state (full_state));
1179 node->add_child_nocopy (_speakers->get_state());
1180 node->add_child_nocopy (_tempo_map->get_state());
1181 node->add_child_nocopy (get_control_protocol_state());
1184 node->add_child_copy (*_extra_xml);
1191 Session::get_control_protocol_state ()
1193 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1194 return cpm.get_state();
1198 Session::set_state (const XMLNode& node, int version)
1202 const XMLProperty* prop;
1205 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1207 if (node.name() != X_("Session")) {
1208 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1212 if ((prop = node.property ("name")) != 0) {
1213 _name = prop->value ();
1216 if ((prop = node.property (X_("sample-rate"))) != 0) {
1218 _nominal_frame_rate = atoi (prop->value());
1220 if (_nominal_frame_rate != _current_frame_rate) {
1221 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1222 if (r.get_value_or (0)) {
1228 setup_raid_path(_session_dir->root_path());
1230 if ((prop = node.property (X_("id-counter"))) != 0) {
1232 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1233 ID::init_counter (x);
1235 /* old sessions used a timebased counter, so fake
1236 the startup ID counter based on a standard
1241 ID::init_counter (now);
1244 if ((prop = node.property (X_("event-counter"))) != 0) {
1245 Evoral::init_event_id_counter (atoi (prop->value()));
1248 IO::disable_connecting ();
1250 Stateful::save_extra_xml (node);
1252 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1253 load_options (*child);
1254 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1255 load_options (*child);
1257 error << _("Session: XML state has no options section") << endmsg;
1260 if (version >= 3000) {
1261 if ((child = find_named_node (node, "Metadata")) == 0) {
1262 warning << _("Session: XML state has no metadata section") << endmsg;
1263 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1268 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1269 _speakers->set_state (*child, version);
1272 if ((child = find_named_node (node, "Sources")) == 0) {
1273 error << _("Session: XML state has no sources section") << endmsg;
1275 } else if (load_sources (*child)) {
1279 if ((child = find_named_node (node, "TempoMap")) == 0) {
1280 error << _("Session: XML state has no Tempo Map section") << endmsg;
1282 } else if (_tempo_map->set_state (*child, version)) {
1286 if ((child = find_named_node (node, "Locations")) == 0) {
1287 error << _("Session: XML state has no locations section") << endmsg;
1289 } else if (_locations->set_state (*child, version)) {
1295 if ((location = _locations->auto_loop_location()) != 0) {
1296 set_auto_loop_location (location);
1299 if ((location = _locations->auto_punch_location()) != 0) {
1300 set_auto_punch_location (location);
1303 if ((location = _locations->session_range_location()) != 0) {
1304 delete _session_range_location;
1305 _session_range_location = location;
1308 if (_session_range_location) {
1309 AudioFileSource::set_header_position_offset (_session_range_location->start());
1312 if ((child = find_named_node (node, "Regions")) == 0) {
1313 error << _("Session: XML state has no Regions section") << endmsg;
1315 } else if (load_regions (*child)) {
1319 if ((child = find_named_node (node, "Playlists")) == 0) {
1320 error << _("Session: XML state has no playlists section") << endmsg;
1322 } else if (playlists->load (*this, *child)) {
1326 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1328 } else if (playlists->load_unused (*this, *child)) {
1332 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1333 if (load_compounds (*child)) {
1338 if (version >= 3000) {
1339 if ((child = find_named_node (node, "Bundles")) == 0) {
1340 warning << _("Session: XML state has no bundles section") << endmsg;
1343 /* We can't load Bundles yet as they need to be able
1344 to convert from port names to Port objects, which can't happen until
1346 _bundle_xml_node = new XMLNode (*child);
1350 if (version < 3000) {
1351 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1352 error << _("Session: XML state has no diskstreams section") << endmsg;
1354 } else if (load_diskstreams_2X (*child, version)) {
1359 if ((child = find_named_node (node, "Routes")) == 0) {
1360 error << _("Session: XML state has no routes section") << endmsg;
1362 } else if (load_routes (*child, version)) {
1366 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1367 _diskstreams_2X.clear ();
1369 if (version >= 3000) {
1371 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1372 error << _("Session: XML state has no route groups section") << endmsg;
1374 } else if (load_route_groups (*child, version)) {
1378 } else if (version < 3000) {
1380 if ((child = find_named_node (node, "EditGroups")) == 0) {
1381 error << _("Session: XML state has no edit groups section") << endmsg;
1383 } else if (load_route_groups (*child, version)) {
1387 if ((child = find_named_node (node, "MixGroups")) == 0) {
1388 error << _("Session: XML state has no mix groups section") << endmsg;
1390 } else if (load_route_groups (*child, version)) {
1395 if ((child = find_named_node (node, "Click")) == 0) {
1396 warning << _("Session: XML state has no click section") << endmsg;
1397 } else if (_click_io) {
1398 const XMLNodeList& children (child->children());
1399 XMLNodeList::const_iterator i = children.begin();
1400 _click_io->set_state (**i, version);
1402 if (i != children.end()) {
1403 _click_gain->set_state (**i, version);
1407 if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
1408 ControlProtocolManager::instance().set_state (*child, version);
1411 update_have_rec_enabled_track ();
1413 /* here beginneth the second phase ... */
1415 StateReady (); /* EMIT SIGNAL */
1424 Session::load_routes (const XMLNode& node, int version)
1427 XMLNodeConstIterator niter;
1428 RouteList new_routes;
1430 nlist = node.children();
1434 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1436 boost::shared_ptr<Route> route;
1437 if (version < 3000) {
1438 route = XMLRouteFactory_2X (**niter, version);
1440 route = XMLRouteFactory (**niter, version);
1444 error << _("Session: cannot create Route from XML description.") << endmsg;
1448 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1450 new_routes.push_back (route);
1453 add_routes (new_routes, false, false, false);
1458 boost::shared_ptr<Route>
1459 Session::XMLRouteFactory (const XMLNode& node, int version)
1461 boost::shared_ptr<Route> ret;
1463 if (node.name() != "Route") {
1467 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1469 DataType type = DataType::AUDIO;
1470 const XMLProperty* prop = node.property("default-type");
1473 type = DataType (prop->value());
1476 assert (type != DataType::NIL);
1480 boost::shared_ptr<Track> track;
1482 if (type == DataType::AUDIO) {
1483 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1485 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1488 if (track->init()) {
1492 if (track->set_state (node, version)) {
1496 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1497 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1502 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1504 if (r->init () == 0 && r->set_state (node, version) == 0) {
1505 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1506 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1515 boost::shared_ptr<Route>
1516 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1518 boost::shared_ptr<Route> ret;
1520 if (node.name() != "Route") {
1524 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1526 ds_prop = node.property (X_("diskstream"));
1529 DataType type = DataType::AUDIO;
1530 const XMLProperty* prop = node.property("default-type");
1533 type = DataType (prop->value());
1536 assert (type != DataType::NIL);
1540 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1541 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1545 if (i == _diskstreams_2X.end()) {
1546 error << _("Could not find diskstream for route") << endmsg;
1547 return boost::shared_ptr<Route> ();
1550 boost::shared_ptr<Track> track;
1552 if (type == DataType::AUDIO) {
1553 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1555 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1558 if (track->init()) {
1562 if (track->set_state (node, version)) {
1566 track->set_diskstream (*i);
1568 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1569 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1574 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1576 if (r->init () == 0 && r->set_state (node, version) == 0) {
1577 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1578 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1588 Session::load_regions (const XMLNode& node)
1591 XMLNodeConstIterator niter;
1592 boost::shared_ptr<Region> region;
1594 nlist = node.children();
1598 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1599 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1600 error << _("Session: cannot create Region from XML description.");
1601 const XMLProperty *name = (**niter).property("name");
1604 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1615 Session::load_compounds (const XMLNode& node)
1617 XMLNodeList calist = node.children();
1618 XMLNodeConstIterator caiter;
1619 XMLProperty *caprop;
1621 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1622 XMLNode* ca = *caiter;
1626 if ((caprop = ca->property (X_("original"))) == 0) {
1629 orig_id = caprop->value();
1631 if ((caprop = ca->property (X_("copy"))) == 0) {
1634 copy_id = caprop->value();
1636 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1637 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1639 if (!orig || !copy) {
1640 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1646 RegionFactory::add_compound_association (orig, copy);
1653 Session::load_nested_sources (const XMLNode& node)
1656 XMLNodeConstIterator niter;
1658 nlist = node.children();
1660 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1661 if ((*niter)->name() == "Source") {
1663 /* it may already exist, so don't recreate it unnecessarily
1666 XMLProperty* prop = (*niter)->property (X_("id"));
1668 error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
1672 ID source_id (prop->value());
1674 if (!source_by_id (source_id)) {
1677 SourceFactory::create (*this, **niter, true);
1679 catch (failed_constructor& err) {
1680 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1687 boost::shared_ptr<Region>
1688 Session::XMLRegionFactory (const XMLNode& node, bool full)
1690 const XMLProperty* type = node.property("type");
1694 const XMLNodeList& nlist = node.children();
1696 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1697 XMLNode *child = (*niter);
1698 if (child->name() == "NestedSource") {
1699 load_nested_sources (*child);
1703 if (!type || type->value() == "audio") {
1704 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1705 } else if (type->value() == "midi") {
1706 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1709 } catch (failed_constructor& err) {
1710 return boost::shared_ptr<Region> ();
1713 return boost::shared_ptr<Region> ();
1716 boost::shared_ptr<AudioRegion>
1717 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1719 const XMLProperty* prop;
1720 boost::shared_ptr<Source> source;
1721 boost::shared_ptr<AudioSource> as;
1723 SourceList master_sources;
1724 uint32_t nchans = 1;
1727 if (node.name() != X_("Region")) {
1728 return boost::shared_ptr<AudioRegion>();
1731 if ((prop = node.property (X_("channels"))) != 0) {
1732 nchans = atoi (prop->value().c_str());
1735 if ((prop = node.property ("name")) == 0) {
1736 cerr << "no name for this region\n";
1740 if ((prop = node.property (X_("source-0"))) == 0) {
1741 if ((prop = node.property ("source")) == 0) {
1742 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1743 return boost::shared_ptr<AudioRegion>();
1747 PBD::ID s_id (prop->value());
1749 if ((source = source_by_id (s_id)) == 0) {
1750 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1751 return boost::shared_ptr<AudioRegion>();
1754 as = boost::dynamic_pointer_cast<AudioSource>(source);
1756 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1757 return boost::shared_ptr<AudioRegion>();
1760 sources.push_back (as);
1762 /* pickup other channels */
1764 for (uint32_t n=1; n < nchans; ++n) {
1765 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1766 if ((prop = node.property (buf)) != 0) {
1768 PBD::ID id2 (prop->value());
1770 if ((source = source_by_id (id2)) == 0) {
1771 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1772 return boost::shared_ptr<AudioRegion>();
1775 as = boost::dynamic_pointer_cast<AudioSource>(source);
1777 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1778 return boost::shared_ptr<AudioRegion>();
1780 sources.push_back (as);
1784 for (uint32_t n = 0; n < nchans; ++n) {
1785 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1786 if ((prop = node.property (buf)) != 0) {
1788 PBD::ID id2 (prop->value());
1790 if ((source = source_by_id (id2)) == 0) {
1791 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1792 return boost::shared_ptr<AudioRegion>();
1795 as = boost::dynamic_pointer_cast<AudioSource>(source);
1797 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1798 return boost::shared_ptr<AudioRegion>();
1800 master_sources.push_back (as);
1805 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1807 /* a final detail: this is the one and only place that we know how long missing files are */
1809 if (region->whole_file()) {
1810 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1811 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1813 sfp->set_length (region->length());
1818 if (!master_sources.empty()) {
1819 if (master_sources.size() != nchans) {
1820 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1822 region->set_master_sources (master_sources);
1830 catch (failed_constructor& err) {
1831 return boost::shared_ptr<AudioRegion>();
1835 boost::shared_ptr<MidiRegion>
1836 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1838 const XMLProperty* prop;
1839 boost::shared_ptr<Source> source;
1840 boost::shared_ptr<MidiSource> ms;
1843 if (node.name() != X_("Region")) {
1844 return boost::shared_ptr<MidiRegion>();
1847 if ((prop = node.property ("name")) == 0) {
1848 cerr << "no name for this region\n";
1852 if ((prop = node.property (X_("source-0"))) == 0) {
1853 if ((prop = node.property ("source")) == 0) {
1854 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1855 return boost::shared_ptr<MidiRegion>();
1859 PBD::ID s_id (prop->value());
1861 if ((source = source_by_id (s_id)) == 0) {
1862 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1863 return boost::shared_ptr<MidiRegion>();
1866 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1868 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1869 return boost::shared_ptr<MidiRegion>();
1872 sources.push_back (ms);
1875 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1876 /* a final detail: this is the one and only place that we know how long missing files are */
1878 if (region->whole_file()) {
1879 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1880 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1882 sfp->set_length (region->length());
1890 catch (failed_constructor& err) {
1891 return boost::shared_ptr<MidiRegion>();
1896 Session::get_sources_as_xml ()
1899 XMLNode* node = new XMLNode (X_("Sources"));
1900 Glib::Threads::Mutex::Lock lm (source_lock);
1902 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1903 node->add_child_nocopy (i->second->get_state());
1910 Session::path_from_region_name (DataType type, string name, string identifier)
1912 char buf[PATH_MAX+1];
1914 SessionDirectory sdir(get_best_session_directory_for_new_source());
1915 std::string source_dir = ((type == DataType::AUDIO)
1916 ? sdir.sound_path() : sdir.midi_path());
1918 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1920 for (n = 0; n < 999999; ++n) {
1921 if (identifier.length()) {
1922 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1923 identifier.c_str(), n, ext.c_str());
1925 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1929 std::string source_path = Glib::build_filename (source_dir, buf);
1931 if (!Glib::file_test (source_path, Glib::FILE_TEST_EXISTS)) {
1936 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1945 Session::load_sources (const XMLNode& node)
1948 XMLNodeConstIterator niter;
1949 boost::shared_ptr<Source> source;
1951 nlist = node.children();
1955 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1958 if ((source = XMLSourceFactory (**niter)) == 0) {
1959 error << _("Session: cannot create Source from XML description.") << endmsg;
1962 } catch (MissingSource& err) {
1966 if (!no_questions_about_missing_files) {
1967 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1972 switch (user_choice) {
1974 /* user added a new search location, so try again */
1979 /* user asked to quit the entire session load
1984 no_questions_about_missing_files = true;
1988 no_questions_about_missing_files = true;
1993 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1994 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2003 boost::shared_ptr<Source>
2004 Session::XMLSourceFactory (const XMLNode& node)
2006 if (node.name() != "Source") {
2007 return boost::shared_ptr<Source>();
2011 /* note: do peak building in another thread when loading session state */
2012 return SourceFactory::create (*this, node, true);
2015 catch (failed_constructor& err) {
2016 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2017 return boost::shared_ptr<Source>();
2022 Session::save_template (string template_name)
2026 if (_state_of_the_state & CannotSave) {
2030 std::string user_template_dir(user_template_directory());
2032 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
2033 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2034 user_template_dir, g_strerror (errno)) << endmsg;
2038 tree.set_root (&get_template());
2040 std::string template_dir_path(user_template_dir);
2042 /* directory to put the template in */
2043 template_dir_path = Glib::build_filename (template_dir_path, template_name);
2045 if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
2046 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2047 template_dir_path) << endmsg;
2051 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
2052 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
2053 template_dir_path, g_strerror (errno)) << endmsg;
2058 std::string template_file_path(template_dir_path);
2059 template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
2061 if (!tree.write (template_file_path)) {
2062 error << _("template not saved") << endmsg;
2066 /* copy plugin state directory */
2068 std::string template_plugin_state_path(template_dir_path);
2069 template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
2071 if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
2072 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
2073 template_plugin_state_path, g_strerror (errno)) << endmsg;
2077 copy_files (plugins_dir(), template_plugin_state_path);
2083 Session::refresh_disk_space ()
2085 #if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
2087 Glib::Threads::Mutex::Lock lm (space_lock);
2089 /* get freespace on every FS that is part of the session path */
2091 _total_free_4k_blocks = 0;
2092 _total_free_4k_blocks_uncertain = false;
2094 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2096 struct statfs statfsbuf;
2097 statfs (i->path.c_str(), &statfsbuf);
2099 double const scale = statfsbuf.f_bsize / 4096.0;
2101 /* See if this filesystem is read-only */
2102 struct statvfs statvfsbuf;
2103 statvfs (i->path.c_str(), &statvfsbuf);
2105 /* f_bavail can be 0 if it is undefined for whatever
2106 filesystem we are looking at; Samba shares mounted
2107 via GVFS are an example of this.
2109 if (statfsbuf.f_bavail == 0) {
2110 /* block count unknown */
2112 i->blocks_unknown = true;
2113 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2114 /* read-only filesystem */
2116 i->blocks_unknown = false;
2118 /* read/write filesystem with known space */
2119 i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2120 i->blocks_unknown = false;
2123 _total_free_4k_blocks += i->blocks;
2124 if (i->blocks_unknown) {
2125 _total_free_4k_blocks_uncertain = true;
2132 Session::get_best_session_directory_for_new_source ()
2134 vector<space_and_path>::iterator i;
2135 string result = _session_dir->root_path();
2137 /* handle common case without system calls */
2139 if (session_dirs.size() == 1) {
2143 /* OK, here's the algorithm we're following here:
2145 We want to select which directory to use for
2146 the next file source to be created. Ideally,
2147 we'd like to use a round-robin process so as to
2148 get maximum performance benefits from splitting
2149 the files across multiple disks.
2151 However, in situations without much diskspace, an
2152 RR approach may end up filling up a filesystem
2153 with new files while others still have space.
2154 Its therefore important to pay some attention to
2155 the freespace in the filesystem holding each
2156 directory as well. However, if we did that by
2157 itself, we'd keep creating new files in the file
2158 system with the most space until it was as full
2159 as all others, thus negating any performance
2160 benefits of this RAID-1 like approach.
2162 So, we use a user-configurable space threshold. If
2163 there are at least 2 filesystems with more than this
2164 much space available, we use RR selection between them.
2165 If not, then we pick the filesystem with the most space.
2167 This gets a good balance between the two
2171 refresh_disk_space ();
2173 int free_enough = 0;
2175 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2176 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2181 if (free_enough >= 2) {
2182 /* use RR selection process, ensuring that the one
2186 i = last_rr_session_dir;
2189 if (++i == session_dirs.end()) {
2190 i = session_dirs.begin();
2193 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2194 SessionDirectory sdir(i->path);
2195 if (sdir.create ()) {
2197 last_rr_session_dir = i;
2202 } while (i != last_rr_session_dir);
2206 /* pick FS with the most freespace (and that
2207 seems to actually work ...)
2210 vector<space_and_path> sorted;
2211 space_and_path_ascending_cmp cmp;
2213 sorted = session_dirs;
2214 sort (sorted.begin(), sorted.end(), cmp);
2216 for (i = sorted.begin(); i != sorted.end(); ++i) {
2217 SessionDirectory sdir(i->path);
2218 if (sdir.create ()) {
2220 last_rr_session_dir = i;
2230 Session::automation_dir () const
2232 return Glib::build_filename (_path, "automation");
2236 Session::analysis_dir () const
2238 return Glib::build_filename (_path, "analysis");
2242 Session::plugins_dir () const
2244 return Glib::build_filename (_path, "plugins");
2248 Session::externals_dir () const
2250 return Glib::build_filename (_path, "externals");
2254 Session::load_bundles (XMLNode const & node)
2256 XMLNodeList nlist = node.children();
2257 XMLNodeConstIterator niter;
2261 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2262 if ((*niter)->name() == "InputBundle") {
2263 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2264 } else if ((*niter)->name() == "OutputBundle") {
2265 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2267 error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2276 Session::load_route_groups (const XMLNode& node, int version)
2278 XMLNodeList nlist = node.children();
2279 XMLNodeConstIterator niter;
2283 if (version >= 3000) {
2285 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2286 if ((*niter)->name() == "RouteGroup") {
2287 RouteGroup* rg = new RouteGroup (*this, "");
2288 add_route_group (rg);
2289 rg->set_state (**niter, version);
2293 } else if (version < 3000) {
2295 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2296 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2297 RouteGroup* rg = new RouteGroup (*this, "");
2298 add_route_group (rg);
2299 rg->set_state (**niter, version);
2308 Session::auto_save()
2310 save_state (_current_snapshot_name);
2314 state_file_filter (const string &str, void */*arg*/)
2316 return (str.length() > strlen(statefile_suffix) &&
2317 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2321 bool operator()(const string* a, const string* b) {
2327 remove_end(string* state)
2329 string statename(*state);
2331 string::size_type start,end;
2332 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2333 statename = statename.substr (start+1);
2336 if ((end = statename.rfind(".ardour")) == string::npos) {
2337 end = statename.length();
2340 return new string(statename.substr (0, end));
2344 Session::possible_states (string path)
2346 PathScanner scanner;
2347 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2349 transform(states->begin(), states->end(), states->begin(), remove_end);
2352 sort (states->begin(), states->end(), cmp);
2358 Session::possible_states () const
2360 return possible_states(_path);
2364 Session::add_route_group (RouteGroup* g)
2366 _route_groups.push_back (g);
2367 route_group_added (g); /* EMIT SIGNAL */
2369 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2370 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2371 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2377 Session::remove_route_group (RouteGroup& rg)
2379 list<RouteGroup*>::iterator i;
2381 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2382 _route_groups.erase (i);
2385 route_group_removed (); /* EMIT SIGNAL */
2389 /** Set a new order for our route groups, without adding or removing any.
2390 * @param groups Route group list in the new order.
2393 Session::reorder_route_groups (list<RouteGroup*> groups)
2395 _route_groups = groups;
2397 route_groups_reordered (); /* EMIT SIGNAL */
2403 Session::route_group_by_name (string name)
2405 list<RouteGroup *>::iterator i;
2407 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2408 if ((*i)->name() == name) {
2416 Session::all_route_group() const
2418 return *_all_route_group;
2422 Session::add_commands (vector<Command*> const & cmds)
2424 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2430 Session::begin_reversible_command (const string& name)
2432 begin_reversible_command (g_quark_from_string (name.c_str ()));
2435 /** Begin a reversible command using a GQuark to identify it.
2436 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2437 * but there must be as many begin...()s as there are commit...()s.
2440 Session::begin_reversible_command (GQuark q)
2442 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2443 to hold all the commands that are committed. This keeps the order of
2444 commands correct in the history.
2447 if (_current_trans == 0) {
2448 /* start a new transaction */
2449 assert (_current_trans_quarks.empty ());
2450 _current_trans = new UndoTransaction();
2451 _current_trans->set_name (g_quark_to_string (q));
2454 _current_trans_quarks.push_front (q);
2458 Session::commit_reversible_command (Command *cmd)
2460 assert (_current_trans);
2461 assert (!_current_trans_quarks.empty ());
2466 _current_trans->add_command (cmd);
2469 _current_trans_quarks.pop_front ();
2471 if (!_current_trans_quarks.empty ()) {
2472 /* the transaction we're committing is not the top-level one */
2476 if (_current_trans->empty()) {
2477 /* no commands were added to the transaction, so just get rid of it */
2478 delete _current_trans;
2483 gettimeofday (&now, 0);
2484 _current_trans->set_timestamp (now);
2486 _history.add (_current_trans);
2491 accept_all_audio_files (const string& path, void */*arg*/)
2493 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2497 if (!AudioFileSource::safe_audio_file_extension (path)) {
2505 accept_all_midi_files (const string& path, void */*arg*/)
2507 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2511 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2512 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2513 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2517 accept_all_state_files (const string& path, void */*arg*/)
2519 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2523 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2527 Session::find_all_sources (string path, set<string>& result)
2532 if (!tree.read (path)) {
2536 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2541 XMLNodeConstIterator niter;
2543 nlist = node->children();
2547 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2551 if ((prop = (*niter)->property (X_("type"))) == 0) {
2555 DataType type (prop->value());
2557 if ((prop = (*niter)->property (X_("name"))) == 0) {
2561 if (Glib::path_is_absolute (prop->value())) {
2562 /* external file, ignore */
2570 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2571 result.insert (found_path);
2579 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2581 PathScanner scanner;
2582 vector<string*>* state_files;
2584 string this_snapshot_path;
2590 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2591 ripped = ripped.substr (0, ripped.length() - 1);
2594 state_files = scanner (ripped, accept_all_state_files, (void *) 0, true, true);
2596 if (state_files == 0) {
2601 this_snapshot_path = _path;
2602 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2603 this_snapshot_path += statefile_suffix;
2605 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2607 if (exclude_this_snapshot && **i == this_snapshot_path) {
2611 if (find_all_sources (**i, result) < 0) {
2619 struct RegionCounter {
2620 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2621 AudioSourceList::iterator iter;
2622 boost::shared_ptr<Region> region;
2625 RegionCounter() : count (0) {}
2629 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2631 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2632 return r.get_value_or (1);
2636 Session::cleanup_regions ()
2638 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2640 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2642 uint32_t used = playlists->region_use_count (i->second);
2644 if (used == 0 && !i->second->automatic ()) {
2645 RegionFactory::map_remove (i->second);
2649 /* dump the history list */
2656 Session::cleanup_sources (CleanupReport& rep)
2658 // FIXME: needs adaptation to midi
2660 vector<boost::shared_ptr<Source> > dead_sources;
2661 PathScanner scanner;
2664 vector<space_and_path>::iterator i;
2665 vector<space_and_path>::iterator nexti;
2666 vector<string*>* candidates;
2667 vector<string*>* candidates2;
2668 vector<string> unused;
2669 set<string> all_sources;
2674 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2676 /* consider deleting all unused playlists */
2678 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2683 /* sync the "all regions" property of each playlist with its current state
2686 playlists->sync_all_regions_with_regions ();
2688 /* find all un-used sources */
2693 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2695 SourceMap::iterator tmp;
2700 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2704 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2705 dead_sources.push_back (i->second);
2706 i->second->drop_references ();
2712 /* build a list of all the possible audio directories for the session */
2714 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2719 SessionDirectory sdir ((*i).path);
2720 audio_path += sdir.sound_path();
2722 if (nexti != session_dirs.end()) {
2730 /* build a list of all the possible midi directories for the session */
2732 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2737 SessionDirectory sdir ((*i).path);
2738 midi_path += sdir.midi_path();
2740 if (nexti != session_dirs.end()) {
2747 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2748 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2754 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2755 candidates->push_back (*i);
2760 candidates = candidates2; // might still be null
2763 /* find all sources, but don't use this snapshot because the
2764 state file on disk still references sources we may have already
2768 find_all_sources_across_snapshots (all_sources, true);
2770 /* add our current source list
2773 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2774 boost::shared_ptr<FileSource> fs;
2775 SourceMap::iterator tmp = i;
2778 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2779 if (playlists->source_use_count (fs) != 0) {
2780 all_sources.insert (fs->path());
2783 /* we might not remove this source from disk, because it may be used
2784 by other snapshots, but its not being used in this version
2785 so lets get rid of it now, along with any representative regions
2789 RegionFactory::remove_regions_using_source (i->second);
2797 char tmppath1[PATH_MAX+1];
2798 char tmppath2[PATH_MAX+1];
2801 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2806 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2808 if (realpath(spath.c_str(), tmppath1) == 0) {
2809 error << string_compose (_("Cannot expand path %1 (%2)"),
2810 spath, strerror (errno)) << endmsg;
2814 if (realpath((*i).c_str(), tmppath2) == 0) {
2815 error << string_compose (_("Cannot expand path %1 (%2)"),
2816 (*i), strerror (errno)) << endmsg;
2820 if (strcmp(tmppath1, tmppath2) == 0) {
2827 unused.push_back (spath);
2836 /* now try to move all unused files into the "dead" directory(ies) */
2838 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2839 struct stat statbuf;
2843 /* don't move the file across filesystems, just
2844 stick it in the `dead_dir_name' directory
2845 on whichever filesystem it was already on.
2848 if ((*x).find ("/sounds/") != string::npos) {
2850 /* old school, go up 1 level */
2852 newpath = Glib::path_get_dirname (*x); // "sounds"
2853 newpath = Glib::path_get_dirname (newpath); // "session-name"
2857 /* new school, go up 4 levels */
2859 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2860 newpath = Glib::path_get_dirname (newpath); // "session-name"
2861 newpath = Glib::path_get_dirname (newpath); // "interchange"
2862 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2865 newpath = Glib::build_filename (newpath, dead_dir_name);
2867 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2868 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2872 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2874 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2876 /* the new path already exists, try versioning */
2878 char buf[PATH_MAX+1];
2882 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2885 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2886 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2890 if (version == 999) {
2891 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2895 newpath = newpath_v;
2900 /* it doesn't exist, or we can't read it or something */
2904 stat ((*x).c_str(), &statbuf);
2906 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2907 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2908 (*x), newpath, strerror (errno))
2913 /* see if there an easy to find peakfile for this file, and remove it.
2916 string base = basename_nosuffix (*x);
2917 base += "%A"; /* this is what we add for the channel suffix of all native files,
2918 or for the first channel of embedded files. it will miss
2919 some peakfiles for other channels
2921 string peakpath = peak_path (base);
2923 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2924 if (::unlink (peakpath.c_str()) != 0) {
2925 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2926 peakpath, _path, strerror (errno))
2928 /* try to back out */
2929 ::rename (newpath.c_str(), _path.c_str());
2934 rep.paths.push_back (*x);
2935 rep.space += statbuf.st_size;
2938 /* dump the history list */
2942 /* save state so we don't end up a session file
2943 referring to non-existent sources.
2950 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2956 Session::cleanup_trash_sources (CleanupReport& rep)
2958 // FIXME: needs adaptation for MIDI
2960 vector<space_and_path>::iterator i;
2966 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2968 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2970 clear_directory (dead_dir, &rep.space, &rep.paths);
2977 Session::set_dirty ()
2979 bool was_dirty = dirty();
2981 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2985 DirtyChanged(); /* EMIT SIGNAL */
2991 Session::set_clean ()
2993 bool was_dirty = dirty();
2995 _state_of_the_state = Clean;
2999 DirtyChanged(); /* EMIT SIGNAL */
3004 Session::set_deletion_in_progress ()
3006 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3010 Session::clear_deletion_in_progress ()
3012 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3016 Session::add_controllable (boost::shared_ptr<Controllable> c)
3018 /* this adds a controllable to the list managed by the Session.
3019 this is a subset of those managed by the Controllable class
3020 itself, and represents the only ones whose state will be saved
3021 as part of the session.
3024 Glib::Threads::Mutex::Lock lm (controllables_lock);
3025 controllables.insert (c);
3028 struct null_deleter { void operator()(void const *) const {} };
3031 Session::remove_controllable (Controllable* c)
3033 if (_state_of_the_state & Deletion) {
3037 Glib::Threads::Mutex::Lock lm (controllables_lock);
3039 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3041 if (x != controllables.end()) {
3042 controllables.erase (x);
3046 boost::shared_ptr<Controllable>
3047 Session::controllable_by_id (const PBD::ID& id)
3049 Glib::Threads::Mutex::Lock lm (controllables_lock);
3051 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3052 if ((*i)->id() == id) {
3057 return boost::shared_ptr<Controllable>();
3060 boost::shared_ptr<Controllable>
3061 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3063 boost::shared_ptr<Controllable> c;
3064 boost::shared_ptr<Route> r;
3066 switch (desc.top_level_type()) {
3067 case ControllableDescriptor::NamedRoute:
3069 std::string str = desc.top_level_name();
3070 if (str == "master") {
3072 } else if (str == "control" || str == "listen") {
3075 r = route_by_name (desc.top_level_name());
3080 case ControllableDescriptor::RemoteControlID:
3081 r = route_by_remote_id (desc.rid());
3089 switch (desc.subtype()) {
3090 case ControllableDescriptor::Gain:
3091 c = r->gain_control ();
3094 case ControllableDescriptor::Solo:
3095 c = r->solo_control();
3098 case ControllableDescriptor::Mute:
3099 c = r->mute_control();
3102 case ControllableDescriptor::Recenable:
3104 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3107 c = t->rec_enable_control ();
3112 case ControllableDescriptor::PanDirection:
3114 c = r->pannable()->pan_azimuth_control;
3118 case ControllableDescriptor::PanWidth:
3120 c = r->pannable()->pan_width_control;
3124 case ControllableDescriptor::PanElevation:
3126 c = r->pannable()->pan_elevation_control;
3130 case ControllableDescriptor::Balance:
3131 /* XXX simple pan control */
3134 case ControllableDescriptor::PluginParameter:
3136 uint32_t plugin = desc.target (0);
3137 uint32_t parameter_index = desc.target (1);
3139 /* revert to zero based counting */
3145 if (parameter_index > 0) {
3149 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3152 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3153 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3158 case ControllableDescriptor::SendGain:
3160 uint32_t send = desc.target (0);
3162 /* revert to zero-based counting */
3168 boost::shared_ptr<Processor> p = r->nth_send (send);
3171 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3172 boost::shared_ptr<Amp> a = s->amp();
3175 c = s->amp()->gain_control();
3182 /* relax and return a null pointer */
3190 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3193 Stateful::add_instant_xml (node, _path);
3196 if (write_to_config) {
3197 Config->add_instant_xml (node);
3202 Session::instant_xml (const string& node_name)
3204 return Stateful::instant_xml (node_name, _path);
3208 Session::save_history (string snapshot_name)
3216 if (snapshot_name.empty()) {
3217 snapshot_name = _current_snapshot_name;
3220 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3221 const string backup_filename = history_filename + backup_suffix;
3222 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3223 const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3225 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3226 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3227 error << _("could not backup old history file, current history not saved") << endmsg;
3232 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3236 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3238 if (!tree.write (xml_path))
3240 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3242 if (g_remove (xml_path.c_str()) != 0) {
3243 error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3244 xml_path, g_strerror (errno)) << endmsg;
3246 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3247 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3248 backup_path, g_strerror (errno)) << endmsg;
3258 Session::restore_history (string snapshot_name)
3262 if (snapshot_name.empty()) {
3263 snapshot_name = _current_snapshot_name;
3266 const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3267 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3269 info << "Loading history from " << xml_path << endmsg;
3271 if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3272 info << string_compose (_("%1: no history file \"%2\" for this session."),
3273 _name, xml_path) << endmsg;
3277 if (!tree.read (xml_path)) {
3278 error << string_compose (_("Could not understand session history file \"%1\""),
3279 xml_path) << endmsg;
3286 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3289 UndoTransaction* ut = new UndoTransaction ();
3292 ut->set_name(t->property("name")->value());
3293 stringstream ss(t->property("tv-sec")->value());
3295 ss.str(t->property("tv-usec")->value());
3297 ut->set_timestamp(tv);
3299 for (XMLNodeConstIterator child_it = t->children().begin();
3300 child_it != t->children().end(); child_it++)
3302 XMLNode *n = *child_it;
3305 if (n->name() == "MementoCommand" ||
3306 n->name() == "MementoUndoCommand" ||
3307 n->name() == "MementoRedoCommand") {
3309 if ((c = memento_command_factory(n))) {
3313 } else if (n->name() == "NoteDiffCommand") {
3314 PBD::ID id (n->property("midi-source")->value());
3315 boost::shared_ptr<MidiSource> midi_source =
3316 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3318 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3320 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3323 } else if (n->name() == "SysExDiffCommand") {
3325 PBD::ID id (n->property("midi-source")->value());
3326 boost::shared_ptr<MidiSource> midi_source =
3327 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3329 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3331 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3334 } else if (n->name() == "PatchChangeDiffCommand") {
3336 PBD::ID id (n->property("midi-source")->value());
3337 boost::shared_ptr<MidiSource> midi_source =
3338 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3340 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3342 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3345 } else if (n->name() == "StatefulDiffCommand") {
3346 if ((c = stateful_diff_command_factory (n))) {
3347 ut->add_command (c);
3350 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3361 Session::config_changed (std::string p, bool ours)
3367 if (p == "seamless-loop") {
3369 } else if (p == "rf-speed") {
3371 } else if (p == "auto-loop") {
3373 } else if (p == "auto-input") {
3375 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3376 /* auto-input only makes a difference if we're rolling */
3377 set_track_monitor_input_status (!config.get_auto_input());
3380 } else if (p == "punch-in") {
3384 if ((location = _locations->auto_punch_location()) != 0) {
3386 if (config.get_punch_in ()) {
3387 replace_event (SessionEvent::PunchIn, location->start());
3389 remove_event (location->start(), SessionEvent::PunchIn);
3393 } else if (p == "punch-out") {
3397 if ((location = _locations->auto_punch_location()) != 0) {
3399 if (config.get_punch_out()) {
3400 replace_event (SessionEvent::PunchOut, location->end());
3402 clear_events (SessionEvent::PunchOut);
3406 } else if (p == "edit-mode") {
3408 Glib::Threads::Mutex::Lock lm (playlists->lock);
3410 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3411 (*i)->set_edit_mode (Config->get_edit_mode ());
3414 } else if (p == "use-video-sync") {
3416 waiting_for_sync_offset = config.get_use_video_sync();
3418 } else if (p == "mmc-control") {
3420 //poke_midi_thread ();
3422 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3424 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3426 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3428 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3430 } else if (p == "midi-control") {
3432 //poke_midi_thread ();
3434 } else if (p == "raid-path") {
3436 setup_raid_path (config.get_raid_path());
3438 } else if (p == "timecode-format") {
3442 } else if (p == "video-pullup") {
3446 } else if (p == "seamless-loop") {
3448 if (play_loop && transport_rolling()) {
3449 // to reset diskstreams etc
3450 request_play_loop (true);
3453 } else if (p == "rf-speed") {
3455 cumulative_rf_motion = 0;
3458 } else if (p == "click-sound") {
3460 setup_click_sounds (1);
3462 } else if (p == "click-emphasis-sound") {
3464 setup_click_sounds (-1);
3466 } else if (p == "clicking") {
3468 if (Config->get_clicking()) {
3469 if (_click_io && click_data) { // don't require emphasis data
3476 } else if (p == "click-gain") {
3479 _click_gain->set_gain (Config->get_click_gain(), this);
3482 } else if (p == "send-mtc") {
3484 if (Config->get_send_mtc ()) {
3485 /* mark us ready to send */
3486 next_quarter_frame_to_send = 0;
3489 } else if (p == "send-mmc") {
3491 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3493 } else if (p == "midi-feedback") {
3495 session_midi_feedback = Config->get_midi_feedback();
3497 } else if (p == "jack-time-master") {
3499 engine().reset_timebase ();
3501 } else if (p == "native-file-header-format") {
3503 if (!first_file_header_format_reset) {
3504 reset_native_file_format ();
3507 first_file_header_format_reset = false;
3509 } else if (p == "native-file-data-format") {
3511 if (!first_file_data_format_reset) {
3512 reset_native_file_format ();
3515 first_file_data_format_reset = false;
3517 } else if (p == "external-sync") {
3518 if (!config.get_external_sync()) {
3519 drop_sync_source ();
3521 switch_to_sync_source (Config->get_sync_source());
3523 } else if (p == "denormal-model") {
3525 } else if (p == "history-depth") {
3526 set_history_depth (Config->get_history_depth());
3527 } else if (p == "remote-model") {
3528 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3531 } else if (p == "sync-all-route-ordering") {
3533 /* sync to editor order unless mixer is used for remote IDs
3536 switch (Config->get_remote_model()) {
3538 sync_order_keys (EditorSort);
3541 sync_order_keys (EditorSort);
3544 sync_order_keys (MixerSort);
3547 } else if (p == "initial-program-change") {
3549 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3552 buf[0] = MIDI::program; // channel zero by default
3553 buf[1] = (Config->get_initial_program_change() & 0x7f);
3555 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3557 } else if (p == "solo-mute-override") {
3558 // catch_up_on_solo_mute_override ();
3559 } else if (p == "listen-position" || p == "pfl-position") {
3560 listen_position_changed ();
3561 } else if (p == "solo-control-is-listen-control") {
3562 solo_control_mode_changed ();
3563 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3564 last_timecode_valid = false;
3565 } else if (p == "playback-buffer-seconds") {
3566 AudioSource::allocate_working_buffers (frame_rate());
3567 } else if (p == "automation-thinning-factor") {
3568 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3569 } else if (p == "ltc-source-port") {
3570 reconnect_ltc_input ();
3571 } else if (p == "ltc-sink-port") {
3572 reconnect_ltc_output ();
3573 } else if (p == "timecode-generator-offset") {
3574 ltc_tx_parse_offset();
3581 Session::set_history_depth (uint32_t d)
3583 _history.set_depth (d);
3587 Session::load_diskstreams_2X (XMLNode const & node, int)
3590 XMLNodeConstIterator citer;
3592 clist = node.children();
3594 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3597 /* diskstreams added automatically by DiskstreamCreated handler */
3598 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3599 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3600 _diskstreams_2X.push_back (dsp);
3602 error << _("Session: unknown diskstream type in XML") << endmsg;
3606 catch (failed_constructor& err) {
3607 error << _("Session: could not load diskstream via XML state") << endmsg;
3615 /** Connect things to the MMC object */
3617 Session::setup_midi_machine_control ()
3619 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3621 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3622 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3623 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3624 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3625 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3626 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3627 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3628 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3629 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3630 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3631 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3632 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3633 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3635 /* also handle MIDI SPP because its so common */
3637 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3638 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3639 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3642 boost::shared_ptr<Controllable>
3643 Session::solo_cut_control() const
3645 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3646 controls in Ardour that currently get presented to the user in the GUI that require
3647 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3649 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3650 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3654 return _solo_cut_control;
3658 Session::rename (const std::string& new_name)
3660 string legal_name = legalize_for_path (new_name);
3666 string const old_sources_root = _session_dir->sources_root();
3668 #define RENAME ::rename
3673 * interchange subdirectory
3677 * Backup files are left unchanged and not renamed.
3680 /* pass one: not 100% safe check that the new directory names don't
3684 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3689 /* this is a stupid hack because Glib::path_get_dirname() is
3690 * lexical-only, and so passing it /a/b/c/ gives a different
3691 * result than passing it /a/b/c ...
3694 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3695 oldstr = oldstr.substr (0, oldstr.length() - 1);
3698 string base = Glib::path_get_dirname (oldstr);
3699 string p = Glib::path_get_basename (oldstr);
3701 newstr = Glib::build_filename (base, legal_name);
3703 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3710 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3715 /* this is a stupid hack because Glib::path_get_dirname() is
3716 * lexical-only, and so passing it /a/b/c/ gives a different
3717 * result than passing it /a/b/c ...
3720 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3721 oldstr = oldstr.substr (0, oldstr.length() - 1);
3724 string base = Glib::path_get_dirname (oldstr);
3725 string p = Glib::path_get_basename (oldstr);
3727 newstr = Glib::build_filename (base, legal_name);
3729 cerr << "Rename " << oldstr << " => " << newstr << endl;
3731 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3736 (*_session_dir) = newstr;
3741 /* directory below interchange */
3743 v.push_back (newstr);
3744 v.push_back (interchange_dir_name);
3747 oldstr = Glib::build_filename (v);
3750 v.push_back (newstr);
3751 v.push_back (interchange_dir_name);
3752 v.push_back (legal_name);
3754 newstr = Glib::build_filename (v);
3756 cerr << "Rename " << oldstr << " => " << newstr << endl;
3758 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3765 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3766 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3768 cerr << "Rename " << oldstr << " => " << newstr << endl;
3770 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3777 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3779 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3780 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3782 cerr << "Rename " << oldstr << " => " << newstr << endl;
3784 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3789 /* update file source paths */
3791 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3792 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3794 string p = fs->path ();
3795 boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3800 /* remove old name from recent sessions */
3802 remove_recent_sessions (_path);
3805 _current_snapshot_name = new_name;
3810 /* save state again to get everything just right */
3812 save_state (_current_snapshot_name);
3815 /* add to recent sessions */
3817 store_recent_sessions (new_name, _path);