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/session_utils.h"
112 #include "ardour/silentfilesource.h"
113 #include "ardour/sndfilesource.h"
114 #include "ardour/source_factory.h"
115 #include "ardour/speakers.h"
116 #include "ardour/template_utils.h"
117 #include "ardour/tempo.h"
118 #include "ardour/ticker.h"
119 #include "ardour/user_bundle.h"
121 #include "control_protocol/control_protocol.h"
127 using namespace ARDOUR;
130 /** @param snapshot_name Snapshot name, without the .ardour prefix */
132 Session::first_stage_init (string fullpath, string snapshot_name)
134 if (fullpath.length() == 0) {
136 throw failed_constructor();
139 char buf[PATH_MAX+1];
140 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
141 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
143 throw failed_constructor();
148 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
149 _path += G_DIR_SEPARATOR;
152 /* these two are just provisional settings. set_state()
153 will likely override them.
156 _name = _current_snapshot_name = snapshot_name;
158 set_history_depth (Config->get_history_depth());
160 _current_frame_rate = _engine.frame_rate ();
161 _nominal_frame_rate = _current_frame_rate;
162 _base_frame_rate = _current_frame_rate;
164 _tempo_map = new TempoMap (_current_frame_rate);
165 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
168 _non_soloed_outs_muted = false;
170 _solo_isolated_cnt = 0;
171 g_atomic_int_set (&processing_prohibited, 0);
172 _transport_speed = 0;
173 _default_transport_speed = 1.0;
174 _last_transport_speed = 0;
175 _target_transport_speed = 0;
176 auto_play_legal = false;
177 transport_sub_state = 0;
178 _transport_frame = 0;
179 _requested_return_frame = -1;
180 _session_range_location = 0;
181 g_atomic_int_set (&_record_status, Disabled);
182 loop_changing = false;
185 _last_roll_location = 0;
186 _last_roll_or_reversal_location = 0;
187 _last_record_location = 0;
188 pending_locate_frame = 0;
189 pending_locate_roll = false;
190 pending_locate_flush = false;
191 state_was_pending = false;
193 outbound_mtc_timecode_frame = 0;
194 next_quarter_frame_to_send = -1;
195 current_block_size = 0;
196 solo_update_disabled = false;
197 _have_captured = false;
198 _worst_output_latency = 0;
199 _worst_input_latency = 0;
200 _worst_track_latency = 0;
201 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
202 _was_seamless = Config->get_seamless_loop ();
204 _send_qf_mtc = false;
205 _pframes_since_last_mtc = 0;
206 g_atomic_int_set (&_playback_load, 100);
207 g_atomic_int_set (&_capture_load, 100);
210 pending_abort = false;
211 destructive_index = 0;
212 first_file_data_format_reset = true;
213 first_file_header_format_reset = true;
214 post_export_sync = false;
217 no_questions_about_missing_files = false;
218 _speakers.reset (new Speakers);
220 ignore_route_processor_changes = false;
221 _pre_export_mmc_enabled = false;
223 AudioDiskstream::allocate_working_buffers();
225 /* default short fade = 15ms */
227 SndFileSource::setup_standard_crossfades (*this, frame_rate());
229 last_mmc_step.tv_sec = 0;
230 last_mmc_step.tv_usec = 0;
233 /* click sounds are unset by default, which causes us to internal
234 waveforms for clicks.
238 click_emphasis_length = 0;
241 process_function = &Session::process_with_events;
243 if (config.get_use_video_sync()) {
244 waiting_for_sync_offset = true;
246 waiting_for_sync_offset = false;
249 last_timecode_when = 0;
250 last_timecode_valid = false;
254 last_rr_session_dir = session_dirs.begin();
255 refresh_disk_space ();
257 /* default: assume simple stereo speaker configuration */
259 _speakers->setup_default_speakers (2);
263 average_slave_delta = 1800; // !!! why 1800 ????
264 have_first_delta_accumulator = false;
265 delta_accumulator_cnt = 0;
266 _slave_state = Stopped;
268 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
269 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
270 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
271 add_controllable (_solo_cut_control);
273 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
275 /* These are all static "per-class" signals */
277 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
278 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
279 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
280 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
281 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
283 /* stop IO objects from doing stuff until we're ready for them */
285 Delivery::disable_panners ();
286 IO::disable_connecting ();
290 Session::second_stage_init ()
292 AudioFileSource::set_peak_dir (_session_dir->peak_path());
295 if (load_state (_current_snapshot_name)) {
300 if (_butler->start_thread()) {
304 if (start_midi_thread ()) {
308 setup_midi_machine_control ();
310 // set_state() will call setup_raid_path(), but if it's a new session we need
311 // to call setup_raid_path() here.
314 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
318 setup_raid_path(_path);
321 /* we can't save till after ::when_engine_running() is called,
322 because otherwise we save state with no connections made.
323 therefore, we reset _state_of_the_state because ::set_state()
324 will have cleared it.
326 we also have to include Loading so that any events that get
327 generated between here and the end of ::when_engine_running()
328 will be processed directly rather than queued.
331 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
333 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
334 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
335 setup_click_sounds (0);
336 setup_midi_control ();
338 /* Pay attention ... */
340 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
341 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
343 midi_clock = new MidiClockTicker ();
344 midi_clock->set_session (this);
347 when_engine_running ();
350 /* handle this one in a different way than all others, so that its clear what happened */
352 catch (AudioEngine::PortRegistrationFailure& err) {
353 error << err.what() << endmsg;
361 BootMessage (_("Reset Remote Controls"));
363 send_full_time_code (0);
364 _engine.transport_locate (0);
366 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
367 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
369 MIDI::Name::MidiPatchManager::instance().set_session (this);
371 /* initial program change will be delivered later; see ::config_changed() */
373 _state_of_the_state = Clean;
375 Port::set_connecting_blocked (false);
377 DirtyChanged (); /* EMIT SIGNAL */
379 if (state_was_pending) {
380 save_state (_current_snapshot_name);
381 remove_pending_capture_state ();
382 state_was_pending = false;
385 BootMessage (_("Session loading complete"));
391 Session::raid_path () const
393 SearchPath raid_search_path;
395 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
396 raid_search_path += (*i).path;
399 return raid_search_path.to_string ();
403 Session::setup_raid_path (string path)
412 session_dirs.clear ();
414 SearchPath search_path(path);
415 SearchPath sound_search_path;
416 SearchPath midi_search_path;
418 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
420 sp.blocks = 0; // not needed
421 session_dirs.push_back (sp);
423 SessionDirectory sdir(sp.path);
425 sound_search_path += sdir.sound_path ();
426 midi_search_path += sdir.midi_path ();
429 // reset the round-robin soundfile path thingie
430 last_rr_session_dir = session_dirs.begin();
434 Session::path_is_within_session (const std::string& path)
436 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
437 if (PBD::path_is_within (i->path, path)) {
445 Session::ensure_subdirs ()
449 dir = session_directory().peak_path();
451 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
452 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
456 dir = session_directory().sound_path();
458 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
459 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
463 dir = session_directory().midi_path();
465 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
466 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
470 dir = session_directory().dead_path();
472 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
473 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
477 dir = session_directory().export_path();
479 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
480 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
484 dir = analysis_dir ();
486 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
487 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
491 dir = plugins_dir ();
493 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
494 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
498 dir = externals_dir ();
500 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
501 error << string_compose(_("Session: cannot create session externals folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
508 /** @param session_template directory containing session template, or empty.
509 * Caller must not hold process lock.
512 Session::create (const string& session_template, BusProfile* bus_profile)
514 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
515 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
519 if (ensure_subdirs ()) {
523 _writable = exists_and_writable (_path);
525 if (!session_template.empty()) {
526 std::string in_path = session_template_dir_to_file (session_template);
528 ifstream in(in_path.c_str());
531 string out_path = _path;
533 out_path += statefile_suffix;
535 ofstream out(out_path.c_str());
541 /* Copy plugin state files from template to new session */
542 std::string template_plugins = Glib::build_filename (session_template, X_("plugins"));
543 copy_files (template_plugins, plugins_dir ());
548 error << string_compose (_("Could not open %1 for writing session template"), out_path)
554 error << string_compose (_("Could not open session template %1 for reading"), in_path)
561 /* set initial start + end point */
563 _state_of_the_state = Clean;
565 /* set up Master Out and Control Out if necessary */
570 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
572 if (bus_profile->master_out_channels) {
573 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
577 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
578 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
581 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
582 r->input()->ensure_io (count, false, this);
583 r->output()->ensure_io (count, false, this);
589 /* prohibit auto-connect to master, because there isn't one */
590 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
594 add_routes (rl, false, false, false);
597 /* this allows the user to override settings with an environment variable.
600 if (no_auto_connect()) {
601 bus_profile->input_ac = AutoConnectOption (0);
602 bus_profile->output_ac = AutoConnectOption (0);
605 Config->set_input_auto_connect (bus_profile->input_ac);
606 Config->set_output_auto_connect (bus_profile->output_ac);
609 if (Config->get_use_monitor_bus() && bus_profile) {
610 add_monitor_section ();
619 Session::maybe_write_autosave()
621 if (dirty() && record_status() != Recording) {
622 save_state("", true);
627 Session::remove_pending_capture_state ()
629 std::string pending_state_file_path(_session_dir->root_path());
631 pending_state_file_path = Glib::build_filename (pending_state_file_path, legalize_for_path (_current_snapshot_name) + pending_suffix);
633 if (!Glib::file_test (pending_state_file_path, Glib::FILE_TEST_EXISTS)) return;
635 if (g_remove (pending_state_file_path.c_str()) != 0) {
636 error << string_compose(_("Could not remove pending capture state at path \"%1\" (%2)"),
637 pending_state_file_path, g_strerror (errno)) << endmsg;
641 /** Rename a state file.
642 * @param old_name Old snapshot name.
643 * @param new_name New snapshot name.
646 Session::rename_state (string old_name, string new_name)
648 if (old_name == _current_snapshot_name || old_name == _name) {
649 /* refuse to rename the current snapshot or the "main" one */
653 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
654 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
656 const std::string old_xml_path(Glib::build_filename (_session_dir->root_path(), old_xml_filename));
657 const std::string new_xml_path(Glib::build_filename (_session_dir->root_path(), new_xml_filename));
659 if (::g_rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
660 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
661 old_name, new_name, g_strerror(errno)) << endmsg;
665 /** Remove a state file.
666 * @param snapshot_name Snapshot name.
669 Session::remove_state (string snapshot_name)
671 if (!_writable || snapshot_name == _current_snapshot_name || snapshot_name == _name) {
672 // refuse to remove the current snapshot or the "main" one
676 std::string xml_path(_session_dir->root_path());
678 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
680 if (!create_backup_file (xml_path)) {
681 // don't remove it if a backup can't be made
682 // create_backup_file will log the error.
687 if (g_remove (xml_path.c_str()) != 0) {
688 error << string_compose(_("Could not remove state file at path \"%1\" (%2)"),
689 xml_path, g_strerror (errno)) << endmsg;
693 #ifdef HAVE_JACK_SESSION
695 Session::jack_session_event (jack_session_event_t * event)
699 struct tm local_time;
702 localtime_r (&n, &local_time);
703 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
705 if (event->type == JackSessionSaveTemplate)
707 if (save_template( timebuf )) {
708 event->flags = JackSessionSaveError;
710 string cmd ("ardour3 -P -U ");
711 cmd += event->client_uuid;
715 event->command_line = strdup (cmd.c_str());
720 if (save_state (timebuf)) {
721 event->flags = JackSessionSaveError;
723 std::string xml_path (_session_dir->root_path());
724 std::string legalized_filename = legalize_for_path (timebuf) + statefile_suffix;
725 xml_path = Glib::build_filename (xml_path, legalized_filename);
727 string cmd ("ardour3 -P -U ");
728 cmd += event->client_uuid;
733 event->command_line = strdup (cmd.c_str());
737 jack_session_reply (_engine.jack(), event);
739 if (event->type == JackSessionSaveAndQuit) {
740 Quit (); /* EMIT SIGNAL */
743 jack_session_event_free( event );
747 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
749 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
752 std::string xml_path(_session_dir->root_path());
754 if (!_writable || (_state_of_the_state & CannotSave)) {
758 if (!_engine.connected ()) {
759 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
765 /* tell sources we're saving first, in case they write out to a new file
766 * which should be saved with the state rather than the old one */
767 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
769 i->second->session_saved();
770 } catch (Evoral::SMF::FileError& e) {
771 error << string_compose ("Could not write to MIDI file %1; MIDI data not saved.", e.file_name ()) << endmsg;
775 tree.set_root (&get_state());
777 if (snapshot_name.empty()) {
778 snapshot_name = _current_snapshot_name;
779 } else if (switch_to_snapshot) {
780 _current_snapshot_name = snapshot_name;
785 /* proper save: use statefile_suffix (.ardour in English) */
787 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + statefile_suffix);
789 /* make a backup copy of the old file */
791 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && !create_backup_file (xml_path)) {
792 // create_backup_file will log the error
798 /* pending save: use pending_suffix (.pending in English) */
799 xml_path = Glib::build_filename (xml_path, legalize_for_path (snapshot_name) + pending_suffix);
802 std::string tmp_path(_session_dir->root_path());
803 tmp_path = Glib::build_filename (tmp_path, legalize_for_path (snapshot_name) + temp_suffix);
805 // cerr << "actually writing state to " << xml_path << endl;
807 if (!tree.write (tmp_path)) {
808 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
809 if (g_remove (tmp_path.c_str()) != 0) {
810 error << string_compose(_("Could not remove temporary state file at path \"%1\" (%2)"),
811 tmp_path, g_strerror (errno)) << endmsg;
817 if (::rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
818 error << string_compose (_("could not rename temporary session file %1 to %2"),
819 tmp_path, xml_path) << endmsg;
820 if (g_remove (tmp_path.c_str()) != 0) {
821 error << string_compose(_("Could not remove temporary state file at path \"%1\" (%2)"),
822 tmp_path, g_strerror (errno)) << endmsg;
830 save_history (snapshot_name);
832 bool was_dirty = dirty();
834 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
837 DirtyChanged (); /* EMIT SIGNAL */
840 StateSaved (snapshot_name); /* EMIT SIGNAL */
847 Session::restore_state (string snapshot_name)
849 if (load_state (snapshot_name) == 0) {
850 set_state (*state_tree->root(), Stateful::loading_state_version);
857 Session::load_state (string snapshot_name)
862 state_was_pending = false;
864 /* check for leftover pending state from a crashed capture attempt */
866 std::string xmlpath(_session_dir->root_path());
867 xmlpath = Glib::build_filename (xmlpath, legalize_for_path (snapshot_name) + pending_suffix);
869 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
871 /* there is pending state from a crashed capture attempt */
873 boost::optional<int> r = AskAboutPendingState();
874 if (r.get_value_or (1)) {
875 state_was_pending = true;
879 if (!state_was_pending) {
880 xmlpath = Glib::build_filename (_session_dir->root_path(), snapshot_name);
883 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
884 xmlpath = Glib::build_filename (_session_dir->root_path(), legalize_for_path (snapshot_name) + statefile_suffix);
885 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
886 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
891 state_tree = new XMLTree;
895 _writable = exists_and_writable (xmlpath);
897 if (!state_tree->read (xmlpath)) {
898 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
904 XMLNode& root (*state_tree->root());
906 if (root.name() != X_("Session")) {
907 error << string_compose (_("Session file %1 is not a session"), xmlpath) << endmsg;
913 const XMLProperty* prop;
915 if ((prop = root.property ("version")) == 0) {
916 /* no version implies very old version of Ardour */
917 Stateful::loading_state_version = 1000;
919 if (prop->value().find ('.') != string::npos) {
920 /* old school version format */
921 if (prop->value()[0] == '2') {
922 Stateful::loading_state_version = 2000;
924 Stateful::loading_state_version = 3000;
927 Stateful::loading_state_version = atoi (prop->value());
931 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) {
933 std::string backup_path(_session_dir->root_path());
934 std::string backup_filename = string_compose ("%1-%2%3", legalize_for_path (snapshot_name), Stateful::loading_state_version, statefile_suffix);
935 backup_path = Glib::build_filename (backup_path, backup_filename);
937 // only create a backup for a given statefile version once
939 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
941 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
942 xmlpath, backup_path, PROGRAM_NAME)
945 if (!copy_file (xmlpath, backup_path)) {;
955 Session::load_options (const XMLNode& node)
957 LocaleGuard lg (X_("POSIX"));
958 config.set_variables (node);
969 Session::get_template()
971 /* if we don't disable rec-enable, diskstreams
972 will believe they need to store their capture
973 sources in their state node.
976 disable_record (false);
982 Session::state (bool full_state)
984 XMLNode* node = new XMLNode("Session");
988 snprintf(buf, sizeof(buf), "%d", CURRENT_SESSION_FILE_VERSION);
989 node->add_property("version", buf);
991 /* store configuration settings */
995 node->add_property ("name", _name);
996 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
997 node->add_property ("sample-rate", buf);
999 if (session_dirs.size() > 1) {
1003 vector<space_and_path>::iterator i = session_dirs.begin();
1004 vector<space_and_path>::iterator next;
1006 ++i; /* skip the first one */
1010 while (i != session_dirs.end()) {
1014 if (next != session_dirs.end()) {
1024 child = node->add_child ("Path");
1025 child->add_content (p);
1029 /* save the ID counter */
1031 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1032 node->add_property ("id-counter", buf);
1034 /* save the event ID counter */
1036 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1037 node->add_property ("event-counter", buf);
1039 /* various options */
1041 node->add_child_nocopy (config.get_variables ());
1043 node->add_child_nocopy (ARDOUR::SessionMetadata::Metadata()->get_state());
1045 child = node->add_child ("Sources");
1048 Glib::Mutex::Lock sl (source_lock);
1050 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1052 /* Don't save information about non-file Sources, or
1053 * about non-destructive file sources that are empty
1054 * and unused by any regions.
1057 boost::shared_ptr<FileSource> fs;
1059 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1061 if (!fs->destructive()) {
1062 if (fs->empty() && !fs->used()) {
1067 child->add_child_nocopy (siter->second->get_state());
1072 child = node->add_child ("Regions");
1075 Glib::Mutex::Lock rl (region_lock);
1076 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1077 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1078 boost::shared_ptr<Region> r = i->second;
1079 /* only store regions not attached to playlists */
1080 if (r->playlist() == 0) {
1081 child->add_child_nocopy (r->state ());
1085 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1087 if (!cassocs.empty()) {
1088 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1090 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1092 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1093 i->first->id().print (buf, sizeof (buf));
1094 can->add_property (X_("copy"), buf);
1095 i->second->id().print (buf, sizeof (buf));
1096 can->add_property (X_("original"), buf);
1097 ca->add_child_nocopy (*can);
1103 node->add_child_nocopy (_locations->get_state());
1105 // for a template, just create a new Locations, populate it
1106 // with the default start and end, and get the state for that.
1107 Locations loc (*this);
1108 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1109 range->set (max_framepos, 0);
1111 node->add_child_nocopy (loc.get_state());
1114 child = node->add_child ("Bundles");
1116 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1117 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1118 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1120 child->add_child_nocopy (b->get_state());
1125 child = node->add_child ("Routes");
1127 boost::shared_ptr<RouteList> r = routes.reader ();
1129 RoutePublicOrderSorter cmp;
1130 RouteList public_order (*r);
1131 public_order.sort (cmp);
1133 /* the sort should have put control outs first */
1136 assert (_monitor_out == public_order.front());
1139 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1140 if (!(*i)->is_hidden()) {
1142 child->add_child_nocopy ((*i)->get_state());
1144 child->add_child_nocopy ((*i)->get_template());
1150 playlists->add_state (node, full_state);
1152 child = node->add_child ("RouteGroups");
1153 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1154 child->add_child_nocopy ((*i)->get_state());
1158 XMLNode* gain_child = node->add_child ("Click");
1159 gain_child->add_child_nocopy (_click_io->state (full_state));
1160 gain_child->add_child_nocopy (_click_gain->state (full_state));
1164 XMLNode* ns_child = node->add_child ("NamedSelections");
1165 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1167 ns_child->add_child_nocopy ((*i)->get_state());
1172 node->add_child_nocopy (_speakers->get_state());
1173 node->add_child_nocopy (_tempo_map->get_state());
1174 node->add_child_nocopy (get_control_protocol_state());
1177 node->add_child_copy (*_extra_xml);
1184 Session::get_control_protocol_state ()
1186 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1187 return cpm.get_state();
1191 Session::set_state (const XMLNode& node, int version)
1195 const XMLProperty* prop;
1198 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1200 if (node.name() != X_("Session")) {
1201 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1205 if ((prop = node.property ("name")) != 0) {
1206 _name = prop->value ();
1209 if ((prop = node.property (X_("sample-rate"))) != 0) {
1211 _nominal_frame_rate = atoi (prop->value());
1213 if (_nominal_frame_rate != _current_frame_rate) {
1214 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1215 if (r.get_value_or (0)) {
1221 setup_raid_path(_session_dir->root_path());
1223 if ((prop = node.property (X_("id-counter"))) != 0) {
1225 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1226 ID::init_counter (x);
1228 /* old sessions used a timebased counter, so fake
1229 the startup ID counter based on a standard
1234 ID::init_counter (now);
1237 if ((prop = node.property (X_("event-counter"))) != 0) {
1238 Evoral::init_event_id_counter (atoi (prop->value()));
1241 IO::disable_connecting ();
1243 Stateful::save_extra_xml (node);
1245 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1246 load_options (*child);
1247 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1248 load_options (*child);
1250 error << _("Session: XML state has no options section") << endmsg;
1253 if (version >= 3000) {
1254 if ((child = find_named_node (node, "Metadata")) == 0) {
1255 warning << _("Session: XML state has no metadata section") << endmsg;
1256 } else if ( ARDOUR::SessionMetadata::Metadata()->set_state (*child, version) ) {
1261 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1262 _speakers->set_state (*child, version);
1265 if ((child = find_named_node (node, "Sources")) == 0) {
1266 error << _("Session: XML state has no sources section") << endmsg;
1268 } else if (load_sources (*child)) {
1272 if ((child = find_named_node (node, "TempoMap")) == 0) {
1273 error << _("Session: XML state has no Tempo Map section") << endmsg;
1275 } else if (_tempo_map->set_state (*child, version)) {
1279 if ((child = find_named_node (node, "Locations")) == 0) {
1280 error << _("Session: XML state has no locations section") << endmsg;
1282 } else if (_locations->set_state (*child, version)) {
1288 if ((location = _locations->auto_loop_location()) != 0) {
1289 set_auto_loop_location (location);
1292 if ((location = _locations->auto_punch_location()) != 0) {
1293 set_auto_punch_location (location);
1296 if ((location = _locations->session_range_location()) != 0) {
1297 delete _session_range_location;
1298 _session_range_location = location;
1301 if (_session_range_location) {
1302 AudioFileSource::set_header_position_offset (_session_range_location->start());
1305 if ((child = find_named_node (node, "Regions")) == 0) {
1306 error << _("Session: XML state has no Regions section") << endmsg;
1308 } else if (load_regions (*child)) {
1312 if ((child = find_named_node (node, "Playlists")) == 0) {
1313 error << _("Session: XML state has no playlists section") << endmsg;
1315 } else if (playlists->load (*this, *child)) {
1319 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1321 } else if (playlists->load_unused (*this, *child)) {
1325 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1326 if (load_compounds (*child)) {
1331 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1332 if (load_named_selections (*child)) {
1337 if (version >= 3000) {
1338 if ((child = find_named_node (node, "Bundles")) == 0) {
1339 warning << _("Session: XML state has no bundles section") << endmsg;
1342 /* We can't load Bundles yet as they need to be able
1343 to convert from port names to Port objects, which can't happen until
1345 _bundle_xml_node = new XMLNode (*child);
1349 if (version < 3000) {
1350 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1351 error << _("Session: XML state has no diskstreams section") << endmsg;
1353 } else if (load_diskstreams_2X (*child, version)) {
1358 if ((child = find_named_node (node, "Routes")) == 0) {
1359 error << _("Session: XML state has no routes section") << endmsg;
1361 } else if (load_routes (*child, version)) {
1365 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1366 _diskstreams_2X.clear ();
1368 if (version >= 3000) {
1370 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1371 error << _("Session: XML state has no route groups section") << endmsg;
1373 } else if (load_route_groups (*child, version)) {
1377 } else if (version < 3000) {
1379 if ((child = find_named_node (node, "EditGroups")) == 0) {
1380 error << _("Session: XML state has no edit groups section") << endmsg;
1382 } else if (load_route_groups (*child, version)) {
1386 if ((child = find_named_node (node, "MixGroups")) == 0) {
1387 error << _("Session: XML state has no mix groups section") << endmsg;
1389 } else if (load_route_groups (*child, version)) {
1394 if ((child = find_named_node (node, "Click")) == 0) {
1395 warning << _("Session: XML state has no click section") << endmsg;
1396 } else if (_click_io) {
1397 const XMLNodeList& children (child->children());
1398 XMLNodeList::const_iterator i = children.begin();
1399 _click_io->set_state (**i, version);
1401 if (i != children.end()) {
1402 _click_gain->set_state (**i, version);
1406 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1407 ControlProtocolManager::instance().set_protocol_states (*child);
1410 update_have_rec_enabled_track ();
1412 /* here beginneth the second phase ... */
1414 StateReady (); /* EMIT SIGNAL */
1423 Session::load_routes (const XMLNode& node, int version)
1426 XMLNodeConstIterator niter;
1427 RouteList new_routes;
1429 nlist = node.children();
1433 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1435 boost::shared_ptr<Route> route;
1436 if (version < 3000) {
1437 route = XMLRouteFactory_2X (**niter, version);
1439 route = XMLRouteFactory (**niter, version);
1443 error << _("Session: cannot create Route from XML description.") << endmsg;
1447 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1449 new_routes.push_back (route);
1452 add_routes (new_routes, false, false, false);
1457 boost::shared_ptr<Route>
1458 Session::XMLRouteFactory (const XMLNode& node, int version)
1460 boost::shared_ptr<Route> ret;
1462 if (node.name() != "Route") {
1466 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1468 DataType type = DataType::AUDIO;
1469 const XMLProperty* prop = node.property("default-type");
1472 type = DataType (prop->value());
1475 assert (type != DataType::NIL);
1479 boost::shared_ptr<Track> track;
1481 if (type == DataType::AUDIO) {
1482 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1484 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1487 if (track->init()) {
1491 if (track->set_state (node, version)) {
1495 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1496 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1501 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1503 if (r->init () == 0 && r->set_state (node, version) == 0) {
1504 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1505 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1514 boost::shared_ptr<Route>
1515 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1517 boost::shared_ptr<Route> ret;
1519 if (node.name() != "Route") {
1523 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1525 ds_prop = node.property (X_("diskstream"));
1528 DataType type = DataType::AUDIO;
1529 const XMLProperty* prop = node.property("default-type");
1532 type = DataType (prop->value());
1535 assert (type != DataType::NIL);
1539 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1540 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1544 if (i == _diskstreams_2X.end()) {
1545 error << _("Could not find diskstream for route") << endmsg;
1546 return boost::shared_ptr<Route> ();
1549 boost::shared_ptr<Track> track;
1551 if (type == DataType::AUDIO) {
1552 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1554 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1557 if (track->init()) {
1561 if (track->set_state (node, version)) {
1565 track->set_diskstream (*i);
1567 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1568 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1573 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1575 if (r->init () == 0 && r->set_state (node, version) == 0) {
1576 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1577 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1587 Session::load_regions (const XMLNode& node)
1590 XMLNodeConstIterator niter;
1591 boost::shared_ptr<Region> region;
1593 nlist = node.children();
1597 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1598 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1599 error << _("Session: cannot create Region from XML description.");
1600 const XMLProperty *name = (**niter).property("name");
1603 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1614 Session::load_compounds (const XMLNode& node)
1616 XMLNodeList calist = node.children();
1617 XMLNodeConstIterator caiter;
1618 XMLProperty *caprop;
1620 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1621 XMLNode* ca = *caiter;
1625 if ((caprop = ca->property (X_("original"))) == 0) {
1628 orig_id = caprop->value();
1630 if ((caprop = ca->property (X_("copy"))) == 0) {
1633 copy_id = caprop->value();
1635 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1636 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1638 if (!orig || !copy) {
1639 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1645 RegionFactory::add_compound_association (orig, copy);
1652 Session::load_nested_sources (const XMLNode& node)
1655 XMLNodeConstIterator niter;
1657 nlist = node.children();
1659 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1660 if ((*niter)->name() == "Source") {
1662 /* it may already exist, so don't recreate it unnecessarily
1665 XMLProperty* prop = (*niter)->property (X_("id"));
1667 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1671 ID source_id (prop->value());
1673 if (!source_by_id (source_id)) {
1676 SourceFactory::create (*this, **niter, true);
1678 catch (failed_constructor& err) {
1679 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1686 boost::shared_ptr<Region>
1687 Session::XMLRegionFactory (const XMLNode& node, bool full)
1689 const XMLProperty* type = node.property("type");
1693 const XMLNodeList& nlist = node.children();
1695 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1696 XMLNode *child = (*niter);
1697 if (child->name() == "NestedSource") {
1698 load_nested_sources (*child);
1702 if (!type || type->value() == "audio") {
1703 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1704 } else if (type->value() == "midi") {
1705 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1708 } catch (failed_constructor& err) {
1709 return boost::shared_ptr<Region> ();
1712 return boost::shared_ptr<Region> ();
1715 boost::shared_ptr<AudioRegion>
1716 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1718 const XMLProperty* prop;
1719 boost::shared_ptr<Source> source;
1720 boost::shared_ptr<AudioSource> as;
1722 SourceList master_sources;
1723 uint32_t nchans = 1;
1726 if (node.name() != X_("Region")) {
1727 return boost::shared_ptr<AudioRegion>();
1730 if ((prop = node.property (X_("channels"))) != 0) {
1731 nchans = atoi (prop->value().c_str());
1734 if ((prop = node.property ("name")) == 0) {
1735 cerr << "no name for this region\n";
1739 if ((prop = node.property (X_("source-0"))) == 0) {
1740 if ((prop = node.property ("source")) == 0) {
1741 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1742 return boost::shared_ptr<AudioRegion>();
1746 PBD::ID s_id (prop->value());
1748 if ((source = source_by_id (s_id)) == 0) {
1749 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1750 return boost::shared_ptr<AudioRegion>();
1753 as = boost::dynamic_pointer_cast<AudioSource>(source);
1755 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1756 return boost::shared_ptr<AudioRegion>();
1759 sources.push_back (as);
1761 /* pickup other channels */
1763 for (uint32_t n=1; n < nchans; ++n) {
1764 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1765 if ((prop = node.property (buf)) != 0) {
1767 PBD::ID id2 (prop->value());
1769 if ((source = source_by_id (id2)) == 0) {
1770 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1771 return boost::shared_ptr<AudioRegion>();
1774 as = boost::dynamic_pointer_cast<AudioSource>(source);
1776 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1777 return boost::shared_ptr<AudioRegion>();
1779 sources.push_back (as);
1783 for (uint32_t n = 0; n < nchans; ++n) {
1784 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1785 if ((prop = node.property (buf)) != 0) {
1787 PBD::ID id2 (prop->value());
1789 if ((source = source_by_id (id2)) == 0) {
1790 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1791 return boost::shared_ptr<AudioRegion>();
1794 as = boost::dynamic_pointer_cast<AudioSource>(source);
1796 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1797 return boost::shared_ptr<AudioRegion>();
1799 master_sources.push_back (as);
1804 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1806 /* a final detail: this is the one and only place that we know how long missing files are */
1808 if (region->whole_file()) {
1809 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1810 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1812 sfp->set_length (region->length());
1817 if (!master_sources.empty()) {
1818 if (master_sources.size() != nchans) {
1819 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1821 region->set_master_sources (master_sources);
1829 catch (failed_constructor& err) {
1830 return boost::shared_ptr<AudioRegion>();
1834 boost::shared_ptr<MidiRegion>
1835 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1837 const XMLProperty* prop;
1838 boost::shared_ptr<Source> source;
1839 boost::shared_ptr<MidiSource> ms;
1842 if (node.name() != X_("Region")) {
1843 return boost::shared_ptr<MidiRegion>();
1846 if ((prop = node.property ("name")) == 0) {
1847 cerr << "no name for this region\n";
1851 if ((prop = node.property (X_("source-0"))) == 0) {
1852 if ((prop = node.property ("source")) == 0) {
1853 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1854 return boost::shared_ptr<MidiRegion>();
1858 PBD::ID s_id (prop->value());
1860 if ((source = source_by_id (s_id)) == 0) {
1861 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1862 return boost::shared_ptr<MidiRegion>();
1865 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1867 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1868 return boost::shared_ptr<MidiRegion>();
1871 sources.push_back (ms);
1874 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1875 /* a final detail: this is the one and only place that we know how long missing files are */
1877 if (region->whole_file()) {
1878 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1879 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1881 sfp->set_length (region->length());
1889 catch (failed_constructor& err) {
1890 return boost::shared_ptr<MidiRegion>();
1895 Session::get_sources_as_xml ()
1898 XMLNode* node = new XMLNode (X_("Sources"));
1899 Glib::Mutex::Lock lm (source_lock);
1901 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1902 node->add_child_nocopy (i->second->get_state());
1909 Session::path_from_region_name (DataType type, string name, string identifier)
1911 char buf[PATH_MAX+1];
1913 SessionDirectory sdir(get_best_session_directory_for_new_source());
1914 std::string source_dir = ((type == DataType::AUDIO)
1915 ? sdir.sound_path() : sdir.midi_path());
1917 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1919 for (n = 0; n < 999999; ++n) {
1920 if (identifier.length()) {
1921 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1922 identifier.c_str(), n, ext.c_str());
1924 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1928 std::string source_path = Glib::build_filename (source_dir, buf);
1930 if (!Glib::file_test (source_path, Glib::FILE_TEST_EXISTS)) {
1935 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1944 Session::load_sources (const XMLNode& node)
1947 XMLNodeConstIterator niter;
1948 boost::shared_ptr<Source> source;
1950 nlist = node.children();
1954 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1957 if ((source = XMLSourceFactory (**niter)) == 0) {
1958 error << _("Session: cannot create Source from XML description.") << endmsg;
1961 } catch (MissingSource& err) {
1965 if (!no_questions_about_missing_files) {
1966 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1971 switch (user_choice) {
1973 /* user added a new search location, so try again */
1978 /* user asked to quit the entire session load
1983 no_questions_about_missing_files = true;
1987 no_questions_about_missing_files = true;
1992 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1993 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2002 boost::shared_ptr<Source>
2003 Session::XMLSourceFactory (const XMLNode& node)
2005 if (node.name() != "Source") {
2006 return boost::shared_ptr<Source>();
2010 /* note: do peak building in another thread when loading session state */
2011 return SourceFactory::create (*this, node, true);
2014 catch (failed_constructor& err) {
2015 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2016 return boost::shared_ptr<Source>();
2021 Session::save_template (string template_name)
2025 if (_state_of_the_state & CannotSave) {
2029 std::string user_template_dir(user_template_directory());
2031 if (g_mkdir_with_parents (user_template_dir.c_str(), 0755) != 0) {
2032 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2033 user_template_dir, g_strerror (errno)) << endmsg;
2037 tree.set_root (&get_template());
2039 std::string template_dir_path(user_template_dir);
2041 /* directory to put the template in */
2042 template_dir_path = Glib::build_filename (template_dir_path, template_name);
2044 if (Glib::file_test (template_dir_path, Glib::FILE_TEST_EXISTS)) {
2045 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2046 template_dir_path) << endmsg;
2050 if (g_mkdir_with_parents (template_dir_path.c_str(), 0755) != 0) {
2051 error << string_compose(_("Could not create directory for Session template\"%1\" (%2)"),
2052 template_dir_path, g_strerror (errno)) << endmsg;
2057 std::string template_file_path(template_dir_path);
2058 template_file_path = Glib::build_filename (template_file_path, template_name + template_suffix);
2060 if (!tree.write (template_file_path)) {
2061 error << _("template not saved") << endmsg;
2065 /* copy plugin state directory */
2067 std::string template_plugin_state_path(template_dir_path);
2068 template_plugin_state_path = Glib::build_filename (template_plugin_state_path, X_("plugins"));
2070 if (g_mkdir_with_parents (template_plugin_state_path.c_str(), 0755) != 0) {
2071 error << string_compose(_("Could not create directory for Session template plugin state\"%1\" (%2)"),
2072 template_plugin_state_path, g_strerror (errno)) << endmsg;
2076 copy_files (plugins_dir(), template_plugin_state_path);
2082 Session::refresh_disk_space ()
2084 #if HAVE_SYS_VFS_H && HAVE_SYS_STATVFS_H
2086 Glib::Mutex::Lock lm (space_lock);
2088 /* get freespace on every FS that is part of the session path */
2090 _total_free_4k_blocks = 0;
2091 _total_free_4k_blocks_uncertain = false;
2093 for (vector<space_and_path>::iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2095 struct statfs statfsbuf;
2096 statfs (i->path.c_str(), &statfsbuf);
2098 double const scale = statfsbuf.f_bsize / 4096.0;
2100 /* See if this filesystem is read-only */
2101 struct statvfs statvfsbuf;
2102 statvfs (i->path.c_str(), &statvfsbuf);
2104 /* f_bavail can be 0 if it is undefined for whatever
2105 filesystem we are looking at; Samba shares mounted
2106 via GVFS are an example of this.
2108 if (statfsbuf.f_bavail == 0) {
2109 /* block count unknown */
2111 i->blocks_unknown = true;
2112 } else if (statvfsbuf.f_flag & ST_RDONLY) {
2113 /* read-only filesystem */
2115 i->blocks_unknown = false;
2117 /* read/write filesystem with known space */
2118 i->blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2119 i->blocks_unknown = false;
2122 _total_free_4k_blocks += i->blocks;
2123 if (i->blocks_unknown) {
2124 _total_free_4k_blocks_uncertain = true;
2131 Session::get_best_session_directory_for_new_source ()
2133 vector<space_and_path>::iterator i;
2134 string result = _session_dir->root_path();
2136 /* handle common case without system calls */
2138 if (session_dirs.size() == 1) {
2142 /* OK, here's the algorithm we're following here:
2144 We want to select which directory to use for
2145 the next file source to be created. Ideally,
2146 we'd like to use a round-robin process so as to
2147 get maximum performance benefits from splitting
2148 the files across multiple disks.
2150 However, in situations without much diskspace, an
2151 RR approach may end up filling up a filesystem
2152 with new files while others still have space.
2153 Its therefore important to pay some attention to
2154 the freespace in the filesystem holding each
2155 directory as well. However, if we did that by
2156 itself, we'd keep creating new files in the file
2157 system with the most space until it was as full
2158 as all others, thus negating any performance
2159 benefits of this RAID-1 like approach.
2161 So, we use a user-configurable space threshold. If
2162 there are at least 2 filesystems with more than this
2163 much space available, we use RR selection between them.
2164 If not, then we pick the filesystem with the most space.
2166 This gets a good balance between the two
2170 refresh_disk_space ();
2172 int free_enough = 0;
2174 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2175 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2180 if (free_enough >= 2) {
2181 /* use RR selection process, ensuring that the one
2185 i = last_rr_session_dir;
2188 if (++i == session_dirs.end()) {
2189 i = session_dirs.begin();
2192 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2193 if (create_session_directory ((*i).path)) {
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 if (create_session_directory ((*i).path)) {
2217 last_rr_session_dir = i;
2227 Session::load_named_selections (const XMLNode& node)
2230 XMLNodeConstIterator niter;
2233 nlist = node.children();
2237 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2239 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2240 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2248 Session::XMLNamedSelectionFactory (const XMLNode& node)
2251 return new NamedSelection (*this, node);
2254 catch (failed_constructor& err) {
2260 Session::automation_dir () const
2262 return Glib::build_filename (_path, "automation");
2266 Session::analysis_dir () const
2268 return Glib::build_filename (_path, "analysis");
2272 Session::plugins_dir () const
2274 return Glib::build_filename (_path, "plugins");
2278 Session::externals_dir () const
2280 return Glib::build_filename (_path, "externals");
2284 Session::load_bundles (XMLNode const & node)
2286 XMLNodeList nlist = node.children();
2287 XMLNodeConstIterator niter;
2291 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2292 if ((*niter)->name() == "InputBundle") {
2293 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2294 } else if ((*niter)->name() == "OutputBundle") {
2295 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2297 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2306 Session::load_route_groups (const XMLNode& node, int version)
2308 XMLNodeList nlist = node.children();
2309 XMLNodeConstIterator niter;
2313 if (version >= 3000) {
2315 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2316 if ((*niter)->name() == "RouteGroup") {
2317 RouteGroup* rg = new RouteGroup (*this, "");
2318 add_route_group (rg);
2319 rg->set_state (**niter, version);
2323 } else if (version < 3000) {
2325 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2326 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2327 RouteGroup* rg = new RouteGroup (*this, "");
2328 add_route_group (rg);
2329 rg->set_state (**niter, version);
2338 Session::auto_save()
2340 save_state (_current_snapshot_name);
2344 state_file_filter (const string &str, void */*arg*/)
2346 return (str.length() > strlen(statefile_suffix) &&
2347 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2351 bool operator()(const string* a, const string* b) {
2357 remove_end(string* state)
2359 string statename(*state);
2361 string::size_type start,end;
2362 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2363 statename = statename.substr (start+1);
2366 if ((end = statename.rfind(".ardour")) == string::npos) {
2367 end = statename.length();
2370 return new string(statename.substr (0, end));
2374 Session::possible_states (string path)
2376 PathScanner scanner;
2377 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2379 transform(states->begin(), states->end(), states->begin(), remove_end);
2382 sort (states->begin(), states->end(), cmp);
2388 Session::possible_states () const
2390 return possible_states(_path);
2394 Session::add_route_group (RouteGroup* g)
2396 _route_groups.push_back (g);
2397 route_group_added (g); /* EMIT SIGNAL */
2399 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2400 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2401 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2407 Session::remove_route_group (RouteGroup& rg)
2409 list<RouteGroup*>::iterator i;
2411 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2412 _route_groups.erase (i);
2415 route_group_removed (); /* EMIT SIGNAL */
2419 /** Set a new order for our route groups, without adding or removing any.
2420 * @param groups Route group list in the new order.
2423 Session::reorder_route_groups (list<RouteGroup*> groups)
2425 _route_groups = groups;
2427 route_groups_reordered (); /* EMIT SIGNAL */
2433 Session::route_group_by_name (string name)
2435 list<RouteGroup *>::iterator i;
2437 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2438 if ((*i)->name() == name) {
2446 Session::all_route_group() const
2448 return *_all_route_group;
2452 Session::add_commands (vector<Command*> const & cmds)
2454 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2460 Session::begin_reversible_command (const string& name)
2462 begin_reversible_command (g_quark_from_string (name.c_str ()));
2465 /** Begin a reversible command using a GQuark to identify it.
2466 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2467 * but there must be as many begin...()s as there are commit...()s.
2470 Session::begin_reversible_command (GQuark q)
2472 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2473 to hold all the commands that are committed. This keeps the order of
2474 commands correct in the history.
2477 if (_current_trans == 0) {
2478 /* start a new transaction */
2479 assert (_current_trans_quarks.empty ());
2480 _current_trans = new UndoTransaction();
2481 _current_trans->set_name (g_quark_to_string (q));
2484 _current_trans_quarks.push_front (q);
2488 Session::commit_reversible_command (Command *cmd)
2490 assert (_current_trans);
2491 assert (!_current_trans_quarks.empty ());
2496 _current_trans->add_command (cmd);
2499 _current_trans_quarks.pop_front ();
2501 if (!_current_trans_quarks.empty ()) {
2502 /* the transaction we're committing is not the top-level one */
2506 if (_current_trans->empty()) {
2507 /* no commands were added to the transaction, so just get rid of it */
2508 delete _current_trans;
2513 gettimeofday (&now, 0);
2514 _current_trans->set_timestamp (now);
2516 _history.add (_current_trans);
2521 accept_all_audio_files (const string& path, void */*arg*/)
2523 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2527 if (!AudioFileSource::safe_audio_file_extension (path)) {
2535 accept_all_midi_files (const string& path, void */*arg*/)
2537 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2541 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2542 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2543 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2547 accept_all_state_files (const string& path, void */*arg*/)
2549 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2553 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2557 Session::find_all_sources (string path, set<string>& result)
2562 if (!tree.read (path)) {
2566 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2571 XMLNodeConstIterator niter;
2573 nlist = node->children();
2577 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2581 if ((prop = (*niter)->property (X_("type"))) == 0) {
2585 DataType type (prop->value());
2587 if ((prop = (*niter)->property (X_("name"))) == 0) {
2591 if (Glib::path_is_absolute (prop->value())) {
2592 /* external file, ignore */
2600 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2601 result.insert (found_path);
2609 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2611 PathScanner scanner;
2612 vector<string*>* state_files;
2614 string this_snapshot_path;
2620 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2621 ripped = ripped.substr (0, ripped.length() - 1);
2624 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2626 if (state_files == 0) {
2631 this_snapshot_path = _path;
2632 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2633 this_snapshot_path += statefile_suffix;
2635 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2637 if (exclude_this_snapshot && **i == this_snapshot_path) {
2641 if (find_all_sources (**i, result) < 0) {
2649 struct RegionCounter {
2650 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2651 AudioSourceList::iterator iter;
2652 boost::shared_ptr<Region> region;
2655 RegionCounter() : count (0) {}
2659 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2661 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2662 return r.get_value_or (1);
2666 Session::cleanup_regions ()
2668 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2670 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2672 uint32_t used = playlists->region_use_count (i->second);
2674 if (used == 0 && !i->second->automatic ()) {
2675 RegionFactory::map_remove (i->second);
2679 /* dump the history list */
2686 Session::cleanup_sources (CleanupReport& rep)
2688 // FIXME: needs adaptation to midi
2690 vector<boost::shared_ptr<Source> > dead_sources;
2691 PathScanner scanner;
2694 vector<space_and_path>::iterator i;
2695 vector<space_and_path>::iterator nexti;
2696 vector<string*>* candidates;
2697 vector<string*>* candidates2;
2698 vector<string> unused;
2699 set<string> all_sources;
2704 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2706 /* consider deleting all unused playlists */
2708 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2713 /* sync the "all regions" property of each playlist with its current state
2716 playlists->sync_all_regions_with_regions ();
2718 /* find all un-used sources */
2723 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2725 SourceMap::iterator tmp;
2730 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2734 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2735 dead_sources.push_back (i->second);
2736 i->second->drop_references ();
2742 /* build a list of all the possible audio directories for the session */
2744 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2749 SessionDirectory sdir ((*i).path);
2750 audio_path += sdir.sound_path();
2752 if (nexti != session_dirs.end()) {
2760 /* build a list of all the possible midi directories for the session */
2762 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2767 SessionDirectory sdir ((*i).path);
2768 midi_path += sdir.midi_path();
2770 if (nexti != session_dirs.end()) {
2777 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2778 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2784 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2785 candidates->push_back (*i);
2790 candidates = candidates2; // might still be null
2793 /* find all sources, but don't use this snapshot because the
2794 state file on disk still references sources we may have already
2798 find_all_sources_across_snapshots (all_sources, true);
2800 /* add our current source list
2803 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2804 boost::shared_ptr<FileSource> fs;
2805 SourceMap::iterator tmp = i;
2808 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2809 if (playlists->source_use_count (fs) != 0) {
2810 all_sources.insert (fs->path());
2813 /* we might not remove this source from disk, because it may be used
2814 by other snapshots, but its not being used in this version
2815 so lets get rid of it now, along with any representative regions
2819 RegionFactory::remove_regions_using_source (i->second);
2827 char tmppath1[PATH_MAX+1];
2828 char tmppath2[PATH_MAX+1];
2831 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2836 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2838 if (realpath(spath.c_str(), tmppath1) == 0) {
2839 error << string_compose (_("Cannot expand path %1 (%2)"),
2840 spath, strerror (errno)) << endmsg;
2844 if (realpath((*i).c_str(), tmppath2) == 0) {
2845 error << string_compose (_("Cannot expand path %1 (%2)"),
2846 (*i), strerror (errno)) << endmsg;
2850 if (strcmp(tmppath1, tmppath2) == 0) {
2857 unused.push_back (spath);
2866 /* now try to move all unused files into the "dead" directory(ies) */
2868 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2869 struct stat statbuf;
2873 /* don't move the file across filesystems, just
2874 stick it in the `dead_dir_name' directory
2875 on whichever filesystem it was already on.
2878 if ((*x).find ("/sounds/") != string::npos) {
2880 /* old school, go up 1 level */
2882 newpath = Glib::path_get_dirname (*x); // "sounds"
2883 newpath = Glib::path_get_dirname (newpath); // "session-name"
2887 /* new school, go up 4 levels */
2889 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2890 newpath = Glib::path_get_dirname (newpath); // "session-name"
2891 newpath = Glib::path_get_dirname (newpath); // "interchange"
2892 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2895 newpath = Glib::build_filename (newpath, dead_dir_name);
2897 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2898 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2902 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2904 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2906 /* the new path already exists, try versioning */
2908 char buf[PATH_MAX+1];
2912 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2915 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2916 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2920 if (version == 999) {
2921 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2925 newpath = newpath_v;
2930 /* it doesn't exist, or we can't read it or something */
2934 stat ((*x).c_str(), &statbuf);
2936 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2937 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2938 (*x), newpath, strerror (errno))
2943 /* see if there an easy to find peakfile for this file, and remove it.
2946 string base = basename_nosuffix (*x);
2947 base += "%A"; /* this is what we add for the channel suffix of all native files,
2948 or for the first channel of embedded files. it will miss
2949 some peakfiles for other channels
2951 string peakpath = peak_path (base);
2953 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2954 if (::unlink (peakpath.c_str()) != 0) {
2955 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2956 peakpath, _path, strerror (errno))
2958 /* try to back out */
2959 ::rename (newpath.c_str(), _path.c_str());
2964 rep.paths.push_back (*x);
2965 rep.space += statbuf.st_size;
2968 /* dump the history list */
2972 /* save state so we don't end up a session file
2973 referring to non-existent sources.
2980 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2986 Session::cleanup_trash_sources (CleanupReport& rep)
2988 // FIXME: needs adaptation for MIDI
2990 vector<space_and_path>::iterator i;
2996 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2998 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
3000 clear_directory (dead_dir, &rep.space, &rep.paths);
3007 Session::set_dirty ()
3009 bool was_dirty = dirty();
3011 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3015 DirtyChanged(); /* EMIT SIGNAL */
3021 Session::set_clean ()
3023 bool was_dirty = dirty();
3025 _state_of_the_state = Clean;
3029 DirtyChanged(); /* EMIT SIGNAL */
3034 Session::set_deletion_in_progress ()
3036 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3040 Session::clear_deletion_in_progress ()
3042 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3046 Session::add_controllable (boost::shared_ptr<Controllable> c)
3048 /* this adds a controllable to the list managed by the Session.
3049 this is a subset of those managed by the Controllable class
3050 itself, and represents the only ones whose state will be saved
3051 as part of the session.
3054 Glib::Mutex::Lock lm (controllables_lock);
3055 controllables.insert (c);
3058 struct null_deleter { void operator()(void const *) const {} };
3061 Session::remove_controllable (Controllable* c)
3063 if (_state_of_the_state & Deletion) {
3067 Glib::Mutex::Lock lm (controllables_lock);
3069 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3071 if (x != controllables.end()) {
3072 controllables.erase (x);
3076 boost::shared_ptr<Controllable>
3077 Session::controllable_by_id (const PBD::ID& id)
3079 Glib::Mutex::Lock lm (controllables_lock);
3081 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3082 if ((*i)->id() == id) {
3087 return boost::shared_ptr<Controllable>();
3090 boost::shared_ptr<Controllable>
3091 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3093 boost::shared_ptr<Controllable> c;
3094 boost::shared_ptr<Route> r;
3096 switch (desc.top_level_type()) {
3097 case ControllableDescriptor::NamedRoute:
3099 std::string str = desc.top_level_name();
3100 if (str == "master") {
3102 } else if (str == "control" || str == "listen") {
3105 r = route_by_name (desc.top_level_name());
3110 case ControllableDescriptor::RemoteControlID:
3111 r = route_by_remote_id (desc.rid());
3119 switch (desc.subtype()) {
3120 case ControllableDescriptor::Gain:
3121 c = r->gain_control ();
3124 case ControllableDescriptor::Solo:
3125 c = r->solo_control();
3128 case ControllableDescriptor::Mute:
3129 c = r->mute_control();
3132 case ControllableDescriptor::Recenable:
3134 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3137 c = t->rec_enable_control ();
3142 case ControllableDescriptor::PanDirection:
3144 c = r->pannable()->pan_azimuth_control;
3148 case ControllableDescriptor::PanWidth:
3150 c = r->pannable()->pan_width_control;
3154 case ControllableDescriptor::PanElevation:
3156 c = r->pannable()->pan_elevation_control;
3160 case ControllableDescriptor::Balance:
3161 /* XXX simple pan control */
3164 case ControllableDescriptor::PluginParameter:
3166 uint32_t plugin = desc.target (0);
3167 uint32_t parameter_index = desc.target (1);
3169 /* revert to zero based counting */
3175 if (parameter_index > 0) {
3179 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3182 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3183 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3188 case ControllableDescriptor::SendGain:
3190 uint32_t send = desc.target (0);
3192 /* revert to zero-based counting */
3198 boost::shared_ptr<Processor> p = r->nth_send (send);
3201 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3202 boost::shared_ptr<Amp> a = s->amp();
3205 c = s->amp()->gain_control();
3212 /* relax and return a null pointer */
3220 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3223 Stateful::add_instant_xml (node, _path);
3226 if (write_to_config) {
3227 Config->add_instant_xml (node);
3232 Session::instant_xml (const string& node_name)
3234 return Stateful::instant_xml (node_name, _path);
3238 Session::save_history (string snapshot_name)
3246 if (snapshot_name.empty()) {
3247 snapshot_name = _current_snapshot_name;
3250 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3251 const string backup_filename = history_filename + backup_suffix;
3252 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), history_filename));
3253 const std::string backup_path(Glib::build_filename (_session_dir->root_path(), backup_filename));
3255 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3256 if (::g_rename (xml_path.c_str(), backup_path.c_str()) != 0) {
3257 error << _("could not backup old history file, current history not saved") << endmsg;
3262 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3266 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3268 if (!tree.write (xml_path))
3270 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3272 if (g_remove (xml_path.c_str()) != 0) {
3273 error << string_compose(_("Could not remove history file at path \"%1\" (%2)"),
3274 xml_path, g_strerror (errno)) << endmsg;
3276 if (::g_rename (backup_path.c_str(), xml_path.c_str()) != 0) {
3277 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3278 backup_path, g_strerror (errno)) << endmsg;
3288 Session::restore_history (string snapshot_name)
3292 if (snapshot_name.empty()) {
3293 snapshot_name = _current_snapshot_name;
3296 const std::string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3297 const std::string xml_path(Glib::build_filename (_session_dir->root_path(), xml_filename));
3299 info << "Loading history from " << xml_path << endmsg;
3301 if (!Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS)) {
3302 info << string_compose (_("%1: no history file \"%2\" for this session."),
3303 _name, xml_path) << endmsg;
3307 if (!tree.read (xml_path)) {
3308 error << string_compose (_("Could not understand session history file \"%1\""),
3309 xml_path) << endmsg;
3316 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3319 UndoTransaction* ut = new UndoTransaction ();
3322 ut->set_name(t->property("name")->value());
3323 stringstream ss(t->property("tv-sec")->value());
3325 ss.str(t->property("tv-usec")->value());
3327 ut->set_timestamp(tv);
3329 for (XMLNodeConstIterator child_it = t->children().begin();
3330 child_it != t->children().end(); child_it++)
3332 XMLNode *n = *child_it;
3335 if (n->name() == "MementoCommand" ||
3336 n->name() == "MementoUndoCommand" ||
3337 n->name() == "MementoRedoCommand") {
3339 if ((c = memento_command_factory(n))) {
3343 } else if (n->name() == "NoteDiffCommand") {
3344 PBD::ID id (n->property("midi-source")->value());
3345 boost::shared_ptr<MidiSource> midi_source =
3346 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3348 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3350 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3353 } else if (n->name() == "SysExDiffCommand") {
3355 PBD::ID id (n->property("midi-source")->value());
3356 boost::shared_ptr<MidiSource> midi_source =
3357 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3359 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3361 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3364 } else if (n->name() == "PatchChangeDiffCommand") {
3366 PBD::ID id (n->property("midi-source")->value());
3367 boost::shared_ptr<MidiSource> midi_source =
3368 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3370 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3372 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3375 } else if (n->name() == "StatefulDiffCommand") {
3376 if ((c = stateful_diff_command_factory (n))) {
3377 ut->add_command (c);
3380 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3391 Session::config_changed (std::string p, bool ours)
3397 if (p == "seamless-loop") {
3399 } else if (p == "rf-speed") {
3401 } else if (p == "auto-loop") {
3403 } else if (p == "auto-input") {
3405 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3406 /* auto-input only makes a difference if we're rolling */
3407 set_track_monitor_input_status (!config.get_auto_input());
3410 } else if (p == "punch-in") {
3414 if ((location = _locations->auto_punch_location()) != 0) {
3416 if (config.get_punch_in ()) {
3417 replace_event (SessionEvent::PunchIn, location->start());
3419 remove_event (location->start(), SessionEvent::PunchIn);
3423 } else if (p == "punch-out") {
3427 if ((location = _locations->auto_punch_location()) != 0) {
3429 if (config.get_punch_out()) {
3430 replace_event (SessionEvent::PunchOut, location->end());
3432 clear_events (SessionEvent::PunchOut);
3436 } else if (p == "edit-mode") {
3438 Glib::Mutex::Lock lm (playlists->lock);
3440 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3441 (*i)->set_edit_mode (Config->get_edit_mode ());
3444 } else if (p == "use-video-sync") {
3446 waiting_for_sync_offset = config.get_use_video_sync();
3448 } else if (p == "mmc-control") {
3450 //poke_midi_thread ();
3452 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3454 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3456 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3458 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3460 } else if (p == "midi-control") {
3462 //poke_midi_thread ();
3464 } else if (p == "raid-path") {
3466 setup_raid_path (config.get_raid_path());
3468 } else if (p == "timecode-format") {
3472 } else if (p == "video-pullup") {
3476 } else if (p == "seamless-loop") {
3478 if (play_loop && transport_rolling()) {
3479 // to reset diskstreams etc
3480 request_play_loop (true);
3483 } else if (p == "rf-speed") {
3485 cumulative_rf_motion = 0;
3488 } else if (p == "click-sound") {
3490 setup_click_sounds (1);
3492 } else if (p == "click-emphasis-sound") {
3494 setup_click_sounds (-1);
3496 } else if (p == "clicking") {
3498 if (Config->get_clicking()) {
3499 if (_click_io && click_data) { // don't require emphasis data
3506 } else if (p == "click-gain") {
3509 _click_gain->set_gain (Config->get_click_gain(), this);
3512 } else if (p == "send-mtc") {
3514 if (Config->get_send_mtc ()) {
3515 /* mark us ready to send */
3516 next_quarter_frame_to_send = 0;
3519 } else if (p == "send-mmc") {
3521 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3523 } else if (p == "midi-feedback") {
3525 session_midi_feedback = Config->get_midi_feedback();
3527 } else if (p == "jack-time-master") {
3529 engine().reset_timebase ();
3531 } else if (p == "native-file-header-format") {
3533 if (!first_file_header_format_reset) {
3534 reset_native_file_format ();
3537 first_file_header_format_reset = false;
3539 } else if (p == "native-file-data-format") {
3541 if (!first_file_data_format_reset) {
3542 reset_native_file_format ();
3545 first_file_data_format_reset = false;
3547 } else if (p == "external-sync") {
3548 if (!config.get_external_sync()) {
3549 drop_sync_source ();
3551 switch_to_sync_source (config.get_sync_source());
3553 } else if (p == "remote-model") {
3554 set_remote_control_ids ();
3555 } else if (p == "denormal-model") {
3557 } else if (p == "history-depth") {
3558 set_history_depth (Config->get_history_depth());
3559 } else if (p == "sync-all-route-ordering") {
3560 sync_order_keys ("session");
3561 } else if (p == "initial-program-change") {
3563 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3566 buf[0] = MIDI::program; // channel zero by default
3567 buf[1] = (Config->get_initial_program_change() & 0x7f);
3569 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3571 } else if (p == "solo-mute-override") {
3572 // catch_up_on_solo_mute_override ();
3573 } else if (p == "listen-position" || p == "pfl-position") {
3574 listen_position_changed ();
3575 } else if (p == "solo-control-is-listen-control") {
3576 solo_control_mode_changed ();
3577 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3578 last_timecode_valid = false;
3579 } else if (p == "playback-buffer-seconds") {
3580 AudioSource::allocate_working_buffers (frame_rate());
3581 } else if (p == "automation-thinning-factor") {
3582 Evoral::ControlList::set_thinning_factor (Config->get_automation_thinning_factor());
3589 Session::set_history_depth (uint32_t d)
3591 _history.set_depth (d);
3595 Session::load_diskstreams_2X (XMLNode const & node, int)
3598 XMLNodeConstIterator citer;
3600 clist = node.children();
3602 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3605 /* diskstreams added automatically by DiskstreamCreated handler */
3606 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3607 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3608 _diskstreams_2X.push_back (dsp);
3610 error << _("Session: unknown diskstream type in XML") << endmsg;
3614 catch (failed_constructor& err) {
3615 error << _("Session: could not load diskstream via XML state") << endmsg;
3623 /** Connect things to the MMC object */
3625 Session::setup_midi_machine_control ()
3627 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3629 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3630 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3631 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3632 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3633 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3634 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3635 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3636 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3637 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3638 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3639 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3640 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3641 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3643 /* also handle MIDI SPP because its so common */
3645 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this));
3646 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this));
3647 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this));
3650 boost::shared_ptr<Controllable>
3651 Session::solo_cut_control() const
3653 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3654 controls in Ardour that currently get presented to the user in the GUI that require
3655 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3657 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3658 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3662 return _solo_cut_control;
3666 Session::rename (const std::string& new_name)
3668 string legal_name = legalize_for_path (new_name);
3674 string const old_sources_root = _session_dir->sources_root();
3676 #define RENAME ::rename
3681 * interchange subdirectory
3685 * Backup files are left unchanged and not renamed.
3688 /* pass one: not 100% safe check that the new directory names don't
3692 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3697 /* this is a stupid hack because Glib::path_get_dirname() is
3698 * lexical-only, and so passing it /a/b/c/ gives a different
3699 * result than passing it /a/b/c ...
3702 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3703 oldstr = oldstr.substr (0, oldstr.length() - 1);
3706 string base = Glib::path_get_dirname (oldstr);
3707 string p = Glib::path_get_basename (oldstr);
3709 newstr = Glib::build_filename (base, legal_name);
3711 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3718 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3723 /* this is a stupid hack because Glib::path_get_dirname() is
3724 * lexical-only, and so passing it /a/b/c/ gives a different
3725 * result than passing it /a/b/c ...
3728 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3729 oldstr = oldstr.substr (0, oldstr.length() - 1);
3732 string base = Glib::path_get_dirname (oldstr);
3733 string p = Glib::path_get_basename (oldstr);
3735 newstr = Glib::build_filename (base, legal_name);
3737 cerr << "Rename " << oldstr << " => " << newstr << endl;
3739 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3744 (*_session_dir) = newstr;
3749 /* directory below interchange */
3751 v.push_back (newstr);
3752 v.push_back (interchange_dir_name);
3755 oldstr = Glib::build_filename (v);
3758 v.push_back (newstr);
3759 v.push_back (interchange_dir_name);
3760 v.push_back (legal_name);
3762 newstr = Glib::build_filename (v);
3764 cerr << "Rename " << oldstr << " => " << newstr << endl;
3766 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3773 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3774 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3776 cerr << "Rename " << oldstr << " => " << newstr << endl;
3778 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3785 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3787 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3788 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3790 cerr << "Rename " << oldstr << " => " << newstr << endl;
3792 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3797 /* update file source paths */
3799 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3800 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3802 string p = fs->path ();
3803 boost::replace_all (p, old_sources_root, _session_dir->sources_root());
3808 /* remove old name from recent sessions */
3810 remove_recent_sessions (_path);
3813 _current_snapshot_name = new_name;
3818 /* save state again to get everything just right */
3820 save_state (_current_snapshot_name);
3823 /* add to recent sessions */
3825 store_recent_sessions (new_name, _path);