2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libardour-config.h"
25 #define __STDC_FORMAT_MACROS 1
34 #include <cstdio> /* snprintf(3) ... grrr */
49 #include <sys/param.h>
50 #include <sys/mount.h>
54 #include <glibmm/thread.h>
56 #include "midi++/mmc.h"
57 #include "midi++/port.h"
59 #include "pbd/boost_debug.h"
60 #include "pbd/controllable_descriptor.h"
61 #include "pbd/enumwriter.h"
62 #include "pbd/error.h"
63 #include "pbd/pathscanner.h"
64 #include "pbd/pthread_utils.h"
65 #include "pbd/search_path.h"
66 #include "pbd/stacktrace.h"
67 #include "pbd/convert.h"
69 #include "ardour/amp.h"
70 #include "ardour/audio_diskstream.h"
71 #include "ardour/audio_track.h"
72 #include "ardour/audioengine.h"
73 #include "ardour/audiofilesource.h"
74 #include "ardour/audioplaylist.h"
75 #include "ardour/audioregion.h"
76 #include "ardour/auditioner.h"
77 #include "ardour/buffer.h"
78 #include "ardour/butler.h"
79 #include "ardour/configuration.h"
80 #include "ardour/control_protocol_manager.h"
81 #include "ardour/crossfade.h"
82 #include "ardour/cycle_timer.h"
83 #include "ardour/directory_names.h"
84 #include "ardour/filename_extensions.h"
85 #include "ardour/io_processor.h"
86 #include "ardour/location.h"
87 #include "ardour/midi_diskstream.h"
88 #include "ardour/midi_patch_manager.h"
89 #include "ardour/midi_playlist.h"
90 #include "ardour/midi_region.h"
91 #include "ardour/midi_source.h"
92 #include "ardour/midi_track.h"
93 #include "ardour/named_selection.h"
94 #include "ardour/processor.h"
95 #include "ardour/region_factory.h"
96 #include "ardour/route_group.h"
97 #include "ardour/send.h"
98 #include "ardour/session.h"
99 #include "ardour/session_directory.h"
100 #include "ardour/session_metadata.h"
101 #include "ardour/session_state_utils.h"
102 #include "ardour/session_playlists.h"
103 #include "ardour/session_utils.h"
104 #include "ardour/silentfilesource.h"
105 #include "ardour/slave.h"
106 #include "ardour/smf_source.h"
107 #include "ardour/sndfile_helpers.h"
108 #include "ardour/sndfilesource.h"
109 #include "ardour/source_factory.h"
110 #include "ardour/template_utils.h"
111 #include "ardour/tempo.h"
112 #include "ardour/ticker.h"
113 #include "ardour/user_bundle.h"
114 #include "ardour/utils.h"
115 #include "ardour/utils.h"
116 #include "ardour/version.h"
117 #include "ardour/playlist_factory.h"
119 #include "control_protocol/control_protocol.h"
125 using namespace ARDOUR;
129 Session::first_stage_init (string fullpath, string snapshot_name)
131 if (fullpath.length() == 0) {
133 throw failed_constructor();
136 char buf[PATH_MAX+1];
137 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
138 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
140 throw failed_constructor();
145 if (_path[_path.length()-1] != '/') {
149 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
155 /* these two are just provisional settings. set_state()
156 will likely override them.
159 _name = _current_snapshot_name = snapshot_name;
161 set_history_depth (Config->get_history_depth());
163 _current_frame_rate = _engine.frame_rate ();
164 _nominal_frame_rate = _current_frame_rate;
165 _base_frame_rate = _current_frame_rate;
167 _tempo_map = new TempoMap (_current_frame_rate);
168 _tempo_map->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::tempo_map_changed, this, _1));
171 _non_soloed_outs_muted = false;
173 g_atomic_int_set (&processing_prohibited, 0);
174 _transport_speed = 0;
175 _last_transport_speed = 0;
176 _target_transport_speed = 0;
177 auto_play_legal = false;
178 transport_sub_state = 0;
179 _transport_frame = 0;
180 _requested_return_frame = -1;
181 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);
994 const RegionFactory::RegionMap& region_map (RegionFactory::all_regions());
995 for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) {
996 boost::shared_ptr<Region> r = i->second;
997 /* only store regions not attached to playlists */
998 if (r->playlist() == 0) {
999 child->add_child_nocopy (r->state (true));
1004 child = node->add_child ("DiskStreams");
1007 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1008 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1009 if (!(*i)->hidden()) {
1010 child->add_child_nocopy ((*i)->get_state());
1016 node->add_child_nocopy (_locations.get_state());
1018 // for a template, just create a new Locations, populate it
1019 // with the default start and end, and get the state for that.
1021 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1022 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1025 end->set_end(compute_initial_length());
1027 node->add_child_nocopy (loc.get_state());
1030 child = node->add_child ("Bundles");
1032 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1033 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1034 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1036 child->add_child_nocopy (b->get_state());
1041 child = node->add_child ("Routes");
1043 boost::shared_ptr<RouteList> r = routes.reader ();
1045 RoutePublicOrderSorter cmp;
1046 RouteList public_order (*r);
1047 public_order.sort (cmp);
1049 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1050 if (!(*i)->is_hidden()) {
1052 child->add_child_nocopy ((*i)->get_state());
1054 child->add_child_nocopy ((*i)->get_template());
1060 playlists->add_state (node, full_state);
1062 child = node->add_child ("RouteGroups");
1063 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1064 child->add_child_nocopy ((*i)->get_state());
1068 child = node->add_child ("Click");
1069 child->add_child_nocopy (_click_io->state (full_state));
1073 child = node->add_child ("NamedSelections");
1074 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1076 child->add_child_nocopy ((*i)->get_state());
1081 node->add_child_nocopy (_tempo_map->get_state());
1083 node->add_child_nocopy (get_control_protocol_state());
1086 node->add_child_copy (*_extra_xml);
1093 Session::get_control_protocol_state ()
1095 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1096 return cpm.get_state();
1100 Session::set_state (const XMLNode& node, int version)
1104 const XMLProperty* prop;
1107 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1109 if (node.name() != X_("Session")){
1110 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1114 if ((prop = node.property ("version")) != 0) {
1115 version = atoi (prop->value ()) * 1000;
1118 if ((prop = node.property ("name")) != 0) {
1119 _name = prop->value ();
1122 if ((prop = node.property (X_("sample-rate"))) != 0) {
1124 _nominal_frame_rate = atoi (prop->value());
1126 if (_nominal_frame_rate != _current_frame_rate) {
1127 if (*AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1133 setup_raid_path(_session_dir->root_path().to_string());
1135 if ((prop = node.property (X_("id-counter"))) != 0) {
1137 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1138 ID::init_counter (x);
1140 /* old sessions used a timebased counter, so fake
1141 the startup ID counter based on a standard
1146 ID::init_counter (now);
1150 IO::disable_connecting ();
1152 /* Object loading order:
1157 MIDI Control // relies on data from Options/Config
1171 if ((child = find_named_node (node, "Extra")) != 0) {
1172 _extra_xml = new XMLNode (*child);
1175 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1176 load_options (*child);
1177 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1178 load_options (*child);
1180 error << _("Session: XML state has no options section") << endmsg;
1183 if (use_config_midi_ports ()) {
1186 if (version >= 3000) {
1187 if ((child = find_named_node (node, "Metadata")) == 0) {
1188 warning << _("Session: XML state has no metadata section") << endmsg;
1189 } else if (_metadata->set_state (*child, version)) {
1194 if ((child = find_named_node (node, "Locations")) == 0) {
1195 error << _("Session: XML state has no locations section") << endmsg;
1197 } else if (_locations.set_state (*child, version)) {
1203 if ((location = _locations.auto_loop_location()) != 0) {
1204 set_auto_loop_location (location);
1207 if ((location = _locations.auto_punch_location()) != 0) {
1208 set_auto_punch_location (location);
1211 if ((location = _locations.end_location()) == 0) {
1212 _locations.add (end_location);
1214 delete end_location;
1215 end_location = location;
1218 if ((location = _locations.start_location()) == 0) {
1219 _locations.add (start_location);
1221 delete start_location;
1222 start_location = location;
1225 AudioFileSource::set_header_position_offset (start_location->start());
1227 if ((child = find_named_node (node, "Sources")) == 0) {
1228 error << _("Session: XML state has no sources section") << endmsg;
1230 } else if (load_sources (*child)) {
1234 if ((child = find_named_node (node, "Regions")) == 0) {
1235 error << _("Session: XML state has no Regions section") << endmsg;
1237 } else if (load_regions (*child)) {
1241 if ((child = find_named_node (node, "Playlists")) == 0) {
1242 error << _("Session: XML state has no playlists section") << endmsg;
1244 } else if (playlists->load (*this, *child)) {
1248 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1250 } else if (playlists->load_unused (*this, *child)) {
1254 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1255 if (load_named_selections (*child)) {
1260 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1261 error << _("Session: XML state has no diskstreams section") << endmsg;
1263 } else if (load_diskstreams (*child)) {
1267 if (version >= 3000) {
1268 if ((child = find_named_node (node, "Bundles")) == 0) {
1269 warning << _("Session: XML state has no bundles section") << endmsg;
1272 /* We can't load Bundles yet as they need to be able
1273 to convert from port names to Port objects, which can't happen until
1275 _bundle_xml_node = new XMLNode (*child);
1279 if ((child = find_named_node (node, "TempoMap")) == 0) {
1280 error << _("Session: XML state has no Tempo Map section") << endmsg;
1282 } else if (_tempo_map->set_state (*child, version)) {
1286 if ((child = find_named_node (node, "Routes")) == 0) {
1287 error << _("Session: XML state has no routes section") << endmsg;
1289 } else if (load_routes (*child, version)) {
1293 if (version >= 3000) {
1295 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1296 error << _("Session: XML state has no route groups section") << endmsg;
1298 } else if (load_route_groups (*child, version)) {
1302 } else if (version < 3000) {
1304 if ((child = find_named_node (node, "EditGroups")) == 0) {
1305 error << _("Session: XML state has no edit groups section") << endmsg;
1307 } else if (load_route_groups (*child, version)) {
1311 if ((child = find_named_node (node, "MixGroups")) == 0) {
1312 error << _("Session: XML state has no mix groups section") << endmsg;
1314 } else if (load_route_groups (*child, version)) {
1319 if ((child = find_named_node (node, "Click")) == 0) {
1320 warning << _("Session: XML state has no click section") << endmsg;
1321 } else if (_click_io) {
1322 _click_io->set_state (*child, version);
1325 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1326 ControlProtocolManager::instance().set_protocol_states (*child);
1329 /* here beginneth the second phase ... */
1331 StateReady (); /* EMIT SIGNAL */
1340 Session::load_routes (const XMLNode& node, int version)
1343 XMLNodeConstIterator niter;
1344 RouteList new_routes;
1346 nlist = node.children();
1350 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1352 boost::shared_ptr<Route> route (XMLRouteFactory (**niter, version));
1355 error << _("Session: cannot create Route from XML description.") << endmsg;
1359 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1361 new_routes.push_back (route);
1364 add_routes (new_routes, false);
1369 boost::shared_ptr<Route>
1370 Session::XMLRouteFactory (const XMLNode& node, int version)
1372 if (node.name() != "Route") {
1373 return boost::shared_ptr<Route> ((Route*) 0);
1376 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1378 DataType type = DataType::AUDIO;
1379 const XMLProperty* prop = node.property("default-type");
1380 boost::shared_ptr<Route> ret;
1383 type = DataType(prop->value());
1386 assert(type != DataType::NIL);
1388 if (has_diskstream) {
1389 if (type == DataType::AUDIO) {
1390 AudioTrack* at = new AudioTrack (*this, node, version);
1391 boost_debug_shared_ptr_mark_interesting (at, "Track");
1395 ret.reset (new MidiTrack (*this, node, version));
1398 Route* rt = new Route (*this, node);
1399 boost_debug_shared_ptr_mark_interesting (rt, "Route");
1407 Session::load_regions (const XMLNode& node)
1410 XMLNodeConstIterator niter;
1411 boost::shared_ptr<Region> region;
1413 nlist = node.children();
1417 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1418 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1419 error << _("Session: cannot create Region from XML description.");
1420 const XMLProperty *name = (**niter).property("name");
1423 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1433 boost::shared_ptr<Region>
1434 Session::XMLRegionFactory (const XMLNode& node, bool full)
1436 const XMLProperty* type = node.property("type");
1440 if ( !type || type->value() == "audio" ) {
1442 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1444 } else if (type->value() == "midi") {
1446 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1450 } catch (failed_constructor& err) {
1451 return boost::shared_ptr<Region> ();
1454 return boost::shared_ptr<Region> ();
1457 boost::shared_ptr<AudioRegion>
1458 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1460 const XMLProperty* prop;
1461 boost::shared_ptr<Source> source;
1462 boost::shared_ptr<AudioSource> as;
1464 SourceList master_sources;
1465 uint32_t nchans = 1;
1468 if (node.name() != X_("Region")) {
1469 return boost::shared_ptr<AudioRegion>();
1472 if ((prop = node.property (X_("channels"))) != 0) {
1473 nchans = atoi (prop->value().c_str());
1476 if ((prop = node.property ("name")) == 0) {
1477 cerr << "no name for this region\n";
1481 if ((prop = node.property (X_("source-0"))) == 0) {
1482 if ((prop = node.property ("source")) == 0) {
1483 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1484 return boost::shared_ptr<AudioRegion>();
1488 PBD::ID s_id (prop->value());
1490 if ((source = source_by_id (s_id)) == 0) {
1491 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1492 return boost::shared_ptr<AudioRegion>();
1495 as = boost::dynamic_pointer_cast<AudioSource>(source);
1497 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1498 return boost::shared_ptr<AudioRegion>();
1501 sources.push_back (as);
1503 /* pickup other channels */
1505 for (uint32_t n=1; n < nchans; ++n) {
1506 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1507 if ((prop = node.property (buf)) != 0) {
1509 PBD::ID id2 (prop->value());
1511 if ((source = source_by_id (id2)) == 0) {
1512 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1513 return boost::shared_ptr<AudioRegion>();
1516 as = boost::dynamic_pointer_cast<AudioSource>(source);
1518 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1519 return boost::shared_ptr<AudioRegion>();
1521 sources.push_back (as);
1525 for (uint32_t n = 0; n < nchans; ++n) {
1526 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1527 if ((prop = node.property (buf)) != 0) {
1529 PBD::ID id2 (prop->value());
1531 if ((source = source_by_id (id2)) == 0) {
1532 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1533 return boost::shared_ptr<AudioRegion>();
1536 as = boost::dynamic_pointer_cast<AudioSource>(source);
1538 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1539 return boost::shared_ptr<AudioRegion>();
1541 master_sources.push_back (as);
1546 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1548 /* a final detail: this is the one and only place that we know how long missing files are */
1550 if (region->whole_file()) {
1551 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1552 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1554 sfp->set_length (region->length());
1559 if (!master_sources.empty()) {
1560 if (master_sources.size() != nchans) {
1561 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1563 region->set_master_sources (master_sources);
1571 catch (failed_constructor& err) {
1572 return boost::shared_ptr<AudioRegion>();
1576 boost::shared_ptr<MidiRegion>
1577 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1579 const XMLProperty* prop;
1580 boost::shared_ptr<Source> source;
1581 boost::shared_ptr<MidiSource> ms;
1583 uint32_t nchans = 1;
1585 if (node.name() != X_("Region")) {
1586 return boost::shared_ptr<MidiRegion>();
1589 if ((prop = node.property (X_("channels"))) != 0) {
1590 nchans = atoi (prop->value().c_str());
1593 if ((prop = node.property ("name")) == 0) {
1594 cerr << "no name for this region\n";
1598 // Multiple midi channels? that's just crazy talk
1599 assert(nchans == 1);
1601 if ((prop = node.property (X_("source-0"))) == 0) {
1602 if ((prop = node.property ("source")) == 0) {
1603 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1604 return boost::shared_ptr<MidiRegion>();
1608 PBD::ID s_id (prop->value());
1610 if ((source = source_by_id (s_id)) == 0) {
1611 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1612 return boost::shared_ptr<MidiRegion>();
1615 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1617 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1618 return boost::shared_ptr<MidiRegion>();
1621 sources.push_back (ms);
1624 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1625 /* a final detail: this is the one and only place that we know how long missing files are */
1627 if (region->whole_file()) {
1628 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1629 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1631 sfp->set_length (region->length());
1639 catch (failed_constructor& err) {
1640 return boost::shared_ptr<MidiRegion>();
1645 Session::get_sources_as_xml ()
1648 XMLNode* node = new XMLNode (X_("Sources"));
1649 Glib::Mutex::Lock lm (source_lock);
1651 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1652 node->add_child_nocopy (i->second->get_state());
1659 Session::path_from_region_name (DataType type, string name, string identifier)
1661 char buf[PATH_MAX+1];
1663 SessionDirectory sdir(get_best_session_directory_for_new_source());
1664 sys::path source_dir = ((type == DataType::AUDIO)
1665 ? sdir.sound_path() : sdir.midi_path());
1667 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1669 for (n = 0; n < 999999; ++n) {
1670 if (identifier.length()) {
1671 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1672 identifier.c_str(), n, ext.c_str());
1674 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1678 sys::path source_path = source_dir / buf;
1680 if (!sys::exists (source_path)) {
1681 return source_path.to_string();
1685 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1694 Session::load_sources (const XMLNode& node)
1697 XMLNodeConstIterator niter;
1698 boost::shared_ptr<Source> source;
1700 nlist = node.children();
1704 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1706 if ((source = XMLSourceFactory (**niter)) == 0) {
1707 error << _("Session: cannot create Source from XML description.") << endmsg;
1709 } catch (MissingSource& err) {
1710 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1711 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1718 boost::shared_ptr<Source>
1719 Session::XMLSourceFactory (const XMLNode& node)
1721 if (node.name() != "Source") {
1722 return boost::shared_ptr<Source>();
1726 /* note: do peak building in another thread when loading session state */
1727 return SourceFactory::create (*this, node, true);
1730 catch (failed_constructor& err) {
1731 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1732 return boost::shared_ptr<Source>();
1737 Session::save_template (string template_name)
1741 if (_state_of_the_state & CannotSave) {
1745 sys::path user_template_dir(user_template_directory());
1749 sys::create_directories (user_template_dir);
1751 catch(sys::filesystem_error& ex)
1753 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1754 user_template_dir.to_string(), ex.what()) << endmsg;
1758 tree.set_root (&get_template());
1760 sys::path template_file_path(user_template_dir);
1761 template_file_path /= template_name + template_suffix;
1763 if (sys::exists (template_file_path))
1765 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1766 template_file_path.to_string()) << endmsg;
1770 if (!tree.write (template_file_path.to_string())) {
1771 error << _("mix template not saved") << endmsg;
1779 Session::rename_template (string old_name, string new_name)
1781 sys::path old_path (user_template_directory());
1782 old_path /= old_name + template_suffix;
1784 sys::path new_path(user_template_directory());
1785 new_path /= new_name + template_suffix;
1787 if (sys::exists (new_path)) {
1788 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1789 new_path.to_string()) << endmsg;
1794 sys::rename (old_path, new_path);
1802 Session::delete_template (string name)
1804 sys::path path = user_template_directory();
1805 path /= name + template_suffix;
1816 Session::refresh_disk_space ()
1819 struct statfs statfsbuf;
1820 vector<space_and_path>::iterator i;
1821 Glib::Mutex::Lock lm (space_lock);
1824 /* get freespace on every FS that is part of the session path */
1826 _total_free_4k_blocks = 0;
1828 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1829 statfs ((*i).path.c_str(), &statfsbuf);
1831 scale = statfsbuf.f_bsize/4096.0;
1833 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1834 _total_free_4k_blocks += (*i).blocks;
1840 Session::get_best_session_directory_for_new_source ()
1842 vector<space_and_path>::iterator i;
1843 string result = _session_dir->root_path().to_string();
1845 /* handle common case without system calls */
1847 if (session_dirs.size() == 1) {
1851 /* OK, here's the algorithm we're following here:
1853 We want to select which directory to use for
1854 the next file source to be created. Ideally,
1855 we'd like to use a round-robin process so as to
1856 get maximum performance benefits from splitting
1857 the files across multiple disks.
1859 However, in situations without much diskspace, an
1860 RR approach may end up filling up a filesystem
1861 with new files while others still have space.
1862 Its therefore important to pay some attention to
1863 the freespace in the filesystem holding each
1864 directory as well. However, if we did that by
1865 itself, we'd keep creating new files in the file
1866 system with the most space until it was as full
1867 as all others, thus negating any performance
1868 benefits of this RAID-1 like approach.
1870 So, we use a user-configurable space threshold. If
1871 there are at least 2 filesystems with more than this
1872 much space available, we use RR selection between them.
1873 If not, then we pick the filesystem with the most space.
1875 This gets a good balance between the two
1879 refresh_disk_space ();
1881 int free_enough = 0;
1883 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1884 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1889 if (free_enough >= 2) {
1890 /* use RR selection process, ensuring that the one
1894 i = last_rr_session_dir;
1897 if (++i == session_dirs.end()) {
1898 i = session_dirs.begin();
1901 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1902 if (create_session_directory ((*i).path)) {
1904 last_rr_session_dir = i;
1909 } while (i != last_rr_session_dir);
1913 /* pick FS with the most freespace (and that
1914 seems to actually work ...)
1917 vector<space_and_path> sorted;
1918 space_and_path_ascending_cmp cmp;
1920 sorted = session_dirs;
1921 sort (sorted.begin(), sorted.end(), cmp);
1923 for (i = sorted.begin(); i != sorted.end(); ++i) {
1924 if (create_session_directory ((*i).path)) {
1926 last_rr_session_dir = i;
1936 Session::load_named_selections (const XMLNode& node)
1939 XMLNodeConstIterator niter;
1942 nlist = node.children();
1946 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1948 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1949 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1957 Session::XMLNamedSelectionFactory (const XMLNode& node)
1960 return new NamedSelection (*this, node);
1963 catch (failed_constructor& err) {
1969 Session::automation_dir () const
1971 return Glib::build_filename (_path, "automation");
1975 Session::analysis_dir () const
1977 return Glib::build_filename (_path, "analysis");
1981 Session::load_bundles (XMLNode const & node)
1983 XMLNodeList nlist = node.children();
1984 XMLNodeConstIterator niter;
1988 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1989 if ((*niter)->name() == "InputBundle") {
1990 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
1991 } else if ((*niter)->name() == "OutputBundle") {
1992 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
1994 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2003 Session::load_route_groups (const XMLNode& node, int version)
2005 XMLNodeList nlist = node.children();
2006 XMLNodeConstIterator niter;
2010 if (version >= 3000) {
2012 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2013 if ((*niter)->name() == "RouteGroup") {
2014 RouteGroup* rg = new RouteGroup (*this, "");
2015 add_route_group (rg);
2016 rg->set_state (**niter, version);
2020 } else if (version < 3000) {
2022 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2023 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2024 RouteGroup* rg = new RouteGroup (*this, "");
2025 add_route_group (rg);
2026 rg->set_state (**niter, version);
2035 Session::auto_save()
2037 save_state (_current_snapshot_name);
2041 state_file_filter (const string &str, void */*arg*/)
2043 return (str.length() > strlen(statefile_suffix) &&
2044 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2048 bool operator()(const string* a, const string* b) {
2054 remove_end(string* state)
2056 string statename(*state);
2058 string::size_type start,end;
2059 if ((start = statename.find_last_of ('/')) != string::npos) {
2060 statename = statename.substr (start+1);
2063 if ((end = statename.rfind(".ardour")) == string::npos) {
2064 end = statename.length();
2067 return new string(statename.substr (0, end));
2071 Session::possible_states (string path)
2073 PathScanner scanner;
2074 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2076 transform(states->begin(), states->end(), states->begin(), remove_end);
2079 sort (states->begin(), states->end(), cmp);
2085 Session::possible_states () const
2087 return possible_states(_path);
2091 Session::add_route_group (RouteGroup* g)
2093 _route_groups.push_back (g);
2094 route_group_added (g); /* EMIT SIGNAL */
2099 Session::remove_route_group (RouteGroup& rg)
2101 list<RouteGroup*>::iterator i;
2103 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2104 _route_groups.erase (i);
2107 route_group_removed (); /* EMIT SIGNAL */
2113 Session::route_group_by_name (string name)
2115 list<RouteGroup *>::iterator i;
2117 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2118 if ((*i)->name() == name) {
2126 Session::start_reversible_command (const string& name)
2128 UndoTransaction* trans = new UndoTransaction();
2129 trans->set_name(name);
2134 Session::finish_reversible_command (UndoTransaction& ut)
2137 gettimeofday(&now, 0);
2138 ut.set_timestamp(now);
2143 Session::begin_reversible_command(const string& name)
2145 UndoTransaction* trans = new UndoTransaction();
2146 trans->set_name(name);
2148 if (!_current_trans.empty()) {
2149 _current_trans.top()->add_command (trans);
2151 _current_trans.push(trans);
2156 Session::commit_reversible_command(Command *cmd)
2158 assert(!_current_trans.empty());
2162 _current_trans.top()->add_command(cmd);
2165 if (_current_trans.top()->empty()) {
2166 _current_trans.pop();
2170 gettimeofday(&now, 0);
2171 _current_trans.top()->set_timestamp(now);
2173 _history.add(_current_trans.top());
2174 _current_trans.pop();
2178 accept_all_non_peak_files (const string& path, void */*arg*/)
2180 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2184 accept_all_state_files (const string& path, void */*arg*/)
2186 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2190 Session::find_all_sources (string path, set<string>& result)
2195 if (!tree.read (path)) {
2199 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2204 XMLNodeConstIterator niter;
2206 nlist = node->children();
2210 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2214 if ((prop = (*niter)->property (X_("type"))) == 0) {
2218 DataType type (prop->value());
2220 if ((prop = (*niter)->property (X_("name"))) == 0) {
2224 if (prop->value()[0] == '/') {
2225 /* external file, ignore */
2229 Glib::ustring found_path;
2233 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2234 result.insert (found_path);
2242 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2244 PathScanner scanner;
2245 vector<string*>* state_files;
2247 string this_snapshot_path;
2253 if (ripped[ripped.length()-1] == '/') {
2254 ripped = ripped.substr (0, ripped.length() - 1);
2257 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2259 if (state_files == 0) {
2264 this_snapshot_path = _path;
2265 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2266 this_snapshot_path += statefile_suffix;
2268 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2270 if (exclude_this_snapshot && **i == this_snapshot_path) {
2274 if (find_all_sources (**i, result) < 0) {
2282 struct RegionCounter {
2283 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2284 AudioSourceList::iterator iter;
2285 boost::shared_ptr<Region> region;
2288 RegionCounter() : count (0) {}
2292 Session::ask_about_playlist_deletion (boost::shared_ptr<Playlist> p)
2294 return *AskAboutPlaylistDeletion (p);
2298 Session::cleanup_sources (CleanupReport& rep)
2300 // FIXME: needs adaptation to midi
2302 vector<boost::shared_ptr<Source> > dead_sources;
2303 PathScanner scanner;
2305 vector<space_and_path>::iterator i;
2306 vector<space_and_path>::iterator nexti;
2307 vector<string*>* soundfiles;
2308 vector<string> unused;
2309 set<string> all_sources;
2314 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2316 /* step 1: consider deleting all unused playlists */
2318 if (playlists->maybe_delete_unused (boost::bind (Session::ask_about_playlist_deletion, _1))) {
2323 /* step 2: find all un-used sources */
2328 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2330 SourceMap::iterator tmp;
2335 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2339 if (!playlists->source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2340 dead_sources.push_back (i->second);
2341 i->second->drop_references ();
2347 /* build a list of all the possible sound directories for the session */
2349 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2354 SessionDirectory sdir ((*i).path);
2355 sound_path += sdir.sound_path().to_string();
2357 if (nexti != session_dirs.end()) {
2364 /* now do the same thing for the files that ended up in the sounds dir(s)
2365 but are not referenced as sources in any snapshot.
2368 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2370 if (soundfiles == 0) {
2374 /* find all sources, but don't use this snapshot because the
2375 state file on disk still references sources we may have already
2379 find_all_sources_across_snapshots (all_sources, true);
2381 /* add our current source list
2384 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2385 boost::shared_ptr<FileSource> fs;
2387 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2388 all_sources.insert (fs->path());
2392 char tmppath1[PATH_MAX+1];
2393 char tmppath2[PATH_MAX+1];
2395 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2400 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2402 realpath(spath.c_str(), tmppath1);
2403 realpath((*i).c_str(), tmppath2);
2405 if (strcmp(tmppath1, tmppath2) == 0) {
2412 unused.push_back (spath);
2416 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2418 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2419 struct stat statbuf;
2421 rep.paths.push_back (*x);
2422 if (stat ((*x).c_str(), &statbuf) == 0) {
2423 rep.space += statbuf.st_size;
2428 /* don't move the file across filesystems, just
2429 stick it in the `dead_sound_dir_name' directory
2430 on whichever filesystem it was already on.
2433 if ((*x).find ("/sounds/") != string::npos) {
2435 /* old school, go up 1 level */
2437 newpath = Glib::path_get_dirname (*x); // "sounds"
2438 newpath = Glib::path_get_dirname (newpath); // "session-name"
2442 /* new school, go up 4 levels */
2444 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2445 newpath = Glib::path_get_dirname (newpath); // "session-name"
2446 newpath = Glib::path_get_dirname (newpath); // "interchange"
2447 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2451 newpath += dead_sound_dir_name;
2453 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2454 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2459 newpath += Glib::path_get_basename ((*x));
2461 if (access (newpath.c_str(), F_OK) == 0) {
2463 /* the new path already exists, try versioning */
2465 char buf[PATH_MAX+1];
2469 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2472 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2473 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2477 if (version == 999) {
2478 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2482 newpath = newpath_v;
2487 /* it doesn't exist, or we can't read it or something */
2491 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2492 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2493 (*x), newpath, strerror (errno))
2498 /* see if there an easy to find peakfile for this file, and remove it.
2501 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2502 peakpath += peakfile_suffix;
2504 if (access (peakpath.c_str(), W_OK) == 0) {
2505 if (::unlink (peakpath.c_str()) != 0) {
2506 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2507 peakpath, _path, strerror (errno))
2509 /* try to back out */
2510 rename (newpath.c_str(), _path.c_str());
2518 /* dump the history list */
2522 /* save state so we don't end up a session file
2523 referring to non-existent sources.
2529 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2535 Session::cleanup_trash_sources (CleanupReport& rep)
2537 // FIXME: needs adaptation for MIDI
2539 vector<space_and_path>::iterator i;
2540 string dead_sound_dir;
2541 struct dirent* dentry;
2542 struct stat statbuf;
2548 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2550 dead_sound_dir = (*i).path;
2551 dead_sound_dir += dead_sound_dir_name;
2553 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2557 while ((dentry = readdir (dead)) != 0) {
2559 /* avoid '.' and '..' */
2561 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2562 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2568 fullpath = dead_sound_dir;
2570 fullpath += dentry->d_name;
2572 if (stat (fullpath.c_str(), &statbuf)) {
2576 if (!S_ISREG (statbuf.st_mode)) {
2580 if (unlink (fullpath.c_str())) {
2581 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2582 fullpath, strerror (errno))
2586 rep.paths.push_back (dentry->d_name);
2587 rep.space += statbuf.st_size;
2598 Session::set_dirty ()
2600 bool was_dirty = dirty();
2602 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2606 DirtyChanged(); /* EMIT SIGNAL */
2612 Session::set_clean ()
2614 bool was_dirty = dirty();
2616 _state_of_the_state = Clean;
2620 DirtyChanged(); /* EMIT SIGNAL */
2625 Session::set_deletion_in_progress ()
2627 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2631 Session::clear_deletion_in_progress ()
2633 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2637 Session::add_controllable (boost::shared_ptr<Controllable> c)
2639 /* this adds a controllable to the list managed by the Session.
2640 this is a subset of those managed by the Controllable class
2641 itself, and represents the only ones whose state will be saved
2642 as part of the session.
2645 Glib::Mutex::Lock lm (controllables_lock);
2646 controllables.insert (c);
2649 struct null_deleter { void operator()(void const *) const {} };
2652 Session::remove_controllable (Controllable* c)
2654 if (_state_of_the_state | Deletion) {
2658 Glib::Mutex::Lock lm (controllables_lock);
2660 Controllables::iterator x = controllables.find (boost::shared_ptr<Controllable>(c, null_deleter()));
2662 if (x != controllables.end()) {
2663 controllables.erase (x);
2667 boost::shared_ptr<Controllable>
2668 Session::controllable_by_id (const PBD::ID& id)
2670 Glib::Mutex::Lock lm (controllables_lock);
2672 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2673 if ((*i)->id() == id) {
2678 return boost::shared_ptr<Controllable>();
2681 boost::shared_ptr<Controllable>
2682 Session::controllable_by_descriptor (const ControllableDescriptor& desc)
2684 boost::shared_ptr<Controllable> c;
2685 boost::shared_ptr<Route> r;
2687 switch (desc.top_level_type()) {
2688 case ControllableDescriptor::NamedRoute:
2690 std::string str = desc.top_level_name();
2691 if (str == "master") {
2693 } else if (str == "control" || str == "listen") {
2696 r = route_by_name (desc.top_level_name());
2701 case ControllableDescriptor::RemoteControlID:
2702 r = route_by_remote_id (desc.rid());
2710 switch (desc.subtype()) {
2711 case ControllableDescriptor::Gain:
2712 c = r->gain_control ();
2715 case ControllableDescriptor::Solo:
2716 c = r->solo_control();
2719 case ControllableDescriptor::Mute:
2720 c = r->mute_control();
2723 case ControllableDescriptor::Recenable:
2725 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(r);
2728 c = t->rec_enable_control ();
2733 case ControllableDescriptor::Pan:
2734 /* XXX pan control */
2737 case ControllableDescriptor::Balance:
2738 /* XXX simple pan control */
2741 case ControllableDescriptor::PluginParameter:
2743 uint32_t plugin = desc.target (0);
2744 uint32_t parameter_index = desc.target (1);
2746 /* revert to zero based counting */
2752 if (parameter_index > 0) {
2756 boost::shared_ptr<Processor> p = r->nth_plugin (plugin);
2759 c = boost::dynamic_pointer_cast<ARDOUR::AutomationControl>(
2760 p->control(Evoral::Parameter(PluginAutomation, 0, parameter_index)));
2765 case ControllableDescriptor::SendGain:
2767 uint32_t send = desc.target (0);
2769 /* revert to zero-based counting */
2775 boost::shared_ptr<Processor> p = r->nth_send (send);
2778 boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
2779 boost::shared_ptr<Amp> a = s->amp();
2782 c = s->amp()->gain_control();
2789 /* relax and return a null pointer */
2797 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2800 Stateful::add_instant_xml (node, _path);
2803 if (write_to_config) {
2804 Config->add_instant_xml (node);
2809 Session::instant_xml (const string& node_name)
2811 return Stateful::instant_xml (node_name, _path);
2815 Session::save_history (string snapshot_name)
2823 if (snapshot_name.empty()) {
2824 snapshot_name = _current_snapshot_name;
2827 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2828 const string backup_filename = history_filename + backup_suffix;
2829 const sys::path xml_path = _session_dir->root_path() / history_filename;
2830 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2832 if (sys::exists (xml_path)) {
2835 sys::rename (xml_path, backup_path);
2837 catch (const sys::filesystem_error& err)
2839 error << _("could not backup old history file, current history not saved") << endmsg;
2844 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2848 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2850 if (!tree.write (xml_path.to_string()))
2852 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2856 sys::remove (xml_path);
2857 sys::rename (backup_path, xml_path);
2859 catch (const sys::filesystem_error& err)
2861 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2862 backup_path.to_string(), err.what()) << endmsg;
2872 Session::restore_history (string snapshot_name)
2876 if (snapshot_name.empty()) {
2877 snapshot_name = _current_snapshot_name;
2880 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
2881 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2883 info << "Loading history from " << xml_path.to_string() << endmsg;
2885 if (!sys::exists (xml_path)) {
2886 info << string_compose (_("%1: no history file \"%2\" for this session."),
2887 _name, xml_path.to_string()) << endmsg;
2891 if (!tree.read (xml_path.to_string())) {
2892 error << string_compose (_("Could not understand session history file \"%1\""),
2893 xml_path.to_string()) << endmsg;
2900 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2903 UndoTransaction* ut = new UndoTransaction ();
2906 ut->set_name(t->property("name")->value());
2907 stringstream ss(t->property("tv-sec")->value());
2909 ss.str(t->property("tv-usec")->value());
2911 ut->set_timestamp(tv);
2913 for (XMLNodeConstIterator child_it = t->children().begin();
2914 child_it != t->children().end(); child_it++)
2916 XMLNode *n = *child_it;
2919 if (n->name() == "MementoCommand" ||
2920 n->name() == "MementoUndoCommand" ||
2921 n->name() == "MementoRedoCommand") {
2923 if ((c = memento_command_factory(n))) {
2927 } else if (n->name() == "DeltaCommand") {
2928 PBD::ID id(n->property("midi-source")->value());
2929 boost::shared_ptr<MidiSource> midi_source =
2930 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2932 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
2934 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2937 } else if (n->name() == "DiffCommand") {
2938 PBD::ID id(n->property("midi-source")->value());
2939 boost::shared_ptr<MidiSource> midi_source =
2940 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2942 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
2944 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2947 } else if (n->name() == "StatefulDiffCommand") {
2948 if ((c = stateful_diff_command_factory (n))) {
2949 ut->add_command (c);
2952 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2963 Session::config_changed (std::string p, bool ours)
2969 if (p == "seamless-loop") {
2971 } else if (p == "rf-speed") {
2973 } else if (p == "auto-loop") {
2975 } else if (p == "auto-input") {
2977 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2978 /* auto-input only makes a difference if we're rolling */
2980 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2982 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2983 if ((*i)->record_enabled ()) {
2984 (*i)->monitor_input (!config.get_auto_input());
2989 } else if (p == "punch-in") {
2993 if ((location = _locations.auto_punch_location()) != 0) {
2995 if (config.get_punch_in ()) {
2996 replace_event (SessionEvent::PunchIn, location->start());
2998 remove_event (location->start(), SessionEvent::PunchIn);
3002 } else if (p == "punch-out") {
3006 if ((location = _locations.auto_punch_location()) != 0) {
3008 if (config.get_punch_out()) {
3009 replace_event (SessionEvent::PunchOut, location->end());
3011 clear_events (SessionEvent::PunchOut);
3015 } else if (p == "edit-mode") {
3017 Glib::Mutex::Lock lm (playlists->lock);
3019 for (SessionPlaylists::List::iterator i = playlists->playlists.begin(); i != playlists->playlists.end(); ++i) {
3020 (*i)->set_edit_mode (Config->get_edit_mode ());
3023 } else if (p == "use-video-sync") {
3025 waiting_for_sync_offset = config.get_use_video_sync();
3027 } else if (p == "mmc-control") {
3029 //poke_midi_thread ();
3031 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3034 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3037 } else if (p == "mmc-send-id") {
3040 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3043 } else if (p == "midi-control") {
3045 //poke_midi_thread ();
3047 } else if (p == "raid-path") {
3049 setup_raid_path (config.get_raid_path());
3051 } else if (p == "timecode-format") {
3055 } else if (p == "video-pullup") {
3059 } else if (p == "seamless-loop") {
3061 if (play_loop && transport_rolling()) {
3062 // to reset diskstreams etc
3063 request_play_loop (true);
3066 } else if (p == "rf-speed") {
3068 cumulative_rf_motion = 0;
3071 } else if (p == "click-sound") {
3073 setup_click_sounds (1);
3075 } else if (p == "click-emphasis-sound") {
3077 setup_click_sounds (-1);
3079 } else if (p == "clicking") {
3081 if (Config->get_clicking()) {
3082 if (_click_io && click_data) { // don't require emphasis data
3089 } else if (p == "send-mtc") {
3091 /* only set the internal flag if we have
3095 if (_mtc_port != 0) {
3096 session_send_mtc = Config->get_send_mtc();
3097 if (session_send_mtc) {
3098 /* mark us ready to send */
3099 next_quarter_frame_to_send = 0;
3102 session_send_mtc = false;
3105 } else if (p == "send-mmc") {
3107 /* only set the internal flag if we have
3111 if (_mmc_port != 0) {
3112 session_send_mmc = Config->get_send_mmc();
3115 session_send_mmc = false;
3118 } else if (p == "midi-feedback") {
3120 /* only set the internal flag if we have
3124 if (_mtc_port != 0) {
3125 session_midi_feedback = Config->get_midi_feedback();
3128 } else if (p == "jack-time-master") {
3130 engine().reset_timebase ();
3132 } else if (p == "native-file-header-format") {
3134 if (!first_file_header_format_reset) {
3135 reset_native_file_format ();
3138 first_file_header_format_reset = false;
3140 } else if (p == "native-file-data-format") {
3142 if (!first_file_data_format_reset) {
3143 reset_native_file_format ();
3146 first_file_data_format_reset = false;
3148 } else if (p == "external-sync") {
3149 if (!config.get_external_sync()) {
3150 drop_sync_source ();
3152 switch_to_sync_source (config.get_sync_source());
3154 } else if (p == "remote-model") {
3155 set_remote_control_ids ();
3156 } else if (p == "denormal-model") {
3158 } else if (p == "history-depth") {
3159 set_history_depth (Config->get_history_depth());
3160 } else if (p == "sync-all-route-ordering") {
3161 sync_order_keys ("session");
3162 } else if (p == "initial-program-change") {
3164 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3167 buf[0] = MIDI::program; // channel zero by default
3168 buf[1] = (Config->get_initial_program_change() & 0x7f);
3170 _mmc_port->midimsg (buf, sizeof (buf), 0);
3172 } else if (p == "initial-program-change") {
3174 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3175 MIDI::byte* buf = new MIDI::byte[2];
3177 buf[0] = MIDI::program; // channel zero by default
3178 buf[1] = (Config->get_initial_program_change() & 0x7f);
3179 // deliver_midi (_mmc_port, buf, 2);
3181 } else if (p == "solo-mute-override") {
3182 // catch_up_on_solo_mute_override ();
3183 } else if (p == "listen-position") {
3184 listen_position_changed ();
3185 } else if (p == "solo-control-is-listen-control") {
3186 solo_control_mode_changed ();
3194 Session::set_history_depth (uint32_t d)
3196 _history.set_depth (d);