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/port.h"
96 #include "ardour/region_factory.h"
97 #include "ardour/route_group.h"
98 #include "ardour/send.h"
99 #include "ardour/session.h"
100 #include "ardour/session_directory.h"
101 #include "ardour/session_metadata.h"
102 #include "ardour/session_state_utils.h"
103 #include "ardour/session_playlists.h"
104 #include "ardour/session_utils.h"
105 #include "ardour/silentfilesource.h"
106 #include "ardour/slave.h"
107 #include "ardour/smf_source.h"
108 #include "ardour/sndfile_helpers.h"
109 #include "ardour/sndfilesource.h"
110 #include "ardour/source_factory.h"
111 #include "ardour/template_utils.h"
112 #include "ardour/tempo.h"
113 #include "ardour/ticker.h"
114 #include "ardour/user_bundle.h"
115 #include "ardour/utils.h"
116 #include "ardour/utils.h"
117 #include "ardour/version.h"
118 #include "ardour/playlist_factory.h"
120 #include "control_protocol/control_protocol.h"
126 using namespace ARDOUR;
130 Session::first_stage_init (string fullpath, string snapshot_name)
132 if (fullpath.length() == 0) {
134 throw failed_constructor();
137 char buf[PATH_MAX+1];
138 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
139 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
141 throw failed_constructor();
146 if (_path[_path.length()-1] != '/') {
150 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
156 /* these two are just provisional settings. set_state()
157 will likely override them.
160 _name = _current_snapshot_name = snapshot_name;
162 set_history_depth (Config->get_history_depth());
164 _current_frame_rate = _engine.frame_rate ();
165 _nominal_frame_rate = _current_frame_rate;
166 _base_frame_rate = _current_frame_rate;
168 _tempo_map = new TempoMap (_current_frame_rate);
169 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
172 _non_soloed_outs_muted = false;
174 _solo_isolated_cnt = 0;
175 g_atomic_int_set (&processing_prohibited, 0);
176 _transport_speed = 0;
177 _last_transport_speed = 0;
178 _target_transport_speed = 0;
179 auto_play_legal = false;
180 transport_sub_state = 0;
181 _transport_frame = 0;
182 _requested_return_frame = -1;
183 _session_range_location = 0;
184 g_atomic_int_set (&_record_status, Disabled);
185 loop_changing = false;
188 _last_roll_location = 0;
189 _last_roll_or_reversal_location = 0;
190 _last_record_location = 0;
191 pending_locate_frame = 0;
192 pending_locate_roll = false;
193 pending_locate_flush = false;
194 state_was_pending = false;
196 outbound_mtc_timecode_frame = 0;
197 next_quarter_frame_to_send = -1;
198 current_block_size = 0;
199 solo_update_disabled = false;
200 _have_captured = false;
201 _worst_output_latency = 0;
202 _worst_input_latency = 0;
203 _worst_track_latency = 0;
204 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
205 _was_seamless = Config->get_seamless_loop ();
207 session_send_mmc = false;
208 session_send_mtc = false;
209 g_atomic_int_set (&_playback_load, 100);
210 g_atomic_int_set (&_capture_load, 100);
213 pending_abort = false;
214 destructive_index = 0;
215 first_file_data_format_reset = true;
216 first_file_header_format_reset = true;
217 post_export_sync = false;
220 AudioDiskstream::allocate_working_buffers();
222 /* default short fade = 15ms */
224 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
225 SndFileSource::setup_standard_crossfades (*this, frame_rate());
227 last_mmc_step.tv_sec = 0;
228 last_mmc_step.tv_usec = 0;
231 /* click sounds are unset by default, which causes us to internal
232 waveforms for clicks.
236 click_emphasis_length = 0;
239 process_function = &Session::process_with_events;
241 if (config.get_use_video_sync()) {
242 waiting_for_sync_offset = true;
244 waiting_for_sync_offset = false;
247 last_timecode_when = 0;
248 _timecode_offset = 0;
249 _timecode_offset_negative = true;
250 last_timecode_valid = false;
254 last_rr_session_dir = session_dirs.begin();
255 refresh_disk_space ();
257 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
261 average_slave_delta = 1800; // !!! why 1800 ????
262 have_first_delta_accumulator = false;
263 delta_accumulator_cnt = 0;
264 _slave_state = Stopped;
266 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
268 /* These are all static "per-class" signals */
270 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
271 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
272 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
273 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
274 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
276 /* stop IO objects from doing stuff until we're ready for them */
278 Delivery::disable_panners ();
279 IO::disable_connecting ();
283 Session::second_stage_init ()
285 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
288 if (load_state (_current_snapshot_name)) {
291 remove_empty_sounds ();
294 if (_butler->start_thread()) {
298 if (start_midi_thread ()) {
302 // set_state() will call setup_raid_path(), but if it's a new session we need
303 // to call setup_raid_path() here.
306 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
310 setup_raid_path(_path);
313 /* we can't save till after ::when_engine_running() is called,
314 because otherwise we save state with no connections made.
315 therefore, we reset _state_of_the_state because ::set_state()
316 will have cleared it.
318 we also have to include Loading so that any events that get
319 generated between here and the end of ::when_engine_running()
320 will be processed directly rather than queued.
323 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
326 _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
327 _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
328 setup_click_sounds (0);
329 setup_midi_control ();
331 /* Pay attention ... */
333 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
334 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
337 when_engine_running ();
340 /* handle this one in a different way than all others, so that its clear what happened */
342 catch (AudioEngine::PortRegistrationFailure& err) {
343 error << err.what() << endmsg;
351 BootMessage (_("Reset Remote Controls"));
353 send_full_time_code (0);
354 _engine.transport_locate (0);
355 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
356 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
358 MidiClockTicker::instance().set_session (this);
359 MIDI::Name::MidiPatchManager::instance().set_session (this);
361 /* initial program change will be delivered later; see ::config_changed() */
363 BootMessage (_("Reset Control Protocols"));
365 ControlProtocolManager::instance().set_session (this);
367 _state_of_the_state = Clean;
369 Port::set_connecting_blocked (false);
371 DirtyChanged (); /* EMIT SIGNAL */
373 if (state_was_pending) {
374 save_state (_current_snapshot_name);
375 remove_pending_capture_state ();
376 state_was_pending = false;
379 BootMessage (_("Session loading complete"));
385 Session::raid_path () const
387 SearchPath raid_search_path;
389 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
390 raid_search_path += sys::path((*i).path);
393 return raid_search_path.to_string ();
397 Session::setup_raid_path (string path)
406 session_dirs.clear ();
408 SearchPath search_path(path);
409 SearchPath sound_search_path;
410 SearchPath midi_search_path;
412 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
413 sp.path = (*i).to_string ();
414 sp.blocks = 0; // not needed
415 session_dirs.push_back (sp);
417 SessionDirectory sdir(sp.path);
419 sound_search_path += sdir.sound_path ();
420 midi_search_path += sdir.midi_path ();
423 // set the search path for each data type
424 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
425 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
427 // reset the round-robin soundfile path thingie
428 last_rr_session_dir = session_dirs.begin();
432 Session::path_is_within_session (const std::string& path)
434 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
435 if (path.find ((*i).path) == 0) {
443 Session::ensure_subdirs ()
447 dir = session_directory().peak_path().to_string();
449 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
450 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
454 dir = session_directory().sound_path().to_string();
456 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
457 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
461 dir = session_directory().midi_path().to_string();
463 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
464 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
468 dir = session_directory().dead_sound_path().to_string();
470 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
471 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
475 dir = session_directory().export_path().to_string();
477 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
478 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
482 dir = analysis_dir ();
484 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
485 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
493 Session::create (const string& mix_template, BusProfile* bus_profile)
496 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
497 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
501 if (ensure_subdirs ()) {
505 if (!mix_template.empty()) {
506 std::string in_path = mix_template;
508 ifstream in(in_path.c_str());
511 string out_path = _path;
513 out_path += statefile_suffix;
515 ofstream out(out_path.c_str());
523 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
529 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
536 /* Instantiate metadata */
538 _metadata = new SessionMetadata ();
540 /* set initial start + end point */
542 _state_of_the_state = Clean;
544 /* set up Master Out and Control Out if necessary */
550 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
552 if (bus_profile->master_out_channels) {
553 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
558 boost_debug_shared_ptr_mark_interesting (rt, "Route");
559 boost::shared_ptr<Route> r (rt);
560 r->input()->ensure_io (count, false, this);
561 r->output()->ensure_io (count, false, this);
562 r->set_remote_control_id (control_id++);
566 if (Config->get_use_monitor_bus()) {
567 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
572 boost_debug_shared_ptr_mark_interesting (rt, "Route");
573 boost::shared_ptr<Route> r (rt);
574 r->input()->ensure_io (count, false, this);
575 r->output()->ensure_io (count, false, this);
576 r->set_remote_control_id (control_id);
582 /* prohibit auto-connect to master, because there isn't one */
583 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
587 add_routes (rl, false);
590 /* this allows the user to override settings with an environment variable.
593 if (no_auto_connect()) {
594 bus_profile->input_ac = AutoConnectOption (0);
595 bus_profile->output_ac = AutoConnectOption (0);
598 Config->set_input_auto_connect (bus_profile->input_ac);
599 Config->set_output_auto_connect (bus_profile->output_ac);
608 Session::maybe_write_autosave()
610 if (dirty() && record_status() != Recording) {
611 save_state("", true);
616 Session::remove_pending_capture_state ()
618 sys::path pending_state_file_path(_session_dir->root_path());
620 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
624 sys::remove (pending_state_file_path);
626 catch(sys::filesystem_error& ex)
628 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
629 pending_state_file_path.to_string(), ex.what()) << endmsg;
633 /** Rename a state file.
634 * @param snapshot_name Snapshot name.
637 Session::rename_state (string old_name, string new_name)
639 if (old_name == _current_snapshot_name || old_name == _name) {
640 /* refuse to rename the current snapshot or the "main" one */
644 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
645 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
647 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
648 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
652 sys::rename (old_xml_path, new_xml_path);
654 catch (const sys::filesystem_error& err)
656 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
657 old_name, new_name, err.what()) << endmsg;
661 /** Remove a state file.
662 * @param snapshot_name Snapshot name.
665 Session::remove_state (string snapshot_name)
667 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
668 // refuse to remove the current snapshot or the "main" one
672 sys::path xml_path(_session_dir->root_path());
674 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
676 if (!create_backup_file (xml_path)) {
677 // don't remove it if a backup can't be made
678 // create_backup_file will log the error.
683 sys::remove (xml_path);
686 #ifdef HAVE_JACK_SESSION
688 Session::jack_session_event (jack_session_event_t * event)
692 struct tm local_time;
695 localtime_r (&n, &local_time);
696 strftime (timebuf, sizeof(timebuf), "JS_%FT%T", &local_time);
698 if (event->type == JackSessionSaveTemplate)
700 if (save_template( timebuf )) {
701 event->flags = JackSessionSaveError;
703 string cmd ("ardour3 -P -U ");
704 cmd += event->client_uuid;
708 event->command_line = strdup (cmd.c_str());
713 if (save_state (timebuf)) {
714 event->flags = JackSessionSaveError;
716 sys::path xml_path (_session_dir->root_path());
717 xml_path /= legalize_for_path (timebuf) + statefile_suffix;
719 string cmd ("ardour3 -P -U ");
720 cmd += event->client_uuid;
722 cmd += xml_path.to_string();
725 event->command_line = strdup (cmd.c_str());
729 jack_session_reply (_engine.jack(), event);
731 if (event->type == JackSessionSaveAndQuit) {
732 // TODO: make ardour quit.
735 jack_session_event_free( event );
740 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
743 sys::path xml_path(_session_dir->root_path());
745 if (!_writable || (_state_of_the_state & CannotSave)) {
749 if (!_engine.connected ()) {
750 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
756 /* tell sources we're saving first, in case they write out to a new file
757 * which should be saved with the state rather than the old one */
758 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
759 i->second->session_saved();
762 tree.set_root (&get_state());
764 if (snapshot_name.empty()) {
765 snapshot_name = _current_snapshot_name;
766 } else if (switch_to_snapshot) {
767 _current_snapshot_name = snapshot_name;
772 /* proper save: use statefile_suffix (.ardour in English) */
774 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
776 /* make a backup copy of the old file */
778 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
779 // create_backup_file will log the error
785 /* pending save: use pending_suffix (.pending in English) */
786 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
789 sys::path tmp_path(_session_dir->root_path());
791 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
793 // cerr << "actually writing state to " << xml_path.to_string() << endl;
795 if (!tree.write (tmp_path.to_string())) {
796 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
797 sys::remove (tmp_path);
802 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
803 error << string_compose (_("could not rename temporary session file %1 to %2"),
804 tmp_path.to_string(), xml_path.to_string()) << endmsg;
805 sys::remove (tmp_path);
812 save_history (snapshot_name);
814 bool was_dirty = dirty();
816 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
819 DirtyChanged (); /* EMIT SIGNAL */
822 StateSaved (snapshot_name); /* EMIT SIGNAL */
829 Session::restore_state (string snapshot_name)
831 if (load_state (snapshot_name) == 0) {
832 set_state (*state_tree->root(), Stateful::loading_state_version);
839 Session::load_state (string snapshot_name)
844 state_was_pending = false;
846 /* check for leftover pending state from a crashed capture attempt */
848 sys::path xmlpath(_session_dir->root_path());
849 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
851 if (sys::exists (xmlpath)) {
853 /* there is pending state from a crashed capture attempt */
855 boost::optional<int> r = AskAboutPendingState();
856 if (r.get_value_or (1)) {
857 state_was_pending = true;
861 if (!state_was_pending) {
862 xmlpath = _session_dir->root_path();
863 xmlpath /= snapshot_name;
866 if (!sys::exists (xmlpath)) {
867 xmlpath = _session_dir->root_path();
868 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
869 if (!sys::exists (xmlpath)) {
870 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
875 state_tree = new XMLTree;
879 /* writable() really reflects the whole folder, but if for any
880 reason the session state file can't be written to, still
884 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
888 if (!state_tree->read (xmlpath.to_string())) {
889 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
895 XMLNode& root (*state_tree->root());
897 if (root.name() != X_("Session")) {
898 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
904 const XMLProperty* prop;
906 if ((prop = root.property ("version")) == 0) {
907 /* no version implies very old version of Ardour */
908 Stateful::loading_state_version = 1000;
914 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
915 Stateful::loading_state_version = (major * 1000) + minor;
918 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
920 sys::path backup_path(_session_dir->root_path());
922 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
924 // only create a backup once
925 if (sys::exists (backup_path)) {
929 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
930 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
935 sys::copy_file (xmlpath, backup_path);
937 catch(sys::filesystem_error& ex)
939 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
940 xmlpath.to_string(), ex.what())
950 Session::load_options (const XMLNode& node)
952 LocaleGuard lg (X_("POSIX"));
953 config.set_variables (node);
964 Session::get_template()
966 /* if we don't disable rec-enable, diskstreams
967 will believe they need to store their capture
968 sources in their state node.
971 disable_record (false);
977 Session::state(bool full_state)
979 XMLNode* node = new XMLNode("Session");
982 // store libardour version, just in case
984 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
985 node->add_property("version", string(buf));
987 /* store configuration settings */
991 node->add_property ("name", _name);
992 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
993 node->add_property ("sample-rate", buf);
995 if (session_dirs.size() > 1) {
999 vector<space_and_path>::iterator i = session_dirs.begin();
1000 vector<space_and_path>::iterator next;
1002 ++i; /* skip the first one */
1006 while (i != session_dirs.end()) {
1010 if (next != session_dirs.end()) {
1020 child = node->add_child ("Path");
1021 child->add_content (p);
1025 /* save the ID counter */
1027 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1028 node->add_property ("id-counter", buf);
1030 /* various options */
1032 node->add_child_nocopy (config.get_variables ());
1034 node->add_child_nocopy (_metadata->get_state());
1036 child = node->add_child ("Sources");
1039 Glib::Mutex::Lock sl (source_lock);
1041 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1043 /* Don't save information about non-destructive file sources that are empty
1044 and unused by any regions.
1047 boost::shared_ptr<FileSource> fs;
1048 if ((fs = boost::dynamic_pointer_cast<FileSource> (siter->second)) != 0) {
1049 if (!fs->destructive()) {
1050 if (fs->empty() && !fs->used()) {
1056 child->add_child_nocopy (siter->second->get_state());
1060 child = node->add_child ("Regions");
1063 Glib::Mutex::Lock rl (region_lock);
1064 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1065 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1066 boost::shared_ptr<Region> r = i->second;
1067 /* only store regions not attached to playlists */
1068 if (r->playlist() == 0) {
1069 child->add_child_nocopy (r->state (true));
1075 node->add_child_nocopy (_locations.get_state());
1077 // for a template, just create a new Locations, populate it
1078 // with the default start and end, and get the state for that.
1080 Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
1081 range->set (max_frames, 0);
1083 node->add_child_nocopy (loc.get_state());
1086 child = node->add_child ("Bundles");
1088 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1089 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1090 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1092 child->add_child_nocopy (b->get_state());
1097 child = node->add_child ("Routes");
1099 boost::shared_ptr<RouteList> r = routes.reader ();
1101 RoutePublicOrderSorter cmp;
1102 RouteList public_order (*r);
1103 public_order.sort (cmp);
1105 /* the sort should have put control outs first */
1108 assert (_monitor_out == public_order.front());
1111 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1112 if (!(*i)->is_hidden()) {
1114 child->add_child_nocopy ((*i)->get_state());
1116 child->add_child_nocopy ((*i)->get_template());
1122 playlists->add_state (node, full_state);
1124 child = node->add_child ("RouteGroups");
1125 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1126 child->add_child_nocopy ((*i)->get_state());
1130 child = node->add_child ("Click");
1131 child->add_child_nocopy (_click_io->state (full_state));
1135 child = node->add_child ("NamedSelections");
1136 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1138 child->add_child_nocopy ((*i)->get_state());
1143 node->add_child_nocopy (_tempo_map->get_state());
1145 node->add_child_nocopy (get_control_protocol_state());
1148 node->add_child_copy (*_extra_xml);
1155 Session::get_control_protocol_state ()
1157 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1158 return cpm.get_state();
1162 Session::set_state (const XMLNode& node, int version)
1166 const XMLProperty* prop;
1169 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1171 if (node.name() != X_("Session")){
1172 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1176 if ((prop = node.property ("version")) != 0) {
1177 version = atoi (prop->value ()) * 1000;
1180 if ((prop = node.property ("name")) != 0) {
1181 _name = prop->value ();
1184 if ((prop = node.property (X_("sample-rate"))) != 0) {
1186 _nominal_frame_rate = atoi (prop->value());
1188 if (_nominal_frame_rate != _current_frame_rate) {
1189 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1190 if (r.get_value_or (0)) {
1196 setup_raid_path(_session_dir->root_path().to_string());
1198 if ((prop = node.property (X_("id-counter"))) != 0) {
1200 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1201 ID::init_counter (x);
1203 /* old sessions used a timebased counter, so fake
1204 the startup ID counter based on a standard
1209 ID::init_counter (now);
1213 IO::disable_connecting ();
1215 /* Object loading order:
1220 MIDI Control // relies on data from Options/Config
1233 if ((child = find_named_node (node, "Extra")) != 0) {
1234 _extra_xml = new XMLNode (*child);
1237 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1238 load_options (*child);
1239 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1240 load_options (*child);
1242 error << _("Session: XML state has no options section") << endmsg;
1245 if (use_config_midi_ports ()) {
1248 if (version >= 3000) {
1249 if ((child = find_named_node (node, "Metadata")) == 0) {
1250 warning << _("Session: XML state has no metadata section") << endmsg;
1251 } else if (_metadata->set_state (*child, version)) {
1256 if ((child = find_named_node (node, "Locations")) == 0) {
1257 error << _("Session: XML state has no locations section") << endmsg;
1259 } else if (_locations.set_state (*child, version)) {
1265 if ((location = _locations.auto_loop_location()) != 0) {
1266 set_auto_loop_location (location);
1269 if ((location = _locations.auto_punch_location()) != 0) {
1270 set_auto_punch_location (location);
1273 if ((location = _locations.session_range_location()) != 0) {
1274 delete _session_range_location;
1275 _session_range_location = location;
1278 if (_session_range_location) {
1279 AudioFileSource::set_header_position_offset (_session_range_location->start());
1282 if ((child = find_named_node (node, "Sources")) == 0) {
1283 error << _("Session: XML state has no sources section") << endmsg;
1285 } else if (load_sources (*child)) {
1289 if ((child = find_named_node (node, "Regions")) == 0) {
1290 error << _("Session: XML state has no Regions section") << endmsg;
1292 } else if (load_regions (*child)) {
1296 if ((child = find_named_node (node, "Playlists")) == 0) {
1297 error << _("Session: XML state has no playlists section") << endmsg;
1299 } else if (playlists->load (*this, *child)) {
1303 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1305 } else if (playlists->load_unused (*this, *child)) {
1309 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1310 if (load_named_selections (*child)) {
1315 if (version >= 3000) {
1316 if ((child = find_named_node (node, "Bundles")) == 0) {
1317 warning << _("Session: XML state has no bundles section") << endmsg;
1320 /* We can't load Bundles yet as they need to be able
1321 to convert from port names to Port objects, which can't happen until
1323 _bundle_xml_node = new XMLNode (*child);
1327 if ((child = find_named_node (node, "TempoMap")) == 0) {
1328 error << _("Session: XML state has no Tempo Map section") << endmsg;
1330 } else if (_tempo_map->set_state (*child, version)) {
1334 if (version < 3000) {
1335 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1336 error << _("Session: XML state has no diskstreams section") << endmsg;
1338 } else if (load_diskstreams_2X (*child, version)) {
1343 if ((child = find_named_node (node, "Routes")) == 0) {
1344 error << _("Session: XML state has no routes section") << endmsg;
1346 } else if (load_routes (*child, version)) {
1350 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1351 _diskstreams_2X.clear ();
1353 if (version >= 3000) {
1355 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1356 error << _("Session: XML state has no route groups section") << endmsg;
1358 } else if (load_route_groups (*child, version)) {
1362 } else if (version < 3000) {
1364 if ((child = find_named_node (node, "EditGroups")) == 0) {
1365 error << _("Session: XML state has no edit groups section") << endmsg;
1367 } else if (load_route_groups (*child, version)) {
1371 if ((child = find_named_node (node, "MixGroups")) == 0) {
1372 error << _("Session: XML state has no mix groups section") << endmsg;
1374 } else if (load_route_groups (*child, version)) {
1379 if ((child = find_named_node (node, "Click")) == 0) {
1380 warning << _("Session: XML state has no click section") << endmsg;
1381 } else if (_click_io) {
1382 _click_io->set_state (*child, version);
1385 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1386 ControlProtocolManager::instance().set_protocol_states (*child);
1389 /* here beginneth the second phase ... */
1391 StateReady (); /* EMIT SIGNAL */
1400 Session::load_routes (const XMLNode& node, int version)
1403 XMLNodeConstIterator niter;
1404 RouteList new_routes;
1406 nlist = node.children();
1410 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1412 boost::shared_ptr<Route> route;
1413 if (version < 3000) {
1414 route = XMLRouteFactory_2X (**niter, version);
1416 route = XMLRouteFactory (**niter, version);
1420 error << _("Session: cannot create Route from XML description.") << endmsg;
1424 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1426 new_routes.push_back (route);
1429 add_routes (new_routes, false);
1434 boost::shared_ptr<Route>
1435 Session::XMLRouteFactory (const XMLNode& node, int version)
1437 boost::shared_ptr<Route> ret;
1439 if (node.name() != "Route") {
1443 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1445 DataType type = DataType::AUDIO;
1446 const XMLProperty* prop = node.property("default-type");
1449 type = DataType (prop->value());
1452 assert (type != DataType::NIL);
1458 if (type == DataType::AUDIO) {
1459 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1462 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1465 if (track->init()) {
1470 if (track->set_state (node, version)) {
1475 boost_debug_shared_ptr_mark_interesting (track, "Track");
1479 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1481 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1482 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1492 boost::shared_ptr<Route>
1493 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1495 boost::shared_ptr<Route> ret;
1497 if (node.name() != "Route") {
1501 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1503 ds_prop = node.property (X_("diskstream"));
1506 DataType type = DataType::AUDIO;
1507 const XMLProperty* prop = node.property("default-type");
1510 type = DataType (prop->value());
1513 assert (type != DataType::NIL);
1517 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1518 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1522 if (i == _diskstreams_2X.end()) {
1523 error << _("Could not find diskstream for route") << endmsg;
1524 return boost::shared_ptr<Route> ();
1529 if (type == DataType::AUDIO) {
1530 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1533 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1536 if (track->init()) {
1541 if (track->set_state (node, version)) {
1546 track->set_diskstream (*i);
1548 boost_debug_shared_ptr_mark_interesting (track, "Track");
1552 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1554 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1555 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1566 Session::load_regions (const XMLNode& node)
1569 XMLNodeConstIterator niter;
1570 boost::shared_ptr<Region> region;
1572 nlist = node.children();
1576 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1577 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1578 error << _("Session: cannot create Region from XML description.");
1579 const XMLProperty *name = (**niter).property("name");
1582 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1592 boost::shared_ptr<Region>
1593 Session::XMLRegionFactory (const XMLNode& node, bool full)
1595 const XMLProperty* type = node.property("type");
1599 if ( !type || type->value() == "audio" ) {
1601 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1603 } else if (type->value() == "midi") {
1605 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1609 } catch (failed_constructor& err) {
1610 return boost::shared_ptr<Region> ();
1613 return boost::shared_ptr<Region> ();
1616 boost::shared_ptr<AudioRegion>
1617 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1619 const XMLProperty* prop;
1620 boost::shared_ptr<Source> source;
1621 boost::shared_ptr<AudioSource> as;
1623 SourceList master_sources;
1624 uint32_t nchans = 1;
1627 if (node.name() != X_("Region")) {
1628 return boost::shared_ptr<AudioRegion>();
1631 if ((prop = node.property (X_("channels"))) != 0) {
1632 nchans = atoi (prop->value().c_str());
1635 if ((prop = node.property ("name")) == 0) {
1636 cerr << "no name for this region\n";
1640 if ((prop = node.property (X_("source-0"))) == 0) {
1641 if ((prop = node.property ("source")) == 0) {
1642 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1643 return boost::shared_ptr<AudioRegion>();
1647 PBD::ID s_id (prop->value());
1649 if ((source = source_by_id (s_id)) == 0) {
1650 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1651 return boost::shared_ptr<AudioRegion>();
1654 as = boost::dynamic_pointer_cast<AudioSource>(source);
1656 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1657 return boost::shared_ptr<AudioRegion>();
1660 sources.push_back (as);
1662 /* pickup other channels */
1664 for (uint32_t n=1; n < nchans; ++n) {
1665 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1666 if ((prop = node.property (buf)) != 0) {
1668 PBD::ID id2 (prop->value());
1670 if ((source = source_by_id (id2)) == 0) {
1671 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1672 return boost::shared_ptr<AudioRegion>();
1675 as = boost::dynamic_pointer_cast<AudioSource>(source);
1677 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1678 return boost::shared_ptr<AudioRegion>();
1680 sources.push_back (as);
1684 for (uint32_t n = 0; n < nchans; ++n) {
1685 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1686 if ((prop = node.property (buf)) != 0) {
1688 PBD::ID id2 (prop->value());
1690 if ((source = source_by_id (id2)) == 0) {
1691 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1692 return boost::shared_ptr<AudioRegion>();
1695 as = boost::dynamic_pointer_cast<AudioSource>(source);
1697 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1698 return boost::shared_ptr<AudioRegion>();
1700 master_sources.push_back (as);
1705 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1707 /* a final detail: this is the one and only place that we know how long missing files are */
1709 if (region->whole_file()) {
1710 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1711 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1713 sfp->set_length (region->length());
1718 if (!master_sources.empty()) {
1719 if (master_sources.size() != nchans) {
1720 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1722 region->set_master_sources (master_sources);
1730 catch (failed_constructor& err) {
1731 return boost::shared_ptr<AudioRegion>();
1735 boost::shared_ptr<MidiRegion>
1736 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1738 const XMLProperty* prop;
1739 boost::shared_ptr<Source> source;
1740 boost::shared_ptr<MidiSource> ms;
1742 uint32_t nchans = 1;
1744 if (node.name() != X_("Region")) {
1745 return boost::shared_ptr<MidiRegion>();
1748 if ((prop = node.property (X_("channels"))) != 0) {
1749 nchans = atoi (prop->value().c_str());
1752 if ((prop = node.property ("name")) == 0) {
1753 cerr << "no name for this region\n";
1757 // Multiple midi channels? that's just crazy talk
1758 assert(nchans == 1);
1760 if ((prop = node.property (X_("source-0"))) == 0) {
1761 if ((prop = node.property ("source")) == 0) {
1762 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1763 return boost::shared_ptr<MidiRegion>();
1767 PBD::ID s_id (prop->value());
1769 if ((source = source_by_id (s_id)) == 0) {
1770 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1771 return boost::shared_ptr<MidiRegion>();
1774 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1776 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1777 return boost::shared_ptr<MidiRegion>();
1780 sources.push_back (ms);
1783 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1784 /* a final detail: this is the one and only place that we know how long missing files are */
1786 if (region->whole_file()) {
1787 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1788 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1790 sfp->set_length (region->length());
1798 catch (failed_constructor& err) {
1799 return boost::shared_ptr<MidiRegion>();
1804 Session::get_sources_as_xml ()
1807 XMLNode* node = new XMLNode (X_("Sources"));
1808 Glib::Mutex::Lock lm (source_lock);
1810 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1811 node->add_child_nocopy (i->second->get_state());
1818 Session::path_from_region_name (DataType type, string name, string identifier)
1820 char buf[PATH_MAX+1];
1822 SessionDirectory sdir(get_best_session_directory_for_new_source());
1823 sys::path source_dir = ((type == DataType::AUDIO)
1824 ? sdir.sound_path() : sdir.midi_path());
1826 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1828 for (n = 0; n < 999999; ++n) {
1829 if (identifier.length()) {
1830 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1831 identifier.c_str(), n, ext.c_str());
1833 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1837 sys::path source_path = source_dir / buf;
1839 if (!sys::exists (source_path)) {
1840 return source_path.to_string();
1844 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1853 Session::load_sources (const XMLNode& node)
1856 XMLNodeConstIterator niter;
1857 boost::shared_ptr<Source> source;
1859 nlist = node.children();
1863 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1865 if ((source = XMLSourceFactory (**niter)) == 0) {
1866 error << _("Session: cannot create Source from XML description.") << endmsg;
1868 } catch (MissingSource& err) {
1869 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1870 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1877 boost::shared_ptr<Source>
1878 Session::XMLSourceFactory (const XMLNode& node)
1880 if (node.name() != "Source") {
1881 return boost::shared_ptr<Source>();
1885 /* note: do peak building in another thread when loading session state */
1886 return SourceFactory::create (*this, node, true);
1889 catch (failed_constructor& err) {
1890 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1891 return boost::shared_ptr<Source>();
1896 Session::save_template (string template_name)
1900 if (_state_of_the_state & CannotSave) {
1904 sys::path user_template_dir(user_template_directory());
1908 sys::create_directories (user_template_dir);
1910 catch(sys::filesystem_error& ex)
1912 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1913 user_template_dir.to_string(), ex.what()) << endmsg;
1917 tree.set_root (&get_template());
1919 sys::path template_file_path(user_template_dir);
1920 template_file_path /= template_name + template_suffix;
1922 if (sys::exists (template_file_path))
1924 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1925 template_file_path.to_string()) << endmsg;
1929 if (!tree.write (template_file_path.to_string())) {
1930 error << _("mix template not saved") << endmsg;
1938 Session::rename_template (string old_name, string new_name)
1940 sys::path old_path (user_template_directory());
1941 old_path /= old_name + template_suffix;
1943 sys::path new_path(user_template_directory());
1944 new_path /= new_name + template_suffix;
1946 if (sys::exists (new_path)) {
1947 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1948 new_path.to_string()) << endmsg;
1953 sys::rename (old_path, new_path);
1961 Session::delete_template (string name)
1963 sys::path path = user_template_directory();
1964 path /= name + template_suffix;
1975 Session::refresh_disk_space ()
1978 struct statfs statfsbuf;
1979 vector<space_and_path>::iterator i;
1980 Glib::Mutex::Lock lm (space_lock);
1983 /* get freespace on every FS that is part of the session path */
1985 _total_free_4k_blocks = 0;
1987 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1988 statfs ((*i).path.c_str(), &statfsbuf);
1990 scale = statfsbuf.f_bsize/4096.0;
1992 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1993 _total_free_4k_blocks += (*i).blocks;
1999 Session::get_best_session_directory_for_new_source ()
2001 vector<space_and_path>::iterator i;
2002 string result = _session_dir->root_path().to_string();
2004 /* handle common case without system calls */
2006 if (session_dirs.size() == 1) {
2010 /* OK, here's the algorithm we're following here:
2012 We want to select which directory to use for
2013 the next file source to be created. Ideally,
2014 we'd like to use a round-robin process so as to
2015 get maximum performance benefits from splitting
2016 the files across multiple disks.
2018 However, in situations without much diskspace, an
2019 RR approach may end up filling up a filesystem
2020 with new files while others still have space.
2021 Its therefore important to pay some attention to
2022 the freespace in the filesystem holding each
2023 directory as well. However, if we did that by
2024 itself, we'd keep creating new files in the file
2025 system with the most space until it was as full
2026 as all others, thus negating any performance
2027 benefits of this RAID-1 like approach.
2029 So, we use a user-configurable space threshold. If
2030 there are at least 2 filesystems with more than this
2031 much space available, we use RR selection between them.
2032 If not, then we pick the filesystem with the most space.
2034 This gets a good balance between the two
2038 refresh_disk_space ();
2040 int free_enough = 0;
2042 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2043 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2048 if (free_enough >= 2) {
2049 /* use RR selection process, ensuring that the one
2053 i = last_rr_session_dir;
2056 if (++i == session_dirs.end()) {
2057 i = session_dirs.begin();
2060 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2061 if (create_session_directory ((*i).path)) {
2063 last_rr_session_dir = i;
2068 } while (i != last_rr_session_dir);
2072 /* pick FS with the most freespace (and that
2073 seems to actually work ...)
2076 vector<space_and_path> sorted;
2077 space_and_path_ascending_cmp cmp;
2079 sorted = session_dirs;
2080 sort (sorted.begin(), sorted.end(), cmp);
2082 for (i = sorted.begin(); i != sorted.end(); ++i) {
2083 if (create_session_directory ((*i).path)) {
2085 last_rr_session_dir = i;
2095 Session::load_named_selections (const XMLNode& node)
2098 XMLNodeConstIterator niter;
2101 nlist = node.children();
2105 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2107 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2108 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2116 Session::XMLNamedSelectionFactory (const XMLNode& node)
2119 return new NamedSelection (*this, node);
2122 catch (failed_constructor& err) {
2128 Session::automation_dir () const
2130 return Glib::build_filename (_path, "automation");
2134 Session::analysis_dir () const
2136 return Glib::build_filename (_path, "analysis");
2140 Session::load_bundles (XMLNode const & node)
2142 XMLNodeList nlist = node.children();
2143 XMLNodeConstIterator niter;
2147 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2148 if ((*niter)->name() == "InputBundle") {
2149 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2150 } else if ((*niter)->name() == "OutputBundle") {
2151 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2153 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2162 Session::load_route_groups (const XMLNode& node, int version)
2164 XMLNodeList nlist = node.children();
2165 XMLNodeConstIterator niter;
2169 if (version >= 3000) {
2171 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2172 if ((*niter)->name() == "RouteGroup") {
2173 RouteGroup* rg = new RouteGroup (*this, "");
2174 add_route_group (rg);
2175 rg->set_state (**niter, version);
2179 } else if (version < 3000) {
2181 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2182 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2183 RouteGroup* rg = new RouteGroup (*this, "");
2184 add_route_group (rg);
2185 rg->set_state (**niter, version);
2194 Session::auto_save()
2196 save_state (_current_snapshot_name);
2200 state_file_filter (const string &str, void */*arg*/)
2202 return (str.length() > strlen(statefile_suffix) &&
2203 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2207 bool operator()(const string* a, const string* b) {
2213 remove_end(string* state)
2215 string statename(*state);
2217 string::size_type start,end;
2218 if ((start = statename.find_last_of ('/')) != string::npos) {
2219 statename = statename.substr (start+1);
2222 if ((end = statename.rfind(".ardour")) == string::npos) {
2223 end = statename.length();
2226 return new string(statename.substr (0, end));
2230 Session::possible_states (string path)
2232 PathScanner scanner;
2233 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2235 transform(states->begin(), states->end(), states->begin(), remove_end);
2238 sort (states->begin(), states->end(), cmp);
2244 Session::possible_states () const
2246 return possible_states(_path);
2250 Session::add_route_group (RouteGroup* g)
2252 _route_groups.push_back (g);
2253 route_group_added (g); /* EMIT SIGNAL */
2258 Session::remove_route_group (RouteGroup& rg)
2260 list<RouteGroup*>::iterator i;
2262 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2263 _route_groups.erase (i);
2266 route_group_removed (); /* EMIT SIGNAL */
2272 Session::route_group_by_name (string name)
2274 list<RouteGroup *>::iterator i;
2276 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2277 if ((*i)->name() == name) {
2285 Session::start_reversible_command (const string& name)
2287 UndoTransaction* trans = new UndoTransaction();
2288 trans->set_name(name);
2293 Session::finish_reversible_command (UndoTransaction& ut)
2296 gettimeofday(&now, 0);
2297 ut.set_timestamp(now);
2302 Session::begin_reversible_command(const string& name)
2304 UndoTransaction* trans = new UndoTransaction();
2305 trans->set_name(name);
2307 if (!_current_trans.empty()) {
2308 _current_trans.top()->add_command (trans);
2310 _current_trans.push(trans);
2315 Session::commit_reversible_command(Command *cmd)
2317 assert(!_current_trans.empty());
2321 _current_trans.top()->add_command(cmd);
2324 if (_current_trans.top()->empty()) {
2325 _current_trans.pop();
2329 gettimeofday(&now, 0);
2330 _current_trans.top()->set_timestamp(now);
2332 _history.add(_current_trans.top());
2333 _current_trans.pop();
2337 accept_all_non_peak_files (const string& path, void */*arg*/)
2339 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2343 accept_all_state_files (const string& path, void */*arg*/)
2345 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2349 Session::find_all_sources (string path, set<string>& result)
2354 if (!tree.read (path)) {
2358 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2363 XMLNodeConstIterator niter;
2365 nlist = node->children();
2369 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2373 if ((prop = (*niter)->property (X_("type"))) == 0) {
2377 DataType type (prop->value());
2379 if ((prop = (*niter)->property (X_("name"))) == 0) {
2383 if (prop->value()[0] == '/') {
2384 /* external file, ignore */
2388 Glib::ustring found_path;
2392 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2393 result.insert (found_path);
2401 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2403 PathScanner scanner;
2404 vector<string*>* state_files;
2406 string this_snapshot_path;
2412 if (ripped[ripped.length()-1] == '/') {
2413 ripped = ripped.substr (0, ripped.length() - 1);
2416 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2418 if (state_files == 0) {
2423 this_snapshot_path = _path;
2424 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2425 this_snapshot_path += statefile_suffix;
2427 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2429 if (exclude_this_snapshot && **i == this_snapshot_path) {
2433 if (find_all_sources (**i, result) < 0) {
2441 struct RegionCounter {
2442 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2443 AudioSourceList::iterator iter;
2444 boost::shared_ptr<Region> region;
2447 RegionCounter() : count (0) {}
2451 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2453 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2454 return r.get_value_or (1);
2458 Session::cleanup_sources (CleanupReport& rep)
2460 // FIXME: needs adaptation to midi
2462 vector<boost::shared_ptr<Source> > dead_sources;
2463 PathScanner scanner;
2465 vector<space_and_path>::iterator i;
2466 vector<space_and_path>::iterator nexti;
2467 vector<string*>* soundfiles;
2468 vector<string> unused;
2469 set<string> all_sources;
2474 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2476 /* step 1: consider deleting all unused playlists */
2478 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2483 /* step 2: find all un-used sources */
2488 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2490 SourceMap::iterator tmp;
2495 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2499 if (!i->second->used() && (i->second->length(i->second->timeline_position() > 0))) {
2500 dead_sources.push_back (i->second);
2501 i->second->drop_references ();
2507 /* build a list of all the possible sound directories for the session */
2509 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2514 SessionDirectory sdir ((*i).path);
2515 sound_path += sdir.sound_path().to_string();
2517 if (nexti != session_dirs.end()) {
2524 /* now do the same thing for the files that ended up in the sounds dir(s)
2525 but are not referenced as sources in any snapshot.
2528 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2530 if (soundfiles == 0) {
2534 /* find all sources, but don't use this snapshot because the
2535 state file on disk still references sources we may have already
2539 find_all_sources_across_snapshots (all_sources, true);
2541 /* add our current source list
2544 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2545 boost::shared_ptr<FileSource> fs;
2547 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2548 all_sources.insert (fs->path());
2552 char tmppath1[PATH_MAX+1];
2553 char tmppath2[PATH_MAX+1];
2555 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2560 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2562 realpath(spath.c_str(), tmppath1);
2563 realpath((*i).c_str(), tmppath2);
2565 if (strcmp(tmppath1, tmppath2) == 0) {
2572 unused.push_back (spath);
2576 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2578 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2579 struct stat statbuf;
2581 rep.paths.push_back (*x);
2582 if (stat ((*x).c_str(), &statbuf) == 0) {
2583 rep.space += statbuf.st_size;
2588 /* don't move the file across filesystems, just
2589 stick it in the `dead_sound_dir_name' directory
2590 on whichever filesystem it was already on.
2593 if ((*x).find ("/sounds/") != string::npos) {
2595 /* old school, go up 1 level */
2597 newpath = Glib::path_get_dirname (*x); // "sounds"
2598 newpath = Glib::path_get_dirname (newpath); // "session-name"
2602 /* new school, go up 4 levels */
2604 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2605 newpath = Glib::path_get_dirname (newpath); // "session-name"
2606 newpath = Glib::path_get_dirname (newpath); // "interchange"
2607 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2611 newpath += dead_sound_dir_name;
2613 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2614 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2619 newpath += Glib::path_get_basename ((*x));
2621 if (access (newpath.c_str(), F_OK) == 0) {
2623 /* the new path already exists, try versioning */
2625 char buf[PATH_MAX+1];
2629 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2632 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2633 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2637 if (version == 999) {
2638 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2642 newpath = newpath_v;
2647 /* it doesn't exist, or we can't read it or something */
2651 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2652 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2653 (*x), newpath, strerror (errno))
2658 /* see if there an easy to find peakfile for this file, and remove it.
2661 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2662 peakpath += peakfile_suffix;
2664 if (access (peakpath.c_str(), W_OK) == 0) {
2665 if (::unlink (peakpath.c_str()) != 0) {
2666 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2667 peakpath, _path, strerror (errno))
2669 /* try to back out */
2670 rename (newpath.c_str(), _path.c_str());
2678 /* dump the history list */
2682 /* save state so we don't end up a session file
2683 referring to non-existent sources.
2689 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2695 Session::cleanup_trash_sources (CleanupReport& rep)
2697 // FIXME: needs adaptation for MIDI
2699 vector<space_and_path>::iterator i;
2700 string dead_sound_dir;
2701 struct dirent* dentry;
2702 struct stat statbuf;
2708 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2710 dead_sound_dir = (*i).path;
2711 dead_sound_dir += dead_sound_dir_name;
2713 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2717 while ((dentry = readdir (dead)) != 0) {
2719 /* avoid '.' and '..' */
2721 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2722 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2728 fullpath = dead_sound_dir;
2730 fullpath += dentry->d_name;
2732 if (stat (fullpath.c_str(), &statbuf)) {
2736 if (!S_ISREG (statbuf.st_mode)) {
2740 if (unlink (fullpath.c_str())) {
2741 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2742 fullpath, strerror (errno))
2746 rep.paths.push_back (dentry->d_name);
2747 rep.space += statbuf.st_size;
2758 Session::set_dirty ()
2760 bool was_dirty = dirty();
2762 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2766 DirtyChanged(); /* EMIT SIGNAL */
2772 Session::set_clean ()
2774 bool was_dirty = dirty();
2776 _state_of_the_state = Clean;
2780 DirtyChanged(); /* EMIT SIGNAL */
2785 Session::set_deletion_in_progress ()
2787 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2791 Session::clear_deletion_in_progress ()
2793 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2797 Session::add_controllable (boost::shared_ptr<Controllable> c)
2799 /* this adds a controllable to the list managed by the Session.
2800 this is a subset of those managed by the Controllable class
2801 itself, and represents the only ones whose state will be saved
2802 as part of the session.
2805 Glib::Mutex::Lock lm (controllables_lock);
2806 controllables.insert (c);
2809 struct null_deleter { void operator()(void const *) const {} };
2812 Session::remove_controllable (Controllable* c)
2814 if (_state_of_the_state | Deletion) {
2818 Glib::Mutex::Lock lm (controllables_lock);
2820 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2822 if (x != controllables.end()) {
2823 controllables.erase (x);
2827 boost::shared_ptr<Controllable>
2828 Session::controllable_by_id (const PBD::ID& id)
2830 Glib::Mutex::Lock lm (controllables_lock);
2832 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2833 if ((*i)->id() == id) {
2838 return boost::shared_ptr<Controllable>();
2841 boost::shared_ptr<Controllable>
2842 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2844 boost::shared_ptr<Controllable> c;
2845 boost::shared_ptr<Route> r;
2847 switch (desc.top_level_type()) {
2848 case ControllableDescriptor::NamedRoute:
2850 std::string str = desc.top_level_name();
2851 if (str == "master") {
2853 } else if (str == "control" || str == "listen") {
2856 r = route_by_name (desc.top_level_name());
2861 case ControllableDescriptor::RemoteControlID:
2862 r = route_by_remote_id (desc.rid());
2870 switch (desc.subtype()) {
2871 case ControllableDescriptor::Gain:
2872 c = r->gain_control ();
2875 case ControllableDescriptor::Solo:
2876 c = r->solo_control();
2879 case ControllableDescriptor::Mute:
2880 c = r->mute_control();
2883 case ControllableDescriptor::Recenable:
2885 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2888 c = t->rec_enable_control ();
2893 case ControllableDescriptor::Pan:
2894 /* XXX pan control */
2897 case ControllableDescriptor::Balance:
2898 /* XXX simple pan control */
2901 case ControllableDescriptor::PluginParameter:
2903 uint32_t plugin = desc.target (0);
2904 uint32_t parameter_index = desc.target (1);
2906 /* revert to zero based counting */
2912 if (parameter_index > 0) {
2916 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2919 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2920 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2925 case ControllableDescriptor::SendGain:
2927 uint32_t send = desc.target (0);
2929 /* revert to zero-based counting */
2935 boost::shared_ptr<Processor> p = r->nth_send (send);
2938 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2939 boost::shared_ptr<Amp> a = s->amp();
2942 c = s->amp()->gain_control();
2949 /* relax and return a null pointer */
2957 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2960 Stateful::add_instant_xml (node, _path);
2963 if (write_to_config) {
2964 Config->add_instant_xml (node);
2969 Session::instant_xml (const string& node_name)
2971 return Stateful::instant_xml (node_name, _path);
2975 Session::save_history (string snapshot_name)
2983 if (snapshot_name.empty()) {
2984 snapshot_name = _current_snapshot_name;
2987 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2988 const string backup_filename = history_filename + backup_suffix;
2989 const sys::path xml_path = _session_dir->root_path() / history_filename;
2990 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2992 if (sys::exists (xml_path)) {
2995 sys::rename (xml_path, backup_path);
2997 catch (const sys::filesystem_error& err)
2999 error << _("could not backup old history file, current history not saved") << endmsg;
3004 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3008 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3010 if (!tree.write (xml_path.to_string()))
3012 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3016 sys::remove (xml_path);
3017 sys::rename (backup_path, xml_path);
3019 catch (const sys::filesystem_error& err)
3021 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3022 backup_path.to_string(), err.what()) << endmsg;
3032 Session::restore_history (string snapshot_name)
3036 if (snapshot_name.empty()) {
3037 snapshot_name = _current_snapshot_name;
3040 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3041 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3043 info << "Loading history from " << xml_path.to_string() << endmsg;
3045 if (!sys::exists (xml_path)) {
3046 info << string_compose (_("%1: no history file \"%2\" for this session."),
3047 _name, xml_path.to_string()) << endmsg;
3051 if (!tree.read (xml_path.to_string())) {
3052 error << string_compose (_("Could not understand session history file \"%1\""),
3053 xml_path.to_string()) << endmsg;
3060 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3063 UndoTransaction* ut = new UndoTransaction ();
3066 ut->set_name(t->property("name")->value());
3067 stringstream ss(t->property("tv-sec")->value());
3069 ss.str(t->property("tv-usec")->value());
3071 ut->set_timestamp(tv);
3073 for (XMLNodeConstIterator child_it = t->children().begin();
3074 child_it != t->children().end(); child_it++)
3076 XMLNode *n = *child_it;
3079 if (n->name() == "MementoCommand" ||
3080 n->name() == "MementoUndoCommand" ||
3081 n->name() == "MementoRedoCommand") {
3083 if ((c = memento_command_factory(n))) {
3087 } else if (n->name() == "DiffCommand") {
3088 PBD::ID id(n->property("midi-source")->value());
3089 boost::shared_ptr<MidiSource> midi_source =
3090 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3092 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3094 error << _("Failed to downcast MidiSource for DiffCommand") << endmsg;
3097 } else if (n->name() == "StatefulDiffCommand") {
3098 if ((c = stateful_diff_command_factory (n))) {
3099 ut->add_command (c);
3102 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3113 Session::config_changed (std::string p, bool ours)
3119 if (p == "seamless-loop") {
3121 } else if (p == "rf-speed") {
3123 } else if (p == "auto-loop") {
3125 } else if (p == "auto-input") {
3127 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3128 /* auto-input only makes a difference if we're rolling */
3130 boost::shared_ptr<RouteList> rl = routes.reader ();
3131 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3132 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3133 if (tr && tr->record_enabled ()) {
3134 tr->monitor_input (!config.get_auto_input());
3139 } else if (p == "punch-in") {
3143 if ((location = _locations.auto_punch_location()) != 0) {
3145 if (config.get_punch_in ()) {
3146 replace_event (SessionEvent::PunchIn, location->start());
3148 remove_event (location->start(), SessionEvent::PunchIn);
3152 } else if (p == "punch-out") {
3156 if ((location = _locations.auto_punch_location()) != 0) {
3158 if (config.get_punch_out()) {
3159 replace_event (SessionEvent::PunchOut, location->end());
3161 clear_events (SessionEvent::PunchOut);
3165 } else if (p == "edit-mode") {
3167 Glib::Mutex::Lock lm (playlists->lock);
3169 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3170 (*i)->set_edit_mode (Config->get_edit_mode ());
3173 } else if (p == "use-video-sync") {
3175 waiting_for_sync_offset = config.get_use_video_sync();
3177 } else if (p == "mmc-control") {
3179 //poke_midi_thread ();
3181 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3184 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3187 } else if (p == "mmc-send-id") {
3190 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3193 } else if (p == "midi-control") {
3195 //poke_midi_thread ();
3197 } else if (p == "raid-path") {
3199 setup_raid_path (config.get_raid_path());
3201 } else if (p == "timecode-format") {
3205 } else if (p == "video-pullup") {
3209 } else if (p == "seamless-loop") {
3211 if (play_loop && transport_rolling()) {
3212 // to reset diskstreams etc
3213 request_play_loop (true);
3216 } else if (p == "rf-speed") {
3218 cumulative_rf_motion = 0;
3221 } else if (p == "click-sound") {
3223 setup_click_sounds (1);
3225 } else if (p == "click-emphasis-sound") {
3227 setup_click_sounds (-1);
3229 } else if (p == "clicking") {
3231 if (Config->get_clicking()) {
3232 if (_click_io && click_data) { // don't require emphasis data
3239 } else if (p == "send-mtc") {
3241 /* only set the internal flag if we have
3245 if (_mtc_port != 0) {
3246 session_send_mtc = Config->get_send_mtc();
3247 if (session_send_mtc) {
3248 /* mark us ready to send */
3249 next_quarter_frame_to_send = 0;
3252 session_send_mtc = false;
3255 } else if (p == "send-mmc") {
3257 /* only set the internal flag if we have
3261 if (_mmc_port != 0) {
3262 session_send_mmc = Config->get_send_mmc();
3265 session_send_mmc = false;
3268 } else if (p == "midi-feedback") {
3270 /* only set the internal flag if we have
3274 if (_mtc_port != 0) {
3275 session_midi_feedback = Config->get_midi_feedback();
3278 } else if (p == "jack-time-master") {
3280 engine().reset_timebase ();
3282 } else if (p == "native-file-header-format") {
3284 if (!first_file_header_format_reset) {
3285 reset_native_file_format ();
3288 first_file_header_format_reset = false;
3290 } else if (p == "native-file-data-format") {
3292 if (!first_file_data_format_reset) {
3293 reset_native_file_format ();
3296 first_file_data_format_reset = false;
3298 } else if (p == "external-sync") {
3299 if (!config.get_external_sync()) {
3300 drop_sync_source ();
3302 switch_to_sync_source (config.get_sync_source());
3304 } else if (p == "remote-model") {
3305 set_remote_control_ids ();
3306 } else if (p == "denormal-model") {
3308 } else if (p == "history-depth") {
3309 set_history_depth (Config->get_history_depth());
3310 } else if (p == "sync-all-route-ordering") {
3311 sync_order_keys ("session");
3312 } else if (p == "initial-program-change") {
3314 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3317 buf[0] = MIDI::program; // channel zero by default
3318 buf[1] = (Config->get_initial_program_change() & 0x7f);
3320 _mmc_port->midimsg (buf, sizeof (buf), 0);
3322 } else if (p == "initial-program-change") {
3324 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3325 MIDI::byte* buf = new MIDI::byte[2];
3327 buf[0] = MIDI::program; // channel zero by default
3328 buf[1] = (Config->get_initial_program_change() & 0x7f);
3329 // deliver_midi (_mmc_port, buf, 2);
3331 } else if (p == "solo-mute-override") {
3332 // catch_up_on_solo_mute_override ();
3333 } else if (p == "listen-position") {
3334 listen_position_changed ();
3335 } else if (p == "solo-control-is-listen-control") {
3336 solo_control_mode_changed ();
3344 Session::set_history_depth (uint32_t d)
3346 _history.set_depth (d);
3350 Session::load_diskstreams_2X (XMLNode const & node, int)
3353 XMLNodeConstIterator citer;
3355 clist = node.children();
3357 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3360 /* diskstreams added automatically by DiskstreamCreated handler */
3361 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3362 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3363 _diskstreams_2X.push_back (dsp);
3365 error << _("Session: unknown diskstream type in XML") << endmsg;
3369 catch (failed_constructor& err) {
3370 error << _("Session: could not load diskstream via XML state") << endmsg;