2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libardour-config.h"
25 #define __STDC_FORMAT_MACROS 1
34 #include <cstdio> /* snprintf(3) ... grrr */
49 #include <sys/param.h>
50 #include <sys/mount.h>
54 #include <glibmm/thread.h>
56 #include "midi++/mmc.h"
57 #include "midi++/port.h"
59 #include "pbd/boost_debug.h"
60 #include "pbd/controllable_descriptor.h"
61 #include "pbd/enumwriter.h"
62 #include "pbd/error.h"
63 #include "pbd/pathscanner.h"
64 #include "pbd/pthread_utils.h"
65 #include "pbd/search_path.h"
66 #include "pbd/stacktrace.h"
67 #include "pbd/convert.h"
69 #include "ardour/amp.h"
70 #include "ardour/audio_diskstream.h"
71 #include "ardour/audio_track.h"
72 #include "ardour/audioengine.h"
73 #include "ardour/audiofilesource.h"
74 #include "ardour/audioplaylist.h"
75 #include "ardour/audioregion.h"
76 #include "ardour/auditioner.h"
77 #include "ardour/buffer.h"
78 #include "ardour/butler.h"
79 #include "ardour/configuration.h"
80 #include "ardour/control_protocol_manager.h"
81 #include "ardour/crossfade.h"
82 #include "ardour/cycle_timer.h"
83 #include "ardour/directory_names.h"
84 #include "ardour/filename_extensions.h"
85 #include "ardour/io_processor.h"
86 #include "ardour/location.h"
87 #include "ardour/midi_diskstream.h"
88 #include "ardour/midi_patch_manager.h"
89 #include "ardour/midi_playlist.h"
90 #include "ardour/midi_region.h"
91 #include "ardour/midi_source.h"
92 #include "ardour/midi_track.h"
93 #include "ardour/named_selection.h"
94 #include "ardour/processor.h"
95 #include "ardour/region_factory.h"
96 #include "ardour/route_group.h"
97 #include "ardour/send.h"
98 #include "ardour/session.h"
99 #include "ardour/session_directory.h"
100 #include "ardour/session_metadata.h"
101 #include "ardour/session_state_utils.h"
102 #include "ardour/session_playlists.h"
103 #include "ardour/session_utils.h"
104 #include "ardour/silentfilesource.h"
105 #include "ardour/slave.h"
106 #include "ardour/smf_source.h"
107 #include "ardour/sndfile_helpers.h"
108 #include "ardour/sndfilesource.h"
109 #include "ardour/source_factory.h"
110 #include "ardour/template_utils.h"
111 #include "ardour/tempo.h"
112 #include "ardour/ticker.h"
113 #include "ardour/user_bundle.h"
114 #include "ardour/utils.h"
115 #include "ardour/utils.h"
116 #include "ardour/version.h"
117 #include "ardour/playlist_factory.h"
119 #include "control_protocol/control_protocol.h"
125 using namespace ARDOUR;
129 Session::first_stage_init (string fullpath, string snapshot_name)
131 if (fullpath.length() == 0) {
133 throw failed_constructor();
136 char buf[PATH_MAX+1];
137 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
138 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
140 throw failed_constructor();
145 if (_path[_path.length()-1] != '/') {
149 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
155 /* these two are just provisional settings. set_state()
156 will likely override them.
159 _name = _current_snapshot_name = snapshot_name;
161 set_history_depth (Config->get_history_depth());
163 _current_frame_rate = _engine.frame_rate ();
164 _nominal_frame_rate = _current_frame_rate;
165 _base_frame_rate = _current_frame_rate;
167 _tempo_map = new TempoMap (_current_frame_rate);
168 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
171 _non_soloed_outs_muted = false;
173 g_atomic_int_set (&processing_prohibited, 0);
174 _transport_speed = 0;
175 _last_transport_speed = 0;
176 _target_transport_speed = 0;
177 auto_play_legal = false;
178 transport_sub_state = 0;
179 _transport_frame = 0;
180 _requested_return_frame = -1;
181 _session_range_location = new Location (0, 0, _("session"), Location::IsSessionRange);
182 g_atomic_int_set (&_record_status, Disabled);
183 loop_changing = false;
186 _last_roll_location = 0;
187 _last_record_location = 0;
188 pending_locate_frame = 0;
189 pending_locate_roll = false;
190 pending_locate_flush = false;
191 state_was_pending = false;
193 outbound_mtc_timecode_frame = 0;
194 next_quarter_frame_to_send = -1;
195 current_block_size = 0;
196 solo_update_disabled = false;
197 _have_captured = false;
198 _worst_output_latency = 0;
199 _worst_input_latency = 0;
200 _worst_track_latency = 0;
201 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
202 _was_seamless = Config->get_seamless_loop ();
204 session_send_mmc = false;
205 session_send_mtc = false;
206 g_atomic_int_set (&_playback_load, 100);
207 g_atomic_int_set (&_capture_load, 100);
208 g_atomic_int_set (&_playback_load_min, 100);
209 g_atomic_int_set (&_capture_load_min, 100);
212 pending_abort = false;
213 destructive_index = 0;
214 first_file_data_format_reset = true;
215 first_file_header_format_reset = true;
216 post_export_sync = false;
219 AudioDiskstream::allocate_working_buffers();
221 /* default short fade = 15ms */
223 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
224 SndFileSource::setup_standard_crossfades (*this, frame_rate());
226 last_mmc_step.tv_sec = 0;
227 last_mmc_step.tv_usec = 0;
230 /* click sounds are unset by default, which causes us to internal
231 waveforms for clicks.
235 click_emphasis_length = 0;
238 process_function = &Session::process_with_events;
240 if (config.get_use_video_sync()) {
241 waiting_for_sync_offset = true;
243 waiting_for_sync_offset = false;
246 last_timecode_when = 0;
247 _timecode_offset = 0;
248 _timecode_offset_negative = true;
249 last_timecode_valid = false;
253 last_rr_session_dir = session_dirs.begin();
254 refresh_disk_space ();
256 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
260 average_slave_delta = 1800; // !!! why 1800 ????
261 have_first_delta_accumulator = false;
262 delta_accumulator_cnt = 0;
263 _slave_state = Stopped;
265 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
267 /* These are all static "per-class" signals */
269 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
270 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
271 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
272 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
273 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
275 /* stop IO objects from doing stuff until we're ready for them */
277 Delivery::disable_panners ();
278 IO::disable_connecting ();
282 Session::second_stage_init ()
284 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
287 if (load_state (_current_snapshot_name)) {
290 remove_empty_sounds ();
293 if (_butler->start_thread()) {
297 if (start_midi_thread ()) {
301 // set_state() will call setup_raid_path(), but if it's a new session we need
302 // to call setup_raid_path() here.
305 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
309 setup_raid_path(_path);
312 /* we can't save till after ::when_engine_running() is called,
313 because otherwise we save state with no connections made.
314 therefore, we reset _state_of_the_state because ::set_state()
315 will have cleared it.
317 we also have to include Loading so that any events that get
318 generated between here and the end of ::when_engine_running()
319 will be processed directly rather than queued.
322 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
325 _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
326 _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
327 setup_click_sounds (0);
328 setup_midi_control ();
330 /* Pay attention ... */
332 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
333 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
336 when_engine_running ();
339 /* handle this one in a different way than all others, so that its clear what happened */
341 catch (AudioEngine::PortRegistrationFailure& err) {
342 error << err.what() << endmsg;
350 BootMessage (_("Reset Remote Controls"));
352 send_full_time_code (0);
353 _engine.transport_locate (0);
354 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
355 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
357 MidiClockTicker::instance().set_session (this);
358 MIDI::Name::MidiPatchManager::instance().set_session (this);
360 /* initial program change will be delivered later; see ::config_changed() */
362 BootMessage (_("Reset Control Protocols"));
364 ControlProtocolManager::instance().set_session (this);
366 config.set_end_marker_is_free (_is_new);
368 _state_of_the_state = Clean;
370 DirtyChanged (); /* EMIT SIGNAL */
372 if (state_was_pending) {
373 save_state (_current_snapshot_name);
374 remove_pending_capture_state ();
375 state_was_pending = false;
378 BootMessage (_("Session loading complete"));
384 Session::raid_path () const
386 SearchPath raid_search_path;
388 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
389 raid_search_path += sys::path((*i).path);
392 return raid_search_path.to_string ();
396 Session::setup_raid_path (string path)
405 session_dirs.clear ();
407 SearchPath search_path(path);
408 SearchPath sound_search_path;
409 SearchPath midi_search_path;
411 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
412 sp.path = (*i).to_string ();
413 sp.blocks = 0; // not needed
414 session_dirs.push_back (sp);
416 SessionDirectory sdir(sp.path);
418 sound_search_path += sdir.sound_path ();
419 midi_search_path += sdir.midi_path ();
422 // set the search path for each data type
423 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
424 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
426 // reset the round-robin soundfile path thingie
427 last_rr_session_dir = session_dirs.begin();
431 Session::path_is_within_session (const std::string& path)
433 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
434 if (path.find ((*i).path) == 0) {
442 Session::ensure_subdirs ()
446 dir = session_directory().peak_path().to_string();
448 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
449 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
453 dir = session_directory().sound_path().to_string();
455 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
456 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
460 dir = session_directory().midi_path().to_string();
462 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
463 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
467 dir = session_directory().dead_sound_path().to_string();
469 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
470 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
474 dir = session_directory().export_path().to_string();
476 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
477 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
481 dir = analysis_dir ();
483 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
484 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
492 Session::create (const string& mix_template, nframes_t initial_length, BusProfile* bus_profile)
495 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
496 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
500 if (ensure_subdirs ()) {
504 if (!mix_template.empty()) {
505 std::string in_path = mix_template;
507 ifstream in(in_path.c_str());
510 string out_path = _path;
512 out_path += statefile_suffix;
514 ofstream out(out_path.c_str());
522 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
528 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
535 /* Instantiate metadata */
537 _metadata = new SessionMetadata ();
539 /* set initial start + end point */
541 _session_range_location->set (0, initial_length);
542 _locations.add (_session_range_location);
544 _state_of_the_state = Clean;
546 /* set up Master Out and Control Out if necessary */
552 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
554 if (bus_profile->master_out_channels) {
555 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
560 boost_debug_shared_ptr_mark_interesting (rt, "Route");
561 boost::shared_ptr<Route> r (rt);
562 r->input()->ensure_io (count, false, this);
563 r->output()->ensure_io (count, false, this);
564 r->set_remote_control_id (control_id++);
568 if (Config->get_use_monitor_bus()) {
569 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
574 boost_debug_shared_ptr_mark_interesting (rt, "Route");
575 boost::shared_ptr<Route> r (rt);
576 r->input()->ensure_io (count, false, this);
577 r->output()->ensure_io (count, false, this);
578 r->set_remote_control_id (control_id);
584 /* prohibit auto-connect to master, because there isn't one */
585 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
589 add_routes (rl, false);
592 /* this allows the user to override settings with an environment variable.
595 if (no_auto_connect()) {
596 bus_profile->input_ac = AutoConnectOption (0);
597 bus_profile->output_ac = AutoConnectOption (0);
600 Config->set_input_auto_connect (bus_profile->input_ac);
601 Config->set_output_auto_connect (bus_profile->output_ac);
610 Session::maybe_write_autosave()
612 if (dirty() && record_status() != Recording) {
613 save_state("", true);
618 Session::remove_pending_capture_state ()
620 sys::path pending_state_file_path(_session_dir->root_path());
622 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
626 sys::remove (pending_state_file_path);
628 catch(sys::filesystem_error& ex)
630 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
631 pending_state_file_path.to_string(), ex.what()) << endmsg;
635 /** Rename a state file.
636 * @param snapshot_name Snapshot name.
639 Session::rename_state (string old_name, string new_name)
641 if (old_name == _current_snapshot_name || old_name == _name) {
642 /* refuse to rename the current snapshot or the "main" one */
646 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
647 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
649 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
650 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
654 sys::rename (old_xml_path, new_xml_path);
656 catch (const sys::filesystem_error& err)
658 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
659 old_name, new_name, err.what()) << endmsg;
663 /** Remove a state file.
664 * @param snapshot_name Snapshot name.
667 Session::remove_state (string snapshot_name)
669 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
670 // refuse to remove the current snapshot or the "main" one
674 sys::path xml_path(_session_dir->root_path());
676 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
678 if (!create_backup_file (xml_path)) {
679 // don't remove it if a backup can't be made
680 // create_backup_file will log the error.
685 sys::remove (xml_path);
688 #ifdef HAVE_JACK_SESSION
690 Session::jack_session_event (jack_session_event_t * event)
692 if (save_state ("jacksession_snap")) {
693 event->flags = JackSessionSaveError;
695 sys::path xml_path (_session_dir->root_path());
696 xml_path /= legalize_for_path ("jacksession_snap") + statefile_suffix;
698 string cmd ("PROG_NAME -U ");
699 cmd += event->client_uuid;
701 cmd += xml_path.to_string();
704 event->command_line = strdup (cmd.c_str());
707 jack_session_reply (_engine.jack(), event);
709 if (event->type == JackSessionSaveAndQuit) {
710 // TODO: make ardour quit.
713 jack_session_event_free( event );
718 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
721 sys::path xml_path(_session_dir->root_path());
723 if (!_writable || (_state_of_the_state & CannotSave)) {
727 if (!_engine.connected ()) {
728 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
734 /* tell sources we're saving first, in case they write out to a new file
735 * which should be saved with the state rather than the old one */
736 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
737 i->second->session_saved();
739 tree.set_root (&get_state());
741 if (snapshot_name.empty()) {
742 snapshot_name = _current_snapshot_name;
743 } else if (switch_to_snapshot) {
744 _current_snapshot_name = snapshot_name;
749 /* proper save: use statefile_suffix (.ardour in English) */
751 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
753 /* make a backup copy of the old file */
755 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
756 // create_backup_file will log the error
762 /* pending save: use pending_suffix (.pending in English) */
763 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
766 sys::path tmp_path(_session_dir->root_path());
768 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
770 // cerr << "actually writing state to " << xml_path.to_string() << endl;
772 if (!tree.write (tmp_path.to_string())) {
773 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
774 sys::remove (tmp_path);
779 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
780 error << string_compose (_("could not rename temporary session file %1 to %2"),
781 tmp_path.to_string(), xml_path.to_string()) << endmsg;
782 sys::remove (tmp_path);
789 save_history (snapshot_name);
791 bool was_dirty = dirty();
793 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
796 DirtyChanged (); /* EMIT SIGNAL */
799 StateSaved (snapshot_name); /* EMIT SIGNAL */
806 Session::restore_state (string snapshot_name)
808 if (load_state (snapshot_name) == 0) {
809 set_state (*state_tree->root(), Stateful::loading_state_version);
816 Session::load_state (string snapshot_name)
821 state_was_pending = false;
823 /* check for leftover pending state from a crashed capture attempt */
825 sys::path xmlpath(_session_dir->root_path());
826 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
828 if (sys::exists (xmlpath)) {
830 /* there is pending state from a crashed capture attempt */
832 if (*AskAboutPendingState()) {
833 state_was_pending = true;
837 if (!state_was_pending) {
838 xmlpath = _session_dir->root_path();
839 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
842 if (!sys::exists (xmlpath)) {
843 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
847 state_tree = new XMLTree;
851 /* writable() really reflects the whole folder, but if for any
852 reason the session state file can't be written to, still
856 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
860 if (!state_tree->read (xmlpath.to_string())) {
861 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
867 XMLNode& root (*state_tree->root());
869 if (root.name() != X_("Session")) {
870 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
876 const XMLProperty* prop;
878 if ((prop = root.property ("version")) == 0) {
879 /* no version implies very old version of Ardour */
880 Stateful::loading_state_version = 1000;
886 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
887 Stateful::loading_state_version = (major * 1000) + minor;
890 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
892 sys::path backup_path(_session_dir->root_path());
894 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
896 // only create a backup once
897 if (sys::exists (backup_path)) {
901 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
902 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
907 sys::copy_file (xmlpath, backup_path);
909 catch(sys::filesystem_error& ex)
911 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
912 xmlpath.to_string(), ex.what())
922 Session::load_options (const XMLNode& node)
924 LocaleGuard lg (X_("POSIX"));
925 config.set_variables (node);
936 Session::get_template()
938 /* if we don't disable rec-enable, diskstreams
939 will believe they need to store their capture
940 sources in their state node.
943 disable_record (false);
949 Session::state(bool full_state)
951 XMLNode* node = new XMLNode("Session");
954 // store libardour version, just in case
956 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
957 node->add_property("version", string(buf));
959 /* store configuration settings */
963 node->add_property ("name", _name);
964 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
965 node->add_property ("sample-rate", buf);
967 if (session_dirs.size() > 1) {
971 vector<space_and_path>::iterator i = session_dirs.begin();
972 vector<space_and_path>::iterator next;
974 ++i; /* skip the first one */
978 while (i != session_dirs.end()) {
982 if (next != session_dirs.end()) {
992 child = node->add_child ("Path");
993 child->add_content (p);
997 /* save the ID counter */
999 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1000 node->add_property ("id-counter", buf);
1002 /* various options */
1004 node->add_child_nocopy (config.get_variables ());
1006 node->add_child_nocopy (_metadata->get_state());
1008 child = node->add_child ("Sources");
1011 Glib::Mutex::Lock sl (source_lock);
1013 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1015 /* Don't save information about non-destructive file sources that are empty */
1016 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
1018 boost::shared_ptr<AudioFileSource> fs;
1019 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
1020 if (!fs->destructive()) {
1021 if (fs->length(fs->timeline_position()) == 0) {
1027 child->add_child_nocopy (siter->second->get_state());
1031 child = node->add_child ("Regions");
1034 Glib::Mutex::Lock rl (region_lock);
1035 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1036 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1037 boost::shared_ptr<Region> r = i->second;
1038 /* only store regions not attached to playlists */
1039 if (r->playlist() == 0) {
1040 child->add_child_nocopy (r->state (true));
1046 node->add_child_nocopy (_locations.get_state());
1048 // for a template, just create a new Locations, populate it
1049 // with the default start and end, and get the state for that.
1051 Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
1052 range->set (0, compute_initial_length ());
1054 node->add_child_nocopy (loc.get_state());
1057 child = node->add_child ("Bundles");
1059 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1060 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1061 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1063 child->add_child_nocopy (b->get_state());
1068 child = node->add_child ("Routes");
1070 boost::shared_ptr<RouteList> r = routes.reader ();
1072 RoutePublicOrderSorter cmp;
1073 RouteList public_order (*r);
1074 public_order.sort (cmp);
1076 /* the sort should have put control outs first */
1079 assert (_monitor_out == public_order.front());
1082 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1083 if (!(*i)->is_hidden()) {
1085 child->add_child_nocopy ((*i)->get_state());
1087 child->add_child_nocopy ((*i)->get_template());
1093 playlists->add_state (node, full_state);
1095 child = node->add_child ("RouteGroups");
1096 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1097 child->add_child_nocopy ((*i)->get_state());
1101 child = node->add_child ("Click");
1102 child->add_child_nocopy (_click_io->state (full_state));
1106 child = node->add_child ("NamedSelections");
1107 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1109 child->add_child_nocopy ((*i)->get_state());
1114 node->add_child_nocopy (_tempo_map->get_state());
1116 node->add_child_nocopy (get_control_protocol_state());
1119 node->add_child_copy (*_extra_xml);
1126 Session::get_control_protocol_state ()
1128 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1129 return cpm.get_state();
1133 Session::set_state (const XMLNode& node, int version)
1137 const XMLProperty* prop;
1140 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1142 if (node.name() != X_("Session")){
1143 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1147 if ((prop = node.property ("version")) != 0) {
1148 version = atoi (prop->value ()) * 1000;
1151 if ((prop = node.property ("name")) != 0) {
1152 _name = prop->value ();
1155 if ((prop = node.property (X_("sample-rate"))) != 0) {
1157 _nominal_frame_rate = atoi (prop->value());
1159 if (_nominal_frame_rate != _current_frame_rate) {
1160 if (*AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1166 setup_raid_path(_session_dir->root_path().to_string());
1168 if ((prop = node.property (X_("id-counter"))) != 0) {
1170 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1171 ID::init_counter (x);
1173 /* old sessions used a timebased counter, so fake
1174 the startup ID counter based on a standard
1179 ID::init_counter (now);
1183 IO::disable_connecting ();
1185 /* Object loading order:
1190 MIDI Control // relies on data from Options/Config
1203 if ((child = find_named_node (node, "Extra")) != 0) {
1204 _extra_xml = new XMLNode (*child);
1207 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1208 load_options (*child);
1209 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1210 load_options (*child);
1212 error << _("Session: XML state has no options section") << endmsg;
1215 if (use_config_midi_ports ()) {
1218 if (version >= 3000) {
1219 if ((child = find_named_node (node, "Metadata")) == 0) {
1220 warning << _("Session: XML state has no metadata section") << endmsg;
1221 } else if (_metadata->set_state (*child, version)) {
1226 if ((child = find_named_node (node, "Locations")) == 0) {
1227 error << _("Session: XML state has no locations section") << endmsg;
1229 } else if (_locations.set_state (*child, version)) {
1235 if ((location = _locations.auto_loop_location()) != 0) {
1236 set_auto_loop_location (location);
1239 if ((location = _locations.auto_punch_location()) != 0) {
1240 set_auto_punch_location (location);
1243 if ((location = _locations.session_range_location()) == 0) {
1244 _locations.add (_session_range_location);
1246 delete _session_range_location;
1247 _session_range_location = location;
1250 AudioFileSource::set_header_position_offset (_session_range_location->start());
1252 if ((child = find_named_node (node, "Sources")) == 0) {
1253 error << _("Session: XML state has no sources section") << endmsg;
1255 } else if (load_sources (*child)) {
1259 if ((child = find_named_node (node, "Regions")) == 0) {
1260 error << _("Session: XML state has no Regions section") << endmsg;
1262 } else if (load_regions (*child)) {
1266 if ((child = find_named_node (node, "Playlists")) == 0) {
1267 error << _("Session: XML state has no playlists section") << endmsg;
1269 } else if (playlists->load (*this, *child)) {
1273 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1275 } else if (playlists->load_unused (*this, *child)) {
1279 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1280 if (load_named_selections (*child)) {
1285 if (version >= 3000) {
1286 if ((child = find_named_node (node, "Bundles")) == 0) {
1287 warning << _("Session: XML state has no bundles section") << endmsg;
1290 /* We can't load Bundles yet as they need to be able
1291 to convert from port names to Port objects, which can't happen until
1293 _bundle_xml_node = new XMLNode (*child);
1297 if ((child = find_named_node (node, "TempoMap")) == 0) {
1298 error << _("Session: XML state has no Tempo Map section") << endmsg;
1300 } else if (_tempo_map->set_state (*child, version)) {
1304 if (version < 3000) {
1305 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1306 error << _("Session: XML state has no diskstreams section") << endmsg;
1308 } else if (load_diskstreams_2X (*child, version)) {
1313 if ((child = find_named_node (node, "Routes")) == 0) {
1314 error << _("Session: XML state has no routes section") << endmsg;
1316 } else if (load_routes (*child, version)) {
1320 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1321 _diskstreams_2X.clear ();
1323 if (version >= 3000) {
1325 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1326 error << _("Session: XML state has no route groups section") << endmsg;
1328 } else if (load_route_groups (*child, version)) {
1332 } else if (version < 3000) {
1334 if ((child = find_named_node (node, "EditGroups")) == 0) {
1335 error << _("Session: XML state has no edit groups section") << endmsg;
1337 } else if (load_route_groups (*child, version)) {
1341 if ((child = find_named_node (node, "MixGroups")) == 0) {
1342 error << _("Session: XML state has no mix groups section") << endmsg;
1344 } else if (load_route_groups (*child, version)) {
1349 if ((child = find_named_node (node, "Click")) == 0) {
1350 warning << _("Session: XML state has no click section") << endmsg;
1351 } else if (_click_io) {
1352 _click_io->set_state (*child, version);
1355 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1356 ControlProtocolManager::instance().set_protocol_states (*child);
1359 /* here beginneth the second phase ... */
1361 StateReady (); /* EMIT SIGNAL */
1370 Session::load_routes (const XMLNode& node, int version)
1373 XMLNodeConstIterator niter;
1374 RouteList new_routes;
1376 nlist = node.children();
1380 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1382 boost::shared_ptr<Route> route;
1383 if (version < 3000) {
1384 route = XMLRouteFactory_2X (**niter, version);
1386 route = XMLRouteFactory (**niter, version);
1390 error << _("Session: cannot create Route from XML description.") << endmsg;
1394 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1396 new_routes.push_back (route);
1399 add_routes (new_routes, false);
1404 boost::shared_ptr<Route>
1405 Session::XMLRouteFactory (const XMLNode& node, int version)
1407 boost::shared_ptr<Route> ret;
1409 if (node.name() != "Route") {
1413 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1415 DataType type = DataType::AUDIO;
1416 const XMLProperty* prop = node.property("default-type");
1419 type = DataType (prop->value());
1422 assert (type != DataType::NIL);
1428 if (type == DataType::AUDIO) {
1429 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1432 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1435 if (track->init()) {
1440 if (track->set_state (node, version)) {
1445 boost_debug_shared_ptr_mark_interesting (track, "Track");
1449 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1451 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1452 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1462 boost::shared_ptr<Route>
1463 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1465 boost::shared_ptr<Route> ret;
1467 if (node.name() != "Route") {
1471 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1473 ds_prop = node.property (X_("diskstream"));
1476 cout << "ds_prop " << ds_prop << "\n";
1478 DataType type = DataType::AUDIO;
1479 const XMLProperty* prop = node.property("default-type");
1482 type = DataType (prop->value());
1485 assert (type != DataType::NIL);
1489 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1490 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1494 if (i == _diskstreams_2X.end()) {
1495 error << _("Could not find diskstream for route") << endmsg;
1496 return boost::shared_ptr<Route> ();
1501 if (type == DataType::AUDIO) {
1502 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1505 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1508 if (track->init()) {
1513 if (track->set_state (node, version)) {
1518 track->set_diskstream (*i);
1520 boost_debug_shared_ptr_mark_interesting (track, "Track");
1524 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1526 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1527 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1538 Session::load_regions (const XMLNode& node)
1541 XMLNodeConstIterator niter;
1542 boost::shared_ptr<Region> region;
1544 nlist = node.children();
1548 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1549 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1550 error << _("Session: cannot create Region from XML description.");
1551 const XMLProperty *name = (**niter).property("name");
1554 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1564 boost::shared_ptr<Region>
1565 Session::XMLRegionFactory (const XMLNode& node, bool full)
1567 const XMLProperty* type = node.property("type");
1571 if ( !type || type->value() == "audio" ) {
1573 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1575 } else if (type->value() == "midi") {
1577 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1581 } catch (failed_constructor& err) {
1582 return boost::shared_ptr<Region> ();
1585 return boost::shared_ptr<Region> ();
1588 boost::shared_ptr<AudioRegion>
1589 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1591 const XMLProperty* prop;
1592 boost::shared_ptr<Source> source;
1593 boost::shared_ptr<AudioSource> as;
1595 SourceList master_sources;
1596 uint32_t nchans = 1;
1599 if (node.name() != X_("Region")) {
1600 return boost::shared_ptr<AudioRegion>();
1603 if ((prop = node.property (X_("channels"))) != 0) {
1604 nchans = atoi (prop->value().c_str());
1607 if ((prop = node.property ("name")) == 0) {
1608 cerr << "no name for this region\n";
1612 if ((prop = node.property (X_("source-0"))) == 0) {
1613 if ((prop = node.property ("source")) == 0) {
1614 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1615 return boost::shared_ptr<AudioRegion>();
1619 PBD::ID s_id (prop->value());
1621 if ((source = source_by_id (s_id)) == 0) {
1622 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1623 return boost::shared_ptr<AudioRegion>();
1626 as = boost::dynamic_pointer_cast<AudioSource>(source);
1628 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1629 return boost::shared_ptr<AudioRegion>();
1632 sources.push_back (as);
1634 /* pickup other channels */
1636 for (uint32_t n=1; n < nchans; ++n) {
1637 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1638 if ((prop = node.property (buf)) != 0) {
1640 PBD::ID id2 (prop->value());
1642 if ((source = source_by_id (id2)) == 0) {
1643 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1644 return boost::shared_ptr<AudioRegion>();
1647 as = boost::dynamic_pointer_cast<AudioSource>(source);
1649 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1650 return boost::shared_ptr<AudioRegion>();
1652 sources.push_back (as);
1656 for (uint32_t n = 0; n < nchans; ++n) {
1657 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1658 if ((prop = node.property (buf)) != 0) {
1660 PBD::ID id2 (prop->value());
1662 if ((source = source_by_id (id2)) == 0) {
1663 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1664 return boost::shared_ptr<AudioRegion>();
1667 as = boost::dynamic_pointer_cast<AudioSource>(source);
1669 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1670 return boost::shared_ptr<AudioRegion>();
1672 master_sources.push_back (as);
1677 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1679 /* a final detail: this is the one and only place that we know how long missing files are */
1681 if (region->whole_file()) {
1682 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1683 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1685 sfp->set_length (region->length());
1690 if (!master_sources.empty()) {
1691 if (master_sources.size() != nchans) {
1692 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1694 region->set_master_sources (master_sources);
1702 catch (failed_constructor& err) {
1703 return boost::shared_ptr<AudioRegion>();
1707 boost::shared_ptr<MidiRegion>
1708 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1710 const XMLProperty* prop;
1711 boost::shared_ptr<Source> source;
1712 boost::shared_ptr<MidiSource> ms;
1714 uint32_t nchans = 1;
1716 if (node.name() != X_("Region")) {
1717 return boost::shared_ptr<MidiRegion>();
1720 if ((prop = node.property (X_("channels"))) != 0) {
1721 nchans = atoi (prop->value().c_str());
1724 if ((prop = node.property ("name")) == 0) {
1725 cerr << "no name for this region\n";
1729 // Multiple midi channels? that's just crazy talk
1730 assert(nchans == 1);
1732 if ((prop = node.property (X_("source-0"))) == 0) {
1733 if ((prop = node.property ("source")) == 0) {
1734 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1735 return boost::shared_ptr<MidiRegion>();
1739 PBD::ID s_id (prop->value());
1741 if ((source = source_by_id (s_id)) == 0) {
1742 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1743 return boost::shared_ptr<MidiRegion>();
1746 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1748 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1749 return boost::shared_ptr<MidiRegion>();
1752 sources.push_back (ms);
1755 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1756 /* a final detail: this is the one and only place that we know how long missing files are */
1758 if (region->whole_file()) {
1759 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1760 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1762 sfp->set_length (region->length());
1770 catch (failed_constructor& err) {
1771 return boost::shared_ptr<MidiRegion>();
1776 Session::get_sources_as_xml ()
1779 XMLNode* node = new XMLNode (X_("Sources"));
1780 Glib::Mutex::Lock lm (source_lock);
1782 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1783 node->add_child_nocopy (i->second->get_state());
1790 Session::path_from_region_name (DataType type, string name, string identifier)
1792 char buf[PATH_MAX+1];
1794 SessionDirectory sdir(get_best_session_directory_for_new_source());
1795 sys::path source_dir = ((type == DataType::AUDIO)
1796 ? sdir.sound_path() : sdir.midi_path());
1798 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1800 for (n = 0; n < 999999; ++n) {
1801 if (identifier.length()) {
1802 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1803 identifier.c_str(), n, ext.c_str());
1805 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1809 sys::path source_path = source_dir / buf;
1811 if (!sys::exists (source_path)) {
1812 return source_path.to_string();
1816 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1825 Session::load_sources (const XMLNode& node)
1828 XMLNodeConstIterator niter;
1829 boost::shared_ptr<Source> source;
1831 nlist = node.children();
1835 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1837 if ((source = XMLSourceFactory (**niter)) == 0) {
1838 error << _("Session: cannot create Source from XML description.") << endmsg;
1840 } catch (MissingSource& err) {
1841 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1842 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1849 boost::shared_ptr<Source>
1850 Session::XMLSourceFactory (const XMLNode& node)
1852 if (node.name() != "Source") {
1853 return boost::shared_ptr<Source>();
1857 /* note: do peak building in another thread when loading session state */
1858 return SourceFactory::create (*this, node, true);
1861 catch (failed_constructor& err) {
1862 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1863 return boost::shared_ptr<Source>();
1868 Session::save_template (string template_name)
1872 if (_state_of_the_state & CannotSave) {
1876 sys::path user_template_dir(user_template_directory());
1880 sys::create_directories (user_template_dir);
1882 catch(sys::filesystem_error& ex)
1884 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1885 user_template_dir.to_string(), ex.what()) << endmsg;
1889 tree.set_root (&get_template());
1891 sys::path template_file_path(user_template_dir);
1892 template_file_path /= template_name + template_suffix;
1894 if (sys::exists (template_file_path))
1896 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1897 template_file_path.to_string()) << endmsg;
1901 if (!tree.write (template_file_path.to_string())) {
1902 error << _("mix template not saved") << endmsg;
1910 Session::rename_template (string old_name, string new_name)
1912 sys::path old_path (user_template_directory());
1913 old_path /= old_name + template_suffix;
1915 sys::path new_path(user_template_directory());
1916 new_path /= new_name + template_suffix;
1918 if (sys::exists (new_path)) {
1919 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1920 new_path.to_string()) << endmsg;
1925 sys::rename (old_path, new_path);
1933 Session::delete_template (string name)
1935 sys::path path = user_template_directory();
1936 path /= name + template_suffix;
1947 Session::refresh_disk_space ()
1950 struct statfs statfsbuf;
1951 vector<space_and_path>::iterator i;
1952 Glib::Mutex::Lock lm (space_lock);
1955 /* get freespace on every FS that is part of the session path */
1957 _total_free_4k_blocks = 0;
1959 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1960 statfs ((*i).path.c_str(), &statfsbuf);
1962 scale = statfsbuf.f_bsize/4096.0;
1964 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1965 _total_free_4k_blocks += (*i).blocks;
1971 Session::get_best_session_directory_for_new_source ()
1973 vector<space_and_path>::iterator i;
1974 string result = _session_dir->root_path().to_string();
1976 /* handle common case without system calls */
1978 if (session_dirs.size() == 1) {
1982 /* OK, here's the algorithm we're following here:
1984 We want to select which directory to use for
1985 the next file source to be created. Ideally,
1986 we'd like to use a round-robin process so as to
1987 get maximum performance benefits from splitting
1988 the files across multiple disks.
1990 However, in situations without much diskspace, an
1991 RR approach may end up filling up a filesystem
1992 with new files while others still have space.
1993 Its therefore important to pay some attention to
1994 the freespace in the filesystem holding each
1995 directory as well. However, if we did that by
1996 itself, we'd keep creating new files in the file
1997 system with the most space until it was as full
1998 as all others, thus negating any performance
1999 benefits of this RAID-1 like approach.
2001 So, we use a user-configurable space threshold. If
2002 there are at least 2 filesystems with more than this
2003 much space available, we use RR selection between them.
2004 If not, then we pick the filesystem with the most space.
2006 This gets a good balance between the two
2010 refresh_disk_space ();
2012 int free_enough = 0;
2014 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2015 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2020 if (free_enough >= 2) {
2021 /* use RR selection process, ensuring that the one
2025 i = last_rr_session_dir;
2028 if (++i == session_dirs.end()) {
2029 i = session_dirs.begin();
2032 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2033 if (create_session_directory ((*i).path)) {
2035 last_rr_session_dir = i;
2040 } while (i != last_rr_session_dir);
2044 /* pick FS with the most freespace (and that
2045 seems to actually work ...)
2048 vector<space_and_path> sorted;
2049 space_and_path_ascending_cmp cmp;
2051 sorted = session_dirs;
2052 sort (sorted.begin(), sorted.end(), cmp);
2054 for (i = sorted.begin(); i != sorted.end(); ++i) {
2055 if (create_session_directory ((*i).path)) {
2057 last_rr_session_dir = i;
2067 Session::load_named_selections (const XMLNode& node)
2070 XMLNodeConstIterator niter;
2073 nlist = node.children();
2077 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2079 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2080 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2088 Session::XMLNamedSelectionFactory (const XMLNode& node)
2091 return new NamedSelection (*this, node);
2094 catch (failed_constructor& err) {
2100 Session::automation_dir () const
2102 return Glib::build_filename (_path, "automation");
2106 Session::analysis_dir () const
2108 return Glib::build_filename (_path, "analysis");
2112 Session::load_bundles (XMLNode const & node)
2114 XMLNodeList nlist = node.children();
2115 XMLNodeConstIterator niter;
2119 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2120 if ((*niter)->name() == "InputBundle") {
2121 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2122 } else if ((*niter)->name() == "OutputBundle") {
2123 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2125 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2134 Session::load_route_groups (const XMLNode& node, int version)
2136 XMLNodeList nlist = node.children();
2137 XMLNodeConstIterator niter;
2141 if (version >= 3000) {
2143 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2144 if ((*niter)->name() == "RouteGroup") {
2145 RouteGroup* rg = new RouteGroup (*this, "");
2146 add_route_group (rg);
2147 rg->set_state (**niter, version);
2151 } else if (version < 3000) {
2153 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2154 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2155 RouteGroup* rg = new RouteGroup (*this, "");
2156 add_route_group (rg);
2157 rg->set_state (**niter, version);
2166 Session::auto_save()
2168 save_state (_current_snapshot_name);
2172 state_file_filter (const string &str, void */*arg*/)
2174 return (str.length() > strlen(statefile_suffix) &&
2175 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2179 bool operator()(const string* a, const string* b) {
2185 remove_end(string* state)
2187 string statename(*state);
2189 string::size_type start,end;
2190 if ((start = statename.find_last_of ('/')) != string::npos) {
2191 statename = statename.substr (start+1);
2194 if ((end = statename.rfind(".ardour")) == string::npos) {
2195 end = statename.length();
2198 return new string(statename.substr (0, end));
2202 Session::possible_states (string path)
2204 PathScanner scanner;
2205 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2207 transform(states->begin(), states->end(), states->begin(), remove_end);
2210 sort (states->begin(), states->end(), cmp);
2216 Session::possible_states () const
2218 return possible_states(_path);
2222 Session::add_route_group (RouteGroup* g)
2224 _route_groups.push_back (g);
2225 route_group_added (g); /* EMIT SIGNAL */
2230 Session::remove_route_group (RouteGroup& rg)
2232 list<RouteGroup*>::iterator i;
2234 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2235 _route_groups.erase (i);
2238 route_group_removed (); /* EMIT SIGNAL */
2244 Session::route_group_by_name (string name)
2246 list<RouteGroup *>::iterator i;
2248 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2249 if ((*i)->name() == name) {
2257 Session::start_reversible_command (const string& name)
2259 UndoTransaction* trans = new UndoTransaction();
2260 trans->set_name(name);
2265 Session::finish_reversible_command (UndoTransaction& ut)
2268 gettimeofday(&now, 0);
2269 ut.set_timestamp(now);
2274 Session::begin_reversible_command(const string& name)
2276 UndoTransaction* trans = new UndoTransaction();
2277 trans->set_name(name);
2279 if (!_current_trans.empty()) {
2280 _current_trans.top()->add_command (trans);
2282 _current_trans.push(trans);
2287 Session::commit_reversible_command(Command *cmd)
2289 assert(!_current_trans.empty());
2293 _current_trans.top()->add_command(cmd);
2296 if (_current_trans.top()->empty()) {
2297 _current_trans.pop();
2301 gettimeofday(&now, 0);
2302 _current_trans.top()->set_timestamp(now);
2304 _history.add(_current_trans.top());
2305 _current_trans.pop();
2309 accept_all_non_peak_files (const string& path, void */*arg*/)
2311 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2315 accept_all_state_files (const string& path, void */*arg*/)
2317 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2321 Session::find_all_sources (string path, set<string>& result)
2326 if (!tree.read (path)) {
2330 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2335 XMLNodeConstIterator niter;
2337 nlist = node->children();
2341 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2345 if ((prop = (*niter)->property (X_("type"))) == 0) {
2349 DataType type (prop->value());
2351 if ((prop = (*niter)->property (X_("name"))) == 0) {
2355 if (prop->value()[0] == '/') {
2356 /* external file, ignore */
2360 Glib::ustring found_path;
2364 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2365 result.insert (found_path);
2373 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2375 PathScanner scanner;
2376 vector<string*>* state_files;
2378 string this_snapshot_path;
2384 if (ripped[ripped.length()-1] == '/') {
2385 ripped = ripped.substr (0, ripped.length() - 1);
2388 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2390 if (state_files == 0) {
2395 this_snapshot_path = _path;
2396 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2397 this_snapshot_path += statefile_suffix;
2399 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2401 if (exclude_this_snapshot && **i == this_snapshot_path) {
2405 if (find_all_sources (**i, result) < 0) {
2413 struct RegionCounter {
2414 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2415 AudioSourceList::iterator iter;
2416 boost::shared_ptr<Region> region;
2419 RegionCounter() : count (0) {}
2423 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2425 return *AskAboutPlaylistDeletion (p);
2429 Session::cleanup_sources (CleanupReport& rep)
2431 // FIXME: needs adaptation to midi
2433 vector<boost::shared_ptr<Source> > dead_sources;
2434 PathScanner scanner;
2436 vector<space_and_path>::iterator i;
2437 vector<space_and_path>::iterator nexti;
2438 vector<string*>* soundfiles;
2439 vector<string> unused;
2440 set<string> all_sources;
2445 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2447 /* step 1: consider deleting all unused playlists */
2449 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2454 /* step 2: find all un-used sources */
2459 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2461 SourceMap::iterator tmp;
2466 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2470 if (!playlists->source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2471 dead_sources.push_back (i->second);
2472 i->second->drop_references ();
2478 /* build a list of all the possible sound directories for the session */
2480 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2485 SessionDirectory sdir ((*i).path);
2486 sound_path += sdir.sound_path().to_string();
2488 if (nexti != session_dirs.end()) {
2495 /* now do the same thing for the files that ended up in the sounds dir(s)
2496 but are not referenced as sources in any snapshot.
2499 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2501 if (soundfiles == 0) {
2505 /* find all sources, but don't use this snapshot because the
2506 state file on disk still references sources we may have already
2510 find_all_sources_across_snapshots (all_sources, true);
2512 /* add our current source list
2515 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2516 boost::shared_ptr<FileSource> fs;
2518 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2519 all_sources.insert (fs->path());
2523 char tmppath1[PATH_MAX+1];
2524 char tmppath2[PATH_MAX+1];
2526 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2531 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2533 realpath(spath.c_str(), tmppath1);
2534 realpath((*i).c_str(), tmppath2);
2536 if (strcmp(tmppath1, tmppath2) == 0) {
2543 unused.push_back (spath);
2547 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2549 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2550 struct stat statbuf;
2552 rep.paths.push_back (*x);
2553 if (stat ((*x).c_str(), &statbuf) == 0) {
2554 rep.space += statbuf.st_size;
2559 /* don't move the file across filesystems, just
2560 stick it in the `dead_sound_dir_name' directory
2561 on whichever filesystem it was already on.
2564 if ((*x).find ("/sounds/") != string::npos) {
2566 /* old school, go up 1 level */
2568 newpath = Glib::path_get_dirname (*x); // "sounds"
2569 newpath = Glib::path_get_dirname (newpath); // "session-name"
2573 /* new school, go up 4 levels */
2575 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2576 newpath = Glib::path_get_dirname (newpath); // "session-name"
2577 newpath = Glib::path_get_dirname (newpath); // "interchange"
2578 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2582 newpath += dead_sound_dir_name;
2584 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2585 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2590 newpath += Glib::path_get_basename ((*x));
2592 if (access (newpath.c_str(), F_OK) == 0) {
2594 /* the new path already exists, try versioning */
2596 char buf[PATH_MAX+1];
2600 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2603 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2604 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2608 if (version == 999) {
2609 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2613 newpath = newpath_v;
2618 /* it doesn't exist, or we can't read it or something */
2622 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2623 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2624 (*x), newpath, strerror (errno))
2629 /* see if there an easy to find peakfile for this file, and remove it.
2632 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2633 peakpath += peakfile_suffix;
2635 if (access (peakpath.c_str(), W_OK) == 0) {
2636 if (::unlink (peakpath.c_str()) != 0) {
2637 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2638 peakpath, _path, strerror (errno))
2640 /* try to back out */
2641 rename (newpath.c_str(), _path.c_str());
2649 /* dump the history list */
2653 /* save state so we don't end up a session file
2654 referring to non-existent sources.
2660 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2666 Session::cleanup_trash_sources (CleanupReport& rep)
2668 // FIXME: needs adaptation for MIDI
2670 vector<space_and_path>::iterator i;
2671 string dead_sound_dir;
2672 struct dirent* dentry;
2673 struct stat statbuf;
2679 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2681 dead_sound_dir = (*i).path;
2682 dead_sound_dir += dead_sound_dir_name;
2684 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2688 while ((dentry = readdir (dead)) != 0) {
2690 /* avoid '.' and '..' */
2692 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2693 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2699 fullpath = dead_sound_dir;
2701 fullpath += dentry->d_name;
2703 if (stat (fullpath.c_str(), &statbuf)) {
2707 if (!S_ISREG (statbuf.st_mode)) {
2711 if (unlink (fullpath.c_str())) {
2712 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2713 fullpath, strerror (errno))
2717 rep.paths.push_back (dentry->d_name);
2718 rep.space += statbuf.st_size;
2729 Session::set_dirty ()
2731 bool was_dirty = dirty();
2733 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2737 DirtyChanged(); /* EMIT SIGNAL */
2743 Session::set_clean ()
2745 bool was_dirty = dirty();
2747 _state_of_the_state = Clean;
2751 DirtyChanged(); /* EMIT SIGNAL */
2756 Session::set_deletion_in_progress ()
2758 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2762 Session::clear_deletion_in_progress ()
2764 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2768 Session::add_controllable (boost::shared_ptr<Controllable> c)
2770 /* this adds a controllable to the list managed by the Session.
2771 this is a subset of those managed by the Controllable class
2772 itself, and represents the only ones whose state will be saved
2773 as part of the session.
2776 Glib::Mutex::Lock lm (controllables_lock);
2777 controllables.insert (c);
2780 struct null_deleter { void operator()(void const *) const {} };
2783 Session::remove_controllable (Controllable* c)
2785 if (_state_of_the_state | Deletion) {
2789 Glib::Mutex::Lock lm (controllables_lock);
2791 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2793 if (x != controllables.end()) {
2794 controllables.erase (x);
2798 boost::shared_ptr<Controllable>
2799 Session::controllable_by_id (const PBD::ID& id)
2801 Glib::Mutex::Lock lm (controllables_lock);
2803 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2804 if ((*i)->id() == id) {
2809 return boost::shared_ptr<Controllable>();
2812 boost::shared_ptr<Controllable>
2813 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2815 boost::shared_ptr<Controllable> c;
2816 boost::shared_ptr<Route> r;
2818 switch (desc.top_level_type()) {
2819 case ControllableDescriptor::NamedRoute:
2821 std::string str = desc.top_level_name();
2822 if (str == "master") {
2824 } else if (str == "control" || str == "listen") {
2827 r = route_by_name (desc.top_level_name());
2832 case ControllableDescriptor::RemoteControlID:
2833 r = route_by_remote_id (desc.rid());
2841 switch (desc.subtype()) {
2842 case ControllableDescriptor::Gain:
2843 c = r->gain_control ();
2846 case ControllableDescriptor::Solo:
2847 c = r->solo_control();
2850 case ControllableDescriptor::Mute:
2851 c = r->mute_control();
2854 case ControllableDescriptor::Recenable:
2856 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2859 c = t->rec_enable_control ();
2864 case ControllableDescriptor::Pan:
2865 /* XXX pan control */
2868 case ControllableDescriptor::Balance:
2869 /* XXX simple pan control */
2872 case ControllableDescriptor::PluginParameter:
2874 uint32_t plugin = desc.target (0);
2875 uint32_t parameter_index = desc.target (1);
2877 /* revert to zero based counting */
2883 if (parameter_index > 0) {
2887 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2890 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2891 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2896 case ControllableDescriptor::SendGain:
2898 uint32_t send = desc.target (0);
2900 /* revert to zero-based counting */
2906 boost::shared_ptr<Processor> p = r->nth_send (send);
2909 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2910 boost::shared_ptr<Amp> a = s->amp();
2913 c = s->amp()->gain_control();
2920 /* relax and return a null pointer */
2928 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2931 Stateful::add_instant_xml (node, _path);
2934 if (write_to_config) {
2935 Config->add_instant_xml (node);
2940 Session::instant_xml (const string& node_name)
2942 return Stateful::instant_xml (node_name, _path);
2946 Session::save_history (string snapshot_name)
2954 if (snapshot_name.empty()) {
2955 snapshot_name = _current_snapshot_name;
2958 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2959 const string backup_filename = history_filename + backup_suffix;
2960 const sys::path xml_path = _session_dir->root_path() / history_filename;
2961 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2963 if (sys::exists (xml_path)) {
2966 sys::rename (xml_path, backup_path);
2968 catch (const sys::filesystem_error& err)
2970 error << _("could not backup old history file, current history not saved") << endmsg;
2975 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2979 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2981 if (!tree.write (xml_path.to_string()))
2983 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2987 sys::remove (xml_path);
2988 sys::rename (backup_path, xml_path);
2990 catch (const sys::filesystem_error& err)
2992 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2993 backup_path.to_string(), err.what()) << endmsg;
3003 Session::restore_history (string snapshot_name)
3007 if (snapshot_name.empty()) {
3008 snapshot_name = _current_snapshot_name;
3011 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3012 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3014 info << "Loading history from " << xml_path.to_string() << endmsg;
3016 if (!sys::exists (xml_path)) {
3017 info << string_compose (_("%1: no history file \"%2\" for this session."),
3018 _name, xml_path.to_string()) << endmsg;
3022 if (!tree.read (xml_path.to_string())) {
3023 error << string_compose (_("Could not understand session history file \"%1\""),
3024 xml_path.to_string()) << endmsg;
3031 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3034 UndoTransaction* ut = new UndoTransaction ();
3037 ut->set_name(t->property("name")->value());
3038 stringstream ss(t->property("tv-sec")->value());
3040 ss.str(t->property("tv-usec")->value());
3042 ut->set_timestamp(tv);
3044 for (XMLNodeConstIterator child_it = t->children().begin();
3045 child_it != t->children().end(); child_it++)
3047 XMLNode *n = *child_it;
3050 if (n->name() == "MementoCommand" ||
3051 n->name() == "MementoUndoCommand" ||
3052 n->name() == "MementoRedoCommand") {
3054 if ((c = memento_command_factory(n))) {
3058 } else if (n->name() == "DeltaCommand") {
3059 PBD::ID id(n->property("midi-source")->value());
3060 boost::shared_ptr<MidiSource> midi_source =
3061 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3063 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3065 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3068 } else if (n->name() == "DiffCommand") {
3069 PBD::ID id(n->property("midi-source")->value());
3070 boost::shared_ptr<MidiSource> midi_source =
3071 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3073 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3075 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3078 } else if (n->name() == "StatefulDiffCommand") {
3079 if ((c = stateful_diff_command_factory (n))) {
3080 ut->add_command (c);
3083 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3094 Session::config_changed (std::string p, bool ours)
3100 if (p == "seamless-loop") {
3102 } else if (p == "rf-speed") {
3104 } else if (p == "auto-loop") {
3106 } else if (p == "auto-input") {
3108 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3109 /* auto-input only makes a difference if we're rolling */
3111 boost::shared_ptr<RouteList> rl = routes.reader ();
3112 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3113 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3114 if (tr && tr->record_enabled ()) {
3115 tr->monitor_input (!config.get_auto_input());
3120 } else if (p == "punch-in") {
3124 if ((location = _locations.auto_punch_location()) != 0) {
3126 if (config.get_punch_in ()) {
3127 replace_event (SessionEvent::PunchIn, location->start());
3129 remove_event (location->start(), SessionEvent::PunchIn);
3133 } else if (p == "punch-out") {
3137 if ((location = _locations.auto_punch_location()) != 0) {
3139 if (config.get_punch_out()) {
3140 replace_event (SessionEvent::PunchOut, location->end());
3142 clear_events (SessionEvent::PunchOut);
3146 } else if (p == "edit-mode") {
3148 Glib::Mutex::Lock lm (playlists->lock);
3150 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3151 (*i)->set_edit_mode (Config->get_edit_mode ());
3154 } else if (p == "use-video-sync") {
3156 waiting_for_sync_offset = config.get_use_video_sync();
3158 } else if (p == "mmc-control") {
3160 //poke_midi_thread ();
3162 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3165 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3168 } else if (p == "mmc-send-id") {
3171 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3174 } else if (p == "midi-control") {
3176 //poke_midi_thread ();
3178 } else if (p == "raid-path") {
3180 setup_raid_path (config.get_raid_path());
3182 } else if (p == "timecode-format") {
3186 } else if (p == "video-pullup") {
3190 } else if (p == "seamless-loop") {
3192 if (play_loop && transport_rolling()) {
3193 // to reset diskstreams etc
3194 request_play_loop (true);
3197 } else if (p == "rf-speed") {
3199 cumulative_rf_motion = 0;
3202 } else if (p == "click-sound") {
3204 setup_click_sounds (1);
3206 } else if (p == "click-emphasis-sound") {
3208 setup_click_sounds (-1);
3210 } else if (p == "clicking") {
3212 if (Config->get_clicking()) {
3213 if (_click_io && click_data) { // don't require emphasis data
3220 } else if (p == "send-mtc") {
3222 /* only set the internal flag if we have
3226 if (_mtc_port != 0) {
3227 session_send_mtc = Config->get_send_mtc();
3228 if (session_send_mtc) {
3229 /* mark us ready to send */
3230 next_quarter_frame_to_send = 0;
3233 session_send_mtc = false;
3236 } else if (p == "send-mmc") {
3238 /* only set the internal flag if we have
3242 if (_mmc_port != 0) {
3243 session_send_mmc = Config->get_send_mmc();
3246 session_send_mmc = false;
3249 } else if (p == "midi-feedback") {
3251 /* only set the internal flag if we have
3255 if (_mtc_port != 0) {
3256 session_midi_feedback = Config->get_midi_feedback();
3259 } else if (p == "jack-time-master") {
3261 engine().reset_timebase ();
3263 } else if (p == "native-file-header-format") {
3265 if (!first_file_header_format_reset) {
3266 reset_native_file_format ();
3269 first_file_header_format_reset = false;
3271 } else if (p == "native-file-data-format") {
3273 if (!first_file_data_format_reset) {
3274 reset_native_file_format ();
3277 first_file_data_format_reset = false;
3279 } else if (p == "external-sync") {
3280 if (!config.get_external_sync()) {
3281 drop_sync_source ();
3283 switch_to_sync_source (config.get_sync_source());
3285 } else if (p == "remote-model") {
3286 set_remote_control_ids ();
3287 } else if (p == "denormal-model") {
3289 } else if (p == "history-depth") {
3290 set_history_depth (Config->get_history_depth());
3291 } else if (p == "sync-all-route-ordering") {
3292 sync_order_keys ("session");
3293 } else if (p == "initial-program-change") {
3295 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3298 buf[0] = MIDI::program; // channel zero by default
3299 buf[1] = (Config->get_initial_program_change() & 0x7f);
3301 _mmc_port->midimsg (buf, sizeof (buf), 0);
3303 } else if (p == "initial-program-change") {
3305 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3306 MIDI::byte* buf = new MIDI::byte[2];
3308 buf[0] = MIDI::program; // channel zero by default
3309 buf[1] = (Config->get_initial_program_change() & 0x7f);
3310 // deliver_midi (_mmc_port, buf, 2);
3312 } else if (p == "solo-mute-override") {
3313 // catch_up_on_solo_mute_override ();
3314 } else if (p == "listen-position") {
3315 listen_position_changed ();
3316 } else if (p == "solo-control-is-listen-control") {
3317 solo_control_mode_changed ();
3325 Session::set_history_depth (uint32_t d)
3327 _history.set_depth (d);
3331 Session::load_diskstreams_2X (XMLNode const & node, int)
3334 XMLNodeConstIterator citer;
3336 clist = node.children();
3338 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3341 /* diskstreams added automatically by DiskstreamCreated handler */
3342 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3343 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3344 _diskstreams_2X.push_back (dsp);
3346 error << _("Session: unknown diskstream type in XML") << endmsg;
3350 catch (failed_constructor& err) {
3351 error << _("Session: could not load diskstream via XML state") << endmsg;