2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libardour-config.h"
25 #define __STDC_FORMAT_MACROS 1
33 #include <sigc++/bind.h>
35 #include <cstdio> /* snprintf(3) ... grrr */
50 #include <sys/param.h>
51 #include <sys/mount.h>
55 #include <glibmm/thread.h>
57 #include "midi++/mmc.h"
58 #include "midi++/port.h"
60 #include "pbd/error.h"
61 #include "pbd/pathscanner.h"
62 #include "pbd/pthread_utils.h"
63 #include "pbd/search_path.h"
64 #include "pbd/stacktrace.h"
66 #include "ardour/audio_diskstream.h"
67 #include "ardour/audio_track.h"
68 #include "ardour/audioengine.h"
69 #include "ardour/audiofilesource.h"
70 #include "ardour/audioplaylist.h"
71 #include "ardour/audioregion.h"
72 #include "ardour/auditioner.h"
73 #include "ardour/buffer.h"
74 #include "ardour/butler.h"
75 #include "ardour/configuration.h"
76 #include "ardour/control_protocol_manager.h"
77 #include "ardour/crossfade.h"
78 #include "ardour/cycle_timer.h"
79 #include "ardour/directory_names.h"
80 #include "ardour/filename_extensions.h"
81 #include "ardour/io_processor.h"
82 #include "ardour/location.h"
83 #include "ardour/midi_diskstream.h"
84 #include "ardour/midi_patch_manager.h"
85 #include "ardour/midi_playlist.h"
86 #include "ardour/midi_region.h"
87 #include "ardour/midi_source.h"
88 #include "ardour/midi_track.h"
89 #include "ardour/named_selection.h"
90 #include "ardour/playlist_factory.h"
91 #include "ardour/processor.h"
92 #include "ardour/region_factory.h"
93 #include "ardour/route_group.h"
94 #include "ardour/send.h"
95 #include "ardour/session.h"
96 #include "ardour/session_directory.h"
97 #include "ardour/session_metadata.h"
98 #include "ardour/session_state_utils.h"
99 #include "ardour/session_utils.h"
100 #include "ardour/silentfilesource.h"
101 #include "ardour/slave.h"
102 #include "ardour/smf_source.h"
103 #include "ardour/sndfile_helpers.h"
104 #include "ardour/sndfilesource.h"
105 #include "ardour/source_factory.h"
106 #include "ardour/template_utils.h"
107 #include "ardour/tempo.h"
108 #include "ardour/ticker.h"
109 #include "ardour/user_bundle.h"
110 #include "ardour/utils.h"
111 #include "ardour/utils.h"
112 #include "ardour/version.h"
114 #include "control_protocol/control_protocol.h"
120 using namespace ARDOUR;
124 Session::first_stage_init (string fullpath, string snapshot_name)
126 if (fullpath.length() == 0) {
128 throw failed_constructor();
131 char buf[PATH_MAX+1];
132 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
133 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
135 throw failed_constructor();
140 if (_path[_path.length()-1] != '/') {
144 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
145 cerr << "Session non-writable based on " << _path << endl;
148 cerr << "Session writable based on " << _path << endl;
152 /* these two are just provisional settings. set_state()
153 will likely override them.
156 _name = _current_snapshot_name = snapshot_name;
158 set_history_depth (Config->get_history_depth());
160 _current_frame_rate = _engine.frame_rate ();
161 _nominal_frame_rate = _current_frame_rate;
162 _base_frame_rate = _current_frame_rate;
164 _tempo_map = new TempoMap (_current_frame_rate);
165 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
168 _non_soloed_outs_muted = false;
170 g_atomic_int_set (&processing_prohibited, 0);
171 _transport_speed = 0;
172 _last_transport_speed = 0;
173 _target_transport_speed = 0;
174 auto_play_legal = false;
175 transport_sub_state = 0;
176 _transport_frame = 0;
177 _requested_return_frame = -1;
178 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
179 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
180 g_atomic_int_set (&_record_status, Disabled);
181 loop_changing = false;
184 _last_roll_location = 0;
185 _last_record_location = 0;
186 pending_locate_frame = 0;
187 pending_locate_roll = false;
188 pending_locate_flush = false;
189 state_was_pending = false;
191 outbound_mtc_timecode_frame = 0;
192 next_quarter_frame_to_send = -1;
193 current_block_size = 0;
194 solo_update_disabled = false;
195 _have_captured = false;
196 _worst_output_latency = 0;
197 _worst_input_latency = 0;
198 _worst_track_latency = 0;
199 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
200 _was_seamless = Config->get_seamless_loop ();
202 session_send_mmc = false;
203 session_send_mtc = false;
204 g_atomic_int_set (&_playback_load, 100);
205 g_atomic_int_set (&_capture_load, 100);
206 g_atomic_int_set (&_playback_load_min, 100);
207 g_atomic_int_set (&_capture_load_min, 100);
210 _exporting_realtime = false;
211 _gain_automation_buffer = 0;
212 _pan_automation_buffer = 0;
214 pending_abort = false;
215 destructive_index = 0;
216 first_file_data_format_reset = true;
217 first_file_header_format_reset = true;
218 post_export_sync = false;
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;
248 last_timecode_when = 0;
249 _timecode_offset = 0;
250 _timecode_offset_negative = true;
251 last_timecode_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 (_butler->start_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"));
873 config.set_variables (node);
884 Session::get_template()
886 /* if we don't disable rec-enable, diskstreams
887 will believe they need to store their capture
888 sources in their state node.
891 disable_record (false);
897 Session::state(bool full_state)
899 XMLNode* node = new XMLNode("Session");
902 // store libardour version, just in case
904 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
905 node->add_property("version", string(buf));
907 /* store configuration settings */
911 node->add_property ("name", _name);
912 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
913 node->add_property ("sample-rate", buf);
915 if (session_dirs.size() > 1) {
919 vector<space_and_path>::iterator i = session_dirs.begin();
920 vector<space_and_path>::iterator next;
922 ++i; /* skip the first one */
926 while (i != session_dirs.end()) {
930 if (next != session_dirs.end()) {
940 child = node->add_child ("Path");
941 child->add_content (p);
945 /* save the ID counter */
947 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
948 node->add_property ("id-counter", buf);
950 /* various options */
952 node->add_child_nocopy (config.get_variables ());
954 node->add_child_nocopy (_metadata->get_state());
956 child = node->add_child ("Sources");
959 Glib::Mutex::Lock sl (source_lock);
961 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
963 /* Don't save information about non-destructive file sources that are empty */
964 /* FIXME: MIDI breaks if this is made FileSource like it should be... */
966 boost::shared_ptr<AudioFileSource> fs;
967 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
968 if (!fs->destructive()) {
969 if (fs->length(fs->timeline_position()) == 0) {
975 child->add_child_nocopy (siter->second->get_state());
979 child = node->add_child ("Regions");
982 Glib::Mutex::Lock rl (region_lock);
984 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
986 /* only store regions not attached to playlists */
988 if (i->second->playlist() == 0) {
989 child->add_child_nocopy (i->second->state (true));
994 child = node->add_child ("DiskStreams");
997 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
998 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
999 if (!(*i)->hidden()) {
1000 child->add_child_nocopy ((*i)->get_state());
1006 node->add_child_nocopy (_locations.get_state());
1008 // for a template, just create a new Locations, populate it
1009 // with the default start and end, and get the state for that.
1011 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1012 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1015 end->set_end(compute_initial_length());
1017 node->add_child_nocopy (loc.get_state());
1020 child = node->add_child ("Bundles");
1022 boost::shared_ptr<BundleList> bundles = _bundles.reader ();
1023 for (BundleList::iterator i = bundles->begin(); i != bundles->end(); ++i) {
1024 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1026 child->add_child_nocopy (b->get_state());
1031 child = node->add_child ("Routes");
1033 boost::shared_ptr<RouteList> r = routes.reader ();
1035 RoutePublicOrderSorter cmp;
1036 RouteList public_order (*r);
1037 public_order.sort (cmp);
1039 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1040 if (!(*i)->is_hidden()) {
1042 child->add_child_nocopy ((*i)->get_state());
1044 child->add_child_nocopy ((*i)->get_template());
1051 child = node->add_child ("RouteGroups");
1052 for (list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
1053 child->add_child_nocopy ((*i)->get_state());
1056 child = node->add_child ("Playlists");
1057 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1058 if (!(*i)->hidden()) {
1059 if (!(*i)->empty()) {
1061 child->add_child_nocopy ((*i)->get_state());
1063 child->add_child_nocopy ((*i)->get_template());
1069 child = node->add_child ("UnusedPlaylists");
1070 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1071 if (!(*i)->hidden()) {
1072 if (!(*i)->empty()) {
1074 child->add_child_nocopy ((*i)->get_state());
1076 child->add_child_nocopy ((*i)->get_template());
1084 child = node->add_child ("Click");
1085 child->add_child_nocopy (_click_io->state (full_state));
1089 child = node->add_child ("NamedSelections");
1090 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1092 child->add_child_nocopy ((*i)->get_state());
1097 node->add_child_nocopy (_tempo_map->get_state());
1099 node->add_child_nocopy (get_control_protocol_state());
1102 node->add_child_copy (*_extra_xml);
1109 Session::get_control_protocol_state ()
1111 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1112 return cpm.get_state();
1116 Session::set_state (const XMLNode& node, int version)
1120 const XMLProperty* prop;
1123 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1125 if (node.name() != X_("Session")){
1126 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1130 if ((prop = node.property ("version")) != 0) {
1131 version = atoi (prop->value ()) * 1000;
1134 if ((prop = node.property ("name")) != 0) {
1135 _name = prop->value ();
1138 if ((prop = node.property (X_("sample-rate"))) != 0) {
1140 _nominal_frame_rate = atoi (prop->value());
1142 if (_nominal_frame_rate != _current_frame_rate) {
1143 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1149 setup_raid_path(_session_dir->root_path().to_string());
1151 if ((prop = node.property (X_("id-counter"))) != 0) {
1153 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1154 ID::init_counter (x);
1156 /* old sessions used a timebased counter, so fake
1157 the startup ID counter based on a standard
1162 ID::init_counter (now);
1166 IO::disable_connecting ();
1168 /* Object loading order:
1173 MIDI Control // relies on data from Options/Config
1187 if ((child = find_named_node (node, "Extra")) != 0) {
1188 _extra_xml = new XMLNode (*child);
1191 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1192 load_options (*child);
1193 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1194 load_options (*child);
1196 error << _("Session: XML state has no options section") << endmsg;
1199 if (use_config_midi_ports ()) {
1202 if (version >= 3000) {
1203 if ((child = find_named_node (node, "Metadata")) == 0) {
1204 warning << _("Session: XML state has no metadata section") << endmsg;
1205 } else if (_metadata->set_state (*child, version)) {
1210 if ((child = find_named_node (node, "Locations")) == 0) {
1211 error << _("Session: XML state has no locations section") << endmsg;
1213 } else if (_locations.set_state (*child, version)) {
1219 if ((location = _locations.auto_loop_location()) != 0) {
1220 set_auto_loop_location (location);
1223 if ((location = _locations.auto_punch_location()) != 0) {
1224 set_auto_punch_location (location);
1227 if ((location = _locations.end_location()) == 0) {
1228 _locations.add (end_location);
1230 delete end_location;
1231 end_location = location;
1234 if ((location = _locations.start_location()) == 0) {
1235 _locations.add (start_location);
1237 delete start_location;
1238 start_location = location;
1241 AudioFileSource::set_header_position_offset (start_location->start());
1243 if ((child = find_named_node (node, "Sources")) == 0) {
1244 error << _("Session: XML state has no sources section") << endmsg;
1246 } else if (load_sources (*child)) {
1250 if ((child = find_named_node (node, "Regions")) == 0) {
1251 error << _("Session: XML state has no Regions section") << endmsg;
1253 } else if (load_regions (*child)) {
1257 if ((child = find_named_node (node, "Playlists")) == 0) {
1258 error << _("Session: XML state has no playlists section") << endmsg;
1260 } else if (load_playlists (*child)) {
1264 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1266 } else if (load_unused_playlists (*child)) {
1270 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1271 if (load_named_selections (*child)) {
1276 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1277 error << _("Session: XML state has no diskstreams section") << endmsg;
1279 } else if (load_diskstreams (*child)) {
1283 if (version >= 3000) {
1284 if ((child = find_named_node (node, "Bundles")) == 0) {
1285 warning << _("Session: XML state has no bundles section") << endmsg;
1288 /* We can't load Bundles yet as they need to be able
1289 to convert from port names to Port objects, which can't happen until
1291 _bundle_xml_node = new XMLNode (*child);
1295 if (version >= 3000) {
1297 if ((child = find_named_node (node, "RouteGroups")) == 0) {
1298 error << _("Session: XML state has no route groups section") << endmsg;
1300 } else if (load_route_groups (*child, version)) {
1304 } else if (version < 3000) {
1306 if ((child = find_named_node (node, "EditGroups")) == 0) {
1307 error << _("Session: XML state has no edit groups section") << endmsg;
1309 } else if (load_route_groups (*child, version)) {
1313 if ((child = find_named_node (node, "MixGroups")) == 0) {
1314 error << _("Session: XML state has no mix groups section") << endmsg;
1316 } else if (load_route_groups (*child, version)) {
1321 if ((child = find_named_node (node, "TempoMap")) == 0) {
1322 error << _("Session: XML state has no Tempo Map section") << endmsg;
1324 } else if (_tempo_map->set_state (*child, version)) {
1328 if ((child = find_named_node (node, "Routes")) == 0) {
1329 error << _("Session: XML state has no routes section") << endmsg;
1331 } else if (load_routes (*child, version)) {
1335 if ((child = find_named_node (node, "Click")) == 0) {
1336 warning << _("Session: XML state has no click section") << endmsg;
1337 } else if (_click_io) {
1338 _click_io->set_state (*child, version);
1341 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1342 ControlProtocolManager::instance().set_protocol_states (*child);
1345 /* here beginneth the second phase ... */
1347 StateReady (); /* EMIT SIGNAL */
1356 Session::load_routes (const XMLNode& node, int version)
1359 XMLNodeConstIterator niter;
1360 RouteList new_routes;
1362 nlist = node.children();
1366 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1368 boost::shared_ptr<Route> route (XMLRouteFactory (**niter, version));
1371 error << _("Session: cannot create Route from XML description.") << endmsg;
1375 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1377 new_routes.push_back (route);
1380 add_routes (new_routes, false);
1385 boost::shared_ptr<Route>
1386 Session::XMLRouteFactory (const XMLNode& node, int version)
1388 if (node.name() != "Route") {
1389 return boost::shared_ptr<Route> ((Route*) 0);
1392 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1394 DataType type = DataType::AUDIO;
1395 const XMLProperty* prop = node.property("default-type");
1398 type = DataType(prop->value());
1401 assert(type != DataType::NIL);
1403 if (has_diskstream) {
1404 if (type == DataType::AUDIO) {
1405 boost::shared_ptr<Route> ret (new AudioTrack (*this, node, version));
1408 boost::shared_ptr<Route> ret (new MidiTrack (*this, node, version));
1412 boost::shared_ptr<Route> ret (new Route (*this, node));
1418 Session::load_regions (const XMLNode& node)
1421 XMLNodeConstIterator niter;
1422 boost::shared_ptr<Region> region;
1424 nlist = node.children();
1428 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1429 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1430 error << _("Session: cannot create Region from XML description.");
1431 const XMLProperty *name = (**niter).property("name");
1434 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1444 boost::shared_ptr<Region>
1445 Session::XMLRegionFactory (const XMLNode& node, bool full)
1447 const XMLProperty* type = node.property("type");
1451 if ( !type || type->value() == "audio" ) {
1453 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1455 } else if (type->value() == "midi") {
1457 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1461 } catch (failed_constructor& err) {
1462 return boost::shared_ptr<Region> ();
1465 return boost::shared_ptr<Region> ();
1468 boost::shared_ptr<AudioRegion>
1469 Session::XMLAudioRegionFactory (const XMLNode& node, bool /*full*/)
1471 const XMLProperty* prop;
1472 boost::shared_ptr<Source> source;
1473 boost::shared_ptr<AudioSource> as;
1475 SourceList master_sources;
1476 uint32_t nchans = 1;
1479 if (node.name() != X_("Region")) {
1480 return boost::shared_ptr<AudioRegion>();
1483 if ((prop = node.property (X_("channels"))) != 0) {
1484 nchans = atoi (prop->value().c_str());
1487 if ((prop = node.property ("name")) == 0) {
1488 cerr << "no name for this region\n";
1492 if ((prop = node.property (X_("source-0"))) == 0) {
1493 if ((prop = node.property ("source")) == 0) {
1494 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1495 return boost::shared_ptr<AudioRegion>();
1499 PBD::ID s_id (prop->value());
1501 if ((source = source_by_id (s_id)) == 0) {
1502 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1503 return boost::shared_ptr<AudioRegion>();
1506 as = boost::dynamic_pointer_cast<AudioSource>(source);
1508 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1509 return boost::shared_ptr<AudioRegion>();
1512 sources.push_back (as);
1514 /* pickup other channels */
1516 for (uint32_t n=1; n < nchans; ++n) {
1517 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1518 if ((prop = node.property (buf)) != 0) {
1520 PBD::ID id2 (prop->value());
1522 if ((source = source_by_id (id2)) == 0) {
1523 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1524 return boost::shared_ptr<AudioRegion>();
1527 as = boost::dynamic_pointer_cast<AudioSource>(source);
1529 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1530 return boost::shared_ptr<AudioRegion>();
1532 sources.push_back (as);
1536 for (uint32_t n = 0; n < nchans; ++n) {
1537 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1538 if ((prop = node.property (buf)) != 0) {
1540 PBD::ID id2 (prop->value());
1542 if ((source = source_by_id (id2)) == 0) {
1543 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1544 return boost::shared_ptr<AudioRegion>();
1547 as = boost::dynamic_pointer_cast<AudioSource>(source);
1549 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1550 return boost::shared_ptr<AudioRegion>();
1552 master_sources.push_back (as);
1557 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1559 /* a final detail: this is the one and only place that we know how long missing files are */
1561 if (region->whole_file()) {
1562 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1563 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1565 sfp->set_length (region->length());
1570 if (!master_sources.empty()) {
1571 if (master_sources.size() != nchans) {
1572 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1574 region->set_master_sources (master_sources);
1582 catch (failed_constructor& err) {
1583 return boost::shared_ptr<AudioRegion>();
1587 boost::shared_ptr<MidiRegion>
1588 Session::XMLMidiRegionFactory (const XMLNode& node, bool /*full*/)
1590 const XMLProperty* prop;
1591 boost::shared_ptr<Source> source;
1592 boost::shared_ptr<MidiSource> ms;
1594 uint32_t nchans = 1;
1596 if (node.name() != X_("Region")) {
1597 return boost::shared_ptr<MidiRegion>();
1600 if ((prop = node.property (X_("channels"))) != 0) {
1601 nchans = atoi (prop->value().c_str());
1604 if ((prop = node.property ("name")) == 0) {
1605 cerr << "no name for this region\n";
1609 // Multiple midi channels? that's just crazy talk
1610 assert(nchans == 1);
1612 if ((prop = node.property (X_("source-0"))) == 0) {
1613 if ((prop = node.property ("source")) == 0) {
1614 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1615 return boost::shared_ptr<MidiRegion>();
1619 PBD::ID s_id (prop->value());
1621 if ((source = source_by_id (s_id)) == 0) {
1622 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1623 return boost::shared_ptr<MidiRegion>();
1626 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1628 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1629 return boost::shared_ptr<MidiRegion>();
1632 sources.push_back (ms);
1635 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1636 /* a final detail: this is the one and only place that we know how long missing files are */
1638 if (region->whole_file()) {
1639 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1640 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1642 sfp->set_length (region->length());
1650 catch (failed_constructor& err) {
1651 return boost::shared_ptr<MidiRegion>();
1656 Session::get_sources_as_xml ()
1659 XMLNode* node = new XMLNode (X_("Sources"));
1660 Glib::Mutex::Lock lm (source_lock);
1662 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1663 node->add_child_nocopy (i->second->get_state());
1670 Session::path_from_region_name (DataType type, string name, string identifier)
1672 char buf[PATH_MAX+1];
1674 SessionDirectory sdir(get_best_session_directory_for_new_source());
1675 sys::path source_dir = ((type == DataType::AUDIO)
1676 ? sdir.sound_path() : sdir.midi_path());
1678 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1680 for (n = 0; n < 999999; ++n) {
1681 if (identifier.length()) {
1682 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1683 identifier.c_str(), n, ext.c_str());
1685 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1689 sys::path source_path = source_dir / buf;
1691 if (!sys::exists (source_path)) {
1692 return source_path.to_string();
1696 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1705 Session::load_sources (const XMLNode& node)
1708 XMLNodeConstIterator niter;
1709 boost::shared_ptr<Source> source;
1711 nlist = node.children();
1715 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1717 if ((source = XMLSourceFactory (**niter)) == 0) {
1718 error << _("Session: cannot create Source from XML description.") << endmsg;
1720 } catch (MissingSource& err) {
1721 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1722 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1729 boost::shared_ptr<Source>
1730 Session::XMLSourceFactory (const XMLNode& node)
1732 if (node.name() != "Source") {
1733 return boost::shared_ptr<Source>();
1737 /* note: do peak building in another thread when loading session state */
1738 return SourceFactory::create (*this, node, true);
1741 catch (failed_constructor& err) {
1742 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1743 return boost::shared_ptr<Source>();
1748 Session::save_template (string template_name)
1752 if (_state_of_the_state & CannotSave) {
1756 sys::path user_template_dir(user_template_directory());
1760 sys::create_directories (user_template_dir);
1762 catch(sys::filesystem_error& ex)
1764 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1765 user_template_dir.to_string(), ex.what()) << endmsg;
1769 tree.set_root (&get_template());
1771 sys::path template_file_path(user_template_dir);
1772 template_file_path /= template_name + template_suffix;
1774 if (sys::exists (template_file_path))
1776 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1777 template_file_path.to_string()) << endmsg;
1781 if (!tree.write (template_file_path.to_string())) {
1782 error << _("mix template not saved") << endmsg;
1790 Session::rename_template (string old_name, string new_name)
1792 sys::path old_path (user_template_directory());
1793 old_path /= old_name + template_suffix;
1795 sys::path new_path(user_template_directory());
1796 new_path /= new_name + template_suffix;
1798 if (sys::exists (new_path)) {
1799 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1800 new_path.to_string()) << endmsg;
1805 sys::rename (old_path, new_path);
1813 Session::delete_template (string name)
1815 sys::path path = user_template_directory();
1816 path /= name + template_suffix;
1827 Session::refresh_disk_space ()
1830 struct statfs statfsbuf;
1831 vector<space_and_path>::iterator i;
1832 Glib::Mutex::Lock lm (space_lock);
1835 /* get freespace on every FS that is part of the session path */
1837 _total_free_4k_blocks = 0;
1839 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1840 statfs ((*i).path.c_str(), &statfsbuf);
1842 scale = statfsbuf.f_bsize/4096.0;
1844 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1845 _total_free_4k_blocks += (*i).blocks;
1851 Session::get_best_session_directory_for_new_source ()
1853 vector<space_and_path>::iterator i;
1854 string result = _session_dir->root_path().to_string();
1856 /* handle common case without system calls */
1858 if (session_dirs.size() == 1) {
1862 /* OK, here's the algorithm we're following here:
1864 We want to select which directory to use for
1865 the next file source to be created. Ideally,
1866 we'd like to use a round-robin process so as to
1867 get maximum performance benefits from splitting
1868 the files across multiple disks.
1870 However, in situations without much diskspace, an
1871 RR approach may end up filling up a filesystem
1872 with new files while others still have space.
1873 Its therefore important to pay some attention to
1874 the freespace in the filesystem holding each
1875 directory as well. However, if we did that by
1876 itself, we'd keep creating new files in the file
1877 system with the most space until it was as full
1878 as all others, thus negating any performance
1879 benefits of this RAID-1 like approach.
1881 So, we use a user-configurable space threshold. If
1882 there are at least 2 filesystems with more than this
1883 much space available, we use RR selection between them.
1884 If not, then we pick the filesystem with the most space.
1886 This gets a good balance between the two
1890 refresh_disk_space ();
1892 int free_enough = 0;
1894 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1895 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1900 if (free_enough >= 2) {
1901 /* use RR selection process, ensuring that the one
1905 i = last_rr_session_dir;
1908 if (++i == session_dirs.end()) {
1909 i = session_dirs.begin();
1912 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1913 if (create_session_directory ((*i).path)) {
1915 last_rr_session_dir = i;
1920 } while (i != last_rr_session_dir);
1924 /* pick FS with the most freespace (and that
1925 seems to actually work ...)
1928 vector<space_and_path> sorted;
1929 space_and_path_ascending_cmp cmp;
1931 sorted = session_dirs;
1932 sort (sorted.begin(), sorted.end(), cmp);
1934 for (i = sorted.begin(); i != sorted.end(); ++i) {
1935 if (create_session_directory ((*i).path)) {
1937 last_rr_session_dir = i;
1947 Session::load_playlists (const XMLNode& node)
1950 XMLNodeConstIterator niter;
1951 boost::shared_ptr<Playlist> playlist;
1953 nlist = node.children();
1957 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1959 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1960 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1968 Session::load_unused_playlists (const XMLNode& node)
1971 XMLNodeConstIterator niter;
1972 boost::shared_ptr<Playlist> playlist;
1974 nlist = node.children();
1978 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1980 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1981 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1985 // now manually untrack it
1987 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1993 boost::shared_ptr<Playlist>
1994 Session::XMLPlaylistFactory (const XMLNode& node)
1997 return PlaylistFactory::create (*this, node);
2000 catch (failed_constructor& err) {
2001 return boost::shared_ptr<Playlist>();
2006 Session::load_named_selections (const XMLNode& node)
2009 XMLNodeConstIterator niter;
2012 nlist = node.children();
2016 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2018 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2019 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2027 Session::XMLNamedSelectionFactory (const XMLNode& node)
2030 return new NamedSelection (*this, node);
2033 catch (failed_constructor& err) {
2039 Session::automation_dir () const
2041 return Glib::build_filename (_path, "automation");
2045 Session::analysis_dir () const
2047 return Glib::build_filename (_path, "analysis");
2051 Session::load_bundles (XMLNode const & node)
2053 XMLNodeList nlist = node.children();
2054 XMLNodeConstIterator niter;
2058 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2059 if ((*niter)->name() == "InputBundle") {
2060 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2061 } else if ((*niter)->name() == "OutputBundle") {
2062 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2064 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2073 Session::load_route_groups (const XMLNode& node, int version)
2075 XMLNodeList nlist = node.children();
2076 XMLNodeConstIterator niter;
2080 if (version >= 3000) {
2082 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2083 if ((*niter)->name() == "RouteGroup") {
2084 RouteGroup* rg = new RouteGroup (*this, "");
2085 add_route_group (rg);
2086 rg->set_state (**niter, version);
2090 } else if (version < 3000) {
2092 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2093 if ((*niter)->name() == "EditGroup" || (*niter)->name() == "MixGroup") {
2094 RouteGroup* rg = new RouteGroup (*this, "");
2095 add_route_group (rg);
2096 rg->set_state (**niter, version);
2105 Session::auto_save()
2107 save_state (_current_snapshot_name);
2111 state_file_filter (const string &str, void */*arg*/)
2113 return (str.length() > strlen(statefile_suffix) &&
2114 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2118 bool operator()(const string* a, const string* b) {
2124 remove_end(string* state)
2126 string statename(*state);
2128 string::size_type start,end;
2129 if ((start = statename.find_last_of ('/')) != string::npos) {
2130 statename = statename.substr (start+1);
2133 if ((end = statename.rfind(".ardour")) == string::npos) {
2134 end = statename.length();
2137 return new string(statename.substr (0, end));
2141 Session::possible_states (string path)
2143 PathScanner scanner;
2144 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2146 transform(states->begin(), states->end(), states->begin(), remove_end);
2149 sort (states->begin(), states->end(), cmp);
2155 Session::possible_states () const
2157 return possible_states(_path);
2161 Session::add_route_group (RouteGroup* g)
2163 _route_groups.push_back (g);
2164 route_group_added (g); /* EMIT SIGNAL */
2169 Session::remove_route_group (RouteGroup& rg)
2171 list<RouteGroup*>::iterator i;
2173 if ((i = find (_route_groups.begin(), _route_groups.end(), &rg)) != _route_groups.end()) {
2174 (*i)->apply (&Route::drop_route_group, this);
2175 _route_groups.erase (i);
2176 route_group_removed (); /* EMIT SIGNAL */
2184 Session::route_group_by_name (string name)
2186 list<RouteGroup *>::iterator i;
2188 for (i = _route_groups.begin(); i != _route_groups.end(); ++i) {
2189 if ((*i)->name() == name) {
2197 Session::begin_reversible_command(const string& name)
2199 UndoTransaction* trans = new UndoTransaction();
2200 trans->set_name(name);
2202 if (!_current_trans.empty()) {
2203 _current_trans.top()->add_command (trans);
2205 _current_trans.push(trans);
2210 Session::commit_reversible_command(Command *cmd)
2212 assert(!_current_trans.empty());
2216 _current_trans.top()->add_command(cmd);
2219 if (_current_trans.top()->empty()) {
2220 _current_trans.pop();
2224 gettimeofday(&now, 0);
2225 _current_trans.top()->set_timestamp(now);
2227 _history.add(_current_trans.top());
2228 _current_trans.pop();
2231 Session::GlobalRouteBooleanState
2232 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2234 GlobalRouteBooleanState s;
2235 boost::shared_ptr<RouteList> r = routes.reader ();
2237 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2238 if (!(*i)->is_hidden()) {
2239 RouteBooleanState v;
2242 Route* r = (*i).get();
2243 v.second = (r->*method)();
2252 Session::GlobalRouteMeterState
2253 Session::get_global_route_metering ()
2255 GlobalRouteMeterState s;
2256 boost::shared_ptr<RouteList> r = routes.reader ();
2258 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2259 if (!(*i)->is_hidden()) {
2263 v.second = (*i)->meter_point();
2273 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2275 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2277 boost::shared_ptr<Route> r = (i->first.lock());
2280 r->set_meter_point (i->second, arg);
2286 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2288 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2290 boost::shared_ptr<Route> r = (i->first.lock());
2293 Route* rp = r.get();
2294 (rp->*method) (i->second, arg);
2300 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2302 set_global_route_boolean (s, &Route::set_mute, src);
2306 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2308 set_global_route_boolean (s, &Route::set_solo, src);
2312 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2314 set_global_route_boolean (s, &Route::set_record_enable, src);
2318 accept_all_non_peak_files (const string& path, void */*arg*/)
2320 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2324 accept_all_state_files (const string& path, void */*arg*/)
2326 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2330 Session::find_all_sources (string path, set<string>& result)
2335 if (!tree.read (path)) {
2339 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2344 XMLNodeConstIterator niter;
2346 nlist = node->children();
2350 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2354 if ((prop = (*niter)->property (X_("type"))) == 0) {
2358 DataType type (prop->value());
2360 if ((prop = (*niter)->property (X_("name"))) == 0) {
2364 if (prop->value()[0] == '/') {
2365 /* external file, ignore */
2369 Glib::ustring found_path;
2373 if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
2374 result.insert (found_path);
2382 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2384 PathScanner scanner;
2385 vector<string*>* state_files;
2387 string this_snapshot_path;
2393 if (ripped[ripped.length()-1] == '/') {
2394 ripped = ripped.substr (0, ripped.length() - 1);
2397 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2399 if (state_files == 0) {
2404 this_snapshot_path = _path;
2405 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2406 this_snapshot_path += statefile_suffix;
2408 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2410 if (exclude_this_snapshot && **i == this_snapshot_path) {
2414 if (find_all_sources (**i, result) < 0) {
2422 struct RegionCounter {
2423 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2424 AudioSourceList::iterator iter;
2425 boost::shared_ptr<Region> region;
2428 RegionCounter() : count (0) {}
2432 Session::cleanup_sources (CleanupReport& rep)
2434 // FIXME: needs adaptation to midi
2436 vector<boost::shared_ptr<Source> > dead_sources;
2437 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2438 PathScanner scanner;
2440 vector<space_and_path>::iterator i;
2441 vector<space_and_path>::iterator nexti;
2442 vector<string*>* soundfiles;
2443 vector<string> unused;
2444 set<string> all_sources;
2449 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2452 /* step 1: consider deleting all unused playlists */
2454 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2457 status = AskAboutPlaylistDeletion (*x);
2466 playlists_tbd.push_back (*x);
2470 /* leave it alone */
2475 /* now delete any that were marked for deletion */
2477 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2478 (*x)->drop_references ();
2481 playlists_tbd.clear ();
2483 /* step 2: find all un-used sources */
2488 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2490 SourceMap::iterator tmp;
2495 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2499 if (!source_use_count(i->second) && i->second->length(i->second->timeline_position()) > 0) {
2500 dead_sources.push_back (i->second);
2501 i->second->GoingAway();
2507 /* build a list of all the possible sound directories for the session */
2509 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2514 SessionDirectory sdir ((*i).path);
2515 sound_path += sdir.sound_path().to_string();
2517 if (nexti != session_dirs.end()) {
2524 /* now do the same thing for the files that ended up in the sounds dir(s)
2525 but are not referenced as sources in any snapshot.
2528 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2530 if (soundfiles == 0) {
2534 /* find all sources, but don't use this snapshot because the
2535 state file on disk still references sources we may have already
2539 find_all_sources_across_snapshots (all_sources, true);
2541 /* add our current source list
2544 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2545 boost::shared_ptr<FileSource> fs;
2547 if ((fs = boost::dynamic_pointer_cast<FileSource> (i->second)) != 0) {
2548 all_sources.insert (fs->path());
2552 char tmppath1[PATH_MAX+1];
2553 char tmppath2[PATH_MAX+1];
2555 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2560 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2562 realpath(spath.c_str(), tmppath1);
2563 realpath((*i).c_str(), tmppath2);
2565 if (strcmp(tmppath1, tmppath2) == 0) {
2572 unused.push_back (spath);
2576 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2578 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2579 struct stat statbuf;
2581 rep.paths.push_back (*x);
2582 if (stat ((*x).c_str(), &statbuf) == 0) {
2583 rep.space += statbuf.st_size;
2588 /* don't move the file across filesystems, just
2589 stick it in the `dead_sound_dir_name' directory
2590 on whichever filesystem it was already on.
2593 if ((*x).find ("/sounds/") != string::npos) {
2595 /* old school, go up 1 level */
2597 newpath = Glib::path_get_dirname (*x); // "sounds"
2598 newpath = Glib::path_get_dirname (newpath); // "session-name"
2602 /* new school, go up 4 levels */
2604 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2605 newpath = Glib::path_get_dirname (newpath); // "session-name"
2606 newpath = Glib::path_get_dirname (newpath); // "interchange"
2607 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2611 newpath += dead_sound_dir_name;
2613 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2614 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2619 newpath += Glib::path_get_basename ((*x));
2621 if (access (newpath.c_str(), F_OK) == 0) {
2623 /* the new path already exists, try versioning */
2625 char buf[PATH_MAX+1];
2629 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2632 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2633 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2637 if (version == 999) {
2638 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2642 newpath = newpath_v;
2647 /* it doesn't exist, or we can't read it or something */
2651 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2652 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2653 (*x), newpath, strerror (errno))
2658 /* see if there an easy to find peakfile for this file, and remove it.
2661 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2662 peakpath += peakfile_suffix;
2664 if (access (peakpath.c_str(), W_OK) == 0) {
2665 if (::unlink (peakpath.c_str()) != 0) {
2666 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2667 peakpath, _path, strerror (errno))
2669 /* try to back out */
2670 rename (newpath.c_str(), _path.c_str());
2678 /* dump the history list */
2682 /* save state so we don't end up a session file
2683 referring to non-existent sources.
2689 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2695 Session::cleanup_trash_sources (CleanupReport& rep)
2697 // FIXME: needs adaptation for MIDI
2699 vector<space_and_path>::iterator i;
2700 string dead_sound_dir;
2701 struct dirent* dentry;
2702 struct stat statbuf;
2708 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2710 dead_sound_dir = (*i).path;
2711 dead_sound_dir += dead_sound_dir_name;
2713 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2717 while ((dentry = readdir (dead)) != 0) {
2719 /* avoid '.' and '..' */
2721 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2722 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2728 fullpath = dead_sound_dir;
2730 fullpath += dentry->d_name;
2732 if (stat (fullpath.c_str(), &statbuf)) {
2736 if (!S_ISREG (statbuf.st_mode)) {
2740 if (unlink (fullpath.c_str())) {
2741 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2742 fullpath, strerror (errno))
2746 rep.paths.push_back (dentry->d_name);
2747 rep.space += statbuf.st_size;
2758 Session::set_dirty ()
2760 bool was_dirty = dirty();
2762 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2766 DirtyChanged(); /* EMIT SIGNAL */
2772 Session::set_clean ()
2774 bool was_dirty = dirty();
2776 _state_of_the_state = Clean;
2780 DirtyChanged(); /* EMIT SIGNAL */
2785 Session::set_deletion_in_progress ()
2787 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2791 Session::clear_deletion_in_progress ()
2793 _state_of_the_state = StateOfTheState (_state_of_the_state & (~Deletion));
2797 Session::add_controllable (boost::shared_ptr<Controllable> c)
2799 /* this adds a controllable to the list managed by the Session.
2800 this is a subset of those managed by the Controllable class
2801 itself, and represents the only ones whose state will be saved
2802 as part of the session.
2805 Glib::Mutex::Lock lm (controllables_lock);
2806 controllables.insert (c);
2809 struct null_deleter { void operator()(void const *) const {} };
2812 Session::remove_controllable (Controllable* c)
2814 if (_state_of_the_state | Deletion) {
2818 Glib::Mutex::Lock lm (controllables_lock);
2820 Controllables::iterator x = controllables.find(
2821 boost::shared_ptr<Controllable>(c, null_deleter()));
2823 if (x != controllables.end()) {
2824 controllables.erase (x);
2828 boost::shared_ptr<Controllable>
2829 Session::controllable_by_id (const PBD::ID& id)
2831 Glib::Mutex::Lock lm (controllables_lock);
2833 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2834 if ((*i)->id() == id) {
2839 return boost::shared_ptr<Controllable>();
2843 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2846 Stateful::add_instant_xml (node, _path);
2849 if (write_to_config) {
2850 Config->add_instant_xml (node);
2855 Session::instant_xml (const string& node_name)
2857 return Stateful::instant_xml (node_name, _path);
2861 Session::save_history (string snapshot_name)
2869 if (snapshot_name.empty()) {
2870 snapshot_name = _current_snapshot_name;
2873 const string history_filename = legalize_for_path (snapshot_name) + history_suffix;
2874 const string backup_filename = history_filename + backup_suffix;
2875 const sys::path xml_path = _session_dir->root_path() / history_filename;
2876 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2878 if (sys::exists (xml_path)) {
2881 sys::rename (xml_path, backup_path);
2883 catch (const sys::filesystem_error& err)
2885 error << _("could not backup old history file, current history not saved") << endmsg;
2890 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2894 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2896 if (!tree.write (xml_path.to_string()))
2898 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2902 sys::remove (xml_path);
2903 sys::rename (backup_path, xml_path);
2905 catch (const sys::filesystem_error& err)
2907 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2908 backup_path.to_string(), err.what()) << endmsg;
2918 Session::restore_history (string snapshot_name)
2922 if (snapshot_name.empty()) {
2923 snapshot_name = _current_snapshot_name;
2926 const string xml_filename = legalize_for_path (snapshot_name) + history_suffix;
2927 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2929 info << "Loading history from " << xml_path.to_string() << endmsg;
2931 if (!sys::exists (xml_path)) {
2932 info << string_compose (_("%1: no history file \"%2\" for this session."),
2933 _name, xml_path.to_string()) << endmsg;
2937 if (!tree.read (xml_path.to_string())) {
2938 error << string_compose (_("Could not understand session history file \"%1\""),
2939 xml_path.to_string()) << endmsg;
2946 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2949 UndoTransaction* ut = new UndoTransaction ();
2952 ut->set_name(t->property("name")->value());
2953 stringstream ss(t->property("tv-sec")->value());
2955 ss.str(t->property("tv-usec")->value());
2957 ut->set_timestamp(tv);
2959 for (XMLNodeConstIterator child_it = t->children().begin();
2960 child_it != t->children().end(); child_it++)
2962 XMLNode *n = *child_it;
2965 if (n->name() == "MementoCommand" ||
2966 n->name() == "MementoUndoCommand" ||
2967 n->name() == "MementoRedoCommand") {
2969 if ((c = memento_command_factory(n))) {
2973 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2975 if ((c = global_state_command_factory (*n))) {
2976 ut->add_command (c);
2979 } else if (n->name() == "DeltaCommand") {
2980 PBD::ID id(n->property("midi-source")->value());
2981 boost::shared_ptr<MidiSource> midi_source =
2982 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
2984 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
2986 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
2989 } else if (n->name() == "DiffCommand") {
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::DiffCommand(midi_source->model(), *n));
2996 error << _("Failed to downcast MidiSource for DeltaCommand") << endmsg;
3000 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3011 Session::config_changed (std::string p, bool ours)
3017 if (p == "seamless-loop") {
3019 } else if (p == "rf-speed") {
3021 } else if (p == "auto-loop") {
3023 } else if (p == "auto-input") {
3025 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3026 /* auto-input only makes a difference if we're rolling */
3028 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3030 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3031 if ((*i)->record_enabled ()) {
3032 (*i)->monitor_input (!config.get_auto_input());
3037 } else if (p == "punch-in") {
3041 if ((location = _locations.auto_punch_location()) != 0) {
3043 if (config.get_punch_in ()) {
3044 replace_event (Event::PunchIn, location->start());
3046 remove_event (location->start(), Event::PunchIn);
3050 } else if (p == "punch-out") {
3054 if ((location = _locations.auto_punch_location()) != 0) {
3056 if (config.get_punch_out()) {
3057 replace_event (Event::PunchOut, location->end());
3059 clear_events (Event::PunchOut);
3063 } else if (p == "edit-mode") {
3065 Glib::Mutex::Lock lm (playlist_lock);
3067 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3068 (*i)->set_edit_mode (Config->get_edit_mode ());
3071 } else if (p == "use-video-sync") {
3073 waiting_for_sync_offset = config.get_use_video_sync();
3075 } else if (p == "mmc-control") {
3077 //poke_midi_thread ();
3079 } else if (p == "mmc-device-id" || p == "mmc-receive-id") {
3082 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3085 } else if (p == "mmc-send-id") {
3088 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3091 } else if (p == "midi-control") {
3093 //poke_midi_thread ();
3095 } else if (p == "raid-path") {
3097 setup_raid_path (config.get_raid_path());
3099 } else if (p == "timecode-format") {
3103 } else if (p == "video-pullup") {
3107 } else if (p == "seamless-loop") {
3109 if (play_loop && transport_rolling()) {
3110 // to reset diskstreams etc
3111 request_play_loop (true);
3114 } else if (p == "rf-speed") {
3116 cumulative_rf_motion = 0;
3119 } else if (p == "click-sound") {
3121 setup_click_sounds (1);
3123 } else if (p == "click-emphasis-sound") {
3125 setup_click_sounds (-1);
3127 } else if (p == "clicking") {
3129 if (Config->get_clicking()) {
3130 if (_click_io && click_data) { // don't require emphasis data
3137 } else if (p == "send-mtc") {
3139 /* only set the internal flag if we have
3143 if (_mtc_port != 0) {
3144 session_send_mtc = Config->get_send_mtc();
3145 if (session_send_mtc) {
3146 /* mark us ready to send */
3147 next_quarter_frame_to_send = 0;
3150 session_send_mtc = false;
3153 } else if (p == "send-mmc") {
3155 /* only set the internal flag if we have
3159 if (_mmc_port != 0) {
3160 session_send_mmc = Config->get_send_mmc();
3163 session_send_mmc = false;
3166 } else if (p == "midi-feedback") {
3168 /* only set the internal flag if we have
3172 if (_mtc_port != 0) {
3173 session_midi_feedback = Config->get_midi_feedback();
3176 } else if (p == "jack-time-master") {
3178 engine().reset_timebase ();
3180 } else if (p == "native-file-header-format") {
3182 if (!first_file_header_format_reset) {
3183 reset_native_file_format ();
3186 first_file_header_format_reset = false;
3188 } else if (p == "native-file-data-format") {
3190 if (!first_file_data_format_reset) {
3191 reset_native_file_format ();
3194 first_file_data_format_reset = false;
3196 } else if (p == "external-sync") {
3197 if (!config.get_external_sync()) {
3198 drop_sync_source ();
3200 use_sync_source (config.get_sync_source());
3202 } else if (p == "remote-model") {
3203 set_remote_control_ids ();
3204 } else if (p == "denormal-model") {
3206 } else if (p == "history-depth") {
3207 set_history_depth (Config->get_history_depth());
3208 } else if (p == "sync-all-route-ordering") {
3209 sync_order_keys ("session");
3210 } else if (p == "initial-program-change") {
3212 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3215 buf[0] = MIDI::program; // channel zero by default
3216 buf[1] = (Config->get_initial_program_change() & 0x7f);
3218 _mmc_port->midimsg (buf, sizeof (buf), 0);
3220 } else if (p == "initial-program-change") {
3222 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3223 MIDI::byte* buf = new MIDI::byte[2];
3225 buf[0] = MIDI::program; // channel zero by default
3226 buf[1] = (Config->get_initial_program_change() & 0x7f);
3227 // deliver_midi (_mmc_port, buf, 2);
3229 } else if (p == "solo-mute-override") {
3230 // catch_up_on_solo_mute_override ();
3231 } else if (p == "listen-position") {
3232 listen_position_changed ();
3233 } else if (p == "solo-control-is-listen-control") {
3234 solo_control_mode_changed ();
3242 Session::set_history_depth (uint32_t d)
3244 _history.set_depth (d);