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/configuration.h"
75 #include "ardour/control_protocol_manager.h"
76 #include "ardour/crossfade.h"
77 #include "ardour/cycle_timer.h"
78 #include "ardour/directory_names.h"
79 #include "ardour/filename_extensions.h"
80 #include "ardour/io_processor.h"
81 #include "ardour/location.h"
82 #include "ardour/midi_diskstream.h"
83 #include "ardour/midi_patch_manager.h"
84 #include "ardour/midi_playlist.h"
85 #include "ardour/midi_region.h"
86 #include "ardour/midi_source.h"
87 #include "ardour/midi_track.h"
88 #include "ardour/named_selection.h"
89 #include "ardour/playlist_factory.h"
90 #include "ardour/processor.h"
91 #include "ardour/region_factory.h"
92 #include "ardour/route_group.h"
93 #include "ardour/send.h"
94 #include "ardour/session.h"
95 #include "ardour/session_directory.h"
96 #include "ardour/session_metadata.h"
97 #include "ardour/session_state_utils.h"
98 #include "ardour/session_utils.h"
99 #include "ardour/silentfilesource.h"
100 #include "ardour/slave.h"
101 #include "ardour/smf_source.h"
102 #include "ardour/sndfile_helpers.h"
103 #include "ardour/sndfilesource.h"
104 #include "ardour/source_factory.h"
105 #include "ardour/template_utils.h"
106 #include "ardour/tempo.h"
107 #include "ardour/ticker.h"
108 #include "ardour/user_bundle.h"
109 #include "ardour/utils.h"
110 #include "ardour/utils.h"
111 #include "ardour/version.h"
113 #include "control_protocol/control_protocol.h"
119 using namespace ARDOUR;
123 Session::first_stage_init (string fullpath, string snapshot_name)
125 if (fullpath.length() == 0) {
127 throw failed_constructor();
130 char buf[PATH_MAX+1];
131 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
132 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
134 throw failed_constructor();
139 if (_path[_path.length()-1] != '/') {
143 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
144 cerr << "Session non-writable based on " << _path << endl;
147 cerr << "Session writable based on " << _path << endl;
151 /* these two are just provisional settings. set_state()
152 will likely override them.
155 _name = _current_snapshot_name = snapshot_name;
157 set_history_depth (Config->get_history_depth());
159 _current_frame_rate = _engine.frame_rate ();
160 _nominal_frame_rate = _current_frame_rate;
161 _base_frame_rate = _current_frame_rate;
163 _tempo_map = new TempoMap (_current_frame_rate);
164 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
167 _non_soloed_outs_muted = false;
169 g_atomic_int_set (&processing_prohibited, 0);
170 _transport_speed = 0;
171 _last_transport_speed = 0;
172 _target_transport_speed = 0;
173 auto_play_legal = false;
174 transport_sub_state = 0;
175 _transport_frame = 0;
176 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
177 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
178 g_atomic_int_set (&_record_status, Disabled);
179 loop_changing = false;
182 _last_roll_location = 0;
183 _last_record_location = 0;
184 pending_locate_frame = 0;
185 pending_locate_roll = false;
186 pending_locate_flush = false;
187 audio_dstream_buffer_size = 0;
188 midi_dstream_buffer_size = 0;
189 state_was_pending = false;
191 outbound_mtc_smpte_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);
202 session_send_mmc = false;
203 session_send_mtc = false;
204 post_transport_work = PostTransportWork (0);
205 g_atomic_int_set (&butler_should_do_transport_work, 0);
206 g_atomic_int_set (&_playback_load, 100);
207 g_atomic_int_set (&_capture_load, 100);
208 g_atomic_int_set (&_playback_load_min, 100);
209 g_atomic_int_set (&_capture_load_min, 100);
212 _exporting_realtime = false;
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 butler_thread = (pthread_t) 0;
221 //midi_thread = (pthread_t) 0;
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;
252 _smpte_offset_negative = true;
253 last_smpte_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 (mem_fun (*this, &Session::graph_reordered));
271 /* These are all static "per-class" signals */
273 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
274 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
275 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
276 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
277 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
278 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
280 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
282 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
284 /* stop IO objects from doing stuff until we're ready for them */
286 Delivery::disable_panners ();
287 IO::disable_connecting ();
291 Session::second_stage_init (bool new_session)
293 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
296 if (load_state (_current_snapshot_name)) {
299 remove_empty_sounds ();
302 if (start_butler_thread()) {
306 if (start_midi_thread ()) {
310 // set_state() will call setup_raid_path(), but if it's a new session we need
311 // to call setup_raid_path() here.
314 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
318 setup_raid_path(_path);
321 /* we can't save till after ::when_engine_running() is called,
322 because otherwise we save state with no connections made.
323 therefore, we reset _state_of_the_state because ::set_state()
324 will have cleared it.
326 we also have to include Loading so that any events that get
327 generated between here and the end of ::when_engine_running()
328 will be processed directly rather than queued.
331 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
334 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
335 _locations.added.connect (mem_fun (this, &Session::locations_added));
336 setup_click_sounds (0);
337 setup_midi_control ();
339 /* Pay attention ... */
341 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
342 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
345 when_engine_running();
348 /* handle this one in a different way than all others, so that its clear what happened */
350 catch (AudioEngine::PortRegistrationFailure& err) {
351 error << err.what() << endmsg;
359 BootMessage (_("Reset Remote Controls"));
361 send_full_time_code (0);
362 _engine.transport_locate (0);
363 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
364 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
366 MidiClockTicker::instance().set_session(*this);
367 MIDI::Name::MidiPatchManager::instance().set_session(*this);
369 /* initial program change will be delivered later; see ::config_changed() */
371 BootMessage (_("Reset Control Protocols"));
373 ControlProtocolManager::instance().set_session (*this);
375 config.set_end_marker_is_free (new_session);
377 _state_of_the_state = Clean;
379 DirtyChanged (); /* EMIT SIGNAL */
381 if (state_was_pending) {
382 save_state (_current_snapshot_name);
383 remove_pending_capture_state ();
384 state_was_pending = false;
387 BootMessage (_("Session loading complete"));
393 Session::raid_path () const
395 SearchPath raid_search_path;
397 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
398 raid_search_path += sys::path((*i).path);
401 return raid_search_path.to_string ();
405 Session::setup_raid_path (string path)
414 session_dirs.clear ();
416 SearchPath search_path(path);
417 SearchPath sound_search_path;
418 SearchPath midi_search_path;
420 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
421 sp.path = (*i).to_string ();
422 sp.blocks = 0; // not needed
423 session_dirs.push_back (sp);
425 SessionDirectory sdir(sp.path);
427 sound_search_path += sdir.sound_path ();
428 midi_search_path += sdir.midi_path ();
431 // set the search path for each data type
432 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
433 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
435 // reset the round-robin soundfile path thingie
436 last_rr_session_dir = session_dirs.begin();
440 Session::ensure_subdirs ()
444 dir = session_directory().peak_path().to_string();
446 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
447 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
451 dir = session_directory().sound_path().to_string();
453 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
454 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
458 dir = session_directory().midi_path().to_string();
460 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
461 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
465 dir = session_directory().dead_sound_path().to_string();
467 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
468 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
472 dir = session_directory().export_path().to_string();
474 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
475 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
479 dir = analysis_dir ();
481 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
482 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
490 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
493 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
494 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
498 if (ensure_subdirs ()) {
502 /* check new_session so we don't overwrite an existing one */
504 if (!mix_template.empty()) {
505 std::string in_path = mix_template;
507 ifstream in(in_path.c_str());
510 string out_path = _path;
512 out_path += statefile_suffix;
514 ofstream out(out_path.c_str());
519 // okay, session is set up. Treat like normal saved
520 // session from now on.
526 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
532 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
539 /* Instantiate metadata */
541 _metadata = new SessionMetadata ();
543 /* set initial start + end point */
545 start_location->set_end (0);
546 _locations.add (start_location);
548 end_location->set_end (initial_length);
549 _locations.add (end_location);
551 _state_of_the_state = Clean;
560 Session::load_diskstreams (const XMLNode& node)
563 XMLNodeConstIterator citer;
565 clist = node.children();
567 for (citer = clist.begin(); citer != clist.end(); ++citer) {
570 /* diskstreams added automatically by DiskstreamCreated handler */
571 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
572 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
573 add_diskstream (dstream);
574 } else if ((*citer)->name() == "MidiDiskstream") {
575 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
576 add_diskstream (dstream);
578 error << _("Session: unknown diskstream type in XML") << endmsg;
582 catch (failed_constructor& err) {
583 error << _("Session: could not load diskstream via XML state") << endmsg;
592 Session::maybe_write_autosave()
594 if (dirty() && record_status() != Recording) {
595 save_state("", true);
600 Session::remove_pending_capture_state ()
602 sys::path pending_state_file_path(_session_dir->root_path());
604 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
608 sys::remove (pending_state_file_path);
610 catch(sys::filesystem_error& ex)
612 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
613 pending_state_file_path.to_string(), ex.what()) << endmsg;
617 /** Rename a state file.
618 * @param snapshot_name Snapshot name.
621 Session::rename_state (string old_name, string new_name)
623 if (old_name == _current_snapshot_name || old_name == _name) {
624 /* refuse to rename the current snapshot or the "main" one */
628 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
629 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
631 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
632 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
636 sys::rename (old_xml_path, new_xml_path);
638 catch (const sys::filesystem_error& err)
640 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
641 old_name, new_name, err.what()) << endmsg;
645 /** Remove a state file.
646 * @param snapshot_name Snapshot name.
649 Session::remove_state (string snapshot_name)
651 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
652 // refuse to remove the current snapshot or the "main" one
656 sys::path xml_path(_session_dir->root_path());
658 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
660 if (!create_backup_file (xml_path)) {
661 // don't remove it if a backup can't be made
662 // create_backup_file will log the error.
667 sys::remove (xml_path);
671 Session::save_state (string snapshot_name, bool pending)
674 sys::path xml_path(_session_dir->root_path());
676 if (!_writable || (_state_of_the_state & CannotSave)) {
680 if (!_engine.connected ()) {
681 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
686 /* tell sources we're saving first, in case they write out to a new file
687 * which should be saved with the state rather than the old one */
688 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
689 i->second->session_saved();
691 tree.set_root (&get_state());
693 if (snapshot_name.empty()) {
694 snapshot_name = _current_snapshot_name;
699 /* proper save: use statefile_suffix (.ardour in English) */
701 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
703 /* make a backup copy of the old file */
705 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
706 // create_backup_file will log the error
712 /* pending save: use pending_suffix (.pending in English) */
713 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
716 sys::path tmp_path(_session_dir->root_path());
718 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
720 // cerr << "actually writing state to " << xml_path.to_string() << endl;
722 if (!tree.write (tmp_path.to_string())) {
723 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
724 sys::remove (tmp_path);
729 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
730 error << string_compose (_("could not rename temporary session file %1 to %2"),
731 tmp_path.to_string(), xml_path.to_string()) << endmsg;
732 sys::remove (tmp_path);
739 save_history (snapshot_name);
741 bool was_dirty = dirty();
743 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
746 DirtyChanged (); /* EMIT SIGNAL */
749 StateSaved (snapshot_name); /* EMIT SIGNAL */
756 Session::restore_state (string snapshot_name)
758 if (load_state (snapshot_name) == 0) {
759 set_state (*state_tree->root(), Stateful::loading_state_version);
766 Session::load_state (string snapshot_name)
771 state_was_pending = false;
773 /* check for leftover pending state from a crashed capture attempt */
775 sys::path xmlpath(_session_dir->root_path());
776 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
778 if (sys::exists (xmlpath)) {
780 /* there is pending state from a crashed capture attempt */
782 if (AskAboutPendingState()) {
783 state_was_pending = true;
787 if (!state_was_pending) {
788 xmlpath = _session_dir->root_path();
789 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
792 if (!sys::exists (xmlpath)) {
793 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
797 state_tree = new XMLTree;
801 /* writable() really reflects the whole folder, but if for any
802 reason the session state file can't be written to, still
806 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
810 if (!state_tree->read (xmlpath.to_string())) {
811 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
817 XMLNode& root (*state_tree->root());
819 if (root.name() != X_("Session")) {
820 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
826 const XMLProperty* prop;
828 if ((prop = root.property ("version")) == 0) {
829 /* no version implies very old version of Ardour */
830 Stateful::loading_state_version = 1000;
836 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
837 Stateful::loading_state_version = (major * 1000) + minor;
840 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
842 sys::path backup_path(_session_dir->root_path());
844 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
846 // only create a backup once
847 if (sys::exists (backup_path)) {
851 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
852 xmlpath.to_string(), backup_path.to_string())
857 sys::copy_file (xmlpath, backup_path);
859 catch(sys::filesystem_error& ex)
861 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
862 xmlpath.to_string(), ex.what())
872 Session::load_options (const XMLNode& node)
874 LocaleGuard lg (X_("POSIX"));
876 config.set_variables (node);
878 /* now reset MIDI ports because the session can have its own
894 Session::get_template()
896 /* if we don't disable rec-enable, diskstreams
897 will believe they need to store their capture
898 sources in their state node.
901 disable_record (false);
907 Session::state(bool full_state)
909 XMLNode* node = new XMLNode("Session");
912 // store libardour version, just in case
914 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
915 node->add_property("version", string(buf));
917 /* store configuration settings */
921 node->add_property ("name", _name);
922 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
923 node->add_property ("sample-rate", buf);
925 if (session_dirs.size() > 1) {
929 vector<space_and_path>::iterator i = session_dirs.begin();
930 vector<space_and_path>::iterator next;
932 ++i; /* skip the first one */
936 while (i != session_dirs.end()) {
940 if (next != session_dirs.end()) {
950 child = node->add_child ("Path");
951 child->add_content (p);
955 /* save the ID counter */
957 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
958 node->add_property ("id-counter", buf);
960 /* various options */
962 node->add_child_nocopy (config.get_variables ());
964 node->add_child_nocopy (_metadata->get_state());
966 child = node->add_child ("Sources");
969 Glib::Mutex::Lock sl (source_lock);
971 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
973 /* Don't save information about non-destructive file sources that are empty */
974 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
976 boost::shared_ptr<AudioFileSource> fs;
977 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
978 if (!fs->destructive()) {
979 if (fs->length(fs->timeline_position()) == 0) {
985 child->add_child_nocopy (siter->second->get_state());
989 child = node->add_child ("Regions");
992 Glib::Mutex::Lock rl (region_lock);
994 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
996 /* only store regions not attached to playlists */
998 if (i->second->playlist() == 0) {
999 child->add_child_nocopy (i->second->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());
1061 child = node->add_child ("RouteGroups");
1062 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1063 child->add_child_nocopy ((*i)->get_state());
1066 child = node->add_child ("Playlists");
1067 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1068 if (!(*i)->hidden()) {
1069 if (!(*i)->empty()) {
1071 child->add_child_nocopy ((*i)->get_state());
1073 child->add_child_nocopy ((*i)->get_template());
1079 child = node->add_child ("UnusedPlaylists");
1080 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1081 if (!(*i)->hidden()) {
1082 if (!(*i)->empty()) {
1084 child->add_child_nocopy ((*i)->get_state());
1086 child->add_child_nocopy ((*i)->get_template());
1094 child = node->add_child ("Click");
1095 child->add_child_nocopy (_click_io->state (full_state));
1099 child = node->add_child ("NamedSelections");
1100 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1102 child->add_child_nocopy ((*i)->get_state());
1107 node->add_child_nocopy (_tempo_map->get_state());
1109 node->add_child_nocopy (get_control_protocol_state());
1112 node->add_child_copy (*_extra_xml);
1119 Session::get_control_protocol_state ()
1121 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1122 return cpm.get_state();
1126 Session::set_state (const XMLNode& node, int version)
1130 const XMLProperty* prop;
1133 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1135 if (node.name() != X_("Session")){
1136 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1140 if ((prop = node.property ("version")) != 0) {
1141 version = atoi (prop->value ()) * 1000;
1144 if ((prop = node.property ("name")) != 0) {
1145 _name = prop->value ();
1148 if ((prop = node.property (X_("sample-rate"))) != 0) {
1150 _nominal_frame_rate = atoi (prop->value());
1152 if (_nominal_frame_rate != _current_frame_rate) {
1153 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1159 setup_raid_path(_session_dir->root_path().to_string());
1161 if ((prop = node.property (X_("id-counter"))) != 0) {
1163 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1164 ID::init_counter (x);
1166 /* old sessions used a timebased counter, so fake
1167 the startup ID counter based on a standard
1172 ID::init_counter (now);
1176 IO::disable_connecting ();
1178 /* Object loading order:
1183 MIDI Control // relies on data from Options/Config
1197 if ((child = find_named_node (node, "Extra")) != 0) {
1198 _extra_xml = new XMLNode (*child);
1201 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1202 load_options (*child);
1203 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1204 load_options (*child);
1206 error << _("Session: XML state has no options section") << endmsg;
1209 if (use_config_midi_ports ()) {
1212 if (version >= 3000) {
1213 if ((child = find_named_node (node, "Metadata")) == 0) {
1214 warning << _("Session: XML state has no metadata section") << endmsg;
1215 } else if (_metadata->set_state (*child, version)) {
1220 if ((child = find_named_node (node, "Locations")) == 0) {
1221 error << _("Session: XML state has no locations section") << endmsg;
1223 } else if (_locations.set_state (*child, version)) {
1229 if ((location = _locations.auto_loop_location()) != 0) {
1230 set_auto_loop_location (location);
1233 if ((location = _locations.auto_punch_location()) != 0) {
1234 set_auto_punch_location (location);
1237 if ((location = _locations.end_location()) == 0) {
1238 _locations.add (end_location);
1240 delete end_location;
1241 end_location = location;
1244 if ((location = _locations.start_location()) == 0) {
1245 _locations.add (start_location);
1247 delete start_location;
1248 start_location = location;
1251 AudioFileSource::set_header_position_offset (start_location->start());
1253 if ((child = find_named_node (node, "Sources")) == 0) {
1254 error << _("Session: XML state has no sources section") << endmsg;
1256 } else if (load_sources (*child)) {
1260 if ((child = find_named_node (node, "Regions")) == 0) {
1261 error << _("Session: XML state has no Regions section") << endmsg;
1263 } else if (load_regions (*child)) {
1267 if ((child = find_named_node (node, "Playlists")) == 0) {
1268 error << _("Session: XML state has no playlists section") << endmsg;
1270 } else if (load_playlists (*child)) {
1274 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1276 } else if (load_unused_playlists (*child)) {
1280 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1281 if (load_named_selections (*child)) {
1286 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1287 error << _("Session: XML state has no diskstreams section") << endmsg;
1289 } else if (load_diskstreams (*child)) {
1293 if (version >= 3000) {
1294 if ((child = find_named_node (node, "Bundles")) == 0) {
1295 warning << _("Session: XML state has no bundles section") << endmsg;
1298 /* We can't load Bundles yet as they need to be able
1299 to convert from port names to Port objects, which can't happen until
1301 _bundle_xml_node = new XMLNode (*child);
1305 if (version >= 3000) {
1307 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1308 error << _("Session: XML state has no route groups section") << endmsg;
1310 } else if (load_route_groups (*child, version)) {
1314 } else if (version < 3000) {
1316 if ((child = find_named_node (node, "EditGroups")) == 0) {
1317 error << _("Session: XML state has no edit groups section") << endmsg;
1319 } else if (load_route_groups (*child, version)) {
1323 if ((child = find_named_node (node, "MixGroups")) == 0) {
1324 error << _("Session: XML state has no mix groups section") << endmsg;
1326 } else if (load_route_groups (*child, version)) {
1331 if ((child = find_named_node (node, "TempoMap")) == 0) {
1332 error << _("Session: XML state has no Tempo Map section") << endmsg;
1334 } else if (_tempo_map->set_state (*child, version)) {
1338 if ((child = find_named_node (node, "Routes")) == 0) {
1339 error << _("Session: XML state has no routes section") << endmsg;
1341 } else if (load_routes (*child, version)) {
1345 if ((child = find_named_node (node, "Click")) == 0) {
1346 warning << _("Session: XML state has no click section") << endmsg;
1347 } else if (_click_io) {
1348 _click_io->set_state (*child, version);
1351 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1352 ControlProtocolManager::instance().set_protocol_states (*child);
1355 /* here beginneth the second phase ... */
1357 StateReady (); /* EMIT SIGNAL */
1366 Session::load_routes (const XMLNode& node, int version)
1369 XMLNodeConstIterator niter;
1370 RouteList new_routes;
1372 nlist = node.children();
1376 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1378 boost::shared_ptr<Route> route (XMLRouteFactory (**niter, version));
1381 error << _("Session: cannot create Route from XML description.") << endmsg;
1385 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1387 new_routes.push_back (route);
1390 add_routes (new_routes, false);
1395 boost::shared_ptr<Route>
1396 Session::XMLRouteFactory (const XMLNode& node, int version)
1398 if (node.name() != "Route") {
1399 return boost::shared_ptr<Route> ((Route*) 0);
1402 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1404 DataType type = DataType::AUDIO;
1405 const XMLProperty* prop = node.property("default-type");
1408 type = DataType(prop->value());
1411 assert(type != DataType::NIL);
1413 if (has_diskstream) {
1414 if (type == DataType::AUDIO) {
1415 boost::shared_ptr<Route> ret (new AudioTrack (*this, node, version));
1418 boost::shared_ptr<Route> ret (new MidiTrack (*this, node, version));
1422 boost::shared_ptr<Route> ret (new Route (*this, node));
1428 Session::load_regions (const XMLNode& node)
1431 XMLNodeConstIterator niter;
1432 boost::shared_ptr<Region> region;
1434 nlist = node.children();
1438 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1439 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1440 error << _("Session: cannot create Region from XML description.");
1441 const XMLProperty *name = (**niter).property("name");
1444 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1454 boost::shared_ptr<Region>
1455 Session::XMLRegionFactory (const XMLNode& node, bool full)
1457 const XMLProperty* type = node.property("type");
1461 if ( !type || type->value() == "audio" ) {
1463 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1465 } else if (type->value() == "midi") {
1467 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1471 } catch (failed_constructor& err) {
1472 return boost::shared_ptr<Region> ();
1475 return boost::shared_ptr<Region> ();
1478 boost::shared_ptr<AudioRegion>
1479 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1481 const XMLProperty* prop;
1482 boost::shared_ptr<Source> source;
1483 boost::shared_ptr<AudioSource> as;
1485 SourceList master_sources;
1486 uint32_t nchans = 1;
1489 if (node.name() != X_("Region")) {
1490 return boost::shared_ptr<AudioRegion>();
1493 if ((prop = node.property (X_("channels"))) != 0) {
1494 nchans = atoi (prop->value().c_str());
1497 if ((prop = node.property ("name")) == 0) {
1498 cerr << "no name for this region\n";
1502 if ((prop = node.property (X_("source-0"))) == 0) {
1503 if ((prop = node.property ("source")) == 0) {
1504 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1505 return boost::shared_ptr<AudioRegion>();
1509 PBD::ID s_id (prop->value());
1511 if ((source = source_by_id (s_id)) == 0) {
1512 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << 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"), s_id) << endmsg;
1519 return boost::shared_ptr<AudioRegion>();
1522 sources.push_back (as);
1524 /* pickup other channels */
1526 for (uint32_t n=1; n < nchans; ++n) {
1527 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1528 if ((prop = node.property (buf)) != 0) {
1530 PBD::ID id2 (prop->value());
1532 if ((source = source_by_id (id2)) == 0) {
1533 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1534 return boost::shared_ptr<AudioRegion>();
1537 as = boost::dynamic_pointer_cast<AudioSource>(source);
1539 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1540 return boost::shared_ptr<AudioRegion>();
1542 sources.push_back (as);
1546 for (uint32_t n = 0; n < nchans; ++n) {
1547 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1548 if ((prop = node.property (buf)) != 0) {
1550 PBD::ID id2 (prop->value());
1552 if ((source = source_by_id (id2)) == 0) {
1553 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1554 return boost::shared_ptr<AudioRegion>();
1557 as = boost::dynamic_pointer_cast<AudioSource>(source);
1559 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1560 return boost::shared_ptr<AudioRegion>();
1562 master_sources.push_back (as);
1567 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1569 /* a final detail: this is the one and only place that we know how long missing files are */
1571 if (region->whole_file()) {
1572 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1573 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1575 sfp->set_length (region->length());
1580 if (!master_sources.empty()) {
1581 if (master_sources.size() != nchans) {
1582 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1584 region->set_master_sources (master_sources);
1592 catch (failed_constructor& err) {
1593 return boost::shared_ptr<AudioRegion>();
1597 boost::shared_ptr<MidiRegion>
1598 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1600 const XMLProperty* prop;
1601 boost::shared_ptr<Source> source;
1602 boost::shared_ptr<MidiSource> ms;
1604 uint32_t nchans = 1;
1606 if (node.name() != X_("Region")) {
1607 return boost::shared_ptr<MidiRegion>();
1610 if ((prop = node.property (X_("channels"))) != 0) {
1611 nchans = atoi (prop->value().c_str());
1614 if ((prop = node.property ("name")) == 0) {
1615 cerr << "no name for this region\n";
1619 // Multiple midi channels? that's just crazy talk
1620 assert(nchans == 1);
1622 if ((prop = node.property (X_("source-0"))) == 0) {
1623 if ((prop = node.property ("source")) == 0) {
1624 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1625 return boost::shared_ptr<MidiRegion>();
1629 PBD::ID s_id (prop->value());
1631 if ((source = source_by_id (s_id)) == 0) {
1632 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1633 return boost::shared_ptr<MidiRegion>();
1636 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1638 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1639 return boost::shared_ptr<MidiRegion>();
1642 sources.push_back (ms);
1645 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1646 /* a final detail: this is the one and only place that we know how long missing files are */
1648 if (region->whole_file()) {
1649 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1650 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1652 sfp->set_length (region->length());
1660 catch (failed_constructor& err) {
1661 return boost::shared_ptr<MidiRegion>();
1666 Session::get_sources_as_xml ()
1669 XMLNode* node = new XMLNode (X_("Sources"));
1670 Glib::Mutex::Lock lm (source_lock);
1672 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1673 node->add_child_nocopy (i->second->get_state());
1680 Session::path_from_region_name (DataType type, string name, string identifier)
1682 char buf[PATH_MAX+1];
1684 SessionDirectory sdir(get_best_session_directory_for_new_source());
1685 sys::path source_dir = ((type == DataType::AUDIO)
1686 ? sdir.sound_path() : sdir.midi_path());
1688 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1690 for (n = 0; n < 999999; ++n) {
1691 if (identifier.length()) {
1692 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1693 identifier.c_str(), n, ext.c_str());
1695 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1699 sys::path source_path = source_dir / buf;
1701 if (!sys::exists (source_path)) {
1702 return source_path.to_string();
1706 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1715 Session::load_sources (const XMLNode& node)
1718 XMLNodeConstIterator niter;
1719 boost::shared_ptr<Source> source;
1721 nlist = node.children();
1725 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1727 if ((source = XMLSourceFactory (**niter)) == 0) {
1728 error << _("Session: cannot create Source from XML description.") << endmsg;
1730 } catch (MissingSource& err) {
1731 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1732 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1739 boost::shared_ptr<Source>
1740 Session::XMLSourceFactory (const XMLNode& node)
1742 if (node.name() != "Source") {
1743 return boost::shared_ptr<Source>();
1747 /* note: do peak building in another thread when loading session state */
1748 return SourceFactory::create (*this, node, true);
1751 catch (failed_constructor& err) {
1752 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1753 return boost::shared_ptr<Source>();
1758 Session::save_template (string template_name)
1762 if (_state_of_the_state & CannotSave) {
1766 sys::path user_template_dir(user_template_directory());
1770 sys::create_directories (user_template_dir);
1772 catch(sys::filesystem_error& ex)
1774 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1775 user_template_dir.to_string(), ex.what()) << endmsg;
1779 tree.set_root (&get_template());
1781 sys::path template_file_path(user_template_dir);
1782 template_file_path /= template_name + template_suffix;
1784 if (sys::exists (template_file_path))
1786 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1787 template_file_path.to_string()) << endmsg;
1791 if (!tree.write (template_file_path.to_string())) {
1792 error << _("mix template not saved") << endmsg;
1800 Session::rename_template (string old_name, string new_name)
1802 sys::path old_path (user_template_directory());
1803 old_path /= old_name + template_suffix;
1805 sys::path new_path(user_template_directory());
1806 new_path /= new_name + template_suffix;
1808 if (sys::exists (new_path)) {
1809 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1810 new_path.to_string()) << endmsg;
1815 sys::rename (old_path, new_path);
1823 Session::delete_template (string name)
1825 sys::path path = user_template_directory();
1826 path /= name + template_suffix;
1837 Session::refresh_disk_space ()
1840 struct statfs statfsbuf;
1841 vector<space_and_path>::iterator i;
1842 Glib::Mutex::Lock lm (space_lock);
1845 /* get freespace on every FS that is part of the session path */
1847 _total_free_4k_blocks = 0;
1849 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1850 statfs ((*i).path.c_str(), &statfsbuf);
1852 scale = statfsbuf.f_bsize/4096.0;
1854 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1855 _total_free_4k_blocks += (*i).blocks;
1861 Session::get_best_session_directory_for_new_source ()
1863 vector<space_and_path>::iterator i;
1864 string result = _session_dir->root_path().to_string();
1866 /* handle common case without system calls */
1868 if (session_dirs.size() == 1) {
1872 /* OK, here's the algorithm we're following here:
1874 We want to select which directory to use for
1875 the next file source to be created. Ideally,
1876 we'd like to use a round-robin process so as to
1877 get maximum performance benefits from splitting
1878 the files across multiple disks.
1880 However, in situations without much diskspace, an
1881 RR approach may end up filling up a filesystem
1882 with new files while others still have space.
1883 Its therefore important to pay some attention to
1884 the freespace in the filesystem holding each
1885 directory as well. However, if we did that by
1886 itself, we'd keep creating new files in the file
1887 system with the most space until it was as full
1888 as all others, thus negating any performance
1889 benefits of this RAID-1 like approach.
1891 So, we use a user-configurable space threshold. If
1892 there are at least 2 filesystems with more than this
1893 much space available, we use RR selection between them.
1894 If not, then we pick the filesystem with the most space.
1896 This gets a good balance between the two
1900 refresh_disk_space ();
1902 int free_enough = 0;
1904 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1905 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1910 if (free_enough >= 2) {
1911 /* use RR selection process, ensuring that the one
1915 i = last_rr_session_dir;
1918 if (++i == session_dirs.end()) {
1919 i = session_dirs.begin();
1922 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1923 if (create_session_directory ((*i).path)) {
1925 last_rr_session_dir = i;
1930 } while (i != last_rr_session_dir);
1934 /* pick FS with the most freespace (and that
1935 seems to actually work ...)
1938 vector<space_and_path> sorted;
1939 space_and_path_ascending_cmp cmp;
1941 sorted = session_dirs;
1942 sort (sorted.begin(), sorted.end(), cmp);
1944 for (i = sorted.begin(); i != sorted.end(); ++i) {
1945 if (create_session_directory ((*i).path)) {
1947 last_rr_session_dir = i;
1957 Session::load_playlists (const XMLNode& node)
1960 XMLNodeConstIterator niter;
1961 boost::shared_ptr<Playlist> playlist;
1963 nlist = node.children();
1967 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1969 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1970 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1978 Session::load_unused_playlists (const XMLNode& node)
1981 XMLNodeConstIterator niter;
1982 boost::shared_ptr<Playlist> playlist;
1984 nlist = node.children();
1988 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1990 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1991 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1995 // now manually untrack it
1997 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
2003 boost::shared_ptr<Playlist>
2004 Session::XMLPlaylistFactory (const XMLNode& node)
2007 return PlaylistFactory::create (*this, node);
2010 catch (failed_constructor& err) {
2011 return boost::shared_ptr<Playlist>();
2016 Session::load_named_selections (const XMLNode& node)
2019 XMLNodeConstIterator niter;
2022 nlist = node.children();
2026 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2028 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2029 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2037 Session::XMLNamedSelectionFactory (const XMLNode& node)
2040 return new NamedSelection (*this, node);
2043 catch (failed_constructor& err) {
2049 Session::automation_dir () const
2051 return Glib::build_filename (_path, "automation");
2055 Session::analysis_dir () const
2057 return Glib::build_filename (_path, "analysis");
2061 Session::load_bundles (XMLNode const & node)
2063 XMLNodeList nlist = node.children();
2064 XMLNodeConstIterator niter;
2068 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2069 if ((*niter)->name() == "InputBundle") {
2070 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2071 } else if ((*niter)->name() == "OutputBundle") {
2072 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2074 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2083 Session::load_route_groups (const XMLNode& node, int version)
2085 XMLNodeList nlist = node.children();
2086 XMLNodeConstIterator niter;
2090 if (version >= 3000) {
2092 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2093 if ((*niter)->name() == "RouteGroup") {
2094 RouteGroup* rg = new RouteGroup (*this, "");
2095 add_route_group (rg);
2096 rg->set_state (**niter, version);
2100 } else if (version < 3000) {
2102 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2103 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2104 RouteGroup* rg = new RouteGroup (*this, "");
2105 add_route_group (rg);
2106 rg->set_state (**niter, version);
2115 Session::auto_save()
2117 save_state (_current_snapshot_name);
2121 state_file_filter (const string &str, void */*arg*/)
2123 return (str.length() > strlen(statefile_suffix) &&
2124 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2128 bool operator()(const string* a, const string* b) {
2134 remove_end(string* state)
2136 string statename(*state);
2138 string::size_type start,end;
2139 if ((start = statename.find_last_of ('/')) != string::npos) {
2140 statename = statename.substr (start+1);
2143 if ((end = statename.rfind(".ardour")) == string::npos) {
2144 end = statename.length();
2147 return new string(statename.substr (0, end));
2151 Session::possible_states (string path)
2153 PathScanner scanner;
2154 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2156 transform(states->begin(), states->end(), states->begin(), remove_end);
2159 sort (states->begin(), states->end(), cmp);
2165 Session::possible_states () const
2167 return possible_states(_path);
2171 Session::add_route_group (RouteGroup* g)
2173 _route_groups.push_back (g);
2174 route_group_added (g); /* EMIT SIGNAL */
2179 Session::remove_route_group (RouteGroup& rg)
2181 list<RouteGroup*>::iterator i;
2183 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2184 (*i)->apply (&Route::drop_route_group, this);
2185 _route_groups.erase (i);
2186 route_group_removed (); /* EMIT SIGNAL */
2194 Session::route_group_by_name (string name)
2196 list<RouteGroup *>::iterator i;
2198 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2199 if ((*i)->name() == name) {
2207 Session::begin_reversible_command(const string& name)
2209 UndoTransaction* trans = new UndoTransaction();
2210 trans->set_name(name);
2212 if (!_current_trans.empty()) {
2213 _current_trans.top()->add_command (trans);
2215 _current_trans.push(trans);
2220 Session::commit_reversible_command(Command *cmd)
2222 assert(!_current_trans.empty());
2226 _current_trans.top()->add_command(cmd);
2229 if (_current_trans.top()->empty()) {
2230 _current_trans.pop();
2234 gettimeofday(&now, 0);
2235 _current_trans.top()->set_timestamp(now);
2237 _history.add(_current_trans.top());
2238 _current_trans.pop();
2241 Session::GlobalRouteBooleanState
2242 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2244 GlobalRouteBooleanState s;
2245 boost::shared_ptr<RouteList> r = routes.reader ();
2247 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2248 if (!(*i)->is_hidden()) {
2249 RouteBooleanState v;
2252 Route* r = (*i).get();
2253 v.second = (r->*method)();
2262 Session::GlobalRouteMeterState
2263 Session::get_global_route_metering ()
2265 GlobalRouteMeterState s;
2266 boost::shared_ptr<RouteList> r = routes.reader ();
2268 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2269 if (!(*i)->is_hidden()) {
2273 v.second = (*i)->meter_point();
2283 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2285 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2287 boost::shared_ptr<Route> r = (i->first.lock());
2290 r->set_meter_point (i->second, arg);
2296 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2298 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2300 boost::shared_ptr<Route> r = (i->first.lock());
2303 Route* rp = r.get();
2304 (rp->*method) (i->second, arg);
2310 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2312 set_global_route_boolean (s, &Route::set_mute, src);
2316 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2318 set_global_route_boolean (s, &Route::set_solo, src);
2322 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2324 set_global_route_boolean (s, &Route::set_record_enable, src);
2328 accept_all_non_peak_files (const string& path, void */*arg*/)
2330 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2334 accept_all_state_files (const string& path, void */*arg*/)
2336 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2340 Session::find_all_sources (string path, set<string>& result)
2345 if (!tree.read (path)) {
2349 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2354 XMLNodeConstIterator niter;
2356 nlist = node->children();
2360 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2364 if ((prop = (*niter)->property (X_("type"))) == 0) {
2368 DataType type (prop->value());
2370 if ((prop = (*niter)->property (X_("name"))) == 0) {
2374 if (prop->value()[0] == '/') {
2375 /* external file, ignore */
2379 Glib::ustring found_path;
2383 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2384 result.insert (found_path);
2392 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2394 PathScanner scanner;
2395 vector<string*>* state_files;
2397 string this_snapshot_path;
2403 if (ripped[ripped.length()-1] == '/') {
2404 ripped = ripped.substr (0, ripped.length() - 1);
2407 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2409 if (state_files == 0) {
2414 this_snapshot_path = _path;
2415 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2416 this_snapshot_path += statefile_suffix;
2418 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2420 if (exclude_this_snapshot && **i == this_snapshot_path) {
2424 if (find_all_sources (**i, result) < 0) {
2432 struct RegionCounter {
2433 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2434 AudioSourceList::iterator iter;
2435 boost::shared_ptr<Region> region;
2438 RegionCounter() : count (0) {}
2442 Session::cleanup_sources (Session::cleanup_report& rep)
2444 // FIXME: needs adaptation to midi
2446 vector<boost::shared_ptr<Source> > dead_sources;
2447 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2448 PathScanner scanner;
2450 vector<space_and_path>::iterator i;
2451 vector<space_and_path>::iterator nexti;
2452 vector<string*>* soundfiles;
2453 vector<string> unused;
2454 set<string> all_sources;
2459 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2462 /* step 1: consider deleting all unused playlists */
2464 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2467 status = AskAboutPlaylistDeletion (*x);
2476 playlists_tbd.push_back (*x);
2480 /* leave it alone */
2485 /* now delete any that were marked for deletion */
2487 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2488 (*x)->drop_references ();
2491 playlists_tbd.clear ();
2493 /* step 2: find all un-used sources */
2498 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2500 SourceMap::iterator tmp;
2505 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2509 if (!i->second->used() && i->second->length(i->second->timeline_position()) > 0) {
2510 dead_sources.push_back (i->second);
2511 i->second->GoingAway();
2517 /* build a list of all the possible sound directories for the session */
2519 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2524 SessionDirectory sdir ((*i).path);
2525 sound_path += sdir.sound_path().to_string();
2527 if (nexti != session_dirs.end()) {
2534 /* now do the same thing for the files that ended up in the sounds dir(s)
2535 but are not referenced as sources in any snapshot.
2538 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2540 if (soundfiles == 0) {
2544 /* find all sources, but don't use this snapshot because the
2545 state file on disk still references sources we may have already
2549 find_all_sources_across_snapshots (all_sources, true);
2551 /* add our current source list
2554 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2555 boost::shared_ptr<FileSource> fs;
2557 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2558 all_sources.insert (fs->path());
2562 char tmppath1[PATH_MAX+1];
2563 char tmppath2[PATH_MAX+1];
2565 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2570 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2572 realpath(spath.c_str(), tmppath1);
2573 realpath((*i).c_str(), tmppath2);
2575 if (strcmp(tmppath1, tmppath2) == 0) {
2582 unused.push_back (spath);
2586 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2588 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2589 struct stat statbuf;
2591 rep.paths.push_back (*x);
2592 if (stat ((*x).c_str(), &statbuf) == 0) {
2593 rep.space += statbuf.st_size;
2598 /* don't move the file across filesystems, just
2599 stick it in the `dead_sound_dir_name' directory
2600 on whichever filesystem it was already on.
2603 if ((*x).find ("/sounds/") != string::npos) {
2605 /* old school, go up 1 level */
2607 newpath = Glib::path_get_dirname (*x); // "sounds"
2608 newpath = Glib::path_get_dirname (newpath); // "session-name"
2612 /* new school, go up 4 levels */
2614 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2615 newpath = Glib::path_get_dirname (newpath); // "session-name"
2616 newpath = Glib::path_get_dirname (newpath); // "interchange"
2617 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2621 newpath += dead_sound_dir_name;
2623 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2624 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2629 newpath += Glib::path_get_basename ((*x));
2631 if (access (newpath.c_str(), F_OK) == 0) {
2633 /* the new path already exists, try versioning */
2635 char buf[PATH_MAX+1];
2639 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2642 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2643 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2647 if (version == 999) {
2648 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2652 newpath = newpath_v;
2657 /* it doesn't exist, or we can't read it or something */
2661 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2662 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2663 (*x), newpath, strerror (errno))
2668 /* see if there an easy to find peakfile for this file, and remove it.
2671 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2672 peakpath += peakfile_suffix;
2674 if (access (peakpath.c_str(), W_OK) == 0) {
2675 if (::unlink (peakpath.c_str()) != 0) {
2676 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2677 peakpath, _path, strerror (errno))
2679 /* try to back out */
2680 rename (newpath.c_str(), _path.c_str());
2688 /* dump the history list */
2692 /* save state so we don't end up a session file
2693 referring to non-existent sources.
2699 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2705 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2707 // FIXME: needs adaptation for MIDI
2709 vector<space_and_path>::iterator i;
2710 string dead_sound_dir;
2711 struct dirent* dentry;
2712 struct stat statbuf;
2718 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2720 dead_sound_dir = (*i).path;
2721 dead_sound_dir += dead_sound_dir_name;
2723 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2727 while ((dentry = readdir (dead)) != 0) {
2729 /* avoid '.' and '..' */
2731 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2732 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2738 fullpath = dead_sound_dir;
2740 fullpath += dentry->d_name;
2742 if (stat (fullpath.c_str(), &statbuf)) {
2746 if (!S_ISREG (statbuf.st_mode)) {
2750 if (unlink (fullpath.c_str())) {
2751 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2752 fullpath, strerror (errno))
2756 rep.paths.push_back (dentry->d_name);
2757 rep.space += statbuf.st_size;
2768 Session::set_dirty ()
2770 bool was_dirty = dirty();
2772 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2776 DirtyChanged(); /* EMIT SIGNAL */
2782 Session::set_clean ()
2784 bool was_dirty = dirty();
2786 _state_of_the_state = Clean;
2790 DirtyChanged(); /* EMIT SIGNAL */
2795 Session::set_deletion_in_progress ()
2797 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2801 Session::clear_deletion_in_progress ()
2803 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2807 Session::add_controllable (boost::shared_ptr<Controllable> c)
2809 /* this adds a controllable to the list managed by the Session.
2810 this is a subset of those managed by the Controllable class
2811 itself, and represents the only ones whose state will be saved
2812 as part of the session.
2815 Glib::Mutex::Lock lm (controllables_lock);
2816 controllables.insert (c);
2819 struct null_deleter { void operator()(void const *) const {} };
2822 Session::remove_controllable (Controllable* c)
2824 if (_state_of_the_state | Deletion) {
2828 Glib::Mutex::Lock lm (controllables_lock);
2830 Controllables::iterator x = controllables.find(
2831 boost::shared_ptr<Controllable>(c, null_deleter()));
2833 if (x != controllables.end()) {
2834 controllables.erase (x);
2838 boost::shared_ptr<Controllable>
2839 Session::controllable_by_id (const PBD::ID& id)
2841 Glib::Mutex::Lock lm (controllables_lock);
2843 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2844 if ((*i)->id() == id) {
2849 return boost::shared_ptr<Controllable>();
2853 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2856 Stateful::add_instant_xml (node, _path);
2859 if (write_to_config) {
2860 Config->add_instant_xml (node);
2865 Session::instant_xml (const string& node_name)
2867 return Stateful::instant_xml (node_name, _path);
2871 Session::save_history (string snapshot_name)
2879 if (snapshot_name.empty()) {
2880 snapshot_name = _current_snapshot_name;
2883 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2884 const string backup_filename = history_filename + backup_suffix;
2885 const sys::path xml_path = _session_dir->root_path() / history_filename;
2886 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2888 if (sys::exists (xml_path)) {
2891 sys::rename (xml_path, backup_path);
2893 catch (const sys::filesystem_error& err)
2895 error << _("could not backup old history file, current history not saved") << endmsg;
2900 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2904 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2906 if (!tree.write (xml_path.to_string()))
2908 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2912 sys::remove (xml_path);
2913 sys::rename (backup_path, xml_path);
2915 catch (const sys::filesystem_error& err)
2917 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2918 backup_path.to_string(), err.what()) << endmsg;
2928 Session::restore_history (string snapshot_name)
2932 if (snapshot_name.empty()) {
2933 snapshot_name = _current_snapshot_name;
2936 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
2937 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2939 cerr << "Loading history from " << xml_path.to_string() << endmsg;
2941 if (!sys::exists (xml_path)) {
2942 info << string_compose (_("%1: no history file \"%2\" for this session."),
2943 _name, xml_path.to_string()) << endmsg;
2947 if (!tree.read (xml_path.to_string())) {
2948 error << string_compose (_("Could not understand session history file \"%1\""),
2949 xml_path.to_string()) << endmsg;
2956 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2959 UndoTransaction* ut = new UndoTransaction ();
2962 ut->set_name(t->property("name")->value());
2963 stringstream ss(t->property("tv-sec")->value());
2965 ss.str(t->property("tv-usec")->value());
2967 ut->set_timestamp(tv);
2969 for (XMLNodeConstIterator child_it = t->children().begin();
2970 child_it != t->children().end(); child_it++)
2972 XMLNode *n = *child_it;
2975 if (n->name() == "MementoCommand" ||
2976 n->name() == "MementoUndoCommand" ||
2977 n->name() == "MementoRedoCommand") {
2979 if ((c = memento_command_factory(n))) {
2983 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2985 if ((c = global_state_command_factory (*n))) {
2986 ut->add_command (c);
2989 } else if (n->name() == "DeltaCommand") {
2990 PBD::ID id(n->property("midi-source")->value());
2991 boost::shared_ptr<MidiSource> midi_source =
2992 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2994 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
2996 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2999 } else if (n->name() == "DiffCommand") {
3000 PBD::ID id(n->property("midi-source")->value());
3001 boost::shared_ptr<MidiSource> midi_source =
3002 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3004 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3006 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3010 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3021 Session::config_changed (std::string p, bool ours)
3027 if (p == "seamless-loop") {
3029 } else if (p == "rf-speed") {
3031 } else if (p == "auto-loop") {
3033 } else if (p == "auto-input") {
3035 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3036 /* auto-input only makes a difference if we're rolling */
3038 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3040 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3041 if ((*i)->record_enabled ()) {
3042 (*i)->monitor_input (!config.get_auto_input());
3047 } else if (p == "punch-in") {
3051 if ((location = _locations.auto_punch_location()) != 0) {
3053 if (config.get_punch_in ()) {
3054 replace_event (Event::PunchIn, location->start());
3056 remove_event (location->start(), Event::PunchIn);
3060 } else if (p == "punch-out") {
3064 if ((location = _locations.auto_punch_location()) != 0) {
3066 if (config.get_punch_out()) {
3067 replace_event (Event::PunchOut, location->end());
3069 clear_events (Event::PunchOut);
3073 } else if (p == "edit-mode") {
3075 Glib::Mutex::Lock lm (playlist_lock);
3077 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3078 (*i)->set_edit_mode (Config->get_edit_mode ());
3081 } else if (p == "use-video-sync") {
3083 waiting_for_sync_offset = config.get_use_video_sync();
3085 } else if (p == "mmc-control") {
3087 //poke_midi_thread ();
3089 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3092 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3095 } else if (p == "mmc-send-id") {
3098 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3101 } else if (p == "midi-control") {
3103 //poke_midi_thread ();
3105 } else if (p == "raid-path") {
3107 setup_raid_path (config.get_raid_path());
3109 } else if (p == "smpte-format") {
3113 } else if (p == "video-pullup") {
3117 } else if (p == "seamless-loop") {
3119 if (play_loop && transport_rolling()) {
3120 // to reset diskstreams etc
3121 request_play_loop (true);
3124 } else if (p == "rf-speed") {
3126 cumulative_rf_motion = 0;
3129 } else if (p == "click-sound") {
3131 setup_click_sounds (1);
3133 } else if (p == "click-emphasis-sound") {
3135 setup_click_sounds (-1);
3137 } else if (p == "clicking") {
3139 if (Config->get_clicking()) {
3140 if (_click_io && click_data) { // don't require emphasis data
3147 } else if (p == "send-mtc") {
3149 /* only set the internal flag if we have
3153 if (_mtc_port != 0) {
3154 session_send_mtc = Config->get_send_mtc();
3155 if (session_send_mtc) {
3156 /* mark us ready to send */
3157 next_quarter_frame_to_send = 0;
3160 session_send_mtc = false;
3163 } else if (p == "send-mmc") {
3165 /* only set the internal flag if we have
3169 if (_mmc_port != 0) {
3170 session_send_mmc = Config->get_send_mmc();
3173 session_send_mmc = false;
3176 } else if (p == "midi-feedback") {
3178 /* only set the internal flag if we have
3182 if (_mtc_port != 0) {
3183 session_midi_feedback = Config->get_midi_feedback();
3186 } else if (p == "jack-time-master") {
3188 engine().reset_timebase ();
3190 } else if (p == "native-file-header-format") {
3192 if (!first_file_header_format_reset) {
3193 reset_native_file_format ();
3196 first_file_header_format_reset = false;
3198 } else if (p == "native-file-data-format") {
3200 if (!first_file_data_format_reset) {
3201 reset_native_file_format ();
3204 first_file_data_format_reset = false;
3206 } else if (p == "slave-source") {
3207 set_slave_source (Config->get_slave_source());
3208 } else if (p == "remote-model") {
3209 set_remote_control_ids ();
3210 } else if (p == "denormal-model") {
3212 } else if (p == "history-depth") {
3213 set_history_depth (Config->get_history_depth());
3214 } else if (p == "sync-all-route-ordering") {
3215 sync_order_keys ("session");
3216 } else if (p == "initial-program-change") {
3218 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3221 buf[0] = MIDI::program; // channel zero by default
3222 buf[1] = (Config->get_initial_program_change() & 0x7f);
3224 _mmc_port->midimsg (buf, sizeof (buf), 0);
3226 } else if (p == "initial-program-change") {
3228 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3229 MIDI::byte* buf = new MIDI::byte[2];
3231 buf[0] = MIDI::program; // channel zero by default
3232 buf[1] = (Config->get_initial_program_change() & 0x7f);
3233 // deliver_midi (_mmc_port, buf, 2);
3235 } else if (p == "solo-mute-override") {
3236 // catch_up_on_solo_mute_override ();
3237 } else if (p == "listen-position") {
3238 listen_position_changed ();
3239 } else if (p == "solo-control-is-listen-control") {
3240 solo_control_mode_changed ();
3248 Session::set_history_depth (uint32_t d)
3250 _history.set_depth (d);