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 = 0;
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);
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 _state_of_the_state = Clean;
368 DirtyChanged (); /* EMIT SIGNAL */
370 if (state_was_pending) {
371 save_state (_current_snapshot_name);
372 remove_pending_capture_state ();
373 state_was_pending = false;
376 BootMessage (_("Session loading complete"));
382 Session::raid_path () const
384 SearchPath raid_search_path;
386 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
387 raid_search_path += sys::path((*i).path);
390 return raid_search_path.to_string ();
394 Session::setup_raid_path (string path)
403 session_dirs.clear ();
405 SearchPath search_path(path);
406 SearchPath sound_search_path;
407 SearchPath midi_search_path;
409 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
410 sp.path = (*i).to_string ();
411 sp.blocks = 0; // not needed
412 session_dirs.push_back (sp);
414 SessionDirectory sdir(sp.path);
416 sound_search_path += sdir.sound_path ();
417 midi_search_path += sdir.midi_path ();
420 // set the search path for each data type
421 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
422 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
424 // reset the round-robin soundfile path thingie
425 last_rr_session_dir = session_dirs.begin();
429 Session::path_is_within_session (const std::string& path)
431 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
432 if (path.find ((*i).path) == 0) {
440 Session::ensure_subdirs ()
444 dir = session_directory().peak_path().to_string();
446 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
447 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
451 dir = session_directory().sound_path().to_string();
453 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
454 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
458 dir = session_directory().midi_path().to_string();
460 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
461 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
465 dir = session_directory().dead_sound_path().to_string();
467 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
468 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
472 dir = session_directory().export_path().to_string();
474 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
475 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
479 dir = analysis_dir ();
481 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
482 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
490 Session::create (const string& mix_template, BusProfile* bus_profile)
493 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
494 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
498 if (ensure_subdirs ()) {
502 if (!mix_template.empty()) {
503 std::string in_path = mix_template;
505 ifstream in(in_path.c_str());
508 string out_path = _path;
510 out_path += statefile_suffix;
512 ofstream out(out_path.c_str());
520 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
526 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
533 /* Instantiate metadata */
535 _metadata = new SessionMetadata ();
537 /* set initial start + end point */
539 _state_of_the_state = Clean;
541 /* set up Master Out and Control Out if necessary */
547 ChanCount count(DataType::AUDIO, bus_profile->master_out_channels);
549 if (bus_profile->master_out_channels) {
550 Route* rt = new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO);
555 boost_debug_shared_ptr_mark_interesting (rt, "Route");
556 boost::shared_ptr<Route> r (rt);
557 r->input()->ensure_io (count, false, this);
558 r->output()->ensure_io (count, false, this);
559 r->set_remote_control_id (control_id++);
563 if (Config->get_use_monitor_bus()) {
564 Route* rt = new Route (*this, _("monitor"), Route::MonitorOut, DataType::AUDIO);
569 boost_debug_shared_ptr_mark_interesting (rt, "Route");
570 boost::shared_ptr<Route> r (rt);
571 r->input()->ensure_io (count, false, this);
572 r->output()->ensure_io (count, false, this);
573 r->set_remote_control_id (control_id);
579 /* prohibit auto-connect to master, because there isn't one */
580 bus_profile->output_ac = AutoConnectOption (bus_profile->output_ac & ~AutoConnectMaster);
584 add_routes (rl, false);
587 /* this allows the user to override settings with an environment variable.
590 if (no_auto_connect()) {
591 bus_profile->input_ac = AutoConnectOption (0);
592 bus_profile->output_ac = AutoConnectOption (0);
595 Config->set_input_auto_connect (bus_profile->input_ac);
596 Config->set_output_auto_connect (bus_profile->output_ac);
605 Session::maybe_write_autosave()
607 if (dirty() && record_status() != Recording) {
608 save_state("", true);
613 Session::remove_pending_capture_state ()
615 sys::path pending_state_file_path(_session_dir->root_path());
617 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
621 sys::remove (pending_state_file_path);
623 catch(sys::filesystem_error& ex)
625 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
626 pending_state_file_path.to_string(), ex.what()) << endmsg;
630 /** Rename a state file.
631 * @param snapshot_name Snapshot name.
634 Session::rename_state (string old_name, string new_name)
636 if (old_name == _current_snapshot_name || old_name == _name) {
637 /* refuse to rename the current snapshot or the "main" one */
641 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
642 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
644 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
645 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
649 sys::rename (old_xml_path, new_xml_path);
651 catch (const sys::filesystem_error& err)
653 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
654 old_name, new_name, err.what()) << endmsg;
658 /** Remove a state file.
659 * @param snapshot_name Snapshot name.
662 Session::remove_state (string snapshot_name)
664 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
665 // refuse to remove the current snapshot or the "main" one
669 sys::path xml_path(_session_dir->root_path());
671 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
673 if (!create_backup_file (xml_path)) {
674 // don't remove it if a backup can't be made
675 // create_backup_file will log the error.
680 sys::remove (xml_path);
683 #ifdef HAVE_JACK_SESSION
685 Session::jack_session_event (jack_session_event_t * event)
687 if (save_state ("jacksession_snap")) {
688 event->flags = JackSessionSaveError;
690 sys::path xml_path (_session_dir->root_path());
691 xml_path /= legalize_for_path ("jacksession_snap") + statefile_suffix;
693 string cmd ("PROG_NAME -U ");
694 cmd += event->client_uuid;
696 cmd += xml_path.to_string();
699 event->command_line = strdup (cmd.c_str());
702 jack_session_reply (_engine.jack(), event);
704 if (event->type == JackSessionSaveAndQuit) {
705 // TODO: make ardour quit.
708 jack_session_event_free( event );
713 Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
716 sys::path xml_path(_session_dir->root_path());
718 if (!_writable || (_state_of_the_state & CannotSave)) {
722 if (!_engine.connected ()) {
723 error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
729 /* tell sources we're saving first, in case they write out to a new file
730 * which should be saved with the state rather than the old one */
731 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
732 i->second->session_saved();
734 tree.set_root (&get_state());
736 if (snapshot_name.empty()) {
737 snapshot_name = _current_snapshot_name;
738 } else if (switch_to_snapshot) {
739 _current_snapshot_name = snapshot_name;
744 /* proper save: use statefile_suffix (.ardour in English) */
746 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
748 /* make a backup copy of the old file */
750 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
751 // create_backup_file will log the error
757 /* pending save: use pending_suffix (.pending in English) */
758 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
761 sys::path tmp_path(_session_dir->root_path());
763 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
765 // cerr << "actually writing state to " << xml_path.to_string() << endl;
767 if (!tree.write (tmp_path.to_string())) {
768 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
769 sys::remove (tmp_path);
774 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
775 error << string_compose (_("could not rename temporary session file %1 to %2"),
776 tmp_path.to_string(), xml_path.to_string()) << endmsg;
777 sys::remove (tmp_path);
784 save_history (snapshot_name);
786 bool was_dirty = dirty();
788 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
791 DirtyChanged (); /* EMIT SIGNAL */
794 StateSaved (snapshot_name); /* EMIT SIGNAL */
801 Session::restore_state (string snapshot_name)
803 if (load_state (snapshot_name) == 0) {
804 set_state (*state_tree->root(), Stateful::loading_state_version);
811 Session::load_state (string snapshot_name)
816 state_was_pending = false;
818 /* check for leftover pending state from a crashed capture attempt */
820 sys::path xmlpath(_session_dir->root_path());
821 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
823 if (sys::exists (xmlpath)) {
825 /* there is pending state from a crashed capture attempt */
827 if (*AskAboutPendingState()) {
828 state_was_pending = true;
832 if (!state_was_pending) {
833 xmlpath = _session_dir->root_path();
834 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
837 if (!sys::exists (xmlpath)) {
838 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
842 state_tree = new XMLTree;
846 /* writable() really reflects the whole folder, but if for any
847 reason the session state file can't be written to, still
851 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
855 if (!state_tree->read (xmlpath.to_string())) {
856 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
862 XMLNode& root (*state_tree->root());
864 if (root.name() != X_("Session")) {
865 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
871 const XMLProperty* prop;
873 if ((prop = root.property ("version")) == 0) {
874 /* no version implies very old version of Ardour */
875 Stateful::loading_state_version = 1000;
881 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
882 Stateful::loading_state_version = (major * 1000) + minor;
885 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
887 sys::path backup_path(_session_dir->root_path());
889 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
891 // only create a backup once
892 if (sys::exists (backup_path)) {
896 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
897 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
902 sys::copy_file (xmlpath, backup_path);
904 catch(sys::filesystem_error& ex)
906 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
907 xmlpath.to_string(), ex.what())
917 Session::load_options (const XMLNode& node)
919 LocaleGuard lg (X_("POSIX"));
920 config.set_variables (node);
931 Session::get_template()
933 /* if we don't disable rec-enable, diskstreams
934 will believe they need to store their capture
935 sources in their state node.
938 disable_record (false);
944 Session::state(bool full_state)
946 XMLNode* node = new XMLNode("Session");
949 // store libardour version, just in case
951 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
952 node->add_property("version", string(buf));
954 /* store configuration settings */
958 node->add_property ("name", _name);
959 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
960 node->add_property ("sample-rate", buf);
962 if (session_dirs.size() > 1) {
966 vector<space_and_path>::iterator i = session_dirs.begin();
967 vector<space_and_path>::iterator next;
969 ++i; /* skip the first one */
973 while (i != session_dirs.end()) {
977 if (next != session_dirs.end()) {
987 child = node->add_child ("Path");
988 child->add_content (p);
992 /* save the ID counter */
994 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
995 node->add_property ("id-counter", buf);
997 /* various options */
999 node->add_child_nocopy (config.get_variables ());
1001 node->add_child_nocopy (_metadata->get_state());
1003 child = node->add_child ("Sources");
1006 Glib::Mutex::Lock sl (source_lock);
1008 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1010 /* Don't save information about non-destructive file sources that are empty */
1011 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
1013 boost::shared_ptr<AudioFileSource> fs;
1014 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
1015 if (!fs->destructive()) {
1016 if (fs->length(fs->timeline_position()) == 0) {
1022 child->add_child_nocopy (siter->second->get_state());
1026 child = node->add_child ("Regions");
1029 Glib::Mutex::Lock rl (region_lock);
1030 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1031 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1032 boost::shared_ptr<Region> r = i->second;
1033 /* only store regions not attached to playlists */
1034 if (r->playlist() == 0) {
1035 child->add_child_nocopy (r->state (true));
1041 node->add_child_nocopy (_locations.get_state());
1043 // for a template, just create a new Locations, populate it
1044 // with the default start and end, and get the state for that.
1046 Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
1047 range->set (max_frames, 0);
1049 node->add_child_nocopy (loc.get_state());
1052 child = node->add_child ("Bundles");
1054 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1055 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1056 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1058 child->add_child_nocopy (b->get_state());
1063 child = node->add_child ("Routes");
1065 boost::shared_ptr<RouteList> r = routes.reader ();
1067 RoutePublicOrderSorter cmp;
1068 RouteList public_order (*r);
1069 public_order.sort (cmp);
1071 /* the sort should have put control outs first */
1074 assert (_monitor_out == public_order.front());
1077 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1078 if (!(*i)->is_hidden()) {
1080 child->add_child_nocopy ((*i)->get_state());
1082 child->add_child_nocopy ((*i)->get_template());
1088 playlists->add_state (node, full_state);
1090 child = node->add_child ("RouteGroups");
1091 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1092 child->add_child_nocopy ((*i)->get_state());
1096 child = node->add_child ("Click");
1097 child->add_child_nocopy (_click_io->state (full_state));
1101 child = node->add_child ("NamedSelections");
1102 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1104 child->add_child_nocopy ((*i)->get_state());
1109 node->add_child_nocopy (_tempo_map->get_state());
1111 node->add_child_nocopy (get_control_protocol_state());
1114 node->add_child_copy (*_extra_xml);
1121 Session::get_control_protocol_state ()
1123 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1124 return cpm.get_state();
1128 Session::set_state (const XMLNode& node, int version)
1132 const XMLProperty* prop;
1135 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1137 if (node.name() != X_("Session")){
1138 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1142 if ((prop = node.property ("version")) != 0) {
1143 version = atoi (prop->value ()) * 1000;
1146 if ((prop = node.property ("name")) != 0) {
1147 _name = prop->value ();
1150 if ((prop = node.property (X_("sample-rate"))) != 0) {
1152 _nominal_frame_rate = atoi (prop->value());
1154 if (_nominal_frame_rate != _current_frame_rate) {
1155 if (*AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1161 setup_raid_path(_session_dir->root_path().to_string());
1163 if ((prop = node.property (X_("id-counter"))) != 0) {
1165 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1166 ID::init_counter (x);
1168 /* old sessions used a timebased counter, so fake
1169 the startup ID counter based on a standard
1174 ID::init_counter (now);
1178 IO::disable_connecting ();
1180 /* Object loading order:
1185 MIDI Control // relies on data from Options/Config
1198 if ((child = find_named_node (node, "Extra")) != 0) {
1199 _extra_xml = new XMLNode (*child);
1202 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1203 load_options (*child);
1204 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1205 load_options (*child);
1207 error << _("Session: XML state has no options section") << endmsg;
1210 if (use_config_midi_ports ()) {
1213 if (version >= 3000) {
1214 if ((child = find_named_node (node, "Metadata")) == 0) {
1215 warning << _("Session: XML state has no metadata section") << endmsg;
1216 } else if (_metadata->set_state (*child, version)) {
1221 if ((child = find_named_node (node, "Locations")) == 0) {
1222 error << _("Session: XML state has no locations section") << endmsg;
1224 } else if (_locations.set_state (*child, version)) {
1230 if ((location = _locations.auto_loop_location()) != 0) {
1231 set_auto_loop_location (location);
1234 if ((location = _locations.auto_punch_location()) != 0) {
1235 set_auto_punch_location (location);
1238 if ((location = _locations.session_range_location()) != 0) {
1239 delete _session_range_location;
1240 _session_range_location = location;
1243 if (_session_range_location) {
1244 AudioFileSource::set_header_position_offset (_session_range_location->start());
1247 if ((child = find_named_node (node, "Sources")) == 0) {
1248 error << _("Session: XML state has no sources section") << endmsg;
1250 } else if (load_sources (*child)) {
1254 if ((child = find_named_node (node, "Regions")) == 0) {
1255 error << _("Session: XML state has no Regions section") << endmsg;
1257 } else if (load_regions (*child)) {
1261 if ((child = find_named_node (node, "Playlists")) == 0) {
1262 error << _("Session: XML state has no playlists section") << endmsg;
1264 } else if (playlists->load (*this, *child)) {
1268 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1270 } else if (playlists->load_unused (*this, *child)) {
1274 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1275 if (load_named_selections (*child)) {
1280 if (version >= 3000) {
1281 if ((child = find_named_node (node, "Bundles")) == 0) {
1282 warning << _("Session: XML state has no bundles section") << endmsg;
1285 /* We can't load Bundles yet as they need to be able
1286 to convert from port names to Port objects, which can't happen until
1288 _bundle_xml_node = new XMLNode (*child);
1292 if ((child = find_named_node (node, "TempoMap")) == 0) {
1293 error << _("Session: XML state has no Tempo Map section") << endmsg;
1295 } else if (_tempo_map->set_state (*child, version)) {
1299 if (version < 3000) {
1300 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1301 error << _("Session: XML state has no diskstreams section") << endmsg;
1303 } else if (load_diskstreams_2X (*child, version)) {
1308 if ((child = find_named_node (node, "Routes")) == 0) {
1309 error << _("Session: XML state has no routes section") << endmsg;
1311 } else if (load_routes (*child, version)) {
1315 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1316 _diskstreams_2X.clear ();
1318 if (version >= 3000) {
1320 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1321 error << _("Session: XML state has no route groups section") << endmsg;
1323 } else if (load_route_groups (*child, version)) {
1327 } else if (version < 3000) {
1329 if ((child = find_named_node (node, "EditGroups")) == 0) {
1330 error << _("Session: XML state has no edit groups section") << endmsg;
1332 } else if (load_route_groups (*child, version)) {
1336 if ((child = find_named_node (node, "MixGroups")) == 0) {
1337 error << _("Session: XML state has no mix groups section") << endmsg;
1339 } else if (load_route_groups (*child, version)) {
1344 if ((child = find_named_node (node, "Click")) == 0) {
1345 warning << _("Session: XML state has no click section") << endmsg;
1346 } else if (_click_io) {
1347 _click_io->set_state (*child, version);
1350 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1351 ControlProtocolManager::instance().set_protocol_states (*child);
1354 /* here beginneth the second phase ... */
1356 StateReady (); /* EMIT SIGNAL */
1365 Session::load_routes (const XMLNode& node, int version)
1368 XMLNodeConstIterator niter;
1369 RouteList new_routes;
1371 nlist = node.children();
1375 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1377 boost::shared_ptr<Route> route;
1378 if (version < 3000) {
1379 route = XMLRouteFactory_2X (**niter, version);
1381 route = XMLRouteFactory (**niter, version);
1385 error << _("Session: cannot create Route from XML description.") << endmsg;
1389 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1391 new_routes.push_back (route);
1394 add_routes (new_routes, false);
1399 boost::shared_ptr<Route>
1400 Session::XMLRouteFactory (const XMLNode& node, int version)
1402 boost::shared_ptr<Route> ret;
1404 if (node.name() != "Route") {
1408 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1410 DataType type = DataType::AUDIO;
1411 const XMLProperty* prop = node.property("default-type");
1414 type = DataType (prop->value());
1417 assert (type != DataType::NIL);
1423 if (type == DataType::AUDIO) {
1424 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1427 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1430 if (track->init()) {
1435 if (track->set_state (node, version)) {
1440 boost_debug_shared_ptr_mark_interesting (track, "Track");
1444 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1446 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1447 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1457 boost::shared_ptr<Route>
1458 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1460 boost::shared_ptr<Route> ret;
1462 if (node.name() != "Route") {
1466 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1468 ds_prop = node.property (X_("diskstream"));
1471 DataType type = DataType::AUDIO;
1472 const XMLProperty* prop = node.property("default-type");
1475 type = DataType (prop->value());
1478 assert (type != DataType::NIL);
1482 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1483 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1487 if (i == _diskstreams_2X.end()) {
1488 error << _("Could not find diskstream for route") << endmsg;
1489 return boost::shared_ptr<Route> ();
1494 if (type == DataType::AUDIO) {
1495 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1498 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1501 if (track->init()) {
1506 if (track->set_state (node, version)) {
1511 track->set_diskstream (*i);
1513 boost_debug_shared_ptr_mark_interesting (track, "Track");
1517 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1519 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1520 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1531 Session::load_regions (const XMLNode& node)
1534 XMLNodeConstIterator niter;
1535 boost::shared_ptr<Region> region;
1537 nlist = node.children();
1541 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1542 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1543 error << _("Session: cannot create Region from XML description.");
1544 const XMLProperty *name = (**niter).property("name");
1547 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1557 boost::shared_ptr<Region>
1558 Session::XMLRegionFactory (const XMLNode& node, bool full)
1560 const XMLProperty* type = node.property("type");
1564 if ( !type || type->value() == "audio" ) {
1566 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1568 } else if (type->value() == "midi") {
1570 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1574 } catch (failed_constructor& err) {
1575 return boost::shared_ptr<Region> ();
1578 return boost::shared_ptr<Region> ();
1581 boost::shared_ptr<AudioRegion>
1582 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1584 const XMLProperty* prop;
1585 boost::shared_ptr<Source> source;
1586 boost::shared_ptr<AudioSource> as;
1588 SourceList master_sources;
1589 uint32_t nchans = 1;
1592 if (node.name() != X_("Region")) {
1593 return boost::shared_ptr<AudioRegion>();
1596 if ((prop = node.property (X_("channels"))) != 0) {
1597 nchans = atoi (prop->value().c_str());
1600 if ((prop = node.property ("name")) == 0) {
1601 cerr << "no name for this region\n";
1605 if ((prop = node.property (X_("source-0"))) == 0) {
1606 if ((prop = node.property ("source")) == 0) {
1607 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1608 return boost::shared_ptr<AudioRegion>();
1612 PBD::ID s_id (prop->value());
1614 if ((source = source_by_id (s_id)) == 0) {
1615 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1616 return boost::shared_ptr<AudioRegion>();
1619 as = boost::dynamic_pointer_cast<AudioSource>(source);
1621 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1622 return boost::shared_ptr<AudioRegion>();
1625 sources.push_back (as);
1627 /* pickup other channels */
1629 for (uint32_t n=1; n < nchans; ++n) {
1630 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1631 if ((prop = node.property (buf)) != 0) {
1633 PBD::ID id2 (prop->value());
1635 if ((source = source_by_id (id2)) == 0) {
1636 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1637 return boost::shared_ptr<AudioRegion>();
1640 as = boost::dynamic_pointer_cast<AudioSource>(source);
1642 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1643 return boost::shared_ptr<AudioRegion>();
1645 sources.push_back (as);
1649 for (uint32_t n = 0; n < nchans; ++n) {
1650 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1651 if ((prop = node.property (buf)) != 0) {
1653 PBD::ID id2 (prop->value());
1655 if ((source = source_by_id (id2)) == 0) {
1656 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1657 return boost::shared_ptr<AudioRegion>();
1660 as = boost::dynamic_pointer_cast<AudioSource>(source);
1662 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1663 return boost::shared_ptr<AudioRegion>();
1665 master_sources.push_back (as);
1670 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1672 /* a final detail: this is the one and only place that we know how long missing files are */
1674 if (region->whole_file()) {
1675 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1676 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1678 sfp->set_length (region->length());
1683 if (!master_sources.empty()) {
1684 if (master_sources.size() != nchans) {
1685 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1687 region->set_master_sources (master_sources);
1695 catch (failed_constructor& err) {
1696 return boost::shared_ptr<AudioRegion>();
1700 boost::shared_ptr<MidiRegion>
1701 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1703 const XMLProperty* prop;
1704 boost::shared_ptr<Source> source;
1705 boost::shared_ptr<MidiSource> ms;
1707 uint32_t nchans = 1;
1709 if (node.name() != X_("Region")) {
1710 return boost::shared_ptr<MidiRegion>();
1713 if ((prop = node.property (X_("channels"))) != 0) {
1714 nchans = atoi (prop->value().c_str());
1717 if ((prop = node.property ("name")) == 0) {
1718 cerr << "no name for this region\n";
1722 // Multiple midi channels? that's just crazy talk
1723 assert(nchans == 1);
1725 if ((prop = node.property (X_("source-0"))) == 0) {
1726 if ((prop = node.property ("source")) == 0) {
1727 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1728 return boost::shared_ptr<MidiRegion>();
1732 PBD::ID s_id (prop->value());
1734 if ((source = source_by_id (s_id)) == 0) {
1735 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1736 return boost::shared_ptr<MidiRegion>();
1739 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1741 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1742 return boost::shared_ptr<MidiRegion>();
1745 sources.push_back (ms);
1748 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1749 /* a final detail: this is the one and only place that we know how long missing files are */
1751 if (region->whole_file()) {
1752 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1753 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1755 sfp->set_length (region->length());
1763 catch (failed_constructor& err) {
1764 return boost::shared_ptr<MidiRegion>();
1769 Session::get_sources_as_xml ()
1772 XMLNode* node = new XMLNode (X_("Sources"));
1773 Glib::Mutex::Lock lm (source_lock);
1775 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1776 node->add_child_nocopy (i->second->get_state());
1783 Session::path_from_region_name (DataType type, string name, string identifier)
1785 char buf[PATH_MAX+1];
1787 SessionDirectory sdir(get_best_session_directory_for_new_source());
1788 sys::path source_dir = ((type == DataType::AUDIO)
1789 ? sdir.sound_path() : sdir.midi_path());
1791 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1793 for (n = 0; n < 999999; ++n) {
1794 if (identifier.length()) {
1795 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1796 identifier.c_str(), n, ext.c_str());
1798 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1802 sys::path source_path = source_dir / buf;
1804 if (!sys::exists (source_path)) {
1805 return source_path.to_string();
1809 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1818 Session::load_sources (const XMLNode& node)
1821 XMLNodeConstIterator niter;
1822 boost::shared_ptr<Source> source;
1824 nlist = node.children();
1828 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1830 if ((source = XMLSourceFactory (**niter)) == 0) {
1831 error << _("Session: cannot create Source from XML description.") << endmsg;
1833 } catch (MissingSource& err) {
1834 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1835 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1842 boost::shared_ptr<Source>
1843 Session::XMLSourceFactory (const XMLNode& node)
1845 if (node.name() != "Source") {
1846 return boost::shared_ptr<Source>();
1850 /* note: do peak building in another thread when loading session state */
1851 return SourceFactory::create (*this, node, true);
1854 catch (failed_constructor& err) {
1855 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1856 return boost::shared_ptr<Source>();
1861 Session::save_template (string template_name)
1865 if (_state_of_the_state & CannotSave) {
1869 sys::path user_template_dir(user_template_directory());
1873 sys::create_directories (user_template_dir);
1875 catch(sys::filesystem_error& ex)
1877 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1878 user_template_dir.to_string(), ex.what()) << endmsg;
1882 tree.set_root (&get_template());
1884 sys::path template_file_path(user_template_dir);
1885 template_file_path /= template_name + template_suffix;
1887 if (sys::exists (template_file_path))
1889 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1890 template_file_path.to_string()) << endmsg;
1894 if (!tree.write (template_file_path.to_string())) {
1895 error << _("mix template not saved") << endmsg;
1903 Session::rename_template (string old_name, string new_name)
1905 sys::path old_path (user_template_directory());
1906 old_path /= old_name + template_suffix;
1908 sys::path new_path(user_template_directory());
1909 new_path /= new_name + template_suffix;
1911 if (sys::exists (new_path)) {
1912 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1913 new_path.to_string()) << endmsg;
1918 sys::rename (old_path, new_path);
1926 Session::delete_template (string name)
1928 sys::path path = user_template_directory();
1929 path /= name + template_suffix;
1940 Session::refresh_disk_space ()
1943 struct statfs statfsbuf;
1944 vector<space_and_path>::iterator i;
1945 Glib::Mutex::Lock lm (space_lock);
1948 /* get freespace on every FS that is part of the session path */
1950 _total_free_4k_blocks = 0;
1952 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1953 statfs ((*i).path.c_str(), &statfsbuf);
1955 scale = statfsbuf.f_bsize/4096.0;
1957 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1958 _total_free_4k_blocks += (*i).blocks;
1964 Session::get_best_session_directory_for_new_source ()
1966 vector<space_and_path>::iterator i;
1967 string result = _session_dir->root_path().to_string();
1969 /* handle common case without system calls */
1971 if (session_dirs.size() == 1) {
1975 /* OK, here's the algorithm we're following here:
1977 We want to select which directory to use for
1978 the next file source to be created. Ideally,
1979 we'd like to use a round-robin process so as to
1980 get maximum performance benefits from splitting
1981 the files across multiple disks.
1983 However, in situations without much diskspace, an
1984 RR approach may end up filling up a filesystem
1985 with new files while others still have space.
1986 Its therefore important to pay some attention to
1987 the freespace in the filesystem holding each
1988 directory as well. However, if we did that by
1989 itself, we'd keep creating new files in the file
1990 system with the most space until it was as full
1991 as all others, thus negating any performance
1992 benefits of this RAID-1 like approach.
1994 So, we use a user-configurable space threshold. If
1995 there are at least 2 filesystems with more than this
1996 much space available, we use RR selection between them.
1997 If not, then we pick the filesystem with the most space.
1999 This gets a good balance between the two
2003 refresh_disk_space ();
2005 int free_enough = 0;
2007 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2008 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2013 if (free_enough >= 2) {
2014 /* use RR selection process, ensuring that the one
2018 i = last_rr_session_dir;
2021 if (++i == session_dirs.end()) {
2022 i = session_dirs.begin();
2025 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2026 if (create_session_directory ((*i).path)) {
2028 last_rr_session_dir = i;
2033 } while (i != last_rr_session_dir);
2037 /* pick FS with the most freespace (and that
2038 seems to actually work ...)
2041 vector<space_and_path> sorted;
2042 space_and_path_ascending_cmp cmp;
2044 sorted = session_dirs;
2045 sort (sorted.begin(), sorted.end(), cmp);
2047 for (i = sorted.begin(); i != sorted.end(); ++i) {
2048 if (create_session_directory ((*i).path)) {
2050 last_rr_session_dir = i;
2060 Session::load_named_selections (const XMLNode& node)
2063 XMLNodeConstIterator niter;
2066 nlist = node.children();
2070 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2072 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2073 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2081 Session::XMLNamedSelectionFactory (const XMLNode& node)
2084 return new NamedSelection (*this, node);
2087 catch (failed_constructor& err) {
2093 Session::automation_dir () const
2095 return Glib::build_filename (_path, "automation");
2099 Session::analysis_dir () const
2101 return Glib::build_filename (_path, "analysis");
2105 Session::load_bundles (XMLNode const & node)
2107 XMLNodeList nlist = node.children();
2108 XMLNodeConstIterator niter;
2112 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2113 if ((*niter)->name() == "InputBundle") {
2114 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2115 } else if ((*niter)->name() == "OutputBundle") {
2116 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2118 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2127 Session::load_route_groups (const XMLNode& node, int version)
2129 XMLNodeList nlist = node.children();
2130 XMLNodeConstIterator niter;
2134 if (version >= 3000) {
2136 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2137 if ((*niter)->name() == "RouteGroup") {
2138 RouteGroup* rg = new RouteGroup (*this, "");
2139 add_route_group (rg);
2140 rg->set_state (**niter, version);
2144 } else if (version < 3000) {
2146 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2147 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2148 RouteGroup* rg = new RouteGroup (*this, "");
2149 add_route_group (rg);
2150 rg->set_state (**niter, version);
2159 Session::auto_save()
2161 save_state (_current_snapshot_name);
2165 state_file_filter (const string &str, void */*arg*/)
2167 return (str.length() > strlen(statefile_suffix) &&
2168 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2172 bool operator()(const string* a, const string* b) {
2178 remove_end(string* state)
2180 string statename(*state);
2182 string::size_type start,end;
2183 if ((start = statename.find_last_of ('/')) != string::npos) {
2184 statename = statename.substr (start+1);
2187 if ((end = statename.rfind(".ardour")) == string::npos) {
2188 end = statename.length();
2191 return new string(statename.substr (0, end));
2195 Session::possible_states (string path)
2197 PathScanner scanner;
2198 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2200 transform(states->begin(), states->end(), states->begin(), remove_end);
2203 sort (states->begin(), states->end(), cmp);
2209 Session::possible_states () const
2211 return possible_states(_path);
2215 Session::add_route_group (RouteGroup* g)
2217 _route_groups.push_back (g);
2218 route_group_added (g); /* EMIT SIGNAL */
2223 Session::remove_route_group (RouteGroup& rg)
2225 list<RouteGroup*>::iterator i;
2227 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2228 _route_groups.erase (i);
2231 route_group_removed (); /* EMIT SIGNAL */
2237 Session::route_group_by_name (string name)
2239 list<RouteGroup *>::iterator i;
2241 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2242 if ((*i)->name() == name) {
2250 Session::start_reversible_command (const string& name)
2252 UndoTransaction* trans = new UndoTransaction();
2253 trans->set_name(name);
2258 Session::finish_reversible_command (UndoTransaction& ut)
2261 gettimeofday(&now, 0);
2262 ut.set_timestamp(now);
2267 Session::begin_reversible_command(const string& name)
2269 UndoTransaction* trans = new UndoTransaction();
2270 trans->set_name(name);
2272 if (!_current_trans.empty()) {
2273 _current_trans.top()->add_command (trans);
2275 _current_trans.push(trans);
2280 Session::commit_reversible_command(Command *cmd)
2282 assert(!_current_trans.empty());
2286 _current_trans.top()->add_command(cmd);
2289 if (_current_trans.top()->empty()) {
2290 _current_trans.pop();
2294 gettimeofday(&now, 0);
2295 _current_trans.top()->set_timestamp(now);
2297 _history.add(_current_trans.top());
2298 _current_trans.pop();
2302 accept_all_non_peak_files (const string& path, void */*arg*/)
2304 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2308 accept_all_state_files (const string& path, void */*arg*/)
2310 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2314 Session::find_all_sources (string path, set<string>& result)
2319 if (!tree.read (path)) {
2323 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2328 XMLNodeConstIterator niter;
2330 nlist = node->children();
2334 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2338 if ((prop = (*niter)->property (X_("type"))) == 0) {
2342 DataType type (prop->value());
2344 if ((prop = (*niter)->property (X_("name"))) == 0) {
2348 if (prop->value()[0] == '/') {
2349 /* external file, ignore */
2353 Glib::ustring found_path;
2357 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2358 result.insert (found_path);
2366 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2368 PathScanner scanner;
2369 vector<string*>* state_files;
2371 string this_snapshot_path;
2377 if (ripped[ripped.length()-1] == '/') {
2378 ripped = ripped.substr (0, ripped.length() - 1);
2381 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2383 if (state_files == 0) {
2388 this_snapshot_path = _path;
2389 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2390 this_snapshot_path += statefile_suffix;
2392 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2394 if (exclude_this_snapshot && **i == this_snapshot_path) {
2398 if (find_all_sources (**i, result) < 0) {
2406 struct RegionCounter {
2407 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2408 AudioSourceList::iterator iter;
2409 boost::shared_ptr<Region> region;
2412 RegionCounter() : count (0) {}
2416 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2418 return *AskAboutPlaylistDeletion (p);
2422 Session::cleanup_sources (CleanupReport& rep)
2424 // FIXME: needs adaptation to midi
2426 vector<boost::shared_ptr<Source> > dead_sources;
2427 PathScanner scanner;
2429 vector<space_and_path>::iterator i;
2430 vector<space_and_path>::iterator nexti;
2431 vector<string*>* soundfiles;
2432 vector<string> unused;
2433 set<string> all_sources;
2438 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2440 /* step 1: consider deleting all unused playlists */
2442 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2447 /* step 2: find all un-used sources */
2452 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2454 SourceMap::iterator tmp;
2459 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2463 if (!playlists->source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2464 dead_sources.push_back (i->second);
2465 i->second->drop_references ();
2471 /* build a list of all the possible sound directories for the session */
2473 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2478 SessionDirectory sdir ((*i).path);
2479 sound_path += sdir.sound_path().to_string();
2481 if (nexti != session_dirs.end()) {
2488 /* now do the same thing for the files that ended up in the sounds dir(s)
2489 but are not referenced as sources in any snapshot.
2492 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2494 if (soundfiles == 0) {
2498 /* find all sources, but don't use this snapshot because the
2499 state file on disk still references sources we may have already
2503 find_all_sources_across_snapshots (all_sources, true);
2505 /* add our current source list
2508 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2509 boost::shared_ptr<FileSource> fs;
2511 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2512 all_sources.insert (fs->path());
2516 char tmppath1[PATH_MAX+1];
2517 char tmppath2[PATH_MAX+1];
2519 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2524 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2526 realpath(spath.c_str(), tmppath1);
2527 realpath((*i).c_str(), tmppath2);
2529 if (strcmp(tmppath1, tmppath2) == 0) {
2536 unused.push_back (spath);
2540 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2542 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2543 struct stat statbuf;
2545 rep.paths.push_back (*x);
2546 if (stat ((*x).c_str(), &statbuf) == 0) {
2547 rep.space += statbuf.st_size;
2552 /* don't move the file across filesystems, just
2553 stick it in the `dead_sound_dir_name' directory
2554 on whichever filesystem it was already on.
2557 if ((*x).find ("/sounds/") != string::npos) {
2559 /* old school, go up 1 level */
2561 newpath = Glib::path_get_dirname (*x); // "sounds"
2562 newpath = Glib::path_get_dirname (newpath); // "session-name"
2566 /* new school, go up 4 levels */
2568 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2569 newpath = Glib::path_get_dirname (newpath); // "session-name"
2570 newpath = Glib::path_get_dirname (newpath); // "interchange"
2571 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2575 newpath += dead_sound_dir_name;
2577 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2578 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2583 newpath += Glib::path_get_basename ((*x));
2585 if (access (newpath.c_str(), F_OK) == 0) {
2587 /* the new path already exists, try versioning */
2589 char buf[PATH_MAX+1];
2593 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2596 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2597 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2601 if (version == 999) {
2602 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2606 newpath = newpath_v;
2611 /* it doesn't exist, or we can't read it or something */
2615 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2616 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2617 (*x), newpath, strerror (errno))
2622 /* see if there an easy to find peakfile for this file, and remove it.
2625 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2626 peakpath += peakfile_suffix;
2628 if (access (peakpath.c_str(), W_OK) == 0) {
2629 if (::unlink (peakpath.c_str()) != 0) {
2630 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2631 peakpath, _path, strerror (errno))
2633 /* try to back out */
2634 rename (newpath.c_str(), _path.c_str());
2642 /* dump the history list */
2646 /* save state so we don't end up a session file
2647 referring to non-existent sources.
2653 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2659 Session::cleanup_trash_sources (CleanupReport& rep)
2661 // FIXME: needs adaptation for MIDI
2663 vector<space_and_path>::iterator i;
2664 string dead_sound_dir;
2665 struct dirent* dentry;
2666 struct stat statbuf;
2672 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2674 dead_sound_dir = (*i).path;
2675 dead_sound_dir += dead_sound_dir_name;
2677 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2681 while ((dentry = readdir (dead)) != 0) {
2683 /* avoid '.' and '..' */
2685 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2686 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2692 fullpath = dead_sound_dir;
2694 fullpath += dentry->d_name;
2696 if (stat (fullpath.c_str(), &statbuf)) {
2700 if (!S_ISREG (statbuf.st_mode)) {
2704 if (unlink (fullpath.c_str())) {
2705 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2706 fullpath, strerror (errno))
2710 rep.paths.push_back (dentry->d_name);
2711 rep.space += statbuf.st_size;
2722 Session::set_dirty ()
2724 bool was_dirty = dirty();
2726 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2730 DirtyChanged(); /* EMIT SIGNAL */
2736 Session::set_clean ()
2738 bool was_dirty = dirty();
2740 _state_of_the_state = Clean;
2744 DirtyChanged(); /* EMIT SIGNAL */
2749 Session::set_deletion_in_progress ()
2751 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2755 Session::clear_deletion_in_progress ()
2757 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2761 Session::add_controllable (boost::shared_ptr<Controllable> c)
2763 /* this adds a controllable to the list managed by the Session.
2764 this is a subset of those managed by the Controllable class
2765 itself, and represents the only ones whose state will be saved
2766 as part of the session.
2769 Glib::Mutex::Lock lm (controllables_lock);
2770 controllables.insert (c);
2773 struct null_deleter { void operator()(void const *) const {} };
2776 Session::remove_controllable (Controllable* c)
2778 if (_state_of_the_state | Deletion) {
2782 Glib::Mutex::Lock lm (controllables_lock);
2784 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2786 if (x != controllables.end()) {
2787 controllables.erase (x);
2791 boost::shared_ptr<Controllable>
2792 Session::controllable_by_id (const PBD::ID& id)
2794 Glib::Mutex::Lock lm (controllables_lock);
2796 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2797 if ((*i)->id() == id) {
2802 return boost::shared_ptr<Controllable>();
2805 boost::shared_ptr<Controllable>
2806 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2808 boost::shared_ptr<Controllable> c;
2809 boost::shared_ptr<Route> r;
2811 switch (desc.top_level_type()) {
2812 case ControllableDescriptor::NamedRoute:
2814 std::string str = desc.top_level_name();
2815 if (str == "master") {
2817 } else if (str == "control" || str == "listen") {
2820 r = route_by_name (desc.top_level_name());
2825 case ControllableDescriptor::RemoteControlID:
2826 r = route_by_remote_id (desc.rid());
2834 switch (desc.subtype()) {
2835 case ControllableDescriptor::Gain:
2836 c = r->gain_control ();
2839 case ControllableDescriptor::Solo:
2840 c = r->solo_control();
2843 case ControllableDescriptor::Mute:
2844 c = r->mute_control();
2847 case ControllableDescriptor::Recenable:
2849 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2852 c = t->rec_enable_control ();
2857 case ControllableDescriptor::Pan:
2858 /* XXX pan control */
2861 case ControllableDescriptor::Balance:
2862 /* XXX simple pan control */
2865 case ControllableDescriptor::PluginParameter:
2867 uint32_t plugin = desc.target (0);
2868 uint32_t parameter_index = desc.target (1);
2870 /* revert to zero based counting */
2876 if (parameter_index > 0) {
2880 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2883 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2884 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2889 case ControllableDescriptor::SendGain:
2891 uint32_t send = desc.target (0);
2893 /* revert to zero-based counting */
2899 boost::shared_ptr<Processor> p = r->nth_send (send);
2902 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2903 boost::shared_ptr<Amp> a = s->amp();
2906 c = s->amp()->gain_control();
2913 /* relax and return a null pointer */
2921 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2924 Stateful::add_instant_xml (node, _path);
2927 if (write_to_config) {
2928 Config->add_instant_xml (node);
2933 Session::instant_xml (const string& node_name)
2935 return Stateful::instant_xml (node_name, _path);
2939 Session::save_history (string snapshot_name)
2947 if (snapshot_name.empty()) {
2948 snapshot_name = _current_snapshot_name;
2951 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2952 const string backup_filename = history_filename + backup_suffix;
2953 const sys::path xml_path = _session_dir->root_path() / history_filename;
2954 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2956 if (sys::exists (xml_path)) {
2959 sys::rename (xml_path, backup_path);
2961 catch (const sys::filesystem_error& err)
2963 error << _("could not backup old history file, current history not saved") << endmsg;
2968 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2972 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2974 if (!tree.write (xml_path.to_string()))
2976 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2980 sys::remove (xml_path);
2981 sys::rename (backup_path, xml_path);
2983 catch (const sys::filesystem_error& err)
2985 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2986 backup_path.to_string(), err.what()) << endmsg;
2996 Session::restore_history (string snapshot_name)
3000 if (snapshot_name.empty()) {
3001 snapshot_name = _current_snapshot_name;
3004 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3005 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3007 info << "Loading history from " << xml_path.to_string() << endmsg;
3009 if (!sys::exists (xml_path)) {
3010 info << string_compose (_("%1: no history file \"%2\" for this session."),
3011 _name, xml_path.to_string()) << endmsg;
3015 if (!tree.read (xml_path.to_string())) {
3016 error << string_compose (_("Could not understand session history file \"%1\""),
3017 xml_path.to_string()) << endmsg;
3024 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3027 UndoTransaction* ut = new UndoTransaction ();
3030 ut->set_name(t->property("name")->value());
3031 stringstream ss(t->property("tv-sec")->value());
3033 ss.str(t->property("tv-usec")->value());
3035 ut->set_timestamp(tv);
3037 for (XMLNodeConstIterator child_it = t->children().begin();
3038 child_it != t->children().end(); child_it++)
3040 XMLNode *n = *child_it;
3043 if (n->name() == "MementoCommand" ||
3044 n->name() == "MementoUndoCommand" ||
3045 n->name() == "MementoRedoCommand") {
3047 if ((c = memento_command_factory(n))) {
3051 } else if (n->name() == "DeltaCommand") {
3052 PBD::ID id(n->property("midi-source")->value());
3053 boost::shared_ptr<MidiSource> midi_source =
3054 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3056 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3058 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3061 } else if (n->name() == "DiffCommand") {
3062 PBD::ID id(n->property("midi-source")->value());
3063 boost::shared_ptr<MidiSource> midi_source =
3064 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3066 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3068 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3071 } else if (n->name() == "StatefulDiffCommand") {
3072 if ((c = stateful_diff_command_factory (n))) {
3073 ut->add_command (c);
3076 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3087 Session::config_changed (std::string p, bool ours)
3093 if (p == "seamless-loop") {
3095 } else if (p == "rf-speed") {
3097 } else if (p == "auto-loop") {
3099 } else if (p == "auto-input") {
3101 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3102 /* auto-input only makes a difference if we're rolling */
3104 boost::shared_ptr<RouteList> rl = routes.reader ();
3105 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3106 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3107 if (tr && tr->record_enabled ()) {
3108 tr->monitor_input (!config.get_auto_input());
3113 } else if (p == "punch-in") {
3117 if ((location = _locations.auto_punch_location()) != 0) {
3119 if (config.get_punch_in ()) {
3120 replace_event (SessionEvent::PunchIn, location->start());
3122 remove_event (location->start(), SessionEvent::PunchIn);
3126 } else if (p == "punch-out") {
3130 if ((location = _locations.auto_punch_location()) != 0) {
3132 if (config.get_punch_out()) {
3133 replace_event (SessionEvent::PunchOut, location->end());
3135 clear_events (SessionEvent::PunchOut);
3139 } else if (p == "edit-mode") {
3141 Glib::Mutex::Lock lm (playlists->lock);
3143 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3144 (*i)->set_edit_mode (Config->get_edit_mode ());
3147 } else if (p == "use-video-sync") {
3149 waiting_for_sync_offset = config.get_use_video_sync();
3151 } else if (p == "mmc-control") {
3153 //poke_midi_thread ();
3155 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3158 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3161 } else if (p == "mmc-send-id") {
3164 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3167 } else if (p == "midi-control") {
3169 //poke_midi_thread ();
3171 } else if (p == "raid-path") {
3173 setup_raid_path (config.get_raid_path());
3175 } else if (p == "timecode-format") {
3179 } else if (p == "video-pullup") {
3183 } else if (p == "seamless-loop") {
3185 if (play_loop && transport_rolling()) {
3186 // to reset diskstreams etc
3187 request_play_loop (true);
3190 } else if (p == "rf-speed") {
3192 cumulative_rf_motion = 0;
3195 } else if (p == "click-sound") {
3197 setup_click_sounds (1);
3199 } else if (p == "click-emphasis-sound") {
3201 setup_click_sounds (-1);
3203 } else if (p == "clicking") {
3205 if (Config->get_clicking()) {
3206 if (_click_io && click_data) { // don't require emphasis data
3213 } else if (p == "send-mtc") {
3215 /* only set the internal flag if we have
3219 if (_mtc_port != 0) {
3220 session_send_mtc = Config->get_send_mtc();
3221 if (session_send_mtc) {
3222 /* mark us ready to send */
3223 next_quarter_frame_to_send = 0;
3226 session_send_mtc = false;
3229 } else if (p == "send-mmc") {
3231 /* only set the internal flag if we have
3235 if (_mmc_port != 0) {
3236 session_send_mmc = Config->get_send_mmc();
3239 session_send_mmc = false;
3242 } else if (p == "midi-feedback") {
3244 /* only set the internal flag if we have
3248 if (_mtc_port != 0) {
3249 session_midi_feedback = Config->get_midi_feedback();
3252 } else if (p == "jack-time-master") {
3254 engine().reset_timebase ();
3256 } else if (p == "native-file-header-format") {
3258 if (!first_file_header_format_reset) {
3259 reset_native_file_format ();
3262 first_file_header_format_reset = false;
3264 } else if (p == "native-file-data-format") {
3266 if (!first_file_data_format_reset) {
3267 reset_native_file_format ();
3270 first_file_data_format_reset = false;
3272 } else if (p == "external-sync") {
3273 if (!config.get_external_sync()) {
3274 drop_sync_source ();
3276 switch_to_sync_source (config.get_sync_source());
3278 } else if (p == "remote-model") {
3279 set_remote_control_ids ();
3280 } else if (p == "denormal-model") {
3282 } else if (p == "history-depth") {
3283 set_history_depth (Config->get_history_depth());
3284 } else if (p == "sync-all-route-ordering") {
3285 sync_order_keys ("session");
3286 } else if (p == "initial-program-change") {
3288 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3291 buf[0] = MIDI::program; // channel zero by default
3292 buf[1] = (Config->get_initial_program_change() & 0x7f);
3294 _mmc_port->midimsg (buf, sizeof (buf), 0);
3296 } else if (p == "initial-program-change") {
3298 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3299 MIDI::byte* buf = new MIDI::byte[2];
3301 buf[0] = MIDI::program; // channel zero by default
3302 buf[1] = (Config->get_initial_program_change() & 0x7f);
3303 // deliver_midi (_mmc_port, buf, 2);
3305 } else if (p == "solo-mute-override") {
3306 // catch_up_on_solo_mute_override ();
3307 } else if (p == "listen-position") {
3308 listen_position_changed ();
3309 } else if (p == "solo-control-is-listen-control") {
3310 solo_control_mode_changed ();
3318 Session::set_history_depth (uint32_t d)
3320 _history.set_depth (d);
3324 Session::load_diskstreams_2X (XMLNode const & node, int)
3327 XMLNodeConstIterator citer;
3329 clist = node.children();
3331 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3334 /* diskstreams added automatically by DiskstreamCreated handler */
3335 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3336 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3337 _diskstreams_2X.push_back (dsp);
3339 error << _("Session: unknown diskstream type in XML") << endmsg;
3343 catch (failed_constructor& err) {
3344 error << _("Session: could not load diskstream via XML state") << endmsg;