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/buffer.h>
68 #include <ardour/audio_diskstream.h>
69 #include <ardour/midi_diskstream.h>
70 #include <ardour/utils.h>
71 #include <ardour/audioplaylist.h>
72 #include <ardour/midi_playlist.h>
73 #include <ardour/smf_source.h>
74 #include <ardour/audiofilesource.h>
75 #include <ardour/silentfilesource.h>
76 #include <ardour/sndfilesource.h>
77 #include <ardour/midi_source.h>
78 #include <ardour/sndfile_helpers.h>
79 #include <ardour/auditioner.h>
80 #include <ardour/export.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);
201 waiting_to_start = 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 /* 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 /= _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 = old_name + statefile_suffix;
627 const string new_xml_filename = 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 /= 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 (_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 /= 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 /= snapshot_name + pending_suffix;
714 sys::path tmp_path(_session_dir->root_path());
716 tmp_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());
764 Session::load_state (string snapshot_name)
771 state_was_pending = false;
773 /* check for leftover pending state from a crashed capture attempt */
775 sys::path xmlpath(_session_dir->root_path());
776 xmlpath /= snapshot_name + pending_suffix;
778 if (sys::exists (xmlpath)) {
780 /* there is pending state from a crashed capture attempt */
782 if (AskAboutPendingState()) {
783 state_was_pending = true;
787 if (!state_was_pending) {
788 xmlpath = _session_dir->root_path();
789 xmlpath /= snapshot_name + statefile_suffix;
792 if (!sys::exists (xmlpath)) {
793 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath.to_string()) << endmsg;
797 state_tree = new XMLTree;
801 if (!state_tree->read (xmlpath.to_string())) {
802 error << string_compose(_("Could not understand ardour file %1"), xmlpath.to_string()) << endmsg;
808 XMLNode& root (*state_tree->root());
810 if (root.name() != X_("Session")) {
811 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath.to_string()) << endmsg;
817 const XMLProperty* prop;
820 if ((prop = root.property ("version")) == 0) {
821 /* no version implies very old version of Ardour */
825 major_version = atoi (prop->value().c_str()); // grab just the first number before the period
826 if (major_version < 2) {
833 sys::path backup_path(_session_dir->root_path());
835 backup_path /= snapshot_name + "-1" + statefile_suffix;
837 // only create a backup once
838 if (sys::exists (backup_path)) {
842 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
843 xmlpath.to_string(), backup_path.to_string())
848 sys::copy_file (xmlpath, backup_path);
850 catch(sys::filesystem_error& ex)
852 error << string_compose (_("Unable to make backup of state file %1 (%2)"),
853 xmlpath.to_string(), ex.what())
863 Session::load_options (const XMLNode& node)
867 LocaleGuard lg (X_("POSIX"));
869 Config->set_variables (node, ConfigVariableBase::Session);
871 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
872 if ((prop = child->property ("val")) != 0) {
873 _end_location_is_free = (prop->value() == "yes");
881 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
883 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
884 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
886 return owner & modified_by_session_or_user;
890 Session::get_options () const
893 LocaleGuard lg (X_("POSIX"));
895 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
897 child = option_root.add_child ("end-marker-is-free");
898 child->add_property ("val", _end_location_is_free ? "yes" : "no");
910 Session::get_template()
912 /* if we don't disable rec-enable, diskstreams
913 will believe they need to store their capture
914 sources in their state node.
917 disable_record (false);
923 Session::state(bool full_state)
925 XMLNode* node = new XMLNode("Session");
928 // store libardour version, just in case
930 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour3_major_version, libardour3_minor_version, libardour3_micro_version);
931 node->add_property("version", string(buf));
933 /* store configuration settings */
937 node->add_property ("name", _name);
938 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
939 node->add_property ("sample-rate", buf);
941 if (session_dirs.size() > 1) {
945 vector<space_and_path>::iterator i = session_dirs.begin();
946 vector<space_and_path>::iterator next;
948 ++i; /* skip the first one */
952 while (i != session_dirs.end()) {
956 if (next != session_dirs.end()) {
966 child = node->add_child ("Path");
967 child->add_content (p);
971 /* save the ID counter */
973 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
974 node->add_property ("id-counter", buf);
976 /* various options */
978 node->add_child_nocopy (get_options());
980 child = node->add_child ("Sources");
983 Glib::Mutex::Lock sl (source_lock);
985 for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
987 /* Don't save information about AudioFileSources that are empty */
989 boost::shared_ptr<AudioFileSource> fs;
991 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
993 /* Don't save sources that are empty, unless they're destructive (which are OK
994 if they are empty, because we will re-use them every time.)
997 if (!fs->destructive()) {
998 if (fs->length() == 0) {
1004 child->add_child_nocopy (siter->second->get_state());
1008 child = node->add_child ("Regions");
1011 Glib::Mutex::Lock rl (region_lock);
1013 for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
1015 /* only store regions not attached to playlists */
1017 if (i->second->playlist() == 0) {
1018 child->add_child_nocopy (i->second->state (true));
1023 child = node->add_child ("DiskStreams");
1026 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1027 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1028 if (!(*i)->hidden()) {
1029 child->add_child_nocopy ((*i)->get_state());
1035 node->add_child_nocopy (_locations.get_state());
1037 // for a template, just create a new Locations, populate it
1038 // with the default start and end, and get the state for that.
1040 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1041 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1044 end->set_end(compute_initial_length());
1046 node->add_child_nocopy (loc.get_state());
1049 child = node->add_child ("Bundles");
1051 Glib::Mutex::Lock lm (bundle_lock);
1052 for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
1053 boost::shared_ptr<UserBundle> b = boost::dynamic_pointer_cast<UserBundle> (*i);
1055 child->add_child_nocopy (b->get_state());
1060 child = node->add_child ("Routes");
1062 boost::shared_ptr<RouteList> r = routes.reader ();
1064 RoutePublicOrderSorter cmp;
1065 RouteList public_order (*r);
1066 public_order.sort (cmp);
1068 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1069 if (!(*i)->is_hidden()) {
1071 child->add_child_nocopy ((*i)->get_state());
1073 child->add_child_nocopy ((*i)->get_template());
1080 child = node->add_child ("EditGroups");
1081 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1082 child->add_child_nocopy ((*i)->get_state());
1085 child = node->add_child ("MixGroups");
1086 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1087 child->add_child_nocopy ((*i)->get_state());
1090 child = node->add_child ("Playlists");
1091 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1092 if (!(*i)->hidden()) {
1093 if (!(*i)->empty()) {
1095 child->add_child_nocopy ((*i)->get_state());
1097 child->add_child_nocopy ((*i)->get_template());
1103 child = node->add_child ("UnusedPlaylists");
1104 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1105 if (!(*i)->hidden()) {
1106 if (!(*i)->empty()) {
1108 child->add_child_nocopy ((*i)->get_state());
1110 child->add_child_nocopy ((*i)->get_template());
1118 child = node->add_child ("Click");
1119 child->add_child_nocopy (_click_io->state (full_state));
1123 child = node->add_child ("NamedSelections");
1124 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1126 child->add_child_nocopy ((*i)->get_state());
1131 node->add_child_nocopy (_tempo_map->get_state());
1133 node->add_child_nocopy (get_control_protocol_state());
1136 node->add_child_copy (*_extra_xml);
1143 Session::get_control_protocol_state ()
1145 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1146 return cpm.get_state();
1150 Session::set_state (const XMLNode& node)
1154 const XMLProperty* prop;
1157 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1159 if (node.name() != X_("Session")){
1160 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1164 if ((prop = node.property ("name")) != 0) {
1165 _name = prop->value ();
1168 if ((prop = node.property (X_("sample-rate"))) != 0) {
1170 _nominal_frame_rate = atoi (prop->value());
1172 if (_nominal_frame_rate != _current_frame_rate) {
1173 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1179 setup_raid_path(_session_dir->root_path().to_string());
1181 if ((prop = node.property (X_("id-counter"))) != 0) {
1183 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1184 ID::init_counter (x);
1186 /* old sessions used a timebased counter, so fake
1187 the startup ID counter based on a standard
1192 ID::init_counter (now);
1196 IO::disable_ports ();
1197 IO::disable_connecting ();
1199 /* Object loading order:
1217 if (use_config_midi_ports ()) {
1220 if ((child = find_named_node (node, "extra")) != 0) {
1221 _extra_xml = new XMLNode (*child);
1224 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1225 load_options (*child);
1226 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1227 load_options (*child);
1229 error << _("Session: XML state has no options section") << endmsg;
1232 if ((child = find_named_node (node, "Locations")) == 0) {
1233 error << _("Session: XML state has no locations section") << endmsg;
1235 } else if (_locations.set_state (*child)) {
1241 if ((location = _locations.auto_loop_location()) != 0) {
1242 set_auto_loop_location (location);
1245 if ((location = _locations.auto_punch_location()) != 0) {
1246 set_auto_punch_location (location);
1249 if ((location = _locations.end_location()) == 0) {
1250 _locations.add (end_location);
1252 delete end_location;
1253 end_location = location;
1256 if ((location = _locations.start_location()) == 0) {
1257 _locations.add (start_location);
1259 delete start_location;
1260 start_location = location;
1263 AudioFileSource::set_header_position_offset (start_location->start());
1265 if ((child = find_named_node (node, "Sources")) == 0) {
1266 error << _("Session: XML state has no sources section") << endmsg;
1268 } else if (load_sources (*child)) {
1272 if ((child = find_named_node (node, "Regions")) == 0) {
1273 error << _("Session: XML state has no Regions section") << endmsg;
1275 } else if (load_regions (*child)) {
1279 if ((child = find_named_node (node, "Playlists")) == 0) {
1280 error << _("Session: XML state has no playlists section") << endmsg;
1282 } else if (load_playlists (*child)) {
1286 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1288 } else if (load_unused_playlists (*child)) {
1292 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1293 if (load_named_selections (*child)) {
1298 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1299 error << _("Session: XML state has no diskstreams section") << endmsg;
1301 } else if (load_diskstreams (*child)) {
1305 if ((child = find_named_node (node, "Bundles")) == 0) {
1306 warning << _("Session: XML state has no bundles section (2.0 session?)") << endmsg;
1309 /* We can't load Bundles yet as they need to be able
1310 to convert from port names to Port objects, which can't happen until
1312 _bundle_xml_node = new XMLNode (*child);
1315 if ((child = find_named_node (node, "EditGroups")) == 0) {
1316 error << _("Session: XML state has no edit groups section") << endmsg;
1318 } else if (load_edit_groups (*child)) {
1322 if ((child = find_named_node (node, "MixGroups")) == 0) {
1323 error << _("Session: XML state has no mix groups section") << endmsg;
1325 } else if (load_mix_groups (*child)) {
1329 if ((child = find_named_node (node, "TempoMap")) == 0) {
1330 error << _("Session: XML state has no Tempo Map section") << endmsg;
1332 } else if (_tempo_map->set_state (*child)) {
1336 if ((child = find_named_node (node, "Routes")) == 0) {
1337 error << _("Session: XML state has no routes section") << endmsg;
1339 } else if (load_routes (*child)) {
1343 if ((child = find_named_node (node, "Click")) == 0) {
1344 warning << _("Session: XML state has no click section") << endmsg;
1345 } else if (_click_io) {
1346 _click_io->set_state (*child);
1349 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1350 ControlProtocolManager::instance().set_protocol_states (*child);
1353 /* here beginneth the second phase ... */
1355 StateReady (); /* EMIT SIGNAL */
1364 Session::load_routes (const XMLNode& node)
1367 XMLNodeConstIterator niter;
1368 RouteList new_routes;
1370 nlist = node.children();
1374 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1376 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1379 error << _("Session: cannot create Route from XML description.") << endmsg;
1383 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1385 new_routes.push_back (route);
1388 add_routes (new_routes, false);
1393 boost::shared_ptr<Route>
1394 Session::XMLRouteFactory (const XMLNode& node)
1396 if (node.name() != "Route") {
1397 return boost::shared_ptr<Route> ((Route*) 0);
1400 bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0);
1402 DataType type = DataType::AUDIO;
1403 const XMLProperty* prop = node.property("default-type");
1405 type = DataType(prop->value());
1407 assert(type != DataType::NIL);
1409 if (has_diskstream) {
1410 if (type == DataType::AUDIO) {
1411 boost::shared_ptr<Route> ret (new AudioTrack (*this, node));
1414 boost::shared_ptr<Route> ret (new MidiTrack (*this, node));
1418 boost::shared_ptr<Route> ret (new Route (*this, node));
1424 Session::load_regions (const XMLNode& node)
1427 XMLNodeConstIterator niter;
1428 boost::shared_ptr<Region> region;
1430 nlist = node.children();
1434 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1435 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1436 error << _("Session: cannot create Region from XML description.");
1437 const XMLProperty *name = (**niter).property("name");
1440 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1450 boost::shared_ptr<Region>
1451 Session::XMLRegionFactory (const XMLNode& node, bool full)
1453 const XMLProperty* type = node.property("type");
1457 if ( !type || type->value() == "audio" ) {
1459 return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
1461 } else if (type->value() == "midi") {
1463 return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
1467 } catch (failed_constructor& err) {
1468 return boost::shared_ptr<Region> ();
1471 return boost::shared_ptr<Region> ();
1474 boost::shared_ptr<AudioRegion>
1475 Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
1477 const XMLProperty* prop;
1478 boost::shared_ptr<Source> source;
1479 boost::shared_ptr<AudioSource> as;
1481 SourceList master_sources;
1482 uint32_t nchans = 1;
1485 if (node.name() != X_("Region")) {
1486 return boost::shared_ptr<AudioRegion>();
1489 if ((prop = node.property (X_("channels"))) != 0) {
1490 nchans = atoi (prop->value().c_str());
1493 if ((prop = node.property ("name")) == 0) {
1494 cerr << "no name for this region\n";
1498 if ((prop = node.property (X_("source-0"))) == 0) {
1499 if ((prop = node.property ("source")) == 0) {
1500 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1501 return boost::shared_ptr<AudioRegion>();
1505 PBD::ID s_id (prop->value());
1507 if ((source = source_by_id (s_id)) == 0) {
1508 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1509 return boost::shared_ptr<AudioRegion>();
1512 as = boost::dynamic_pointer_cast<AudioSource>(source);
1514 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1515 return boost::shared_ptr<AudioRegion>();
1518 sources.push_back (as);
1520 /* pickup other channels */
1522 for (uint32_t n=1; n < nchans; ++n) {
1523 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1524 if ((prop = node.property (buf)) != 0) {
1526 PBD::ID id2 (prop->value());
1528 if ((source = source_by_id (id2)) == 0) {
1529 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1530 return boost::shared_ptr<AudioRegion>();
1533 as = boost::dynamic_pointer_cast<AudioSource>(source);
1535 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1536 return boost::shared_ptr<AudioRegion>();
1538 sources.push_back (as);
1542 for (uint32_t n=1; n < nchans; ++n) {
1543 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1544 if ((prop = node.property (buf)) != 0) {
1546 PBD::ID id2 (prop->value());
1548 if ((source = source_by_id (id2)) == 0) {
1549 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1550 return boost::shared_ptr<AudioRegion>();
1553 as = boost::dynamic_pointer_cast<AudioSource>(source);
1555 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1556 return boost::shared_ptr<AudioRegion>();
1558 master_sources.push_back (as);
1563 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1565 /* a final detail: this is the one and only place that we know how long missing files are */
1567 if (region->whole_file()) {
1568 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1569 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1571 sfp->set_length (region->length());
1576 if (!master_sources.empty()) {
1577 if (master_sources.size() == nchans) {
1578 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1580 region->set_master_sources (master_sources);
1588 catch (failed_constructor& err) {
1589 return boost::shared_ptr<AudioRegion>();
1593 boost::shared_ptr<MidiRegion>
1594 Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
1596 const XMLProperty* prop;
1597 boost::shared_ptr<Source> source;
1598 boost::shared_ptr<MidiSource> ms;
1600 uint32_t nchans = 1;
1602 if (node.name() != X_("Region")) {
1603 return boost::shared_ptr<MidiRegion>();
1606 if ((prop = node.property (X_("channels"))) != 0) {
1607 nchans = atoi (prop->value().c_str());
1610 if ((prop = node.property ("name")) == 0) {
1611 cerr << "no name for this region\n";
1615 // Multiple midi channels? that's just crazy talk
1616 assert(nchans == 1);
1618 if ((prop = node.property (X_("source-0"))) == 0) {
1619 if ((prop = node.property ("source")) == 0) {
1620 error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
1621 return boost::shared_ptr<MidiRegion>();
1625 PBD::ID s_id (prop->value());
1627 if ((source = source_by_id (s_id)) == 0) {
1628 error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
1629 return boost::shared_ptr<MidiRegion>();
1632 ms = boost::dynamic_pointer_cast<MidiSource>(source);
1634 error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
1635 return boost::shared_ptr<MidiRegion>();
1638 sources.push_back (ms);
1641 boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
1642 /* a final detail: this is the one and only place that we know how long missing files are */
1644 if (region->whole_file()) {
1645 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1646 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1648 sfp->set_length (region->length());
1656 catch (failed_constructor& err) {
1657 return boost::shared_ptr<MidiRegion>();
1662 Session::get_sources_as_xml ()
1665 XMLNode* node = new XMLNode (X_("Sources"));
1666 Glib::Mutex::Lock lm (source_lock);
1668 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
1669 node->add_child_nocopy (i->second->get_state());
1676 Session::path_from_region_name (DataType type, string name, string identifier)
1678 char buf[PATH_MAX+1];
1680 SessionDirectory sdir(get_best_session_directory_for_new_source());
1681 sys::path source_dir = ((type == DataType::AUDIO)
1682 ? sdir.sound_path() : sdir.midi_path());
1684 string ext = ((type == DataType::AUDIO) ? ".wav" : ".mid");
1686 for (n = 0; n < 999999; ++n) {
1687 if (identifier.length()) {
1688 snprintf (buf, sizeof(buf), "%s%s%" PRIu32 "%s", name.c_str(),
1689 identifier.c_str(), n, ext.c_str());
1691 snprintf (buf, sizeof(buf), "%s-%" PRIu32 "%s", name.c_str(),
1695 sys::path source_path = source_dir / buf;
1697 if (!sys::exists (source_path)) {
1698 return source_path.to_string();
1702 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1711 Session::load_sources (const XMLNode& node)
1714 XMLNodeConstIterator niter;
1715 boost::shared_ptr<Source> source;
1717 nlist = node.children();
1721 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1724 if ((source = XMLSourceFactory (**niter)) == 0) {
1725 error << _("Session: cannot create Source from XML description.") << endmsg;
1729 catch (non_existent_source& err) {
1730 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1731 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1738 boost::shared_ptr<Source>
1739 Session::XMLSourceFactory (const XMLNode& node)
1741 if (node.name() != "Source") {
1742 return boost::shared_ptr<Source>();
1746 /* note: do peak building in another thread when loading session state */
1747 return SourceFactory::create (*this, node, true);
1750 catch (failed_constructor& err) {
1751 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1752 return boost::shared_ptr<Source>();
1757 Session::save_template (string template_name)
1761 if (_state_of_the_state & CannotSave) {
1765 sys::path user_template_dir(user_template_directory());
1769 sys::create_directories (user_template_dir);
1771 catch(sys::filesystem_error& ex)
1773 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"),
1774 user_template_dir.to_string(), ex.what()) << endmsg;
1778 tree.set_root (&get_template());
1780 sys::path template_file_path(user_template_dir);
1781 template_file_path /= template_name + template_suffix;
1783 if (sys::exists (template_file_path))
1785 warning << string_compose(_("Template \"%1\" already exists - new version not created"),
1786 template_file_path.to_string()) << endmsg;
1790 if (!tree.write (template_file_path.to_string())) {
1791 error << _("mix template not saved") << endmsg;
1799 Session::rename_template (string old_name, string new_name)
1801 sys::path old_path (user_template_directory());
1802 old_path /= old_name + template_suffix;
1804 sys::path new_path(user_template_directory());
1805 new_path /= new_name + template_suffix;
1807 if (sys::exists (new_path)) {
1808 warning << string_compose(_("Template \"%1\" already exists - template not renamed"),
1809 new_path.to_string()) << endmsg;
1814 sys::rename (old_path, new_path);
1822 Session::delete_template (string name)
1824 sys::path path = user_template_directory();
1825 path /= name + template_suffix;
1836 Session::refresh_disk_space ()
1839 struct statfs statfsbuf;
1840 vector<space_and_path>::iterator i;
1841 Glib::Mutex::Lock lm (space_lock);
1844 /* get freespace on every FS that is part of the session path */
1846 _total_free_4k_blocks = 0;
1848 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1849 statfs ((*i).path.c_str(), &statfsbuf);
1851 scale = statfsbuf.f_bsize/4096.0;
1853 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1854 _total_free_4k_blocks += (*i).blocks;
1860 Session::get_best_session_directory_for_new_source ()
1862 vector<space_and_path>::iterator i;
1863 string result = _session_dir->root_path().to_string();
1865 /* handle common case without system calls */
1867 if (session_dirs.size() == 1) {
1871 /* OK, here's the algorithm we're following here:
1873 We want to select which directory to use for
1874 the next file source to be created. Ideally,
1875 we'd like to use a round-robin process so as to
1876 get maximum performance benefits from splitting
1877 the files across multiple disks.
1879 However, in situations without much diskspace, an
1880 RR approach may end up filling up a filesystem
1881 with new files while others still have space.
1882 Its therefore important to pay some attention to
1883 the freespace in the filesystem holding each
1884 directory as well. However, if we did that by
1885 itself, we'd keep creating new files in the file
1886 system with the most space until it was as full
1887 as all others, thus negating any performance
1888 benefits of this RAID-1 like approach.
1890 So, we use a user-configurable space threshold. If
1891 there are at least 2 filesystems with more than this
1892 much space available, we use RR selection between them.
1893 If not, then we pick the filesystem with the most space.
1895 This gets a good balance between the two
1899 refresh_disk_space ();
1901 int free_enough = 0;
1903 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1904 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1909 if (free_enough >= 2) {
1910 /* use RR selection process, ensuring that the one
1914 i = last_rr_session_dir;
1917 if (++i == session_dirs.end()) {
1918 i = session_dirs.begin();
1921 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1922 if (create_session_directory ((*i).path)) {
1924 last_rr_session_dir = i;
1929 } while (i != last_rr_session_dir);
1933 /* pick FS with the most freespace (and that
1934 seems to actually work ...)
1937 vector<space_and_path> sorted;
1938 space_and_path_ascending_cmp cmp;
1940 sorted = session_dirs;
1941 sort (sorted.begin(), sorted.end(), cmp);
1943 for (i = sorted.begin(); i != sorted.end(); ++i) {
1944 if (create_session_directory ((*i).path)) {
1946 last_rr_session_dir = i;
1956 Session::load_playlists (const XMLNode& node)
1959 XMLNodeConstIterator niter;
1960 boost::shared_ptr<Playlist> playlist;
1962 nlist = node.children();
1966 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1968 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1969 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1977 Session::load_unused_playlists (const XMLNode& node)
1980 XMLNodeConstIterator niter;
1981 boost::shared_ptr<Playlist> playlist;
1983 nlist = node.children();
1987 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1989 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1990 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1994 // now manually untrack it
1996 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
2002 boost::shared_ptr<Playlist>
2003 Session::XMLPlaylistFactory (const XMLNode& node)
2006 return PlaylistFactory::create (*this, node);
2009 catch (failed_constructor& err) {
2010 return boost::shared_ptr<Playlist>();
2015 Session::load_named_selections (const XMLNode& node)
2018 XMLNodeConstIterator niter;
2021 nlist = node.children();
2025 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2027 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
2028 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
2036 Session::XMLNamedSelectionFactory (const XMLNode& node)
2039 return new NamedSelection (*this, node);
2042 catch (failed_constructor& err) {
2048 Session::automation_dir () const
2050 return Glib::build_filename (_path, "automation");
2054 Session::analysis_dir () const
2056 return Glib::build_filename (_path, "analysis");
2060 Session::load_bundles (XMLNode const & node)
2062 XMLNodeList nlist = node.children();
2063 XMLNodeConstIterator niter;
2067 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2068 if ((*niter)->name() == "InputBundle") {
2069 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, true)));
2070 } else if ((*niter)->name() == "OutputBundle") {
2071 add_bundle (boost::shared_ptr<UserBundle> (new UserBundle (**niter, false)));
2073 error << string_compose(_("Unknown node \"%1\" found in Bundles list from state file"), (*niter)->name()) << endmsg;
2082 Session::load_edit_groups (const XMLNode& node)
2084 return load_route_groups (node, true);
2088 Session::load_mix_groups (const XMLNode& node)
2090 return load_route_groups (node, false);
2094 Session::load_route_groups (const XMLNode& node, bool edit)
2096 XMLNodeList nlist = node.children();
2097 XMLNodeConstIterator niter;
2102 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2103 if ((*niter)->name() == "RouteGroup") {
2105 rg = add_edit_group ("");
2106 rg->set_state (**niter);
2108 rg = add_mix_group ("");
2109 rg->set_state (**niter);
2118 Session::auto_save()
2120 save_state (_current_snapshot_name);
2124 state_file_filter (const string &str, void *arg)
2126 return (str.length() > strlen(statefile_suffix) &&
2127 str.find (statefile_suffix) == (str.length() - strlen (statefile_suffix)));
2131 bool operator()(const string* a, const string* b) {
2137 remove_end(string* state)
2139 string statename(*state);
2141 string::size_type start,end;
2142 if ((start = statename.find_last_of ('/')) != string::npos) {
2143 statename = statename.substr (start+1);
2146 if ((end = statename.rfind(".ardour")) == string::npos) {
2147 end = statename.length();
2150 return new string(statename.substr (0, end));
2154 Session::possible_states (string path)
2156 PathScanner scanner;
2157 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2159 transform(states->begin(), states->end(), states->begin(), remove_end);
2162 sort (states->begin(), states->end(), cmp);
2168 Session::possible_states () const
2170 return possible_states(_path);
2174 Session::add_edit_group (string name)
2176 RouteGroup* rg = new RouteGroup (*this, name);
2177 edit_groups.push_back (rg);
2178 edit_group_added (rg); /* EMIT SIGNAL */
2184 Session::add_mix_group (string name)
2186 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2187 mix_groups.push_back (rg);
2188 mix_group_added (rg); /* EMIT SIGNAL */
2194 Session::remove_edit_group (RouteGroup& rg)
2196 list<RouteGroup*>::iterator i;
2198 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2199 (*i)->apply (&Route::drop_edit_group, this);
2200 edit_groups.erase (i);
2201 edit_group_removed (); /* EMIT SIGNAL */
2208 Session::remove_mix_group (RouteGroup& rg)
2210 list<RouteGroup*>::iterator i;
2212 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2213 (*i)->apply (&Route::drop_mix_group, this);
2214 mix_groups.erase (i);
2215 mix_group_removed (); /* EMIT SIGNAL */
2222 Session::mix_group_by_name (string name)
2224 list<RouteGroup *>::iterator i;
2226 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2227 if ((*i)->name() == name) {
2235 Session::edit_group_by_name (string name)
2237 list<RouteGroup *>::iterator i;
2239 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2240 if ((*i)->name() == name) {
2248 Session::begin_reversible_command (const string& name)
2250 current_trans = new UndoTransaction;
2251 current_trans->set_name (name);
2255 Session::commit_reversible_command (Command *cmd)
2260 current_trans->add_command (cmd);
2263 if (current_trans->empty()) {
2267 gettimeofday (&now, 0);
2268 current_trans->set_timestamp (now);
2270 _history.add (current_trans);
2273 Session::GlobalRouteBooleanState
2274 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2276 GlobalRouteBooleanState s;
2277 boost::shared_ptr<RouteList> r = routes.reader ();
2279 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2280 if (!(*i)->is_hidden()) {
2281 RouteBooleanState v;
2284 Route* r = (*i).get();
2285 v.second = (r->*method)();
2294 Session::GlobalRouteMeterState
2295 Session::get_global_route_metering ()
2297 GlobalRouteMeterState s;
2298 boost::shared_ptr<RouteList> r = routes.reader ();
2300 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2301 if (!(*i)->is_hidden()) {
2305 v.second = (*i)->meter_point();
2315 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2317 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2319 boost::shared_ptr<Route> r = (i->first.lock());
2322 r->set_meter_point (i->second, arg);
2328 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2330 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2332 boost::shared_ptr<Route> r = (i->first.lock());
2335 Route* rp = r.get();
2336 (rp->*method) (i->second, arg);
2342 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2344 set_global_route_boolean (s, &Route::set_mute, src);
2348 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2350 set_global_route_boolean (s, &Route::set_solo, src);
2354 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2356 set_global_route_boolean (s, &Route::set_record_enable, src);
2361 Session::global_mute_memento (void* src)
2363 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2367 Session::global_metering_memento (void* src)
2369 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2373 Session::global_solo_memento (void* src)
2375 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2379 Session::global_record_enable_memento (void* src)
2381 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2386 accept_all_non_peak_files (const string& path, void *arg)
2388 return (path.length() > 5 && path.find (peakfile_suffix) != (path.length() - 5));
2392 accept_all_state_files (const string& path, void *arg)
2394 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2398 Session::find_all_sources (string path, set<string>& result)
2403 if (!tree.read (path)) {
2407 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2412 XMLNodeConstIterator niter;
2414 nlist = node->children();
2418 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2422 if ((prop = (*niter)->property (X_("name"))) == 0) {
2426 if (prop->value()[0] == '/') {
2427 /* external file, ignore */
2431 sys::path source_path = _session_dir->sound_path ();
2433 source_path /= prop->value ();
2435 result.insert (source_path.to_string ());
2442 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2444 PathScanner scanner;
2445 vector<string*>* state_files;
2447 string this_snapshot_path;
2453 if (ripped[ripped.length()-1] == '/') {
2454 ripped = ripped.substr (0, ripped.length() - 1);
2457 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2459 if (state_files == 0) {
2464 this_snapshot_path = _path;
2465 this_snapshot_path += _current_snapshot_name;
2466 this_snapshot_path += statefile_suffix;
2468 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2470 if (exclude_this_snapshot && **i == this_snapshot_path) {
2474 if (find_all_sources (**i, result) < 0) {
2482 struct RegionCounter {
2483 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2484 AudioSourceList::iterator iter;
2485 boost::shared_ptr<Region> region;
2488 RegionCounter() : count (0) {}
2492 Session::cleanup_sources (Session::cleanup_report& rep)
2494 // FIXME: needs adaptation to midi
2496 vector<boost::shared_ptr<Source> > dead_sources;
2497 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2498 PathScanner scanner;
2500 vector<space_and_path>::iterator i;
2501 vector<space_and_path>::iterator nexti;
2502 vector<string*>* soundfiles;
2503 vector<string> unused;
2504 set<string> all_sources;
2509 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2512 /* step 1: consider deleting all unused playlists */
2514 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2517 status = AskAboutPlaylistDeletion (*x);
2526 playlists_tbd.push_back (*x);
2530 /* leave it alone */
2535 /* now delete any that were marked for deletion */
2537 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2538 (*x)->drop_references ();
2541 playlists_tbd.clear ();
2543 /* step 2: find all un-used sources */
2548 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
2550 SourceMap::iterator tmp;
2555 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2559 if (!i->second->used() && i->second->length() > 0) {
2560 dead_sources.push_back (i->second);
2561 i->second->GoingAway();
2567 /* build a list of all the possible sound directories for the session */
2569 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2574 SessionDirectory sdir ((*i).path);
2575 sound_path += sdir.sound_path().to_string();
2577 if (nexti != session_dirs.end()) {
2584 /* now do the same thing for the files that ended up in the sounds dir(s)
2585 but are not referenced as sources in any snapshot.
2588 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2590 if (soundfiles == 0) {
2594 /* find all sources, but don't use this snapshot because the
2595 state file on disk still references sources we may have already
2599 find_all_sources_across_snapshots (all_sources, true);
2601 /* add our current source list
2604 for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
2605 boost::shared_ptr<AudioFileSource> fs;
2607 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2608 all_sources.insert (fs->path());
2612 char tmppath1[PATH_MAX+1];
2613 char tmppath2[PATH_MAX+1];
2615 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2620 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2622 realpath(spath.c_str(), tmppath1);
2623 realpath((*i).c_str(), tmppath2);
2625 if (strcmp(tmppath1, tmppath2) == 0) {
2632 unused.push_back (spath);
2636 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2638 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2639 struct stat statbuf;
2641 rep.paths.push_back (*x);
2642 if (stat ((*x).c_str(), &statbuf) == 0) {
2643 rep.space += statbuf.st_size;
2648 /* don't move the file across filesystems, just
2649 stick it in the `dead_sound_dir_name' directory
2650 on whichever filesystem it was already on.
2653 if ((*x).find ("/sounds/") != string::npos) {
2655 /* old school, go up 1 level */
2657 newpath = Glib::path_get_dirname (*x); // "sounds"
2658 newpath = Glib::path_get_dirname (newpath); // "session-name"
2662 /* new school, go up 4 levels */
2664 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2665 newpath = Glib::path_get_dirname (newpath); // "session-name"
2666 newpath = Glib::path_get_dirname (newpath); // "interchange"
2667 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2671 newpath += dead_sound_dir_name;
2673 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2674 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2679 newpath += Glib::path_get_basename ((*x));
2681 if (access (newpath.c_str(), F_OK) == 0) {
2683 /* the new path already exists, try versioning */
2685 char buf[PATH_MAX+1];
2689 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2692 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2693 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2697 if (version == 999) {
2698 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2702 newpath = newpath_v;
2707 /* it doesn't exist, or we can't read it or something */
2711 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2712 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2713 (*x), newpath, strerror (errno))
2718 /* see if there an easy to find peakfile for this file, and remove it.
2721 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2722 peakpath += peakfile_suffix;
2724 if (access (peakpath.c_str(), W_OK) == 0) {
2725 if (::unlink (peakpath.c_str()) != 0) {
2726 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2727 peakpath, _path, strerror (errno))
2729 /* try to back out */
2730 rename (newpath.c_str(), _path.c_str());
2738 /* dump the history list */
2742 /* save state so we don't end up a session file
2743 referring to non-existent sources.
2749 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2755 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2757 // FIXME: needs adaptation for MIDI
2759 vector<space_and_path>::iterator i;
2760 string dead_sound_dir;
2761 struct dirent* dentry;
2762 struct stat statbuf;
2768 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2770 dead_sound_dir = (*i).path;
2771 dead_sound_dir += dead_sound_dir_name;
2773 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2777 while ((dentry = readdir (dead)) != 0) {
2779 /* avoid '.' and '..' */
2781 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2782 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2788 fullpath = dead_sound_dir;
2790 fullpath += dentry->d_name;
2792 if (stat (fullpath.c_str(), &statbuf)) {
2796 if (!S_ISREG (statbuf.st_mode)) {
2800 if (unlink (fullpath.c_str())) {
2801 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2802 fullpath, strerror (errno))
2806 rep.paths.push_back (dentry->d_name);
2807 rep.space += statbuf.st_size;
2818 Session::set_dirty ()
2820 bool was_dirty = dirty();
2822 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2826 DirtyChanged(); /* EMIT SIGNAL */
2832 Session::set_clean ()
2834 bool was_dirty = dirty();
2836 _state_of_the_state = Clean;
2840 DirtyChanged(); /* EMIT SIGNAL */
2845 Session::set_deletion_in_progress ()
2847 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2852 Session::add_controllable (boost::shared_ptr<Controllable> c)
2854 /* this adds a controllable to the list managed by the Session.
2855 this is a subset of those managed by the Controllable class
2856 itself, and represents the only ones whose state will be saved
2857 as part of the session.
2860 Glib::Mutex::Lock lm (controllables_lock);
2861 controllables.insert (c);
2864 struct null_deleter { void operator()(void const *) const {} };
2867 Session::remove_controllable (Controllable* c)
2869 if (_state_of_the_state | Deletion) {
2873 Glib::Mutex::Lock lm (controllables_lock);
2875 Controllables::iterator x = controllables.find(
2876 boost::shared_ptr<Controllable>(c, null_deleter()));
2878 if (x != controllables.end()) {
2879 controllables.erase (x);
2883 boost::shared_ptr<Controllable>
2884 Session::controllable_by_id (const PBD::ID& id)
2886 Glib::Mutex::Lock lm (controllables_lock);
2888 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2889 if ((*i)->id() == id) {
2894 return boost::shared_ptr<Controllable>();
2898 Session::add_instant_xml (XMLNode& node)
2900 Stateful::add_instant_xml (node, _path);
2901 Config->add_instant_xml (node);
2905 Session::instant_xml (const string& node_name)
2907 return Stateful::instant_xml (node_name, _path);
2911 Session::save_history (string snapshot_name)
2915 if (snapshot_name.empty()) {
2916 snapshot_name = _current_snapshot_name;
2919 const string history_filename = snapshot_name + history_suffix;
2920 const string backup_filename = history_filename + backup_suffix;
2921 const sys::path xml_path = _session_dir->root_path() / history_filename;
2922 const sys::path backup_path = _session_dir->root_path() / backup_filename;
2924 if (sys::exists (xml_path)) {
2927 sys::rename (xml_path, backup_path);
2929 catch (const sys::filesystem_error& err)
2931 error << _("could not backup old history file, current history not saved") << endmsg;
2937 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
2941 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2943 if (!tree.write (xml_path.to_string()))
2945 error << string_compose (_("history could not be saved to %1"), xml_path.to_string()) << endmsg;
2949 sys::remove (xml_path);
2950 sys::rename (backup_path, xml_path);
2952 catch (const sys::filesystem_error& err)
2954 error << string_compose (_("could not restore history file from backup %1 (%2)"),
2955 backup_path.to_string(), err.what()) << endmsg;
2965 Session::restore_history (string snapshot_name)
2969 if (snapshot_name.empty()) {
2970 snapshot_name = _current_snapshot_name;
2973 const string xml_filename = snapshot_name + history_suffix;
2974 const sys::path xml_path = _session_dir->root_path() / xml_filename;
2976 cerr << "Loading history from " << xml_path.to_string() << endmsg;
2978 if (!sys::exists (xml_path)) {
2979 info << string_compose (_("%1: no history file \"%2\" for this session."),
2980 _name, xml_path.to_string()) << endmsg;
2984 if (!tree.read (xml_path.to_string())) {
2985 error << string_compose (_("Could not understand session history file \"%1\""),
2986 xml_path.to_string()) << endmsg;
2993 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2996 UndoTransaction* ut = new UndoTransaction ();
2999 ut->set_name(t->property("name")->value());
3000 stringstream ss(t->property("tv_sec")->value());
3002 ss.str(t->property("tv_usec")->value());
3004 ut->set_timestamp(tv);
3006 for (XMLNodeConstIterator child_it = t->children().begin();
3007 child_it != t->children().end();
3010 XMLNode *n = *child_it;
3013 if (n->name() == "MementoCommand" ||
3014 n->name() == "MementoUndoCommand" ||
3015 n->name() == "MementoRedoCommand") {
3017 if ((c = memento_command_factory(n))) {
3021 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3023 if ((c = global_state_command_factory (*n))) {
3024 ut->add_command (c);
3027 } else if (n->name() == "DeltaCommand") {
3028 PBD::ID id(n->property("midi_source")->value());
3029 boost::shared_ptr<MidiSource> midi_source =
3030 boost::dynamic_pointer_cast<MidiSource, Source>(source_by_id(id));
3032 ut->add_command(new MidiModel::DeltaCommand(midi_source->model(), *n));
3034 error << "FIXME: Failed to downcast MidiSource for DeltaCommand" << endmsg;
3037 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3048 Session::config_changed (const char* parameter_name)
3050 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3052 if (PARAM_IS ("seamless-loop")) {
3054 } else if (PARAM_IS ("rf-speed")) {
3056 } else if (PARAM_IS ("auto-loop")) {
3058 } else if (PARAM_IS ("auto-input")) {
3060 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3061 /* auto-input only makes a difference if we're rolling */
3063 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3065 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3066 if ((*i)->record_enabled ()) {
3067 (*i)->monitor_input (!Config->get_auto_input());
3072 } else if (PARAM_IS ("punch-in")) {
3076 if ((location = _locations.auto_punch_location()) != 0) {
3078 if (Config->get_punch_in ()) {
3079 replace_event (Event::PunchIn, location->start());
3081 remove_event (location->start(), Event::PunchIn);
3085 } else if (PARAM_IS ("punch-out")) {
3089 if ((location = _locations.auto_punch_location()) != 0) {
3091 if (Config->get_punch_out()) {
3092 replace_event (Event::PunchOut, location->end());
3094 clear_events (Event::PunchOut);
3098 } else if (PARAM_IS ("edit-mode")) {
3100 Glib::Mutex::Lock lm (playlist_lock);
3102 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3103 (*i)->set_edit_mode (Config->get_edit_mode ());
3106 } else if (PARAM_IS ("use-video-sync")) {
3108 waiting_for_sync_offset = Config->get_use_video_sync();
3110 } else if (PARAM_IS ("mmc-control")) {
3112 //poke_midi_thread ();
3114 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
3117 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3120 } else if (PARAM_IS ("mmc-send-id")) {
3123 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3126 } else if (PARAM_IS ("midi-control")) {
3128 //poke_midi_thread ();
3130 } else if (PARAM_IS ("raid-path")) {
3132 setup_raid_path (Config->get_raid_path());
3134 } else if (PARAM_IS ("smpte-format")) {
3138 } else if (PARAM_IS ("video-pullup")) {
3142 } else if (PARAM_IS ("seamless-loop")) {
3144 if (play_loop && transport_rolling()) {
3145 // to reset diskstreams etc
3146 request_play_loop (true);
3149 } else if (PARAM_IS ("rf-speed")) {
3151 cumulative_rf_motion = 0;
3154 } else if (PARAM_IS ("click-sound")) {
3156 setup_click_sounds (1);
3158 } else if (PARAM_IS ("click-emphasis-sound")) {
3160 setup_click_sounds (-1);
3162 } else if (PARAM_IS ("clicking")) {
3164 if (Config->get_clicking()) {
3165 if (_click_io && click_data) { // don't require emphasis data
3172 } else if (PARAM_IS ("send-mtc")) {
3174 /* only set the internal flag if we have
3178 if (_mtc_port != 0) {
3179 session_send_mtc = Config->get_send_mtc();
3180 if (session_send_mtc) {
3181 /* mark us ready to send */
3182 next_quarter_frame_to_send = 0;
3185 session_send_mtc = false;
3188 } else if (PARAM_IS ("send-mmc")) {
3190 /* only set the internal flag if we have
3194 if (_mmc_port != 0) {
3195 session_send_mmc = Config->get_send_mmc();
3198 session_send_mmc = false;
3201 } else if (PARAM_IS ("midi-feedback")) {
3203 /* only set the internal flag if we have
3207 if (_mtc_port != 0) {
3208 session_midi_feedback = Config->get_midi_feedback();
3211 } else if (PARAM_IS ("jack-time-master")) {
3213 engine().reset_timebase ();
3215 } else if (PARAM_IS ("native-file-header-format")) {
3217 if (!first_file_header_format_reset) {
3218 reset_native_file_format ();
3221 first_file_header_format_reset = false;
3223 } else if (PARAM_IS ("native-file-data-format")) {
3225 if (!first_file_data_format_reset) {
3226 reset_native_file_format ();
3229 first_file_data_format_reset = false;
3231 } else if (PARAM_IS ("slave-source")) {
3232 set_slave_source (Config->get_slave_source());
3233 } else if (PARAM_IS ("remote-model")) {
3234 set_remote_control_ids ();
3235 } else if (PARAM_IS ("denormal-model")) {
3237 } else if (PARAM_IS ("history-depth")) {
3238 set_history_depth (Config->get_history_depth());
3239 } else if (PARAM_IS ("sync-all-route-ordering")) {
3250 Session::set_history_depth (uint32_t d)
3252 _history.set_depth (d);