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/thread.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 (%s)"), 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 destructive_index = 0;
210 first_file_data_format_reset = true;
211 first_file_header_format_reset = true;
212 post_export_sync = false;
215 no_questions_about_missing_files = false;
216 _speakers.reset (new Speakers);
218 ignore_route_processor_changes = false;
219 _pre_export_mmc_enabled = false;
221 AudioDiskstream::allocate_working_buffers();
223 /* default short fade = 15ms */
225 SndFileSource::setup_standard_crossfades (*this, frame_rate());
227 last_mmc_step.tv_sec = 0;
228 last_mmc_step.tv_usec = 0;
231 /* click sounds are unset by default, which causes us to internal
232 waveforms for clicks.
236 click_emphasis_length = 0;
239 process_function = &Session::process_with_events;
241 if (config.get_use_video_sync()) {
242 waiting_for_sync_offset = true;
244 waiting_for_sync_offset = false;
247 last_timecode_when = 0;
248 last_timecode_valid = false;
252 last_rr_session_dir = session_dirs.begin();
253 refresh_disk_space ();
255 /* default: assume simple stereo speaker configuration */
257 _speakers->setup_default_speakers (2);
261 average_slave_delta = 1800; // !!! why 1800 ????
262 have_first_delta_accumulator = false;
263 delta_accumulator_cnt = 0;
264 _slave_state = Stopped;
266 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
267 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
268 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
269 add_controllable (_solo_cut_control);
271 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
273 /* These are all static "per-class" signals */
275 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
276 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
277 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
278 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
279 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
281 /* stop IO objects from doing stuff until we're ready for them */
283 Delivery::disable_panners ();
284 IO::disable_connecting ();
288 Session::second_stage_init ()
290 AudioFileSource::set_peak_dir (_session_dir->peak_path());
293 if (load_state (_current_snapshot_name)) {
298 if (_butler->start_thread()) {
302 if (start_midi_thread ()) {
306 setup_midi_machine_control ();
308 // set_state() will call setup_raid_path(), but if it's a new session we need
309 // to call setup_raid_path() here.
312 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
316 setup_raid_path(_path);
319 /* we can't save till after ::when_engine_running() is called,
320 because otherwise we save state with no connections made.
321 therefore, we reset _state_of_the_state because ::set_state()
322 will have cleared it.
324 we also have to include Loading so that any events that get
325 generated between here and the end of ::when_engine_running()
326 will be processed directly rather than queued.
329 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
331 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
332 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
333 setup_click_sounds (0);
334 setup_midi_control ();
336 /* Pay attention ... */
338 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
339 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
341 midi_clock = new MidiClockTicker ();
342 midi_clock->set_session (this);
345 when_engine_running ();
348 /* handle this one in a different way than all others, so that its clear what happened */
350 catch (AudioEngine::PortRegistrationFailure& err) {
351 error << err.what() << endmsg;
359 BootMessage (_("Reset Remote Controls"));
361 send_full_time_code (0);
362 _engine.transport_locate (0);
364 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
365 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
367 MIDI::Name::MidiPatchManager::instance().set_session (this);
369 /* initial program change will be delivered later; see ::config_changed() */
371 _state_of_the_state = Clean;
373 Port::set_connecting_blocked (false);
375 DirtyChanged (); /* EMIT SIGNAL */
377 if (state_was_pending) {
378 save_state (_current_snapshot_name);
379 remove_pending_capture_state ();
380 state_was_pending = false;
383 BootMessage (_("Session loading complete"));
389 Session::raid_path () const
391 SearchPath raid_search_path;
393 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
394 raid_search_path += (*i).path;
397 return raid_search_path.to_string ();
401 Session::setup_raid_path (string path)
410 session_dirs.clear ();
412 SearchPath search_path(path);
413 SearchPath sound_search_path;
414 SearchPath midi_search_path;
416 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
418 sp.blocks = 0; // not needed
419 session_dirs.push_back (sp);
421 SessionDirectory sdir(sp.path);
423 sound_search_path += sdir.sound_path ();
424 midi_search_path += sdir.midi_path ();
427 // reset the round-robin soundfile path thingie
428 last_rr_session_dir = session_dirs.begin();
432 Session::path_is_within_session (const std::string& path)
434 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
435 if (PBD::path_is_within (i->path, path)) {
443 Session::ensure_subdirs ()
447 dir = session_directory().peak_path();
449 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
450 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
454 dir = session_directory().sound_path();
456 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
457 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
461 dir = session_directory().midi_path();
463 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
464 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
468 dir = session_directory().dead_path();
470 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
471 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
475 dir = session_directory().export_path();
477 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
478 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
482 dir = analysis_dir ();
484 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
485 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
489 dir = plugins_dir ();
491 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
492 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
496 dir = externals_dir ();
498 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
499 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
506 /** @param session_template directory containing session template, or empty.
507 * Caller must not hold process lock.
510 Session::create (const string& session_template, BusProfile* bus_profile)
512 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
513 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
517 if (ensure_subdirs ()) {
521 _writable = exists_and_writable (_path);
523 if (!session_template.empty()) {
524 std::string in_path = session_template_dir_to_file (session_template);
526 ifstream in(in_path.c_str());
529 string out_path = _path;
531 out_path += statefile_suffix;
533 ofstream out(out_path.c_str());
539 /* Copy plugin state files from template to new session */
540 std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
541 copy_files (template_plugins, plugins_dir ());
546 error << string_compose (_("Could not open %1 for writing session template"), out_path)
552 error << string_compose (_("Could not open session template %1 for reading"), in_path)
559 /* set initial start + end point */
561 _state_of_the_state = Clean;
563 /* set up Master Out and Control Out if necessary */
568 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
570 if (bus_profile->master_out_channels) {
571 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
575 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
576 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
579 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
580 r->input()->ensure_io (count, false, this);
581 r->output()->ensure_io (count, false, this);
587 /* prohibit auto-connect to master, because there isn't one */
588 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
592 add_routes (rl, false, false, false);
595 /* this allows the user to override settings with an environment variable.
598 if (no_auto_connect()) {
599 bus_profile->input_ac = AutoConnectOption (0);
600 bus_profile->output_ac = AutoConnectOption (0);
603 Config->set_input_auto_connect (bus_profile->input_ac);
604 Config->set_output_auto_connect (bus_profile->output_ac);
607 if (Config->get_use_monitor_bus() && bus_profile) {
608 add_monitor_section ();
617 Session::maybe_write_autosave()
619 if (dirty() && record_status() != Recording) {
620 save_state("", true);
625 Session::remove_pending_capture_state ()
627 std::string pending_state_file_path(_session_dir->root_path());
629 pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
631 if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
633 if (g_remove (pending_state_file_path.c_str()) != 0) {
634 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
635 pending_state_file_path, g_strerror (errno)) << endmsg;
639 /** Rename a state file.
640 * @param old_name Old snapshot name.
641 * @param new_name New snapshot name.
644 Session::rename_state (string old_name, string new_name)
646 if (old_name == _current_snapshot_name || old_name == _name) {
647 /* refuse to rename the current snapshot or the "main" one */
651 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
652 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
654 const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
655 const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
657 if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
658 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
659 old_name, new_name, g_strerror(errno)) << endmsg;
663 /** Remove a state file.
664 * @param snapshot_name Snapshot name.
667 Session::remove_state (string snapshot_name)
669 if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
670 // refuse to remove the current snapshot or the "main" one
674 std::string xml_path(_session_dir->root_path());
676 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
678 if (!create_backup_file (xml_path)) {
679 // don't remove it if a backup can't be made
680 // create_backup_file will log the error.
685 if (g_remove (xml_path.c_str()) != 0) {
686 error << string_compose(_("Could not remove state file at path \"%1\" (%2)"),
687 xml_path, g_strerror (errno)) << endmsg;
691 #ifdef HAVE_JACK_SESSION
693 Session::jack_session_event (jack_session_event_t * event)
697 struct tm local_time;
700 localtime_r (&n, &local_time);
701 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
703 if (event->type == JackSessionSaveTemplate)
705 if (save_template( timebuf )) {
706 event->flags = JackSessionSaveError;
708 string cmd ("ardour3 -P -U ");
709 cmd += event->client_uuid;
713 event->command_line = strdup (cmd.c_str());
718 if (save_state (timebuf)) {
719 event->flags = JackSessionSaveError;
721 std::string xml_path (_session_dir->root_path());
722 std::string legalized_filename = legalize_for_path (timebuf) + statefile_suffix;
723 xml_path = Glib::build_filename (xml_path, legalized_filename);
725 string cmd ("ardour3 -P -U ");
726 cmd += event->client_uuid;
731 event->command_line = strdup (cmd.c_str());
735 jack_session_reply (_engine.jack(), event);
737 if (event->type == JackSessionSaveAndQuit) {
738 Quit (); /* EMIT SIGNAL */
741 jack_session_event_free( event );
745 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
747 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
750 std::string xml_path(_session_dir->root_path());
752 if (!_writable || (_state_of_the_state & CannotSave)) {
756 if (!_engine.connected ()) {
757 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
763 /* tell sources we're saving first, in case they write out to a new file
764 * which should be saved with the state rather than the old one */
765 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
767 i->second->session_saved();
768 } catch (Evoral::SMF::FileError& e) {
769 error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
773 tree.set_root (&get_state());
775 if (snapshot_name.empty()) {
776 snapshot_name = _current_snapshot_name;
777 } else if (switch_to_snapshot) {
778 _current_snapshot_name = snapshot_name;
783 /* proper save: use statefile_suffix (.ardour in English) */
785 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
787 /* make a backup copy of the old file */
789 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
790 // create_backup_file will log the error
796 /* pending save: use pending_suffix (.pending in English) */
797 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
800 std::string tmp_path(_session_dir->root_path());
801 tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
803 // cerr << "actually writing state to " << xml_path << endl;
805 if (!tree.write (tmp_path)) {
806 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
807 if (g_remove (tmp_path.c_str()) != 0) {
808 error << string_compose(_("Could not remove temporary state file at path \"%1\" (%2)"),
809 tmp_path, g_strerror (errno)) << endmsg;
815 if (::rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
816 error << string_compose (_("could not rename temporary session file %1 to %2"),
817 tmp_path, xml_path) << endmsg;
818 if (g_remove (tmp_path.c_str()) != 0) {
819 error << string_compose(_("Could not remove temporary state file at path \"%1\" (%2)"),
820 tmp_path, g_strerror (errno)) << endmsg;
828 save_history (snapshot_name);
830 bool was_dirty = dirty();
832 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
835 DirtyChanged (); /* EMIT SIGNAL */
838 StateSaved (snapshot_name); /* EMIT SIGNAL */
845 Session::restore_state (string snapshot_name)
847 if (load_state (snapshot_name) == 0) {
848 set_state (*state_tree->root(), Stateful::loading_state_version);
855 Session::load_state (string snapshot_name)
860 state_was_pending = false;
862 /* check for leftover pending state from a crashed capture attempt */
864 std::string xmlpath(_session_dir->root_path());
865 xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
867 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
869 /* there is pending state from a crashed capture attempt */
871 boost::optional<int> r = AskAboutPendingState();
872 if (r.get_value_or (1)) {
873 state_was_pending = true;
877 if (!state_was_pending) {
878 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
881 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
882 xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
883 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
884 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
889 state_tree = new XMLTree;
893 _writable = exists_and_writable (xmlpath);
895 if (!state_tree->read (xmlpath)) {
896 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
902 XMLNode& root (*state_tree->root());
904 if (root.name() != X_("Session")) {
905 error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
911 const XMLProperty* prop;
913 if ((prop = root.property ("version")) == 0) {
914 /* no version implies very old version of Ardour */
915 Stateful::loading_state_version = 1000;
917 if (prop->value().find ('.') != string::npos) {
918 /* old school version format */
919 if (prop->value()[0] == '2') {
920 Stateful::loading_state_version = 2000;
922 Stateful::loading_state_version = 3000;
925 Stateful::loading_state_version = atoi (prop->value());
929 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
931 std::string backup_path(_session_dir->root_path());
932 std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
933 backup_path = Glib::build_filename (backup_path, backup_filename);
935 // only create a backup for a given statefile version once
937 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
939 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
940 xmlpath, backup_path, PROGRAM_NAME)
943 if (!copy_file (xmlpath, backup_path)) {;
953 Session::load_options (const XMLNode& node)
955 LocaleGuard lg (X_("POSIX"));
956 config.set_variables (node);
967 Session::get_template()
969 /* if we don't disable rec-enable, diskstreams
970 will believe they need to store their capture
971 sources in their state node.
974 disable_record (false);
980 Session::state (bool full_state)
982 XMLNode* node = new XMLNode("Session");
986 snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
987 node->add_property("version", buf);
989 /* store configuration settings */
993 node->add_property ("name", _name);
994 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
995 node->add_property ("sample-rate", buf);
997 if (session_dirs.size() > 1) {
1001 vector<space_and_path>::iterator i = session_dirs.begin();
1002 vector<space_and_path>::iterator next;
1004 ++i; /* skip the first one */
1008 while (i != session_dirs.end()) {
1012 if (next != session_dirs.end()) {
1022 child = node->add_child ("Path");
1023 child->add_content (p);
1027 /* save the ID counter */
1029 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1030 node->add_property ("id-counter", buf);
1032 /* save the event ID counter */
1034 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1035 node->add_property ("event-counter", buf);
1037 /* various options */
1039 node->add_child_nocopy (config.get_variables ());
1041 node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1043 child = node->add_child ("Sources");
1046 Glib::Mutex::Lock sl (source_lock);
1048 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1050 /* Don't save information about non-file Sources, or
1051 * about non-destructive file sources that are empty
1052 * and unused by any regions.
1055 boost::shared_ptr<FileSource> fs;
1057 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1059 if (!fs->destructive()) {
1060 if (fs->empty() && !fs->used()) {
1065 child->add_child_nocopy (siter->second->get_state());
1070 child = node->add_child ("Regions");
1073 Glib::Mutex::Lock rl (region_lock);
1074 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1075 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1076 boost::shared_ptr<Region> r = i->second;
1077 /* only store regions not attached to playlists */
1078 if (r->playlist() == 0) {
1079 child->add_child_nocopy (r->state ());
1083 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1085 if (!cassocs.empty()) {
1086 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1088 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1090 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1091 i->first->id().print (buf, sizeof (buf));
1092 can->add_property (X_("copy"), buf);
1093 i->second->id().print (buf, sizeof (buf));
1094 can->add_property (X_("original"), buf);
1095 ca->add_child_nocopy (*can);
1101 node->add_child_nocopy (_locations->get_state());
1103 // for a template, just create a new Locations, populate it
1104 // with the default start and end, and get the state for that.
1105 Locations loc (*this);
1106 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1107 range->set (max_framepos, 0);
1109 node->add_child_nocopy (loc.get_state());
1112 child = node->add_child ("Bundles");
1114 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1115 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1116 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1118 child->add_child_nocopy (b->get_state());
1123 child = node->add_child ("Routes");
1125 boost::shared_ptr<RouteList> r = routes.reader ();
1127 RoutePublicOrderSorter cmp;
1128 RouteList public_order (*r);
1129 public_order.sort (cmp);
1131 /* the sort should have put control outs first */
1134 assert (_monitor_out == public_order.front());
1137 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1138 if (!(*i)->is_hidden()) {
1140 child->add_child_nocopy ((*i)->get_state());
1142 child->add_child_nocopy ((*i)->get_template());
1148 playlists->add_state (node, full_state);
1150 child = node->add_child ("RouteGroups");
1151 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1152 child->add_child_nocopy ((*i)->get_state());
1156 XMLNode* gain_child = node->add_child ("Click");
1157 gain_child->add_child_nocopy (_click_io->state (full_state));
1158 gain_child->add_child_nocopy (_click_gain->state (full_state));
1161 node->add_child_nocopy (_speakers->get_state());
1162 node->add_child_nocopy (_tempo_map->get_state());
1163 node->add_child_nocopy (get_control_protocol_state());
1166 node->add_child_copy (*_extra_xml);
1173 Session::get_control_protocol_state ()
1175 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1176 return cpm.get_state();
1180 Session::set_state (const XMLNode& node, int version)
1184 const XMLProperty* prop;
1187 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1189 if (node.name() != X_("Session")) {
1190 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1194 if ((prop = node.property ("name")) != 0) {
1195 _name = prop->value ();
1198 if ((prop = node.property (X_("sample-rate"))) != 0) {
1200 _nominal_frame_rate = atoi (prop->value());
1202 if (_nominal_frame_rate != _current_frame_rate) {
1203 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1204 if (r.get_value_or (0)) {
1210 setup_raid_path(_session_dir->root_path());
1212 if ((prop = node.property (X_("id-counter"))) != 0) {
1214 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1215 ID::init_counter (x);
1217 /* old sessions used a timebased counter, so fake
1218 the startup ID counter based on a standard
1223 ID::init_counter (now);
1226 if ((prop = node.property (X_("event-counter"))) != 0) {
1227 Evoral::init_event_id_counter (atoi (prop->value()));
1230 IO::disable_connecting ();
1232 Stateful::save_extra_xml (node);
1234 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1235 load_options (*child);
1236 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1237 load_options (*child);
1239 error << _("Session: XML state has no options section") << endmsg;
1242 if (version >= 3000) {
1243 if ((child = find_named_node (node, "Metadata")) == 0) {
1244 warning << _("Session: XML state has no metadata section") << endmsg;
1245 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1250 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1251 _speakers->set_state (*child, version);
1254 if ((child = find_named_node (node, "Sources")) == 0) {
1255 error << _("Session: XML state has no sources section") << endmsg;
1257 } else if (load_sources (*child)) {
1261 if ((child = find_named_node (node, "TempoMap")) == 0) {
1262 error << _("Session: XML state has no Tempo Map section") << endmsg;
1264 } else if (_tempo_map->set_state (*child, version)) {
1268 if ((child = find_named_node (node, "Locations")) == 0) {
1269 error << _("Session: XML state has no locations section") << endmsg;
1271 } else if (_locations->set_state (*child, version)) {
1277 if ((location = _locations->auto_loop_location()) != 0) {
1278 set_auto_loop_location (location);
1281 if ((location = _locations->auto_punch_location()) != 0) {
1282 set_auto_punch_location (location);
1285 if ((location = _locations->session_range_location()) != 0) {
1286 delete _session_range_location;
1287 _session_range_location = location;
1290 if (_session_range_location) {
1291 AudioFileSource::set_header_position_offset (_session_range_location->start());
1294 if ((child = find_named_node (node, "Regions")) == 0) {
1295 error << _("Session: XML state has no Regions section") << endmsg;
1297 } else if (load_regions (*child)) {
1301 if ((child = find_named_node (node, "Playlists")) == 0) {
1302 error << _("Session: XML state has no playlists section") << endmsg;
1304 } else if (playlists->load (*this, *child)) {
1308 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1310 } else if (playlists->load_unused (*this, *child)) {
1314 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1315 if (load_compounds (*child)) {
1320 if (version >= 3000) {
1321 if ((child = find_named_node (node, "Bundles")) == 0) {
1322 warning << _("Session: XML state has no bundles section") << endmsg;
1325 /* We can't load Bundles yet as they need to be able
1326 to convert from port names to Port objects, which can't happen until
1328 _bundle_xml_node = new XMLNode (*child);
1332 if (version < 3000) {
1333 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1334 error << _("Session: XML state has no diskstreams section") << endmsg;
1336 } else if (load_diskstreams_2X (*child, version)) {
1341 if ((child = find_named_node (node, "Routes")) == 0) {
1342 error << _("Session: XML state has no routes section") << endmsg;
1344 } else if (load_routes (*child, version)) {
1348 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1349 _diskstreams_2X.clear ();
1351 if (version >= 3000) {
1353 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1354 error << _("Session: XML state has no route groups section") << endmsg;
1356 } else if (load_route_groups (*child, version)) {
1360 } else if (version < 3000) {
1362 if ((child = find_named_node (node, "EditGroups")) == 0) {
1363 error << _("Session: XML state has no edit groups section") << endmsg;
1365 } else if (load_route_groups (*child, version)) {
1369 if ((child = find_named_node (node, "MixGroups")) == 0) {
1370 error << _("Session: XML state has no mix groups section") << endmsg;
1372 } else if (load_route_groups (*child, version)) {
1377 if ((child = find_named_node (node, "Click")) == 0) {
1378 warning << _("Session: XML state has no click section") << endmsg;
1379 } else if (_click_io) {
1380 const XMLNodeList& children (child->children());
1381 XMLNodeList::const_iterator i = children.begin();
1382 _click_io->set_state (**i, version);
1384 if (i != children.end()) {
1385 _click_gain->set_state (**i, version);
1389 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1390 ControlProtocolManager::instance().set_protocol_states (*child);
1393 update_have_rec_enabled_track ();
1395 /* here beginneth the second phase ... */
1397 StateReady (); /* EMIT SIGNAL */
1406 Session::load_routes (const XMLNode& node, int version)
1409 XMLNodeConstIterator niter;
1410 RouteList new_routes;
1412 nlist = node.children();
1416 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1418 boost::shared_ptr<Route> route;
1419 if (version < 3000) {
1420 route = XMLRouteFactory_2X (**niter, version);
1422 route = XMLRouteFactory (**niter, version);
1426 error << _("Session: cannot create Route from XML description.") << endmsg;
1430 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1432 new_routes.push_back (route);
1435 add_routes (new_routes, false, false, false);
1440 boost::shared_ptr<Route>
1441 Session::XMLRouteFactory (const XMLNode& node, int version)
1443 boost::shared_ptr<Route> ret;
1445 if (node.name() != "Route") {
1449 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1451 DataType type = DataType::AUDIO;
1452 const XMLProperty* prop = node.property("default-type");
1455 type = DataType (prop->value());
1458 assert (type != DataType::NIL);
1462 boost::shared_ptr<Track> track;
1464 if (type == DataType::AUDIO) {
1465 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1467 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1470 if (track->init()) {
1474 if (track->set_state (node, version)) {
1478 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1479 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1484 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1486 if (r->init () == 0 && r->set_state (node, version) == 0) {
1487 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1488 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1497 boost::shared_ptr<Route>
1498 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1500 boost::shared_ptr<Route> ret;
1502 if (node.name() != "Route") {
1506 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1508 ds_prop = node.property (X_("diskstream"));
1511 DataType type = DataType::AUDIO;
1512 const XMLProperty* prop = node.property("default-type");
1515 type = DataType (prop->value());
1518 assert (type != DataType::NIL);
1522 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1523 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1527 if (i == _diskstreams_2X.end()) {
1528 error << _("Could not find diskstream for route") << endmsg;
1529 return boost::shared_ptr<Route> ();
1532 boost::shared_ptr<Track> track;
1534 if (type == DataType::AUDIO) {
1535 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1537 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1540 if (track->init()) {
1544 if (track->set_state (node, version)) {
1548 track->set_diskstream (*i);
1550 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1551 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1556 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1558 if (r->init () == 0 && r->set_state (node, version) == 0) {
1559 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1560 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1570 Session::load_regions (const XMLNode& node)
1573 XMLNodeConstIterator niter;
1574 boost::shared_ptr<Region> region;
1576 nlist = node.children();
1580 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1581 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1582 error << _("Session: cannot create Region from XML description.");
1583 const XMLProperty *name = (**niter).property("name");
1586 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1597 Session::load_compounds (const XMLNode& node)
1599 XMLNodeList calist = node.children();
1600 XMLNodeConstIterator caiter;
1601 XMLProperty *caprop;
1603 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1604 XMLNode* ca = *caiter;
1608 if ((caprop = ca->property (X_("original"))) == 0) {
1611 orig_id = caprop->value();
1613 if ((caprop = ca->property (X_("copy"))) == 0) {
1616 copy_id = caprop->value();
1618 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1619 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1621 if (!orig || !copy) {
1622 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1628 RegionFactory::add_compound_association (orig, copy);
1635 Session::load_nested_sources (const XMLNode& node)
1638 XMLNodeConstIterator niter;
1640 nlist = node.children();
1642 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1643 if ((*niter)->name() == "Source") {
1645 /* it may already exist, so don't recreate it unnecessarily
1648 XMLProperty* prop = (*niter)->property (X_("id"));
1650 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1654 ID source_id (prop->value());
1656 if (!source_by_id (source_id)) {
1659 SourceFactory::create (*this, **niter, true);
1661 catch (failed_constructor& err) {
1662 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1669 boost::shared_ptr<Region>
1670 Session::XMLRegionFactory (const XMLNode& node, bool full)
1672 const XMLProperty* type = node.property("type");
1676 const XMLNodeList& nlist = node.children();
1678 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1679 XMLNode *child = (*niter);
1680 if (child->name() == "NestedSource") {
1681 load_nested_sources (*child);
1685 if (!type || type->value() == "audio") {
1686 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1687 } else if (type->value() == "midi") {
1688 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1691 } catch (failed_constructor& err) {
1692 return boost::shared_ptr<Region> ();
1695 return boost::shared_ptr<Region> ();
1698 boost::shared_ptr<AudioRegion>
1699 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1701 const XMLProperty* prop;
1702 boost::shared_ptr<Source> source;
1703 boost::shared_ptr<AudioSource> as;
1705 SourceList master_sources;
1706 uint32_t nchans = 1;
1709 if (node.name() != X_("Region")) {
1710 return boost::shared_ptr<AudioRegion>();
1713 if ((prop = node.property (X_("channels"))) != 0) {
1714 nchans = atoi (prop->value().c_str());
1717 if ((prop = node.property ("name")) == 0) {
1718 cerr << "no name for this region\n";
1722 if ((prop = node.property (X_("source-0"))) == 0) {
1723 if ((prop = node.property ("source")) == 0) {
1724 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1725 return boost::shared_ptr<AudioRegion>();
1729 PBD::ID s_id (prop->value());
1731 if ((source = source_by_id (s_id)) == 0) {
1732 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1733 return boost::shared_ptr<AudioRegion>();
1736 as = boost::dynamic_pointer_cast<AudioSource>(source);
1738 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1739 return boost::shared_ptr<AudioRegion>();
1742 sources.push_back (as);
1744 /* pickup other channels */
1746 for (uint32_t n=1; n < nchans; ++n) {
1747 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1748 if ((prop = node.property (buf)) != 0) {
1750 PBD::ID id2 (prop->value());
1752 if ((source = source_by_id (id2)) == 0) {
1753 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1754 return boost::shared_ptr<AudioRegion>();
1757 as = boost::dynamic_pointer_cast<AudioSource>(source);
1759 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1760 return boost::shared_ptr<AudioRegion>();
1762 sources.push_back (as);
1766 for (uint32_t n = 0; n < nchans; ++n) {
1767 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1768 if ((prop = node.property (buf)) != 0) {
1770 PBD::ID id2 (prop->value());
1772 if ((source = source_by_id (id2)) == 0) {
1773 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1774 return boost::shared_ptr<AudioRegion>();
1777 as = boost::dynamic_pointer_cast<AudioSource>(source);
1779 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1780 return boost::shared_ptr<AudioRegion>();
1782 master_sources.push_back (as);
1787 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1789 /* a final detail: this is the one and only place that we know how long missing files are */
1791 if (region->whole_file()) {
1792 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1793 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1795 sfp->set_length (region->length());
1800 if (!master_sources.empty()) {
1801 if (master_sources.size() != nchans) {
1802 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1804 region->set_master_sources (master_sources);
1812 catch (failed_constructor& err) {
1813 return boost::shared_ptr<AudioRegion>();
1817 boost::shared_ptr<MidiRegion>
1818 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1820 const XMLProperty* prop;
1821 boost::shared_ptr<Source> source;
1822 boost::shared_ptr<MidiSource> ms;
1825 if (node.name() != X_("Region")) {
1826 return boost::shared_ptr<MidiRegion>();
1829 if ((prop = node.property ("name")) == 0) {
1830 cerr << "no name for this region\n";
1834 if ((prop = node.property (X_("source-0"))) == 0) {
1835 if ((prop = node.property ("source")) == 0) {
1836 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1837 return boost::shared_ptr<MidiRegion>();
1841 PBD::ID s_id (prop->value());
1843 if ((source = source_by_id (s_id)) == 0) {
1844 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1845 return boost::shared_ptr<MidiRegion>();
1848 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1850 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1851 return boost::shared_ptr<MidiRegion>();
1854 sources.push_back (ms);
1857 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1858 /* a final detail: this is the one and only place that we know how long missing files are */
1860 if (region->whole_file()) {
1861 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1862 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1864 sfp->set_length (region->length());
1872 catch (failed_constructor& err) {
1873 return boost::shared_ptr<MidiRegion>();
1878 Session::get_sources_as_xml ()
1881 XMLNode* node = new XMLNode (X_("Sources"));
1882 Glib::Mutex::Lock lm (source_lock);
1884 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1885 node->add_child_nocopy (i->second->get_state());
1892 Session::path_from_region_name (DataType type, string name, string identifier)
1894 char buf[PATH_MAX+1];
1896 SessionDirectory sdir(get_best_session_directory_for_new_source());
1897 std::string source_dir = ((type == DataType::AUDIO)
1898 ? sdir.sound_path() : sdir.midi_path());
1900 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1902 for (n = 0; n < 999999; ++n) {
1903 if (identifier.length()) {
1904 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1905 identifier.c_str(), n, ext.c_str());
1907 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1911 std::string source_path = Glib::build_filename (source_dir, buf);
1913 if (!Glib::file_test (source_path, Glib::FILE_TEST_EXISTS)) {
1918 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1927 Session::load_sources (const XMLNode& node)
1930 XMLNodeConstIterator niter;
1931 boost::shared_ptr<Source> source;
1933 nlist = node.children();
1937 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1940 if ((source = XMLSourceFactory (**niter)) == 0) {
1941 error << _("Session: cannot create Source from XML description.") << endmsg;
1944 } catch (MissingSource& err) {
1948 if (!no_questions_about_missing_files) {
1949 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1954 switch (user_choice) {
1956 /* user added a new search location, so try again */
1961 /* user asked to quit the entire session load
1966 no_questions_about_missing_files = true;
1970 no_questions_about_missing_files = true;
1975 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1976 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1985 boost::shared_ptr<Source>
1986 Session::XMLSourceFactory (const XMLNode& node)
1988 if (node.name() != "Source") {
1989 return boost::shared_ptr<Source>();
1993 /* note: do peak building in another thread when loading session state */
1994 return SourceFactory::create (*this, node, true);
1997 catch (failed_constructor& err) {
1998 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1999 return boost::shared_ptr<Source>();
2004 Session::save_template (string template_name)
2008 if (_state_of_the_state & CannotSave) {
2012 std::string user_template_dir(user_template_directory());
2014 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
2015 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2016 user_template_dir, g_strerror (errno)) << endmsg;
2020 tree.set_root (&get_template());
2022 std::string template_dir_path(user_template_dir);
2024 /* directory to put the template in */
2025 template_dir_path = Glib::build_filename (template_dir_path, template_name);
2027 if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
2028 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2029 template_dir_path) << endmsg;
2033 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
2034 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
2035 template_dir_path, g_strerror (errno)) << endmsg;
2040 std::string template_file_path(template_dir_path);
2041 template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
2043 if (!tree.write (template_file_path)) {
2044 error << _("template not saved") << endmsg;
2048 /* copy plugin state directory */
2050 std::string template_plugin_state_path(template_dir_path);
2051 template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
2053 if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
2054 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
2055 template_plugin_state_path, g_strerror (errno)) << endmsg;
2059 copy_files (plugins_dir(), template_plugin_state_path);
2065 Session::refresh_disk_space ()
2067 #if HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H
2069 Glib::Mutex::Lock lm (space_lock);
2071 /* get freespace on every FS that is part of the session path */
2073 _total_free_4k_blocks = 0;
2074 _total_free_4k_blocks_uncertain = false;
2076 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2078 struct statfs statfsbuf;
2079 statfs (i->path.c_str(), &statfsbuf);
2081 double const scale = statfsbuf.f_bsize / 4096.0;
2083 /* See if this filesystem is read-only */
2084 struct statvfs statvfsbuf;
2085 statvfs (i->path.c_str(), &statvfsbuf);
2087 /* f_bavail can be 0 if it is undefined for whatever
2088 filesystem we are looking at; Samba shares mounted
2089 via GVFS are an example of this.
2091 if (statfsbuf.f_bavail == 0) {
2092 /* block count unknown */
2094 i->blocks_unknown = true;
2095 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2096 /* read-only filesystem */
2098 i->blocks_unknown = false;
2100 /* read/write filesystem with known space */
2101 i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2102 i->blocks_unknown = false;
2105 _total_free_4k_blocks += i->blocks;
2106 if (i->blocks_unknown) {
2107 _total_free_4k_blocks_uncertain = true;
2114 Session::get_best_session_directory_for_new_source ()
2116 vector<space_and_path>::iterator i;
2117 string result = _session_dir->root_path();
2119 /* handle common case without system calls */
2121 if (session_dirs.size() == 1) {
2125 /* OK, here's the algorithm we're following here:
2127 We want to select which directory to use for
2128 the next file source to be created. Ideally,
2129 we'd like to use a round-robin process so as to
2130 get maximum performance benefits from splitting
2131 the files across multiple disks.
2133 However, in situations without much diskspace, an
2134 RR approach may end up filling up a filesystem
2135 with new files while others still have space.
2136 Its therefore important to pay some attention to
2137 the freespace in the filesystem holding each
2138 directory as well. However, if we did that by
2139 itself, we'd keep creating new files in the file
2140 system with the most space until it was as full
2141 as all others, thus negating any performance
2142 benefits of this RAID-1 like approach.
2144 So, we use a user-configurable space threshold. If
2145 there are at least 2 filesystems with more than this
2146 much space available, we use RR selection between them.
2147 If not, then we pick the filesystem with the most space.
2149 This gets a good balance between the two
2153 refresh_disk_space ();
2155 int free_enough = 0;
2157 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2158 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2163 if (free_enough >= 2) {
2164 /* use RR selection process, ensuring that the one
2168 i = last_rr_session_dir;
2171 if (++i == session_dirs.end()) {
2172 i = session_dirs.begin();
2175 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2176 SessionDirectory sdir(i->path);
2177 if (sdir.create ()) {
2179 last_rr_session_dir = i;
2184 } while (i != last_rr_session_dir);
2188 /* pick FS with the most freespace (and that
2189 seems to actually work ...)
2192 vector<space_and_path> sorted;
2193 space_and_path_ascending_cmp cmp;
2195 sorted = session_dirs;
2196 sort (sorted.begin(), sorted.end(), cmp);
2198 for (i = sorted.begin(); i != sorted.end(); ++i) {
2199 SessionDirectory sdir(i->path);
2200 if (sdir.create ()) {
2202 last_rr_session_dir = i;
2212 Session::automation_dir () const
2214 return Glib::build_filename (_path, "automation");
2218 Session::analysis_dir () const
2220 return Glib::build_filename (_path, "analysis");
2224 Session::plugins_dir () const
2226 return Glib::build_filename (_path, "plugins");
2230 Session::externals_dir () const
2232 return Glib::build_filename (_path, "externals");
2236 Session::load_bundles (XMLNode const & node)
2238 XMLNodeList nlist = node.children();
2239 XMLNodeConstIterator niter;
2243 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2244 if ((*niter)->name() == "InputBundle") {
2245 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2246 } else if ((*niter)->name() == "OutputBundle") {
2247 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2249 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2258 Session::load_route_groups (const XMLNode& node, int version)
2260 XMLNodeList nlist = node.children();
2261 XMLNodeConstIterator niter;
2265 if (version >= 3000) {
2267 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2268 if ((*niter)->name() == "RouteGroup") {
2269 RouteGroup* rg = new RouteGroup (*this, "");
2270 add_route_group (rg);
2271 rg->set_state (**niter, version);
2275 } else if (version < 3000) {
2277 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2278 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2279 RouteGroup* rg = new RouteGroup (*this, "");
2280 add_route_group (rg);
2281 rg->set_state (**niter, version);
2290 Session::auto_save()
2292 save_state (_current_snapshot_name);
2296 state_file_filter (const string &str, void */*arg*/)
2298 return (str.length() > strlen(statefile_suffix) &&
2299 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2303 bool operator()(const string* a, const string* b) {
2309 remove_end(string* state)
2311 string statename(*state);
2313 string::size_type start,end;
2314 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2315 statename = statename.substr (start+1);
2318 if ((end = statename.rfind(".ardour")) == string::npos) {
2319 end = statename.length();
2322 return new string(statename.substr (0, end));
2326 Session::possible_states (string path)
2328 PathScanner scanner;
2329 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2331 transform(states->begin(), states->end(), states->begin(), remove_end);
2334 sort (states->begin(), states->end(), cmp);
2340 Session::possible_states () const
2342 return possible_states(_path);
2346 Session::add_route_group (RouteGroup* g)
2348 _route_groups.push_back (g);
2349 route_group_added (g); /* EMIT SIGNAL */
2351 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2352 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2353 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2359 Session::remove_route_group (RouteGroup& rg)
2361 list<RouteGroup*>::iterator i;
2363 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2364 _route_groups.erase (i);
2367 route_group_removed (); /* EMIT SIGNAL */
2371 /** Set a new order for our route groups, without adding or removing any.
2372 * @param groups Route group list in the new order.
2375 Session::reorder_route_groups (list<RouteGroup*> groups)
2377 _route_groups = groups;
2379 route_groups_reordered (); /* EMIT SIGNAL */
2385 Session::route_group_by_name (string name)
2387 list<RouteGroup *>::iterator i;
2389 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2390 if ((*i)->name() == name) {
2398 Session::all_route_group() const
2400 return *_all_route_group;
2404 Session::add_commands (vector<Command*> const & cmds)
2406 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2412 Session::begin_reversible_command (const string& name)
2414 begin_reversible_command (g_quark_from_string (name.c_str ()));
2417 /** Begin a reversible command using a GQuark to identify it.
2418 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2419 * but there must be as many begin...()s as there are commit...()s.
2422 Session::begin_reversible_command (GQuark q)
2424 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2425 to hold all the commands that are committed. This keeps the order of
2426 commands correct in the history.
2429 if (_current_trans == 0) {
2430 /* start a new transaction */
2431 assert (_current_trans_quarks.empty ());
2432 _current_trans = new UndoTransaction();
2433 _current_trans->set_name (g_quark_to_string (q));
2436 _current_trans_quarks.push_front (q);
2440 Session::commit_reversible_command (Command *cmd)
2442 assert (_current_trans);
2443 assert (!_current_trans_quarks.empty ());
2448 _current_trans->add_command (cmd);
2451 _current_trans_quarks.pop_front ();
2453 if (!_current_trans_quarks.empty ()) {
2454 /* the transaction we're committing is not the top-level one */
2458 if (_current_trans->empty()) {
2459 /* no commands were added to the transaction, so just get rid of it */
2460 delete _current_trans;
2465 gettimeofday (&now, 0);
2466 _current_trans->set_timestamp (now);
2468 _history.add (_current_trans);
2473 accept_all_audio_files (const string& path, void */*arg*/)
2475 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2479 if (!AudioFileSource::safe_audio_file_extension (path)) {
2487 accept_all_midi_files (const string& path, void */*arg*/)
2489 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2493 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2494 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2495 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2499 accept_all_state_files (const string& path, void */*arg*/)
2501 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2505 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2509 Session::find_all_sources (string path, set<string>& result)
2514 if (!tree.read (path)) {
2518 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2523 XMLNodeConstIterator niter;
2525 nlist = node->children();
2529 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2533 if ((prop = (*niter)->property (X_("type"))) == 0) {
2537 DataType type (prop->value());
2539 if ((prop = (*niter)->property (X_("name"))) == 0) {
2543 if (Glib::path_is_absolute (prop->value())) {
2544 /* external file, ignore */
2552 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2553 result.insert (found_path);
2561 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2563 PathScanner scanner;
2564 vector<string*>* state_files;
2566 string this_snapshot_path;
2572 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2573 ripped = ripped.substr (0, ripped.length() - 1);
2576 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2578 if (state_files == 0) {
2583 this_snapshot_path = _path;
2584 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2585 this_snapshot_path += statefile_suffix;
2587 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2589 if (exclude_this_snapshot && **i == this_snapshot_path) {
2593 if (find_all_sources (**i, result) < 0) {
2601 struct RegionCounter {
2602 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2603 AudioSourceList::iterator iter;
2604 boost::shared_ptr<Region> region;
2607 RegionCounter() : count (0) {}
2611 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2613 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2614 return r.get_value_or (1);
2618 Session::cleanup_regions ()
2620 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2622 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2624 uint32_t used = playlists->region_use_count (i->second);
2626 if (used == 0 && !i->second->automatic ()) {
2627 RegionFactory::map_remove (i->second);
2631 /* dump the history list */
2638 Session::cleanup_sources (CleanupReport& rep)
2640 // FIXME: needs adaptation to midi
2642 vector<boost::shared_ptr<Source> > dead_sources;
2643 PathScanner scanner;
2646 vector<space_and_path>::iterator i;
2647 vector<space_and_path>::iterator nexti;
2648 vector<string*>* candidates;
2649 vector<string*>* candidates2;
2650 vector<string> unused;
2651 set<string> all_sources;
2656 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2658 /* consider deleting all unused playlists */
2660 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2665 /* sync the "all regions" property of each playlist with its current state
2668 playlists->sync_all_regions_with_regions ();
2670 /* find all un-used sources */
2675 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2677 SourceMap::iterator tmp;
2682 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2686 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2687 dead_sources.push_back (i->second);
2688 i->second->drop_references ();
2694 /* build a list of all the possible audio directories for the session */
2696 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2701 SessionDirectory sdir ((*i).path);
2702 audio_path += sdir.sound_path();
2704 if (nexti != session_dirs.end()) {
2712 /* build a list of all the possible midi directories for the session */
2714 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2719 SessionDirectory sdir ((*i).path);
2720 midi_path += sdir.midi_path();
2722 if (nexti != session_dirs.end()) {
2729 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2730 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2736 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2737 candidates->push_back (*i);
2742 candidates = candidates2; // might still be null
2745 /* find all sources, but don't use this snapshot because the
2746 state file on disk still references sources we may have already
2750 find_all_sources_across_snapshots (all_sources, true);
2752 /* add our current source list
2755 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2756 boost::shared_ptr<FileSource> fs;
2757 SourceMap::iterator tmp = i;
2760 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2761 if (playlists->source_use_count (fs) != 0) {
2762 all_sources.insert (fs->path());
2765 /* we might not remove this source from disk, because it may be used
2766 by other snapshots, but its not being used in this version
2767 so lets get rid of it now, along with any representative regions
2771 RegionFactory::remove_regions_using_source (i->second);
2779 char tmppath1[PATH_MAX+1];
2780 char tmppath2[PATH_MAX+1];
2783 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2788 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2790 if (realpath(spath.c_str(), tmppath1) == 0) {
2791 error << string_compose (_("Cannot expand path %1 (%2)"),
2792 spath, strerror (errno)) << endmsg;
2796 if (realpath((*i).c_str(), tmppath2) == 0) {
2797 error << string_compose (_("Cannot expand path %1 (%2)"),
2798 (*i), strerror (errno)) << endmsg;
2802 if (strcmp(tmppath1, tmppath2) == 0) {
2809 unused.push_back (spath);
2818 /* now try to move all unused files into the "dead" directory(ies) */
2820 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2821 struct stat statbuf;
2825 /* don't move the file across filesystems, just
2826 stick it in the `dead_dir_name' directory
2827 on whichever filesystem it was already on.
2830 if ((*x).find ("/sounds/") != string::npos) {
2832 /* old school, go up 1 level */
2834 newpath = Glib::path_get_dirname (*x); // "sounds"
2835 newpath = Glib::path_get_dirname (newpath); // "session-name"
2839 /* new school, go up 4 levels */
2841 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2842 newpath = Glib::path_get_dirname (newpath); // "session-name"
2843 newpath = Glib::path_get_dirname (newpath); // "interchange"
2844 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2847 newpath = Glib::build_filename (newpath, dead_dir_name);
2849 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2850 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2854 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2856 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2858 /* the new path already exists, try versioning */
2860 char buf[PATH_MAX+1];
2864 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2867 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2868 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2872 if (version == 999) {
2873 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2877 newpath = newpath_v;
2882 /* it doesn't exist, or we can't read it or something */
2886 stat ((*x).c_str(), &statbuf);
2888 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2889 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2890 (*x), newpath, strerror (errno))
2895 /* see if there an easy to find peakfile for this file, and remove it.
2898 string base = basename_nosuffix (*x);
2899 base += "%A"; /* this is what we add for the channel suffix of all native files,
2900 or for the first channel of embedded files. it will miss
2901 some peakfiles for other channels
2903 string peakpath = peak_path (base);
2905 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2906 if (::unlink (peakpath.c_str()) != 0) {
2907 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2908 peakpath, _path, strerror (errno))
2910 /* try to back out */
2911 ::rename (newpath.c_str(), _path.c_str());
2916 rep.paths.push_back (*x);
2917 rep.space += statbuf.st_size;
2920 /* dump the history list */
2924 /* save state so we don't end up a session file
2925 referring to non-existent sources.
2932 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2938 Session::cleanup_trash_sources (CleanupReport& rep)
2940 // FIXME: needs adaptation for MIDI
2942 vector<space_and_path>::iterator i;
2948 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2950 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2952 clear_directory (dead_dir, &rep.space, &rep.paths);
2959 Session::set_dirty ()
2961 bool was_dirty = dirty();
2963 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2967 DirtyChanged(); /* EMIT SIGNAL */
2973 Session::set_clean ()
2975 bool was_dirty = dirty();
2977 _state_of_the_state = Clean;
2981 DirtyChanged(); /* EMIT SIGNAL */
2986 Session::set_deletion_in_progress ()
2988 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2992 Session::clear_deletion_in_progress ()
2994 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2998 Session::add_controllable (boost::shared_ptr<Controllable> c)
3000 /* this adds a controllable to the list managed by the Session.
3001 this is a subset of those managed by the Controllable class
3002 itself, and represents the only ones whose state will be saved
3003 as part of the session.
3006 Glib::Mutex::Lock lm (controllables_lock);
3007 controllables.insert (c);
3010 struct null_deleter { void operator()(void const *) const {} };
3013 Session::remove_controllable (Controllable* c)
3015 if (_state_of_the_state & Deletion) {
3019 Glib::Mutex::Lock lm (controllables_lock);
3021 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3023 if (x != controllables.end()) {
3024 controllables.erase (x);
3028 boost::shared_ptr<Controllable>
3029 Session::controllable_by_id (const PBD::ID& id)
3031 Glib::Mutex::Lock lm (controllables_lock);
3033 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3034 if ((*i)->id() == id) {
3039 return boost::shared_ptr<Controllable>();
3042 boost::shared_ptr<Controllable>
3043 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3045 boost::shared_ptr<Controllable> c;
3046 boost::shared_ptr<Route> r;
3048 switch (desc.top_level_type()) {
3049 case ControllableDescriptor::NamedRoute:
3051 std::string str = desc.top_level_name();
3052 if (str == "master") {
3054 } else if (str == "control" || str == "listen") {
3057 r = route_by_name (desc.top_level_name());
3062 case ControllableDescriptor::RemoteControlID:
3063 r = route_by_remote_id (desc.rid());
3071 switch (desc.subtype()) {
3072 case ControllableDescriptor::Gain:
3073 c = r->gain_control ();
3076 case ControllableDescriptor::Solo:
3077 c = r->solo_control();
3080 case ControllableDescriptor::Mute:
3081 c = r->mute_control();
3084 case ControllableDescriptor::Recenable:
3086 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3089 c = t->rec_enable_control ();
3094 case ControllableDescriptor::PanDirection:
3096 c = r->pannable()->pan_azimuth_control;
3100 case ControllableDescriptor::PanWidth:
3102 c = r->pannable()->pan_width_control;
3106 case ControllableDescriptor::PanElevation:
3108 c = r->pannable()->pan_elevation_control;
3112 case ControllableDescriptor::Balance:
3113 /* XXX simple pan control */
3116 case ControllableDescriptor::PluginParameter:
3118 uint32_t plugin = desc.target (0);
3119 uint32_t parameter_index = desc.target (1);
3121 /* revert to zero based counting */
3127 if (parameter_index > 0) {
3131 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3134 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3135 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3140 case ControllableDescriptor::SendGain:
3142 uint32_t send = desc.target (0);
3144 /* revert to zero-based counting */
3150 boost::shared_ptr<Processor> p = r->nth_send (send);
3153 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3154 boost::shared_ptr<Amp> a = s->amp();
3157 c = s->amp()->gain_control();
3164 /* relax and return a null pointer */
3172 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3175 Stateful::add_instant_xml (node, _path);
3178 if (write_to_config) {
3179 Config->add_instant_xml (node);
3184 Session::instant_xml (const string& node_name)
3186 return Stateful::instant_xml (node_name, _path);
3190 Session::save_history (string snapshot_name)
3198 if (snapshot_name.empty()) {
3199 snapshot_name = _current_snapshot_name;
3202 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3203 const string backup_filename = history_filename + backup_suffix;
3204 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3205 const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3207 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3208 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3209 error << _("could not backup old history file, current history not saved") << endmsg;
3214 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3218 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3220 if (!tree.write (xml_path))
3222 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3224 if (g_remove (xml_path.c_str()) != 0) {
3225 error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3226 xml_path, g_strerror (errno)) << endmsg;
3228 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3229 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3230 backup_path, g_strerror (errno)) << endmsg;
3240 Session::restore_history (string snapshot_name)
3244 if (snapshot_name.empty()) {
3245 snapshot_name = _current_snapshot_name;
3248 const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3249 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3251 info << "Loading history from " << xml_path << endmsg;
3253 if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3254 info << string_compose (_("%1: no history file \"%2\" for this session."),
3255 _name, xml_path) << endmsg;
3259 if (!tree.read (xml_path)) {
3260 error << string_compose (_("Could not understand session history file \"%1\""),
3261 xml_path) << endmsg;
3268 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3271 UndoTransaction* ut = new UndoTransaction ();
3274 ut->set_name(t->property("name")->value());
3275 stringstream ss(t->property("tv-sec")->value());
3277 ss.str(t->property("tv-usec")->value());
3279 ut->set_timestamp(tv);
3281 for (XMLNodeConstIterator child_it = t->children().begin();
3282 child_it != t->children().end(); child_it++)
3284 XMLNode *n = *child_it;
3287 if (n->name() == "MementoCommand" ||
3288 n->name() == "MementoUndoCommand" ||
3289 n->name() == "MementoRedoCommand") {
3291 if ((c = memento_command_factory(n))) {
3295 } else if (n->name() == "NoteDiffCommand") {
3296 PBD::ID id (n->property("midi-source")->value());
3297 boost::shared_ptr<MidiSource> midi_source =
3298 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3300 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3302 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3305 } else if (n->name() == "SysExDiffCommand") {
3307 PBD::ID id (n->property("midi-source")->value());
3308 boost::shared_ptr<MidiSource> midi_source =
3309 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3311 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3313 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3316 } else if (n->name() == "PatchChangeDiffCommand") {
3318 PBD::ID id (n->property("midi-source")->value());
3319 boost::shared_ptr<MidiSource> midi_source =
3320 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3322 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3324 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3327 } else if (n->name() == "StatefulDiffCommand") {
3328 if ((c = stateful_diff_command_factory (n))) {
3329 ut->add_command (c);
3332 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3343 Session::config_changed (std::string p, bool ours)
3349 if (p == "seamless-loop") {
3351 } else if (p == "rf-speed") {
3353 } else if (p == "auto-loop") {
3355 } else if (p == "auto-input") {
3357 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3358 /* auto-input only makes a difference if we're rolling */
3359 set_track_monitor_input_status (!config.get_auto_input());
3362 } else if (p == "punch-in") {
3366 if ((location = _locations->auto_punch_location()) != 0) {
3368 if (config.get_punch_in ()) {
3369 replace_event (SessionEvent::PunchIn, location->start());
3371 remove_event (location->start(), SessionEvent::PunchIn);
3375 } else if (p == "punch-out") {
3379 if ((location = _locations->auto_punch_location()) != 0) {
3381 if (config.get_punch_out()) {
3382 replace_event (SessionEvent::PunchOut, location->end());
3384 clear_events (SessionEvent::PunchOut);
3388 } else if (p == "edit-mode") {
3390 Glib::Mutex::Lock lm (playlists->lock);
3392 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3393 (*i)->set_edit_mode (Config->get_edit_mode ());
3396 } else if (p == "use-video-sync") {
3398 waiting_for_sync_offset = config.get_use_video_sync();
3400 } else if (p == "mmc-control") {
3402 //poke_midi_thread ();
3404 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3406 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3408 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3410 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3412 } else if (p == "midi-control") {
3414 //poke_midi_thread ();
3416 } else if (p == "raid-path") {
3418 setup_raid_path (config.get_raid_path());
3420 } else if (p == "timecode-format") {
3424 } else if (p == "video-pullup") {
3428 } else if (p == "seamless-loop") {
3430 if (play_loop && transport_rolling()) {
3431 // to reset diskstreams etc
3432 request_play_loop (true);
3435 } else if (p == "rf-speed") {
3437 cumulative_rf_motion = 0;
3440 } else if (p == "click-sound") {
3442 setup_click_sounds (1);
3444 } else if (p == "click-emphasis-sound") {
3446 setup_click_sounds (-1);
3448 } else if (p == "clicking") {
3450 if (Config->get_clicking()) {
3451 if (_click_io && click_data) { // don't require emphasis data
3458 } else if (p == "click-gain") {
3461 _click_gain->set_gain (Config->get_click_gain(), this);
3464 } else if (p == "send-mtc") {
3466 if (Config->get_send_mtc ()) {
3467 /* mark us ready to send */
3468 next_quarter_frame_to_send = 0;
3471 } else if (p == "send-mmc") {
3473 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3475 } else if (p == "midi-feedback") {
3477 session_midi_feedback = Config->get_midi_feedback();
3479 } else if (p == "jack-time-master") {
3481 engine().reset_timebase ();
3483 } else if (p == "native-file-header-format") {
3485 if (!first_file_header_format_reset) {
3486 reset_native_file_format ();
3489 first_file_header_format_reset = false;
3491 } else if (p == "native-file-data-format") {
3493 if (!first_file_data_format_reset) {
3494 reset_native_file_format ();
3497 first_file_data_format_reset = false;
3499 } else if (p == "external-sync") {
3500 if (!config.get_external_sync()) {
3501 drop_sync_source ();
3503 switch_to_sync_source (config.get_sync_source());
3505 } else if (p == "denormal-model") {
3507 } else if (p == "history-depth") {
3508 set_history_depth (Config->get_history_depth());
3509 } else if (p == "remote-model") {
3510 switch (Config->get_remote_model()) {
3514 sync_remote_id_from_order_keys (MixerSort);
3517 sync_remote_id_from_order_keys (EditorSort);
3520 } else if (p == "sync-all-route-ordering") {
3522 /* sync to editor order unless mixer is used for remote IDs
3525 switch (Config->get_remote_model()) {
3527 sync_order_keys (EditorSort);
3530 sync_order_keys (EditorSort);
3533 sync_order_keys (MixerSort);
3536 } else if (p == "initial-program-change") {
3538 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3541 buf[0] = MIDI::program; // channel zero by default
3542 buf[1] = (Config->get_initial_program_change() & 0x7f);
3544 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3546 } else if (p == "solo-mute-override") {
3547 // catch_up_on_solo_mute_override ();
3548 } else if (p == "listen-position" || p == "pfl-position") {
3549 listen_position_changed ();
3550 } else if (p == "solo-control-is-listen-control") {
3551 solo_control_mode_changed ();
3552 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3553 last_timecode_valid = false;
3554 } else if (p == "playback-buffer-seconds") {
3555 AudioSource::allocate_working_buffers (frame_rate());
3556 } else if (p == "automation-thinning-factor") {
3557 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3564 Session::set_history_depth (uint32_t d)
3566 _history.set_depth (d);
3570 Session::load_diskstreams_2X (XMLNode const & node, int)
3573 XMLNodeConstIterator citer;
3575 clist = node.children();
3577 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3580 /* diskstreams added automatically by DiskstreamCreated handler */
3581 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3582 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3583 _diskstreams_2X.push_back (dsp);
3585 error << _("Session: unknown diskstream type in XML") << endmsg;
3589 catch (failed_constructor& err) {
3590 error << _("Session: could not load diskstream via XML state") << endmsg;
3598 /** Connect things to the MMC object */
3600 Session::setup_midi_machine_control ()
3602 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3604 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3605 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3606 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3607 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3608 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3609 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3610 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3611 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3612 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3613 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3614 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3615 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3616 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3618 /* also handle MIDI SPP because its so common */
3620 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3621 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3622 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3625 boost::shared_ptr<Controllable>
3626 Session::solo_cut_control() const
3628 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3629 controls in Ardour that currently get presented to the user in the GUI that require
3630 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3632 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3633 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3637 return _solo_cut_control;
3641 Session::rename (const std::string& new_name)
3643 string legal_name = legalize_for_path (new_name);
3649 string const old_sources_root = _session_dir->sources_root();
3651 #define RENAME ::rename
3656 * interchange subdirectory
3660 * Backup files are left unchanged and not renamed.
3663 /* pass one: not 100% safe check that the new directory names don't
3667 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3672 /* this is a stupid hack because Glib::path_get_dirname() is
3673 * lexical-only, and so passing it /a/b/c/ gives a different
3674 * result than passing it /a/b/c ...
3677 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3678 oldstr = oldstr.substr (0, oldstr.length() - 1);
3681 string base = Glib::path_get_dirname (oldstr);
3682 string p = Glib::path_get_basename (oldstr);
3684 newstr = Glib::build_filename (base, legal_name);
3686 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3693 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3698 /* this is a stupid hack because Glib::path_get_dirname() is
3699 * lexical-only, and so passing it /a/b/c/ gives a different
3700 * result than passing it /a/b/c ...
3703 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3704 oldstr = oldstr.substr (0, oldstr.length() - 1);
3707 string base = Glib::path_get_dirname (oldstr);
3708 string p = Glib::path_get_basename (oldstr);
3710 newstr = Glib::build_filename (base, legal_name);
3712 cerr << "Rename " << oldstr << " => " << newstr << endl;
3714 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3719 (*_session_dir) = newstr;
3724 /* directory below interchange */
3726 v.push_back (newstr);
3727 v.push_back (interchange_dir_name);
3730 oldstr = Glib::build_filename (v);
3733 v.push_back (newstr);
3734 v.push_back (interchange_dir_name);
3735 v.push_back (legal_name);
3737 newstr = Glib::build_filename (v);
3739 cerr << "Rename " << oldstr << " => " << newstr << endl;
3741 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3748 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3749 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3751 cerr << "Rename " << oldstr << " => " << newstr << endl;
3753 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3760 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3762 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3763 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3765 cerr << "Rename " << oldstr << " => " << newstr << endl;
3767 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3772 /* update file source paths */
3774 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3775 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3777 string p = fs->path ();
3778 boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3783 /* remove old name from recent sessions */
3785 remove_recent_sessions (_path);
3788 _current_snapshot_name = new_name;
3793 /* save state again to get everything just right */
3795 save_state (_current_snapshot_name);
3798 /* add to recent sessions */
3800 store_recent_sessions (new_name, _path);