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/named_selection.h"
97 #include "ardour/pannable.h"
98 #include "ardour/playlist_factory.h"
99 #include "ardour/port.h"
100 #include "ardour/processor.h"
101 #include "ardour/proxy_controllable.h"
102 #include "ardour/recent_sessions.h"
103 #include "ardour/region_factory.h"
104 #include "ardour/route_group.h"
105 #include "ardour/send.h"
106 #include "ardour/session.h"
107 #include "ardour/session_directory.h"
108 #include "ardour/session_metadata.h"
109 #include "ardour/session_playlists.h"
110 #include "ardour/session_state_utils.h"
111 #include "ardour/silentfilesource.h"
112 #include "ardour/sndfilesource.h"
113 #include "ardour/source_factory.h"
114 #include "ardour/speakers.h"
115 #include "ardour/template_utils.h"
116 #include "ardour/tempo.h"
117 #include "ardour/ticker.h"
118 #include "ardour/user_bundle.h"
120 #include "control_protocol/control_protocol.h"
126 using namespace ARDOUR;
129 /** @param snapshot_name Snapshot name, without the .ardour prefix */
131 Session::first_stage_init (string fullpath, string snapshot_name)
133 if (fullpath.length() == 0) {
135 throw failed_constructor();
138 char buf[PATH_MAX+1];
139 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
140 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
142 throw failed_constructor();
147 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
148 _path += G_DIR_SEPARATOR;
151 /* these two are just provisional settings. set_state()
152 will likely override them.
155 _name = _current_snapshot_name = snapshot_name;
157 set_history_depth (Config->get_history_depth());
159 _current_frame_rate = _engine.frame_rate ();
160 _nominal_frame_rate = _current_frame_rate;
161 _base_frame_rate = _current_frame_rate;
163 _tempo_map = new TempoMap (_current_frame_rate);
164 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
167 _non_soloed_outs_muted = false;
169 _solo_isolated_cnt = 0;
170 g_atomic_int_set (&processing_prohibited, 0);
171 _transport_speed = 0;
172 _default_transport_speed = 1.0;
173 _last_transport_speed = 0;
174 _target_transport_speed = 0;
175 auto_play_legal = false;
176 transport_sub_state = 0;
177 _transport_frame = 0;
178 _requested_return_frame = -1;
179 _session_range_location = 0;
180 g_atomic_int_set (&_record_status, Disabled);
181 loop_changing = false;
184 _last_roll_location = 0;
185 _last_roll_or_reversal_location = 0;
186 _last_record_location = 0;
187 pending_locate_frame = 0;
188 pending_locate_roll = false;
189 pending_locate_flush = false;
190 state_was_pending = false;
192 outbound_mtc_timecode_frame = 0;
193 next_quarter_frame_to_send = -1;
194 current_block_size = 0;
195 solo_update_disabled = false;
196 _have_captured = false;
197 _worst_output_latency = 0;
198 _worst_input_latency = 0;
199 _worst_track_latency = 0;
200 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
201 _was_seamless = Config->get_seamless_loop ();
203 _send_qf_mtc = false;
204 _pframes_since_last_mtc = 0;
205 g_atomic_int_set (&_playback_load, 100);
206 g_atomic_int_set (&_capture_load, 100);
209 pending_abort = 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);
370 /* initial program change will be delivered later; see ::config_changed() */
372 _state_of_the_state = Clean;
374 Port::set_connecting_blocked (false);
376 DirtyChanged (); /* EMIT SIGNAL */
378 if (state_was_pending) {
379 save_state (_current_snapshot_name);
380 remove_pending_capture_state ();
381 state_was_pending = false;
384 BootMessage (_("Session loading complete"));
390 Session::raid_path () const
392 SearchPath raid_search_path;
394 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
395 raid_search_path += (*i).path;
398 return raid_search_path.to_string ();
402 Session::setup_raid_path (string path)
411 session_dirs.clear ();
413 SearchPath search_path(path);
414 SearchPath sound_search_path;
415 SearchPath midi_search_path;
417 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
419 sp.blocks = 0; // not needed
420 session_dirs.push_back (sp);
422 SessionDirectory sdir(sp.path);
424 sound_search_path += sdir.sound_path ();
425 midi_search_path += sdir.midi_path ();
428 // reset the round-robin soundfile path thingie
429 last_rr_session_dir = session_dirs.begin();
433 Session::path_is_within_session (const std::string& path)
435 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
436 if (PBD::path_is_within (i->path, path)) {
444 Session::ensure_subdirs ()
448 dir = session_directory().peak_path();
450 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
451 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
455 dir = session_directory().sound_path();
457 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
458 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
462 dir = session_directory().midi_path();
464 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
465 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
469 dir = session_directory().dead_path();
471 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
472 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
476 dir = session_directory().export_path();
478 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
479 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483 dir = analysis_dir ();
485 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
486 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
490 dir = plugins_dir ();
492 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
493 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
497 dir = externals_dir ();
499 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
500 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
507 /** @param session_template directory containing session template, or empty.
508 * Caller must not hold process lock.
511 Session::create (const string& session_template, BusProfile* bus_profile)
513 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
514 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
518 if (ensure_subdirs ()) {
522 _writable = exists_and_writable (_path);
524 if (!session_template.empty()) {
525 std::string in_path = session_template_dir_to_file (session_template);
527 ifstream in(in_path.c_str());
530 string out_path = _path;
532 out_path += statefile_suffix;
534 ofstream out(out_path.c_str());
540 /* Copy plugin state files from template to new session */
541 std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
542 copy_files (template_plugins, plugins_dir ());
547 error << string_compose (_("Could not open %1 for writing session template"), out_path)
553 error << string_compose (_("Could not open session template %1 for reading"), in_path)
560 /* set initial start + end point */
562 _state_of_the_state = Clean;
564 /* set up Master Out and Control Out if necessary */
569 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
571 if (bus_profile->master_out_channels) {
572 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
576 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
577 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
580 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
581 r->input()->ensure_io (count, false, this);
582 r->output()->ensure_io (count, false, this);
588 /* prohibit auto-connect to master, because there isn't one */
589 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
593 add_routes (rl, false, false, false);
596 /* this allows the user to override settings with an environment variable.
599 if (no_auto_connect()) {
600 bus_profile->input_ac = AutoConnectOption (0);
601 bus_profile->output_ac = AutoConnectOption (0);
604 Config->set_input_auto_connect (bus_profile->input_ac);
605 Config->set_output_auto_connect (bus_profile->output_ac);
608 if (Config->get_use_monitor_bus() && bus_profile) {
609 add_monitor_section ();
618 Session::maybe_write_autosave()
620 if (dirty() && record_status() != Recording) {
621 save_state("", true);
626 Session::remove_pending_capture_state ()
628 std::string pending_state_file_path(_session_dir->root_path());
630 pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
632 if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
634 if (g_remove (pending_state_file_path.c_str()) != 0) {
635 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
636 pending_state_file_path, g_strerror (errno)) << endmsg;
640 /** Rename a state file.
641 * @param old_name Old snapshot name.
642 * @param new_name New snapshot name.
645 Session::rename_state (string old_name, string new_name)
647 if (old_name == _current_snapshot_name || old_name == _name) {
648 /* refuse to rename the current snapshot or the "main" one */
652 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
653 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
655 const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
656 const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
658 if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
659 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
660 old_name, new_name, g_strerror(errno)) << endmsg;
664 /** Remove a state file.
665 * @param snapshot_name Snapshot name.
668 Session::remove_state (string snapshot_name)
670 if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
671 // refuse to remove the current snapshot or the "main" one
675 std::string xml_path(_session_dir->root_path());
677 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
679 if (!create_backup_file (xml_path)) {
680 // don't remove it if a backup can't be made
681 // create_backup_file will log the error.
686 if (g_remove (xml_path.c_str()) != 0) {
687 error << string_compose(_("Could not remove state file at path \"%1\" (%2)"),
688 xml_path, g_strerror (errno)) << endmsg;
692 #ifdef HAVE_JACK_SESSION
694 Session::jack_session_event (jack_session_event_t * event)
698 struct tm local_time;
701 localtime_r (&n, &local_time);
702 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
704 if (event->type == JackSessionSaveTemplate)
706 if (save_template( timebuf )) {
707 event->flags = JackSessionSaveError;
709 string cmd ("ardour3 -P -U ");
710 cmd += event->client_uuid;
714 event->command_line = strdup (cmd.c_str());
719 if (save_state (timebuf)) {
720 event->flags = JackSessionSaveError;
722 std::string xml_path (_session_dir->root_path());
723 std::string legalized_filename = legalize_for_path (timebuf) + statefile_suffix;
724 xml_path = Glib::build_filename (xml_path, legalized_filename);
726 string cmd ("ardour3 -P -U ");
727 cmd += event->client_uuid;
732 event->command_line = strdup (cmd.c_str());
736 jack_session_reply (_engine.jack(), event);
738 if (event->type == JackSessionSaveAndQuit) {
739 Quit (); /* EMIT SIGNAL */
742 jack_session_event_free( event );
746 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
748 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
751 std::string xml_path(_session_dir->root_path());
753 if (!_writable || (_state_of_the_state & CannotSave)) {
757 if (!_engine.connected ()) {
758 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
764 /* tell sources we're saving first, in case they write out to a new file
765 * which should be saved with the state rather than the old one */
766 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
768 i->second->session_saved();
769 } catch (Evoral::SMF::FileError& e) {
770 error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
774 tree.set_root (&get_state());
776 if (snapshot_name.empty()) {
777 snapshot_name = _current_snapshot_name;
778 } else if (switch_to_snapshot) {
779 _current_snapshot_name = snapshot_name;
784 /* proper save: use statefile_suffix (.ardour in English) */
786 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
788 /* make a backup copy of the old file */
790 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
791 // create_backup_file will log the error
797 /* pending save: use pending_suffix (.pending in English) */
798 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
801 std::string tmp_path(_session_dir->root_path());
802 tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
804 // cerr << "actually writing state to " << xml_path << endl;
806 if (!tree.write (tmp_path)) {
807 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
808 if (g_remove (tmp_path.c_str()) != 0) {
809 error << string_compose(_("Could not remove temporary state file at path \"%1\" (%2)"),
810 tmp_path, g_strerror (errno)) << endmsg;
816 if (::rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
817 error << string_compose (_("could not rename temporary session file %1 to %2"),
818 tmp_path, xml_path) << endmsg;
819 if (g_remove (tmp_path.c_str()) != 0) {
820 error << string_compose(_("Could not remove temporary state file at path \"%1\" (%2)"),
821 tmp_path, g_strerror (errno)) << endmsg;
829 save_history (snapshot_name);
831 bool was_dirty = dirty();
833 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
836 DirtyChanged (); /* EMIT SIGNAL */
839 StateSaved (snapshot_name); /* EMIT SIGNAL */
846 Session::restore_state (string snapshot_name)
848 if (load_state (snapshot_name) == 0) {
849 set_state (*state_tree->root(), Stateful::loading_state_version);
856 Session::load_state (string snapshot_name)
861 state_was_pending = false;
863 /* check for leftover pending state from a crashed capture attempt */
865 std::string xmlpath(_session_dir->root_path());
866 xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
868 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
870 /* there is pending state from a crashed capture attempt */
872 boost::optional<int> r = AskAboutPendingState();
873 if (r.get_value_or (1)) {
874 state_was_pending = true;
878 if (!state_was_pending) {
879 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
882 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
883 xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
884 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
885 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
890 state_tree = new XMLTree;
894 _writable = exists_and_writable (xmlpath);
896 if (!state_tree->read (xmlpath)) {
897 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
903 XMLNode& root (*state_tree->root());
905 if (root.name() != X_("Session")) {
906 error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
912 const XMLProperty* prop;
914 if ((prop = root.property ("version")) == 0) {
915 /* no version implies very old version of Ardour */
916 Stateful::loading_state_version = 1000;
918 if (prop->value().find ('.') != string::npos) {
919 /* old school version format */
920 if (prop->value()[0] == '2') {
921 Stateful::loading_state_version = 2000;
923 Stateful::loading_state_version = 3000;
926 Stateful::loading_state_version = atoi (prop->value());
930 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
932 std::string backup_path(_session_dir->root_path());
933 std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
934 backup_path = Glib::build_filename (backup_path, backup_filename);
936 // only create a backup for a given statefile version once
938 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
940 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
941 xmlpath, backup_path, PROGRAM_NAME)
944 if (!copy_file (xmlpath, backup_path)) {;
954 Session::load_options (const XMLNode& node)
956 LocaleGuard lg (X_("POSIX"));
957 config.set_variables (node);
968 Session::get_template()
970 /* if we don't disable rec-enable, diskstreams
971 will believe they need to store their capture
972 sources in their state node.
975 disable_record (false);
981 Session::state (bool full_state)
983 XMLNode* node = new XMLNode("Session");
987 snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
988 node->add_property("version", buf);
990 /* store configuration settings */
994 node->add_property ("name", _name);
995 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
996 node->add_property ("sample-rate", buf);
998 if (session_dirs.size() > 1) {
1002 vector<space_and_path>::iterator i = session_dirs.begin();
1003 vector<space_and_path>::iterator next;
1005 ++i; /* skip the first one */
1009 while (i != session_dirs.end()) {
1013 if (next != session_dirs.end()) {
1023 child = node->add_child ("Path");
1024 child->add_content (p);
1028 /* save the ID counter */
1030 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1031 node->add_property ("id-counter", buf);
1033 /* save the event ID counter */
1035 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1036 node->add_property ("event-counter", buf);
1038 /* various options */
1040 node->add_child_nocopy (config.get_variables ());
1042 node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1044 child = node->add_child ("Sources");
1047 Glib::Mutex::Lock sl (source_lock);
1049 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1051 /* Don't save information about non-file Sources, or
1052 * about non-destructive file sources that are empty
1053 * and unused by any regions.
1056 boost::shared_ptr<FileSource> fs;
1058 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1060 if (!fs->destructive()) {
1061 if (fs->empty() && !fs->used()) {
1066 child->add_child_nocopy (siter->second->get_state());
1071 child = node->add_child ("Regions");
1074 Glib::Mutex::Lock rl (region_lock);
1075 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1076 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1077 boost::shared_ptr<Region> r = i->second;
1078 /* only store regions not attached to playlists */
1079 if (r->playlist() == 0) {
1080 child->add_child_nocopy (r->state ());
1084 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1086 if (!cassocs.empty()) {
1087 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1089 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1091 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1092 i->first->id().print (buf, sizeof (buf));
1093 can->add_property (X_("copy"), buf);
1094 i->second->id().print (buf, sizeof (buf));
1095 can->add_property (X_("original"), buf);
1096 ca->add_child_nocopy (*can);
1102 node->add_child_nocopy (_locations->get_state());
1104 // for a template, just create a new Locations, populate it
1105 // with the default start and end, and get the state for that.
1106 Locations loc (*this);
1107 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1108 range->set (max_framepos, 0);
1110 node->add_child_nocopy (loc.get_state());
1113 child = node->add_child ("Bundles");
1115 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1116 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1117 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1119 child->add_child_nocopy (b->get_state());
1124 child = node->add_child ("Routes");
1126 boost::shared_ptr<RouteList> r = routes.reader ();
1128 RoutePublicOrderSorter cmp;
1129 RouteList public_order (*r);
1130 public_order.sort (cmp);
1132 /* the sort should have put control outs first */
1135 assert (_monitor_out == public_order.front());
1138 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1139 if (!(*i)->is_hidden()) {
1141 child->add_child_nocopy ((*i)->get_state());
1143 child->add_child_nocopy ((*i)->get_template());
1149 playlists->add_state (node, full_state);
1151 child = node->add_child ("RouteGroups");
1152 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1153 child->add_child_nocopy ((*i)->get_state());
1157 XMLNode* gain_child = node->add_child ("Click");
1158 gain_child->add_child_nocopy (_click_io->state (full_state));
1159 gain_child->add_child_nocopy (_click_gain->state (full_state));
1163 XMLNode* ns_child = node->add_child ("NamedSelections");
1164 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1166 ns_child->add_child_nocopy ((*i)->get_state());
1171 node->add_child_nocopy (_speakers->get_state());
1172 node->add_child_nocopy (_tempo_map->get_state());
1173 node->add_child_nocopy (get_control_protocol_state());
1176 node->add_child_copy (*_extra_xml);
1183 Session::get_control_protocol_state ()
1185 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1186 return cpm.get_state();
1190 Session::set_state (const XMLNode& node, int version)
1194 const XMLProperty* prop;
1197 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1199 if (node.name() != X_("Session")) {
1200 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1204 if ((prop = node.property ("name")) != 0) {
1205 _name = prop->value ();
1208 if ((prop = node.property (X_("sample-rate"))) != 0) {
1210 _nominal_frame_rate = atoi (prop->value());
1212 if (_nominal_frame_rate != _current_frame_rate) {
1213 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1214 if (r.get_value_or (0)) {
1220 setup_raid_path(_session_dir->root_path());
1222 if ((prop = node.property (X_("id-counter"))) != 0) {
1224 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1225 ID::init_counter (x);
1227 /* old sessions used a timebased counter, so fake
1228 the startup ID counter based on a standard
1233 ID::init_counter (now);
1236 if ((prop = node.property (X_("event-counter"))) != 0) {
1237 Evoral::init_event_id_counter (atoi (prop->value()));
1240 IO::disable_connecting ();
1242 Stateful::save_extra_xml (node);
1244 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1245 load_options (*child);
1246 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1247 load_options (*child);
1249 error << _("Session: XML state has no options section") << endmsg;
1252 if (version >= 3000) {
1253 if ((child = find_named_node (node, "Metadata")) == 0) {
1254 warning << _("Session: XML state has no metadata section") << endmsg;
1255 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1260 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1261 _speakers->set_state (*child, version);
1264 if ((child = find_named_node (node, "Sources")) == 0) {
1265 error << _("Session: XML state has no sources section") << endmsg;
1267 } else if (load_sources (*child)) {
1271 if ((child = find_named_node (node, "TempoMap")) == 0) {
1272 error << _("Session: XML state has no Tempo Map section") << endmsg;
1274 } else if (_tempo_map->set_state (*child, version)) {
1278 if ((child = find_named_node (node, "Locations")) == 0) {
1279 error << _("Session: XML state has no locations section") << endmsg;
1281 } else if (_locations->set_state (*child, version)) {
1287 if ((location = _locations->auto_loop_location()) != 0) {
1288 set_auto_loop_location (location);
1291 if ((location = _locations->auto_punch_location()) != 0) {
1292 set_auto_punch_location (location);
1295 if ((location = _locations->session_range_location()) != 0) {
1296 delete _session_range_location;
1297 _session_range_location = location;
1300 if (_session_range_location) {
1301 AudioFileSource::set_header_position_offset (_session_range_location->start());
1304 if ((child = find_named_node (node, "Regions")) == 0) {
1305 error << _("Session: XML state has no Regions section") << endmsg;
1307 } else if (load_regions (*child)) {
1311 if ((child = find_named_node (node, "Playlists")) == 0) {
1312 error << _("Session: XML state has no playlists section") << endmsg;
1314 } else if (playlists->load (*this, *child)) {
1318 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1320 } else if (playlists->load_unused (*this, *child)) {
1324 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1325 if (load_compounds (*child)) {
1330 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1331 if (load_named_selections (*child)) {
1336 if (version >= 3000) {
1337 if ((child = find_named_node (node, "Bundles")) == 0) {
1338 warning << _("Session: XML state has no bundles section") << endmsg;
1341 /* We can't load Bundles yet as they need to be able
1342 to convert from port names to Port objects, which can't happen until
1344 _bundle_xml_node = new XMLNode (*child);
1348 if (version < 3000) {
1349 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1350 error << _("Session: XML state has no diskstreams section") << endmsg;
1352 } else if (load_diskstreams_2X (*child, version)) {
1357 if ((child = find_named_node (node, "Routes")) == 0) {
1358 error << _("Session: XML state has no routes section") << endmsg;
1360 } else if (load_routes (*child, version)) {
1364 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1365 _diskstreams_2X.clear ();
1367 if (version >= 3000) {
1369 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1370 error << _("Session: XML state has no route groups section") << endmsg;
1372 } else if (load_route_groups (*child, version)) {
1376 } else if (version < 3000) {
1378 if ((child = find_named_node (node, "EditGroups")) == 0) {
1379 error << _("Session: XML state has no edit groups section") << endmsg;
1381 } else if (load_route_groups (*child, version)) {
1385 if ((child = find_named_node (node, "MixGroups")) == 0) {
1386 error << _("Session: XML state has no mix groups section") << endmsg;
1388 } else if (load_route_groups (*child, version)) {
1393 if ((child = find_named_node (node, "Click")) == 0) {
1394 warning << _("Session: XML state has no click section") << endmsg;
1395 } else if (_click_io) {
1396 const XMLNodeList& children (child->children());
1397 XMLNodeList::const_iterator i = children.begin();
1398 _click_io->set_state (**i, version);
1400 if (i != children.end()) {
1401 _click_gain->set_state (**i, version);
1405 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1406 ControlProtocolManager::instance().set_protocol_states (*child);
1409 update_have_rec_enabled_track ();
1411 /* here beginneth the second phase ... */
1413 StateReady (); /* EMIT SIGNAL */
1422 Session::load_routes (const XMLNode& node, int version)
1425 XMLNodeConstIterator niter;
1426 RouteList new_routes;
1428 nlist = node.children();
1432 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1434 boost::shared_ptr<Route> route;
1435 if (version < 3000) {
1436 route = XMLRouteFactory_2X (**niter, version);
1438 route = XMLRouteFactory (**niter, version);
1442 error << _("Session: cannot create Route from XML description.") << endmsg;
1446 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1448 new_routes.push_back (route);
1451 add_routes (new_routes, false, false, false);
1456 boost::shared_ptr<Route>
1457 Session::XMLRouteFactory (const XMLNode& node, int version)
1459 boost::shared_ptr<Route> ret;
1461 if (node.name() != "Route") {
1465 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1467 DataType type = DataType::AUDIO;
1468 const XMLProperty* prop = node.property("default-type");
1471 type = DataType (prop->value());
1474 assert (type != DataType::NIL);
1478 boost::shared_ptr<Track> track;
1480 if (type == DataType::AUDIO) {
1481 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1483 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1486 if (track->init()) {
1490 if (track->set_state (node, version)) {
1494 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1495 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1500 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1502 if (r->init () == 0 && r->set_state (node, version) == 0) {
1503 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1504 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1513 boost::shared_ptr<Route>
1514 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1516 boost::shared_ptr<Route> ret;
1518 if (node.name() != "Route") {
1522 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1524 ds_prop = node.property (X_("diskstream"));
1527 DataType type = DataType::AUDIO;
1528 const XMLProperty* prop = node.property("default-type");
1531 type = DataType (prop->value());
1534 assert (type != DataType::NIL);
1538 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1539 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1543 if (i == _diskstreams_2X.end()) {
1544 error << _("Could not find diskstream for route") << endmsg;
1545 return boost::shared_ptr<Route> ();
1548 boost::shared_ptr<Track> track;
1550 if (type == DataType::AUDIO) {
1551 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1553 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1556 if (track->init()) {
1560 if (track->set_state (node, version)) {
1564 track->set_diskstream (*i);
1566 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1567 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1572 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1574 if (r->init () == 0 && r->set_state (node, version) == 0) {
1575 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1576 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1586 Session::load_regions (const XMLNode& node)
1589 XMLNodeConstIterator niter;
1590 boost::shared_ptr<Region> region;
1592 nlist = node.children();
1596 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1597 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1598 error << _("Session: cannot create Region from XML description.");
1599 const XMLProperty *name = (**niter).property("name");
1602 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1613 Session::load_compounds (const XMLNode& node)
1615 XMLNodeList calist = node.children();
1616 XMLNodeConstIterator caiter;
1617 XMLProperty *caprop;
1619 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1620 XMLNode* ca = *caiter;
1624 if ((caprop = ca->property (X_("original"))) == 0) {
1627 orig_id = caprop->value();
1629 if ((caprop = ca->property (X_("copy"))) == 0) {
1632 copy_id = caprop->value();
1634 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1635 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1637 if (!orig || !copy) {
1638 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1644 RegionFactory::add_compound_association (orig, copy);
1651 Session::load_nested_sources (const XMLNode& node)
1654 XMLNodeConstIterator niter;
1656 nlist = node.children();
1658 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1659 if ((*niter)->name() == "Source") {
1661 /* it may already exist, so don't recreate it unnecessarily
1664 XMLProperty* prop = (*niter)->property (X_("id"));
1666 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1670 ID source_id (prop->value());
1672 if (!source_by_id (source_id)) {
1675 SourceFactory::create (*this, **niter, true);
1677 catch (failed_constructor& err) {
1678 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1685 boost::shared_ptr<Region>
1686 Session::XMLRegionFactory (const XMLNode& node, bool full)
1688 const XMLProperty* type = node.property("type");
1692 const XMLNodeList& nlist = node.children();
1694 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1695 XMLNode *child = (*niter);
1696 if (child->name() == "NestedSource") {
1697 load_nested_sources (*child);
1701 if (!type || type->value() == "audio") {
1702 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1703 } else if (type->value() == "midi") {
1704 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1707 } catch (failed_constructor& err) {
1708 return boost::shared_ptr<Region> ();
1711 return boost::shared_ptr<Region> ();
1714 boost::shared_ptr<AudioRegion>
1715 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1717 const XMLProperty* prop;
1718 boost::shared_ptr<Source> source;
1719 boost::shared_ptr<AudioSource> as;
1721 SourceList master_sources;
1722 uint32_t nchans = 1;
1725 if (node.name() != X_("Region")) {
1726 return boost::shared_ptr<AudioRegion>();
1729 if ((prop = node.property (X_("channels"))) != 0) {
1730 nchans = atoi (prop->value().c_str());
1733 if ((prop = node.property ("name")) == 0) {
1734 cerr << "no name for this region\n";
1738 if ((prop = node.property (X_("source-0"))) == 0) {
1739 if ((prop = node.property ("source")) == 0) {
1740 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1741 return boost::shared_ptr<AudioRegion>();
1745 PBD::ID s_id (prop->value());
1747 if ((source = source_by_id (s_id)) == 0) {
1748 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1749 return boost::shared_ptr<AudioRegion>();
1752 as = boost::dynamic_pointer_cast<AudioSource>(source);
1754 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1755 return boost::shared_ptr<AudioRegion>();
1758 sources.push_back (as);
1760 /* pickup other channels */
1762 for (uint32_t n=1; n < nchans; ++n) {
1763 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1764 if ((prop = node.property (buf)) != 0) {
1766 PBD::ID id2 (prop->value());
1768 if ((source = source_by_id (id2)) == 0) {
1769 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1770 return boost::shared_ptr<AudioRegion>();
1773 as = boost::dynamic_pointer_cast<AudioSource>(source);
1775 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1776 return boost::shared_ptr<AudioRegion>();
1778 sources.push_back (as);
1782 for (uint32_t n = 0; n < nchans; ++n) {
1783 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1784 if ((prop = node.property (buf)) != 0) {
1786 PBD::ID id2 (prop->value());
1788 if ((source = source_by_id (id2)) == 0) {
1789 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1790 return boost::shared_ptr<AudioRegion>();
1793 as = boost::dynamic_pointer_cast<AudioSource>(source);
1795 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1796 return boost::shared_ptr<AudioRegion>();
1798 master_sources.push_back (as);
1803 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1805 /* a final detail: this is the one and only place that we know how long missing files are */
1807 if (region->whole_file()) {
1808 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1809 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1811 sfp->set_length (region->length());
1816 if (!master_sources.empty()) {
1817 if (master_sources.size() != nchans) {
1818 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1820 region->set_master_sources (master_sources);
1828 catch (failed_constructor& err) {
1829 return boost::shared_ptr<AudioRegion>();
1833 boost::shared_ptr<MidiRegion>
1834 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1836 const XMLProperty* prop;
1837 boost::shared_ptr<Source> source;
1838 boost::shared_ptr<MidiSource> ms;
1841 if (node.name() != X_("Region")) {
1842 return boost::shared_ptr<MidiRegion>();
1845 if ((prop = node.property ("name")) == 0) {
1846 cerr << "no name for this region\n";
1850 if ((prop = node.property (X_("source-0"))) == 0) {
1851 if ((prop = node.property ("source")) == 0) {
1852 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1853 return boost::shared_ptr<MidiRegion>();
1857 PBD::ID s_id (prop->value());
1859 if ((source = source_by_id (s_id)) == 0) {
1860 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1861 return boost::shared_ptr<MidiRegion>();
1864 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1866 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1867 return boost::shared_ptr<MidiRegion>();
1870 sources.push_back (ms);
1873 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1874 /* a final detail: this is the one and only place that we know how long missing files are */
1876 if (region->whole_file()) {
1877 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1878 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1880 sfp->set_length (region->length());
1888 catch (failed_constructor& err) {
1889 return boost::shared_ptr<MidiRegion>();
1894 Session::get_sources_as_xml ()
1897 XMLNode* node = new XMLNode (X_("Sources"));
1898 Glib::Mutex::Lock lm (source_lock);
1900 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1901 node->add_child_nocopy (i->second->get_state());
1908 Session::path_from_region_name (DataType type, string name, string identifier)
1910 char buf[PATH_MAX+1];
1912 SessionDirectory sdir(get_best_session_directory_for_new_source());
1913 std::string source_dir = ((type == DataType::AUDIO)
1914 ? sdir.sound_path() : sdir.midi_path());
1916 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1918 for (n = 0; n < 999999; ++n) {
1919 if (identifier.length()) {
1920 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1921 identifier.c_str(), n, ext.c_str());
1923 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1927 std::string source_path = Glib::build_filename (source_dir, buf);
1929 if (!Glib::file_test (source_path, Glib::FILE_TEST_EXISTS)) {
1934 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1943 Session::load_sources (const XMLNode& node)
1946 XMLNodeConstIterator niter;
1947 boost::shared_ptr<Source> source;
1949 nlist = node.children();
1953 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1956 if ((source = XMLSourceFactory (**niter)) == 0) {
1957 error << _("Session: cannot create Source from XML description.") << endmsg;
1960 } catch (MissingSource& err) {
1964 if (!no_questions_about_missing_files) {
1965 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1970 switch (user_choice) {
1972 /* user added a new search location, so try again */
1977 /* user asked to quit the entire session load
1982 no_questions_about_missing_files = true;
1986 no_questions_about_missing_files = true;
1991 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1992 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2001 boost::shared_ptr<Source>
2002 Session::XMLSourceFactory (const XMLNode& node)
2004 if (node.name() != "Source") {
2005 return boost::shared_ptr<Source>();
2009 /* note: do peak building in another thread when loading session state */
2010 return SourceFactory::create (*this, node, true);
2013 catch (failed_constructor& err) {
2014 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2015 return boost::shared_ptr<Source>();
2020 Session::save_template (string template_name)
2024 if (_state_of_the_state & CannotSave) {
2028 std::string user_template_dir(user_template_directory());
2030 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
2031 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2032 user_template_dir, g_strerror (errno)) << endmsg;
2036 tree.set_root (&get_template());
2038 std::string template_dir_path(user_template_dir);
2040 /* directory to put the template in */
2041 template_dir_path = Glib::build_filename (template_dir_path, template_name);
2043 if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
2044 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2045 template_dir_path) << endmsg;
2049 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
2050 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
2051 template_dir_path, g_strerror (errno)) << endmsg;
2056 std::string template_file_path(template_dir_path);
2057 template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
2059 if (!tree.write (template_file_path)) {
2060 error << _("template not saved") << endmsg;
2064 /* copy plugin state directory */
2066 std::string template_plugin_state_path(template_dir_path);
2067 template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
2069 if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
2070 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
2071 template_plugin_state_path, g_strerror (errno)) << endmsg;
2075 copy_files (plugins_dir(), template_plugin_state_path);
2081 Session::refresh_disk_space ()
2083 #if HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H
2085 Glib::Mutex::Lock lm (space_lock);
2087 /* get freespace on every FS that is part of the session path */
2089 _total_free_4k_blocks = 0;
2090 _total_free_4k_blocks_uncertain = false;
2092 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2094 struct statfs statfsbuf;
2095 statfs (i->path.c_str(), &statfsbuf);
2097 double const scale = statfsbuf.f_bsize / 4096.0;
2099 /* See if this filesystem is read-only */
2100 struct statvfs statvfsbuf;
2101 statvfs (i->path.c_str(), &statvfsbuf);
2103 /* f_bavail can be 0 if it is undefined for whatever
2104 filesystem we are looking at; Samba shares mounted
2105 via GVFS are an example of this.
2107 if (statfsbuf.f_bavail == 0) {
2108 /* block count unknown */
2110 i->blocks_unknown = true;
2111 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2112 /* read-only filesystem */
2114 i->blocks_unknown = false;
2116 /* read/write filesystem with known space */
2117 i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2118 i->blocks_unknown = false;
2121 _total_free_4k_blocks += i->blocks;
2122 if (i->blocks_unknown) {
2123 _total_free_4k_blocks_uncertain = true;
2130 Session::get_best_session_directory_for_new_source ()
2132 vector<space_and_path>::iterator i;
2133 string result = _session_dir->root_path();
2135 /* handle common case without system calls */
2137 if (session_dirs.size() == 1) {
2141 /* OK, here's the algorithm we're following here:
2143 We want to select which directory to use for
2144 the next file source to be created. Ideally,
2145 we'd like to use a round-robin process so as to
2146 get maximum performance benefits from splitting
2147 the files across multiple disks.
2149 However, in situations without much diskspace, an
2150 RR approach may end up filling up a filesystem
2151 with new files while others still have space.
2152 Its therefore important to pay some attention to
2153 the freespace in the filesystem holding each
2154 directory as well. However, if we did that by
2155 itself, we'd keep creating new files in the file
2156 system with the most space until it was as full
2157 as all others, thus negating any performance
2158 benefits of this RAID-1 like approach.
2160 So, we use a user-configurable space threshold. If
2161 there are at least 2 filesystems with more than this
2162 much space available, we use RR selection between them.
2163 If not, then we pick the filesystem with the most space.
2165 This gets a good balance between the two
2169 refresh_disk_space ();
2171 int free_enough = 0;
2173 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2174 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2179 if (free_enough >= 2) {
2180 /* use RR selection process, ensuring that the one
2184 i = last_rr_session_dir;
2187 if (++i == session_dirs.end()) {
2188 i = session_dirs.begin();
2191 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2192 SessionDirectory sdir(i->path);
2193 if (sdir.create ()) {
2195 last_rr_session_dir = i;
2200 } while (i != last_rr_session_dir);
2204 /* pick FS with the most freespace (and that
2205 seems to actually work ...)
2208 vector<space_and_path> sorted;
2209 space_and_path_ascending_cmp cmp;
2211 sorted = session_dirs;
2212 sort (sorted.begin(), sorted.end(), cmp);
2214 for (i = sorted.begin(); i != sorted.end(); ++i) {
2215 SessionDirectory sdir(i->path);
2216 if (sdir.create ()) {
2218 last_rr_session_dir = i;
2228 Session::load_named_selections (const XMLNode& node)
2231 XMLNodeConstIterator niter;
2234 nlist = node.children();
2238 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2240 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2241 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2249 Session::XMLNamedSelectionFactory (const XMLNode& node)
2252 return new NamedSelection (*this, node);
2255 catch (failed_constructor& err) {
2261 Session::automation_dir () const
2263 return Glib::build_filename (_path, "automation");
2267 Session::analysis_dir () const
2269 return Glib::build_filename (_path, "analysis");
2273 Session::plugins_dir () const
2275 return Glib::build_filename (_path, "plugins");
2279 Session::externals_dir () const
2281 return Glib::build_filename (_path, "externals");
2285 Session::load_bundles (XMLNode const & node)
2287 XMLNodeList nlist = node.children();
2288 XMLNodeConstIterator niter;
2292 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2293 if ((*niter)->name() == "InputBundle") {
2294 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2295 } else if ((*niter)->name() == "OutputBundle") {
2296 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2298 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2307 Session::load_route_groups (const XMLNode& node, int version)
2309 XMLNodeList nlist = node.children();
2310 XMLNodeConstIterator niter;
2314 if (version >= 3000) {
2316 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2317 if ((*niter)->name() == "RouteGroup") {
2318 RouteGroup* rg = new RouteGroup (*this, "");
2319 add_route_group (rg);
2320 rg->set_state (**niter, version);
2324 } else if (version < 3000) {
2326 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2327 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2328 RouteGroup* rg = new RouteGroup (*this, "");
2329 add_route_group (rg);
2330 rg->set_state (**niter, version);
2339 Session::auto_save()
2341 save_state (_current_snapshot_name);
2345 state_file_filter (const string &str, void */*arg*/)
2347 return (str.length() > strlen(statefile_suffix) &&
2348 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2352 bool operator()(const string* a, const string* b) {
2358 remove_end(string* state)
2360 string statename(*state);
2362 string::size_type start,end;
2363 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2364 statename = statename.substr (start+1);
2367 if ((end = statename.rfind(".ardour")) == string::npos) {
2368 end = statename.length();
2371 return new string(statename.substr (0, end));
2375 Session::possible_states (string path)
2377 PathScanner scanner;
2378 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2380 transform(states->begin(), states->end(), states->begin(), remove_end);
2383 sort (states->begin(), states->end(), cmp);
2389 Session::possible_states () const
2391 return possible_states(_path);
2395 Session::add_route_group (RouteGroup* g)
2397 _route_groups.push_back (g);
2398 route_group_added (g); /* EMIT SIGNAL */
2400 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2401 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2402 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2408 Session::remove_route_group (RouteGroup& rg)
2410 list<RouteGroup*>::iterator i;
2412 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2413 _route_groups.erase (i);
2416 route_group_removed (); /* EMIT SIGNAL */
2420 /** Set a new order for our route groups, without adding or removing any.
2421 * @param groups Route group list in the new order.
2424 Session::reorder_route_groups (list<RouteGroup*> groups)
2426 _route_groups = groups;
2428 route_groups_reordered (); /* EMIT SIGNAL */
2434 Session::route_group_by_name (string name)
2436 list<RouteGroup *>::iterator i;
2438 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2439 if ((*i)->name() == name) {
2447 Session::all_route_group() const
2449 return *_all_route_group;
2453 Session::add_commands (vector<Command*> const & cmds)
2455 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2461 Session::begin_reversible_command (const string& name)
2463 begin_reversible_command (g_quark_from_string (name.c_str ()));
2466 /** Begin a reversible command using a GQuark to identify it.
2467 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2468 * but there must be as many begin...()s as there are commit...()s.
2471 Session::begin_reversible_command (GQuark q)
2473 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2474 to hold all the commands that are committed. This keeps the order of
2475 commands correct in the history.
2478 if (_current_trans == 0) {
2479 /* start a new transaction */
2480 assert (_current_trans_quarks.empty ());
2481 _current_trans = new UndoTransaction();
2482 _current_trans->set_name (g_quark_to_string (q));
2485 _current_trans_quarks.push_front (q);
2489 Session::commit_reversible_command (Command *cmd)
2491 assert (_current_trans);
2492 assert (!_current_trans_quarks.empty ());
2497 _current_trans->add_command (cmd);
2500 _current_trans_quarks.pop_front ();
2502 if (!_current_trans_quarks.empty ()) {
2503 /* the transaction we're committing is not the top-level one */
2507 if (_current_trans->empty()) {
2508 /* no commands were added to the transaction, so just get rid of it */
2509 delete _current_trans;
2514 gettimeofday (&now, 0);
2515 _current_trans->set_timestamp (now);
2517 _history.add (_current_trans);
2522 accept_all_audio_files (const string& path, void */*arg*/)
2524 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2528 if (!AudioFileSource::safe_audio_file_extension (path)) {
2536 accept_all_midi_files (const string& path, void */*arg*/)
2538 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2542 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2543 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2544 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2548 accept_all_state_files (const string& path, void */*arg*/)
2550 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2554 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2558 Session::find_all_sources (string path, set<string>& result)
2563 if (!tree.read (path)) {
2567 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2572 XMLNodeConstIterator niter;
2574 nlist = node->children();
2578 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2582 if ((prop = (*niter)->property (X_("type"))) == 0) {
2586 DataType type (prop->value());
2588 if ((prop = (*niter)->property (X_("name"))) == 0) {
2592 if (Glib::path_is_absolute (prop->value())) {
2593 /* external file, ignore */
2601 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2602 result.insert (found_path);
2610 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2612 PathScanner scanner;
2613 vector<string*>* state_files;
2615 string this_snapshot_path;
2621 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2622 ripped = ripped.substr (0, ripped.length() - 1);
2625 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2627 if (state_files == 0) {
2632 this_snapshot_path = _path;
2633 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2634 this_snapshot_path += statefile_suffix;
2636 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2638 if (exclude_this_snapshot && **i == this_snapshot_path) {
2642 if (find_all_sources (**i, result) < 0) {
2650 struct RegionCounter {
2651 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2652 AudioSourceList::iterator iter;
2653 boost::shared_ptr<Region> region;
2656 RegionCounter() : count (0) {}
2660 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2662 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2663 return r.get_value_or (1);
2667 Session::cleanup_regions ()
2669 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2671 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2673 uint32_t used = playlists->region_use_count (i->second);
2675 if (used == 0 && !i->second->automatic ()) {
2676 RegionFactory::map_remove (i->second);
2680 /* dump the history list */
2687 Session::cleanup_sources (CleanupReport& rep)
2689 // FIXME: needs adaptation to midi
2691 vector<boost::shared_ptr<Source> > dead_sources;
2692 PathScanner scanner;
2695 vector<space_and_path>::iterator i;
2696 vector<space_and_path>::iterator nexti;
2697 vector<string*>* candidates;
2698 vector<string*>* candidates2;
2699 vector<string> unused;
2700 set<string> all_sources;
2705 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2707 /* consider deleting all unused playlists */
2709 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2714 /* sync the "all regions" property of each playlist with its current state
2717 playlists->sync_all_regions_with_regions ();
2719 /* find all un-used sources */
2724 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2726 SourceMap::iterator tmp;
2731 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2735 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2736 dead_sources.push_back (i->second);
2737 i->second->drop_references ();
2743 /* build a list of all the possible audio directories for the session */
2745 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2750 SessionDirectory sdir ((*i).path);
2751 audio_path += sdir.sound_path();
2753 if (nexti != session_dirs.end()) {
2761 /* build a list of all the possible midi directories for the session */
2763 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2768 SessionDirectory sdir ((*i).path);
2769 midi_path += sdir.midi_path();
2771 if (nexti != session_dirs.end()) {
2778 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2779 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2785 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2786 candidates->push_back (*i);
2791 candidates = candidates2; // might still be null
2794 /* find all sources, but don't use this snapshot because the
2795 state file on disk still references sources we may have already
2799 find_all_sources_across_snapshots (all_sources, true);
2801 /* add our current source list
2804 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2805 boost::shared_ptr<FileSource> fs;
2806 SourceMap::iterator tmp = i;
2809 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2810 if (playlists->source_use_count (fs) != 0) {
2811 all_sources.insert (fs->path());
2814 /* we might not remove this source from disk, because it may be used
2815 by other snapshots, but its not being used in this version
2816 so lets get rid of it now, along with any representative regions
2820 RegionFactory::remove_regions_using_source (i->second);
2828 char tmppath1[PATH_MAX+1];
2829 char tmppath2[PATH_MAX+1];
2832 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2837 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2839 if (realpath(spath.c_str(), tmppath1) == 0) {
2840 error << string_compose (_("Cannot expand path %1 (%2)"),
2841 spath, strerror (errno)) << endmsg;
2845 if (realpath((*i).c_str(), tmppath2) == 0) {
2846 error << string_compose (_("Cannot expand path %1 (%2)"),
2847 (*i), strerror (errno)) << endmsg;
2851 if (strcmp(tmppath1, tmppath2) == 0) {
2858 unused.push_back (spath);
2867 /* now try to move all unused files into the "dead" directory(ies) */
2869 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2870 struct stat statbuf;
2874 /* don't move the file across filesystems, just
2875 stick it in the `dead_dir_name' directory
2876 on whichever filesystem it was already on.
2879 if ((*x).find ("/sounds/") != string::npos) {
2881 /* old school, go up 1 level */
2883 newpath = Glib::path_get_dirname (*x); // "sounds"
2884 newpath = Glib::path_get_dirname (newpath); // "session-name"
2888 /* new school, go up 4 levels */
2890 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2891 newpath = Glib::path_get_dirname (newpath); // "session-name"
2892 newpath = Glib::path_get_dirname (newpath); // "interchange"
2893 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2896 newpath = Glib::build_filename (newpath, dead_dir_name);
2898 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2899 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2903 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2905 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2907 /* the new path already exists, try versioning */
2909 char buf[PATH_MAX+1];
2913 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2916 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2917 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2921 if (version == 999) {
2922 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2926 newpath = newpath_v;
2931 /* it doesn't exist, or we can't read it or something */
2935 stat ((*x).c_str(), &statbuf);
2937 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2938 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2939 (*x), newpath, strerror (errno))
2944 /* see if there an easy to find peakfile for this file, and remove it.
2947 string base = basename_nosuffix (*x);
2948 base += "%A"; /* this is what we add for the channel suffix of all native files,
2949 or for the first channel of embedded files. it will miss
2950 some peakfiles for other channels
2952 string peakpath = peak_path (base);
2954 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2955 if (::unlink (peakpath.c_str()) != 0) {
2956 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2957 peakpath, _path, strerror (errno))
2959 /* try to back out */
2960 ::rename (newpath.c_str(), _path.c_str());
2965 rep.paths.push_back (*x);
2966 rep.space += statbuf.st_size;
2969 /* dump the history list */
2973 /* save state so we don't end up a session file
2974 referring to non-existent sources.
2981 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2987 Session::cleanup_trash_sources (CleanupReport& rep)
2989 // FIXME: needs adaptation for MIDI
2991 vector<space_and_path>::iterator i;
2997 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2999 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
3001 clear_directory (dead_dir, &rep.space, &rep.paths);
3008 Session::set_dirty ()
3010 bool was_dirty = dirty();
3012 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3016 DirtyChanged(); /* EMIT SIGNAL */
3022 Session::set_clean ()
3024 bool was_dirty = dirty();
3026 _state_of_the_state = Clean;
3030 DirtyChanged(); /* EMIT SIGNAL */
3035 Session::set_deletion_in_progress ()
3037 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3041 Session::clear_deletion_in_progress ()
3043 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3047 Session::add_controllable (boost::shared_ptr<Controllable> c)
3049 /* this adds a controllable to the list managed by the Session.
3050 this is a subset of those managed by the Controllable class
3051 itself, and represents the only ones whose state will be saved
3052 as part of the session.
3055 Glib::Mutex::Lock lm (controllables_lock);
3056 controllables.insert (c);
3059 struct null_deleter { void operator()(void const *) const {} };
3062 Session::remove_controllable (Controllable* c)
3064 if (_state_of_the_state & Deletion) {
3068 Glib::Mutex::Lock lm (controllables_lock);
3070 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3072 if (x != controllables.end()) {
3073 controllables.erase (x);
3077 boost::shared_ptr<Controllable>
3078 Session::controllable_by_id (const PBD::ID& id)
3080 Glib::Mutex::Lock lm (controllables_lock);
3082 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3083 if ((*i)->id() == id) {
3088 return boost::shared_ptr<Controllable>();
3091 boost::shared_ptr<Controllable>
3092 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3094 boost::shared_ptr<Controllable> c;
3095 boost::shared_ptr<Route> r;
3097 switch (desc.top_level_type()) {
3098 case ControllableDescriptor::NamedRoute:
3100 std::string str = desc.top_level_name();
3101 if (str == "master") {
3103 } else if (str == "control" || str == "listen") {
3106 r = route_by_name (desc.top_level_name());
3111 case ControllableDescriptor::RemoteControlID:
3112 r = route_by_remote_id (desc.rid());
3120 switch (desc.subtype()) {
3121 case ControllableDescriptor::Gain:
3122 c = r->gain_control ();
3125 case ControllableDescriptor::Solo:
3126 c = r->solo_control();
3129 case ControllableDescriptor::Mute:
3130 c = r->mute_control();
3133 case ControllableDescriptor::Recenable:
3135 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3138 c = t->rec_enable_control ();
3143 case ControllableDescriptor::PanDirection:
3145 c = r->pannable()->pan_azimuth_control;
3149 case ControllableDescriptor::PanWidth:
3151 c = r->pannable()->pan_width_control;
3155 case ControllableDescriptor::PanElevation:
3157 c = r->pannable()->pan_elevation_control;
3161 case ControllableDescriptor::Balance:
3162 /* XXX simple pan control */
3165 case ControllableDescriptor::PluginParameter:
3167 uint32_t plugin = desc.target (0);
3168 uint32_t parameter_index = desc.target (1);
3170 /* revert to zero based counting */
3176 if (parameter_index > 0) {
3180 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3183 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3184 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3189 case ControllableDescriptor::SendGain:
3191 uint32_t send = desc.target (0);
3193 /* revert to zero-based counting */
3199 boost::shared_ptr<Processor> p = r->nth_send (send);
3202 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3203 boost::shared_ptr<Amp> a = s->amp();
3206 c = s->amp()->gain_control();
3213 /* relax and return a null pointer */
3221 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3224 Stateful::add_instant_xml (node, _path);
3227 if (write_to_config) {
3228 Config->add_instant_xml (node);
3233 Session::instant_xml (const string& node_name)
3235 return Stateful::instant_xml (node_name, _path);
3239 Session::save_history (string snapshot_name)
3247 if (snapshot_name.empty()) {
3248 snapshot_name = _current_snapshot_name;
3251 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3252 const string backup_filename = history_filename + backup_suffix;
3253 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3254 const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3256 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3257 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3258 error << _("could not backup old history file, current history not saved") << endmsg;
3263 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3267 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3269 if (!tree.write (xml_path))
3271 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3273 if (g_remove (xml_path.c_str()) != 0) {
3274 error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3275 xml_path, g_strerror (errno)) << endmsg;
3277 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3278 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3279 backup_path, g_strerror (errno)) << endmsg;
3289 Session::restore_history (string snapshot_name)
3293 if (snapshot_name.empty()) {
3294 snapshot_name = _current_snapshot_name;
3297 const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3298 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3300 info << "Loading history from " << xml_path << endmsg;
3302 if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3303 info << string_compose (_("%1: no history file \"%2\" for this session."),
3304 _name, xml_path) << endmsg;
3308 if (!tree.read (xml_path)) {
3309 error << string_compose (_("Could not understand session history file \"%1\""),
3310 xml_path) << endmsg;
3317 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3320 UndoTransaction* ut = new UndoTransaction ();
3323 ut->set_name(t->property("name")->value());
3324 stringstream ss(t->property("tv-sec")->value());
3326 ss.str(t->property("tv-usec")->value());
3328 ut->set_timestamp(tv);
3330 for (XMLNodeConstIterator child_it = t->children().begin();
3331 child_it != t->children().end(); child_it++)
3333 XMLNode *n = *child_it;
3336 if (n->name() == "MementoCommand" ||
3337 n->name() == "MementoUndoCommand" ||
3338 n->name() == "MementoRedoCommand") {
3340 if ((c = memento_command_factory(n))) {
3344 } else if (n->name() == "NoteDiffCommand") {
3345 PBD::ID id (n->property("midi-source")->value());
3346 boost::shared_ptr<MidiSource> midi_source =
3347 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3349 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3351 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3354 } else if (n->name() == "SysExDiffCommand") {
3356 PBD::ID id (n->property("midi-source")->value());
3357 boost::shared_ptr<MidiSource> midi_source =
3358 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3360 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3362 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3365 } else if (n->name() == "PatchChangeDiffCommand") {
3367 PBD::ID id (n->property("midi-source")->value());
3368 boost::shared_ptr<MidiSource> midi_source =
3369 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3371 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3373 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3376 } else if (n->name() == "StatefulDiffCommand") {
3377 if ((c = stateful_diff_command_factory (n))) {
3378 ut->add_command (c);
3381 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3392 Session::config_changed (std::string p, bool ours)
3398 if (p == "seamless-loop") {
3400 } else if (p == "rf-speed") {
3402 } else if (p == "auto-loop") {
3404 } else if (p == "auto-input") {
3406 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3407 /* auto-input only makes a difference if we're rolling */
3408 set_track_monitor_input_status (!config.get_auto_input());
3411 } else if (p == "punch-in") {
3415 if ((location = _locations->auto_punch_location()) != 0) {
3417 if (config.get_punch_in ()) {
3418 replace_event (SessionEvent::PunchIn, location->start());
3420 remove_event (location->start(), SessionEvent::PunchIn);
3424 } else if (p == "punch-out") {
3428 if ((location = _locations->auto_punch_location()) != 0) {
3430 if (config.get_punch_out()) {
3431 replace_event (SessionEvent::PunchOut, location->end());
3433 clear_events (SessionEvent::PunchOut);
3437 } else if (p == "edit-mode") {
3439 Glib::Mutex::Lock lm (playlists->lock);
3441 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3442 (*i)->set_edit_mode (Config->get_edit_mode ());
3445 } else if (p == "use-video-sync") {
3447 waiting_for_sync_offset = config.get_use_video_sync();
3449 } else if (p == "mmc-control") {
3451 //poke_midi_thread ();
3453 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3455 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3457 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3459 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3461 } else if (p == "midi-control") {
3463 //poke_midi_thread ();
3465 } else if (p == "raid-path") {
3467 setup_raid_path (config.get_raid_path());
3469 } else if (p == "timecode-format") {
3473 } else if (p == "video-pullup") {
3477 } else if (p == "seamless-loop") {
3479 if (play_loop && transport_rolling()) {
3480 // to reset diskstreams etc
3481 request_play_loop (true);
3484 } else if (p == "rf-speed") {
3486 cumulative_rf_motion = 0;
3489 } else if (p == "click-sound") {
3491 setup_click_sounds (1);
3493 } else if (p == "click-emphasis-sound") {
3495 setup_click_sounds (-1);
3497 } else if (p == "clicking") {
3499 if (Config->get_clicking()) {
3500 if (_click_io && click_data) { // don't require emphasis data
3507 } else if (p == "click-gain") {
3510 _click_gain->set_gain (Config->get_click_gain(), this);
3513 } else if (p == "send-mtc") {
3515 if (Config->get_send_mtc ()) {
3516 /* mark us ready to send */
3517 next_quarter_frame_to_send = 0;
3520 } else if (p == "send-mmc") {
3522 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3524 } else if (p == "midi-feedback") {
3526 session_midi_feedback = Config->get_midi_feedback();
3528 } else if (p == "jack-time-master") {
3530 engine().reset_timebase ();
3532 } else if (p == "native-file-header-format") {
3534 if (!first_file_header_format_reset) {
3535 reset_native_file_format ();
3538 first_file_header_format_reset = false;
3540 } else if (p == "native-file-data-format") {
3542 if (!first_file_data_format_reset) {
3543 reset_native_file_format ();
3546 first_file_data_format_reset = false;
3548 } else if (p == "external-sync") {
3549 if (!config.get_external_sync()) {
3550 drop_sync_source ();
3552 switch_to_sync_source (config.get_sync_source());
3554 } else if (p == "remote-model") {
3555 set_remote_control_ids ();
3556 } else if (p == "denormal-model") {
3558 } else if (p == "history-depth") {
3559 set_history_depth (Config->get_history_depth());
3560 } else if (p == "sync-all-route-ordering") {
3561 sync_order_keys ("session");
3562 } else if (p == "initial-program-change") {
3564 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3567 buf[0] = MIDI::program; // channel zero by default
3568 buf[1] = (Config->get_initial_program_change() & 0x7f);
3570 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3572 } else if (p == "solo-mute-override") {
3573 // catch_up_on_solo_mute_override ();
3574 } else if (p == "listen-position" || p == "pfl-position") {
3575 listen_position_changed ();
3576 } else if (p == "solo-control-is-listen-control") {
3577 solo_control_mode_changed ();
3578 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3579 last_timecode_valid = false;
3580 } else if (p == "playback-buffer-seconds") {
3581 AudioSource::allocate_working_buffers (frame_rate());
3582 } else if (p == "automation-thinning-factor") {
3583 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3590 Session::set_history_depth (uint32_t d)
3592 _history.set_depth (d);
3596 Session::load_diskstreams_2X (XMLNode const & node, int)
3599 XMLNodeConstIterator citer;
3601 clist = node.children();
3603 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3606 /* diskstreams added automatically by DiskstreamCreated handler */
3607 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3608 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3609 _diskstreams_2X.push_back (dsp);
3611 error << _("Session: unknown diskstream type in XML") << endmsg;
3615 catch (failed_constructor& err) {
3616 error << _("Session: could not load diskstream via XML state") << endmsg;
3624 /** Connect things to the MMC object */
3626 Session::setup_midi_machine_control ()
3628 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3630 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3631 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3632 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3633 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3634 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3635 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3636 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3637 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3638 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3639 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3640 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3641 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3642 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3644 /* also handle MIDI SPP because its so common */
3646 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3647 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3648 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3651 boost::shared_ptr<Controllable>
3652 Session::solo_cut_control() const
3654 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3655 controls in Ardour that currently get presented to the user in the GUI that require
3656 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3658 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3659 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3663 return _solo_cut_control;
3667 Session::rename (const std::string& new_name)
3669 string legal_name = legalize_for_path (new_name);
3675 string const old_sources_root = _session_dir->sources_root();
3677 #define RENAME ::rename
3682 * interchange subdirectory
3686 * Backup files are left unchanged and not renamed.
3689 /* pass one: not 100% safe check that the new directory names don't
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 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3719 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3724 /* this is a stupid hack because Glib::path_get_dirname() is
3725 * lexical-only, and so passing it /a/b/c/ gives a different
3726 * result than passing it /a/b/c ...
3729 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3730 oldstr = oldstr.substr (0, oldstr.length() - 1);
3733 string base = Glib::path_get_dirname (oldstr);
3734 string p = Glib::path_get_basename (oldstr);
3736 newstr = Glib::build_filename (base, legal_name);
3738 cerr << "Rename " << oldstr << " => " << newstr << endl;
3740 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3745 (*_session_dir) = newstr;
3750 /* directory below interchange */
3752 v.push_back (newstr);
3753 v.push_back (interchange_dir_name);
3756 oldstr = Glib::build_filename (v);
3759 v.push_back (newstr);
3760 v.push_back (interchange_dir_name);
3761 v.push_back (legal_name);
3763 newstr = Glib::build_filename (v);
3765 cerr << "Rename " << oldstr << " => " << newstr << endl;
3767 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3774 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3775 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3777 cerr << "Rename " << oldstr << " => " << newstr << endl;
3779 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3786 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3788 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3789 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3791 cerr << "Rename " << oldstr << " => " << newstr << endl;
3793 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3798 /* update file source paths */
3800 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3801 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3803 string p = fs->path ();
3804 boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3809 /* remove old name from recent sessions */
3811 remove_recent_sessions (_path);
3814 _current_snapshot_name = new_name;
3819 /* save state again to get everything just right */
3821 save_state (_current_snapshot_name);
3824 /* add to recent sessions */
3826 store_recent_sessions (new_name, _path);