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>
52 #include <glibmm/thread.h>
54 #include <boost/algorithm/string.hpp>
56 #include "midi++/mmc.h"
57 #include "midi++/port.h"
58 #include "midi++/manager.h"
60 #include "pbd/boost_debug.h"
61 #include "pbd/basename.h"
62 #include "pbd/controllable_descriptor.h"
63 #include "pbd/enumwriter.h"
64 #include "pbd/error.h"
65 #include "pbd/pathscanner.h"
66 #include "pbd/pthread_utils.h"
67 #include "pbd/search_path.h"
68 #include "pbd/stacktrace.h"
69 #include "pbd/convert.h"
70 #include "pbd/clear_dir.h"
72 #include "ardour/amp.h"
73 #include "ardour/audio_diskstream.h"
74 #include "ardour/audio_playlist_source.h"
75 #include "ardour/audio_track.h"
76 #include "ardour/audioengine.h"
77 #include "ardour/audiofilesource.h"
78 #include "ardour/audioplaylist.h"
79 #include "ardour/audioregion.h"
80 #include "ardour/auditioner.h"
81 #include "ardour/automation_control.h"
82 #include "ardour/buffer.h"
83 #include "ardour/butler.h"
84 #include "ardour/configuration.h"
85 #include "ardour/control_protocol_manager.h"
86 #include "ardour/crossfade.h"
87 #include "ardour/cycle_timer.h"
88 #include "ardour/directory_names.h"
89 #include "ardour/filename_extensions.h"
90 #include "ardour/io_processor.h"
91 #include "ardour/location.h"
92 #include "ardour/midi_diskstream.h"
93 #include "ardour/midi_model.h"
94 #include "ardour/midi_patch_manager.h"
95 #include "ardour/midi_playlist.h"
96 #include "ardour/midi_region.h"
97 #include "ardour/midi_source.h"
98 #include "ardour/midi_track.h"
99 #include "ardour/named_selection.h"
100 #include "ardour/pannable.h"
101 #include "ardour/processor.h"
102 #include "ardour/port.h"
103 #include "ardour/proxy_controllable.h"
104 #include "ardour/recent_sessions.h"
105 #include "ardour/region_factory.h"
106 #include "ardour/route_group.h"
107 #include "ardour/send.h"
108 #include "ardour/session.h"
109 #include "ardour/session_directory.h"
110 #include "ardour/session_metadata.h"
111 #include "ardour/session_state_utils.h"
112 #include "ardour/session_playlists.h"
113 #include "ardour/session_utils.h"
114 #include "ardour/silentfilesource.h"
115 #include "ardour/slave.h"
116 #include "ardour/smf_source.h"
117 #include "ardour/sndfile_helpers.h"
118 #include "ardour/sndfilesource.h"
119 #include "ardour/source_factory.h"
120 #include "ardour/speakers.h"
121 #include "ardour/template_utils.h"
122 #include "ardour/tempo.h"
123 #include "ardour/ticker.h"
124 #include "ardour/user_bundle.h"
125 #include "ardour/utils.h"
126 #include "ardour/utils.h"
127 #include "ardour/version.h"
128 #include "ardour/playlist_factory.h"
130 #include "control_protocol/control_protocol.h"
136 using namespace ARDOUR;
139 /** @param snapshot_name Snapshot name, without the .ardour prefix */
141 Session::first_stage_init (string fullpath, string snapshot_name)
143 if (fullpath.length() == 0) {
145 throw failed_constructor();
148 char buf[PATH_MAX+1];
149 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
150 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
152 throw failed_constructor();
157 if (_path[_path.length()-1] != G_DIR_SEPARATOR) {
158 _path += G_DIR_SEPARATOR;
161 /* these two are just provisional settings. set_state()
162 will likely override them.
165 _name = _current_snapshot_name = snapshot_name;
167 set_history_depth (Config->get_history_depth());
169 _current_frame_rate = _engine.frame_rate ();
170 _nominal_frame_rate = _current_frame_rate;
171 _base_frame_rate = _current_frame_rate;
173 _tempo_map = new TempoMap (_current_frame_rate);
174 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
177 _non_soloed_outs_muted = false;
179 _solo_isolated_cnt = 0;
180 g_atomic_int_set (&processing_prohibited, 0);
181 _transport_speed = 0;
182 _last_transport_speed = 0;
183 _target_transport_speed = 0;
184 auto_play_legal = false;
185 transport_sub_state = 0;
186 _transport_frame = 0;
187 _requested_return_frame = -1;
188 _session_range_location = 0;
189 g_atomic_int_set (&_record_status, Disabled);
190 loop_changing = false;
193 _last_roll_location = 0;
194 _last_roll_or_reversal_location = 0;
195 _last_record_location = 0;
196 pending_locate_frame = 0;
197 pending_locate_roll = false;
198 pending_locate_flush = false;
199 state_was_pending = false;
201 outbound_mtc_timecode_frame = 0;
202 next_quarter_frame_to_send = -1;
203 current_block_size = 0;
204 solo_update_disabled = false;
205 _have_captured = false;
206 _worst_output_latency = 0;
207 _worst_input_latency = 0;
208 _worst_track_latency = 0;
209 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
210 _was_seamless = Config->get_seamless_loop ();
212 _send_qf_mtc = false;
213 _pframes_since_last_mtc = 0;
214 g_atomic_int_set (&_playback_load, 100);
215 g_atomic_int_set (&_capture_load, 100);
218 pending_abort = false;
219 destructive_index = 0;
220 first_file_data_format_reset = true;
221 first_file_header_format_reset = true;
222 post_export_sync = false;
225 no_questions_about_missing_files = false;
226 _speakers.reset (new Speakers);
228 AudioDiskstream::allocate_working_buffers();
230 /* default short fade = 15ms */
232 Crossfade::set_short_xfade_length ((framecnt_t) floor (config.get_short_xfade_seconds() * frame_rate()));
233 SndFileSource::setup_standard_crossfades (*this, frame_rate());
235 last_mmc_step.tv_sec = 0;
236 last_mmc_step.tv_usec = 0;
239 /* click sounds are unset by default, which causes us to internal
240 waveforms for clicks.
244 click_emphasis_length = 0;
247 process_function = &Session::process_with_events;
249 if (config.get_use_video_sync()) {
250 waiting_for_sync_offset = true;
252 waiting_for_sync_offset = false;
255 last_timecode_when = 0;
256 last_timecode_valid = false;
260 last_rr_session_dir = session_dirs.begin();
261 refresh_disk_space ();
263 /* default: assume simple stereo speaker configuration */
265 _speakers->setup_default_speakers (2);
269 average_slave_delta = 1800; // !!! why 1800 ????
270 have_first_delta_accumulator = false;
271 delta_accumulator_cnt = 0;
272 _slave_state = Stopped;
274 _solo_cut_control.reset (new ProxyControllable (_("solo cut control (dB)"), PBD::Controllable::GainLike,
275 boost::bind (&RCConfiguration::set_solo_mute_gain, Config, _1),
276 boost::bind (&RCConfiguration::get_solo_mute_gain, Config)));
277 add_controllable (_solo_cut_control);
279 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
281 /* These are all static "per-class" signals */
283 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
284 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
285 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
286 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
287 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
289 /* stop IO objects from doing stuff until we're ready for them */
291 Delivery::disable_panners ();
292 IO::disable_connecting ();
296 Session::second_stage_init ()
298 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
301 if (load_state (_current_snapshot_name)) {
306 if (_butler->start_thread()) {
310 if (start_midi_thread ()) {
314 setup_midi_machine_control ();
316 // set_state() will call setup_raid_path(), but if it's a new session we need
317 // to call setup_raid_path() here.
320 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
324 setup_raid_path(_path);
327 /* we can't save till after ::when_engine_running() is called,
328 because otherwise we save state with no connections made.
329 therefore, we reset _state_of_the_state because ::set_state()
330 will have cleared it.
332 we also have to include Loading so that any events that get
333 generated between here and the end of ::when_engine_running()
334 will be processed directly rather than queued.
337 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
339 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
340 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
341 setup_click_sounds (0);
342 setup_midi_control ();
344 /* Pay attention ... */
346 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
347 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
350 when_engine_running ();
353 /* handle this one in a different way than all others, so that its clear what happened */
355 catch (AudioEngine::PortRegistrationFailure& err) {
356 error << err.what() << endmsg;
364 BootMessage (_("Reset Remote Controls"));
366 send_full_time_code (0);
367 _engine.transport_locate (0);
369 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
370 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
372 MidiClockTicker::instance().set_session (this);
373 MIDI::Name::MidiPatchManager::instance().set_session (this);
375 /* initial program change will be delivered later; see ::config_changed() */
377 _state_of_the_state = Clean;
379 Port::set_connecting_blocked (false);
381 DirtyChanged (); /* EMIT SIGNAL */
383 if (state_was_pending) {
384 save_state (_current_snapshot_name);
385 remove_pending_capture_state ();
386 state_was_pending = false;
389 BootMessage (_("Session loading complete"));
395 Session::raid_path () const
397 SearchPath raid_search_path;
399 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
400 raid_search_path += sys::path((*i).path);
403 return raid_search_path.to_string ();
407 Session::setup_raid_path (string path)
416 session_dirs.clear ();
418 SearchPath search_path(path);
419 SearchPath sound_search_path;
420 SearchPath midi_search_path;
422 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
423 sp.path = (*i).to_string ();
424 sp.blocks = 0; // not needed
425 session_dirs.push_back (sp);
427 SessionDirectory sdir(sp.path);
429 sound_search_path += sdir.sound_path ();
430 midi_search_path += sdir.midi_path ();
433 // reset the round-robin soundfile path thingie
434 last_rr_session_dir = session_dirs.begin();
438 Session::path_is_within_session (const std::string& path)
440 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
441 if (path.find ((*i).path) == 0) {
449 Session::ensure_subdirs ()
453 dir = session_directory().peak_path().to_string();
455 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
456 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
460 dir = session_directory().sound_path().to_string();
462 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
463 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
467 dir = session_directory().midi_path().to_string();
469 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
470 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
474 dir = session_directory().dead_path().to_string();
476 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
477 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
481 dir = session_directory().export_path().to_string();
483 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
484 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
488 dir = analysis_dir ();
490 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
491 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
495 dir = plugins_dir ();
497 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
498 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
505 /** @param session_template directory containing session template, or empty.
506 * Caller must not hold process lock.
509 Session::create (const string& session_template, BusProfile* bus_profile)
511 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
512 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
516 if (ensure_subdirs ()) {
520 _writable = exists_and_writable (sys::path (_path));
522 if (!session_template.empty()) {
523 std::string in_path = session_template_dir_to_file (session_template);
525 ifstream in(in_path.c_str());
528 string out_path = _path;
530 out_path += statefile_suffix;
532 ofstream out(out_path.c_str());
538 /* Copy plugin state files from template to new session */
539 sys::path template_plugins = session_template;
540 template_plugins /= X_("plugins");
541 sys::copy_files (template_plugins, plugins_dir ());
546 error << string_compose (_("Could not open %1 for writing session template"), out_path)
552 error << string_compose (_("Could not open session template %1 for reading"), in_path)
559 /* Instantiate metadata */
561 _metadata = new SessionMetadata ();
563 /* set initial start + end point */
565 _state_of_the_state = Clean;
567 /* set up Master Out and Control Out if necessary */
573 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
575 if (bus_profile->master_out_channels) {
576 boost::shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
580 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
581 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
584 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
585 r->input()->ensure_io (count, false, this);
586 r->output()->ensure_io (count, false, this);
588 r->set_remote_control_id (control_id++);
592 if (Config->get_use_monitor_bus()) {
593 boost::shared_ptr<Route> r (new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO));
597 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
598 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
601 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
602 r->input()->ensure_io (count, false, this);
603 r->output()->ensure_io (count, false, this);
605 r->set_remote_control_id (control_id);
611 /* prohibit auto-connect to master, because there isn't one */
612 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
616 add_routes (rl, false, false);
619 /* this allows the user to override settings with an environment variable.
622 if (no_auto_connect()) {
623 bus_profile->input_ac = AutoConnectOption (0);
624 bus_profile->output_ac = AutoConnectOption (0);
627 Config->set_input_auto_connect (bus_profile->input_ac);
628 Config->set_output_auto_connect (bus_profile->output_ac);
637 Session::maybe_write_autosave()
639 if (dirty() && record_status() != Recording) {
640 save_state("", true);
645 Session::remove_pending_capture_state ()
647 sys::path pending_state_file_path(_session_dir->root_path());
649 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
653 sys::remove (pending_state_file_path);
655 catch(sys::filesystem_error& ex)
657 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
658 pending_state_file_path.to_string(), ex.what()) << endmsg;
662 /** Rename a state file.
663 * @param old_name Old snapshot name.
664 * @param new_name New snapshot name.
667 Session::rename_state (string old_name, string new_name)
669 if (old_name == _current_snapshot_name || old_name == _name) {
670 /* refuse to rename the current snapshot or the "main" one */
674 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
675 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
677 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
678 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
682 sys::rename (old_xml_path, new_xml_path);
684 catch (const sys::filesystem_error& err)
686 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
687 old_name, new_name, err.what()) << endmsg;
691 /** Remove a state file.
692 * @param snapshot_name Snapshot name.
695 Session::remove_state (string snapshot_name)
697 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
698 // refuse to remove the current snapshot or the "main" one
702 sys::path xml_path(_session_dir->root_path());
704 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
706 if (!create_backup_file (xml_path)) {
707 // don't remove it if a backup can't be made
708 // create_backup_file will log the error.
713 sys::remove (xml_path);
716 #ifdef HAVE_JACK_SESSION
718 Session::jack_session_event (jack_session_event_t * event)
722 struct tm local_time;
725 localtime_r (&n, &local_time);
726 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
728 if (event->type == JackSessionSaveTemplate)
730 if (save_template( timebuf )) {
731 event->flags = JackSessionSaveError;
733 string cmd ("ardour3 -P -U ");
734 cmd += event->client_uuid;
738 event->command_line = strdup (cmd.c_str());
743 if (save_state (timebuf)) {
744 event->flags = JackSessionSaveError;
746 sys::path xml_path (_session_dir->root_path());
747 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
749 string cmd ("ardour3 -P -U ");
750 cmd += event->client_uuid;
752 cmd += xml_path.to_string();
755 event->command_line = strdup (cmd.c_str());
759 jack_session_reply (_engine.jack(), event);
761 if (event->type == JackSessionSaveAndQuit) {
762 Quit (); /* EMIT SIGNAL */
765 jack_session_event_free( event );
769 /** @param snapshot_name Name to save under, without .ardour / .pending prefix */
771 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
774 sys::path xml_path(_session_dir->root_path());
776 if (!_writable || (_state_of_the_state & CannotSave)) {
780 if (!_engine.connected ()) {
781 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
787 /* tell sources we're saving first, in case they write out to a new file
788 * which should be saved with the state rather than the old one */
789 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
790 i->second->session_saved();
793 tree.set_root (&get_state());
795 if (snapshot_name.empty()) {
796 snapshot_name = _current_snapshot_name;
797 } else if (switch_to_snapshot) {
798 _current_snapshot_name = snapshot_name;
803 /* proper save: use statefile_suffix (.ardour in English) */
805 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
807 /* make a backup copy of the old file */
809 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
810 // create_backup_file will log the error
816 /* pending save: use pending_suffix (.pending in English) */
817 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
820 sys::path tmp_path(_session_dir->root_path());
822 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
824 // cerr << "actually writing state to " << xml_path.to_string() << endl;
826 if (!tree.write (tmp_path.to_string())) {
827 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
828 sys::remove (tmp_path);
833 if (::rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
834 error << string_compose (_("could not rename temporary session file %1 to %2"),
835 tmp_path.to_string(), xml_path.to_string()) << endmsg;
836 sys::remove (tmp_path);
843 save_history (snapshot_name);
845 bool was_dirty = dirty();
847 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
850 DirtyChanged (); /* EMIT SIGNAL */
853 StateSaved (snapshot_name); /* EMIT SIGNAL */
860 Session::restore_state (string snapshot_name)
862 if (load_state (snapshot_name) == 0) {
863 set_state (*state_tree->root(), Stateful::loading_state_version);
870 Session::load_state (string snapshot_name)
875 state_was_pending = false;
877 /* check for leftover pending state from a crashed capture attempt */
879 sys::path xmlpath(_session_dir->root_path());
880 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
882 if (sys::exists (xmlpath)) {
884 /* there is pending state from a crashed capture attempt */
886 boost::optional<int> r = AskAboutPendingState();
887 if (r.get_value_or (1)) {
888 state_was_pending = true;
892 if (!state_was_pending) {
893 xmlpath = _session_dir->root_path();
894 xmlpath /= snapshot_name;
897 if (!sys::exists (xmlpath)) {
898 xmlpath = _session_dir->root_path();
899 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
900 if (!sys::exists (xmlpath)) {
901 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
906 state_tree = new XMLTree;
910 _writable = exists_and_writable (xmlpath);
912 if (!state_tree->read (xmlpath.to_string())) {
913 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
919 XMLNode& root (*state_tree->root());
921 if (root.name() != X_("Session")) {
922 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
928 const XMLProperty* prop;
930 if ((prop = root.property ("version")) == 0) {
931 /* no version implies very old version of Ardour */
932 Stateful::loading_state_version = 1000;
938 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
939 Stateful::loading_state_version = (major * 1000) + minor;
942 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
944 sys::path backup_path(_session_dir->root_path());
946 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
948 // only create a backup once
949 if (sys::exists (backup_path)) {
953 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
954 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
959 sys::copy_file (xmlpath, backup_path);
961 catch(sys::filesystem_error& ex)
963 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
964 xmlpath.to_string(), ex.what())
974 Session::load_options (const XMLNode& node)
976 LocaleGuard lg (X_("POSIX"));
979 XMLNode node_copy = node;
981 /* XXX: evil hack: fix up sessions from before the layering alterations
985 XMLNodeList children = node_copy.children ();
986 for (XMLNodeIterator i = children.begin(); i != children.end(); ++i) {
987 XMLProperty* p = (*i)->property (X_("name"));
988 if (p && p->name() == X_("name") && p->value() == X_("layer-model") ) {
989 p = (*i)->property (X_("value"));
990 if (p && p->value() == X_("MoveAddHigher")) {
991 (*i)->add_property (X_("value"), X_("AddOrBoundsChangeHigher"));
996 config.set_variables (node_copy);
1002 Session::get_state()
1008 Session::get_template()
1010 /* if we don't disable rec-enable, diskstreams
1011 will believe they need to store their capture
1012 sources in their state node.
1015 disable_record (false);
1017 return state(false);
1021 Session::state(bool full_state)
1023 XMLNode* node = new XMLNode("Session");
1026 // store libardour version, just in case
1028 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
1029 node->add_property("version", string(buf));
1031 /* store configuration settings */
1035 node->add_property ("name", _name);
1036 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1037 node->add_property ("sample-rate", buf);
1039 if (session_dirs.size() > 1) {
1043 vector<space_and_path>::iterator i = session_dirs.begin();
1044 vector<space_and_path>::iterator next;
1046 ++i; /* skip the first one */
1050 while (i != session_dirs.end()) {
1054 if (next != session_dirs.end()) {
1064 child = node->add_child ("Path");
1065 child->add_content (p);
1069 /* save the ID counter */
1071 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1072 node->add_property ("id-counter", buf);
1074 /* save the event ID counter */
1076 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1077 node->add_property ("event-counter", buf);
1079 /* various options */
1081 node->add_child_nocopy (config.get_variables ());
1083 node->add_child_nocopy (_metadata->get_state());
1085 child = node->add_child ("Sources");
1088 Glib::Mutex::Lock sl (source_lock);
1090 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1092 /* Don't save information about non-file Sources, or
1093 * about non-destructive file sources that are empty
1094 * and unused by any regions.
1097 boost::shared_ptr<FileSource> fs;
1099 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1101 if (!fs->destructive()) {
1102 if (fs->empty() && !fs->used()) {
1107 child->add_child_nocopy (siter->second->get_state());
1112 child = node->add_child ("Regions");
1115 Glib::Mutex::Lock rl (region_lock);
1116 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1117 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1118 boost::shared_ptr<Region> r = i->second;
1119 /* only store regions not attached to playlists */
1120 if (r->playlist() == 0) {
1121 child->add_child_nocopy (r->state ());
1125 RegionFactory::CompoundAssociations& cassocs (RegionFactory::compound_associations());
1127 if (!cassocs.empty()) {
1128 XMLNode* ca = node->add_child (X_("CompoundAssociations"));
1130 for (RegionFactory::CompoundAssociations::iterator i = cassocs.begin(); i != cassocs.end(); ++i) {
1132 XMLNode* can = new XMLNode (X_("CompoundAssociation"));
1133 i->first->id().print (buf, sizeof (buf));
1134 can->add_property (X_("copy"), buf);
1135 i->second->id().print (buf, sizeof (buf));
1136 can->add_property (X_("original"), buf);
1137 ca->add_child_nocopy (*can);
1143 node->add_child_nocopy (_locations->get_state());
1145 // for a template, just create a new Locations, populate it
1146 // with the default start and end, and get the state for that.
1147 Locations loc (*this);
1148 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1149 range->set (max_framepos, 0);
1151 node->add_child_nocopy (loc.get_state());
1154 child = node->add_child ("Bundles");
1156 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1157 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1158 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1160 child->add_child_nocopy (b->get_state());
1165 child = node->add_child ("Routes");
1167 boost::shared_ptr<RouteList> r = routes.reader ();
1169 RoutePublicOrderSorter cmp;
1170 RouteList public_order (*r);
1171 public_order.sort (cmp);
1173 /* the sort should have put control outs first */
1176 assert (_monitor_out == public_order.front());
1179 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1180 if (!(*i)->is_hidden()) {
1182 child->add_child_nocopy ((*i)->get_state());
1184 child->add_child_nocopy ((*i)->get_template());
1190 playlists->add_state (node, full_state);
1192 child = node->add_child ("RouteGroups");
1193 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1194 child->add_child_nocopy ((*i)->get_state());
1198 child = node->add_child ("Click");
1199 child->add_child_nocopy (_click_io->state (full_state));
1203 child = node->add_child ("NamedSelections");
1204 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1206 child->add_child_nocopy ((*i)->get_state());
1211 node->add_child_nocopy (_speakers->get_state());
1212 node->add_child_nocopy (_tempo_map->get_state());
1213 node->add_child_nocopy (get_control_protocol_state());
1216 node->add_child_copy (*_extra_xml);
1223 Session::get_control_protocol_state ()
1225 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1226 return cpm.get_state();
1230 Session::set_state (const XMLNode& node, int version)
1234 const XMLProperty* prop;
1237 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1239 if (node.name() != X_("Session")) {
1240 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1244 if ((prop = node.property ("version")) != 0) {
1245 version = atoi (prop->value ()) * 1000;
1248 if ((prop = node.property ("name")) != 0) {
1249 _name = prop->value ();
1252 if ((prop = node.property (X_("sample-rate"))) != 0) {
1254 _nominal_frame_rate = atoi (prop->value());
1256 if (_nominal_frame_rate != _current_frame_rate) {
1257 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1258 if (r.get_value_or (0)) {
1264 setup_raid_path(_session_dir->root_path().to_string());
1266 if ((prop = node.property (X_("id-counter"))) != 0) {
1268 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1269 ID::init_counter (x);
1271 /* old sessions used a timebased counter, so fake
1272 the startup ID counter based on a standard
1277 ID::init_counter (now);
1280 if ((prop = node.property (X_("event-counter"))) != 0) {
1281 Evoral::init_event_id_counter (atoi (prop->value()));
1284 IO::disable_connecting ();
1286 Stateful::save_extra_xml (node);
1288 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1289 load_options (*child);
1290 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1291 load_options (*child);
1293 error << _("Session: XML state has no options section") << endmsg;
1296 if (version >= 3000) {
1297 if ((child = find_named_node (node, "Metadata")) == 0) {
1298 warning << _("Session: XML state has no metadata section") << endmsg;
1299 } else if (_metadata->set_state (*child, version)) {
1304 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1305 _speakers->set_state (*child, version);
1308 if ((child = find_named_node (node, "Sources")) == 0) {
1309 error << _("Session: XML state has no sources section") << endmsg;
1311 } else if (load_sources (*child)) {
1315 if ((child = find_named_node (node, "TempoMap")) == 0) {
1316 error << _("Session: XML state has no Tempo Map section") << endmsg;
1318 } else if (_tempo_map->set_state (*child, version)) {
1322 if ((child = find_named_node (node, "Locations")) == 0) {
1323 error << _("Session: XML state has no locations section") << endmsg;
1325 } else if (_locations->set_state (*child, version)) {
1331 if ((location = _locations->auto_loop_location()) != 0) {
1332 set_auto_loop_location (location);
1335 if ((location = _locations->auto_punch_location()) != 0) {
1336 set_auto_punch_location (location);
1339 if ((location = _locations->session_range_location()) != 0) {
1340 delete _session_range_location;
1341 _session_range_location = location;
1344 if (_session_range_location) {
1345 AudioFileSource::set_header_position_offset (_session_range_location->start());
1348 if ((child = find_named_node (node, "Regions")) == 0) {
1349 error << _("Session: XML state has no Regions section") << endmsg;
1351 } else if (load_regions (*child)) {
1355 if ((child = find_named_node (node, "Playlists")) == 0) {
1356 error << _("Session: XML state has no playlists section") << endmsg;
1358 } else if (playlists->load (*this, *child)) {
1362 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1364 } else if (playlists->load_unused (*this, *child)) {
1368 if ((child = find_named_node (node, "CompoundAssociations")) != 0) {
1369 if (load_compounds (*child)) {
1374 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1375 if (load_named_selections (*child)) {
1380 if (version >= 3000) {
1381 if ((child = find_named_node (node, "Bundles")) == 0) {
1382 warning << _("Session: XML state has no bundles section") << endmsg;
1385 /* We can't load Bundles yet as they need to be able
1386 to convert from port names to Port objects, which can't happen until
1388 _bundle_xml_node = new XMLNode (*child);
1392 if (version < 3000) {
1393 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1394 error << _("Session: XML state has no diskstreams section") << endmsg;
1396 } else if (load_diskstreams_2X (*child, version)) {
1401 if ((child = find_named_node (node, "Routes")) == 0) {
1402 error << _("Session: XML state has no routes section") << endmsg;
1404 } else if (load_routes (*child, version)) {
1408 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1409 _diskstreams_2X.clear ();
1411 if (version >= 3000) {
1413 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1414 error << _("Session: XML state has no route groups section") << endmsg;
1416 } else if (load_route_groups (*child, version)) {
1420 } else if (version < 3000) {
1422 if ((child = find_named_node (node, "EditGroups")) == 0) {
1423 error << _("Session: XML state has no edit groups section") << endmsg;
1425 } else if (load_route_groups (*child, version)) {
1429 if ((child = find_named_node (node, "MixGroups")) == 0) {
1430 error << _("Session: XML state has no mix groups section") << endmsg;
1432 } else if (load_route_groups (*child, version)) {
1437 if ((child = find_named_node (node, "Click")) == 0) {
1438 warning << _("Session: XML state has no click section") << endmsg;
1439 } else if (_click_io) {
1440 _click_io->set_state (*child, version);
1443 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1444 ControlProtocolManager::instance().set_protocol_states (*child);
1447 /* here beginneth the second phase ... */
1449 StateReady (); /* EMIT SIGNAL */
1458 Session::load_routes (const XMLNode& node, int version)
1461 XMLNodeConstIterator niter;
1462 RouteList new_routes;
1464 nlist = node.children();
1468 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1470 boost::shared_ptr<Route> route;
1471 if (version < 3000) {
1472 route = XMLRouteFactory_2X (**niter, version);
1474 route = XMLRouteFactory (**niter, version);
1478 error << _("Session: cannot create Route from XML description.") << endmsg;
1482 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1484 new_routes.push_back (route);
1487 add_routes (new_routes, false, false);
1492 boost::shared_ptr<Route>
1493 Session::XMLRouteFactory (const XMLNode& node, int version)
1495 boost::shared_ptr<Route> ret;
1497 if (node.name() != "Route") {
1501 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1503 DataType type = DataType::AUDIO;
1504 const XMLProperty* prop = node.property("default-type");
1507 type = DataType (prop->value());
1510 assert (type != DataType::NIL);
1514 boost::shared_ptr<Track> track;
1516 if (type == DataType::AUDIO) {
1517 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1519 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1522 if (track->init()) {
1526 if (track->set_state (node, version)) {
1530 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1531 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1536 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1538 if (r->init () == 0 && r->set_state (node, version) == 0) {
1539 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1540 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1549 boost::shared_ptr<Route>
1550 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1552 boost::shared_ptr<Route> ret;
1554 if (node.name() != "Route") {
1558 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1560 ds_prop = node.property (X_("diskstream"));
1563 DataType type = DataType::AUDIO;
1564 const XMLProperty* prop = node.property("default-type");
1567 type = DataType (prop->value());
1570 assert (type != DataType::NIL);
1574 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1575 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1579 if (i == _diskstreams_2X.end()) {
1580 error << _("Could not find diskstream for route") << endmsg;
1581 return boost::shared_ptr<Route> ();
1584 boost::shared_ptr<Track> track;
1586 if (type == DataType::AUDIO) {
1587 track.reset (new AudioTrack (*this, X_("toBeResetFroXML")));
1589 track.reset (new MidiTrack (*this, X_("toBeResetFroXML")));
1592 if (track->init()) {
1596 if (track->set_state (node, version)) {
1600 track->set_diskstream (*i);
1602 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1603 // boost_debug_shared_ptr_mark_interesting (track.get(), "Track");
1608 boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML")));
1610 if (r->init () == 0 && r->set_state (node, version) == 0) {
1611 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1612 // boost_debug_shared_ptr_mark_interesting (r.get(), "Route");
1622 Session::load_regions (const XMLNode& node)
1625 XMLNodeConstIterator niter;
1626 boost::shared_ptr<Region> region;
1628 nlist = node.children();
1632 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1633 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1634 error << _("Session: cannot create Region from XML description.");
1635 const XMLProperty *name = (**niter).property("name");
1638 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1649 Session::load_compounds (const XMLNode& node)
1651 XMLNodeList calist = node.children();
1652 XMLNodeConstIterator caiter;
1653 XMLProperty *caprop;
1655 for (caiter = calist.begin(); caiter != calist.end(); ++caiter) {
1656 XMLNode* ca = *caiter;
1660 if ((caprop = ca->property (X_("original"))) == 0) {
1663 orig_id = caprop->value();
1665 if ((caprop = ca->property (X_("copy"))) == 0) {
1668 copy_id = caprop->value();
1670 boost::shared_ptr<Region> orig = RegionFactory::region_by_id (orig_id);
1671 boost::shared_ptr<Region> copy = RegionFactory::region_by_id (copy_id);
1673 if (!orig || !copy) {
1674 warning << string_compose (_("Regions in compound description not found (ID's %1 and %2): ignored"),
1680 RegionFactory::add_compound_association (orig, copy);
1687 Session::load_nested_sources (const XMLNode& node)
1690 XMLNodeConstIterator niter;
1692 nlist = node.children();
1694 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1695 if ((*niter)->name() == "Source") {
1697 /* it may already exist, so don't recreate it unnecessarily
1700 XMLProperty* prop = (*niter)->property (X_("id"));
1702 error << _("Nested source has no ID info in session state file! (ignored)") << endmsg;
1706 ID source_id (prop->value());
1708 if (!source_by_id (source_id)) {
1711 SourceFactory::create (*this, **niter, true);
1713 catch (failed_constructor& err) {
1714 error << string_compose (_("Cannot reconstruct nested source for region %1"), name()) << endmsg;
1721 boost::shared_ptr<Region>
1722 Session::XMLRegionFactory (const XMLNode& node, bool full)
1724 const XMLProperty* type = node.property("type");
1728 const XMLNodeList& nlist = node.children();
1730 for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
1731 XMLNode *child = (*niter);
1732 if (child->name() == "NestedSource") {
1733 load_nested_sources (*child);
1737 if (!type || type->value() == "audio") {
1738 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1739 } else if (type->value() == "midi") {
1740 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1743 } catch (failed_constructor& err) {
1744 return boost::shared_ptr<Region> ();
1747 return boost::shared_ptr<Region> ();
1750 boost::shared_ptr<AudioRegion>
1751 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1753 const XMLProperty* prop;
1754 boost::shared_ptr<Source> source;
1755 boost::shared_ptr<AudioSource> as;
1757 SourceList master_sources;
1758 uint32_t nchans = 1;
1761 if (node.name() != X_("Region")) {
1762 return boost::shared_ptr<AudioRegion>();
1765 if ((prop = node.property (X_("channels"))) != 0) {
1766 nchans = atoi (prop->value().c_str());
1769 if ((prop = node.property ("name")) == 0) {
1770 cerr << "no name for this region\n";
1774 if ((prop = node.property (X_("source-0"))) == 0) {
1775 if ((prop = node.property ("source")) == 0) {
1776 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1777 return boost::shared_ptr<AudioRegion>();
1781 PBD::ID s_id (prop->value());
1783 if ((source = source_by_id (s_id)) == 0) {
1784 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1785 return boost::shared_ptr<AudioRegion>();
1788 as = boost::dynamic_pointer_cast<AudioSource>(source);
1790 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1791 return boost::shared_ptr<AudioRegion>();
1794 sources.push_back (as);
1796 /* pickup other channels */
1798 for (uint32_t n=1; n < nchans; ++n) {
1799 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1800 if ((prop = node.property (buf)) != 0) {
1802 PBD::ID id2 (prop->value());
1804 if ((source = source_by_id (id2)) == 0) {
1805 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1806 return boost::shared_ptr<AudioRegion>();
1809 as = boost::dynamic_pointer_cast<AudioSource>(source);
1811 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1812 return boost::shared_ptr<AudioRegion>();
1814 sources.push_back (as);
1818 for (uint32_t n = 0; n < nchans; ++n) {
1819 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1820 if ((prop = node.property (buf)) != 0) {
1822 PBD::ID id2 (prop->value());
1824 if ((source = source_by_id (id2)) == 0) {
1825 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1826 return boost::shared_ptr<AudioRegion>();
1829 as = boost::dynamic_pointer_cast<AudioSource>(source);
1831 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1832 return boost::shared_ptr<AudioRegion>();
1834 master_sources.push_back (as);
1839 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1841 /* a final detail: this is the one and only place that we know how long missing files are */
1843 if (region->whole_file()) {
1844 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1845 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1847 sfp->set_length (region->length());
1852 if (!master_sources.empty()) {
1853 if (master_sources.size() != nchans) {
1854 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1856 region->set_master_sources (master_sources);
1864 catch (failed_constructor& err) {
1865 return boost::shared_ptr<AudioRegion>();
1869 boost::shared_ptr<MidiRegion>
1870 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1872 const XMLProperty* prop;
1873 boost::shared_ptr<Source> source;
1874 boost::shared_ptr<MidiSource> ms;
1877 if (node.name() != X_("Region")) {
1878 return boost::shared_ptr<MidiRegion>();
1881 if ((prop = node.property ("name")) == 0) {
1882 cerr << "no name for this region\n";
1886 if ((prop = node.property (X_("source-0"))) == 0) {
1887 if ((prop = node.property ("source")) == 0) {
1888 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1889 return boost::shared_ptr<MidiRegion>();
1893 PBD::ID s_id (prop->value());
1895 if ((source = source_by_id (s_id)) == 0) {
1896 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1897 return boost::shared_ptr<MidiRegion>();
1900 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1902 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1903 return boost::shared_ptr<MidiRegion>();
1906 sources.push_back (ms);
1909 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1910 /* a final detail: this is the one and only place that we know how long missing files are */
1912 if (region->whole_file()) {
1913 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1914 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1916 sfp->set_length (region->length());
1924 catch (failed_constructor& err) {
1925 return boost::shared_ptr<MidiRegion>();
1930 Session::get_sources_as_xml ()
1933 XMLNode* node = new XMLNode (X_("Sources"));
1934 Glib::Mutex::Lock lm (source_lock);
1936 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1937 node->add_child_nocopy (i->second->get_state());
1944 Session::path_from_region_name (DataType type, string name, string identifier)
1946 char buf[PATH_MAX+1];
1948 SessionDirectory sdir(get_best_session_directory_for_new_source());
1949 sys::path source_dir = ((type == DataType::AUDIO)
1950 ? sdir.sound_path() : sdir.midi_path());
1952 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1954 for (n = 0; n < 999999; ++n) {
1955 if (identifier.length()) {
1956 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1957 identifier.c_str(), n, ext.c_str());
1959 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1963 sys::path source_path = source_dir / buf;
1965 if (!sys::exists (source_path)) {
1966 return source_path.to_string();
1970 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1979 Session::load_sources (const XMLNode& node)
1982 XMLNodeConstIterator niter;
1983 boost::shared_ptr<Source> source;
1985 nlist = node.children();
1989 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1992 if ((source = XMLSourceFactory (**niter)) == 0) {
1993 error << _("Session: cannot create Source from XML description.") << endmsg;
1996 } catch (MissingSource& err) {
2000 if (!no_questions_about_missing_files) {
2001 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
2006 switch (user_choice) {
2008 /* user added a new search location, so try again */
2013 /* user asked to quit the entire session load
2018 no_questions_about_missing_files = true;
2022 no_questions_about_missing_files = true;
2027 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
2028 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
2037 boost::shared_ptr<Source>
2038 Session::XMLSourceFactory (const XMLNode& node)
2040 if (node.name() != "Source") {
2041 return boost::shared_ptr<Source>();
2045 /* note: do peak building in another thread when loading session state */
2046 return SourceFactory::create (*this, node, true);
2049 catch (failed_constructor& err) {
2050 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
2051 return boost::shared_ptr<Source>();
2056 Session::save_template (string template_name)
2060 if (_state_of_the_state & CannotSave) {
2064 sys::path user_template_dir(user_template_directory());
2068 sys::create_directories (user_template_dir);
2070 catch(sys::filesystem_error& ex)
2072 error << string_compose(_("Could not create templates directory \"%1\" (%2)"),
2073 user_template_dir.to_string(), ex.what()) << endmsg;
2077 tree.set_root (&get_template());
2079 sys::path template_dir_path(user_template_dir);
2081 /* directory to put the template in */
2082 template_dir_path /= template_name;
2083 if (sys::exists (template_dir_path))
2085 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2086 template_dir_path.to_string()) << endmsg;
2090 sys::create_directories (template_dir_path);
2093 sys::path template_file_path = template_dir_path;
2094 template_file_path /= template_name + template_suffix;
2096 if (!tree.write (template_file_path.to_string())) {
2097 error << _("template not saved") << endmsg;
2101 /* copy plugin state directory */
2103 sys::path template_plugin_state_path = template_dir_path;
2104 template_plugin_state_path /= X_("plugins");
2105 sys::create_directories (template_plugin_state_path);
2106 sys::copy_files (plugins_dir(), template_plugin_state_path);
2112 Session::refresh_disk_space ()
2115 struct statfs statfsbuf;
2116 vector<space_and_path>::iterator i;
2117 Glib::Mutex::Lock lm (space_lock);
2120 /* get freespace on every FS that is part of the session path */
2122 _total_free_4k_blocks = 0;
2124 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2125 statfs ((*i).path.c_str(), &statfsbuf);
2127 scale = statfsbuf.f_bsize/4096.0;
2129 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2130 _total_free_4k_blocks += (*i).blocks;
2136 Session::get_best_session_directory_for_new_source ()
2138 vector<space_and_path>::iterator i;
2139 string result = _session_dir->root_path().to_string();
2141 /* handle common case without system calls */
2143 if (session_dirs.size() == 1) {
2147 /* OK, here's the algorithm we're following here:
2149 We want to select which directory to use for
2150 the next file source to be created. Ideally,
2151 we'd like to use a round-robin process so as to
2152 get maximum performance benefits from splitting
2153 the files across multiple disks.
2155 However, in situations without much diskspace, an
2156 RR approach may end up filling up a filesystem
2157 with new files while others still have space.
2158 Its therefore important to pay some attention to
2159 the freespace in the filesystem holding each
2160 directory as well. However, if we did that by
2161 itself, we'd keep creating new files in the file
2162 system with the most space until it was as full
2163 as all others, thus negating any performance
2164 benefits of this RAID-1 like approach.
2166 So, we use a user-configurable space threshold. If
2167 there are at least 2 filesystems with more than this
2168 much space available, we use RR selection between them.
2169 If not, then we pick the filesystem with the most space.
2171 This gets a good balance between the two
2175 refresh_disk_space ();
2177 int free_enough = 0;
2179 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2180 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2185 if (free_enough >= 2) {
2186 /* use RR selection process, ensuring that the one
2190 i = last_rr_session_dir;
2193 if (++i == session_dirs.end()) {
2194 i = session_dirs.begin();
2197 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2198 if (create_session_directory ((*i).path)) {
2200 last_rr_session_dir = i;
2205 } while (i != last_rr_session_dir);
2209 /* pick FS with the most freespace (and that
2210 seems to actually work ...)
2213 vector<space_and_path> sorted;
2214 space_and_path_ascending_cmp cmp;
2216 sorted = session_dirs;
2217 sort (sorted.begin(), sorted.end(), cmp);
2219 for (i = sorted.begin(); i != sorted.end(); ++i) {
2220 if (create_session_directory ((*i).path)) {
2222 last_rr_session_dir = i;
2232 Session::load_named_selections (const XMLNode& node)
2235 XMLNodeConstIterator niter;
2238 nlist = node.children();
2242 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2244 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2245 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2253 Session::XMLNamedSelectionFactory (const XMLNode& node)
2256 return new NamedSelection (*this, node);
2259 catch (failed_constructor& err) {
2265 Session::automation_dir () const
2267 return Glib::build_filename (_path, "automation");
2271 Session::analysis_dir () const
2273 return Glib::build_filename (_path, "analysis");
2277 Session::plugins_dir () const
2279 return Glib::build_filename (_path, "plugins");
2283 Session::load_bundles (XMLNode const & node)
2285 XMLNodeList nlist = node.children();
2286 XMLNodeConstIterator niter;
2290 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2291 if ((*niter)->name() == "InputBundle") {
2292 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2293 } else if ((*niter)->name() == "OutputBundle") {
2294 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2296 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2305 Session::load_route_groups (const XMLNode& node, int version)
2307 XMLNodeList nlist = node.children();
2308 XMLNodeConstIterator niter;
2312 if (version >= 3000) {
2314 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2315 if ((*niter)->name() == "RouteGroup") {
2316 RouteGroup* rg = new RouteGroup (*this, "");
2317 add_route_group (rg);
2318 rg->set_state (**niter, version);
2322 } else if (version < 3000) {
2324 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2325 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2326 RouteGroup* rg = new RouteGroup (*this, "");
2327 add_route_group (rg);
2328 rg->set_state (**niter, version);
2337 Session::auto_save()
2339 save_state (_current_snapshot_name);
2343 state_file_filter (const string &str, void */*arg*/)
2345 return (str.length() > strlen(statefile_suffix) &&
2346 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2350 bool operator()(const string* a, const string* b) {
2356 remove_end(string* state)
2358 string statename(*state);
2360 string::size_type start,end;
2361 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2362 statename = statename.substr (start+1);
2365 if ((end = statename.rfind(".ardour")) == string::npos) {
2366 end = statename.length();
2369 return new string(statename.substr (0, end));
2373 Session::possible_states (string path)
2375 PathScanner scanner;
2376 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2378 transform(states->begin(), states->end(), states->begin(), remove_end);
2381 sort (states->begin(), states->end(), cmp);
2387 Session::possible_states () const
2389 return possible_states(_path);
2393 Session::add_route_group (RouteGroup* g)
2395 _route_groups.push_back (g);
2396 route_group_added (g); /* EMIT SIGNAL */
2398 g->RouteAdded.connect_same_thread (*this, boost::bind (&Session::route_added_to_route_group, this, _1, _2));
2399 g->RouteRemoved.connect_same_thread (*this, boost::bind (&Session::route_removed_from_route_group, this, _1, _2));
2400 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_property_changed, this, g));
2406 Session::remove_route_group (RouteGroup& rg)
2408 list<RouteGroup*>::iterator i;
2410 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2411 _route_groups.erase (i);
2414 route_group_removed (); /* EMIT SIGNAL */
2418 /** Set a new order for our route groups, without adding or removing any.
2419 * @param groups Route group list in the new order.
2422 Session::reorder_route_groups (list<RouteGroup*> groups)
2424 _route_groups = groups;
2426 route_groups_reordered (); /* EMIT SIGNAL */
2432 Session::route_group_by_name (string name)
2434 list<RouteGroup *>::iterator i;
2436 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2437 if ((*i)->name() == name) {
2445 Session::all_route_group() const
2447 return *_all_route_group;
2451 Session::add_commands (vector<Command*> const & cmds)
2453 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2459 Session::begin_reversible_command (const string& name)
2461 begin_reversible_command (g_quark_from_string (name.c_str ()));
2464 /** Begin a reversible command using a GQuark to identify it.
2465 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2466 * but there must be as many begin...()s as there are commit...()s.
2469 Session::begin_reversible_command (GQuark q)
2471 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2472 to hold all the commands that are committed. This keeps the order of
2473 commands correct in the history.
2476 if (_current_trans == 0) {
2477 /* start a new transaction */
2478 assert (_current_trans_quarks.empty ());
2479 _current_trans = new UndoTransaction();
2480 _current_trans->set_name (g_quark_to_string (q));
2483 _current_trans_quarks.push_front (q);
2487 Session::commit_reversible_command (Command *cmd)
2489 assert (_current_trans);
2490 assert (!_current_trans_quarks.empty ());
2495 _current_trans->add_command (cmd);
2498 _current_trans_quarks.pop_front ();
2500 if (!_current_trans_quarks.empty ()) {
2501 /* the transaction we're committing is not the top-level one */
2505 if (_current_trans->empty()) {
2506 /* no commands were added to the transaction, so just get rid of it */
2507 delete _current_trans;
2512 gettimeofday (&now, 0);
2513 _current_trans->set_timestamp (now);
2515 _history.add (_current_trans);
2520 accept_all_audio_files (const string& path, void */*arg*/)
2522 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2526 if (!AudioFileSource::safe_audio_file_extension (path)) {
2534 accept_all_midi_files (const string& path, void */*arg*/)
2536 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2540 return ((path.length() > 4 && path.find (".mid") != (path.length() - 4)) ||
2541 (path.length() > 4 && path.find (".smf") != (path.length() - 4)) ||
2542 (path.length() > 5 && path.find (".midi") != (path.length() - 5)));
2546 accept_all_state_files (const string& path, void */*arg*/)
2548 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2552 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2556 Session::find_all_sources (string path, set<string>& result)
2561 if (!tree.read (path)) {
2565 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2570 XMLNodeConstIterator niter;
2572 nlist = node->children();
2576 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2580 if ((prop = (*niter)->property (X_("type"))) == 0) {
2584 DataType type (prop->value());
2586 if ((prop = (*niter)->property (X_("name"))) == 0) {
2590 if (Glib::path_is_absolute (prop->value())) {
2591 /* external file, ignore */
2599 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2600 result.insert (found_path);
2608 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2610 PathScanner scanner;
2611 vector<string*>* state_files;
2613 string this_snapshot_path;
2619 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2620 ripped = ripped.substr (0, ripped.length() - 1);
2623 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2625 if (state_files == 0) {
2630 this_snapshot_path = _path;
2631 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2632 this_snapshot_path += statefile_suffix;
2634 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2636 if (exclude_this_snapshot && **i == this_snapshot_path) {
2640 if (find_all_sources (**i, result) < 0) {
2648 struct RegionCounter {
2649 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2650 AudioSourceList::iterator iter;
2651 boost::shared_ptr<Region> region;
2654 RegionCounter() : count (0) {}
2658 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2660 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2661 return r.get_value_or (1);
2665 Session::cleanup_regions ()
2667 const RegionFactory::RegionMap& regions (RegionFactory::regions());
2669 for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) {
2671 uint32_t used = playlists->region_use_count (i->second);
2673 if (used == 0 && !i->second->automatic ()) {
2674 RegionFactory::map_remove (i->second);
2678 /* dump the history list */
2685 Session::cleanup_sources (CleanupReport& rep)
2687 // FIXME: needs adaptation to midi
2689 vector<boost::shared_ptr<Source> > dead_sources;
2690 PathScanner scanner;
2693 vector<space_and_path>::iterator i;
2694 vector<space_and_path>::iterator nexti;
2695 vector<string*>* candidates;
2696 vector<string*>* candidates2;
2697 vector<string> unused;
2698 set<string> all_sources;
2703 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2705 /* consider deleting all unused playlists */
2707 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2712 /* sync the "all regions" property of each playlist with its current state
2715 playlists->sync_all_regions_with_regions ();
2717 /* find all un-used sources */
2722 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2724 SourceMap::iterator tmp;
2729 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2733 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2734 dead_sources.push_back (i->second);
2735 i->second->drop_references ();
2741 /* build a list of all the possible audio directories for the session */
2743 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2748 SessionDirectory sdir ((*i).path);
2749 audio_path += sdir.sound_path().to_string();
2751 if (nexti != session_dirs.end()) {
2759 /* build a list of all the possible midi directories for the session */
2761 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2766 SessionDirectory sdir ((*i).path);
2767 midi_path += sdir.midi_path().to_string();
2769 if (nexti != session_dirs.end()) {
2776 candidates = scanner (audio_path, accept_all_audio_files, (void *) 0, true, true);
2777 candidates2 = scanner (midi_path, accept_all_midi_files, (void *) 0, true, true);
2783 for (vector<string*>::iterator i = candidates2->begin(); i != candidates2->end(); ++i) {
2784 candidates->push_back (*i);
2789 candidates = candidates2; // might still be null
2792 /* find all sources, but don't use this snapshot because the
2793 state file on disk still references sources we may have already
2797 find_all_sources_across_snapshots (all_sources, true);
2799 /* add our current source list
2802 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2803 boost::shared_ptr<FileSource> fs;
2804 SourceMap::iterator tmp = i;
2807 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2808 if (playlists->source_use_count (fs) != 0) {
2809 all_sources.insert (fs->path());
2812 /* we might not remove this source from disk, because it may be used
2813 by other snapshots, but its not being used in this version
2814 so lets get rid of it now, along with any representative regions
2818 RegionFactory::remove_regions_using_source (i->second);
2826 char tmppath1[PATH_MAX+1];
2827 char tmppath2[PATH_MAX+1];
2830 for (vector<string*>::iterator x = candidates->begin(); x != candidates->end(); ++x) {
2835 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2837 if (realpath(spath.c_str(), tmppath1) == 0) {
2838 error << string_compose (_("Cannot expand path %1 (%2)"),
2839 spath, strerror (errno)) << endmsg;
2843 if (realpath((*i).c_str(), tmppath2) == 0) {
2844 error << string_compose (_("Cannot expand path %1 (%2)"),
2845 (*i), strerror (errno)) << endmsg;
2849 if (strcmp(tmppath1, tmppath2) == 0) {
2856 unused.push_back (spath);
2865 /* now try to move all unused files into the "dead" directory(ies) */
2867 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2868 struct stat statbuf;
2872 /* don't move the file across filesystems, just
2873 stick it in the `dead_dir_name' directory
2874 on whichever filesystem it was already on.
2877 if ((*x).find ("/sounds/") != string::npos) {
2879 /* old school, go up 1 level */
2881 newpath = Glib::path_get_dirname (*x); // "sounds"
2882 newpath = Glib::path_get_dirname (newpath); // "session-name"
2886 /* new school, go up 4 levels */
2888 newpath = Glib::path_get_dirname (*x); // "audiofiles" or "midifiles"
2889 newpath = Glib::path_get_dirname (newpath); // "session-name"
2890 newpath = Glib::path_get_dirname (newpath); // "interchange"
2891 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2894 newpath = Glib::build_filename (newpath, dead_dir_name);
2896 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2897 error << string_compose(_("Session: cannot create dead file folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2901 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2903 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2905 /* the new path already exists, try versioning */
2907 char buf[PATH_MAX+1];
2911 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2914 while (Glib::file_test (newpath_v.c_str(), Glib::FILE_TEST_EXISTS) && version < 999) {
2915 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2919 if (version == 999) {
2920 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2924 newpath = newpath_v;
2929 /* it doesn't exist, or we can't read it or something */
2933 stat ((*x).c_str(), &statbuf);
2935 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2936 error << string_compose (_("cannot rename unused file source from %1 to %2 (%3)"),
2937 (*x), newpath, strerror (errno))
2942 /* see if there an easy to find peakfile for this file, and remove it.
2945 string base = basename_nosuffix (*x);
2946 base += "%A"; /* this is what we add for the channel suffix of all native files,
2947 or for the first channel of embedded files. it will miss
2948 some peakfiles for other channels
2950 string peakpath = peak_path (base);
2952 if (Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
2953 if (::unlink (peakpath.c_str()) != 0) {
2954 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2955 peakpath, _path, strerror (errno))
2957 /* try to back out */
2958 ::rename (newpath.c_str(), _path.c_str());
2963 rep.paths.push_back (*x);
2964 rep.space += statbuf.st_size;
2967 /* dump the history list */
2971 /* save state so we don't end up a session file
2972 referring to non-existent sources.
2979 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2985 Session::cleanup_trash_sources (CleanupReport& rep)
2987 // FIXME: needs adaptation for MIDI
2989 vector<space_and_path>::iterator i;
2995 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2997 dead_dir = Glib::build_filename ((*i).path, dead_dir_name);
2999 clear_directory (dead_dir, &rep.space, &rep.paths);
3006 Session::set_dirty ()
3008 bool was_dirty = dirty();
3010 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3014 DirtyChanged(); /* EMIT SIGNAL */
3020 Session::set_clean ()
3022 bool was_dirty = dirty();
3024 _state_of_the_state = Clean;
3028 DirtyChanged(); /* EMIT SIGNAL */
3033 Session::set_deletion_in_progress ()
3035 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3039 Session::clear_deletion_in_progress ()
3041 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
3045 Session::add_controllable (boost::shared_ptr<Controllable> c)
3047 /* this adds a controllable to the list managed by the Session.
3048 this is a subset of those managed by the Controllable class
3049 itself, and represents the only ones whose state will be saved
3050 as part of the session.
3053 Glib::Mutex::Lock lm (controllables_lock);
3054 controllables.insert (c);
3057 struct null_deleter { void operator()(void const *) const {} };
3060 Session::remove_controllable (Controllable* c)
3062 if (_state_of_the_state | Deletion) {
3066 Glib::Mutex::Lock lm (controllables_lock);
3068 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
3070 if (x != controllables.end()) {
3071 controllables.erase (x);
3075 boost::shared_ptr<Controllable>
3076 Session::controllable_by_id (const PBD::ID& id)
3078 Glib::Mutex::Lock lm (controllables_lock);
3080 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3081 if ((*i)->id() == id) {
3086 return boost::shared_ptr<Controllable>();
3089 boost::shared_ptr<Controllable>
3090 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
3092 boost::shared_ptr<Controllable> c;
3093 boost::shared_ptr<Route> r;
3095 switch (desc.top_level_type()) {
3096 case ControllableDescriptor::NamedRoute:
3098 std::string str = desc.top_level_name();
3099 if (str == "master") {
3101 } else if (str == "control" || str == "listen") {
3104 r = route_by_name (desc.top_level_name());
3109 case ControllableDescriptor::RemoteControlID:
3110 r = route_by_remote_id (desc.rid());
3118 switch (desc.subtype()) {
3119 case ControllableDescriptor::Gain:
3120 c = r->gain_control ();
3123 case ControllableDescriptor::Solo:
3124 c = r->solo_control();
3127 case ControllableDescriptor::Mute:
3128 c = r->mute_control();
3131 case ControllableDescriptor::Recenable:
3133 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3136 c = t->rec_enable_control ();
3141 case ControllableDescriptor::PanDirection:
3143 c = r->pannable()->pan_azimuth_control;
3147 case ControllableDescriptor::PanWidth:
3149 c = r->pannable()->pan_width_control;
3153 case ControllableDescriptor::PanElevation:
3155 c = r->pannable()->pan_elevation_control;
3159 case ControllableDescriptor::Balance:
3160 /* XXX simple pan control */
3163 case ControllableDescriptor::PluginParameter:
3165 uint32_t plugin = desc.target (0);
3166 uint32_t parameter_index = desc.target (1);
3168 /* revert to zero based counting */
3174 if (parameter_index > 0) {
3178 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3181 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3182 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3187 case ControllableDescriptor::SendGain:
3189 uint32_t send = desc.target (0);
3191 /* revert to zero-based counting */
3197 boost::shared_ptr<Processor> p = r->nth_send (send);
3200 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3201 boost::shared_ptr<Amp> a = s->amp();
3204 c = s->amp()->gain_control();
3211 /* relax and return a null pointer */
3219 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3222 Stateful::add_instant_xml (node, _path);
3225 if (write_to_config) {
3226 Config->add_instant_xml (node);
3231 Session::instant_xml (const string& node_name)
3233 return Stateful::instant_xml (node_name, _path);
3237 Session::save_history (string snapshot_name)
3245 if (snapshot_name.empty()) {
3246 snapshot_name = _current_snapshot_name;
3249 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3250 const string backup_filename = history_filename + backup_suffix;
3251 const sys::path xml_path = _session_dir->root_path() / history_filename;
3252 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3254 if (sys::exists (xml_path)) {
3257 sys::rename (xml_path, backup_path);
3259 catch (const sys::filesystem_error& err)
3261 error << _("could not backup old history file, current history not saved") << endmsg;
3266 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3270 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3272 if (!tree.write (xml_path.to_string()))
3274 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3278 sys::remove (xml_path);
3279 sys::rename (backup_path, xml_path);
3281 catch (const sys::filesystem_error& err)
3283 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3284 backup_path.to_string(), err.what()) << endmsg;
3294 Session::restore_history (string snapshot_name)
3298 if (snapshot_name.empty()) {
3299 snapshot_name = _current_snapshot_name;
3302 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3303 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3305 info << "Loading history from " << xml_path.to_string() << endmsg;
3307 if (!sys::exists (xml_path)) {
3308 info << string_compose (_("%1: no history file \"%2\" for this session."),
3309 _name, xml_path.to_string()) << endmsg;
3313 if (!tree.read (xml_path.to_string())) {
3314 error << string_compose (_("Could not understand session history file \"%1\""),
3315 xml_path.to_string()) << endmsg;
3322 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3325 UndoTransaction* ut = new UndoTransaction ();
3328 ut->set_name(t->property("name")->value());
3329 stringstream ss(t->property("tv-sec")->value());
3331 ss.str(t->property("tv-usec")->value());
3333 ut->set_timestamp(tv);
3335 for (XMLNodeConstIterator child_it = t->children().begin();
3336 child_it != t->children().end(); child_it++)
3338 XMLNode *n = *child_it;
3341 if (n->name() == "MementoCommand" ||
3342 n->name() == "MementoUndoCommand" ||
3343 n->name() == "MementoRedoCommand") {
3345 if ((c = memento_command_factory(n))) {
3349 } else if (n->name() == "NoteDiffCommand") {
3350 PBD::ID id (n->property("midi-source")->value());
3351 boost::shared_ptr<MidiSource> midi_source =
3352 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3354 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3356 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3359 } else if (n->name() == "SysExDiffCommand") {
3361 PBD::ID id (n->property("midi-source")->value());
3362 boost::shared_ptr<MidiSource> midi_source =
3363 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3365 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3367 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3370 } else if (n->name() == "PatchChangeDiffCommand") {
3372 PBD::ID id (n->property("midi-source")->value());
3373 boost::shared_ptr<MidiSource> midi_source =
3374 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3376 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3378 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3381 } else if (n->name() == "StatefulDiffCommand") {
3382 if ((c = stateful_diff_command_factory (n))) {
3383 ut->add_command (c);
3386 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3397 Session::config_changed (std::string p, bool ours)
3403 if (p == "seamless-loop") {
3405 } else if (p == "rf-speed") {
3407 } else if (p == "auto-loop") {
3409 } else if (p == "auto-input") {
3411 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3412 /* auto-input only makes a difference if we're rolling */
3413 set_track_monitor_input_status (!config.get_auto_input());
3416 } else if (p == "punch-in") {
3420 if ((location = _locations->auto_punch_location()) != 0) {
3422 if (config.get_punch_in ()) {
3423 replace_event (SessionEvent::PunchIn, location->start());
3425 remove_event (location->start(), SessionEvent::PunchIn);
3429 } else if (p == "punch-out") {
3433 if ((location = _locations->auto_punch_location()) != 0) {
3435 if (config.get_punch_out()) {
3436 replace_event (SessionEvent::PunchOut, location->end());
3438 clear_events (SessionEvent::PunchOut);
3442 } else if (p == "edit-mode") {
3444 Glib::Mutex::Lock lm (playlists->lock);
3446 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3447 (*i)->set_edit_mode (Config->get_edit_mode ());
3450 } else if (p == "use-video-sync") {
3452 waiting_for_sync_offset = config.get_use_video_sync();
3454 } else if (p == "mmc-control") {
3456 //poke_midi_thread ();
3458 } else if (p == "mmc-device-id" || p == "mmc-receive-id" || p == "mmc-receive-device-id") {
3460 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3462 } else if (p == "mmc-send-id" || p == "mmc-send-device-id") {
3464 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3466 } else if (p == "midi-control") {
3468 //poke_midi_thread ();
3470 } else if (p == "raid-path") {
3472 setup_raid_path (config.get_raid_path());
3474 } else if (p == "timecode-format") {
3478 } else if (p == "video-pullup") {
3482 } else if (p == "seamless-loop") {
3484 if (play_loop && transport_rolling()) {
3485 // to reset diskstreams etc
3486 request_play_loop (true);
3489 } else if (p == "rf-speed") {
3491 cumulative_rf_motion = 0;
3494 } else if (p == "click-sound") {
3496 setup_click_sounds (1);
3498 } else if (p == "click-emphasis-sound") {
3500 setup_click_sounds (-1);
3502 } else if (p == "clicking") {
3504 if (Config->get_clicking()) {
3505 if (_click_io && click_data) { // don't require emphasis data
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());
3587 Session::set_history_depth (uint32_t d)
3589 _history.set_depth (d);
3593 Session::load_diskstreams_2X (XMLNode const & node, int)
3596 XMLNodeConstIterator citer;
3598 clist = node.children();
3600 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3603 /* diskstreams added automatically by DiskstreamCreated handler */
3604 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3605 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3606 _diskstreams_2X.push_back (dsp);
3608 error << _("Session: unknown diskstream type in XML") << endmsg;
3612 catch (failed_constructor& err) {
3613 error << _("Session: could not load diskstream via XML state") << endmsg;
3621 /** Connect things to the MMC object */
3623 Session::setup_midi_machine_control ()
3625 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3627 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3628 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3629 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3630 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3631 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3632 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3633 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3634 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3635 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3636 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3637 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3638 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3639 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3641 /* also handle MIDI SPP because its so common */
3643 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3644 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3645 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));
3648 boost::shared_ptr<Controllable>
3649 Session::solo_cut_control() const
3651 /* the solo cut control is a bit of an anomaly, at least as of Febrary 2011. There are no other
3652 controls in Ardour that currently get presented to the user in the GUI that require
3653 access as a Controllable and are also NOT owned by some SessionObject (e.g. Route, or MonitorProcessor).
3655 its actually an RCConfiguration parameter, so we use a ProxyControllable to wrap
3656 it up as a Controllable. Changes to the Controllable will just map back to the RCConfiguration
3660 return _solo_cut_control;
3664 Session::rename (const std::string& new_name)
3666 string legal_name = legalize_for_path (new_name);
3672 string const old_sources_root = _session_dir->sources_root().to_string ();
3674 #define RENAME ::rename
3679 * interchange subdirectory
3683 * Backup files are left unchanged and not renamed.
3686 /* pass one: not 100% safe check that the new directory names don't
3690 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3695 /* this is a stupid hack because Glib::path_get_dirname() is
3696 * lexical-only, and so passing it /a/b/c/ gives a different
3697 * result than passing it /a/b/c ...
3700 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3701 oldstr = oldstr.substr (0, oldstr.length() - 1);
3704 string base = Glib::path_get_dirname (oldstr);
3705 string p = Glib::path_get_basename (oldstr);
3707 newstr = Glib::build_filename (base, legal_name);
3709 if (Glib::file_test (newstr, Glib::FILE_TEST_EXISTS)) {
3716 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
3721 /* this is a stupid hack because Glib::path_get_dirname() is
3722 * lexical-only, and so passing it /a/b/c/ gives a different
3723 * result than passing it /a/b/c ...
3726 if (oldstr[oldstr.length()-1] == G_DIR_SEPARATOR) {
3727 oldstr = oldstr.substr (0, oldstr.length() - 1);
3730 string base = Glib::path_get_dirname (oldstr);
3731 string p = Glib::path_get_basename (oldstr);
3733 newstr = Glib::build_filename (base, legal_name);
3735 cerr << "Rename " << oldstr << " => " << newstr << endl;
3737 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3742 (*_session_dir) = newstr;
3747 /* directory below interchange */
3749 v.push_back (newstr);
3750 v.push_back (interchange_dir_name);
3753 oldstr = Glib::build_filename (v);
3756 v.push_back (newstr);
3757 v.push_back (interchange_dir_name);
3758 v.push_back (legal_name);
3760 newstr = Glib::build_filename (v);
3762 cerr << "Rename " << oldstr << " => " << newstr << endl;
3764 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3771 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + statefile_suffix;
3772 newstr= Glib::build_filename (newpath, legal_name) + statefile_suffix;
3774 cerr << "Rename " << oldstr << " => " << newstr << endl;
3776 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3783 oldstr = Glib::build_filename (newpath, _current_snapshot_name) + history_suffix;
3785 if (Glib::file_test (oldstr, Glib::FILE_TEST_EXISTS)) {
3786 newstr = Glib::build_filename (newpath, legal_name) + history_suffix;
3788 cerr << "Rename " << oldstr << " => " << newstr << endl;
3790 if (RENAME (oldstr.c_str(), newstr.c_str()) != 0) {
3795 /* update file source paths */
3797 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
3798 boost::shared_ptr<FileSource> fs = boost::dynamic_pointer_cast<FileSource> (i->second);
3800 string p = fs->path ();
3801 boost::replace_all (p, old_sources_root, _session_dir->sources_root().to_string ());
3806 /* remove old name from recent sessions */
3808 remove_recent_sessions (_path);
3811 _current_snapshot_name = new_name;
3816 /* save state again to get everything just right */
3818 save_state (_current_snapshot_name);
3821 /* add to recent sessions */
3823 store_recent_sessions (new_name, _path);