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 session_send_mtc = false;
210 g_atomic_int_set (&_playback_load, 100);
211 g_atomic_int_set (&_capture_load, 100);
214 pending_abort = false;
215 destructive_index = 0;
216 first_file_data_format_reset = true;
217 first_file_header_format_reset = true;
218 post_export_sync = false;
221 no_questions_about_missing_files = false;
224 AudioDiskstream::allocate_working_buffers();
226 /* default short fade = 15ms */
228 Crossfade::set_short_xfade_length ((framecnt_t) floor (config.get_short_xfade_seconds() * frame_rate()));
229 SndFileSource::setup_standard_crossfades (*this, frame_rate());
231 last_mmc_step.tv_sec = 0;
232 last_mmc_step.tv_usec = 0;
235 /* click sounds are unset by default, which causes us to internal
236 waveforms for clicks.
240 click_emphasis_length = 0;
243 process_function = &Session::process_with_events;
245 if (config.get_use_video_sync()) {
246 waiting_for_sync_offset = true;
248 waiting_for_sync_offset = false;
251 last_timecode_when = 0;
252 last_timecode_valid = false;
256 last_rr_session_dir = session_dirs.begin();
257 refresh_disk_space ();
259 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
263 average_slave_delta = 1800; // !!! why 1800 ????
264 have_first_delta_accumulator = false;
265 delta_accumulator_cnt = 0;
266 _slave_state = Stopped;
268 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
270 /* These are all static "per-class" signals */
272 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
273 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
274 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
275 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
276 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
278 /* stop IO objects from doing stuff until we're ready for them */
280 Delivery::disable_panners ();
281 IO::disable_connecting ();
285 Session::second_stage_init ()
287 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
290 if (load_state (_current_snapshot_name)) {
293 cleanup_stubfiles ();
296 if (_butler->start_thread()) {
300 if (start_midi_thread ()) {
304 setup_midi_machine_control ();
306 // set_state() will call setup_raid_path(), but if it's a new session we need
307 // to call setup_raid_path() here.
310 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
314 setup_raid_path(_path);
317 /* we can't save till after ::when_engine_running() is called,
318 because otherwise we save state with no connections made.
319 therefore, we reset _state_of_the_state because ::set_state()
320 will have cleared it.
322 we also have to include Loading so that any events that get
323 generated between here and the end of ::when_engine_running()
324 will be processed directly rather than queued.
327 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
329 _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
330 _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
331 setup_click_sounds (0);
332 setup_midi_control ();
334 /* Pay attention ... */
336 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
337 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
340 when_engine_running ();
343 /* handle this one in a different way than all others, so that its clear what happened */
345 catch (AudioEngine::PortRegistrationFailure& err) {
346 error << err.what() << endmsg;
354 BootMessage (_("Reset Remote Controls"));
356 send_full_time_code (0);
357 _engine.transport_locate (0);
359 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (MIDI::MachineControl::cmdMmcReset));
360 MIDI::Manager::instance()->mmc()->send (MIDI::MachineControlCommand (Timecode::Time ()));
362 MidiClockTicker::instance().set_session (this);
363 MIDI::Name::MidiPatchManager::instance().set_session (this);
365 /* initial program change will be delivered later; see ::config_changed() */
367 BootMessage (_("Reset Control Protocols"));
369 ControlProtocolManager::instance().set_session (this);
371 _state_of_the_state = Clean;
373 Port::set_connecting_blocked (false);
375 DirtyChanged (); /* EMIT SIGNAL */
377 if (state_was_pending) {
378 save_state (_current_snapshot_name);
379 remove_pending_capture_state ();
380 state_was_pending = false;
383 BootMessage (_("Session loading complete"));
389 Session::raid_path () const
391 SearchPath raid_search_path;
393 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
394 raid_search_path += sys::path((*i).path);
397 return raid_search_path.to_string ();
401 Session::setup_raid_path (string path)
410 session_dirs.clear ();
412 SearchPath search_path(path);
413 SearchPath sound_search_path;
414 SearchPath midi_search_path;
416 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
417 sp.path = (*i).to_string ();
418 sp.blocks = 0; // not needed
419 session_dirs.push_back (sp);
421 SessionDirectory sdir(sp.path);
423 sound_search_path += sdir.sound_path ();
424 midi_search_path += sdir.midi_path ();
427 // reset the round-robin soundfile path thingie
428 last_rr_session_dir = session_dirs.begin();
432 Session::path_is_within_session (const std::string& path)
434 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
435 if (path.find ((*i).path) == 0) {
443 Session::ensure_subdirs ()
447 dir = session_directory().peak_path().to_string();
449 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
450 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
454 dir = session_directory().sound_path().to_string();
456 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
457 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
461 dir = session_directory().sound_stub_path().to_string();
463 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
464 error << string_compose(_("Session: cannot create session stub sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
468 dir = session_directory().midi_path().to_string();
470 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
471 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
475 dir = session_directory().midi_stub_path().to_string();
477 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
478 error << string_compose(_("Session: cannot create session stub midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
482 dir = session_directory().dead_sound_path().to_string();
484 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
485 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
489 dir = session_directory().export_path().to_string();
491 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
492 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
496 dir = analysis_dir ();
498 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
499 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
503 dir = plugins_dir ();
505 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
506 error << string_compose(_("Session: cannot create session plugins folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
513 /** Caller must not hold process lock */
515 Session::create (const string& mix_template, BusProfile* bus_profile)
518 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
519 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
523 if (ensure_subdirs ()) {
527 if (!mix_template.empty()) {
528 std::string in_path = mix_template;
530 ifstream in(in_path.c_str());
533 string out_path = _path;
535 out_path += statefile_suffix;
537 ofstream out(out_path.c_str());
545 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
551 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
558 /* Instantiate metadata */
560 _metadata = new SessionMetadata ();
562 /* set initial start + end point */
564 _state_of_the_state = Clean;
566 /* set up Master Out and Control Out if necessary */
572 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
574 if (bus_profile->master_out_channels) {
575 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
580 boost_debug_shared_ptr_mark_interesting (rt, "Route");
581 boost::shared_ptr<Route> r (rt);
583 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
584 r->input()->ensure_io (count, false, this);
585 r->output()->ensure_io (count, false, this);
587 r->set_remote_control_id (control_id++);
591 if (Config->get_use_monitor_bus()) {
592 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
597 boost_debug_shared_ptr_mark_interesting (rt, "Route");
598 boost::shared_ptr<Route> r (rt);
600 Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
601 r->input()->ensure_io (count, false, this);
602 r->output()->ensure_io (count, false, this);
604 r->set_remote_control_id (control_id);
610 /* prohibit auto-connect to master, because there isn't one */
611 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
615 add_routes (rl, false);
618 /* this allows the user to override settings with an environment variable.
621 if (no_auto_connect()) {
622 bus_profile->input_ac = AutoConnectOption (0);
623 bus_profile->output_ac = AutoConnectOption (0);
626 Config->set_input_auto_connect (bus_profile->input_ac);
627 Config->set_output_auto_connect (bus_profile->output_ac);
636 Session::maybe_write_autosave()
638 if (dirty() && record_status() != Recording) {
639 save_state("", true);
644 Session::remove_pending_capture_state ()
646 sys::path pending_state_file_path(_session_dir->root_path());
648 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
652 sys::remove (pending_state_file_path);
654 catch(sys::filesystem_error& ex)
656 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
657 pending_state_file_path.to_string(), ex.what()) << endmsg;
661 /** Rename a state file.
662 * @param snapshot_name Snapshot name.
665 Session::rename_state (string old_name, string new_name)
667 if (old_name == _current_snapshot_name || old_name == _name) {
668 /* refuse to rename the current snapshot or the "main" one */
672 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
673 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
675 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
676 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
680 sys::rename (old_xml_path, new_xml_path);
682 catch (const sys::filesystem_error& err)
684 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
685 old_name, new_name, err.what()) << endmsg;
689 /** Remove a state file.
690 * @param snapshot_name Snapshot name.
693 Session::remove_state (string snapshot_name)
695 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
696 // refuse to remove the current snapshot or the "main" one
700 sys::path xml_path(_session_dir->root_path());
702 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
704 if (!create_backup_file (xml_path)) {
705 // don't remove it if a backup can't be made
706 // create_backup_file will log the error.
711 sys::remove (xml_path);
714 #ifdef HAVE_JACK_SESSION
716 Session::jack_session_event (jack_session_event_t * event)
720 struct tm local_time;
723 localtime_r (&n, &local_time);
724 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
726 if (event->type == JackSessionSaveTemplate)
728 if (save_template( timebuf )) {
729 event->flags = JackSessionSaveError;
731 string cmd ("ardour3 -P -U ");
732 cmd += event->client_uuid;
736 event->command_line = strdup (cmd.c_str());
741 if (save_state (timebuf)) {
742 event->flags = JackSessionSaveError;
744 sys::path xml_path (_session_dir->root_path());
745 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
747 string cmd ("ardour3 -P -U ");
748 cmd += event->client_uuid;
750 cmd += xml_path.to_string();
753 event->command_line = strdup (cmd.c_str());
757 jack_session_reply (_engine.jack(), event);
759 if (event->type == JackSessionSaveAndQuit) {
760 Quit (); /* EMIT SIGNAL */
763 jack_session_event_free( event );
768 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
771 sys::path xml_path(_session_dir->root_path());
773 if (!_writable || (_state_of_the_state & CannotSave)) {
777 if (!_engine.connected ()) {
778 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
784 /* tell sources we're saving first, in case they write out to a new file
785 * which should be saved with the state rather than the old one */
786 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
787 i->second->session_saved();
790 tree.set_root (&get_state());
792 if (snapshot_name.empty()) {
793 snapshot_name = _current_snapshot_name;
794 } else if (switch_to_snapshot) {
795 _current_snapshot_name = snapshot_name;
800 /* proper save: use statefile_suffix (.ardour in English) */
802 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
804 /* make a backup copy of the old file */
806 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
807 // create_backup_file will log the error
813 /* pending save: use pending_suffix (.pending in English) */
814 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
817 sys::path tmp_path(_session_dir->root_path());
819 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
821 // cerr << "actually writing state to " << xml_path.to_string() << endl;
823 if (!tree.write (tmp_path.to_string())) {
824 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
825 sys::remove (tmp_path);
830 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
831 error << string_compose (_("could not rename temporary session file %1 to %2"),
832 tmp_path.to_string(), xml_path.to_string()) << endmsg;
833 sys::remove (tmp_path);
840 save_history (snapshot_name);
842 bool was_dirty = dirty();
844 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
847 DirtyChanged (); /* EMIT SIGNAL */
850 StateSaved (snapshot_name); /* EMIT SIGNAL */
857 Session::restore_state (string snapshot_name)
859 if (load_state (snapshot_name) == 0) {
860 set_state (*state_tree->root(), Stateful::loading_state_version);
867 Session::load_state (string snapshot_name)
872 state_was_pending = false;
874 /* check for leftover pending state from a crashed capture attempt */
876 sys::path xmlpath(_session_dir->root_path());
877 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
879 if (sys::exists (xmlpath)) {
881 /* there is pending state from a crashed capture attempt */
883 boost::optional<int> r = AskAboutPendingState();
884 if (r.get_value_or (1)) {
885 state_was_pending = true;
889 if (!state_was_pending) {
890 xmlpath = _session_dir->root_path();
891 xmlpath /= snapshot_name;
894 if (!sys::exists (xmlpath)) {
895 xmlpath = _session_dir->root_path();
896 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
897 if (!sys::exists (xmlpath)) {
898 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
903 state_tree = new XMLTree;
907 /* writable() really reflects the whole folder, but if for any
908 reason the session state file can't be written to, still
912 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
916 if (!state_tree->read (xmlpath.to_string())) {
917 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
923 XMLNode& root (*state_tree->root());
925 if (root.name() != X_("Session")) {
926 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
932 const XMLProperty* prop;
934 if ((prop = root.property ("version")) == 0) {
935 /* no version implies very old version of Ardour */
936 Stateful::loading_state_version = 1000;
942 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
943 Stateful::loading_state_version = (major * 1000) + minor;
946 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
948 sys::path backup_path(_session_dir->root_path());
950 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
952 // only create a backup once
953 if (sys::exists (backup_path)) {
957 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
958 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
963 sys::copy_file (xmlpath, backup_path);
965 catch(sys::filesystem_error& ex)
967 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
968 xmlpath.to_string(), ex.what())
978 Session::load_options (const XMLNode& node)
980 LocaleGuard lg (X_("POSIX"));
981 config.set_variables (node);
992 Session::get_template()
994 /* if we don't disable rec-enable, diskstreams
995 will believe they need to store their capture
996 sources in their state node.
999 disable_record (false);
1001 return state(false);
1005 Session::state(bool full_state)
1007 XMLNode* node = new XMLNode("Session");
1010 // store libardour version, just in case
1012 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
1013 node->add_property("version", string(buf));
1015 /* store configuration settings */
1019 node->add_property ("name", _name);
1020 snprintf (buf, sizeof (buf), "%" PRId64, _nominal_frame_rate);
1021 node->add_property ("sample-rate", buf);
1023 if (session_dirs.size() > 1) {
1027 vector<space_and_path>::iterator i = session_dirs.begin();
1028 vector<space_and_path>::iterator next;
1030 ++i; /* skip the first one */
1034 while (i != session_dirs.end()) {
1038 if (next != session_dirs.end()) {
1048 child = node->add_child ("Path");
1049 child->add_content (p);
1053 /* save the ID counter */
1055 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1056 node->add_property ("id-counter", buf);
1058 /* save the event ID counter */
1060 snprintf (buf, sizeof (buf), "%d", Evoral::event_id_counter());
1061 node->add_property ("event-counter", buf);
1063 /* various options */
1065 node->add_child_nocopy (config.get_variables ());
1067 node->add_child_nocopy (_metadata->get_state());
1069 child = node->add_child ("Sources");
1072 Glib::Mutex::Lock sl (source_lock);
1074 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1076 /* Don't save information about non-destructive file sources that are empty
1077 and unused by any regions.
1080 boost::shared_ptr<FileSource> fs;
1081 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1082 if (!fs->destructive()) {
1083 if (fs->empty() && !fs->used()) {
1089 child->add_child_nocopy (siter->second->get_state());
1093 child = node->add_child ("Regions");
1096 Glib::Mutex::Lock rl (region_lock);
1097 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1098 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1099 boost::shared_ptr<Region> r = i->second;
1100 /* only store regions not attached to playlists */
1101 if (r->playlist() == 0) {
1102 child->add_child_nocopy (r->state ());
1108 node->add_child_nocopy (_locations->get_state());
1110 // for a template, just create a new Locations, populate it
1111 // with the default start and end, and get the state for that.
1112 Locations loc (*this);
1113 Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
1114 range->set (max_framepos, 0);
1116 node->add_child_nocopy (loc.get_state());
1119 child = node->add_child ("Bundles");
1121 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1122 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1123 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1125 child->add_child_nocopy (b->get_state());
1130 child = node->add_child ("Routes");
1132 boost::shared_ptr<RouteList> r = routes.reader ();
1134 RoutePublicOrderSorter cmp;
1135 RouteList public_order (*r);
1136 public_order.sort (cmp);
1138 /* the sort should have put control outs first */
1141 assert (_monitor_out == public_order.front());
1144 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1145 if (!(*i)->is_hidden()) {
1147 child->add_child_nocopy ((*i)->get_state());
1149 child->add_child_nocopy ((*i)->get_template());
1155 playlists->add_state (node, full_state);
1157 child = node->add_child ("RouteGroups");
1158 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1159 child->add_child_nocopy ((*i)->get_state());
1163 child = node->add_child ("Click");
1164 child->add_child_nocopy (_click_io->state (full_state));
1168 child = node->add_child ("NamedSelections");
1169 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1171 child->add_child_nocopy ((*i)->get_state());
1176 node->add_child_nocopy (_tempo_map->get_state());
1178 node->add_child_nocopy (get_control_protocol_state());
1181 node->add_child_copy (*_extra_xml);
1188 Session::get_control_protocol_state ()
1190 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1191 return cpm.get_state();
1195 Session::set_state (const XMLNode& node, int version)
1199 const XMLProperty* prop;
1202 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1204 if (node.name() != X_("Session")){
1205 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1209 if ((prop = node.property ("version")) != 0) {
1210 version = atoi (prop->value ()) * 1000;
1213 if ((prop = node.property ("name")) != 0) {
1214 _name = prop->value ();
1217 if ((prop = node.property (X_("sample-rate"))) != 0) {
1219 _nominal_frame_rate = atoi (prop->value());
1221 if (_nominal_frame_rate != _current_frame_rate) {
1222 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1223 if (r.get_value_or (0)) {
1229 setup_raid_path(_session_dir->root_path().to_string());
1231 if ((prop = node.property (X_("id-counter"))) != 0) {
1233 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1234 ID::init_counter (x);
1236 /* old sessions used a timebased counter, so fake
1237 the startup ID counter based on a standard
1242 ID::init_counter (now);
1245 if ((prop = node.property (X_("event-counter"))) != 0) {
1246 Evoral::init_event_id_counter (atoi (prop->value()));
1249 IO::disable_connecting ();
1251 /* Object loading order:
1256 MIDI Control // relies on data from Options/Config
1269 if ((child = find_named_node (node, "Extra")) != 0) {
1270 _extra_xml = new XMLNode (*child);
1273 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1274 load_options (*child);
1275 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1276 load_options (*child);
1278 error << _("Session: XML state has no options section") << endmsg;
1281 if (version >= 3000) {
1282 if ((child = find_named_node (node, "Metadata")) == 0) {
1283 warning << _("Session: XML state has no metadata section") << endmsg;
1284 } else if (_metadata->set_state (*child, version)) {
1289 if ((child = find_named_node (node, "Locations")) == 0) {
1290 error << _("Session: XML state has no locations section") << endmsg;
1292 } else if (_locations->set_state (*child, version)) {
1298 if ((location = _locations->auto_loop_location()) != 0) {
1299 set_auto_loop_location (location);
1302 if ((location = _locations->auto_punch_location()) != 0) {
1303 set_auto_punch_location (location);
1306 if ((location = _locations->session_range_location()) != 0) {
1307 delete _session_range_location;
1308 _session_range_location = location;
1311 if (_session_range_location) {
1312 AudioFileSource::set_header_position_offset (_session_range_location->start());
1315 if ((child = find_named_node (node, "Sources")) == 0) {
1316 error << _("Session: XML state has no sources section") << endmsg;
1318 } else if (load_sources (*child)) {
1322 if ((child = find_named_node (node, "Regions")) == 0) {
1323 error << _("Session: XML state has no Regions section") << endmsg;
1325 } else if (load_regions (*child)) {
1329 if ((child = find_named_node (node, "Playlists")) == 0) {
1330 error << _("Session: XML state has no playlists section") << endmsg;
1332 } else if (playlists->load (*this, *child)) {
1336 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1338 } else if (playlists->load_unused (*this, *child)) {
1342 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1343 if (load_named_selections (*child)) {
1348 if (version >= 3000) {
1349 if ((child = find_named_node (node, "Bundles")) == 0) {
1350 warning << _("Session: XML state has no bundles section") << endmsg;
1353 /* We can't load Bundles yet as they need to be able
1354 to convert from port names to Port objects, which can't happen until
1356 _bundle_xml_node = new XMLNode (*child);
1360 if ((child = find_named_node (node, "TempoMap")) == 0) {
1361 error << _("Session: XML state has no Tempo Map section") << endmsg;
1363 } else if (_tempo_map->set_state (*child, version)) {
1367 if (version < 3000) {
1368 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1369 error << _("Session: XML state has no diskstreams section") << endmsg;
1371 } else if (load_diskstreams_2X (*child, version)) {
1376 if ((child = find_named_node (node, "Routes")) == 0) {
1377 error << _("Session: XML state has no routes section") << endmsg;
1379 } else if (load_routes (*child, version)) {
1383 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1384 _diskstreams_2X.clear ();
1386 if (version >= 3000) {
1388 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1389 error << _("Session: XML state has no route groups section") << endmsg;
1391 } else if (load_route_groups (*child, version)) {
1395 } else if (version < 3000) {
1397 if ((child = find_named_node (node, "EditGroups")) == 0) {
1398 error << _("Session: XML state has no edit groups section") << endmsg;
1400 } else if (load_route_groups (*child, version)) {
1404 if ((child = find_named_node (node, "MixGroups")) == 0) {
1405 error << _("Session: XML state has no mix groups section") << endmsg;
1407 } else if (load_route_groups (*child, version)) {
1412 if ((child = find_named_node (node, "Click")) == 0) {
1413 warning << _("Session: XML state has no click section") << endmsg;
1414 } else if (_click_io) {
1415 _click_io->set_state (*child, version);
1418 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1419 ControlProtocolManager::instance().set_protocol_states (*child);
1422 /* here beginneth the second phase ... */
1424 StateReady (); /* EMIT SIGNAL */
1433 Session::load_routes (const XMLNode& node, int version)
1436 XMLNodeConstIterator niter;
1437 RouteList new_routes;
1439 nlist = node.children();
1443 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1445 boost::shared_ptr<Route> route;
1446 if (version < 3000) {
1447 route = XMLRouteFactory_2X (**niter, version);
1449 route = XMLRouteFactory (**niter, version);
1453 error << _("Session: cannot create Route from XML description.") << endmsg;
1457 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1459 new_routes.push_back (route);
1462 add_routes (new_routes, false);
1467 boost::shared_ptr<Route>
1468 Session::XMLRouteFactory (const XMLNode& node, int version)
1470 boost::shared_ptr<Route> ret;
1472 if (node.name() != "Route") {
1476 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1478 DataType type = DataType::AUDIO;
1479 const XMLProperty* prop = node.property("default-type");
1482 type = DataType (prop->value());
1485 assert (type != DataType::NIL);
1491 if (type == DataType::AUDIO) {
1492 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1495 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1498 if (track->init()) {
1503 if (track->set_state (node, version)) {
1508 boost_debug_shared_ptr_mark_interesting (track, "Track");
1512 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1514 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1515 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1525 boost::shared_ptr<Route>
1526 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1528 boost::shared_ptr<Route> ret;
1530 if (node.name() != "Route") {
1534 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1536 ds_prop = node.property (X_("diskstream"));
1539 DataType type = DataType::AUDIO;
1540 const XMLProperty* prop = node.property("default-type");
1543 type = DataType (prop->value());
1546 assert (type != DataType::NIL);
1550 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1551 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1555 if (i == _diskstreams_2X.end()) {
1556 error << _("Could not find diskstream for route") << endmsg;
1557 return boost::shared_ptr<Route> ();
1562 if (type == DataType::AUDIO) {
1563 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1566 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1569 if (track->init()) {
1574 if (track->set_state (node, version)) {
1579 track->set_diskstream (*i);
1581 boost_debug_shared_ptr_mark_interesting (track, "Track");
1585 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1587 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1588 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1599 Session::load_regions (const XMLNode& node)
1602 XMLNodeConstIterator niter;
1603 boost::shared_ptr<Region> region;
1605 nlist = node.children();
1609 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1610 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1611 error << _("Session: cannot create Region from XML description.");
1612 const XMLProperty *name = (**niter).property("name");
1615 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1625 boost::shared_ptr<Region>
1626 Session::XMLRegionFactory (const XMLNode& node, bool full)
1628 const XMLProperty* type = node.property("type");
1632 if (!type || type->value() == "audio") {
1633 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1634 } else if (type->value() == "midi") {
1635 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1638 } catch (failed_constructor& err) {
1639 return boost::shared_ptr<Region> ();
1642 return boost::shared_ptr<Region> ();
1645 boost::shared_ptr<AudioRegion>
1646 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1648 const XMLProperty* prop;
1649 boost::shared_ptr<Source> source;
1650 boost::shared_ptr<AudioSource> as;
1652 SourceList master_sources;
1653 uint32_t nchans = 1;
1656 if (node.name() != X_("Region")) {
1657 return boost::shared_ptr<AudioRegion>();
1660 if ((prop = node.property (X_("channels"))) != 0) {
1661 nchans = atoi (prop->value().c_str());
1664 if ((prop = node.property ("name")) == 0) {
1665 cerr << "no name for this region\n";
1669 if ((prop = node.property (X_("source-0"))) == 0) {
1670 if ((prop = node.property ("source")) == 0) {
1671 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1672 return boost::shared_ptr<AudioRegion>();
1676 PBD::ID s_id (prop->value());
1678 if ((source = source_by_id (s_id)) == 0) {
1679 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1680 return boost::shared_ptr<AudioRegion>();
1683 as = boost::dynamic_pointer_cast<AudioSource>(source);
1685 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1686 return boost::shared_ptr<AudioRegion>();
1689 sources.push_back (as);
1691 /* pickup other channels */
1693 for (uint32_t n=1; n < nchans; ++n) {
1694 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1695 if ((prop = node.property (buf)) != 0) {
1697 PBD::ID id2 (prop->value());
1699 if ((source = source_by_id (id2)) == 0) {
1700 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1701 return boost::shared_ptr<AudioRegion>();
1704 as = boost::dynamic_pointer_cast<AudioSource>(source);
1706 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1707 return boost::shared_ptr<AudioRegion>();
1709 sources.push_back (as);
1713 for (uint32_t n = 0; n < nchans; ++n) {
1714 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1715 if ((prop = node.property (buf)) != 0) {
1717 PBD::ID id2 (prop->value());
1719 if ((source = source_by_id (id2)) == 0) {
1720 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1721 return boost::shared_ptr<AudioRegion>();
1724 as = boost::dynamic_pointer_cast<AudioSource>(source);
1726 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1727 return boost::shared_ptr<AudioRegion>();
1729 master_sources.push_back (as);
1734 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1736 /* a final detail: this is the one and only place that we know how long missing files are */
1738 if (region->whole_file()) {
1739 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1740 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1742 sfp->set_length (region->length());
1747 if (!master_sources.empty()) {
1748 if (master_sources.size() != nchans) {
1749 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1751 region->set_master_sources (master_sources);
1759 catch (failed_constructor& err) {
1760 return boost::shared_ptr<AudioRegion>();
1764 boost::shared_ptr<MidiRegion>
1765 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1767 const XMLProperty* prop;
1768 boost::shared_ptr<Source> source;
1769 boost::shared_ptr<MidiSource> ms;
1772 if (node.name() != X_("Region")) {
1773 return boost::shared_ptr<MidiRegion>();
1776 if ((prop = node.property ("name")) == 0) {
1777 cerr << "no name for this region\n";
1781 if ((prop = node.property (X_("source-0"))) == 0) {
1782 if ((prop = node.property ("source")) == 0) {
1783 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1784 return boost::shared_ptr<MidiRegion>();
1788 PBD::ID s_id (prop->value());
1790 if ((source = source_by_id (s_id)) == 0) {
1791 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1792 return boost::shared_ptr<MidiRegion>();
1795 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1797 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1798 return boost::shared_ptr<MidiRegion>();
1801 sources.push_back (ms);
1804 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1805 /* a final detail: this is the one and only place that we know how long missing files are */
1807 if (region->whole_file()) {
1808 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1809 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1811 sfp->set_length (region->length());
1819 catch (failed_constructor& err) {
1820 return boost::shared_ptr<MidiRegion>();
1825 Session::get_sources_as_xml ()
1828 XMLNode* node = new XMLNode (X_("Sources"));
1829 Glib::Mutex::Lock lm (source_lock);
1831 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1832 node->add_child_nocopy (i->second->get_state());
1839 Session::path_from_region_name (DataType type, string name, string identifier)
1841 char buf[PATH_MAX+1];
1843 SessionDirectory sdir(get_best_session_directory_for_new_source());
1844 sys::path source_dir = ((type == DataType::AUDIO)
1845 ? sdir.sound_path() : sdir.midi_path());
1847 string ext = native_header_format_extension (config.get_native_file_header_format(), type);
1849 for (n = 0; n < 999999; ++n) {
1850 if (identifier.length()) {
1851 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1852 identifier.c_str(), n, ext.c_str());
1854 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1858 sys::path source_path = source_dir / buf;
1860 if (!sys::exists (source_path)) {
1861 return source_path.to_string();
1865 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1874 Session::load_sources (const XMLNode& node)
1877 XMLNodeConstIterator niter;
1878 boost::shared_ptr<Source> source;
1880 nlist = node.children();
1884 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1887 if ((source = XMLSourceFactory (**niter)) == 0) {
1888 error << _("Session: cannot create Source from XML description.") << endmsg;
1891 } catch (MissingSource& err) {
1895 if (!no_questions_about_missing_files) {
1896 user_choice = MissingFile (this, err.path, err.type).get_value_or (-1);
1901 switch (user_choice) {
1903 /* user added a new search location, so try again */
1908 /* user asked to quit the entire session load
1913 no_questions_about_missing_files = true;
1917 no_questions_about_missing_files = true;
1922 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1923 source = SourceFactory::createSilent (*this, **niter, max_framecnt, _current_frame_rate);
1932 boost::shared_ptr<Source>
1933 Session::XMLSourceFactory (const XMLNode& node)
1935 if (node.name() != "Source") {
1936 return boost::shared_ptr<Source>();
1940 /* note: do peak building in another thread when loading session state */
1941 return SourceFactory::create (*this, node, true);
1944 catch (failed_constructor& err) {
1945 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1946 return boost::shared_ptr<Source>();
1951 Session::save_template (string template_name)
1955 if (_state_of_the_state & CannotSave) {
1959 sys::path user_template_dir(user_template_directory());
1963 sys::create_directories (user_template_dir);
1965 catch(sys::filesystem_error& ex)
1967 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1968 user_template_dir.to_string(), ex.what()) << endmsg;
1972 tree.set_root (&get_template());
1974 sys::path template_file_path(user_template_dir);
1975 template_file_path /= template_name + template_suffix;
1977 if (sys::exists (template_file_path))
1979 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1980 template_file_path.to_string()) << endmsg;
1984 if (!tree.write (template_file_path.to_string())) {
1985 error << _("mix template not saved") << endmsg;
1993 Session::rename_template (string old_name, string new_name)
1995 sys::path old_path (user_template_directory());
1996 old_path /= old_name + template_suffix;
1998 sys::path new_path(user_template_directory());
1999 new_path /= new_name + template_suffix;
2001 if (sys::exists (new_path)) {
2002 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
2003 new_path.to_string()) << endmsg;
2008 sys::rename (old_path, new_path);
2016 Session::delete_template (string name)
2018 sys::path path = user_template_directory();
2019 path /= name + template_suffix;
2030 Session::refresh_disk_space ()
2033 struct statfs statfsbuf;
2034 vector<space_and_path>::iterator i;
2035 Glib::Mutex::Lock lm (space_lock);
2038 /* get freespace on every FS that is part of the session path */
2040 _total_free_4k_blocks = 0;
2042 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2043 statfs ((*i).path.c_str(), &statfsbuf);
2045 scale = statfsbuf.f_bsize/4096.0;
2047 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
2048 _total_free_4k_blocks += (*i).blocks;
2054 Session::get_best_session_directory_for_new_source ()
2056 vector<space_and_path>::iterator i;
2057 string result = _session_dir->root_path().to_string();
2059 /* handle common case without system calls */
2061 if (session_dirs.size() == 1) {
2065 /* OK, here's the algorithm we're following here:
2067 We want to select which directory to use for
2068 the next file source to be created. Ideally,
2069 we'd like to use a round-robin process so as to
2070 get maximum performance benefits from splitting
2071 the files across multiple disks.
2073 However, in situations without much diskspace, an
2074 RR approach may end up filling up a filesystem
2075 with new files while others still have space.
2076 Its therefore important to pay some attention to
2077 the freespace in the filesystem holding each
2078 directory as well. However, if we did that by
2079 itself, we'd keep creating new files in the file
2080 system with the most space until it was as full
2081 as all others, thus negating any performance
2082 benefits of this RAID-1 like approach.
2084 So, we use a user-configurable space threshold. If
2085 there are at least 2 filesystems with more than this
2086 much space available, we use RR selection between them.
2087 If not, then we pick the filesystem with the most space.
2089 This gets a good balance between the two
2093 refresh_disk_space ();
2095 int free_enough = 0;
2097 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2098 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2103 if (free_enough >= 2) {
2104 /* use RR selection process, ensuring that the one
2108 i = last_rr_session_dir;
2111 if (++i == session_dirs.end()) {
2112 i = session_dirs.begin();
2115 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2116 if (create_session_directory ((*i).path)) {
2118 last_rr_session_dir = i;
2123 } while (i != last_rr_session_dir);
2127 /* pick FS with the most freespace (and that
2128 seems to actually work ...)
2131 vector<space_and_path> sorted;
2132 space_and_path_ascending_cmp cmp;
2134 sorted = session_dirs;
2135 sort (sorted.begin(), sorted.end(), cmp);
2137 for (i = sorted.begin(); i != sorted.end(); ++i) {
2138 if (create_session_directory ((*i).path)) {
2140 last_rr_session_dir = i;
2150 Session::load_named_selections (const XMLNode& node)
2153 XMLNodeConstIterator niter;
2156 nlist = node.children();
2160 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2162 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2163 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2171 Session::XMLNamedSelectionFactory (const XMLNode& node)
2174 return new NamedSelection (*this, node);
2177 catch (failed_constructor& err) {
2183 Session::automation_dir () const
2185 return Glib::build_filename (_path, "automation");
2189 Session::analysis_dir () const
2191 return Glib::build_filename (_path, "analysis");
2195 Session::plugins_dir () const
2197 return Glib::build_filename (_path, "plugins");
2201 Session::load_bundles (XMLNode const & node)
2203 XMLNodeList nlist = node.children();
2204 XMLNodeConstIterator niter;
2208 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2209 if ((*niter)->name() == "InputBundle") {
2210 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2211 } else if ((*niter)->name() == "OutputBundle") {
2212 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2214 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2223 Session::load_route_groups (const XMLNode& node, int version)
2225 XMLNodeList nlist = node.children();
2226 XMLNodeConstIterator niter;
2230 if (version >= 3000) {
2232 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2233 if ((*niter)->name() == "RouteGroup") {
2234 RouteGroup* rg = new RouteGroup (*this, "");
2235 add_route_group (rg);
2236 rg->set_state (**niter, version);
2240 } else if (version < 3000) {
2242 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2243 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2244 RouteGroup* rg = new RouteGroup (*this, "");
2245 add_route_group (rg);
2246 rg->set_state (**niter, version);
2255 Session::auto_save()
2257 save_state (_current_snapshot_name);
2261 state_file_filter (const string &str, void */*arg*/)
2263 return (str.length() > strlen(statefile_suffix) &&
2264 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2268 bool operator()(const string* a, const string* b) {
2274 remove_end(string* state)
2276 string statename(*state);
2278 string::size_type start,end;
2279 if ((start = statename.find_last_of (G_DIR_SEPARATOR)) != string::npos) {
2280 statename = statename.substr (start+1);
2283 if ((end = statename.rfind(".ardour")) == string::npos) {
2284 end = statename.length();
2287 return new string(statename.substr (0, end));
2291 Session::possible_states (string path)
2293 PathScanner scanner;
2294 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2296 transform(states->begin(), states->end(), states->begin(), remove_end);
2299 sort (states->begin(), states->end(), cmp);
2305 Session::possible_states () const
2307 return possible_states(_path);
2311 Session::add_route_group (RouteGroup* g)
2313 _route_groups.push_back (g);
2314 route_group_added (g); /* EMIT SIGNAL */
2316 g->MembershipChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2317 g->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::route_group_changed, this));
2323 Session::remove_route_group (RouteGroup& rg)
2325 list<RouteGroup*>::iterator i;
2327 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2328 _route_groups.erase (i);
2331 route_group_removed (); /* EMIT SIGNAL */
2337 Session::route_group_by_name (string name)
2339 list<RouteGroup *>::iterator i;
2341 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2342 if ((*i)->name() == name) {
2350 Session::all_route_group() const
2352 return *_all_route_group;
2356 Session::start_reversible_command (const string& name)
2358 UndoTransaction* trans = new UndoTransaction();
2359 trans->set_name(name);
2364 Session::finish_reversible_command (UndoTransaction& ut)
2367 gettimeofday(&now, 0);
2368 ut.set_timestamp(now);
2373 Session::add_commands (vector<Command*> const & cmds)
2375 for (vector<Command*>::const_iterator i = cmds.begin(); i != cmds.end(); ++i) {
2381 Session::begin_reversible_command(const string& name)
2383 UndoTransaction* trans = new UndoTransaction();
2384 trans->set_name(name);
2386 if (!_current_trans.empty()) {
2387 _current_trans.top()->add_command (trans);
2389 _current_trans.push(trans);
2394 Session::commit_reversible_command(Command *cmd)
2396 assert(!_current_trans.empty());
2400 _current_trans.top()->add_command(cmd);
2403 if (_current_trans.top()->empty()) {
2404 _current_trans.pop();
2408 gettimeofday(&now, 0);
2409 _current_trans.top()->set_timestamp(now);
2411 _history.add(_current_trans.top());
2412 _current_trans.pop();
2416 accept_all_non_peak_files (const string& path, void */*arg*/)
2418 if (!Glib::file_test (path, Glib::FILE_TEST_IS_REGULAR)) {
2422 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2426 accept_all_state_files (const string& path, void */*arg*/)
2428 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2432 Session::find_all_sources (string path, set<string>& result)
2437 if (!tree.read (path)) {
2441 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2446 XMLNodeConstIterator niter;
2448 nlist = node->children();
2452 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2456 if ((prop = (*niter)->property (X_("type"))) == 0) {
2460 DataType type (prop->value());
2462 if ((prop = (*niter)->property (X_("name"))) == 0) {
2466 if (Glib::path_is_absolute (prop->value())) {
2467 /* external file, ignore */
2475 if (FileSource::find (*this, type, prop->value(), true, is_new, chan, found_path)) {
2476 result.insert (found_path);
2484 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2486 PathScanner scanner;
2487 vector<string*>* state_files;
2489 string this_snapshot_path;
2495 if (ripped[ripped.length()-1] == G_DIR_SEPARATOR) {
2496 ripped = ripped.substr (0, ripped.length() - 1);
2499 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2501 if (state_files == 0) {
2506 this_snapshot_path = _path;
2507 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2508 this_snapshot_path += statefile_suffix;
2510 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2512 if (exclude_this_snapshot && **i == this_snapshot_path) {
2516 if (find_all_sources (**i, result) < 0) {
2524 struct RegionCounter {
2525 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2526 AudioSourceList::iterator iter;
2527 boost::shared_ptr<Region> region;
2530 RegionCounter() : count (0) {}
2534 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2536 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2537 return r.get_value_or (1);
2541 Session::cleanup_sources (CleanupReport& rep)
2543 // FIXME: needs adaptation to midi
2545 vector<boost::shared_ptr<Source> > dead_sources;
2546 PathScanner scanner;
2548 vector<space_and_path>::iterator i;
2549 vector<space_and_path>::iterator nexti;
2550 vector<string*>* soundfiles;
2551 vector<string> unused;
2552 set<string> all_sources;
2557 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2559 /* step 1: consider deleting all unused playlists */
2561 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2566 /* step 2: find all un-used sources */
2571 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2573 SourceMap::iterator tmp;
2578 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2582 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2583 dead_sources.push_back (i->second);
2584 i->second->drop_references ();
2590 /* build a list of all the possible sound directories for the session */
2592 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2597 SessionDirectory sdir ((*i).path);
2598 sound_path += sdir.sound_path().to_string();
2600 if (nexti != session_dirs.end()) {
2607 /* now do the same thing for the files that ended up in the sounds dir(s)
2608 but are not referenced as sources in any snapshot.
2611 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2613 if (soundfiles == 0) {
2617 /* find all sources, but don't use this snapshot because the
2618 state file on disk still references sources we may have already
2622 find_all_sources_across_snapshots (all_sources, true);
2624 /* add our current source list
2627 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2628 boost::shared_ptr<FileSource> fs;
2630 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2631 all_sources.insert (fs->path());
2635 char tmppath1[PATH_MAX+1];
2636 char tmppath2[PATH_MAX+1];
2638 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2643 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2645 if (realpath(spath.c_str(), tmppath1) == 0) {
2646 error << string_compose (_("Cannot expand path %1 (%2)"),
2647 spath, strerror (errno)) << endmsg;
2651 if (realpath((*i).c_str(), tmppath2) == 0) {
2652 error << string_compose (_("Cannot expand path %1 (%2)"),
2653 (*i), strerror (errno)) << endmsg;
2657 if (strcmp(tmppath1, tmppath2) == 0) {
2664 unused.push_back (spath);
2668 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2670 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2671 struct stat statbuf;
2673 rep.paths.push_back (*x);
2674 if (stat ((*x).c_str(), &statbuf) == 0) {
2675 rep.space += statbuf.st_size;
2680 /* don't move the file across filesystems, just
2681 stick it in the `dead_sound_dir_name' directory
2682 on whichever filesystem it was already on.
2685 if ((*x).find ("/sounds/") != string::npos) {
2687 /* old school, go up 1 level */
2689 newpath = Glib::path_get_dirname (*x); // "sounds"
2690 newpath = Glib::path_get_dirname (newpath); // "session-name"
2694 /* new school, go up 4 levels */
2696 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2697 newpath = Glib::path_get_dirname (newpath); // "session-name"
2698 newpath = Glib::path_get_dirname (newpath); // "interchange"
2699 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2702 newpath = Glib::build_filename (newpath, dead_sound_dir_name);
2704 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2705 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2709 newpath = Glib::build_filename (newpath, Glib::path_get_basename ((*x)));
2711 if (Glib::file_test (newpath, Glib::FILE_TEST_EXISTS)) {
2713 /* the new path already exists, try versioning */
2715 char buf[PATH_MAX+1];
2719 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2722 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2723 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2727 if (version == 999) {
2728 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2732 newpath = newpath_v;
2737 /* it doesn't exist, or we can't read it or something */
2741 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2742 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2743 (*x), newpath, strerror (errno))
2748 /* see if there an easy to find peakfile for this file, and remove it.
2751 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2752 peakpath += peakfile_suffix;
2754 if (access (peakpath.c_str(), W_OK) == 0) {
2755 if (::unlink (peakpath.c_str()) != 0) {
2756 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2757 peakpath, _path, strerror (errno))
2759 /* try to back out */
2760 rename (newpath.c_str(), _path.c_str());
2768 /* dump the history list */
2772 /* save state so we don't end up a session file
2773 referring to non-existent sources.
2779 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2785 Session::cleanup_trash_sources (CleanupReport& rep)
2787 // FIXME: needs adaptation for MIDI
2789 vector<space_and_path>::iterator i;
2790 string dead_sound_dir;
2795 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2797 dead_sound_dir = (*i).path;
2798 dead_sound_dir += dead_sound_dir_name;
2800 clear_directory (dead_sound_dir, &rep.space, &rep.paths);
2807 Session::cleanup_stubfiles ()
2809 vector<space_and_path>::iterator i;
2811 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2814 string lname = legalize_for_path (_name);
2818 /* XXX this is a hack caused by semantic conflicts
2819 between space_and_path and the SessionDirectory concept.
2822 v.push_back ((*i).path);
2823 v.push_back ("interchange");
2824 v.push_back (lname);
2825 v.push_back ("audiofiles");
2826 v.push_back (stub_dir_name);
2828 dir = Glib::build_filename (v);
2830 clear_directory (dir);
2833 v.push_back ((*i).path);
2834 v.push_back ("interchange");
2835 v.push_back (lname);
2836 v.push_back ("midifiles");
2837 v.push_back (stub_dir_name);
2839 dir = Glib::build_filename (v);
2841 clear_directory (dir);
2846 Session::set_dirty ()
2848 bool was_dirty = dirty();
2850 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2854 DirtyChanged(); /* EMIT SIGNAL */
2860 Session::set_clean ()
2862 bool was_dirty = dirty();
2864 _state_of_the_state = Clean;
2868 DirtyChanged(); /* EMIT SIGNAL */
2873 Session::set_deletion_in_progress ()
2875 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2879 Session::clear_deletion_in_progress ()
2881 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2885 Session::add_controllable (boost::shared_ptr<Controllable> c)
2887 /* this adds a controllable to the list managed by the Session.
2888 this is a subset of those managed by the Controllable class
2889 itself, and represents the only ones whose state will be saved
2890 as part of the session.
2893 Glib::Mutex::Lock lm (controllables_lock);
2894 controllables.insert (c);
2897 struct null_deleter { void operator()(void const *) const {} };
2900 Session::remove_controllable (Controllable* c)
2902 if (_state_of_the_state | Deletion) {
2906 Glib::Mutex::Lock lm (controllables_lock);
2908 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2910 if (x != controllables.end()) {
2911 controllables.erase (x);
2915 boost::shared_ptr<Controllable>
2916 Session::controllable_by_id (const PBD::ID& id)
2918 Glib::Mutex::Lock lm (controllables_lock);
2920 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2921 if ((*i)->id() == id) {
2926 return boost::shared_ptr<Controllable>();
2929 boost::shared_ptr<Controllable>
2930 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2932 boost::shared_ptr<Controllable> c;
2933 boost::shared_ptr<Route> r;
2935 switch (desc.top_level_type()) {
2936 case ControllableDescriptor::NamedRoute:
2938 std::string str = desc.top_level_name();
2939 if (str == "master") {
2941 } else if (str == "control" || str == "listen") {
2944 r = route_by_name (desc.top_level_name());
2949 case ControllableDescriptor::RemoteControlID:
2950 r = route_by_remote_id (desc.rid());
2958 switch (desc.subtype()) {
2959 case ControllableDescriptor::Gain:
2960 c = r->gain_control ();
2963 case ControllableDescriptor::Solo:
2964 c = r->solo_control();
2967 case ControllableDescriptor::Mute:
2968 c = r->mute_control();
2971 case ControllableDescriptor::Recenable:
2973 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2976 c = t->rec_enable_control ();
2981 case ControllableDescriptor::PanDirection:
2983 boost::shared_ptr<Panner> p = r->panner();
2985 c = p->direction_control();
2990 case ControllableDescriptor::PanWidth:
2992 boost::shared_ptr<Panner> p = r->panner();
2994 c = p->width_control();
2999 case ControllableDescriptor::Balance:
3000 /* XXX simple pan control */
3003 case ControllableDescriptor::PluginParameter:
3005 uint32_t plugin = desc.target (0);
3006 uint32_t parameter_index = desc.target (1);
3008 /* revert to zero based counting */
3014 if (parameter_index > 0) {
3018 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
3021 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
3022 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
3027 case ControllableDescriptor::SendGain:
3029 uint32_t send = desc.target (0);
3031 /* revert to zero-based counting */
3037 boost::shared_ptr<Processor> p = r->nth_send (send);
3040 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
3041 boost::shared_ptr<Amp> a = s->amp();
3044 c = s->amp()->gain_control();
3051 /* relax and return a null pointer */
3059 Session::add_instant_xml (XMLNode& node, bool write_to_config)
3062 Stateful::add_instant_xml (node, _path);
3065 if (write_to_config) {
3066 Config->add_instant_xml (node);
3071 Session::instant_xml (const string& node_name)
3073 return Stateful::instant_xml (node_name, _path);
3077 Session::save_history (string snapshot_name)
3085 if (snapshot_name.empty()) {
3086 snapshot_name = _current_snapshot_name;
3089 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
3090 const string backup_filename = history_filename + backup_suffix;
3091 const sys::path xml_path = _session_dir->root_path() / history_filename;
3092 const sys::path backup_path = _session_dir->root_path() / backup_filename;
3094 if (sys::exists (xml_path)) {
3097 sys::rename (xml_path, backup_path);
3099 catch (const sys::filesystem_error& err)
3101 error << _("could not backup old history file, current history not saved") << endmsg;
3106 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3110 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3112 if (!tree.write (xml_path.to_string()))
3114 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3118 sys::remove (xml_path);
3119 sys::rename (backup_path, xml_path);
3121 catch (const sys::filesystem_error& err)
3123 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3124 backup_path.to_string(), err.what()) << endmsg;
3134 Session::restore_history (string snapshot_name)
3138 if (snapshot_name.empty()) {
3139 snapshot_name = _current_snapshot_name;
3142 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3143 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3145 info << "Loading history from " << xml_path.to_string() << endmsg;
3147 if (!sys::exists (xml_path)) {
3148 info << string_compose (_("%1: no history file \"%2\" for this session."),
3149 _name, xml_path.to_string()) << endmsg;
3153 if (!tree.read (xml_path.to_string())) {
3154 error << string_compose (_("Could not understand session history file \"%1\""),
3155 xml_path.to_string()) << endmsg;
3162 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3165 UndoTransaction* ut = new UndoTransaction ();
3168 ut->set_name(t->property("name")->value());
3169 stringstream ss(t->property("tv-sec")->value());
3171 ss.str(t->property("tv-usec")->value());
3173 ut->set_timestamp(tv);
3175 for (XMLNodeConstIterator child_it = t->children().begin();
3176 child_it != t->children().end(); child_it++)
3178 XMLNode *n = *child_it;
3181 if (n->name() == "MementoCommand" ||
3182 n->name() == "MementoUndoCommand" ||
3183 n->name() == "MementoRedoCommand") {
3185 if ((c = memento_command_factory(n))) {
3189 } else if (n->name() == "NoteDiffCommand") {
3190 PBD::ID id (n->property("midi-source")->value());
3191 boost::shared_ptr<MidiSource> midi_source =
3192 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3194 ut->add_command (new MidiModel::NoteDiffCommand(midi_source->model(), *n));
3196 error << _("Failed to downcast MidiSource for NoteDiffCommand") << endmsg;
3199 } else if (n->name() == "StatefulDiffCommand") {
3200 if ((c = stateful_diff_command_factory (n))) {
3201 ut->add_command (c);
3204 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3215 Session::config_changed (std::string p, bool ours)
3221 if (p == "seamless-loop") {
3223 } else if (p == "rf-speed") {
3225 } else if (p == "auto-loop") {
3227 } else if (p == "auto-input") {
3229 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3230 /* auto-input only makes a difference if we're rolling */
3232 boost::shared_ptr<RouteList> rl = routes.reader ();
3233 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3234 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3235 if (tr && tr->record_enabled ()) {
3236 tr->monitor_input (!config.get_auto_input());
3241 } else if (p == "punch-in") {
3245 if ((location = _locations->auto_punch_location()) != 0) {
3247 if (config.get_punch_in ()) {
3248 replace_event (SessionEvent::PunchIn, location->start());
3250 remove_event (location->start(), SessionEvent::PunchIn);
3254 } else if (p == "punch-out") {
3258 if ((location = _locations->auto_punch_location()) != 0) {
3260 if (config.get_punch_out()) {
3261 replace_event (SessionEvent::PunchOut, location->end());
3263 clear_events (SessionEvent::PunchOut);
3267 } else if (p == "edit-mode") {
3269 Glib::Mutex::Lock lm (playlists->lock);
3271 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3272 (*i)->set_edit_mode (Config->get_edit_mode ());
3275 } else if (p == "use-video-sync") {
3277 waiting_for_sync_offset = config.get_use_video_sync();
3279 } else if (p == "mmc-control") {
3281 //poke_midi_thread ();
3283 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3285 MIDI::Manager::instance()->mmc()->set_receive_device_id (Config->get_mmc_receive_device_id());
3287 } else if (p == "mmc-send-id") {
3289 MIDI::Manager::instance()->mmc()->set_send_device_id (Config->get_mmc_send_device_id());
3291 } else if (p == "midi-control") {
3293 //poke_midi_thread ();
3295 } else if (p == "raid-path") {
3297 setup_raid_path (config.get_raid_path());
3299 } else if (p == "timecode-format") {
3303 } else if (p == "video-pullup") {
3307 } else if (p == "seamless-loop") {
3309 if (play_loop && transport_rolling()) {
3310 // to reset diskstreams etc
3311 request_play_loop (true);
3314 } else if (p == "rf-speed") {
3316 cumulative_rf_motion = 0;
3319 } else if (p == "click-sound") {
3321 setup_click_sounds (1);
3323 } else if (p == "click-emphasis-sound") {
3325 setup_click_sounds (-1);
3327 } else if (p == "clicking") {
3329 if (Config->get_clicking()) {
3330 if (_click_io && click_data) { // don't require emphasis data
3337 } else if (p == "send-mtc") {
3339 session_send_mtc = Config->get_send_mtc();
3340 if (session_send_mtc) {
3341 /* mark us ready to send */
3342 next_quarter_frame_to_send = 0;
3345 } else if (p == "send-mmc") {
3347 MIDI::Manager::instance()->mmc()->enable_send (Config->get_send_mmc ());
3349 } else if (p == "midi-feedback") {
3351 session_midi_feedback = Config->get_midi_feedback();
3353 } else if (p == "jack-time-master") {
3355 engine().reset_timebase ();
3357 } else if (p == "native-file-header-format") {
3359 if (!first_file_header_format_reset) {
3360 reset_native_file_format ();
3363 first_file_header_format_reset = false;
3365 } else if (p == "native-file-data-format") {
3367 if (!first_file_data_format_reset) {
3368 reset_native_file_format ();
3371 first_file_data_format_reset = false;
3373 } else if (p == "external-sync") {
3374 if (!config.get_external_sync()) {
3375 drop_sync_source ();
3377 switch_to_sync_source (config.get_sync_source());
3379 } else if (p == "remote-model") {
3380 set_remote_control_ids ();
3381 } else if (p == "denormal-model") {
3383 } else if (p == "history-depth") {
3384 set_history_depth (Config->get_history_depth());
3385 } else if (p == "sync-all-route-ordering") {
3386 sync_order_keys ("session");
3387 } else if (p == "initial-program-change") {
3389 if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {
3392 buf[0] = MIDI::program; // channel zero by default
3393 buf[1] = (Config->get_initial_program_change() & 0x7f);
3395 MIDI::Manager::instance()->mmc()->output_port()->midimsg (buf, sizeof (buf), 0);
3397 } else if (p == "solo-mute-override") {
3398 // catch_up_on_solo_mute_override ();
3399 } else if (p == "listen-position") {
3400 listen_position_changed ();
3401 } else if (p == "solo-control-is-listen-control") {
3402 solo_control_mode_changed ();
3403 } else if (p == "timecode-offset" || p == "timecode-offset-negative") {
3404 last_timecode_valid = false;
3411 Session::set_history_depth (uint32_t d)
3413 _history.set_depth (d);
3417 Session::load_diskstreams_2X (XMLNode const & node, int)
3420 XMLNodeConstIterator citer;
3422 clist = node.children();
3424 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3427 /* diskstreams added automatically by DiskstreamCreated handler */
3428 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3429 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3430 _diskstreams_2X.push_back (dsp);
3432 error << _("Session: unknown diskstream type in XML") << endmsg;
3436 catch (failed_constructor& err) {
3437 error << _("Session: could not load diskstream via XML state") << endmsg;
3445 /** Connect things to the MMC object */
3447 Session::setup_midi_machine_control ()
3449 MIDI::MachineControl* mmc = MIDI::Manager::instance()->mmc ();
3451 mmc->Play.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3452 mmc->DeferredPlay.connect_same_thread (*this, boost::bind (&Session::mmc_deferred_play, this, _1));
3453 mmc->Stop.connect_same_thread (*this, boost::bind (&Session::mmc_stop, this, _1));
3454 mmc->FastForward.connect_same_thread (*this, boost::bind (&Session::mmc_fast_forward, this, _1));
3455 mmc->Rewind.connect_same_thread (*this, boost::bind (&Session::mmc_rewind, this, _1));
3456 mmc->Pause.connect_same_thread (*this, boost::bind (&Session::mmc_pause, this, _1));
3457 mmc->RecordPause.connect_same_thread (*this, boost::bind (&Session::mmc_record_pause, this, _1));
3458 mmc->RecordStrobe.connect_same_thread (*this, boost::bind (&Session::mmc_record_strobe, this, _1));
3459 mmc->RecordExit.connect_same_thread (*this, boost::bind (&Session::mmc_record_exit, this, _1));
3460 mmc->Locate.connect_same_thread (*this, boost::bind (&Session::mmc_locate, this, _1, _2));
3461 mmc->Step.connect_same_thread (*this, boost::bind (&Session::mmc_step, this, _1, _2));
3462 mmc->Shuttle.connect_same_thread (*this, boost::bind (&Session::mmc_shuttle, this, _1, _2, _3));
3463 mmc->TrackRecordStatusChange.connect_same_thread (*this, boost::bind (&Session::mmc_record_enable, this, _1, _2, _3));
3465 /* also handle MIDI SPP because its so common */
3467 mmc->SPPStart.connect_same_thread (*this, boost::bind (&Session::spp_start, this, _1, _2));
3468 mmc->SPPContinue.connect_same_thread (*this, boost::bind (&Session::spp_continue, this, _1, _2));
3469 mmc->SPPStop.connect_same_thread (*this, boost::bind (&Session::spp_stop, this, _1, _2));