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"
33 #include <cstdio> /* snprintf(3) ... grrr */
47 #include <sys/param.h>
48 #include <sys/mount.h>
52 #include <glibmm/thread.h>
54 #include "midi++/mmc.h"
55 #include "midi++/port.h"
56 #include "midi++/manager.h"
58 #include "pbd/boost_debug.h"
59 #include "pbd/controllable_descriptor.h"
60 #include "pbd/enumwriter.h"
61 #include "pbd/error.h"
62 #include "pbd/pathscanner.h"
63 #include "pbd/pthread_utils.h"
64 #include "pbd/search_path.h"
65 #include "pbd/stacktrace.h"
66 #include "pbd/convert.h"
67 #include "pbd/clear_dir.h"
69 #include "ardour/amp.h"
70 #include "ardour/audio_diskstream.h"
71 #include "ardour/audio_track.h"
72 #include "ardour/audioengine.h"
73 #include "ardour/audiofilesource.h"
74 #include "ardour/audioplaylist.h"
75 #include "ardour/audioregion.h"
76 #include "ardour/auditioner.h"
77 #include "ardour/automation_control.h"
78 #include "ardour/buffer.h"
79 #include "ardour/butler.h"
80 #include "ardour/configuration.h"
81 #include "ardour/control_protocol_manager.h"
82 #include "ardour/crossfade.h"
83 #include "ardour/cycle_timer.h"
84 #include "ardour/directory_names.h"
85 #include "ardour/filename_extensions.h"
86 #include "ardour/io_processor.h"
87 #include "ardour/location.h"
88 #include "ardour/midi_diskstream.h"
89 #include "ardour/midi_patch_manager.h"
90 #include "ardour/midi_playlist.h"
91 #include "ardour/midi_region.h"
92 #include "ardour/midi_source.h"
93 #include "ardour/midi_track.h"
94 #include "ardour/named_selection.h"
95 #include "ardour/pannable.h"
96 #include "ardour/processor.h"
97 #include "ardour/port.h"
98 #include "ardour/region_factory.h"
99 #include "ardour/route_group.h"
100 #include "ardour/send.h"
101 #include "ardour/session.h"
102 #include "ardour/session_directory.h"
103 #include "ardour/session_metadata.h"
104 #include "ardour/session_state_utils.h"
105 #include "ardour/session_playlists.h"
106 #include "ardour/session_utils.h"
107 #include "ardour/silentfilesource.h"
108 #include "ardour/slave.h"
109 #include "ardour/smf_source.h"
110 #include "ardour/sndfile_helpers.h"
111 #include "ardour/sndfilesource.h"
112 #include "ardour/source_factory.h"
113 #include "ardour/template_utils.h"
114 #include "ardour/tempo.h"
115 #include "ardour/ticker.h"
116 #include "ardour/user_bundle.h"
117 #include "ardour/utils.h"
118 #include "ardour/utils.h"
119 #include "ardour/version.h"
120 #include "ardour/playlist_factory.h"
122 #include "control_protocol/control_protocol.h"
128 using namespace ARDOUR;
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] != '/') {
149 _path += G_DIR_SEPARATOR;
152 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
158 /* these two are just provisional settings. set_state()
159 will likely override them.
162 _name = _current_snapshot_name = snapshot_name;
164 set_history_depth (Config->get_history_depth());
166 _current_frame_rate = _engine.frame_rate ();
167 _nominal_frame_rate = _current_frame_rate;
168 _base_frame_rate = _current_frame_rate;
170 _tempo_map = new TempoMap (_current_frame_rate);
171 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
174 _non_soloed_outs_muted = false;
176 _solo_isolated_cnt = 0;
177 g_atomic_int_set (&processing_prohibited, 0);
178 _transport_speed = 0;
179 _last_transport_speed = 0;
180 _target_transport_speed = 0;
181 auto_play_legal = false;
182 transport_sub_state = 0;
183 _transport_frame = 0;
184 _requested_return_frame = -1;
185 _session_range_location = 0;
186 g_atomic_int_set (&_record_status, Disabled);
187 loop_changing = false;
190 _last_roll_location = 0;
191 _last_roll_or_reversal_location = 0;
192 _last_record_location = 0;
193 pending_locate_frame = 0;
194 pending_locate_roll = false;
195 pending_locate_flush = false;
196 state_was_pending = false;
198 outbound_mtc_timecode_frame = 0;
199 next_quarter_frame_to_send = -1;
200 current_block_size = 0;
201 solo_update_disabled = false;
202 _have_captured = false;
203 _worst_output_latency = 0;
204 _worst_input_latency = 0;
205 _worst_track_latency = 0;
206 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
207 _was_seamless = Config->get_seamless_loop ();
209 _send_qf_mtc = false;
210 _pframes_since_last_mtc = 0;
211 g_atomic_int_set (&_playback_load, 100);
212 g_atomic_int_set (&_capture_load, 100);
215 pending_abort = false;
216 destructive_index = 0;
217 first_file_data_format_reset = true;
218 first_file_header_format_reset = true;
219 post_export_sync = false;
222 no_questions_about_missing_files = false;
223 _speakers = new Speakers;
225 AudioDiskstream::allocate_working_buffers();
227 /* default short fade = 15ms */
229 Crossfade::set_short_xfade_length ((framecnt_t) floor (config.get_short_xfade_seconds() * frame_rate()));
230 SndFileSource::setup_standard_crossfades (*this, frame_rate());
232 last_mmc_step.tv_sec = 0;
233 last_mmc_step.tv_usec = 0;
236 /* click sounds are unset by default, which causes us to internal
237 waveforms for clicks.
241 click_emphasis_length = 0;
244 process_function = &Session::process_with_events;
246 if (config.get_use_video_sync()) {
247 waiting_for_sync_offset = true;
249 waiting_for_sync_offset = false;
252 last_timecode_when = 0;
253 last_timecode_valid = false;
257 last_rr_session_dir = session_dirs.begin();
258 refresh_disk_space ();
260 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
262 /* default: assume simple stereo speaker configuration */
264 _speakers->setup_default_speakers (2);
268 average_slave_delta = 1800; // !!! why 1800 ????
269 have_first_delta_accumulator = false;
270 delta_accumulator_cnt = 0;
271 _slave_state = Stopped;
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().to_string());
295 if (load_state (_current_snapshot_name)) {
298 cleanup_stubfiles ();
301 if (_butler->start_thread()) {
305 if (start_midi_thread ()) {
309 setup_midi_machine_control ();
311 // set_state() will call setup_raid_path(), but if it's a new session we need
312 // to call setup_raid_path() here.
315 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
319 setup_raid_path(_path);
322 /* we can't save till after ::when_engine_running() is called,
323 because otherwise we save state with no connections made.
324 therefore, we reset _state_of_the_state because ::set_state()
325 will have cleared it.
327 we also have to include Loading so that any events that get
328 generated between here and the end of ::when_engine_running()
329 will be processed directly rather than queued.
332 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
334 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
335 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
336 setup_click_sounds (0);
337 setup_midi_control ();
339 /* Pay attention ... */
341 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
342 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
345 when_engine_running ();
348 /* handle this one in a different way than all others, so that its clear what happened */
350 catch (AudioEngine::PortRegistrationFailure& err) {
351 error << err.what() << endmsg;
359 BootMessage (_("Reset Remote Controls"));
361 send_full_time_code (0);
362 _engine.transport_locate (0);
364 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
365 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
367 MidiClockTicker::instance().set_session (this);
368 MIDI::Name::MidiPatchManager::instance().set_session (this);
370 /* initial program change will be delivered later; see ::config_changed() */
372 BootMessage (_("Reset Control Protocols"));
374 ControlProtocolManager::instance().set_session (this);
376 _state_of_the_state = Clean;
378 Port::set_connecting_blocked (false);
380 DirtyChanged (); /* EMIT SIGNAL */
382 if (state_was_pending) {
383 save_state (_current_snapshot_name);
384 remove_pending_capture_state ();
385 state_was_pending = false;
388 BootMessage (_("Session loading complete"));
394 Session::raid_path () const
396 SearchPath raid_search_path;
398 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
399 raid_search_path += sys::path((*i).path);
402 return raid_search_path.to_string ();
406 Session::setup_raid_path (string path)
415 session_dirs.clear ();
417 SearchPath search_path(path);
418 SearchPath sound_search_path;
419 SearchPath midi_search_path;
421 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
422 sp.path = (*i).to_string ();
423 sp.blocks = 0; // not needed
424 session_dirs.push_back (sp);
426 SessionDirectory sdir(sp.path);
428 sound_search_path += sdir.sound_path ();
429 midi_search_path += sdir.midi_path ();
432 // reset the round-robin soundfile path thingie
433 last_rr_session_dir = session_dirs.begin();
437 Session::path_is_within_session (const std::string& path)
439 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
440 if (path.find ((*i).path) == 0) {
448 Session::ensure_subdirs ()
452 dir = session_directory().peak_path().to_string();
454 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
455 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
459 dir = session_directory().sound_path().to_string();
461 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
462 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
466 dir = session_directory().sound_stub_path().to_string();
468 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
469 error << string_compose(_("Session: cannot create session stub sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
473 dir = session_directory().midi_path().to_string();
475 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
476 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
480 dir = session_directory().midi_stub_path().to_string();
482 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
483 error << string_compose(_("Session: cannot create session stub midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
487 dir = session_directory().dead_sound_path().to_string();
489 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
490 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
494 dir = session_directory().export_path().to_string();
496 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
497 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
501 dir = analysis_dir ();
503 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
504 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
508 dir = plugins_dir ();
510 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
511 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
518 /** Caller must not hold process lock */
520 Session::create (const string& mix_template, BusProfile* bus_profile)
523 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
524 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
528 if (ensure_subdirs ()) {
532 if (!mix_template.empty()) {
533 std::string in_path = mix_template;
535 ifstream in(in_path.c_str());
538 string out_path = _path;
540 out_path += statefile_suffix;
542 ofstream out(out_path.c_str());
550 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
556 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
563 /* Instantiate metadata */
565 _metadata = new SessionMetadata ();
567 /* set initial start + end point */
569 _state_of_the_state = Clean;
571 /* set up Master Out and Control Out if necessary */
577 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
579 if (bus_profile->master_out_channels) {
580 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
585 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
586 boost_debug_shared_ptr_mark_interesting (rt, "Route");
588 boost::shared_ptr<Route> r (rt);
590 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
591 r->input()->ensure_io (count, false, this);
592 r->output()->ensure_io (count, false, this);
594 r->set_remote_control_id (control_id++);
598 if (Config->get_use_monitor_bus()) {
599 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
604 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
605 boost_debug_shared_ptr_mark_interesting (rt, "Route");
607 boost::shared_ptr<Route> r (rt);
609 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
610 r->input()->ensure_io (count, false, this);
611 r->output()->ensure_io (count, false, this);
613 r->set_remote_control_id (control_id);
619 /* prohibit auto-connect to master, because there isn't one */
620 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
624 add_routes (rl, false);
627 /* this allows the user to override settings with an environment variable.
630 if (no_auto_connect()) {
631 bus_profile->input_ac = AutoConnectOption (0);
632 bus_profile->output_ac = AutoConnectOption (0);
635 Config->set_input_auto_connect (bus_profile->input_ac);
636 Config->set_output_auto_connect (bus_profile->output_ac);
645 Session::maybe_write_autosave()
647 if (dirty() && record_status() != Recording) {
648 save_state("", true);
653 Session::remove_pending_capture_state ()
655 sys::path pending_state_file_path(_session_dir->root_path());
657 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
661 sys::remove (pending_state_file_path);
663 catch(sys::filesystem_error& ex)
665 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
666 pending_state_file_path.to_string(), ex.what()) << endmsg;
670 /** Rename a state file.
671 * @param snapshot_name Snapshot name.
674 Session::rename_state (string old_name, string new_name)
676 if (old_name == _current_snapshot_name || old_name == _name) {
677 /* refuse to rename the current snapshot or the "main" one */
681 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
682 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
684 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
685 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
689 sys::rename (old_xml_path, new_xml_path);
691 catch (const sys::filesystem_error& err)
693 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
694 old_name, new_name, err.what()) << endmsg;
698 /** Remove a state file.
699 * @param snapshot_name Snapshot name.
702 Session::remove_state (string snapshot_name)
704 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
705 // refuse to remove the current snapshot or the "main" one
709 sys::path xml_path(_session_dir->root_path());
711 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
713 if (!create_backup_file (xml_path)) {
714 // don't remove it if a backup can't be made
715 // create_backup_file will log the error.
720 sys::remove (xml_path);
723 #ifdef HAVE_JACK_SESSION
725 Session::jack_session_event (jack_session_event_t * event)
729 struct tm local_time;
732 localtime_r (&n, &local_time);
733 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
735 if (event->type == JackSessionSaveTemplate)
737 if (save_template( timebuf )) {
738 event->flags = JackSessionSaveError;
740 string cmd ("ardour3 -P -U ");
741 cmd += event->client_uuid;
745 event->command_line = strdup (cmd.c_str());
750 if (save_state (timebuf)) {
751 event->flags = JackSessionSaveError;
753 sys::path xml_path (_session_dir->root_path());
754 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
756 string cmd ("ardour3 -P -U ");
757 cmd += event->client_uuid;
759 cmd += xml_path.to_string();
762 event->command_line = strdup (cmd.c_str());
766 jack_session_reply (_engine.jack(), event);
768 if (event->type == JackSessionSaveAndQuit) {
769 Quit (); /* EMIT SIGNAL */
772 jack_session_event_free( event );
777 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
780 sys::path xml_path(_session_dir->root_path());
782 if (!_writable || (_state_of_the_state & CannotSave)) {
786 if (!_engine.connected ()) {
787 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
793 /* tell sources we're saving first, in case they write out to a new file
794 * which should be saved with the state rather than the old one */
795 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
796 i->second->session_saved();
799 tree.set_root (&get_state());
801 if (snapshot_name.empty()) {
802 snapshot_name = _current_snapshot_name;
803 } else if (switch_to_snapshot) {
804 _current_snapshot_name = snapshot_name;
809 /* proper save: use statefile_suffix (.ardour in English) */
811 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
813 /* make a backup copy of the old file */
815 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
816 // create_backup_file will log the error
822 /* pending save: use pending_suffix (.pending in English) */
823 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
826 sys::path tmp_path(_session_dir->root_path());
828 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
830 // cerr << "actually writing state to " << xml_path.to_string() << endl;
832 if (!tree.write (tmp_path.to_string())) {
833 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
834 sys::remove (tmp_path);
839 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
840 error << string_compose (_("could not rename temporary session file %1 to %2"),
841 tmp_path.to_string(), xml_path.to_string()) << endmsg;
842 sys::remove (tmp_path);
849 save_history (snapshot_name);
851 bool was_dirty = dirty();
853 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
856 DirtyChanged (); /* EMIT SIGNAL */
859 StateSaved (snapshot_name); /* EMIT SIGNAL */
866 Session::restore_state (string snapshot_name)
868 if (load_state (snapshot_name) == 0) {
869 set_state (*state_tree->root(), Stateful::loading_state_version);
876 Session::load_state (string snapshot_name)
881 state_was_pending = false;
883 /* check for leftover pending state from a crashed capture attempt */
885 sys::path xmlpath(_session_dir->root_path());
886 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
888 if (sys::exists (xmlpath)) {
890 /* there is pending state from a crashed capture attempt */
892 boost::optional<int> r = AskAboutPendingState();
893 if (r.get_value_or (1)) {
894 state_was_pending = true;
898 if (!state_was_pending) {
899 xmlpath = _session_dir->root_path();
900 xmlpath /= snapshot_name;
903 if (!sys::exists (xmlpath)) {
904 xmlpath = _session_dir->root_path();
905 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
906 if (!sys::exists (xmlpath)) {
907 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
912 state_tree = new XMLTree;
916 /* writable() really reflects the whole folder, but if for any
917 reason the session state file can't be written to, still
921 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
925 if (!state_tree->read (xmlpath.to_string())) {
926 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
932 XMLNode& root (*state_tree->root());
934 if (root.name() != X_("Session")) {
935 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
941 const XMLProperty* prop;
943 if ((prop = root.property ("version")) == 0) {
944 /* no version implies very old version of Ardour */
945 Stateful::loading_state_version = 1000;
951 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
952 Stateful::loading_state_version = (major * 1000) + minor;
955 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
957 sys::path backup_path(_session_dir->root_path());
959 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
961 // only create a backup once
962 if (sys::exists (backup_path)) {
966 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
967 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
972 sys::copy_file (xmlpath, backup_path);
974 catch(sys::filesystem_error& ex)
976 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
977 xmlpath.to_string(), ex.what())
987 Session::load_options (const XMLNode& node)
989 LocaleGuard lg (X_("POSIX"));
990 config.set_variables (node);
1001 Session::get_template()
1003 /* if we don't disable rec-enable, diskstreams
1004 will believe they need to store their capture
1005 sources in their state node.
1008 disable_record (false);
1010 return state(false);
1014 Session::state(bool full_state)
1016 XMLNode* node = new XMLNode("Session");
1019 // store libardour version, just in case
1021 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
1022 node->add_property("version", string(buf));
1024 /* store configuration settings */
1028 node->add_property ("name", _name);
1029 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1030 node->add_property ("sample-rate", buf);
1032 if (session_dirs.size() > 1) {
1036 vector<space_and_path>::iterator i = session_dirs.begin();
1037 vector<space_and_path>::iterator next;
1039 ++i; /* skip the first one */
1043 while (i != session_dirs.end()) {
1047 if (next != session_dirs.end()) {
1057 child = node->add_child ("Path");
1058 child->add_content (p);
1062 /* save the ID counter */
1064 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1065 node->add_property ("id-counter", buf);
1067 /* save the event ID counter */
1069 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1070 node->add_property ("event-counter", buf);
1072 /* various options */
1074 node->add_child_nocopy (config.get_variables ());
1076 node->add_child_nocopy (_metadata->get_state());
1078 child = node->add_child ("Sources");
1081 Glib::Mutex::Lock sl (source_lock);
1083 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1085 /* Don't save information about non-destructive file sources that are empty
1086 and unused by any regions.
1089 boost::shared_ptr<FileSource> fs;
1090 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1091 if (!fs->destructive()) {
1092 if (fs->empty() && !fs->used()) {
1098 child->add_child_nocopy (siter->second->get_state());
1102 child = node->add_child ("Regions");
1105 Glib::Mutex::Lock rl (region_lock);
1106 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1107 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1108 boost::shared_ptr<Region> r = i->second;
1109 /* only store regions not attached to playlists */
1110 if (r->playlist() == 0) {
1111 child->add_child_nocopy (r->state ());
1117 node->add_child_nocopy (_locations->get_state());
1119 // for a template, just create a new Locations, populate it
1120 // with the default start and end, and get the state for that.
1121 Locations loc (*this);
1122 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1123 range->set (max_framepos, 0);
1125 node->add_child_nocopy (loc.get_state());
1128 child = node->add_child ("Bundles");
1130 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1131 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1132 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1134 child->add_child_nocopy (b->get_state());
1139 child = node->add_child ("Routes");
1141 boost::shared_ptr<RouteList> r = routes.reader ();
1143 RoutePublicOrderSorter cmp;
1144 RouteList public_order (*r);
1145 public_order.sort (cmp);
1147 /* the sort should have put control outs first */
1150 assert (_monitor_out == public_order.front());
1153 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1154 if (!(*i)->is_hidden()) {
1156 child->add_child_nocopy ((*i)->get_state());
1158 child->add_child_nocopy ((*i)->get_template());
1164 playlists->add_state (node, full_state);
1166 child = node->add_child ("RouteGroups");
1167 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1168 child->add_child_nocopy ((*i)->get_state());
1172 child = node->add_child ("Click");
1173 child->add_child_nocopy (_click_io->state (full_state));
1177 child = node->add_child ("NamedSelections");
1178 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1180 child->add_child_nocopy ((*i)->get_state());
1185 node->add_child_nocopy (_speakers->get_state());
1187 node->add_child_nocopy (_tempo_map->get_state());
1189 node->add_child_nocopy (get_control_protocol_state());
1192 node->add_child_copy (*_extra_xml);
1199 Session::get_control_protocol_state ()
1201 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1202 return cpm.get_state();
1206 Session::set_state (const XMLNode& node, int version)
1210 const XMLProperty* prop;
1213 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1215 if (node.name() != X_("Session")){
1216 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1220 if ((prop = node.property ("version")) != 0) {
1221 version = atoi (prop->value ()) * 1000;
1224 if ((prop = node.property ("name")) != 0) {
1225 _name = prop->value ();
1228 if ((prop = node.property (X_("sample-rate"))) != 0) {
1230 _nominal_frame_rate = atoi (prop->value());
1232 if (_nominal_frame_rate != _current_frame_rate) {
1233 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1234 if (r.get_value_or (0)) {
1240 setup_raid_path(_session_dir->root_path().to_string());
1242 if ((prop = node.property (X_("id-counter"))) != 0) {
1244 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1245 ID::init_counter (x);
1247 /* old sessions used a timebased counter, so fake
1248 the startup ID counter based on a standard
1253 ID::init_counter (now);
1256 if ((prop = node.property (X_("event-counter"))) != 0) {
1257 Evoral::init_event_id_counter (atoi (prop->value()));
1260 IO::disable_connecting ();
1262 /* Object loading order:
1267 MIDI Control // relies on data from Options/Config
1280 if ((child = find_named_node (node, "Extra")) != 0) {
1281 _extra_xml = new XMLNode (*child);
1284 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1285 load_options (*child);
1286 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1287 load_options (*child);
1289 error << _("Session: XML state has no options section") << endmsg;
1292 if (version >= 3000) {
1293 if ((child = find_named_node (node, "Metadata")) == 0) {
1294 warning << _("Session: XML state has no metadata section") << endmsg;
1295 } else if (_metadata->set_state (*child, version)) {
1300 if ((child = find_named_node (node, "Locations")) == 0) {
1301 error << _("Session: XML state has no locations section") << endmsg;
1303 } else if (_locations->set_state (*child, version)) {
1307 if ((child = find_named_node (node, X_("Speakers"))) != 0) {
1308 _speakers->set_state (*child, version);
1313 if ((location = _locations->auto_loop_location()) != 0) {
1314 set_auto_loop_location (location);
1317 if ((location = _locations->auto_punch_location()) != 0) {
1318 set_auto_punch_location (location);
1321 if ((location = _locations->session_range_location()) != 0) {
1322 delete _session_range_location;
1323 _session_range_location = location;
1326 if (_session_range_location) {
1327 AudioFileSource::set_header_position_offset (_session_range_location->start());
1330 if ((child = find_named_node (node, "Sources")) == 0) {
1331 error << _("Session: XML state has no sources section") << endmsg;
1333 } else if (load_sources (*child)) {
1337 if ((child = find_named_node (node, "Regions")) == 0) {
1338 error << _("Session: XML state has no Regions section") << endmsg;
1340 } else if (load_regions (*child)) {
1344 if ((child = find_named_node (node, "Playlists")) == 0) {
1345 error << _("Session: XML state has no playlists section") << endmsg;
1347 } else if (playlists->load (*this, *child)) {
1351 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1353 } else if (playlists->load_unused (*this, *child)) {
1357 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1358 if (load_named_selections (*child)) {
1363 if (version >= 3000) {
1364 if ((child = find_named_node (node, "Bundles")) == 0) {
1365 warning << _("Session: XML state has no bundles section") << endmsg;
1368 /* We can't load Bundles yet as they need to be able
1369 to convert from port names to Port objects, which can't happen until
1371 _bundle_xml_node = new XMLNode (*child);
1375 if ((child = find_named_node (node, "TempoMap")) == 0) {
1376 error << _("Session: XML state has no Tempo Map section") << endmsg;
1378 } else if (_tempo_map->set_state (*child, version)) {
1382 if (version < 3000) {
1383 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1384 error << _("Session: XML state has no diskstreams section") << endmsg;
1386 } else if (load_diskstreams_2X (*child, version)) {
1391 if ((child = find_named_node (node, "Routes")) == 0) {
1392 error << _("Session: XML state has no routes section") << endmsg;
1394 } else if (load_routes (*child, version)) {
1398 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1399 _diskstreams_2X.clear ();
1401 if (version >= 3000) {
1403 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1404 error << _("Session: XML state has no route groups section") << endmsg;
1406 } else if (load_route_groups (*child, version)) {
1410 } else if (version < 3000) {
1412 if ((child = find_named_node (node, "EditGroups")) == 0) {
1413 error << _("Session: XML state has no edit groups section") << endmsg;
1415 } else if (load_route_groups (*child, version)) {
1419 if ((child = find_named_node (node, "MixGroups")) == 0) {
1420 error << _("Session: XML state has no mix groups section") << endmsg;
1422 } else if (load_route_groups (*child, version)) {
1427 if ((child = find_named_node (node, "Click")) == 0) {
1428 warning << _("Session: XML state has no click section") << endmsg;
1429 } else if (_click_io) {
1430 _click_io->set_state (*child, version);
1433 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1434 ControlProtocolManager::instance().set_protocol_states (*child);
1437 /* here beginneth the second phase ... */
1439 StateReady (); /* EMIT SIGNAL */
1448 Session::load_routes (const XMLNode& node, int version)
1451 XMLNodeConstIterator niter;
1452 RouteList new_routes;
1454 nlist = node.children();
1458 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1460 boost::shared_ptr<Route> route;
1461 if (version < 3000) {
1462 route = XMLRouteFactory_2X (**niter, version);
1464 route = XMLRouteFactory (**niter, version);
1468 error << _("Session: cannot create Route from XML description.") << endmsg;
1472 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1474 new_routes.push_back (route);
1477 add_routes (new_routes, false);
1482 boost::shared_ptr<Route>
1483 Session::XMLRouteFactory (const XMLNode& node, int version)
1485 boost::shared_ptr<Route> ret;
1487 if (node.name() != "Route") {
1491 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1493 DataType type = DataType::AUDIO;
1494 const XMLProperty* prop = node.property("default-type");
1497 type = DataType (prop->value());
1500 assert (type != DataType::NIL);
1506 if (type == DataType::AUDIO) {
1507 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1510 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1513 if (track->init()) {
1518 if (track->set_state (node, version)) {
1523 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1524 boost_debug_shared_ptr_mark_interesting (track, "Track");
1529 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1531 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1532 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1533 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1544 boost::shared_ptr<Route>
1545 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1547 boost::shared_ptr<Route> ret;
1549 if (node.name() != "Route") {
1553 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1555 ds_prop = node.property (X_("diskstream"));
1558 DataType type = DataType::AUDIO;
1559 const XMLProperty* prop = node.property("default-type");
1562 type = DataType (prop->value());
1565 assert (type != DataType::NIL);
1569 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1570 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1574 if (i == _diskstreams_2X.end()) {
1575 error << _("Could not find diskstream for route") << endmsg;
1576 return boost::shared_ptr<Route> ();
1581 if (type == DataType::AUDIO) {
1582 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1585 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1588 if (track->init()) {
1593 if (track->set_state (node, version)) {
1598 track->set_diskstream (*i);
1600 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1601 boost_debug_shared_ptr_mark_interesting (track, "Track");
1606 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1608 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1609 #ifdef BOOST_SP_ENABLE_DEBUG_HOOKS
1610 boost_debug_shared_ptr_mark_interesting (rt, "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());
1648 boost::shared_ptr<Region>
1649 Session::XMLRegionFactory (const XMLNode& node, bool full)
1651 const XMLProperty* type = node.property("type");
1655 if (!type || type->value() == "audio") {
1656 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1657 } else if (type->value() == "midi") {
1658 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1661 } catch (failed_constructor& err) {
1662 return boost::shared_ptr<Region> ();
1665 return boost::shared_ptr<Region> ();
1668 boost::shared_ptr<AudioRegion>
1669 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1671 const XMLProperty* prop;
1672 boost::shared_ptr<Source> source;
1673 boost::shared_ptr<AudioSource> as;
1675 SourceList master_sources;
1676 uint32_t nchans = 1;
1679 if (node.name() != X_("Region")) {
1680 return boost::shared_ptr<AudioRegion>();
1683 if ((prop = node.property (X_("channels"))) != 0) {
1684 nchans = atoi (prop->value().c_str());
1687 if ((prop = node.property ("name")) == 0) {
1688 cerr << "no name for this region\n";
1692 if ((prop = node.property (X_("source-0"))) == 0) {
1693 if ((prop = node.property ("source")) == 0) {
1694 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1695 return boost::shared_ptr<AudioRegion>();
1699 PBD::ID s_id (prop->value());
1701 if ((source = source_by_id (s_id)) == 0) {
1702 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1703 return boost::shared_ptr<AudioRegion>();
1706 as = boost::dynamic_pointer_cast<AudioSource>(source);
1708 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1709 return boost::shared_ptr<AudioRegion>();
1712 sources.push_back (as);
1714 /* pickup other channels */
1716 for (uint32_t n=1; n < nchans; ++n) {
1717 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1718 if ((prop = node.property (buf)) != 0) {
1720 PBD::ID id2 (prop->value());
1722 if ((source = source_by_id (id2)) == 0) {
1723 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1724 return boost::shared_ptr<AudioRegion>();
1727 as = boost::dynamic_pointer_cast<AudioSource>(source);
1729 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1730 return boost::shared_ptr<AudioRegion>();
1732 sources.push_back (as);
1736 for (uint32_t n = 0; n < nchans; ++n) {
1737 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1738 if ((prop = node.property (buf)) != 0) {
1740 PBD::ID id2 (prop->value());
1742 if ((source = source_by_id (id2)) == 0) {
1743 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1744 return boost::shared_ptr<AudioRegion>();
1747 as = boost::dynamic_pointer_cast<AudioSource>(source);
1749 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1750 return boost::shared_ptr<AudioRegion>();
1752 master_sources.push_back (as);
1757 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1759 /* a final detail: this is the one and only place that we know how long missing files are */
1761 if (region->whole_file()) {
1762 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1763 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1765 sfp->set_length (region->length());
1770 if (!master_sources.empty()) {
1771 if (master_sources.size() != nchans) {
1772 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1774 region->set_master_sources (master_sources);
1782 catch (failed_constructor& err) {
1783 return boost::shared_ptr<AudioRegion>();
1787 boost::shared_ptr<MidiRegion>
1788 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1790 const XMLProperty* prop;
1791 boost::shared_ptr<Source> source;
1792 boost::shared_ptr<MidiSource> ms;
1795 if (node.name() != X_("Region")) {
1796 return boost::shared_ptr<MidiRegion>();
1799 if ((prop = node.property ("name")) == 0) {
1800 cerr << "no name for this region\n";
1804 if ((prop = node.property (X_("source-0"))) == 0) {
1805 if ((prop = node.property ("source")) == 0) {
1806 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1807 return boost::shared_ptr<MidiRegion>();
1811 PBD::ID s_id (prop->value());
1813 if ((source = source_by_id (s_id)) == 0) {
1814 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1815 return boost::shared_ptr<MidiRegion>();
1818 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1820 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1821 return boost::shared_ptr<MidiRegion>();
1824 sources.push_back (ms);
1827 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1828 /* a final detail: this is the one and only place that we know how long missing files are */
1830 if (region->whole_file()) {
1831 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1832 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1834 sfp->set_length (region->length());
1842 catch (failed_constructor& err) {
1843 return boost::shared_ptr<MidiRegion>();
1848 Session::get_sources_as_xml ()
1851 XMLNode* node = new XMLNode (X_("Sources"));
1852 Glib::Mutex::Lock lm (source_lock);
1854 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1855 node->add_child_nocopy (i->second->get_state());
1862 Session::path_from_region_name (DataType type, string name, string identifier)
1864 char buf[PATH_MAX+1];
1866 SessionDirectory sdir(get_best_session_directory_for_new_source());
1867 sys::path source_dir = ((type == DataType::AUDIO)
1868 ? sdir.sound_path() : sdir.midi_path());
1870 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1872 for (n = 0; n < 999999; ++n) {
1873 if (identifier.length()) {
1874 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1875 identifier.c_str(), n, ext.c_str());
1877 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1881 sys::path source_path = source_dir / buf;
1883 if (!sys::exists (source_path)) {
1884 return source_path.to_string();
1888 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1897 Session::load_sources (const XMLNode& node)
1900 XMLNodeConstIterator niter;
1901 boost::shared_ptr<Source> source;
1903 nlist = node.children();
1907 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1910 if ((source = XMLSourceFactory (**niter)) == 0) {
1911 error << _("Session: cannot create Source from XML description.") << endmsg;
1914 } catch (MissingSource& err) {
1918 if (!no_questions_about_missing_files) {
1919 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1924 switch (user_choice) {
1926 /* user added a new search location, so try again */
1931 /* user asked to quit the entire session load
1936 no_questions_about_missing_files = true;
1940 no_questions_about_missing_files = true;
1945 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1946 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1955 boost::shared_ptr<Source>
1956 Session::XMLSourceFactory (const XMLNode& node)
1958 if (node.name() != "Source") {
1959 return boost::shared_ptr<Source>();
1963 /* note: do peak building in another thread when loading session state */
1964 return SourceFactory::create (*this, node, true);
1967 catch (failed_constructor& err) {
1968 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1969 return boost::shared_ptr<Source>();
1974 Session::save_template (string template_name)
1978 if (_state_of_the_state & CannotSave) {
1982 sys::path user_template_dir(user_template_directory());
1986 sys::create_directories (user_template_dir);
1988 catch(sys::filesystem_error& ex)
1990 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1991 user_template_dir.to_string(), ex.what()) << endmsg;
1995 tree.set_root (&get_template());
1997 sys::path template_file_path(user_template_dir);
1998 template_file_path /= template_name + template_suffix;
2000 if (sys::exists (template_file_path))
2002 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
2003 template_file_path.to_string()) << endmsg;
2007 if (!tree.write (template_file_path.to_string())) {
2008 error << _("mix template not saved") << endmsg;
2016 Session::rename_template (string old_name, string new_name)
2018 sys::path old_path (user_template_directory());
2019 old_path /= old_name + template_suffix;
2021 sys::path new_path(user_template_directory());
2022 new_path /= new_name + template_suffix;
2024 if (sys::exists (new_path)) {
2025 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
2026 new_path.to_string()) << endmsg;
2031 sys::rename (old_path, new_path);
2039 Session::delete_template (string name)
2041 sys::path path = user_template_directory();
2042 path /= name + template_suffix;
2053 Session::refresh_disk_space ()
2056 struct statfs statfsbuf;
2057 vector<space_and_path>::iterator i;
2058 Glib::Mutex::Lock lm (space_lock);
2061 /* get freespace on every FS that is part of the session path */
2063 _total_free_4k_blocks = 0;
2065 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2066 statfs ((*i).path.c_str(), &statfsbuf);
2068 scale = statfsbuf.f_bsize/4096.0;
2070 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2071 _total_free_4k_blocks += (*i).blocks;
2077 Session::get_best_session_directory_for_new_source ()
2079 vector<space_and_path>::iterator i;
2080 string result = _session_dir->root_path().to_string();
2082 /* handle common case without system calls */
2084 if (session_dirs.size() == 1) {
2088 /* OK, here's the algorithm we're following here:
2090 We want to select which directory to use for
2091 the next file source to be created. Ideally,
2092 we'd like to use a round-robin process so as to
2093 get maximum performance benefits from splitting
2094 the files across multiple disks.
2096 However, in situations without much diskspace, an
2097 RR approach may end up filling up a filesystem
2098 with new files while others still have space.
2099 Its therefore important to pay some attention to
2100 the freespace in the filesystem holding each
2101 directory as well. However, if we did that by
2102 itself, we'd keep creating new files in the file
2103 system with the most space until it was as full
2104 as all others, thus negating any performance
2105 benefits of this RAID-1 like approach.
2107 So, we use a user-configurable space threshold. If
2108 there are at least 2 filesystems with more than this
2109 much space available, we use RR selection between them.
2110 If not, then we pick the filesystem with the most space.
2112 This gets a good balance between the two
2116 refresh_disk_space ();
2118 int free_enough = 0;
2120 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2121 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2126 if (free_enough >= 2) {
2127 /* use RR selection process, ensuring that the one
2131 i = last_rr_session_dir;
2134 if (++i == session_dirs.end()) {
2135 i = session_dirs.begin();
2138 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2139 if (create_session_directory ((*i).path)) {
2141 last_rr_session_dir = i;
2146 } while (i != last_rr_session_dir);
2150 /* pick FS with the most freespace (and that
2151 seems to actually work ...)
2154 vector<space_and_path> sorted;
2155 space_and_path_ascending_cmp cmp;
2157 sorted = session_dirs;
2158 sort (sorted.begin(), sorted.end(), cmp);
2160 for (i = sorted.begin(); i != sorted.end(); ++i) {
2161 if (create_session_directory ((*i).path)) {
2163 last_rr_session_dir = i;
2173 Session::load_named_selections (const XMLNode& node)
2176 XMLNodeConstIterator niter;
2179 nlist = node.children();
2183 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2185 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2186 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2194 Session::XMLNamedSelectionFactory (const XMLNode& node)
2197 return new NamedSelection (*this, node);
2200 catch (failed_constructor& err) {
2206 Session::automation_dir () const
2208 return Glib::build_filename (_path, "automation");
2212 Session::analysis_dir () const
2214 return Glib::build_filename (_path, "analysis");
2218 Session::plugins_dir () const
2220 return Glib::build_filename (_path, "plugins");
2224 Session::load_bundles (XMLNode const & node)
2226 XMLNodeList nlist = node.children();
2227 XMLNodeConstIterator niter;
2231 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2232 if ((*niter)->name() == "InputBundle") {
2233 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2234 } else if ((*niter)->name() == "OutputBundle") {
2235 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2237 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2246 Session::load_route_groups (const XMLNode& node, int version)
2248 XMLNodeList nlist = node.children();
2249 XMLNodeConstIterator niter;
2253 if (version >= 3000) {
2255 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2256 if ((*niter)->name() == "RouteGroup") {
2257 RouteGroup* rg = new RouteGroup (*this, "");
2258 add_route_group (rg);
2259 rg->set_state (**niter, version);
2263 } else if (version < 3000) {
2265 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2266 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2267 RouteGroup* rg = new RouteGroup (*this, "");
2268 add_route_group (rg);
2269 rg->set_state (**niter, version);
2278 Session::auto_save()
2280 save_state (_current_snapshot_name);
2284 state_file_filter (const string &str, void */*arg*/)
2286 return (str.length() > strlen(statefile_suffix) &&
2287 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2291 bool operator()(const string* a, const string* b) {
2297 remove_end(string* state)
2299 string statename(*state);
2301 string::size_type start,end;
2302 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2303 statename = statename.substr (start+1);
2306 if ((end = statename.rfind(".ardour")) == string::npos) {
2307 end = statename.length();
2310 return new string(statename.substr (0, end));
2314 Session::possible_states (string path)
2316 PathScanner scanner;
2317 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2319 transform(states->begin(), states->end(), states->begin(), remove_end);
2322 sort (states->begin(), states->end(), cmp);
2328 Session::possible_states () const
2330 return possible_states(_path);
2334 Session::add_route_group (RouteGroup* g)
2336 _route_groups.push_back (g);
2337 route_group_added (g); /* EMIT SIGNAL */
2339 g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2340 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2346 Session::remove_route_group (RouteGroup& rg)
2348 list<RouteGroup*>::iterator i;
2350 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2351 _route_groups.erase (i);
2354 route_group_removed (); /* EMIT SIGNAL */
2360 Session::route_group_by_name (string name)
2362 list<RouteGroup *>::iterator i;
2364 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2365 if ((*i)->name() == name) {
2373 Session::all_route_group() const
2375 return *_all_route_group;
2379 Session::add_commands (vector<Command*> const & cmds)
2381 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2387 Session::begin_reversible_command (const string& name)
2389 begin_reversible_command (g_quark_from_string (name.c_str ()));
2392 /** Begin a reversible command using a GQuark to identify it.
2393 * begin_reversible_command() and commit_reversible_command() calls may be nested,
2394 * but there must be as many begin...()s as there are commit...()s.
2397 Session::begin_reversible_command (GQuark q)
2399 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2400 to hold all the commands that are committed. This keeps the order of
2401 commands correct in the history.
2404 if (_current_trans == 0) {
2405 /* start a new transaction */
2406 assert (_current_trans_quarks.empty ());
2407 _current_trans = new UndoTransaction();
2408 _current_trans->set_name (g_quark_to_string (q));
2411 _current_trans_quarks.push_front (q);
2415 Session::commit_reversible_command (Command *cmd)
2417 assert (_current_trans);
2418 assert (!_current_trans_quarks.empty ());
2423 _current_trans->add_command (cmd);
2426 _current_trans_quarks.pop_front ();
2428 if (!_current_trans_quarks.empty ()) {
2429 /* the transaction we're committing is not the top-level one */
2433 if (_current_trans->empty()) {
2434 /* no commands were added to the transaction, so just get rid of it */
2435 delete _current_trans;
2440 gettimeofday (&now, 0);
2441 _current_trans->set_timestamp (now);
2443 _history.add (_current_trans);
2448 accept_all_non_peak_files (const string& path, void */*arg*/)
2450 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2454 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2458 accept_all_state_files (const string& path, void */*arg*/)
2460 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2464 Session::find_all_sources (string path, set<string>& result)
2469 if (!tree.read (path)) {
2473 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2478 XMLNodeConstIterator niter;
2480 nlist = node->children();
2484 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2488 if ((prop = (*niter)->property (X_("type"))) == 0) {
2492 DataType type (prop->value());
2494 if ((prop = (*niter)->property (X_("name"))) == 0) {
2498 if (Glib::path_is_absolute (prop->value())) {
2499 /* external file, ignore */
2507 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2508 result.insert (found_path);
2516 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2518 PathScanner scanner;
2519 vector<string*>* state_files;
2521 string this_snapshot_path;
2527 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2528 ripped = ripped.substr (0, ripped.length() - 1);
2531 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2533 if (state_files == 0) {
2538 this_snapshot_path = _path;
2539 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2540 this_snapshot_path += statefile_suffix;
2542 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2544 if (exclude_this_snapshot && **i == this_snapshot_path) {
2548 if (find_all_sources (**i, result) < 0) {
2556 struct RegionCounter {
2557 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2558 AudioSourceList::iterator iter;
2559 boost::shared_ptr<Region> region;
2562 RegionCounter() : count (0) {}
2566 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2568 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2569 return r.get_value_or (1);
2573 Session::cleanup_sources (CleanupReport& rep)
2575 // FIXME: needs adaptation to midi
2577 vector<boost::shared_ptr<Source> > dead_sources;
2578 PathScanner scanner;
2580 vector<space_and_path>::iterator i;
2581 vector<space_and_path>::iterator nexti;
2582 vector<string*>* soundfiles;
2583 vector<string> unused;
2584 set<string> all_sources;
2589 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2591 /* step 1: consider deleting all unused playlists */
2593 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2598 /* step 2: find all un-used sources */
2603 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2605 SourceMap::iterator tmp;
2610 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2614 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2615 dead_sources.push_back (i->second);
2616 i->second->drop_references ();
2622 /* build a list of all the possible sound directories for the session */
2624 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2629 SessionDirectory sdir ((*i).path);
2630 sound_path += sdir.sound_path().to_string();
2632 if (nexti != session_dirs.end()) {
2639 /* now do the same thing for the files that ended up in the sounds dir(s)
2640 but are not referenced as sources in any snapshot.
2643 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2645 if (soundfiles == 0) {
2649 /* find all sources, but don't use this snapshot because the
2650 state file on disk still references sources we may have already
2654 find_all_sources_across_snapshots (all_sources, true);
2656 /* add our current source list
2659 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2660 boost::shared_ptr<FileSource> fs;
2662 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2663 all_sources.insert (fs->path());
2667 char tmppath1[PATH_MAX+1];
2668 char tmppath2[PATH_MAX+1];
2670 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2675 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2677 if (realpath(spath.c_str(), tmppath1) == 0) {
2678 error << string_compose (_("Cannot expand path %1 (%2)"),
2679 spath, strerror (errno)) << endmsg;
2683 if (realpath((*i).c_str(), tmppath2) == 0) {
2684 error << string_compose (_("Cannot expand path %1 (%2)"),
2685 (*i), strerror (errno)) << endmsg;
2689 if (strcmp(tmppath1, tmppath2) == 0) {
2696 unused.push_back (spath);
2700 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2702 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2703 struct stat statbuf;
2705 rep.paths.push_back (*x);
2706 if (stat ((*x).c_str(), &statbuf) == 0) {
2707 rep.space += statbuf.st_size;
2712 /* don't move the file across filesystems, just
2713 stick it in the `dead_sound_dir_name' directory
2714 on whichever filesystem it was already on.
2717 if ((*x).find ("/sounds/") != string::npos) {
2719 /* old school, go up 1 level */
2721 newpath = Glib::path_get_dirname (*x); // "sounds"
2722 newpath = Glib::path_get_dirname (newpath); // "session-name"
2726 /* new school, go up 4 levels */
2728 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2729 newpath = Glib::path_get_dirname (newpath); // "session-name"
2730 newpath = Glib::path_get_dirname (newpath); // "interchange"
2731 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2734 newpath = Glib::build_filename (newpath, dead_sound_dir_name);
2736 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2737 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2741 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2743 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2745 /* the new path already exists, try versioning */
2747 char buf[PATH_MAX+1];
2751 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2754 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2755 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2759 if (version == 999) {
2760 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2764 newpath = newpath_v;
2769 /* it doesn't exist, or we can't read it or something */
2773 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2774 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2775 (*x), newpath, strerror (errno))
2780 /* see if there an easy to find peakfile for this file, and remove it.
2783 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2784 peakpath += peakfile_suffix;
2786 if (access (peakpath.c_str(), W_OK) == 0) {
2787 if (::unlink (peakpath.c_str()) != 0) {
2788 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2789 peakpath, _path, strerror (errno))
2791 /* try to back out */
2792 rename (newpath.c_str(), _path.c_str());
2800 /* dump the history list */
2804 /* save state so we don't end up a session file
2805 referring to non-existent sources.
2811 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2817 Session::cleanup_trash_sources (CleanupReport& rep)
2819 // FIXME: needs adaptation for MIDI
2821 vector<space_and_path>::iterator i;
2822 string dead_sound_dir;
2827 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2829 dead_sound_dir = (*i).path;
2830 dead_sound_dir += dead_sound_dir_name;
2832 clear_directory (dead_sound_dir, &rep.space, &rep.paths);
2839 Session::cleanup_stubfiles ()
2841 vector<space_and_path>::iterator i;
2843 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2846 string lname = legalize_for_path (_name);
2850 /* XXX this is a hack caused by semantic conflicts
2851 between space_and_path and the SessionDirectory concept.
2854 v.push_back ((*i).path);
2855 v.push_back ("interchange");
2856 v.push_back (lname);
2857 v.push_back ("audiofiles");
2858 v.push_back (stub_dir_name);
2860 dir = Glib::build_filename (v);
2862 clear_directory (dir);
2865 v.push_back ((*i).path);
2866 v.push_back ("interchange");
2867 v.push_back (lname);
2868 v.push_back ("midifiles");
2869 v.push_back (stub_dir_name);
2871 dir = Glib::build_filename (v);
2873 clear_directory (dir);
2878 Session::set_dirty ()
2880 bool was_dirty = dirty();
2882 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2886 DirtyChanged(); /* EMIT SIGNAL */
2892 Session::set_clean ()
2894 bool was_dirty = dirty();
2896 _state_of_the_state = Clean;
2900 DirtyChanged(); /* EMIT SIGNAL */
2905 Session::set_deletion_in_progress ()
2907 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2911 Session::clear_deletion_in_progress ()
2913 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2917 Session::add_controllable (boost::shared_ptr<Controllable> c)
2919 /* this adds a controllable to the list managed by the Session.
2920 this is a subset of those managed by the Controllable class
2921 itself, and represents the only ones whose state will be saved
2922 as part of the session.
2925 Glib::Mutex::Lock lm (controllables_lock);
2926 controllables.insert (c);
2929 struct null_deleter { void operator()(void const *) const {} };
2932 Session::remove_controllable (Controllable* c)
2934 if (_state_of_the_state | Deletion) {
2938 Glib::Mutex::Lock lm (controllables_lock);
2940 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2942 if (x != controllables.end()) {
2943 controllables.erase (x);
2947 boost::shared_ptr<Controllable>
2948 Session::controllable_by_id (const PBD::ID& id)
2950 Glib::Mutex::Lock lm (controllables_lock);
2952 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2953 if ((*i)->id() == id) {
2958 return boost::shared_ptr<Controllable>();
2961 boost::shared_ptr<Controllable>
2962 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2964 boost::shared_ptr<Controllable> c;
2965 boost::shared_ptr<Route> r;
2967 switch (desc.top_level_type()) {
2968 case ControllableDescriptor::NamedRoute:
2970 std::string str = desc.top_level_name();
2971 if (str == "master") {
2973 } else if (str == "control" || str == "listen") {
2976 r = route_by_name (desc.top_level_name());
2981 case ControllableDescriptor::RemoteControlID:
2982 r = route_by_remote_id (desc.rid());
2990 switch (desc.subtype()) {
2991 case ControllableDescriptor::Gain:
2992 c = r->gain_control ();
2995 case ControllableDescriptor::Solo:
2996 c = r->solo_control();
2999 case ControllableDescriptor::Mute:
3000 c = r->mute_control();
3003 case ControllableDescriptor::Recenable:
3005 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
3008 c = t->rec_enable_control ();
3013 case ControllableDescriptor::PanDirection:
3015 c = r->pannable()->pan_azimuth_control;
3019 case ControllableDescriptor::PanWidth:
3021 c = r->pannable()->pan_width_control;
3025 case ControllableDescriptor::PanElevation:
3027 c = r->pannable()->pan_elevation_control;
3031 case ControllableDescriptor::Balance:
3032 /* XXX simple pan control */
3035 case ControllableDescriptor::PluginParameter:
3037 uint32_t plugin = desc.target (0);
3038 uint32_t parameter_index = desc.target (1);
3040 /* revert to zero based counting */
3046 if (parameter_index > 0) {
3050 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3053 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3054 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3059 case ControllableDescriptor::SendGain:
3061 uint32_t send = desc.target (0);
3063 /* revert to zero-based counting */
3069 boost::shared_ptr<Processor> p = r->nth_send (send);
3072 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3073 boost::shared_ptr<Amp> a = s->amp();
3076 c = s->amp()->gain_control();
3083 /* relax and return a null pointer */
3091 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3094 Stateful::add_instant_xml (node, _path);
3097 if (write_to_config) {
3098 Config->add_instant_xml (node);
3103 Session::instant_xml (const string& node_name)
3105 return Stateful::instant_xml (node_name, _path);
3109 Session::save_history (string snapshot_name)
3117 if (snapshot_name.empty()) {
3118 snapshot_name = _current_snapshot_name;
3121 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3122 const string backup_filename = history_filename + backup_suffix;
3123 const sys::path xml_path = _session_dir->root_path() / history_filename;
3124 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3126 if (sys::exists (xml_path)) {
3129 sys::rename (xml_path, backup_path);
3131 catch (const sys::filesystem_error& err)
3133 error << _("could not backup old history file, current history not saved") << endmsg;
3138 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3142 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3144 if (!tree.write (xml_path.to_string()))
3146 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3150 sys::remove (xml_path);
3151 sys::rename (backup_path, xml_path);
3153 catch (const sys::filesystem_error& err)
3155 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3156 backup_path.to_string(), err.what()) << endmsg;
3166 Session::restore_history (string snapshot_name)
3170 if (snapshot_name.empty()) {
3171 snapshot_name = _current_snapshot_name;
3174 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3175 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3177 info << "Loading history from " << xml_path.to_string() << endmsg;
3179 if (!sys::exists (xml_path)) {
3180 info << string_compose (_("%1: no history file \"%2\" for this session."),
3181 _name, xml_path.to_string()) << endmsg;
3185 if (!tree.read (xml_path.to_string())) {
3186 error << string_compose (_("Could not understand session history file \"%1\""),
3187 xml_path.to_string()) << endmsg;
3194 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3197 UndoTransaction* ut = new UndoTransaction ();
3200 ut->set_name(t->property("name")->value());
3201 stringstream ss(t->property("tv-sec")->value());
3203 ss.str(t->property("tv-usec")->value());
3205 ut->set_timestamp(tv);
3207 for (XMLNodeConstIterator child_it = t->children().begin();
3208 child_it != t->children().end(); child_it++)
3210 XMLNode *n = *child_it;
3213 if (n->name() == "MementoCommand" ||
3214 n->name() == "MementoUndoCommand" ||
3215 n->name() == "MementoRedoCommand") {
3217 if ((c = memento_command_factory(n))) {
3221 } else if (n->name() == "NoteDiffCommand") {
3222 PBD::ID id (n->property("midi-source")->value());
3223 boost::shared_ptr<MidiSource> midi_source =
3224 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3226 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3228 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3231 } else if (n->name() == "SysExDiffCommand") {
3233 PBD::ID id (n->property("midi-source")->value());
3234 boost::shared_ptr<MidiSource> midi_source =
3235 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3237 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3239 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3242 } else if (n->name() == "PatchChangeDiffCommand") {
3244 PBD::ID id (n->property("midi-source")->value());
3245 boost::shared_ptr<MidiSource> midi_source =
3246 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3248 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3250 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3253 } else if (n->name() == "StatefulDiffCommand") {
3254 if ((c = stateful_diff_command_factory (n))) {
3255 ut->add_command (c);
3258 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3269 Session::config_changed (std::string p, bool ours)
3275 if (p == "seamless-loop") {
3277 } else if (p == "rf-speed") {
3279 } else if (p == "auto-loop") {
3281 } else if (p == "auto-input") {
3283 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3284 /* auto-input only makes a difference if we're rolling */
3286 boost::shared_ptr<RouteList> rl = routes.reader ();
3287 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3288 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3289 if (tr && tr->record_enabled ()) {
3290 tr->monitor_input (!config.get_auto_input());
3295 } else if (p == "punch-in") {
3299 if ((location = _locations->auto_punch_location()) != 0) {
3301 if (config.get_punch_in ()) {
3302 replace_event (SessionEvent::PunchIn, location->start());
3304 remove_event (location->start(), SessionEvent::PunchIn);
3308 } else if (p == "punch-out") {
3312 if ((location = _locations->auto_punch_location()) != 0) {
3314 if (config.get_punch_out()) {
3315 replace_event (SessionEvent::PunchOut, location->end());
3317 clear_events (SessionEvent::PunchOut);
3321 } else if (p == "edit-mode") {
3323 Glib::Mutex::Lock lm (playlists->lock);
3325 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3326 (*i)->set_edit_mode (Config->get_edit_mode ());
3329 } else if (p == "use-video-sync") {
3331 waiting_for_sync_offset = config.get_use_video_sync();
3333 } else if (p == "mmc-control") {
3335 //poke_midi_thread ();
3337 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3339 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3341 } else if (p == "mmc-send-id") {
3343 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3345 } else if (p == "midi-control") {
3347 //poke_midi_thread ();
3349 } else if (p == "raid-path") {
3351 setup_raid_path (config.get_raid_path());
3353 } else if (p == "timecode-format") {
3357 } else if (p == "video-pullup") {
3361 } else if (p == "seamless-loop") {
3363 if (play_loop && transport_rolling()) {
3364 // to reset diskstreams etc
3365 request_play_loop (true);
3368 } else if (p == "rf-speed") {
3370 cumulative_rf_motion = 0;
3373 } else if (p == "click-sound") {
3375 setup_click_sounds (1);
3377 } else if (p == "click-emphasis-sound") {
3379 setup_click_sounds (-1);
3381 } else if (p == "clicking") {
3383 if (Config->get_clicking()) {
3384 if (_click_io && click_data) { // don't require emphasis data
3391 } else if (p == "send-mtc") {
3393 if (Config->get_send_mtc ()) {
3394 /* mark us ready to send */
3395 next_quarter_frame_to_send = 0;
3398 } else if (p == "send-mmc") {
3400 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3402 } else if (p == "midi-feedback") {
3404 session_midi_feedback = Config->get_midi_feedback();
3406 } else if (p == "jack-time-master") {
3408 engine().reset_timebase ();
3410 } else if (p == "native-file-header-format") {
3412 if (!first_file_header_format_reset) {
3413 reset_native_file_format ();
3416 first_file_header_format_reset = false;
3418 } else if (p == "native-file-data-format") {
3420 if (!first_file_data_format_reset) {
3421 reset_native_file_format ();
3424 first_file_data_format_reset = false;
3426 } else if (p == "external-sync") {
3427 if (!config.get_external_sync()) {
3428 drop_sync_source ();
3430 switch_to_sync_source (config.get_sync_source());
3432 } else if (p == "remote-model") {
3433 set_remote_control_ids ();
3434 } else if (p == "denormal-model") {
3436 } else if (p == "history-depth") {
3437 set_history_depth (Config->get_history_depth());
3438 } else if (p == "sync-all-route-ordering") {
3439 sync_order_keys ("session");
3440 } else if (p == "initial-program-change") {
3442 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3445 buf[0] = MIDI::program; // channel zero by default
3446 buf[1] = (Config->get_initial_program_change() & 0x7f);
3448 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3450 } else if (p == "solo-mute-override") {
3451 // catch_up_on_solo_mute_override ();
3452 } else if (p == "listen-position") {
3453 listen_position_changed ();
3454 } else if (p == "solo-control-is-listen-control") {
3455 solo_control_mode_changed ();
3456 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3457 last_timecode_valid = false;
3464 Session::set_history_depth (uint32_t d)
3466 _history.set_depth (d);
3470 Session::load_diskstreams_2X (XMLNode const & node, int)
3473 XMLNodeConstIterator citer;
3475 clist = node.children();
3477 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3480 /* diskstreams added automatically by DiskstreamCreated handler */
3481 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3482 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3483 _diskstreams_2X.push_back (dsp);
3485 error << _("Session: unknown diskstream type in XML") << endmsg;
3489 catch (failed_constructor& err) {
3490 error << _("Session: could not load diskstream via XML state") << endmsg;
3498 /** Connect things to the MMC object */
3500 Session::setup_midi_machine_control ()
3502 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3504 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3505 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3506 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3507 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3508 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3509 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3510 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3511 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3512 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3513 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3514 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3515 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3516 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3518 /* also handle MIDI SPP because its so common */
3520 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3521 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3522 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));