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 += _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 + old_name + _statefile_suffix;
622 const string new_xml_path = _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 + 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 += 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 += snapshot_name;
695 xml_path += _pending_suffix;
702 tmp_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 += 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 += 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 += 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) {
1363 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1366 error << _("Session: cannot create Route from XML description.") << endmsg;
1370 BootMessage (string_compose (_("Loaded track/bus %1"), route->name()));
1372 new_routes.push_back (route);
1375 add_routes (new_routes, false);
1380 boost::shared_ptr<Route>
1381 Session::XMLRouteFactory (const XMLNode& node)
1383 if (node.name() != "Route") {
1384 return boost::shared_ptr<Route> ((Route*) 0);
1387 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1388 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1391 boost::shared_ptr<Route> x (new Route (*this, node));
1397 Session::load_regions (const XMLNode& node)
1400 XMLNodeConstIterator niter;
1401 boost::shared_ptr<AudioRegion> region;
1403 nlist = node.children();
1407 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1408 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1409 error << _("Session: cannot create Region from XML description.");
1410 const XMLProperty *name = (**niter).property("name");
1413 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1423 boost::shared_ptr<AudioRegion>
1424 Session::XMLRegionFactory (const XMLNode& node, bool full)
1426 const XMLProperty* prop;
1427 boost::shared_ptr<Source> source;
1428 boost::shared_ptr<AudioSource> as;
1430 SourceList master_sources;
1431 uint32_t nchans = 1;
1434 if (node.name() != X_("Region")) {
1435 return boost::shared_ptr<AudioRegion>();
1438 if ((prop = node.property (X_("channels"))) != 0) {
1439 nchans = atoi (prop->value().c_str());
1443 if ((prop = node.property ("name")) == 0) {
1444 cerr << "no name for this region\n";
1448 if ((prop = node.property (X_("source-0"))) == 0) {
1449 if ((prop = node.property ("source")) == 0) {
1450 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1451 return boost::shared_ptr<AudioRegion>();
1455 PBD::ID s_id (prop->value());
1457 if ((source = source_by_id (s_id)) == 0) {
1458 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1459 return boost::shared_ptr<AudioRegion>();
1462 as = boost::dynamic_pointer_cast<AudioSource>(source);
1464 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1465 return boost::shared_ptr<AudioRegion>();
1468 sources.push_back (as);
1470 /* pickup other channels */
1472 for (uint32_t n=1; n < nchans; ++n) {
1473 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1474 if ((prop = node.property (buf)) != 0) {
1476 PBD::ID id2 (prop->value());
1478 if ((source = source_by_id (id2)) == 0) {
1479 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1480 return boost::shared_ptr<AudioRegion>();
1483 as = boost::dynamic_pointer_cast<AudioSource>(source);
1485 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1486 return boost::shared_ptr<AudioRegion>();
1488 sources.push_back (as);
1492 for (uint32_t n=0; n < nchans; ++n) {
1493 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1494 if ((prop = node.property (buf)) != 0) {
1496 PBD::ID id2 (prop->value());
1498 if ((source = source_by_id (id2)) == 0) {
1499 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1500 return boost::shared_ptr<AudioRegion>();
1503 as = boost::dynamic_pointer_cast<AudioSource>(source);
1505 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1506 return boost::shared_ptr<AudioRegion>();
1508 master_sources.push_back (as);
1513 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1515 /* a final detail: this is the one and only place that we know how long missing files are */
1517 if (region->whole_file()) {
1518 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1519 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1521 sfp->set_length (region->length());
1526 if (!master_sources.empty()) {
1527 if (master_sources.size() != nchans) {
1528 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1530 region->set_master_sources (master_sources);
1538 catch (failed_constructor& err) {
1539 return boost::shared_ptr<AudioRegion>();
1544 Session::get_sources_as_xml ()
1547 XMLNode* node = new XMLNode (X_("Sources"));
1548 Glib::Mutex::Lock lm (audio_source_lock);
1550 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1551 node->add_child_nocopy (i->second->get_state());
1554 /* XXX get MIDI and other sources here */
1560 Session::path_from_region_name (string name, string identifier)
1562 char buf[PATH_MAX+1];
1564 string dir = discover_best_sound_dir ();
1566 for (n = 0; n < 999999; ++n) {
1567 if (identifier.length()) {
1568 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1569 identifier.c_str(), n);
1571 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1574 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1579 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1588 Session::load_sources (const XMLNode& node)
1591 XMLNodeConstIterator niter;
1592 boost::shared_ptr<Source> source;
1594 nlist = node.children();
1598 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1601 if ((source = XMLSourceFactory (**niter)) == 0) {
1602 error << _("Session: cannot create Source from XML description.") << endmsg;
1606 catch (non_existent_source& err) {
1607 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1608 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1615 boost::shared_ptr<Source>
1616 Session::XMLSourceFactory (const XMLNode& node)
1618 if (node.name() != "Source") {
1619 return boost::shared_ptr<Source>();
1623 /* note: do peak building in another thread when loading session state */
1624 return SourceFactory::create (*this, node, true);
1627 catch (failed_constructor& err) {
1628 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1629 return boost::shared_ptr<Source>();
1634 Session::save_template (string template_name)
1637 string xml_path, bak_path, template_path;
1639 if (_state_of_the_state & CannotSave) {
1644 string dir = template_dir();
1646 if ((dp = opendir (dir.c_str()))) {
1649 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1650 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1655 tree.set_root (&get_template());
1657 xml_path = Glib::build_filename(dir, template_name + _template_suffix);
1659 ifstream in(xml_path.c_str());
1662 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1668 if (!tree.write (xml_path)) {
1669 error << _("mix template not saved") << endmsg;
1677 Session::rename_template (string old_name, string new_name)
1679 string old_path = Glib::build_filename(template_dir(), old_name + _template_suffix);
1680 string new_path = Glib::build_filename(template_dir(), new_name + _template_suffix);
1682 return rename (old_path.c_str(), new_path.c_str());
1686 Session::delete_template (string name)
1688 string template_path = Glib::build_filename(template_dir(), name + _template_suffix);
1690 return remove (template_path.c_str());
1694 Session::refresh_disk_space ()
1697 struct statfs statfsbuf;
1698 vector<space_and_path>::iterator i;
1699 Glib::Mutex::Lock lm (space_lock);
1702 /* get freespace on every FS that is part of the session path */
1704 _total_free_4k_blocks = 0;
1706 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1707 statfs ((*i).path.c_str(), &statfsbuf);
1709 scale = statfsbuf.f_bsize/4096.0;
1711 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1712 _total_free_4k_blocks += (*i).blocks;
1718 Session::ensure_sound_dir (string path, string& result)
1723 /* Ensure that the parent directory exists */
1725 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1726 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1730 /* Ensure that the sounds directory exists */
1732 result = Glib::build_filename(path, sound_dir_name);
1734 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1735 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1739 dead = Glib::build_filename(path, dead_sound_dir_name);
1741 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1742 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1746 peak = Glib::build_filename(path, peak_dir_name);
1748 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1749 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1753 /* callers expect this to be terminated ... */
1760 Session::discover_best_sound_dir (bool destructive)
1762 vector<space_and_path>::iterator i;
1765 /* handle common case without system calls */
1767 if (session_dirs.size() == 1) {
1771 /* OK, here's the algorithm we're following here:
1773 We want to select which directory to use for
1774 the next file source to be created. Ideally,
1775 we'd like to use a round-robin process so as to
1776 get maximum performance benefits from splitting
1777 the files across multiple disks.
1779 However, in situations without much diskspace, an
1780 RR approach may end up filling up a filesystem
1781 with new files while others still have space.
1782 Its therefore important to pay some attention to
1783 the freespace in the filesystem holding each
1784 directory as well. However, if we did that by
1785 itself, we'd keep creating new files in the file
1786 system with the most space until it was as full
1787 as all others, thus negating any performance
1788 benefits of this RAID-1 like approach.
1790 So, we use a user-configurable space threshold. If
1791 there are at least 2 filesystems with more than this
1792 much space available, we use RR selection between them.
1793 If not, then we pick the filesystem with the most space.
1795 This gets a good balance between the two
1799 refresh_disk_space ();
1801 int free_enough = 0;
1803 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1804 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1809 if (free_enough >= 2) {
1811 bool found_it = false;
1813 /* use RR selection process, ensuring that the one
1817 i = last_rr_session_dir;
1820 if (++i == session_dirs.end()) {
1821 i = session_dirs.begin();
1824 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1825 if (ensure_sound_dir ((*i).path, result) == 0) {
1826 last_rr_session_dir = i;
1832 } while (i != last_rr_session_dir);
1835 result = sound_dir();
1840 /* pick FS with the most freespace (and that
1841 seems to actually work ...)
1844 vector<space_and_path> sorted;
1845 space_and_path_ascending_cmp cmp;
1847 sorted = session_dirs;
1848 sort (sorted.begin(), sorted.end(), cmp);
1850 for (i = sorted.begin(); i != sorted.end(); ++i) {
1851 if (ensure_sound_dir ((*i).path, result) == 0) {
1852 last_rr_session_dir = i;
1857 /* if the above fails, fall back to the most simplistic solution */
1859 if (i == sorted.end()) {
1868 Session::load_playlists (const XMLNode& node)
1871 XMLNodeConstIterator niter;
1872 boost::shared_ptr<Playlist> playlist;
1874 nlist = node.children();
1878 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1880 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1881 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1889 Session::load_unused_playlists (const XMLNode& node)
1892 XMLNodeConstIterator niter;
1893 boost::shared_ptr<Playlist> playlist;
1895 nlist = node.children();
1899 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1901 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1902 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1906 // now manually untrack it
1908 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1915 boost::shared_ptr<Playlist>
1916 Session::XMLPlaylistFactory (const XMLNode& node)
1919 return PlaylistFactory::create (*this, node);
1922 catch (failed_constructor& err) {
1923 return boost::shared_ptr<Playlist>();
1928 Session::load_named_selections (const XMLNode& node)
1931 XMLNodeConstIterator niter;
1934 nlist = node.children();
1938 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1940 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1941 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1949 Session::XMLNamedSelectionFactory (const XMLNode& node)
1952 return new NamedSelection (*this, node);
1955 catch (failed_constructor& err) {
1961 Session::dead_sound_dir () const
1964 res += dead_sound_dir_name;
1970 Session::old_sound_dir (bool with_path) const
1978 res += old_sound_dir_name;
1984 Session::sound_dir (bool with_path) const
1988 vector<string> parts;
1996 parts.push_back(interchange_dir_name);
1997 parts.push_back(legalize_for_path (_name));
1998 parts.push_back(sound_dir_name);
2000 res += Glib::build_filename(parts);
2007 /* if this already exists, don't check for the old session sound directory */
2009 if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2013 /* possibly support old session structure */
2016 string old_withpath;
2018 old_nopath += old_sound_dir_name;
2021 old_withpath = _path;
2022 old_withpath += old_sound_dir_name;
2024 if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2026 return old_withpath;
2031 /* ok, old "sounds" directory isn't there, return the new path */
2037 Session::peak_dir () const
2039 return Glib::build_filename (_path, peak_dir_name);
2043 Session::automation_dir () const
2045 return Glib::build_filename (_path, "automation");
2049 Session::analysis_dir () const
2051 return Glib::build_filename (_path, "analysis");
2055 Session::template_dir ()
2057 return Glib::build_filename (get_user_ardour_path(), "templates");
2061 Session::export_dir () const
2063 return Glib::build_filename (_path, export_dir_name);
2067 Session::suffixed_search_path (string suffix, bool data)
2071 path += get_user_ardour_path();
2072 if (path[path.length()-1] != ':') {
2077 path += get_system_data_path();
2079 path += get_system_module_path();
2082 vector<string> split_path;
2084 split (path, split_path, ':');
2087 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2092 if (distance (i, split_path.end()) != 1) {
2101 Session::template_path ()
2103 return suffixed_search_path (X_("templates"), true);
2107 Session::control_protocol_path ()
2109 char *p = getenv ("ARDOUR_CONTROL_SURFACE_PATH");
2113 return suffixed_search_path (X_("surfaces"), false);
2117 Session::load_connections (const XMLNode& node)
2119 XMLNodeList nlist = node.children();
2120 XMLNodeConstIterator niter;
2124 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2125 if ((*niter)->name() == "InputConnection") {
2126 add_connection (new ARDOUR::InputConnection (**niter));
2127 } else if ((*niter)->name() == "OutputConnection") {
2128 add_connection (new ARDOUR::OutputConnection (**niter));
2130 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2139 Session::load_edit_groups (const XMLNode& node)
2141 return load_route_groups (node, true);
2145 Session::load_mix_groups (const XMLNode& node)
2147 return load_route_groups (node, false);
2151 Session::load_route_groups (const XMLNode& node, bool edit)
2153 XMLNodeList nlist = node.children();
2154 XMLNodeConstIterator niter;
2159 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2160 if ((*niter)->name() == "RouteGroup") {
2162 rg = add_edit_group ("");
2163 rg->set_state (**niter);
2165 rg = add_mix_group ("");
2166 rg->set_state (**niter);
2175 state_file_filter (const string &str, void *arg)
2177 return (str.length() > strlen(Session::statefile_suffix()) &&
2178 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2182 bool operator()(const string* a, const string* b) {
2188 remove_end(string* state)
2190 string statename(*state);
2192 string::size_type start,end;
2193 if ((start = statename.find_last_of ('/')) != string::npos) {
2194 statename = statename.substr (start+1);
2197 if ((end = statename.rfind(".ardour")) == string::npos) {
2198 end = statename.length();
2201 return new string(statename.substr (0, end));
2205 Session::possible_states (string path)
2207 PathScanner scanner;
2208 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2210 transform(states->begin(), states->end(), states->begin(), remove_end);
2213 sort (states->begin(), states->end(), cmp);
2219 Session::possible_states () const
2221 return possible_states(_path);
2225 Session::auto_save()
2227 save_state (_current_snapshot_name);
2231 Session::add_edit_group (string name)
2233 RouteGroup* rg = new RouteGroup (*this, name);
2234 edit_groups.push_back (rg);
2235 edit_group_added (rg); /* EMIT SIGNAL */
2241 Session::add_mix_group (string name)
2243 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2244 mix_groups.push_back (rg);
2245 mix_group_added (rg); /* EMIT SIGNAL */
2251 Session::remove_edit_group (RouteGroup& rg)
2253 list<RouteGroup*>::iterator i;
2255 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2256 (*i)->apply (&Route::drop_edit_group, this);
2257 edit_groups.erase (i);
2258 edit_group_removed (); /* EMIT SIGNAL */
2265 Session::remove_mix_group (RouteGroup& rg)
2267 list<RouteGroup*>::iterator i;
2269 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2270 (*i)->apply (&Route::drop_mix_group, this);
2271 mix_groups.erase (i);
2272 mix_group_removed (); /* EMIT SIGNAL */
2279 Session::mix_group_by_name (string name)
2281 list<RouteGroup *>::iterator i;
2283 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2284 if ((*i)->name() == name) {
2292 Session::edit_group_by_name (string name)
2294 list<RouteGroup *>::iterator i;
2296 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2297 if ((*i)->name() == name) {
2305 Session::begin_reversible_command (string name)
2307 current_trans = new UndoTransaction;
2308 current_trans->set_name (name);
2312 Session::commit_reversible_command (Command *cmd)
2317 current_trans->add_command (cmd);
2320 if (current_trans->empty()) {
2324 gettimeofday (&now, 0);
2325 current_trans->set_timestamp (now);
2327 _history.add (current_trans);
2330 Session::GlobalRouteBooleanState
2331 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2333 GlobalRouteBooleanState s;
2334 boost::shared_ptr<RouteList> r = routes.reader ();
2336 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2337 if (!(*i)->hidden()) {
2338 RouteBooleanState v;
2341 Route* r = (*i).get();
2342 v.second = (r->*method)();
2351 Session::GlobalRouteMeterState
2352 Session::get_global_route_metering ()
2354 GlobalRouteMeterState s;
2355 boost::shared_ptr<RouteList> r = routes.reader ();
2357 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2358 if (!(*i)->hidden()) {
2362 v.second = (*i)->meter_point();
2372 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2374 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2376 boost::shared_ptr<Route> r = (i->first.lock());
2379 r->set_meter_point (i->second, arg);
2385 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2387 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2389 boost::shared_ptr<Route> r = (i->first.lock());
2392 Route* rp = r.get();
2393 (rp->*method) (i->second, arg);
2399 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2401 set_global_route_boolean (s, &Route::set_mute, src);
2405 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2407 set_global_route_boolean (s, &Route::set_solo, src);
2411 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2413 set_global_route_boolean (s, &Route::set_record_enable, src);
2418 Session::global_mute_memento (void* src)
2420 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2424 Session::global_metering_memento (void* src)
2426 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2430 Session::global_solo_memento (void* src)
2432 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2436 Session::global_record_enable_memento (void* src)
2438 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2443 template_filter (const string &str, void *arg)
2445 return (str.length() > strlen(Session::template_suffix()) &&
2446 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2450 Session::get_template_list (list<string> &template_names)
2452 vector<string *> *templates;
2453 PathScanner scanner;
2456 path = template_path ();
2458 templates = scanner (path, template_filter, 0, false, true);
2460 vector<string*>::iterator i;
2461 for (i = templates->begin(); i != templates->end(); ++i) {
2462 string fullpath = *(*i);
2465 start = fullpath.find_last_of ('/') + 1;
2466 if ((end = fullpath.find_last_of ('.')) <0) {
2467 end = fullpath.length();
2470 template_names.push_back(fullpath.substr(start, (end-start)));
2475 Session::read_favorite_dirs (FavoriteDirs & favs)
2477 Glib::ustring path = Glib::build_filename (get_user_ardour_path(), "favorite_dirs");
2479 ifstream fav (path.c_str());
2484 if (errno != ENOENT) {
2485 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2496 getline(fav, newfav);
2502 favs.push_back (newfav);
2509 Session::write_favorite_dirs (FavoriteDirs & favs)
2511 Glib::ustring path = Glib::build_filename (get_user_ardour_path(), "favorite_dirs");
2513 ofstream fav (path.c_str());
2519 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2520 fav << (*i) << endl;
2527 accept_all_non_peak_files (const string& path, void *arg)
2529 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2533 accept_all_state_files (const string& path, void *arg)
2535 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2539 Session::find_all_sources (string path, set<string>& result)
2544 if (!tree.read (path)) {
2548 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2553 XMLNodeConstIterator niter;
2555 nlist = node->children();
2559 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2563 if ((prop = (*niter)->property (X_("name"))) == 0) {
2567 if (prop->value()[0] == '/') {
2568 /* external file, ignore */
2572 string path = _path; /* /-terminated */
2573 path += sound_dir_name;
2575 path += prop->value();
2577 result.insert (path);
2584 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2586 PathScanner scanner;
2587 vector<string*>* state_files;
2589 string this_snapshot_path;
2595 if (ripped[ripped.length()-1] == '/') {
2596 ripped = ripped.substr (0, ripped.length() - 1);
2599 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2601 if (state_files == 0) {
2606 this_snapshot_path = _path;
2607 this_snapshot_path += _current_snapshot_name;
2608 this_snapshot_path += _statefile_suffix;
2610 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2612 if (exclude_this_snapshot && **i == this_snapshot_path) {
2616 if (find_all_sources (**i, result) < 0) {
2624 struct RegionCounter {
2625 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2626 AudioSourceList::iterator iter;
2627 boost::shared_ptr<Region> region;
2630 RegionCounter() : count (0) {}
2634 Session::cleanup_sources (Session::cleanup_report& rep)
2636 vector<boost::shared_ptr<Source> > dead_sources;
2637 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2638 PathScanner scanner;
2640 vector<space_and_path>::iterator i;
2641 vector<space_and_path>::iterator nexti;
2642 vector<string*>* soundfiles;
2643 vector<string> unused;
2644 set<string> all_sources;
2649 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2652 /* step 1: consider deleting all unused playlists */
2654 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2657 status = AskAboutPlaylistDeletion (*x);
2666 playlists_tbd.push_back (*x);
2670 /* leave it alone */
2675 /* now delete any that were marked for deletion */
2677 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2678 (*x)->drop_references ();
2681 playlists_tbd.clear ();
2683 /* step 2: find all un-used sources */
2688 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2690 AudioSourceList::iterator tmp;
2695 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2699 if (!i->second->used() && i->second->length() > 0) {
2700 dead_sources.push_back (i->second);
2701 i->second->GoingAway();
2707 /* build a list of all the possible sound directories for the session */
2709 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2714 sound_path += (*i).path;
2715 sound_path += sound_dir (false);
2717 if (nexti != session_dirs.end()) {
2724 /* now do the same thing for the files that ended up in the sounds dir(s)
2725 but are not referenced as sources in any snapshot.
2728 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2730 if (soundfiles == 0) {
2734 /* find all sources, but don't use this snapshot because the
2735 state file on disk still references sources we may have already
2739 find_all_sources_across_snapshots (all_sources, true);
2741 /* add our current source list
2744 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2745 boost::shared_ptr<AudioFileSource> fs;
2747 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2748 all_sources.insert (fs->path());
2752 char tmppath1[PATH_MAX+1];
2753 char tmppath2[PATH_MAX+1];
2755 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2760 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2762 realpath(spath.c_str(), tmppath1);
2763 realpath((*i).c_str(), tmppath2);
2765 if (strcmp(tmppath1, tmppath2) == 0) {
2772 unused.push_back (spath);
2776 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2778 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2779 struct stat statbuf;
2781 rep.paths.push_back (*x);
2782 if (stat ((*x).c_str(), &statbuf) == 0) {
2783 rep.space += statbuf.st_size;
2788 /* don't move the file across filesystems, just
2789 stick it in the `dead_sound_dir_name' directory
2790 on whichever filesystem it was already on.
2793 if ((*x).find ("/sounds/") != string::npos) {
2795 /* old school, go up 1 level */
2797 newpath = Glib::path_get_dirname (*x); // "sounds"
2798 newpath = Glib::path_get_dirname (newpath); // "session-name"
2802 /* new school, go up 4 levels */
2804 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2805 newpath = Glib::path_get_dirname (newpath); // "session-name"
2806 newpath = Glib::path_get_dirname (newpath); // "interchange"
2807 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2811 newpath += dead_sound_dir_name;
2813 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2814 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2819 newpath += Glib::path_get_basename ((*x));
2821 if (access (newpath.c_str(), F_OK) == 0) {
2823 /* the new path already exists, try versioning */
2825 char buf[PATH_MAX+1];
2829 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2832 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2833 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2837 if (version == 999) {
2838 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2842 newpath = newpath_v;
2847 /* it doesn't exist, or we can't read it or something */
2851 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2852 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2853 (*x), newpath, strerror (errno))
2858 /* see if there an easy to find peakfile for this file, and remove it.
2861 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2862 peakpath += ".peak";
2864 if (access (peakpath.c_str(), W_OK) == 0) {
2865 if (::unlink (peakpath.c_str()) != 0) {
2866 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2867 peakpath, _path, strerror (errno))
2869 /* try to back out */
2870 rename (newpath.c_str(), _path.c_str());
2878 /* dump the history list */
2882 /* save state so we don't end up a session file
2883 referring to non-existent sources.
2889 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2895 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2897 vector<space_and_path>::iterator i;
2898 string dead_sound_dir;
2899 struct dirent* dentry;
2900 struct stat statbuf;
2906 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2908 dead_sound_dir = (*i).path;
2909 dead_sound_dir += dead_sound_dir_name;
2911 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2915 while ((dentry = readdir (dead)) != 0) {
2917 /* avoid '.' and '..' */
2919 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2920 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2926 fullpath = dead_sound_dir;
2928 fullpath += dentry->d_name;
2930 if (stat (fullpath.c_str(), &statbuf)) {
2934 if (!S_ISREG (statbuf.st_mode)) {
2938 if (unlink (fullpath.c_str())) {
2939 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2940 fullpath, strerror (errno))
2944 rep.paths.push_back (dentry->d_name);
2945 rep.space += statbuf.st_size;
2956 Session::set_dirty ()
2958 bool was_dirty = dirty();
2960 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2964 DirtyChanged(); /* EMIT SIGNAL */
2970 Session::set_clean ()
2972 bool was_dirty = dirty();
2974 _state_of_the_state = Clean;
2978 DirtyChanged(); /* EMIT SIGNAL */
2983 Session::set_deletion_in_progress ()
2985 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2990 Session::add_controllable (Controllable* c)
2992 /* this adds a controllable to the list managed by the Session.
2993 this is a subset of those managed by the Controllable class
2994 itself, and represents the only ones whose state will be saved
2995 as part of the session.
2998 Glib::Mutex::Lock lm (controllables_lock);
2999 controllables.insert (c);
3003 Session::remove_controllable (Controllable* c)
3005 if (_state_of_the_state | Deletion) {
3009 Glib::Mutex::Lock lm (controllables_lock);
3011 Controllables::iterator x = controllables.find (c);
3013 if (x != controllables.end()) {
3014 controllables.erase (x);
3019 Session::controllable_by_id (const PBD::ID& id)
3021 Glib::Mutex::Lock lm (controllables_lock);
3023 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3024 if ((*i)->id() == id) {
3033 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3035 Stateful::add_instant_xml (node, dir);
3036 Config->add_instant_xml (node, get_user_ardour_path());
3040 Session::save_history (string snapshot_name)
3046 if (snapshot_name.empty()) {
3047 snapshot_name = _current_snapshot_name;
3050 xml_path = _path + snapshot_name + ".history";
3052 bak_path = xml_path + ".bak";
3054 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && ::rename (xml_path.c_str(), bak_path.c_str())) {
3055 error << _("could not backup old history file, current history not saved.") << endmsg;
3059 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3063 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3065 if (!tree.write (xml_path))
3067 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3069 /* don't leave a corrupt file lying around if it is
3073 if (unlink (xml_path.c_str())) {
3074 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3076 if (rename (bak_path.c_str(), xml_path.c_str()))
3078 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3089 Session::restore_history (string snapshot_name)
3094 if (snapshot_name.empty()) {
3095 snapshot_name = _current_snapshot_name;
3099 xmlpath = _path + snapshot_name + ".history";
3100 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3102 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3106 if (!tree.read (xmlpath)) {
3107 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3111 /* replace history */
3114 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3117 UndoTransaction* ut = new UndoTransaction ();
3120 ut->set_name(t->property("name")->value());
3121 stringstream ss(t->property("tv_sec")->value());
3123 ss.str(t->property("tv_usec")->value());
3125 ut->set_timestamp(tv);
3127 for (XMLNodeConstIterator child_it = t->children().begin();
3128 child_it != t->children().end();
3131 XMLNode *n = *child_it;
3134 if (n->name() == "MementoCommand" ||
3135 n->name() == "MementoUndoCommand" ||
3136 n->name() == "MementoRedoCommand") {
3138 if ((c = memento_command_factory(n))) {
3142 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3144 if ((c = global_state_command_factory (*n))) {
3145 ut->add_command (c);
3150 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3161 Session::config_changed (const char* parameter_name)
3163 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3165 if (PARAM_IS ("seamless-loop")) {
3167 } else if (PARAM_IS ("rf-speed")) {
3169 } else if (PARAM_IS ("auto-loop")) {
3171 } else if (PARAM_IS ("auto-input")) {
3173 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3174 /* auto-input only makes a difference if we're rolling */
3176 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3178 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3179 if ((*i)->record_enabled ()) {
3180 (*i)->monitor_input (!Config->get_auto_input());
3185 } else if (PARAM_IS ("punch-in")) {
3189 if ((location = _locations.auto_punch_location()) != 0) {
3191 if (Config->get_punch_in ()) {
3192 replace_event (Event::PunchIn, location->start());
3194 remove_event (location->start(), Event::PunchIn);
3198 } else if (PARAM_IS ("punch-out")) {
3202 if ((location = _locations.auto_punch_location()) != 0) {
3204 if (Config->get_punch_out()) {
3205 replace_event (Event::PunchOut, location->end());
3207 clear_events (Event::PunchOut);
3211 } else if (PARAM_IS ("edit-mode")) {
3213 Glib::Mutex::Lock lm (playlist_lock);
3215 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3216 (*i)->set_edit_mode (Config->get_edit_mode ());
3219 } else if (PARAM_IS ("use-video-sync")) {
3221 waiting_for_sync_offset = Config->get_use_video_sync();
3223 } else if (PARAM_IS ("mmc-control")) {
3225 poke_midi_thread ();
3227 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-device-id")) {
3229 set_mmc_receive_device_id (Config->get_mmc_receive_device_id());
3231 } else if (PARAM_IS ("mmc-send-device-id")) {
3233 set_mmc_send_device_id (Config->get_mmc_send_device_id());
3235 } else if (PARAM_IS ("midi-control")) {
3237 poke_midi_thread ();
3239 } else if (PARAM_IS ("raid-path")) {
3241 setup_raid_path (Config->get_raid_path());
3243 } else if (PARAM_IS ("smpte-format")) {
3247 } else if (PARAM_IS ("video-pullup")) {
3251 } else if (PARAM_IS ("seamless-loop")) {
3253 if (play_loop && transport_rolling()) {
3254 // to reset diskstreams etc
3255 request_play_loop (true);
3258 } else if (PARAM_IS ("rf-speed")) {
3260 cumulative_rf_motion = 0;
3263 } else if (PARAM_IS ("click-sound")) {
3265 setup_click_sounds (1);
3267 } else if (PARAM_IS ("click-emphasis-sound")) {
3269 setup_click_sounds (-1);
3271 } else if (PARAM_IS ("clicking")) {
3273 if (Config->get_clicking()) {
3274 if (_click_io && click_data) { // don't require emphasis data
3281 } else if (PARAM_IS ("send-mtc")) {
3283 /* only set the internal flag if we have
3287 if (_mtc_port != 0) {
3288 session_send_mtc = Config->get_send_mtc();
3289 if (session_send_mtc) {
3290 /* mark us ready to send */
3291 next_quarter_frame_to_send = 0;
3294 session_send_mtc = false;
3297 } else if (PARAM_IS ("send-mmc")) {
3299 /* only set the internal flag if we have
3303 if (_mmc_port != 0) {
3304 session_send_mmc = Config->get_send_mmc();
3307 session_send_mmc = false;
3310 } else if (PARAM_IS ("midi-feedback")) {
3312 /* only set the internal flag if we have
3316 if (_mtc_port != 0) {
3317 session_midi_feedback = Config->get_midi_feedback();
3320 } else if (PARAM_IS ("jack-time-master")) {
3322 engine().reset_timebase ();
3324 } else if (PARAM_IS ("native-file-header-format")) {
3326 if (!first_file_header_format_reset) {
3327 reset_native_file_format ();
3330 first_file_header_format_reset = false;
3332 } else if (PARAM_IS ("native-file-data-format")) {
3334 if (!first_file_data_format_reset) {
3335 reset_native_file_format ();
3338 first_file_data_format_reset = false;
3340 } else if (PARAM_IS ("slave-source")) {
3341 set_slave_source (Config->get_slave_source());
3342 } else if (PARAM_IS ("remote-model")) {
3343 set_remote_control_ids ();
3344 } else if (PARAM_IS ("denormal-model")) {
3346 } else if (PARAM_IS ("history-depth")) {
3347 set_history_depth (Config->get_history_depth());
3348 } else if (PARAM_IS ("sync-all-route-ordering")) {
3349 sync_order_keys ("session");
3350 } else if (PARAM_IS ("initial-program-change")) {
3352 if (_mmc_port && Config->get_initial_program_change() >= 0) {
3353 MIDI::byte* buf = new MIDI::byte[2];
3355 buf[0] = MIDI::program; // channel zero by default
3356 buf[1] = (Config->get_initial_program_change() & 0x7f);
3357 deliver_midi (_mmc_port, buf, 2);
3359 } else if (PARAM_IS ("solo-mute-override")) {
3360 catch_up_on_solo_mute_override ();
3370 Session::set_history_depth (uint32_t d)
3372 _history.set_depth (d);