2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libardour-config.h"
25 #define __STDC_FORMAT_MACROS 1
34 #include <cstdio> /* snprintf(3) ... grrr */
49 #include <sys/param.h>
50 #include <sys/mount.h>
54 #include <glibmm/thread.h>
56 #include "midi++/mmc.h"
57 #include "midi++/port.h"
59 #include "pbd/boost_debug.h"
60 #include "pbd/controllable_descriptor.h"
61 #include "pbd/enumwriter.h"
62 #include "pbd/error.h"
63 #include "pbd/pathscanner.h"
64 #include "pbd/pthread_utils.h"
65 #include "pbd/search_path.h"
66 #include "pbd/stacktrace.h"
67 #include "pbd/convert.h"
69 #include "ardour/amp.h"
70 #include "ardour/audio_diskstream.h"
71 #include "ardour/audio_track.h"
72 #include "ardour/audioengine.h"
73 #include "ardour/audiofilesource.h"
74 #include "ardour/audioplaylist.h"
75 #include "ardour/audioregion.h"
76 #include "ardour/auditioner.h"
77 #include "ardour/buffer.h"
78 #include "ardour/butler.h"
79 #include "ardour/configuration.h"
80 #include "ardour/control_protocol_manager.h"
81 #include "ardour/crossfade.h"
82 #include "ardour/cycle_timer.h"
83 #include "ardour/directory_names.h"
84 #include "ardour/filename_extensions.h"
85 #include "ardour/io_processor.h"
86 #include "ardour/location.h"
87 #include "ardour/midi_diskstream.h"
88 #include "ardour/midi_patch_manager.h"
89 #include "ardour/midi_playlist.h"
90 #include "ardour/midi_region.h"
91 #include "ardour/midi_source.h"
92 #include "ardour/midi_track.h"
93 #include "ardour/named_selection.h"
94 #include "ardour/processor.h"
95 #include "ardour/region_factory.h"
96 #include "ardour/route_group.h"
97 #include "ardour/send.h"
98 #include "ardour/session.h"
99 #include "ardour/session_directory.h"
100 #include "ardour/session_metadata.h"
101 #include "ardour/session_state_utils.h"
102 #include "ardour/session_playlists.h"
103 #include "ardour/session_utils.h"
104 #include "ardour/silentfilesource.h"
105 #include "ardour/slave.h"
106 #include "ardour/smf_source.h"
107 #include "ardour/sndfile_helpers.h"
108 #include "ardour/sndfilesource.h"
109 #include "ardour/source_factory.h"
110 #include "ardour/template_utils.h"
111 #include "ardour/tempo.h"
112 #include "ardour/ticker.h"
113 #include "ardour/user_bundle.h"
114 #include "ardour/utils.h"
115 #include "ardour/utils.h"
116 #include "ardour/version.h"
117 #include "ardour/playlist_factory.h"
119 #include "control_protocol/control_protocol.h"
125 using namespace ARDOUR;
129 Session::first_stage_init (string fullpath, string snapshot_name)
131 if (fullpath.length() == 0) {
133 throw failed_constructor();
136 char buf[PATH_MAX+1];
137 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
138 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
140 throw failed_constructor();
145 if (_path[_path.length()-1] != '/') {
149 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
155 /* these two are just provisional settings. set_state()
156 will likely override them.
159 _name = _current_snapshot_name = snapshot_name;
161 set_history_depth (Config->get_history_depth());
163 _current_frame_rate = _engine.frame_rate ();
164 _nominal_frame_rate = _current_frame_rate;
165 _base_frame_rate = _current_frame_rate;
167 _tempo_map = new TempoMap (_current_frame_rate);
168 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
171 _non_soloed_outs_muted = false;
173 _solo_isolated_cnt = 0;
174 g_atomic_int_set (&processing_prohibited, 0);
175 _transport_speed = 0;
176 _last_transport_speed = 0;
177 _target_transport_speed = 0;
178 auto_play_legal = false;
179 transport_sub_state = 0;
180 _transport_frame = 0;
181 _requested_return_frame = -1;
182 _session_range_location = new Location (0, 0, _("session"), Location::IsSessionRange);
183 g_atomic_int_set (&_record_status, Disabled);
184 loop_changing = false;
187 _last_roll_location = 0;
188 _last_roll_or_reversal_location = 0;
189 _last_record_location = 0;
190 pending_locate_frame = 0;
191 pending_locate_roll = false;
192 pending_locate_flush = false;
193 state_was_pending = false;
195 outbound_mtc_timecode_frame = 0;
196 next_quarter_frame_to_send = -1;
197 current_block_size = 0;
198 solo_update_disabled = false;
199 _have_captured = false;
200 _worst_output_latency = 0;
201 _worst_input_latency = 0;
202 _worst_track_latency = 0;
203 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
204 _was_seamless = Config->get_seamless_loop ();
206 session_send_mmc = false;
207 session_send_mtc = false;
208 g_atomic_int_set (&_playback_load, 100);
209 g_atomic_int_set (&_capture_load, 100);
210 g_atomic_int_set (&_playback_load_min, 100);
211 g_atomic_int_set (&_capture_load_min, 100);
214 pending_abort = false;
215 destructive_index = 0;
216 first_file_data_format_reset = true;
217 first_file_header_format_reset = true;
218 post_export_sync = false;
221 AudioDiskstream::allocate_working_buffers();
223 /* default short fade = 15ms */
225 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
226 SndFileSource::setup_standard_crossfades (*this, frame_rate());
228 last_mmc_step.tv_sec = 0;
229 last_mmc_step.tv_usec = 0;
232 /* click sounds are unset by default, which causes us to internal
233 waveforms for clicks.
237 click_emphasis_length = 0;
240 process_function = &Session::process_with_events;
242 if (config.get_use_video_sync()) {
243 waiting_for_sync_offset = true;
245 waiting_for_sync_offset = false;
248 last_timecode_when = 0;
249 _timecode_offset = 0;
250 _timecode_offset_negative = true;
251 last_timecode_valid = false;
255 last_rr_session_dir = session_dirs.begin();
256 refresh_disk_space ();
258 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
262 average_slave_delta = 1800; // !!! why 1800 ????
263 have_first_delta_accumulator = false;
264 delta_accumulator_cnt = 0;
265 _slave_state = Stopped;
267 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
269 /* These are all static "per-class" signals */
271 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
272 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
273 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
274 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
275 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
277 /* stop IO objects from doing stuff until we're ready for them */
279 Delivery::disable_panners ();
280 IO::disable_connecting ();
284 Session::second_stage_init ()
286 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
289 if (load_state (_current_snapshot_name)) {
292 remove_empty_sounds ();
295 if (_butler->start_thread()) {
299 if (start_midi_thread ()) {
303 // set_state() will call setup_raid_path(), but if it's a new session we need
304 // to call setup_raid_path() here.
307 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
311 setup_raid_path(_path);
314 /* we can't save till after ::when_engine_running() is called,
315 because otherwise we save state with no connections made.
316 therefore, we reset _state_of_the_state because ::set_state()
317 will have cleared it.
319 we also have to include Loading so that any events that get
320 generated between here and the end of ::when_engine_running()
321 will be processed directly rather than queued.
324 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
327 _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
328 _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
329 setup_click_sounds (0);
330 setup_midi_control ();
332 /* Pay attention ... */
334 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
335 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
338 when_engine_running ();
341 /* handle this one in a different way than all others, so that its clear what happened */
343 catch (AudioEngine::PortRegistrationFailure& err) {
344 error << err.what() << endmsg;
352 BootMessage (_("Reset Remote Controls"));
354 send_full_time_code (0);
355 _engine.transport_locate (0);
356 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
357 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
359 MidiClockTicker::instance().set_session (this);
360 MIDI::Name::MidiPatchManager::instance().set_session (this);
362 /* initial program change will be delivered later; see ::config_changed() */
364 BootMessage (_("Reset Control Protocols"));
366 ControlProtocolManager::instance().set_session (this);
368 config.set_end_marker_is_free (_is_new);
370 _state_of_the_state = Clean;
372 DirtyChanged (); /* EMIT SIGNAL */
374 if (state_was_pending) {
375 save_state (_current_snapshot_name);
376 remove_pending_capture_state ();
377 state_was_pending = false;
380 BootMessage (_("Session loading complete"));
386 Session::raid_path () const
388 SearchPath raid_search_path;
390 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
391 raid_search_path += sys::path((*i).path);
394 return raid_search_path.to_string ();
398 Session::setup_raid_path (string path)
407 session_dirs.clear ();
409 SearchPath search_path(path);
410 SearchPath sound_search_path;
411 SearchPath midi_search_path;
413 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
414 sp.path = (*i).to_string ();
415 sp.blocks = 0; // not needed
416 session_dirs.push_back (sp);
418 SessionDirectory sdir(sp.path);
420 sound_search_path += sdir.sound_path ();
421 midi_search_path += sdir.midi_path ();
424 // set the search path for each data type
425 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
426 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
428 // reset the round-robin soundfile path thingie
429 last_rr_session_dir = session_dirs.begin();
433 Session::path_is_within_session (const std::string& path)
435 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
436 if (path.find ((*i).path) == 0) {
444 Session::ensure_subdirs ()
448 dir = session_directory().peak_path().to_string();
450 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
451 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
455 dir = session_directory().sound_path().to_string();
457 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
458 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
462 dir = session_directory().midi_path().to_string();
464 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
465 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
469 dir = session_directory().dead_sound_path().to_string();
471 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
472 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
476 dir = session_directory().export_path().to_string();
478 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
479 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483 dir = analysis_dir ();
485 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
486 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
494 Session::create (const string& mix_template, nframes_t initial_length, BusProfile* bus_profile)
497 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
498 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
502 if (ensure_subdirs ()) {
506 if (!mix_template.empty()) {
507 std::string in_path = mix_template;
509 ifstream in(in_path.c_str());
512 string out_path = _path;
514 out_path += statefile_suffix;
516 ofstream out(out_path.c_str());
524 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
530 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
537 /* Instantiate metadata */
539 _metadata = new SessionMetadata ();
541 /* set initial start + end point */
543 _session_range_location->set (0, initial_length);
544 _locations.add (_session_range_location);
546 _state_of_the_state = Clean;
548 /* set up Master Out and Control Out if necessary */
554 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
556 if (bus_profile->master_out_channels) {
557 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
562 boost_debug_shared_ptr_mark_interesting (rt, "Route");
563 boost::shared_ptr<Route> r (rt);
564 r->input()->ensure_io (count, false, this);
565 r->output()->ensure_io (count, false, this);
566 r->set_remote_control_id (control_id++);
570 if (Config->get_use_monitor_bus()) {
571 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
576 boost_debug_shared_ptr_mark_interesting (rt, "Route");
577 boost::shared_ptr<Route> r (rt);
578 r->input()->ensure_io (count, false, this);
579 r->output()->ensure_io (count, false, this);
580 r->set_remote_control_id (control_id);
586 /* prohibit auto-connect to master, because there isn't one */
587 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
591 add_routes (rl, false);
594 /* this allows the user to override settings with an environment variable.
597 if (no_auto_connect()) {
598 bus_profile->input_ac = AutoConnectOption (0);
599 bus_profile->output_ac = AutoConnectOption (0);
602 Config->set_input_auto_connect (bus_profile->input_ac);
603 Config->set_output_auto_connect (bus_profile->output_ac);
612 Session::maybe_write_autosave()
614 if (dirty() && record_status() != Recording) {
615 save_state("", true);
620 Session::remove_pending_capture_state ()
622 sys::path pending_state_file_path(_session_dir->root_path());
624 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
628 sys::remove (pending_state_file_path);
630 catch(sys::filesystem_error& ex)
632 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
633 pending_state_file_path.to_string(), ex.what()) << endmsg;
637 /** Rename a state file.
638 * @param snapshot_name Snapshot name.
641 Session::rename_state (string old_name, string new_name)
643 if (old_name == _current_snapshot_name || old_name == _name) {
644 /* refuse to rename the current snapshot or the "main" one */
648 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
649 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
651 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
652 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
656 sys::rename (old_xml_path, new_xml_path);
658 catch (const sys::filesystem_error& err)
660 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
661 old_name, new_name, err.what()) << endmsg;
665 /** Remove a state file.
666 * @param snapshot_name Snapshot name.
669 Session::remove_state (string snapshot_name)
671 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
672 // refuse to remove the current snapshot or the "main" one
676 sys::path xml_path(_session_dir->root_path());
678 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
680 if (!create_backup_file (xml_path)) {
681 // don't remove it if a backup can't be made
682 // create_backup_file will log the error.
687 sys::remove (xml_path);
690 #ifdef HAVE_JACK_SESSION
692 Session::jack_session_event (jack_session_event_t * event)
694 if (save_state ("jacksession_snap")) {
695 event->flags = JackSessionSaveError;
697 sys::path xml_path (_session_dir->root_path());
698 xml_path /= legalize_for_path ("jacksession_snap") + statefile_suffix;
700 string cmd ("PROG_NAME -U ");
701 cmd += event->client_uuid;
703 cmd += xml_path.to_string();
706 event->command_line = strdup (cmd.c_str());
709 jack_session_reply (_engine.jack(), event);
711 if (event->type == JackSessionSaveAndQuit) {
712 // TODO: make ardour quit.
715 jack_session_event_free( event );
720 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
723 sys::path xml_path(_session_dir->root_path());
725 if (!_writable || (_state_of_the_state & CannotSave)) {
729 if (!_engine.connected ()) {
730 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
736 /* tell sources we're saving first, in case they write out to a new file
737 * which should be saved with the state rather than the old one */
738 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
739 i->second->session_saved();
741 tree.set_root (&get_state());
743 if (snapshot_name.empty()) {
744 snapshot_name = _current_snapshot_name;
745 } else if (switch_to_snapshot) {
746 _current_snapshot_name = snapshot_name;
751 /* proper save: use statefile_suffix (.ardour in English) */
753 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
755 /* make a backup copy of the old file */
757 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
758 // create_backup_file will log the error
764 /* pending save: use pending_suffix (.pending in English) */
765 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
768 sys::path tmp_path(_session_dir->root_path());
770 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
772 // cerr << "actually writing state to " << xml_path.to_string() << endl;
774 if (!tree.write (tmp_path.to_string())) {
775 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
776 sys::remove (tmp_path);
781 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
782 error << string_compose (_("could not rename temporary session file %1 to %2"),
783 tmp_path.to_string(), xml_path.to_string()) << endmsg;
784 sys::remove (tmp_path);
791 save_history (snapshot_name);
793 bool was_dirty = dirty();
795 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
798 DirtyChanged (); /* EMIT SIGNAL */
801 StateSaved (snapshot_name); /* EMIT SIGNAL */
808 Session::restore_state (string snapshot_name)
810 if (load_state (snapshot_name) == 0) {
811 set_state (*state_tree->root(), Stateful::loading_state_version);
818 Session::load_state (string snapshot_name)
823 state_was_pending = false;
825 /* check for leftover pending state from a crashed capture attempt */
827 sys::path xmlpath(_session_dir->root_path());
828 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
830 if (sys::exists (xmlpath)) {
832 /* there is pending state from a crashed capture attempt */
834 if (*AskAboutPendingState()) {
835 state_was_pending = true;
839 if (!state_was_pending) {
840 xmlpath = _session_dir->root_path();
841 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
844 if (!sys::exists (xmlpath)) {
845 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
849 state_tree = new XMLTree;
853 /* writable() really reflects the whole folder, but if for any
854 reason the session state file can't be written to, still
858 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
862 if (!state_tree->read (xmlpath.to_string())) {
863 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
869 XMLNode& root (*state_tree->root());
871 if (root.name() != X_("Session")) {
872 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
878 const XMLProperty* prop;
880 if ((prop = root.property ("version")) == 0) {
881 /* no version implies very old version of Ardour */
882 Stateful::loading_state_version = 1000;
888 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
889 Stateful::loading_state_version = (major * 1000) + minor;
892 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
894 sys::path backup_path(_session_dir->root_path());
896 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
898 // only create a backup once
899 if (sys::exists (backup_path)) {
903 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
904 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
909 sys::copy_file (xmlpath, backup_path);
911 catch(sys::filesystem_error& ex)
913 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
914 xmlpath.to_string(), ex.what())
924 Session::load_options (const XMLNode& node)
926 LocaleGuard lg (X_("POSIX"));
927 config.set_variables (node);
938 Session::get_template()
940 /* if we don't disable rec-enable, diskstreams
941 will believe they need to store their capture
942 sources in their state node.
945 disable_record (false);
951 Session::state(bool full_state)
953 XMLNode* node = new XMLNode("Session");
956 // store libardour version, just in case
958 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
959 node->add_property("version", string(buf));
961 /* store configuration settings */
965 node->add_property ("name", _name);
966 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
967 node->add_property ("sample-rate", buf);
969 if (session_dirs.size() > 1) {
973 vector<space_and_path>::iterator i = session_dirs.begin();
974 vector<space_and_path>::iterator next;
976 ++i; /* skip the first one */
980 while (i != session_dirs.end()) {
984 if (next != session_dirs.end()) {
994 child = node->add_child ("Path");
995 child->add_content (p);
999 /* save the ID counter */
1001 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
1002 node->add_property ("id-counter", buf);
1004 /* various options */
1006 node->add_child_nocopy (config.get_variables ());
1008 node->add_child_nocopy (_metadata->get_state());
1010 child = node->add_child ("Sources");
1013 Glib::Mutex::Lock sl (source_lock);
1015 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1017 /* Don't save information about non-destructive file sources that are empty */
1018 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
1020 boost::shared_ptr<AudioFileSource> fs;
1021 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
1022 if (!fs->destructive()) {
1023 if (fs->length(fs->timeline_position()) == 0) {
1029 child->add_child_nocopy (siter->second->get_state());
1033 child = node->add_child ("Regions");
1036 Glib::Mutex::Lock rl (region_lock);
1037 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1038 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1039 boost::shared_ptr<Region> r = i->second;
1040 /* only store regions not attached to playlists */
1041 if (r->playlist() == 0) {
1042 child->add_child_nocopy (r->state (true));
1048 node->add_child_nocopy (_locations.get_state());
1050 // for a template, just create a new Locations, populate it
1051 // with the default start and end, and get the state for that.
1053 Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
1054 range->set (0, compute_initial_length ());
1056 node->add_child_nocopy (loc.get_state());
1059 child = node->add_child ("Bundles");
1061 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1062 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1063 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1065 child->add_child_nocopy (b->get_state());
1070 child = node->add_child ("Routes");
1072 boost::shared_ptr<RouteList> r = routes.reader ();
1074 RoutePublicOrderSorter cmp;
1075 RouteList public_order (*r);
1076 public_order.sort (cmp);
1078 /* the sort should have put control outs first */
1081 assert (_monitor_out == public_order.front());
1084 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1085 if (!(*i)->is_hidden()) {
1087 child->add_child_nocopy ((*i)->get_state());
1089 child->add_child_nocopy ((*i)->get_template());
1095 playlists->add_state (node, full_state);
1097 child = node->add_child ("RouteGroups");
1098 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1099 child->add_child_nocopy ((*i)->get_state());
1103 child = node->add_child ("Click");
1104 child->add_child_nocopy (_click_io->state (full_state));
1108 child = node->add_child ("NamedSelections");
1109 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1111 child->add_child_nocopy ((*i)->get_state());
1116 node->add_child_nocopy (_tempo_map->get_state());
1118 node->add_child_nocopy (get_control_protocol_state());
1121 node->add_child_copy (*_extra_xml);
1128 Session::get_control_protocol_state ()
1130 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1131 return cpm.get_state();
1135 Session::set_state (const XMLNode& node, int version)
1139 const XMLProperty* prop;
1142 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1144 if (node.name() != X_("Session")){
1145 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1149 if ((prop = node.property ("version")) != 0) {
1150 version = atoi (prop->value ()) * 1000;
1153 if ((prop = node.property ("name")) != 0) {
1154 _name = prop->value ();
1157 if ((prop = node.property (X_("sample-rate"))) != 0) {
1159 _nominal_frame_rate = atoi (prop->value());
1161 if (_nominal_frame_rate != _current_frame_rate) {
1162 if (*AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1168 setup_raid_path(_session_dir->root_path().to_string());
1170 if ((prop = node.property (X_("id-counter"))) != 0) {
1172 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1173 ID::init_counter (x);
1175 /* old sessions used a timebased counter, so fake
1176 the startup ID counter based on a standard
1181 ID::init_counter (now);
1185 IO::disable_connecting ();
1187 /* Object loading order:
1192 MIDI Control // relies on data from Options/Config
1205 if ((child = find_named_node (node, "Extra")) != 0) {
1206 _extra_xml = new XMLNode (*child);
1209 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1210 load_options (*child);
1211 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1212 load_options (*child);
1214 error << _("Session: XML state has no options section") << endmsg;
1217 if (use_config_midi_ports ()) {
1220 if (version >= 3000) {
1221 if ((child = find_named_node (node, "Metadata")) == 0) {
1222 warning << _("Session: XML state has no metadata section") << endmsg;
1223 } else if (_metadata->set_state (*child, version)) {
1228 if ((child = find_named_node (node, "Locations")) == 0) {
1229 error << _("Session: XML state has no locations section") << endmsg;
1231 } else if (_locations.set_state (*child, version)) {
1237 if ((location = _locations.auto_loop_location()) != 0) {
1238 set_auto_loop_location (location);
1241 if ((location = _locations.auto_punch_location()) != 0) {
1242 set_auto_punch_location (location);
1245 if ((location = _locations.session_range_location()) == 0) {
1246 _locations.add (_session_range_location);
1248 delete _session_range_location;
1249 _session_range_location = location;
1252 AudioFileSource::set_header_position_offset (_session_range_location->start());
1254 if ((child = find_named_node (node, "Sources")) == 0) {
1255 error << _("Session: XML state has no sources section") << endmsg;
1257 } else if (load_sources (*child)) {
1261 if ((child = find_named_node (node, "Regions")) == 0) {
1262 error << _("Session: XML state has no Regions section") << endmsg;
1264 } else if (load_regions (*child)) {
1268 if ((child = find_named_node (node, "Playlists")) == 0) {
1269 error << _("Session: XML state has no playlists section") << endmsg;
1271 } else if (playlists->load (*this, *child)) {
1275 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1277 } else if (playlists->load_unused (*this, *child)) {
1281 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1282 if (load_named_selections (*child)) {
1287 if (version >= 3000) {
1288 if ((child = find_named_node (node, "Bundles")) == 0) {
1289 warning << _("Session: XML state has no bundles section") << endmsg;
1292 /* We can't load Bundles yet as they need to be able
1293 to convert from port names to Port objects, which can't happen until
1295 _bundle_xml_node = new XMLNode (*child);
1299 if ((child = find_named_node (node, "TempoMap")) == 0) {
1300 error << _("Session: XML state has no Tempo Map section") << endmsg;
1302 } else if (_tempo_map->set_state (*child, version)) {
1306 if (version < 3000) {
1307 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1308 error << _("Session: XML state has no diskstreams section") << endmsg;
1310 } else if (load_diskstreams_2X (*child, version)) {
1315 if ((child = find_named_node (node, "Routes")) == 0) {
1316 error << _("Session: XML state has no routes section") << endmsg;
1318 } else if (load_routes (*child, version)) {
1322 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1323 _diskstreams_2X.clear ();
1325 if (version >= 3000) {
1327 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1328 error << _("Session: XML state has no route groups section") << endmsg;
1330 } else if (load_route_groups (*child, version)) {
1334 } else if (version < 3000) {
1336 if ((child = find_named_node (node, "EditGroups")) == 0) {
1337 error << _("Session: XML state has no edit groups section") << endmsg;
1339 } else if (load_route_groups (*child, version)) {
1343 if ((child = find_named_node (node, "MixGroups")) == 0) {
1344 error << _("Session: XML state has no mix groups section") << endmsg;
1346 } else if (load_route_groups (*child, version)) {
1351 if ((child = find_named_node (node, "Click")) == 0) {
1352 warning << _("Session: XML state has no click section") << endmsg;
1353 } else if (_click_io) {
1354 _click_io->set_state (*child, version);
1357 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1358 ControlProtocolManager::instance().set_protocol_states (*child);
1361 /* here beginneth the second phase ... */
1363 StateReady (); /* EMIT SIGNAL */
1372 Session::load_routes (const XMLNode& node, int version)
1375 XMLNodeConstIterator niter;
1376 RouteList new_routes;
1378 nlist = node.children();
1382 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1384 boost::shared_ptr<Route> route;
1385 if (version < 3000) {
1386 route = XMLRouteFactory_2X (**niter, version);
1388 route = XMLRouteFactory (**niter, version);
1392 error << _("Session: cannot create Route from XML description.") << endmsg;
1396 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1398 new_routes.push_back (route);
1401 add_routes (new_routes, false);
1406 boost::shared_ptr<Route>
1407 Session::XMLRouteFactory (const XMLNode& node, int version)
1409 boost::shared_ptr<Route> ret;
1411 if (node.name() != "Route") {
1415 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1417 DataType type = DataType::AUDIO;
1418 const XMLProperty* prop = node.property("default-type");
1421 type = DataType (prop->value());
1424 assert (type != DataType::NIL);
1430 if (type == DataType::AUDIO) {
1431 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1434 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1437 if (track->init()) {
1442 if (track->set_state (node, version)) {
1447 boost_debug_shared_ptr_mark_interesting (track, "Track");
1451 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1453 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1454 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1464 boost::shared_ptr<Route>
1465 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1467 boost::shared_ptr<Route> ret;
1469 if (node.name() != "Route") {
1473 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1475 ds_prop = node.property (X_("diskstream"));
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;