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();
735 tree.set_root (&get_state());
737 if (snapshot_name.empty()) {
738 snapshot_name = _current_snapshot_name;
739 } else if (switch_to_snapshot) {
740 _current_snapshot_name = snapshot_name;
745 /* proper save: use statefile_suffix (.ardour in English) */
747 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
749 /* make a backup copy of the old file */
751 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
752 // create_backup_file will log the error
758 /* pending save: use pending_suffix (.pending in English) */
759 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
762 sys::path tmp_path(_session_dir->root_path());
764 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
766 // cerr << "actually writing state to " << xml_path.to_string() << endl;
768 if (!tree.write (tmp_path.to_string())) {
769 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
770 sys::remove (tmp_path);
775 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
776 error << string_compose (_("could not rename temporary session file %1 to %2"),
777 tmp_path.to_string(), xml_path.to_string()) << endmsg;
778 sys::remove (tmp_path);
785 save_history (snapshot_name);
787 bool was_dirty = dirty();
789 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
792 DirtyChanged (); /* EMIT SIGNAL */
795 StateSaved (snapshot_name); /* EMIT SIGNAL */
802 Session::restore_state (string snapshot_name)
804 if (load_state (snapshot_name) == 0) {
805 set_state (*state_tree->root(), Stateful::loading_state_version);
812 Session::load_state (string snapshot_name)
817 state_was_pending = false;
819 /* check for leftover pending state from a crashed capture attempt */
821 sys::path xmlpath(_session_dir->root_path());
822 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
824 if (sys::exists (xmlpath)) {
826 /* there is pending state from a crashed capture attempt */
828 if (*AskAboutPendingState()) {
829 state_was_pending = true;
833 if (!state_was_pending) {
834 xmlpath = _session_dir->root_path();
835 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
838 if (!sys::exists (xmlpath)) {
839 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
843 state_tree = new XMLTree;
847 /* writable() really reflects the whole folder, but if for any
848 reason the session state file can't be written to, still
852 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
856 if (!state_tree->read (xmlpath.to_string())) {
857 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
863 XMLNode& root (*state_tree->root());
865 if (root.name() != X_("Session")) {
866 error << string_compose (_("Session file %1 is not a session"), xmlpath.to_string()) << endmsg;
872 const XMLProperty* prop;
874 if ((prop = root.property ("version")) == 0) {
875 /* no version implies very old version of Ardour */
876 Stateful::loading_state_version = 1000;
882 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
883 Stateful::loading_state_version = (major * 1000) + minor;
886 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
888 sys::path backup_path(_session_dir->root_path());
890 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
892 // only create a backup once
893 if (sys::exists (backup_path)) {
897 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with %3 versions before 2.0 from now on"),
898 xmlpath.to_string(), backup_path.to_string(), PROGRAM_NAME)
903 sys::copy_file (xmlpath, backup_path);
905 catch(sys::filesystem_error& ex)
907 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
908 xmlpath.to_string(), ex.what())
918 Session::load_options (const XMLNode& node)
920 LocaleGuard lg (X_("POSIX"));
921 config.set_variables (node);
932 Session::get_template()
934 /* if we don't disable rec-enable, diskstreams
935 will believe they need to store their capture
936 sources in their state node.
939 disable_record (false);
945 Session::state(bool full_state)
947 XMLNode* node = new XMLNode("Session");
950 // store libardour version, just in case
952 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
953 node->add_property("version", string(buf));
955 /* store configuration settings */
959 node->add_property ("name", _name);
960 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
961 node->add_property ("sample-rate", buf);
963 if (session_dirs.size() > 1) {
967 vector<space_and_path>::iterator i = session_dirs.begin();
968 vector<space_and_path>::iterator next;
970 ++i; /* skip the first one */
974 while (i != session_dirs.end()) {
978 if (next != session_dirs.end()) {
988 child = node->add_child ("Path");
989 child->add_content (p);
993 /* save the ID counter */
995 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
996 node->add_property ("id-counter", buf);
998 /* various options */
1000 node->add_child_nocopy (config.get_variables ());
1002 node->add_child_nocopy (_metadata->get_state());
1004 child = node->add_child ("Sources");
1007 Glib::Mutex::Lock sl (source_lock);
1009 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
1011 /* Don't save information about non-destructive file sources that are empty */
1012 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
1014 boost::shared_ptr<AudioFileSource> fs;
1015 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
1016 if (!fs->destructive()) {
1017 if (fs->length(fs->timeline_position()) == 0) {
1023 child->add_child_nocopy (siter->second->get_state());
1027 child = node->add_child ("Regions");
1030 Glib::Mutex::Lock rl (region_lock);
1031 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
1032 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
1033 boost::shared_ptr<Region> r = i->second;
1034 /* only store regions not attached to playlists */
1035 if (r->playlist() == 0) {
1036 child->add_child_nocopy (r->state (true));
1042 node->add_child_nocopy (_locations.get_state());
1044 // for a template, just create a new Locations, populate it
1045 // with the default start and end, and get the state for that.
1047 Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
1048 range->set (max_frames, 0);
1050 node->add_child_nocopy (loc.get_state());
1053 child = node->add_child ("Bundles");
1055 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1056 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1057 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1059 child->add_child_nocopy (b->get_state());
1064 child = node->add_child ("Routes");
1066 boost::shared_ptr<RouteList> r = routes.reader ();
1068 RoutePublicOrderSorter cmp;
1069 RouteList public_order (*r);
1070 public_order.sort (cmp);
1072 /* the sort should have put control outs first */
1075 assert (_monitor_out == public_order.front());
1078 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1079 if (!(*i)->is_hidden()) {
1081 child->add_child_nocopy ((*i)->get_state());
1083 child->add_child_nocopy ((*i)->get_template());
1089 playlists->add_state (node, full_state);
1091 child = node->add_child ("RouteGroups");
1092 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1093 child->add_child_nocopy ((*i)->get_state());
1097 child = node->add_child ("Click");
1098 child->add_child_nocopy (_click_io->state (full_state));
1102 child = node->add_child ("NamedSelections");
1103 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1105 child->add_child_nocopy ((*i)->get_state());
1110 node->add_child_nocopy (_tempo_map->get_state());
1112 node->add_child_nocopy (get_control_protocol_state());
1115 node->add_child_copy (*_extra_xml);
1122 Session::get_control_protocol_state ()
1124 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1125 return cpm.get_state();
1129 Session::set_state (const XMLNode& node, int version)
1133 const XMLProperty* prop;
1136 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1138 if (node.name() != X_("Session")){
1139 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1143 if ((prop = node.property ("version")) != 0) {
1144 version = atoi (prop->value ()) * 1000;
1147 if ((prop = node.property ("name")) != 0) {
1148 _name = prop->value ();
1151 if ((prop = node.property (X_("sample-rate"))) != 0) {
1153 _nominal_frame_rate = atoi (prop->value());
1155 if (_nominal_frame_rate != _current_frame_rate) {
1156 if (*AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1162 setup_raid_path(_session_dir->root_path().to_string());
1164 if ((prop = node.property (X_("id-counter"))) != 0) {
1166 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1167 ID::init_counter (x);
1169 /* old sessions used a timebased counter, so fake
1170 the startup ID counter based on a standard
1175 ID::init_counter (now);
1179 IO::disable_connecting ();
1181 /* Object loading order:
1186 MIDI Control // relies on data from Options/Config
1199 if ((child = find_named_node (node, "Extra")) != 0) {
1200 _extra_xml = new XMLNode (*child);
1203 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1204 load_options (*child);
1205 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1206 load_options (*child);
1208 error << _("Session: XML state has no options section") << endmsg;
1211 if (use_config_midi_ports ()) {
1214 if (version >= 3000) {
1215 if ((child = find_named_node (node, "Metadata")) == 0) {
1216 warning << _("Session: XML state has no metadata section") << endmsg;
1217 } else if (_metadata->set_state (*child, version)) {
1222 if ((child = find_named_node (node, "Locations")) == 0) {
1223 error << _("Session: XML state has no locations section") << endmsg;
1225 } else if (_locations.set_state (*child, version)) {
1231 if ((location = _locations.auto_loop_location()) != 0) {
1232 set_auto_loop_location (location);
1235 if ((location = _locations.auto_punch_location()) != 0) {
1236 set_auto_punch_location (location);
1239 if ((location = _locations.session_range_location()) != 0) {
1240 delete _session_range_location;
1241 _session_range_location = location;
1244 if (_session_range_location) {
1245 AudioFileSource::set_header_position_offset (_session_range_location->start());
1248 if ((child = find_named_node (node, "Sources")) == 0) {
1249 error << _("Session: XML state has no sources section") << endmsg;
1251 } else if (load_sources (*child)) {
1255 if ((child = find_named_node (node, "Regions")) == 0) {
1256 error << _("Session: XML state has no Regions section") << endmsg;
1258 } else if (load_regions (*child)) {
1262 if ((child = find_named_node (node, "Playlists")) == 0) {
1263 error << _("Session: XML state has no playlists section") << endmsg;
1265 } else if (playlists->load (*this, *child)) {
1269 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1271 } else if (playlists->load_unused (*this, *child)) {
1275 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1276 if (load_named_selections (*child)) {
1281 if (version >= 3000) {
1282 if ((child = find_named_node (node, "Bundles")) == 0) {
1283 warning << _("Session: XML state has no bundles section") << endmsg;
1286 /* We can't load Bundles yet as they need to be able
1287 to convert from port names to Port objects, which can't happen until
1289 _bundle_xml_node = new XMLNode (*child);
1293 if ((child = find_named_node (node, "TempoMap")) == 0) {
1294 error << _("Session: XML state has no Tempo Map section") << endmsg;
1296 } else if (_tempo_map->set_state (*child, version)) {
1300 if (version < 3000) {
1301 if ((child = find_named_node (node, X_("DiskStreams"))) == 0) {
1302 error << _("Session: XML state has no diskstreams section") << endmsg;
1304 } else if (load_diskstreams_2X (*child, version)) {
1309 if ((child = find_named_node (node, "Routes")) == 0) {
1310 error << _("Session: XML state has no routes section") << endmsg;
1312 } else if (load_routes (*child, version)) {
1316 /* our diskstreams list is no longer needed as they are now all owned by their Route */
1317 _diskstreams_2X.clear ();
1319 if (version >= 3000) {
1321 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1322 error << _("Session: XML state has no route groups section") << endmsg;
1324 } else if (load_route_groups (*child, version)) {
1328 } else if (version < 3000) {
1330 if ((child = find_named_node (node, "EditGroups")) == 0) {
1331 error << _("Session: XML state has no edit groups section") << endmsg;
1333 } else if (load_route_groups (*child, version)) {
1337 if ((child = find_named_node (node, "MixGroups")) == 0) {
1338 error << _("Session: XML state has no mix groups section") << endmsg;
1340 } else if (load_route_groups (*child, version)) {
1345 if ((child = find_named_node (node, "Click")) == 0) {
1346 warning << _("Session: XML state has no click section") << endmsg;
1347 } else if (_click_io) {
1348 _click_io->set_state (*child, version);
1351 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1352 ControlProtocolManager::instance().set_protocol_states (*child);
1355 /* here beginneth the second phase ... */
1357 StateReady (); /* EMIT SIGNAL */
1366 Session::load_routes (const XMLNode& node, int version)
1369 XMLNodeConstIterator niter;
1370 RouteList new_routes;
1372 nlist = node.children();
1376 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1378 boost::shared_ptr<Route> route;
1379 if (version < 3000) {
1380 route = XMLRouteFactory_2X (**niter, version);
1382 route = XMLRouteFactory (**niter, version);
1386 error << _("Session: cannot create Route from XML description.") << endmsg;
1390 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1392 new_routes.push_back (route);
1395 add_routes (new_routes, false);
1400 boost::shared_ptr<Route>
1401 Session::XMLRouteFactory (const XMLNode& node, int version)
1403 boost::shared_ptr<Route> ret;
1405 if (node.name() != "Route") {
1409 XMLNode* ds_child = find_named_node (node, X_("Diskstream"));
1411 DataType type = DataType::AUDIO;
1412 const XMLProperty* prop = node.property("default-type");
1415 type = DataType (prop->value());
1418 assert (type != DataType::NIL);
1424 if (type == DataType::AUDIO) {
1425 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1428 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1431 if (track->init()) {
1436 if (track->set_state (node, version)) {
1441 boost_debug_shared_ptr_mark_interesting (track, "Track");
1445 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1447 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1448 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1458 boost::shared_ptr<Route>
1459 Session::XMLRouteFactory_2X (const XMLNode& node, int version)
1461 boost::shared_ptr<Route> ret;
1463 if (node.name() != "Route") {
1467 XMLProperty const * ds_prop = node.property (X_("diskstream-id"));
1469 ds_prop = node.property (X_("diskstream"));
1472 DataType type = DataType::AUDIO;
1473 const XMLProperty* prop = node.property("default-type");
1476 type = DataType (prop->value());
1479 assert (type != DataType::NIL);
1483 list<boost::shared_ptr<Diskstream> >::iterator i = _diskstreams_2X.begin ();
1484 while (i != _diskstreams_2X.end() && (*i)->id() != ds_prop->value()) {
1488 if (i == _diskstreams_2X.end()) {
1489 error << _("Could not find diskstream for route") << endmsg;
1490 return boost::shared_ptr<Route> ();
1495 if (type == DataType::AUDIO) {
1496 track = new AudioTrack (*this, X_("toBeResetFroXML"));
1499 track = new MidiTrack (*this, X_("toBeResetFroXML"));
1502 if (track->init()) {
1507 if (track->set_state (node, version)) {
1512 track->set_diskstream (*i);
1514 boost_debug_shared_ptr_mark_interesting (track, "Track");
1518 Route* rt = new Route (*this, X_("toBeResetFroXML"));
1520 if (rt->init () == 0 && rt->set_state (node, version) == 0) {
1521 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1532 Session::load_regions (const XMLNode& node)
1535 XMLNodeConstIterator niter;
1536 boost::shared_ptr<Region> region;
1538 nlist = node.children();
1542 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1543 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1544 error << _("Session: cannot create Region from XML description.");
1545 const XMLProperty *name = (**niter).property("name");
1548 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1558 boost::shared_ptr<Region>
1559 Session::XMLRegionFactory (const XMLNode& node, bool full)
1561 const XMLProperty* type = node.property("type");
1565 if ( !type || type->value() == "audio" ) {
1567 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1569 } else if (type->value() == "midi") {
1571 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1575 } catch (failed_constructor& err) {
1576 return boost::shared_ptr<Region> ();
1579 return boost::shared_ptr<Region> ();
1582 boost::shared_ptr<AudioRegion>
1583 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1585 const XMLProperty* prop;
1586 boost::shared_ptr<Source> source;
1587 boost::shared_ptr<AudioSource> as;
1589 SourceList master_sources;
1590 uint32_t nchans = 1;
1593 if (node.name() != X_("Region")) {
1594 return boost::shared_ptr<AudioRegion>();
1597 if ((prop = node.property (X_("channels"))) != 0) {
1598 nchans = atoi (prop->value().c_str());
1601 if ((prop = node.property ("name")) == 0) {
1602 cerr << "no name for this region\n";
1606 if ((prop = node.property (X_("source-0"))) == 0) {
1607 if ((prop = node.property ("source")) == 0) {
1608 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1609 return boost::shared_ptr<AudioRegion>();
1613 PBD::ID s_id (prop->value());
1615 if ((source = source_by_id (s_id)) == 0) {
1616 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1617 return boost::shared_ptr<AudioRegion>();
1620 as = boost::dynamic_pointer_cast<AudioSource>(source);
1622 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1623 return boost::shared_ptr<AudioRegion>();
1626 sources.push_back (as);
1628 /* pickup other channels */
1630 for (uint32_t n=1; n < nchans; ++n) {
1631 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1632 if ((prop = node.property (buf)) != 0) {
1634 PBD::ID id2 (prop->value());
1636 if ((source = source_by_id (id2)) == 0) {
1637 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1638 return boost::shared_ptr<AudioRegion>();
1641 as = boost::dynamic_pointer_cast<AudioSource>(source);
1643 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1644 return boost::shared_ptr<AudioRegion>();
1646 sources.push_back (as);
1650 for (uint32_t n = 0; n < nchans; ++n) {
1651 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1652 if ((prop = node.property (buf)) != 0) {
1654 PBD::ID id2 (prop->value());
1656 if ((source = source_by_id (id2)) == 0) {
1657 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1658 return boost::shared_ptr<AudioRegion>();
1661 as = boost::dynamic_pointer_cast<AudioSource>(source);
1663 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1664 return boost::shared_ptr<AudioRegion>();
1666 master_sources.push_back (as);
1671 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1673 /* a final detail: this is the one and only place that we know how long missing files are */
1675 if (region->whole_file()) {
1676 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1677 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1679 sfp->set_length (region->length());
1684 if (!master_sources.empty()) {
1685 if (master_sources.size() != nchans) {
1686 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1688 region->set_master_sources (master_sources);
1696 catch (failed_constructor& err) {
1697 return boost::shared_ptr<AudioRegion>();
1701 boost::shared_ptr<MidiRegion>
1702 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1704 const XMLProperty* prop;
1705 boost::shared_ptr<Source> source;
1706 boost::shared_ptr<MidiSource> ms;
1708 uint32_t nchans = 1;
1710 if (node.name() != X_("Region")) {
1711 return boost::shared_ptr<MidiRegion>();
1714 if ((prop = node.property (X_("channels"))) != 0) {
1715 nchans = atoi (prop->value().c_str());
1718 if ((prop = node.property ("name")) == 0) {
1719 cerr << "no name for this region\n";
1723 // Multiple midi channels? that's just crazy talk
1724 assert(nchans == 1);
1726 if ((prop = node.property (X_("source-0"))) == 0) {
1727 if ((prop = node.property ("source")) == 0) {
1728 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1729 return boost::shared_ptr<MidiRegion>();
1733 PBD::ID s_id (prop->value());
1735 if ((source = source_by_id (s_id)) == 0) {
1736 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1737 return boost::shared_ptr<MidiRegion>();
1740 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1742 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1743 return boost::shared_ptr<MidiRegion>();
1746 sources.push_back (ms);
1749 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1750 /* a final detail: this is the one and only place that we know how long missing files are */
1752 if (region->whole_file()) {
1753 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1754 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1756 sfp->set_length (region->length());
1764 catch (failed_constructor& err) {
1765 return boost::shared_ptr<MidiRegion>();
1770 Session::get_sources_as_xml ()
1773 XMLNode* node = new XMLNode (X_("Sources"));
1774 Glib::Mutex::Lock lm (source_lock);
1776 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1777 node->add_child_nocopy (i->second->get_state());
1784 Session::path_from_region_name (DataType type, string name, string identifier)
1786 char buf[PATH_MAX+1];
1788 SessionDirectory sdir(get_best_session_directory_for_new_source());
1789 sys::path source_dir = ((type == DataType::AUDIO)
1790 ? sdir.sound_path() : sdir.midi_path());
1792 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1794 for (n = 0; n < 999999; ++n) {
1795 if (identifier.length()) {
1796 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1797 identifier.c_str(), n, ext.c_str());
1799 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1803 sys::path source_path = source_dir / buf;
1805 if (!sys::exists (source_path)) {
1806 return source_path.to_string();
1810 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1819 Session::load_sources (const XMLNode& node)
1822 XMLNodeConstIterator niter;
1823 boost::shared_ptr<Source> source;
1825 nlist = node.children();
1829 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1831 if ((source = XMLSourceFactory (**niter)) == 0) {
1832 error << _("Session: cannot create Source from XML description.") << endmsg;
1834 } catch (MissingSource& err) {
1835 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1836 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1843 boost::shared_ptr<Source>
1844 Session::XMLSourceFactory (const XMLNode& node)
1846 if (node.name() != "Source") {
1847 return boost::shared_ptr<Source>();
1851 /* note: do peak building in another thread when loading session state */
1852 return SourceFactory::create (*this, node, true);
1855 catch (failed_constructor& err) {
1856 error << string_compose (_("Found a sound file that cannot be used by %1. Talk to the progammers."), PROGRAM_NAME) << endmsg;
1857 return boost::shared_ptr<Source>();
1862 Session::save_template (string template_name)
1866 if (_state_of_the_state & CannotSave) {
1870 sys::path user_template_dir(user_template_directory());
1874 sys::create_directories (user_template_dir);
1876 catch(sys::filesystem_error& ex)
1878 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1879 user_template_dir.to_string(), ex.what()) << endmsg;
1883 tree.set_root (&get_template());
1885 sys::path template_file_path(user_template_dir);
1886 template_file_path /= template_name + template_suffix;
1888 if (sys::exists (template_file_path))
1890 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1891 template_file_path.to_string()) << endmsg;
1895 if (!tree.write (template_file_path.to_string())) {
1896 error << _("mix template not saved") << endmsg;
1904 Session::rename_template (string old_name, string new_name)
1906 sys::path old_path (user_template_directory());
1907 old_path /= old_name + template_suffix;
1909 sys::path new_path(user_template_directory());
1910 new_path /= new_name + template_suffix;
1912 if (sys::exists (new_path)) {
1913 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1914 new_path.to_string()) << endmsg;
1919 sys::rename (old_path, new_path);
1927 Session::delete_template (string name)
1929 sys::path path = user_template_directory();
1930 path /= name + template_suffix;
1941 Session::refresh_disk_space ()
1944 struct statfs statfsbuf;
1945 vector<space_and_path>::iterator i;
1946 Glib::Mutex::Lock lm (space_lock);
1949 /* get freespace on every FS that is part of the session path */
1951 _total_free_4k_blocks = 0;
1953 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1954 statfs ((*i).path.c_str(), &statfsbuf);
1956 scale = statfsbuf.f_bsize/4096.0;
1958 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1959 _total_free_4k_blocks += (*i).blocks;
1965 Session::get_best_session_directory_for_new_source ()
1967 vector<space_and_path>::iterator i;
1968 string result = _session_dir->root_path().to_string();
1970 /* handle common case without system calls */
1972 if (session_dirs.size() == 1) {
1976 /* OK, here's the algorithm we're following here:
1978 We want to select which directory to use for
1979 the next file source to be created. Ideally,
1980 we'd like to use a round-robin process so as to
1981 get maximum performance benefits from splitting
1982 the files across multiple disks.
1984 However, in situations without much diskspace, an
1985 RR approach may end up filling up a filesystem
1986 with new files while others still have space.
1987 Its therefore important to pay some attention to
1988 the freespace in the filesystem holding each
1989 directory as well. However, if we did that by
1990 itself, we'd keep creating new files in the file
1991 system with the most space until it was as full
1992 as all others, thus negating any performance
1993 benefits of this RAID-1 like approach.
1995 So, we use a user-configurable space threshold. If
1996 there are at least 2 filesystems with more than this
1997 much space available, we use RR selection between them.
1998 If not, then we pick the filesystem with the most space.
2000 This gets a good balance between the two
2004 refresh_disk_space ();
2006 int free_enough = 0;
2008 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2009 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2014 if (free_enough >= 2) {
2015 /* use RR selection process, ensuring that the one
2019 i = last_rr_session_dir;
2022 if (++i == session_dirs.end()) {
2023 i = session_dirs.begin();
2026 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
2027 if (create_session_directory ((*i).path)) {
2029 last_rr_session_dir = i;
2034 } while (i != last_rr_session_dir);
2038 /* pick FS with the most freespace (and that
2039 seems to actually work ...)
2042 vector<space_and_path> sorted;
2043 space_and_path_ascending_cmp cmp;
2045 sorted = session_dirs;
2046 sort (sorted.begin(), sorted.end(), cmp);
2048 for (i = sorted.begin(); i != sorted.end(); ++i) {
2049 if (create_session_directory ((*i).path)) {
2051 last_rr_session_dir = i;
2061 Session::load_named_selections (const XMLNode& node)
2064 XMLNodeConstIterator niter;
2067 nlist = node.children();
2071 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2073 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2074 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2082 Session::XMLNamedSelectionFactory (const XMLNode& node)
2085 return new NamedSelection (*this, node);
2088 catch (failed_constructor& err) {
2094 Session::automation_dir () const
2096 return Glib::build_filename (_path, "automation");
2100 Session::analysis_dir () const
2102 return Glib::build_filename (_path, "analysis");
2106 Session::load_bundles (XMLNode const & node)
2108 XMLNodeList nlist = node.children();
2109 XMLNodeConstIterator niter;
2113 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2114 if ((*niter)->name() == "InputBundle") {
2115 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2116 } else if ((*niter)->name() == "OutputBundle") {
2117 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2119 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2128 Session::load_route_groups (const XMLNode& node, int version)
2130 XMLNodeList nlist = node.children();
2131 XMLNodeConstIterator niter;
2135 if (version >= 3000) {
2137 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2138 if ((*niter)->name() == "RouteGroup") {
2139 RouteGroup* rg = new RouteGroup (*this, "");
2140 add_route_group (rg);
2141 rg->set_state (**niter, version);
2145 } else if (version < 3000) {
2147 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2148 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2149 RouteGroup* rg = new RouteGroup (*this, "");
2150 add_route_group (rg);
2151 rg->set_state (**niter, version);
2160 Session::auto_save()
2162 save_state (_current_snapshot_name);
2166 state_file_filter (const string &str, void */*arg*/)
2168 return (str.length() > strlen(statefile_suffix) &&
2169 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2173 bool operator()(const string* a, const string* b) {
2179 remove_end(string* state)
2181 string statename(*state);
2183 string::size_type start,end;
2184 if ((start = statename.find_last_of ('/')) != string::npos) {
2185 statename = statename.substr (start+1);
2188 if ((end = statename.rfind(".ardour")) == string::npos) {
2189 end = statename.length();
2192 return new string(statename.substr (0, end));
2196 Session::possible_states (string path)
2198 PathScanner scanner;
2199 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2201 transform(states->begin(), states->end(), states->begin(), remove_end);
2204 sort (states->begin(), states->end(), cmp);
2210 Session::possible_states () const
2212 return possible_states(_path);
2216 Session::add_route_group (RouteGroup* g)
2218 _route_groups.push_back (g);
2219 route_group_added (g); /* EMIT SIGNAL */
2224 Session::remove_route_group (RouteGroup& rg)
2226 list<RouteGroup*>::iterator i;
2228 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2229 _route_groups.erase (i);
2232 route_group_removed (); /* EMIT SIGNAL */
2238 Session::route_group_by_name (string name)
2240 list<RouteGroup *>::iterator i;
2242 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2243 if ((*i)->name() == name) {
2251 Session::start_reversible_command (const string& name)
2253 UndoTransaction* trans = new UndoTransaction();
2254 trans->set_name(name);
2259 Session::finish_reversible_command (UndoTransaction& ut)
2262 gettimeofday(&now, 0);
2263 ut.set_timestamp(now);
2268 Session::begin_reversible_command(const string& name)
2270 UndoTransaction* trans = new UndoTransaction();
2271 trans->set_name(name);
2273 if (!_current_trans.empty()) {
2274 _current_trans.top()->add_command (trans);
2276 _current_trans.push(trans);
2281 Session::commit_reversible_command(Command *cmd)
2283 assert(!_current_trans.empty());
2287 _current_trans.top()->add_command(cmd);
2290 if (_current_trans.top()->empty()) {
2291 _current_trans.pop();
2295 gettimeofday(&now, 0);
2296 _current_trans.top()->set_timestamp(now);
2298 _history.add(_current_trans.top());
2299 _current_trans.pop();
2303 accept_all_non_peak_files (const string& path, void */*arg*/)
2305 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2309 accept_all_state_files (const string& path, void */*arg*/)
2311 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2315 Session::find_all_sources (string path, set<string>& result)
2320 if (!tree.read (path)) {
2324 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2329 XMLNodeConstIterator niter;
2331 nlist = node->children();
2335 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2339 if ((prop = (*niter)->property (X_("type"))) == 0) {
2343 DataType type (prop->value());
2345 if ((prop = (*niter)->property (X_("name"))) == 0) {
2349 if (prop->value()[0] == '/') {
2350 /* external file, ignore */
2354 Glib::ustring found_path;
2358 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2359 result.insert (found_path);
2367 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2369 PathScanner scanner;
2370 vector<string*>* state_files;
2372 string this_snapshot_path;
2378 if (ripped[ripped.length()-1] == '/') {
2379 ripped = ripped.substr (0, ripped.length() - 1);
2382 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2384 if (state_files == 0) {
2389 this_snapshot_path = _path;
2390 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2391 this_snapshot_path += statefile_suffix;
2393 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2395 if (exclude_this_snapshot && **i == this_snapshot_path) {
2399 if (find_all_sources (**i, result) < 0) {
2407 struct RegionCounter {
2408 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2409 AudioSourceList::iterator iter;
2410 boost::shared_ptr<Region> region;
2413 RegionCounter() : count (0) {}
2417 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2419 return *AskAboutPlaylistDeletion (p);
2423 Session::cleanup_sources (CleanupReport& rep)
2425 // FIXME: needs adaptation to midi
2427 vector<boost::shared_ptr<Source> > dead_sources;
2428 PathScanner scanner;
2430 vector<space_and_path>::iterator i;
2431 vector<space_and_path>::iterator nexti;
2432 vector<string*>* soundfiles;
2433 vector<string> unused;
2434 set<string> all_sources;
2439 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2441 /* step 1: consider deleting all unused playlists */
2443 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2448 /* step 2: find all un-used sources */
2453 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2455 SourceMap::iterator tmp;
2460 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2464 if (!playlists->source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2465 dead_sources.push_back (i->second);
2466 i->second->drop_references ();
2472 /* build a list of all the possible sound directories for the session */
2474 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2479 SessionDirectory sdir ((*i).path);
2480 sound_path += sdir.sound_path().to_string();
2482 if (nexti != session_dirs.end()) {
2489 /* now do the same thing for the files that ended up in the sounds dir(s)
2490 but are not referenced as sources in any snapshot.
2493 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2495 if (soundfiles == 0) {
2499 /* find all sources, but don't use this snapshot because the
2500 state file on disk still references sources we may have already
2504 find_all_sources_across_snapshots (all_sources, true);
2506 /* add our current source list
2509 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2510 boost::shared_ptr<FileSource> fs;
2512 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2513 all_sources.insert (fs->path());
2517 char tmppath1[PATH_MAX+1];
2518 char tmppath2[PATH_MAX+1];
2520 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2525 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2527 realpath(spath.c_str(), tmppath1);
2528 realpath((*i).c_str(), tmppath2);
2530 if (strcmp(tmppath1, tmppath2) == 0) {
2537 unused.push_back (spath);
2541 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2543 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2544 struct stat statbuf;
2546 rep.paths.push_back (*x);
2547 if (stat ((*x).c_str(), &statbuf) == 0) {
2548 rep.space += statbuf.st_size;
2553 /* don't move the file across filesystems, just
2554 stick it in the `dead_sound_dir_name' directory
2555 on whichever filesystem it was already on.
2558 if ((*x).find ("/sounds/") != string::npos) {
2560 /* old school, go up 1 level */
2562 newpath = Glib::path_get_dirname (*x); // "sounds"
2563 newpath = Glib::path_get_dirname (newpath); // "session-name"
2567 /* new school, go up 4 levels */
2569 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2570 newpath = Glib::path_get_dirname (newpath); // "session-name"
2571 newpath = Glib::path_get_dirname (newpath); // "interchange"
2572 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2576 newpath += dead_sound_dir_name;
2578 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2579 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2584 newpath += Glib::path_get_basename ((*x));
2586 if (access (newpath.c_str(), F_OK) == 0) {
2588 /* the new path already exists, try versioning */
2590 char buf[PATH_MAX+1];
2594 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2597 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2598 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2602 if (version == 999) {
2603 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2607 newpath = newpath_v;
2612 /* it doesn't exist, or we can't read it or something */
2616 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2617 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2618 (*x), newpath, strerror (errno))
2623 /* see if there an easy to find peakfile for this file, and remove it.
2626 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2627 peakpath += peakfile_suffix;
2629 if (access (peakpath.c_str(), W_OK) == 0) {
2630 if (::unlink (peakpath.c_str()) != 0) {
2631 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2632 peakpath, _path, strerror (errno))
2634 /* try to back out */
2635 rename (newpath.c_str(), _path.c_str());
2643 /* dump the history list */
2647 /* save state so we don't end up a session file
2648 referring to non-existent sources.
2654 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2660 Session::cleanup_trash_sources (CleanupReport& rep)
2662 // FIXME: needs adaptation for MIDI
2664 vector<space_and_path>::iterator i;
2665 string dead_sound_dir;
2666 struct dirent* dentry;
2667 struct stat statbuf;
2673 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2675 dead_sound_dir = (*i).path;
2676 dead_sound_dir += dead_sound_dir_name;
2678 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2682 while ((dentry = readdir (dead)) != 0) {
2684 /* avoid '.' and '..' */
2686 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2687 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2693 fullpath = dead_sound_dir;
2695 fullpath += dentry->d_name;
2697 if (stat (fullpath.c_str(), &statbuf)) {
2701 if (!S_ISREG (statbuf.st_mode)) {
2705 if (unlink (fullpath.c_str())) {
2706 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2707 fullpath, strerror (errno))
2711 rep.paths.push_back (dentry->d_name);
2712 rep.space += statbuf.st_size;
2723 Session::set_dirty ()
2725 bool was_dirty = dirty();
2727 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2731 DirtyChanged(); /* EMIT SIGNAL */
2737 Session::set_clean ()
2739 bool was_dirty = dirty();
2741 _state_of_the_state = Clean;
2745 DirtyChanged(); /* EMIT SIGNAL */
2750 Session::set_deletion_in_progress ()
2752 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2756 Session::clear_deletion_in_progress ()
2758 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2762 Session::add_controllable (boost::shared_ptr<Controllable> c)
2764 /* this adds a controllable to the list managed by the Session.
2765 this is a subset of those managed by the Controllable class
2766 itself, and represents the only ones whose state will be saved
2767 as part of the session.
2770 Glib::Mutex::Lock lm (controllables_lock);
2771 controllables.insert (c);
2774 struct null_deleter { void operator()(void const *) const {} };
2777 Session::remove_controllable (Controllable* c)
2779 if (_state_of_the_state | Deletion) {
2783 Glib::Mutex::Lock lm (controllables_lock);
2785 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2787 if (x != controllables.end()) {
2788 controllables.erase (x);
2792 boost::shared_ptr<Controllable>
2793 Session::controllable_by_id (const PBD::ID& id)
2795 Glib::Mutex::Lock lm (controllables_lock);
2797 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2798 if ((*i)->id() == id) {
2803 return boost::shared_ptr<Controllable>();
2806 boost::shared_ptr<Controllable>
2807 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2809 boost::shared_ptr<Controllable> c;
2810 boost::shared_ptr<Route> r;
2812 switch (desc.top_level_type()) {
2813 case ControllableDescriptor::NamedRoute:
2815 std::string str = desc.top_level_name();
2816 if (str == "master") {
2818 } else if (str == "control" || str == "listen") {
2821 r = route_by_name (desc.top_level_name());
2826 case ControllableDescriptor::RemoteControlID:
2827 r = route_by_remote_id (desc.rid());
2835 switch (desc.subtype()) {
2836 case ControllableDescriptor::Gain:
2837 c = r->gain_control ();
2840 case ControllableDescriptor::Solo:
2841 c = r->solo_control();
2844 case ControllableDescriptor::Mute:
2845 c = r->mute_control();
2848 case ControllableDescriptor::Recenable:
2850 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2853 c = t->rec_enable_control ();
2858 case ControllableDescriptor::Pan:
2859 /* XXX pan control */
2862 case ControllableDescriptor::Balance:
2863 /* XXX simple pan control */
2866 case ControllableDescriptor::PluginParameter:
2868 uint32_t plugin = desc.target (0);
2869 uint32_t parameter_index = desc.target (1);
2871 /* revert to zero based counting */
2877 if (parameter_index > 0) {
2881 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2884 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2885 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2890 case ControllableDescriptor::SendGain:
2892 uint32_t send = desc.target (0);
2894 /* revert to zero-based counting */
2900 boost::shared_ptr<Processor> p = r->nth_send (send);
2903 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2904 boost::shared_ptr<Amp> a = s->amp();
2907 c = s->amp()->gain_control();
2914 /* relax and return a null pointer */
2922 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2925 Stateful::add_instant_xml (node, _path);
2928 if (write_to_config) {
2929 Config->add_instant_xml (node);
2934 Session::instant_xml (const string& node_name)
2936 return Stateful::instant_xml (node_name, _path);
2940 Session::save_history (string snapshot_name)
2948 if (snapshot_name.empty()) {
2949 snapshot_name = _current_snapshot_name;
2952 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2953 const string backup_filename = history_filename + backup_suffix;
2954 const sys::path xml_path = _session_dir->root_path() / history_filename;
2955 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2957 if (sys::exists (xml_path)) {
2960 sys::rename (xml_path, backup_path);
2962 catch (const sys::filesystem_error& err)
2964 error << _("could not backup old history file, current history not saved") << endmsg;
2969 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2973 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2975 if (!tree.write (xml_path.to_string()))
2977 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2981 sys::remove (xml_path);
2982 sys::rename (backup_path, xml_path);
2984 catch (const sys::filesystem_error& err)
2986 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2987 backup_path.to_string(), err.what()) << endmsg;
2997 Session::restore_history (string snapshot_name)
3001 if (snapshot_name.empty()) {
3002 snapshot_name = _current_snapshot_name;
3005 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
3006 const sys::path xml_path = _session_dir->root_path() / xml_filename;
3008 info << "Loading history from " << xml_path.to_string() << endmsg;
3010 if (!sys::exists (xml_path)) {
3011 info << string_compose (_("%1: no history file \"%2\" for this session."),
3012 _name, xml_path.to_string()) << endmsg;
3016 if (!tree.read (xml_path.to_string())) {
3017 error << string_compose (_("Could not understand session history file \"%1\""),
3018 xml_path.to_string()) << endmsg;
3025 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3028 UndoTransaction* ut = new UndoTransaction ();
3031 ut->set_name(t->property("name")->value());
3032 stringstream ss(t->property("tv-sec")->value());
3034 ss.str(t->property("tv-usec")->value());
3036 ut->set_timestamp(tv);
3038 for (XMLNodeConstIterator child_it = t->children().begin();
3039 child_it != t->children().end(); child_it++)
3041 XMLNode *n = *child_it;
3044 if (n->name() == "MementoCommand" ||
3045 n->name() == "MementoUndoCommand" ||
3046 n->name() == "MementoRedoCommand") {
3048 if ((c = memento_command_factory(n))) {
3052 } else if (n->name() == "DeltaCommand") {
3053 PBD::ID id(n->property("midi-source")->value());
3054 boost::shared_ptr<MidiSource> midi_source =
3055 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3057 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3059 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3062 } else if (n->name() == "DiffCommand") {
3063 PBD::ID id(n->property("midi-source")->value());
3064 boost::shared_ptr<MidiSource> midi_source =
3065 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3067 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3069 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3072 } else if (n->name() == "StatefulDiffCommand") {
3073 if ((c = stateful_diff_command_factory (n))) {
3074 ut->add_command (c);
3077 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3088 Session::config_changed (std::string p, bool ours)
3094 if (p == "seamless-loop") {
3096 } else if (p == "rf-speed") {
3098 } else if (p == "auto-loop") {
3100 } else if (p == "auto-input") {
3102 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3103 /* auto-input only makes a difference if we're rolling */
3105 boost::shared_ptr<RouteList> rl = routes.reader ();
3106 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
3107 boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
3108 if (tr && tr->record_enabled ()) {
3109 tr->monitor_input (!config.get_auto_input());
3114 } else if (p == "punch-in") {
3118 if ((location = _locations.auto_punch_location()) != 0) {
3120 if (config.get_punch_in ()) {
3121 replace_event (SessionEvent::PunchIn, location->start());
3123 remove_event (location->start(), SessionEvent::PunchIn);
3127 } else if (p == "punch-out") {
3131 if ((location = _locations.auto_punch_location()) != 0) {
3133 if (config.get_punch_out()) {
3134 replace_event (SessionEvent::PunchOut, location->end());
3136 clear_events (SessionEvent::PunchOut);
3140 } else if (p == "edit-mode") {
3142 Glib::Mutex::Lock lm (playlists->lock);
3144 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3145 (*i)->set_edit_mode (Config->get_edit_mode ());
3148 } else if (p == "use-video-sync") {
3150 waiting_for_sync_offset = config.get_use_video_sync();
3152 } else if (p == "mmc-control") {
3154 //poke_midi_thread ();
3156 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3159 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3162 } else if (p == "mmc-send-id") {
3165 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3168 } else if (p == "midi-control") {
3170 //poke_midi_thread ();
3172 } else if (p == "raid-path") {
3174 setup_raid_path (config.get_raid_path());
3176 } else if (p == "timecode-format") {
3180 } else if (p == "video-pullup") {
3184 } else if (p == "seamless-loop") {
3186 if (play_loop && transport_rolling()) {
3187 // to reset diskstreams etc
3188 request_play_loop (true);
3191 } else if (p == "rf-speed") {
3193 cumulative_rf_motion = 0;
3196 } else if (p == "click-sound") {
3198 setup_click_sounds (1);
3200 } else if (p == "click-emphasis-sound") {
3202 setup_click_sounds (-1);
3204 } else if (p == "clicking") {
3206 if (Config->get_clicking()) {
3207 if (_click_io && click_data) { // don't require emphasis data
3214 } else if (p == "send-mtc") {
3216 /* only set the internal flag if we have
3220 if (_mtc_port != 0) {
3221 session_send_mtc = Config->get_send_mtc();
3222 if (session_send_mtc) {
3223 /* mark us ready to send */
3224 next_quarter_frame_to_send = 0;
3227 session_send_mtc = false;
3230 } else if (p == "send-mmc") {
3232 /* only set the internal flag if we have
3236 if (_mmc_port != 0) {
3237 session_send_mmc = Config->get_send_mmc();
3240 session_send_mmc = false;
3243 } else if (p == "midi-feedback") {
3245 /* only set the internal flag if we have
3249 if (_mtc_port != 0) {
3250 session_midi_feedback = Config->get_midi_feedback();
3253 } else if (p == "jack-time-master") {
3255 engine().reset_timebase ();
3257 } else if (p == "native-file-header-format") {
3259 if (!first_file_header_format_reset) {
3260 reset_native_file_format ();
3263 first_file_header_format_reset = false;
3265 } else if (p == "native-file-data-format") {
3267 if (!first_file_data_format_reset) {
3268 reset_native_file_format ();
3271 first_file_data_format_reset = false;
3273 } else if (p == "external-sync") {
3274 if (!config.get_external_sync()) {
3275 drop_sync_source ();
3277 switch_to_sync_source (config.get_sync_source());
3279 } else if (p == "remote-model") {
3280 set_remote_control_ids ();
3281 } else if (p == "denormal-model") {
3283 } else if (p == "history-depth") {
3284 set_history_depth (Config->get_history_depth());
3285 } else if (p == "sync-all-route-ordering") {
3286 sync_order_keys ("session");
3287 } else if (p == "initial-program-change") {
3289 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3292 buf[0] = MIDI::program; // channel zero by default
3293 buf[1] = (Config->get_initial_program_change() & 0x7f);
3295 _mmc_port->midimsg (buf, sizeof (buf), 0);
3297 } else if (p == "initial-program-change") {
3299 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3300 MIDI::byte* buf = new MIDI::byte[2];
3302 buf[0] = MIDI::program; // channel zero by default
3303 buf[1] = (Config->get_initial_program_change() & 0x7f);
3304 // deliver_midi (_mmc_port, buf, 2);
3306 } else if (p == "solo-mute-override") {
3307 // catch_up_on_solo_mute_override ();
3308 } else if (p == "listen-position") {
3309 listen_position_changed ();
3310 } else if (p == "solo-control-is-listen-control") {
3311 solo_control_mode_changed ();
3319 Session::set_history_depth (uint32_t d)
3321 _history.set_depth (d);
3325 Session::load_diskstreams_2X (XMLNode const & node, int)
3328 XMLNodeConstIterator citer;
3330 clist = node.children();
3332 for (citer = clist.begin(); citer != clist.end(); ++citer) {
3335 /* diskstreams added automatically by DiskstreamCreated handler */
3336 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
3337 boost::shared_ptr<AudioDiskstream> dsp (new AudioDiskstream (*this, **citer));
3338 _diskstreams_2X.push_back (dsp);
3340 error << _("Session: unknown diskstream type in XML") << endmsg;
3344 catch (failed_constructor& err) {
3345 error << _("Session: could not load diskstream via XML state") << endmsg;