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;
158 state_was_pending = false;
160 outbound_mtc_smpte_frame = 0;
161 next_quarter_frame_to_send = -1;
162 current_block_size = 0;
163 solo_update_disabled = false;
164 currently_soloing = false;
165 _have_captured = false;
166 _worst_output_latency = 0;
167 _worst_input_latency = 0;
168 _worst_track_latency = 0;
169 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
173 session_send_mmc = false;
174 session_send_mtc = false;
175 post_transport_work = PostTransportWork (0);
176 g_atomic_int_set (&butler_should_do_transport_work, 0);
177 g_atomic_int_set (&butler_active, 0);
178 g_atomic_int_set (&_playback_load, 100);
179 g_atomic_int_set (&_capture_load, 100);
180 g_atomic_int_set (&_playback_load_min, 100);
181 g_atomic_int_set (&_capture_load_min, 100);
184 _gain_automation_buffer = 0;
185 _pan_automation_buffer = 0;
187 pending_abort = false;
188 destructive_index = 0;
190 first_file_data_format_reset = true;
191 first_file_header_format_reset = true;
192 butler_thread = (pthread_t) 0;
194 AudioDiskstream::allocate_working_buffers();
196 /* default short fade = 15ms */
198 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
199 SndFileSource::setup_standard_crossfades (frame_rate());
201 last_mmc_step.tv_sec = 0;
202 last_mmc_step.tv_usec = 0;
205 /* click sounds are unset by default, which causes us to internal
206 waveforms for clicks.
210 click_emphasis_length = 0;
213 process_function = &Session::process_with_events;
215 if (Config->get_use_video_sync()) {
216 waiting_for_sync_offset = true;
218 waiting_for_sync_offset = false;
223 _smpte_offset_negative = true;
224 last_smpte_valid = false;
228 last_rr_session_dir = session_dirs.begin();
229 refresh_disk_space ();
231 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
235 average_slave_delta = 1800; // !!! why 1800 ????
236 have_first_delta_accumulator = false;
237 delta_accumulator_cnt = 0;
238 slave_state = Stopped;
240 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
242 /* These are all static "per-class" signals */
244 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
245 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
246 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
247 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
248 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
249 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
251 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
253 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
255 /* stop IO objects from doing stuff until we're ready for them */
257 IO::disable_panners ();
258 IO::disable_ports ();
259 IO::disable_connecting ();
263 Session::second_stage_init (bool new_session)
265 AudioFileSource::set_peak_dir (peak_dir());
268 if (load_state (_current_snapshot_name)) {
271 remove_empty_sounds ();
274 if (start_butler_thread()) {
278 if (start_midi_thread ()) {
282 // set_state() will call setup_raid_path(), but if it's a new session we need
283 // to call setup_raid_path() here.
286 if (set_state (*state_tree->root())) {
290 setup_raid_path(_path);
293 /* we can't save till after ::when_engine_running() is called,
294 because otherwise we save state with no connections made.
295 therefore, we reset _state_of_the_state because ::set_state()
296 will have cleared it.
298 we also have to include Loading so that any events that get
299 generated between here and the end of ::when_engine_running()
300 will be processed directly rather than queued.
303 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
306 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
307 _locations.added.connect (mem_fun (this, &Session::locations_added));
308 setup_click_sounds (0);
309 setup_midi_control ();
311 /* Pay attention ... */
313 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
314 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
317 when_engine_running();
320 /* handle this one in a different way than all others, so that its clear what happened */
322 catch (AudioEngine::PortRegistrationFailure& err) {
331 BootMessage (_("Reset Remote Controls"));
333 send_full_time_code ();
334 _engine.transport_locate (0);
335 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
336 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
338 /* initial program change will be delivered later; see ::config_changed() */
340 BootMessage (_("Reset Control Protocols"));
342 ControlProtocolManager::instance().set_session (*this);
345 _end_location_is_free = true;
347 _end_location_is_free = false;
350 _state_of_the_state = Clean;
352 DirtyChanged (); /* EMIT SIGNAL */
354 if (state_was_pending) {
355 save_state (_current_snapshot_name);
356 remove_pending_capture_state ();
357 state_was_pending = false;
360 BootMessage (_("Session loading complete"));
366 Session::raid_path () const
370 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
375 return path.substr (0, path.length() - 1); // drop final colon
379 Session::setup_raid_path (string path)
381 string::size_type colon;
385 string::size_type len = path.length();
390 if (path.length() == 0) {
394 session_dirs.clear ();
396 for (string::size_type n = 0; n < len; ++n) {
397 if (path[n] == ':') {
404 /* no multiple search path, just one location (common case) */
408 session_dirs.push_back (sp);
411 AudioFileSource::set_search_path (Glib::build_filename(sp.path, sound_dir (false)));
417 while ((colon = remaining.find_first_of (':')) != string::npos) {
420 sp.path = remaining.substr (0, colon);
421 session_dirs.push_back (sp);
423 /* add sounds to file search path */
425 fspath += Glib::build_filename(sp.path, sound_dir (false));
428 remaining = remaining.substr (colon+1);
431 if (remaining.length()) {
437 fspath += Glib::build_filename(sp.path, sound_dir (false));
440 session_dirs.push_back (sp);
443 /* set the AudioFileSource search path */
445 AudioFileSource::set_search_path (fspath);
447 /* reset the round-robin soundfile path thingie */
449 last_rr_session_dir = session_dirs.begin();
453 Session::ensure_subdirs ()
459 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
460 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
464 /* if this is is an existing session with an old "sounds" directory, just use it. see Session::sound_dir() for more details */
466 if (!Glib::file_test (old_sound_dir(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
470 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
471 error << string_compose(_("Session: cannot create session sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
476 dir = dead_sound_dir ();
478 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
479 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
485 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
486 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
490 dir = analysis_dir ();
492 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
493 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
501 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
504 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
505 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
509 if (ensure_subdirs ()) {
513 /* check new_session so we don't overwrite an existing one */
515 if (!mix_template.empty()) {
516 std::string in_path = mix_template;
518 ifstream in(in_path.c_str());
521 string out_path = _path;
523 out_path += _statefile_suffix;
525 ofstream out(out_path.c_str());
530 // okay, session is set up. Treat like normal saved
531 // session from now on.
537 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
543 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
550 /* set initial start + end point */
552 start_location->set_end (0);
553 _locations.add (start_location);
555 end_location->set_end (initial_length);
556 _locations.add (end_location);
558 _state_of_the_state = Clean;
566 Session::load_diskstreams (const XMLNode& node)
569 XMLNodeConstIterator citer;
571 clist = node.children();
573 for (citer = clist.begin(); citer != clist.end(); ++citer) {
577 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
578 add_diskstream (dstream);
581 catch (failed_constructor& err) {
582 error << _("Session: could not load diskstream via XML state") << endmsg;
591 Session::maybe_write_autosave()
593 if (dirty() && record_status() != Recording) {
594 save_state("", true);
599 Session::remove_pending_capture_state ()
604 xml_path += legalize_for_path (_current_snapshot_name);
605 xml_path += _pending_suffix;
607 unlink (xml_path.c_str());
610 /** Rename a state file.
611 * @param snapshot_name Snapshot name.
614 Session::rename_state (string old_name, string new_name)
616 if (old_name == _current_snapshot_name || old_name == _name) {
617 /* refuse to rename the current snapshot or the "main" one */
621 const string old_xml_path = _path + legalize_for_path (old_name) + _statefile_suffix;
622 const string new_xml_path = _path + legalize_for_path (new_name) + _statefile_suffix;
624 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
625 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
629 /** Remove a state file.
630 * @param snapshot_name Snapshot name.
633 Session::remove_state (string snapshot_name)
635 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
636 /* refuse to remove the current snapshot or the "main" one */
640 const string xml_path = _path + legalize_for_path (snapshot_name) + _statefile_suffix;
642 /* make a backup copy of the state file */
643 const string bak_path = xml_path + ".bak";
644 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
645 copy_file (xml_path, bak_path);
649 unlink (xml_path.c_str());
653 Session::save_state (string snapshot_name, bool pending)
659 if (_state_of_the_state & CannotSave) {
663 if (!_engine.connected ()) {
664 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
669 tree.set_root (&get_state());
671 if (snapshot_name.empty()) {
672 snapshot_name = _current_snapshot_name;
677 /* proper save: use _statefile_suffix (.ardour in English) */
679 xml_path += legalize_for_path (snapshot_name);
680 xml_path += _statefile_suffix;
682 /* make a backup copy of the old file */
686 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
687 copy_file (xml_path, bak_path);
692 /* pending save: use _pending_suffix (.pending in English) */
694 xml_path += legalize_for_path (snapshot_name);
695 xml_path += _pending_suffix;
702 tmp_path += legalize_for_path (snapshot_name);
705 // cerr << "actually writing state to " << xml_path << endl;
707 if (!tree.write (tmp_path)) {
708 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
709 unlink (tmp_path.c_str());
714 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
715 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
716 unlink (tmp_path.c_str());
723 save_history (snapshot_name);
725 bool was_dirty = dirty();
727 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
731 DirtyChanged (); /* EMIT SIGNAL */
734 StateSaved (snapshot_name); /* EMIT SIGNAL */
741 Session::restore_state (string snapshot_name)
743 if (load_state (snapshot_name) == 0) {
744 set_state (*state_tree->root());
751 Session::load_state (string snapshot_name)
760 state_was_pending = false;
762 /* check for leftover pending state from a crashed capture attempt */
765 xmlpath += legalize_for_path (snapshot_name);
766 xmlpath += _pending_suffix;
768 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
770 /* there is pending state from a crashed capture attempt */
772 if (AskAboutPendingState()) {
773 state_was_pending = true;
777 if (!state_was_pending) {
780 xmlpath += legalize_for_path (snapshot_name);
781 xmlpath += _statefile_suffix;
784 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
785 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
789 state_tree = new XMLTree;
793 if (!state_tree->read (xmlpath)) {
794 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
800 XMLNode& root (*state_tree->root());
802 if (root.name() != X_("Session")) {
803 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
809 const XMLProperty* prop;
812 if ((prop = root.property ("version")) == 0) {
813 /* no version implies very old version of Ardour */
817 major_version = atoi (prop->value()); // grab just the first number before the period
818 if (major_version < 2) {
827 backup_path += legalize_for_path (snapshot_name);
829 backup_path += _statefile_suffix;
831 /* don't make another copy if it already exists */
833 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
834 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
835 xmlpath, backup_path)
838 copy_file (xmlpath, backup_path);
840 /* if it fails, don't worry. right? */
848 Session::load_options (const XMLNode& node)
852 LocaleGuard lg (X_("POSIX"));
854 Config->set_variables (node, ConfigVariableBase::Session);
856 /* now reset MIDI ports because the session can have its own
862 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
863 if ((prop = child->property ("val")) != 0) {
864 _end_location_is_free = (prop->value() == "yes");
872 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
874 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
875 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
877 return owner & modified_by_session_or_user;
881 Session::get_options () const
884 LocaleGuard lg (X_("POSIX"));
886 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
888 child = option_root.add_child ("end-marker-is-free");
889 child->add_property ("val", _end_location_is_free ? "yes" : "no");
901 Session::get_template()
903 /* if we don't disable rec-enable, diskstreams
904 will believe they need to store their capture
905 sources in their state node.
908 disable_record (false);
914 Session::state(bool full_state)
916 XMLNode* node = new XMLNode("Session");
919 // store libardour version, just in case
921 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour2_major_version, libardour2_minor_version, libardour2_micro_version);
922 node->add_property("version", string(buf));
924 /* store configuration settings */
928 node->add_property ("name", _name);
929 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
930 node->add_property ("sample-rate", buf);
932 if (session_dirs.size() > 1) {
936 vector<space_and_path>::iterator i = session_dirs.begin();
937 vector<space_and_path>::iterator next;
939 ++i; /* skip the first one */
943 while (i != session_dirs.end()) {
947 if (next != session_dirs.end()) {
957 child = node->add_child ("Path");
958 child->add_content (p);
962 /* save the ID counter */
964 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
965 node->add_property ("id-counter", buf);
967 /* various options */
969 node->add_child_nocopy (get_options());
971 child = node->add_child ("Sources");
974 Glib::Mutex::Lock sl (audio_source_lock);
976 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
978 /* Don't save information about AudioFileSources that are empty */
980 boost::shared_ptr<AudioFileSource> fs;
982 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
984 /* destructive file sources are OK if they are empty, because
985 we will re-use them every time.
988 if (!fs->destructive()) {
989 if (fs->length() == 0) {
995 child->add_child_nocopy (siter->second->get_state());
999 child = node->add_child ("Regions");
1002 Glib::Mutex::Lock rl (region_lock);
1004 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1006 /* only store regions not attached to playlists */
1008 if (i->second->playlist() == 0) {
1009 child->add_child_nocopy (i->second->state (true));
1014 child = node->add_child ("DiskStreams");
1017 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1018 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1019 if (!(*i)->hidden()) {
1020 child->add_child_nocopy ((*i)->get_state());
1026 node->add_child_nocopy (_locations.get_state());
1028 // for a template, just create a new Locations, populate it
1029 // with the default start and end, and get the state for that.
1031 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1032 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1035 end->set_end(compute_initial_length());
1037 node->add_child_nocopy (loc.get_state());
1040 child = node->add_child ("Connections");
1042 Glib::Mutex::Lock lm (connection_lock);
1043 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1044 if (!(*i)->system_dependent()) {
1045 child->add_child_nocopy ((*i)->get_state());
1050 child = node->add_child ("Routes");
1052 boost::shared_ptr<RouteList> r = routes.reader ();
1054 RoutePublicOrderSorter cmp;
1055 RouteList public_order (*r);
1056 public_order.sort (cmp);
1058 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1059 if (!(*i)->hidden()) {
1061 child->add_child_nocopy ((*i)->get_state());
1063 child->add_child_nocopy ((*i)->get_template());
1070 child = node->add_child ("EditGroups");
1071 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1072 child->add_child_nocopy ((*i)->get_state());
1075 child = node->add_child ("MixGroups");
1076 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1077 child->add_child_nocopy ((*i)->get_state());
1080 child = node->add_child ("Playlists");
1081 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1082 if (!(*i)->hidden()) {
1083 if (!(*i)->empty()) {
1085 child->add_child_nocopy ((*i)->get_state());
1087 child->add_child_nocopy ((*i)->get_template());
1093 child = node->add_child ("UnusedPlaylists");
1094 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1095 if (!(*i)->hidden()) {
1096 if (!(*i)->empty()) {
1098 child->add_child_nocopy ((*i)->get_state());
1100 child->add_child_nocopy ((*i)->get_template());
1108 child = node->add_child ("Click");
1109 child->add_child_nocopy (_click_io->state (full_state));
1113 child = node->add_child ("NamedSelections");
1114 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1116 child->add_child_nocopy ((*i)->get_state());
1121 node->add_child_nocopy (_tempo_map->get_state());
1123 node->add_child_nocopy (get_control_protocol_state());
1126 node->add_child_copy (*_extra_xml);
1133 Session::get_control_protocol_state ()
1135 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1136 return cpm.get_state();
1140 Session::set_state (const XMLNode& node)
1144 const XMLProperty* prop;
1147 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1149 if (node.name() != X_("Session")){
1150 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1154 if ((prop = node.property ("name")) != 0) {
1155 _name = prop->value ();
1158 if ((prop = node.property (X_("sample-rate"))) != 0) {
1160 _nominal_frame_rate = atoi (prop->value());
1162 if (_nominal_frame_rate != _current_frame_rate) {
1163 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1169 setup_raid_path(_path);
1171 if ((prop = node.property (X_("id-counter"))) != 0) {
1173 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1174 ID::init_counter (x);
1176 /* old sessions used a timebased counter, so fake
1177 the startup ID counter based on a standard
1182 ID::init_counter (now);
1186 IO::disable_ports ();
1187 IO::disable_connecting ();
1189 /* Object loading order:
1194 MIDI <= relies on data from Options/Config
1207 if ((child = find_named_node (node, "extra")) != 0) {
1208 _extra_xml = new XMLNode (*child);
1211 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1212 load_options (*child);
1213 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1214 load_options (*child);
1216 error << _("Session: XML state has no options section") << endmsg;
1219 if (use_config_midi_ports ()) {
1222 if ((child = find_named_node (node, "Locations")) == 0) {
1223 error << _("Session: XML state has no locations section") << endmsg;
1225 } else if (_locations.set_state (*child)) {
1231 if ((location = _locations.auto_loop_location()) != 0) {
1232 set_auto_loop_location (location);
1235 if ((location = _locations.auto_punch_location()) != 0) {
1236 set_auto_punch_location (location);
1239 if ((location = _locations.end_location()) == 0) {
1240 _locations.add (end_location);
1242 delete end_location;
1243 end_location = location;
1246 if ((location = _locations.start_location()) == 0) {
1247 _locations.add (start_location);
1249 delete start_location;
1250 start_location = location;
1253 AudioFileSource::set_header_position_offset (start_location->start());
1255 if ((child = find_named_node (node, "Sources")) == 0) {
1256 error << _("Session: XML state has no sources section") << endmsg;
1258 } else if (load_sources (*child)) {
1262 if ((child = find_named_node (node, "Regions")) == 0) {
1263 error << _("Session: XML state has no Regions section") << endmsg;
1265 } else if (load_regions (*child)) {
1269 if ((child = find_named_node (node, "Playlists")) == 0) {
1270 error << _("Session: XML state has no playlists section") << endmsg;
1272 } else if (load_playlists (*child)) {
1276 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1278 } else if (load_unused_playlists (*child)) {
1282 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1283 if (load_named_selections (*child)) {
1288 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1289 error << _("Session: XML state has no diskstreams section") << endmsg;
1291 } else if (load_diskstreams (*child)) {
1295 if ((child = find_named_node (node, "Connections")) == 0) {
1296 error << _("Session: XML state has no connections section") << endmsg;
1298 } else if (load_connections (*child)) {
1302 if ((child = find_named_node (node, "EditGroups")) == 0) {
1303 error << _("Session: XML state has no edit groups section") << endmsg;
1305 } else if (load_edit_groups (*child)) {
1309 if ((child = find_named_node (node, "MixGroups")) == 0) {
1310 error << _("Session: XML state has no mix groups section") << endmsg;
1312 } else if (load_mix_groups (*child)) {
1316 if ((child = find_named_node (node, "TempoMap")) == 0) {
1317 error << _("Session: XML state has no Tempo Map section") << endmsg;
1319 } else if (_tempo_map->set_state (*child)) {
1323 if ((child = find_named_node (node, "Routes")) == 0) {
1324 error << _("Session: XML state has no routes section") << endmsg;
1326 } else if (load_routes (*child)) {
1330 if ((child = find_named_node (node, "Click")) == 0) {
1331 warning << _("Session: XML state has no click section") << endmsg;
1332 } else if (_click_io) {
1333 _click_io->set_state (*child);
1336 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1337 ControlProtocolManager::instance().set_protocol_states (*child);
1340 /* here beginneth the second phase ... */
1342 StateReady (); /* EMIT SIGNAL */
1351 Session::load_routes (const XMLNode& node)
1354 XMLNodeConstIterator niter;
1355 RouteList new_routes;
1357 nlist = node.children();
1361 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1362 XMLProperty* prop = (*niter)->property ("default-type");
1364 if (prop && prop->value() == "unknown" ) {
1365 std::cout << "ignoring route with type unknown. (video-track)" << std::endl;
1366 // Note: this may mess up remote_control IDs or more..
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::route_template_dir ()
2070 return Glib::build_filename (get_user_ardour_path(), "route_templates");
2074 Session::export_dir () const
2076 return Glib::build_filename (_path, export_dir_name);
2080 Session::suffixed_search_path (string suffix, bool data)
2084 path += get_user_ardour_path();
2085 if (path[path.length()-1] != ':') {
2090 path += get_system_data_path();
2092 path += get_system_module_path();
2095 vector<string> split_path;
2097 split (path, split_path, ':');
2100 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2105 if (distance (i, split_path.end()) != 1) {
2114 Session::template_path ()
2116 return suffixed_search_path (X_("templates"), true);
2121 Session::route_template_path ()
2123 return suffixed_search_path (X_("route_templates"), true);
2127 Session::control_protocol_path ()
2129 char *p = getenv ("ARDOUR_CONTROL_SURFACE_PATH");
2133 return suffixed_search_path (X_("surfaces"), false);
2137 Session::load_connections (const XMLNode& node)
2139 XMLNodeList nlist = node.children();
2140 XMLNodeConstIterator niter;
2144 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2145 if ((*niter)->name() == "InputConnection") {
2146 add_connection (new ARDOUR::InputConnection (**niter));
2147 } else if ((*niter)->name() == "OutputConnection") {
2148 add_connection (new ARDOUR::OutputConnection (**niter));
2150 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2159 Session::load_edit_groups (const XMLNode& node)
2161 return load_route_groups (node, true);
2165 Session::load_mix_groups (const XMLNode& node)
2167 return load_route_groups (node, false);
2171 Session::load_route_groups (const XMLNode& node, bool edit)
2173 XMLNodeList nlist = node.children();
2174 XMLNodeConstIterator niter;
2179 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2180 if ((*niter)->name() == "RouteGroup") {
2182 rg = add_edit_group ("");
2183 rg->set_state (**niter);
2185 rg = add_mix_group ("");
2186 rg->set_state (**niter);
2195 state_file_filter (const string &str, void *arg)
2197 return (str.length() > strlen(Session::statefile_suffix()) &&
2198 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2202 bool operator()(const string* a, const string* b) {
2208 remove_end(string* state)
2210 string statename(*state);
2212 string::size_type start,end;
2213 if ((start = statename.find_last_of ('/')) != string::npos) {
2214 statename = statename.substr (start+1);
2217 if ((end = statename.rfind(".ardour")) == string::npos) {
2218 end = statename.length();
2221 return new string(statename.substr (0, end));
2225 Session::possible_states (string path)
2227 PathScanner scanner;
2228 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2230 transform(states->begin(), states->end(), states->begin(), remove_end);
2233 sort (states->begin(), states->end(), cmp);
2239 Session::possible_states () const
2241 return possible_states(_path);
2245 Session::auto_save()
2247 save_state (_current_snapshot_name);
2251 Session::add_edit_group (string name)
2253 RouteGroup* rg = new RouteGroup (*this, name);
2254 edit_groups.push_back (rg);
2255 edit_group_added (rg); /* EMIT SIGNAL */
2261 Session::add_mix_group (string name)
2263 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2264 mix_groups.push_back (rg);
2265 mix_group_added (rg); /* EMIT SIGNAL */
2271 Session::remove_edit_group (RouteGroup& rg)
2273 list<RouteGroup*>::iterator i;
2275 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2276 (*i)->apply (&Route::drop_edit_group, this);
2277 edit_groups.erase (i);
2278 edit_group_removed (); /* EMIT SIGNAL */
2285 Session::remove_mix_group (RouteGroup& rg)
2287 list<RouteGroup*>::iterator i;
2289 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2290 (*i)->apply (&Route::drop_mix_group, this);
2291 mix_groups.erase (i);
2292 mix_group_removed (); /* EMIT SIGNAL */
2299 Session::mix_group_by_name (string name)
2301 list<RouteGroup *>::iterator i;
2303 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2304 if ((*i)->name() == name) {
2312 Session::edit_group_by_name (string name)
2314 list<RouteGroup *>::iterator i;
2316 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2317 if ((*i)->name() == name) {
2325 Session::begin_reversible_command (string name)
2327 current_trans = new UndoTransaction;
2328 current_trans->set_name (name);
2332 Session::commit_reversible_command (Command *cmd)
2337 current_trans->add_command (cmd);
2340 if (current_trans->empty()) {
2344 gettimeofday (&now, 0);
2345 current_trans->set_timestamp (now);
2347 _history.add (current_trans);
2350 Session::GlobalRouteBooleanState
2351 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2353 GlobalRouteBooleanState s;
2354 boost::shared_ptr<RouteList> r = routes.reader ();
2356 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2357 if (!(*i)->hidden()) {
2358 RouteBooleanState v;
2361 Route* r = (*i).get();
2362 v.second = (r->*method)();
2371 Session::GlobalRouteMeterState
2372 Session::get_global_route_metering ()
2374 GlobalRouteMeterState s;
2375 boost::shared_ptr<RouteList> r = routes.reader ();
2377 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2378 if (!(*i)->hidden()) {
2382 v.second = (*i)->meter_point();
2392 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2394 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2396 boost::shared_ptr<Route> r = (i->first.lock());
2399 r->set_meter_point (i->second, arg);
2405 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2407 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2409 boost::shared_ptr<Route> r = (i->first.lock());
2412 Route* rp = r.get();
2413 (rp->*method) (i->second, arg);
2419 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2421 set_global_route_boolean (s, &Route::set_mute, src);
2425 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2427 set_global_route_boolean (s, &Route::set_solo, src);
2431 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2433 set_global_route_boolean (s, &Route::set_record_enable, src);
2438 Session::global_mute_memento (void* src)
2440 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2444 Session::global_metering_memento (void* src)
2446 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2450 Session::global_solo_memento (void* src)
2452 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2456 Session::global_record_enable_memento (void* src)
2458 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2463 template_filter (const string &str, void *arg)
2465 return (str.length() > strlen(Session::template_suffix()) &&
2466 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2470 Session::get_template_list (list<string> &template_names)
2472 vector<string *> *templates;
2473 PathScanner scanner;
2476 path = template_path ();
2478 templates = scanner (path, template_filter, 0, false, true);
2480 vector<string*>::iterator i;
2481 for (i = templates->begin(); i != templates->end(); ++i) {
2482 string fullpath = *(*i);
2485 start = fullpath.find_last_of ('/') + 1;
2486 if ((end = fullpath.find_last_of ('.')) <0) {
2487 end = fullpath.length();
2490 template_names.push_back(fullpath.substr(start, (end-start)));
2495 Session::get_route_templates (vector<RouteTemplateInfo>& template_names)
2497 vector<string *> *templates;
2498 PathScanner scanner;
2501 path = route_template_path ();
2503 templates = scanner (path, template_filter, 0, false, true);
2509 for (vector<string*>::iterator i = templates->begin(); i != templates->end(); ++i) {
2510 string fullpath = *(*i);
2514 if (!tree.read (fullpath.c_str())) {
2518 XMLNode* root = tree.root();
2520 RouteTemplateInfo rti;
2522 rti.name = IO::name_from_state (*root->children().front());
2523 rti.path = fullpath;
2525 template_names.push_back (rti);
2532 Session::read_favorite_dirs (FavoriteDirs & favs)
2534 Glib::ustring path = Glib::build_filename (get_user_ardour_path(), "favorite_dirs");
2536 ifstream fav (path.c_str());
2541 if (errno != ENOENT) {
2542 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2553 getline(fav, newfav);
2559 favs.push_back (newfav);
2566 Session::write_favorite_dirs (FavoriteDirs & favs)
2568 Glib::ustring path = Glib::build_filename (get_user_ardour_path(), "favorite_dirs");
2570 ofstream fav (path.c_str());
2576 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2577 fav << (*i) << endl;
2584 accept_all_non_peak_files (const string& path, void *arg)
2586 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2590 accept_all_state_files (const string& path, void *arg)
2592 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2596 Session::find_all_sources (string path, set<string>& result)
2601 if (!tree.read (path)) {
2605 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2610 XMLNodeConstIterator niter;
2612 nlist = node->children();
2616 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2620 if ((prop = (*niter)->property (X_("name"))) == 0) {
2624 if (prop->value()[0] == '/') {
2625 /* external file, ignore */
2629 /* now we have to actually find the file */
2636 if (AudioFileSource::find (prop->value(), true, false, is_new, chan, path, name)) {
2637 cerr << "Got " << path << " from XML source with prop = " << prop->value() << endl;
2638 result.insert (path);
2646 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2648 PathScanner scanner;
2649 vector<string*>* state_files;
2651 string this_snapshot_path;
2657 if (ripped[ripped.length()-1] == '/') {
2658 ripped = ripped.substr (0, ripped.length() - 1);
2661 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2663 if (state_files == 0) {
2668 this_snapshot_path = _path;
2669 this_snapshot_path += legalize_for_path (_current_snapshot_name);
2670 this_snapshot_path += _statefile_suffix;
2672 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2674 if (exclude_this_snapshot && **i == this_snapshot_path) {
2678 if (find_all_sources (**i, result) < 0) {
2686 struct RegionCounter {
2687 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2688 AudioSourceList::iterator iter;
2689 boost::shared_ptr<Region> region;
2692 RegionCounter() : count (0) {}
2696 Session::cleanup_sources (Session::cleanup_report& rep)
2698 vector<boost::shared_ptr<Source> > dead_sources;
2699 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2700 PathScanner scanner;
2702 vector<space_and_path>::iterator i;
2703 vector<space_and_path>::iterator nexti;
2704 vector<string*>* soundfiles;
2705 vector<string> unused;
2706 set<string> all_sources;
2711 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2714 /* step 1: consider deleting all unused playlists */
2716 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2719 status = AskAboutPlaylistDeletion (*x);
2728 playlists_tbd.push_back (*x);
2732 /* leave it alone */
2737 /* now delete any that were marked for deletion */
2739 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2740 (*x)->drop_references ();
2743 playlists_tbd.clear ();
2745 /* step 2: find all un-used sources */
2750 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2752 AudioSourceList::iterator tmp;
2757 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2761 if (!i->second->used() && i->second->length() > 0) {
2762 dead_sources.push_back (i->second);
2763 i->second->GoingAway();
2769 /* build a list of all the possible sound directories for the session */
2771 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2776 sound_path += (*i).path;
2777 sound_path += sound_dir (false);
2779 if (nexti != session_dirs.end()) {
2786 /* now do the same thing for the files that ended up in the sounds dir(s)
2787 but are not referenced as sources in any snapshot.
2790 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2792 if (soundfiles == 0) {
2796 /* find all sources, but don't use this snapshot because the
2797 state file on disk still references sources we may have already
2801 find_all_sources_across_snapshots (all_sources, true);
2803 /* add our current source list
2806 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2807 boost::shared_ptr<AudioFileSource> fs;
2809 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2810 all_sources.insert (fs->path());
2814 char tmppath1[PATH_MAX+1];
2815 char tmppath2[PATH_MAX+1];
2817 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2822 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2824 realpath(spath.c_str(), tmppath1);
2825 realpath((*i).c_str(), tmppath2);
2827 cerr << "comparing " << tmppath1 << " and " << tmppath2 << endl;
2829 if (strcmp(tmppath1, tmppath2) == 0) {
2836 unused.push_back (spath);
2840 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2842 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2843 struct stat statbuf;
2845 rep.paths.push_back (*x);
2846 if (stat ((*x).c_str(), &statbuf) == 0) {
2847 rep.space += statbuf.st_size;
2852 /* don't move the file across filesystems, just
2853 stick it in the `dead_sound_dir_name' directory
2854 on whichever filesystem it was already on.
2857 if ((*x).find ("/sounds/") != string::npos) {
2859 /* old school, go up 1 level */
2861 newpath = Glib::path_get_dirname (*x); // "sounds"
2862 newpath = Glib::path_get_dirname (newpath); // "session-name"
2866 /* new school, go up 4 levels */
2868 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2869 newpath = Glib::path_get_dirname (newpath); // "session-name"
2870 newpath = Glib::path_get_dirname (newpath); // "interchange"
2871 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2875 newpath += dead_sound_dir_name;
2877 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2878 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2883 newpath += Glib::path_get_basename ((*x));
2885 if (access (newpath.c_str(), F_OK) == 0) {
2887 /* the new path already exists, try versioning */
2889 char buf[PATH_MAX+1];
2893 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2896 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2897 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2901 if (version == 999) {
2902 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2906 newpath = newpath_v;
2911 /* it doesn't exist, or we can't read it or something */
2915 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2916 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2917 (*x), newpath, strerror (errno))
2922 /* see if there an easy to find peakfile for this file, and remove it.
2925 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2926 peakpath += ".peak";
2928 if (access (peakpath.c_str(), W_OK) == 0) {
2929 if (::unlink (peakpath.c_str()) != 0) {
2930 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2931 peakpath, _path, strerror (errno))
2933 /* try to back out */
2934 rename (newpath.c_str(), _path.c_str());
2942 /* dump the history list */
2946 /* save state so we don't end up a session file
2947 referring to non-existent sources.
2953 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2959 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2961 vector<space_and_path>::iterator i;
2962 string dead_sound_dir;
2963 struct dirent* dentry;
2964 struct stat statbuf;
2970 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2972 dead_sound_dir = (*i).path;
2973 dead_sound_dir += dead_sound_dir_name;
2975 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2979 while ((dentry = readdir (dead)) != 0) {
2981 /* avoid '.' and '..' */
2983 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2984 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2990 fullpath = dead_sound_dir;
2992 fullpath += dentry->d_name;
2994 if (stat (fullpath.c_str(), &statbuf)) {
2998 if (!S_ISREG (statbuf.st_mode)) {
3002 if (unlink (fullpath.c_str())) {
3003 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
3004 fullpath, strerror (errno))
3008 rep.paths.push_back (dentry->d_name);
3009 rep.space += statbuf.st_size;
3020 Session::set_dirty ()
3022 bool was_dirty = dirty();
3024 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
3028 DirtyChanged(); /* EMIT SIGNAL */
3034 Session::set_clean ()
3036 bool was_dirty = dirty();
3038 _state_of_the_state = Clean;
3042 DirtyChanged(); /* EMIT SIGNAL */
3047 Session::set_deletion_in_progress ()
3049 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3054 Session::add_controllable (Controllable* c)
3056 /* this adds a controllable to the list managed by the Session.
3057 this is a subset of those managed by the Controllable class
3058 itself, and represents the only ones whose state will be saved
3059 as part of the session.
3062 Glib::Mutex::Lock lm (controllables_lock);
3063 controllables.insert (c);
3067 Session::remove_controllable (Controllable* c)
3069 if (_state_of_the_state | Deletion) {
3073 Glib::Mutex::Lock lm (controllables_lock);
3075 Controllables::iterator x = controllables.find (c);
3077 if (x != controllables.end()) {
3078 controllables.erase (x);
3083 Session::controllable_by_id (const PBD::ID& id)
3085 Glib::Mutex::Lock lm (controllables_lock);
3087 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3088 if ((*i)->id() == id) {
3097 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3099 Stateful::add_instant_xml (node, dir);
3100 Config->add_instant_xml (node, get_user_ardour_path());
3104 Session::save_history (string snapshot_name)
3110 if (snapshot_name.empty()) {
3111 snapshot_name = _current_snapshot_name;
3114 xml_path = _path + legalize_for_path (snapshot_name) + ".history";
3116 bak_path = xml_path + ".bak";
3118 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && ::rename (xml_path.c_str(), bak_path.c_str())) {
3119 error << _("could not backup old history file, current history not saved.") << endmsg;
3123 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3127 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3129 if (!tree.write (xml_path))
3131 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3133 /* don't leave a corrupt file lying around if it is
3137 if (unlink (xml_path.c_str())) {
3138 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3140 if (rename (bak_path.c_str(), xml_path.c_str()))
3142 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3153 Session::restore_history (string snapshot_name)
3158 if (snapshot_name.empty()) {
3159 snapshot_name = _current_snapshot_name;
3163 xmlpath = _path + legalize_for_path (snapshot_name) + ".history";
3164 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3166 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3170 if (!tree.read (xmlpath)) {
3171 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3175 /* replace history */
3178 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3181 UndoTransaction* ut = new UndoTransaction ();
3184 ut->set_name(t->property("name")->value());
3185 stringstream ss(t->property("tv_sec")->value());
3187 ss.str(t->property("tv_usec")->value());
3189 ut->set_timestamp(tv);
3191 for (XMLNodeConstIterator child_it = t->children().begin();
3192 child_it != t->children().end();
3195 XMLNode *n = *child_it;
3198 if (n->name() == "MementoCommand" ||
3199 n->name() == "MementoUndoCommand" ||
3200 n->name() == "MementoRedoCommand") {
3202 if ((c = memento_command_factory(n))) {
3206 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3208 if ((c = global_state_command_factory (*n))) {
3209 ut->add_command (c);
3214 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3225 Session::config_changed (const char* parameter_name)
3227 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3229 if (PARAM_IS ("seamless-loop")) {
3231 } else if (PARAM_IS ("rf-speed")) {
3233 } else if (PARAM_IS ("auto-loop")) {
3235 } else if (PARAM_IS ("auto-input")) {
3237 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3238 /* auto-input only makes a difference if we're rolling */
3240 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3242 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3243 if ((*i)->record_enabled ()) {
3244 (*i)->monitor_input (!Config->get_auto_input());
3249 } else if (PARAM_IS ("punch-in")) {
3253 if ((location = _locations.auto_punch_location()) != 0) {
3255 if (Config->get_punch_in ()) {
3256 replace_event (Event::PunchIn, location->start());
3258 remove_event (location->start(), Event::PunchIn);
3262 } else if (PARAM_IS ("punch-out")) {
3266 if ((location = _locations.auto_punch_location()) != 0) {
3268 if (Config->get_punch_out()) {
3269 replace_event (Event::PunchOut, location->end());
3271 clear_events (Event::PunchOut);
3275 } else if (PARAM_IS ("edit-mode")) {
3277 Glib::Mutex::Lock lm (playlist_lock);
3279 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3280 (*i)->set_edit_mode (Config->get_edit_mode ());
3283 } else if (PARAM_IS ("use-video-sync")) {
3285 waiting_for_sync_offset = Config->get_use_video_sync();
3287 } else if (PARAM_IS ("mmc-control")) {
3289 poke_midi_thread ();
3291 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-device-id")) {
3293 set_mmc_receive_device_id (Config->get_mmc_receive_device_id());
3295 } else if (PARAM_IS ("mmc-send-device-id")) {
3297 set_mmc_send_device_id (Config->get_mmc_send_device_id());
3299 } else if (PARAM_IS ("midi-control")) {
3301 poke_midi_thread ();
3303 } else if (PARAM_IS ("raid-path")) {
3305 setup_raid_path (Config->get_raid_path());
3307 } else if (PARAM_IS ("smpte-format")) {
3311 } else if (PARAM_IS ("video-pullup")) {
3315 } else if (PARAM_IS ("seamless-loop")) {
3317 if (play_loop && transport_rolling()) {
3318 // to reset diskstreams etc
3319 request_play_loop (true);
3322 } else if (PARAM_IS ("rf-speed")) {
3324 cumulative_rf_motion = 0;
3327 } else if (PARAM_IS ("click-sound")) {
3329 setup_click_sounds (1);
3331 } else if (PARAM_IS ("click-emphasis-sound")) {
3333 setup_click_sounds (-1);
3335 } else if (PARAM_IS ("clicking")) {
3337 if (Config->get_clicking()) {
3338 if (_click_io && click_data) { // don't require emphasis data
3345 } else if (PARAM_IS ("send-mtc")) {
3347 /* only set the internal flag if we have
3351 if (_mtc_port != 0) {
3352 session_send_mtc = Config->get_send_mtc();
3353 if (session_send_mtc) {
3354 /* mark us ready to send */
3355 next_quarter_frame_to_send = 0;
3358 session_send_mtc = false;
3361 } else if (PARAM_IS ("send-mmc")) {
3363 /* only set the internal flag if we have
3367 if (_mmc_port != 0) {
3368 session_send_mmc = Config->get_send_mmc();
3371 session_send_mmc = false;
3374 } else if (PARAM_IS ("midi-feedback")) {
3376 /* only set the internal flag if we have
3380 if (_mtc_port != 0) {
3381 session_midi_feedback = Config->get_midi_feedback();
3384 } else if (PARAM_IS ("jack-time-master")) {
3386 engine().reset_timebase ();
3388 } else if (PARAM_IS ("native-file-header-format")) {
3390 if (!first_file_header_format_reset) {
3391 reset_native_file_format ();
3394 first_file_header_format_reset = false;
3396 } else if (PARAM_IS ("native-file-data-format")) {
3398 if (!first_file_data_format_reset) {
3399 reset_native_file_format ();
3402 first_file_data_format_reset = false;
3404 } else if (PARAM_IS ("slave-source")) {
3405 set_slave_source (Config->get_slave_source());
3406 } else if (PARAM_IS ("remote-model")) {
3407 set_remote_control_ids ();
3408 } else if (PARAM_IS ("denormal-model")) {
3410 } else if (PARAM_IS ("history-depth")) {
3411 set_history_depth (Config->get_history_depth());
3412 } else if (PARAM_IS ("sync-all-route-ordering")) {
3413 sync_order_keys ("session");
3414 } else if (PARAM_IS ("initial-program-change")) {
3416 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3417 MIDI::byte* buf = new MIDI::byte[2];
3419 buf[0] = MIDI::program; // channel zero by default
3420 buf[1] = (Config->get_initial_program_change() & 0x7f);
3421 deliver_midi (_mmc_port, buf, 2);
3423 } else if (PARAM_IS ("solo-mute-override")) {
3424 catch_up_on_solo_mute_override ();
3434 Session::set_history_depth (uint32_t d)
3436 _history.set_depth (d);