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"
25 #define __STDC_FORMAT_MACROS 1
34 #include <cstdio> /* snprintf(3) ... grrr */
49 #include <sys/param.h>
50 #include <sys/mount.h>
54 #include <glibmm/thread.h>
56 #include "midi++/mmc.h"
57 #include "midi++/port.h"
59 #include "pbd/boost_debug.h"
60 #include "pbd/controllable_descriptor.h"
61 #include "pbd/enumwriter.h"
62 #include "pbd/error.h"
63 #include "pbd/pathscanner.h"
64 #include "pbd/pthread_utils.h"
65 #include "pbd/search_path.h"
66 #include "pbd/stacktrace.h"
67 #include "pbd/convert.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/buffer.h"
78 #include "ardour/butler.h"
79 #include "ardour/configuration.h"
80 #include "ardour/control_protocol_manager.h"
81 #include "ardour/crossfade.h"
82 #include "ardour/cycle_timer.h"
83 #include "ardour/directory_names.h"
84 #include "ardour/filename_extensions.h"
85 #include "ardour/io_processor.h"
86 #include "ardour/location.h"
87 #include "ardour/midi_diskstream.h"
88 #include "ardour/midi_patch_manager.h"
89 #include "ardour/midi_playlist.h"
90 #include "ardour/midi_region.h"
91 #include "ardour/midi_source.h"
92 #include "ardour/midi_track.h"
93 #include "ardour/named_selection.h"
94 #include "ardour/processor.h"
95 #include "ardour/region_factory.h"
96 #include "ardour/route_group.h"
97 #include "ardour/send.h"
98 #include "ardour/session.h"
99 #include "ardour/session_directory.h"
100 #include "ardour/session_metadata.h"
101 #include "ardour/session_state_utils.h"
102 #include "ardour/session_playlists.h"
103 #include "ardour/session_utils.h"
104 #include "ardour/silentfilesource.h"
105 #include "ardour/slave.h"
106 #include "ardour/smf_source.h"
107 #include "ardour/sndfile_helpers.h"
108 #include "ardour/sndfilesource.h"
109 #include "ardour/source_factory.h"
110 #include "ardour/template_utils.h"
111 #include "ardour/tempo.h"
112 #include "ardour/ticker.h"
113 #include "ardour/user_bundle.h"
114 #include "ardour/utils.h"
115 #include "ardour/utils.h"
116 #include "ardour/version.h"
117 #include "ardour/playlist_factory.h"
119 #include "control_protocol/control_protocol.h"
125 using namespace ARDOUR;
129 Session::first_stage_init (string fullpath, string snapshot_name)
131 if (fullpath.length() == 0) {
133 throw failed_constructor();
136 char buf[PATH_MAX+1];
137 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
138 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
140 throw failed_constructor();
145 if (_path[_path.length()-1] != '/') {
149 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
155 /* these two are just provisional settings. set_state()
156 will likely override them.
159 _name = _current_snapshot_name = snapshot_name;
161 set_history_depth (Config->get_history_depth());
163 _current_frame_rate = _engine.frame_rate ();
164 _nominal_frame_rate = _current_frame_rate;
165 _base_frame_rate = _current_frame_rate;
167 _tempo_map = new TempoMap (_current_frame_rate);
168 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
171 _non_soloed_outs_muted = false;
173 _solo_isolated_cnt = 0;
174 g_atomic_int_set (&processing_prohibited, 0);
175 _transport_speed = 0;
176 _last_transport_speed = 0;
177 _target_transport_speed = 0;
178 auto_play_legal = false;
179 transport_sub_state = 0;
180 _transport_frame = 0;
181 _requested_return_frame = -1;
182 _session_range_location = 0;
183 g_atomic_int_set (&_record_status, Disabled);
184 loop_changing = false;
187 _last_roll_location = 0;
188 _last_roll_or_reversal_location = 0;
189 _last_record_location = 0;
190 pending_locate_frame = 0;
191 pending_locate_roll = false;
192 pending_locate_flush = false;
193 state_was_pending = false;
195 outbound_mtc_timecode_frame = 0;
196 next_quarter_frame_to_send = -1;
197 current_block_size = 0;
198 solo_update_disabled = false;
199 _have_captured = false;
200 _worst_output_latency = 0;
201 _worst_input_latency = 0;
202 _worst_track_latency = 0;
203 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
204 _was_seamless = Config->get_seamless_loop ();
206 session_send_mmc = false;
207 session_send_mtc = false;
208 g_atomic_int_set (&_playback_load, 100);
209 g_atomic_int_set (&_capture_load, 100);
210 g_atomic_int_set (&_playback_load_min, 100);
211 g_atomic_int_set (&_capture_load_min, 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 AudioDiskstream::allocate_working_buffers();
223 /* default short fade = 15ms */
225 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
226 SndFileSource::setup_standard_crossfades (*this, frame_rate());
228 last_mmc_step.tv_sec = 0;
229 last_mmc_step.tv_usec = 0;
232 /* click sounds are unset by default, which causes us to internal
233 waveforms for clicks.
237 click_emphasis_length = 0;
240 process_function = &Session::process_with_events;
242 if (config.get_use_video_sync()) {
243 waiting_for_sync_offset = true;
245 waiting_for_sync_offset = false;
248 last_timecode_when = 0;
249 _timecode_offset = 0;
250 _timecode_offset_negative = true;
251 last_timecode_valid = false;
255 last_rr_session_dir = session_dirs.begin();
256 refresh_disk_space ();
258 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
262 average_slave_delta = 1800; // !!! why 1800 ????
263 have_first_delta_accumulator = false;
264 delta_accumulator_cnt = 0;
265 _slave_state = Stopped;
267 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
269 /* These are all static "per-class" signals */
271 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
272 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
273 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
274 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
275 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
277 /* stop IO objects from doing stuff until we're ready for them */
279 Delivery::disable_panners ();
280 IO::disable_connecting ();
284 Session::second_stage_init ()
286 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
289 if (load_state (_current_snapshot_name)) {
292 remove_empty_sounds ();
295 if (_butler->start_thread()) {
299 if (start_midi_thread ()) {
303 // set_state() will call setup_raid_path(), but if it's a new session we need
304 // to call setup_raid_path() here.
307 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
311 setup_raid_path(_path);
314 /* we can't save till after ::when_engine_running() is called,
315 because otherwise we save state with no connections made.
316 therefore, we reset _state_of_the_state because ::set_state()
317 will have cleared it.
319 we also have to include Loading so that any events that get
320 generated between here and the end of ::when_engine_running()
321 will be processed directly rather than queued.
324 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
327 _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
328 _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
329 setup_click_sounds (0);
330 setup_midi_control ();
332 /* Pay attention ... */
334 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
335 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
338 when_engine_running ();
341 /* handle this one in a different way than all others, so that its clear what happened */
343 catch (AudioEngine::PortRegistrationFailure& err) {
344 error << err.what() << endmsg;
352 BootMessage (_("Reset Remote Controls"));
354 send_full_time_code (0);
355 _engine.transport_locate (0);
356 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
357 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
359 MidiClockTicker::instance().set_session (this);
360 MIDI::Name::MidiPatchManager::instance().set_session (this);
362 /* initial program change will be delivered later; see ::config_changed() */
364 BootMessage (_("Reset Control Protocols"));
366 ControlProtocolManager::instance().set_session (this);
368 _state_of_the_state = Clean;
370 DirtyChanged (); /* EMIT SIGNAL */
372 if (state_was_pending) {
373 save_state (_current_snapshot_name);
374 remove_pending_capture_state ();
375 state_was_pending = false;
378 BootMessage (_("Session loading complete"));
384 Session::raid_path () const
386 SearchPath raid_search_path;
388 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
389 raid_search_path += sys::path((*i).path);
392 return raid_search_path.to_string ();
396 Session::setup_raid_path (string path)
405 session_dirs.clear ();
407 SearchPath search_path(path);
408 SearchPath sound_search_path;
409 SearchPath midi_search_path;
411 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
412 sp.path = (*i).to_string ();
413 sp.blocks = 0; // not needed
414 session_dirs.push_back (sp);
416 SessionDirectory sdir(sp.path);
418 sound_search_path += sdir.sound_path ();
419 midi_search_path += sdir.midi_path ();
422 // set the search path for each data type
423 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
424 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
426 // reset the round-robin soundfile path thingie
427 last_rr_session_dir = session_dirs.begin();
431 Session::path_is_within_session (const std::string& path)
433 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
434 if (path.find ((*i).path) == 0) {
442 Session::ensure_subdirs ()
446 dir = session_directory().peak_path().to_string();
448 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
449 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
453 dir = session_directory().sound_path().to_string();
455 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
456 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
460 dir = session_directory().midi_path().to_string();
462 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
463 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
467 dir = session_directory().dead_sound_path().to_string();
469 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
470 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
474 dir = session_directory().export_path().to_string();
476 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
477 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
481 dir = analysis_dir ();
483 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
484 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
492 Session::create (const string& mix_template, BusProfile* bus_profile)
495 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
496 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
500 if (ensure_subdirs ()) {
504 if (!mix_template.empty()) {
505 std::string in_path = mix_template;
507 ifstream in(in_path.c_str());
510 string out_path = _path;
512 out_path += statefile_suffix;
514 ofstream out(out_path.c_str());
522 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
528 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
535 /* Instantiate metadata */
537 _metadata = new SessionMetadata ();
539 /* set initial start + end point */
541 _state_of_the_state = Clean;
543 /* set up Master Out and Control Out if necessary */
549 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
551 if (bus_profile->master_out_channels) {
552 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
557 boost_debug_shared_ptr_mark_interesting (rt, "Route");
558 boost::shared_ptr<Route> r (rt);
559 r->input()->ensure_io (count, false, this);
560 r->output()->ensure_io (count, false, this);
561 r->set_remote_control_id (control_id++);
565 if (Config->get_use_monitor_bus()) {
566 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
571 boost_debug_shared_ptr_mark_interesting (rt, "Route");
572 boost::shared_ptr<Route> r (rt);
573 r->input()->ensure_io (count, false, this);
574 r->output()->ensure_io (count, false, this);
575 r->set_remote_control_id (control_id);
581 /* prohibit auto-connect to master, because there isn't one */
582 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
586 add_routes (rl, false);
589 /* this allows the user to override settings with an environment variable.
592 if (no_auto_connect()) {
593 bus_profile->input_ac = AutoConnectOption (0);
594 bus_profile->output_ac = AutoConnectOption (0);
597 Config->set_input_auto_connect (bus_profile->input_ac);
598 Config->set_output_auto_connect (bus_profile->output_ac);
607 Session::maybe_write_autosave()
609 if (dirty() && record_status() != Recording) {
610 save_state("", true);
615 Session::remove_pending_capture_state ()
617 sys::path pending_state_file_path(_session_dir->root_path());
619 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
623 sys::remove (pending_state_file_path);
625 catch(sys::filesystem_error& ex)
627 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
628 pending_state_file_path.to_string(), ex.what()) << endmsg;
632 /** Rename a state file.
633 * @param snapshot_name Snapshot name.
636 Session::rename_state (string old_name, string new_name)
638 if (old_name == _current_snapshot_name || old_name == _name) {
639 /* refuse to rename the current snapshot or the "main" one */
643 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
644 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
646 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
647 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
651 sys::rename (old_xml_path, new_xml_path);
653 catch (const sys::filesystem_error& err)
655 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
656 old_name, new_name, err.what()) << endmsg;
660 /** Remove a state file.
661 * @param snapshot_name Snapshot name.
664 Session::remove_state (string snapshot_name)
666 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
667 // refuse to remove the current snapshot or the "main" one
671 sys::path xml_path(_session_dir->root_path());
673 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
675 if (!create_backup_file (xml_path)) {
676 // don't remove it if a backup can't be made
677 // create_backup_file will log the error.
682 sys::remove (xml_path);
685 #ifdef HAVE_JACK_SESSION
687 Session::jack_session_event (jack_session_event_t * event)
689 if (save_state ("jacksession_snap")) {
690 event->flags = JackSessionSaveError;
692 sys::path xml_path (_session_dir->root_path());
693 xml_path /= legalize_for_path ("jacksession_snap") + statefile_suffix;
695 string cmd ("PROG_NAME -U ");
696 cmd += event->client_uuid;
698 cmd += xml_path.to_string();
701 event->command_line = strdup (cmd.c_str());
704 jack_session_reply (_engine.jack(), event);
706 if (event->type == JackSessionSaveAndQuit) {
707 // TODO: make ardour quit.
710 jack_session_event_free( event );
715 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
718 sys::path xml_path(_session_dir->root_path());
720 if (!_writable || (_state_of_the_state & CannotSave)) {
724 if (!_engine.connected ()) {
725 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
731 /* tell sources we're saving first, in case they write out to a new file
732 * which should be saved with the state rather than the old one */
733 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
734 i->second->session_saved();
736 tree.set_root (&get_state());
738 if (snapshot_name.empty()) {
739 snapshot_name = _current_snapshot_name;
740 } else if (switch_to_snapshot) {
741 _current_snapshot_name = snapshot_name;
746 /* proper save: use statefile_suffix (.ardour in English) */
748 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
750 /* make a backup copy of the old file */
752 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
753 // create_backup_file will log the error
759 /* pending save: use pending_suffix (.pending in English) */
760 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
763 sys::path tmp_path(_session_dir->root_path());
765 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
767 // cerr << "actually writing state to " << xml_path.to_string() << endl;
769 if (!tree.write (tmp_path.to_string())) {
770 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
771 sys::remove (tmp_path);
776 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
777 error << string_compose (_("could not rename temporary session file %1 to %2"),
778 tmp_path.to_string(), xml_path.to_string()) << endmsg;
779 sys::remove (tmp_path);
786 save_history (snapshot_name);
788 bool was_dirty = dirty();
790 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
793 DirtyChanged (); /* EMIT SIGNAL */
796 StateSaved (snapshot_name); /* EMIT SIGNAL */
803 Session::restore_state (string snapshot_name)
805 if (load_state (snapshot_name) == 0) {
806 set_state (*state_tree->root(), Stateful::loading_state_version);
813 Session::load_state (string snapshot_name)
818 state_was_pending = false;
820 /* check for leftover pending state from a crashed capture attempt */
822 sys::path xmlpath(_session_dir->root_path());
823 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
825 if (sys::exists (xmlpath)) {
827 /* there is pending state from a crashed capture attempt */
829 if (*AskAboutPendingState()) {
830 state_was_pending = true;
834 if (!state_was_pending) {
835 xmlpath = _session_dir->root_path();
836 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
839 if (!sys::exists (xmlpath)) {
840 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
844 state_tree = new XMLTree;
848 /* writable() really reflects the whole folder, but if for any
849 reason the session state file can't be written to, still
853 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
857 if (!state_tree->read (xmlpath.to_string())) {
858 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
864 XMLNode& root (*state_tree->root());
866 if (root.name() != X_("Session")) {
867 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
873 const XMLProperty* prop;
875 if ((prop = root.property ("version")) == 0) {
876 /* no version implies very old version of Ardour */
877 Stateful::loading_state_version = 1000;
883 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
884 Stateful::loading_state_version = (major * 1000) + minor;
887 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
889 sys::path backup_path(_session_dir->root_path());
891 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
893 // only create a backup once
894 if (sys::exists (backup_path)) {
898 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
899 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
904 sys::copy_file (xmlpath, backup_path);
906 catch(sys::filesystem_error& ex)
908 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
909 xmlpath.to_string(), ex.what())
919 Session::load_options (const XMLNode& node)
921 LocaleGuard lg (X_("POSIX"));
922 config.set_variables (node);
933 Session::get_template()
935 /* if we don't disable rec-enable, diskstreams
936 will believe they need to store their capture
937 sources in their state node.
940 disable_record (false);
946 Session::state(bool full_state)
948 XMLNode* node = new XMLNode("Session");
951 // store libardour version, just in case
953 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
954 node->add_property("version", string(buf));
956 /* store configuration settings */
960 node->add_property ("name", _name);
961 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
962 node->add_property ("sample-rate", buf);
964 if (session_dirs.size() > 1) {
968 vector<space_and_path>::iterator i = session_dirs.begin();
969 vector<space_and_path>::iterator next;
971 ++i; /* skip the first one */
975 while (i != session_dirs.end()) {
979 if (next != session_dirs.end()) {
989 child = node->add_child ("Path");
990 child->add_content (p);
994 /* save the ID counter */
996 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
997 node->add_property ("id-counter", buf);
999 /* various options */
1001 node->add_child_nocopy (config.get_variables ());
1003 node->add_child_nocopy (_metadata->get_state());
1005 child = node->add_child ("Sources");
1008 Glib::Mutex::Lock sl (source_lock);
1010 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1012 /* Don't save information about non-destructive file sources that are empty */
1013 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
1015 boost::shared_ptr<AudioFileSource> fs;
1016 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
1017 if (!fs->destructive()) {
1018 if (fs->length(fs->timeline_position()) == 0) {
1024 child->add_child_nocopy (siter->second->get_state());
1028 child = node->add_child ("Regions");
1031 Glib::Mutex::Lock rl (region_lock);
1032 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1033 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1034 boost::shared_ptr<Region> r = i->second;
1035 /* only store regions not attached to playlists */
1036 if (r->playlist() == 0) {
1037 child->add_child_nocopy (r->state (true));
1043 node->add_child_nocopy (_locations.get_state());
1045 // for a template, just create a new Locations, populate it
1046 // with the default start and end, and get the state for that.
1048 Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
1049 range->set (max_frames, 0);
1051 node->add_child_nocopy (loc.get_state());
1054 child = node->add_child ("Bundles");
1056 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1057 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1058 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1060 child->add_child_nocopy (b->get_state());
1065 child = node->add_child ("Routes");
1067 boost::shared_ptr<RouteList> r = routes.reader ();
1069 RoutePublicOrderSorter cmp;
1070 RouteList public_order (*r);
1071 public_order.sort (cmp);
1073 /* the sort should have put control outs first */
1076 assert (_monitor_out == public_order.front());
1079 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1080 if (!(*i)->is_hidden()) {
1082 child->add_child_nocopy ((*i)->get_state());
1084 child->add_child_nocopy ((*i)->get_template());
1090 playlists->add_state (node, full_state);
1092 child = node->add_child ("RouteGroups");
1093 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1094 child->add_child_nocopy ((*i)->get_state());
1098 child = node->add_child ("Click");
1099 child->add_child_nocopy (_click_io->state (full_state));
1103 child = node->add_child ("NamedSelections");
1104 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1106 child->add_child_nocopy ((*i)->get_state());
1111 node->add_child_nocopy (_tempo_map->get_state());
1113 node->add_child_nocopy (get_control_protocol_state());
1116 node->add_child_copy (*_extra_xml);
1123 Session::get_control_protocol_state ()
1125 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1126 return cpm.get_state();
1130 Session::set_state (const XMLNode& node, int version)
1134 const XMLProperty* prop;
1137 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1139 if (node.name() != X_("Session")){
1140 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1144 if ((prop = node.property ("version")) != 0) {
1145 version = atoi (prop->value ()) * 1000;
1148 if ((prop = node.property ("name")) != 0) {
1149 _name = prop->value ();
1152 if ((prop = node.property (X_("sample-rate"))) != 0) {
1154 _nominal_frame_rate = atoi (prop->value());
1156 if (_nominal_frame_rate != _current_frame_rate) {
1157 if (*AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1163 setup_raid_path(_session_dir->root_path().to_string());
1165 if ((prop = node.property (X_("id-counter"))) != 0) {
1167 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1168 ID::init_counter (x);
1170 /* old sessions used a timebased counter, so fake
1171 the startup ID counter based on a standard
1176 ID::init_counter (now);
1180 IO::disable_connecting ();
1182 /* Object loading order:
1187 MIDI Control // relies on data from Options/Config
1200 if ((child = find_named_node (node, "Extra")) != 0) {
1201 _extra_xml = new XMLNode (*child);
1204 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1205 load_options (*child);
1206 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1207 load_options (*child);
1209 error << _("Session: XML state has no options section") << endmsg;
1212 if (use_config_midi_ports ()) {
1215 if (version >= 3000) {
1216 if ((child = find_named_node (node, "Metadata")) == 0) {
1217 warning << _("Session: XML state has no metadata section") << endmsg;
1218 } else if (_metadata->set_state (*child, version)) {
1223 if ((child = find_named_node (node, "Locations")) == 0) {
1224 error << _("Session: XML state has no locations section") << endmsg;
1226 } else if (_locations.set_state (*child, version)) {
1232 if ((location = _locations.auto_loop_location()) != 0) {
1233 set_auto_loop_location (location);
1236 if ((location = _locations.auto_punch_location()) != 0) {
1237 set_auto_punch_location (location);
1240 if ((location = _locations.session_range_location()) != 0) {
1241 delete _session_range_location;
1242 _session_range_location = location;
1245 if (_session_range_location) {
1246 AudioFileSource::set_header_position_offset (_session_range_location->start());
1249 if ((child = find_named_node (node, "Sources")) == 0) {
1250 error << _("Session: XML state has no sources section") << endmsg;
1252 } else if (load_sources (*child)) {
1256 if ((child = find_named_node (node, "Regions")) == 0) {
1257 error << _("Session: XML state has no Regions section") << endmsg;
1259 } else if (load_regions (*child)) {
1263 if ((child = find_named_node (node, "Playlists")) == 0) {
1264 error << _("Session: XML state has no playlists section") << endmsg;
1266 } else if (playlists->load (*this, *child)) {
1270 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1272 } else if (playlists->load_unused (*this, *child)) {
1276 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1277 if (load_named_selections (*child)) {
1282 if (version >= 3000) {
1283 if ((child = find_named_node (node, "Bundles")) == 0) {
1284 warning << _("Session: XML state has no bundles section") << endmsg;
1287 /* We can't load Bundles yet as they need to be able
1288 to convert from port names to Port objects, which can't happen until
1290 _bundle_xml_node = new XMLNode (*child);
1294 if ((child = find_named_node (node, "TempoMap")) == 0) {
1295 error << _("Session: XML state has no Tempo Map section") << endmsg;
1297 } else if (_tempo_map->set_state (*child, version)) {
1301 if (version < 3000) {
1302 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1303 error << _("Session: XML state has no diskstreams section") << endmsg;
1305 } else if (load_diskstreams_2X (*child, version)) {
1310 if ((child = find_named_node (node, "Routes")) == 0) {
1311 error << _("Session: XML state has no routes section") << endmsg;
1313 } else if (load_routes (*child, version)) {
1317 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1318 _diskstreams_2X.clear ();
1320 if (version >= 3000) {
1322 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1323 error << _("Session: XML state has no route groups section") << endmsg;
1325 } else if (load_route_groups (*child, version)) {
1329 } else if (version < 3000) {
1331 if ((child = find_named_node (node, "EditGroups")) == 0) {
1332 error << _("Session: XML state has no edit groups section") << endmsg;
1334 } else if (load_route_groups (*child, version)) {
1338 if ((child = find_named_node (node, "MixGroups")) == 0) {
1339 error << _("Session: XML state has no mix groups section") << endmsg;
1341 } else if (load_route_groups (*child, version)) {
1346 if ((child = find_named_node (node, "Click")) == 0) {
1347 warning << _("Session: XML state has no click section") << endmsg;
1348 } else if (_click_io) {
1349 _click_io->set_state (*child, version);
1352 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1353 ControlProtocolManager::instance().set_protocol_states (*child);
1356 /* here beginneth the second phase ... */
1358 StateReady (); /* EMIT SIGNAL */
1367 Session::load_routes (const XMLNode& node, int version)
1370 XMLNodeConstIterator niter;
1371 RouteList new_routes;
1373 nlist = node.children();
1377 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1379 boost::shared_ptr<Route> route;
1380 if (version < 3000) {
1381 route = XMLRouteFactory_2X (**niter, version);
1383 route = XMLRouteFactory (**niter, version);
1387 error << _("Session: cannot create Route from XML description.") << endmsg;
1391 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1393 new_routes.push_back (route);
1396 add_routes (new_routes, false);
1401 boost::shared_ptr<Route>
1402 Session::XMLRouteFactory (const XMLNode& node, int version)
1404 boost::shared_ptr<Route> ret;
1406 if (node.name() != "Route") {
1410 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1412 DataType type = DataType::AUDIO;
1413 const XMLProperty* prop = node.property("default-type");
1416 type = DataType (prop->value());
1419 assert (type != DataType::NIL);
1425 if (type == DataType::AUDIO) {
1426 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1429 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1432 if (track->init()) {
1437 if (track->set_state (node, version)) {
1442 boost_debug_shared_ptr_mark_interesting (track, "Track");
1446 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1448 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1449 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1459 boost::shared_ptr<Route>
1460 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1462 boost::shared_ptr<Route> ret;
1464 if (node.name() != "Route") {
1468 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1470 ds_prop = node.property (X_("diskstream"));
1473 DataType type = DataType::AUDIO;
1474 const XMLProperty* prop = node.property("default-type");
1477 type = DataType (prop->value());
1480 assert (type != DataType::NIL);
1484 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1485 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1489 if (i == _diskstreams_2X.end()) {
1490 error << _("Could not find diskstream for route") << endmsg;
1491 return boost::shared_ptr<Route> ();
1496 if (type == DataType::AUDIO) {
1497 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1500 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1503 if (track->init()) {
1508 if (track->set_state (node, version)) {
1513 track->set_diskstream (*i);
1515 boost_debug_shared_ptr_mark_interesting (track, "Track");
1519 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1521 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1522 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1533 Session::load_regions (const XMLNode& node)
1536 XMLNodeConstIterator niter;
1537 boost::shared_ptr<Region> region;
1539 nlist = node.children();
1543 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1544 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1545 error << _("Session: cannot create Region from XML description.");
1546 const XMLProperty *name = (**niter).property("name");
1549 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1559 boost::shared_ptr<Region>
1560 Session::XMLRegionFactory (const XMLNode& node, bool full)
1562 const XMLProperty* type = node.property("type");
1566 if ( !type || type->value() == "audio" ) {
1568 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1570 } else if (type->value() == "midi") {
1572 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1576 } catch (failed_constructor& err) {
1577 return boost::shared_ptr<Region> ();
1580 return boost::shared_ptr<Region> ();
1583 boost::shared_ptr<AudioRegion>
1584 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1586 const XMLProperty* prop;
1587 boost::shared_ptr<Source> source;
1588 boost::shared_ptr<AudioSource> as;
1590 SourceList master_sources;
1591 uint32_t nchans = 1;
1594 if (node.name() != X_("Region")) {
1595 return boost::shared_ptr<AudioRegion>();
1598 if ((prop = node.property (X_("channels"))) != 0) {
1599 nchans = atoi (prop->value().c_str());
1602 if ((prop = node.property ("name")) == 0) {
1603 cerr << "no name for this region\n";
1607 if ((prop = node.property (X_("source-0"))) == 0) {
1608 if ((prop = node.property ("source")) == 0) {
1609 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1610 return boost::shared_ptr<AudioRegion>();
1614 PBD::ID s_id (prop->value());
1616 if ((source = source_by_id (s_id)) == 0) {
1617 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1618 return boost::shared_ptr<AudioRegion>();
1621 as = boost::dynamic_pointer_cast<AudioSource>(source);
1623 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1624 return boost::shared_ptr<AudioRegion>();
1627 sources.push_back (as);
1629 /* pickup other channels */
1631 for (uint32_t n=1; n < nchans; ++n) {
1632 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1633 if ((prop = node.property (buf)) != 0) {
1635 PBD::ID id2 (prop->value());
1637 if ((source = source_by_id (id2)) == 0) {
1638 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1639 return boost::shared_ptr<AudioRegion>();
1642 as = boost::dynamic_pointer_cast<AudioSource>(source);
1644 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1645 return boost::shared_ptr<AudioRegion>();
1647 sources.push_back (as);
1651 for (uint32_t n = 0; n < nchans; ++n) {
1652 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1653 if ((prop = node.property (buf)) != 0) {
1655 PBD::ID id2 (prop->value());
1657 if ((source = source_by_id (id2)) == 0) {
1658 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1659 return boost::shared_ptr<AudioRegion>();
1662 as = boost::dynamic_pointer_cast<AudioSource>(source);
1664 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1665 return boost::shared_ptr<AudioRegion>();
1667 master_sources.push_back (as);
1672 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1674 /* a final detail: this is the one and only place that we know how long missing files are */
1676 if (region->whole_file()) {
1677 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1678 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1680 sfp->set_length (region->length());
1685 if (!master_sources.empty()) {
1686 if (master_sources.size() != nchans) {
1687 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1689 region->set_master_sources (master_sources);
1697 catch (failed_constructor& err) {
1698 return boost::shared_ptr<AudioRegion>();
1702 boost::shared_ptr<MidiRegion>
1703 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1705 const XMLProperty* prop;
1706 boost::shared_ptr<Source> source;
1707 boost::shared_ptr<MidiSource> ms;
1709 uint32_t nchans = 1;
1711 if (node.name() != X_("Region")) {
1712 return boost::shared_ptr<MidiRegion>();
1715 if ((prop = node.property (X_("channels"))) != 0) {
1716 nchans = atoi (prop->value().c_str());
1719 if ((prop = node.property ("name")) == 0) {
1720 cerr << "no name for this region\n";
1724 // Multiple midi channels? that's just crazy talk
1725 assert(nchans == 1);
1727 if ((prop = node.property (X_("source-0"))) == 0) {
1728 if ((prop = node.property ("source")) == 0) {
1729 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1730 return boost::shared_ptr<MidiRegion>();
1734 PBD::ID s_id (prop->value());
1736 if ((source = source_by_id (s_id)) == 0) {
1737 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1738 return boost::shared_ptr<MidiRegion>();
1741 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1743 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1744 return boost::shared_ptr<MidiRegion>();
1747 sources.push_back (ms);
1750 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1751 /* a final detail: this is the one and only place that we know how long missing files are */
1753 if (region->whole_file()) {
1754 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1755 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1757 sfp->set_length (region->length());
1765 catch (failed_constructor& err) {
1766 return boost::shared_ptr<MidiRegion>();
1771 Session::get_sources_as_xml ()
1774 XMLNode* node = new XMLNode (X_("Sources"));
1775 Glib::Mutex::Lock lm (source_lock);
1777 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1778 node->add_child_nocopy (i->second->get_state());
1785 Session::path_from_region_name (DataType type, string name, string identifier)
1787 char buf[PATH_MAX+1];
1789 SessionDirectory sdir(get_best_session_directory_for_new_source());
1790 sys::path source_dir = ((type == DataType::AUDIO)
1791 ? sdir.sound_path() : sdir.midi_path());
1793 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1795 for (n = 0; n < 999999; ++n) {
1796 if (identifier.length()) {
1797 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1798 identifier.c_str(), n, ext.c_str());
1800 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1804 sys::path source_path = source_dir / buf;
1806 if (!sys::exists (source_path)) {
1807 return source_path.to_string();
1811 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1820 Session::load_sources (const XMLNode& node)
1823 XMLNodeConstIterator niter;
1824 boost::shared_ptr<Source> source;
1826 nlist = node.children();
1830 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1832 if ((source = XMLSourceFactory (**niter)) == 0) {
1833 error << _("Session: cannot create Source from XML description.") << endmsg;
1835 } catch (MissingSource& err) {
1836 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1837 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1844 boost::shared_ptr<Source>
1845 Session::XMLSourceFactory (const XMLNode& node)
1847 if (node.name() != "Source") {
1848 return boost::shared_ptr<Source>();
1852 /* note: do peak building in another thread when loading session state */
1853 return SourceFactory::create (*this, node, true);
1856 catch (failed_constructor& err) {
1857 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1858 return boost::shared_ptr<Source>();
1863 Session::save_template (string template_name)
1867 if (_state_of_the_state & CannotSave) {
1871 sys::path user_template_dir(user_template_directory());
1875 sys::create_directories (user_template_dir);
1877 catch(sys::filesystem_error& ex)
1879 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1880 user_template_dir.to_string(), ex.what()) << endmsg;
1884 tree.set_root (&get_template());
1886 sys::path template_file_path(user_template_dir);
1887 template_file_path /= template_name + template_suffix;
1889 if (sys::exists (template_file_path))
1891 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1892 template_file_path.to_string()) << endmsg;
1896 if (!tree.write (template_file_path.to_string())) {
1897 error << _("mix template not saved") << endmsg;
1905 Session::rename_template (string old_name, string new_name)
1907 sys::path old_path (user_template_directory());
1908 old_path /= old_name + template_suffix;
1910 sys::path new_path(user_template_directory());
1911 new_path /= new_name + template_suffix;
1913 if (sys::exists (new_path)) {
1914 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1915 new_path.to_string()) << endmsg;
1920 sys::rename (old_path, new_path);
1928 Session::delete_template (string name)
1930 sys::path path = user_template_directory();
1931 path /= name + template_suffix;
1942 Session::refresh_disk_space ()
1945 struct statfs statfsbuf;
1946 vector<space_and_path>::iterator i;
1947 Glib::Mutex::Lock lm (space_lock);
1950 /* get freespace on every FS that is part of the session path */
1952 _total_free_4k_blocks = 0;
1954 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1955 statfs ((*i).path.c_str(), &statfsbuf);
1957 scale = statfsbuf.f_bsize/4096.0;
1959 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1960 _total_free_4k_blocks += (*i).blocks;
1966 Session::get_best_session_directory_for_new_source ()
1968 vector<space_and_path>::iterator i;
1969 string result = _session_dir->root_path().to_string();
1971 /* handle common case without system calls */
1973 if (session_dirs.size() == 1) {
1977 /* OK, here's the algorithm we're following here:
1979 We want to select which directory to use for
1980 the next file source to be created. Ideally,
1981 we'd like to use a round-robin process so as to
1982 get maximum performance benefits from splitting
1983 the files across multiple disks.
1985 However, in situations without much diskspace, an
1986 RR approach may end up filling up a filesystem
1987 with new files while others still have space.
1988 Its therefore important to pay some attention to
1989 the freespace in the filesystem holding each
1990 directory as well. However, if we did that by
1991 itself, we'd keep creating new files in the file
1992 system with the most space until it was as full
1993 as all others, thus negating any performance
1994 benefits of this RAID-1 like approach.
1996 So, we use a user-configurable space threshold. If
1997 there are at least 2 filesystems with more than this
1998 much space available, we use RR selection between them.
1999 If not, then we pick the filesystem with the most space.
2001 This gets a good balance between the two
2005 refresh_disk_space ();
2007 int free_enough = 0;
2009 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2010 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2015 if (free_enough >= 2) {
2016 /* use RR selection process, ensuring that the one
2020 i = last_rr_session_dir;
2023 if (++i == session_dirs.end()) {
2024 i = session_dirs.begin();
2027 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2028 if (create_session_directory ((*i).path)) {
2030 last_rr_session_dir = i;
2035 } while (i != last_rr_session_dir);
2039 /* pick FS with the most freespace (and that
2040 seems to actually work ...)
2043 vector<space_and_path> sorted;
2044 space_and_path_ascending_cmp cmp;
2046 sorted = session_dirs;
2047 sort (sorted.begin(), sorted.end(), cmp);
2049 for (i = sorted.begin(); i != sorted.end(); ++i) {
2050 if (create_session_directory ((*i).path)) {
2052 last_rr_session_dir = i;
2062 Session::load_named_selections (const XMLNode& node)
2065 XMLNodeConstIterator niter;
2068 nlist = node.children();
2072 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2074 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2075 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2083 Session::XMLNamedSelectionFactory (const XMLNode& node)
2086 return new NamedSelection (*this, node);
2089 catch (failed_constructor& err) {
2095 Session::automation_dir () const
2097 return Glib::build_filename (_path, "automation");
2101 Session::analysis_dir () const
2103 return Glib::build_filename (_path, "analysis");
2107 Session::load_bundles (XMLNode const & node)
2109 XMLNodeList nlist = node.children();
2110 XMLNodeConstIterator niter;
2114 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2115 if ((*niter)->name() == "InputBundle") {
2116 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2117 } else if ((*niter)->name() == "OutputBundle") {
2118 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2120 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2129 Session::load_route_groups (const XMLNode& node, int version)
2131 XMLNodeList nlist = node.children();
2132 XMLNodeConstIterator niter;
2136 if (version >= 3000) {
2138 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2139 if ((*niter)->name() == "RouteGroup") {
2140 RouteGroup* rg = new RouteGroup (*this, "");
2141 add_route_group (rg);
2142 rg->set_state (**niter, version);
2146 } else if (version < 3000) {
2148 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2149 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2150 RouteGroup* rg = new RouteGroup (*this, "");
2151 add_route_group (rg);
2152 rg->set_state (**niter, version);
2161 Session::auto_save()
2163 save_state (_current_snapshot_name);
2167 state_file_filter (const string &str, void */*arg*/)
2169 return (str.length() > strlen(statefile_suffix) &&
2170 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2174 bool operator()(const string* a, const string* b) {
2180 remove_end(string* state)
2182 string statename(*state);
2184 string::size_type start,end;
2185 if ((start = statename.find_last_of ('/')) != string::npos) {
2186 statename = statename.substr (start+1);
2189 if ((end = statename.rfind(".ardour")) == string::npos) {
2190 end = statename.length();
2193 return new string(statename.substr (0, end));
2197 Session::possible_states (string path)
2199 PathScanner scanner;
2200 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2202 transform(states->begin(), states->end(), states->begin(), remove_end);
2205 sort (states->begin(), states->end(), cmp);
2211 Session::possible_states () const
2213 return possible_states(_path);
2217 Session::add_route_group (RouteGroup* g)
2219 _route_groups.push_back (g);
2220 route_group_added (g); /* EMIT SIGNAL */
2225 Session::remove_route_group (RouteGroup& rg)
2227 list<RouteGroup*>::iterator i;
2229 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2230 _route_groups.erase (i);
2233 route_group_removed (); /* EMIT SIGNAL */
2239 Session::route_group_by_name (string name)
2241 list<RouteGroup *>::iterator i;
2243 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2244 if ((*i)->name() == name) {
2252 Session::start_reversible_command (const string& name)
2254 UndoTransaction* trans = new UndoTransaction();
2255 trans->set_name(name);
2260 Session::finish_reversible_command (UndoTransaction& ut)
2263 gettimeofday(&now, 0);
2264 ut.set_timestamp(now);
2269 Session::begin_reversible_command(const string& name)
2271 UndoTransaction* trans = new UndoTransaction();
2272 trans->set_name(name);
2274 if (!_current_trans.empty()) {
2275 _current_trans.top()->add_command (trans);
2277 _current_trans.push(trans);
2282 Session::commit_reversible_command(Command *cmd)
2284 assert(!_current_trans.empty());
2288 _current_trans.top()->add_command(cmd);
2291 if (_current_trans.top()->empty()) {
2292 _current_trans.pop();
2296 gettimeofday(&now, 0);
2297 _current_trans.top()->set_timestamp(now);
2299 _history.add(_current_trans.top());
2300 _current_trans.pop();
2304 accept_all_non_peak_files (const string& path, void */*arg*/)
2306 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2310 accept_all_state_files (const string& path, void */*arg*/)
2312 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2316 Session::find_all_sources (string path, set<string>& result)
2321 if (!tree.read (path)) {
2325 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2330 XMLNodeConstIterator niter;
2332 nlist = node->children();
2336 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2340 if ((prop = (*niter)->property (X_("type"))) == 0) {
2344 DataType type (prop->value());
2346 if ((prop = (*niter)->property (X_("name"))) == 0) {
2350 if (prop->value()[0] == '/') {
2351 /* external file, ignore */
2355 Glib::ustring found_path;
2359 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2360 result.insert (found_path);
2368 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2370 PathScanner scanner;
2371 vector<string*>* state_files;
2373 string this_snapshot_path;
2379 if (ripped[ripped.length()-1] == '/') {
2380 ripped = ripped.substr (0, ripped.length() - 1);
2383 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2385 if (state_files == 0) {
2390 this_snapshot_path = _path;
2391 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2392 this_snapshot_path += statefile_suffix;
2394 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2396 if (exclude_this_snapshot && **i == this_snapshot_path) {
2400 if (find_all_sources (**i, result) < 0) {
2408 struct RegionCounter {
2409 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2410 AudioSourceList::iterator iter;
2411 boost::shared_ptr<Region> region;
2414 RegionCounter() : count (0) {}
2418 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2420 return *AskAboutPlaylistDeletion (p);
2424 Session::cleanup_sources (CleanupReport& rep)
2426 // FIXME: needs adaptation to midi
2428 vector<boost::shared_ptr<Source> > dead_sources;
2429 PathScanner scanner;
2431 vector<space_and_path>::iterator i;
2432 vector<space_and_path>::iterator nexti;
2433 vector<string*>* soundfiles;
2434 vector<string> unused;
2435 set<string> all_sources;
2440 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2442 /* step 1: consider deleting all unused playlists */
2444 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2449 /* step 2: find all un-used sources */
2454 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2456 SourceMap::iterator tmp;
2461 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2465 if (!playlists->source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2466 dead_sources.push_back (i->second);
2467 i->second->drop_references ();
2473 /* build a list of all the possible sound directories for the session */
2475 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2480 SessionDirectory sdir ((*i).path);
2481 sound_path += sdir.sound_path().to_string();
2483 if (nexti != session_dirs.end()) {
2490 /* now do the same thing for the files that ended up in the sounds dir(s)
2491 but are not referenced as sources in any snapshot.
2494 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2496 if (soundfiles == 0) {
2500 /* find all sources, but don't use this snapshot because the
2501 state file on disk still references sources we may have already
2505 find_all_sources_across_snapshots (all_sources, true);
2507 /* add our current source list
2510 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2511 boost::shared_ptr<FileSource> fs;
2513 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2514 all_sources.insert (fs->path());
2518 char tmppath1[PATH_MAX+1];
2519 char tmppath2[PATH_MAX+1];
2521 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2526 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2528 realpath(spath.c_str(), tmppath1);
2529 realpath((*i).c_str(), tmppath2);
2531 if (strcmp(tmppath1, tmppath2) == 0) {
2538 unused.push_back (spath);
2542 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2544 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2545 struct stat statbuf;
2547 rep.paths.push_back (*x);
2548 if (stat ((*x).c_str(), &statbuf) == 0) {
2549 rep.space += statbuf.st_size;
2554 /* don't move the file across filesystems, just
2555 stick it in the `dead_sound_dir_name' directory
2556 on whichever filesystem it was already on.
2559 if ((*x).find ("/sounds/") != string::npos) {
2561 /* old school, go up 1 level */
2563 newpath = Glib::path_get_dirname (*x); // "sounds"
2564 newpath = Glib::path_get_dirname (newpath); // "session-name"
2568 /* new school, go up 4 levels */
2570 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2571 newpath = Glib::path_get_dirname (newpath); // "session-name"
2572 newpath = Glib::path_get_dirname (newpath); // "interchange"
2573 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2577 newpath += dead_sound_dir_name;
2579 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2580 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2585 newpath += Glib::path_get_basename ((*x));
2587 if (access (newpath.c_str(), F_OK) == 0) {
2589 /* the new path already exists, try versioning */
2591 char buf[PATH_MAX+1];
2595 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2598 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2599 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2603 if (version == 999) {
2604 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2608 newpath = newpath_v;
2613 /* it doesn't exist, or we can't read it or something */
2617 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2618 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2619 (*x), newpath, strerror (errno))
2624 /* see if there an easy to find peakfile for this file, and remove it.
2627 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2628 peakpath += peakfile_suffix;
2630 if (access (peakpath.c_str(), W_OK) == 0) {
2631 if (::unlink (peakpath.c_str()) != 0) {
2632 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2633 peakpath, _path, strerror (errno))
2635 /* try to back out */
2636 rename (newpath.c_str(), _path.c_str());
2644 /* dump the history list */
2648 /* save state so we don't end up a session file
2649 referring to non-existent sources.
2655 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2661 Session::cleanup_trash_sources (CleanupReport& rep)
2663 // FIXME: needs adaptation for MIDI
2665 vector<space_and_path>::iterator i;
2666 string dead_sound_dir;
2667 struct dirent* dentry;
2668 struct stat statbuf;
2674 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2676 dead_sound_dir = (*i).path;
2677 dead_sound_dir += dead_sound_dir_name;
2679 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2683 while ((dentry = readdir (dead)) != 0) {
2685 /* avoid '.' and '..' */
2687 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2688 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2694 fullpath = dead_sound_dir;
2696 fullpath += dentry->d_name;
2698 if (stat (fullpath.c_str(), &statbuf)) {
2702 if (!S_ISREG (statbuf.st_mode)) {
2706 if (unlink (fullpath.c_str())) {
2707 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2708 fullpath, strerror (errno))
2712 rep.paths.push_back (dentry->d_name);
2713 rep.space += statbuf.st_size;
2724 Session::set_dirty ()
2726 bool was_dirty = dirty();
2728 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2732 DirtyChanged(); /* EMIT SIGNAL */
2738 Session::set_clean ()
2740 bool was_dirty = dirty();
2742 _state_of_the_state = Clean;
2746 DirtyChanged(); /* EMIT SIGNAL */
2751 Session::set_deletion_in_progress ()
2753 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2757 Session::clear_deletion_in_progress ()
2759 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2763 Session::add_controllable (boost::shared_ptr<Controllable> c)
2765 /* this adds a controllable to the list managed by the Session.
2766 this is a subset of those managed by the Controllable class
2767 itself, and represents the only ones whose state will be saved
2768 as part of the session.
2771 Glib::Mutex::Lock lm (controllables_lock);
2772 controllables.insert (c);
2775 struct null_deleter { void operator()(void const *) const {} };
2778 Session::remove_controllable (Controllable* c)
2780 if (_state_of_the_state | Deletion) {
2784 Glib::Mutex::Lock lm (controllables_lock);
2786 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2788 if (x != controllables.end()) {
2789 controllables.erase (x);
2793 boost::shared_ptr<Controllable>
2794 Session::controllable_by_id (const PBD::ID& id)
2796 Glib::Mutex::Lock lm (controllables_lock);
2798 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2799 if ((*i)->id() == id) {
2804 return boost::shared_ptr<Controllable>();
2807 boost::shared_ptr<Controllable>
2808 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2810 boost::shared_ptr<Controllable> c;
2811 boost::shared_ptr<Route> r;
2813 switch (desc.top_level_type()) {
2814 case ControllableDescriptor::NamedRoute:
2816 std::string str = desc.top_level_name();
2817 if (str == "master") {
2819 } else if (str == "control" || str == "listen") {
2822 r = route_by_name (desc.top_level_name());
2827 case ControllableDescriptor::RemoteControlID:
2828 r = route_by_remote_id (desc.rid());
2836 switch (desc.subtype()) {
2837 case ControllableDescriptor::Gain:
2838 c = r->gain_control ();
2841 case ControllableDescriptor::Solo:
2842 c = r->solo_control();
2845 case ControllableDescriptor::Mute:
2846 c = r->mute_control();
2849 case ControllableDescriptor::Recenable:
2851 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2854 c = t->rec_enable_control ();
2859 case ControllableDescriptor::Pan:
2860 /* XXX pan control */
2863 case ControllableDescriptor::Balance:
2864 /* XXX simple pan control */
2867 case ControllableDescriptor::PluginParameter:
2869 uint32_t plugin = desc.target (0);
2870 uint32_t parameter_index = desc.target (1);
2872 /* revert to zero based counting */
2878 if (parameter_index > 0) {
2882 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2885 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2886 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2891 case ControllableDescriptor::SendGain:
2893 uint32_t send = desc.target (0);
2895 /* revert to zero-based counting */
2901 boost::shared_ptr<Processor> p = r->nth_send (send);
2904 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2905 boost::shared_ptr<Amp> a = s->amp();
2908 c = s->amp()->gain_control();
2915 /* relax and return a null pointer */
2923 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2926 Stateful::add_instant_xml (node, _path);
2929 if (write_to_config) {
2930 Config->add_instant_xml (node);
2935 Session::instant_xml (const string& node_name)
2937 return Stateful::instant_xml (node_name, _path);
2941 Session::save_history (string snapshot_name)
2949 if (snapshot_name.empty()) {
2950 snapshot_name = _current_snapshot_name;
2953 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2954 const string backup_filename = history_filename + backup_suffix;
2955 const sys::path xml_path = _session_dir->root_path() / history_filename;
2956 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2958 if (sys::exists (xml_path)) {
2961 sys::rename (xml_path, backup_path);
2963 catch (const sys::filesystem_error& err)
2965 error << _("could not backup old history file, current history not saved") << endmsg;
2970 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2974 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2976 if (!tree.write (xml_path.to_string()))
2978 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2982 sys::remove (xml_path);
2983 sys::rename (backup_path, xml_path);
2985 catch (const sys::filesystem_error& err)
2987 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2988 backup_path.to_string(), err.what()) << endmsg;
2998 Session::restore_history (string snapshot_name)
3002 if (snapshot_name.empty()) {
3003 snapshot_name = _current_snapshot_name;
3006 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3007 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3009 info << "Loading history from " << xml_path.to_string() << endmsg;
3011 if (!sys::exists (xml_path)) {
3012 info << string_compose (_("%1: no history file \"%2\" for this session."),
3013 _name, xml_path.to_string()) << endmsg;
3017 if (!tree.read (xml_path.to_string())) {
3018 error << string_compose (_("Could not understand session history file \"%1\""),
3019 xml_path.to_string()) << endmsg;
3026 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3029 UndoTransaction* ut = new UndoTransaction ();
3032 ut->set_name(t->property("name")->value());
3033 stringstream ss(t->property("tv-sec")->value());
3035 ss.str(t->property("tv-usec")->value());
3037 ut->set_timestamp(tv);
3039 for (XMLNodeConstIterator child_it = t->children().begin();
3040 child_it != t->children().end(); child_it++)
3042 XMLNode *n = *child_it;
3045 if (n->name() == "MementoCommand" ||
3046 n->name() == "MementoUndoCommand" ||
3047 n->name() == "MementoRedoCommand") {
3049 if ((c = memento_command_factory(n))) {
3053 } else if (n->name() == "DeltaCommand") {
3054 PBD::ID id(n->property("midi-source")->value());
3055 boost::shared_ptr<MidiSource> midi_source =
3056 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3058 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3060 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3063 } else if (n->name() == "DiffCommand") {
3064 PBD::ID id(n->property("midi-source")->value());
3065 boost::shared_ptr<MidiSource> midi_source =
3066 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3068 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3070 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3073 } else if (n->name() == "StatefulDiffCommand") {
3074 if ((c = stateful_diff_command_factory (n))) {
3075 ut->add_command (c);
3078 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3089 Session::config_changed (std::string p, bool ours)
3095 if (p == "seamless-loop") {
3097 } else if (p == "rf-speed") {
3099 } else if (p == "auto-loop") {
3101 } else if (p == "auto-input") {
3103 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3104 /* auto-input only makes a difference if we're rolling */
3106 boost::shared_ptr<RouteList> rl = routes.reader ();
3107 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3108 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3109 if (tr && tr->record_enabled ()) {
3110 tr->monitor_input (!config.get_auto_input());
3115 } else if (p == "punch-in") {
3119 if ((location = _locations.auto_punch_location()) != 0) {
3121 if (config.get_punch_in ()) {
3122 replace_event (SessionEvent::PunchIn, location->start());
3124 remove_event (location->start(), SessionEvent::PunchIn);
3128 } else if (p == "punch-out") {
3132 if ((location = _locations.auto_punch_location()) != 0) {
3134 if (config.get_punch_out()) {
3135 replace_event (SessionEvent::PunchOut, location->end());
3137 clear_events (SessionEvent::PunchOut);
3141 } else if (p == "edit-mode") {
3143 Glib::Mutex::Lock lm (playlists->lock);
3145 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3146 (*i)->set_edit_mode (Config->get_edit_mode ());
3149 } else if (p == "use-video-sync") {
3151 waiting_for_sync_offset = config.get_use_video_sync();
3153 } else if (p == "mmc-control") {
3155 //poke_midi_thread ();
3157 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3160 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3163 } else if (p == "mmc-send-id") {
3166 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3169 } else if (p == "midi-control") {
3171 //poke_midi_thread ();
3173 } else if (p == "raid-path") {
3175 setup_raid_path (config.get_raid_path());
3177 } else if (p == "timecode-format") {
3181 } else if (p == "video-pullup") {
3185 } else if (p == "seamless-loop") {
3187 if (play_loop && transport_rolling()) {
3188 // to reset diskstreams etc
3189 request_play_loop (true);
3192 } else if (p == "rf-speed") {
3194 cumulative_rf_motion = 0;
3197 } else if (p == "click-sound") {
3199 setup_click_sounds (1);
3201 } else if (p == "click-emphasis-sound") {
3203 setup_click_sounds (-1);
3205 } else if (p == "clicking") {
3207 if (Config->get_clicking()) {
3208 if (_click_io && click_data) { // don't require emphasis data
3215 } else if (p == "send-mtc") {
3217 /* only set the internal flag if we have
3221 if (_mtc_port != 0) {
3222 session_send_mtc = Config->get_send_mtc();
3223 if (session_send_mtc) {
3224 /* mark us ready to send */
3225 next_quarter_frame_to_send = 0;
3228 session_send_mtc = false;
3231 } else if (p == "send-mmc") {
3233 /* only set the internal flag if we have
3237 if (_mmc_port != 0) {
3238 session_send_mmc = Config->get_send_mmc();
3241 session_send_mmc = false;
3244 } else if (p == "midi-feedback") {
3246 /* only set the internal flag if we have
3250 if (_mtc_port != 0) {
3251 session_midi_feedback = Config->get_midi_feedback();
3254 } else if (p == "jack-time-master") {
3256 engine().reset_timebase ();
3258 } else if (p == "native-file-header-format") {
3260 if (!first_file_header_format_reset) {
3261 reset_native_file_format ();
3264 first_file_header_format_reset = false;
3266 } else if (p == "native-file-data-format") {
3268 if (!first_file_data_format_reset) {
3269 reset_native_file_format ();
3272 first_file_data_format_reset = false;
3274 } else if (p == "external-sync") {
3275 if (!config.get_external_sync()) {
3276 drop_sync_source ();
3278 switch_to_sync_source (config.get_sync_source());
3280 } else if (p == "remote-model") {
3281 set_remote_control_ids ();
3282 } else if (p == "denormal-model") {
3284 } else if (p == "history-depth") {
3285 set_history_depth (Config->get_history_depth());
3286 } else if (p == "sync-all-route-ordering") {
3287 sync_order_keys ("session");
3288 } else if (p == "initial-program-change") {
3290 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3293 buf[0] = MIDI::program; // channel zero by default
3294 buf[1] = (Config->get_initial_program_change() & 0x7f);
3296 _mmc_port->midimsg (buf, sizeof (buf), 0);
3298 } else if (p == "initial-program-change") {
3300 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3301 MIDI::byte* buf = new MIDI::byte[2];
3303 buf[0] = MIDI::program; // channel zero by default
3304 buf[1] = (Config->get_initial_program_change() & 0x7f);
3305 // deliver_midi (_mmc_port, buf, 2);
3307 } else if (p == "solo-mute-override") {
3308 // catch_up_on_solo_mute_override ();
3309 } else if (p == "listen-position") {
3310 listen_position_changed ();
3311 } else if (p == "solo-control-is-listen-control") {
3312 solo_control_mode_changed ();
3320 Session::set_history_depth (uint32_t d)
3322 _history.set_depth (d);
3326 Session::load_diskstreams_2X (XMLNode const & node, int)
3329 XMLNodeConstIterator citer;
3331 clist = node.children();
3333 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3336 /* diskstreams added automatically by DiskstreamCreated handler */
3337 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3338 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3339 _diskstreams_2X.push_back (dsp);
3341 error << _("Session: unknown diskstream type in XML") << endmsg;
3345 catch (failed_constructor& err) {
3346 error << _("Session: could not load diskstream via XML state") << endmsg;