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
33 #include <sigc++/bind.h>
35 #include <cstdio> /* snprintf(3) ... grrr */
50 #include <sys/param.h>
51 #include <sys/mount.h>
55 #include <glibmm/thread.h>
57 #include "midi++/mmc.h"
58 #include "midi++/port.h"
60 #include "pbd/error.h"
61 #include "pbd/pathscanner.h"
62 #include "pbd/pthread_utils.h"
63 #include "pbd/search_path.h"
64 #include "pbd/stacktrace.h"
66 #include "ardour/audio_diskstream.h"
67 #include "ardour/audio_track.h"
68 #include "ardour/audioengine.h"
69 #include "ardour/audiofilesource.h"
70 #include "ardour/audioplaylist.h"
71 #include "ardour/audioregion.h"
72 #include "ardour/auditioner.h"
73 #include "ardour/buffer.h"
74 #include "ardour/butler.h"
75 #include "ardour/configuration.h"
76 #include "ardour/control_protocol_manager.h"
77 #include "ardour/crossfade.h"
78 #include "ardour/cycle_timer.h"
79 #include "ardour/directory_names.h"
80 #include "ardour/filename_extensions.h"
81 #include "ardour/io_processor.h"
82 #include "ardour/location.h"
83 #include "ardour/midi_diskstream.h"
84 #include "ardour/midi_patch_manager.h"
85 #include "ardour/midi_playlist.h"
86 #include "ardour/midi_region.h"
87 #include "ardour/midi_source.h"
88 #include "ardour/midi_track.h"
89 #include "ardour/named_selection.h"
90 #include "ardour/playlist_factory.h"
91 #include "ardour/processor.h"
92 #include "ardour/region_factory.h"
93 #include "ardour/route_group.h"
94 #include "ardour/send.h"
95 #include "ardour/session.h"
96 #include "ardour/session_directory.h"
97 #include "ardour/session_metadata.h"
98 #include "ardour/session_state_utils.h"
99 #include "ardour/session_utils.h"
100 #include "ardour/silentfilesource.h"
101 #include "ardour/slave.h"
102 #include "ardour/smf_source.h"
103 #include "ardour/sndfile_helpers.h"
104 #include "ardour/sndfilesource.h"
105 #include "ardour/source_factory.h"
106 #include "ardour/template_utils.h"
107 #include "ardour/tempo.h"
108 #include "ardour/ticker.h"
109 #include "ardour/user_bundle.h"
110 #include "ardour/utils.h"
111 #include "ardour/utils.h"
112 #include "ardour/version.h"
114 #include "control_protocol/control_protocol.h"
120 using namespace ARDOUR;
124 Session::first_stage_init (string fullpath, string snapshot_name)
126 if (fullpath.length() == 0) {
128 throw failed_constructor();
131 char buf[PATH_MAX+1];
132 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
133 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
135 throw failed_constructor();
140 if (_path[_path.length()-1] != '/') {
144 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
145 cerr << "Session non-writable based on " << _path << endl;
148 cerr << "Session writable based on " << _path << endl;
152 /* these two are just provisional settings. set_state()
153 will likely override them.
156 _name = _current_snapshot_name = snapshot_name;
158 set_history_depth (Config->get_history_depth());
160 _current_frame_rate = _engine.frame_rate ();
161 _nominal_frame_rate = _current_frame_rate;
162 _base_frame_rate = _current_frame_rate;
164 _tempo_map = new TempoMap (_current_frame_rate);
165 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
168 _non_soloed_outs_muted = false;
170 g_atomic_int_set (&processing_prohibited, 0);
171 _transport_speed = 0;
172 _last_transport_speed = 0;
173 _target_transport_speed = 0;
174 auto_play_legal = false;
175 transport_sub_state = 0;
176 _transport_frame = 0;
177 _requested_return_frame = -1;
178 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
179 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
180 g_atomic_int_set (&_record_status, Disabled);
181 loop_changing = false;
184 _last_roll_location = 0;
185 _last_record_location = 0;
186 pending_locate_frame = 0;
187 pending_locate_roll = false;
188 pending_locate_flush = false;
189 state_was_pending = false;
191 outbound_mtc_timecode_frame = 0;
192 next_quarter_frame_to_send = -1;
193 current_block_size = 0;
194 solo_update_disabled = false;
195 _have_captured = false;
196 _worst_output_latency = 0;
197 _worst_input_latency = 0;
198 _worst_track_latency = 0;
199 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
200 _was_seamless = Config->get_seamless_loop ();
202 session_send_mmc = false;
203 session_send_mtc = false;
204 g_atomic_int_set (&_playback_load, 100);
205 g_atomic_int_set (&_capture_load, 100);
206 g_atomic_int_set (&_playback_load_min, 100);
207 g_atomic_int_set (&_capture_load_min, 100);
210 _exporting_realtime = false;
211 _gain_automation_buffer = 0;
212 _pan_automation_buffer = 0;
214 pending_abort = false;
215 destructive_index = 0;
216 first_file_data_format_reset = true;
217 first_file_header_format_reset = true;
218 //midi_thread = (pthread_t) 0;
220 AudioDiskstream::allocate_working_buffers();
222 /* default short fade = 15ms */
224 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
225 SndFileSource::setup_standard_crossfades (*this, frame_rate());
227 last_mmc_step.tv_sec = 0;
228 last_mmc_step.tv_usec = 0;
231 /* click sounds are unset by default, which causes us to internal
232 waveforms for clicks.
236 click_emphasis_length = 0;
239 process_function = &Session::process_with_events;
241 if (config.get_use_video_sync()) {
242 waiting_for_sync_offset = true;
244 waiting_for_sync_offset = false;
247 last_timecode_when = 0;
248 _timecode_offset = 0;
249 _timecode_offset_negative = true;
250 last_timecode_valid = false;
254 last_rr_session_dir = session_dirs.begin();
255 refresh_disk_space ();
257 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
261 average_slave_delta = 1800; // !!! why 1800 ????
262 have_first_delta_accumulator = false;
263 delta_accumulator_cnt = 0;
264 slave_state = Stopped;
266 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
268 /* These are all static "per-class" signals */
270 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
271 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
272 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
273 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
274 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
275 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
277 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
279 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
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 (mem_fun (this, &Session::locations_changed));
332 _locations.added.connect (mem_fun (this, &Session::locations_added));
333 setup_click_sounds (0);
334 setup_midi_control ();
336 /* Pay attention ... */
338 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
339 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
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::ensure_subdirs ()
441 dir = session_directory().peak_path().to_string();
443 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
444 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
448 dir = session_directory().sound_path().to_string();
450 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
451 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
455 dir = session_directory().midi_path().to_string();
457 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
458 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
462 dir = session_directory().dead_sound_path().to_string();
464 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
465 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
469 dir = session_directory().export_path().to_string();
471 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
472 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
476 dir = analysis_dir ();
478 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
479 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
487 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
490 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
491 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
495 if (ensure_subdirs ()) {
499 /* check new_session so we don't overwrite an existing one */
501 if (!mix_template.empty()) {
502 std::string in_path = mix_template;
504 ifstream in(in_path.c_str());
507 string out_path = _path;
509 out_path += statefile_suffix;
511 ofstream out(out_path.c_str());
516 // okay, session is set up. Treat like normal saved
517 // session from now on.
523 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
529 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
536 /* Instantiate metadata */
538 _metadata = new SessionMetadata ();
540 /* set initial start + end point */
542 start_location->set_end (0);
543 _locations.add (start_location);
545 end_location->set_end (initial_length);
546 _locations.add (end_location);
548 _state_of_the_state = Clean;
557 Session::load_diskstreams (const XMLNode& node)
560 XMLNodeConstIterator citer;
562 clist = node.children();
564 for (citer = clist.begin(); citer != clist.end(); ++citer) {
567 /* diskstreams added automatically by DiskstreamCreated handler */
568 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
569 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
570 add_diskstream (dstream);
571 } else if ((*citer)->name() == "MidiDiskstream") {
572 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
573 add_diskstream (dstream);
575 error << _("Session: unknown diskstream type in XML") << endmsg;
579 catch (failed_constructor& err) {
580 error << _("Session: could not load diskstream via XML state") << endmsg;
589 Session::maybe_write_autosave()
591 if (dirty() && record_status() != Recording) {
592 save_state("", true);
597 Session::remove_pending_capture_state ()
599 sys::path pending_state_file_path(_session_dir->root_path());
601 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
605 sys::remove (pending_state_file_path);
607 catch(sys::filesystem_error& ex)
609 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
610 pending_state_file_path.to_string(), ex.what()) << endmsg;
614 /** Rename a state file.
615 * @param snapshot_name Snapshot name.
618 Session::rename_state (string old_name, string new_name)
620 if (old_name == _current_snapshot_name || old_name == _name) {
621 /* refuse to rename the current snapshot or the "main" one */
625 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
626 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
628 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
629 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
633 sys::rename (old_xml_path, new_xml_path);
635 catch (const sys::filesystem_error& err)
637 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
638 old_name, new_name, err.what()) << endmsg;
642 /** Remove a state file.
643 * @param snapshot_name Snapshot name.
646 Session::remove_state (string snapshot_name)
648 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
649 // refuse to remove the current snapshot or the "main" one
653 sys::path xml_path(_session_dir->root_path());
655 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
657 if (!create_backup_file (xml_path)) {
658 // don't remove it if a backup can't be made
659 // create_backup_file will log the error.
664 sys::remove (xml_path);
668 Session::save_state (string snapshot_name, bool pending)
671 sys::path xml_path(_session_dir->root_path());
673 if (!_writable || (_state_of_the_state & CannotSave)) {
677 if (!_engine.connected ()) {
678 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
683 /* tell sources we're saving first, in case they write out to a new file
684 * which should be saved with the state rather than the old one */
685 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
686 i->second->session_saved();
688 tree.set_root (&get_state());
690 if (snapshot_name.empty()) {
691 snapshot_name = _current_snapshot_name;
696 /* proper save: use statefile_suffix (.ardour in English) */
698 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
700 /* make a backup copy of the old file */
702 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
703 // create_backup_file will log the error
709 /* pending save: use pending_suffix (.pending in English) */
710 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
713 sys::path tmp_path(_session_dir->root_path());
715 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
717 // cerr << "actually writing state to " << xml_path.to_string() << endl;
719 if (!tree.write (tmp_path.to_string())) {
720 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
721 sys::remove (tmp_path);
726 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
727 error << string_compose (_("could not rename temporary session file %1 to %2"),
728 tmp_path.to_string(), xml_path.to_string()) << endmsg;
729 sys::remove (tmp_path);
736 save_history (snapshot_name);
738 bool was_dirty = dirty();
740 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
743 DirtyChanged (); /* EMIT SIGNAL */
746 StateSaved (snapshot_name); /* EMIT SIGNAL */
753 Session::restore_state (string snapshot_name)
755 if (load_state (snapshot_name) == 0) {
756 set_state (*state_tree->root(), Stateful::loading_state_version);
763 Session::load_state (string snapshot_name)
768 state_was_pending = false;
770 /* check for leftover pending state from a crashed capture attempt */
772 sys::path xmlpath(_session_dir->root_path());
773 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
775 if (sys::exists (xmlpath)) {
777 /* there is pending state from a crashed capture attempt */
779 if (AskAboutPendingState()) {
780 state_was_pending = true;
784 if (!state_was_pending) {
785 xmlpath = _session_dir->root_path();
786 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
789 if (!sys::exists (xmlpath)) {
790 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
794 state_tree = new XMLTree;
798 /* writable() really reflects the whole folder, but if for any
799 reason the session state file can't be written to, still
803 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
807 if (!state_tree->read (xmlpath.to_string())) {
808 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
814 XMLNode& root (*state_tree->root());
816 if (root.name() != X_("Session")) {
817 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
823 const XMLProperty* prop;
825 if ((prop = root.property ("version")) == 0) {
826 /* no version implies very old version of Ardour */
827 Stateful::loading_state_version = 1000;
833 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
834 Stateful::loading_state_version = (major * 1000) + minor;
837 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
839 sys::path backup_path(_session_dir->root_path());
841 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
843 // only create a backup once
844 if (sys::exists (backup_path)) {
848 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
849 xmlpath.to_string(), backup_path.to_string())
854 sys::copy_file (xmlpath, backup_path);
856 catch(sys::filesystem_error& ex)
858 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
859 xmlpath.to_string(), ex.what())
869 Session::load_options (const XMLNode& node)
871 LocaleGuard lg (X_("POSIX"));
873 config.set_variables (node);
875 /* now reset MIDI ports because the session can have its own
891 Session::get_template()
893 /* if we don't disable rec-enable, diskstreams
894 will believe they need to store their capture
895 sources in their state node.
898 disable_record (false);
904 Session::state(bool full_state)
906 XMLNode* node = new XMLNode("Session");
909 // store libardour version, just in case
911 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
912 node->add_property("version", string(buf));
914 /* store configuration settings */
918 node->add_property ("name", _name);
919 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
920 node->add_property ("sample-rate", buf);
922 if (session_dirs.size() > 1) {
926 vector<space_and_path>::iterator i = session_dirs.begin();
927 vector<space_and_path>::iterator next;
929 ++i; /* skip the first one */
933 while (i != session_dirs.end()) {
937 if (next != session_dirs.end()) {
947 child = node->add_child ("Path");
948 child->add_content (p);
952 /* save the ID counter */
954 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
955 node->add_property ("id-counter", buf);
957 /* various options */
959 node->add_child_nocopy (config.get_variables ());
961 node->add_child_nocopy (_metadata->get_state());
963 child = node->add_child ("Sources");
966 Glib::Mutex::Lock sl (source_lock);
968 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
970 /* Don't save information about non-destructive file sources that are empty */
971 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
973 boost::shared_ptr<AudioFileSource> fs;
974 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
975 if (!fs->destructive()) {
976 if (fs->length(fs->timeline_position()) == 0) {
982 child->add_child_nocopy (siter->second->get_state());
986 child = node->add_child ("Regions");
989 Glib::Mutex::Lock rl (region_lock);
991 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
993 /* only store regions not attached to playlists */
995 if (i->second->playlist() == 0) {
996 child->add_child_nocopy (i->second->state (true));
1001 child = node->add_child ("DiskStreams");
1004 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1005 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1006 if (!(*i)->hidden()) {
1007 child->add_child_nocopy ((*i)->get_state());
1013 node->add_child_nocopy (_locations.get_state());
1015 // for a template, just create a new Locations, populate it
1016 // with the default start and end, and get the state for that.
1018 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1019 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1022 end->set_end(compute_initial_length());
1024 node->add_child_nocopy (loc.get_state());
1027 child = node->add_child ("Bundles");
1029 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1030 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1031 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1033 child->add_child_nocopy (b->get_state());
1038 child = node->add_child ("Routes");
1040 boost::shared_ptr<RouteList> r = routes.reader ();
1042 RoutePublicOrderSorter cmp;
1043 RouteList public_order (*r);
1044 public_order.sort (cmp);
1046 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1047 if (!(*i)->is_hidden()) {
1049 child->add_child_nocopy ((*i)->get_state());
1051 child->add_child_nocopy ((*i)->get_template());
1058 child = node->add_child ("RouteGroups");
1059 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1060 child->add_child_nocopy ((*i)->get_state());
1063 child = node->add_child ("Playlists");
1064 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1065 if (!(*i)->hidden()) {
1066 if (!(*i)->empty()) {
1068 child->add_child_nocopy ((*i)->get_state());
1070 child->add_child_nocopy ((*i)->get_template());
1076 child = node->add_child ("UnusedPlaylists");
1077 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1078 if (!(*i)->hidden()) {
1079 if (!(*i)->empty()) {
1081 child->add_child_nocopy ((*i)->get_state());
1083 child->add_child_nocopy ((*i)->get_template());
1091 child = node->add_child ("Click");
1092 child->add_child_nocopy (_click_io->state (full_state));
1096 child = node->add_child ("NamedSelections");
1097 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1099 child->add_child_nocopy ((*i)->get_state());
1104 node->add_child_nocopy (_tempo_map->get_state());
1106 node->add_child_nocopy (get_control_protocol_state());
1109 node->add_child_copy (*_extra_xml);
1116 Session::get_control_protocol_state ()
1118 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1119 return cpm.get_state();
1123 Session::set_state (const XMLNode& node, int version)
1127 const XMLProperty* prop;
1130 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1132 if (node.name() != X_("Session")){
1133 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1137 if ((prop = node.property ("version")) != 0) {
1138 version = atoi (prop->value ()) * 1000;
1141 if ((prop = node.property ("name")) != 0) {
1142 _name = prop->value ();
1145 if ((prop = node.property (X_("sample-rate"))) != 0) {
1147 _nominal_frame_rate = atoi (prop->value());
1149 if (_nominal_frame_rate != _current_frame_rate) {
1150 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1156 setup_raid_path(_session_dir->root_path().to_string());
1158 if ((prop = node.property (X_("id-counter"))) != 0) {
1160 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1161 ID::init_counter (x);
1163 /* old sessions used a timebased counter, so fake
1164 the startup ID counter based on a standard
1169 ID::init_counter (now);
1173 IO::disable_connecting ();
1175 /* Object loading order:
1180 MIDI Control // relies on data from Options/Config
1194 if ((child = find_named_node (node, "Extra")) != 0) {
1195 _extra_xml = new XMLNode (*child);
1198 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1199 load_options (*child);
1200 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1201 load_options (*child);
1203 error << _("Session: XML state has no options section") << endmsg;
1206 if (use_config_midi_ports ()) {
1209 if (version >= 3000) {
1210 if ((child = find_named_node (node, "Metadata")) == 0) {
1211 warning << _("Session: XML state has no metadata section") << endmsg;
1212 } else if (_metadata->set_state (*child, version)) {
1217 if ((child = find_named_node (node, "Locations")) == 0) {
1218 error << _("Session: XML state has no locations section") << endmsg;
1220 } else if (_locations.set_state (*child, version)) {
1226 if ((location = _locations.auto_loop_location()) != 0) {
1227 set_auto_loop_location (location);
1230 if ((location = _locations.auto_punch_location()) != 0) {
1231 set_auto_punch_location (location);
1234 if ((location = _locations.end_location()) == 0) {
1235 _locations.add (end_location);
1237 delete end_location;
1238 end_location = location;
1241 if ((location = _locations.start_location()) == 0) {
1242 _locations.add (start_location);
1244 delete start_location;
1245 start_location = location;
1248 AudioFileSource::set_header_position_offset (start_location->start());
1250 if ((child = find_named_node (node, "Sources")) == 0) {
1251 error << _("Session: XML state has no sources section") << endmsg;
1253 } else if (load_sources (*child)) {
1257 if ((child = find_named_node (node, "Regions")) == 0) {
1258 error << _("Session: XML state has no Regions section") << endmsg;
1260 } else if (load_regions (*child)) {
1264 if ((child = find_named_node (node, "Playlists")) == 0) {
1265 error << _("Session: XML state has no playlists section") << endmsg;
1267 } else if (load_playlists (*child)) {
1271 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1273 } else if (load_unused_playlists (*child)) {
1277 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1278 if (load_named_selections (*child)) {
1283 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1284 error << _("Session: XML state has no diskstreams section") << endmsg;
1286 } else if (load_diskstreams (*child)) {
1290 if (version >= 3000) {
1291 if ((child = find_named_node (node, "Bundles")) == 0) {
1292 warning << _("Session: XML state has no bundles section") << endmsg;
1295 /* We can't load Bundles yet as they need to be able
1296 to convert from port names to Port objects, which can't happen until
1298 _bundle_xml_node = new XMLNode (*child);
1302 if (version >= 3000) {
1304 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1305 error << _("Session: XML state has no route groups section") << endmsg;
1307 } else if (load_route_groups (*child, version)) {
1311 } else if (version < 3000) {
1313 if ((child = find_named_node (node, "EditGroups")) == 0) {
1314 error << _("Session: XML state has no edit groups section") << endmsg;
1316 } else if (load_route_groups (*child, version)) {
1320 if ((child = find_named_node (node, "MixGroups")) == 0) {
1321 error << _("Session: XML state has no mix groups section") << endmsg;
1323 } else if (load_route_groups (*child, version)) {
1328 if ((child = find_named_node (node, "TempoMap")) == 0) {
1329 error << _("Session: XML state has no Tempo Map section") << endmsg;
1331 } else if (_tempo_map->set_state (*child, version)) {
1335 if ((child = find_named_node (node, "Routes")) == 0) {
1336 error << _("Session: XML state has no routes section") << endmsg;
1338 } else if (load_routes (*child, version)) {
1342 if ((child = find_named_node (node, "Click")) == 0) {
1343 warning << _("Session: XML state has no click section") << endmsg;
1344 } else if (_click_io) {
1345 _click_io->set_state (*child, version);
1348 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1349 ControlProtocolManager::instance().set_protocol_states (*child);
1352 /* here beginneth the second phase ... */
1354 StateReady (); /* EMIT SIGNAL */
1363 Session::load_routes (const XMLNode& node, int version)
1366 XMLNodeConstIterator niter;
1367 RouteList new_routes;
1369 nlist = node.children();
1373 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1375 boost::shared_ptr<Route> route (XMLRouteFactory (**niter, version));
1378 error << _("Session: cannot create Route from XML description.") << endmsg;
1382 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1384 new_routes.push_back (route);
1387 add_routes (new_routes, false);
1392 boost::shared_ptr<Route>
1393 Session::XMLRouteFactory (const XMLNode& node, int version)
1395 if (node.name() != "Route") {
1396 return boost::shared_ptr<Route> ((Route*) 0);
1399 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1401 DataType type = DataType::AUDIO;
1402 const XMLProperty* prop = node.property("default-type");
1405 type = DataType(prop->value());
1408 assert(type != DataType::NIL);
1410 if (has_diskstream) {
1411 if (type == DataType::AUDIO) {
1412 boost::shared_ptr<Route> ret (new AudioTrack (*this, node, version));
1415 boost::shared_ptr<Route> ret (new MidiTrack (*this, node, version));
1419 boost::shared_ptr<Route> ret (new Route (*this, node));
1425 Session::load_regions (const XMLNode& node)
1428 XMLNodeConstIterator niter;
1429 boost::shared_ptr<Region> region;
1431 nlist = node.children();
1435 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1436 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1437 error << _("Session: cannot create Region from XML description.");
1438 const XMLProperty *name = (**niter).property("name");
1441 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1451 boost::shared_ptr<Region>
1452 Session::XMLRegionFactory (const XMLNode& node, bool full)
1454 const XMLProperty* type = node.property("type");
1458 if ( !type || type->value() == "audio" ) {
1460 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1462 } else if (type->value() == "midi") {
1464 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1468 } catch (failed_constructor& err) {
1469 return boost::shared_ptr<Region> ();
1472 return boost::shared_ptr<Region> ();
1475 boost::shared_ptr<AudioRegion>
1476 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1478 const XMLProperty* prop;
1479 boost::shared_ptr<Source> source;
1480 boost::shared_ptr<AudioSource> as;
1482 SourceList master_sources;
1483 uint32_t nchans = 1;
1486 if (node.name() != X_("Region")) {
1487 return boost::shared_ptr<AudioRegion>();
1490 if ((prop = node.property (X_("channels"))) != 0) {
1491 nchans = atoi (prop->value().c_str());
1494 if ((prop = node.property ("name")) == 0) {
1495 cerr << "no name for this region\n";
1499 if ((prop = node.property (X_("source-0"))) == 0) {
1500 if ((prop = node.property ("source")) == 0) {
1501 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1502 return boost::shared_ptr<AudioRegion>();
1506 PBD::ID s_id (prop->value());
1508 if ((source = source_by_id (s_id)) == 0) {
1509 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1510 return boost::shared_ptr<AudioRegion>();
1513 as = boost::dynamic_pointer_cast<AudioSource>(source);
1515 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1516 return boost::shared_ptr<AudioRegion>();
1519 sources.push_back (as);
1521 /* pickup other channels */
1523 for (uint32_t n=1; n < nchans; ++n) {
1524 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1525 if ((prop = node.property (buf)) != 0) {
1527 PBD::ID id2 (prop->value());
1529 if ((source = source_by_id (id2)) == 0) {
1530 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1531 return boost::shared_ptr<AudioRegion>();
1534 as = boost::dynamic_pointer_cast<AudioSource>(source);
1536 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1537 return boost::shared_ptr<AudioRegion>();
1539 sources.push_back (as);
1543 for (uint32_t n = 0; n < nchans; ++n) {
1544 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1545 if ((prop = node.property (buf)) != 0) {
1547 PBD::ID id2 (prop->value());
1549 if ((source = source_by_id (id2)) == 0) {
1550 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1551 return boost::shared_ptr<AudioRegion>();
1554 as = boost::dynamic_pointer_cast<AudioSource>(source);
1556 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1557 return boost::shared_ptr<AudioRegion>();
1559 master_sources.push_back (as);
1564 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1566 /* a final detail: this is the one and only place that we know how long missing files are */
1568 if (region->whole_file()) {
1569 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1570 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1572 sfp->set_length (region->length());
1577 if (!master_sources.empty()) {
1578 if (master_sources.size() != nchans) {
1579 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1581 region->set_master_sources (master_sources);
1589 catch (failed_constructor& err) {
1590 return boost::shared_ptr<AudioRegion>();
1594 boost::shared_ptr<MidiRegion>
1595 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1597 const XMLProperty* prop;
1598 boost::shared_ptr<Source> source;
1599 boost::shared_ptr<MidiSource> ms;
1601 uint32_t nchans = 1;
1603 if (node.name() != X_("Region")) {
1604 return boost::shared_ptr<MidiRegion>();
1607 if ((prop = node.property (X_("channels"))) != 0) {
1608 nchans = atoi (prop->value().c_str());
1611 if ((prop = node.property ("name")) == 0) {
1612 cerr << "no name for this region\n";
1616 // Multiple midi channels? that's just crazy talk
1617 assert(nchans == 1);
1619 if ((prop = node.property (X_("source-0"))) == 0) {
1620 if ((prop = node.property ("source")) == 0) {
1621 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1622 return boost::shared_ptr<MidiRegion>();
1626 PBD::ID s_id (prop->value());
1628 if ((source = source_by_id (s_id)) == 0) {
1629 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1630 return boost::shared_ptr<MidiRegion>();
1633 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1635 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1636 return boost::shared_ptr<MidiRegion>();
1639 sources.push_back (ms);
1642 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1643 /* a final detail: this is the one and only place that we know how long missing files are */
1645 if (region->whole_file()) {
1646 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1647 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1649 sfp->set_length (region->length());
1657 catch (failed_constructor& err) {
1658 return boost::shared_ptr<MidiRegion>();
1663 Session::get_sources_as_xml ()
1666 XMLNode* node = new XMLNode (X_("Sources"));
1667 Glib::Mutex::Lock lm (source_lock);
1669 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1670 node->add_child_nocopy (i->second->get_state());
1677 Session::path_from_region_name (DataType type, string name, string identifier)
1679 char buf[PATH_MAX+1];
1681 SessionDirectory sdir(get_best_session_directory_for_new_source());
1682 sys::path source_dir = ((type == DataType::AUDIO)
1683 ? sdir.sound_path() : sdir.midi_path());
1685 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1687 for (n = 0; n < 999999; ++n) {
1688 if (identifier.length()) {
1689 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1690 identifier.c_str(), n, ext.c_str());
1692 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1696 sys::path source_path = source_dir / buf;
1698 if (!sys::exists (source_path)) {
1699 return source_path.to_string();
1703 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1712 Session::load_sources (const XMLNode& node)
1715 XMLNodeConstIterator niter;
1716 boost::shared_ptr<Source> source;
1718 nlist = node.children();
1722 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1724 if ((source = XMLSourceFactory (**niter)) == 0) {
1725 error << _("Session: cannot create Source from XML description.") << endmsg;
1727 } catch (MissingSource& err) {
1728 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1729 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1736 boost::shared_ptr<Source>
1737 Session::XMLSourceFactory (const XMLNode& node)
1739 if (node.name() != "Source") {
1740 return boost::shared_ptr<Source>();
1744 /* note: do peak building in another thread when loading session state */
1745 return SourceFactory::create (*this, node, true);
1748 catch (failed_constructor& err) {
1749 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1750 return boost::shared_ptr<Source>();
1755 Session::save_template (string template_name)
1759 if (_state_of_the_state & CannotSave) {
1763 sys::path user_template_dir(user_template_directory());
1767 sys::create_directories (user_template_dir);
1769 catch(sys::filesystem_error& ex)
1771 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1772 user_template_dir.to_string(), ex.what()) << endmsg;
1776 tree.set_root (&get_template());
1778 sys::path template_file_path(user_template_dir);
1779 template_file_path /= template_name + template_suffix;
1781 if (sys::exists (template_file_path))
1783 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1784 template_file_path.to_string()) << endmsg;
1788 if (!tree.write (template_file_path.to_string())) {
1789 error << _("mix template not saved") << endmsg;
1797 Session::rename_template (string old_name, string new_name)
1799 sys::path old_path (user_template_directory());
1800 old_path /= old_name + template_suffix;
1802 sys::path new_path(user_template_directory());
1803 new_path /= new_name + template_suffix;
1805 if (sys::exists (new_path)) {
1806 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1807 new_path.to_string()) << endmsg;
1812 sys::rename (old_path, new_path);
1820 Session::delete_template (string name)
1822 sys::path path = user_template_directory();
1823 path /= name + template_suffix;
1834 Session::refresh_disk_space ()
1837 struct statfs statfsbuf;
1838 vector<space_and_path>::iterator i;
1839 Glib::Mutex::Lock lm (space_lock);
1842 /* get freespace on every FS that is part of the session path */
1844 _total_free_4k_blocks = 0;
1846 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1847 statfs ((*i).path.c_str(), &statfsbuf);
1849 scale = statfsbuf.f_bsize/4096.0;
1851 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1852 _total_free_4k_blocks += (*i).blocks;
1858 Session::get_best_session_directory_for_new_source ()
1860 vector<space_and_path>::iterator i;
1861 string result = _session_dir->root_path().to_string();
1863 /* handle common case without system calls */
1865 if (session_dirs.size() == 1) {
1869 /* OK, here's the algorithm we're following here:
1871 We want to select which directory to use for
1872 the next file source to be created. Ideally,
1873 we'd like to use a round-robin process so as to
1874 get maximum performance benefits from splitting
1875 the files across multiple disks.
1877 However, in situations without much diskspace, an
1878 RR approach may end up filling up a filesystem
1879 with new files while others still have space.
1880 Its therefore important to pay some attention to
1881 the freespace in the filesystem holding each
1882 directory as well. However, if we did that by
1883 itself, we'd keep creating new files in the file
1884 system with the most space until it was as full
1885 as all others, thus negating any performance
1886 benefits of this RAID-1 like approach.
1888 So, we use a user-configurable space threshold. If
1889 there are at least 2 filesystems with more than this
1890 much space available, we use RR selection between them.
1891 If not, then we pick the filesystem with the most space.
1893 This gets a good balance between the two
1897 refresh_disk_space ();
1899 int free_enough = 0;
1901 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1902 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1907 if (free_enough >= 2) {
1908 /* use RR selection process, ensuring that the one
1912 i = last_rr_session_dir;
1915 if (++i == session_dirs.end()) {
1916 i = session_dirs.begin();
1919 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1920 if (create_session_directory ((*i).path)) {
1922 last_rr_session_dir = i;
1927 } while (i != last_rr_session_dir);
1931 /* pick FS with the most freespace (and that
1932 seems to actually work ...)
1935 vector<space_and_path> sorted;
1936 space_and_path_ascending_cmp cmp;
1938 sorted = session_dirs;
1939 sort (sorted.begin(), sorted.end(), cmp);
1941 for (i = sorted.begin(); i != sorted.end(); ++i) {
1942 if (create_session_directory ((*i).path)) {
1944 last_rr_session_dir = i;
1954 Session::load_playlists (const XMLNode& node)
1957 XMLNodeConstIterator niter;
1958 boost::shared_ptr<Playlist> playlist;
1960 nlist = node.children();
1964 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1966 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1967 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1975 Session::load_unused_playlists (const XMLNode& node)
1978 XMLNodeConstIterator niter;
1979 boost::shared_ptr<Playlist> playlist;
1981 nlist = node.children();
1985 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1987 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1988 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1992 // now manually untrack it
1994 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
2000 boost::shared_ptr<Playlist>
2001 Session::XMLPlaylistFactory (const XMLNode& node)
2004 return PlaylistFactory::create (*this, node);
2007 catch (failed_constructor& err) {
2008 return boost::shared_ptr<Playlist>();
2013 Session::load_named_selections (const XMLNode& node)
2016 XMLNodeConstIterator niter;
2019 nlist = node.children();
2023 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2025 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2026 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2034 Session::XMLNamedSelectionFactory (const XMLNode& node)
2037 return new NamedSelection (*this, node);
2040 catch (failed_constructor& err) {
2046 Session::automation_dir () const
2048 return Glib::build_filename (_path, "automation");
2052 Session::analysis_dir () const
2054 return Glib::build_filename (_path, "analysis");
2058 Session::load_bundles (XMLNode const & node)
2060 XMLNodeList nlist = node.children();
2061 XMLNodeConstIterator niter;
2065 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2066 if ((*niter)->name() == "InputBundle") {
2067 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2068 } else if ((*niter)->name() == "OutputBundle") {
2069 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2071 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2080 Session::load_route_groups (const XMLNode& node, int version)
2082 XMLNodeList nlist = node.children();
2083 XMLNodeConstIterator niter;
2087 if (version >= 3000) {
2089 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2090 if ((*niter)->name() == "RouteGroup") {
2091 RouteGroup* rg = new RouteGroup (*this, "");
2092 add_route_group (rg);
2093 rg->set_state (**niter, version);
2097 } else if (version < 3000) {
2099 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2100 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2101 RouteGroup* rg = new RouteGroup (*this, "");
2102 add_route_group (rg);
2103 rg->set_state (**niter, version);
2112 Session::auto_save()
2114 save_state (_current_snapshot_name);
2118 state_file_filter (const string &str, void */*arg*/)
2120 return (str.length() > strlen(statefile_suffix) &&
2121 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2125 bool operator()(const string* a, const string* b) {
2131 remove_end(string* state)
2133 string statename(*state);
2135 string::size_type start,end;
2136 if ((start = statename.find_last_of ('/')) != string::npos) {
2137 statename = statename.substr (start+1);
2140 if ((end = statename.rfind(".ardour")) == string::npos) {
2141 end = statename.length();
2144 return new string(statename.substr (0, end));
2148 Session::possible_states (string path)
2150 PathScanner scanner;
2151 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2153 transform(states->begin(), states->end(), states->begin(), remove_end);
2156 sort (states->begin(), states->end(), cmp);
2162 Session::possible_states () const
2164 return possible_states(_path);
2168 Session::add_route_group (RouteGroup* g)
2170 _route_groups.push_back (g);
2171 route_group_added (g); /* EMIT SIGNAL */
2176 Session::remove_route_group (RouteGroup& rg)
2178 list<RouteGroup*>::iterator i;
2180 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2181 (*i)->apply (&Route::drop_route_group, this);
2182 _route_groups.erase (i);
2183 route_group_removed (); /* EMIT SIGNAL */
2191 Session::route_group_by_name (string name)
2193 list<RouteGroup *>::iterator i;
2195 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2196 if ((*i)->name() == name) {
2204 Session::begin_reversible_command(const string& name)
2206 UndoTransaction* trans = new UndoTransaction();
2207 trans->set_name(name);
2209 if (!_current_trans.empty()) {
2210 _current_trans.top()->add_command (trans);
2212 _current_trans.push(trans);
2217 Session::commit_reversible_command(Command *cmd)
2219 assert(!_current_trans.empty());
2223 _current_trans.top()->add_command(cmd);
2226 if (_current_trans.top()->empty()) {
2227 _current_trans.pop();
2231 gettimeofday(&now, 0);
2232 _current_trans.top()->set_timestamp(now);
2234 _history.add(_current_trans.top());
2235 _current_trans.pop();
2238 Session::GlobalRouteBooleanState
2239 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2241 GlobalRouteBooleanState s;
2242 boost::shared_ptr<RouteList> r = routes.reader ();
2244 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2245 if (!(*i)->is_hidden()) {
2246 RouteBooleanState v;
2249 Route* r = (*i).get();
2250 v.second = (r->*method)();
2259 Session::GlobalRouteMeterState
2260 Session::get_global_route_metering ()
2262 GlobalRouteMeterState s;
2263 boost::shared_ptr<RouteList> r = routes.reader ();
2265 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2266 if (!(*i)->is_hidden()) {
2270 v.second = (*i)->meter_point();
2280 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2282 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2284 boost::shared_ptr<Route> r = (i->first.lock());
2287 r->set_meter_point (i->second, arg);
2293 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2295 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2297 boost::shared_ptr<Route> r = (i->first.lock());
2300 Route* rp = r.get();
2301 (rp->*method) (i->second, arg);
2307 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2309 set_global_route_boolean (s, &Route::set_mute, src);
2313 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2315 set_global_route_boolean (s, &Route::set_solo, src);
2319 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2321 set_global_route_boolean (s, &Route::set_record_enable, src);
2325 accept_all_non_peak_files (const string& path, void */*arg*/)
2327 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2331 accept_all_state_files (const string& path, void */*arg*/)
2333 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2337 Session::find_all_sources (string path, set<string>& result)
2342 if (!tree.read (path)) {
2346 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2351 XMLNodeConstIterator niter;
2353 nlist = node->children();
2357 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2361 if ((prop = (*niter)->property (X_("type"))) == 0) {
2365 DataType type (prop->value());
2367 if ((prop = (*niter)->property (X_("name"))) == 0) {
2371 if (prop->value()[0] == '/') {
2372 /* external file, ignore */
2376 Glib::ustring found_path;
2380 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2381 result.insert (found_path);
2389 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2391 PathScanner scanner;
2392 vector<string*>* state_files;
2394 string this_snapshot_path;
2400 if (ripped[ripped.length()-1] == '/') {
2401 ripped = ripped.substr (0, ripped.length() - 1);
2404 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2406 if (state_files == 0) {
2411 this_snapshot_path = _path;
2412 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2413 this_snapshot_path += statefile_suffix;
2415 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2417 if (exclude_this_snapshot && **i == this_snapshot_path) {
2421 if (find_all_sources (**i, result) < 0) {
2429 struct RegionCounter {
2430 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2431 AudioSourceList::iterator iter;
2432 boost::shared_ptr<Region> region;
2435 RegionCounter() : count (0) {}
2439 Session::cleanup_sources (CleanupReport& rep)
2441 // FIXME: needs adaptation to midi
2443 vector<boost::shared_ptr<Source> > dead_sources;
2444 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2445 PathScanner scanner;
2447 vector<space_and_path>::iterator i;
2448 vector<space_and_path>::iterator nexti;
2449 vector<string*>* soundfiles;
2450 vector<string> unused;
2451 set<string> all_sources;
2456 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2459 /* step 1: consider deleting all unused playlists */
2461 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2464 status = AskAboutPlaylistDeletion (*x);
2473 playlists_tbd.push_back (*x);
2477 /* leave it alone */
2482 /* now delete any that were marked for deletion */
2484 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2485 (*x)->drop_references ();
2488 playlists_tbd.clear ();
2490 /* step 2: find all un-used sources */
2495 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2497 SourceMap::iterator tmp;
2502 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2506 if (!source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2507 dead_sources.push_back (i->second);
2508 i->second->GoingAway();
2514 /* build a list of all the possible sound directories for the session */
2516 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2521 SessionDirectory sdir ((*i).path);
2522 sound_path += sdir.sound_path().to_string();
2524 if (nexti != session_dirs.end()) {
2531 /* now do the same thing for the files that ended up in the sounds dir(s)
2532 but are not referenced as sources in any snapshot.
2535 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2537 if (soundfiles == 0) {
2541 /* find all sources, but don't use this snapshot because the
2542 state file on disk still references sources we may have already
2546 find_all_sources_across_snapshots (all_sources, true);
2548 /* add our current source list
2551 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2552 boost::shared_ptr<FileSource> fs;
2554 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2555 all_sources.insert (fs->path());
2559 char tmppath1[PATH_MAX+1];
2560 char tmppath2[PATH_MAX+1];
2562 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2567 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2569 realpath(spath.c_str(), tmppath1);
2570 realpath((*i).c_str(), tmppath2);
2572 if (strcmp(tmppath1, tmppath2) == 0) {
2579 unused.push_back (spath);
2583 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2585 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2586 struct stat statbuf;
2588 rep.paths.push_back (*x);
2589 if (stat ((*x).c_str(), &statbuf) == 0) {
2590 rep.space += statbuf.st_size;
2595 /* don't move the file across filesystems, just
2596 stick it in the `dead_sound_dir_name' directory
2597 on whichever filesystem it was already on.
2600 if ((*x).find ("/sounds/") != string::npos) {
2602 /* old school, go up 1 level */
2604 newpath = Glib::path_get_dirname (*x); // "sounds"
2605 newpath = Glib::path_get_dirname (newpath); // "session-name"
2609 /* new school, go up 4 levels */
2611 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2612 newpath = Glib::path_get_dirname (newpath); // "session-name"
2613 newpath = Glib::path_get_dirname (newpath); // "interchange"
2614 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2618 newpath += dead_sound_dir_name;
2620 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2621 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2626 newpath += Glib::path_get_basename ((*x));
2628 if (access (newpath.c_str(), F_OK) == 0) {
2630 /* the new path already exists, try versioning */
2632 char buf[PATH_MAX+1];
2636 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2639 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2640 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2644 if (version == 999) {
2645 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2649 newpath = newpath_v;
2654 /* it doesn't exist, or we can't read it or something */
2658 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2659 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2660 (*x), newpath, strerror (errno))
2665 /* see if there an easy to find peakfile for this file, and remove it.
2668 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2669 peakpath += peakfile_suffix;
2671 if (access (peakpath.c_str(), W_OK) == 0) {
2672 if (::unlink (peakpath.c_str()) != 0) {
2673 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2674 peakpath, _path, strerror (errno))
2676 /* try to back out */
2677 rename (newpath.c_str(), _path.c_str());
2685 /* dump the history list */
2689 /* save state so we don't end up a session file
2690 referring to non-existent sources.
2696 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2702 Session::cleanup_trash_sources (CleanupReport& rep)
2704 // FIXME: needs adaptation for MIDI
2706 vector<space_and_path>::iterator i;
2707 string dead_sound_dir;
2708 struct dirent* dentry;
2709 struct stat statbuf;
2715 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2717 dead_sound_dir = (*i).path;
2718 dead_sound_dir += dead_sound_dir_name;
2720 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2724 while ((dentry = readdir (dead)) != 0) {
2726 /* avoid '.' and '..' */
2728 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2729 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2735 fullpath = dead_sound_dir;
2737 fullpath += dentry->d_name;
2739 if (stat (fullpath.c_str(), &statbuf)) {
2743 if (!S_ISREG (statbuf.st_mode)) {
2747 if (unlink (fullpath.c_str())) {
2748 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2749 fullpath, strerror (errno))
2753 rep.paths.push_back (dentry->d_name);
2754 rep.space += statbuf.st_size;
2765 Session::set_dirty ()
2767 bool was_dirty = dirty();
2769 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2773 DirtyChanged(); /* EMIT SIGNAL */
2779 Session::set_clean ()
2781 bool was_dirty = dirty();
2783 _state_of_the_state = Clean;
2787 DirtyChanged(); /* EMIT SIGNAL */
2792 Session::set_deletion_in_progress ()
2794 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2798 Session::clear_deletion_in_progress ()
2800 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2804 Session::add_controllable (boost::shared_ptr<Controllable> c)
2806 /* this adds a controllable to the list managed by the Session.
2807 this is a subset of those managed by the Controllable class
2808 itself, and represents the only ones whose state will be saved
2809 as part of the session.
2812 Glib::Mutex::Lock lm (controllables_lock);
2813 controllables.insert (c);
2816 struct null_deleter { void operator()(void const *) const {} };
2819 Session::remove_controllable (Controllable* c)
2821 if (_state_of_the_state | Deletion) {
2825 Glib::Mutex::Lock lm (controllables_lock);
2827 Controllables::iterator x = controllables.find(
2828 boost::shared_ptr<Controllable>(c, null_deleter()));
2830 if (x != controllables.end()) {
2831 controllables.erase (x);
2835 boost::shared_ptr<Controllable>
2836 Session::controllable_by_id (const PBD::ID& id)
2838 Glib::Mutex::Lock lm (controllables_lock);
2840 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2841 if ((*i)->id() == id) {
2846 return boost::shared_ptr<Controllable>();
2850 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2853 Stateful::add_instant_xml (node, _path);
2856 if (write_to_config) {
2857 Config->add_instant_xml (node);
2862 Session::instant_xml (const string& node_name)
2864 return Stateful::instant_xml (node_name, _path);
2868 Session::save_history (string snapshot_name)
2876 if (snapshot_name.empty()) {
2877 snapshot_name = _current_snapshot_name;
2880 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2881 const string backup_filename = history_filename + backup_suffix;
2882 const sys::path xml_path = _session_dir->root_path() / history_filename;
2883 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2885 if (sys::exists (xml_path)) {
2888 sys::rename (xml_path, backup_path);
2890 catch (const sys::filesystem_error& err)
2892 error << _("could not backup old history file, current history not saved") << endmsg;
2897 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2901 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2903 if (!tree.write (xml_path.to_string()))
2905 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2909 sys::remove (xml_path);
2910 sys::rename (backup_path, xml_path);
2912 catch (const sys::filesystem_error& err)
2914 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2915 backup_path.to_string(), err.what()) << endmsg;
2925 Session::restore_history (string snapshot_name)
2929 if (snapshot_name.empty()) {
2930 snapshot_name = _current_snapshot_name;
2933 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
2934 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2936 info << "Loading history from " << xml_path.to_string() << endmsg;
2938 if (!sys::exists (xml_path)) {
2939 info << string_compose (_("%1: no history file \"%2\" for this session."),
2940 _name, xml_path.to_string()) << endmsg;
2944 if (!tree.read (xml_path.to_string())) {
2945 error << string_compose (_("Could not understand session history file \"%1\""),
2946 xml_path.to_string()) << endmsg;
2953 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2956 UndoTransaction* ut = new UndoTransaction ();
2959 ut->set_name(t->property("name")->value());
2960 stringstream ss(t->property("tv-sec")->value());
2962 ss.str(t->property("tv-usec")->value());
2964 ut->set_timestamp(tv);
2966 for (XMLNodeConstIterator child_it = t->children().begin();
2967 child_it != t->children().end(); child_it++)
2969 XMLNode *n = *child_it;
2972 if (n->name() == "MementoCommand" ||
2973 n->name() == "MementoUndoCommand" ||
2974 n->name() == "MementoRedoCommand") {
2976 if ((c = memento_command_factory(n))) {
2980 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2982 if ((c = global_state_command_factory (*n))) {
2983 ut->add_command (c);
2986 } else if (n->name() == "DeltaCommand") {
2987 PBD::ID id(n->property("midi-source")->value());
2988 boost::shared_ptr<MidiSource> midi_source =
2989 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2991 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
2993 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2996 } else if (n->name() == "DiffCommand") {
2997 PBD::ID id(n->property("midi-source")->value());
2998 boost::shared_ptr<MidiSource> midi_source =
2999 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3001 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3003 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3007 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3018 Session::config_changed (std::string p, bool ours)
3024 if (p == "seamless-loop") {
3026 } else if (p == "rf-speed") {
3028 } else if (p == "auto-loop") {
3030 } else if (p == "auto-input") {
3032 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3033 /* auto-input only makes a difference if we're rolling */
3035 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3037 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3038 if ((*i)->record_enabled ()) {
3039 (*i)->monitor_input (!config.get_auto_input());
3044 } else if (p == "punch-in") {
3048 if ((location = _locations.auto_punch_location()) != 0) {
3050 if (config.get_punch_in ()) {
3051 replace_event (Event::PunchIn, location->start());
3053 remove_event (location->start(), Event::PunchIn);
3057 } else if (p == "punch-out") {
3061 if ((location = _locations.auto_punch_location()) != 0) {
3063 if (config.get_punch_out()) {
3064 replace_event (Event::PunchOut, location->end());
3066 clear_events (Event::PunchOut);
3070 } else if (p == "edit-mode") {
3072 Glib::Mutex::Lock lm (playlist_lock);
3074 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3075 (*i)->set_edit_mode (Config->get_edit_mode ());
3078 } else if (p == "use-video-sync") {
3080 waiting_for_sync_offset = config.get_use_video_sync();
3082 } else if (p == "mmc-control") {
3084 //poke_midi_thread ();
3086 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3089 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3092 } else if (p == "mmc-send-id") {
3095 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3098 } else if (p == "midi-control") {
3100 //poke_midi_thread ();
3102 } else if (p == "raid-path") {
3104 setup_raid_path (config.get_raid_path());
3106 } else if (p == "timecode-format") {
3110 } else if (p == "video-pullup") {
3114 } else if (p == "seamless-loop") {
3116 if (play_loop && transport_rolling()) {
3117 // to reset diskstreams etc
3118 request_play_loop (true);
3121 } else if (p == "rf-speed") {
3123 cumulative_rf_motion = 0;
3126 } else if (p == "click-sound") {
3128 setup_click_sounds (1);
3130 } else if (p == "click-emphasis-sound") {
3132 setup_click_sounds (-1);
3134 } else if (p == "clicking") {
3136 if (Config->get_clicking()) {
3137 if (_click_io && click_data) { // don't require emphasis data
3144 } else if (p == "send-mtc") {
3146 /* only set the internal flag if we have
3150 if (_mtc_port != 0) {
3151 session_send_mtc = Config->get_send_mtc();
3152 if (session_send_mtc) {
3153 /* mark us ready to send */
3154 next_quarter_frame_to_send = 0;
3157 session_send_mtc = false;
3160 } else if (p == "send-mmc") {
3162 /* only set the internal flag if we have
3166 if (_mmc_port != 0) {
3167 session_send_mmc = Config->get_send_mmc();
3170 session_send_mmc = false;
3173 } else if (p == "midi-feedback") {
3175 /* only set the internal flag if we have
3179 if (_mtc_port != 0) {
3180 session_midi_feedback = Config->get_midi_feedback();
3183 } else if (p == "jack-time-master") {
3185 engine().reset_timebase ();
3187 } else if (p == "native-file-header-format") {
3189 if (!first_file_header_format_reset) {
3190 reset_native_file_format ();
3193 first_file_header_format_reset = false;
3195 } else if (p == "native-file-data-format") {
3197 if (!first_file_data_format_reset) {
3198 reset_native_file_format ();
3201 first_file_data_format_reset = false;
3203 } else if (p == "slave-source") {
3204 set_slave_source (Config->get_slave_source());
3205 } else if (p == "remote-model") {
3206 set_remote_control_ids ();
3207 } else if (p == "denormal-model") {
3209 } else if (p == "history-depth") {
3210 set_history_depth (Config->get_history_depth());
3211 } else if (p == "sync-all-route-ordering") {
3212 sync_order_keys ("session");
3213 } else if (p == "initial-program-change") {
3215 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3218 buf[0] = MIDI::program; // channel zero by default
3219 buf[1] = (Config->get_initial_program_change() & 0x7f);
3221 _mmc_port->midimsg (buf, sizeof (buf), 0);
3223 } else if (p == "initial-program-change") {
3225 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3226 MIDI::byte* buf = new MIDI::byte[2];
3228 buf[0] = MIDI::program; // channel zero by default
3229 buf[1] = (Config->get_initial_program_change() & 0x7f);
3230 // deliver_midi (_mmc_port, buf, 2);
3232 } else if (p == "solo-mute-override") {
3233 // catch_up_on_solo_mute_override ();
3234 } else if (p == "listen-position") {
3235 listen_position_changed ();
3236 } else if (p == "solo-control-is-listen-control") {
3237 solo_control_mode_changed ();
3245 Session::set_history_depth (uint32_t d)
3247 _history.set_depth (d);