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 g_atomic_int_set (&processing_prohibited, 0);
174 _transport_speed = 0;
175 _last_transport_speed = 0;
176 _target_transport_speed = 0;
177 auto_play_legal = false;
178 transport_sub_state = 0;
179 _transport_frame = 0;
180 _requested_return_frame = -1;
181 _session_range_location = new Location (0, 0, _("session"), Location::IsSessionRange);
182 g_atomic_int_set (&_record_status, Disabled);
183 loop_changing = false;
186 _last_roll_location = 0;
187 _last_record_location = 0;
188 pending_locate_frame = 0;
189 pending_locate_roll = false;
190 pending_locate_flush = false;
191 state_was_pending = false;
193 outbound_mtc_timecode_frame = 0;
194 next_quarter_frame_to_send = -1;
195 current_block_size = 0;
196 solo_update_disabled = false;
197 _have_captured = false;
198 _worst_output_latency = 0;
199 _worst_input_latency = 0;
200 _worst_track_latency = 0;
201 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
202 _was_seamless = Config->get_seamless_loop ();
204 session_send_mmc = false;
205 session_send_mtc = false;
206 g_atomic_int_set (&_playback_load, 100);
207 g_atomic_int_set (&_capture_load, 100);
208 g_atomic_int_set (&_playback_load_min, 100);
209 g_atomic_int_set (&_capture_load_min, 100);
212 pending_abort = false;
213 destructive_index = 0;
214 first_file_data_format_reset = true;
215 first_file_header_format_reset = true;
216 post_export_sync = false;
219 AudioDiskstream::allocate_working_buffers();
221 /* default short fade = 15ms */
223 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
224 SndFileSource::setup_standard_crossfades (*this, frame_rate());
226 last_mmc_step.tv_sec = 0;
227 last_mmc_step.tv_usec = 0;
230 /* click sounds are unset by default, which causes us to internal
231 waveforms for clicks.
235 click_emphasis_length = 0;
238 process_function = &Session::process_with_events;
240 if (config.get_use_video_sync()) {
241 waiting_for_sync_offset = true;
243 waiting_for_sync_offset = false;
246 last_timecode_when = 0;
247 _timecode_offset = 0;
248 _timecode_offset_negative = true;
249 last_timecode_valid = false;
253 last_rr_session_dir = session_dirs.begin();
254 refresh_disk_space ();
256 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
260 average_slave_delta = 1800; // !!! why 1800 ????
261 have_first_delta_accumulator = false;
262 delta_accumulator_cnt = 0;
263 _slave_state = Stopped;
265 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
267 /* These are all static "per-class" signals */
269 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
270 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
271 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
272 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
273 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
275 /* stop IO objects from doing stuff until we're ready for them */
277 Delivery::disable_panners ();
278 IO::disable_connecting ();
282 Session::second_stage_init ()
284 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
287 if (load_state (_current_snapshot_name)) {
290 remove_empty_sounds ();
293 if (_butler->start_thread()) {
297 if (start_midi_thread ()) {
301 // set_state() will call setup_raid_path(), but if it's a new session we need
302 // to call setup_raid_path() here.
305 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
309 setup_raid_path(_path);
312 /* we can't save till after ::when_engine_running() is called,
313 because otherwise we save state with no connections made.
314 therefore, we reset _state_of_the_state because ::set_state()
315 will have cleared it.
317 we also have to include Loading so that any events that get
318 generated between here and the end of ::when_engine_running()
319 will be processed directly rather than queued.
322 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
325 _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
326 _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
327 setup_click_sounds (0);
328 setup_midi_control ();
330 /* Pay attention ... */
332 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
333 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
336 when_engine_running ();
339 /* handle this one in a different way than all others, so that its clear what happened */
341 catch (AudioEngine::PortRegistrationFailure& err) {
342 error << err.what() << endmsg;
350 BootMessage (_("Reset Remote Controls"));
352 send_full_time_code (0);
353 _engine.transport_locate (0);
354 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
355 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
357 MidiClockTicker::instance().set_session (this);
358 MIDI::Name::MidiPatchManager::instance().set_session (this);
360 /* initial program change will be delivered later; see ::config_changed() */
362 BootMessage (_("Reset Control Protocols"));
364 ControlProtocolManager::instance().set_session (this);
366 config.set_end_marker_is_free (_is_new);
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, nframes_t initial_length, 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());
521 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
527 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
534 /* Instantiate metadata */
536 _metadata = new SessionMetadata ();
538 /* set initial start + end point */
540 _session_range_location->set (0, initial_length);
541 _locations.add (_session_range_location);
543 _state_of_the_state = Clean;
545 /* set up Master Out and Control Out if necessary */
551 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
553 if (bus_profile->master_out_channels) {
554 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
559 boost_debug_shared_ptr_mark_interesting (rt, "Route");
560 boost::shared_ptr<Route> r (rt);
561 r->input()->ensure_io (count, false, this);
562 r->output()->ensure_io (count, false, this);
563 r->set_remote_control_id (control_id++);
567 if (Config->get_use_monitor_bus()) {
568 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
573 boost_debug_shared_ptr_mark_interesting (rt, "Route");
574 boost::shared_ptr<Route> r (rt);
575 r->input()->ensure_io (count, false, this);
576 r->output()->ensure_io (count, false, this);
577 r->set_remote_control_id (control_id);
583 /* prohibit auto-connect to master, because there isn't one */
584 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
588 add_routes (rl, false);
591 /* this allows the user to override settings with an environment variable.
594 if (no_auto_connect()) {
595 bus_profile->input_ac = AutoConnectOption (0);
596 bus_profile->output_ac = AutoConnectOption (0);
599 Config->set_input_auto_connect (bus_profile->input_ac);
600 Config->set_output_auto_connect (bus_profile->output_ac);
609 Session::maybe_write_autosave()
611 if (dirty() && record_status() != Recording) {
612 save_state("", true);
617 Session::remove_pending_capture_state ()
619 sys::path pending_state_file_path(_session_dir->root_path());
621 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
625 sys::remove (pending_state_file_path);
627 catch(sys::filesystem_error& ex)
629 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
630 pending_state_file_path.to_string(), ex.what()) << endmsg;
634 /** Rename a state file.
635 * @param snapshot_name Snapshot name.
638 Session::rename_state (string old_name, string new_name)
640 if (old_name == _current_snapshot_name || old_name == _name) {
641 /* refuse to rename the current snapshot or the "main" one */
645 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
646 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
648 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
649 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
653 sys::rename (old_xml_path, new_xml_path);
655 catch (const sys::filesystem_error& err)
657 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
658 old_name, new_name, err.what()) << endmsg;
662 /** Remove a state file.
663 * @param snapshot_name Snapshot name.
666 Session::remove_state (string snapshot_name)
668 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
669 // refuse to remove the current snapshot or the "main" one
673 sys::path xml_path(_session_dir->root_path());
675 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
677 if (!create_backup_file (xml_path)) {
678 // don't remove it if a backup can't be made
679 // create_backup_file will log the error.
684 sys::remove (xml_path);
687 #ifdef HAVE_JACK_SESSION
689 Session::jack_session_event (jack_session_event_t * event)
691 if (save_state ("jacksession_snap")) {
692 event->flags = JackSessionSaveError;
694 sys::path xml_path (_session_dir->root_path());
695 xml_path /= legalize_for_path ("jacksession_snap") + statefile_suffix;
697 string cmd ("PROG_NAME -U ");
698 cmd += event->client_uuid;
700 cmd += xml_path.to_string();
703 event->command_line = strdup (cmd.c_str());
706 jack_session_reply (_engine.jack(), event);
708 if (event->type == JackSessionSaveAndQuit) {
709 // TODO: make ardour quit.
712 jack_session_event_free( event );
717 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
720 sys::path xml_path(_session_dir->root_path());
722 if (!_writable || (_state_of_the_state & CannotSave)) {
726 if (!_engine.connected ()) {
727 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
733 /* tell sources we're saving first, in case they write out to a new file
734 * which should be saved with the state rather than the old one */
735 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
736 i->second->session_saved();
738 tree.set_root (&get_state());
740 if (snapshot_name.empty()) {
741 snapshot_name = _current_snapshot_name;
742 } else if (switch_to_snapshot) {
743 _current_snapshot_name = snapshot_name;
748 /* proper save: use statefile_suffix (.ardour in English) */
750 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
752 /* make a backup copy of the old file */
754 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
755 // create_backup_file will log the error
761 /* pending save: use pending_suffix (.pending in English) */
762 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
765 sys::path tmp_path(_session_dir->root_path());
767 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
769 // cerr << "actually writing state to " << xml_path.to_string() << endl;
771 if (!tree.write (tmp_path.to_string())) {
772 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
773 sys::remove (tmp_path);
778 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
779 error << string_compose (_("could not rename temporary session file %1 to %2"),
780 tmp_path.to_string(), xml_path.to_string()) << endmsg;
781 sys::remove (tmp_path);
788 save_history (snapshot_name);
790 bool was_dirty = dirty();
792 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
795 DirtyChanged (); /* EMIT SIGNAL */
798 StateSaved (snapshot_name); /* EMIT SIGNAL */
805 Session::restore_state (string snapshot_name)
807 if (load_state (snapshot_name) == 0) {
808 set_state (*state_tree->root(), Stateful::loading_state_version);
815 Session::load_state (string snapshot_name)
820 state_was_pending = false;
822 /* check for leftover pending state from a crashed capture attempt */
824 sys::path xmlpath(_session_dir->root_path());
825 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
827 if (sys::exists (xmlpath)) {
829 /* there is pending state from a crashed capture attempt */
831 if (*AskAboutPendingState()) {
832 state_was_pending = true;
836 if (!state_was_pending) {
837 xmlpath = _session_dir->root_path();
838 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
841 if (!sys::exists (xmlpath)) {
842 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
846 state_tree = new XMLTree;
850 /* writable() really reflects the whole folder, but if for any
851 reason the session state file can't be written to, still
855 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
859 if (!state_tree->read (xmlpath.to_string())) {
860 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
866 XMLNode& root (*state_tree->root());
868 if (root.name() != X_("Session")) {
869 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
875 const XMLProperty* prop;
877 if ((prop = root.property ("version")) == 0) {
878 /* no version implies very old version of Ardour */
879 Stateful::loading_state_version = 1000;
885 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
886 Stateful::loading_state_version = (major * 1000) + minor;
889 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
891 sys::path backup_path(_session_dir->root_path());
893 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
895 // only create a backup once
896 if (sys::exists (backup_path)) {
900 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
901 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
906 sys::copy_file (xmlpath, backup_path);
908 catch(sys::filesystem_error& ex)
910 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
911 xmlpath.to_string(), ex.what())
921 Session::load_options (const XMLNode& node)
923 LocaleGuard lg (X_("POSIX"));
924 config.set_variables (node);
935 Session::get_template()
937 /* if we don't disable rec-enable, diskstreams
938 will believe they need to store their capture
939 sources in their state node.
942 disable_record (false);
948 Session::state(bool full_state)
950 XMLNode* node = new XMLNode("Session");
953 // store libardour version, just in case
955 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
956 node->add_property("version", string(buf));
958 /* store configuration settings */
962 node->add_property ("name", _name);
963 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
964 node->add_property ("sample-rate", buf);
966 if (session_dirs.size() > 1) {
970 vector<space_and_path>::iterator i = session_dirs.begin();
971 vector<space_and_path>::iterator next;
973 ++i; /* skip the first one */
977 while (i != session_dirs.end()) {
981 if (next != session_dirs.end()) {
991 child = node->add_child ("Path");
992 child->add_content (p);
996 /* save the ID counter */
998 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
999 node->add_property ("id-counter", buf);
1001 /* various options */
1003 node->add_child_nocopy (config.get_variables ());
1005 node->add_child_nocopy (_metadata->get_state());
1007 child = node->add_child ("Sources");
1010 Glib::Mutex::Lock sl (source_lock);
1012 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1014 /* Don't save information about non-destructive file sources that are empty */
1015 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
1017 boost::shared_ptr<AudioFileSource> fs;
1018 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
1019 if (!fs->destructive()) {
1020 if (fs->length(fs->timeline_position()) == 0) {
1026 child->add_child_nocopy (siter->second->get_state());
1030 child = node->add_child ("Regions");
1033 Glib::Mutex::Lock rl (region_lock);
1034 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1035 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1036 boost::shared_ptr<Region> r = i->second;
1037 /* only store regions not attached to playlists */
1038 if (r->playlist() == 0) {
1039 child->add_child_nocopy (r->state (true));
1045 node->add_child_nocopy (_locations.get_state());
1047 // for a template, just create a new Locations, populate it
1048 // with the default start and end, and get the state for that.
1050 Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
1051 range->set (0, compute_initial_length ());
1053 node->add_child_nocopy (loc.get_state());
1056 child = node->add_child ("Bundles");
1058 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1059 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1060 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1062 child->add_child_nocopy (b->get_state());
1067 child = node->add_child ("Routes");
1069 boost::shared_ptr<RouteList> r = routes.reader ();
1071 RoutePublicOrderSorter cmp;
1072 RouteList public_order (*r);
1073 public_order.sort (cmp);
1075 /* the sort should have put control outs first */
1078 assert (_monitor_out == public_order.front());
1081 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1082 if (!(*i)->is_hidden()) {
1084 child->add_child_nocopy ((*i)->get_state());
1086 child->add_child_nocopy ((*i)->get_template());
1092 playlists->add_state (node, full_state);
1094 child = node->add_child ("RouteGroups");
1095 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1096 child->add_child_nocopy ((*i)->get_state());
1100 child = node->add_child ("Click");
1101 child->add_child_nocopy (_click_io->state (full_state));
1105 child = node->add_child ("NamedSelections");
1106 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1108 child->add_child_nocopy ((*i)->get_state());
1113 node->add_child_nocopy (_tempo_map->get_state());
1115 node->add_child_nocopy (get_control_protocol_state());
1118 node->add_child_copy (*_extra_xml);
1125 Session::get_control_protocol_state ()
1127 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1128 return cpm.get_state();
1132 Session::set_state (const XMLNode& node, int version)
1136 const XMLProperty* prop;
1139 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1141 if (node.name() != X_("Session")){
1142 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1146 if ((prop = node.property ("version")) != 0) {
1147 version = atoi (prop->value ()) * 1000;
1150 if ((prop = node.property ("name")) != 0) {
1151 _name = prop->value ();
1154 if ((prop = node.property (X_("sample-rate"))) != 0) {
1156 _nominal_frame_rate = atoi (prop->value());
1158 if (_nominal_frame_rate != _current_frame_rate) {
1159 if (*AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1165 setup_raid_path(_session_dir->root_path().to_string());
1167 if ((prop = node.property (X_("id-counter"))) != 0) {
1169 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1170 ID::init_counter (x);
1172 /* old sessions used a timebased counter, so fake
1173 the startup ID counter based on a standard
1178 ID::init_counter (now);
1182 IO::disable_connecting ();
1184 /* Object loading order:
1189 MIDI Control // relies on data from Options/Config
1202 if ((child = find_named_node (node, "Extra")) != 0) {
1203 _extra_xml = new XMLNode (*child);
1206 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1207 load_options (*child);
1208 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1209 load_options (*child);
1211 error << _("Session: XML state has no options section") << endmsg;
1214 if (use_config_midi_ports ()) {
1217 if (version >= 3000) {
1218 if ((child = find_named_node (node, "Metadata")) == 0) {
1219 warning << _("Session: XML state has no metadata section") << endmsg;
1220 } else if (_metadata->set_state (*child, version)) {
1225 if ((child = find_named_node (node, "Locations")) == 0) {
1226 error << _("Session: XML state has no locations section") << endmsg;
1228 } else if (_locations.set_state (*child, version)) {
1234 if ((location = _locations.auto_loop_location()) != 0) {
1235 set_auto_loop_location (location);
1238 if ((location = _locations.auto_punch_location()) != 0) {
1239 set_auto_punch_location (location);
1242 if ((location = _locations.session_range_location()) == 0) {
1243 _locations.add (_session_range_location);
1245 delete _session_range_location;
1246 _session_range_location = location;
1249 AudioFileSource::set_header_position_offset (_session_range_location->start());
1251 if ((child = find_named_node (node, "Sources")) == 0) {
1252 error << _("Session: XML state has no sources section") << endmsg;
1254 } else if (load_sources (*child)) {
1258 if ((child = find_named_node (node, "Regions")) == 0) {
1259 error << _("Session: XML state has no Regions section") << endmsg;
1261 } else if (load_regions (*child)) {
1265 if ((child = find_named_node (node, "Playlists")) == 0) {
1266 error << _("Session: XML state has no playlists section") << endmsg;
1268 } else if (playlists->load (*this, *child)) {
1272 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1274 } else if (playlists->load_unused (*this, *child)) {
1278 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1279 if (load_named_selections (*child)) {
1284 if (version >= 3000) {
1285 if ((child = find_named_node (node, "Bundles")) == 0) {
1286 warning << _("Session: XML state has no bundles section") << endmsg;
1289 /* We can't load Bundles yet as they need to be able
1290 to convert from port names to Port objects, which can't happen until
1292 _bundle_xml_node = new XMLNode (*child);
1296 if ((child = find_named_node (node, "TempoMap")) == 0) {
1297 error << _("Session: XML state has no Tempo Map section") << endmsg;
1299 } else if (_tempo_map->set_state (*child, version)) {
1303 if (version < 3000) {
1304 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1305 error << _("Session: XML state has no diskstreams section") << endmsg;
1307 } else if (load_diskstreams_2X (*child, version)) {
1312 if ((child = find_named_node (node, "Routes")) == 0) {
1313 error << _("Session: XML state has no routes section") << endmsg;
1315 } else if (load_routes (*child, version)) {
1319 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1320 _diskstreams_2X.clear ();
1322 if (version >= 3000) {
1324 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1325 error << _("Session: XML state has no route groups section") << endmsg;
1327 } else if (load_route_groups (*child, version)) {
1331 } else if (version < 3000) {
1333 if ((child = find_named_node (node, "EditGroups")) == 0) {
1334 error << _("Session: XML state has no edit groups section") << endmsg;
1336 } else if (load_route_groups (*child, version)) {
1340 if ((child = find_named_node (node, "MixGroups")) == 0) {
1341 error << _("Session: XML state has no mix groups section") << endmsg;
1343 } else if (load_route_groups (*child, version)) {
1348 if ((child = find_named_node (node, "Click")) == 0) {
1349 warning << _("Session: XML state has no click section") << endmsg;
1350 } else if (_click_io) {
1351 _click_io->set_state (*child, version);
1354 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1355 ControlProtocolManager::instance().set_protocol_states (*child);
1358 /* here beginneth the second phase ... */
1360 StateReady (); /* EMIT SIGNAL */
1369 Session::load_routes (const XMLNode& node, int version)
1372 XMLNodeConstIterator niter;
1373 RouteList new_routes;
1375 nlist = node.children();
1379 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1381 boost::shared_ptr<Route> route;
1382 if (version < 3000) {
1383 route = XMLRouteFactory_2X (**niter, version);
1385 route = XMLRouteFactory (**niter, version);
1389 error << _("Session: cannot create Route from XML description.") << endmsg;
1393 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1395 new_routes.push_back (route);
1398 add_routes (new_routes, false);
1403 boost::shared_ptr<Route>
1404 Session::XMLRouteFactory (const XMLNode& node, int version)
1406 boost::shared_ptr<Route> ret;
1408 if (node.name() != "Route") {
1412 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1414 DataType type = DataType::AUDIO;
1415 const XMLProperty* prop = node.property("default-type");
1418 type = DataType (prop->value());
1421 assert (type != DataType::NIL);
1427 if (type == DataType::AUDIO) {
1428 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1431 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1434 if (track->init()) {
1439 if (track->set_state (node, version)) {
1444 boost_debug_shared_ptr_mark_interesting (track, "Track");
1448 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1450 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1451 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1461 boost::shared_ptr<Route>
1462 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1464 boost::shared_ptr<Route> ret;
1466 if (node.name() != "Route") {
1470 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1472 ds_prop = node.property (X_("diskstream"));
1475 cout << "ds_prop " << ds_prop << "\n";
1477 DataType type = DataType::AUDIO;
1478 const XMLProperty* prop = node.property("default-type");
1481 type = DataType (prop->value());
1484 assert (type != DataType::NIL);
1488 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1489 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1493 if (i == _diskstreams_2X.end()) {
1494 error << _("Could not find diskstream for route") << endmsg;
1495 return boost::shared_ptr<Route> ();
1500 if (type == DataType::AUDIO) {
1501 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1504 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1507 if (track->init()) {
1512 if (track->set_state (node, version)) {
1517 track->set_diskstream (*i);
1519 boost_debug_shared_ptr_mark_interesting (track, "Track");
1523 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1525 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1526 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1537 Session::load_regions (const XMLNode& node)
1540 XMLNodeConstIterator niter;
1541 boost::shared_ptr<Region> region;
1543 nlist = node.children();
1547 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1548 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1549 error << _("Session: cannot create Region from XML description.");
1550 const XMLProperty *name = (**niter).property("name");
1553 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1563 boost::shared_ptr<Region>
1564 Session::XMLRegionFactory (const XMLNode& node, bool full)
1566 const XMLProperty* type = node.property("type");
1570 if ( !type || type->value() == "audio" ) {
1572 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1574 } else if (type->value() == "midi") {
1576 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1580 } catch (failed_constructor& err) {
1581 return boost::shared_ptr<Region> ();
1584 return boost::shared_ptr<Region> ();
1587 boost::shared_ptr<AudioRegion>
1588 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1590 const XMLProperty* prop;
1591 boost::shared_ptr<Source> source;
1592 boost::shared_ptr<AudioSource> as;
1594 SourceList master_sources;
1595 uint32_t nchans = 1;
1598 if (node.name() != X_("Region")) {
1599 return boost::shared_ptr<AudioRegion>();
1602 if ((prop = node.property (X_("channels"))) != 0) {
1603 nchans = atoi (prop->value().c_str());
1606 if ((prop = node.property ("name")) == 0) {
1607 cerr << "no name for this region\n";
1611 if ((prop = node.property (X_("source-0"))) == 0) {
1612 if ((prop = node.property ("source")) == 0) {
1613 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1614 return boost::shared_ptr<AudioRegion>();
1618 PBD::ID s_id (prop->value());
1620 if ((source = source_by_id (s_id)) == 0) {
1621 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1622 return boost::shared_ptr<AudioRegion>();
1625 as = boost::dynamic_pointer_cast<AudioSource>(source);
1627 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1628 return boost::shared_ptr<AudioRegion>();
1631 sources.push_back (as);
1633 /* pickup other channels */
1635 for (uint32_t n=1; n < nchans; ++n) {
1636 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1637 if ((prop = node.property (buf)) != 0) {
1639 PBD::ID id2 (prop->value());
1641 if ((source = source_by_id (id2)) == 0) {
1642 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1643 return boost::shared_ptr<AudioRegion>();
1646 as = boost::dynamic_pointer_cast<AudioSource>(source);
1648 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1649 return boost::shared_ptr<AudioRegion>();
1651 sources.push_back (as);
1655 for (uint32_t n = 0; n < nchans; ++n) {
1656 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1657 if ((prop = node.property (buf)) != 0) {
1659 PBD::ID id2 (prop->value());
1661 if ((source = source_by_id (id2)) == 0) {
1662 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1663 return boost::shared_ptr<AudioRegion>();
1666 as = boost::dynamic_pointer_cast<AudioSource>(source);
1668 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1669 return boost::shared_ptr<AudioRegion>();
1671 master_sources.push_back (as);
1676 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1678 /* a final detail: this is the one and only place that we know how long missing files are */
1680 if (region->whole_file()) {
1681 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1682 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1684 sfp->set_length (region->length());
1689 if (!master_sources.empty()) {
1690 if (master_sources.size() != nchans) {
1691 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1693 region->set_master_sources (master_sources);
1701 catch (failed_constructor& err) {
1702 return boost::shared_ptr<AudioRegion>();
1706 boost::shared_ptr<MidiRegion>
1707 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1709 const XMLProperty* prop;
1710 boost::shared_ptr<Source> source;
1711 boost::shared_ptr<MidiSource> ms;
1713 uint32_t nchans = 1;
1715 if (node.name() != X_("Region")) {
1716 return boost::shared_ptr<MidiRegion>();
1719 if ((prop = node.property (X_("channels"))) != 0) {
1720 nchans = atoi (prop->value().c_str());
1723 if ((prop = node.property ("name")) == 0) {
1724 cerr << "no name for this region\n";
1728 // Multiple midi channels? that's just crazy talk
1729 assert(nchans == 1);
1731 if ((prop = node.property (X_("source-0"))) == 0) {
1732 if ((prop = node.property ("source")) == 0) {
1733 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1734 return boost::shared_ptr<MidiRegion>();
1738 PBD::ID s_id (prop->value());
1740 if ((source = source_by_id (s_id)) == 0) {
1741 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1742 return boost::shared_ptr<MidiRegion>();
1745 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1747 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1748 return boost::shared_ptr<MidiRegion>();
1751 sources.push_back (ms);
1754 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1755 /* a final detail: this is the one and only place that we know how long missing files are */
1757 if (region->whole_file()) {
1758 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1759 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1761 sfp->set_length (region->length());
1769 catch (failed_constructor& err) {
1770 return boost::shared_ptr<MidiRegion>();
1775 Session::get_sources_as_xml ()
1778 XMLNode* node = new XMLNode (X_("Sources"));
1779 Glib::Mutex::Lock lm (source_lock);
1781 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1782 node->add_child_nocopy (i->second->get_state());
1789 Session::path_from_region_name (DataType type, string name, string identifier)
1791 char buf[PATH_MAX+1];
1793 SessionDirectory sdir(get_best_session_directory_for_new_source());
1794 sys::path source_dir = ((type == DataType::AUDIO)
1795 ? sdir.sound_path() : sdir.midi_path());
1797 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1799 for (n = 0; n < 999999; ++n) {
1800 if (identifier.length()) {
1801 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1802 identifier.c_str(), n, ext.c_str());
1804 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1808 sys::path source_path = source_dir / buf;
1810 if (!sys::exists (source_path)) {
1811 return source_path.to_string();
1815 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1824 Session::load_sources (const XMLNode& node)
1827 XMLNodeConstIterator niter;
1828 boost::shared_ptr<Source> source;
1830 nlist = node.children();
1834 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1836 if ((source = XMLSourceFactory (**niter)) == 0) {
1837 error << _("Session: cannot create Source from XML description.") << endmsg;
1839 } catch (MissingSource& err) {
1840 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1841 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1848 boost::shared_ptr<Source>
1849 Session::XMLSourceFactory (const XMLNode& node)
1851 if (node.name() != "Source") {
1852 return boost::shared_ptr<Source>();
1856 /* note: do peak building in another thread when loading session state */
1857 return SourceFactory::create (*this, node, true);
1860 catch (failed_constructor& err) {
1861 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1862 return boost::shared_ptr<Source>();
1867 Session::save_template (string template_name)
1871 if (_state_of_the_state & CannotSave) {
1875 sys::path user_template_dir(user_template_directory());
1879 sys::create_directories (user_template_dir);
1881 catch(sys::filesystem_error& ex)
1883 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1884 user_template_dir.to_string(), ex.what()) << endmsg;
1888 tree.set_root (&get_template());
1890 sys::path template_file_path(user_template_dir);
1891 template_file_path /= template_name + template_suffix;
1893 if (sys::exists (template_file_path))
1895 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1896 template_file_path.to_string()) << endmsg;
1900 if (!tree.write (template_file_path.to_string())) {
1901 error << _("mix template not saved") << endmsg;
1909 Session::rename_template (string old_name, string new_name)
1911 sys::path old_path (user_template_directory());
1912 old_path /= old_name + template_suffix;
1914 sys::path new_path(user_template_directory());
1915 new_path /= new_name + template_suffix;
1917 if (sys::exists (new_path)) {
1918 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1919 new_path.to_string()) << endmsg;
1924 sys::rename (old_path, new_path);
1932 Session::delete_template (string name)
1934 sys::path path = user_template_directory();
1935 path /= name + template_suffix;
1946 Session::refresh_disk_space ()
1949 struct statfs statfsbuf;
1950 vector<space_and_path>::iterator i;
1951 Glib::Mutex::Lock lm (space_lock);
1954 /* get freespace on every FS that is part of the session path */
1956 _total_free_4k_blocks = 0;
1958 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1959 statfs ((*i).path.c_str(), &statfsbuf);
1961 scale = statfsbuf.f_bsize/4096.0;
1963 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1964 _total_free_4k_blocks += (*i).blocks;
1970 Session::get_best_session_directory_for_new_source ()
1972 vector<space_and_path>::iterator i;
1973 string result = _session_dir->root_path().to_string();
1975 /* handle common case without system calls */
1977 if (session_dirs.size() == 1) {
1981 /* OK, here's the algorithm we're following here:
1983 We want to select which directory to use for
1984 the next file source to be created. Ideally,
1985 we'd like to use a round-robin process so as to
1986 get maximum performance benefits from splitting
1987 the files across multiple disks.
1989 However, in situations without much diskspace, an
1990 RR approach may end up filling up a filesystem
1991 with new files while others still have space.
1992 Its therefore important to pay some attention to
1993 the freespace in the filesystem holding each
1994 directory as well. However, if we did that by
1995 itself, we'd keep creating new files in the file
1996 system with the most space until it was as full
1997 as all others, thus negating any performance
1998 benefits of this RAID-1 like approach.
2000 So, we use a user-configurable space threshold. If
2001 there are at least 2 filesystems with more than this
2002 much space available, we use RR selection between them.
2003 If not, then we pick the filesystem with the most space.
2005 This gets a good balance between the two
2009 refresh_disk_space ();
2011 int free_enough = 0;
2013 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2014 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2019 if (free_enough >= 2) {
2020 /* use RR selection process, ensuring that the one
2024 i = last_rr_session_dir;
2027 if (++i == session_dirs.end()) {
2028 i = session_dirs.begin();
2031 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2032 if (create_session_directory ((*i).path)) {
2034 last_rr_session_dir = i;
2039 } while (i != last_rr_session_dir);
2043 /* pick FS with the most freespace (and that
2044 seems to actually work ...)
2047 vector<space_and_path> sorted;
2048 space_and_path_ascending_cmp cmp;
2050 sorted = session_dirs;
2051 sort (sorted.begin(), sorted.end(), cmp);
2053 for (i = sorted.begin(); i != sorted.end(); ++i) {
2054 if (create_session_directory ((*i).path)) {
2056 last_rr_session_dir = i;
2066 Session::load_named_selections (const XMLNode& node)
2069 XMLNodeConstIterator niter;
2072 nlist = node.children();
2076 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2078 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2079 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2087 Session::XMLNamedSelectionFactory (const XMLNode& node)
2090 return new NamedSelection (*this, node);
2093 catch (failed_constructor& err) {
2099 Session::automation_dir () const
2101 return Glib::build_filename (_path, "automation");
2105 Session::analysis_dir () const
2107 return Glib::build_filename (_path, "analysis");
2111 Session::load_bundles (XMLNode const & node)
2113 XMLNodeList nlist = node.children();
2114 XMLNodeConstIterator niter;
2118 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2119 if ((*niter)->name() == "InputBundle") {
2120 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2121 } else if ((*niter)->name() == "OutputBundle") {
2122 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2124 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2133 Session::load_route_groups (const XMLNode& node, int version)
2135 XMLNodeList nlist = node.children();
2136 XMLNodeConstIterator niter;
2140 if (version >= 3000) {
2142 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2143 if ((*niter)->name() == "RouteGroup") {
2144 RouteGroup* rg = new RouteGroup (*this, "");
2145 add_route_group (rg);
2146 rg->set_state (**niter, version);
2150 } else if (version < 3000) {
2152 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2153 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2154 RouteGroup* rg = new RouteGroup (*this, "");
2155 add_route_group (rg);
2156 rg->set_state (**niter, version);
2165 Session::auto_save()
2167 save_state (_current_snapshot_name);
2171 state_file_filter (const string &str, void */*arg*/)
2173 return (str.length() > strlen(statefile_suffix) &&
2174 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2178 bool operator()(const string* a, const string* b) {
2184 remove_end(string* state)
2186 string statename(*state);
2188 string::size_type start,end;
2189 if ((start = statename.find_last_of ('/')) != string::npos) {
2190 statename = statename.substr (start+1);
2193 if ((end = statename.rfind(".ardour")) == string::npos) {
2194 end = statename.length();
2197 return new string(statename.substr (0, end));
2201 Session::possible_states (string path)
2203 PathScanner scanner;
2204 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2206 transform(states->begin(), states->end(), states->begin(), remove_end);
2209 sort (states->begin(), states->end(), cmp);
2215 Session::possible_states () const
2217 return possible_states(_path);
2221 Session::add_route_group (RouteGroup* g)
2223 _route_groups.push_back (g);
2224 route_group_added (g); /* EMIT SIGNAL */
2229 Session::remove_route_group (RouteGroup& rg)
2231 list<RouteGroup*>::iterator i;
2233 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2234 _route_groups.erase (i);
2237 route_group_removed (); /* EMIT SIGNAL */
2243 Session::route_group_by_name (string name)
2245 list<RouteGroup *>::iterator i;
2247 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2248 if ((*i)->name() == name) {
2256 Session::start_reversible_command (const string& name)
2258 UndoTransaction* trans = new UndoTransaction();
2259 trans->set_name(name);
2264 Session::finish_reversible_command (UndoTransaction& ut)
2267 gettimeofday(&now, 0);
2268 ut.set_timestamp(now);
2273 Session::begin_reversible_command(const string& name)
2275 UndoTransaction* trans = new UndoTransaction();
2276 trans->set_name(name);
2278 if (!_current_trans.empty()) {
2279 _current_trans.top()->add_command (trans);
2281 _current_trans.push(trans);
2286 Session::commit_reversible_command(Command *cmd)
2288 assert(!_current_trans.empty());
2292 _current_trans.top()->add_command(cmd);
2295 if (_current_trans.top()->empty()) {
2296 _current_trans.pop();
2300 gettimeofday(&now, 0);
2301 _current_trans.top()->set_timestamp(now);
2303 _history.add(_current_trans.top());
2304 _current_trans.pop();
2308 accept_all_non_peak_files (const string& path, void */*arg*/)
2310 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2314 accept_all_state_files (const string& path, void */*arg*/)
2316 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2320 Session::find_all_sources (string path, set<string>& result)
2325 if (!tree.read (path)) {
2329 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2334 XMLNodeConstIterator niter;
2336 nlist = node->children();
2340 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2344 if ((prop = (*niter)->property (X_("type"))) == 0) {
2348 DataType type (prop->value());
2350 if ((prop = (*niter)->property (X_("name"))) == 0) {
2354 if (prop->value()[0] == '/') {
2355 /* external file, ignore */
2359 Glib::ustring found_path;
2363 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2364 result.insert (found_path);
2372 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2374 PathScanner scanner;
2375 vector<string*>* state_files;
2377 string this_snapshot_path;
2383 if (ripped[ripped.length()-1] == '/') {
2384 ripped = ripped.substr (0, ripped.length() - 1);
2387 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2389 if (state_files == 0) {
2394 this_snapshot_path = _path;
2395 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2396 this_snapshot_path += statefile_suffix;
2398 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2400 if (exclude_this_snapshot && **i == this_snapshot_path) {
2404 if (find_all_sources (**i, result) < 0) {
2412 struct RegionCounter {
2413 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2414 AudioSourceList::iterator iter;
2415 boost::shared_ptr<Region> region;
2418 RegionCounter() : count (0) {}
2422 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2424 return *AskAboutPlaylistDeletion (p);
2428 Session::cleanup_sources (CleanupReport& rep)
2430 // FIXME: needs adaptation to midi
2432 vector<boost::shared_ptr<Source> > dead_sources;
2433 PathScanner scanner;
2435 vector<space_and_path>::iterator i;
2436 vector<space_and_path>::iterator nexti;
2437 vector<string*>* soundfiles;
2438 vector<string> unused;
2439 set<string> all_sources;
2444 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2446 /* step 1: consider deleting all unused playlists */
2448 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2453 /* step 2: find all un-used sources */
2458 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2460 SourceMap::iterator tmp;
2465 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2469 if (!playlists->source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2470 dead_sources.push_back (i->second);
2471 i->second->drop_references ();
2477 /* build a list of all the possible sound directories for the session */
2479 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2484 SessionDirectory sdir ((*i).path);
2485 sound_path += sdir.sound_path().to_string();
2487 if (nexti != session_dirs.end()) {
2494 /* now do the same thing for the files that ended up in the sounds dir(s)
2495 but are not referenced as sources in any snapshot.
2498 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2500 if (soundfiles == 0) {
2504 /* find all sources, but don't use this snapshot because the
2505 state file on disk still references sources we may have already
2509 find_all_sources_across_snapshots (all_sources, true);
2511 /* add our current source list
2514 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2515 boost::shared_ptr<FileSource> fs;
2517 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2518 all_sources.insert (fs->path());
2522 char tmppath1[PATH_MAX+1];
2523 char tmppath2[PATH_MAX+1];
2525 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2530 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2532 realpath(spath.c_str(), tmppath1);
2533 realpath((*i).c_str(), tmppath2);
2535 if (strcmp(tmppath1, tmppath2) == 0) {
2542 unused.push_back (spath);
2546 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2548 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2549 struct stat statbuf;
2551 rep.paths.push_back (*x);
2552 if (stat ((*x).c_str(), &statbuf) == 0) {
2553 rep.space += statbuf.st_size;
2558 /* don't move the file across filesystems, just
2559 stick it in the `dead_sound_dir_name' directory
2560 on whichever filesystem it was already on.
2563 if ((*x).find ("/sounds/") != string::npos) {
2565 /* old school, go up 1 level */
2567 newpath = Glib::path_get_dirname (*x); // "sounds"
2568 newpath = Glib::path_get_dirname (newpath); // "session-name"
2572 /* new school, go up 4 levels */
2574 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2575 newpath = Glib::path_get_dirname (newpath); // "session-name"
2576 newpath = Glib::path_get_dirname (newpath); // "interchange"
2577 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2581 newpath += dead_sound_dir_name;
2583 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2584 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2589 newpath += Glib::path_get_basename ((*x));
2591 if (access (newpath.c_str(), F_OK) == 0) {
2593 /* the new path already exists, try versioning */
2595 char buf[PATH_MAX+1];
2599 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2602 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2603 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2607 if (version == 999) {
2608 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2612 newpath = newpath_v;
2617 /* it doesn't exist, or we can't read it or something */
2621 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2622 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2623 (*x), newpath, strerror (errno))
2628 /* see if there an easy to find peakfile for this file, and remove it.
2631 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2632 peakpath += peakfile_suffix;
2634 if (access (peakpath.c_str(), W_OK) == 0) {
2635 if (::unlink (peakpath.c_str()) != 0) {
2636 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2637 peakpath, _path, strerror (errno))
2639 /* try to back out */
2640 rename (newpath.c_str(), _path.c_str());
2648 /* dump the history list */
2652 /* save state so we don't end up a session file
2653 referring to non-existent sources.
2659 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2665 Session::cleanup_trash_sources (CleanupReport& rep)
2667 // FIXME: needs adaptation for MIDI
2669 vector<space_and_path>::iterator i;
2670 string dead_sound_dir;
2671 struct dirent* dentry;
2672 struct stat statbuf;
2678 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2680 dead_sound_dir = (*i).path;
2681 dead_sound_dir += dead_sound_dir_name;
2683 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2687 while ((dentry = readdir (dead)) != 0) {
2689 /* avoid '.' and '..' */
2691 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2692 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2698 fullpath = dead_sound_dir;
2700 fullpath += dentry->d_name;
2702 if (stat (fullpath.c_str(), &statbuf)) {
2706 if (!S_ISREG (statbuf.st_mode)) {
2710 if (unlink (fullpath.c_str())) {
2711 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2712 fullpath, strerror (errno))
2716 rep.paths.push_back (dentry->d_name);
2717 rep.space += statbuf.st_size;
2728 Session::set_dirty ()
2730 bool was_dirty = dirty();
2732 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2736 DirtyChanged(); /* EMIT SIGNAL */
2742 Session::set_clean ()
2744 bool was_dirty = dirty();
2746 _state_of_the_state = Clean;
2750 DirtyChanged(); /* EMIT SIGNAL */
2755 Session::set_deletion_in_progress ()
2757 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2761 Session::clear_deletion_in_progress ()
2763 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2767 Session::add_controllable (boost::shared_ptr<Controllable> c)
2769 /* this adds a controllable to the list managed by the Session.
2770 this is a subset of those managed by the Controllable class
2771 itself, and represents the only ones whose state will be saved
2772 as part of the session.
2775 Glib::Mutex::Lock lm (controllables_lock);
2776 controllables.insert (c);
2779 struct null_deleter { void operator()(void const *) const {} };
2782 Session::remove_controllable (Controllable* c)
2784 if (_state_of_the_state | Deletion) {
2788 Glib::Mutex::Lock lm (controllables_lock);
2790 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2792 if (x != controllables.end()) {
2793 controllables.erase (x);
2797 boost::shared_ptr<Controllable>
2798 Session::controllable_by_id (const PBD::ID& id)
2800 Glib::Mutex::Lock lm (controllables_lock);
2802 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2803 if ((*i)->id() == id) {
2808 return boost::shared_ptr<Controllable>();
2811 boost::shared_ptr<Controllable>
2812 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2814 boost::shared_ptr<Controllable> c;
2815 boost::shared_ptr<Route> r;
2817 switch (desc.top_level_type()) {
2818 case ControllableDescriptor::NamedRoute:
2820 std::string str = desc.top_level_name();
2821 if (str == "master") {
2823 } else if (str == "control" || str == "listen") {
2826 r = route_by_name (desc.top_level_name());
2831 case ControllableDescriptor::RemoteControlID:
2832 r = route_by_remote_id (desc.rid());
2840 switch (desc.subtype()) {
2841 case ControllableDescriptor::Gain:
2842 c = r->gain_control ();
2845 case ControllableDescriptor::Solo:
2846 c = r->solo_control();
2849 case ControllableDescriptor::Mute:
2850 c = r->mute_control();
2853 case ControllableDescriptor::Recenable:
2855 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2858 c = t->rec_enable_control ();
2863 case ControllableDescriptor::Pan:
2864 /* XXX pan control */
2867 case ControllableDescriptor::Balance:
2868 /* XXX simple pan control */
2871 case ControllableDescriptor::PluginParameter:
2873 uint32_t plugin = desc.target (0);
2874 uint32_t parameter_index = desc.target (1);
2876 /* revert to zero based counting */
2882 if (parameter_index > 0) {
2886 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2889 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2890 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2895 case ControllableDescriptor::SendGain:
2897 uint32_t send = desc.target (0);
2899 /* revert to zero-based counting */
2905 boost::shared_ptr<Processor> p = r->nth_send (send);
2908 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2909 boost::shared_ptr<Amp> a = s->amp();
2912 c = s->amp()->gain_control();
2919 /* relax and return a null pointer */
2927 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2930 Stateful::add_instant_xml (node, _path);
2933 if (write_to_config) {
2934 Config->add_instant_xml (node);
2939 Session::instant_xml (const string& node_name)
2941 return Stateful::instant_xml (node_name, _path);
2945 Session::save_history (string snapshot_name)
2953 if (snapshot_name.empty()) {
2954 snapshot_name = _current_snapshot_name;
2957 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2958 const string backup_filename = history_filename + backup_suffix;
2959 const sys::path xml_path = _session_dir->root_path() / history_filename;
2960 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2962 if (sys::exists (xml_path)) {
2965 sys::rename (xml_path, backup_path);
2967 catch (const sys::filesystem_error& err)
2969 error << _("could not backup old history file, current history not saved") << endmsg;
2974 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2978 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2980 if (!tree.write (xml_path.to_string()))
2982 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2986 sys::remove (xml_path);
2987 sys::rename (backup_path, xml_path);
2989 catch (const sys::filesystem_error& err)
2991 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2992 backup_path.to_string(), err.what()) << endmsg;
3002 Session::restore_history (string snapshot_name)
3006 if (snapshot_name.empty()) {
3007 snapshot_name = _current_snapshot_name;
3010 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3011 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3013 info << "Loading history from " << xml_path.to_string() << endmsg;
3015 if (!sys::exists (xml_path)) {
3016 info << string_compose (_("%1: no history file \"%2\" for this session."),
3017 _name, xml_path.to_string()) << endmsg;
3021 if (!tree.read (xml_path.to_string())) {
3022 error << string_compose (_("Could not understand session history file \"%1\""),
3023 xml_path.to_string()) << endmsg;
3030 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3033 UndoTransaction* ut = new UndoTransaction ();
3036 ut->set_name(t->property("name")->value());
3037 stringstream ss(t->property("tv-sec")->value());
3039 ss.str(t->property("tv-usec")->value());
3041 ut->set_timestamp(tv);
3043 for (XMLNodeConstIterator child_it = t->children().begin();
3044 child_it != t->children().end(); child_it++)
3046 XMLNode *n = *child_it;
3049 if (n->name() == "MementoCommand" ||
3050 n->name() == "MementoUndoCommand" ||
3051 n->name() == "MementoRedoCommand") {
3053 if ((c = memento_command_factory(n))) {
3057 } else if (n->name() == "DeltaCommand") {
3058 PBD::ID id(n->property("midi-source")->value());
3059 boost::shared_ptr<MidiSource> midi_source =
3060 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3062 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3064 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3067 } else if (n->name() == "DiffCommand") {
3068 PBD::ID id(n->property("midi-source")->value());
3069 boost::shared_ptr<MidiSource> midi_source =
3070 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3072 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3074 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3077 } else if (n->name() == "StatefulDiffCommand") {
3078 if ((c = stateful_diff_command_factory (n))) {
3079 ut->add_command (c);
3082 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3093 Session::config_changed (std::string p, bool ours)
3099 if (p == "seamless-loop") {
3101 } else if (p == "rf-speed") {
3103 } else if (p == "auto-loop") {
3105 } else if (p == "auto-input") {
3107 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3108 /* auto-input only makes a difference if we're rolling */
3110 boost::shared_ptr<RouteList> rl = routes.reader ();
3111 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3112 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3113 if (tr && tr->record_enabled ()) {
3114 tr->monitor_input (!config.get_auto_input());
3119 } else if (p == "punch-in") {
3123 if ((location = _locations.auto_punch_location()) != 0) {
3125 if (config.get_punch_in ()) {
3126 replace_event (SessionEvent::PunchIn, location->start());
3128 remove_event (location->start(), SessionEvent::PunchIn);
3132 } else if (p == "punch-out") {
3136 if ((location = _locations.auto_punch_location()) != 0) {
3138 if (config.get_punch_out()) {
3139 replace_event (SessionEvent::PunchOut, location->end());
3141 clear_events (SessionEvent::PunchOut);
3145 } else if (p == "edit-mode") {
3147 Glib::Mutex::Lock lm (playlists->lock);
3149 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3150 (*i)->set_edit_mode (Config->get_edit_mode ());
3153 } else if (p == "use-video-sync") {
3155 waiting_for_sync_offset = config.get_use_video_sync();
3157 } else if (p == "mmc-control") {
3159 //poke_midi_thread ();
3161 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3164 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3167 } else if (p == "mmc-send-id") {
3170 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3173 } else if (p == "midi-control") {
3175 //poke_midi_thread ();
3177 } else if (p == "raid-path") {
3179 setup_raid_path (config.get_raid_path());
3181 } else if (p == "timecode-format") {
3185 } else if (p == "video-pullup") {
3189 } else if (p == "seamless-loop") {
3191 if (play_loop && transport_rolling()) {
3192 // to reset diskstreams etc
3193 request_play_loop (true);
3196 } else if (p == "rf-speed") {
3198 cumulative_rf_motion = 0;
3201 } else if (p == "click-sound") {
3203 setup_click_sounds (1);
3205 } else if (p == "click-emphasis-sound") {
3207 setup_click_sounds (-1);
3209 } else if (p == "clicking") {
3211 if (Config->get_clicking()) {
3212 if (_click_io && click_data) { // don't require emphasis data
3219 } else if (p == "send-mtc") {
3221 /* only set the internal flag if we have
3225 if (_mtc_port != 0) {
3226 session_send_mtc = Config->get_send_mtc();
3227 if (session_send_mtc) {
3228 /* mark us ready to send */
3229 next_quarter_frame_to_send = 0;
3232 session_send_mtc = false;
3235 } else if (p == "send-mmc") {
3237 /* only set the internal flag if we have
3241 if (_mmc_port != 0) {
3242 session_send_mmc = Config->get_send_mmc();
3245 session_send_mmc = false;
3248 } else if (p == "midi-feedback") {
3250 /* only set the internal flag if we have
3254 if (_mtc_port != 0) {
3255 session_midi_feedback = Config->get_midi_feedback();
3258 } else if (p == "jack-time-master") {
3260 engine().reset_timebase ();
3262 } else if (p == "native-file-header-format") {
3264 if (!first_file_header_format_reset) {
3265 reset_native_file_format ();
3268 first_file_header_format_reset = false;
3270 } else if (p == "native-file-data-format") {
3272 if (!first_file_data_format_reset) {
3273 reset_native_file_format ();
3276 first_file_data_format_reset = false;
3278 } else if (p == "external-sync") {
3279 if (!config.get_external_sync()) {
3280 drop_sync_source ();
3282 switch_to_sync_source (config.get_sync_source());
3284 } else if (p == "remote-model") {
3285 set_remote_control_ids ();
3286 } else if (p == "denormal-model") {
3288 } else if (p == "history-depth") {
3289 set_history_depth (Config->get_history_depth());
3290 } else if (p == "sync-all-route-ordering") {
3291 sync_order_keys ("session");
3292 } else if (p == "initial-program-change") {
3294 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3297 buf[0] = MIDI::program; // channel zero by default
3298 buf[1] = (Config->get_initial_program_change() & 0x7f);
3300 _mmc_port->midimsg (buf, sizeof (buf), 0);
3302 } else if (p == "initial-program-change") {
3304 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3305 MIDI::byte* buf = new MIDI::byte[2];
3307 buf[0] = MIDI::program; // channel zero by default
3308 buf[1] = (Config->get_initial_program_change() & 0x7f);
3309 // deliver_midi (_mmc_port, buf, 2);
3311 } else if (p == "solo-mute-override") {
3312 // catch_up_on_solo_mute_override ();
3313 } else if (p == "listen-position") {
3314 listen_position_changed ();
3315 } else if (p == "solo-control-is-listen-control") {
3316 solo_control_mode_changed ();
3324 Session::set_history_depth (uint32_t d)
3326 _history.set_depth (d);
3330 Session::load_diskstreams_2X (XMLNode const & node, int)
3333 XMLNodeConstIterator citer;
3335 clist = node.children();
3337 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3340 /* diskstreams added automatically by DiskstreamCreated handler */
3341 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3342 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3343 _diskstreams_2X.push_back (dsp);
3345 error << _("Session: unknown diskstream type in XML") << endmsg;
3349 catch (failed_constructor& err) {
3350 error << _("Session: could not load diskstream via XML state") << endmsg;