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 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
1046 boost::shared_ptr<AudioFileSource> fs;
1047 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
1048 if (!fs->destructive()) {
1049 if (fs->length(fs->timeline_position()) == 0) {
1055 child->add_child_nocopy (siter->second->get_state());
1059 child = node->add_child ("Regions");
1062 Glib::Mutex::Lock rl (region_lock);
1063 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1064 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1065 boost::shared_ptr<Region> r = i->second;
1066 /* only store regions not attached to playlists */
1067 if (r->playlist() == 0) {
1068 child->add_child_nocopy (r->state (true));
1074 node->add_child_nocopy (_locations.get_state());
1076 // for a template, just create a new Locations, populate it
1077 // with the default start and end, and get the state for that.
1079 Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
1080 range->set (max_frames, 0);
1082 node->add_child_nocopy (loc.get_state());
1085 child = node->add_child ("Bundles");
1087 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1088 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1089 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1091 child->add_child_nocopy (b->get_state());
1096 child = node->add_child ("Routes");
1098 boost::shared_ptr<RouteList> r = routes.reader ();
1100 RoutePublicOrderSorter cmp;
1101 RouteList public_order (*r);
1102 public_order.sort (cmp);
1104 /* the sort should have put control outs first */
1107 assert (_monitor_out == public_order.front());
1110 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1111 if (!(*i)->is_hidden()) {
1113 child->add_child_nocopy ((*i)->get_state());
1115 child->add_child_nocopy ((*i)->get_template());
1121 playlists->add_state (node, full_state);
1123 child = node->add_child ("RouteGroups");
1124 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1125 child->add_child_nocopy ((*i)->get_state());
1129 child = node->add_child ("Click");
1130 child->add_child_nocopy (_click_io->state (full_state));
1134 child = node->add_child ("NamedSelections");
1135 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1137 child->add_child_nocopy ((*i)->get_state());
1142 node->add_child_nocopy (_tempo_map->get_state());
1144 node->add_child_nocopy (get_control_protocol_state());
1147 node->add_child_copy (*_extra_xml);
1154 Session::get_control_protocol_state ()
1156 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1157 return cpm.get_state();
1161 Session::set_state (const XMLNode& node, int version)
1165 const XMLProperty* prop;
1168 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1170 if (node.name() != X_("Session")){
1171 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1175 if ((prop = node.property ("version")) != 0) {
1176 version = atoi (prop->value ()) * 1000;
1179 if ((prop = node.property ("name")) != 0) {
1180 _name = prop->value ();
1183 if ((prop = node.property (X_("sample-rate"))) != 0) {
1185 _nominal_frame_rate = atoi (prop->value());
1187 if (_nominal_frame_rate != _current_frame_rate) {
1188 boost::optional<int> r = AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate);
1189 if (r.get_value_or (0)) {
1195 setup_raid_path(_session_dir->root_path().to_string());
1197 if ((prop = node.property (X_("id-counter"))) != 0) {
1199 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1200 ID::init_counter (x);
1202 /* old sessions used a timebased counter, so fake
1203 the startup ID counter based on a standard
1208 ID::init_counter (now);
1212 IO::disable_connecting ();
1214 /* Object loading order:
1219 MIDI Control // relies on data from Options/Config
1232 if ((child = find_named_node (node, "Extra")) != 0) {
1233 _extra_xml = new XMLNode (*child);
1236 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1237 load_options (*child);
1238 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1239 load_options (*child);
1241 error << _("Session: XML state has no options section") << endmsg;
1244 if (use_config_midi_ports ()) {
1247 if (version >= 3000) {
1248 if ((child = find_named_node (node, "Metadata")) == 0) {
1249 warning << _("Session: XML state has no metadata section") << endmsg;
1250 } else if (_metadata->set_state (*child, version)) {
1255 if ((child = find_named_node (node, "Locations")) == 0) {
1256 error << _("Session: XML state has no locations section") << endmsg;
1258 } else if (_locations.set_state (*child, version)) {
1264 if ((location = _locations.auto_loop_location()) != 0) {
1265 set_auto_loop_location (location);
1268 if ((location = _locations.auto_punch_location()) != 0) {
1269 set_auto_punch_location (location);
1272 if ((location = _locations.session_range_location()) != 0) {
1273 delete _session_range_location;
1274 _session_range_location = location;
1277 if (_session_range_location) {
1278 AudioFileSource::set_header_position_offset (_session_range_location->start());
1281 if ((child = find_named_node (node, "Sources")) == 0) {
1282 error << _("Session: XML state has no sources section") << endmsg;
1284 } else if (load_sources (*child)) {
1288 if ((child = find_named_node (node, "Regions")) == 0) {
1289 error << _("Session: XML state has no Regions section") << endmsg;
1291 } else if (load_regions (*child)) {
1295 if ((child = find_named_node (node, "Playlists")) == 0) {
1296 error << _("Session: XML state has no playlists section") << endmsg;
1298 } else if (playlists->load (*this, *child)) {
1302 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1304 } else if (playlists->load_unused (*this, *child)) {
1308 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1309 if (load_named_selections (*child)) {
1314 if (version >= 3000) {
1315 if ((child = find_named_node (node, "Bundles")) == 0) {
1316 warning << _("Session: XML state has no bundles section") << endmsg;
1319 /* We can't load Bundles yet as they need to be able
1320 to convert from port names to Port objects, which can't happen until
1322 _bundle_xml_node = new XMLNode (*child);
1326 if ((child = find_named_node (node, "TempoMap")) == 0) {
1327 error << _("Session: XML state has no Tempo Map section") << endmsg;
1329 } else if (_tempo_map->set_state (*child, version)) {
1333 if (version < 3000) {
1334 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1335 error << _("Session: XML state has no diskstreams section") << endmsg;
1337 } else if (load_diskstreams_2X (*child, version)) {
1342 if ((child = find_named_node (node, "Routes")) == 0) {
1343 error << _("Session: XML state has no routes section") << endmsg;
1345 } else if (load_routes (*child, version)) {
1349 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1350 _diskstreams_2X.clear ();
1352 if (version >= 3000) {
1354 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1355 error << _("Session: XML state has no route groups section") << endmsg;
1357 } else if (load_route_groups (*child, version)) {
1361 } else if (version < 3000) {
1363 if ((child = find_named_node (node, "EditGroups")) == 0) {
1364 error << _("Session: XML state has no edit groups section") << endmsg;
1366 } else if (load_route_groups (*child, version)) {
1370 if ((child = find_named_node (node, "MixGroups")) == 0) {
1371 error << _("Session: XML state has no mix groups section") << endmsg;
1373 } else if (load_route_groups (*child, version)) {
1378 if ((child = find_named_node (node, "Click")) == 0) {
1379 warning << _("Session: XML state has no click section") << endmsg;
1380 } else if (_click_io) {
1381 _click_io->set_state (*child, version);
1384 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1385 ControlProtocolManager::instance().set_protocol_states (*child);
1388 /* here beginneth the second phase ... */
1390 StateReady (); /* EMIT SIGNAL */
1399 Session::load_routes (const XMLNode& node, int version)
1402 XMLNodeConstIterator niter;
1403 RouteList new_routes;
1405 nlist = node.children();
1409 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1411 boost::shared_ptr<Route> route;
1412 if (version < 3000) {
1413 route = XMLRouteFactory_2X (**niter, version);
1415 route = XMLRouteFactory (**niter, version);
1419 error << _("Session: cannot create Route from XML description.") << endmsg;
1423 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1425 new_routes.push_back (route);
1428 add_routes (new_routes, false);
1433 boost::shared_ptr<Route>
1434 Session::XMLRouteFactory (const XMLNode& node, int version)
1436 boost::shared_ptr<Route> ret;
1438 if (node.name() != "Route") {
1442 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1444 DataType type = DataType::AUDIO;
1445 const XMLProperty* prop = node.property("default-type");
1448 type = DataType (prop->value());
1451 assert (type != DataType::NIL);
1457 if (type == DataType::AUDIO) {
1458 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1461 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1464 if (track->init()) {
1469 if (track->set_state (node, version)) {
1474 boost_debug_shared_ptr_mark_interesting (track, "Track");
1478 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1480 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1481 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1491 boost::shared_ptr<Route>
1492 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1494 boost::shared_ptr<Route> ret;
1496 if (node.name() != "Route") {
1500 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1502 ds_prop = node.property (X_("diskstream"));
1505 DataType type = DataType::AUDIO;
1506 const XMLProperty* prop = node.property("default-type");
1509 type = DataType (prop->value());
1512 assert (type != DataType::NIL);
1516 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1517 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1521 if (i == _diskstreams_2X.end()) {
1522 error << _("Could not find diskstream for route") << endmsg;
1523 return boost::shared_ptr<Route> ();
1528 if (type == DataType::AUDIO) {
1529 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1532 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1535 if (track->init()) {
1540 if (track->set_state (node, version)) {
1545 track->set_diskstream (*i);
1547 boost_debug_shared_ptr_mark_interesting (track, "Track");
1551 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1553 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1554 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1565 Session::load_regions (const XMLNode& node)
1568 XMLNodeConstIterator niter;
1569 boost::shared_ptr<Region> region;
1571 nlist = node.children();
1575 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1576 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1577 error << _("Session: cannot create Region from XML description.");
1578 const XMLProperty *name = (**niter).property("name");
1581 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1591 boost::shared_ptr<Region>
1592 Session::XMLRegionFactory (const XMLNode& node, bool full)
1594 const XMLProperty* type = node.property("type");
1598 if ( !type || type->value() == "audio" ) {
1600 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1602 } else if (type->value() == "midi") {
1604 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1608 } catch (failed_constructor& err) {
1609 return boost::shared_ptr<Region> ();
1612 return boost::shared_ptr<Region> ();
1615 boost::shared_ptr<AudioRegion>
1616 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1618 const XMLProperty* prop;
1619 boost::shared_ptr<Source> source;
1620 boost::shared_ptr<AudioSource> as;
1622 SourceList master_sources;
1623 uint32_t nchans = 1;
1626 if (node.name() != X_("Region")) {
1627 return boost::shared_ptr<AudioRegion>();
1630 if ((prop = node.property (X_("channels"))) != 0) {
1631 nchans = atoi (prop->value().c_str());
1634 if ((prop = node.property ("name")) == 0) {
1635 cerr << "no name for this region\n";
1639 if ((prop = node.property (X_("source-0"))) == 0) {
1640 if ((prop = node.property ("source")) == 0) {
1641 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1642 return boost::shared_ptr<AudioRegion>();
1646 PBD::ID s_id (prop->value());
1648 if ((source = source_by_id (s_id)) == 0) {
1649 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1650 return boost::shared_ptr<AudioRegion>();
1653 as = boost::dynamic_pointer_cast<AudioSource>(source);
1655 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1656 return boost::shared_ptr<AudioRegion>();
1659 sources.push_back (as);
1661 /* pickup other channels */
1663 for (uint32_t n=1; n < nchans; ++n) {
1664 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1665 if ((prop = node.property (buf)) != 0) {
1667 PBD::ID id2 (prop->value());
1669 if ((source = source_by_id (id2)) == 0) {
1670 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1671 return boost::shared_ptr<AudioRegion>();
1674 as = boost::dynamic_pointer_cast<AudioSource>(source);
1676 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1677 return boost::shared_ptr<AudioRegion>();
1679 sources.push_back (as);
1683 for (uint32_t n = 0; n < nchans; ++n) {
1684 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1685 if ((prop = node.property (buf)) != 0) {
1687 PBD::ID id2 (prop->value());
1689 if ((source = source_by_id (id2)) == 0) {
1690 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1691 return boost::shared_ptr<AudioRegion>();
1694 as = boost::dynamic_pointer_cast<AudioSource>(source);
1696 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1697 return boost::shared_ptr<AudioRegion>();
1699 master_sources.push_back (as);
1704 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1706 /* a final detail: this is the one and only place that we know how long missing files are */
1708 if (region->whole_file()) {
1709 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1710 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1712 sfp->set_length (region->length());
1717 if (!master_sources.empty()) {
1718 if (master_sources.size() != nchans) {
1719 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1721 region->set_master_sources (master_sources);
1729 catch (failed_constructor& err) {
1730 return boost::shared_ptr<AudioRegion>();
1734 boost::shared_ptr<MidiRegion>
1735 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1737 const XMLProperty* prop;
1738 boost::shared_ptr<Source> source;
1739 boost::shared_ptr<MidiSource> ms;
1741 uint32_t nchans = 1;
1743 if (node.name() != X_("Region")) {
1744 return boost::shared_ptr<MidiRegion>();
1747 if ((prop = node.property (X_("channels"))) != 0) {
1748 nchans = atoi (prop->value().c_str());
1751 if ((prop = node.property ("name")) == 0) {
1752 cerr << "no name for this region\n";
1756 // Multiple midi channels? that's just crazy talk
1757 assert(nchans == 1);
1759 if ((prop = node.property (X_("source-0"))) == 0) {
1760 if ((prop = node.property ("source")) == 0) {
1761 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1762 return boost::shared_ptr<MidiRegion>();
1766 PBD::ID s_id (prop->value());
1768 if ((source = source_by_id (s_id)) == 0) {
1769 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1770 return boost::shared_ptr<MidiRegion>();
1773 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1775 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1776 return boost::shared_ptr<MidiRegion>();
1779 sources.push_back (ms);
1782 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1783 /* a final detail: this is the one and only place that we know how long missing files are */
1785 if (region->whole_file()) {
1786 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1787 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1789 sfp->set_length (region->length());
1797 catch (failed_constructor& err) {
1798 return boost::shared_ptr<MidiRegion>();
1803 Session::get_sources_as_xml ()
1806 XMLNode* node = new XMLNode (X_("Sources"));
1807 Glib::Mutex::Lock lm (source_lock);
1809 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1810 node->add_child_nocopy (i->second->get_state());
1817 Session::path_from_region_name (DataType type, string name, string identifier)
1819 char buf[PATH_MAX+1];
1821 SessionDirectory sdir(get_best_session_directory_for_new_source());
1822 sys::path source_dir = ((type == DataType::AUDIO)
1823 ? sdir.sound_path() : sdir.midi_path());
1825 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1827 for (n = 0; n < 999999; ++n) {
1828 if (identifier.length()) {
1829 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1830 identifier.c_str(), n, ext.c_str());
1832 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1836 sys::path source_path = source_dir / buf;
1838 if (!sys::exists (source_path)) {
1839 return source_path.to_string();
1843 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1852 Session::load_sources (const XMLNode& node)
1855 XMLNodeConstIterator niter;
1856 boost::shared_ptr<Source> source;
1858 nlist = node.children();
1862 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1864 if ((source = XMLSourceFactory (**niter)) == 0) {
1865 error << _("Session: cannot create Source from XML description.") << endmsg;
1867 } catch (MissingSource& err) {
1868 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1869 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1876 boost::shared_ptr<Source>
1877 Session::XMLSourceFactory (const XMLNode& node)
1879 if (node.name() != "Source") {
1880 return boost::shared_ptr<Source>();
1884 /* note: do peak building in another thread when loading session state */
1885 return SourceFactory::create (*this, node, true);
1888 catch (failed_constructor& err) {
1889 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1890 return boost::shared_ptr<Source>();
1895 Session::save_template (string template_name)
1899 if (_state_of_the_state & CannotSave) {
1903 sys::path user_template_dir(user_template_directory());
1907 sys::create_directories (user_template_dir);
1909 catch(sys::filesystem_error& ex)
1911 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1912 user_template_dir.to_string(), ex.what()) << endmsg;
1916 tree.set_root (&get_template());
1918 sys::path template_file_path(user_template_dir);
1919 template_file_path /= template_name + template_suffix;
1921 if (sys::exists (template_file_path))
1923 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1924 template_file_path.to_string()) << endmsg;
1928 if (!tree.write (template_file_path.to_string())) {
1929 error << _("mix template not saved") << endmsg;
1937 Session::rename_template (string old_name, string new_name)
1939 sys::path old_path (user_template_directory());
1940 old_path /= old_name + template_suffix;
1942 sys::path new_path(user_template_directory());
1943 new_path /= new_name + template_suffix;
1945 if (sys::exists (new_path)) {
1946 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1947 new_path.to_string()) << endmsg;
1952 sys::rename (old_path, new_path);
1960 Session::delete_template (string name)
1962 sys::path path = user_template_directory();
1963 path /= name + template_suffix;
1974 Session::refresh_disk_space ()
1977 struct statfs statfsbuf;
1978 vector<space_and_path>::iterator i;
1979 Glib::Mutex::Lock lm (space_lock);
1982 /* get freespace on every FS that is part of the session path */
1984 _total_free_4k_blocks = 0;
1986 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1987 statfs ((*i).path.c_str(), &statfsbuf);
1989 scale = statfsbuf.f_bsize/4096.0;
1991 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1992 _total_free_4k_blocks += (*i).blocks;
1998 Session::get_best_session_directory_for_new_source ()
2000 vector<space_and_path>::iterator i;
2001 string result = _session_dir->root_path().to_string();
2003 /* handle common case without system calls */
2005 if (session_dirs.size() == 1) {
2009 /* OK, here's the algorithm we're following here:
2011 We want to select which directory to use for
2012 the next file source to be created. Ideally,
2013 we'd like to use a round-robin process so as to
2014 get maximum performance benefits from splitting
2015 the files across multiple disks.
2017 However, in situations without much diskspace, an
2018 RR approach may end up filling up a filesystem
2019 with new files while others still have space.
2020 Its therefore important to pay some attention to
2021 the freespace in the filesystem holding each
2022 directory as well. However, if we did that by
2023 itself, we'd keep creating new files in the file
2024 system with the most space until it was as full
2025 as all others, thus negating any performance
2026 benefits of this RAID-1 like approach.
2028 So, we use a user-configurable space threshold. If
2029 there are at least 2 filesystems with more than this
2030 much space available, we use RR selection between them.
2031 If not, then we pick the filesystem with the most space.
2033 This gets a good balance between the two
2037 refresh_disk_space ();
2039 int free_enough = 0;
2041 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2042 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2047 if (free_enough >= 2) {
2048 /* use RR selection process, ensuring that the one
2052 i = last_rr_session_dir;
2055 if (++i == session_dirs.end()) {
2056 i = session_dirs.begin();
2059 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2060 if (create_session_directory ((*i).path)) {
2062 last_rr_session_dir = i;
2067 } while (i != last_rr_session_dir);
2071 /* pick FS with the most freespace (and that
2072 seems to actually work ...)
2075 vector<space_and_path> sorted;
2076 space_and_path_ascending_cmp cmp;
2078 sorted = session_dirs;
2079 sort (sorted.begin(), sorted.end(), cmp);
2081 for (i = sorted.begin(); i != sorted.end(); ++i) {
2082 if (create_session_directory ((*i).path)) {
2084 last_rr_session_dir = i;
2094 Session::load_named_selections (const XMLNode& node)
2097 XMLNodeConstIterator niter;
2100 nlist = node.children();
2104 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2106 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2107 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2115 Session::XMLNamedSelectionFactory (const XMLNode& node)
2118 return new NamedSelection (*this, node);
2121 catch (failed_constructor& err) {
2127 Session::automation_dir () const
2129 return Glib::build_filename (_path, "automation");
2133 Session::analysis_dir () const
2135 return Glib::build_filename (_path, "analysis");
2139 Session::load_bundles (XMLNode const & node)
2141 XMLNodeList nlist = node.children();
2142 XMLNodeConstIterator niter;
2146 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2147 if ((*niter)->name() == "InputBundle") {
2148 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2149 } else if ((*niter)->name() == "OutputBundle") {
2150 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2152 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2161 Session::load_route_groups (const XMLNode& node, int version)
2163 XMLNodeList nlist = node.children();
2164 XMLNodeConstIterator niter;
2168 if (version >= 3000) {
2170 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2171 if ((*niter)->name() == "RouteGroup") {
2172 RouteGroup* rg = new RouteGroup (*this, "");
2173 add_route_group (rg);
2174 rg->set_state (**niter, version);
2178 } else if (version < 3000) {
2180 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2181 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2182 RouteGroup* rg = new RouteGroup (*this, "");
2183 add_route_group (rg);
2184 rg->set_state (**niter, version);
2193 Session::auto_save()
2195 save_state (_current_snapshot_name);
2199 state_file_filter (const string &str, void */*arg*/)
2201 return (str.length() > strlen(statefile_suffix) &&
2202 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2206 bool operator()(const string* a, const string* b) {
2212 remove_end(string* state)
2214 string statename(*state);
2216 string::size_type start,end;
2217 if ((start = statename.find_last_of ('/')) != string::npos) {
2218 statename = statename.substr (start+1);
2221 if ((end = statename.rfind(".ardour")) == string::npos) {
2222 end = statename.length();
2225 return new string(statename.substr (0, end));
2229 Session::possible_states (string path)
2231 PathScanner scanner;
2232 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2234 transform(states->begin(), states->end(), states->begin(), remove_end);
2237 sort (states->begin(), states->end(), cmp);
2243 Session::possible_states () const
2245 return possible_states(_path);
2249 Session::add_route_group (RouteGroup* g)
2251 _route_groups.push_back (g);
2252 route_group_added (g); /* EMIT SIGNAL */
2257 Session::remove_route_group (RouteGroup& rg)
2259 list<RouteGroup*>::iterator i;
2261 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2262 _route_groups.erase (i);
2265 route_group_removed (); /* EMIT SIGNAL */
2271 Session::route_group_by_name (string name)
2273 list<RouteGroup *>::iterator i;
2275 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2276 if ((*i)->name() == name) {
2284 Session::start_reversible_command (const string& name)
2286 UndoTransaction* trans = new UndoTransaction();
2287 trans->set_name(name);
2292 Session::finish_reversible_command (UndoTransaction& ut)
2295 gettimeofday(&now, 0);
2296 ut.set_timestamp(now);
2301 Session::begin_reversible_command(const string& name)
2303 UndoTransaction* trans = new UndoTransaction();
2304 trans->set_name(name);
2306 if (!_current_trans.empty()) {
2307 _current_trans.top()->add_command (trans);
2309 _current_trans.push(trans);
2314 Session::commit_reversible_command(Command *cmd)
2316 assert(!_current_trans.empty());
2320 _current_trans.top()->add_command(cmd);
2323 if (_current_trans.top()->empty()) {
2324 _current_trans.pop();
2328 gettimeofday(&now, 0);
2329 _current_trans.top()->set_timestamp(now);
2331 _history.add(_current_trans.top());
2332 _current_trans.pop();
2336 accept_all_non_peak_files (const string& path, void */*arg*/)
2338 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2342 accept_all_state_files (const string& path, void */*arg*/)
2344 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2348 Session::find_all_sources (string path, set<string>& result)
2353 if (!tree.read (path)) {
2357 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2362 XMLNodeConstIterator niter;
2364 nlist = node->children();
2368 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2372 if ((prop = (*niter)->property (X_("type"))) == 0) {
2376 DataType type (prop->value());
2378 if ((prop = (*niter)->property (X_("name"))) == 0) {
2382 if (prop->value()[0] == '/') {
2383 /* external file, ignore */
2387 Glib::ustring found_path;
2391 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2392 result.insert (found_path);
2400 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2402 PathScanner scanner;
2403 vector<string*>* state_files;
2405 string this_snapshot_path;
2411 if (ripped[ripped.length()-1] == '/') {
2412 ripped = ripped.substr (0, ripped.length() - 1);
2415 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2417 if (state_files == 0) {
2422 this_snapshot_path = _path;
2423 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2424 this_snapshot_path += statefile_suffix;
2426 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2428 if (exclude_this_snapshot && **i == this_snapshot_path) {
2432 if (find_all_sources (**i, result) < 0) {
2440 struct RegionCounter {
2441 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2442 AudioSourceList::iterator iter;
2443 boost::shared_ptr<Region> region;
2446 RegionCounter() : count (0) {}
2450 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2452 boost::optional<int> r = AskAboutPlaylistDeletion (p);
2453 return r.get_value_or (1);
2457 Session::cleanup_sources (CleanupReport& rep)
2459 // FIXME: needs adaptation to midi
2461 vector<boost::shared_ptr<Source> > dead_sources;
2462 PathScanner scanner;
2464 vector<space_and_path>::iterator i;
2465 vector<space_and_path>::iterator nexti;
2466 vector<string*>* soundfiles;
2467 vector<string> unused;
2468 set<string> all_sources;
2473 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2475 /* step 1: consider deleting all unused playlists */
2477 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2482 /* step 2: find all un-used sources */
2487 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2489 SourceMap::iterator tmp;
2494 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2498 if (!playlists->source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2499 dead_sources.push_back (i->second);
2500 i->second->drop_references ();
2506 /* build a list of all the possible sound directories for the session */
2508 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2513 SessionDirectory sdir ((*i).path);
2514 sound_path += sdir.sound_path().to_string();
2516 if (nexti != session_dirs.end()) {
2523 /* now do the same thing for the files that ended up in the sounds dir(s)
2524 but are not referenced as sources in any snapshot.
2527 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2529 if (soundfiles == 0) {
2533 /* find all sources, but don't use this snapshot because the
2534 state file on disk still references sources we may have already
2538 find_all_sources_across_snapshots (all_sources, true);
2540 /* add our current source list
2543 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2544 boost::shared_ptr<FileSource> fs;
2546 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2547 all_sources.insert (fs->path());
2551 char tmppath1[PATH_MAX+1];
2552 char tmppath2[PATH_MAX+1];
2554 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2559 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2561 realpath(spath.c_str(), tmppath1);
2562 realpath((*i).c_str(), tmppath2);
2564 if (strcmp(tmppath1, tmppath2) == 0) {
2571 unused.push_back (spath);
2575 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2577 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2578 struct stat statbuf;
2580 rep.paths.push_back (*x);
2581 if (stat ((*x).c_str(), &statbuf) == 0) {
2582 rep.space += statbuf.st_size;
2587 /* don't move the file across filesystems, just
2588 stick it in the `dead_sound_dir_name' directory
2589 on whichever filesystem it was already on.
2592 if ((*x).find ("/sounds/") != string::npos) {
2594 /* old school, go up 1 level */
2596 newpath = Glib::path_get_dirname (*x); // "sounds"
2597 newpath = Glib::path_get_dirname (newpath); // "session-name"
2601 /* new school, go up 4 levels */
2603 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2604 newpath = Glib::path_get_dirname (newpath); // "session-name"
2605 newpath = Glib::path_get_dirname (newpath); // "interchange"
2606 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2610 newpath += dead_sound_dir_name;
2612 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2613 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2618 newpath += Glib::path_get_basename ((*x));
2620 if (access (newpath.c_str(), F_OK) == 0) {
2622 /* the new path already exists, try versioning */
2624 char buf[PATH_MAX+1];
2628 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2631 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2632 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2636 if (version == 999) {
2637 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2641 newpath = newpath_v;
2646 /* it doesn't exist, or we can't read it or something */
2650 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2651 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2652 (*x), newpath, strerror (errno))
2657 /* see if there an easy to find peakfile for this file, and remove it.
2660 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2661 peakpath += peakfile_suffix;
2663 if (access (peakpath.c_str(), W_OK) == 0) {
2664 if (::unlink (peakpath.c_str()) != 0) {
2665 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2666 peakpath, _path, strerror (errno))
2668 /* try to back out */
2669 rename (newpath.c_str(), _path.c_str());
2677 /* dump the history list */
2681 /* save state so we don't end up a session file
2682 referring to non-existent sources.
2688 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2694 Session::cleanup_trash_sources (CleanupReport& rep)
2696 // FIXME: needs adaptation for MIDI
2698 vector<space_and_path>::iterator i;
2699 string dead_sound_dir;
2700 struct dirent* dentry;
2701 struct stat statbuf;
2707 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2709 dead_sound_dir = (*i).path;
2710 dead_sound_dir += dead_sound_dir_name;
2712 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2716 while ((dentry = readdir (dead)) != 0) {
2718 /* avoid '.' and '..' */
2720 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2721 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2727 fullpath = dead_sound_dir;
2729 fullpath += dentry->d_name;
2731 if (stat (fullpath.c_str(), &statbuf)) {
2735 if (!S_ISREG (statbuf.st_mode)) {
2739 if (unlink (fullpath.c_str())) {
2740 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2741 fullpath, strerror (errno))
2745 rep.paths.push_back (dentry->d_name);
2746 rep.space += statbuf.st_size;
2757 Session::set_dirty ()
2759 bool was_dirty = dirty();
2761 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2765 DirtyChanged(); /* EMIT SIGNAL */
2771 Session::set_clean ()
2773 bool was_dirty = dirty();
2775 _state_of_the_state = Clean;
2779 DirtyChanged(); /* EMIT SIGNAL */
2784 Session::set_deletion_in_progress ()
2786 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2790 Session::clear_deletion_in_progress ()
2792 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2796 Session::add_controllable (boost::shared_ptr<Controllable> c)
2798 /* this adds a controllable to the list managed by the Session.
2799 this is a subset of those managed by the Controllable class
2800 itself, and represents the only ones whose state will be saved
2801 as part of the session.
2804 Glib::Mutex::Lock lm (controllables_lock);
2805 controllables.insert (c);
2808 struct null_deleter { void operator()(void const *) const {} };
2811 Session::remove_controllable (Controllable* c)
2813 if (_state_of_the_state | Deletion) {
2817 Glib::Mutex::Lock lm (controllables_lock);
2819 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2821 if (x != controllables.end()) {
2822 controllables.erase (x);
2826 boost::shared_ptr<Controllable>
2827 Session::controllable_by_id (const PBD::ID& id)
2829 Glib::Mutex::Lock lm (controllables_lock);
2831 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2832 if ((*i)->id() == id) {
2837 return boost::shared_ptr<Controllable>();
2840 boost::shared_ptr<Controllable>
2841 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2843 boost::shared_ptr<Controllable> c;
2844 boost::shared_ptr<Route> r;
2846 switch (desc.top_level_type()) {
2847 case ControllableDescriptor::NamedRoute:
2849 std::string str = desc.top_level_name();
2850 if (str == "master") {
2852 } else if (str == "control" || str == "listen") {
2855 r = route_by_name (desc.top_level_name());
2860 case ControllableDescriptor::RemoteControlID:
2861 r = route_by_remote_id (desc.rid());
2869 switch (desc.subtype()) {
2870 case ControllableDescriptor::Gain:
2871 c = r->gain_control ();
2874 case ControllableDescriptor::Solo:
2875 c = r->solo_control();
2878 case ControllableDescriptor::Mute:
2879 c = r->mute_control();
2882 case ControllableDescriptor::Recenable:
2884 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2887 c = t->rec_enable_control ();
2892 case ControllableDescriptor::Pan:
2893 /* XXX pan control */
2896 case ControllableDescriptor::Balance:
2897 /* XXX simple pan control */
2900 case ControllableDescriptor::PluginParameter:
2902 uint32_t plugin = desc.target (0);
2903 uint32_t parameter_index = desc.target (1);
2905 /* revert to zero based counting */
2911 if (parameter_index > 0) {
2915 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2918 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2919 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2924 case ControllableDescriptor::SendGain:
2926 uint32_t send = desc.target (0);
2928 /* revert to zero-based counting */
2934 boost::shared_ptr<Processor> p = r->nth_send (send);
2937 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2938 boost::shared_ptr<Amp> a = s->amp();
2941 c = s->amp()->gain_control();
2948 /* relax and return a null pointer */
2956 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2959 Stateful::add_instant_xml (node, _path);
2962 if (write_to_config) {
2963 Config->add_instant_xml (node);
2968 Session::instant_xml (const string& node_name)
2970 return Stateful::instant_xml (node_name, _path);
2974 Session::save_history (string snapshot_name)
2982 if (snapshot_name.empty()) {
2983 snapshot_name = _current_snapshot_name;
2986 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2987 const string backup_filename = history_filename + backup_suffix;
2988 const sys::path xml_path = _session_dir->root_path() / history_filename;
2989 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2991 if (sys::exists (xml_path)) {
2994 sys::rename (xml_path, backup_path);
2996 catch (const sys::filesystem_error& err)
2998 error << _("could not backup old history file, current history not saved") << endmsg;
3003 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3007 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3009 if (!tree.write (xml_path.to_string()))
3011 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
3015 sys::remove (xml_path);
3016 sys::rename (backup_path, xml_path);
3018 catch (const sys::filesystem_error& err)
3020 error << string_compose (_("could not restore history file from backup %1 (%2)"),
3021 backup_path.to_string(), err.what()) << endmsg;
3031 Session::restore_history (string snapshot_name)
3035 if (snapshot_name.empty()) {
3036 snapshot_name = _current_snapshot_name;
3039 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3040 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3042 info << "Loading history from " << xml_path.to_string() << endmsg;
3044 if (!sys::exists (xml_path)) {
3045 info << string_compose (_("%1: no history file \"%2\" for this session."),
3046 _name, xml_path.to_string()) << endmsg;
3050 if (!tree.read (xml_path.to_string())) {
3051 error << string_compose (_("Could not understand session history file \"%1\""),
3052 xml_path.to_string()) << endmsg;
3059 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3062 UndoTransaction* ut = new UndoTransaction ();
3065 ut->set_name(t->property("name")->value());
3066 stringstream ss(t->property("tv-sec")->value());
3068 ss.str(t->property("tv-usec")->value());
3070 ut->set_timestamp(tv);
3072 for (XMLNodeConstIterator child_it = t->children().begin();
3073 child_it != t->children().end(); child_it++)
3075 XMLNode *n = *child_it;
3078 if (n->name() == "MementoCommand" ||
3079 n->name() == "MementoUndoCommand" ||
3080 n->name() == "MementoRedoCommand") {
3082 if ((c = memento_command_factory(n))) {
3086 } else if (n->name() == "DiffCommand") {
3087 PBD::ID id(n->property("midi-source")->value());
3088 boost::shared_ptr<MidiSource> midi_source =
3089 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3091 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3093 error << _("Failed to downcast MidiSource for DiffCommand") << endmsg;
3096 } else if (n->name() == "StatefulDiffCommand") {
3097 if ((c = stateful_diff_command_factory (n))) {
3098 ut->add_command (c);
3101 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3112 Session::config_changed (std::string p, bool ours)
3118 if (p == "seamless-loop") {
3120 } else if (p == "rf-speed") {
3122 } else if (p == "auto-loop") {
3124 } else if (p == "auto-input") {
3126 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3127 /* auto-input only makes a difference if we're rolling */
3129 boost::shared_ptr<RouteList> rl = routes.reader ();
3130 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3131 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3132 if (tr && tr->record_enabled ()) {
3133 tr->monitor_input (!config.get_auto_input());
3138 } else if (p == "punch-in") {
3142 if ((location = _locations.auto_punch_location()) != 0) {
3144 if (config.get_punch_in ()) {
3145 replace_event (SessionEvent::PunchIn, location->start());
3147 remove_event (location->start(), SessionEvent::PunchIn);
3151 } else if (p == "punch-out") {
3155 if ((location = _locations.auto_punch_location()) != 0) {
3157 if (config.get_punch_out()) {
3158 replace_event (SessionEvent::PunchOut, location->end());
3160 clear_events (SessionEvent::PunchOut);
3164 } else if (p == "edit-mode") {
3166 Glib::Mutex::Lock lm (playlists->lock);
3168 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3169 (*i)->set_edit_mode (Config->get_edit_mode ());
3172 } else if (p == "use-video-sync") {
3174 waiting_for_sync_offset = config.get_use_video_sync();
3176 } else if (p == "mmc-control") {
3178 //poke_midi_thread ();
3180 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3183 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3186 } else if (p == "mmc-send-id") {
3189 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3192 } else if (p == "midi-control") {
3194 //poke_midi_thread ();
3196 } else if (p == "raid-path") {
3198 setup_raid_path (config.get_raid_path());
3200 } else if (p == "timecode-format") {
3204 } else if (p == "video-pullup") {
3208 } else if (p == "seamless-loop") {
3210 if (play_loop && transport_rolling()) {
3211 // to reset diskstreams etc
3212 request_play_loop (true);
3215 } else if (p == "rf-speed") {
3217 cumulative_rf_motion = 0;
3220 } else if (p == "click-sound") {
3222 setup_click_sounds (1);
3224 } else if (p == "click-emphasis-sound") {
3226 setup_click_sounds (-1);
3228 } else if (p == "clicking") {
3230 if (Config->get_clicking()) {
3231 if (_click_io && click_data) { // don't require emphasis data
3238 } else if (p == "send-mtc") {
3240 /* only set the internal flag if we have
3244 if (_mtc_port != 0) {
3245 session_send_mtc = Config->get_send_mtc();
3246 if (session_send_mtc) {
3247 /* mark us ready to send */
3248 next_quarter_frame_to_send = 0;
3251 session_send_mtc = false;
3254 } else if (p == "send-mmc") {
3256 /* only set the internal flag if we have
3260 if (_mmc_port != 0) {
3261 session_send_mmc = Config->get_send_mmc();
3264 session_send_mmc = false;
3267 } else if (p == "midi-feedback") {
3269 /* only set the internal flag if we have
3273 if (_mtc_port != 0) {
3274 session_midi_feedback = Config->get_midi_feedback();
3277 } else if (p == "jack-time-master") {
3279 engine().reset_timebase ();
3281 } else if (p == "native-file-header-format") {
3283 if (!first_file_header_format_reset) {
3284 reset_native_file_format ();
3287 first_file_header_format_reset = false;
3289 } else if (p == "native-file-data-format") {
3291 if (!first_file_data_format_reset) {
3292 reset_native_file_format ();
3295 first_file_data_format_reset = false;
3297 } else if (p == "external-sync") {
3298 if (!config.get_external_sync()) {
3299 drop_sync_source ();
3301 switch_to_sync_source (config.get_sync_source());
3303 } else if (p == "remote-model") {
3304 set_remote_control_ids ();
3305 } else if (p == "denormal-model") {
3307 } else if (p == "history-depth") {
3308 set_history_depth (Config->get_history_depth());
3309 } else if (p == "sync-all-route-ordering") {
3310 sync_order_keys ("session");
3311 } else if (p == "initial-program-change") {
3313 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3316 buf[0] = MIDI::program; // channel zero by default
3317 buf[1] = (Config->get_initial_program_change() & 0x7f);
3319 _mmc_port->midimsg (buf, sizeof (buf), 0);
3321 } else if (p == "initial-program-change") {
3323 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3324 MIDI::byte* buf = new MIDI::byte[2];
3326 buf[0] = MIDI::program; // channel zero by default
3327 buf[1] = (Config->get_initial_program_change() & 0x7f);
3328 // deliver_midi (_mmc_port, buf, 2);
3330 } else if (p == "solo-mute-override") {
3331 // catch_up_on_solo_mute_override ();
3332 } else if (p == "listen-position") {
3333 listen_position_changed ();
3334 } else if (p == "solo-control-is-listen-control") {
3335 solo_control_mode_changed ();
3343 Session::set_history_depth (uint32_t d)
3345 _history.set_depth (d);
3349 Session::load_diskstreams_2X (XMLNode const & node, int)
3352 XMLNodeConstIterator citer;
3354 clist = node.children();
3356 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3359 /* diskstreams added automatically by DiskstreamCreated handler */
3360 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3361 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3362 _diskstreams_2X.push_back (dsp);
3364 error << _("Session: unknown diskstream type in XML") << endmsg;
3368 catch (failed_constructor& err) {
3369 error << _("Session: could not load diskstream via XML state") << endmsg;