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.
25 #include <sigc++/bind.h>
27 #include <cstdio> /* snprintf(3) ... grrr */
42 #include <sys/param.h>
43 #include <sys/mount.h>
47 #include <glibmm/thread.h>
49 #include <midi++/mmc.h>
50 #include <midi++/port.h>
52 #include <pbd/error.h>
53 #include <pbd/pathscanner.h>
54 #include <pbd/pthread_utils.h>
55 #include <pbd/strsplit.h>
56 #include <pbd/stacktrace.h>
57 #include <pbd/copyfile.h>
59 #include <ardour/audioengine.h>
60 #include <ardour/configuration.h>
61 #include <ardour/session.h>
62 #include <ardour/audio_diskstream.h>
63 #include <ardour/utils.h>
64 #include <ardour/audioplaylist.h>
65 #include <ardour/audiofilesource.h>
66 #include <ardour/silentfilesource.h>
67 #include <ardour/sndfilesource.h>
68 #include <ardour/sndfile_helpers.h>
69 #include <ardour/auditioner.h>
70 #include <ardour/export.h>
71 #include <ardour/redirect.h>
72 #include <ardour/send.h>
73 #include <ardour/insert.h>
74 #include <ardour/connection.h>
75 #include <ardour/slave.h>
76 #include <ardour/tempo.h>
77 #include <ardour/audio_track.h>
78 #include <ardour/cycle_timer.h>
79 #include <ardour/utils.h>
80 #include <ardour/named_selection.h>
81 #include <ardour/version.h>
82 #include <ardour/location.h>
83 #include <ardour/audioregion.h>
84 #include <ardour/crossfade.h>
85 #include <ardour/control_protocol_manager.h>
86 #include <ardour/region_factory.h>
87 #include <ardour/source_factory.h>
88 #include <ardour/playlist_factory.h>
90 #include <control_protocol/control_protocol.h>
96 using namespace ARDOUR;
100 Session::first_stage_init (string fullpath, string snapshot_name)
102 if (fullpath.length() == 0) {
104 throw failed_constructor();
107 char buf[PATH_MAX+1];
108 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
109 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
111 throw failed_constructor();
116 if (_path[_path.length()-1] != '/') {
120 if (Glib::file_test (_path, Glib::FILE_TEST_EXISTS) && ::access (_path.c_str(), W_OK)) {
121 cerr << "Session non-writable based on " << _path << endl;
124 cerr << "Session writable based on " << _path << endl;
128 set_history_depth (Config->get_history_depth());
131 /* these two are just provisional settings. set_state()
132 will likely override them.
135 _name = _current_snapshot_name = snapshot_name;
137 _current_frame_rate = _engine.frame_rate ();
138 _nominal_frame_rate = _current_frame_rate;
139 _base_frame_rate = _current_frame_rate;
141 _tempo_map = new TempoMap (_current_frame_rate);
142 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
144 g_atomic_int_set (&processing_prohibited, 0);
145 post_transport_work = PostTransportWork (0);
147 _transport_speed = 0;
148 _last_transport_speed = 0;
149 auto_play_legal = false;
150 transport_sub_state = 0;
151 _transport_frame = 0;
153 _requested_return_frame = -1;
154 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
155 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
156 _end_location_is_free = true;
157 g_atomic_int_set (&_record_status, Disabled);
158 loop_changing = false;
161 _last_roll_location = 0;
162 _last_record_location = 0;
163 pending_locate_frame = 0;
164 pending_locate_roll = false;
165 pending_locate_flush = false;
166 dstream_buffer_size = 0;
167 state_was_pending = false;
169 outbound_mtc_smpte_frame = 0;
170 next_quarter_frame_to_send = -1;
171 current_block_size = 0;
172 solo_update_disabled = false;
173 currently_soloing = false;
174 _was_seamless = Config->get_seamless_loop ();
175 _have_captured = false;
176 _worst_output_latency = 0;
177 _worst_input_latency = 0;
178 _worst_track_latency = 0;
179 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
183 session_send_mmc = false;
184 session_send_mtc = false;
185 post_transport_work = PostTransportWork (0);
186 g_atomic_int_set (&butler_should_do_transport_work, 0);
187 g_atomic_int_set (&butler_active, 0);
188 g_atomic_int_set (&_playback_load, 100);
189 g_atomic_int_set (&_capture_load, 100);
190 g_atomic_int_set (&_playback_load_min, 100);
191 g_atomic_int_set (&_capture_load_min, 100);
194 _gain_automation_buffer = 0;
195 _pan_automation_buffer = 0;
197 pending_abort = false;
198 pending_clear_substate = false;
199 destructive_index = 0;
201 first_file_data_format_reset = true;
202 first_file_header_format_reset = true;
203 butler_thread = (pthread_t) 0;
205 AudioDiskstream::allocate_working_buffers();
207 /* default short fade = 15ms */
209 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
210 SndFileSource::setup_standard_crossfades (frame_rate());
212 last_mmc_step.tv_sec = 0;
213 last_mmc_step.tv_usec = 0;
216 /* click sounds are unset by default, which causes us to internal
217 waveforms for clicks.
221 click_emphasis_length = 0;
224 process_function = &Session::process_with_events;
226 if (Config->get_use_video_sync()) {
227 waiting_for_sync_offset = true;
229 waiting_for_sync_offset = false;
234 _smpte_offset_negative = true;
235 last_smpte_valid = false;
239 last_rr_session_dir = session_dirs.begin();
240 refresh_disk_space ();
242 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
246 average_slave_delta = 1800; // !!! why 1800 ????
247 have_first_delta_accumulator = false;
248 delta_accumulator_cnt = 0;
249 slave_state = Stopped;
251 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
253 /* These are all static "per-class" signals */
255 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
256 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
257 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
258 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
259 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
260 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
262 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
264 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
266 /* stop IO objects from doing stuff until we're ready for them */
268 IO::disable_panners ();
269 IO::disable_ports ();
270 IO::disable_connecting ();
274 Session::second_stage_init (bool new_session)
276 AudioFileSource::set_peak_dir (peak_dir());
279 if (load_state (_current_snapshot_name)) {
282 remove_empty_sounds ();
285 if (start_butler_thread()) {
289 if (start_midi_thread ()) {
293 // set_state() will call setup_raid_path(), but if it's a new session we need
294 // to call setup_raid_path() here.
297 if (set_state (*state_tree->root())) {
301 setup_raid_path(_path);
304 /* we can't save till after ::when_engine_running() is called,
305 because otherwise we save state with no connections made.
306 therefore, we reset _state_of_the_state because ::set_state()
307 will have cleared it.
309 we also have to include Loading so that any events that get
310 generated between here and the end of ::when_engine_running()
311 will be processed directly rather than queued.
314 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
317 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
318 _locations.added.connect (mem_fun (this, &Session::locations_added));
319 setup_click_sounds (0);
320 setup_midi_control ();
322 /* Pay attention ... */
324 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
325 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
328 when_engine_running();
331 /* handle this one in a different way than all others, so that its clear what happened */
333 catch (AudioEngine::PortRegistrationFailure& err) {
342 BootMessage (_("Reset Remote Controls"));
344 send_full_time_code ();
345 _engine.transport_locate (0);
346 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
347 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
349 /* initial program change will be delivered later; see ::config_changed() */
351 BootMessage (_("Reset Control Protocols"));
353 ControlProtocolManager::instance().set_session (*this);
356 _end_location_is_free = true;
358 _end_location_is_free = false;
361 _state_of_the_state = Clean;
363 DirtyChanged (); /* EMIT SIGNAL */
365 if (state_was_pending) {
366 save_state (_current_snapshot_name);
367 remove_pending_capture_state ();
368 state_was_pending = false;
371 BootMessage (_("Session loading complete"));
377 Session::raid_path () const
381 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
386 return path.substr (0, path.length() - 1); // drop final colon
390 Session::setup_raid_path (string path)
392 string::size_type colon;
396 string::size_type len = path.length();
401 if (path.length() == 0) {
405 session_dirs.clear ();
407 for (string::size_type n = 0; n < len; ++n) {
408 if (path[n] == ':') {
415 /* no multiple search path, just one location (common case) */
419 session_dirs.push_back (sp);
422 AudioFileSource::set_search_path (Glib::build_filename(sp.path, sound_dir (false)));
428 while ((colon = remaining.find_first_of (':')) != string::npos) {
431 sp.path = remaining.substr (0, colon);
432 session_dirs.push_back (sp);
434 /* add sounds to file search path */
436 fspath += Glib::build_filename(sp.path, sound_dir (false));
439 remaining = remaining.substr (colon+1);
442 if (remaining.length()) {
448 fspath += Glib::build_filename(sp.path, sound_dir (false));
451 session_dirs.push_back (sp);
454 /* set the AudioFileSource search path */
456 AudioFileSource::set_search_path (fspath);
458 /* reset the round-robin soundfile path thingie */
460 last_rr_session_dir = session_dirs.begin();
464 Session::ensure_subdirs ()
470 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
471 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
475 /* if this is is an existing session with an old "sounds" directory, just use it. see Session::sound_dir() for more details */
477 if (!Glib::file_test (old_sound_dir(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
481 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
482 error << string_compose(_("Session: cannot create session sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
487 dir = dead_sound_dir ();
489 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
490 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
496 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
497 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
501 dir = analysis_dir ();
503 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
504 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
512 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
515 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
516 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
520 if (ensure_subdirs ()) {
524 /* check new_session so we don't overwrite an existing one */
526 if (!mix_template.empty()) {
527 std::string in_path = mix_template;
529 ifstream in(in_path.c_str());
532 string out_path = _path;
534 out_path += _statefile_suffix;
536 ofstream out(out_path.c_str());
541 // okay, session is set up. Treat like normal saved
542 // session from now on.
548 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
554 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
561 /* set initial start + end point */
563 start_location->set_end (0);
564 _locations.add (start_location);
566 end_location->set_end (initial_length);
567 _locations.add (end_location);
569 _state_of_the_state = Clean;
577 Session::load_diskstreams (const XMLNode& node)
580 XMLNodeConstIterator citer;
582 clist = node.children();
584 for (citer = clist.begin(); citer != clist.end(); ++citer) {
588 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
589 add_diskstream (dstream);
592 catch (failed_constructor& err) {
593 error << _("Session: could not load diskstream via XML state") << endmsg;
602 Session::maybe_write_autosave()
604 if (dirty() && record_status() != Recording) {
605 save_state("", true);
610 Session::remove_pending_capture_state ()
615 xml_path += _current_snapshot_name;
616 xml_path += _pending_suffix;
618 unlink (xml_path.c_str());
621 /** Rename a state file.
622 * @param snapshot_name Snapshot name.
625 Session::rename_state (string old_name, string new_name)
627 if (old_name == _current_snapshot_name || old_name == _name) {
628 /* refuse to rename the current snapshot or the "main" one */
632 const string old_xml_path = _path + old_name + _statefile_suffix;
633 const string new_xml_path = _path + new_name + _statefile_suffix;
635 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
636 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
640 /** Remove a state file.
641 * @param snapshot_name Snapshot name.
644 Session::remove_state (string snapshot_name)
646 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
647 /* refuse to remove the current snapshot or the "main" one */
651 const string xml_path = _path + snapshot_name + _statefile_suffix;
653 /* make a backup copy of the state file */
654 const string bak_path = xml_path + ".bak";
655 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
656 copy_file (xml_path, bak_path);
660 unlink (xml_path.c_str());
664 Session::save_state (string snapshot_name, bool pending)
670 if (!_writable || (_state_of_the_state & CannotSave)) {
674 if (!_engine.connected ()) {
675 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
680 tree.set_root (&get_state());
682 if (snapshot_name.empty()) {
683 snapshot_name = _current_snapshot_name;
688 /* proper save: use _statefile_suffix (.ardour in English) */
690 xml_path += snapshot_name;
691 xml_path += _statefile_suffix;
693 /* make a backup copy of the old file */
697 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
698 copy_file (xml_path, bak_path);
703 /* pending save: use _pending_suffix (.pending in English) */
705 xml_path += snapshot_name;
706 xml_path += _pending_suffix;
713 tmp_path += snapshot_name;
716 // cerr << "actually writing state to " << xml_path << endl;
718 if (!tree.write (tmp_path)) {
719 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
720 unlink (tmp_path.c_str());
725 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
726 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
727 unlink (tmp_path.c_str());
734 save_history (snapshot_name);
736 bool was_dirty = dirty();
738 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
742 DirtyChanged (); /* EMIT SIGNAL */
745 StateSaved (snapshot_name); /* EMIT SIGNAL */
752 Session::restore_state (string snapshot_name)
754 if (load_state (snapshot_name) == 0) {
755 set_state (*state_tree->root());
762 Session::load_state (string snapshot_name)
771 state_was_pending = false;
773 /* check for leftover pending state from a crashed capture attempt */
776 xmlpath += snapshot_name;
777 xmlpath += _pending_suffix;
779 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
781 /* there is pending state from a crashed capture attempt */
783 if (AskAboutPendingState()) {
784 state_was_pending = true;
788 if (!state_was_pending) {
791 xmlpath += snapshot_name;
792 xmlpath += _statefile_suffix;
795 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
796 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
800 state_tree = new XMLTree;
804 /* writable() really reflects the whole folder, but if for any
805 reason the session state file can't be written to, still
809 if (::access (xmlpath.c_str(), W_OK) != 0) {
813 if (!state_tree->read (xmlpath)) {
814 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
820 XMLNode& root (*state_tree->root());
822 if (root.name() != X_("Session")) {
823 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
829 const XMLProperty* prop;
832 if ((prop = root.property ("version")) == 0) {
833 /* no version implies very old version of Ardour */
837 major_version = atoi (prop->value()); // grab just the first number before the period
838 if (major_version < 2) {
847 backup_path += snapshot_name;
849 backup_path += _statefile_suffix;
851 /* don't make another copy if it already exists */
853 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
854 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
855 xmlpath, backup_path)
858 copy_file (xmlpath, backup_path);
860 /* if it fails, don't worry. right? */
868 Session::load_options (const XMLNode& node)
872 LocaleGuard lg (X_("POSIX"));
874 Config->set_variables (node, ConfigVariableBase::Session);
876 /* now reset MIDI ports because the session can have its own
882 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
883 if ((prop = child->property ("val")) != 0) {
884 _end_location_is_free = string_is_affirmative (prop->value());
892 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
894 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
895 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
897 return owner & modified_by_session_or_user;
901 Session::get_options () const
904 LocaleGuard lg (X_("POSIX"));
906 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
908 child = option_root.add_child ("end-marker-is-free");
909 child->add_property ("val", _end_location_is_free ? "yes" : "no");
921 Session::get_template()
923 /* if we don't disable rec-enable, diskstreams
924 will believe they need to store their capture
925 sources in their state node.
928 disable_record (false);
934 Session::state(bool full_state)
936 XMLNode* node = new XMLNode("Session");
939 // store libardour version, just in case
941 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour2_major_version, libardour2_minor_version, libardour2_micro_version);
942 node->add_property("version", string(buf));
944 /* store configuration settings */
948 node->add_property ("name", _name);
949 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
950 node->add_property ("sample-rate", buf);
952 if (session_dirs.size() > 1) {
956 vector<space_and_path>::iterator i = session_dirs.begin();
957 vector<space_and_path>::iterator next;
959 ++i; /* skip the first one */
963 while (i != session_dirs.end()) {
967 if (next != session_dirs.end()) {
977 child = node->add_child ("Path");
978 child->add_content (p);
982 /* save the ID counter */
984 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
985 node->add_property ("id-counter", buf);
987 /* various options */
989 node->add_child_nocopy (get_options());
991 child = node->add_child ("Sources");
994 Glib::Mutex::Lock sl (audio_source_lock);
996 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
998 /* Don't save information about AudioFileSources that are empty */
1000 boost::shared_ptr<AudioFileSource> fs;
1002 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
1004 /* destructive file sources are OK if they are empty, because
1005 we will re-use them every time.
1008 if (!fs->destructive()) {
1009 if (fs->length() == 0) {
1015 child->add_child_nocopy (siter->second->get_state());
1019 child = node->add_child ("Regions");
1022 Glib::Mutex::Lock rl (region_lock);
1024 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1026 /* only store regions not attached to playlists */
1028 if (i->second->playlist() == 0) {
1029 child->add_child_nocopy (i->second->state (true));
1034 child = node->add_child ("DiskStreams");
1037 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1038 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1039 if (!(*i)->hidden()) {
1040 child->add_child_nocopy ((*i)->get_state());
1046 node->add_child_nocopy (_locations.get_state());
1048 // for a template, just create a new Locations, populate it
1049 // with the default start and end, and get the state for that.
1051 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1052 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1055 end->set_end(compute_initial_length());
1057 node->add_child_nocopy (loc.get_state());
1060 child = node->add_child ("Connections");
1062 Glib::Mutex::Lock lm (connection_lock);
1063 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1064 if (!(*i)->system_dependent()) {
1065 child->add_child_nocopy ((*i)->get_state());
1070 child = node->add_child ("Routes");
1072 boost::shared_ptr<RouteList> r = routes.reader ();
1074 RoutePublicOrderSorter cmp;
1075 RouteList public_order (*r);
1076 public_order.sort (cmp);
1078 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1079 if (!(*i)->hidden()) {
1081 child->add_child_nocopy ((*i)->get_state());
1083 child->add_child_nocopy ((*i)->get_template());
1090 child = node->add_child ("EditGroups");
1091 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1092 child->add_child_nocopy ((*i)->get_state());
1095 child = node->add_child ("MixGroups");
1096 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1097 child->add_child_nocopy ((*i)->get_state());
1100 child = node->add_child ("Playlists");
1101 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1102 if (!(*i)->hidden()) {
1103 if (!(*i)->empty()) {
1105 child->add_child_nocopy ((*i)->get_state());
1107 child->add_child_nocopy ((*i)->get_template());
1113 child = node->add_child ("UnusedPlaylists");
1114 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1115 if (!(*i)->hidden()) {
1116 if (!(*i)->empty()) {
1118 child->add_child_nocopy ((*i)->get_state());
1120 child->add_child_nocopy ((*i)->get_template());
1128 child = node->add_child ("Click");
1129 child->add_child_nocopy (_click_io->state (full_state));
1133 child = node->add_child ("NamedSelections");
1134 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1136 child->add_child_nocopy ((*i)->get_state());
1141 node->add_child_nocopy (_tempo_map->get_state());
1143 node->add_child_nocopy (get_control_protocol_state());
1146 node->add_child_copy (*_extra_xml);
1153 Session::get_control_protocol_state ()
1155 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1156 return cpm.get_state();
1160 Session::set_state (const XMLNode& node)
1164 const XMLProperty* prop;
1167 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1169 if (node.name() != X_("Session")){
1170 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1174 if ((prop = node.property ("name")) != 0) {
1175 _name = prop->value ();
1178 if ((prop = node.property (X_("sample-rate"))) != 0) {
1180 _nominal_frame_rate = atoi (prop->value());
1182 if (_nominal_frame_rate != _current_frame_rate) {
1183 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1184 throw SRMismatchRejected();
1189 setup_raid_path(_path);
1191 if ((prop = node.property (X_("id-counter"))) != 0) {
1193 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1194 ID::init_counter (x);
1196 /* old sessions used a timebased counter, so fake
1197 the startup ID counter based on a standard
1202 ID::init_counter (now);
1206 IO::disable_ports ();
1207 IO::disable_connecting ();
1209 /* Object loading order:
1214 MIDI <= relies on data from Options/Config
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 (use_config_midi_ports ()) {
1242 if ((child = find_named_node (node, "Locations")) == 0) {
1243 error << _("Session: XML state has no locations section") << endmsg;
1245 } else if (_locations.set_state (*child)) {
1251 if ((location = _locations.auto_loop_location()) != 0) {
1252 set_auto_loop_location (location);
1255 if ((location = _locations.auto_punch_location()) != 0) {
1256 set_auto_punch_location (location);
1259 if ((location = _locations.end_location()) == 0) {
1260 _locations.add (end_location);
1262 delete end_location;
1263 end_location = location;
1266 if ((location = _locations.start_location()) == 0) {
1267 _locations.add (start_location);
1269 delete start_location;
1270 start_location = location;
1273 AudioFileSource::set_header_position_offset (start_location->start());
1275 if ((child = find_named_node (node, "Sources")) == 0) {
1276 error << _("Session: XML state has no sources section") << endmsg;
1278 } else if (load_sources (*child)) {
1282 if ((child = find_named_node (node, "Regions")) == 0) {
1283 error << _("Session: XML state has no Regions section") << endmsg;
1285 } else if (load_regions (*child)) {
1289 if ((child = find_named_node (node, "Playlists")) == 0) {
1290 error << _("Session: XML state has no playlists section") << endmsg;
1292 } else if (load_playlists (*child)) {
1296 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1298 } else if (load_unused_playlists (*child)) {
1302 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1303 if (load_named_selections (*child)) {
1308 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1309 error << _("Session: XML state has no diskstreams section") << endmsg;
1311 } else if (load_diskstreams (*child)) {
1315 if ((child = find_named_node (node, "Connections")) == 0) {
1316 error << _("Session: XML state has no connections section") << endmsg;
1318 } else if (load_connections (*child)) {
1322 if ((child = find_named_node (node, "EditGroups")) == 0) {
1323 error << _("Session: XML state has no edit groups section") << endmsg;
1325 } else if (load_edit_groups (*child)) {
1329 if ((child = find_named_node (node, "MixGroups")) == 0) {
1330 error << _("Session: XML state has no mix groups section") << endmsg;
1332 } else if (load_mix_groups (*child)) {
1336 if ((child = find_named_node (node, "TempoMap")) == 0) {
1337 error << _("Session: XML state has no Tempo Map section") << endmsg;
1339 } else if (_tempo_map->set_state (*child)) {
1343 if ((child = find_named_node (node, "Routes")) == 0) {
1344 error << _("Session: XML state has no routes section") << endmsg;
1346 } else if (load_routes (*child)) {
1350 if ((child = find_named_node (node, "Click")) == 0) {
1351 warning << _("Session: XML state has no click section") << endmsg;
1352 } else if (_click_io) {
1353 _click_io->set_state (*child);
1356 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1357 ControlProtocolManager::instance().set_protocol_states (*child);
1360 /* here beginneth the second phase ... */
1362 StateReady (); /* EMIT SIGNAL */
1371 Session::load_routes (const XMLNode& node)
1374 XMLNodeConstIterator niter;
1375 RouteList new_routes;
1377 nlist = node.children();
1381 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1382 XMLProperty* prop = (*niter)->property ("default-type");
1384 if (prop && prop->value() == "unknown" ) {
1385 std::cout << "ignoring route with type unknown. (video-track)" << std::endl;
1386 // Note: this may mess up remote_control IDs or more..
1390 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1393 error << _("Session: cannot create Route from XML description.") << endmsg;
1397 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1399 new_routes.push_back (route);
1402 add_routes (new_routes, false);
1407 boost::shared_ptr<Route>
1408 Session::XMLRouteFactory (const XMLNode& node)
1410 if (node.name() != "Route") {
1411 return boost::shared_ptr<Route> ((Route*) 0);
1414 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1415 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1418 boost::shared_ptr<Route> x (new Route (*this, node));
1424 Session::load_regions (const XMLNode& node)
1427 XMLNodeConstIterator niter;
1428 boost::shared_ptr<AudioRegion> 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<AudioRegion>
1451 Session::XMLRegionFactory (const XMLNode& node, bool full)
1453 const XMLProperty* prop;
1454 boost::shared_ptr<Source> source;
1455 boost::shared_ptr<AudioSource> as;
1457 SourceList master_sources;
1458 uint32_t nchans = 1;
1461 if (node.name() != X_("Region")) {
1462 return boost::shared_ptr<AudioRegion>();
1465 if ((prop = node.property (X_("channels"))) != 0) {
1466 nchans = atoi (prop->value().c_str());
1470 if ((prop = node.property ("name")) == 0) {
1471 cerr << "no name for this region\n";
1475 if ((prop = node.property (X_("source-0"))) == 0) {
1476 if ((prop = node.property ("source")) == 0) {
1477 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1478 return boost::shared_ptr<AudioRegion>();
1482 PBD::ID s_id (prop->value());
1484 if ((source = source_by_id (s_id)) == 0) {
1485 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1486 return boost::shared_ptr<AudioRegion>();
1489 as = boost::dynamic_pointer_cast<AudioSource>(source);
1491 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1492 return boost::shared_ptr<AudioRegion>();
1495 sources.push_back (as);
1497 /* pickup other channels */
1499 for (uint32_t n=1; n < nchans; ++n) {
1500 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1501 if ((prop = node.property (buf)) != 0) {
1503 PBD::ID id2 (prop->value());
1505 if ((source = source_by_id (id2)) == 0) {
1506 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1507 return boost::shared_ptr<AudioRegion>();
1510 as = boost::dynamic_pointer_cast<AudioSource>(source);
1512 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1513 return boost::shared_ptr<AudioRegion>();
1515 sources.push_back (as);
1519 for (uint32_t n=0; n < nchans; ++n) {
1520 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1521 if ((prop = node.property (buf)) != 0) {
1523 PBD::ID id2 (prop->value());
1525 if ((source = source_by_id (id2)) == 0) {
1526 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1527 return boost::shared_ptr<AudioRegion>();
1530 as = boost::dynamic_pointer_cast<AudioSource>(source);
1532 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1533 return boost::shared_ptr<AudioRegion>();
1535 master_sources.push_back (as);
1540 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1542 /* a final detail: this is the one and only place that we know how long missing files are */
1544 if (region->whole_file()) {
1545 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1546 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1548 sfp->set_length (region->length());
1553 if (!master_sources.empty()) {
1554 if (master_sources.size() != nchans) {
1555 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1557 region->set_master_sources (master_sources);
1565 catch (failed_constructor& err) {
1566 return boost::shared_ptr<AudioRegion>();
1571 Session::get_sources_as_xml ()
1574 XMLNode* node = new XMLNode (X_("Sources"));
1575 Glib::Mutex::Lock lm (audio_source_lock);
1577 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1578 node->add_child_nocopy (i->second->get_state());
1581 /* XXX get MIDI and other sources here */
1587 Session::path_from_region_name (string name, string identifier)
1589 char buf[PATH_MAX+1];
1591 string dir = discover_best_sound_dir ();
1593 for (n = 0; n < 999999; ++n) {
1594 if (identifier.length()) {
1595 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1596 identifier.c_str(), n);
1598 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1601 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1606 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1615 Session::load_sources (const XMLNode& node)
1618 XMLNodeConstIterator niter;
1619 boost::shared_ptr<Source> source;
1621 nlist = node.children();
1625 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1628 if ((source = XMLSourceFactory (**niter)) == 0) {
1629 error << _("Session: cannot create Source from XML description.") << endmsg;
1633 catch (non_existent_source& err) {
1634 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1635 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1642 boost::shared_ptr<Source>
1643 Session::XMLSourceFactory (const XMLNode& node)
1645 if (node.name() != "Source") {
1646 return boost::shared_ptr<Source>();
1650 /* note: do peak building in another thread when loading session state */
1651 return SourceFactory::create (*this, node, true);
1654 catch (failed_constructor& err) {
1655 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1656 return boost::shared_ptr<Source>();
1661 Session::save_template (string template_name)
1664 string xml_path, bak_path, template_path;
1666 if (_state_of_the_state & CannotSave) {
1671 string dir = template_dir();
1673 if ((dp = opendir (dir.c_str()))) {
1676 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1677 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1682 tree.set_root (&get_template());
1684 xml_path = Glib::build_filename(dir, template_name + _template_suffix);
1686 ifstream in(xml_path.c_str());
1689 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1695 if (!tree.write (xml_path)) {
1696 error << _("mix template not saved") << endmsg;
1704 Session::rename_template (string old_name, string new_name)
1706 string old_path = Glib::build_filename(template_dir(), old_name + _template_suffix);
1707 string new_path = Glib::build_filename(template_dir(), new_name + _template_suffix);
1709 return rename (old_path.c_str(), new_path.c_str());
1713 Session::delete_template (string name)
1715 string template_path = Glib::build_filename(template_dir(), name + _template_suffix);
1717 return remove (template_path.c_str());
1721 Session::refresh_disk_space ()
1724 struct statfs statfsbuf;
1725 vector<space_and_path>::iterator i;
1726 Glib::Mutex::Lock lm (space_lock);
1729 /* get freespace on every FS that is part of the session path */
1731 _total_free_4k_blocks = 0;
1733 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1734 statfs ((*i).path.c_str(), &statfsbuf);
1736 scale = statfsbuf.f_bsize/4096.0;
1738 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1739 _total_free_4k_blocks += (*i).blocks;
1745 Session::ensure_sound_dir (string path, string& result)
1750 /* Ensure that the parent directory exists */
1752 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1753 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1757 /* Ensure that the sounds directory exists */
1759 result = Glib::build_filename(path, sound_dir_name);
1761 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1762 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1766 dead = Glib::build_filename(path, dead_sound_dir_name);
1768 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1769 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1773 peak = Glib::build_filename(path, peak_dir_name);
1775 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1776 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1780 /* callers expect this to be terminated ... */
1787 Session::discover_best_sound_dir (bool destructive)
1789 vector<space_and_path>::iterator i;
1792 /* handle common case without system calls */
1794 if (session_dirs.size() == 1) {
1798 /* OK, here's the algorithm we're following here:
1800 We want to select which directory to use for
1801 the next file source to be created. Ideally,
1802 we'd like to use a round-robin process so as to
1803 get maximum performance benefits from splitting
1804 the files across multiple disks.
1806 However, in situations without much diskspace, an
1807 RR approach may end up filling up a filesystem
1808 with new files while others still have space.
1809 Its therefore important to pay some attention to
1810 the freespace in the filesystem holding each
1811 directory as well. However, if we did that by
1812 itself, we'd keep creating new files in the file
1813 system with the most space until it was as full
1814 as all others, thus negating any performance
1815 benefits of this RAID-1 like approach.
1817 So, we use a user-configurable space threshold. If
1818 there are at least 2 filesystems with more than this
1819 much space available, we use RR selection between them.
1820 If not, then we pick the filesystem with the most space.
1822 This gets a good balance between the two
1826 refresh_disk_space ();
1828 int free_enough = 0;
1830 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1831 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1836 if (free_enough >= 2) {
1838 bool found_it = false;
1840 /* use RR selection process, ensuring that the one
1844 i = last_rr_session_dir;
1847 if (++i == session_dirs.end()) {
1848 i = session_dirs.begin();
1851 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1852 if (ensure_sound_dir ((*i).path, result) == 0) {
1853 last_rr_session_dir = i;
1859 } while (i != last_rr_session_dir);
1862 result = sound_dir();
1867 /* pick FS with the most freespace (and that
1868 seems to actually work ...)
1871 vector<space_and_path> sorted;
1872 space_and_path_ascending_cmp cmp;
1874 sorted = session_dirs;
1875 sort (sorted.begin(), sorted.end(), cmp);
1877 for (i = sorted.begin(); i != sorted.end(); ++i) {
1878 if (ensure_sound_dir ((*i).path, result) == 0) {
1879 last_rr_session_dir = i;
1884 /* if the above fails, fall back to the most simplistic solution */
1886 if (i == sorted.end()) {
1895 Session::load_playlists (const XMLNode& node)
1898 XMLNodeConstIterator niter;
1899 boost::shared_ptr<Playlist> playlist;
1901 nlist = node.children();
1905 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1907 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1908 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1916 Session::load_unused_playlists (const XMLNode& node)
1919 XMLNodeConstIterator niter;
1920 boost::shared_ptr<Playlist> playlist;
1922 nlist = node.children();
1926 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1928 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1929 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1933 // now manually untrack it
1935 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1942 boost::shared_ptr<Playlist>
1943 Session::XMLPlaylistFactory (const XMLNode& node)
1946 return PlaylistFactory::create (*this, node);
1949 catch (failed_constructor& err) {
1950 return boost::shared_ptr<Playlist>();
1955 Session::load_named_selections (const XMLNode& node)
1958 XMLNodeConstIterator niter;
1961 nlist = node.children();
1965 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1967 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1968 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1976 Session::XMLNamedSelectionFactory (const XMLNode& node)
1979 return new NamedSelection (*this, node);
1982 catch (failed_constructor& err) {
1988 Session::dead_sound_dir () const
1991 res += dead_sound_dir_name;
1997 Session::old_sound_dir (bool with_path) const
2005 res += old_sound_dir_name;
2011 Session::sound_dir (bool with_path) const
2015 vector<string> parts;
2023 parts.push_back(interchange_dir_name);
2024 parts.push_back(legalize_for_path (_name));
2025 parts.push_back(sound_dir_name);
2027 res += Glib::build_filename(parts);
2034 /* if this already exists, don't check for the old session sound directory */
2036 if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2040 /* possibly support old session structure */
2043 string old_withpath;
2045 old_nopath += old_sound_dir_name;
2048 old_withpath = _path;
2049 old_withpath += old_sound_dir_name;
2051 if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2053 return old_withpath;
2058 /* ok, old "sounds" directory isn't there, return the new path */
2064 Session::peak_dir () const
2066 return Glib::build_filename (_path, peak_dir_name);
2070 Session::automation_dir () const
2072 return Glib::build_filename (_path, "automation");
2076 Session::analysis_dir () const
2078 return Glib::build_filename (_path, "analysis");
2082 Session::template_dir ()
2084 return Glib::build_filename (get_user_ardour_path(), "templates");
2088 Session::route_template_dir ()
2090 return Glib::build_filename (get_user_ardour_path(), "route_templates");
2094 Session::export_dir () const
2096 return Glib::build_filename (_path, export_dir_name);
2100 Session::suffixed_search_path (string suffix, bool data)
2104 path += get_user_ardour_path();
2105 if (path[path.length()-1] != ':') {
2110 path += get_system_data_path();
2112 path += get_system_module_path();
2115 vector<string> split_path;
2117 split (path, split_path, ':');
2120 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2125 if (distance (i, split_path.end()) != 1) {
2134 Session::template_path ()
2136 return suffixed_search_path (X_("templates"), true);
2141 Session::route_template_path ()
2143 return suffixed_search_path (X_("route_templates"), true);
2147 Session::control_protocol_path ()
2149 char *p = getenv ("ARDOUR_CONTROL_SURFACE_PATH");
2153 return suffixed_search_path (X_("surfaces"), false);
2157 Session::load_connections (const XMLNode& node)
2159 XMLNodeList nlist = node.children();
2160 XMLNodeConstIterator niter;
2164 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2165 if ((*niter)->name() == "InputConnection") {
2166 add_connection (new ARDOUR::InputConnection (**niter));
2167 } else if ((*niter)->name() == "OutputConnection") {
2168 add_connection (new ARDOUR::OutputConnection (**niter));
2170 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2179 Session::load_edit_groups (const XMLNode& node)
2181 return load_route_groups (node, true);
2185 Session::load_mix_groups (const XMLNode& node)
2187 return load_route_groups (node, false);
2191 Session::load_route_groups (const XMLNode& node, bool edit)
2193 XMLNodeList nlist = node.children();
2194 XMLNodeConstIterator niter;
2199 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2200 if ((*niter)->name() == "RouteGroup") {
2202 rg = add_edit_group ("");
2203 rg->set_state (**niter);
2205 rg = add_mix_group ("");
2206 rg->set_state (**niter);
2215 state_file_filter (const string &str, void *arg)
2217 return (str.length() > strlen(Session::statefile_suffix()) &&
2218 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2222 bool operator()(const string* a, const string* b) {
2228 remove_end(string* state)
2230 string statename(*state);
2232 string::size_type start,end;
2233 if ((start = statename.find_last_of ('/')) != string::npos) {
2234 statename = statename.substr (start+1);
2237 if ((end = statename.rfind(".ardour")) == string::npos) {
2238 end = statename.length();
2241 return new string(statename.substr (0, end));
2245 Session::possible_states (string path)
2247 PathScanner scanner;
2248 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2250 transform(states->begin(), states->end(), states->begin(), remove_end);
2253 sort (states->begin(), states->end(), cmp);
2259 Session::possible_states () const
2261 return possible_states(_path);
2265 Session::auto_save()
2267 save_state (_current_snapshot_name);
2271 Session::add_edit_group (string name)
2273 RouteGroup* rg = new RouteGroup (*this, name);
2274 edit_groups.push_back (rg);
2275 edit_group_added (rg); /* EMIT SIGNAL */
2281 Session::add_mix_group (string name)
2283 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2284 mix_groups.push_back (rg);
2285 mix_group_added (rg); /* EMIT SIGNAL */
2291 Session::remove_edit_group (RouteGroup& rg)
2293 list<RouteGroup*>::iterator i;
2295 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2296 (*i)->apply (&Route::drop_edit_group, this);
2297 edit_groups.erase (i);
2298 edit_group_removed (); /* EMIT SIGNAL */
2305 Session::remove_mix_group (RouteGroup& rg)
2307 list<RouteGroup*>::iterator i;
2309 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2310 (*i)->apply (&Route::drop_mix_group, this);
2311 mix_groups.erase (i);
2312 mix_group_removed (); /* EMIT SIGNAL */
2319 Session::mix_group_by_name (string name)
2321 list<RouteGroup *>::iterator i;
2323 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2324 if ((*i)->name() == name) {
2332 Session::edit_group_by_name (string name)
2334 list<RouteGroup *>::iterator i;
2336 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2337 if ((*i)->name() == name) {
2345 Session::begin_reversible_command (string name)
2347 current_trans = new UndoTransaction;
2348 current_trans->set_name (name);
2352 Session::commit_reversible_command (Command *cmd)
2357 current_trans->add_command (cmd);
2360 if (current_trans->empty()) {
2364 gettimeofday (&now, 0);
2365 current_trans->set_timestamp (now);
2367 _history.add (current_trans);
2370 Session::GlobalRouteBooleanState
2371 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2373 GlobalRouteBooleanState s;
2374 boost::shared_ptr<RouteList> r = routes.reader ();
2376 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2377 if (!(*i)->hidden()) {
2378 RouteBooleanState v;
2381 Route* r = (*i).get();
2382 v.second = (r->*method)();
2391 Session::GlobalRouteMeterState
2392 Session::get_global_route_metering ()
2394 GlobalRouteMeterState s;
2395 boost::shared_ptr<RouteList> r = routes.reader ();
2397 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2398 if (!(*i)->hidden()) {
2402 v.second = (*i)->meter_point();
2412 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2414 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2416 boost::shared_ptr<Route> r = (i->first.lock());
2419 r->set_meter_point (i->second, arg);
2425 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2427 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2429 boost::shared_ptr<Route> r = (i->first.lock());
2432 Route* rp = r.get();
2433 (rp->*method) (i->second, arg);
2439 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2441 set_global_route_boolean (s, &Route::set_mute, src);
2445 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2447 set_global_route_boolean (s, &Route::set_solo, src);
2451 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2453 set_global_route_boolean (s, &Route::set_record_enable, src);
2458 Session::global_mute_memento (void* src)
2460 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2464 Session::global_metering_memento (void* src)
2466 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2470 Session::global_solo_memento (void* src)
2472 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2476 Session::global_record_enable_memento (void* src)
2478 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2483 template_filter (const string &str, void *arg)
2485 return (str.length() > strlen(Session::template_suffix()) &&
2486 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2490 Session::get_template_list (list<string> &template_names)
2492 vector<string *> *templates;
2493 PathScanner scanner;
2496 path = template_path ();
2498 templates = scanner (path, template_filter, 0, false, true);
2500 vector<string*>::iterator i;
2501 for (i = templates->begin(); i != templates->end(); ++i) {
2502 string fullpath = *(*i);
2505 start = fullpath.find_last_of ('/') + 1;
2506 if ((end = fullpath.find_last_of ('.')) <0) {
2507 end = fullpath.length();
2510 template_names.push_back(fullpath.substr(start, (end-start)));
2515 Session::get_route_templates (vector<RouteTemplateInfo>& template_names)
2517 vector<string *> *templates;
2518 PathScanner scanner;
2521 path = route_template_path ();
2523 templates = scanner (path, template_filter, 0, false, true);
2529 for (vector<string*>::iterator i = templates->begin(); i != templates->end(); ++i) {
2530 string fullpath = *(*i);
2534 if (!tree.read (fullpath.c_str())) {
2538 XMLNode* root = tree.root();
2540 RouteTemplateInfo rti;
2542 rti.name = IO::name_from_state (*root->children().front());
2543 rti.path = fullpath;
2545 template_names.push_back (rti);
2552 Session::read_favorite_dirs (FavoriteDirs & favs)
2554 Glib::ustring path = Glib::build_filename (get_user_ardour_path(), "favorite_dirs");
2556 ifstream fav (path.c_str());
2561 if (errno != ENOENT) {
2562 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2573 getline(fav, newfav);
2579 favs.push_back (newfav);
2586 Session::write_favorite_dirs (FavoriteDirs & favs)
2588 Glib::ustring path = Glib::build_filename (get_user_ardour_path(), "favorite_dirs");
2590 ofstream fav (path.c_str());
2596 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2597 fav << (*i) << endl;
2604 accept_all_non_peak_files (const string& path, void *arg)
2606 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2610 accept_all_state_files (const string& path, void *arg)
2612 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2616 Session::find_all_sources (string path, set<string>& result)
2621 if (!tree.read (path)) {
2625 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2630 XMLNodeConstIterator niter;
2632 nlist = node->children();
2636 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2640 if ((prop = (*niter)->property (X_("name"))) == 0) {
2644 if (prop->value()[0] == '/') {
2645 /* external file, ignore */
2649 /* now we have to actually find the file */
2656 if (AudioFileSource::find (prop->value(), true, false, is_new, chan, path, name)) {
2657 cerr << "Got " << path << " from XML source with prop = " << prop->value() << endl;
2658 result.insert (path);
2666 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2668 PathScanner scanner;
2669 vector<string*>* state_files;
2671 string this_snapshot_path;
2677 if (ripped[ripped.length()-1] == '/') {
2678 ripped = ripped.substr (0, ripped.length() - 1);
2681 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2683 if (state_files == 0) {
2688 this_snapshot_path = _path;
2689 this_snapshot_path += _current_snapshot_name;
2690 this_snapshot_path += _statefile_suffix;
2692 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2694 if (exclude_this_snapshot && **i == this_snapshot_path) {
2698 if (find_all_sources (**i, result) < 0) {
2706 struct RegionCounter {
2707 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2708 AudioSourceList::iterator iter;
2709 boost::shared_ptr<Region> region;
2712 RegionCounter() : count (0) {}
2716 Session::cleanup_sources (Session::cleanup_report& rep)
2718 vector<boost::shared_ptr<Source> > dead_sources;
2719 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2720 PathScanner scanner;
2722 vector<space_and_path>::iterator i;
2723 vector<space_and_path>::iterator nexti;
2724 vector<string*>* soundfiles;
2725 vector<string> unused;
2726 set<string> all_sources;
2731 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2734 /* step 1: consider deleting all unused playlists */
2736 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2739 status = AskAboutPlaylistDeletion (*x);
2748 playlists_tbd.push_back (*x);
2752 /* leave it alone */
2757 /* now delete any that were marked for deletion */
2759 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2760 (*x)->drop_references ();
2763 playlists_tbd.clear ();
2765 /* step 2: find all un-used sources */
2770 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2772 AudioSourceList::iterator tmp;
2777 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2781 if (!i->second->used() && i->second->length() > 0) {
2782 dead_sources.push_back (i->second);
2783 i->second->GoingAway();
2789 /* build a list of all the possible sound directories for the session */
2791 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2796 sound_path += (*i).path;
2797 sound_path += sound_dir (false);
2799 if (nexti != session_dirs.end()) {
2806 /* now do the same thing for the files that ended up in the sounds dir(s)
2807 but are not referenced as sources in any snapshot.
2810 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2812 if (soundfiles == 0) {
2816 /* find all sources, but don't use this snapshot because the
2817 state file on disk still references sources we may have already
2821 find_all_sources_across_snapshots (all_sources, true);
2823 /* add our current source list
2826 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2827 boost::shared_ptr<AudioFileSource> fs;
2829 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2830 all_sources.insert (fs->path());
2834 char tmppath1[PATH_MAX+1];
2835 char tmppath2[PATH_MAX+1];
2837 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2842 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2844 realpath(spath.c_str(), tmppath1);
2845 realpath((*i).c_str(), tmppath2);
2847 cerr << "comparing " << tmppath1 << " and " << tmppath2 << endl;
2849 if (strcmp(tmppath1, tmppath2) == 0) {
2856 unused.push_back (spath);
2860 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2862 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2863 struct stat statbuf;
2865 rep.paths.push_back (*x);
2866 if (stat ((*x).c_str(), &statbuf) == 0) {
2867 rep.space += statbuf.st_size;
2872 /* don't move the file across filesystems, just
2873 stick it in the `dead_sound_dir_name' directory
2874 on whichever filesystem it was already on.
2877 if ((*x).find ("/sounds/") != string::npos) {
2879 /* old school, go up 1 level */
2881 newpath = Glib::path_get_dirname (*x); // "sounds"
2882 newpath = Glib::path_get_dirname (newpath); // "session-name"
2886 /* new school, go up 4 levels */
2888 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2889 newpath = Glib::path_get_dirname (newpath); // "session-name"
2890 newpath = Glib::path_get_dirname (newpath); // "interchange"
2891 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2895 newpath += dead_sound_dir_name;
2897 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2898 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2903 newpath += Glib::path_get_basename ((*x));
2905 if (access (newpath.c_str(), F_OK) == 0) {
2907 /* the new path already exists, try versioning */
2909 char buf[PATH_MAX+1];
2913 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2916 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2917 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2921 if (version == 999) {
2922 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2926 newpath = newpath_v;
2931 /* it doesn't exist, or we can't read it or something */
2935 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2936 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2937 (*x), newpath, strerror (errno))
2942 /* see if there an easy to find peakfile for this file, and remove it.
2945 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2946 peakpath += ".peak";
2948 if (access (peakpath.c_str(), W_OK) == 0) {
2949 if (::unlink (peakpath.c_str()) != 0) {
2950 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2951 peakpath, _path, strerror (errno))
2953 /* try to back out */
2954 rename (newpath.c_str(), _path.c_str());
2962 /* dump the history list */
2966 /* save state so we don't end up a session file
2967 referring to non-existent sources.
2973 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2979 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2981 vector<space_and_path>::iterator i;
2982 string dead_sound_dir;
2983 struct dirent* dentry;
2984 struct stat statbuf;
2990 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2992 dead_sound_dir = (*i).path;
2993 dead_sound_dir += dead_sound_dir_name;
2995 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2999 while ((dentry = readdir (dead)) != 0) {
3001 /* avoid '.' and '..' */
3003 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
3004 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
3010 fullpath = dead_sound_dir;
3012 fullpath += dentry->d_name;
3014 if (stat (fullpath.c_str(), &statbuf)) {
3018 if (!S_ISREG (statbuf.st_mode)) {
3022 if (unlink (fullpath.c_str())) {
3023 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3024 fullpath, strerror (errno))
3028 rep.paths.push_back (dentry->d_name);
3029 rep.space += statbuf.st_size;
3040 Session::set_dirty ()
3042 bool was_dirty = dirty();
3044 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3048 DirtyChanged(); /* EMIT SIGNAL */
3054 Session::set_clean ()
3056 bool was_dirty = dirty();
3058 _state_of_the_state = Clean;
3062 DirtyChanged(); /* EMIT SIGNAL */
3067 Session::set_deletion_in_progress ()
3069 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3074 Session::add_controllable (Controllable* c)
3076 /* this adds a controllable to the list managed by the Session.
3077 this is a subset of those managed by the Controllable class
3078 itself, and represents the only ones whose state will be saved
3079 as part of the session.
3082 Glib::Mutex::Lock lm (controllables_lock);
3083 controllables.insert (c);
3087 Session::remove_controllable (Controllable* c)
3089 if (_state_of_the_state | Deletion) {
3093 Glib::Mutex::Lock lm (controllables_lock);
3095 Controllables::iterator x = controllables.find (c);
3097 if (x != controllables.end()) {
3098 controllables.erase (x);
3103 Session::controllable_by_id (const PBD::ID& id)
3105 Glib::Mutex::Lock lm (controllables_lock);
3107 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3108 if ((*i)->id() == id) {
3117 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3120 Stateful::add_instant_xml (node, dir);
3122 Config->add_instant_xml (node, get_user_ardour_path());
3126 Session::save_history (string snapshot_name)
3136 if (snapshot_name.empty()) {
3137 snapshot_name = _current_snapshot_name;
3140 xml_path = _path + snapshot_name + ".history";
3142 bak_path = xml_path + ".bak";
3144 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && ::rename (xml_path.c_str(), bak_path.c_str())) {
3145 error << _("could not backup old history file, current history not saved.") << endmsg;
3149 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3153 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3155 if (!tree.write (xml_path))
3157 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3159 /* don't leave a corrupt file lying around if it is
3163 if (unlink (xml_path.c_str())) {
3164 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3166 if (rename (bak_path.c_str(), xml_path.c_str()))
3168 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3179 Session::restore_history (string snapshot_name)
3184 if (snapshot_name.empty()) {
3185 snapshot_name = _current_snapshot_name;
3189 xmlpath = _path + snapshot_name + ".history";
3190 info << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3192 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3196 if (!tree.read (xmlpath)) {
3197 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3201 /* replace history */
3204 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3207 UndoTransaction* ut = new UndoTransaction ();
3210 ut->set_name(t->property("name")->value());
3211 stringstream ss(t->property("tv_sec")->value());
3213 ss.str(t->property("tv_usec")->value());
3215 ut->set_timestamp(tv);
3217 for (XMLNodeConstIterator child_it = t->children().begin();
3218 child_it != t->children().end();
3221 XMLNode *n = *child_it;
3224 if (n->name() == "MementoCommand" ||
3225 n->name() == "MementoUndoCommand" ||
3226 n->name() == "MementoRedoCommand") {
3228 if ((c = memento_command_factory(n))) {
3232 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3234 if ((c = global_state_command_factory (*n))) {
3235 ut->add_command (c);
3240 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3251 Session::config_changed (const char* parameter_name)
3253 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3255 if (PARAM_IS ("seamless-loop")) {
3257 } else if (PARAM_IS ("rf-speed")) {
3259 } else if (PARAM_IS ("auto-loop")) {
3261 } else if (PARAM_IS ("auto-input")) {
3263 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3264 /* auto-input only makes a difference if we're rolling */
3266 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3268 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3269 if ((*i)->record_enabled ()) {
3270 (*i)->monitor_input (!Config->get_auto_input());
3275 } else if (PARAM_IS ("punch-in")) {
3279 if ((location = _locations.auto_punch_location()) != 0) {
3281 if (Config->get_punch_in ()) {
3282 replace_event (Event::PunchIn, location->start());
3284 remove_event (location->start(), Event::PunchIn);
3288 } else if (PARAM_IS ("punch-out")) {
3292 if ((location = _locations.auto_punch_location()) != 0) {
3294 if (Config->get_punch_out()) {
3295 replace_event (Event::PunchOut, location->end());
3297 clear_events (Event::PunchOut);
3301 } else if (PARAM_IS ("edit-mode")) {
3303 Glib::Mutex::Lock lm (playlist_lock);
3305 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3306 (*i)->set_edit_mode (Config->get_edit_mode ());
3309 } else if (PARAM_IS ("use-video-sync")) {
3311 waiting_for_sync_offset = Config->get_use_video_sync();
3313 } else if (PARAM_IS ("mmc-control")) {
3315 poke_midi_thread ();
3317 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-device-id")) {
3319 set_mmc_receive_device_id (Config->get_mmc_receive_device_id());
3321 } else if (PARAM_IS ("mmc-send-device-id")) {
3323 set_mmc_send_device_id (Config->get_mmc_send_device_id());
3325 } else if (PARAM_IS ("midi-control")) {
3327 poke_midi_thread ();
3329 } else if (PARAM_IS ("raid-path")) {
3331 setup_raid_path (Config->get_raid_path());
3333 } else if (PARAM_IS ("smpte-format")) {
3337 } else if (PARAM_IS ("video-pullup")) {
3341 } else if (PARAM_IS ("seamless-loop")) {
3343 if (play_loop && transport_rolling()) {
3344 // to reset diskstreams etc
3345 request_play_loop (true);
3348 } else if (PARAM_IS ("rf-speed")) {
3350 cumulative_rf_motion = 0;
3353 } else if (PARAM_IS ("click-sound")) {
3355 setup_click_sounds (1);
3357 } else if (PARAM_IS ("click-emphasis-sound")) {
3359 setup_click_sounds (-1);
3361 } else if (PARAM_IS ("clicking")) {
3363 if (Config->get_clicking()) {
3364 if (_click_io && click_data) { // don't require emphasis data
3371 } else if (PARAM_IS ("send-mtc")) {
3373 /* only set the internal flag if we have
3377 if (_mtc_port != 0) {
3378 session_send_mtc = Config->get_send_mtc();
3379 if (session_send_mtc) {
3380 /* mark us ready to send */
3381 next_quarter_frame_to_send = 0;
3384 session_send_mtc = false;
3387 } else if (PARAM_IS ("send-mmc")) {
3389 /* only set the internal flag if we have
3393 if (_mmc_port != 0) {
3394 session_send_mmc = Config->get_send_mmc();
3397 session_send_mmc = false;
3400 } else if (PARAM_IS ("midi-feedback")) {
3402 /* only set the internal flag if we have
3406 if (_mtc_port != 0) {
3407 session_midi_feedback = Config->get_midi_feedback();
3410 } else if (PARAM_IS ("jack-time-master")) {
3412 engine().reset_timebase ();
3414 } else if (PARAM_IS ("native-file-header-format")) {
3416 if (!first_file_header_format_reset) {
3417 reset_native_file_format ();
3420 first_file_header_format_reset = false;
3422 } else if (PARAM_IS ("native-file-data-format")) {
3424 if (!first_file_data_format_reset) {
3425 reset_native_file_format ();
3428 first_file_data_format_reset = false;
3430 } else if (PARAM_IS ("slave-source")) {
3431 set_slave_source (Config->get_slave_source());
3432 } else if (PARAM_IS ("remote-model")) {
3433 set_remote_control_ids ();
3434 } else if (PARAM_IS ("denormal-model")) {
3436 } else if (PARAM_IS ("history-depth")) {
3437 set_history_depth (Config->get_history_depth());
3438 } else if (PARAM_IS ("sync-all-route-ordering")) {
3439 sync_order_keys ("session");
3440 } else if (PARAM_IS ("initial-program-change")) {
3442 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3443 MIDI::byte* buf = new MIDI::byte[2];
3445 buf[0] = MIDI::program; // channel zero by default
3446 buf[1] = (Config->get_initial_program_change() & 0x7f);
3447 deliver_midi (_mmc_port, buf, 2);
3449 } else if (PARAM_IS ("solo-mute-override")) {
3450 catch_up_on_solo_mute_override ();
3460 Session::set_history_depth (uint32_t d)
3462 _history.set_depth (d);