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.
20 #define __STDC_FORMAT_MACROS 1
28 #include <sigc++/bind.h>
30 #include <cstdio> /* snprintf(3) ... grrr */
45 #include <sys/param.h>
46 #include <sys/mount.h>
50 #include <glibmm/thread.h>
52 #include <midi++/mmc.h>
53 #include <midi++/port.h>
55 #include <pbd/error.h>
56 #include <pbd/pathscanner.h>
57 #include <pbd/pthread_utils.h>
58 #include <pbd/search_path.h>
59 #include <pbd/stacktrace.h>
61 #include <ardour/audioengine.h>
62 #include <ardour/configuration.h>
63 #include <ardour/session.h>
64 #include <ardour/session_directory.h>
65 #include <ardour/session_utils.h>
66 #include <ardour/session_state_utils.h>
67 #include <ardour/session_metadata.h>
68 #include <ardour/buffer.h>
69 #include <ardour/audio_diskstream.h>
70 #include <ardour/midi_diskstream.h>
71 #include <ardour/utils.h>
72 #include <ardour/audioplaylist.h>
73 #include <ardour/midi_playlist.h>
74 #include <ardour/smf_source.h>
75 #include <ardour/audiofilesource.h>
76 #include <ardour/silentfilesource.h>
77 #include <ardour/sndfilesource.h>
78 #include <ardour/midi_source.h>
79 #include <ardour/sndfile_helpers.h>
80 #include <ardour/auditioner.h>
81 #include <ardour/io_processor.h>
82 #include <ardour/send.h>
83 #include <ardour/processor.h>
84 #include <ardour/bundle.h>
85 #include <ardour/slave.h>
86 #include <ardour/tempo.h>
87 #include <ardour/audio_track.h>
88 #include <ardour/midi_track.h>
89 #include <ardour/cycle_timer.h>
90 #include <ardour/utils.h>
91 #include <ardour/named_selection.h>
92 #include <ardour/version.h>
93 #include <ardour/location.h>
94 #include <ardour/audioregion.h>
95 #include <ardour/midi_region.h>
96 #include <ardour/crossfade.h>
97 #include <ardour/control_protocol_manager.h>
98 #include <ardour/region_factory.h>
99 #include <ardour/source_factory.h>
100 #include <ardour/playlist_factory.h>
101 #include <ardour/filename_extensions.h>
102 #include <ardour/directory_names.h>
103 #include <ardour/template_utils.h>
105 #include <control_protocol/control_protocol.h>
111 using namespace ARDOUR;
115 Session::first_stage_init (string fullpath, string snapshot_name)
117 if (fullpath.length() == 0) {
119 throw failed_constructor();
122 char buf[PATH_MAX+1];
123 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
124 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
126 throw failed_constructor();
131 if (_path[_path.length()-1] != '/') {
135 /* these two are just provisional settings. set_state()
136 will likely override them.
139 _name = _current_snapshot_name = snapshot_name;
141 set_history_depth (Config->get_history_depth());
143 _current_frame_rate = _engine.frame_rate ();
144 _nominal_frame_rate = _current_frame_rate;
145 _base_frame_rate = _current_frame_rate;
147 _tempo_map = new TempoMap (_current_frame_rate);
148 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
152 g_atomic_int_set (&processing_prohibited, 0);
154 _transport_speed = 0;
155 _last_transport_speed = 0;
156 auto_play_legal = false;
157 transport_sub_state = 0;
158 _transport_frame = 0;
160 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
161 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
162 _end_location_is_free = true;
163 g_atomic_int_set (&_record_status, Disabled);
164 loop_changing = false;
166 _last_roll_location = 0;
167 _last_record_location = 0;
168 pending_locate_frame = 0;
169 pending_locate_roll = false;
170 pending_locate_flush = false;
171 audio_dstream_buffer_size = 0;
172 midi_dstream_buffer_size = 0;
174 state_was_pending = false;
176 outbound_mtc_smpte_frame = 0;
177 next_quarter_frame_to_send = -1;
178 current_block_size = 0;
179 solo_update_disabled = false;
180 currently_soloing = false;
181 _have_captured = false;
182 _worst_output_latency = 0;
183 _worst_input_latency = 0;
184 _worst_track_latency = 0;
185 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
188 butler_mixdown_buffer = 0;
189 butler_gain_buffer = 0;
191 session_send_mmc = false;
192 session_send_mtc = false;
193 post_transport_work = PostTransportWork (0);
194 g_atomic_int_set (&butler_should_do_transport_work, 0);
195 g_atomic_int_set (&butler_active, 0);
196 g_atomic_int_set (&_playback_load, 100);
197 g_atomic_int_set (&_capture_load, 100);
198 g_atomic_int_set (&_playback_load_min, 100);
199 g_atomic_int_set (&_capture_load_min, 100);
202 _exporting_realtime = false;
203 _gain_automation_buffer = 0;
204 _pan_automation_buffer = 0;
206 pending_abort = false;
207 destructive_index = 0;
209 first_file_data_format_reset = true;
210 first_file_header_format_reset = true;
211 butler_thread = (pthread_t) 0;
212 //midi_thread = (pthread_t) 0;
214 AudioDiskstream::allocate_working_buffers();
216 /* default short fade = 15ms */
218 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
219 SndFileSource::setup_standard_crossfades (frame_rate());
221 last_mmc_step.tv_sec = 0;
222 last_mmc_step.tv_usec = 0;
225 /* click sounds are unset by default, which causes us to internal
226 waveforms for clicks.
230 click_emphasis_data = 0;
232 click_emphasis_length = 0;
235 process_function = &Session::process_with_events;
237 if (Config->get_use_video_sync()) {
238 waiting_for_sync_offset = true;
240 waiting_for_sync_offset = false;
245 _smpte_offset_negative = true;
246 last_smpte_valid = false;
250 last_rr_session_dir = session_dirs.begin();
251 refresh_disk_space ();
253 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
257 average_slave_delta = 1800;
258 have_first_delta_accumulator = false;
259 delta_accumulator_cnt = 0;
260 slave_state = Stopped;
262 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
264 /* These are all static "per-class" signals */
266 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
267 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
268 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
269 Processor::ProcessorCreated.connect (mem_fun (*this, &Session::add_processor));
270 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
271 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
273 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
275 IO::PortCountChanged.connect (mem_fun (*this, &Session::ensure_buffers));
277 /* stop IO objects from doing stuff until we're ready for them */
279 IO::disable_panners ();
280 IO::disable_ports ();
281 IO::disable_connecting ();
285 Session::second_stage_init (bool new_session)
287 AudioFileSource::set_peak_dir (_session_dir->peak_path().to_string());
290 if (load_state (_current_snapshot_name)) {
293 remove_empty_sounds ();
296 if (start_butler_thread()) {
300 if (start_midi_thread ()) {
304 // set_state() will call setup_raid_path(), but if it's a new session we need
305 // to call setup_raid_path() here.
308 if (set_state (*state_tree->root())) {
312 setup_raid_path(_path);
315 /* we can't save till after ::when_engine_running() is called,
316 because otherwise we save state with no connections made.
317 therefore, we reset _state_of_the_state because ::set_state()
318 will have cleared it.
320 we also have to include Loading so that any events that get
321 generated between here and the end of ::when_engine_running()
322 will be processed directly rather than queued.
325 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
328 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
329 _locations.added.connect (mem_fun (this, &Session::locations_added));
330 setup_click_sounds (0);
331 setup_midi_control ();
333 /* Pay attention ... */
335 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
336 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
339 when_engine_running();
342 /* handle this one in a different way than all others, so that its clear what happened */
344 catch (AudioEngine::PortRegistrationFailure& err) {
345 error << _("Unable to create all required ports")
354 BootMessage (_("Reset Remote Controls"));
356 send_full_time_code (0);
357 _engine.transport_locate (0);
358 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
359 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
361 BootMessage (_("Reset Control Protocols"));
363 ControlProtocolManager::instance().set_session (*this);
366 _end_location_is_free = true;
368 _end_location_is_free = false;
371 _state_of_the_state = Clean;
373 DirtyChanged (); /* EMIT SIGNAL */
375 if (state_was_pending) {
376 save_state (_current_snapshot_name);
377 remove_pending_capture_state ();
378 state_was_pending = false;
381 BootMessage (_("Session loading complete"));
387 Session::raid_path () const
389 SearchPath raid_search_path;
391 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
392 raid_search_path += sys::path((*i).path);
395 return raid_search_path.to_string ();
399 Session::setup_raid_path (string path)
408 session_dirs.clear ();
410 SearchPath search_path(path);
411 SearchPath sound_search_path;
412 SearchPath midi_search_path;
415 SearchPath::const_iterator i = search_path.begin();
416 i != search_path.end();
420 sp.path = (*i).to_string ();
421 sp.blocks = 0; // not needed
422 session_dirs.push_back (sp);
424 SessionDirectory sdir(sp.path);
426 sound_search_path += sdir.sound_path ();
427 midi_search_path += sdir.midi_path ();
430 // set the AudioFileSource and SMFSource search path
432 AudioFileSource::set_search_path (sound_search_path.to_string ());
433 SMFSource::set_search_path (midi_search_path.to_string ());
436 // reset the round-robin soundfile path thingie
438 last_rr_session_dir = session_dirs.begin();
442 Session::ensure_subdirs ()
446 dir = session_directory().peak_path().to_string();
448 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
449 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
453 dir = session_directory().sound_path().to_string();
455 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
456 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
460 dir = session_directory().midi_path().to_string();
462 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
463 error << string_compose(_("Session: cannot create session midi dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
467 dir = session_directory().dead_sound_path().to_string();
469 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
470 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
474 dir = session_directory().export_path().to_string();
476 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
477 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
481 dir = analysis_dir ();
483 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
484 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
492 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
495 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
496 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
500 if (ensure_subdirs ()) {
504 /* check new_session so we don't overwrite an existing one */
506 if (!mix_template.empty()) {
507 std::string in_path = mix_template;
509 ifstream in(in_path.c_str());
512 string out_path = _path;
514 out_path += statefile_suffix;
516 ofstream out(out_path.c_str());
521 // okay, session is set up. Treat like normal saved
522 // session from now on.
528 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
534 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
541 /* Instantiate metadata */
543 _metadata = new SessionMetadata ();
545 /* set initial start + end point */
547 start_location->set_end (0);
548 _locations.add (start_location);
550 end_location->set_end (initial_length);
551 _locations.add (end_location);
553 _state_of_the_state = Clean;
562 Session::load_diskstreams (const XMLNode& node)
565 XMLNodeConstIterator citer;
567 clist = node.children();
569 for (citer = clist.begin(); citer != clist.end(); ++citer) {
572 /* diskstreams added automatically by DiskstreamCreated handler */
573 if ((*citer)->name() == "AudioDiskstream" || (*citer)->name() == "DiskStream") {
574 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
575 add_diskstream (dstream);
576 } else if ((*citer)->name() == "MidiDiskstream") {
577 boost::shared_ptr<MidiDiskstream> dstream (new MidiDiskstream (*this, **citer));
578 add_diskstream (dstream);
580 error << _("Session: unknown diskstream type in XML") << endmsg;
584 catch (failed_constructor& err) {
585 error << _("Session: could not load diskstream via XML state") << endmsg;
594 Session::maybe_write_autosave()
596 if (dirty() && record_status() != Recording) {
597 save_state("", true);
602 Session::remove_pending_capture_state ()
604 sys::path pending_state_file_path(_session_dir->root_path());
606 pending_state_file_path /= _current_snapshot_name + pending_suffix;
610 sys::remove (pending_state_file_path);
612 catch(sys::filesystem_error& ex)
614 error << string_compose(_("Could remove pending capture state at path \"%1\" (%2)"),
615 pending_state_file_path.to_string(), ex.what()) << endmsg;
619 /** Rename a state file.
620 * @param snapshot_name Snapshot name.
623 Session::rename_state (string old_name, string new_name)
625 if (old_name == _current_snapshot_name || old_name == _name) {
626 /* refuse to rename the current snapshot or the "main" one */
630 const string old_xml_filename = old_name + statefile_suffix;
631 const string new_xml_filename = new_name + statefile_suffix;
633 const sys::path old_xml_path = _session_dir->root_path() / old_xml_filename;
634 const sys::path new_xml_path = _session_dir->root_path() / new_xml_filename;
638 sys::rename (old_xml_path, new_xml_path);
640 catch (const sys::filesystem_error& err)
642 error << string_compose(_("could not rename snapshot %1 to %2 (%3)"),
643 old_name, new_name, err.what()) << endmsg;
647 /** Remove a state file.
648 * @param snapshot_name Snapshot name.
651 Session::remove_state (string snapshot_name)
653 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
654 // refuse to remove the current snapshot or the "main" one
658 sys::path xml_path(_session_dir->root_path());
660 xml_path /= snapshot_name + statefile_suffix;
662 if (!create_backup_file (xml_path)) {
663 // don't remove it if a backup can't be made
664 // create_backup_file will log the error.
669 sys::remove (xml_path);
673 Session::save_state (string snapshot_name, bool pending)
676 sys::path xml_path(_session_dir->root_path());
678 if (_state_of_the_state & CannotSave) {
682 if (!_engine.connected ()) {
683 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
688 /* tell sources we're saving first, in case they write out to a new file
689 * which should be saved with the state rather than the old one */
690 for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i)
691 i->second->session_saved();
693 tree.set_root (&get_state());
695 if (snapshot_name.empty()) {
696 snapshot_name = _current_snapshot_name;
701 /* proper save: use statefile_suffix (.ardour in English) */
703 xml_path /= snapshot_name + statefile_suffix;
705 /* make a backup copy of the old file */
707 if (sys::exists(xml_path) && !create_backup_file (xml_path)) {
708 // create_backup_file will log the error
714 /* pending save: use pending_suffix (.pending in English) */
715 xml_path /= snapshot_name + pending_suffix;
718 sys::path tmp_path(_session_dir->root_path());
720 tmp_path /= snapshot_name + temp_suffix;
722 // cerr << "actually writing state to " << xml_path.to_string() << endl;
724 if (!tree.write (tmp_path.to_string())) {
725 error << string_compose (_("state could not be saved to %1"), tmp_path.to_string()) << endmsg;
726 sys::remove (tmp_path);
731 if (rename (tmp_path.to_string().c_str(), xml_path.to_string().c_str()) != 0) {
732 error << string_compose (_("could not rename temporary session file %1 to %2"),
733 tmp_path.to_string(), xml_path.to_string()) << endmsg;
734 sys::remove (tmp_path);
741 save_history (snapshot_name);
743 bool was_dirty = dirty();
745 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
748 DirtyChanged (); /* EMIT SIGNAL */
751 StateSaved (snapshot_name); /* EMIT SIGNAL */
758 Session::restore_state (string snapshot_name)
760 if (load_state (snapshot_name) == 0) {
761 set_state (*state_tree->root());
768 Session::load_state (string snapshot_name)
775 state_was_pending = false;
777 /* check for leftover pending state from a crashed capture attempt */
779 sys::path xmlpath(_session_dir->root_path());
780 xmlpath /= snapshot_name + pending_suffix;
782 if (sys::exists (xmlpath)) {
784 /* there is pending state from a crashed capture attempt */
786 if (AskAboutPendingState()) {
787 state_was_pending = true;
791 if (!state_was_pending) {
792 xmlpath = _session_dir->root_path();
793 xmlpath /= snapshot_name + statefile_suffix;
796 if (!sys::exists (xmlpath)) {
797 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
801 state_tree = new XMLTree;
805 if (!state_tree->read (xmlpath.to_string())) {
806 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
812 XMLNode& root (*state_tree->root());
814 if (root.name() != X_("Session")) {
815 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
821 const XMLProperty* prop;
822 bool is_old = false; // session is _very_ old (pre-2.0)
824 if ((prop = root.property ("version")) == 0) {
825 /* no version implies very old version of Ardour */
829 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
830 if (major_version < 2) {
837 sys::path backup_path(_session_dir->root_path());
839 backup_path /= snapshot_name + "-1" + statefile_suffix;
841 // only create a backup once
842 if (sys::exists (backup_path)) {
846 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
847 xmlpath.to_string(), backup_path.to_string())
852 sys::copy_file (xmlpath, backup_path);
854 catch(sys::filesystem_error& ex)
856 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
857 xmlpath.to_string(), ex.what())
867 Session::load_options (const XMLNode& node)
871 LocaleGuard lg (X_("POSIX"));
873 Config->set_variables (node, ConfigVariableBase::Session);
875 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
876 if ((prop = child->property ("val")) != 0) {
877 _end_location_is_free = (prop->value() == "yes");
885 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
887 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
888 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
890 return owner & modified_by_session_or_user;
894 Session::get_options () const
897 LocaleGuard lg (X_("POSIX"));
899 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
901 child = option_root.add_child ("end-marker-is-free");
902 child->add_property ("val", _end_location_is_free ? "yes" : "no");
914 Session::get_template()
916 /* if we don't disable rec-enable, diskstreams
917 will believe they need to store their capture
918 sources in their state node.
921 disable_record (false);
927 Session::state(bool full_state)
929 XMLNode* node = new XMLNode("Session");
932 // store libardour version, just in case
934 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
935 node->add_property("version", string(buf));
937 /* store configuration settings */
941 node->add_property ("name", _name);
942 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
943 node->add_property ("sample-rate", buf);
945 if (session_dirs.size() > 1) {
949 vector<space_and_path>::iterator i = session_dirs.begin();
950 vector<space_and_path>::iterator next;
952 ++i; /* skip the first one */
956 while (i != session_dirs.end()) {
960 if (next != session_dirs.end()) {
970 child = node->add_child ("Path");
971 child->add_content (p);
975 /* save the ID counter */
977 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
978 node->add_property ("id-counter", buf);
980 /* various options */
982 node->add_child_nocopy (get_options());
984 node->add_child_nocopy (_metadata->get_state());
986 child = node->add_child ("Sources");
989 Glib::Mutex::Lock sl (source_lock);
991 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
993 /* Don't save information about AudioFileSources that are empty */
995 boost::shared_ptr<AudioFileSource> fs;
997 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
999 /* Don't save sources that are empty, unless they're destructive (which are OK
1000 if they are empty, because we will re-use them every time.)
1003 if (!fs->destructive()) {
1004 if (fs->length() == 0) {
1010 child->add_child_nocopy (siter->second->get_state());
1014 child = node->add_child ("Regions");
1017 Glib::Mutex::Lock rl (region_lock);
1019 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
1021 /* only store regions not attached to playlists */
1023 if (i->second->playlist() == 0) {
1024 child->add_child_nocopy (i->second->state (true));
1029 child = node->add_child ("DiskStreams");
1032 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1033 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1034 if (!(*i)->hidden()) {
1035 child->add_child_nocopy ((*i)->get_state());
1041 node->add_child_nocopy (_locations.get_state());
1043 // for a template, just create a new Locations, populate it
1044 // with the default start and end, and get the state for that.
1046 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1047 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1050 end->set_end(compute_initial_length());
1052 node->add_child_nocopy (loc.get_state());
1055 child = node->add_child ("Bundles");
1057 Glib::Mutex::Lock lm (bundle_lock);
1058 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
1059 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1061 child->add_child_nocopy (b->get_state());
1066 child = node->add_child ("Routes");
1068 boost::shared_ptr<RouteList> r = routes.reader ();
1070 RoutePublicOrderSorter cmp;
1071 RouteList public_order (*r);
1072 public_order.sort (cmp);
1074 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1075 if (!(*i)->is_hidden()) {
1077 child->add_child_nocopy ((*i)->get_state());
1079 child->add_child_nocopy ((*i)->get_template());
1086 child = node->add_child ("EditGroups");
1087 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1088 child->add_child_nocopy ((*i)->get_state());
1091 child = node->add_child ("MixGroups");
1092 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1093 child->add_child_nocopy ((*i)->get_state());
1096 child = node->add_child ("Playlists");
1097 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1098 if (!(*i)->hidden()) {
1099 if (!(*i)->empty()) {
1101 child->add_child_nocopy ((*i)->get_state());
1103 child->add_child_nocopy ((*i)->get_template());
1109 child = node->add_child ("UnusedPlaylists");
1110 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1111 if (!(*i)->hidden()) {
1112 if (!(*i)->empty()) {
1114 child->add_child_nocopy ((*i)->get_state());
1116 child->add_child_nocopy ((*i)->get_template());
1124 child = node->add_child ("Click");
1125 child->add_child_nocopy (_click_io->state (full_state));
1129 child = node->add_child ("NamedSelections");
1130 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1132 child->add_child_nocopy ((*i)->get_state());
1137 node->add_child_nocopy (_tempo_map->get_state());
1139 node->add_child_nocopy (get_control_protocol_state());
1142 node->add_child_copy (*_extra_xml);
1149 Session::get_control_protocol_state ()
1151 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1152 return cpm.get_state();
1156 Session::set_state (const XMLNode& node)
1160 const XMLProperty* prop;
1163 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1165 if (node.name() != X_("Session")){
1166 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1170 if ((prop = node.property ("name")) != 0) {
1171 _name = prop->value ();
1174 if ((prop = node.property (X_("sample-rate"))) != 0) {
1176 _nominal_frame_rate = atoi (prop->value());
1178 if (_nominal_frame_rate != _current_frame_rate) {
1179 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1185 setup_raid_path(_session_dir->root_path().to_string());
1187 if ((prop = node.property (X_("id-counter"))) != 0) {
1189 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1190 ID::init_counter (x);
1192 /* old sessions used a timebased counter, so fake
1193 the startup ID counter based on a standard
1198 ID::init_counter (now);
1202 IO::disable_ports ();
1203 IO::disable_connecting ();
1205 /* Object loading order:
1224 if (use_config_midi_ports ()) {
1227 if ((child = find_named_node (node, "extra")) != 0) {
1228 _extra_xml = new XMLNode (*child);
1231 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1232 load_options (*child);
1233 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1234 load_options (*child);
1236 error << _("Session: XML state has no options section") << endmsg;
1239 if ((child = find_named_node (node, "Metadata")) == 0) {
1240 warning << _("Session: XML state has no metadata section (2.0 session?)") << endmsg;
1241 } else if (_metadata->set_state (*child)) {
1245 if ((child = find_named_node (node, "Locations")) == 0) {
1246 error << _("Session: XML state has no locations section") << endmsg;
1248 } else if (_locations.set_state (*child)) {
1254 if ((location = _locations.auto_loop_location()) != 0) {
1255 set_auto_loop_location (location);
1258 if ((location = _locations.auto_punch_location()) != 0) {
1259 set_auto_punch_location (location);
1262 if ((location = _locations.end_location()) == 0) {
1263 _locations.add (end_location);
1265 delete end_location;
1266 end_location = location;
1269 if ((location = _locations.start_location()) == 0) {
1270 _locations.add (start_location);
1272 delete start_location;
1273 start_location = location;
1276 AudioFileSource::set_header_position_offset (start_location->start());
1278 if ((child = find_named_node (node, "Sources")) == 0) {
1279 error << _("Session: XML state has no sources section") << endmsg;
1281 } else if (load_sources (*child)) {
1285 if ((child = find_named_node (node, "Regions")) == 0) {
1286 error << _("Session: XML state has no Regions section") << endmsg;
1288 } else if (load_regions (*child)) {
1292 if ((child = find_named_node (node, "Playlists")) == 0) {
1293 error << _("Session: XML state has no playlists section") << endmsg;
1295 } else if (load_playlists (*child)) {
1299 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1301 } else if (load_unused_playlists (*child)) {
1305 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1306 if (load_named_selections (*child)) {
1311 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1312 error << _("Session: XML state has no diskstreams section") << endmsg;
1314 } else if (load_diskstreams (*child)) {
1318 if ((child = find_named_node (node, "Bundles")) == 0) {
1319 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1322 /* We can't load Bundles yet as they need to be able
1323 to convert from port names to Port objects, which can't happen until
1325 _bundle_xml_node = new XMLNode (*child);
1328 if ((child = find_named_node (node, "EditGroups")) == 0) {
1329 error << _("Session: XML state has no edit groups section") << endmsg;
1331 } else if (load_edit_groups (*child)) {
1335 if ((child = find_named_node (node, "MixGroups")) == 0) {
1336 error << _("Session: XML state has no mix groups section") << endmsg;
1338 } else if (load_mix_groups (*child)) {
1342 if ((child = find_named_node (node, "TempoMap")) == 0) {
1343 error << _("Session: XML state has no Tempo Map section") << endmsg;
1345 } else if (_tempo_map->set_state (*child)) {
1349 if ((child = find_named_node (node, "Routes")) == 0) {
1350 error << _("Session: XML state has no routes section") << endmsg;
1352 } else if (load_routes (*child)) {
1356 if ((child = find_named_node (node, "Click")) == 0) {
1357 warning << _("Session: XML state has no click section") << endmsg;
1358 } else if (_click_io) {
1359 _click_io->set_state (*child);
1362 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1363 ControlProtocolManager::instance().set_protocol_states (*child);
1366 /* here beginneth the second phase ... */
1368 StateReady (); /* EMIT SIGNAL */
1377 Session::load_routes (const XMLNode& node)
1380 XMLNodeConstIterator niter;
1381 RouteList new_routes;
1383 nlist = node.children();
1387 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1389 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1392 error << _("Session: cannot create Route from XML description.") << endmsg;
1396 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1398 new_routes.push_back (route);
1401 add_routes (new_routes, false);
1406 boost::shared_ptr<Route>
1407 Session::XMLRouteFactory (const XMLNode& node)
1409 if (node.name() != "Route") {
1410 return boost::shared_ptr<Route> ((Route*) 0);
1413 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1415 DataType type = DataType::AUDIO;
1416 const XMLProperty* prop = node.property("default-type");
1418 type = DataType(prop->value());
1420 assert(type != DataType::NIL);
1422 if (has_diskstream) {
1423 if (type == DataType::AUDIO) {
1424 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1427 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1431 boost::shared_ptr<Route> ret (new Route (*this, node));
1437 Session::load_regions (const XMLNode& node)
1440 XMLNodeConstIterator niter;
1441 boost::shared_ptr<Region> region;
1443 nlist = node.children();
1447 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1448 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1449 error << _("Session: cannot create Region from XML description.");
1450 const XMLProperty *name = (**niter).property("name");
1453 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1463 boost::shared_ptr<Region>
1464 Session::XMLRegionFactory (const XMLNode& node, bool full)
1466 const XMLProperty* type = node.property("type");
1470 if ( !type || type->value() == "audio" ) {
1472 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1474 } else if (type->value() == "midi") {
1476 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1480 } catch (failed_constructor& err) {
1481 return boost::shared_ptr<Region> ();
1484 return boost::shared_ptr<Region> ();
1487 boost::shared_ptr<AudioRegion>
1488 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1490 const XMLProperty* prop;
1491 boost::shared_ptr<Source> source;
1492 boost::shared_ptr<AudioSource> as;
1494 SourceList master_sources;
1495 uint32_t nchans = 1;
1498 if (node.name() != X_("Region")) {
1499 return boost::shared_ptr<AudioRegion>();
1502 if ((prop = node.property (X_("channels"))) != 0) {
1503 nchans = atoi (prop->value().c_str());
1506 if ((prop = node.property ("name")) == 0) {
1507 cerr << "no name for this region\n";
1511 if ((prop = node.property (X_("source-0"))) == 0) {
1512 if ((prop = node.property ("source")) == 0) {
1513 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1514 return boost::shared_ptr<AudioRegion>();
1518 PBD::ID s_id (prop->value());
1520 if ((source = source_by_id (s_id)) == 0) {
1521 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1522 return boost::shared_ptr<AudioRegion>();
1525 as = boost::dynamic_pointer_cast<AudioSource>(source);
1527 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1528 return boost::shared_ptr<AudioRegion>();
1531 sources.push_back (as);
1533 /* pickup other channels */
1535 for (uint32_t n=1; n < nchans; ++n) {
1536 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1537 if ((prop = node.property (buf)) != 0) {
1539 PBD::ID id2 (prop->value());
1541 if ((source = source_by_id (id2)) == 0) {
1542 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1543 return boost::shared_ptr<AudioRegion>();
1546 as = boost::dynamic_pointer_cast<AudioSource>(source);
1548 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1549 return boost::shared_ptr<AudioRegion>();
1551 sources.push_back (as);
1555 for (uint32_t n=1; n < nchans; ++n) {
1556 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1557 if ((prop = node.property (buf)) != 0) {
1559 PBD::ID id2 (prop->value());
1561 if ((source = source_by_id (id2)) == 0) {
1562 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1563 return boost::shared_ptr<AudioRegion>();
1566 as = boost::dynamic_pointer_cast<AudioSource>(source);
1568 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1569 return boost::shared_ptr<AudioRegion>();
1571 master_sources.push_back (as);
1576 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1578 /* a final detail: this is the one and only place that we know how long missing files are */
1580 if (region->whole_file()) {
1581 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1582 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1584 sfp->set_length (region->length());
1589 if (!master_sources.empty()) {
1590 if (master_sources.size() == nchans) {
1591 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1593 region->set_master_sources (master_sources);
1601 catch (failed_constructor& err) {
1602 return boost::shared_ptr<AudioRegion>();
1606 boost::shared_ptr<MidiRegion>
1607 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1609 const XMLProperty* prop;
1610 boost::shared_ptr<Source> source;
1611 boost::shared_ptr<MidiSource> ms;
1613 uint32_t nchans = 1;
1615 if (node.name() != X_("Region")) {
1616 return boost::shared_ptr<MidiRegion>();
1619 if ((prop = node.property (X_("channels"))) != 0) {
1620 nchans = atoi (prop->value().c_str());
1623 if ((prop = node.property ("name")) == 0) {
1624 cerr << "no name for this region\n";
1628 // Multiple midi channels? that's just crazy talk
1629 assert(nchans == 1);
1631 if ((prop = node.property (X_("source-0"))) == 0) {
1632 if ((prop = node.property ("source")) == 0) {
1633 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1634 return boost::shared_ptr<MidiRegion>();
1638 PBD::ID s_id (prop->value());
1640 if ((source = source_by_id (s_id)) == 0) {
1641 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1642 return boost::shared_ptr<MidiRegion>();
1645 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1647 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1648 return boost::shared_ptr<MidiRegion>();
1651 sources.push_back (ms);
1654 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1655 /* a final detail: this is the one and only place that we know how long missing files are */
1657 if (region->whole_file()) {
1658 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1659 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1661 sfp->set_length (region->length());
1669 catch (failed_constructor& err) {
1670 return boost::shared_ptr<MidiRegion>();
1675 Session::get_sources_as_xml ()
1678 XMLNode* node = new XMLNode (X_("Sources"));
1679 Glib::Mutex::Lock lm (source_lock);
1681 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1682 node->add_child_nocopy (i->second->get_state());
1689 Session::path_from_region_name (DataType type, string name, string identifier)
1691 char buf[PATH_MAX+1];
1693 SessionDirectory sdir(get_best_session_directory_for_new_source());
1694 sys::path source_dir = ((type == DataType::AUDIO)
1695 ? sdir.sound_path() : sdir.midi_path());
1697 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1699 for (n = 0; n < 999999; ++n) {
1700 if (identifier.length()) {
1701 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1702 identifier.c_str(), n, ext.c_str());
1704 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1708 sys::path source_path = source_dir / buf;
1710 if (!sys::exists (source_path)) {
1711 return source_path.to_string();
1715 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1724 Session::load_sources (const XMLNode& node)
1727 XMLNodeConstIterator niter;
1728 boost::shared_ptr<Source> source;
1730 nlist = node.children();
1734 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1737 if ((source = XMLSourceFactory (**niter)) == 0) {
1738 error << _("Session: cannot create Source from XML description.") << endmsg;
1742 catch (non_existent_source& err) {
1743 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1744 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1751 boost::shared_ptr<Source>
1752 Session::XMLSourceFactory (const XMLNode& node)
1754 if (node.name() != "Source") {
1755 return boost::shared_ptr<Source>();
1759 /* note: do peak building in another thread when loading session state */
1760 return SourceFactory::create (*this, node, true);
1763 catch (failed_constructor& err) {
1764 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1765 return boost::shared_ptr<Source>();
1770 Session::save_template (string template_name)
1774 if (_state_of_the_state & CannotSave) {
1778 sys::path user_template_dir(user_template_directory());
1782 sys::create_directories (user_template_dir);
1784 catch(sys::filesystem_error& ex)
1786 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1787 user_template_dir.to_string(), ex.what()) << endmsg;
1791 tree.set_root (&get_template());
1793 sys::path template_file_path(user_template_dir);
1794 template_file_path /= template_name + template_suffix;
1796 if (sys::exists (template_file_path))
1798 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1799 template_file_path.to_string()) << endmsg;
1803 if (!tree.write (template_file_path.to_string())) {
1804 error << _("mix template not saved") << endmsg;
1812 Session::rename_template (string old_name, string new_name)
1814 sys::path old_path (user_template_directory());
1815 old_path /= old_name + template_suffix;
1817 sys::path new_path(user_template_directory());
1818 new_path /= new_name + template_suffix;
1820 if (sys::exists (new_path)) {
1821 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1822 new_path.to_string()) << endmsg;
1827 sys::rename (old_path, new_path);
1835 Session::delete_template (string name)
1837 sys::path path = user_template_directory();
1838 path /= name + template_suffix;
1849 Session::refresh_disk_space ()
1852 struct statfs statfsbuf;
1853 vector<space_and_path>::iterator i;
1854 Glib::Mutex::Lock lm (space_lock);
1857 /* get freespace on every FS that is part of the session path */
1859 _total_free_4k_blocks = 0;
1861 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1862 statfs ((*i).path.c_str(), &statfsbuf);
1864 scale = statfsbuf.f_bsize/4096.0;
1866 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1867 _total_free_4k_blocks += (*i).blocks;
1873 Session::get_best_session_directory_for_new_source ()
1875 vector<space_and_path>::iterator i;
1876 string result = _session_dir->root_path().to_string();
1878 /* handle common case without system calls */
1880 if (session_dirs.size() == 1) {
1884 /* OK, here's the algorithm we're following here:
1886 We want to select which directory to use for
1887 the next file source to be created. Ideally,
1888 we'd like to use a round-robin process so as to
1889 get maximum performance benefits from splitting
1890 the files across multiple disks.
1892 However, in situations without much diskspace, an
1893 RR approach may end up filling up a filesystem
1894 with new files while others still have space.
1895 Its therefore important to pay some attention to
1896 the freespace in the filesystem holding each
1897 directory as well. However, if we did that by
1898 itself, we'd keep creating new files in the file
1899 system with the most space until it was as full
1900 as all others, thus negating any performance
1901 benefits of this RAID-1 like approach.
1903 So, we use a user-configurable space threshold. If
1904 there are at least 2 filesystems with more than this
1905 much space available, we use RR selection between them.
1906 If not, then we pick the filesystem with the most space.
1908 This gets a good balance between the two
1912 refresh_disk_space ();
1914 int free_enough = 0;
1916 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1917 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1922 if (free_enough >= 2) {
1923 /* use RR selection process, ensuring that the one
1927 i = last_rr_session_dir;
1930 if (++i == session_dirs.end()) {
1931 i = session_dirs.begin();
1934 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1935 if (create_session_directory ((*i).path)) {
1937 last_rr_session_dir = i;
1942 } while (i != last_rr_session_dir);
1946 /* pick FS with the most freespace (and that
1947 seems to actually work ...)
1950 vector<space_and_path> sorted;
1951 space_and_path_ascending_cmp cmp;
1953 sorted = session_dirs;
1954 sort (sorted.begin(), sorted.end(), cmp);
1956 for (i = sorted.begin(); i != sorted.end(); ++i) {
1957 if (create_session_directory ((*i).path)) {
1959 last_rr_session_dir = i;
1969 Session::load_playlists (const XMLNode& node)
1972 XMLNodeConstIterator niter;
1973 boost::shared_ptr<Playlist> playlist;
1975 nlist = node.children();
1979 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1981 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1982 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1990 Session::load_unused_playlists (const XMLNode& node)
1993 XMLNodeConstIterator niter;
1994 boost::shared_ptr<Playlist> playlist;
1996 nlist = node.children();
2000 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2002 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
2003 error << _("Session: cannot create Playlist from XML description.") << endmsg;
2007 // now manually untrack it
2009 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
2015 boost::shared_ptr<Playlist>
2016 Session::XMLPlaylistFactory (const XMLNode& node)
2019 return PlaylistFactory::create (*this, node);
2022 catch (failed_constructor& err) {
2023 return boost::shared_ptr<Playlist>();
2028 Session::load_named_selections (const XMLNode& node)
2031 XMLNodeConstIterator niter;
2034 nlist = node.children();
2038 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2040 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2041 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2049 Session::XMLNamedSelectionFactory (const XMLNode& node)
2052 return new NamedSelection (*this, node);
2055 catch (failed_constructor& err) {
2061 Session::automation_dir () const
2063 return Glib::build_filename (_path, "automation");
2067 Session::analysis_dir () const
2069 return Glib::build_filename (_path, "analysis");
2073 Session::load_bundles (XMLNode const & node)
2075 XMLNodeList nlist = node.children();
2076 XMLNodeConstIterator niter;
2080 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2081 if ((*niter)->name() == "InputBundle") {
2082 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2083 } else if ((*niter)->name() == "OutputBundle") {
2084 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2086 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2095 Session::load_edit_groups (const XMLNode& node)
2097 return load_route_groups (node, true);
2101 Session::load_mix_groups (const XMLNode& node)
2103 return load_route_groups (node, false);
2107 Session::load_route_groups (const XMLNode& node, bool edit)
2109 XMLNodeList nlist = node.children();
2110 XMLNodeConstIterator niter;
2115 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2116 if ((*niter)->name() == "RouteGroup") {
2118 rg = add_edit_group ("");
2119 rg->set_state (**niter);
2121 rg = add_mix_group ("");
2122 rg->set_state (**niter);
2131 Session::auto_save()
2133 save_state (_current_snapshot_name);
2137 state_file_filter (const string &str, void *arg)
2139 return (str.length() > strlen(statefile_suffix) &&
2140 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2144 bool operator()(const string* a, const string* b) {
2150 remove_end(string* state)
2152 string statename(*state);
2154 string::size_type start,end;
2155 if ((start = statename.find_last_of ('/')) != string::npos) {
2156 statename = statename.substr (start+1);
2159 if ((end = statename.rfind(".ardour")) == string::npos) {
2160 end = statename.length();
2163 return new string(statename.substr (0, end));
2167 Session::possible_states (string path)
2169 PathScanner scanner;
2170 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2172 transform(states->begin(), states->end(), states->begin(), remove_end);
2175 sort (states->begin(), states->end(), cmp);
2181 Session::possible_states () const
2183 return possible_states(_path);
2187 Session::add_edit_group (string name)
2189 RouteGroup* rg = new RouteGroup (*this, name);
2190 edit_groups.push_back (rg);
2191 edit_group_added (rg); /* EMIT SIGNAL */
2197 Session::add_mix_group (string name)
2199 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2200 mix_groups.push_back (rg);
2201 mix_group_added (rg); /* EMIT SIGNAL */
2207 Session::remove_edit_group (RouteGroup& rg)
2209 list<RouteGroup*>::iterator i;
2211 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2212 (*i)->apply (&Route::drop_edit_group, this);
2213 edit_groups.erase (i);
2214 edit_group_removed (); /* EMIT SIGNAL */
2221 Session::remove_mix_group (RouteGroup& rg)
2223 list<RouteGroup*>::iterator i;
2225 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2226 (*i)->apply (&Route::drop_mix_group, this);
2227 mix_groups.erase (i);
2228 mix_group_removed (); /* EMIT SIGNAL */
2235 Session::mix_group_by_name (string name)
2237 list<RouteGroup *>::iterator i;
2239 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2240 if ((*i)->name() == name) {
2248 Session::edit_group_by_name (string name)
2250 list<RouteGroup *>::iterator i;
2252 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2253 if ((*i)->name() == name) {
2261 Session::begin_reversible_command (const string& name)
2263 current_trans = new UndoTransaction;
2264 current_trans->set_name (name);
2268 Session::commit_reversible_command (Command *cmd)
2273 current_trans->add_command (cmd);
2276 if (current_trans->empty()) {
2280 gettimeofday (&now, 0);
2281 current_trans->set_timestamp (now);
2283 _history.add (current_trans);
2286 Session::GlobalRouteBooleanState
2287 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2289 GlobalRouteBooleanState s;
2290 boost::shared_ptr<RouteList> r = routes.reader ();
2292 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2293 if (!(*i)->is_hidden()) {
2294 RouteBooleanState v;
2297 Route* r = (*i).get();
2298 v.second = (r->*method)();
2307 Session::GlobalRouteMeterState
2308 Session::get_global_route_metering ()
2310 GlobalRouteMeterState s;
2311 boost::shared_ptr<RouteList> r = routes.reader ();
2313 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2314 if (!(*i)->is_hidden()) {
2318 v.second = (*i)->meter_point();
2328 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2330 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2332 boost::shared_ptr<Route> r = (i->first.lock());
2335 r->set_meter_point (i->second, arg);
2341 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2343 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2345 boost::shared_ptr<Route> r = (i->first.lock());
2348 Route* rp = r.get();
2349 (rp->*method) (i->second, arg);
2355 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2357 set_global_route_boolean (s, &Route::set_mute, src);
2361 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2363 set_global_route_boolean (s, &Route::set_solo, src);
2367 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2369 set_global_route_boolean (s, &Route::set_record_enable, src);
2374 Session::global_mute_memento (void* src)
2376 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2380 Session::global_metering_memento (void* src)
2382 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2386 Session::global_solo_memento (void* src)
2388 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2392 Session::global_record_enable_memento (void* src)
2394 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2399 accept_all_non_peak_files (const string& path, void *arg)
2401 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2405 accept_all_state_files (const string& path, void *arg)
2407 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2411 Session::find_all_sources (string path, set<string>& result)
2416 if (!tree.read (path)) {
2420 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2425 XMLNodeConstIterator niter;
2427 nlist = node->children();
2431 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2435 if ((prop = (*niter)->property (X_("name"))) == 0) {
2439 if (prop->value()[0] == '/') {
2440 /* external file, ignore */
2444 sys::path source_path = _session_dir->sound_path ();
2446 source_path /= prop->value ();
2448 result.insert (source_path.to_string ());
2455 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2457 PathScanner scanner;
2458 vector<string*>* state_files;
2460 string this_snapshot_path;
2466 if (ripped[ripped.length()-1] == '/') {
2467 ripped = ripped.substr (0, ripped.length() - 1);
2470 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2472 if (state_files == 0) {
2477 this_snapshot_path = _path;
2478 this_snapshot_path += _current_snapshot_name;
2479 this_snapshot_path += statefile_suffix;
2481 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2483 if (exclude_this_snapshot && **i == this_snapshot_path) {
2487 if (find_all_sources (**i, result) < 0) {
2495 struct RegionCounter {
2496 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2497 AudioSourceList::iterator iter;
2498 boost::shared_ptr<Region> region;
2501 RegionCounter() : count (0) {}
2505 Session::cleanup_sources (Session::cleanup_report& rep)
2507 // FIXME: needs adaptation to midi
2509 vector<boost::shared_ptr<Source> > dead_sources;
2510 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2511 PathScanner scanner;
2513 vector<space_and_path>::iterator i;
2514 vector<space_and_path>::iterator nexti;
2515 vector<string*>* soundfiles;
2516 vector<string> unused;
2517 set<string> all_sources;
2522 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2525 /* step 1: consider deleting all unused playlists */
2527 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2530 status = AskAboutPlaylistDeletion (*x);
2539 playlists_tbd.push_back (*x);
2543 /* leave it alone */
2548 /* now delete any that were marked for deletion */
2550 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2551 (*x)->drop_references ();
2554 playlists_tbd.clear ();
2556 /* step 2: find all un-used sources */
2561 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2563 SourceMap::iterator tmp;
2568 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2572 if (!i->second->used() && i->second->length() > 0) {
2573 dead_sources.push_back (i->second);
2574 i->second->GoingAway();
2580 /* build a list of all the possible sound directories for the session */
2582 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2587 SessionDirectory sdir ((*i).path);
2588 sound_path += sdir.sound_path().to_string();
2590 if (nexti != session_dirs.end()) {
2597 /* now do the same thing for the files that ended up in the sounds dir(s)
2598 but are not referenced as sources in any snapshot.
2601 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2603 if (soundfiles == 0) {
2607 /* find all sources, but don't use this snapshot because the
2608 state file on disk still references sources we may have already
2612 find_all_sources_across_snapshots (all_sources, true);
2614 /* add our current source list
2617 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2618 boost::shared_ptr<AudioFileSource> fs;
2620 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2621 all_sources.insert (fs->path());
2625 char tmppath1[PATH_MAX+1];
2626 char tmppath2[PATH_MAX+1];
2628 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2633 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2635 realpath(spath.c_str(), tmppath1);
2636 realpath((*i).c_str(), tmppath2);
2638 if (strcmp(tmppath1, tmppath2) == 0) {
2645 unused.push_back (spath);
2649 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2651 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2652 struct stat statbuf;
2654 rep.paths.push_back (*x);
2655 if (stat ((*x).c_str(), &statbuf) == 0) {
2656 rep.space += statbuf.st_size;
2661 /* don't move the file across filesystems, just
2662 stick it in the `dead_sound_dir_name' directory
2663 on whichever filesystem it was already on.
2666 if ((*x).find ("/sounds/") != string::npos) {
2668 /* old school, go up 1 level */
2670 newpath = Glib::path_get_dirname (*x); // "sounds"
2671 newpath = Glib::path_get_dirname (newpath); // "session-name"
2675 /* new school, go up 4 levels */
2677 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2678 newpath = Glib::path_get_dirname (newpath); // "session-name"
2679 newpath = Glib::path_get_dirname (newpath); // "interchange"
2680 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2684 newpath += dead_sound_dir_name;
2686 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2687 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2692 newpath += Glib::path_get_basename ((*x));
2694 if (access (newpath.c_str(), F_OK) == 0) {
2696 /* the new path already exists, try versioning */
2698 char buf[PATH_MAX+1];
2702 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2705 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2706 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2710 if (version == 999) {
2711 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2715 newpath = newpath_v;
2720 /* it doesn't exist, or we can't read it or something */
2724 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2725 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2726 (*x), newpath, strerror (errno))
2731 /* see if there an easy to find peakfile for this file, and remove it.
2734 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2735 peakpath += peakfile_suffix;
2737 if (access (peakpath.c_str(), W_OK) == 0) {
2738 if (::unlink (peakpath.c_str()) != 0) {
2739 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2740 peakpath, _path, strerror (errno))
2742 /* try to back out */
2743 rename (newpath.c_str(), _path.c_str());
2751 /* dump the history list */
2755 /* save state so we don't end up a session file
2756 referring to non-existent sources.
2762 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2768 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2770 // FIXME: needs adaptation for MIDI
2772 vector<space_and_path>::iterator i;
2773 string dead_sound_dir;
2774 struct dirent* dentry;
2775 struct stat statbuf;
2781 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2783 dead_sound_dir = (*i).path;
2784 dead_sound_dir += dead_sound_dir_name;
2786 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2790 while ((dentry = readdir (dead)) != 0) {
2792 /* avoid '.' and '..' */
2794 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2795 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2801 fullpath = dead_sound_dir;
2803 fullpath += dentry->d_name;
2805 if (stat (fullpath.c_str(), &statbuf)) {
2809 if (!S_ISREG (statbuf.st_mode)) {
2813 if (unlink (fullpath.c_str())) {
2814 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2815 fullpath, strerror (errno))
2819 rep.paths.push_back (dentry->d_name);
2820 rep.space += statbuf.st_size;
2831 Session::set_dirty ()
2833 bool was_dirty = dirty();
2835 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2839 DirtyChanged(); /* EMIT SIGNAL */
2845 Session::set_clean ()
2847 bool was_dirty = dirty();
2849 _state_of_the_state = Clean;
2853 DirtyChanged(); /* EMIT SIGNAL */
2858 Session::set_deletion_in_progress ()
2860 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2865 Session::add_controllable (boost::shared_ptr<Controllable> c)
2867 /* this adds a controllable to the list managed by the Session.
2868 this is a subset of those managed by the Controllable class
2869 itself, and represents the only ones whose state will be saved
2870 as part of the session.
2873 Glib::Mutex::Lock lm (controllables_lock);
2874 controllables.insert (c);
2877 struct null_deleter { void operator()(void const *) const {} };
2880 Session::remove_controllable (Controllable* c)
2882 if (_state_of_the_state | Deletion) {
2886 Glib::Mutex::Lock lm (controllables_lock);
2888 Controllables::iterator x = controllables.find(
2889 boost::shared_ptr<Controllable>(c, null_deleter()));
2891 if (x != controllables.end()) {
2892 controllables.erase (x);
2896 boost::shared_ptr<Controllable>
2897 Session::controllable_by_id (const PBD::ID& id)
2899 Glib::Mutex::Lock lm (controllables_lock);
2901 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2902 if ((*i)->id() == id) {
2907 return boost::shared_ptr<Controllable>();
2911 Session::add_instant_xml (XMLNode& node, bool write_to_config)
2913 Stateful::add_instant_xml (node, _path);
2914 if (write_to_config) {
2915 Config->add_instant_xml (node);
2920 Session::instant_xml (const string& node_name)
2922 return Stateful::instant_xml (node_name, _path);
2926 Session::save_history (string snapshot_name)
2930 if (snapshot_name.empty()) {
2931 snapshot_name = _current_snapshot_name;
2934 const string history_filename = snapshot_name + history_suffix;
2935 const string backup_filename = history_filename + backup_suffix;
2936 const sys::path xml_path = _session_dir->root_path() / history_filename;
2937 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2939 if (sys::exists (xml_path)) {
2942 sys::rename (xml_path, backup_path);
2944 catch (const sys::filesystem_error& err)
2946 error << _("could not backup old history file, current history not saved") << endmsg;
2952 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2956 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2958 if (!tree.write (xml_path.to_string()))
2960 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2964 sys::remove (xml_path);
2965 sys::rename (backup_path, xml_path);
2967 catch (const sys::filesystem_error& err)
2969 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2970 backup_path.to_string(), err.what()) << endmsg;
2980 Session::restore_history (string snapshot_name)
2984 if (snapshot_name.empty()) {
2985 snapshot_name = _current_snapshot_name;
2988 const string xml_filename = snapshot_name + history_suffix;
2989 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2991 cerr << "Loading history from " << xml_path.to_string() << endmsg;
2993 if (!sys::exists (xml_path)) {
2994 info << string_compose (_("%1: no history file \"%2\" for this session."),
2995 _name, xml_path.to_string()) << endmsg;
2999 if (!tree.read (xml_path.to_string())) {
3000 error << string_compose (_("Could not understand session history file \"%1\""),
3001 xml_path.to_string()) << endmsg;
3008 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3011 UndoTransaction* ut = new UndoTransaction ();
3014 ut->set_name(t->property("name")->value());
3015 stringstream ss(t->property("tv-sec")->value());
3017 ss.str(t->property("tv-usec")->value());
3019 ut->set_timestamp(tv);
3021 for (XMLNodeConstIterator child_it = t->children().begin();
3022 child_it != t->children().end(); child_it++)
3024 XMLNode *n = *child_it;
3027 if (n->name() == "MementoCommand" ||
3028 n->name() == "MementoUndoCommand" ||
3029 n->name() == "MementoRedoCommand") {
3031 if ((c = memento_command_factory(n))) {
3035 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3037 if ((c = global_state_command_factory (*n))) {
3038 ut->add_command (c);
3041 } else if (n->name() == "DeltaCommand") {
3042 PBD::ID id(n->property("midi-source")->value());
3043 boost::shared_ptr<MidiSource> midi_source =
3044 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3046 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3048 error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
3051 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3062 Session::config_changed (const char* parameter_name)
3064 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3066 if (PARAM_IS ("seamless-loop")) {
3068 } else if (PARAM_IS ("rf-speed")) {
3070 } else if (PARAM_IS ("auto-loop")) {
3072 } else if (PARAM_IS ("auto-input")) {
3074 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3075 /* auto-input only makes a difference if we're rolling */
3077 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3079 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3080 if ((*i)->record_enabled ()) {
3081 (*i)->monitor_input (!Config->get_auto_input());
3086 } else if (PARAM_IS ("punch-in")) {
3090 if ((location = _locations.auto_punch_location()) != 0) {
3092 if (Config->get_punch_in ()) {
3093 replace_event (Event::PunchIn, location->start());
3095 remove_event (location->start(), Event::PunchIn);
3099 } else if (PARAM_IS ("punch-out")) {
3103 if ((location = _locations.auto_punch_location()) != 0) {
3105 if (Config->get_punch_out()) {
3106 replace_event (Event::PunchOut, location->end());
3108 clear_events (Event::PunchOut);
3112 } else if (PARAM_IS ("edit-mode")) {
3114 Glib::Mutex::Lock lm (playlist_lock);
3116 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3117 (*i)->set_edit_mode (Config->get_edit_mode ());
3120 } else if (PARAM_IS ("use-video-sync")) {
3122 waiting_for_sync_offset = Config->get_use_video_sync();
3124 } else if (PARAM_IS ("mmc-control")) {
3126 //poke_midi_thread ();
3128 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
3131 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3134 } else if (PARAM_IS ("mmc-send-id")) {
3137 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3140 } else if (PARAM_IS ("midi-control")) {
3142 //poke_midi_thread ();
3144 } else if (PARAM_IS ("raid-path")) {
3146 setup_raid_path (Config->get_raid_path());
3148 } else if (PARAM_IS ("smpte-format")) {
3152 } else if (PARAM_IS ("video-pullup")) {
3156 } else if (PARAM_IS ("seamless-loop")) {
3158 if (play_loop && transport_rolling()) {
3159 // to reset diskstreams etc
3160 request_play_loop (true);
3163 } else if (PARAM_IS ("rf-speed")) {
3165 cumulative_rf_motion = 0;
3168 } else if (PARAM_IS ("click-sound")) {
3170 setup_click_sounds (1);
3172 } else if (PARAM_IS ("click-emphasis-sound")) {
3174 setup_click_sounds (-1);
3176 } else if (PARAM_IS ("clicking")) {
3178 if (Config->get_clicking()) {
3179 if (_click_io && click_data) { // don't require emphasis data
3186 } else if (PARAM_IS ("send-mtc")) {
3188 /* only set the internal flag if we have
3192 if (_mtc_port != 0) {
3193 session_send_mtc = Config->get_send_mtc();
3194 if (session_send_mtc) {
3195 /* mark us ready to send */
3196 next_quarter_frame_to_send = 0;
3199 session_send_mtc = false;
3202 } else if (PARAM_IS ("send-mmc")) {
3204 /* only set the internal flag if we have
3208 if (_mmc_port != 0) {
3209 session_send_mmc = Config->get_send_mmc();
3212 session_send_mmc = false;
3215 } else if (PARAM_IS ("midi-feedback")) {
3217 /* only set the internal flag if we have
3221 if (_mtc_port != 0) {
3222 session_midi_feedback = Config->get_midi_feedback();
3225 } else if (PARAM_IS ("jack-time-master")) {
3227 engine().reset_timebase ();
3229 } else if (PARAM_IS ("native-file-header-format")) {
3231 if (!first_file_header_format_reset) {
3232 reset_native_file_format ();
3235 first_file_header_format_reset = false;
3237 } else if (PARAM_IS ("native-file-data-format")) {
3239 if (!first_file_data_format_reset) {
3240 reset_native_file_format ();
3243 first_file_data_format_reset = false;
3245 } else if (PARAM_IS ("slave-source")) {
3246 set_slave_source (Config->get_slave_source());
3247 } else if (PARAM_IS ("remote-model")) {
3248 set_remote_control_ids ();
3249 } else if (PARAM_IS ("denormal-model")) {
3251 } else if (PARAM_IS ("history-depth")) {
3252 set_history_depth (Config->get_history_depth());
3253 } else if (PARAM_IS ("sync-all-route-ordering")) {
3264 Session::set_history_depth (uint32_t d)
3266 _history.set_depth (d);