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 (%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 _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)
699 struct tm local_time;
702 localtime_r (&n, &local_time);
703 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
705 if (event->type == JackSessionSaveTemplate)
707 if (save_template( timebuf )) {
708 event->flags = JackSessionSaveError;
710 string cmd ("ardour3 -P -U ");
711 cmd += event->client_uuid;
715 event->command_line = strdup (cmd.c_str());
720 if (save_state (timebuf)) {
721 event->flags = JackSessionSaveError;
723 std::string xml_path (_session_dir->root_path());
724 std::string legalized_filename = legalize_for_path (timebuf) + statefile_suffix;
725 xml_path = Glib::build_filename (xml_path, legalized_filename);
727 string cmd ("ardour3 -P -U ");
728 cmd += event->client_uuid;
733 event->command_line = strdup (cmd.c_str());
737 jack_session_reply (_engine.jack(), event);
739 if (event->type == JackSessionSaveAndQuit) {
740 Quit (); /* EMIT SIGNAL */
743 jack_session_event_free( event );
747 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
749 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
752 std::string xml_path(_session_dir->root_path());
754 if (!_writable || (_state_of_the_state & CannotSave)) {
758 if (!_engine.connected ()) {
759 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
765 /* tell sources we're saving first, in case they write out to a new file
766 * which should be saved with the state rather than the old one */
767 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
769 i->second->session_saved();
770 } catch (Evoral::SMF::FileError& e) {
771 error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
775 tree.set_root (&get_state());
777 if (snapshot_name.empty()) {
778 snapshot_name = _current_snapshot_name;
779 } else if (switch_to_snapshot) {
780 _current_snapshot_name = snapshot_name;
785 /* proper save: use statefile_suffix (.ardour in English) */
787 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
789 /* make a backup copy of the old file */
791 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
792 // create_backup_file will log the error
798 /* pending save: use pending_suffix (.pending in English) */
799 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
802 std::string tmp_path(_session_dir->root_path());
803 tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
805 // cerr << "actually writing state to " << xml_path << endl;
807 if (!tree.write (tmp_path)) {
808 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
809 if (g_remove (tmp_path.c_str()) != 0) {
810 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
811 tmp_path, g_strerror (errno)) << endmsg;
817 if (::rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
818 error << string_compose (_("could not rename temporary session file %1 to %2"),
819 tmp_path, xml_path) << endmsg;
820 if (g_remove (tmp_path.c_str()) != 0) {
821 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
822 tmp_path, g_strerror (errno)) << endmsg;
830 save_history (snapshot_name);
832 bool was_dirty = dirty();
834 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
837 DirtyChanged (); /* EMIT SIGNAL */
840 StateSaved (snapshot_name); /* EMIT SIGNAL */
847 Session::restore_state (string snapshot_name)
849 if (load_state (snapshot_name) == 0) {
850 set_state (*state_tree->root(), Stateful::loading_state_version);
857 Session::load_state (string snapshot_name)
862 state_was_pending = false;
864 /* check for leftover pending state from a crashed capture attempt */
866 std::string xmlpath(_session_dir->root_path());
867 xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
869 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
871 /* there is pending state from a crashed capture attempt */
873 boost::optional<int> r = AskAboutPendingState();
874 if (r.get_value_or (1)) {
875 state_was_pending = true;
879 if (!state_was_pending) {
880 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
883 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
884 xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
885 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
886 error << string_compose(_("%1: session file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
891 state_tree = new XMLTree;
895 _writable = exists_and_writable (xmlpath);
897 if (!state_tree->read (xmlpath)) {
898 error << string_compose(_("Could not understand session file %1"), xmlpath) << endmsg;
904 XMLNode& root (*state_tree->root());
906 if (root.name() != X_("Session")) {
907 error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
913 const XMLProperty* prop;
915 if ((prop = root.property ("version")) == 0) {
916 /* no version implies very old version of Ardour */
917 Stateful::loading_state_version = 1000;
919 if (prop->value().find ('.') != string::npos) {
920 /* old school version format */
921 if (prop->value()[0] == '2') {
922 Stateful::loading_state_version = 2000;
924 Stateful::loading_state_version = 3000;
927 Stateful::loading_state_version = atoi (prop->value());
931 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
933 std::string backup_path(_session_dir->root_path());
934 std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
935 backup_path = Glib::build_filename (backup_path, backup_filename);
937 // only create a backup for a given statefile version once
939 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
941 VersionMismatch (xmlpath, backup_path);
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::Threads::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::Threads::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 if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
1080 child->add_child_nocopy ((boost::dynamic_pointer_cast<AudioRegion>(r))->get_basic_state ());
1082 child->add_child_nocopy (r->get_state ());
1087 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1089 if (!cassocs.empty()) {
1090 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1092 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1094 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1095 i->first->id().print (buf, sizeof (buf));
1096 can->add_property (X_("copy"), buf);
1097 i->second->id().print (buf, sizeof (buf));
1098 can->add_property (X_("original"), buf);
1099 ca->add_child_nocopy (*can);
1105 node->add_child_nocopy (_locations->get_state());
1107 // for a template, just create a new Locations, populate it
1108 // with the default start and end, and get the state for that.
1109 Locations loc (*this);
1110 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1111 range->set (max_framepos, 0);
1113 node->add_child_nocopy (loc.get_state());
1116 child = node->add_child ("Bundles");
1118 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1119 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1120 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1122 child->add_child_nocopy (b->get_state());
1127 child = node->add_child ("Routes");
1129 boost::shared_ptr<RouteList> r = routes.reader ();
1131 RoutePublicOrderSorter cmp;
1132 RouteList public_order (*r);
1133 public_order.sort (cmp);
1135 /* the sort should have put control outs first */
1138 assert (_monitor_out == public_order.front());
1141 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1142 if (!(*i)->is_hidden()) {
1144 child->add_child_nocopy ((*i)->get_state());
1146 child->add_child_nocopy ((*i)->get_template());
1152 playlists->add_state (node, full_state);
1154 child = node->add_child ("RouteGroups");
1155 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1156 child->add_child_nocopy ((*i)->get_state());
1160 XMLNode* gain_child = node->add_child ("Click");
1161 gain_child->add_child_nocopy (_click_io->state (full_state));
1162 gain_child->add_child_nocopy (_click_gain->state (full_state));
1166 XMLNode* ltc_input_child = node->add_child ("LTC-In");
1167 ltc_input_child->add_child_nocopy (_ltc_input->state (full_state));
1171 XMLNode* ltc_output_child = node->add_child ("LTC-Out");
1172 ltc_output_child->add_child_nocopy (_ltc_output->state (full_state));
1175 node->add_child_nocopy (_speakers->get_state());
1176 node->add_child_nocopy (_tempo_map->get_state());
1177 node->add_child_nocopy (get_control_protocol_state());
1180 node->add_child_copy (*_extra_xml);
1187 Session::get_control_protocol_state ()
1189 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1190 return cpm.get_state();
1194 Session::set_state (const XMLNode& node, int version)
1198 const XMLProperty* prop;
1201 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1203 if (node.name() != X_("Session")) {
1204 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1208 if ((prop = node.property ("name")) != 0) {
1209 _name = prop->value ();
1212 if ((prop = node.property (X_("sample-rate"))) != 0) {
1214 _nominal_frame_rate = atoi (prop->value());
1216 if (_nominal_frame_rate != _current_frame_rate) {
1217 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1218 if (r.get_value_or (0)) {
1224 setup_raid_path(_session_dir->root_path());
1226 if ((prop = node.property (X_("id-counter"))) != 0) {
1228 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1229 ID::init_counter (x);
1231 /* old sessions used a timebased counter, so fake
1232 the startup ID counter based on a standard
1237 ID::init_counter (now);
1240 if ((prop = node.property (X_("event-counter"))) != 0) {
1241 Evoral::init_event_id_counter (atoi (prop->value()));
1244 IO::disable_connecting ();
1246 Stateful::save_extra_xml (node);
1248 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1249 load_options (*child);
1250 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1251 load_options (*child);
1253 error << _("Session: XML state has no options section") << endmsg;
1256 if (version >= 3000) {
1257 if ((child = find_named_node (node, "Metadata")) == 0) {
1258 warning << _("Session: XML state has no metadata section") << endmsg;
1259 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1264 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1265 _speakers->set_state (*child, version);
1268 if ((child = find_named_node (node, "Sources")) == 0) {
1269 error << _("Session: XML state has no sources section") << endmsg;
1271 } else if (load_sources (*child)) {
1275 if ((child = find_named_node (node, "TempoMap")) == 0) {
1276 error << _("Session: XML state has no Tempo Map section") << endmsg;
1278 } else if (_tempo_map->set_state (*child, version)) {
1282 if ((child = find_named_node (node, "Locations")) == 0) {
1283 error << _("Session: XML state has no locations section") << endmsg;
1285 } else if (_locations->set_state (*child, version)) {
1291 if ((location = _locations->auto_loop_location()) != 0) {
1292 set_auto_loop_location (location);
1295 if ((location = _locations->auto_punch_location()) != 0) {
1296 set_auto_punch_location (location);
1299 if ((location = _locations->session_range_location()) != 0) {
1300 delete _session_range_location;
1301 _session_range_location = location;
1304 if (_session_range_location) {
1305 AudioFileSource::set_header_position_offset (_session_range_location->start());
1308 if ((child = find_named_node (node, "Regions")) == 0) {
1309 error << _("Session: XML state has no Regions section") << endmsg;
1311 } else if (load_regions (*child)) {
1315 if ((child = find_named_node (node, "Playlists")) == 0) {
1316 error << _("Session: XML state has no playlists section") << endmsg;
1318 } else if (playlists->load (*this, *child)) {
1322 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1324 } else if (playlists->load_unused (*this, *child)) {
1328 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1329 if (load_compounds (*child)) {
1334 if (version >= 3000) {
1335 if ((child = find_named_node (node, "Bundles")) == 0) {
1336 warning << _("Session: XML state has no bundles section") << endmsg;
1339 /* We can't load Bundles yet as they need to be able
1340 to convert from port names to Port objects, which can't happen until
1342 _bundle_xml_node = new XMLNode (*child);
1346 if (version < 3000) {
1347 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1348 error << _("Session: XML state has no diskstreams section") << endmsg;
1350 } else if (load_diskstreams_2X (*child, version)) {
1355 if ((child = find_named_node (node, "Routes")) == 0) {
1356 error << _("Session: XML state has no routes section") << endmsg;
1358 } else if (load_routes (*child, version)) {
1362 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1363 _diskstreams_2X.clear ();
1365 if (version >= 3000) {
1367 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1368 error << _("Session: XML state has no route groups section") << endmsg;
1370 } else if (load_route_groups (*child, version)) {
1374 } else if (version < 3000) {
1376 if ((child = find_named_node (node, "EditGroups")) == 0) {
1377 error << _("Session: XML state has no edit groups section") << endmsg;
1379 } else if (load_route_groups (*child, version)) {
1383 if ((child = find_named_node (node, "MixGroups")) == 0) {
1384 error << _("Session: XML state has no mix groups section") << endmsg;
1386 } else if (load_route_groups (*child, version)) {
1391 if ((child = find_named_node (node, "Click")) == 0) {
1392 warning << _("Session: XML state has no click section") << endmsg;
1393 } else if (_click_io) {
1394 const XMLNodeList& children (child->children());
1395 XMLNodeList::const_iterator i = children.begin();
1396 _click_io->set_state (**i, version);
1398 if (i != children.end()) {
1399 _click_gain->set_state (**i, version);
1403 if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
1404 ControlProtocolManager::instance().set_state (*child, version);
1407 update_have_rec_enabled_track ();
1409 /* here beginneth the second phase ... */
1411 StateReady (); /* EMIT SIGNAL */
1420 Session::load_routes (const XMLNode& node, int version)
1423 XMLNodeConstIterator niter;
1424 RouteList new_routes;
1426 nlist = node.children();
1430 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1432 boost::shared_ptr<Route> route;
1433 if (version < 3000) {
1434 route = XMLRouteFactory_2X (**niter, version);
1436 route = XMLRouteFactory (**niter, version);
1440 error << _("Session: cannot create Route from XML description.") << endmsg;
1444 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1446 new_routes.push_back (route);
1449 add_routes (new_routes, false, false, false);
1454 boost::shared_ptr<Route>
1455 Session::XMLRouteFactory (const XMLNode& node, int version)
1457 boost::shared_ptr<Route> ret;
1459 if (node.name() != "Route") {
1463 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1465 DataType type = DataType::AUDIO;
1466 const XMLProperty* prop = node.property("default-type");
1469 type = DataType (prop->value());
1472 assert (type != DataType::NIL);
1476 boost::shared_ptr<Track> track;
1478 if (type == DataType::AUDIO) {
1479 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1481 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1484 if (track->init()) {
1488 if (track->set_state (node, version)) {
1492 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1493 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1498 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1500 if (r->init () == 0 && r->set_state (node, version) == 0) {
1501 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1502 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1511 boost::shared_ptr<Route>
1512 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1514 boost::shared_ptr<Route> ret;
1516 if (node.name() != "Route") {
1520 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1522 ds_prop = node.property (X_("diskstream"));
1525 DataType type = DataType::AUDIO;
1526 const XMLProperty* prop = node.property("default-type");
1529 type = DataType (prop->value());
1532 assert (type != DataType::NIL);
1536 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1537 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1541 if (i == _diskstreams_2X.end()) {
1542 error << _("Could not find diskstream for route") << endmsg;
1543 return boost::shared_ptr<Route> ();
1546 boost::shared_ptr<Track> track;
1548 if (type == DataType::AUDIO) {
1549 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1551 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1554 if (track->init()) {
1558 if (track->set_state (node, version)) {
1562 track->set_diskstream (*i);
1564 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1565 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1570 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1572 if (r->init () == 0 && r->set_state (node, version) == 0) {
1573 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1574 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1584 Session::load_regions (const XMLNode& node)
1587 XMLNodeConstIterator niter;
1588 boost::shared_ptr<Region> region;
1590 nlist = node.children();
1594 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1595 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1596 error << _("Session: cannot create Region from XML description.");
1597 const XMLProperty *name = (**niter).property("name");
1600 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1611 Session::load_compounds (const XMLNode& node)
1613 XMLNodeList calist = node.children();
1614 XMLNodeConstIterator caiter;
1615 XMLProperty *caprop;
1617 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1618 XMLNode* ca = *caiter;
1622 if ((caprop = ca->property (X_("original"))) == 0) {
1625 orig_id = caprop->value();
1627 if ((caprop = ca->property (X_("copy"))) == 0) {
1630 copy_id = caprop->value();
1632 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1633 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1635 if (!orig || !copy) {
1636 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1642 RegionFactory::add_compound_association (orig, copy);
1649 Session::load_nested_sources (const XMLNode& node)
1652 XMLNodeConstIterator niter;
1654 nlist = node.children();
1656 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1657 if ((*niter)->name() == "Source") {
1659 /* it may already exist, so don't recreate it unnecessarily
1662 XMLProperty* prop = (*niter)->property (X_("id"));
1664 error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
1668 ID source_id (prop->value());
1670 if (!source_by_id (source_id)) {
1673 SourceFactory::create (*this, **niter, true);
1675 catch (failed_constructor& err) {
1676 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1683 boost::shared_ptr<Region>
1684 Session::XMLRegionFactory (const XMLNode& node, bool full)
1686 const XMLProperty* type = node.property("type");
1690 const XMLNodeList& nlist = node.children();
1692 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1693 XMLNode *child = (*niter);
1694 if (child->name() == "NestedSource") {
1695 load_nested_sources (*child);
1699 if (!type || type->value() == "audio") {
1700 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1701 } else if (type->value() == "midi") {
1702 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1705 } catch (failed_constructor& err) {
1706 return boost::shared_ptr<Region> ();
1709 return boost::shared_ptr<Region> ();
1712 boost::shared_ptr<AudioRegion>
1713 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1715 const XMLProperty* prop;
1716 boost::shared_ptr<Source> source;
1717 boost::shared_ptr<AudioSource> as;
1719 SourceList master_sources;
1720 uint32_t nchans = 1;
1723 if (node.name() != X_("Region")) {
1724 return boost::shared_ptr<AudioRegion>();
1727 if ((prop = node.property (X_("channels"))) != 0) {
1728 nchans = atoi (prop->value().c_str());
1731 if ((prop = node.property ("name")) == 0) {
1732 cerr << "no name for this region\n";
1736 if ((prop = node.property (X_("source-0"))) == 0) {
1737 if ((prop = node.property ("source")) == 0) {
1738 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1739 return boost::shared_ptr<AudioRegion>();
1743 PBD::ID s_id (prop->value());
1745 if ((source = source_by_id (s_id)) == 0) {
1746 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1747 return boost::shared_ptr<AudioRegion>();
1750 as = boost::dynamic_pointer_cast<AudioSource>(source);
1752 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1753 return boost::shared_ptr<AudioRegion>();
1756 sources.push_back (as);
1758 /* pickup other channels */
1760 for (uint32_t n=1; n < nchans; ++n) {
1761 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1762 if ((prop = node.property (buf)) != 0) {
1764 PBD::ID id2 (prop->value());
1766 if ((source = source_by_id (id2)) == 0) {
1767 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1768 return boost::shared_ptr<AudioRegion>();
1771 as = boost::dynamic_pointer_cast<AudioSource>(source);
1773 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1774 return boost::shared_ptr<AudioRegion>();
1776 sources.push_back (as);
1780 for (uint32_t n = 0; n < nchans; ++n) {
1781 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1782 if ((prop = node.property (buf)) != 0) {
1784 PBD::ID id2 (prop->value());
1786 if ((source = source_by_id (id2)) == 0) {
1787 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1788 return boost::shared_ptr<AudioRegion>();
1791 as = boost::dynamic_pointer_cast<AudioSource>(source);
1793 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1794 return boost::shared_ptr<AudioRegion>();
1796 master_sources.push_back (as);
1801 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1803 /* a final detail: this is the one and only place that we know how long missing files are */
1805 if (region->whole_file()) {
1806 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1807 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1809 sfp->set_length (region->length());
1814 if (!master_sources.empty()) {
1815 if (master_sources.size() != nchans) {
1816 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1818 region->set_master_sources (master_sources);
1826 catch (failed_constructor& err) {
1827 return boost::shared_ptr<AudioRegion>();
1831 boost::shared_ptr<MidiRegion>
1832 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1834 const XMLProperty* prop;
1835 boost::shared_ptr<Source> source;
1836 boost::shared_ptr<MidiSource> ms;
1839 if (node.name() != X_("Region")) {
1840 return boost::shared_ptr<MidiRegion>();
1843 if ((prop = node.property ("name")) == 0) {
1844 cerr << "no name for this region\n";
1848 if ((prop = node.property (X_("source-0"))) == 0) {
1849 if ((prop = node.property ("source")) == 0) {
1850 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1851 return boost::shared_ptr<MidiRegion>();
1855 PBD::ID s_id (prop->value());
1857 if ((source = source_by_id (s_id)) == 0) {
1858 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1859 return boost::shared_ptr<MidiRegion>();
1862 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1864 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1865 return boost::shared_ptr<MidiRegion>();
1868 sources.push_back (ms);
1871 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1872 /* a final detail: this is the one and only place that we know how long missing files are */
1874 if (region->whole_file()) {
1875 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1876 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1878 sfp->set_length (region->length());
1886 catch (failed_constructor& err) {
1887 return boost::shared_ptr<MidiRegion>();
1892 Session::get_sources_as_xml ()
1895 XMLNode* node = new XMLNode (X_("Sources"));
1896 Glib::Threads::Mutex::Lock lm (source_lock);
1898 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1899 node->add_child_nocopy (i->second->get_state());
1906 Session::path_from_region_name (DataType type, string name, string identifier)
1908 char buf[PATH_MAX+1];
1910 SessionDirectory sdir(get_best_session_directory_for_new_source());
1911 std::string source_dir = ((type == DataType::AUDIO)
1912 ? sdir.sound_path() : sdir.midi_path());
1914 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1916 for (n = 0; n < 999999; ++n) {
1917 if (identifier.length()) {
1918 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1919 identifier.c_str(), n, ext.c_str());
1921 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1925 std::string source_path = Glib::build_filename (source_dir, buf);
1927 if (!Glib::file_test (source_path, Glib::FILE_TEST_EXISTS)) {
1932 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1941 Session::load_sources (const XMLNode& node)
1944 XMLNodeConstIterator niter;
1945 boost::shared_ptr<Source> source;
1947 nlist = node.children();
1951 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1954 if ((source = XMLSourceFactory (**niter)) == 0) {
1955 error << _("Session: cannot create Source from XML description.") << endmsg;
1958 } catch (MissingSource& err) {
1962 if (!no_questions_about_missing_files) {
1963 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1968 switch (user_choice) {
1970 /* user added a new search location, so try again */
1975 /* user asked to quit the entire session load
1980 no_questions_about_missing_files = true;
1984 no_questions_about_missing_files = true;
1989 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1990 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1999 boost::shared_ptr<Source>
2000 Session::XMLSourceFactory (const XMLNode& node)
2002 if (node.name() != "Source") {
2003 return boost::shared_ptr<Source>();
2007 /* note: do peak building in another thread when loading session state */
2008 return SourceFactory::create (*this, node, true);
2011 catch (failed_constructor& err) {
2012 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2013 return boost::shared_ptr<Source>();
2018 Session::save_template (string template_name)
2022 if (_state_of_the_state & CannotSave) {
2026 std::string user_template_dir(user_template_directory());
2028 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
2029 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2030 user_template_dir, g_strerror (errno)) << endmsg;
2034 tree.set_root (&get_template());
2036 std::string template_dir_path(user_template_dir);
2038 /* directory to put the template in */
2039 template_dir_path = Glib::build_filename (template_dir_path, template_name);
2041 if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
2042 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2043 template_dir_path) << endmsg;
2047 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
2048 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
2049 template_dir_path, g_strerror (errno)) << endmsg;
2054 std::string template_file_path(template_dir_path);
2055 template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
2057 if (!tree.write (template_file_path)) {
2058 error << _("template not saved") << endmsg;
2062 /* copy plugin state directory */
2064 std::string template_plugin_state_path(template_dir_path);
2065 template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
2067 if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
2068 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
2069 template_plugin_state_path, g_strerror (errno)) << endmsg;
2073 copy_files (plugins_dir(), template_plugin_state_path);
2079 Session::refresh_disk_space ()
2081 #if HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H
2083 Glib::Threads::Mutex::Lock lm (space_lock);
2085 /* get freespace on every FS that is part of the session path */
2087 _total_free_4k_blocks = 0;
2088 _total_free_4k_blocks_uncertain = false;
2090 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2092 struct statfs statfsbuf;
2093 statfs (i->path.c_str(), &statfsbuf);
2095 double const scale = statfsbuf.f_bsize / 4096.0;
2097 /* See if this filesystem is read-only */
2098 struct statvfs statvfsbuf;
2099 statvfs (i->path.c_str(), &statvfsbuf);
2101 /* f_bavail can be 0 if it is undefined for whatever
2102 filesystem we are looking at; Samba shares mounted
2103 via GVFS are an example of this.
2105 if (statfsbuf.f_bavail == 0) {
2106 /* block count unknown */
2108 i->blocks_unknown = true;
2109 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2110 /* read-only filesystem */
2112 i->blocks_unknown = false;
2114 /* read/write filesystem with known space */
2115 i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2116 i->blocks_unknown = false;
2119 _total_free_4k_blocks += i->blocks;
2120 if (i->blocks_unknown) {
2121 _total_free_4k_blocks_uncertain = true;
2128 Session::get_best_session_directory_for_new_source ()
2130 vector<space_and_path>::iterator i;
2131 string result = _session_dir->root_path();
2133 /* handle common case without system calls */
2135 if (session_dirs.size() == 1) {
2139 /* OK, here's the algorithm we're following here:
2141 We want to select which directory to use for
2142 the next file source to be created. Ideally,
2143 we'd like to use a round-robin process so as to
2144 get maximum performance benefits from splitting
2145 the files across multiple disks.
2147 However, in situations without much diskspace, an
2148 RR approach may end up filling up a filesystem
2149 with new files while others still have space.
2150 Its therefore important to pay some attention to
2151 the freespace in the filesystem holding each
2152 directory as well. However, if we did that by
2153 itself, we'd keep creating new files in the file
2154 system with the most space until it was as full
2155 as all others, thus negating any performance
2156 benefits of this RAID-1 like approach.
2158 So, we use a user-configurable space threshold. If
2159 there are at least 2 filesystems with more than this
2160 much space available, we use RR selection between them.
2161 If not, then we pick the filesystem with the most space.
2163 This gets a good balance between the two
2167 refresh_disk_space ();
2169 int free_enough = 0;
2171 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2172 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2177 if (free_enough >= 2) {
2178 /* use RR selection process, ensuring that the one
2182 i = last_rr_session_dir;
2185 if (++i == session_dirs.end()) {
2186 i = session_dirs.begin();
2189 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2190 SessionDirectory sdir(i->path);
2191 if (sdir.create ()) {
2193 last_rr_session_dir = i;
2198 } while (i != last_rr_session_dir);
2202 /* pick FS with the most freespace (and that
2203 seems to actually work ...)
2206 vector<space_and_path> sorted;
2207 space_and_path_ascending_cmp cmp;
2209 sorted = session_dirs;
2210 sort (sorted.begin(), sorted.end(), cmp);
2212 for (i = sorted.begin(); i != sorted.end(); ++i) {
2213 SessionDirectory sdir(i->path);
2214 if (sdir.create ()) {
2216 last_rr_session_dir = i;
2226 Session::automation_dir () const
2228 return Glib::build_filename (_path, "automation");
2232 Session::analysis_dir () const
2234 return Glib::build_filename (_path, "analysis");
2238 Session::plugins_dir () const
2240 return Glib::build_filename (_path, "plugins");
2244 Session::externals_dir () const
2246 return Glib::build_filename (_path, "externals");
2250 Session::load_bundles (XMLNode const & node)
2252 XMLNodeList nlist = node.children();
2253 XMLNodeConstIterator niter;
2257 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2258 if ((*niter)->name() == "InputBundle") {
2259 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2260 } else if ((*niter)->name() == "OutputBundle") {
2261 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2263 error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2272 Session::load_route_groups (const XMLNode& node, int version)
2274 XMLNodeList nlist = node.children();
2275 XMLNodeConstIterator niter;
2279 if (version >= 3000) {
2281 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2282 if ((*niter)->name() == "RouteGroup") {
2283 RouteGroup* rg = new RouteGroup (*this, "");
2284 add_route_group (rg);
2285 rg->set_state (**niter, version);
2289 } else if (version < 3000) {
2291 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2292 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2293 RouteGroup* rg = new RouteGroup (*this, "");
2294 add_route_group (rg);
2295 rg->set_state (**niter, version);
2304 Session::auto_save()
2306 save_state (_current_snapshot_name);
2310 state_file_filter (const string &str, void */*arg*/)
2312 return (str.length() > strlen(statefile_suffix) &&
2313 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2317 bool operator()(const string* a, const string* b) {
2323 remove_end(string* state)
2325 string statename(*state);
2327 string::size_type start,end;
2328 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2329 statename = statename.substr (start+1);
2332 if ((end = statename.rfind(".ardour")) == string::npos) {
2333 end = statename.length();
2336 return new string(statename.substr (0, end));
2340 Session::possible_states (string path)
2342 PathScanner scanner;
2343 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2345 transform(states->begin(), states->end(), states->begin(), remove_end);
2348 sort (states->begin(), states->end(), cmp);
2354 Session::possible_states () const
2356 return possible_states(_path);
2360 Session::add_route_group (RouteGroup* g)
2362 _route_groups.push_back (g);
2363 route_group_added (g); /* EMIT SIGNAL */
2365 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2366 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2367 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2373 Session::remove_route_group (RouteGroup& rg)
2375 list<RouteGroup*>::iterator i;
2377 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2378 _route_groups.erase (i);
2381 route_group_removed (); /* EMIT SIGNAL */
2385 /** Set a new order for our route groups, without adding or removing any.
2386 * @param groups Route group list in the new order.
2389 Session::reorder_route_groups (list<RouteGroup*> groups)
2391 _route_groups = groups;
2393 route_groups_reordered (); /* EMIT SIGNAL */
2399 Session::route_group_by_name (string name)
2401 list<RouteGroup *>::iterator i;
2403 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2404 if ((*i)->name() == name) {
2412 Session::all_route_group() const
2414 return *_all_route_group;
2418 Session::add_commands (vector<Command*> const & cmds)
2420 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2426 Session::begin_reversible_command (const string& name)
2428 begin_reversible_command (g_quark_from_string (name.c_str ()));
2431 /** Begin a reversible command using a GQuark to identify it.
2432 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2433 * but there must be as many begin...()s as there are commit...()s.
2436 Session::begin_reversible_command (GQuark q)
2438 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2439 to hold all the commands that are committed. This keeps the order of
2440 commands correct in the history.
2443 if (_current_trans == 0) {
2444 /* start a new transaction */
2445 assert (_current_trans_quarks.empty ());
2446 _current_trans = new UndoTransaction();
2447 _current_trans->set_name (g_quark_to_string (q));
2450 _current_trans_quarks.push_front (q);
2454 Session::commit_reversible_command (Command *cmd)
2456 assert (_current_trans);
2457 assert (!_current_trans_quarks.empty ());
2462 _current_trans->add_command (cmd);
2465 _current_trans_quarks.pop_front ();
2467 if (!_current_trans_quarks.empty ()) {
2468 /* the transaction we're committing is not the top-level one */
2472 if (_current_trans->empty()) {
2473 /* no commands were added to the transaction, so just get rid of it */
2474 delete _current_trans;
2479 gettimeofday (&now, 0);
2480 _current_trans->set_timestamp (now);
2482 _history.add (_current_trans);
2487 accept_all_audio_files (const string& path, void */*arg*/)
2489 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2493 if (!AudioFileSource::safe_audio_file_extension (path)) {
2501 accept_all_midi_files (const string& path, void */*arg*/)
2503 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2507 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2508 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2509 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2513 accept_all_state_files (const string& path, void */*arg*/)
2515 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2519 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2523 Session::find_all_sources (string path, set<string>& result)
2528 if (!tree.read (path)) {
2532 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2537 XMLNodeConstIterator niter;
2539 nlist = node->children();
2543 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2547 if ((prop = (*niter)->property (X_("type"))) == 0) {
2551 DataType type (prop->value());
2553 if ((prop = (*niter)->property (X_("name"))) == 0) {
2557 if (Glib::path_is_absolute (prop->value())) {
2558 /* external file, ignore */
2566 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2567 result.insert (found_path);
2575 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2577 PathScanner scanner;
2578 vector<string*>* state_files;
2580 string this_snapshot_path;
2586 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2587 ripped = ripped.substr (0, ripped.length() - 1);
2590 state_files = scanner (ripped, accept_all_state_files, (void *) 0, true, true);
2592 if (state_files == 0) {
2597 this_snapshot_path = _path;
2598 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2599 this_snapshot_path += statefile_suffix;
2601 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2603 if (exclude_this_snapshot && **i == this_snapshot_path) {
2607 if (find_all_sources (**i, result) < 0) {
2615 struct RegionCounter {
2616 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2617 AudioSourceList::iterator iter;
2618 boost::shared_ptr<Region> region;
2621 RegionCounter() : count (0) {}
2625 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2627 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2628 return r.get_value_or (1);
2632 Session::cleanup_regions ()
2634 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2636 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2638 uint32_t used = playlists->region_use_count (i->second);
2640 if (used == 0 && !i->second->automatic ()) {
2641 RegionFactory::map_remove (i->second);
2645 /* dump the history list */
2652 Session::cleanup_sources (CleanupReport& rep)
2654 // FIXME: needs adaptation to midi
2656 vector<boost::shared_ptr<Source> > dead_sources;
2657 PathScanner scanner;
2660 vector<space_and_path>::iterator i;
2661 vector<space_and_path>::iterator nexti;
2662 vector<string*>* candidates;
2663 vector<string*>* candidates2;
2664 vector<string> unused;
2665 set<string> all_sources;
2670 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2672 /* consider deleting all unused playlists */
2674 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2679 /* sync the "all regions" property of each playlist with its current state
2682 playlists->sync_all_regions_with_regions ();
2684 /* find all un-used sources */
2689 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2691 SourceMap::iterator tmp;
2696 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2700 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2701 dead_sources.push_back (i->second);
2702 i->second->drop_references ();
2708 /* build a list of all the possible audio directories for the session */
2710 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2715 SessionDirectory sdir ((*i).path);
2716 audio_path += sdir.sound_path();
2718 if (nexti != session_dirs.end()) {
2726 /* build a list of all the possible midi directories for the session */
2728 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2733 SessionDirectory sdir ((*i).path);
2734 midi_path += sdir.midi_path();
2736 if (nexti != session_dirs.end()) {
2743 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2744 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2750 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2751 candidates->push_back (*i);
2756 candidates = candidates2; // might still be null
2759 /* find all sources, but don't use this snapshot because the
2760 state file on disk still references sources we may have already
2764 find_all_sources_across_snapshots (all_sources, true);
2766 /* add our current source list
2769 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2770 boost::shared_ptr<FileSource> fs;
2771 SourceMap::iterator tmp = i;
2774 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2775 if (playlists->source_use_count (fs) != 0) {
2776 all_sources.insert (fs->path());
2779 /* we might not remove this source from disk, because it may be used
2780 by other snapshots, but its not being used in this version
2781 so lets get rid of it now, along with any representative regions
2785 RegionFactory::remove_regions_using_source (i->second);
2793 char tmppath1[PATH_MAX+1];
2794 char tmppath2[PATH_MAX+1];
2797 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2802 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2804 if (realpath(spath.c_str(), tmppath1) == 0) {
2805 error << string_compose (_("Cannot expand path %1 (%2)"),
2806 spath, strerror (errno)) << endmsg;
2810 if (realpath((*i).c_str(), tmppath2) == 0) {
2811 error << string_compose (_("Cannot expand path %1 (%2)"),
2812 (*i), strerror (errno)) << endmsg;
2816 if (strcmp(tmppath1, tmppath2) == 0) {
2823 unused.push_back (spath);
2832 /* now try to move all unused files into the "dead" directory(ies) */
2834 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2835 struct stat statbuf;
2839 /* don't move the file across filesystems, just
2840 stick it in the `dead_dir_name' directory
2841 on whichever filesystem it was already on.
2844 if ((*x).find ("/sounds/") != string::npos) {
2846 /* old school, go up 1 level */
2848 newpath = Glib::path_get_dirname (*x); // "sounds"
2849 newpath = Glib::path_get_dirname (newpath); // "session-name"
2853 /* new school, go up 4 levels */
2855 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2856 newpath = Glib::path_get_dirname (newpath); // "session-name"
2857 newpath = Glib::path_get_dirname (newpath); // "interchange"
2858 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2861 newpath = Glib::build_filename (newpath, dead_dir_name);
2863 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2864 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2868 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2870 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2872 /* the new path already exists, try versioning */
2874 char buf[PATH_MAX+1];
2878 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2881 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2882 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2886 if (version == 999) {
2887 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2891 newpath = newpath_v;
2896 /* it doesn't exist, or we can't read it or something */
2900 stat ((*x).c_str(), &statbuf);
2902 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2903 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2904 (*x), newpath, strerror (errno))
2909 /* see if there an easy to find peakfile for this file, and remove it.
2912 string base = basename_nosuffix (*x);
2913 base += "%A"; /* this is what we add for the channel suffix of all native files,
2914 or for the first channel of embedded files. it will miss
2915 some peakfiles for other channels
2917 string peakpath = peak_path (base);
2919 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2920 if (::unlink (peakpath.c_str()) != 0) {
2921 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2922 peakpath, _path, strerror (errno))
2924 /* try to back out */
2925 ::rename (newpath.c_str(), _path.c_str());
2930 rep.paths.push_back (*x);
2931 rep.space += statbuf.st_size;
2934 /* dump the history list */
2938 /* save state so we don't end up a session file
2939 referring to non-existent sources.
2946 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2952 Session::cleanup_trash_sources (CleanupReport& rep)
2954 // FIXME: needs adaptation for MIDI
2956 vector<space_and_path>::iterator i;
2962 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2964 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2966 clear_directory (dead_dir, &rep.space, &rep.paths);
2973 Session::set_dirty ()
2975 bool was_dirty = dirty();
2977 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2981 DirtyChanged(); /* EMIT SIGNAL */
2987 Session::set_clean ()
2989 bool was_dirty = dirty();
2991 _state_of_the_state = Clean;
2995 DirtyChanged(); /* EMIT SIGNAL */
3000 Session::set_deletion_in_progress ()
3002 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3006 Session::clear_deletion_in_progress ()
3008 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3012 Session::add_controllable (boost::shared_ptr<Controllable> c)
3014 /* this adds a controllable to the list managed by the Session.
3015 this is a subset of those managed by the Controllable class
3016 itself, and represents the only ones whose state will be saved
3017 as part of the session.
3020 Glib::Threads::Mutex::Lock lm (controllables_lock);
3021 controllables.insert (c);
3024 struct null_deleter { void operator()(void const *) const {} };
3027 Session::remove_controllable (Controllable* c)
3029 if (_state_of_the_state & Deletion) {
3033 Glib::Threads::Mutex::Lock lm (controllables_lock);
3035 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3037 if (x != controllables.end()) {
3038 controllables.erase (x);
3042 boost::shared_ptr<Controllable>
3043 Session::controllable_by_id (const PBD::ID& id)
3045 Glib::Threads::Mutex::Lock lm (controllables_lock);
3047 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3048 if ((*i)->id() == id) {
3053 return boost::shared_ptr<Controllable>();
3056 boost::shared_ptr<Controllable>
3057 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3059 boost::shared_ptr<Controllable> c;
3060 boost::shared_ptr<Route> r;
3062 switch (desc.top_level_type()) {
3063 case ControllableDescriptor::NamedRoute:
3065 std::string str = desc.top_level_name();
3066 if (str == "master") {
3068 } else if (str == "control" || str == "listen") {
3071 r = route_by_name (desc.top_level_name());
3076 case ControllableDescriptor::RemoteControlID:
3077 r = route_by_remote_id (desc.rid());
3085 switch (desc.subtype()) {
3086 case ControllableDescriptor::Gain:
3087 c = r->gain_control ();
3090 case ControllableDescriptor::Solo:
3091 c = r->solo_control();
3094 case ControllableDescriptor::Mute:
3095 c = r->mute_control();
3098 case ControllableDescriptor::Recenable:
3100 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3103 c = t->rec_enable_control ();
3108 case ControllableDescriptor::PanDirection:
3110 c = r->pannable()->pan_azimuth_control;
3114 case ControllableDescriptor::PanWidth:
3116 c = r->pannable()->pan_width_control;
3120 case ControllableDescriptor::PanElevation:
3122 c = r->pannable()->pan_elevation_control;
3126 case ControllableDescriptor::Balance:
3127 /* XXX simple pan control */
3130 case ControllableDescriptor::PluginParameter:
3132 uint32_t plugin = desc.target (0);
3133 uint32_t parameter_index = desc.target (1);
3135 /* revert to zero based counting */
3141 if (parameter_index > 0) {
3145 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3148 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3149 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3154 case ControllableDescriptor::SendGain:
3156 uint32_t send = desc.target (0);
3158 /* revert to zero-based counting */
3164 boost::shared_ptr<Processor> p = r->nth_send (send);
3167 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3168 boost::shared_ptr<Amp> a = s->amp();
3171 c = s->amp()->gain_control();
3178 /* relax and return a null pointer */
3186 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3189 Stateful::add_instant_xml (node, _path);
3192 if (write_to_config) {
3193 Config->add_instant_xml (node);
3198 Session::instant_xml (const string& node_name)
3200 return Stateful::instant_xml (node_name, _path);
3204 Session::save_history (string snapshot_name)
3212 if (snapshot_name.empty()) {
3213 snapshot_name = _current_snapshot_name;
3216 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3217 const string backup_filename = history_filename + backup_suffix;
3218 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3219 const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3221 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3222 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3223 error << _("could not backup old history file, current history not saved") << endmsg;
3228 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3232 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3234 if (!tree.write (xml_path))
3236 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3238 if (g_remove (xml_path.c_str()) != 0) {
3239 error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3240 xml_path, g_strerror (errno)) << endmsg;
3242 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3243 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3244 backup_path, g_strerror (errno)) << endmsg;
3254 Session::restore_history (string snapshot_name)
3258 if (snapshot_name.empty()) {
3259 snapshot_name = _current_snapshot_name;
3262 const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3263 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3265 info << "Loading history from " << xml_path << endmsg;
3267 if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3268 info << string_compose (_("%1: no history file \"%2\" for this session."),
3269 _name, xml_path) << endmsg;
3273 if (!tree.read (xml_path)) {
3274 error << string_compose (_("Could not understand session history file \"%1\""),
3275 xml_path) << endmsg;
3282 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3285 UndoTransaction* ut = new UndoTransaction ();
3288 ut->set_name(t->property("name")->value());
3289 stringstream ss(t->property("tv-sec")->value());
3291 ss.str(t->property("tv-usec")->value());
3293 ut->set_timestamp(tv);
3295 for (XMLNodeConstIterator child_it = t->children().begin();
3296 child_it != t->children().end(); child_it++)
3298 XMLNode *n = *child_it;
3301 if (n->name() == "MementoCommand" ||
3302 n->name() == "MementoUndoCommand" ||
3303 n->name() == "MementoRedoCommand") {
3305 if ((c = memento_command_factory(n))) {
3309 } else if (n->name() == "NoteDiffCommand") {
3310 PBD::ID id (n->property("midi-source")->value());
3311 boost::shared_ptr<MidiSource> midi_source =
3312 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3314 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3316 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3319 } else if (n->name() == "SysExDiffCommand") {
3321 PBD::ID id (n->property("midi-source")->value());
3322 boost::shared_ptr<MidiSource> midi_source =
3323 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3325 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3327 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3330 } else if (n->name() == "PatchChangeDiffCommand") {
3332 PBD::ID id (n->property("midi-source")->value());
3333 boost::shared_ptr<MidiSource> midi_source =
3334 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3336 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3338 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3341 } else if (n->name() == "StatefulDiffCommand") {
3342 if ((c = stateful_diff_command_factory (n))) {
3343 ut->add_command (c);
3346 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3357 Session::config_changed (std::string p, bool ours)
3363 if (p == "seamless-loop") {
3365 } else if (p == "rf-speed") {
3367 } else if (p == "auto-loop") {
3369 } else if (p == "auto-input") {
3371 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3372 /* auto-input only makes a difference if we're rolling */
3373 set_track_monitor_input_status (!config.get_auto_input());
3376 } else if (p == "punch-in") {
3380 if ((location = _locations->auto_punch_location()) != 0) {
3382 if (config.get_punch_in ()) {
3383 replace_event (SessionEvent::PunchIn, location->start());
3385 remove_event (location->start(), SessionEvent::PunchIn);
3389 } else if (p == "punch-out") {
3393 if ((location = _locations->auto_punch_location()) != 0) {
3395 if (config.get_punch_out()) {
3396 replace_event (SessionEvent::PunchOut, location->end());
3398 clear_events (SessionEvent::PunchOut);
3402 } else if (p == "edit-mode") {
3404 Glib::Threads::Mutex::Lock lm (playlists->lock);
3406 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3407 (*i)->set_edit_mode (Config->get_edit_mode ());
3410 } else if (p == "use-video-sync") {
3412 waiting_for_sync_offset = config.get_use_video_sync();
3414 } else if (p == "mmc-control") {
3416 //poke_midi_thread ();
3418 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3420 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3422 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3424 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3426 } else if (p == "midi-control") {
3428 //poke_midi_thread ();
3430 } else if (p == "raid-path") {
3432 setup_raid_path (config.get_raid_path());
3434 } else if (p == "timecode-format") {
3438 } else if (p == "video-pullup") {
3442 } else if (p == "seamless-loop") {
3444 if (play_loop && transport_rolling()) {
3445 // to reset diskstreams etc
3446 request_play_loop (true);
3449 } else if (p == "rf-speed") {
3451 cumulative_rf_motion = 0;
3454 } else if (p == "click-sound") {
3456 setup_click_sounds (1);
3458 } else if (p == "click-emphasis-sound") {
3460 setup_click_sounds (-1);
3462 } else if (p == "clicking") {
3464 if (Config->get_clicking()) {
3465 if (_click_io && click_data) { // don't require emphasis data
3472 } else if (p == "click-gain") {
3475 _click_gain->set_gain (Config->get_click_gain(), this);
3478 } else if (p == "send-mtc") {
3480 if (Config->get_send_mtc ()) {
3481 /* mark us ready to send */
3482 next_quarter_frame_to_send = 0;
3485 } else if (p == "send-mmc") {
3487 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3489 } else if (p == "midi-feedback") {
3491 session_midi_feedback = Config->get_midi_feedback();
3493 } else if (p == "jack-time-master") {
3495 engine().reset_timebase ();
3497 } else if (p == "native-file-header-format") {
3499 if (!first_file_header_format_reset) {
3500 reset_native_file_format ();
3503 first_file_header_format_reset = false;
3505 } else if (p == "native-file-data-format") {
3507 if (!first_file_data_format_reset) {
3508 reset_native_file_format ();
3511 first_file_data_format_reset = false;
3513 } else if (p == "external-sync") {
3514 if (!config.get_external_sync()) {
3515 drop_sync_source ();
3517 switch_to_sync_source (Config->get_sync_source());
3519 } else if (p == "denormal-model") {
3521 } else if (p == "history-depth") {
3522 set_history_depth (Config->get_history_depth());
3523 } else if (p == "remote-model") {
3524 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3527 } else if (p == "sync-all-route-ordering") {
3529 /* sync to editor order unless mixer is used for remote IDs
3532 switch (Config->get_remote_model()) {
3534 sync_order_keys (EditorSort);
3537 sync_order_keys (EditorSort);
3540 sync_order_keys (MixerSort);
3543 } else if (p == "initial-program-change") {
3545 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3548 buf[0] = MIDI::program; // channel zero by default
3549 buf[1] = (Config->get_initial_program_change() & 0x7f);
3551 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3553 } else if (p == "solo-mute-override") {
3554 // catch_up_on_solo_mute_override ();
3555 } else if (p == "listen-position" || p == "pfl-position") {
3556 listen_position_changed ();
3557 } else if (p == "solo-control-is-listen-control") {
3558 solo_control_mode_changed ();
3559 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3560 last_timecode_valid = false;
3561 } else if (p == "playback-buffer-seconds") {
3562 AudioSource::allocate_working_buffers (frame_rate());
3563 } else if (p == "automation-thinning-factor") {
3564 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3565 } else if (p == "ltc-source-port") {
3566 reconnect_ltc_input ();
3567 } else if (p == "ltc-sink-port") {
3568 reconnect_ltc_output ();
3569 } else if (p == "timecode-generator-offset") {
3570 ltc_tx_parse_offset();
3577 Session::set_history_depth (uint32_t d)
3579 _history.set_depth (d);
3583 Session::load_diskstreams_2X (XMLNode const & node, int)
3586 XMLNodeConstIterator citer;
3588 clist = node.children();
3590 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3593 /* diskstreams added automatically by DiskstreamCreated handler */
3594 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3595 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3596 _diskstreams_2X.push_back (dsp);
3598 error << _("Session: unknown diskstream type in XML") << endmsg;
3602 catch (failed_constructor& err) {
3603 error << _("Session: could not load diskstream via XML state") << endmsg;
3611 /** Connect things to the MMC object */
3613 Session::setup_midi_machine_control ()
3615 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3617 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3618 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3619 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3620 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3621 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3622 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3623 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3624 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3625 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3626 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3627 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3628 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3629 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3631 /* also handle MIDI SPP because its so common */
3633 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3634 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3635 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3638 boost::shared_ptr<Controllable>
3639 Session::solo_cut_control() const
3641 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3642 controls in Ardour that currently get presented to the user in the GUI that require
3643 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3645 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3646 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3650 return _solo_cut_control;
3654 Session::rename (const std::string& new_name)
3656 string legal_name = legalize_for_path (new_name);
3662 string const old_sources_root = _session_dir->sources_root();
3664 #define RENAME ::rename
3669 * interchange subdirectory
3673 * Backup files are left unchanged and not renamed.
3676 /* pass one: not 100% safe check that the new directory names don't
3680 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3685 /* this is a stupid hack because Glib::path_get_dirname() is
3686 * lexical-only, and so passing it /a/b/c/ gives a different
3687 * result than passing it /a/b/c ...
3690 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3691 oldstr = oldstr.substr (0, oldstr.length() - 1);
3694 string base = Glib::path_get_dirname (oldstr);
3695 string p = Glib::path_get_basename (oldstr);
3697 newstr = Glib::build_filename (base, legal_name);
3699 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3706 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3711 /* this is a stupid hack because Glib::path_get_dirname() is
3712 * lexical-only, and so passing it /a/b/c/ gives a different
3713 * result than passing it /a/b/c ...
3716 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3717 oldstr = oldstr.substr (0, oldstr.length() - 1);
3720 string base = Glib::path_get_dirname (oldstr);
3721 string p = Glib::path_get_basename (oldstr);
3723 newstr = Glib::build_filename (base, legal_name);
3725 cerr << "Rename " << oldstr << " => " << newstr << endl;
3727 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3732 (*_session_dir) = newstr;
3737 /* directory below interchange */
3739 v.push_back (newstr);
3740 v.push_back (interchange_dir_name);
3743 oldstr = Glib::build_filename (v);
3746 v.push_back (newstr);
3747 v.push_back (interchange_dir_name);
3748 v.push_back (legal_name);
3750 newstr = Glib::build_filename (v);
3752 cerr << "Rename " << oldstr << " => " << newstr << endl;
3754 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3761 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3762 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3764 cerr << "Rename " << oldstr << " => " << newstr << endl;
3766 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3773 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3775 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3776 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3778 cerr << "Rename " << oldstr << " => " << newstr << endl;
3780 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3785 /* update file source paths */
3787 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3788 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3790 string p = fs->path ();
3791 boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3796 /* remove old name from recent sessions */
3798 remove_recent_sessions (_path);
3801 _current_snapshot_name = new_name;
3806 /* save state again to get everything just right */
3808 save_state (_current_snapshot_name);
3811 /* add to recent sessions */
3813 store_recent_sessions (new_name, _path);