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"
64 #include "evoral/SMF.hpp"
66 #include "pbd/boost_debug.h"
67 #include "pbd/basename.h"
68 #include "pbd/controllable_descriptor.h"
69 #include "pbd/enumwriter.h"
70 #include "pbd/error.h"
71 #include "pbd/file_utils.h"
72 #include "pbd/pathscanner.h"
73 #include "pbd/pthread_utils.h"
74 #include "pbd/stacktrace.h"
75 #include "pbd/convert.h"
76 #include "pbd/clear_dir.h"
78 #include "ardour/amp.h"
79 #include "ardour/audio_diskstream.h"
80 #include "ardour/audio_track.h"
81 #include "ardour/audioengine.h"
82 #include "ardour/audiofilesource.h"
83 #include "ardour/audioregion.h"
84 #include "ardour/automation_control.h"
85 #include "ardour/butler.h"
86 #include "ardour/control_protocol_manager.h"
87 #include "ardour/directory_names.h"
88 #include "ardour/filename_extensions.h"
89 #include "ardour/location.h"
90 #include "ardour/midi_model.h"
91 #include "ardour/midi_patch_manager.h"
92 #include "ardour/midi_region.h"
93 #include "ardour/midi_source.h"
94 #include "ardour/midi_track.h"
95 #include "ardour/pannable.h"
96 #include "ardour/playlist_factory.h"
97 #include "ardour/port.h"
98 #include "ardour/processor.h"
99 #include "ardour/proxy_controllable.h"
100 #include "ardour/recent_sessions.h"
101 #include "ardour/region_factory.h"
102 #include "ardour/route_group.h"
103 #include "ardour/send.h"
104 #include "ardour/session.h"
105 #include "ardour/session_directory.h"
106 #include "ardour/session_metadata.h"
107 #include "ardour/session_playlists.h"
108 #include "ardour/session_state_utils.h"
109 #include "ardour/silentfilesource.h"
110 #include "ardour/sndfilesource.h"
111 #include "ardour/source_factory.h"
112 #include "ardour/speakers.h"
113 #include "ardour/template_utils.h"
114 #include "ardour/tempo.h"
115 #include "ardour/ticker.h"
116 #include "ardour/user_bundle.h"
118 #include "control_protocol/control_protocol.h"
124 using namespace ARDOUR;
127 /** @param snapshot_name Snapshot name, without the .ardour prefix */
129 Session::first_stage_init (string fullpath, string snapshot_name)
131 if (fullpath.length() == 0) {
133 throw failed_constructor();
136 char buf[PATH_MAX+1];
137 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
138 error << string_compose(_("Could not use path %1 (%2)"), buf, strerror(errno)) << endmsg;
140 throw failed_constructor();
145 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
146 _path += G_DIR_SEPARATOR;
149 /* these two are just provisional settings. set_state()
150 will likely override them.
153 _name = _current_snapshot_name = snapshot_name;
155 set_history_depth (Config->get_history_depth());
157 _current_frame_rate = _engine.sample_rate ();
158 _nominal_frame_rate = _current_frame_rate;
159 _base_frame_rate = _current_frame_rate;
161 _tempo_map = new TempoMap (_current_frame_rate);
162 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
165 _non_soloed_outs_muted = false;
167 _solo_isolated_cnt = 0;
168 g_atomic_int_set (&processing_prohibited, 0);
169 _transport_speed = 0;
170 _default_transport_speed = 1.0;
171 _last_transport_speed = 0;
172 _target_transport_speed = 0;
173 auto_play_legal = false;
174 transport_sub_state = 0;
175 _transport_frame = 0;
176 _requested_return_frame = -1;
177 _session_range_location = 0;
178 g_atomic_int_set (&_record_status, Disabled);
179 loop_changing = false;
182 _last_roll_location = 0;
183 _last_roll_or_reversal_location = 0;
184 _last_record_location = 0;
185 pending_locate_frame = 0;
186 pending_locate_roll = false;
187 pending_locate_flush = false;
188 state_was_pending = false;
190 outbound_mtc_timecode_frame = 0;
191 next_quarter_frame_to_send = -1;
192 current_block_size = 0;
193 solo_update_disabled = false;
194 _have_captured = false;
195 _worst_output_latency = 0;
196 _worst_input_latency = 0;
197 _worst_track_latency = 0;
198 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
199 _was_seamless = Config->get_seamless_loop ();
201 _send_qf_mtc = false;
202 _pframes_since_last_mtc = 0;
203 g_atomic_int_set (&_playback_load, 100);
204 g_atomic_int_set (&_capture_load, 100);
207 pending_abort = false;
208 _adding_routes_in_progress = false;
209 destructive_index = 0;
210 first_file_data_format_reset = true;
211 first_file_header_format_reset = true;
212 post_export_sync = false;
215 no_questions_about_missing_files = false;
216 _speakers.reset (new Speakers);
218 ignore_route_processor_changes = false;
219 _pre_export_mmc_enabled = false;
221 AudioDiskstream::allocate_working_buffers();
223 /* default short fade = 15ms */
225 SndFileSource::setup_standard_crossfades (*this, frame_rate());
227 last_mmc_step.tv_sec = 0;
228 last_mmc_step.tv_usec = 0;
231 /* click sounds are unset by default, which causes us to internal
232 waveforms for clicks.
236 click_emphasis_length = 0;
239 process_function = &Session::process_with_events;
241 if (config.get_use_video_sync()) {
242 waiting_for_sync_offset = true;
244 waiting_for_sync_offset = false;
247 last_timecode_when = 0;
248 last_timecode_valid = false;
252 last_rr_session_dir = session_dirs.begin();
253 refresh_disk_space ();
255 /* default: assume simple stereo speaker configuration */
257 _speakers->setup_default_speakers (2);
261 average_slave_delta = 1800; // !!! why 1800 ????
262 have_first_delta_accumulator = false;
263 delta_accumulator_cnt = 0;
264 _slave_state = Stopped;
266 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
267 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
268 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
269 add_controllable (_solo_cut_control);
271 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
273 /* These are all static "per-class" signals */
275 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
276 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
277 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
278 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
279 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
281 /* stop IO objects from doing stuff until we're ready for them */
283 Delivery::disable_panners ();
284 IO::disable_connecting ();
288 Session::second_stage_init ()
290 AudioFileSource::set_peak_dir (_session_dir->peak_path());
293 if (load_state (_current_snapshot_name)) {
298 if (_butler->start_thread()) {
302 if (start_midi_thread ()) {
306 setup_midi_machine_control ();
308 // set_state() will call setup_raid_path(), but if it's a new session we need
309 // to call setup_raid_path() here.
312 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
316 setup_raid_path(_path);
319 /* we can't save till after ::when_engine_running() is called,
320 because otherwise we save state with no connections made.
321 therefore, we reset _state_of_the_state because ::set_state()
322 will have cleared it.
324 we also have to include Loading so that any events that get
325 generated between here and the end of ::when_engine_running()
326 will be processed directly rather than queued.
329 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
331 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
332 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
333 setup_click_sounds (0);
334 setup_midi_control ();
336 /* Pay attention ... */
338 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
339 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
341 midi_clock = new MidiClockTicker ();
342 midi_clock->set_session (this);
345 when_engine_running ();
348 /* handle this one in a different way than all others, so that its clear what happened */
350 catch (AudioEngine::PortRegistrationFailure& err) {
351 error << err.what() << endmsg;
359 BootMessage (_("Reset Remote Controls"));
361 // send_full_time_code (0);
362 _engine.transport_locate (0);
364 AudioEngine::instance()->mmc().send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
365 AudioEngine::instance()->mmc().send (MIDI::MachineControlCommand (Timecode::Time ()));
367 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::Threads::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 session 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)
696 char timebuf[128], *tmp;
698 struct tm local_time;
701 localtime_r (&n, &local_time);
702 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
704 while ((tmp = strchr(timebuf, ':'))) { *tmp = '.'; }
706 if (event->type == JackSessionSaveTemplate)
708 if (save_template( timebuf )) {
709 event->flags = JackSessionSaveError;
711 string cmd ("ardour3 -P -U ");
712 cmd += event->client_uuid;
716 event->command_line = strdup (cmd.c_str());
721 if (save_state (timebuf)) {
722 event->flags = JackSessionSaveError;
724 std::string xml_path (_session_dir->root_path());
725 std::string legalized_filename = legalize_for_path (timebuf) + statefile_suffix;
726 xml_path = Glib::build_filename (xml_path, legalized_filename);
728 string cmd ("ardour3 -P -U ");
729 cmd += event->client_uuid;
734 event->command_line = strdup (cmd.c_str());
738 /* this won't be called if the port engine in use is not JACK, so we do
739 not have to worry about the type of PortEngine::private_handle()
742 jack_client_t* jack_client = (jack_client_t*) AudioEngine::instance()->port_engine().private_handle();
745 jack_session_reply (jack_client, event);
748 if (event->type == JackSessionSaveAndQuit) {
749 Quit (); /* EMIT SIGNAL */
752 jack_session_event_free( event );
756 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
758 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
761 std::string xml_path(_session_dir->root_path());
763 if (!_writable || (_state_of_the_state & CannotSave)) {
767 if (!_engine.connected ()) {
768 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
774 /* tell sources we're saving first, in case they write out to a new file
775 * which should be saved with the state rather than the old one */
776 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
778 i->second->session_saved();
779 } catch (Evoral::SMF::FileError& e) {
780 error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
784 SaveSession (); /* EMIT SIGNAL */
786 tree.set_root (&get_state());
788 if (snapshot_name.empty()) {
789 snapshot_name = _current_snapshot_name;
790 } else if (switch_to_snapshot) {
791 _current_snapshot_name = snapshot_name;
796 /* proper save: use statefile_suffix (.ardour in English) */
798 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
800 /* make a backup copy of the old file */
802 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
803 // create_backup_file will log the error
809 /* pending save: use pending_suffix (.pending in English) */
810 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
813 std::string tmp_path(_session_dir->root_path());
814 tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
816 // cerr << "actually writing state to " << xml_path << endl;
818 if (!tree.write (tmp_path)) {
819 error << string_compose (_("state could not be saved to %1"), tmp_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;
828 if (::rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
829 error << string_compose (_("could not rename temporary session file %1 to %2"),
830 tmp_path, xml_path) << endmsg;
831 if (g_remove (tmp_path.c_str()) != 0) {
832 error << string_compose(_("Could not remove temporary session file at path \"%1\" (%2)"),
833 tmp_path, g_strerror (errno)) << endmsg;
841 save_history (snapshot_name);
843 bool was_dirty = dirty();
845 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
848 DirtyChanged (); /* EMIT SIGNAL */
851 StateSaved (snapshot_name); /* EMIT SIGNAL */
858 Session::restore_state (string snapshot_name)
860 if (load_state (snapshot_name) == 0) {
861 set_state (*state_tree->root(), Stateful::loading_state_version);
868 Session::load_state (string snapshot_name)
873 state_was_pending = false;
875 /* check for leftover pending state from a crashed capture attempt */
877 std::string xmlpath(_session_dir->root_path());
878 xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
880 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
882 /* there is pending state from a crashed capture attempt */
884 boost::optional<int> r = AskAboutPendingState();
885 if (r.get_value_or (1)) {
886 state_was_pending = true;
890 if (!state_was_pending) {
891 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
894 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
895 xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
896 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
897 error << string_compose(_("%1: session file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
902 state_tree = new XMLTree;
906 _writable = exists_and_writable (xmlpath);
908 if (!state_tree->read (xmlpath)) {
909 error << string_compose(_("Could not understand session file %1"), xmlpath) << endmsg;
915 XMLNode& root (*state_tree->root());
917 if (root.name() != X_("Session")) {
918 error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
924 const XMLProperty* prop;
926 if ((prop = root.property ("version")) == 0) {
927 /* no version implies very old version of Ardour */
928 Stateful::loading_state_version = 1000;
930 if (prop->value().find ('.') != string::npos) {
931 /* old school version format */
932 if (prop->value()[0] == '2') {
933 Stateful::loading_state_version = 2000;
935 Stateful::loading_state_version = 3000;
938 Stateful::loading_state_version = atoi (prop->value());
942 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
944 std::string backup_path(_session_dir->root_path());
945 std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
946 backup_path = Glib::build_filename (backup_path, backup_filename);
948 // only create a backup for a given statefile version once
950 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
952 VersionMismatch (xmlpath, backup_path);
954 if (!copy_file (xmlpath, backup_path)) {;
964 Session::load_options (const XMLNode& node)
966 LocaleGuard lg (X_("POSIX"));
967 config.set_variables (node);
978 Session::get_template()
980 /* if we don't disable rec-enable, diskstreams
981 will believe they need to store their capture
982 sources in their state node.
985 disable_record (false);
991 Session::state (bool full_state)
993 XMLNode* node = new XMLNode("Session");
997 snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
998 node->add_property("version", buf);
1000 /* store configuration settings */
1004 node->add_property ("name", _name);
1005 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1006 node->add_property ("sample-rate", buf);
1008 if (session_dirs.size() > 1) {
1012 vector<space_and_path>::iterator i = session_dirs.begin();
1013 vector<space_and_path>::iterator next;
1015 ++i; /* skip the first one */
1019 while (i != session_dirs.end()) {
1023 if (next != session_dirs.end()) {
1033 child = node->add_child ("Path");
1034 child->add_content (p);
1038 /* save the ID counter */
1040 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1041 node->add_property ("id-counter", buf);
1043 /* save the event ID counter */
1045 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1046 node->add_property ("event-counter", buf);
1048 /* various options */
1050 node->add_child_nocopy (config.get_variables ());
1052 node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1054 child = node->add_child ("Sources");
1057 Glib::Threads::Mutex::Lock sl (source_lock);
1059 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1061 /* Don't save information about non-file Sources, or
1062 * about non-destructive file sources that are empty
1063 * and unused by any regions.
1066 boost::shared_ptr<FileSource> fs;
1068 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1070 if (!fs->destructive()) {
1071 if (fs->empty() && !fs->used()) {
1076 child->add_child_nocopy (siter->second->get_state());
1081 child = node->add_child ("Regions");
1084 Glib::Threads::Mutex::Lock rl (region_lock);
1085 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1086 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1087 boost::shared_ptr<Region> r = i->second;
1088 /* only store regions not attached to playlists */
1089 if (r->playlist() == 0) {
1090 if (boost::dynamic_pointer_cast<AudioRegion>(r)) {
1091 child->add_child_nocopy ((boost::dynamic_pointer_cast<AudioRegion>(r))->get_basic_state ());
1093 child->add_child_nocopy (r->get_state ());
1098 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1100 if (!cassocs.empty()) {
1101 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1103 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1105 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1106 i->first->id().print (buf, sizeof (buf));
1107 can->add_property (X_("copy"), buf);
1108 i->second->id().print (buf, sizeof (buf));
1109 can->add_property (X_("original"), buf);
1110 ca->add_child_nocopy (*can);
1116 node->add_child_nocopy (_locations->get_state());
1118 // for a template, just create a new Locations, populate it
1119 // with the default start and end, and get the state for that.
1120 Locations loc (*this);
1121 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1122 range->set (max_framepos, 0);
1124 node->add_child_nocopy (loc.get_state());
1127 child = node->add_child ("Bundles");
1129 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1130 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1131 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1133 child->add_child_nocopy (b->get_state());
1138 child = node->add_child ("Routes");
1140 boost::shared_ptr<RouteList> r = routes.reader ();
1142 RoutePublicOrderSorter cmp;
1143 RouteList public_order (*r);
1144 public_order.sort (cmp);
1146 /* the sort should have put control outs first */
1149 assert (_monitor_out == public_order.front());
1152 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1153 if (!(*i)->is_auditioner()) {
1155 child->add_child_nocopy ((*i)->get_state());
1157 child->add_child_nocopy ((*i)->get_template());
1163 playlists->add_state (node, full_state);
1165 child = node->add_child ("RouteGroups");
1166 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1167 child->add_child_nocopy ((*i)->get_state());
1171 XMLNode* gain_child = node->add_child ("Click");
1172 gain_child->add_child_nocopy (_click_io->state (full_state));
1173 gain_child->add_child_nocopy (_click_gain->state (full_state));
1177 XMLNode* ltc_input_child = node->add_child ("LTC-In");
1178 ltc_input_child->add_child_nocopy (_ltc_input->state (full_state));
1182 XMLNode* ltc_output_child = node->add_child ("LTC-Out");
1183 ltc_output_child->add_child_nocopy (_ltc_output->state (full_state));
1186 node->add_child_nocopy (_speakers->get_state());
1187 node->add_child_nocopy (_tempo_map->get_state());
1188 node->add_child_nocopy (get_control_protocol_state());
1191 node->add_child_copy (*_extra_xml);
1198 Session::get_control_protocol_state ()
1200 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1201 return cpm.get_state();
1205 Session::set_state (const XMLNode& node, int version)
1209 const XMLProperty* prop;
1212 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1214 if (node.name() != X_("Session")) {
1215 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1219 if ((prop = node.property ("name")) != 0) {
1220 _name = prop->value ();
1223 if ((prop = node.property (X_("sample-rate"))) != 0) {
1225 _nominal_frame_rate = atoi (prop->value());
1227 if (_nominal_frame_rate != _current_frame_rate) {
1228 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1229 if (r.get_value_or (0)) {
1235 setup_raid_path(_session_dir->root_path());
1237 if ((prop = node.property (X_("id-counter"))) != 0) {
1239 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1240 ID::init_counter (x);
1242 /* old sessions used a timebased counter, so fake
1243 the startup ID counter based on a standard
1248 ID::init_counter (now);
1251 if ((prop = node.property (X_("event-counter"))) != 0) {
1252 Evoral::init_event_id_counter (atoi (prop->value()));
1255 IO::disable_connecting ();
1257 Stateful::save_extra_xml (node);
1259 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1260 load_options (*child);
1261 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1262 load_options (*child);
1264 error << _("Session: XML state has no options section") << endmsg;
1267 if (version >= 3000) {
1268 if ((child = find_named_node (node, "Metadata")) == 0) {
1269 warning << _("Session: XML state has no metadata section") << endmsg;
1270 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1275 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1276 _speakers->set_state (*child, version);
1279 if ((child = find_named_node (node, "Sources")) == 0) {
1280 error << _("Session: XML state has no sources section") << endmsg;
1282 } else if (load_sources (*child)) {
1286 if ((child = find_named_node (node, "TempoMap")) == 0) {
1287 error << _("Session: XML state has no Tempo Map section") << endmsg;
1289 } else if (_tempo_map->set_state (*child, version)) {
1293 if ((child = find_named_node (node, "Locations")) == 0) {
1294 error << _("Session: XML state has no locations section") << endmsg;
1296 } else if (_locations->set_state (*child, version)) {
1302 if ((location = _locations->auto_loop_location()) != 0) {
1303 set_auto_loop_location (location);
1306 if ((location = _locations->auto_punch_location()) != 0) {
1307 set_auto_punch_location (location);
1310 if ((location = _locations->session_range_location()) != 0) {
1311 delete _session_range_location;
1312 _session_range_location = location;
1315 if (_session_range_location) {
1316 AudioFileSource::set_header_position_offset (_session_range_location->start());
1319 if ((child = find_named_node (node, "Regions")) == 0) {
1320 error << _("Session: XML state has no Regions section") << endmsg;
1322 } else if (load_regions (*child)) {
1326 if ((child = find_named_node (node, "Playlists")) == 0) {
1327 error << _("Session: XML state has no playlists section") << endmsg;
1329 } else if (playlists->load (*this, *child)) {
1333 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1335 } else if (playlists->load_unused (*this, *child)) {
1339 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1340 if (load_compounds (*child)) {
1345 if (version >= 3000) {
1346 if ((child = find_named_node (node, "Bundles")) == 0) {
1347 warning << _("Session: XML state has no bundles section") << endmsg;
1350 /* We can't load Bundles yet as they need to be able
1351 to convert from port names to Port objects, which can't happen until
1353 _bundle_xml_node = new XMLNode (*child);
1357 if (version < 3000) {
1358 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1359 error << _("Session: XML state has no diskstreams section") << endmsg;
1361 } else if (load_diskstreams_2X (*child, version)) {
1366 if ((child = find_named_node (node, "Routes")) == 0) {
1367 error << _("Session: XML state has no routes section") << endmsg;
1369 } else if (load_routes (*child, version)) {
1373 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1374 _diskstreams_2X.clear ();
1376 if (version >= 3000) {
1378 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1379 error << _("Session: XML state has no route groups section") << endmsg;
1381 } else if (load_route_groups (*child, version)) {
1385 } else if (version < 3000) {
1387 if ((child = find_named_node (node, "EditGroups")) == 0) {
1388 error << _("Session: XML state has no edit groups section") << endmsg;
1390 } else if (load_route_groups (*child, version)) {
1394 if ((child = find_named_node (node, "MixGroups")) == 0) {
1395 error << _("Session: XML state has no mix groups section") << endmsg;
1397 } else if (load_route_groups (*child, version)) {
1402 if ((child = find_named_node (node, "Click")) == 0) {
1403 warning << _("Session: XML state has no click section") << endmsg;
1404 } else if (_click_io) {
1405 const XMLNodeList& children (child->children());
1406 XMLNodeList::const_iterator i = children.begin();
1407 _click_io->set_state (**i, version);
1409 if (i != children.end()) {
1410 _click_gain->set_state (**i, version);
1414 if ((child = find_named_node (node, ControlProtocolManager::state_node_name)) != 0) {
1415 ControlProtocolManager::instance().set_state (*child, version);
1418 update_have_rec_enabled_track ();
1420 /* here beginneth the second phase ... */
1422 StateReady (); /* EMIT SIGNAL */
1431 Session::load_routes (const XMLNode& node, int version)
1434 XMLNodeConstIterator niter;
1435 RouteList new_routes;
1437 nlist = node.children();
1441 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1443 boost::shared_ptr<Route> route;
1444 if (version < 3000) {
1445 route = XMLRouteFactory_2X (**niter, version);
1447 route = XMLRouteFactory (**niter, version);
1451 error << _("Session: cannot create Route from XML description.") << endmsg;
1455 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1457 new_routes.push_back (route);
1460 add_routes (new_routes, false, false, false);
1465 boost::shared_ptr<Route>
1466 Session::XMLRouteFactory (const XMLNode& node, int version)
1468 boost::shared_ptr<Route> ret;
1470 if (node.name() != "Route") {
1474 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1476 DataType type = DataType::AUDIO;
1477 const XMLProperty* prop = node.property("default-type");
1480 type = DataType (prop->value());
1483 assert (type != DataType::NIL);
1487 boost::shared_ptr<Track> track;
1489 if (type == DataType::AUDIO) {
1490 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1492 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1495 if (track->init()) {
1499 if (track->set_state (node, version)) {
1503 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1504 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1509 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1511 if (r->init () == 0 && r->set_state (node, version) == 0) {
1512 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1513 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1522 boost::shared_ptr<Route>
1523 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1525 boost::shared_ptr<Route> ret;
1527 if (node.name() != "Route") {
1531 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1533 ds_prop = node.property (X_("diskstream"));
1536 DataType type = DataType::AUDIO;
1537 const XMLProperty* prop = node.property("default-type");
1540 type = DataType (prop->value());
1543 assert (type != DataType::NIL);
1547 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1548 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1552 if (i == _diskstreams_2X.end()) {
1553 error << _("Could not find diskstream for route") << endmsg;
1554 return boost::shared_ptr<Route> ();
1557 boost::shared_ptr<Track> track;
1559 if (type == DataType::AUDIO) {
1560 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1562 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1565 if (track->init()) {
1569 if (track->set_state (node, version)) {
1573 track->set_diskstream (*i);
1575 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1576 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1581 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1583 if (r->init () == 0 && r->set_state (node, version) == 0) {
1584 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1585 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1595 Session::load_regions (const XMLNode& node)
1598 XMLNodeConstIterator niter;
1599 boost::shared_ptr<Region> region;
1601 nlist = node.children();
1605 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1606 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1607 error << _("Session: cannot create Region from XML description.");
1608 const XMLProperty *name = (**niter).property("name");
1611 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1622 Session::load_compounds (const XMLNode& node)
1624 XMLNodeList calist = node.children();
1625 XMLNodeConstIterator caiter;
1626 XMLProperty *caprop;
1628 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1629 XMLNode* ca = *caiter;
1633 if ((caprop = ca->property (X_("original"))) == 0) {
1636 orig_id = caprop->value();
1638 if ((caprop = ca->property (X_("copy"))) == 0) {
1641 copy_id = caprop->value();
1643 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1644 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1646 if (!orig || !copy) {
1647 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1653 RegionFactory::add_compound_association (orig, copy);
1660 Session::load_nested_sources (const XMLNode& node)
1663 XMLNodeConstIterator niter;
1665 nlist = node.children();
1667 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1668 if ((*niter)->name() == "Source") {
1670 /* it may already exist, so don't recreate it unnecessarily
1673 XMLProperty* prop = (*niter)->property (X_("id"));
1675 error << _("Nested source has no ID info in session file! (ignored)") << endmsg;
1679 ID source_id (prop->value());
1681 if (!source_by_id (source_id)) {
1684 SourceFactory::create (*this, **niter, true);
1686 catch (failed_constructor& err) {
1687 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1694 boost::shared_ptr<Region>
1695 Session::XMLRegionFactory (const XMLNode& node, bool full)
1697 const XMLProperty* type = node.property("type");
1701 const XMLNodeList& nlist = node.children();
1703 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1704 XMLNode *child = (*niter);
1705 if (child->name() == "NestedSource") {
1706 load_nested_sources (*child);
1710 if (!type || type->value() == "audio") {
1711 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1712 } else if (type->value() == "midi") {
1713 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1716 } catch (failed_constructor& err) {
1717 return boost::shared_ptr<Region> ();
1720 return boost::shared_ptr<Region> ();
1723 boost::shared_ptr<AudioRegion>
1724 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1726 const XMLProperty* prop;
1727 boost::shared_ptr<Source> source;
1728 boost::shared_ptr<AudioSource> as;
1730 SourceList master_sources;
1731 uint32_t nchans = 1;
1734 if (node.name() != X_("Region")) {
1735 return boost::shared_ptr<AudioRegion>();
1738 if ((prop = node.property (X_("channels"))) != 0) {
1739 nchans = atoi (prop->value().c_str());
1742 if ((prop = node.property ("name")) == 0) {
1743 cerr << "no name for this region\n";
1747 if ((prop = node.property (X_("source-0"))) == 0) {
1748 if ((prop = node.property ("source")) == 0) {
1749 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1750 return boost::shared_ptr<AudioRegion>();
1754 PBD::ID s_id (prop->value());
1756 if ((source = source_by_id (s_id)) == 0) {
1757 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1758 return boost::shared_ptr<AudioRegion>();
1761 as = boost::dynamic_pointer_cast<AudioSource>(source);
1763 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1764 return boost::shared_ptr<AudioRegion>();
1767 sources.push_back (as);
1769 /* pickup other channels */
1771 for (uint32_t n=1; n < nchans; ++n) {
1772 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1773 if ((prop = node.property (buf)) != 0) {
1775 PBD::ID id2 (prop->value());
1777 if ((source = source_by_id (id2)) == 0) {
1778 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1779 return boost::shared_ptr<AudioRegion>();
1782 as = boost::dynamic_pointer_cast<AudioSource>(source);
1784 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1785 return boost::shared_ptr<AudioRegion>();
1787 sources.push_back (as);
1791 for (uint32_t n = 0; n < nchans; ++n) {
1792 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1793 if ((prop = node.property (buf)) != 0) {
1795 PBD::ID id2 (prop->value());
1797 if ((source = source_by_id (id2)) == 0) {
1798 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1799 return boost::shared_ptr<AudioRegion>();
1802 as = boost::dynamic_pointer_cast<AudioSource>(source);
1804 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1805 return boost::shared_ptr<AudioRegion>();
1807 master_sources.push_back (as);
1812 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1814 /* a final detail: this is the one and only place that we know how long missing files are */
1816 if (region->whole_file()) {
1817 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1818 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1820 sfp->set_length (region->length());
1825 if (!master_sources.empty()) {
1826 if (master_sources.size() != nchans) {
1827 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1829 region->set_master_sources (master_sources);
1837 catch (failed_constructor& err) {
1838 return boost::shared_ptr<AudioRegion>();
1842 boost::shared_ptr<MidiRegion>
1843 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1845 const XMLProperty* prop;
1846 boost::shared_ptr<Source> source;
1847 boost::shared_ptr<MidiSource> ms;
1850 if (node.name() != X_("Region")) {
1851 return boost::shared_ptr<MidiRegion>();
1854 if ((prop = node.property ("name")) == 0) {
1855 cerr << "no name for this region\n";
1859 if ((prop = node.property (X_("source-0"))) == 0) {
1860 if ((prop = node.property ("source")) == 0) {
1861 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1862 return boost::shared_ptr<MidiRegion>();
1866 PBD::ID s_id (prop->value());
1868 if ((source = source_by_id (s_id)) == 0) {
1869 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1870 return boost::shared_ptr<MidiRegion>();
1873 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1875 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1876 return boost::shared_ptr<MidiRegion>();
1879 sources.push_back (ms);
1882 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1883 /* a final detail: this is the one and only place that we know how long missing files are */
1885 if (region->whole_file()) {
1886 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1887 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1889 sfp->set_length (region->length());
1897 catch (failed_constructor& err) {
1898 return boost::shared_ptr<MidiRegion>();
1903 Session::get_sources_as_xml ()
1906 XMLNode* node = new XMLNode (X_("Sources"));
1907 Glib::Threads::Mutex::Lock lm (source_lock);
1909 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1910 node->add_child_nocopy (i->second->get_state());
1917 Session::path_from_region_name (DataType type, string name, string identifier)
1919 char buf[PATH_MAX+1];
1921 SessionDirectory sdir(get_best_session_directory_for_new_source());
1922 std::string source_dir = ((type == DataType::AUDIO)
1923 ? sdir.sound_path() : sdir.midi_path());
1925 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1927 for (n = 0; n < 999999; ++n) {
1928 if (identifier.length()) {
1929 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1930 identifier.c_str(), n, ext.c_str());
1932 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1936 std::string source_path = Glib::build_filename (source_dir, buf);
1938 if (!Glib::file_test (source_path, Glib::FILE_TEST_EXISTS)) {
1943 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1952 Session::load_sources (const XMLNode& node)
1955 XMLNodeConstIterator niter;
1956 boost::shared_ptr<Source> source;
1958 nlist = node.children();
1962 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1965 if ((source = XMLSourceFactory (**niter)) == 0) {
1966 error << _("Session: cannot create Source from XML description.") << endmsg;
1969 } catch (MissingSource& err) {
1973 if (!no_questions_about_missing_files) {
1974 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1979 switch (user_choice) {
1981 /* user added a new search location, so try again */
1986 /* user asked to quit the entire session load
1991 no_questions_about_missing_files = true;
1995 no_questions_about_missing_files = true;
2000 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
2001 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2010 boost::shared_ptr<Source>
2011 Session::XMLSourceFactory (const XMLNode& node)
2013 if (node.name() != "Source") {
2014 return boost::shared_ptr<Source>();
2018 /* note: do peak building in another thread when loading session state */
2019 return SourceFactory::create (*this, node, true);
2022 catch (failed_constructor& err) {
2023 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2024 return boost::shared_ptr<Source>();
2029 Session::save_template (string template_name)
2033 if (_state_of_the_state & CannotSave) {
2037 std::string user_template_dir(user_template_directory());
2039 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
2040 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2041 user_template_dir, g_strerror (errno)) << endmsg;
2045 tree.set_root (&get_template());
2047 std::string template_dir_path(user_template_dir);
2049 /* directory to put the template in */
2050 template_dir_path = Glib::build_filename (template_dir_path, template_name);
2052 if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
2053 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2054 template_dir_path) << endmsg;
2058 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
2059 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
2060 template_dir_path, g_strerror (errno)) << endmsg;
2065 std::string template_file_path(template_dir_path);
2066 template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
2068 if (!tree.write (template_file_path)) {
2069 error << _("template not saved") << endmsg;
2073 /* copy plugin state directory */
2075 std::string template_plugin_state_path(template_dir_path);
2076 template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
2078 if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
2079 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
2080 template_plugin_state_path, g_strerror (errno)) << endmsg;
2084 copy_files (plugins_dir(), template_plugin_state_path);
2090 Session::refresh_disk_space ()
2092 #if __APPLE__ || (HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H)
2094 Glib::Threads::Mutex::Lock lm (space_lock);
2096 /* get freespace on every FS that is part of the session path */
2098 _total_free_4k_blocks = 0;
2099 _total_free_4k_blocks_uncertain = false;
2101 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2103 struct statfs statfsbuf;
2104 statfs (i->path.c_str(), &statfsbuf);
2106 double const scale = statfsbuf.f_bsize / 4096.0;
2108 /* See if this filesystem is read-only */
2109 struct statvfs statvfsbuf;
2110 statvfs (i->path.c_str(), &statvfsbuf);
2112 /* f_bavail can be 0 if it is undefined for whatever
2113 filesystem we are looking at; Samba shares mounted
2114 via GVFS are an example of this.
2116 if (statfsbuf.f_bavail == 0) {
2117 /* block count unknown */
2119 i->blocks_unknown = true;
2120 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2121 /* read-only filesystem */
2123 i->blocks_unknown = false;
2125 /* read/write filesystem with known space */
2126 i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2127 i->blocks_unknown = false;
2130 _total_free_4k_blocks += i->blocks;
2131 if (i->blocks_unknown) {
2132 _total_free_4k_blocks_uncertain = true;
2139 Session::get_best_session_directory_for_new_source ()
2141 vector<space_and_path>::iterator i;
2142 string result = _session_dir->root_path();
2144 /* handle common case without system calls */
2146 if (session_dirs.size() == 1) {
2150 /* OK, here's the algorithm we're following here:
2152 We want to select which directory to use for
2153 the next file source to be created. Ideally,
2154 we'd like to use a round-robin process so as to
2155 get maximum performance benefits from splitting
2156 the files across multiple disks.
2158 However, in situations without much diskspace, an
2159 RR approach may end up filling up a filesystem
2160 with new files while others still have space.
2161 Its therefore important to pay some attention to
2162 the freespace in the filesystem holding each
2163 directory as well. However, if we did that by
2164 itself, we'd keep creating new files in the file
2165 system with the most space until it was as full
2166 as all others, thus negating any performance
2167 benefits of this RAID-1 like approach.
2169 So, we use a user-configurable space threshold. If
2170 there are at least 2 filesystems with more than this
2171 much space available, we use RR selection between them.
2172 If not, then we pick the filesystem with the most space.
2174 This gets a good balance between the two
2178 refresh_disk_space ();
2180 int free_enough = 0;
2182 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2183 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2188 if (free_enough >= 2) {
2189 /* use RR selection process, ensuring that the one
2193 i = last_rr_session_dir;
2196 if (++i == session_dirs.end()) {
2197 i = session_dirs.begin();
2200 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2201 SessionDirectory sdir(i->path);
2202 if (sdir.create ()) {
2204 last_rr_session_dir = i;
2209 } while (i != last_rr_session_dir);
2213 /* pick FS with the most freespace (and that
2214 seems to actually work ...)
2217 vector<space_and_path> sorted;
2218 space_and_path_ascending_cmp cmp;
2220 sorted = session_dirs;
2221 sort (sorted.begin(), sorted.end(), cmp);
2223 for (i = sorted.begin(); i != sorted.end(); ++i) {
2224 SessionDirectory sdir(i->path);
2225 if (sdir.create ()) {
2227 last_rr_session_dir = i;
2237 Session::automation_dir () const
2239 return Glib::build_filename (_path, "automation");
2243 Session::analysis_dir () const
2245 return Glib::build_filename (_path, "analysis");
2249 Session::plugins_dir () const
2251 return Glib::build_filename (_path, "plugins");
2255 Session::externals_dir () const
2257 return Glib::build_filename (_path, "externals");
2261 Session::load_bundles (XMLNode const & node)
2263 XMLNodeList nlist = node.children();
2264 XMLNodeConstIterator niter;
2268 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2269 if ((*niter)->name() == "InputBundle") {
2270 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2271 } else if ((*niter)->name() == "OutputBundle") {
2272 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2274 error << string_compose(_("Unknown node \"%1\" found in Bundles list from session file"), (*niter)->name()) << endmsg;
2283 Session::load_route_groups (const XMLNode& node, int version)
2285 XMLNodeList nlist = node.children();
2286 XMLNodeConstIterator niter;
2290 if (version >= 3000) {
2292 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2293 if ((*niter)->name() == "RouteGroup") {
2294 RouteGroup* rg = new RouteGroup (*this, "");
2295 add_route_group (rg);
2296 rg->set_state (**niter, version);
2300 } else if (version < 3000) {
2302 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2303 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2304 RouteGroup* rg = new RouteGroup (*this, "");
2305 add_route_group (rg);
2306 rg->set_state (**niter, version);
2315 Session::auto_save()
2317 save_state (_current_snapshot_name);
2321 state_file_filter (const string &str, void */*arg*/)
2323 return (str.length() > strlen(statefile_suffix) &&
2324 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2328 bool operator()(const string* a, const string* b) {
2334 remove_end(string* state)
2336 string statename(*state);
2338 string::size_type start,end;
2339 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2340 statename = statename.substr (start+1);
2343 if ((end = statename.rfind(".ardour")) == string::npos) {
2344 end = statename.length();
2347 return new string(statename.substr (0, end));
2351 Session::possible_states (string path)
2353 PathScanner scanner;
2354 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2356 transform(states->begin(), states->end(), states->begin(), remove_end);
2359 sort (states->begin(), states->end(), cmp);
2365 Session::possible_states () const
2367 return possible_states(_path);
2371 Session::add_route_group (RouteGroup* g)
2373 _route_groups.push_back (g);
2374 route_group_added (g); /* EMIT SIGNAL */
2376 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2377 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2378 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2384 Session::remove_route_group (RouteGroup& rg)
2386 list<RouteGroup*>::iterator i;
2388 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2389 _route_groups.erase (i);
2392 route_group_removed (); /* EMIT SIGNAL */
2396 /** Set a new order for our route groups, without adding or removing any.
2397 * @param groups Route group list in the new order.
2400 Session::reorder_route_groups (list<RouteGroup*> groups)
2402 _route_groups = groups;
2404 route_groups_reordered (); /* EMIT SIGNAL */
2410 Session::route_group_by_name (string name)
2412 list<RouteGroup *>::iterator i;
2414 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2415 if ((*i)->name() == name) {
2423 Session::all_route_group() const
2425 return *_all_route_group;
2429 Session::add_commands (vector<Command*> const & cmds)
2431 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2437 Session::begin_reversible_command (const string& name)
2439 begin_reversible_command (g_quark_from_string (name.c_str ()));
2442 /** Begin a reversible command using a GQuark to identify it.
2443 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2444 * but there must be as many begin...()s as there are commit...()s.
2447 Session::begin_reversible_command (GQuark q)
2449 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2450 to hold all the commands that are committed. This keeps the order of
2451 commands correct in the history.
2454 if (_current_trans == 0) {
2455 /* start a new transaction */
2456 assert (_current_trans_quarks.empty ());
2457 _current_trans = new UndoTransaction();
2458 _current_trans->set_name (g_quark_to_string (q));
2461 _current_trans_quarks.push_front (q);
2465 Session::commit_reversible_command (Command *cmd)
2467 assert (_current_trans);
2468 assert (!_current_trans_quarks.empty ());
2473 _current_trans->add_command (cmd);
2476 _current_trans_quarks.pop_front ();
2478 if (!_current_trans_quarks.empty ()) {
2479 /* the transaction we're committing is not the top-level one */
2483 if (_current_trans->empty()) {
2484 /* no commands were added to the transaction, so just get rid of it */
2485 delete _current_trans;
2490 gettimeofday (&now, 0);
2491 _current_trans->set_timestamp (now);
2493 _history.add (_current_trans);
2498 accept_all_audio_files (const string& path, void */*arg*/)
2500 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2504 if (!AudioFileSource::safe_audio_file_extension (path)) {
2512 accept_all_midi_files (const string& path, void */*arg*/)
2514 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2518 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2519 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2520 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2524 accept_all_state_files (const string& path, void */*arg*/)
2526 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2530 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2534 Session::find_all_sources (string path, set<string>& result)
2539 if (!tree.read (path)) {
2543 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2548 XMLNodeConstIterator niter;
2550 nlist = node->children();
2554 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2558 if ((prop = (*niter)->property (X_("type"))) == 0) {
2562 DataType type (prop->value());
2564 if ((prop = (*niter)->property (X_("name"))) == 0) {
2568 if (Glib::path_is_absolute (prop->value())) {
2569 /* external file, ignore */
2577 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2578 result.insert (found_path);
2586 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2588 PathScanner scanner;
2589 vector<string*>* state_files;
2591 string this_snapshot_path;
2597 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2598 ripped = ripped.substr (0, ripped.length() - 1);
2601 state_files = scanner (ripped, accept_all_state_files, (void *) 0, true, true);
2603 if (state_files == 0) {
2608 this_snapshot_path = _path;
2609 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2610 this_snapshot_path += statefile_suffix;
2612 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2614 if (exclude_this_snapshot && **i == this_snapshot_path) {
2618 if (find_all_sources (**i, result) < 0) {
2626 struct RegionCounter {
2627 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2628 AudioSourceList::iterator iter;
2629 boost::shared_ptr<Region> region;
2632 RegionCounter() : count (0) {}
2636 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2638 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2639 return r.get_value_or (1);
2643 Session::cleanup_regions ()
2645 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2647 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2649 uint32_t used = playlists->region_use_count (i->second);
2651 if (used == 0 && !i->second->automatic ()) {
2652 RegionFactory::map_remove (i->second);
2656 /* dump the history list */
2663 Session::cleanup_sources (CleanupReport& rep)
2665 // FIXME: needs adaptation to midi
2667 vector<boost::shared_ptr<Source> > dead_sources;
2668 PathScanner scanner;
2671 vector<space_and_path>::iterator i;
2672 vector<space_and_path>::iterator nexti;
2673 vector<string*>* candidates;
2674 vector<string*>* candidates2;
2675 vector<string> unused;
2676 set<string> all_sources;
2681 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2683 /* consider deleting all unused playlists */
2685 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2690 /* sync the "all regions" property of each playlist with its current state
2693 playlists->sync_all_regions_with_regions ();
2695 /* find all un-used sources */
2700 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2702 SourceMap::iterator tmp;
2707 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2711 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2712 dead_sources.push_back (i->second);
2713 i->second->drop_references ();
2719 /* build a list of all the possible audio directories for the session */
2721 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2726 SessionDirectory sdir ((*i).path);
2727 audio_path += sdir.sound_path();
2729 if (nexti != session_dirs.end()) {
2737 /* build a list of all the possible midi directories for the session */
2739 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2744 SessionDirectory sdir ((*i).path);
2745 midi_path += sdir.midi_path();
2747 if (nexti != session_dirs.end()) {
2754 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2755 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2761 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2762 candidates->push_back (*i);
2767 candidates = candidates2; // might still be null
2770 /* find all sources, but don't use this snapshot because the
2771 state file on disk still references sources we may have already
2775 find_all_sources_across_snapshots (all_sources, true);
2777 /* add our current source list
2780 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2781 boost::shared_ptr<FileSource> fs;
2782 SourceMap::iterator tmp = i;
2785 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2786 if (playlists->source_use_count (fs) != 0) {
2787 all_sources.insert (fs->path());
2790 /* we might not remove this source from disk, because it may be used
2791 by other snapshots, but its not being used in this version
2792 so lets get rid of it now, along with any representative regions
2796 RegionFactory::remove_regions_using_source (i->second);
2804 char tmppath1[PATH_MAX+1];
2805 char tmppath2[PATH_MAX+1];
2808 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2813 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2815 if (realpath(spath.c_str(), tmppath1) == 0) {
2816 error << string_compose (_("Cannot expand path %1 (%2)"),
2817 spath, strerror (errno)) << endmsg;
2821 if (realpath((*i).c_str(), tmppath2) == 0) {
2822 error << string_compose (_("Cannot expand path %1 (%2)"),
2823 (*i), strerror (errno)) << endmsg;
2827 if (strcmp(tmppath1, tmppath2) == 0) {
2834 unused.push_back (spath);
2843 /* now try to move all unused files into the "dead" directory(ies) */
2845 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2846 struct stat statbuf;
2850 /* don't move the file across filesystems, just
2851 stick it in the `dead_dir_name' directory
2852 on whichever filesystem it was already on.
2855 if ((*x).find ("/sounds/") != string::npos) {
2857 /* old school, go up 1 level */
2859 newpath = Glib::path_get_dirname (*x); // "sounds"
2860 newpath = Glib::path_get_dirname (newpath); // "session-name"
2864 /* new school, go up 4 levels */
2866 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2867 newpath = Glib::path_get_dirname (newpath); // "session-name"
2868 newpath = Glib::path_get_dirname (newpath); // "interchange"
2869 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2872 newpath = Glib::build_filename (newpath, dead_dir_name);
2874 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2875 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2879 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2881 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2883 /* the new path already exists, try versioning */
2885 char buf[PATH_MAX+1];
2889 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2892 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2893 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2897 if (version == 999) {
2898 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2902 newpath = newpath_v;
2907 /* it doesn't exist, or we can't read it or something */
2911 stat ((*x).c_str(), &statbuf);
2913 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2914 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2915 (*x), newpath, strerror (errno))
2920 /* see if there an easy to find peakfile for this file, and remove it.
2923 string base = basename_nosuffix (*x);
2924 base += "%A"; /* this is what we add for the channel suffix of all native files,
2925 or for the first channel of embedded files. it will miss
2926 some peakfiles for other channels
2928 string peakpath = peak_path (base);
2930 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2931 if (::unlink (peakpath.c_str()) != 0) {
2932 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2933 peakpath, _path, strerror (errno))
2935 /* try to back out */
2936 ::rename (newpath.c_str(), _path.c_str());
2941 rep.paths.push_back (*x);
2942 rep.space += statbuf.st_size;
2945 /* dump the history list */
2949 /* save state so we don't end up a session file
2950 referring to non-existent sources.
2957 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2963 Session::cleanup_trash_sources (CleanupReport& rep)
2965 // FIXME: needs adaptation for MIDI
2967 vector<space_and_path>::iterator i;
2973 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2975 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2977 clear_directory (dead_dir, &rep.space, &rep.paths);
2984 Session::set_dirty ()
2986 bool was_dirty = dirty();
2988 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2992 DirtyChanged(); /* EMIT SIGNAL */
2998 Session::set_clean ()
3000 bool was_dirty = dirty();
3002 _state_of_the_state = Clean;
3006 DirtyChanged(); /* EMIT SIGNAL */
3011 Session::set_deletion_in_progress ()
3013 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3017 Session::clear_deletion_in_progress ()
3019 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3023 Session::add_controllable (boost::shared_ptr<Controllable> c)
3025 /* this adds a controllable to the list managed by the Session.
3026 this is a subset of those managed by the Controllable class
3027 itself, and represents the only ones whose state will be saved
3028 as part of the session.
3031 Glib::Threads::Mutex::Lock lm (controllables_lock);
3032 controllables.insert (c);
3035 struct null_deleter { void operator()(void const *) const {} };
3038 Session::remove_controllable (Controllable* c)
3040 if (_state_of_the_state & Deletion) {
3044 Glib::Threads::Mutex::Lock lm (controllables_lock);
3046 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3048 if (x != controllables.end()) {
3049 controllables.erase (x);
3053 boost::shared_ptr<Controllable>
3054 Session::controllable_by_id (const PBD::ID& id)
3056 Glib::Threads::Mutex::Lock lm (controllables_lock);
3058 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3059 if ((*i)->id() == id) {
3064 return boost::shared_ptr<Controllable>();
3067 boost::shared_ptr<Controllable>
3068 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3070 boost::shared_ptr<Controllable> c;
3071 boost::shared_ptr<Route> r;
3073 switch (desc.top_level_type()) {
3074 case ControllableDescriptor::NamedRoute:
3076 std::string str = desc.top_level_name();
3077 if (str == "master") {
3079 } else if (str == "control" || str == "listen") {
3082 r = route_by_name (desc.top_level_name());
3087 case ControllableDescriptor::RemoteControlID:
3088 r = route_by_remote_id (desc.rid());
3096 switch (desc.subtype()) {
3097 case ControllableDescriptor::Gain:
3098 c = r->gain_control ();
3101 case ControllableDescriptor::Solo:
3102 c = r->solo_control();
3105 case ControllableDescriptor::Mute:
3106 c = r->mute_control();
3109 case ControllableDescriptor::Recenable:
3111 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3114 c = t->rec_enable_control ();
3119 case ControllableDescriptor::PanDirection:
3121 c = r->pannable()->pan_azimuth_control;
3125 case ControllableDescriptor::PanWidth:
3127 c = r->pannable()->pan_width_control;
3131 case ControllableDescriptor::PanElevation:
3133 c = r->pannable()->pan_elevation_control;
3137 case ControllableDescriptor::Balance:
3138 /* XXX simple pan control */
3141 case ControllableDescriptor::PluginParameter:
3143 uint32_t plugin = desc.target (0);
3144 uint32_t parameter_index = desc.target (1);
3146 /* revert to zero based counting */
3152 if (parameter_index > 0) {
3156 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3159 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3160 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3165 case ControllableDescriptor::SendGain:
3167 uint32_t send = desc.target (0);
3169 /* revert to zero-based counting */
3175 boost::shared_ptr<Processor> p = r->nth_send (send);
3178 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3179 boost::shared_ptr<Amp> a = s->amp();
3182 c = s->amp()->gain_control();
3189 /* relax and return a null pointer */
3197 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3200 Stateful::add_instant_xml (node, _path);
3203 if (write_to_config) {
3204 Config->add_instant_xml (node);
3209 Session::instant_xml (const string& node_name)
3211 return Stateful::instant_xml (node_name, _path);
3215 Session::save_history (string snapshot_name)
3223 if (snapshot_name.empty()) {
3224 snapshot_name = _current_snapshot_name;
3227 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3228 const string backup_filename = history_filename + backup_suffix;
3229 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3230 const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3232 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3233 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3234 error << _("could not backup old history file, current history not saved") << endmsg;
3239 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3243 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3245 if (!tree.write (xml_path))
3247 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3249 if (g_remove (xml_path.c_str()) != 0) {
3250 error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3251 xml_path, g_strerror (errno)) << endmsg;
3253 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3254 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3255 backup_path, g_strerror (errno)) << endmsg;
3265 Session::restore_history (string snapshot_name)
3269 if (snapshot_name.empty()) {
3270 snapshot_name = _current_snapshot_name;
3273 const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3274 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3276 info << "Loading history from " << xml_path << endmsg;
3278 if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3279 info << string_compose (_("%1: no history file \"%2\" for this session."),
3280 _name, xml_path) << endmsg;
3284 if (!tree.read (xml_path)) {
3285 error << string_compose (_("Could not understand session history file \"%1\""),
3286 xml_path) << endmsg;
3293 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3296 UndoTransaction* ut = new UndoTransaction ();
3299 ut->set_name(t->property("name")->value());
3300 stringstream ss(t->property("tv-sec")->value());
3302 ss.str(t->property("tv-usec")->value());
3304 ut->set_timestamp(tv);
3306 for (XMLNodeConstIterator child_it = t->children().begin();
3307 child_it != t->children().end(); child_it++)
3309 XMLNode *n = *child_it;
3312 if (n->name() == "MementoCommand" ||
3313 n->name() == "MementoUndoCommand" ||
3314 n->name() == "MementoRedoCommand") {
3316 if ((c = memento_command_factory(n))) {
3320 } else if (n->name() == "NoteDiffCommand") {
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::NoteDiffCommand(midi_source->model(), *n));
3327 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3330 } else if (n->name() == "SysExDiffCommand") {
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::SysExDiffCommand (midi_source->model(), *n));
3338 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3341 } else if (n->name() == "PatchChangeDiffCommand") {
3343 PBD::ID id (n->property("midi-source")->value());
3344 boost::shared_ptr<MidiSource> midi_source =
3345 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3347 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3349 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3352 } else if (n->name() == "StatefulDiffCommand") {
3353 if ((c = stateful_diff_command_factory (n))) {
3354 ut->add_command (c);
3357 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3368 Session::config_changed (std::string p, bool ours)
3374 if (p == "seamless-loop") {
3376 } else if (p == "rf-speed") {
3378 } else if (p == "auto-loop") {
3380 } else if (p == "auto-input") {
3382 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3383 /* auto-input only makes a difference if we're rolling */
3384 set_track_monitor_input_status (!config.get_auto_input());
3387 } else if (p == "punch-in") {
3391 if ((location = _locations->auto_punch_location()) != 0) {
3393 if (config.get_punch_in ()) {
3394 replace_event (SessionEvent::PunchIn, location->start());
3396 remove_event (location->start(), SessionEvent::PunchIn);
3400 } else if (p == "punch-out") {
3404 if ((location = _locations->auto_punch_location()) != 0) {
3406 if (config.get_punch_out()) {
3407 replace_event (SessionEvent::PunchOut, location->end());
3409 clear_events (SessionEvent::PunchOut);
3413 } else if (p == "edit-mode") {
3415 Glib::Threads::Mutex::Lock lm (playlists->lock);
3417 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3418 (*i)->set_edit_mode (Config->get_edit_mode ());
3421 } else if (p == "use-video-sync") {
3423 waiting_for_sync_offset = config.get_use_video_sync();
3425 } else if (p == "mmc-control") {
3427 //poke_midi_thread ();
3429 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3431 AudioEngine::instance()->mmc().set_receive_device_id (Config->get_mmc_receive_device_id());
3433 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3435 AudioEngine::instance()->mmc().set_send_device_id (Config->get_mmc_send_device_id());
3437 } else if (p == "midi-control") {
3439 //poke_midi_thread ();
3441 } else if (p == "raid-path") {
3443 setup_raid_path (config.get_raid_path());
3445 } else if (p == "timecode-format") {
3449 } else if (p == "video-pullup") {
3453 } else if (p == "seamless-loop") {
3455 if (play_loop && transport_rolling()) {
3456 // to reset diskstreams etc
3457 request_play_loop (true);
3460 } else if (p == "rf-speed") {
3462 cumulative_rf_motion = 0;
3465 } else if (p == "click-sound") {
3467 setup_click_sounds (1);
3469 } else if (p == "click-emphasis-sound") {
3471 setup_click_sounds (-1);
3473 } else if (p == "clicking") {
3475 if (Config->get_clicking()) {
3476 if (_click_io && click_data) { // don't require emphasis data
3483 } else if (p == "click-gain") {
3486 _click_gain->set_gain (Config->get_click_gain(), this);
3489 } else if (p == "send-mtc") {
3491 if (Config->get_send_mtc ()) {
3492 /* mark us ready to send */
3493 next_quarter_frame_to_send = 0;
3496 } else if (p == "send-mmc") {
3498 AudioEngine::instance()->mmc().enable_send (Config->get_send_mmc ());
3500 } else if (p == "midi-feedback") {
3502 session_midi_feedback = Config->get_midi_feedback();
3504 } else if (p == "jack-time-master") {
3506 engine().reset_timebase ();
3508 } else if (p == "native-file-header-format") {
3510 if (!first_file_header_format_reset) {
3511 reset_native_file_format ();
3514 first_file_header_format_reset = false;
3516 } else if (p == "native-file-data-format") {
3518 if (!first_file_data_format_reset) {
3519 reset_native_file_format ();
3522 first_file_data_format_reset = false;
3524 } else if (p == "external-sync") {
3525 if (!config.get_external_sync()) {
3526 drop_sync_source ();
3528 switch_to_sync_source (Config->get_sync_source());
3530 } else if (p == "denormal-model") {
3532 } else if (p == "history-depth") {
3533 set_history_depth (Config->get_history_depth());
3534 } else if (p == "remote-model") {
3535 /* XXX DO SOMETHING HERE TO TELL THE GUI THAT WE NEED
3538 } else if (p == "sync-all-route-ordering") {
3540 /* sync to editor order unless mixer is used for remote IDs
3543 switch (Config->get_remote_model()) {
3545 sync_order_keys (EditorSort);
3548 sync_order_keys (EditorSort);
3551 sync_order_keys (MixerSort);
3554 } else if (p == "initial-program-change") {
3556 if (AudioEngine::instance()->mmc().output_port() && Config->get_initial_program_change() >= 0) {
3559 buf[0] = MIDI::program; // channel zero by default
3560 buf[1] = (Config->get_initial_program_change() & 0x7f);
3562 AudioEngine::instance()->mmc().output_port()->midimsg (buf, sizeof (buf), 0);
3564 } else if (p == "solo-mute-override") {
3565 // catch_up_on_solo_mute_override ();
3566 } else if (p == "listen-position" || p == "pfl-position") {
3567 listen_position_changed ();
3568 } else if (p == "solo-control-is-listen-control") {
3569 solo_control_mode_changed ();
3570 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3571 last_timecode_valid = false;
3572 } else if (p == "playback-buffer-seconds") {
3573 AudioSource::allocate_working_buffers (frame_rate());
3574 } else if (p == "automation-thinning-factor") {
3575 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3576 } else if (p == "ltc-source-port") {
3577 reconnect_ltc_input ();
3578 } else if (p == "ltc-sink-port") {
3579 reconnect_ltc_output ();
3580 } else if (p == "timecode-generator-offset") {
3581 ltc_tx_parse_offset();
3588 Session::set_history_depth (uint32_t d)
3590 _history.set_depth (d);
3594 Session::load_diskstreams_2X (XMLNode const & node, int)
3597 XMLNodeConstIterator citer;
3599 clist = node.children();
3601 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3604 /* diskstreams added automatically by DiskstreamCreated handler */
3605 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3606 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3607 _diskstreams_2X.push_back (dsp);
3609 error << _("Session: unknown diskstream type in XML") << endmsg;
3613 catch (failed_constructor& err) {
3614 error << _("Session: could not load diskstream via XML state") << endmsg;
3622 /** Connect things to the MMC object */
3624 Session::setup_midi_machine_control ()
3626 MIDI::MachineControl& mmc (AudioEngine::instance()->mmc ());
3628 mmc.Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3629 mmc.DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3630 mmc.Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3631 mmc.FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3632 mmc.Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3633 mmc.Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3634 mmc.RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3635 mmc.RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3636 mmc.RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3637 mmc.Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3638 mmc.Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3639 mmc.Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3640 mmc.TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3642 /* also handle MIDI SPP because its so common */
3644 mmc.SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3645 mmc.SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3646 mmc.SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3649 boost::shared_ptr<Controllable>
3650 Session::solo_cut_control() const
3652 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3653 controls in Ardour that currently get presented to the user in the GUI that require
3654 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3656 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3657 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3661 return _solo_cut_control;
3665 Session::rename (const std::string& new_name)
3667 string legal_name = legalize_for_path (new_name);
3673 string const old_sources_root = _session_dir->sources_root();
3675 #define RENAME ::rename
3680 * interchange subdirectory
3684 * Backup files are left unchanged and not renamed.
3687 /* pass one: not 100% safe check that the new directory names don't
3691 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3696 /* this is a stupid hack because Glib::path_get_dirname() is
3697 * lexical-only, and so passing it /a/b/c/ gives a different
3698 * result than passing it /a/b/c ...
3701 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3702 oldstr = oldstr.substr (0, oldstr.length() - 1);
3705 string base = Glib::path_get_dirname (oldstr);
3706 string p = Glib::path_get_basename (oldstr);
3708 newstr = Glib::build_filename (base, legal_name);
3710 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3717 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3722 /* this is a stupid hack because Glib::path_get_dirname() is
3723 * lexical-only, and so passing it /a/b/c/ gives a different
3724 * result than passing it /a/b/c ...
3727 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3728 oldstr = oldstr.substr (0, oldstr.length() - 1);
3731 string base = Glib::path_get_dirname (oldstr);
3732 string p = Glib::path_get_basename (oldstr);
3734 newstr = Glib::build_filename (base, legal_name);
3736 cerr << "Rename " << oldstr << " => " << newstr << endl;
3738 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3743 (*_session_dir) = newstr;
3748 /* directory below interchange */
3750 v.push_back (newstr);
3751 v.push_back (interchange_dir_name);
3754 oldstr = Glib::build_filename (v);
3757 v.push_back (newstr);
3758 v.push_back (interchange_dir_name);
3759 v.push_back (legal_name);
3761 newstr = Glib::build_filename (v);
3763 cerr << "Rename " << oldstr << " => " << newstr << endl;
3765 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3772 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3773 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3775 cerr << "Rename " << oldstr << " => " << newstr << endl;
3777 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3784 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3786 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3787 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3789 cerr << "Rename " << oldstr << " => " << newstr << endl;
3791 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3796 /* update file source paths */
3798 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3799 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3801 string p = fs->path ();
3802 boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3807 /* remove old name from recent sessions */
3809 remove_recent_sessions (_path);
3812 _current_snapshot_name = new_name;
3817 /* save state again to get everything just right */
3819 save_state (_current_snapshot_name);
3822 /* add to recent sessions */
3824 store_recent_sessions (new_name, _path);