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/panner.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;
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 */
264 average_slave_delta = 1800; // !!! why 1800 ????
265 have_first_delta_accumulator = false;
266 delta_accumulator_cnt = 0;
267 _slave_state = Stopped;
269 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
271 /* These are all static "per-class" signals */
273 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
274 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
275 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
276 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
277 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
279 /* stop IO objects from doing stuff until we're ready for them */
281 Delivery::disable_panners ();
282 IO::disable_connecting ();
286 Session::second_stage_init ()
288 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
291 if (load_state (_current_snapshot_name)) {
294 cleanup_stubfiles ();
297 if (_butler->start_thread()) {
301 if (start_midi_thread ()) {
305 setup_midi_machine_control ();
307 // set_state() will call setup_raid_path(), but if it's a new session we need
308 // to call setup_raid_path() here.
311 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
315 setup_raid_path(_path);
318 /* we can't save till after ::when_engine_running() is called,
319 because otherwise we save state with no connections made.
320 therefore, we reset _state_of_the_state because ::set_state()
321 will have cleared it.
323 we also have to include Loading so that any events that get
324 generated between here and the end of ::when_engine_running()
325 will be processed directly rather than queued.
328 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
330 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
331 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
332 setup_click_sounds (0);
333 setup_midi_control ();
335 /* Pay attention ... */
337 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
338 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
341 when_engine_running ();
344 /* handle this one in a different way than all others, so that its clear what happened */
346 catch (AudioEngine::PortRegistrationFailure& err) {
347 error << err.what() << endmsg;
355 BootMessage (_("Reset Remote Controls"));
357 send_full_time_code (0);
358 _engine.transport_locate (0);
360 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
361 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
363 MidiClockTicker::instance().set_session (this);
364 MIDI::Name::MidiPatchManager::instance().set_session (this);
366 /* initial program change will be delivered later; see ::config_changed() */
368 BootMessage (_("Reset Control Protocols"));
370 ControlProtocolManager::instance().set_session (this);
372 _state_of_the_state = Clean;
374 Port::set_connecting_blocked (false);
376 DirtyChanged (); /* EMIT SIGNAL */
378 if (state_was_pending) {
379 save_state (_current_snapshot_name);
380 remove_pending_capture_state ();
381 state_was_pending = false;
384 BootMessage (_("Session loading complete"));
390 Session::raid_path () const
392 SearchPath raid_search_path;
394 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
395 raid_search_path += sys::path((*i).path);
398 return raid_search_path.to_string ();
402 Session::setup_raid_path (string path)
411 session_dirs.clear ();
413 SearchPath search_path(path);
414 SearchPath sound_search_path;
415 SearchPath midi_search_path;
417 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
418 sp.path = (*i).to_string ();
419 sp.blocks = 0; // not needed
420 session_dirs.push_back (sp);
422 SessionDirectory sdir(sp.path);
424 sound_search_path += sdir.sound_path ();
425 midi_search_path += sdir.midi_path ();
428 // reset the round-robin soundfile path thingie
429 last_rr_session_dir = session_dirs.begin();
433 Session::path_is_within_session (const std::string& path)
435 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
436 if (path.find ((*i).path) == 0) {
444 Session::ensure_subdirs ()
448 dir = session_directory().peak_path().to_string();
450 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
451 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
455 dir = session_directory().sound_path().to_string();
457 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
458 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
462 dir = session_directory().sound_stub_path().to_string();
464 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
465 error << string_compose(_("Session: cannot create session stub sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
469 dir = session_directory().midi_path().to_string();
471 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
472 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
476 dir = session_directory().midi_stub_path().to_string();
478 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
479 error << string_compose(_("Session: cannot create session stub midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483 dir = session_directory().dead_sound_path().to_string();
485 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
486 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
490 dir = session_directory().export_path().to_string();
492 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
493 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
497 dir = analysis_dir ();
499 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
500 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
504 dir = plugins_dir ();
506 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
507 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
514 /** Caller must not hold process lock */
516 Session::create (const string& mix_template, BusProfile* bus_profile)
519 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
520 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
524 if (ensure_subdirs ()) {
528 if (!mix_template.empty()) {
529 std::string in_path = mix_template;
531 ifstream in(in_path.c_str());
534 string out_path = _path;
536 out_path += statefile_suffix;
538 ofstream out(out_path.c_str());
546 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
552 error << string_compose (_("Could not open mix 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 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
581 boost_debug_shared_ptr_mark_interesting (rt, "Route");
582 boost::shared_ptr<Route> r (rt);
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 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
598 boost_debug_shared_ptr_mark_interesting (rt, "Route");
599 boost::shared_ptr<Route> r (rt);
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);
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 snapshot_name Snapshot name.
666 Session::rename_state (string old_name, string new_name)
668 if (old_name == _current_snapshot_name || old_name == _name) {
669 /* refuse to rename the current snapshot or the "main" one */
673 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
674 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
676 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
677 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
681 sys::rename (old_xml_path, new_xml_path);
683 catch (const sys::filesystem_error& err)
685 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
686 old_name, new_name, err.what()) << endmsg;
690 /** Remove a state file.
691 * @param snapshot_name Snapshot name.
694 Session::remove_state (string snapshot_name)
696 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
697 // refuse to remove the current snapshot or the "main" one
701 sys::path xml_path(_session_dir->root_path());
703 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
705 if (!create_backup_file (xml_path)) {
706 // don't remove it if a backup can't be made
707 // create_backup_file will log the error.
712 sys::remove (xml_path);
715 #ifdef HAVE_JACK_SESSION
717 Session::jack_session_event (jack_session_event_t * event)
721 struct tm local_time;
724 localtime_r (&n, &local_time);
725 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
727 if (event->type == JackSessionSaveTemplate)
729 if (save_template( timebuf )) {
730 event->flags = JackSessionSaveError;
732 string cmd ("ardour3 -P -U ");
733 cmd += event->client_uuid;
737 event->command_line = strdup (cmd.c_str());
742 if (save_state (timebuf)) {
743 event->flags = JackSessionSaveError;
745 sys::path xml_path (_session_dir->root_path());
746 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
748 string cmd ("ardour3 -P -U ");
749 cmd += event->client_uuid;
751 cmd += xml_path.to_string();
754 event->command_line = strdup (cmd.c_str());
758 jack_session_reply (_engine.jack(), event);
760 if (event->type == JackSessionSaveAndQuit) {
761 Quit (); /* EMIT SIGNAL */
764 jack_session_event_free( event );
769 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
772 sys::path xml_path(_session_dir->root_path());
774 if (!_writable || (_state_of_the_state & CannotSave)) {
778 if (!_engine.connected ()) {
779 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
785 /* tell sources we're saving first, in case they write out to a new file
786 * which should be saved with the state rather than the old one */
787 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
788 i->second->session_saved();
791 tree.set_root (&get_state());
793 if (snapshot_name.empty()) {
794 snapshot_name = _current_snapshot_name;
795 } else if (switch_to_snapshot) {
796 _current_snapshot_name = snapshot_name;
801 /* proper save: use statefile_suffix (.ardour in English) */
803 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
805 /* make a backup copy of the old file */
807 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
808 // create_backup_file will log the error
814 /* pending save: use pending_suffix (.pending in English) */
815 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
818 sys::path tmp_path(_session_dir->root_path());
820 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
822 // cerr << "actually writing state to " << xml_path.to_string() << endl;
824 if (!tree.write (tmp_path.to_string())) {
825 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
826 sys::remove (tmp_path);
831 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
832 error << string_compose (_("could not rename temporary session file %1 to %2"),
833 tmp_path.to_string(), xml_path.to_string()) << endmsg;
834 sys::remove (tmp_path);
841 save_history (snapshot_name);
843 bool was_dirty = dirty();
845 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
848 DirtyChanged (); /* EMIT SIGNAL */
851 StateSaved (snapshot_name); /* EMIT SIGNAL */
858 Session::restore_state (string snapshot_name)
860 if (load_state (snapshot_name) == 0) {
861 set_state (*state_tree->root(), Stateful::loading_state_version);
868 Session::load_state (string snapshot_name)
873 state_was_pending = false;
875 /* check for leftover pending state from a crashed capture attempt */
877 sys::path xmlpath(_session_dir->root_path());
878 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
880 if (sys::exists (xmlpath)) {
882 /* there is pending state from a crashed capture attempt */
884 boost::optional<int> r = AskAboutPendingState();
885 if (r.get_value_or (1)) {
886 state_was_pending = true;
890 if (!state_was_pending) {
891 xmlpath = _session_dir->root_path();
892 xmlpath /= snapshot_name;
895 if (!sys::exists (xmlpath)) {
896 xmlpath = _session_dir->root_path();
897 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
898 if (!sys::exists (xmlpath)) {
899 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
904 state_tree = new XMLTree;
908 /* writable() really reflects the whole folder, but if for any
909 reason the session state file can't be written to, still
913 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
917 if (!state_tree->read (xmlpath.to_string())) {
918 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
924 XMLNode& root (*state_tree->root());
926 if (root.name() != X_("Session")) {
927 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
933 const XMLProperty* prop;
935 if ((prop = root.property ("version")) == 0) {
936 /* no version implies very old version of Ardour */
937 Stateful::loading_state_version = 1000;
943 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
944 Stateful::loading_state_version = (major * 1000) + minor;
947 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
949 sys::path backup_path(_session_dir->root_path());
951 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
953 // only create a backup once
954 if (sys::exists (backup_path)) {
958 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
959 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
964 sys::copy_file (xmlpath, backup_path);
966 catch(sys::filesystem_error& ex)
968 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
969 xmlpath.to_string(), ex.what())
979 Session::load_options (const XMLNode& node)
981 LocaleGuard lg (X_("POSIX"));
982 config.set_variables (node);
993 Session::get_template()
995 /* if we don't disable rec-enable, diskstreams
996 will believe they need to store their capture
997 sources in their state node.
1000 disable_record (false);
1002 return state(false);
1006 Session::state(bool full_state)
1008 XMLNode* node = new XMLNode("Session");
1011 // store libardour version, just in case
1013 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
1014 node->add_property("version", string(buf));
1016 /* store configuration settings */
1020 node->add_property ("name", _name);
1021 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1022 node->add_property ("sample-rate", buf);
1024 if (session_dirs.size() > 1) {
1028 vector<space_and_path>::iterator i = session_dirs.begin();
1029 vector<space_and_path>::iterator next;
1031 ++i; /* skip the first one */
1035 while (i != session_dirs.end()) {
1039 if (next != session_dirs.end()) {
1049 child = node->add_child ("Path");
1050 child->add_content (p);
1054 /* save the ID counter */
1056 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1057 node->add_property ("id-counter", buf);
1059 /* save the event ID counter */
1061 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1062 node->add_property ("event-counter", buf);
1064 /* various options */
1066 node->add_child_nocopy (config.get_variables ());
1068 node->add_child_nocopy (_metadata->get_state());
1070 child = node->add_child ("Sources");
1073 Glib::Mutex::Lock sl (source_lock);
1075 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1077 /* Don't save information about non-destructive file sources that are empty
1078 and unused by any regions.
1081 boost::shared_ptr<FileSource> fs;
1082 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1083 if (!fs->destructive()) {
1084 if (fs->empty() && !fs->used()) {
1090 child->add_child_nocopy (siter->second->get_state());
1094 child = node->add_child ("Regions");
1097 Glib::Mutex::Lock rl (region_lock);
1098 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1099 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1100 boost::shared_ptr<Region> r = i->second;
1101 /* only store regions not attached to playlists */
1102 if (r->playlist() == 0) {
1103 child->add_child_nocopy (r->state ());
1109 node->add_child_nocopy (_locations->get_state());
1111 // for a template, just create a new Locations, populate it
1112 // with the default start and end, and get the state for that.
1113 Locations loc (*this);
1114 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1115 range->set (max_framepos, 0);
1117 node->add_child_nocopy (loc.get_state());
1120 child = node->add_child ("Bundles");
1122 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1123 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1124 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1126 child->add_child_nocopy (b->get_state());
1131 child = node->add_child ("Routes");
1133 boost::shared_ptr<RouteList> r = routes.reader ();
1135 RoutePublicOrderSorter cmp;
1136 RouteList public_order (*r);
1137 public_order.sort (cmp);
1139 /* the sort should have put control outs first */
1142 assert (_monitor_out == public_order.front());
1145 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1146 if (!(*i)->is_hidden()) {
1148 child->add_child_nocopy ((*i)->get_state());
1150 child->add_child_nocopy ((*i)->get_template());
1156 playlists->add_state (node, full_state);
1158 child = node->add_child ("RouteGroups");
1159 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1160 child->add_child_nocopy ((*i)->get_state());
1164 child = node->add_child ("Click");
1165 child->add_child_nocopy (_click_io->state (full_state));
1169 child = node->add_child ("NamedSelections");
1170 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1172 child->add_child_nocopy ((*i)->get_state());
1177 node->add_child_nocopy (_tempo_map->get_state());
1179 node->add_child_nocopy (get_control_protocol_state());
1182 node->add_child_copy (*_extra_xml);
1189 Session::get_control_protocol_state ()
1191 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1192 return cpm.get_state();
1196 Session::set_state (const XMLNode& node, int version)
1200 const XMLProperty* prop;
1203 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1205 if (node.name() != X_("Session")){
1206 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1210 if ((prop = node.property ("version")) != 0) {
1211 version = atoi (prop->value ()) * 1000;
1214 if ((prop = node.property ("name")) != 0) {
1215 _name = prop->value ();
1218 if ((prop = node.property (X_("sample-rate"))) != 0) {
1220 _nominal_frame_rate = atoi (prop->value());
1222 if (_nominal_frame_rate != _current_frame_rate) {
1223 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1224 if (r.get_value_or (0)) {
1230 setup_raid_path(_session_dir->root_path().to_string());
1232 if ((prop = node.property (X_("id-counter"))) != 0) {
1234 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1235 ID::init_counter (x);
1237 /* old sessions used a timebased counter, so fake
1238 the startup ID counter based on a standard
1243 ID::init_counter (now);
1246 if ((prop = node.property (X_("event-counter"))) != 0) {
1247 Evoral::init_event_id_counter (atoi (prop->value()));
1250 IO::disable_connecting ();
1252 /* Object loading order:
1257 MIDI Control // relies on data from Options/Config
1270 if ((child = find_named_node (node, "Extra")) != 0) {
1271 _extra_xml = new XMLNode (*child);
1274 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1275 load_options (*child);
1276 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1277 load_options (*child);
1279 error << _("Session: XML state has no options section") << endmsg;
1282 if (version >= 3000) {
1283 if ((child = find_named_node (node, "Metadata")) == 0) {
1284 warning << _("Session: XML state has no metadata section") << endmsg;
1285 } else if (_metadata->set_state (*child, version)) {
1290 if ((child = find_named_node (node, "Locations")) == 0) {
1291 error << _("Session: XML state has no locations section") << endmsg;
1293 } else if (_locations->set_state (*child, version)) {
1299 if ((location = _locations->auto_loop_location()) != 0) {
1300 set_auto_loop_location (location);
1303 if ((location = _locations->auto_punch_location()) != 0) {
1304 set_auto_punch_location (location);
1307 if ((location = _locations->session_range_location()) != 0) {
1308 delete _session_range_location;
1309 _session_range_location = location;
1312 if (_session_range_location) {
1313 AudioFileSource::set_header_position_offset (_session_range_location->start());
1316 if ((child = find_named_node (node, "Sources")) == 0) {
1317 error << _("Session: XML state has no sources section") << endmsg;
1319 } else if (load_sources (*child)) {
1323 if ((child = find_named_node (node, "Regions")) == 0) {
1324 error << _("Session: XML state has no Regions section") << endmsg;
1326 } else if (load_regions (*child)) {
1330 if ((child = find_named_node (node, "Playlists")) == 0) {
1331 error << _("Session: XML state has no playlists section") << endmsg;
1333 } else if (playlists->load (*this, *child)) {
1337 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1339 } else if (playlists->load_unused (*this, *child)) {
1343 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1344 if (load_named_selections (*child)) {
1349 if (version >= 3000) {
1350 if ((child = find_named_node (node, "Bundles")) == 0) {
1351 warning << _("Session: XML state has no bundles section") << endmsg;
1354 /* We can't load Bundles yet as they need to be able
1355 to convert from port names to Port objects, which can't happen until
1357 _bundle_xml_node = new XMLNode (*child);
1361 if ((child = find_named_node (node, "TempoMap")) == 0) {
1362 error << _("Session: XML state has no Tempo Map section") << endmsg;
1364 } else if (_tempo_map->set_state (*child, version)) {
1368 if (version < 3000) {
1369 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1370 error << _("Session: XML state has no diskstreams section") << endmsg;
1372 } else if (load_diskstreams_2X (*child, version)) {
1377 if ((child = find_named_node (node, "Routes")) == 0) {
1378 error << _("Session: XML state has no routes section") << endmsg;
1380 } else if (load_routes (*child, version)) {
1384 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1385 _diskstreams_2X.clear ();
1387 if (version >= 3000) {
1389 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1390 error << _("Session: XML state has no route groups section") << endmsg;
1392 } else if (load_route_groups (*child, version)) {
1396 } else if (version < 3000) {
1398 if ((child = find_named_node (node, "EditGroups")) == 0) {
1399 error << _("Session: XML state has no edit groups section") << endmsg;
1401 } else if (load_route_groups (*child, version)) {
1405 if ((child = find_named_node (node, "MixGroups")) == 0) {
1406 error << _("Session: XML state has no mix groups section") << endmsg;
1408 } else if (load_route_groups (*child, version)) {
1413 if ((child = find_named_node (node, "Click")) == 0) {
1414 warning << _("Session: XML state has no click section") << endmsg;
1415 } else if (_click_io) {
1416 _click_io->set_state (*child, version);
1419 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1420 ControlProtocolManager::instance().set_protocol_states (*child);
1423 /* here beginneth the second phase ... */
1425 StateReady (); /* EMIT SIGNAL */
1434 Session::load_routes (const XMLNode& node, int version)
1437 XMLNodeConstIterator niter;
1438 RouteList new_routes;
1440 nlist = node.children();
1444 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1446 boost::shared_ptr<Route> route;
1447 if (version < 3000) {
1448 route = XMLRouteFactory_2X (**niter, version);
1450 route = XMLRouteFactory (**niter, version);
1454 error << _("Session: cannot create Route from XML description.") << endmsg;
1458 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1460 new_routes.push_back (route);
1463 add_routes (new_routes, false);
1468 boost::shared_ptr<Route>
1469 Session::XMLRouteFactory (const XMLNode& node, int version)
1471 boost::shared_ptr<Route> ret;
1473 if (node.name() != "Route") {
1477 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1479 DataType type = DataType::AUDIO;
1480 const XMLProperty* prop = node.property("default-type");
1483 type = DataType (prop->value());
1486 assert (type != DataType::NIL);
1492 if (type == DataType::AUDIO) {
1493 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1496 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1499 if (track->init()) {
1504 if (track->set_state (node, version)) {
1509 boost_debug_shared_ptr_mark_interesting (track, "Track");
1513 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1515 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1516 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1526 boost::shared_ptr<Route>
1527 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1529 boost::shared_ptr<Route> ret;
1531 if (node.name() != "Route") {
1535 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1537 ds_prop = node.property (X_("diskstream"));
1540 DataType type = DataType::AUDIO;
1541 const XMLProperty* prop = node.property("default-type");
1544 type = DataType (prop->value());
1547 assert (type != DataType::NIL);
1551 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1552 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1556 if (i == _diskstreams_2X.end()) {
1557 error << _("Could not find diskstream for route") << endmsg;
1558 return boost::shared_ptr<Route> ();
1563 if (type == DataType::AUDIO) {
1564 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1567 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1570 if (track->init()) {
1575 if (track->set_state (node, version)) {
1580 track->set_diskstream (*i);
1582 boost_debug_shared_ptr_mark_interesting (track, "Track");
1586 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1588 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1589 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1600 Session::load_regions (const XMLNode& node)
1603 XMLNodeConstIterator niter;
1604 boost::shared_ptr<Region> region;
1606 nlist = node.children();
1610 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1611 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1612 error << _("Session: cannot create Region from XML description.");
1613 const XMLProperty *name = (**niter).property("name");
1616 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1626 boost::shared_ptr<Region>
1627 Session::XMLRegionFactory (const XMLNode& node, bool full)
1629 const XMLProperty* type = node.property("type");
1633 if (!type || type->value() == "audio") {
1634 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1635 } else if (type->value() == "midi") {
1636 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1639 } catch (failed_constructor& err) {
1640 return boost::shared_ptr<Region> ();
1643 return boost::shared_ptr<Region> ();
1646 boost::shared_ptr<AudioRegion>
1647 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1649 const XMLProperty* prop;
1650 boost::shared_ptr<Source> source;
1651 boost::shared_ptr<AudioSource> as;
1653 SourceList master_sources;
1654 uint32_t nchans = 1;
1657 if (node.name() != X_("Region")) {
1658 return boost::shared_ptr<AudioRegion>();
1661 if ((prop = node.property (X_("channels"))) != 0) {
1662 nchans = atoi (prop->value().c_str());
1665 if ((prop = node.property ("name")) == 0) {
1666 cerr << "no name for this region\n";
1670 if ((prop = node.property (X_("source-0"))) == 0) {
1671 if ((prop = node.property ("source")) == 0) {
1672 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1673 return boost::shared_ptr<AudioRegion>();
1677 PBD::ID s_id (prop->value());
1679 if ((source = source_by_id (s_id)) == 0) {
1680 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1681 return boost::shared_ptr<AudioRegion>();
1684 as = boost::dynamic_pointer_cast<AudioSource>(source);
1686 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1687 return boost::shared_ptr<AudioRegion>();
1690 sources.push_back (as);
1692 /* pickup other channels */
1694 for (uint32_t n=1; n < nchans; ++n) {
1695 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1696 if ((prop = node.property (buf)) != 0) {
1698 PBD::ID id2 (prop->value());
1700 if ((source = source_by_id (id2)) == 0) {
1701 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1702 return boost::shared_ptr<AudioRegion>();
1705 as = boost::dynamic_pointer_cast<AudioSource>(source);
1707 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1708 return boost::shared_ptr<AudioRegion>();
1710 sources.push_back (as);
1714 for (uint32_t n = 0; n < nchans; ++n) {
1715 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1716 if ((prop = node.property (buf)) != 0) {
1718 PBD::ID id2 (prop->value());
1720 if ((source = source_by_id (id2)) == 0) {
1721 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1722 return boost::shared_ptr<AudioRegion>();
1725 as = boost::dynamic_pointer_cast<AudioSource>(source);
1727 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1728 return boost::shared_ptr<AudioRegion>();
1730 master_sources.push_back (as);
1735 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1737 /* a final detail: this is the one and only place that we know how long missing files are */
1739 if (region->whole_file()) {
1740 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1741 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1743 sfp->set_length (region->length());
1748 if (!master_sources.empty()) {
1749 if (master_sources.size() != nchans) {
1750 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1752 region->set_master_sources (master_sources);
1760 catch (failed_constructor& err) {
1761 return boost::shared_ptr<AudioRegion>();
1765 boost::shared_ptr<MidiRegion>
1766 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1768 const XMLProperty* prop;
1769 boost::shared_ptr<Source> source;
1770 boost::shared_ptr<MidiSource> ms;
1773 if (node.name() != X_("Region")) {
1774 return boost::shared_ptr<MidiRegion>();
1777 if ((prop = node.property ("name")) == 0) {
1778 cerr << "no name for this region\n";
1782 if ((prop = node.property (X_("source-0"))) == 0) {
1783 if ((prop = node.property ("source")) == 0) {
1784 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1785 return boost::shared_ptr<MidiRegion>();
1789 PBD::ID s_id (prop->value());
1791 if ((source = source_by_id (s_id)) == 0) {
1792 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1793 return boost::shared_ptr<MidiRegion>();
1796 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1798 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1799 return boost::shared_ptr<MidiRegion>();
1802 sources.push_back (ms);
1805 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1806 /* a final detail: this is the one and only place that we know how long missing files are */
1808 if (region->whole_file()) {
1809 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1810 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1812 sfp->set_length (region->length());
1820 catch (failed_constructor& err) {
1821 return boost::shared_ptr<MidiRegion>();
1826 Session::get_sources_as_xml ()
1829 XMLNode* node = new XMLNode (X_("Sources"));
1830 Glib::Mutex::Lock lm (source_lock);
1832 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1833 node->add_child_nocopy (i->second->get_state());
1840 Session::path_from_region_name (DataType type, string name, string identifier)
1842 char buf[PATH_MAX+1];
1844 SessionDirectory sdir(get_best_session_directory_for_new_source());
1845 sys::path source_dir = ((type == DataType::AUDIO)
1846 ? sdir.sound_path() : sdir.midi_path());
1848 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1850 for (n = 0; n < 999999; ++n) {
1851 if (identifier.length()) {
1852 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1853 identifier.c_str(), n, ext.c_str());
1855 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1859 sys::path source_path = source_dir / buf;
1861 if (!sys::exists (source_path)) {
1862 return source_path.to_string();
1866 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1875 Session::load_sources (const XMLNode& node)
1878 XMLNodeConstIterator niter;
1879 boost::shared_ptr<Source> source;
1881 nlist = node.children();
1885 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1888 if ((source = XMLSourceFactory (**niter)) == 0) {
1889 error << _("Session: cannot create Source from XML description.") << endmsg;
1892 } catch (MissingSource& err) {
1896 if (!no_questions_about_missing_files) {
1897 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1902 switch (user_choice) {
1904 /* user added a new search location, so try again */
1909 /* user asked to quit the entire session load
1914 no_questions_about_missing_files = true;
1918 no_questions_about_missing_files = true;
1923 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1924 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1933 boost::shared_ptr<Source>
1934 Session::XMLSourceFactory (const XMLNode& node)
1936 if (node.name() != "Source") {
1937 return boost::shared_ptr<Source>();
1941 /* note: do peak building in another thread when loading session state */
1942 return SourceFactory::create (*this, node, true);
1945 catch (failed_constructor& err) {
1946 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1947 return boost::shared_ptr<Source>();
1952 Session::save_template (string template_name)
1956 if (_state_of_the_state & CannotSave) {
1960 sys::path user_template_dir(user_template_directory());
1964 sys::create_directories (user_template_dir);
1966 catch(sys::filesystem_error& ex)
1968 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1969 user_template_dir.to_string(), ex.what()) << endmsg;
1973 tree.set_root (&get_template());
1975 sys::path template_file_path(user_template_dir);
1976 template_file_path /= template_name + template_suffix;
1978 if (sys::exists (template_file_path))
1980 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1981 template_file_path.to_string()) << endmsg;
1985 if (!tree.write (template_file_path.to_string())) {
1986 error << _("mix template not saved") << endmsg;
1994 Session::rename_template (string old_name, string new_name)
1996 sys::path old_path (user_template_directory());
1997 old_path /= old_name + template_suffix;
1999 sys::path new_path(user_template_directory());
2000 new_path /= new_name + template_suffix;
2002 if (sys::exists (new_path)) {
2003 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
2004 new_path.to_string()) << endmsg;
2009 sys::rename (old_path, new_path);
2017 Session::delete_template (string name)
2019 sys::path path = user_template_directory();
2020 path /= name + template_suffix;
2031 Session::refresh_disk_space ()
2034 struct statfs statfsbuf;
2035 vector<space_and_path>::iterator i;
2036 Glib::Mutex::Lock lm (space_lock);
2039 /* get freespace on every FS that is part of the session path */
2041 _total_free_4k_blocks = 0;
2043 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2044 statfs ((*i).path.c_str(), &statfsbuf);
2046 scale = statfsbuf.f_bsize/4096.0;
2048 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2049 _total_free_4k_blocks += (*i).blocks;
2055 Session::get_best_session_directory_for_new_source ()
2057 vector<space_and_path>::iterator i;
2058 string result = _session_dir->root_path().to_string();
2060 /* handle common case without system calls */
2062 if (session_dirs.size() == 1) {
2066 /* OK, here's the algorithm we're following here:
2068 We want to select which directory to use for
2069 the next file source to be created. Ideally,
2070 we'd like to use a round-robin process so as to
2071 get maximum performance benefits from splitting
2072 the files across multiple disks.
2074 However, in situations without much diskspace, an
2075 RR approach may end up filling up a filesystem
2076 with new files while others still have space.
2077 Its therefore important to pay some attention to
2078 the freespace in the filesystem holding each
2079 directory as well. However, if we did that by
2080 itself, we'd keep creating new files in the file
2081 system with the most space until it was as full
2082 as all others, thus negating any performance
2083 benefits of this RAID-1 like approach.
2085 So, we use a user-configurable space threshold. If
2086 there are at least 2 filesystems with more than this
2087 much space available, we use RR selection between them.
2088 If not, then we pick the filesystem with the most space.
2090 This gets a good balance between the two
2094 refresh_disk_space ();
2096 int free_enough = 0;
2098 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2099 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2104 if (free_enough >= 2) {
2105 /* use RR selection process, ensuring that the one
2109 i = last_rr_session_dir;
2112 if (++i == session_dirs.end()) {
2113 i = session_dirs.begin();
2116 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2117 if (create_session_directory ((*i).path)) {
2119 last_rr_session_dir = i;
2124 } while (i != last_rr_session_dir);
2128 /* pick FS with the most freespace (and that
2129 seems to actually work ...)
2132 vector<space_and_path> sorted;
2133 space_and_path_ascending_cmp cmp;
2135 sorted = session_dirs;
2136 sort (sorted.begin(), sorted.end(), cmp);
2138 for (i = sorted.begin(); i != sorted.end(); ++i) {
2139 if (create_session_directory ((*i).path)) {
2141 last_rr_session_dir = i;
2151 Session::load_named_selections (const XMLNode& node)
2154 XMLNodeConstIterator niter;
2157 nlist = node.children();
2161 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2163 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2164 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2172 Session::XMLNamedSelectionFactory (const XMLNode& node)
2175 return new NamedSelection (*this, node);
2178 catch (failed_constructor& err) {
2184 Session::automation_dir () const
2186 return Glib::build_filename (_path, "automation");
2190 Session::analysis_dir () const
2192 return Glib::build_filename (_path, "analysis");
2196 Session::plugins_dir () const
2198 return Glib::build_filename (_path, "plugins");
2202 Session::load_bundles (XMLNode const & node)
2204 XMLNodeList nlist = node.children();
2205 XMLNodeConstIterator niter;
2209 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2210 if ((*niter)->name() == "InputBundle") {
2211 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2212 } else if ((*niter)->name() == "OutputBundle") {
2213 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2215 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2224 Session::load_route_groups (const XMLNode& node, int version)
2226 XMLNodeList nlist = node.children();
2227 XMLNodeConstIterator niter;
2231 if (version >= 3000) {
2233 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2234 if ((*niter)->name() == "RouteGroup") {
2235 RouteGroup* rg = new RouteGroup (*this, "");
2236 add_route_group (rg);
2237 rg->set_state (**niter, version);
2241 } else if (version < 3000) {
2243 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2244 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2245 RouteGroup* rg = new RouteGroup (*this, "");
2246 add_route_group (rg);
2247 rg->set_state (**niter, version);
2256 Session::auto_save()
2258 save_state (_current_snapshot_name);
2262 state_file_filter (const string &str, void */*arg*/)
2264 return (str.length() > strlen(statefile_suffix) &&
2265 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2269 bool operator()(const string* a, const string* b) {
2275 remove_end(string* state)
2277 string statename(*state);
2279 string::size_type start,end;
2280 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2281 statename = statename.substr (start+1);
2284 if ((end = statename.rfind(".ardour")) == string::npos) {
2285 end = statename.length();
2288 return new string(statename.substr (0, end));
2292 Session::possible_states (string path)
2294 PathScanner scanner;
2295 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2297 transform(states->begin(), states->end(), states->begin(), remove_end);
2300 sort (states->begin(), states->end(), cmp);
2306 Session::possible_states () const
2308 return possible_states(_path);
2312 Session::add_route_group (RouteGroup* g)
2314 _route_groups.push_back (g);
2315 route_group_added (g); /* EMIT SIGNAL */
2317 g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2318 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2324 Session::remove_route_group (RouteGroup& rg)
2326 list<RouteGroup*>::iterator i;
2328 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2329 _route_groups.erase (i);
2332 route_group_removed (); /* EMIT SIGNAL */
2338 Session::route_group_by_name (string name)
2340 list<RouteGroup *>::iterator i;
2342 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2343 if ((*i)->name() == name) {
2351 Session::all_route_group() const
2353 return *_all_route_group;
2357 Session::add_commands (vector<Command*> const & cmds)
2359 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2365 Session::begin_reversible_command (const string& name)
2367 /* If nested begin/commit pairs are used, we create just one UndoTransaction
2368 to hold all the commands that are committed. This keeps the order of
2369 commands correct in the history.
2372 if (_current_trans == 0) {
2373 /* start a new transaction */
2374 assert (_current_trans_depth == 0);
2375 _current_trans = new UndoTransaction();
2376 _current_trans->set_name (name);
2378 /* use the existing transaction */
2379 ++_current_trans_depth;
2384 Session::commit_reversible_command (Command *cmd)
2386 assert (_current_trans);
2387 assert (_current_trans_depth > 0);
2392 _current_trans->add_command (cmd);
2395 --_current_trans_depth;
2397 if (_current_trans_depth > 0) {
2398 /* the transaction we're committing is not the top-level one */
2402 if (_current_trans->empty()) {
2403 /* no commands were added to the transaction, so just get rid of it */
2404 delete _current_trans;
2409 gettimeofday (&now, 0);
2410 _current_trans->set_timestamp (now);
2412 _history.add (_current_trans);
2417 accept_all_non_peak_files (const string& path, void */*arg*/)
2419 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2423 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2427 accept_all_state_files (const string& path, void */*arg*/)
2429 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2433 Session::find_all_sources (string path, set<string>& result)
2438 if (!tree.read (path)) {
2442 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2447 XMLNodeConstIterator niter;
2449 nlist = node->children();
2453 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2457 if ((prop = (*niter)->property (X_("type"))) == 0) {
2461 DataType type (prop->value());
2463 if ((prop = (*niter)->property (X_("name"))) == 0) {
2467 if (Glib::path_is_absolute (prop->value())) {
2468 /* external file, ignore */
2476 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2477 result.insert (found_path);
2485 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2487 PathScanner scanner;
2488 vector<string*>* state_files;
2490 string this_snapshot_path;
2496 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2497 ripped = ripped.substr (0, ripped.length() - 1);
2500 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2502 if (state_files == 0) {
2507 this_snapshot_path = _path;
2508 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2509 this_snapshot_path += statefile_suffix;
2511 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2513 if (exclude_this_snapshot && **i == this_snapshot_path) {
2517 if (find_all_sources (**i, result) < 0) {
2525 struct RegionCounter {
2526 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2527 AudioSourceList::iterator iter;
2528 boost::shared_ptr<Region> region;
2531 RegionCounter() : count (0) {}
2535 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2537 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2538 return r.get_value_or (1);
2542 Session::cleanup_sources (CleanupReport& rep)
2544 // FIXME: needs adaptation to midi
2546 vector<boost::shared_ptr<Source> > dead_sources;
2547 PathScanner scanner;
2549 vector<space_and_path>::iterator i;
2550 vector<space_and_path>::iterator nexti;
2551 vector<string*>* soundfiles;
2552 vector<string> unused;
2553 set<string> all_sources;
2558 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2560 /* step 1: consider deleting all unused playlists */
2562 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2567 /* step 2: find all un-used sources */
2572 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2574 SourceMap::iterator tmp;
2579 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2583 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2584 dead_sources.push_back (i->second);
2585 i->second->drop_references ();
2591 /* build a list of all the possible sound directories for the session */
2593 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2598 SessionDirectory sdir ((*i).path);
2599 sound_path += sdir.sound_path().to_string();
2601 if (nexti != session_dirs.end()) {
2608 /* now do the same thing for the files that ended up in the sounds dir(s)
2609 but are not referenced as sources in any snapshot.
2612 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2614 if (soundfiles == 0) {
2618 /* find all sources, but don't use this snapshot because the
2619 state file on disk still references sources we may have already
2623 find_all_sources_across_snapshots (all_sources, true);
2625 /* add our current source list
2628 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2629 boost::shared_ptr<FileSource> fs;
2631 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2632 all_sources.insert (fs->path());
2636 char tmppath1[PATH_MAX+1];
2637 char tmppath2[PATH_MAX+1];
2639 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2644 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2646 if (realpath(spath.c_str(), tmppath1) == 0) {
2647 error << string_compose (_("Cannot expand path %1 (%2)"),
2648 spath, strerror (errno)) << endmsg;
2652 if (realpath((*i).c_str(), tmppath2) == 0) {
2653 error << string_compose (_("Cannot expand path %1 (%2)"),
2654 (*i), strerror (errno)) << endmsg;
2658 if (strcmp(tmppath1, tmppath2) == 0) {
2665 unused.push_back (spath);
2669 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2671 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2672 struct stat statbuf;
2674 rep.paths.push_back (*x);
2675 if (stat ((*x).c_str(), &statbuf) == 0) {
2676 rep.space += statbuf.st_size;
2681 /* don't move the file across filesystems, just
2682 stick it in the `dead_sound_dir_name' directory
2683 on whichever filesystem it was already on.
2686 if ((*x).find ("/sounds/") != string::npos) {
2688 /* old school, go up 1 level */
2690 newpath = Glib::path_get_dirname (*x); // "sounds"
2691 newpath = Glib::path_get_dirname (newpath); // "session-name"
2695 /* new school, go up 4 levels */
2697 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2698 newpath = Glib::path_get_dirname (newpath); // "session-name"
2699 newpath = Glib::path_get_dirname (newpath); // "interchange"
2700 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2703 newpath = Glib::build_filename (newpath, dead_sound_dir_name);
2705 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2706 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2710 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2712 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2714 /* the new path already exists, try versioning */
2716 char buf[PATH_MAX+1];
2720 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2723 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2724 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2728 if (version == 999) {
2729 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2733 newpath = newpath_v;
2738 /* it doesn't exist, or we can't read it or something */
2742 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2743 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2744 (*x), newpath, strerror (errno))
2749 /* see if there an easy to find peakfile for this file, and remove it.
2752 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2753 peakpath += peakfile_suffix;
2755 if (access (peakpath.c_str(), W_OK) == 0) {
2756 if (::unlink (peakpath.c_str()) != 0) {
2757 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2758 peakpath, _path, strerror (errno))
2760 /* try to back out */
2761 rename (newpath.c_str(), _path.c_str());
2769 /* dump the history list */
2773 /* save state so we don't end up a session file
2774 referring to non-existent sources.
2780 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2786 Session::cleanup_trash_sources (CleanupReport& rep)
2788 // FIXME: needs adaptation for MIDI
2790 vector<space_and_path>::iterator i;
2791 string dead_sound_dir;
2796 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2798 dead_sound_dir = (*i).path;
2799 dead_sound_dir += dead_sound_dir_name;
2801 clear_directory (dead_sound_dir, &rep.space, &rep.paths);
2808 Session::cleanup_stubfiles ()
2810 vector<space_and_path>::iterator i;
2812 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2815 string lname = legalize_for_path (_name);
2819 /* XXX this is a hack caused by semantic conflicts
2820 between space_and_path and the SessionDirectory concept.
2823 v.push_back ((*i).path);
2824 v.push_back ("interchange");
2825 v.push_back (lname);
2826 v.push_back ("audiofiles");
2827 v.push_back (stub_dir_name);
2829 dir = Glib::build_filename (v);
2831 clear_directory (dir);
2834 v.push_back ((*i).path);
2835 v.push_back ("interchange");
2836 v.push_back (lname);
2837 v.push_back ("midifiles");
2838 v.push_back (stub_dir_name);
2840 dir = Glib::build_filename (v);
2842 clear_directory (dir);
2847 Session::set_dirty ()
2849 bool was_dirty = dirty();
2851 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2855 DirtyChanged(); /* EMIT SIGNAL */
2861 Session::set_clean ()
2863 bool was_dirty = dirty();
2865 _state_of_the_state = Clean;
2869 DirtyChanged(); /* EMIT SIGNAL */
2874 Session::set_deletion_in_progress ()
2876 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2880 Session::clear_deletion_in_progress ()
2882 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2886 Session::add_controllable (boost::shared_ptr<Controllable> c)
2888 /* this adds a controllable to the list managed by the Session.
2889 this is a subset of those managed by the Controllable class
2890 itself, and represents the only ones whose state will be saved
2891 as part of the session.
2894 Glib::Mutex::Lock lm (controllables_lock);
2895 controllables.insert (c);
2898 struct null_deleter { void operator()(void const *) const {} };
2901 Session::remove_controllable (Controllable* c)
2903 if (_state_of_the_state | Deletion) {
2907 Glib::Mutex::Lock lm (controllables_lock);
2909 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2911 if (x != controllables.end()) {
2912 controllables.erase (x);
2916 boost::shared_ptr<Controllable>
2917 Session::controllable_by_id (const PBD::ID& id)
2919 Glib::Mutex::Lock lm (controllables_lock);
2921 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2922 if ((*i)->id() == id) {
2927 return boost::shared_ptr<Controllable>();
2930 boost::shared_ptr<Controllable>
2931 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2933 boost::shared_ptr<Controllable> c;
2934 boost::shared_ptr<Route> r;
2936 switch (desc.top_level_type()) {
2937 case ControllableDescriptor::NamedRoute:
2939 std::string str = desc.top_level_name();
2940 if (str == "master") {
2942 } else if (str == "control" || str == "listen") {
2945 r = route_by_name (desc.top_level_name());
2950 case ControllableDescriptor::RemoteControlID:
2951 r = route_by_remote_id (desc.rid());
2959 switch (desc.subtype()) {
2960 case ControllableDescriptor::Gain:
2961 c = r->gain_control ();
2964 case ControllableDescriptor::Solo:
2965 c = r->solo_control();
2968 case ControllableDescriptor::Mute:
2969 c = r->mute_control();
2972 case ControllableDescriptor::Recenable:
2974 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2977 c = t->rec_enable_control ();
2982 case ControllableDescriptor::PanDirection:
2984 boost::shared_ptr<Panner> p = r->panner();
2986 c = p->direction_control();
2991 case ControllableDescriptor::PanWidth:
2993 boost::shared_ptr<Panner> p = r->panner();
2995 c = p->width_control();
3000 case ControllableDescriptor::Balance:
3001 /* XXX simple pan control */
3004 case ControllableDescriptor::PluginParameter:
3006 uint32_t plugin = desc.target (0);
3007 uint32_t parameter_index = desc.target (1);
3009 /* revert to zero based counting */
3015 if (parameter_index > 0) {
3019 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3022 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3023 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3028 case ControllableDescriptor::SendGain:
3030 uint32_t send = desc.target (0);
3032 /* revert to zero-based counting */
3038 boost::shared_ptr<Processor> p = r->nth_send (send);
3041 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3042 boost::shared_ptr<Amp> a = s->amp();
3045 c = s->amp()->gain_control();
3052 /* relax and return a null pointer */
3060 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3063 Stateful::add_instant_xml (node, _path);
3066 if (write_to_config) {
3067 Config->add_instant_xml (node);
3072 Session::instant_xml (const string& node_name)
3074 return Stateful::instant_xml (node_name, _path);
3078 Session::save_history (string snapshot_name)
3086 if (snapshot_name.empty()) {
3087 snapshot_name = _current_snapshot_name;
3090 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3091 const string backup_filename = history_filename + backup_suffix;
3092 const sys::path xml_path = _session_dir->root_path() / history_filename;
3093 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3095 if (sys::exists (xml_path)) {
3098 sys::rename (xml_path, backup_path);
3100 catch (const sys::filesystem_error& err)
3102 error << _("could not backup old history file, current history not saved") << endmsg;
3107 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3111 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3113 if (!tree.write (xml_path.to_string()))
3115 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3119 sys::remove (xml_path);
3120 sys::rename (backup_path, xml_path);
3122 catch (const sys::filesystem_error& err)
3124 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3125 backup_path.to_string(), err.what()) << endmsg;
3135 Session::restore_history (string snapshot_name)
3139 if (snapshot_name.empty()) {
3140 snapshot_name = _current_snapshot_name;
3143 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3144 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3146 info << "Loading history from " << xml_path.to_string() << endmsg;
3148 if (!sys::exists (xml_path)) {
3149 info << string_compose (_("%1: no history file \"%2\" for this session."),
3150 _name, xml_path.to_string()) << endmsg;
3154 if (!tree.read (xml_path.to_string())) {
3155 error << string_compose (_("Could not understand session history file \"%1\""),
3156 xml_path.to_string()) << endmsg;
3163 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3166 UndoTransaction* ut = new UndoTransaction ();
3169 ut->set_name(t->property("name")->value());
3170 stringstream ss(t->property("tv-sec")->value());
3172 ss.str(t->property("tv-usec")->value());
3174 ut->set_timestamp(tv);
3176 for (XMLNodeConstIterator child_it = t->children().begin();
3177 child_it != t->children().end(); child_it++)
3179 XMLNode *n = *child_it;
3182 if (n->name() == "MementoCommand" ||
3183 n->name() == "MementoUndoCommand" ||
3184 n->name() == "MementoRedoCommand") {
3186 if ((c = memento_command_factory(n))) {
3190 } else if (n->name() == "NoteDiffCommand") {
3191 PBD::ID id (n->property("midi-source")->value());
3192 boost::shared_ptr<MidiSource> midi_source =
3193 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3195 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3197 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3200 } else if (n->name() == "SysExDiffCommand") {
3202 PBD::ID id (n->property("midi-source")->value());
3203 boost::shared_ptr<MidiSource> midi_source =
3204 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3206 ut->add_command (new MidiModel::SysExDiffCommand (midi_source->model(), *n));
3208 error << _("Failed to downcast MidiSource for SysExDiffCommand") << endmsg;
3211 } else if (n->name() == "PatchChangeDiffCommand") {
3213 PBD::ID id (n->property("midi-source")->value());
3214 boost::shared_ptr<MidiSource> midi_source =
3215 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3217 ut->add_command (new MidiModel::PatchChangeDiffCommand (midi_source->model(), *n));
3219 error << _("Failed to downcast MidiSource for PatchChangeDiffCommand") << endmsg;
3222 } else if (n->name() == "StatefulDiffCommand") {
3223 if ((c = stateful_diff_command_factory (n))) {
3224 ut->add_command (c);
3227 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3238 Session::config_changed (std::string p, bool ours)
3244 if (p == "seamless-loop") {
3246 } else if (p == "rf-speed") {
3248 } else if (p == "auto-loop") {
3250 } else if (p == "auto-input") {
3252 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3253 /* auto-input only makes a difference if we're rolling */
3255 boost::shared_ptr<RouteList> rl = routes.reader ();
3256 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3257 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3258 if (tr && tr->record_enabled ()) {
3259 tr->monitor_input (!config.get_auto_input());
3264 } else if (p == "punch-in") {
3268 if ((location = _locations->auto_punch_location()) != 0) {
3270 if (config.get_punch_in ()) {
3271 replace_event (SessionEvent::PunchIn, location->start());
3273 remove_event (location->start(), SessionEvent::PunchIn);
3277 } else if (p == "punch-out") {
3281 if ((location = _locations->auto_punch_location()) != 0) {
3283 if (config.get_punch_out()) {
3284 replace_event (SessionEvent::PunchOut, location->end());
3286 clear_events (SessionEvent::PunchOut);
3290 } else if (p == "edit-mode") {
3292 Glib::Mutex::Lock lm (playlists->lock);
3294 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3295 (*i)->set_edit_mode (Config->get_edit_mode ());
3298 } else if (p == "use-video-sync") {
3300 waiting_for_sync_offset = config.get_use_video_sync();
3302 } else if (p == "mmc-control") {
3304 //poke_midi_thread ();
3306 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3308 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3310 } else if (p == "mmc-send-id") {
3312 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3314 } else if (p == "midi-control") {
3316 //poke_midi_thread ();
3318 } else if (p == "raid-path") {
3320 setup_raid_path (config.get_raid_path());
3322 } else if (p == "timecode-format") {
3326 } else if (p == "video-pullup") {
3330 } else if (p == "seamless-loop") {
3332 if (play_loop && transport_rolling()) {
3333 // to reset diskstreams etc
3334 request_play_loop (true);
3337 } else if (p == "rf-speed") {
3339 cumulative_rf_motion = 0;
3342 } else if (p == "click-sound") {
3344 setup_click_sounds (1);
3346 } else if (p == "click-emphasis-sound") {
3348 setup_click_sounds (-1);
3350 } else if (p == "clicking") {
3352 if (Config->get_clicking()) {
3353 if (_click_io && click_data) { // don't require emphasis data
3360 } else if (p == "send-mtc") {
3362 if (Config->get_send_mtc ()) {
3363 /* mark us ready to send */
3364 next_quarter_frame_to_send = 0;
3367 } else if (p == "send-mmc") {
3369 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3371 } else if (p == "midi-feedback") {
3373 session_midi_feedback = Config->get_midi_feedback();
3375 } else if (p == "jack-time-master") {
3377 engine().reset_timebase ();
3379 } else if (p == "native-file-header-format") {
3381 if (!first_file_header_format_reset) {
3382 reset_native_file_format ();
3385 first_file_header_format_reset = false;
3387 } else if (p == "native-file-data-format") {
3389 if (!first_file_data_format_reset) {
3390 reset_native_file_format ();
3393 first_file_data_format_reset = false;
3395 } else if (p == "external-sync") {
3396 if (!config.get_external_sync()) {
3397 drop_sync_source ();
3399 switch_to_sync_source (config.get_sync_source());
3401 } else if (p == "remote-model") {
3402 set_remote_control_ids ();
3403 } else if (p == "denormal-model") {
3405 } else if (p == "history-depth") {
3406 set_history_depth (Config->get_history_depth());
3407 } else if (p == "sync-all-route-ordering") {
3408 sync_order_keys ("session");
3409 } else if (p == "initial-program-change") {
3411 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3414 buf[0] = MIDI::program; // channel zero by default
3415 buf[1] = (Config->get_initial_program_change() & 0x7f);
3417 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3419 } else if (p == "solo-mute-override") {
3420 // catch_up_on_solo_mute_override ();
3421 } else if (p == "listen-position") {
3422 listen_position_changed ();
3423 } else if (p == "solo-control-is-listen-control") {
3424 solo_control_mode_changed ();
3425 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3426 last_timecode_valid = false;
3433 Session::set_history_depth (uint32_t d)
3435 _history.set_depth (d);
3439 Session::load_diskstreams_2X (XMLNode const & node, int)
3442 XMLNodeConstIterator citer;
3444 clist = node.children();
3446 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3449 /* diskstreams added automatically by DiskstreamCreated handler */
3450 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3451 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3452 _diskstreams_2X.push_back (dsp);
3454 error << _("Session: unknown diskstream type in XML") << endmsg;
3458 catch (failed_constructor& err) {
3459 error << _("Session: could not load diskstream via XML state") << endmsg;
3467 /** Connect things to the MMC object */
3469 Session::setup_midi_machine_control ()
3471 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3473 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3474 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3475 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3476 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3477 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3478 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3479 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3480 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3481 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3482 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3483 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3484 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3485 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3487 /* also handle MIDI SPP because its so common */
3489 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3490 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3491 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));