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"
68 #include "ardour/amp.h"
69 #include "ardour/audio_diskstream.h"
70 #include "ardour/audio_track.h"
71 #include "ardour/audioengine.h"
72 #include "ardour/audiofilesource.h"
73 #include "ardour/audioplaylist.h"
74 #include "ardour/audioregion.h"
75 #include "ardour/auditioner.h"
76 #include "ardour/buffer.h"
77 #include "ardour/butler.h"
78 #include "ardour/configuration.h"
79 #include "ardour/control_protocol_manager.h"
80 #include "ardour/crossfade.h"
81 #include "ardour/cycle_timer.h"
82 #include "ardour/directory_names.h"
83 #include "ardour/filename_extensions.h"
84 #include "ardour/io_processor.h"
85 #include "ardour/location.h"
86 #include "ardour/midi_diskstream.h"
87 #include "ardour/midi_patch_manager.h"
88 #include "ardour/midi_playlist.h"
89 #include "ardour/midi_region.h"
90 #include "ardour/midi_source.h"
91 #include "ardour/midi_track.h"
92 #include "ardour/named_selection.h"
93 #include "ardour/processor.h"
94 #include "ardour/region_command.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->StateChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
171 _non_soloed_outs_muted = false;
173 g_atomic_int_set (&processing_prohibited, 0);
174 _transport_speed = 0;
175 _last_transport_speed = 0;
176 _target_transport_speed = 0;
177 auto_play_legal = false;
178 transport_sub_state = 0;
179 _transport_frame = 0;
180 _requested_return_frame = -1;
181 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
182 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
183 g_atomic_int_set (&_record_status, Disabled);
184 loop_changing = false;
187 _last_roll_location = 0;
188 _last_record_location = 0;
189 pending_locate_frame = 0;
190 pending_locate_roll = false;
191 pending_locate_flush = false;
192 state_was_pending = false;
194 outbound_mtc_timecode_frame = 0;
195 next_quarter_frame_to_send = -1;
196 current_block_size = 0;
197 solo_update_disabled = false;
198 _have_captured = false;
199 _worst_output_latency = 0;
200 _worst_input_latency = 0;
201 _worst_track_latency = 0;
202 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
203 _was_seamless = Config->get_seamless_loop ();
205 session_send_mmc = false;
206 session_send_mtc = false;
207 g_atomic_int_set (&_playback_load, 100);
208 g_atomic_int_set (&_capture_load, 100);
209 g_atomic_int_set (&_playback_load_min, 100);
210 g_atomic_int_set (&_capture_load_min, 100);
213 _gain_automation_buffer = 0;
214 _pan_automation_buffer = 0;
216 pending_abort = false;
217 destructive_index = 0;
218 first_file_data_format_reset = true;
219 first_file_header_format_reset = true;
220 post_export_sync = false;
223 AudioDiskstream::allocate_working_buffers();
225 /* default short fade = 15ms */
227 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
228 SndFileSource::setup_standard_crossfades (*this, frame_rate());
230 last_mmc_step.tv_sec = 0;
231 last_mmc_step.tv_usec = 0;
234 /* click sounds are unset by default, which causes us to internal
235 waveforms for clicks.
239 click_emphasis_length = 0;
242 process_function = &Session::process_with_events;
244 if (config.get_use_video_sync()) {
245 waiting_for_sync_offset = true;
247 waiting_for_sync_offset = false;
250 last_timecode_when = 0;
251 _timecode_offset = 0;
252 _timecode_offset_negative = true;
253 last_timecode_valid = false;
257 last_rr_session_dir = session_dirs.begin();
258 refresh_disk_space ();
260 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
264 average_slave_delta = 1800; // !!! why 1800 ????
265 have_first_delta_accumulator = false;
266 delta_accumulator_cnt = 0;
267 _slave_state = Stopped;
269 _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
271 /* These are all static "per-class" signals */
273 RegionFactory::CheckNewRegion.connect_same_thread (*this, boost::bind (&Session::add_region, this, _1));
274 SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
275 PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
276 Processor::ProcessorCreated.connect_same_thread (*this, boost::bind (&Session::add_processor, this, _1));
277 AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
278 Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
279 IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));
281 /* stop IO objects from doing stuff until we're ready for them */
283 Delivery::disable_panners ();
284 IO::disable_connecting ();
288 Session::second_stage_init (bool new_session)
290 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
293 if (load_state (_current_snapshot_name)) {
296 remove_empty_sounds ();
299 if (_butler->start_thread()) {
303 if (start_midi_thread ()) {
307 // set_state() will call setup_raid_path(), but if it's a new session we need
308 // to call setup_raid_path() here.
311 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
315 setup_raid_path(_path);
318 /* we can't save till after ::when_engine_running() is called,
319 because otherwise we save state with no connections made.
320 therefore, we reset _state_of_the_state because ::set_state()
321 will have cleared it.
323 we also have to include Loading so that any events that get
324 generated between here and the end of ::when_engine_running()
325 will be processed directly rather than queued.
328 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
331 _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
332 _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
333 setup_click_sounds (0);
334 setup_midi_control ();
336 /* Pay attention ... */
338 _engine.Halted.connect_same_thread (*this, boost::bind (&Session::engine_halted, this));
339 _engine.Xrun.connect_same_thread (*this, boost::bind (&Session::xrun_recovery, this));
342 when_engine_running();
345 /* handle this one in a different way than all others, so that its clear what happened */
347 catch (AudioEngine::PortRegistrationFailure& err) {
348 error << err.what() << endmsg;
356 BootMessage (_("Reset Remote Controls"));
358 send_full_time_code (0);
359 _engine.transport_locate (0);
360 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
361 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
363 MidiClockTicker::instance().set_session (this);
364 MIDI::Name::MidiPatchManager::instance().set_session (this);
366 /* initial program change will be delivered later; see ::config_changed() */
368 BootMessage (_("Reset Control Protocols"));
370 ControlProtocolManager::instance().set_session (this);
372 config.set_end_marker_is_free (new_session);
374 _state_of_the_state = Clean;
376 DirtyChanged (); /* EMIT SIGNAL */
378 if (state_was_pending) {
379 save_state (_current_snapshot_name);
380 remove_pending_capture_state ();
381 state_was_pending = false;
384 BootMessage (_("Session loading complete"));
390 Session::raid_path () const
392 SearchPath raid_search_path;
394 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
395 raid_search_path += sys::path((*i).path);
398 return raid_search_path.to_string ();
402 Session::setup_raid_path (string path)
411 session_dirs.clear ();
413 SearchPath search_path(path);
414 SearchPath sound_search_path;
415 SearchPath midi_search_path;
417 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
418 sp.path = (*i).to_string ();
419 sp.blocks = 0; // not needed
420 session_dirs.push_back (sp);
422 SessionDirectory sdir(sp.path);
424 sound_search_path += sdir.sound_path ();
425 midi_search_path += sdir.midi_path ();
428 // set the search path for each data type
429 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
430 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
432 // reset the round-robin soundfile path thingie
433 last_rr_session_dir = session_dirs.begin();
437 Session::path_is_within_session (const std::string& path)
439 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
440 if (path.find ((*i).path) == 0) {
448 Session::ensure_subdirs ()
452 dir = session_directory().peak_path().to_string();
454 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
455 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
459 dir = session_directory().sound_path().to_string();
461 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
462 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
466 dir = session_directory().midi_path().to_string();
468 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
469 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
473 dir = session_directory().dead_sound_path().to_string();
475 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
476 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
480 dir = session_directory().export_path().to_string();
482 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
483 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
487 dir = analysis_dir ();
489 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
490 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
498 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
501 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
502 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
506 if (ensure_subdirs ()) {
510 /* check new_session so we don't overwrite an existing one */
512 if (!mix_template.empty()) {
513 std::string in_path = mix_template;
515 ifstream in(in_path.c_str());
518 string out_path = _path;
520 out_path += statefile_suffix;
522 ofstream out(out_path.c_str());
527 // okay, session is set up. Treat like normal saved
528 // session from now on.
534 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
540 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
547 /* Instantiate metadata */
549 _metadata = new SessionMetadata ();
551 /* set initial start + end point */
553 start_location->set_end (0);
554 _locations.add (start_location);
556 end_location->set_end (initial_length);
557 _locations.add (end_location);
559 _state_of_the_state = Clean;
568 Session::load_diskstreams (const XMLNode& node)
571 XMLNodeConstIterator citer;
573 clist = node.children();
575 for (citer = clist.begin(); citer != clist.end(); ++citer) {
578 /* diskstreams added automatically by DiskstreamCreated handler */
579 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
580 AudioDiskstream* dsp (new AudioDiskstream (*this, **citer));
581 boost::shared_ptr<AudioDiskstream> dstream (dsp);
582 add_diskstream (dstream);
583 } else if ((*citer)->name() == "MidiDiskstream") {
584 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
585 add_diskstream (dstream);
587 error << _("Session: unknown diskstream type in XML") << endmsg;
591 catch (failed_constructor& err) {
592 error << _("Session: could not load diskstream via XML state") << endmsg;
601 Session::maybe_write_autosave()
603 if (dirty() && record_status() != Recording) {
604 save_state("", true);
609 Session::remove_pending_capture_state ()
611 sys::path pending_state_file_path(_session_dir->root_path());
613 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
617 sys::remove (pending_state_file_path);
619 catch(sys::filesystem_error& ex)
621 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
622 pending_state_file_path.to_string(), ex.what()) << endmsg;
626 /** Rename a state file.
627 * @param snapshot_name Snapshot name.
630 Session::rename_state (string old_name, string new_name)
632 if (old_name == _current_snapshot_name || old_name == _name) {
633 /* refuse to rename the current snapshot or the "main" one */
637 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
638 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
640 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
641 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
645 sys::rename (old_xml_path, new_xml_path);
647 catch (const sys::filesystem_error& err)
649 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
650 old_name, new_name, err.what()) << endmsg;
654 /** Remove a state file.
655 * @param snapshot_name Snapshot name.
658 Session::remove_state (string snapshot_name)
660 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
661 // refuse to remove the current snapshot or the "main" one
665 sys::path xml_path(_session_dir->root_path());
667 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
669 if (!create_backup_file (xml_path)) {
670 // don't remove it if a backup can't be made
671 // create_backup_file will log the error.
676 sys::remove (xml_path);
680 Session::save_state (string snapshot_name, bool pending)
683 sys::path xml_path(_session_dir->root_path());
685 if (!_writable || (_state_of_the_state & CannotSave)) {
689 if (!_engine.connected ()) {
690 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
695 /* tell sources we're saving first, in case they write out to a new file
696 * which should be saved with the state rather than the old one */
697 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
698 i->second->session_saved();
700 tree.set_root (&get_state());
702 if (snapshot_name.empty()) {
703 snapshot_name = _current_snapshot_name;
708 /* proper save: use statefile_suffix (.ardour in English) */
710 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
712 /* make a backup copy of the old file */
714 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
715 // create_backup_file will log the error
721 /* pending save: use pending_suffix (.pending in English) */
722 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
725 sys::path tmp_path(_session_dir->root_path());
727 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
729 // cerr << "actually writing state to " << xml_path.to_string() << endl;
731 if (!tree.write (tmp_path.to_string())) {
732 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
733 sys::remove (tmp_path);
738 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
739 error << string_compose (_("could not rename temporary session file %1 to %2"),
740 tmp_path.to_string(), xml_path.to_string()) << endmsg;
741 sys::remove (tmp_path);
748 save_history (snapshot_name);
750 bool was_dirty = dirty();
752 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
755 DirtyChanged (); /* EMIT SIGNAL */
758 StateSaved (snapshot_name); /* EMIT SIGNAL */
765 Session::restore_state (string snapshot_name)
767 if (load_state (snapshot_name) == 0) {
768 set_state (*state_tree->root(), Stateful::loading_state_version);
775 Session::load_state (string snapshot_name)
780 state_was_pending = false;
782 /* check for leftover pending state from a crashed capture attempt */
784 sys::path xmlpath(_session_dir->root_path());
785 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
787 if (sys::exists (xmlpath)) {
789 /* there is pending state from a crashed capture attempt */
791 if (*AskAboutPendingState()) {
792 state_was_pending = true;
796 if (!state_was_pending) {
797 xmlpath = _session_dir->root_path();
798 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
801 if (!sys::exists (xmlpath)) {
802 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
806 state_tree = new XMLTree;
810 /* writable() really reflects the whole folder, but if for any
811 reason the session state file can't be written to, still
815 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
819 if (!state_tree->read (xmlpath.to_string())) {
820 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
826 XMLNode& root (*state_tree->root());
828 if (root.name() != X_("Session")) {
829 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
835 const XMLProperty* prop;
837 if ((prop = root.property ("version")) == 0) {
838 /* no version implies very old version of Ardour */
839 Stateful::loading_state_version = 1000;
845 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
846 Stateful::loading_state_version = (major * 1000) + minor;
849 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
851 sys::path backup_path(_session_dir->root_path());
853 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
855 // only create a backup once
856 if (sys::exists (backup_path)) {
860 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
861 xmlpath.to_string(), backup_path.to_string())
866 sys::copy_file (xmlpath, backup_path);
868 catch(sys::filesystem_error& ex)
870 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
871 xmlpath.to_string(), ex.what())
881 Session::load_options (const XMLNode& node)
883 LocaleGuard lg (X_("POSIX"));
884 config.set_variables (node);
895 Session::get_template()
897 /* if we don't disable rec-enable, diskstreams
898 will believe they need to store their capture
899 sources in their state node.
902 disable_record (false);
908 Session::state(bool full_state)
910 XMLNode* node = new XMLNode("Session");
913 // store libardour version, just in case
915 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
916 node->add_property("version", string(buf));
918 /* store configuration settings */
922 node->add_property ("name", _name);
923 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
924 node->add_property ("sample-rate", buf);
926 if (session_dirs.size() > 1) {
930 vector<space_and_path>::iterator i = session_dirs.begin();
931 vector<space_and_path>::iterator next;
933 ++i; /* skip the first one */
937 while (i != session_dirs.end()) {
941 if (next != session_dirs.end()) {
951 child = node->add_child ("Path");
952 child->add_content (p);
956 /* save the ID counter */
958 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
959 node->add_property ("id-counter", buf);
961 /* various options */
963 node->add_child_nocopy (config.get_variables ());
965 node->add_child_nocopy (_metadata->get_state());
967 child = node->add_child ("Sources");
970 Glib::Mutex::Lock sl (source_lock);
972 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
974 /* Don't save information about non-destructive file sources that are empty */
975 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
977 boost::shared_ptr<AudioFileSource> fs;
978 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
979 if (!fs->destructive()) {
980 if (fs->length(fs->timeline_position()) == 0) {
986 child->add_child_nocopy (siter->second->get_state());
990 child = node->add_child ("Regions");
993 Glib::Mutex::Lock rl (region_lock);
995 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
997 /* only store regions not attached to playlists */
999 if (i->second->playlist() == 0) {
1000 child->add_child_nocopy (i->second->state (true));
1005 child = node->add_child ("DiskStreams");
1008 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1009 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1010 if (!(*i)->hidden()) {
1011 child->add_child_nocopy ((*i)->get_state());
1017 node->add_child_nocopy (_locations.get_state());
1019 // for a template, just create a new Locations, populate it
1020 // with the default start and end, and get the state for that.
1022 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1023 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1026 end->set_end(compute_initial_length());
1028 node->add_child_nocopy (loc.get_state());
1031 child = node->add_child ("Bundles");
1033 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1034 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1035 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1037 child->add_child_nocopy (b->get_state());
1042 child = node->add_child ("Routes");
1044 boost::shared_ptr<RouteList> r = routes.reader ();
1046 RoutePublicOrderSorter cmp;
1047 RouteList public_order (*r);
1048 public_order.sort (cmp);
1050 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1051 if (!(*i)->is_hidden()) {
1053 child->add_child_nocopy ((*i)->get_state());
1055 child->add_child_nocopy ((*i)->get_template());
1061 playlists->add_state (node, full_state);
1063 child = node->add_child ("RouteGroups");
1064 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1065 child->add_child_nocopy ((*i)->get_state());
1069 child = node->add_child ("Click");
1070 child->add_child_nocopy (_click_io->state (full_state));
1074 child = node->add_child ("NamedSelections");
1075 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1077 child->add_child_nocopy ((*i)->get_state());
1082 node->add_child_nocopy (_tempo_map->get_state());
1084 node->add_child_nocopy (get_control_protocol_state());
1087 node->add_child_copy (*_extra_xml);
1094 Session::get_control_protocol_state ()
1096 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1097 return cpm.get_state();
1101 Session::set_state (const XMLNode& node, int version)
1105 const XMLProperty* prop;
1108 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1110 if (node.name() != X_("Session")){
1111 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1115 if ((prop = node.property ("version")) != 0) {
1116 version = atoi (prop->value ()) * 1000;
1119 if ((prop = node.property ("name")) != 0) {
1120 _name = prop->value ();
1123 if ((prop = node.property (X_("sample-rate"))) != 0) {
1125 _nominal_frame_rate = atoi (prop->value());
1127 if (_nominal_frame_rate != _current_frame_rate) {
1128 if (*AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1134 setup_raid_path(_session_dir->root_path().to_string());
1136 if ((prop = node.property (X_("id-counter"))) != 0) {
1138 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1139 ID::init_counter (x);
1141 /* old sessions used a timebased counter, so fake
1142 the startup ID counter based on a standard
1147 ID::init_counter (now);
1151 IO::disable_connecting ();
1153 /* Object loading order:
1158 MIDI Control // relies on data from Options/Config
1172 if ((child = find_named_node (node, "Extra")) != 0) {
1173 _extra_xml = new XMLNode (*child);
1176 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1177 load_options (*child);
1178 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1179 load_options (*child);
1181 error << _("Session: XML state has no options section") << endmsg;
1184 if (use_config_midi_ports ()) {
1187 if (version >= 3000) {
1188 if ((child = find_named_node (node, "Metadata")) == 0) {
1189 warning << _("Session: XML state has no metadata section") << endmsg;
1190 } else if (_metadata->set_state (*child, version)) {
1195 if ((child = find_named_node (node, "Locations")) == 0) {
1196 error << _("Session: XML state has no locations section") << endmsg;
1198 } else if (_locations.set_state (*child, version)) {
1204 if ((location = _locations.auto_loop_location()) != 0) {
1205 set_auto_loop_location (location);
1208 if ((location = _locations.auto_punch_location()) != 0) {
1209 set_auto_punch_location (location);
1212 if ((location = _locations.end_location()) == 0) {
1213 _locations.add (end_location);
1215 delete end_location;
1216 end_location = location;
1219 if ((location = _locations.start_location()) == 0) {
1220 _locations.add (start_location);
1222 delete start_location;
1223 start_location = location;
1226 AudioFileSource::set_header_position_offset (start_location->start());
1228 if ((child = find_named_node (node, "Sources")) == 0) {
1229 error << _("Session: XML state has no sources section") << endmsg;
1231 } else if (load_sources (*child)) {
1235 if ((child = find_named_node (node, "Regions")) == 0) {
1236 error << _("Session: XML state has no Regions section") << endmsg;
1238 } else if (load_regions (*child)) {
1242 if ((child = find_named_node (node, "Playlists")) == 0) {
1243 error << _("Session: XML state has no playlists section") << endmsg;
1245 } else if (playlists->load (*this, *child)) {
1249 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1251 } else if (playlists->load_unused (*this, *child)) {
1255 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1256 if (load_named_selections (*child)) {
1261 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1262 error << _("Session: XML state has no diskstreams section") << endmsg;
1264 } else if (load_diskstreams (*child)) {
1268 if (version >= 3000) {
1269 if ((child = find_named_node (node, "Bundles")) == 0) {
1270 warning << _("Session: XML state has no bundles section") << endmsg;
1273 /* We can't load Bundles yet as they need to be able
1274 to convert from port names to Port objects, which can't happen until
1276 _bundle_xml_node = new XMLNode (*child);
1280 if ((child = find_named_node (node, "TempoMap")) == 0) {
1281 error << _("Session: XML state has no Tempo Map section") << endmsg;
1283 } else if (_tempo_map->set_state (*child, version)) {
1287 if ((child = find_named_node (node, "Routes")) == 0) {
1288 error << _("Session: XML state has no routes section") << endmsg;
1290 } else if (load_routes (*child, version)) {
1294 if (version >= 3000) {
1296 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1297 error << _("Session: XML state has no route groups section") << endmsg;
1299 } else if (load_route_groups (*child, version)) {
1303 } else if (version < 3000) {
1305 if ((child = find_named_node (node, "EditGroups")) == 0) {
1306 error << _("Session: XML state has no edit groups section") << endmsg;
1308 } else if (load_route_groups (*child, version)) {
1312 if ((child = find_named_node (node, "MixGroups")) == 0) {
1313 error << _("Session: XML state has no mix groups section") << endmsg;
1315 } else if (load_route_groups (*child, version)) {
1320 if ((child = find_named_node (node, "Click")) == 0) {
1321 warning << _("Session: XML state has no click section") << endmsg;
1322 } else if (_click_io) {
1323 _click_io->set_state (*child, version);
1326 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1327 ControlProtocolManager::instance().set_protocol_states (*child);
1330 /* here beginneth the second phase ... */
1332 StateReady (); /* EMIT SIGNAL */
1341 Session::load_routes (const XMLNode& node, int version)
1344 XMLNodeConstIterator niter;
1345 RouteList new_routes;
1347 nlist = node.children();
1351 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1353 boost::shared_ptr<Route> route (XMLRouteFactory (**niter, version));
1356 error << _("Session: cannot create Route from XML description.") << endmsg;
1360 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1362 new_routes.push_back (route);
1365 add_routes (new_routes, false);
1370 boost::shared_ptr<Route>
1371 Session::XMLRouteFactory (const XMLNode& node, int version)
1373 if (node.name() != "Route") {
1374 return boost::shared_ptr<Route> ((Route*) 0);
1377 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1379 DataType type = DataType::AUDIO;
1380 const XMLProperty* prop = node.property("default-type");
1381 boost::shared_ptr<Route> ret;
1384 type = DataType(prop->value());
1387 assert(type != DataType::NIL);
1389 if (has_diskstream) {
1390 if (type == DataType::AUDIO) {
1391 AudioTrack* at = new AudioTrack (*this, node, version);
1392 boost_debug_shared_ptr_mark_interesting (at, "Track");
1396 ret.reset (new MidiTrack (*this, node, version));
1399 Route* rt = new Route (*this, node);
1400 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1408 Session::load_regions (const XMLNode& node)
1411 XMLNodeConstIterator niter;
1412 boost::shared_ptr<Region> region;
1414 nlist = node.children();
1418 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1419 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1420 error << _("Session: cannot create Region from XML description.");
1421 const XMLProperty *name = (**niter).property("name");
1424 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1434 boost::shared_ptr<Region>
1435 Session::XMLRegionFactory (const XMLNode& node, bool full)
1437 const XMLProperty* type = node.property("type");
1441 if ( !type || type->value() == "audio" ) {
1443 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1445 } else if (type->value() == "midi") {
1447 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1451 } catch (failed_constructor& err) {
1452 return boost::shared_ptr<Region> ();
1455 return boost::shared_ptr<Region> ();
1458 boost::shared_ptr<AudioRegion>
1459 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1461 const XMLProperty* prop;
1462 boost::shared_ptr<Source> source;
1463 boost::shared_ptr<AudioSource> as;
1465 SourceList master_sources;
1466 uint32_t nchans = 1;
1469 if (node.name() != X_("Region")) {
1470 return boost::shared_ptr<AudioRegion>();
1473 if ((prop = node.property (X_("channels"))) != 0) {
1474 nchans = atoi (prop->value().c_str());
1477 if ((prop = node.property ("name")) == 0) {
1478 cerr << "no name for this region\n";
1482 if ((prop = node.property (X_("source-0"))) == 0) {
1483 if ((prop = node.property ("source")) == 0) {
1484 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1485 return boost::shared_ptr<AudioRegion>();
1489 PBD::ID s_id (prop->value());
1491 if ((source = source_by_id (s_id)) == 0) {
1492 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1493 return boost::shared_ptr<AudioRegion>();
1496 as = boost::dynamic_pointer_cast<AudioSource>(source);
1498 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1499 return boost::shared_ptr<AudioRegion>();
1502 sources.push_back (as);
1504 /* pickup other channels */
1506 for (uint32_t n=1; n < nchans; ++n) {
1507 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1508 if ((prop = node.property (buf)) != 0) {
1510 PBD::ID id2 (prop->value());
1512 if ((source = source_by_id (id2)) == 0) {
1513 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1514 return boost::shared_ptr<AudioRegion>();
1517 as = boost::dynamic_pointer_cast<AudioSource>(source);
1519 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1520 return boost::shared_ptr<AudioRegion>();
1522 sources.push_back (as);
1526 for (uint32_t n = 0; n < nchans; ++n) {
1527 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1528 if ((prop = node.property (buf)) != 0) {
1530 PBD::ID id2 (prop->value());
1532 if ((source = source_by_id (id2)) == 0) {
1533 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1534 return boost::shared_ptr<AudioRegion>();
1537 as = boost::dynamic_pointer_cast<AudioSource>(source);
1539 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1540 return boost::shared_ptr<AudioRegion>();
1542 master_sources.push_back (as);
1547 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1549 /* a final detail: this is the one and only place that we know how long missing files are */
1551 if (region->whole_file()) {
1552 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1553 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1555 sfp->set_length (region->length());
1560 if (!master_sources.empty()) {
1561 if (master_sources.size() != nchans) {
1562 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1564 region->set_master_sources (master_sources);
1572 catch (failed_constructor& err) {
1573 return boost::shared_ptr<AudioRegion>();
1577 boost::shared_ptr<MidiRegion>
1578 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1580 const XMLProperty* prop;
1581 boost::shared_ptr<Source> source;
1582 boost::shared_ptr<MidiSource> ms;
1584 uint32_t nchans = 1;
1586 if (node.name() != X_("Region")) {
1587 return boost::shared_ptr<MidiRegion>();
1590 if ((prop = node.property (X_("channels"))) != 0) {
1591 nchans = atoi (prop->value().c_str());
1594 if ((prop = node.property ("name")) == 0) {
1595 cerr << "no name for this region\n";
1599 // Multiple midi channels? that's just crazy talk
1600 assert(nchans == 1);
1602 if ((prop = node.property (X_("source-0"))) == 0) {
1603 if ((prop = node.property ("source")) == 0) {
1604 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1605 return boost::shared_ptr<MidiRegion>();
1609 PBD::ID s_id (prop->value());
1611 if ((source = source_by_id (s_id)) == 0) {
1612 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1613 return boost::shared_ptr<MidiRegion>();
1616 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1618 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1619 return boost::shared_ptr<MidiRegion>();
1622 sources.push_back (ms);
1625 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1626 /* a final detail: this is the one and only place that we know how long missing files are */
1628 if (region->whole_file()) {
1629 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1630 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1632 sfp->set_length (region->length());
1640 catch (failed_constructor& err) {
1641 return boost::shared_ptr<MidiRegion>();
1646 Session::get_sources_as_xml ()
1649 XMLNode* node = new XMLNode (X_("Sources"));
1650 Glib::Mutex::Lock lm (source_lock);
1652 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1653 node->add_child_nocopy (i->second->get_state());
1660 Session::path_from_region_name (DataType type, string name, string identifier)
1662 char buf[PATH_MAX+1];
1664 SessionDirectory sdir(get_best_session_directory_for_new_source());
1665 sys::path source_dir = ((type == DataType::AUDIO)
1666 ? sdir.sound_path() : sdir.midi_path());
1668 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1670 for (n = 0; n < 999999; ++n) {
1671 if (identifier.length()) {
1672 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1673 identifier.c_str(), n, ext.c_str());
1675 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1679 sys::path source_path = source_dir / buf;
1681 if (!sys::exists (source_path)) {
1682 return source_path.to_string();
1686 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1695 Session::load_sources (const XMLNode& node)
1698 XMLNodeConstIterator niter;
1699 boost::shared_ptr<Source> source;
1701 nlist = node.children();
1705 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1707 if ((source = XMLSourceFactory (**niter)) == 0) {
1708 error << _("Session: cannot create Source from XML description.") << endmsg;
1710 } catch (MissingSource& err) {
1711 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1712 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1719 boost::shared_ptr<Source>
1720 Session::XMLSourceFactory (const XMLNode& node)
1722 if (node.name() != "Source") {
1723 return boost::shared_ptr<Source>();
1727 /* note: do peak building in another thread when loading session state */
1728 return SourceFactory::create (*this, node, true);
1731 catch (failed_constructor& err) {
1732 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1733 return boost::shared_ptr<Source>();
1738 Session::save_template (string template_name)
1742 if (_state_of_the_state & CannotSave) {
1746 sys::path user_template_dir(user_template_directory());
1750 sys::create_directories (user_template_dir);
1752 catch(sys::filesystem_error& ex)
1754 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1755 user_template_dir.to_string(), ex.what()) << endmsg;
1759 tree.set_root (&get_template());
1761 sys::path template_file_path(user_template_dir);
1762 template_file_path /= template_name + template_suffix;
1764 if (sys::exists (template_file_path))
1766 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1767 template_file_path.to_string()) << endmsg;
1771 if (!tree.write (template_file_path.to_string())) {
1772 error << _("mix template not saved") << endmsg;
1780 Session::rename_template (string old_name, string new_name)
1782 sys::path old_path (user_template_directory());
1783 old_path /= old_name + template_suffix;
1785 sys::path new_path(user_template_directory());
1786 new_path /= new_name + template_suffix;
1788 if (sys::exists (new_path)) {
1789 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1790 new_path.to_string()) << endmsg;
1795 sys::rename (old_path, new_path);
1803 Session::delete_template (string name)
1805 sys::path path = user_template_directory();
1806 path /= name + template_suffix;
1817 Session::refresh_disk_space ()
1820 struct statfs statfsbuf;
1821 vector<space_and_path>::iterator i;
1822 Glib::Mutex::Lock lm (space_lock);
1825 /* get freespace on every FS that is part of the session path */
1827 _total_free_4k_blocks = 0;
1829 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1830 statfs ((*i).path.c_str(), &statfsbuf);
1832 scale = statfsbuf.f_bsize/4096.0;
1834 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1835 _total_free_4k_blocks += (*i).blocks;
1841 Session::get_best_session_directory_for_new_source ()
1843 vector<space_and_path>::iterator i;
1844 string result = _session_dir->root_path().to_string();
1846 /* handle common case without system calls */
1848 if (session_dirs.size() == 1) {
1852 /* OK, here's the algorithm we're following here:
1854 We want to select which directory to use for
1855 the next file source to be created. Ideally,
1856 we'd like to use a round-robin process so as to
1857 get maximum performance benefits from splitting
1858 the files across multiple disks.
1860 However, in situations without much diskspace, an
1861 RR approach may end up filling up a filesystem
1862 with new files while others still have space.
1863 Its therefore important to pay some attention to
1864 the freespace in the filesystem holding each
1865 directory as well. However, if we did that by
1866 itself, we'd keep creating new files in the file
1867 system with the most space until it was as full
1868 as all others, thus negating any performance
1869 benefits of this RAID-1 like approach.
1871 So, we use a user-configurable space threshold. If
1872 there are at least 2 filesystems with more than this
1873 much space available, we use RR selection between them.
1874 If not, then we pick the filesystem with the most space.
1876 This gets a good balance between the two
1880 refresh_disk_space ();
1882 int free_enough = 0;
1884 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1885 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1890 if (free_enough >= 2) {
1891 /* use RR selection process, ensuring that the one
1895 i = last_rr_session_dir;
1898 if (++i == session_dirs.end()) {
1899 i = session_dirs.begin();
1902 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1903 if (create_session_directory ((*i).path)) {
1905 last_rr_session_dir = i;
1910 } while (i != last_rr_session_dir);
1914 /* pick FS with the most freespace (and that
1915 seems to actually work ...)
1918 vector<space_and_path> sorted;
1919 space_and_path_ascending_cmp cmp;
1921 sorted = session_dirs;
1922 sort (sorted.begin(), sorted.end(), cmp);
1924 for (i = sorted.begin(); i != sorted.end(); ++i) {
1925 if (create_session_directory ((*i).path)) {
1927 last_rr_session_dir = i;
1937 Session::load_named_selections (const XMLNode& node)
1940 XMLNodeConstIterator niter;
1943 nlist = node.children();
1947 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1949 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1950 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1958 Session::XMLNamedSelectionFactory (const XMLNode& node)
1961 return new NamedSelection (*this, node);
1964 catch (failed_constructor& err) {
1970 Session::automation_dir () const
1972 return Glib::build_filename (_path, "automation");
1976 Session::analysis_dir () const
1978 return Glib::build_filename (_path, "analysis");
1982 Session::load_bundles (XMLNode const & node)
1984 XMLNodeList nlist = node.children();
1985 XMLNodeConstIterator niter;
1989 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1990 if ((*niter)->name() == "InputBundle") {
1991 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
1992 } else if ((*niter)->name() == "OutputBundle") {
1993 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
1995 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2004 Session::load_route_groups (const XMLNode& node, int version)
2006 XMLNodeList nlist = node.children();
2007 XMLNodeConstIterator niter;
2011 if (version >= 3000) {
2013 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2014 if ((*niter)->name() == "RouteGroup") {
2015 RouteGroup* rg = new RouteGroup (*this, "");
2016 add_route_group (rg);
2017 rg->set_state (**niter, version);
2021 } else if (version < 3000) {
2023 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2024 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2025 RouteGroup* rg = new RouteGroup (*this, "");
2026 add_route_group (rg);
2027 rg->set_state (**niter, version);
2036 Session::auto_save()
2038 save_state (_current_snapshot_name);
2042 state_file_filter (const string &str, void */*arg*/)
2044 return (str.length() > strlen(statefile_suffix) &&
2045 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2049 bool operator()(const string* a, const string* b) {
2055 remove_end(string* state)
2057 string statename(*state);
2059 string::size_type start,end;
2060 if ((start = statename.find_last_of ('/')) != string::npos) {
2061 statename = statename.substr (start+1);
2064 if ((end = statename.rfind(".ardour")) == string::npos) {
2065 end = statename.length();
2068 return new string(statename.substr (0, end));
2072 Session::possible_states (string path)
2074 PathScanner scanner;
2075 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2077 transform(states->begin(), states->end(), states->begin(), remove_end);
2080 sort (states->begin(), states->end(), cmp);
2086 Session::possible_states () const
2088 return possible_states(_path);
2092 Session::add_route_group (RouteGroup* g)
2094 _route_groups.push_back (g);
2095 route_group_added (g); /* EMIT SIGNAL */
2100 Session::remove_route_group (RouteGroup& rg)
2102 list<RouteGroup*>::iterator i;
2104 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2105 _route_groups.erase (i);
2108 route_group_removed (); /* EMIT SIGNAL */
2114 Session::route_group_by_name (string name)
2116 list<RouteGroup *>::iterator i;
2118 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2119 if ((*i)->name() == name) {
2127 Session::start_reversible_command (const string& name)
2129 UndoTransaction* trans = new UndoTransaction();
2130 trans->set_name(name);
2135 Session::finish_reversible_command (UndoTransaction& ut)
2138 gettimeofday(&now, 0);
2139 ut.set_timestamp(now);
2144 Session::begin_reversible_command(const string& name)
2146 UndoTransaction* trans = new UndoTransaction();
2147 trans->set_name(name);
2149 if (!_current_trans.empty()) {
2150 _current_trans.top()->add_command (trans);
2152 _current_trans.push(trans);
2157 Session::commit_reversible_command(Command *cmd)
2159 assert(!_current_trans.empty());
2163 _current_trans.top()->add_command(cmd);
2166 if (_current_trans.top()->empty()) {
2167 _current_trans.pop();
2171 gettimeofday(&now, 0);
2172 _current_trans.top()->set_timestamp(now);
2174 _history.add(_current_trans.top());
2175 _current_trans.pop();
2179 accept_all_non_peak_files (const string& path, void */*arg*/)
2181 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2185 accept_all_state_files (const string& path, void */*arg*/)
2187 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2191 Session::find_all_sources (string path, set<string>& result)
2196 if (!tree.read (path)) {
2200 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2205 XMLNodeConstIterator niter;
2207 nlist = node->children();
2211 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2215 if ((prop = (*niter)->property (X_("type"))) == 0) {
2219 DataType type (prop->value());
2221 if ((prop = (*niter)->property (X_("name"))) == 0) {
2225 if (prop->value()[0] == '/') {
2226 /* external file, ignore */
2230 Glib::ustring found_path;
2234 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2235 result.insert (found_path);
2243 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2245 PathScanner scanner;
2246 vector<string*>* state_files;
2248 string this_snapshot_path;
2254 if (ripped[ripped.length()-1] == '/') {
2255 ripped = ripped.substr (0, ripped.length() - 1);
2258 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2260 if (state_files == 0) {
2265 this_snapshot_path = _path;
2266 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2267 this_snapshot_path += statefile_suffix;
2269 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2271 if (exclude_this_snapshot && **i == this_snapshot_path) {
2275 if (find_all_sources (**i, result) < 0) {
2283 struct RegionCounter {
2284 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2285 AudioSourceList::iterator iter;
2286 boost::shared_ptr<Region> region;
2289 RegionCounter() : count (0) {}
2293 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2295 return *AskAboutPlaylistDeletion (p);
2299 Session::cleanup_sources (CleanupReport& rep)
2301 // FIXME: needs adaptation to midi
2303 vector<boost::shared_ptr<Source> > dead_sources;
2304 PathScanner scanner;
2306 vector<space_and_path>::iterator i;
2307 vector<space_and_path>::iterator nexti;
2308 vector<string*>* soundfiles;
2309 vector<string> unused;
2310 set<string> all_sources;
2315 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2317 /* step 1: consider deleting all unused playlists */
2319 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2324 /* step 2: find all un-used sources */
2329 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2331 SourceMap::iterator tmp;
2336 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2340 if (!playlists->source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2341 dead_sources.push_back (i->second);
2342 i->second->drop_references ();
2348 /* build a list of all the possible sound directories for the session */
2350 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2355 SessionDirectory sdir ((*i).path);
2356 sound_path += sdir.sound_path().to_string();
2358 if (nexti != session_dirs.end()) {
2365 /* now do the same thing for the files that ended up in the sounds dir(s)
2366 but are not referenced as sources in any snapshot.
2369 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2371 if (soundfiles == 0) {
2375 /* find all sources, but don't use this snapshot because the
2376 state file on disk still references sources we may have already
2380 find_all_sources_across_snapshots (all_sources, true);
2382 /* add our current source list
2385 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2386 boost::shared_ptr<FileSource> fs;
2388 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2389 all_sources.insert (fs->path());
2393 char tmppath1[PATH_MAX+1];
2394 char tmppath2[PATH_MAX+1];
2396 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2401 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2403 realpath(spath.c_str(), tmppath1);
2404 realpath((*i).c_str(), tmppath2);
2406 if (strcmp(tmppath1, tmppath2) == 0) {
2413 unused.push_back (spath);
2417 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2419 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2420 struct stat statbuf;
2422 rep.paths.push_back (*x);
2423 if (stat ((*x).c_str(), &statbuf) == 0) {
2424 rep.space += statbuf.st_size;
2429 /* don't move the file across filesystems, just
2430 stick it in the `dead_sound_dir_name' directory
2431 on whichever filesystem it was already on.
2434 if ((*x).find ("/sounds/") != string::npos) {
2436 /* old school, go up 1 level */
2438 newpath = Glib::path_get_dirname (*x); // "sounds"
2439 newpath = Glib::path_get_dirname (newpath); // "session-name"
2443 /* new school, go up 4 levels */
2445 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2446 newpath = Glib::path_get_dirname (newpath); // "session-name"
2447 newpath = Glib::path_get_dirname (newpath); // "interchange"
2448 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2452 newpath += dead_sound_dir_name;
2454 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2455 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2460 newpath += Glib::path_get_basename ((*x));
2462 if (access (newpath.c_str(), F_OK) == 0) {
2464 /* the new path already exists, try versioning */
2466 char buf[PATH_MAX+1];
2470 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2473 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2474 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2478 if (version == 999) {
2479 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2483 newpath = newpath_v;
2488 /* it doesn't exist, or we can't read it or something */
2492 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2493 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2494 (*x), newpath, strerror (errno))
2499 /* see if there an easy to find peakfile for this file, and remove it.
2502 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2503 peakpath += peakfile_suffix;
2505 if (access (peakpath.c_str(), W_OK) == 0) {
2506 if (::unlink (peakpath.c_str()) != 0) {
2507 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2508 peakpath, _path, strerror (errno))
2510 /* try to back out */
2511 rename (newpath.c_str(), _path.c_str());
2519 /* dump the history list */
2523 /* save state so we don't end up a session file
2524 referring to non-existent sources.
2530 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2536 Session::cleanup_trash_sources (CleanupReport& rep)
2538 // FIXME: needs adaptation for MIDI
2540 vector<space_and_path>::iterator i;
2541 string dead_sound_dir;
2542 struct dirent* dentry;
2543 struct stat statbuf;
2549 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2551 dead_sound_dir = (*i).path;
2552 dead_sound_dir += dead_sound_dir_name;
2554 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2558 while ((dentry = readdir (dead)) != 0) {
2560 /* avoid '.' and '..' */
2562 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2563 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2569 fullpath = dead_sound_dir;
2571 fullpath += dentry->d_name;
2573 if (stat (fullpath.c_str(), &statbuf)) {
2577 if (!S_ISREG (statbuf.st_mode)) {
2581 if (unlink (fullpath.c_str())) {
2582 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2583 fullpath, strerror (errno))
2587 rep.paths.push_back (dentry->d_name);
2588 rep.space += statbuf.st_size;
2599 Session::set_dirty ()
2601 bool was_dirty = dirty();
2603 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2607 DirtyChanged(); /* EMIT SIGNAL */
2613 Session::set_clean ()
2615 bool was_dirty = dirty();
2617 _state_of_the_state = Clean;
2621 DirtyChanged(); /* EMIT SIGNAL */
2626 Session::set_deletion_in_progress ()
2628 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2632 Session::clear_deletion_in_progress ()
2634 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2638 Session::add_controllable (boost::shared_ptr<Controllable> c)
2640 /* this adds a controllable to the list managed by the Session.
2641 this is a subset of those managed by the Controllable class
2642 itself, and represents the only ones whose state will be saved
2643 as part of the session.
2646 Glib::Mutex::Lock lm (controllables_lock);
2647 controllables.insert (c);
2650 struct null_deleter { void operator()(void const *) const {} };
2653 Session::remove_controllable (Controllable* c)
2655 if (_state_of_the_state | Deletion) {
2659 Glib::Mutex::Lock lm (controllables_lock);
2661 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2663 if (x != controllables.end()) {
2664 controllables.erase (x);
2668 boost::shared_ptr<Controllable>
2669 Session::controllable_by_id (const PBD::ID& id)
2671 Glib::Mutex::Lock lm (controllables_lock);
2673 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2674 if ((*i)->id() == id) {
2679 return boost::shared_ptr<Controllable>();
2682 boost::shared_ptr<Controllable>
2683 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2685 boost::shared_ptr<Controllable> c;
2686 boost::shared_ptr<Route> r;
2688 switch (desc.top_level_type()) {
2689 case ControllableDescriptor::NamedRoute:
2691 std::string str = desc.top_level_name();
2692 if (str == "master") {
2694 } else if (str == "control" || str == "listen") {
2697 r = route_by_name (desc.top_level_name());
2702 case ControllableDescriptor::RemoteControlID:
2703 r = route_by_remote_id (desc.rid());
2711 switch (desc.subtype()) {
2712 case ControllableDescriptor::Gain:
2713 c = r->gain_control ();
2716 case ControllableDescriptor::Solo:
2717 c = r->solo_control();
2720 case ControllableDescriptor::Mute:
2721 c = r->mute_control();
2724 case ControllableDescriptor::Recenable:
2726 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2729 c = t->rec_enable_control ();
2734 case ControllableDescriptor::Pan:
2735 /* XXX pan control */
2738 case ControllableDescriptor::Balance:
2739 /* XXX simple pan control */
2742 case ControllableDescriptor::PluginParameter:
2744 uint32_t plugin = desc.target (0);
2745 uint32_t parameter_index = desc.target (1);
2747 /* revert to zero based counting */
2753 if (parameter_index > 0) {
2757 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2760 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2761 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2766 case ControllableDescriptor::SendGain:
2768 uint32_t send = desc.target (0);
2770 /* revert to zero-based counting */
2776 boost::shared_ptr<Processor> p = r->nth_send (send);
2779 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2780 boost::shared_ptr<Amp> a = s->amp();
2783 c = s->amp()->gain_control();
2790 /* relax and return a null pointer */
2798 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2801 Stateful::add_instant_xml (node, _path);
2804 if (write_to_config) {
2805 Config->add_instant_xml (node);
2810 Session::instant_xml (const string& node_name)
2812 return Stateful::instant_xml (node_name, _path);
2816 Session::save_history (string snapshot_name)
2824 if (snapshot_name.empty()) {
2825 snapshot_name = _current_snapshot_name;
2828 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2829 const string backup_filename = history_filename + backup_suffix;
2830 const sys::path xml_path = _session_dir->root_path() / history_filename;
2831 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2833 if (sys::exists (xml_path)) {
2836 sys::rename (xml_path, backup_path);
2838 catch (const sys::filesystem_error& err)
2840 error << _("could not backup old history file, current history not saved") << endmsg;
2845 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2849 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2851 if (!tree.write (xml_path.to_string()))
2853 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2857 sys::remove (xml_path);
2858 sys::rename (backup_path, xml_path);
2860 catch (const sys::filesystem_error& err)
2862 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2863 backup_path.to_string(), err.what()) << endmsg;
2873 Session::restore_history (string snapshot_name)
2877 if (snapshot_name.empty()) {
2878 snapshot_name = _current_snapshot_name;
2881 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
2882 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2884 info << "Loading history from " << xml_path.to_string() << endmsg;
2886 if (!sys::exists (xml_path)) {
2887 info << string_compose (_("%1: no history file \"%2\" for this session."),
2888 _name, xml_path.to_string()) << endmsg;
2892 if (!tree.read (xml_path.to_string())) {
2893 error << string_compose (_("Could not understand session history file \"%1\""),
2894 xml_path.to_string()) << endmsg;
2901 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2904 UndoTransaction* ut = new UndoTransaction ();
2907 ut->set_name(t->property("name")->value());
2908 stringstream ss(t->property("tv-sec")->value());
2910 ss.str(t->property("tv-usec")->value());
2912 ut->set_timestamp(tv);
2914 for (XMLNodeConstIterator child_it = t->children().begin();
2915 child_it != t->children().end(); child_it++)
2917 XMLNode *n = *child_it;
2920 if (n->name() == "MementoCommand" ||
2921 n->name() == "MementoUndoCommand" ||
2922 n->name() == "MementoRedoCommand") {
2924 if ((c = memento_command_factory(n))) {
2928 } else if (n->name() == "DeltaCommand") {
2929 PBD::ID id(n->property("midi-source")->value());
2930 boost::shared_ptr<MidiSource> midi_source =
2931 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2933 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
2935 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2938 } else if (n->name() == "DiffCommand") {
2939 PBD::ID id(n->property("midi-source")->value());
2940 boost::shared_ptr<MidiSource> midi_source =
2941 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2943 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
2945 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2948 } else if (n->name() == "RegionCommand") {
2949 PBD::ID id (n->property ("region")->value());
2950 boost::shared_ptr<Region> region = RegionFactory::region_by_id (id);
2953 ut->add_command (new RegionCommand (region, *n));
2955 error << string_compose (_("Region command references an unknown region ID=%1"), id.to_s()) << endmsg;
2958 } else if (n->name() == "StatefulDiffCommand") {
2959 if ((c = stateful_diff_command_factory (n))) {
2960 ut->add_command (c);
2963 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2974 Session::config_changed (std::string p, bool ours)
2980 if (p == "seamless-loop") {
2982 } else if (p == "rf-speed") {
2984 } else if (p == "auto-loop") {
2986 } else if (p == "auto-input") {
2988 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2989 /* auto-input only makes a difference if we're rolling */
2991 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2993 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2994 if ((*i)->record_enabled ()) {
2995 (*i)->monitor_input (!config.get_auto_input());
3000 } else if (p == "punch-in") {
3004 if ((location = _locations.auto_punch_location()) != 0) {
3006 if (config.get_punch_in ()) {
3007 replace_event (SessionEvent::PunchIn, location->start());
3009 remove_event (location->start(), SessionEvent::PunchIn);
3013 } else if (p == "punch-out") {
3017 if ((location = _locations.auto_punch_location()) != 0) {
3019 if (config.get_punch_out()) {
3020 replace_event (SessionEvent::PunchOut, location->end());
3022 clear_events (SessionEvent::PunchOut);
3026 } else if (p == "edit-mode") {
3028 Glib::Mutex::Lock lm (playlists->lock);
3030 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3031 (*i)->set_edit_mode (Config->get_edit_mode ());
3034 } else if (p == "use-video-sync") {
3036 waiting_for_sync_offset = config.get_use_video_sync();
3038 } else if (p == "mmc-control") {
3040 //poke_midi_thread ();
3042 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3045 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3048 } else if (p == "mmc-send-id") {
3051 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3054 } else if (p == "midi-control") {
3056 //poke_midi_thread ();
3058 } else if (p == "raid-path") {
3060 setup_raid_path (config.get_raid_path());
3062 } else if (p == "timecode-format") {
3066 } else if (p == "video-pullup") {
3070 } else if (p == "seamless-loop") {
3072 if (play_loop && transport_rolling()) {
3073 // to reset diskstreams etc
3074 request_play_loop (true);
3077 } else if (p == "rf-speed") {
3079 cumulative_rf_motion = 0;
3082 } else if (p == "click-sound") {
3084 setup_click_sounds (1);
3086 } else if (p == "click-emphasis-sound") {
3088 setup_click_sounds (-1);
3090 } else if (p == "clicking") {
3092 if (Config->get_clicking()) {
3093 if (_click_io && click_data) { // don't require emphasis data
3100 } else if (p == "send-mtc") {
3102 /* only set the internal flag if we have
3106 if (_mtc_port != 0) {
3107 session_send_mtc = Config->get_send_mtc();
3108 if (session_send_mtc) {
3109 /* mark us ready to send */
3110 next_quarter_frame_to_send = 0;
3113 session_send_mtc = false;
3116 } else if (p == "send-mmc") {
3118 /* only set the internal flag if we have
3122 if (_mmc_port != 0) {
3123 session_send_mmc = Config->get_send_mmc();
3126 session_send_mmc = false;
3129 } else if (p == "midi-feedback") {
3131 /* only set the internal flag if we have
3135 if (_mtc_port != 0) {
3136 session_midi_feedback = Config->get_midi_feedback();
3139 } else if (p == "jack-time-master") {
3141 engine().reset_timebase ();
3143 } else if (p == "native-file-header-format") {
3145 if (!first_file_header_format_reset) {
3146 reset_native_file_format ();
3149 first_file_header_format_reset = false;
3151 } else if (p == "native-file-data-format") {
3153 if (!first_file_data_format_reset) {
3154 reset_native_file_format ();
3157 first_file_data_format_reset = false;
3159 } else if (p == "external-sync") {
3160 if (!config.get_external_sync()) {
3161 drop_sync_source ();
3163 switch_to_sync_source (config.get_sync_source());
3165 } else if (p == "remote-model") {
3166 set_remote_control_ids ();
3167 } else if (p == "denormal-model") {
3169 } else if (p == "history-depth") {
3170 set_history_depth (Config->get_history_depth());
3171 } else if (p == "sync-all-route-ordering") {
3172 sync_order_keys ("session");
3173 } else if (p == "initial-program-change") {
3175 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3178 buf[0] = MIDI::program; // channel zero by default
3179 buf[1] = (Config->get_initial_program_change() & 0x7f);
3181 _mmc_port->midimsg (buf, sizeof (buf), 0);
3183 } else if (p == "initial-program-change") {
3185 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3186 MIDI::byte* buf = new MIDI::byte[2];
3188 buf[0] = MIDI::program; // channel zero by default
3189 buf[1] = (Config->get_initial_program_change() & 0x7f);
3190 // deliver_midi (_mmc_port, buf, 2);
3192 } else if (p == "solo-mute-override") {
3193 // catch_up_on_solo_mute_override ();
3194 } else if (p == "listen-position") {
3195 listen_position_changed ();
3196 } else if (p == "solo-control-is-listen-control") {
3197 solo_control_mode_changed ();
3205 Session::set_history_depth (uint32_t d)
3207 _history.set_depth (d);