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 set_history_depth (Config->get_history_depth());
123 /* these two are just provisional settings. set_state()
124 will likely override them.
127 _name = _current_snapshot_name = snapshot_name;
129 _current_frame_rate = _engine.frame_rate ();
130 _nominal_frame_rate = _current_frame_rate;
131 _base_frame_rate = _current_frame_rate;
133 _tempo_map = new TempoMap (_current_frame_rate);
134 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
136 g_atomic_int_set (&processing_prohibited, 0);
138 _transport_speed = 0;
139 _last_transport_speed = 0;
140 auto_play_legal = false;
141 transport_sub_state = 0;
142 _transport_frame = 0;
144 _requested_return_frame = -1;
145 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
146 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
147 _end_location_is_free = true;
148 g_atomic_int_set (&_record_status, Disabled);
149 loop_changing = false;
152 _last_roll_location = 0;
153 _last_record_location = 0;
154 pending_locate_frame = 0;
155 pending_locate_roll = false;
156 pending_locate_flush = false;
157 dstream_buffer_size = 0;
159 state_was_pending = false;
161 outbound_mtc_smpte_frame = 0;
162 next_quarter_frame_to_send = -1;
163 current_block_size = 0;
164 solo_update_disabled = false;
165 currently_soloing = false;
166 _have_captured = false;
167 _worst_output_latency = 0;
168 _worst_input_latency = 0;
169 _worst_track_latency = 0;
170 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
174 butler_mixdown_buffer = 0;
175 butler_gain_buffer = 0;
177 session_send_mmc = false;
178 session_send_mtc = false;
179 post_transport_work = PostTransportWork (0);
180 g_atomic_int_set (&butler_should_do_transport_work, 0);
181 g_atomic_int_set (&butler_active, 0);
182 g_atomic_int_set (&_playback_load, 100);
183 g_atomic_int_set (&_capture_load, 100);
184 g_atomic_int_set (&_playback_load_min, 100);
185 g_atomic_int_set (&_capture_load_min, 100);
188 _gain_automation_buffer = 0;
189 _pan_automation_buffer = 0;
191 pending_abort = false;
192 destructive_index = 0;
194 first_file_data_format_reset = true;
195 first_file_header_format_reset = true;
196 butler_thread = (pthread_t) 0;
197 midi_thread = (pthread_t) 0;
199 AudioDiskstream::allocate_working_buffers();
201 /* default short fade = 15ms */
203 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
204 SndFileSource::setup_standard_crossfades (frame_rate());
206 last_mmc_step.tv_sec = 0;
207 last_mmc_step.tv_usec = 0;
210 /* click sounds are unset by default, which causes us to internal
211 waveforms for clicks.
215 click_emphasis_data = 0;
217 click_emphasis_length = 0;
220 process_function = &Session::process_with_events;
222 if (Config->get_use_video_sync()) {
223 waiting_for_sync_offset = true;
225 waiting_for_sync_offset = false;
230 _smpte_offset_negative = true;
231 last_smpte_valid = false;
235 last_rr_session_dir = session_dirs.begin();
236 refresh_disk_space ();
238 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
242 average_slave_delta = 1800; // !!! why 1800 ????
243 have_first_delta_accumulator = false;
244 delta_accumulator_cnt = 0;
245 slave_state = Stopped;
247 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
249 /* These are all static "per-class" signals */
251 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
252 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
253 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
254 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
255 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
256 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
258 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
260 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
262 /* stop IO objects from doing stuff until we're ready for them */
264 IO::disable_panners ();
265 IO::disable_ports ();
266 IO::disable_connecting ();
270 Session::second_stage_init (bool new_session)
272 AudioFileSource::set_peak_dir (peak_dir());
275 if (load_state (_current_snapshot_name)) {
278 remove_empty_sounds ();
281 if (start_butler_thread()) {
285 if (start_midi_thread ()) {
289 // set_state() will call setup_raid_path(), but if it's a new session we need
290 // to call setup_raid_path() here.
293 if (set_state (*state_tree->root())) {
297 setup_raid_path(_path);
300 /* we can't save till after ::when_engine_running() is called,
301 because otherwise we save state with no connections made.
302 therefore, we reset _state_of_the_state because ::set_state()
303 will have cleared it.
305 we also have to include Loading so that any events that get
306 generated between here and the end of ::when_engine_running()
307 will be processed directly rather than queued.
310 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
313 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
314 _locations.added.connect (mem_fun (this, &Session::locations_added));
315 setup_click_sounds (0);
316 setup_midi_control ();
318 /* Pay attention ... */
320 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
321 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
324 when_engine_running();
327 /* handle this one in a different way than all others, so that its clear what happened */
329 catch (AudioEngine::PortRegistrationFailure& err) {
338 BootMessage (_("Reset Remote Controls"));
340 send_full_time_code ();
341 _engine.transport_locate (0);
342 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
343 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
345 /* initial program change will be delivered later; see ::config_changed() */
347 BootMessage (_("Reset Control Protocols"));
349 ControlProtocolManager::instance().set_session (*this);
352 _end_location_is_free = true;
354 _end_location_is_free = false;
357 _state_of_the_state = Clean;
359 DirtyChanged (); /* EMIT SIGNAL */
361 if (state_was_pending) {
362 save_state (_current_snapshot_name);
363 remove_pending_capture_state ();
364 state_was_pending = false;
367 BootMessage (_("Session loading complete"));
373 Session::raid_path () const
377 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
382 return path.substr (0, path.length() - 1); // drop final colon
386 Session::setup_raid_path (string path)
388 string::size_type colon;
392 string::size_type len = path.length();
397 if (path.length() == 0) {
401 session_dirs.clear ();
403 for (string::size_type n = 0; n < len; ++n) {
404 if (path[n] == ':') {
411 /* no multiple search path, just one location (common case) */
415 session_dirs.push_back (sp);
418 AudioFileSource::set_search_path (Glib::build_filename(sp.path, sound_dir (false)));
424 while ((colon = remaining.find_first_of (':')) != string::npos) {
427 sp.path = remaining.substr (0, colon);
428 session_dirs.push_back (sp);
430 /* add sounds to file search path */
432 fspath += Glib::build_filename(sp.path, sound_dir (false));
435 remaining = remaining.substr (colon+1);
438 if (remaining.length()) {
444 fspath += Glib::build_filename(sp.path, sound_dir (false));
447 session_dirs.push_back (sp);
450 /* set the AudioFileSource search path */
452 AudioFileSource::set_search_path (fspath);
454 /* reset the round-robin soundfile path thingie */
456 last_rr_session_dir = session_dirs.begin();
460 Session::ensure_subdirs ()
466 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
467 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471 /* if this is is an existing session with an old "sounds" directory, just use it. see Session::sound_dir() for more details */
473 if (!Glib::file_test (old_sound_dir(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
477 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
478 error << string_compose(_("Session: cannot create session sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483 dir = dead_sound_dir ();
485 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
486 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
492 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
493 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
497 dir = analysis_dir ();
499 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
500 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
508 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
511 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
512 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
516 if (ensure_subdirs ()) {
520 /* check new_session so we don't overwrite an existing one */
522 if (!mix_template.empty()) {
523 std::string in_path = mix_template;
525 ifstream in(in_path.c_str());
528 string out_path = _path;
530 out_path += _statefile_suffix;
532 ofstream out(out_path.c_str());
537 // okay, session is set up. Treat like normal saved
538 // session from now on.
544 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
550 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
557 /* set initial start + end point */
559 start_location->set_end (0);
560 _locations.add (start_location);
562 end_location->set_end (initial_length);
563 _locations.add (end_location);
565 _state_of_the_state = Clean;
573 Session::load_diskstreams (const XMLNode& node)
576 XMLNodeConstIterator citer;
578 clist = node.children();
580 for (citer = clist.begin(); citer != clist.end(); ++citer) {
584 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
585 add_diskstream (dstream);
588 catch (failed_constructor& err) {
589 error << _("Session: could not load diskstream via XML state") << endmsg;
598 Session::maybe_write_autosave()
600 if (dirty() && record_status() != Recording) {
601 save_state("", true);
606 Session::remove_pending_capture_state ()
611 xml_path += _current_snapshot_name;
612 xml_path += _pending_suffix;
614 unlink (xml_path.c_str());
617 /** Rename a state file.
618 * @param snapshot_name Snapshot name.
621 Session::rename_state (string old_name, string new_name)
623 if (old_name == _current_snapshot_name || old_name == _name) {
624 /* refuse to rename the current snapshot or the "main" one */
628 const string old_xml_path = _path + old_name + _statefile_suffix;
629 const string new_xml_path = _path + new_name + _statefile_suffix;
631 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
632 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
636 /** Remove a state file.
637 * @param snapshot_name Snapshot name.
640 Session::remove_state (string snapshot_name)
642 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
643 /* refuse to remove the current snapshot or the "main" one */
647 const string xml_path = _path + snapshot_name + _statefile_suffix;
649 /* make a backup copy of the state file */
650 const string bak_path = xml_path + ".bak";
651 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
652 copy_file (xml_path, bak_path);
656 unlink (xml_path.c_str());
660 Session::save_state (string snapshot_name, bool pending)
666 if (_state_of_the_state & CannotSave) {
670 if (!_engine.connected ()) {
671 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
676 tree.set_root (&get_state());
678 if (snapshot_name.empty()) {
679 snapshot_name = _current_snapshot_name;
684 /* proper save: use _statefile_suffix (.ardour in English) */
686 xml_path += snapshot_name;
687 xml_path += _statefile_suffix;
689 /* make a backup copy of the old file */
693 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
694 copy_file (xml_path, bak_path);
699 /* pending save: use _pending_suffix (.pending in English) */
701 xml_path += snapshot_name;
702 xml_path += _pending_suffix;
709 tmp_path += snapshot_name;
712 // cerr << "actually writing state to " << xml_path << endl;
714 if (!tree.write (tmp_path)) {
715 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
716 unlink (tmp_path.c_str());
721 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
722 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
723 unlink (tmp_path.c_str());
730 save_history (snapshot_name);
732 bool was_dirty = dirty();
734 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
738 DirtyChanged (); /* EMIT SIGNAL */
741 StateSaved (snapshot_name); /* EMIT SIGNAL */
748 Session::restore_state (string snapshot_name)
750 if (load_state (snapshot_name) == 0) {
751 set_state (*state_tree->root());
758 Session::load_state (string snapshot_name)
767 state_was_pending = false;
769 /* check for leftover pending state from a crashed capture attempt */
772 xmlpath += snapshot_name;
773 xmlpath += _pending_suffix;
775 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
777 /* there is pending state from a crashed capture attempt */
779 if (AskAboutPendingState()) {
780 state_was_pending = true;
784 if (!state_was_pending) {
787 xmlpath += snapshot_name;
788 xmlpath += _statefile_suffix;
791 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
792 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
796 state_tree = new XMLTree;
800 if (!state_tree->read (xmlpath)) {
801 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
807 XMLNode& root (*state_tree->root());
809 if (root.name() != X_("Session")) {
810 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
816 const XMLProperty* prop;
819 if ((prop = root.property ("version")) == 0) {
820 /* no version implies very old version of Ardour */
824 major_version = atoi (prop->value()); // grab just the first number before the period
825 if (major_version < 2) {
834 backup_path += snapshot_name;
836 backup_path += _statefile_suffix;
838 /* don't make another copy if it already exists */
840 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
841 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
842 xmlpath, backup_path)
845 copy_file (xmlpath, backup_path);
847 /* if it fails, don't worry. right? */
855 Session::load_options (const XMLNode& node)
859 LocaleGuard lg (X_("POSIX"));
861 Config->set_variables (node, ConfigVariableBase::Session);
863 /* now reset MIDI ports because the session can have its own
869 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
870 if ((prop = child->property ("val")) != 0) {
871 _end_location_is_free = (prop->value() == "yes");
879 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
881 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
882 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
884 return owner & modified_by_session_or_user;
888 Session::get_options () const
891 LocaleGuard lg (X_("POSIX"));
893 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
895 child = option_root.add_child ("end-marker-is-free");
896 child->add_property ("val", _end_location_is_free ? "yes" : "no");
908 Session::get_template()
910 /* if we don't disable rec-enable, diskstreams
911 will believe they need to store their capture
912 sources in their state node.
915 disable_record (false);
921 Session::state(bool full_state)
923 XMLNode* node = new XMLNode("Session");
926 // store libardour version, just in case
928 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour2_major_version, libardour2_minor_version, libardour2_micro_version);
929 node->add_property("version", string(buf));
931 /* store configuration settings */
935 node->add_property ("name", _name);
936 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
937 node->add_property ("sample-rate", buf);
939 if (session_dirs.size() > 1) {
943 vector<space_and_path>::iterator i = session_dirs.begin();
944 vector<space_and_path>::iterator next;
946 ++i; /* skip the first one */
950 while (i != session_dirs.end()) {
954 if (next != session_dirs.end()) {
964 child = node->add_child ("Path");
965 child->add_content (p);
969 /* save the ID counter */
971 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
972 node->add_property ("id-counter", buf);
974 /* various options */
976 node->add_child_nocopy (get_options());
978 child = node->add_child ("Sources");
981 Glib::Mutex::Lock sl (audio_source_lock);
983 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
985 /* Don't save information about AudioFileSources that are empty */
987 boost::shared_ptr<AudioFileSource> fs;
989 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
991 /* destructive file sources are OK if they are empty, because
992 we will re-use them every time.
995 if (!fs->destructive()) {
996 if (fs->length() == 0) {
1002 child->add_child_nocopy (siter->second->get_state());
1006 child = node->add_child ("Regions");
1009 Glib::Mutex::Lock rl (region_lock);
1011 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1013 /* only store regions not attached to playlists */
1015 if (i->second->playlist() == 0) {
1016 child->add_child_nocopy (i->second->state (true));
1021 child = node->add_child ("DiskStreams");
1024 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1025 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1026 if (!(*i)->hidden()) {
1027 child->add_child_nocopy ((*i)->get_state());
1033 node->add_child_nocopy (_locations.get_state());
1035 // for a template, just create a new Locations, populate it
1036 // with the default start and end, and get the state for that.
1038 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1039 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1042 end->set_end(compute_initial_length());
1044 node->add_child_nocopy (loc.get_state());
1047 child = node->add_child ("Connections");
1049 Glib::Mutex::Lock lm (connection_lock);
1050 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1051 if (!(*i)->system_dependent()) {
1052 child->add_child_nocopy ((*i)->get_state());
1057 child = node->add_child ("Routes");
1059 boost::shared_ptr<RouteList> r = routes.reader ();
1061 RoutePublicOrderSorter cmp;
1062 RouteList public_order (*r);
1063 public_order.sort (cmp);
1065 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1066 if (!(*i)->hidden()) {
1068 child->add_child_nocopy ((*i)->get_state());
1070 child->add_child_nocopy ((*i)->get_template());
1077 child = node->add_child ("EditGroups");
1078 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1079 child->add_child_nocopy ((*i)->get_state());
1082 child = node->add_child ("MixGroups");
1083 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1084 child->add_child_nocopy ((*i)->get_state());
1087 child = node->add_child ("Playlists");
1088 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1089 if (!(*i)->hidden()) {
1090 if (!(*i)->empty()) {
1092 child->add_child_nocopy ((*i)->get_state());
1094 child->add_child_nocopy ((*i)->get_template());
1100 child = node->add_child ("UnusedPlaylists");
1101 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_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());
1115 child = node->add_child ("Click");
1116 child->add_child_nocopy (_click_io->state (full_state));
1120 child = node->add_child ("NamedSelections");
1121 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1123 child->add_child_nocopy ((*i)->get_state());
1128 node->add_child_nocopy (_tempo_map->get_state());
1130 node->add_child_nocopy (get_control_protocol_state());
1133 node->add_child_copy (*_extra_xml);
1140 Session::get_control_protocol_state ()
1142 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1143 return cpm.get_state();
1147 Session::set_state (const XMLNode& node)
1151 const XMLProperty* prop;
1154 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1156 if (node.name() != X_("Session")){
1157 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1161 if ((prop = node.property ("name")) != 0) {
1162 _name = prop->value ();
1165 if ((prop = node.property (X_("sample-rate"))) != 0) {
1167 _nominal_frame_rate = atoi (prop->value());
1169 if (_nominal_frame_rate != _current_frame_rate) {
1170 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1176 setup_raid_path(_path);
1178 if ((prop = node.property (X_("id-counter"))) != 0) {
1180 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1181 ID::init_counter (x);
1183 /* old sessions used a timebased counter, so fake
1184 the startup ID counter based on a standard
1189 ID::init_counter (now);
1193 IO::disable_ports ();
1194 IO::disable_connecting ();
1196 /* Object loading order:
1201 MIDI <= relies on data from Options/Config
1214 if ((child = find_named_node (node, "extra")) != 0) {
1215 _extra_xml = new XMLNode (*child);
1218 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1219 load_options (*child);
1220 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1221 load_options (*child);
1223 error << _("Session: XML state has no options section") << endmsg;
1226 if (use_config_midi_ports ()) {
1229 if ((child = find_named_node (node, "Locations")) == 0) {
1230 error << _("Session: XML state has no locations section") << endmsg;
1232 } else if (_locations.set_state (*child)) {
1238 if ((location = _locations.auto_loop_location()) != 0) {
1239 set_auto_loop_location (location);
1242 if ((location = _locations.auto_punch_location()) != 0) {
1243 set_auto_punch_location (location);
1246 if ((location = _locations.end_location()) == 0) {
1247 _locations.add (end_location);
1249 delete end_location;
1250 end_location = location;
1253 if ((location = _locations.start_location()) == 0) {
1254 _locations.add (start_location);
1256 delete start_location;
1257 start_location = location;
1260 AudioFileSource::set_header_position_offset (start_location->start());
1262 if ((child = find_named_node (node, "Sources")) == 0) {
1263 error << _("Session: XML state has no sources section") << endmsg;
1265 } else if (load_sources (*child)) {
1269 if ((child = find_named_node (node, "Regions")) == 0) {
1270 error << _("Session: XML state has no Regions section") << endmsg;
1272 } else if (load_regions (*child)) {
1276 if ((child = find_named_node (node, "Playlists")) == 0) {
1277 error << _("Session: XML state has no playlists section") << endmsg;
1279 } else if (load_playlists (*child)) {
1283 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1285 } else if (load_unused_playlists (*child)) {
1289 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1290 if (load_named_selections (*child)) {
1295 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1296 error << _("Session: XML state has no diskstreams section") << endmsg;
1298 } else if (load_diskstreams (*child)) {
1302 if ((child = find_named_node (node, "Connections")) == 0) {
1303 error << _("Session: XML state has no connections section") << endmsg;
1305 } else if (load_connections (*child)) {
1309 if ((child = find_named_node (node, "EditGroups")) == 0) {
1310 error << _("Session: XML state has no edit groups section") << endmsg;
1312 } else if (load_edit_groups (*child)) {
1316 if ((child = find_named_node (node, "MixGroups")) == 0) {
1317 error << _("Session: XML state has no mix groups section") << endmsg;
1319 } else if (load_mix_groups (*child)) {
1323 if ((child = find_named_node (node, "TempoMap")) == 0) {
1324 error << _("Session: XML state has no Tempo Map section") << endmsg;
1326 } else if (_tempo_map->set_state (*child)) {
1330 if ((child = find_named_node (node, "Routes")) == 0) {
1331 error << _("Session: XML state has no routes section") << endmsg;
1333 } else if (load_routes (*child)) {
1337 if ((child = find_named_node (node, "Click")) == 0) {
1338 warning << _("Session: XML state has no click section") << endmsg;
1339 } else if (_click_io) {
1340 _click_io->set_state (*child);
1343 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1344 ControlProtocolManager::instance().set_protocol_states (*child);
1347 /* here beginneth the second phase ... */
1349 StateReady (); /* EMIT SIGNAL */
1358 Session::load_routes (const XMLNode& node)
1361 XMLNodeConstIterator niter;
1362 RouteList new_routes;
1364 nlist = node.children();
1368 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1370 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1373 error << _("Session: cannot create Route from XML description.") << endmsg;
1377 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1379 new_routes.push_back (route);
1382 add_routes (new_routes, false);
1387 boost::shared_ptr<Route>
1388 Session::XMLRouteFactory (const XMLNode& node)
1390 if (node.name() != "Route") {
1391 return boost::shared_ptr<Route> ((Route*) 0);
1394 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1395 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1398 boost::shared_ptr<Route> x (new Route (*this, node));
1404 Session::load_regions (const XMLNode& node)
1407 XMLNodeConstIterator niter;
1408 boost::shared_ptr<AudioRegion> region;
1410 nlist = node.children();
1414 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1415 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1416 error << _("Session: cannot create Region from XML description.");
1417 const XMLProperty *name = (**niter).property("name");
1420 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1430 boost::shared_ptr<AudioRegion>
1431 Session::XMLRegionFactory (const XMLNode& node, bool full)
1433 const XMLProperty* prop;
1434 boost::shared_ptr<Source> source;
1435 boost::shared_ptr<AudioSource> as;
1437 SourceList master_sources;
1438 uint32_t nchans = 1;
1441 if (node.name() != X_("Region")) {
1442 return boost::shared_ptr<AudioRegion>();
1445 if ((prop = node.property (X_("channels"))) != 0) {
1446 nchans = atoi (prop->value().c_str());
1450 if ((prop = node.property ("name")) == 0) {
1451 cerr << "no name for this region\n";
1455 if ((prop = node.property (X_("source-0"))) == 0) {
1456 if ((prop = node.property ("source")) == 0) {
1457 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1458 return boost::shared_ptr<AudioRegion>();
1462 PBD::ID s_id (prop->value());
1464 if ((source = source_by_id (s_id)) == 0) {
1465 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1466 return boost::shared_ptr<AudioRegion>();
1469 as = boost::dynamic_pointer_cast<AudioSource>(source);
1471 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1472 return boost::shared_ptr<AudioRegion>();
1475 sources.push_back (as);
1477 /* pickup other channels */
1479 for (uint32_t n=1; n < nchans; ++n) {
1480 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1481 if ((prop = node.property (buf)) != 0) {
1483 PBD::ID id2 (prop->value());
1485 if ((source = source_by_id (id2)) == 0) {
1486 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1487 return boost::shared_ptr<AudioRegion>();
1490 as = boost::dynamic_pointer_cast<AudioSource>(source);
1492 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1493 return boost::shared_ptr<AudioRegion>();
1495 sources.push_back (as);
1499 for (uint32_t n=0; n < nchans; ++n) {
1500 snprintf (buf, sizeof(buf), X_("master-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 master_sources.push_back (as);
1520 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1522 /* a final detail: this is the one and only place that we know how long missing files are */
1524 if (region->whole_file()) {
1525 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1526 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1528 sfp->set_length (region->length());
1533 if (!master_sources.empty()) {
1534 if (master_sources.size() != nchans) {
1535 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1537 region->set_master_sources (master_sources);
1545 catch (failed_constructor& err) {
1546 return boost::shared_ptr<AudioRegion>();
1551 Session::get_sources_as_xml ()
1554 XMLNode* node = new XMLNode (X_("Sources"));
1555 Glib::Mutex::Lock lm (audio_source_lock);
1557 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1558 node->add_child_nocopy (i->second->get_state());
1561 /* XXX get MIDI and other sources here */
1567 Session::path_from_region_name (string name, string identifier)
1569 char buf[PATH_MAX+1];
1571 string dir = discover_best_sound_dir ();
1573 for (n = 0; n < 999999; ++n) {
1574 if (identifier.length()) {
1575 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1576 identifier.c_str(), n);
1578 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1581 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1586 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1595 Session::load_sources (const XMLNode& node)
1598 XMLNodeConstIterator niter;
1599 boost::shared_ptr<Source> source;
1601 nlist = node.children();
1605 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1608 if ((source = XMLSourceFactory (**niter)) == 0) {
1609 error << _("Session: cannot create Source from XML description.") << endmsg;
1613 catch (non_existent_source& err) {
1614 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1615 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1622 boost::shared_ptr<Source>
1623 Session::XMLSourceFactory (const XMLNode& node)
1625 if (node.name() != "Source") {
1626 return boost::shared_ptr<Source>();
1630 /* note: do peak building in another thread when loading session state */
1631 return SourceFactory::create (*this, node, true);
1634 catch (failed_constructor& err) {
1635 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1636 return boost::shared_ptr<Source>();
1641 Session::save_template (string template_name)
1644 string xml_path, bak_path, template_path;
1646 if (_state_of_the_state & CannotSave) {
1651 string dir = template_dir();
1653 if ((dp = opendir (dir.c_str()))) {
1656 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1657 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1662 tree.set_root (&get_template());
1664 xml_path = Glib::build_filename(dir, template_name + _template_suffix);
1666 ifstream in(xml_path.c_str());
1669 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1675 if (!tree.write (xml_path)) {
1676 error << _("mix template not saved") << endmsg;
1684 Session::rename_template (string old_name, string new_name)
1686 string old_path = Glib::build_filename(template_dir(), old_name + _template_suffix);
1687 string new_path = Glib::build_filename(template_dir(), new_name + _template_suffix);
1689 return rename (old_path.c_str(), new_path.c_str());
1693 Session::delete_template (string name)
1695 string template_path = Glib::build_filename(template_dir(), name + _template_suffix);
1697 return remove (template_path.c_str());
1701 Session::refresh_disk_space ()
1704 struct statfs statfsbuf;
1705 vector<space_and_path>::iterator i;
1706 Glib::Mutex::Lock lm (space_lock);
1709 /* get freespace on every FS that is part of the session path */
1711 _total_free_4k_blocks = 0;
1713 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1714 statfs ((*i).path.c_str(), &statfsbuf);
1716 scale = statfsbuf.f_bsize/4096.0;
1718 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1719 _total_free_4k_blocks += (*i).blocks;
1725 Session::ensure_sound_dir (string path, string& result)
1730 /* Ensure that the parent directory exists */
1732 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1733 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1737 /* Ensure that the sounds directory exists */
1739 result = Glib::build_filename(path, sound_dir_name);
1741 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1742 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1746 dead = Glib::build_filename(path, dead_sound_dir_name);
1748 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1749 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1753 peak = Glib::build_filename(path, peak_dir_name);
1755 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1756 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1760 /* callers expect this to be terminated ... */
1767 Session::discover_best_sound_dir (bool destructive)
1769 vector<space_and_path>::iterator i;
1772 /* handle common case without system calls */
1774 if (session_dirs.size() == 1) {
1778 /* OK, here's the algorithm we're following here:
1780 We want to select which directory to use for
1781 the next file source to be created. Ideally,
1782 we'd like to use a round-robin process so as to
1783 get maximum performance benefits from splitting
1784 the files across multiple disks.
1786 However, in situations without much diskspace, an
1787 RR approach may end up filling up a filesystem
1788 with new files while others still have space.
1789 Its therefore important to pay some attention to
1790 the freespace in the filesystem holding each
1791 directory as well. However, if we did that by
1792 itself, we'd keep creating new files in the file
1793 system with the most space until it was as full
1794 as all others, thus negating any performance
1795 benefits of this RAID-1 like approach.
1797 So, we use a user-configurable space threshold. If
1798 there are at least 2 filesystems with more than this
1799 much space available, we use RR selection between them.
1800 If not, then we pick the filesystem with the most space.
1802 This gets a good balance between the two
1806 refresh_disk_space ();
1808 int free_enough = 0;
1810 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1811 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1816 if (free_enough >= 2) {
1818 bool found_it = false;
1820 /* use RR selection process, ensuring that the one
1824 i = last_rr_session_dir;
1827 if (++i == session_dirs.end()) {
1828 i = session_dirs.begin();
1831 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1832 if (ensure_sound_dir ((*i).path, result) == 0) {
1833 last_rr_session_dir = i;
1839 } while (i != last_rr_session_dir);
1842 result = sound_dir();
1847 /* pick FS with the most freespace (and that
1848 seems to actually work ...)
1851 vector<space_and_path> sorted;
1852 space_and_path_ascending_cmp cmp;
1854 sorted = session_dirs;
1855 sort (sorted.begin(), sorted.end(), cmp);
1857 for (i = sorted.begin(); i != sorted.end(); ++i) {
1858 if (ensure_sound_dir ((*i).path, result) == 0) {
1859 last_rr_session_dir = i;
1864 /* if the above fails, fall back to the most simplistic solution */
1866 if (i == sorted.end()) {
1875 Session::load_playlists (const XMLNode& node)
1878 XMLNodeConstIterator niter;
1879 boost::shared_ptr<Playlist> playlist;
1881 nlist = node.children();
1885 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1887 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1888 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1896 Session::load_unused_playlists (const XMLNode& node)
1899 XMLNodeConstIterator niter;
1900 boost::shared_ptr<Playlist> playlist;
1902 nlist = node.children();
1906 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1908 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1909 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1913 // now manually untrack it
1915 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1922 boost::shared_ptr<Playlist>
1923 Session::XMLPlaylistFactory (const XMLNode& node)
1926 return PlaylistFactory::create (*this, node);
1929 catch (failed_constructor& err) {
1930 return boost::shared_ptr<Playlist>();
1935 Session::load_named_selections (const XMLNode& node)
1938 XMLNodeConstIterator niter;
1941 nlist = node.children();
1945 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1947 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1948 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1956 Session::XMLNamedSelectionFactory (const XMLNode& node)
1959 return new NamedSelection (*this, node);
1962 catch (failed_constructor& err) {
1968 Session::dead_sound_dir () const
1971 res += dead_sound_dir_name;
1977 Session::old_sound_dir (bool with_path) const
1985 res += old_sound_dir_name;
1991 Session::sound_dir (bool with_path) const
1995 vector<string> parts;
2003 parts.push_back(interchange_dir_name);
2004 parts.push_back(legalize_for_path (_name));
2005 parts.push_back(sound_dir_name);
2007 res += Glib::build_filename(parts);
2014 /* if this already exists, don't check for the old session sound directory */
2016 if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2020 /* possibly support old session structure */
2023 string old_withpath;
2025 old_nopath += old_sound_dir_name;
2028 old_withpath = _path;
2029 old_withpath += old_sound_dir_name;
2031 if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2033 return old_withpath;
2038 /* ok, old "sounds" directory isn't there, return the new path */
2044 Session::peak_dir () const
2046 return Glib::build_filename (_path, peak_dir_name);
2050 Session::automation_dir () const
2052 return Glib::build_filename (_path, "automation");
2056 Session::analysis_dir () const
2058 return Glib::build_filename (_path, "analysis");
2062 Session::template_dir ()
2064 return Glib::build_filename (get_user_ardour_path(), "templates");
2068 Session::export_dir () const
2070 return Glib::build_filename (_path, export_dir_name);
2074 Session::suffixed_search_path (string suffix, bool data)
2078 path += get_user_ardour_path();
2079 if (path[path.length()-1] != ':') {
2084 path += get_system_data_path();
2086 path += get_system_module_path();
2089 vector<string> split_path;
2091 split (path, split_path, ':');
2094 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2099 if (distance (i, split_path.end()) != 1) {
2108 Session::template_path ()
2110 return suffixed_search_path (X_("templates"), true);
2114 Session::control_protocol_path ()
2116 char *p = getenv ("ARDOUR_CONTROL_SURFACE_PATH");
2120 return suffixed_search_path (X_("surfaces"), false);
2124 Session::load_connections (const XMLNode& node)
2126 XMLNodeList nlist = node.children();
2127 XMLNodeConstIterator niter;
2131 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2132 if ((*niter)->name() == "InputConnection") {
2133 add_connection (new ARDOUR::InputConnection (**niter));
2134 } else if ((*niter)->name() == "OutputConnection") {
2135 add_connection (new ARDOUR::OutputConnection (**niter));
2137 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2146 Session::load_edit_groups (const XMLNode& node)
2148 return load_route_groups (node, true);
2152 Session::load_mix_groups (const XMLNode& node)
2154 return load_route_groups (node, false);
2158 Session::load_route_groups (const XMLNode& node, bool edit)
2160 XMLNodeList nlist = node.children();
2161 XMLNodeConstIterator niter;
2166 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2167 if ((*niter)->name() == "RouteGroup") {
2169 rg = add_edit_group ("");
2170 rg->set_state (**niter);
2172 rg = add_mix_group ("");
2173 rg->set_state (**niter);
2182 state_file_filter (const string &str, void *arg)
2184 return (str.length() > strlen(Session::statefile_suffix()) &&
2185 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2189 bool operator()(const string* a, const string* b) {
2195 remove_end(string* state)
2197 string statename(*state);
2199 string::size_type start,end;
2200 if ((start = statename.find_last_of ('/')) != string::npos) {
2201 statename = statename.substr (start+1);
2204 if ((end = statename.rfind(".ardour")) == string::npos) {
2205 end = statename.length();
2208 return new string(statename.substr (0, end));
2212 Session::possible_states (string path)
2214 PathScanner scanner;
2215 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2217 transform(states->begin(), states->end(), states->begin(), remove_end);
2220 sort (states->begin(), states->end(), cmp);
2226 Session::possible_states () const
2228 return possible_states(_path);
2232 Session::auto_save()
2234 save_state (_current_snapshot_name);
2238 Session::add_edit_group (string name)
2240 RouteGroup* rg = new RouteGroup (*this, name);
2241 edit_groups.push_back (rg);
2242 edit_group_added (rg); /* EMIT SIGNAL */
2248 Session::add_mix_group (string name)
2250 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2251 mix_groups.push_back (rg);
2252 mix_group_added (rg); /* EMIT SIGNAL */
2258 Session::remove_edit_group (RouteGroup& rg)
2260 list<RouteGroup*>::iterator i;
2262 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2263 (*i)->apply (&Route::drop_edit_group, this);
2264 edit_groups.erase (i);
2265 edit_group_removed (); /* EMIT SIGNAL */
2272 Session::remove_mix_group (RouteGroup& rg)
2274 list<RouteGroup*>::iterator i;
2276 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2277 (*i)->apply (&Route::drop_mix_group, this);
2278 mix_groups.erase (i);
2279 mix_group_removed (); /* EMIT SIGNAL */
2286 Session::mix_group_by_name (string name)
2288 list<RouteGroup *>::iterator i;
2290 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2291 if ((*i)->name() == name) {
2299 Session::edit_group_by_name (string name)
2301 list<RouteGroup *>::iterator i;
2303 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2304 if ((*i)->name() == name) {
2312 Session::begin_reversible_command (string name)
2314 current_trans = new UndoTransaction;
2315 current_trans->set_name (name);
2319 Session::commit_reversible_command (Command *cmd)
2324 current_trans->add_command (cmd);
2327 if (current_trans->empty()) {
2331 gettimeofday (&now, 0);
2332 current_trans->set_timestamp (now);
2334 _history.add (current_trans);
2337 Session::GlobalRouteBooleanState
2338 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2340 GlobalRouteBooleanState s;
2341 boost::shared_ptr<RouteList> r = routes.reader ();
2343 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2344 if (!(*i)->hidden()) {
2345 RouteBooleanState v;
2348 Route* r = (*i).get();
2349 v.second = (r->*method)();
2358 Session::GlobalRouteMeterState
2359 Session::get_global_route_metering ()
2361 GlobalRouteMeterState s;
2362 boost::shared_ptr<RouteList> r = routes.reader ();
2364 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2365 if (!(*i)->hidden()) {
2369 v.second = (*i)->meter_point();
2379 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2381 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2383 boost::shared_ptr<Route> r = (i->first.lock());
2386 r->set_meter_point (i->second, arg);
2392 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2394 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2396 boost::shared_ptr<Route> r = (i->first.lock());
2399 Route* rp = r.get();
2400 (rp->*method) (i->second, arg);
2406 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2408 set_global_route_boolean (s, &Route::set_mute, src);
2412 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2414 set_global_route_boolean (s, &Route::set_solo, src);
2418 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2420 set_global_route_boolean (s, &Route::set_record_enable, src);
2425 Session::global_mute_memento (void* src)
2427 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2431 Session::global_metering_memento (void* src)
2433 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2437 Session::global_solo_memento (void* src)
2439 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2443 Session::global_record_enable_memento (void* src)
2445 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2450 template_filter (const string &str, void *arg)
2452 return (str.length() > strlen(Session::template_suffix()) &&
2453 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2457 Session::get_template_list (list<string> &template_names)
2459 vector<string *> *templates;
2460 PathScanner scanner;
2463 path = template_path ();
2465 templates = scanner (path, template_filter, 0, false, true);
2467 vector<string*>::iterator i;
2468 for (i = templates->begin(); i != templates->end(); ++i) {
2469 string fullpath = *(*i);
2472 start = fullpath.find_last_of ('/') + 1;
2473 if ((end = fullpath.find_last_of ('.')) <0) {
2474 end = fullpath.length();
2477 template_names.push_back(fullpath.substr(start, (end-start)));
2482 Session::read_favorite_dirs (FavoriteDirs & favs)
2484 Glib::ustring path = Glib::build_filename (get_user_ardour_path(), "favorite_dirs");
2486 ifstream fav (path.c_str());
2491 if (errno != ENOENT) {
2492 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2503 getline(fav, newfav);
2509 favs.push_back (newfav);
2516 Session::write_favorite_dirs (FavoriteDirs & favs)
2518 Glib::ustring path = Glib::build_filename (get_user_ardour_path(), "favorite_dirs");
2520 ofstream fav (path.c_str());
2526 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2527 fav << (*i) << endl;
2534 accept_all_non_peak_files (const string& path, void *arg)
2536 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2540 accept_all_state_files (const string& path, void *arg)
2542 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2546 Session::find_all_sources (string path, set<string>& result)
2551 if (!tree.read (path)) {
2555 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2560 XMLNodeConstIterator niter;
2562 nlist = node->children();
2566 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2570 if ((prop = (*niter)->property (X_("name"))) == 0) {
2574 if (prop->value()[0] == '/') {
2575 /* external file, ignore */
2579 string path = _path; /* /-terminated */
2580 path += sound_dir_name;
2582 path += prop->value();
2584 result.insert (path);
2591 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2593 PathScanner scanner;
2594 vector<string*>* state_files;
2596 string this_snapshot_path;
2602 if (ripped[ripped.length()-1] == '/') {
2603 ripped = ripped.substr (0, ripped.length() - 1);
2606 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2608 if (state_files == 0) {
2613 this_snapshot_path = _path;
2614 this_snapshot_path += _current_snapshot_name;
2615 this_snapshot_path += _statefile_suffix;
2617 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2619 if (exclude_this_snapshot && **i == this_snapshot_path) {
2623 if (find_all_sources (**i, result) < 0) {
2631 struct RegionCounter {
2632 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2633 AudioSourceList::iterator iter;
2634 boost::shared_ptr<Region> region;
2637 RegionCounter() : count (0) {}
2641 Session::cleanup_sources (Session::cleanup_report& rep)
2643 vector<boost::shared_ptr<Source> > dead_sources;
2644 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2645 PathScanner scanner;
2647 vector<space_and_path>::iterator i;
2648 vector<space_and_path>::iterator nexti;
2649 vector<string*>* soundfiles;
2650 vector<string> unused;
2651 set<string> all_sources;
2656 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2659 /* step 1: consider deleting all unused playlists */
2661 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2664 status = AskAboutPlaylistDeletion (*x);
2673 playlists_tbd.push_back (*x);
2677 /* leave it alone */
2682 /* now delete any that were marked for deletion */
2684 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2685 (*x)->drop_references ();
2688 playlists_tbd.clear ();
2690 /* step 2: find all un-used sources */
2695 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2697 AudioSourceList::iterator tmp;
2702 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2706 if (!i->second->used() && i->second->length() > 0) {
2707 dead_sources.push_back (i->second);
2708 i->second->GoingAway();
2714 /* build a list of all the possible sound directories for the session */
2716 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2721 sound_path += (*i).path;
2722 sound_path += sound_dir (false);
2724 if (nexti != session_dirs.end()) {
2731 /* now do the same thing for the files that ended up in the sounds dir(s)
2732 but are not referenced as sources in any snapshot.
2735 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2737 if (soundfiles == 0) {
2741 /* find all sources, but don't use this snapshot because the
2742 state file on disk still references sources we may have already
2746 find_all_sources_across_snapshots (all_sources, true);
2748 /* add our current source list
2751 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2752 boost::shared_ptr<AudioFileSource> fs;
2754 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2755 all_sources.insert (fs->path());
2759 char tmppath1[PATH_MAX+1];
2760 char tmppath2[PATH_MAX+1];
2762 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2767 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2769 realpath(spath.c_str(), tmppath1);
2770 realpath((*i).c_str(), tmppath2);
2772 if (strcmp(tmppath1, tmppath2) == 0) {
2779 unused.push_back (spath);
2783 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2785 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2786 struct stat statbuf;
2788 rep.paths.push_back (*x);
2789 if (stat ((*x).c_str(), &statbuf) == 0) {
2790 rep.space += statbuf.st_size;
2795 /* don't move the file across filesystems, just
2796 stick it in the `dead_sound_dir_name' directory
2797 on whichever filesystem it was already on.
2800 if ((*x).find ("/sounds/") != string::npos) {
2802 /* old school, go up 1 level */
2804 newpath = Glib::path_get_dirname (*x); // "sounds"
2805 newpath = Glib::path_get_dirname (newpath); // "session-name"
2809 /* new school, go up 4 levels */
2811 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2812 newpath = Glib::path_get_dirname (newpath); // "session-name"
2813 newpath = Glib::path_get_dirname (newpath); // "interchange"
2814 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2818 newpath += dead_sound_dir_name;
2820 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2821 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2826 newpath += Glib::path_get_basename ((*x));
2828 if (access (newpath.c_str(), F_OK) == 0) {
2830 /* the new path already exists, try versioning */
2832 char buf[PATH_MAX+1];
2836 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2839 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2840 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2844 if (version == 999) {
2845 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2849 newpath = newpath_v;
2854 /* it doesn't exist, or we can't read it or something */
2858 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2859 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2860 (*x), newpath, strerror (errno))
2865 /* see if there an easy to find peakfile for this file, and remove it.
2868 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2869 peakpath += ".peak";
2871 if (access (peakpath.c_str(), W_OK) == 0) {
2872 if (::unlink (peakpath.c_str()) != 0) {
2873 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2874 peakpath, _path, strerror (errno))
2876 /* try to back out */
2877 rename (newpath.c_str(), _path.c_str());
2885 /* dump the history list */
2889 /* save state so we don't end up a session file
2890 referring to non-existent sources.
2896 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2902 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2904 vector<space_and_path>::iterator i;
2905 string dead_sound_dir;
2906 struct dirent* dentry;
2907 struct stat statbuf;
2913 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2915 dead_sound_dir = (*i).path;
2916 dead_sound_dir += dead_sound_dir_name;
2918 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2922 while ((dentry = readdir (dead)) != 0) {
2924 /* avoid '.' and '..' */
2926 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2927 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2933 fullpath = dead_sound_dir;
2935 fullpath += dentry->d_name;
2937 if (stat (fullpath.c_str(), &statbuf)) {
2941 if (!S_ISREG (statbuf.st_mode)) {
2945 if (unlink (fullpath.c_str())) {
2946 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2947 fullpath, strerror (errno))
2951 rep.paths.push_back (dentry->d_name);
2952 rep.space += statbuf.st_size;
2963 Session::set_dirty ()
2965 bool was_dirty = dirty();
2967 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2971 DirtyChanged(); /* EMIT SIGNAL */
2977 Session::set_clean ()
2979 bool was_dirty = dirty();
2981 _state_of_the_state = Clean;
2985 DirtyChanged(); /* EMIT SIGNAL */
2990 Session::set_deletion_in_progress ()
2992 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2997 Session::add_controllable (Controllable* c)
2999 /* this adds a controllable to the list managed by the Session.
3000 this is a subset of those managed by the Controllable class
3001 itself, and represents the only ones whose state will be saved
3002 as part of the session.
3005 Glib::Mutex::Lock lm (controllables_lock);
3006 controllables.insert (c);
3010 Session::remove_controllable (Controllable* c)
3012 if (_state_of_the_state | Deletion) {
3016 Glib::Mutex::Lock lm (controllables_lock);
3018 Controllables::iterator x = controllables.find (c);
3020 if (x != controllables.end()) {
3021 controllables.erase (x);
3026 Session::controllable_by_id (const PBD::ID& id)
3028 Glib::Mutex::Lock lm (controllables_lock);
3030 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3031 if ((*i)->id() == id) {
3040 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3042 Stateful::add_instant_xml (node, dir);
3043 Config->add_instant_xml (node, get_user_ardour_path());
3047 Session::save_history (string snapshot_name)
3053 if (snapshot_name.empty()) {
3054 snapshot_name = _current_snapshot_name;
3057 xml_path = _path + snapshot_name + ".history";
3059 bak_path = xml_path + ".bak";
3061 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && ::rename (xml_path.c_str(), bak_path.c_str())) {
3062 error << _("could not backup old history file, current history not saved.") << endmsg;
3066 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3070 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3072 if (!tree.write (xml_path))
3074 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3076 /* don't leave a corrupt file lying around if it is
3080 if (unlink (xml_path.c_str())) {
3081 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3083 if (rename (bak_path.c_str(), xml_path.c_str()))
3085 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3096 Session::restore_history (string snapshot_name)
3101 if (snapshot_name.empty()) {
3102 snapshot_name = _current_snapshot_name;
3106 xmlpath = _path + snapshot_name + ".history";
3107 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3109 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3113 if (!tree.read (xmlpath)) {
3114 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3118 /* replace history */
3121 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3124 UndoTransaction* ut = new UndoTransaction ();
3127 ut->set_name(t->property("name")->value());
3128 stringstream ss(t->property("tv_sec")->value());
3130 ss.str(t->property("tv_usec")->value());
3132 ut->set_timestamp(tv);
3134 for (XMLNodeConstIterator child_it = t->children().begin();
3135 child_it != t->children().end();
3138 XMLNode *n = *child_it;
3141 if (n->name() == "MementoCommand" ||
3142 n->name() == "MementoUndoCommand" ||
3143 n->name() == "MementoRedoCommand") {
3145 if ((c = memento_command_factory(n))) {
3149 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3151 if ((c = global_state_command_factory (*n))) {
3152 ut->add_command (c);
3157 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3168 Session::config_changed (const char* parameter_name)
3170 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3172 if (PARAM_IS ("seamless-loop")) {
3174 } else if (PARAM_IS ("rf-speed")) {
3176 } else if (PARAM_IS ("auto-loop")) {
3178 } else if (PARAM_IS ("auto-input")) {
3180 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3181 /* auto-input only makes a difference if we're rolling */
3183 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3185 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3186 if ((*i)->record_enabled ()) {
3187 (*i)->monitor_input (!Config->get_auto_input());
3192 } else if (PARAM_IS ("punch-in")) {
3196 if ((location = _locations.auto_punch_location()) != 0) {
3198 if (Config->get_punch_in ()) {
3199 replace_event (Event::PunchIn, location->start());
3201 remove_event (location->start(), Event::PunchIn);
3205 } else if (PARAM_IS ("punch-out")) {
3209 if ((location = _locations.auto_punch_location()) != 0) {
3211 if (Config->get_punch_out()) {
3212 replace_event (Event::PunchOut, location->end());
3214 clear_events (Event::PunchOut);
3218 } else if (PARAM_IS ("edit-mode")) {
3220 Glib::Mutex::Lock lm (playlist_lock);
3222 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3223 (*i)->set_edit_mode (Config->get_edit_mode ());
3226 } else if (PARAM_IS ("use-video-sync")) {
3228 waiting_for_sync_offset = Config->get_use_video_sync();
3230 } else if (PARAM_IS ("mmc-control")) {
3232 poke_midi_thread ();
3234 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-device-id")) {
3236 set_mmc_receive_device_id (Config->get_mmc_receive_device_id());
3238 } else if (PARAM_IS ("mmc-send-device-id")) {
3240 set_mmc_send_device_id (Config->get_mmc_send_device_id());
3242 } else if (PARAM_IS ("midi-control")) {
3244 poke_midi_thread ();
3246 } else if (PARAM_IS ("raid-path")) {
3248 setup_raid_path (Config->get_raid_path());
3250 } else if (PARAM_IS ("smpte-format")) {
3254 } else if (PARAM_IS ("video-pullup")) {
3258 } else if (PARAM_IS ("seamless-loop")) {
3260 if (play_loop && transport_rolling()) {
3261 // to reset diskstreams etc
3262 request_play_loop (true);
3265 } else if (PARAM_IS ("rf-speed")) {
3267 cumulative_rf_motion = 0;
3270 } else if (PARAM_IS ("click-sound")) {
3272 setup_click_sounds (1);
3274 } else if (PARAM_IS ("click-emphasis-sound")) {
3276 setup_click_sounds (-1);
3278 } else if (PARAM_IS ("clicking")) {
3280 if (Config->get_clicking()) {
3281 if (_click_io && click_data) { // don't require emphasis data
3288 } else if (PARAM_IS ("send-mtc")) {
3290 /* only set the internal flag if we have
3294 if (_mtc_port != 0) {
3295 session_send_mtc = Config->get_send_mtc();
3296 if (session_send_mtc) {
3297 /* mark us ready to send */
3298 next_quarter_frame_to_send = 0;
3301 session_send_mtc = false;
3304 } else if (PARAM_IS ("send-mmc")) {
3306 /* only set the internal flag if we have
3310 if (_mmc_port != 0) {
3311 session_send_mmc = Config->get_send_mmc();
3314 session_send_mmc = false;
3317 } else if (PARAM_IS ("midi-feedback")) {
3319 /* only set the internal flag if we have
3323 if (_mtc_port != 0) {
3324 session_midi_feedback = Config->get_midi_feedback();
3327 } else if (PARAM_IS ("jack-time-master")) {
3329 engine().reset_timebase ();
3331 } else if (PARAM_IS ("native-file-header-format")) {
3333 if (!first_file_header_format_reset) {
3334 reset_native_file_format ();
3337 first_file_header_format_reset = false;
3339 } else if (PARAM_IS ("native-file-data-format")) {
3341 if (!first_file_data_format_reset) {
3342 reset_native_file_format ();
3345 first_file_data_format_reset = false;
3347 } else if (PARAM_IS ("slave-source")) {
3348 set_slave_source (Config->get_slave_source());
3349 } else if (PARAM_IS ("remote-model")) {
3350 set_remote_control_ids ();
3351 } else if (PARAM_IS ("denormal-model")) {
3353 } else if (PARAM_IS ("history-depth")) {
3354 set_history_depth (Config->get_history_depth());
3355 } else if (PARAM_IS ("sync-all-route-ordering")) {
3356 sync_order_keys ("session");
3357 } else if (PARAM_IS ("initial-program-change")) {
3359 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3360 MIDI::byte* buf = new MIDI::byte[2];
3362 buf[0] = MIDI::program; // channel zero by default
3363 buf[1] = (Config->get_initial_program_change() & 0x7f);
3364 deliver_midi (_mmc_port, buf, 2);
3366 } else if (PARAM_IS ("solo-mute-override")) {
3367 catch_up_on_solo_mute_override ();
3377 Session::set_history_depth (uint32_t d)
3379 _history.set_depth (d);