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 (&_playback_load, 100);
206 g_atomic_int_set (&_capture_load, 100);
207 g_atomic_int_set (&_playback_load_min, 100);
208 g_atomic_int_set (&_capture_load_min, 100);
211 _exporting_realtime = false;
212 _gain_automation_buffer = 0;
213 _pan_automation_buffer = 0;
215 pending_abort = false;
216 destructive_index = 0;
217 first_file_data_format_reset = true;
218 first_file_header_format_reset = true;
219 //midi_thread = (pthread_t) 0;
221 AudioDiskstream::allocate_working_buffers();
223 /* default short fade = 15ms */
225 Crossfade::set_short_xfade_length ((nframes_t) floor (config.get_short_xfade_seconds() * frame_rate()));
226 SndFileSource::setup_standard_crossfades (*this, frame_rate());
228 last_mmc_step.tv_sec = 0;
229 last_mmc_step.tv_usec = 0;
232 /* click sounds are unset by default, which causes us to internal
233 waveforms for clicks.
237 click_emphasis_length = 0;
240 process_function = &Session::process_with_events;
242 if (config.get_use_video_sync()) {
243 waiting_for_sync_offset = true;
245 waiting_for_sync_offset = false;
250 _smpte_offset_negative = true;
251 last_smpte_valid = false;
255 last_rr_session_dir = session_dirs.begin();
256 refresh_disk_space ();
258 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
262 average_slave_delta = 1800; // !!! why 1800 ????
263 have_first_delta_accumulator = false;
264 delta_accumulator_cnt = 0;
265 slave_state = Stopped;
267 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
269 /* These are all static "per-class" signals */
271 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
272 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
273 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
274 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
275 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
276 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
278 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
280 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
282 /* stop IO objects from doing stuff until we're ready for them */
284 Delivery::disable_panners ();
285 IO::disable_connecting ();
289 Session::second_stage_init (bool new_session)
291 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
294 if (load_state (_current_snapshot_name)) {
297 remove_empty_sounds ();
300 if (start_butler_thread()) {
304 if (start_midi_thread ()) {
308 // set_state() will call setup_raid_path(), but if it's a new session we need
309 // to call setup_raid_path() here.
312 if (set_state (*state_tree->root(), Stateful::loading_state_version)) {
316 setup_raid_path(_path);
319 /* we can't save till after ::when_engine_running() is called,
320 because otherwise we save state with no connections made.
321 therefore, we reset _state_of_the_state because ::set_state()
322 will have cleared it.
324 we also have to include Loading so that any events that get
325 generated between here and the end of ::when_engine_running()
326 will be processed directly rather than queued.
329 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
332 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
333 _locations.added.connect (mem_fun (this, &Session::locations_added));
334 setup_click_sounds (0);
335 setup_midi_control ();
337 /* Pay attention ... */
339 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
340 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
343 when_engine_running();
346 /* handle this one in a different way than all others, so that its clear what happened */
348 catch (AudioEngine::PortRegistrationFailure& err) {
349 error << err.what() << endmsg;
357 BootMessage (_("Reset Remote Controls"));
359 send_full_time_code (0);
360 _engine.transport_locate (0);
361 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
362 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
364 MidiClockTicker::instance().set_session(*this);
365 MIDI::Name::MidiPatchManager::instance().set_session(*this);
367 /* initial program change will be delivered later; see ::config_changed() */
369 BootMessage (_("Reset Control Protocols"));
371 ControlProtocolManager::instance().set_session (*this);
373 config.set_end_marker_is_free (new_session);
375 _state_of_the_state = Clean;
377 DirtyChanged (); /* EMIT SIGNAL */
379 if (state_was_pending) {
380 save_state (_current_snapshot_name);
381 remove_pending_capture_state ();
382 state_was_pending = false;
385 BootMessage (_("Session loading complete"));
391 Session::raid_path () const
393 SearchPath raid_search_path;
395 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
396 raid_search_path += sys::path((*i).path);
399 return raid_search_path.to_string ();
403 Session::setup_raid_path (string path)
412 session_dirs.clear ();
414 SearchPath search_path(path);
415 SearchPath sound_search_path;
416 SearchPath midi_search_path;
418 for (SearchPath::const_iterator i = search_path.begin(); i != search_path.end(); ++i) {
419 sp.path = (*i).to_string ();
420 sp.blocks = 0; // not needed
421 session_dirs.push_back (sp);
423 SessionDirectory sdir(sp.path);
425 sound_search_path += sdir.sound_path ();
426 midi_search_path += sdir.midi_path ();
429 // set the search path for each data type
430 FileSource::set_search_path (DataType::AUDIO, sound_search_path.to_string ());
431 SMFSource::set_search_path (DataType::MIDI, midi_search_path.to_string ());
433 // reset the round-robin soundfile path thingie
434 last_rr_session_dir = session_dirs.begin();
438 Session::ensure_subdirs ()
442 dir = session_directory().peak_path().to_string();
444 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
445 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
449 dir = session_directory().sound_path().to_string();
451 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
452 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
456 dir = session_directory().midi_path().to_string();
458 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
459 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
463 dir = session_directory().dead_sound_path().to_string();
465 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
466 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
470 dir = session_directory().export_path().to_string();
472 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
473 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
477 dir = analysis_dir ();
479 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
480 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
488 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
491 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
492 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
496 if (ensure_subdirs ()) {
500 /* check new_session so we don't overwrite an existing one */
502 if (!mix_template.empty()) {
503 std::string in_path = mix_template;
505 ifstream in(in_path.c_str());
508 string out_path = _path;
510 out_path += statefile_suffix;
512 ofstream out(out_path.c_str());
517 // okay, session is set up. Treat like normal saved
518 // session from now on.
524 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
530 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
537 /* Instantiate metadata */
539 _metadata = new SessionMetadata ();
541 /* set initial start + end point */
543 start_location->set_end (0);
544 _locations.add (start_location);
546 end_location->set_end (initial_length);
547 _locations.add (end_location);
549 _state_of_the_state = Clean;
558 Session::load_diskstreams (const XMLNode& node)
561 XMLNodeConstIterator citer;
563 clist = node.children();
565 for (citer = clist.begin(); citer != clist.end(); ++citer) {
568 /* diskstreams added automatically by DiskstreamCreated handler */
569 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
570 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
571 add_diskstream (dstream);
572 } else if ((*citer)->name() == "MidiDiskstream") {
573 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
574 add_diskstream (dstream);
576 error << _("Session: unknown diskstream type in XML") << endmsg;
580 catch (failed_constructor& err) {
581 error << _("Session: could not load diskstream via XML state") << endmsg;
590 Session::maybe_write_autosave()
592 if (dirty() && record_status() != Recording) {
593 save_state("", true);
598 Session::remove_pending_capture_state ()
600 sys::path pending_state_file_path(_session_dir->root_path());
602 pending_state_file_path /= legalize_for_path (_current_snapshot_name) + pending_suffix;
606 sys::remove (pending_state_file_path);
608 catch(sys::filesystem_error& ex)
610 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
611 pending_state_file_path.to_string(), ex.what()) << endmsg;
615 /** Rename a state file.
616 * @param snapshot_name Snapshot name.
619 Session::rename_state (string old_name, string new_name)
621 if (old_name == _current_snapshot_name || old_name == _name) {
622 /* refuse to rename the current snapshot or the "main" one */
626 const string old_xml_filename = legalize_for_path (old_name) + statefile_suffix;
627 const string new_xml_filename = legalize_for_path (new_name) + statefile_suffix;
629 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
630 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
634 sys::rename (old_xml_path, new_xml_path);
636 catch (const sys::filesystem_error& err)
638 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
639 old_name, new_name, err.what()) << endmsg;
643 /** Remove a state file.
644 * @param snapshot_name Snapshot name.
647 Session::remove_state (string snapshot_name)
649 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
650 // refuse to remove the current snapshot or the "main" one
654 sys::path xml_path(_session_dir->root_path());
656 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
658 if (!create_backup_file (xml_path)) {
659 // don't remove it if a backup can't be made
660 // create_backup_file will log the error.
665 sys::remove (xml_path);
669 Session::save_state (string snapshot_name, bool pending)
672 sys::path xml_path(_session_dir->root_path());
674 if (!_writable || (_state_of_the_state & CannotSave)) {
678 if (!_engine.connected ()) {
679 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
684 /* tell sources we're saving first, in case they write out to a new file
685 * which should be saved with the state rather than the old one */
686 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
687 i->second->session_saved();
689 tree.set_root (&get_state());
691 if (snapshot_name.empty()) {
692 snapshot_name = _current_snapshot_name;
697 /* proper save: use statefile_suffix (.ardour in English) */
699 xml_path /= legalize_for_path (snapshot_name) + statefile_suffix;
701 /* make a backup copy of the old file */
703 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
704 // create_backup_file will log the error
710 /* pending save: use pending_suffix (.pending in English) */
711 xml_path /= legalize_for_path (snapshot_name) + pending_suffix;
714 sys::path tmp_path(_session_dir->root_path());
716 tmp_path /= legalize_for_path (snapshot_name) + temp_suffix;
718 // cerr << "actually writing state to " << xml_path.to_string() << endl;
720 if (!tree.write (tmp_path.to_string())) {
721 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
722 sys::remove (tmp_path);
727 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
728 error << string_compose (_("could not rename temporary session file %1 to %2"),
729 tmp_path.to_string(), xml_path.to_string()) << endmsg;
730 sys::remove (tmp_path);
737 save_history (snapshot_name);
739 bool was_dirty = dirty();
741 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
744 DirtyChanged (); /* EMIT SIGNAL */
747 StateSaved (snapshot_name); /* EMIT SIGNAL */
754 Session::restore_state (string snapshot_name)
756 if (load_state (snapshot_name) == 0) {
757 set_state (*state_tree->root(), Stateful::loading_state_version);
764 Session::load_state (string snapshot_name)
769 state_was_pending = false;
771 /* check for leftover pending state from a crashed capture attempt */
773 sys::path xmlpath(_session_dir->root_path());
774 xmlpath /= legalize_for_path (snapshot_name) + pending_suffix;
776 if (sys::exists (xmlpath)) {
778 /* there is pending state from a crashed capture attempt */
780 if (AskAboutPendingState()) {
781 state_was_pending = true;
785 if (!state_was_pending) {
786 xmlpath = _session_dir->root_path();
787 xmlpath /= legalize_for_path (snapshot_name) + statefile_suffix;
790 if (!sys::exists (xmlpath)) {
791 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
795 state_tree = new XMLTree;
799 /* writable() really reflects the whole folder, but if for any
800 reason the session state file can't be written to, still
804 if (::access (xmlpath.to_string().c_str(), W_OK) != 0) {
808 if (!state_tree->read (xmlpath.to_string())) {
809 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
815 XMLNode& root (*state_tree->root());
817 if (root.name() != X_("Session")) {
818 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
824 const XMLProperty* prop;
826 if ((prop = root.property ("version")) == 0) {
827 /* no version implies very old version of Ardour */
828 Stateful::loading_state_version = 1000;
834 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
835 Stateful::loading_state_version = (major * 1000) + minor;
838 if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION) {
840 sys::path backup_path(_session_dir->root_path());
842 backup_path /= legalize_for_path (snapshot_name) + "-1" + statefile_suffix;
844 // only create a backup once
845 if (sys::exists (backup_path)) {
849 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
850 xmlpath.to_string(), backup_path.to_string())
855 sys::copy_file (xmlpath, backup_path);
857 catch(sys::filesystem_error& ex)
859 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
860 xmlpath.to_string(), ex.what())
870 Session::load_options (const XMLNode& node)
872 LocaleGuard lg (X_("POSIX"));
874 config.set_variables (node);
876 /* now reset MIDI ports because the session can have its own
892 Session::get_template()
894 /* if we don't disable rec-enable, diskstreams
895 will believe they need to store their capture
896 sources in their state node.
899 disable_record (false);
905 Session::state(bool full_state)
907 XMLNode* node = new XMLNode("Session");
910 // store libardour version, just in case
912 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
913 node->add_property("version", string(buf));
915 /* store configuration settings */
919 node->add_property ("name", _name);
920 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
921 node->add_property ("sample-rate", buf);
923 if (session_dirs.size() > 1) {
927 vector<space_and_path>::iterator i = session_dirs.begin();
928 vector<space_and_path>::iterator next;
930 ++i; /* skip the first one */
934 while (i != session_dirs.end()) {
938 if (next != session_dirs.end()) {
948 child = node->add_child ("Path");
949 child->add_content (p);
953 /* save the ID counter */
955 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
956 node->add_property ("id-counter", buf);
958 /* various options */
960 node->add_child_nocopy (config.get_variables ());
962 node->add_child_nocopy (_metadata->get_state());
964 child = node->add_child ("Sources");
967 Glib::Mutex::Lock sl (source_lock);
969 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
971 /* Don't save information about non-destructive file sources that are empty */
972 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
974 boost::shared_ptr<AudioFileSource> fs;
975 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
976 if (!fs->destructive()) {
977 if (fs->length(fs->timeline_position()) == 0) {
983 child->add_child_nocopy (siter->second->get_state());
987 child = node->add_child ("Regions");
990 Glib::Mutex::Lock rl (region_lock);
992 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
994 /* only store regions not attached to playlists */
996 if (i->second->playlist() == 0) {
997 child->add_child_nocopy (i->second->state (true));
1002 child = node->add_child ("DiskStreams");
1005 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1006 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1007 if (!(*i)->hidden()) {
1008 child->add_child_nocopy ((*i)->get_state());
1014 node->add_child_nocopy (_locations.get_state());
1016 // for a template, just create a new Locations, populate it
1017 // with the default start and end, and get the state for that.
1019 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1020 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1023 end->set_end(compute_initial_length());
1025 node->add_child_nocopy (loc.get_state());
1028 child = node->add_child ("Bundles");
1030 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1031 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1032 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1034 child->add_child_nocopy (b->get_state());
1039 child = node->add_child ("Routes");
1041 boost::shared_ptr<RouteList> r = routes.reader ();
1043 RoutePublicOrderSorter cmp;
1044 RouteList public_order (*r);
1045 public_order.sort (cmp);
1047 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1048 if (!(*i)->is_hidden()) {
1050 child->add_child_nocopy ((*i)->get_state());
1052 child->add_child_nocopy ((*i)->get_template());
1059 child = node->add_child ("RouteGroups");
1060 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1061 child->add_child_nocopy ((*i)->get_state());
1064 child = node->add_child ("Playlists");
1065 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1066 if (!(*i)->hidden()) {
1067 if (!(*i)->empty()) {
1069 child->add_child_nocopy ((*i)->get_state());
1071 child->add_child_nocopy ((*i)->get_template());
1077 child = node->add_child ("UnusedPlaylists");
1078 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1079 if (!(*i)->hidden()) {
1080 if (!(*i)->empty()) {
1082 child->add_child_nocopy ((*i)->get_state());
1084 child->add_child_nocopy ((*i)->get_template());
1092 child = node->add_child ("Click");
1093 child->add_child_nocopy (_click_io->state (full_state));
1097 child = node->add_child ("NamedSelections");
1098 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1100 child->add_child_nocopy ((*i)->get_state());
1105 node->add_child_nocopy (_tempo_map->get_state());
1107 node->add_child_nocopy (get_control_protocol_state());
1110 node->add_child_copy (*_extra_xml);
1117 Session::get_control_protocol_state ()
1119 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1120 return cpm.get_state();
1124 Session::set_state (const XMLNode& node, int version)
1128 const XMLProperty* prop;
1131 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1133 if (node.name() != X_("Session")){
1134 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1138 if ((prop = node.property ("version")) != 0) {
1139 version = atoi (prop->value ()) * 1000;
1142 if ((prop = node.property ("name")) != 0) {
1143 _name = prop->value ();
1146 if ((prop = node.property (X_("sample-rate"))) != 0) {
1148 _nominal_frame_rate = atoi (prop->value());
1150 if (_nominal_frame_rate != _current_frame_rate) {
1151 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1157 setup_raid_path(_session_dir->root_path().to_string());
1159 if ((prop = node.property (X_("id-counter"))) != 0) {
1161 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1162 ID::init_counter (x);
1164 /* old sessions used a timebased counter, so fake
1165 the startup ID counter based on a standard
1170 ID::init_counter (now);
1174 IO::disable_connecting ();
1176 /* Object loading order:
1181 MIDI Control // relies on data from Options/Config
1195 if ((child = find_named_node (node, "Extra")) != 0) {
1196 _extra_xml = new XMLNode (*child);
1199 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1200 load_options (*child);
1201 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1202 load_options (*child);
1204 error << _("Session: XML state has no options section") << endmsg;
1207 if (use_config_midi_ports ()) {
1210 if (version >= 3000) {
1211 if ((child = find_named_node (node, "Metadata")) == 0) {
1212 warning << _("Session: XML state has no metadata section") << endmsg;
1213 } else if (_metadata->set_state (*child, version)) {
1218 if ((child = find_named_node (node, "Locations")) == 0) {
1219 error << _("Session: XML state has no locations section") << endmsg;
1221 } else if (_locations.set_state (*child, version)) {
1227 if ((location = _locations.auto_loop_location()) != 0) {
1228 set_auto_loop_location (location);
1231 if ((location = _locations.auto_punch_location()) != 0) {
1232 set_auto_punch_location (location);
1235 if ((location = _locations.end_location()) == 0) {
1236 _locations.add (end_location);
1238 delete end_location;
1239 end_location = location;
1242 if ((location = _locations.start_location()) == 0) {
1243 _locations.add (start_location);
1245 delete start_location;
1246 start_location = location;
1249 AudioFileSource::set_header_position_offset (start_location->start());
1251 if ((child = find_named_node (node, "Sources")) == 0) {
1252 error << _("Session: XML state has no sources section") << endmsg;
1254 } else if (load_sources (*child)) {
1258 if ((child = find_named_node (node, "Regions")) == 0) {
1259 error << _("Session: XML state has no Regions section") << endmsg;
1261 } else if (load_regions (*child)) {
1265 if ((child = find_named_node (node, "Playlists")) == 0) {
1266 error << _("Session: XML state has no playlists section") << endmsg;
1268 } else if (load_playlists (*child)) {
1272 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1274 } else if (load_unused_playlists (*child)) {
1278 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1279 if (load_named_selections (*child)) {
1284 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1285 error << _("Session: XML state has no diskstreams section") << endmsg;
1287 } else if (load_diskstreams (*child)) {
1291 if (version >= 3000) {
1292 if ((child = find_named_node (node, "Bundles")) == 0) {
1293 warning << _("Session: XML state has no bundles section") << endmsg;
1296 /* We can't load Bundles yet as they need to be able
1297 to convert from port names to Port objects, which can't happen until
1299 _bundle_xml_node = new XMLNode (*child);
1303 if (version >= 3000) {
1305 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1306 error << _("Session: XML state has no route groups section") << endmsg;
1308 } else if (load_route_groups (*child, version)) {
1312 } else if (version < 3000) {
1314 if ((child = find_named_node (node, "EditGroups")) == 0) {
1315 error << _("Session: XML state has no edit groups section") << endmsg;
1317 } else if (load_route_groups (*child, version)) {
1321 if ((child = find_named_node (node, "MixGroups")) == 0) {
1322 error << _("Session: XML state has no mix groups section") << endmsg;
1324 } else if (load_route_groups (*child, version)) {
1329 if ((child = find_named_node (node, "TempoMap")) == 0) {
1330 error << _("Session: XML state has no Tempo Map section") << endmsg;
1332 } else if (_tempo_map->set_state (*child, version)) {
1336 if ((child = find_named_node (node, "Routes")) == 0) {
1337 error << _("Session: XML state has no routes section") << endmsg;
1339 } else if (load_routes (*child, version)) {
1343 if ((child = find_named_node (node, "Click")) == 0) {
1344 warning << _("Session: XML state has no click section") << endmsg;
1345 } else if (_click_io) {
1346 _click_io->set_state (*child, version);
1349 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1350 ControlProtocolManager::instance().set_protocol_states (*child);
1353 /* here beginneth the second phase ... */
1355 StateReady (); /* EMIT SIGNAL */
1364 Session::load_routes (const XMLNode& node, int version)
1367 XMLNodeConstIterator niter;
1368 RouteList new_routes;
1370 nlist = node.children();
1374 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1376 boost::shared_ptr<Route> route (XMLRouteFactory (**niter, version));
1379 error << _("Session: cannot create Route from XML description.") << endmsg;
1383 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1385 new_routes.push_back (route);
1388 add_routes (new_routes, false);
1393 boost::shared_ptr<Route>
1394 Session::XMLRouteFactory (const XMLNode& node, int version)
1396 if (node.name() != "Route") {
1397 return boost::shared_ptr<Route> ((Route*) 0);
1400 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1402 DataType type = DataType::AUDIO;
1403 const XMLProperty* prop = node.property("default-type");
1406 type = DataType(prop->value());
1409 assert(type != DataType::NIL);
1411 if (has_diskstream) {
1412 if (type == DataType::AUDIO) {
1413 boost::shared_ptr<Route> ret (new AudioTrack (*this, node, version));
1416 boost::shared_ptr<Route> ret (new MidiTrack (*this, node, version));
1420 boost::shared_ptr<Route> ret (new Route (*this, node));
1426 Session::load_regions (const XMLNode& node)
1429 XMLNodeConstIterator niter;
1430 boost::shared_ptr<Region> region;
1432 nlist = node.children();
1436 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1437 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1438 error << _("Session: cannot create Region from XML description.");
1439 const XMLProperty *name = (**niter).property("name");
1442 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1452 boost::shared_ptr<Region>
1453 Session::XMLRegionFactory (const XMLNode& node, bool full)
1455 const XMLProperty* type = node.property("type");
1459 if ( !type || type->value() == "audio" ) {
1461 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1463 } else if (type->value() == "midi") {
1465 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1469 } catch (failed_constructor& err) {
1470 return boost::shared_ptr<Region> ();
1473 return boost::shared_ptr<Region> ();
1476 boost::shared_ptr<AudioRegion>
1477 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1479 const XMLProperty* prop;
1480 boost::shared_ptr<Source> source;
1481 boost::shared_ptr<AudioSource> as;
1483 SourceList master_sources;
1484 uint32_t nchans = 1;
1487 if (node.name() != X_("Region")) {
1488 return boost::shared_ptr<AudioRegion>();
1491 if ((prop = node.property (X_("channels"))) != 0) {
1492 nchans = atoi (prop->value().c_str());
1495 if ((prop = node.property ("name")) == 0) {
1496 cerr << "no name for this region\n";
1500 if ((prop = node.property (X_("source-0"))) == 0) {
1501 if ((prop = node.property ("source")) == 0) {
1502 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1503 return boost::shared_ptr<AudioRegion>();
1507 PBD::ID s_id (prop->value());
1509 if ((source = source_by_id (s_id)) == 0) {
1510 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1511 return boost::shared_ptr<AudioRegion>();
1514 as = boost::dynamic_pointer_cast<AudioSource>(source);
1516 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1517 return boost::shared_ptr<AudioRegion>();
1520 sources.push_back (as);
1522 /* pickup other channels */
1524 for (uint32_t n=1; n < nchans; ++n) {
1525 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1526 if ((prop = node.property (buf)) != 0) {
1528 PBD::ID id2 (prop->value());
1530 if ((source = source_by_id (id2)) == 0) {
1531 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1532 return boost::shared_ptr<AudioRegion>();
1535 as = boost::dynamic_pointer_cast<AudioSource>(source);
1537 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1538 return boost::shared_ptr<AudioRegion>();
1540 sources.push_back (as);
1544 for (uint32_t n = 0; n < nchans; ++n) {
1545 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1546 if ((prop = node.property (buf)) != 0) {
1548 PBD::ID id2 (prop->value());
1550 if ((source = source_by_id (id2)) == 0) {
1551 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1552 return boost::shared_ptr<AudioRegion>();
1555 as = boost::dynamic_pointer_cast<AudioSource>(source);
1557 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1558 return boost::shared_ptr<AudioRegion>();
1560 master_sources.push_back (as);
1565 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1567 /* a final detail: this is the one and only place that we know how long missing files are */
1569 if (region->whole_file()) {
1570 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1571 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1573 sfp->set_length (region->length());
1578 if (!master_sources.empty()) {
1579 if (master_sources.size() != nchans) {
1580 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1582 region->set_master_sources (master_sources);
1590 catch (failed_constructor& err) {
1591 return boost::shared_ptr<AudioRegion>();
1595 boost::shared_ptr<MidiRegion>
1596 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1598 const XMLProperty* prop;
1599 boost::shared_ptr<Source> source;
1600 boost::shared_ptr<MidiSource> ms;
1602 uint32_t nchans = 1;
1604 if (node.name() != X_("Region")) {
1605 return boost::shared_ptr<MidiRegion>();
1608 if ((prop = node.property (X_("channels"))) != 0) {
1609 nchans = atoi (prop->value().c_str());
1612 if ((prop = node.property ("name")) == 0) {
1613 cerr << "no name for this region\n";
1617 // Multiple midi channels? that's just crazy talk
1618 assert(nchans == 1);
1620 if ((prop = node.property (X_("source-0"))) == 0) {
1621 if ((prop = node.property ("source")) == 0) {
1622 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1623 return boost::shared_ptr<MidiRegion>();
1627 PBD::ID s_id (prop->value());
1629 if ((source = source_by_id (s_id)) == 0) {
1630 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1631 return boost::shared_ptr<MidiRegion>();
1634 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1636 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1637 return boost::shared_ptr<MidiRegion>();
1640 sources.push_back (ms);
1643 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1644 /* a final detail: this is the one and only place that we know how long missing files are */
1646 if (region->whole_file()) {
1647 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1648 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1650 sfp->set_length (region->length());
1658 catch (failed_constructor& err) {
1659 return boost::shared_ptr<MidiRegion>();
1664 Session::get_sources_as_xml ()
1667 XMLNode* node = new XMLNode (X_("Sources"));
1668 Glib::Mutex::Lock lm (source_lock);
1670 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1671 node->add_child_nocopy (i->second->get_state());
1678 Session::path_from_region_name (DataType type, string name, string identifier)
1680 char buf[PATH_MAX+1];
1682 SessionDirectory sdir(get_best_session_directory_for_new_source());
1683 sys::path source_dir = ((type == DataType::AUDIO)
1684 ? sdir.sound_path() : sdir.midi_path());
1686 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1688 for (n = 0; n < 999999; ++n) {
1689 if (identifier.length()) {
1690 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1691 identifier.c_str(), n, ext.c_str());
1693 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1697 sys::path source_path = source_dir / buf;
1699 if (!sys::exists (source_path)) {
1700 return source_path.to_string();
1704 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1713 Session::load_sources (const XMLNode& node)
1716 XMLNodeConstIterator niter;
1717 boost::shared_ptr<Source> source;
1719 nlist = node.children();
1723 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1725 if ((source = XMLSourceFactory (**niter)) == 0) {
1726 error << _("Session: cannot create Source from XML description.") << endmsg;
1728 } catch (MissingSource& err) {
1729 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1730 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1737 boost::shared_ptr<Source>
1738 Session::XMLSourceFactory (const XMLNode& node)
1740 if (node.name() != "Source") {
1741 return boost::shared_ptr<Source>();
1745 /* note: do peak building in another thread when loading session state */
1746 return SourceFactory::create (*this, node, true);
1749 catch (failed_constructor& err) {
1750 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1751 return boost::shared_ptr<Source>();
1756 Session::save_template (string template_name)
1760 if (_state_of_the_state & CannotSave) {
1764 sys::path user_template_dir(user_template_directory());
1768 sys::create_directories (user_template_dir);
1770 catch(sys::filesystem_error& ex)
1772 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1773 user_template_dir.to_string(), ex.what()) << endmsg;
1777 tree.set_root (&get_template());
1779 sys::path template_file_path(user_template_dir);
1780 template_file_path /= template_name + template_suffix;
1782 if (sys::exists (template_file_path))
1784 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1785 template_file_path.to_string()) << endmsg;
1789 if (!tree.write (template_file_path.to_string())) {
1790 error << _("mix template not saved") << endmsg;
1798 Session::rename_template (string old_name, string new_name)
1800 sys::path old_path (user_template_directory());
1801 old_path /= old_name + template_suffix;
1803 sys::path new_path(user_template_directory());
1804 new_path /= new_name + template_suffix;
1806 if (sys::exists (new_path)) {
1807 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1808 new_path.to_string()) << endmsg;
1813 sys::rename (old_path, new_path);
1821 Session::delete_template (string name)
1823 sys::path path = user_template_directory();
1824 path /= name + template_suffix;
1835 Session::refresh_disk_space ()
1838 struct statfs statfsbuf;
1839 vector<space_and_path>::iterator i;
1840 Glib::Mutex::Lock lm (space_lock);
1843 /* get freespace on every FS that is part of the session path */
1845 _total_free_4k_blocks = 0;
1847 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1848 statfs ((*i).path.c_str(), &statfsbuf);
1850 scale = statfsbuf.f_bsize/4096.0;
1852 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1853 _total_free_4k_blocks += (*i).blocks;
1859 Session::get_best_session_directory_for_new_source ()
1861 vector<space_and_path>::iterator i;
1862 string result = _session_dir->root_path().to_string();
1864 /* handle common case without system calls */
1866 if (session_dirs.size() == 1) {
1870 /* OK, here's the algorithm we're following here:
1872 We want to select which directory to use for
1873 the next file source to be created. Ideally,
1874 we'd like to use a round-robin process so as to
1875 get maximum performance benefits from splitting
1876 the files across multiple disks.
1878 However, in situations without much diskspace, an
1879 RR approach may end up filling up a filesystem
1880 with new files while others still have space.
1881 Its therefore important to pay some attention to
1882 the freespace in the filesystem holding each
1883 directory as well. However, if we did that by
1884 itself, we'd keep creating new files in the file
1885 system with the most space until it was as full
1886 as all others, thus negating any performance
1887 benefits of this RAID-1 like approach.
1889 So, we use a user-configurable space threshold. If
1890 there are at least 2 filesystems with more than this
1891 much space available, we use RR selection between them.
1892 If not, then we pick the filesystem with the most space.
1894 This gets a good balance between the two
1898 refresh_disk_space ();
1900 int free_enough = 0;
1902 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1903 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1908 if (free_enough >= 2) {
1909 /* use RR selection process, ensuring that the one
1913 i = last_rr_session_dir;
1916 if (++i == session_dirs.end()) {
1917 i = session_dirs.begin();
1920 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1921 if (create_session_directory ((*i).path)) {
1923 last_rr_session_dir = i;
1928 } while (i != last_rr_session_dir);
1932 /* pick FS with the most freespace (and that
1933 seems to actually work ...)
1936 vector<space_and_path> sorted;
1937 space_and_path_ascending_cmp cmp;
1939 sorted = session_dirs;
1940 sort (sorted.begin(), sorted.end(), cmp);
1942 for (i = sorted.begin(); i != sorted.end(); ++i) {
1943 if (create_session_directory ((*i).path)) {
1945 last_rr_session_dir = i;
1955 Session::load_playlists (const XMLNode& node)
1958 XMLNodeConstIterator niter;
1959 boost::shared_ptr<Playlist> playlist;
1961 nlist = node.children();
1965 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1967 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1968 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1976 Session::load_unused_playlists (const XMLNode& node)
1979 XMLNodeConstIterator niter;
1980 boost::shared_ptr<Playlist> playlist;
1982 nlist = node.children();
1986 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1988 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1989 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1993 // now manually untrack it
1995 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
2001 boost::shared_ptr<Playlist>
2002 Session::XMLPlaylistFactory (const XMLNode& node)
2005 return PlaylistFactory::create (*this, node);
2008 catch (failed_constructor& err) {
2009 return boost::shared_ptr<Playlist>();
2014 Session::load_named_selections (const XMLNode& node)
2017 XMLNodeConstIterator niter;
2020 nlist = node.children();
2024 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2026 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2027 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2035 Session::XMLNamedSelectionFactory (const XMLNode& node)
2038 return new NamedSelection (*this, node);
2041 catch (failed_constructor& err) {
2047 Session::automation_dir () const
2049 return Glib::build_filename (_path, "automation");
2053 Session::analysis_dir () const
2055 return Glib::build_filename (_path, "analysis");
2059 Session::load_bundles (XMLNode const & node)
2061 XMLNodeList nlist = node.children();
2062 XMLNodeConstIterator niter;
2066 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2067 if ((*niter)->name() == "InputBundle") {
2068 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2069 } else if ((*niter)->name() == "OutputBundle") {
2070 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2072 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2081 Session::load_route_groups (const XMLNode& node, int version)
2083 XMLNodeList nlist = node.children();
2084 XMLNodeConstIterator niter;
2088 if (version >= 3000) {
2090 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2091 if ((*niter)->name() == "RouteGroup") {
2092 RouteGroup* rg = new RouteGroup (*this, "");
2093 add_route_group (rg);
2094 rg->set_state (**niter, version);
2098 } else if (version < 3000) {
2100 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2101 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2102 RouteGroup* rg = new RouteGroup (*this, "");
2103 add_route_group (rg);
2104 rg->set_state (**niter, version);
2113 Session::auto_save()
2115 save_state (_current_snapshot_name);
2119 state_file_filter (const string &str, void */*arg*/)
2121 return (str.length() > strlen(statefile_suffix) &&
2122 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2126 bool operator()(const string* a, const string* b) {
2132 remove_end(string* state)
2134 string statename(*state);
2136 string::size_type start,end;
2137 if ((start = statename.find_last_of ('/')) != string::npos) {
2138 statename = statename.substr (start+1);
2141 if ((end = statename.rfind(".ardour")) == string::npos) {
2142 end = statename.length();
2145 return new string(statename.substr (0, end));
2149 Session::possible_states (string path)
2151 PathScanner scanner;
2152 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2154 transform(states->begin(), states->end(), states->begin(), remove_end);
2157 sort (states->begin(), states->end(), cmp);
2163 Session::possible_states () const
2165 return possible_states(_path);
2169 Session::add_route_group (RouteGroup* g)
2171 _route_groups.push_back (g);
2172 route_group_added (g); /* EMIT SIGNAL */
2177 Session::remove_route_group (RouteGroup& rg)
2179 list<RouteGroup*>::iterator i;
2181 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2182 (*i)->apply (&Route::drop_route_group, this);
2183 _route_groups.erase (i);
2184 route_group_removed (); /* EMIT SIGNAL */
2192 Session::route_group_by_name (string name)
2194 list<RouteGroup *>::iterator i;
2196 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2197 if ((*i)->name() == name) {
2205 Session::begin_reversible_command(const string& name)
2207 UndoTransaction* trans = new UndoTransaction();
2208 trans->set_name(name);
2210 if (!_current_trans.empty()) {
2211 _current_trans.top()->add_command (trans);
2213 _current_trans.push(trans);
2218 Session::commit_reversible_command(Command *cmd)
2220 assert(!_current_trans.empty());
2224 _current_trans.top()->add_command(cmd);
2227 if (_current_trans.top()->empty()) {
2228 _current_trans.pop();
2232 gettimeofday(&now, 0);
2233 _current_trans.top()->set_timestamp(now);
2235 _history.add(_current_trans.top());
2236 _current_trans.pop();
2239 Session::GlobalRouteBooleanState
2240 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2242 GlobalRouteBooleanState s;
2243 boost::shared_ptr<RouteList> r = routes.reader ();
2245 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2246 if (!(*i)->is_hidden()) {
2247 RouteBooleanState v;
2250 Route* r = (*i).get();
2251 v.second = (r->*method)();
2260 Session::GlobalRouteMeterState
2261 Session::get_global_route_metering ()
2263 GlobalRouteMeterState s;
2264 boost::shared_ptr<RouteList> r = routes.reader ();
2266 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2267 if (!(*i)->is_hidden()) {
2271 v.second = (*i)->meter_point();
2281 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2283 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2285 boost::shared_ptr<Route> r = (i->first.lock());
2288 r->set_meter_point (i->second, arg);
2294 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2296 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2298 boost::shared_ptr<Route> r = (i->first.lock());
2301 Route* rp = r.get();
2302 (rp->*method) (i->second, arg);
2308 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2310 set_global_route_boolean (s, &Route::set_mute, src);
2314 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2316 set_global_route_boolean (s, &Route::set_solo, src);
2320 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2322 set_global_route_boolean (s, &Route::set_record_enable, src);
2326 accept_all_non_peak_files (const string& path, void */*arg*/)
2328 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2332 accept_all_state_files (const string& path, void */*arg*/)
2334 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2338 Session::find_all_sources (string path, set<string>& result)
2343 if (!tree.read (path)) {
2347 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2352 XMLNodeConstIterator niter;
2354 nlist = node->children();
2358 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2362 if ((prop = (*niter)->property (X_("type"))) == 0) {
2366 DataType type (prop->value());
2368 if ((prop = (*niter)->property (X_("name"))) == 0) {
2372 if (prop->value()[0] == '/') {
2373 /* external file, ignore */
2377 Glib::ustring found_path;
2381 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2382 result.insert (found_path);
2390 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2392 PathScanner scanner;
2393 vector<string*>* state_files;
2395 string this_snapshot_path;
2401 if (ripped[ripped.length()-1] == '/') {
2402 ripped = ripped.substr (0, ripped.length() - 1);
2405 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2407 if (state_files == 0) {
2412 this_snapshot_path = _path;
2413 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2414 this_snapshot_path += statefile_suffix;
2416 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2418 if (exclude_this_snapshot && **i == this_snapshot_path) {
2422 if (find_all_sources (**i, result) < 0) {
2430 struct RegionCounter {
2431 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2432 AudioSourceList::iterator iter;
2433 boost::shared_ptr<Region> region;
2436 RegionCounter() : count (0) {}
2440 Session::cleanup_sources (Session::cleanup_report& rep)
2442 // FIXME: needs adaptation to midi
2444 vector<boost::shared_ptr<Source> > dead_sources;
2445 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2446 PathScanner scanner;
2448 vector<space_and_path>::iterator i;
2449 vector<space_and_path>::iterator nexti;
2450 vector<string*>* soundfiles;
2451 vector<string> unused;
2452 set<string> all_sources;
2457 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2460 /* step 1: consider deleting all unused playlists */
2462 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2465 status = AskAboutPlaylistDeletion (*x);
2474 playlists_tbd.push_back (*x);
2478 /* leave it alone */
2483 /* now delete any that were marked for deletion */
2485 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2486 (*x)->drop_references ();
2489 playlists_tbd.clear ();
2491 /* step 2: find all un-used sources */
2496 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2498 SourceMap::iterator tmp;
2503 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2507 if (!i->second->used() && i->second->length(i->second->timeline_position()) > 0) {
2508 dead_sources.push_back (i->second);
2509 i->second->GoingAway();
2515 /* build a list of all the possible sound directories for the session */
2517 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2522 SessionDirectory sdir ((*i).path);
2523 sound_path += sdir.sound_path().to_string();
2525 if (nexti != session_dirs.end()) {
2532 /* now do the same thing for the files that ended up in the sounds dir(s)
2533 but are not referenced as sources in any snapshot.
2536 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2538 if (soundfiles == 0) {
2542 /* find all sources, but don't use this snapshot because the
2543 state file on disk still references sources we may have already
2547 find_all_sources_across_snapshots (all_sources, true);
2549 /* add our current source list
2552 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2553 boost::shared_ptr<FileSource> fs;
2555 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2556 all_sources.insert (fs->path());
2560 char tmppath1[PATH_MAX+1];
2561 char tmppath2[PATH_MAX+1];
2563 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2568 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2570 realpath(spath.c_str(), tmppath1);
2571 realpath((*i).c_str(), tmppath2);
2573 if (strcmp(tmppath1, tmppath2) == 0) {
2580 unused.push_back (spath);
2584 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2586 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2587 struct stat statbuf;
2589 rep.paths.push_back (*x);
2590 if (stat ((*x).c_str(), &statbuf) == 0) {
2591 rep.space += statbuf.st_size;
2596 /* don't move the file across filesystems, just
2597 stick it in the `dead_sound_dir_name' directory
2598 on whichever filesystem it was already on.
2601 if ((*x).find ("/sounds/") != string::npos) {
2603 /* old school, go up 1 level */
2605 newpath = Glib::path_get_dirname (*x); // "sounds"
2606 newpath = Glib::path_get_dirname (newpath); // "session-name"
2610 /* new school, go up 4 levels */
2612 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2613 newpath = Glib::path_get_dirname (newpath); // "session-name"
2614 newpath = Glib::path_get_dirname (newpath); // "interchange"
2615 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2619 newpath += dead_sound_dir_name;
2621 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2622 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2627 newpath += Glib::path_get_basename ((*x));
2629 if (access (newpath.c_str(), F_OK) == 0) {
2631 /* the new path already exists, try versioning */
2633 char buf[PATH_MAX+1];
2637 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2640 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2641 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2645 if (version == 999) {
2646 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2650 newpath = newpath_v;
2655 /* it doesn't exist, or we can't read it or something */
2659 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2660 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2661 (*x), newpath, strerror (errno))
2666 /* see if there an easy to find peakfile for this file, and remove it.
2669 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2670 peakpath += peakfile_suffix;
2672 if (access (peakpath.c_str(), W_OK) == 0) {
2673 if (::unlink (peakpath.c_str()) != 0) {
2674 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2675 peakpath, _path, strerror (errno))
2677 /* try to back out */
2678 rename (newpath.c_str(), _path.c_str());
2686 /* dump the history list */
2690 /* save state so we don't end up a session file
2691 referring to non-existent sources.
2697 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2703 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2705 // FIXME: needs adaptation for MIDI
2707 vector<space_and_path>::iterator i;
2708 string dead_sound_dir;
2709 struct dirent* dentry;
2710 struct stat statbuf;
2716 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2718 dead_sound_dir = (*i).path;
2719 dead_sound_dir += dead_sound_dir_name;
2721 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2725 while ((dentry = readdir (dead)) != 0) {
2727 /* avoid '.' and '..' */
2729 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2730 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2736 fullpath = dead_sound_dir;
2738 fullpath += dentry->d_name;
2740 if (stat (fullpath.c_str(), &statbuf)) {
2744 if (!S_ISREG (statbuf.st_mode)) {
2748 if (unlink (fullpath.c_str())) {
2749 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2750 fullpath, strerror (errno))
2754 rep.paths.push_back (dentry->d_name);
2755 rep.space += statbuf.st_size;
2766 Session::set_dirty ()
2768 bool was_dirty = dirty();
2770 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2774 DirtyChanged(); /* EMIT SIGNAL */
2780 Session::set_clean ()
2782 bool was_dirty = dirty();
2784 _state_of_the_state = Clean;
2788 DirtyChanged(); /* EMIT SIGNAL */
2793 Session::set_deletion_in_progress ()
2795 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2799 Session::clear_deletion_in_progress ()
2801 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2805 Session::add_controllable (boost::shared_ptr<Controllable> c)
2807 /* this adds a controllable to the list managed by the Session.
2808 this is a subset of those managed by the Controllable class
2809 itself, and represents the only ones whose state will be saved
2810 as part of the session.
2813 Glib::Mutex::Lock lm (controllables_lock);
2814 controllables.insert (c);
2817 struct null_deleter { void operator()(void const *) const {} };
2820 Session::remove_controllable (Controllable* c)
2822 if (_state_of_the_state | Deletion) {
2826 Glib::Mutex::Lock lm (controllables_lock);
2828 Controllables::iterator x = controllables.find(
2829 boost::shared_ptr<Controllable>(c, null_deleter()));
2831 if (x != controllables.end()) {
2832 controllables.erase (x);
2836 boost::shared_ptr<Controllable>
2837 Session::controllable_by_id (const PBD::ID& id)
2839 Glib::Mutex::Lock lm (controllables_lock);
2841 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2842 if ((*i)->id() == id) {
2847 return boost::shared_ptr<Controllable>();
2851 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2854 Stateful::add_instant_xml (node, _path);
2857 if (write_to_config) {
2858 Config->add_instant_xml (node);
2863 Session::instant_xml (const string& node_name)
2865 return Stateful::instant_xml (node_name, _path);
2869 Session::save_history (string snapshot_name)
2877 if (snapshot_name.empty()) {
2878 snapshot_name = _current_snapshot_name;
2881 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2882 const string backup_filename = history_filename + backup_suffix;
2883 const sys::path xml_path = _session_dir->root_path() / history_filename;
2884 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2886 if (sys::exists (xml_path)) {
2889 sys::rename (xml_path, backup_path);
2891 catch (const sys::filesystem_error& err)
2893 error << _("could not backup old history file, current history not saved") << endmsg;
2898 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2902 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2904 if (!tree.write (xml_path.to_string()))
2906 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2910 sys::remove (xml_path);
2911 sys::rename (backup_path, xml_path);
2913 catch (const sys::filesystem_error& err)
2915 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2916 backup_path.to_string(), err.what()) << endmsg;
2926 Session::restore_history (string snapshot_name)
2930 if (snapshot_name.empty()) {
2931 snapshot_name = _current_snapshot_name;
2934 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
2935 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2937 info << "Loading history from " << xml_path.to_string() << endmsg;
2939 if (!sys::exists (xml_path)) {
2940 info << string_compose (_("%1: no history file \"%2\" for this session."),
2941 _name, xml_path.to_string()) << endmsg;
2945 if (!tree.read (xml_path.to_string())) {
2946 error << string_compose (_("Could not understand session history file \"%1\""),
2947 xml_path.to_string()) << endmsg;
2954 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2957 UndoTransaction* ut = new UndoTransaction ();
2960 ut->set_name(t->property("name")->value());
2961 stringstream ss(t->property("tv-sec")->value());
2963 ss.str(t->property("tv-usec")->value());
2965 ut->set_timestamp(tv);
2967 for (XMLNodeConstIterator child_it = t->children().begin();
2968 child_it != t->children().end(); child_it++)
2970 XMLNode *n = *child_it;
2973 if (n->name() == "MementoCommand" ||
2974 n->name() == "MementoUndoCommand" ||
2975 n->name() == "MementoRedoCommand") {
2977 if ((c = memento_command_factory(n))) {
2981 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2983 if ((c = global_state_command_factory (*n))) {
2984 ut->add_command (c);
2987 } else if (n->name() == "DeltaCommand") {
2988 PBD::ID id(n->property("midi-source")->value());
2989 boost::shared_ptr<MidiSource> midi_source =
2990 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2992 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
2994 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2997 } else if (n->name() == "DiffCommand") {
2998 PBD::ID id(n->property("midi-source")->value());
2999 boost::shared_ptr<MidiSource> midi_source =
3000 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3002 ut->add_command(new MidiModel::DiffCommand(midi_source->model(), *n));
3004 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3008 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3019 Session::config_changed (std::string p, bool ours)
3025 if (p == "seamless-loop") {
3027 } else if (p == "rf-speed") {
3029 } else if (p == "auto-loop") {
3031 } else if (p == "auto-input") {
3033 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3034 /* auto-input only makes a difference if we're rolling */
3036 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3038 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3039 if ((*i)->record_enabled ()) {
3040 (*i)->monitor_input (!config.get_auto_input());
3045 } else if (p == "punch-in") {
3049 if ((location = _locations.auto_punch_location()) != 0) {
3051 if (config.get_punch_in ()) {
3052 replace_event (Event::PunchIn, location->start());
3054 remove_event (location->start(), Event::PunchIn);
3058 } else if (p == "punch-out") {
3062 if ((location = _locations.auto_punch_location()) != 0) {
3064 if (config.get_punch_out()) {
3065 replace_event (Event::PunchOut, location->end());
3067 clear_events (Event::PunchOut);
3071 } else if (p == "edit-mode") {
3073 Glib::Mutex::Lock lm (playlist_lock);
3075 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3076 (*i)->set_edit_mode (Config->get_edit_mode ());
3079 } else if (p == "use-video-sync") {
3081 waiting_for_sync_offset = config.get_use_video_sync();
3083 } else if (p == "mmc-control") {
3085 //poke_midi_thread ();
3087 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3090 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3093 } else if (p == "mmc-send-id") {
3096 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3099 } else if (p == "midi-control") {
3101 //poke_midi_thread ();
3103 } else if (p == "raid-path") {
3105 setup_raid_path (config.get_raid_path());
3107 } else if (p == "smpte-format") {
3111 } else if (p == "video-pullup") {
3115 } else if (p == "seamless-loop") {
3117 if (play_loop && transport_rolling()) {
3118 // to reset diskstreams etc
3119 request_play_loop (true);
3122 } else if (p == "rf-speed") {
3124 cumulative_rf_motion = 0;
3127 } else if (p == "click-sound") {
3129 setup_click_sounds (1);
3131 } else if (p == "click-emphasis-sound") {
3133 setup_click_sounds (-1);
3135 } else if (p == "clicking") {
3137 if (Config->get_clicking()) {
3138 if (_click_io && click_data) { // don't require emphasis data
3145 } else if (p == "send-mtc") {
3147 /* only set the internal flag if we have
3151 if (_mtc_port != 0) {
3152 session_send_mtc = Config->get_send_mtc();
3153 if (session_send_mtc) {
3154 /* mark us ready to send */
3155 next_quarter_frame_to_send = 0;
3158 session_send_mtc = false;
3161 } else if (p == "send-mmc") {
3163 /* only set the internal flag if we have
3167 if (_mmc_port != 0) {
3168 session_send_mmc = Config->get_send_mmc();
3171 session_send_mmc = false;
3174 } else if (p == "midi-feedback") {
3176 /* only set the internal flag if we have
3180 if (_mtc_port != 0) {
3181 session_midi_feedback = Config->get_midi_feedback();
3184 } else if (p == "jack-time-master") {
3186 engine().reset_timebase ();
3188 } else if (p == "native-file-header-format") {
3190 if (!first_file_header_format_reset) {
3191 reset_native_file_format ();
3194 first_file_header_format_reset = false;
3196 } else if (p == "native-file-data-format") {
3198 if (!first_file_data_format_reset) {
3199 reset_native_file_format ();
3202 first_file_data_format_reset = false;
3204 } else if (p == "slave-source") {
3205 set_slave_source (Config->get_slave_source());
3206 } else if (p == "remote-model") {
3207 set_remote_control_ids ();
3208 } else if (p == "denormal-model") {
3210 } else if (p == "history-depth") {
3211 set_history_depth (Config->get_history_depth());
3212 } else if (p == "sync-all-route-ordering") {
3213 sync_order_keys ("session");
3214 } else if (p == "initial-program-change") {
3216 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3219 buf[0] = MIDI::program; // channel zero by default
3220 buf[1] = (Config->get_initial_program_change() & 0x7f);
3222 _mmc_port->midimsg (buf, sizeof (buf), 0);
3224 } else if (p == "initial-program-change") {
3226 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3227 MIDI::byte* buf = new MIDI::byte[2];
3229 buf[0] = MIDI::program; // channel zero by default
3230 buf[1] = (Config->get_initial_program_change() & 0x7f);
3231 // deliver_midi (_mmc_port, buf, 2);
3233 } else if (p == "solo-mute-override") {
3234 // catch_up_on_solo_mute_override ();
3235 } else if (p == "listen-position") {
3236 listen_position_changed ();
3237 } else if (p == "solo-control-is-listen-control") {
3238 solo_control_mode_changed ();
3246 Session::set_history_depth (uint32_t d)
3248 _history.set_depth (d);