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>
48 #include <midi++/mmc.h>
49 #include <midi++/port.h>
50 #include <pbd/error.h>
52 #include <glibmm/thread.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 _tempo_map = new TempoMap (_current_frame_rate);
131 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
133 g_atomic_int_set (&processing_prohibited, 0);
135 _transport_speed = 0;
136 _last_transport_speed = 0;
137 auto_play_legal = false;
138 transport_sub_state = 0;
139 _transport_frame = 0;
141 _requested_return_frame = -1;
142 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
143 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
144 _end_location_is_free = true;
145 g_atomic_int_set (&_record_status, Disabled);
146 loop_changing = false;
148 _last_roll_location = 0;
149 _last_record_location = 0;
150 pending_locate_frame = 0;
151 pending_locate_roll = false;
152 pending_locate_flush = false;
153 dstream_buffer_size = 0;
155 state_was_pending = false;
157 outbound_mtc_smpte_frame = 0;
158 next_quarter_frame_to_send = -1;
159 current_block_size = 0;
160 solo_update_disabled = false;
161 currently_soloing = false;
162 _have_captured = false;
163 _worst_output_latency = 0;
164 _worst_input_latency = 0;
165 _worst_track_latency = 0;
166 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
169 butler_mixdown_buffer = 0;
170 butler_gain_buffer = 0;
172 session_send_mmc = false;
173 session_send_mtc = false;
174 post_transport_work = PostTransportWork (0);
175 g_atomic_int_set (&butler_should_do_transport_work, 0);
176 g_atomic_int_set (&butler_active, 0);
177 g_atomic_int_set (&_playback_load, 100);
178 g_atomic_int_set (&_capture_load, 100);
179 g_atomic_int_set (&_playback_load_min, 100);
180 g_atomic_int_set (&_capture_load_min, 100);
182 waiting_to_start = false;
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;
193 midi_thread = (pthread_t) 0;
195 AudioDiskstream::allocate_working_buffers();
197 /* default short fade = 15ms */
199 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
200 SndFileSource::setup_standard_crossfades (frame_rate());
202 last_mmc_step.tv_sec = 0;
203 last_mmc_step.tv_usec = 0;
206 /* click sounds are unset by default, which causes us to internal
207 waveforms for clicks.
211 click_emphasis_data = 0;
213 click_emphasis_length = 0;
216 process_function = &Session::process_with_events;
218 if (Config->get_use_video_sync()) {
219 waiting_for_sync_offset = true;
221 waiting_for_sync_offset = false;
224 _current_frame_rate = 48000;
225 _base_frame_rate = 48000;
229 _smpte_offset_negative = true;
230 last_smpte_valid = false;
234 last_rr_session_dir = session_dirs.begin();
235 refresh_disk_space ();
237 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
241 average_slave_delta = 1800;
242 have_first_delta_accumulator = false;
243 delta_accumulator_cnt = 0;
244 slave_state = Stopped;
246 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
248 /* These are all static "per-class" signals */
250 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
251 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
252 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
253 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
254 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
255 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
257 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
259 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
261 /* stop IO objects from doing stuff until we're ready for them */
263 IO::disable_panners ();
264 IO::disable_ports ();
265 IO::disable_connecting ();
269 Session::second_stage_init (bool new_session)
271 AudioFileSource::set_peak_dir (peak_dir());
274 if (load_state (_current_snapshot_name)) {
277 remove_empty_sounds ();
280 if (start_butler_thread()) {
284 if (start_midi_thread ()) {
288 // set_state() will call setup_raid_path(), but if it's a new session we need
289 // to call setup_raid_path() here.
291 if (set_state (*state_tree->root())) {
295 setup_raid_path(_path);
298 /* we can't save till after ::when_engine_running() is called,
299 because otherwise we save state with no connections made.
300 therefore, we reset _state_of_the_state because ::set_state()
301 will have cleared it.
303 we also have to include Loading so that any events that get
304 generated between here and the end of ::when_engine_running()
305 will be processed directly rather than queued.
308 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
310 // set_auto_input (true);
311 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
312 _locations.added.connect (mem_fun (this, &Session::locations_added));
313 setup_click_sounds (0);
314 setup_midi_control ();
316 /* Pay attention ... */
318 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
319 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
322 when_engine_running();
325 /* handle this one in a different way than all others, so that its clear what happened */
327 catch (AudioEngine::PortRegistrationFailure& err) {
328 error << _("Unable to create all required ports")
337 send_full_time_code ();
338 _engine.transport_locate (0);
339 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
340 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
342 ControlProtocolManager::instance().set_session (*this);
345 _end_location_is_free = true;
347 _end_location_is_free = false;
354 Session::raid_path () const
358 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
363 return path.substr (0, path.length() - 1); // drop final colon
367 Session::setup_raid_path (string path)
369 string::size_type colon;
373 string::size_type len = path.length();
378 if (path.length() == 0) {
382 session_dirs.clear ();
384 for (string::size_type n = 0; n < len; ++n) {
385 if (path[n] == ':') {
392 /* no multiple search path, just one location (common case) */
396 session_dirs.push_back (sp);
403 if (fspath[fspath.length()-1] != '/') {
407 fspath += sound_dir (false);
409 AudioFileSource::set_search_path (fspath);
416 while ((colon = remaining.find_first_of (':')) != string::npos) {
419 sp.path = remaining.substr (0, colon);
420 session_dirs.push_back (sp);
422 /* add sounds to file search path */
425 if (fspath[fspath.length()-1] != '/') {
428 fspath += sound_dir (false);
431 remaining = remaining.substr (colon+1);
434 if (remaining.length()) {
441 if (fspath[fspath.length()-1] != '/') {
444 fspath += sound_dir (false);
447 session_dirs.push_back (sp);
450 /* set the AudioFileSource search path */
452 AudioFileSource::set_search_path (fspath);
454 /* reset the round-robin soundfile path thingie */
456 last_rr_session_dir = session_dirs.begin();
460 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
464 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
465 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
471 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
472 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
476 /* if this is is an existing session with an old "sounds" directory, just use it. see Session::sound_dir() for more details */
478 if (!Glib::file_test (old_sound_dir(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
482 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
483 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
488 dir = dead_sound_dir ();
490 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
491 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
497 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
498 error << string_compose(_("Session: cannot create session export dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
503 /* check new_session so we don't overwrite an existing one */
505 if (!mix_template.empty()) {
506 std::string in_path = mix_template;
508 ifstream in(in_path.c_str());
511 string out_path = _path;
513 out_path += _statefile_suffix;
515 ofstream out(out_path.c_str());
520 // okay, session is set up. Treat like normal saved
521 // session from now on.
527 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
533 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
540 /* set initial start + end point */
542 start_location->set_end (0);
543 _locations.add (start_location);
545 end_location->set_end (initial_length);
546 _locations.add (end_location);
548 _state_of_the_state = Clean;
550 if (save_state (_current_snapshot_name)) {
558 Session::load_diskstreams (const XMLNode& node)
561 XMLNodeConstIterator citer;
563 clist = node.children();
565 for (citer = clist.begin(); citer != clist.end(); ++citer) {
569 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
570 add_diskstream (dstream);
573 catch (failed_constructor& err) {
574 error << _("Session: could not load diskstream via XML state") << endmsg;
583 Session::maybe_write_autosave()
585 if (dirty() && record_status() != Recording) {
586 save_state("", true);
591 Session::remove_pending_capture_state ()
596 xml_path += _current_snapshot_name;
597 xml_path += _pending_suffix;
599 unlink (xml_path.c_str());
602 /** Rename a state file.
603 * @param snapshot_name Snapshot name.
606 Session::rename_state (string old_name, string new_name)
608 if (old_name == _current_snapshot_name || old_name == _name) {
609 /* refuse to rename the current snapshot or the "main" one */
613 const string old_xml_path = _path + old_name + _statefile_suffix;
614 const string new_xml_path = _path + new_name + _statefile_suffix;
616 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
617 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
621 /** Remove a state file.
622 * @param snapshot_name Snapshot name.
625 Session::remove_state (string snapshot_name)
627 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
628 /* refuse to remove the current snapshot or the "main" one */
632 const string xml_path = _path + snapshot_name + _statefile_suffix;
634 /* make a backup copy of the state file */
635 const string bak_path = xml_path + ".bak";
636 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
637 copy_file (xml_path, bak_path);
641 unlink (xml_path.c_str());
645 Session::save_state (string snapshot_name, bool pending)
651 if (_state_of_the_state & CannotSave) {
655 if (!_engine.connected ()) {
656 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
661 tree.set_root (&get_state());
663 if (snapshot_name.empty()) {
664 snapshot_name = _current_snapshot_name;
669 /* proper save: use _statefile_suffix (.ardour in English) */
671 xml_path += snapshot_name;
672 xml_path += _statefile_suffix;
674 /* make a backup copy of the old file */
678 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
679 copy_file (xml_path, bak_path);
684 /* pending save: use _pending_suffix (.pending in English) */
686 xml_path += snapshot_name;
687 xml_path += _pending_suffix;
694 tmp_path += snapshot_name;
697 // cerr << "actually writing state to " << xml_path << endl;
699 if (!tree.write (tmp_path)) {
700 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
701 unlink (tmp_path.c_str());
706 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
707 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
708 unlink (tmp_path.c_str());
715 save_history (snapshot_name);
717 bool was_dirty = dirty();
719 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
722 DirtyChanged (); /* EMIT SIGNAL */
725 StateSaved (snapshot_name); /* EMIT SIGNAL */
732 Session::restore_state (string snapshot_name)
734 if (load_state (snapshot_name) == 0) {
735 set_state (*state_tree->root());
742 Session::load_state (string snapshot_name)
751 state_was_pending = false;
753 /* check for leftover pending state from a crashed capture attempt */
756 xmlpath += snapshot_name;
757 xmlpath += _pending_suffix;
759 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
761 /* there is pending state from a crashed capture attempt */
763 if (AskAboutPendingState()) {
764 state_was_pending = true;
768 if (!state_was_pending) {
771 xmlpath += snapshot_name;
772 xmlpath += _statefile_suffix;
775 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
776 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
780 state_tree = new XMLTree;
784 if (!state_tree->read (xmlpath)) {
785 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
791 XMLNode& root (*state_tree->root());
793 if (root.name() != X_("Session")) {
794 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
800 const XMLProperty* prop;
803 if ((prop = root.property ("version")) == 0) {
804 /* no version implies very old version of Ardour */
808 major_version = atoi (prop->value()); // grab just the first number before the period
809 if (major_version < 2) {
818 backup_path += snapshot_name;
820 backup_path += _statefile_suffix;
822 /* don't make another copy if it already exists */
824 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
825 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
826 xmlpath, backup_path)
829 copy_file (xmlpath, backup_path);
831 /* if it fails, don't worry. right? */
839 Session::load_options (const XMLNode& node)
843 LocaleGuard lg (X_("POSIX"));
845 Config->set_variables (node, ConfigVariableBase::Session);
847 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
848 if ((prop = child->property ("val")) != 0) {
849 _end_location_is_free = (prop->value() == "yes");
857 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
859 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
860 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
862 return owner & modified_by_session_or_user;
866 Session::get_options () const
869 LocaleGuard lg (X_("POSIX"));
871 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
873 child = option_root.add_child ("end-marker-is-free");
874 child->add_property ("val", _end_location_is_free ? "yes" : "no");
886 Session::get_template()
888 /* if we don't disable rec-enable, diskstreams
889 will believe they need to store their capture
890 sources in their state node.
893 disable_record (false);
899 Session::state(bool full_state)
901 XMLNode* node = new XMLNode("Session");
904 // store libardour version, just in case
906 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
907 libardour2_major_version, libardour2_minor_version, libardour2_micro_version);
908 node->add_property("version", string(buf));
910 /* store configuration settings */
915 node->add_property ("name", _name);
917 if (session_dirs.size() > 1) {
921 vector<space_and_path>::iterator i = session_dirs.begin();
922 vector<space_and_path>::iterator next;
924 ++i; /* skip the first one */
928 while (i != session_dirs.end()) {
932 if (next != session_dirs.end()) {
942 child = node->add_child ("Path");
943 child->add_content (p);
947 /* save the ID counter */
949 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
950 node->add_property ("id-counter", buf);
952 /* various options */
954 node->add_child_nocopy (get_options());
956 child = node->add_child ("Sources");
959 Glib::Mutex::Lock sl (audio_source_lock);
961 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
963 /* Don't save information about AudioFileSources that are empty */
965 boost::shared_ptr<AudioFileSource> fs;
967 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
969 /* destructive file sources are OK if they are empty, because
970 we will re-use them every time.
973 if (!fs->destructive()) {
974 if (fs->length() == 0) {
980 child->add_child_nocopy (siter->second->get_state());
984 child = node->add_child ("Regions");
987 Glib::Mutex::Lock rl (region_lock);
989 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
991 /* only store regions not attached to playlists */
993 if (i->second->playlist() == 0) {
994 child->add_child_nocopy (i->second->state (true));
999 child = node->add_child ("DiskStreams");
1002 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1003 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1004 if (!(*i)->hidden()) {
1005 child->add_child_nocopy ((*i)->get_state());
1011 node->add_child_nocopy (_locations.get_state());
1013 // for a template, just create a new Locations, populate it
1014 // with the default start and end, and get the state for that.
1016 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1017 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1020 end->set_end(compute_initial_length());
1022 node->add_child_nocopy (loc.get_state());
1025 child = node->add_child ("Connections");
1027 Glib::Mutex::Lock lm (connection_lock);
1028 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1029 if (!(*i)->system_dependent()) {
1030 child->add_child_nocopy ((*i)->get_state());
1035 child = node->add_child ("Routes");
1037 boost::shared_ptr<RouteList> r = routes.reader ();
1039 RoutePublicOrderSorter cmp;
1040 RouteList public_order (*r);
1041 public_order.sort (cmp);
1043 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1044 if (!(*i)->hidden()) {
1046 child->add_child_nocopy ((*i)->get_state());
1048 child->add_child_nocopy ((*i)->get_template());
1055 child = node->add_child ("EditGroups");
1056 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1057 child->add_child_nocopy ((*i)->get_state());
1060 child = node->add_child ("MixGroups");
1061 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1062 child->add_child_nocopy ((*i)->get_state());
1065 child = node->add_child ("Playlists");
1066 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1067 if (!(*i)->hidden()) {
1068 if (!(*i)->empty()) {
1070 child->add_child_nocopy ((*i)->get_state());
1072 child->add_child_nocopy ((*i)->get_template());
1078 child = node->add_child ("UnusedPlaylists");
1079 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1080 if (!(*i)->hidden()) {
1081 if (!(*i)->empty()) {
1083 child->add_child_nocopy ((*i)->get_state());
1085 child->add_child_nocopy ((*i)->get_template());
1093 child = node->add_child ("Click");
1094 child->add_child_nocopy (_click_io->state (full_state));
1098 child = node->add_child ("NamedSelections");
1099 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1101 child->add_child_nocopy ((*i)->get_state());
1106 node->add_child_nocopy (_tempo_map->get_state());
1108 node->add_child_nocopy (get_control_protocol_state());
1111 node->add_child_copy (*_extra_xml);
1118 Session::get_control_protocol_state ()
1120 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1121 return cpm.get_state();
1125 Session::set_state (const XMLNode& node)
1129 const XMLProperty* prop;
1132 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1134 if (node.name() != X_("Session")){
1135 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1139 if ((prop = node.property ("name")) != 0) {
1140 _name = prop->value ();
1143 setup_raid_path(_path);
1145 if ((prop = node.property (X_("id-counter"))) != 0) {
1147 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1148 ID::init_counter (x);
1150 /* old sessions used a timebased counter, so fake
1151 the startup ID counter based on a standard
1156 ID::init_counter (now);
1160 IO::disable_ports ();
1161 IO::disable_connecting ();
1163 /* Object loading order:
1181 if (use_config_midi_ports ()) {
1184 if ((child = find_named_node (node, "extra")) != 0) {
1185 _extra_xml = new XMLNode (*child);
1188 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1189 load_options (*child);
1190 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1191 load_options (*child);
1193 error << _("Session: XML state has no options section") << endmsg;
1196 if ((child = find_named_node (node, "Locations")) == 0) {
1197 error << _("Session: XML state has no locations section") << endmsg;
1199 } else if (_locations.set_state (*child)) {
1205 if ((location = _locations.auto_loop_location()) != 0) {
1206 set_auto_loop_location (location);
1209 if ((location = _locations.auto_punch_location()) != 0) {
1210 set_auto_punch_location (location);
1213 if ((location = _locations.end_location()) == 0) {
1214 _locations.add (end_location);
1216 delete end_location;
1217 end_location = location;
1220 if ((location = _locations.start_location()) == 0) {
1221 _locations.add (start_location);
1223 delete start_location;
1224 start_location = location;
1227 AudioFileSource::set_header_position_offset (start_location->start());
1229 if ((child = find_named_node (node, "Sources")) == 0) {
1230 error << _("Session: XML state has no sources section") << endmsg;
1232 } else if (load_sources (*child)) {
1236 if ((child = find_named_node (node, "Regions")) == 0) {
1237 error << _("Session: XML state has no Regions section") << endmsg;
1239 } else if (load_regions (*child)) {
1243 if ((child = find_named_node (node, "Playlists")) == 0) {
1244 error << _("Session: XML state has no playlists section") << endmsg;
1246 } else if (load_playlists (*child)) {
1250 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1252 } else if (load_unused_playlists (*child)) {
1256 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1257 if (load_named_selections (*child)) {
1262 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1263 error << _("Session: XML state has no diskstreams section") << endmsg;
1265 } else if (load_diskstreams (*child)) {
1269 if ((child = find_named_node (node, "Connections")) == 0) {
1270 error << _("Session: XML state has no connections section") << endmsg;
1272 } else if (load_connections (*child)) {
1276 if ((child = find_named_node (node, "EditGroups")) == 0) {
1277 error << _("Session: XML state has no edit groups section") << endmsg;
1279 } else if (load_edit_groups (*child)) {
1283 if ((child = find_named_node (node, "MixGroups")) == 0) {
1284 error << _("Session: XML state has no mix groups section") << endmsg;
1286 } else if (load_mix_groups (*child)) {
1290 if ((child = find_named_node (node, "TempoMap")) == 0) {
1291 error << _("Session: XML state has no Tempo Map section") << endmsg;
1293 } else if (_tempo_map->set_state (*child)) {
1297 if ((child = find_named_node (node, "Routes")) == 0) {
1298 error << _("Session: XML state has no routes section") << endmsg;
1300 } else if (load_routes (*child)) {
1304 if ((child = find_named_node (node, "Click")) == 0) {
1305 warning << _("Session: XML state has no click section") << endmsg;
1306 } else if (_click_io) {
1307 _click_io->set_state (*child);
1310 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1311 ControlProtocolManager::instance().set_protocol_states (*child);
1314 /* here beginneth the second phase ... */
1316 StateReady (); /* EMIT SIGNAL */
1318 _state_of_the_state = Clean;
1320 if (state_was_pending) {
1321 save_state (_current_snapshot_name);
1322 remove_pending_capture_state ();
1323 state_was_pending = false;
1333 Session::load_routes (const XMLNode& node)
1336 XMLNodeConstIterator niter;
1337 RouteList new_routes;
1339 nlist = node.children();
1343 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1345 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1348 error << _("Session: cannot create Route from XML description.") << endmsg;
1352 new_routes.push_back (route);
1355 add_routes (new_routes);
1360 boost::shared_ptr<Route>
1361 Session::XMLRouteFactory (const XMLNode& node)
1363 if (node.name() != "Route") {
1364 return boost::shared_ptr<Route> ((Route*) 0);
1367 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1368 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1371 boost::shared_ptr<Route> x (new Route (*this, node));
1377 Session::load_regions (const XMLNode& node)
1380 XMLNodeConstIterator niter;
1381 boost::shared_ptr<AudioRegion> region;
1383 nlist = node.children();
1387 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1388 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1389 error << _("Session: cannot create Region from XML description.") << endmsg;
1396 boost::shared_ptr<AudioRegion>
1397 Session::XMLRegionFactory (const XMLNode& node, bool full)
1399 const XMLProperty* prop;
1400 boost::shared_ptr<Source> source;
1401 boost::shared_ptr<AudioSource> as;
1403 SourceList master_sources;
1404 uint32_t nchans = 1;
1407 if (node.name() != X_("Region")) {
1408 return boost::shared_ptr<AudioRegion>();
1411 if ((prop = node.property (X_("channels"))) != 0) {
1412 nchans = atoi (prop->value().c_str());
1416 if ((prop = node.property ("name")) == 0) {
1417 cerr << "no name for this region\n";
1421 if ((prop = node.property (X_("source-0"))) == 0) {
1422 if ((prop = node.property ("source")) == 0) {
1423 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1424 return boost::shared_ptr<AudioRegion>();
1428 PBD::ID s_id (prop->value());
1430 if ((source = source_by_id (s_id)) == 0) {
1431 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1432 return boost::shared_ptr<AudioRegion>();
1435 as = boost::dynamic_pointer_cast<AudioSource>(source);
1437 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1438 return boost::shared_ptr<AudioRegion>();
1441 sources.push_back (as);
1443 /* pickup other channels */
1445 for (uint32_t n=1; n < nchans; ++n) {
1446 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1447 if ((prop = node.property (buf)) != 0) {
1449 PBD::ID id2 (prop->value());
1451 if ((source = source_by_id (id2)) == 0) {
1452 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1453 return boost::shared_ptr<AudioRegion>();
1456 as = boost::dynamic_pointer_cast<AudioSource>(source);
1458 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1459 return boost::shared_ptr<AudioRegion>();
1461 sources.push_back (as);
1465 for (uint32_t n=0; n < nchans; ++n) {
1466 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1467 if ((prop = node.property (buf)) != 0) {
1469 PBD::ID id2 (prop->value());
1471 if ((source = source_by_id (id2)) == 0) {
1472 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1473 return boost::shared_ptr<AudioRegion>();
1476 as = boost::dynamic_pointer_cast<AudioSource>(source);
1478 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1479 return boost::shared_ptr<AudioRegion>();
1481 master_sources.push_back (as);
1486 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1488 /* a final detail: this is the one and only place that we know how long missing files are */
1490 if (region->whole_file()) {
1491 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1492 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1494 sfp->set_length (region->length());
1499 if (!master_sources.empty()) {
1500 if (master_sources.size() != nchans) {
1501 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1503 region->set_master_sources (master_sources);
1511 catch (failed_constructor& err) {
1512 return boost::shared_ptr<AudioRegion>();
1517 Session::get_sources_as_xml ()
1520 XMLNode* node = new XMLNode (X_("Sources"));
1521 Glib::Mutex::Lock lm (audio_source_lock);
1523 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1524 node->add_child_nocopy (i->second->get_state());
1527 /* XXX get MIDI and other sources here */
1533 Session::path_from_region_name (string name, string identifier)
1535 char buf[PATH_MAX+1];
1537 string dir = discover_best_sound_dir ();
1539 for (n = 0; n < 999999; ++n) {
1540 if (identifier.length()) {
1541 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1542 identifier.c_str(), n);
1544 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1547 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1552 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1561 Session::load_sources (const XMLNode& node)
1564 XMLNodeConstIterator niter;
1565 boost::shared_ptr<Source> source;
1567 nlist = node.children();
1571 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1574 if ((source = XMLSourceFactory (**niter)) == 0) {
1575 error << _("Session: cannot create Source from XML description.") << endmsg;
1579 catch (non_existent_source& err) {
1580 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1581 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1588 boost::shared_ptr<Source>
1589 Session::XMLSourceFactory (const XMLNode& node)
1591 if (node.name() != "Source") {
1592 return boost::shared_ptr<Source>();
1596 return SourceFactory::create (*this, node);
1599 catch (failed_constructor& err) {
1600 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1601 return boost::shared_ptr<Source>();
1606 Session::save_template (string template_name)
1609 string xml_path, bak_path, template_path;
1611 if (_state_of_the_state & CannotSave) {
1616 string dir = template_dir();
1618 if ((dp = opendir (dir.c_str()))) {
1621 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1622 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1627 tree.set_root (&get_template());
1630 xml_path += template_name;
1631 xml_path += _template_suffix;
1633 ifstream in(xml_path.c_str());
1636 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1642 if (!tree.write (xml_path)) {
1643 error << _("mix template not saved") << endmsg;
1651 Session::rename_template (string old_name, string new_name)
1653 string old_path = template_dir() + old_name + _template_suffix;
1654 string new_path = template_dir() + new_name + _template_suffix;
1656 return rename (old_path.c_str(), new_path.c_str());
1660 Session::delete_template (string name)
1662 string template_path = template_dir();
1663 template_path += name;
1664 template_path += _template_suffix;
1666 return remove (template_path.c_str());
1670 Session::refresh_disk_space ()
1673 struct statfs statfsbuf;
1674 vector<space_and_path>::iterator i;
1675 Glib::Mutex::Lock lm (space_lock);
1678 /* get freespace on every FS that is part of the session path */
1680 _total_free_4k_blocks = 0;
1682 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1683 statfs ((*i).path.c_str(), &statfsbuf);
1685 scale = statfsbuf.f_bsize/4096.0;
1687 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1688 _total_free_4k_blocks += (*i).blocks;
1694 Session::ensure_sound_dir (string path, string& result)
1699 /* Ensure that the parent directory exists */
1701 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1702 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1706 /* Ensure that the sounds directory exists */
1710 result += sound_dir_name;
1712 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1713 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1719 dead += dead_sound_dir_name;
1721 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1722 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1728 peak += peak_dir_name;
1730 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1731 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1735 /* callers expect this to be terminated ... */
1742 Session::discover_best_sound_dir (bool destructive)
1744 vector<space_and_path>::iterator i;
1747 /* handle common case without system calls */
1749 if (session_dirs.size() == 1) {
1753 /* OK, here's the algorithm we're following here:
1755 We want to select which directory to use for
1756 the next file source to be created. Ideally,
1757 we'd like to use a round-robin process so as to
1758 get maximum performance benefits from splitting
1759 the files across multiple disks.
1761 However, in situations without much diskspace, an
1762 RR approach may end up filling up a filesystem
1763 with new files while others still have space.
1764 Its therefore important to pay some attention to
1765 the freespace in the filesystem holding each
1766 directory as well. However, if we did that by
1767 itself, we'd keep creating new files in the file
1768 system with the most space until it was as full
1769 as all others, thus negating any performance
1770 benefits of this RAID-1 like approach.
1772 So, we use a user-configurable space threshold. If
1773 there are at least 2 filesystems with more than this
1774 much space available, we use RR selection between them.
1775 If not, then we pick the filesystem with the most space.
1777 This gets a good balance between the two
1781 refresh_disk_space ();
1783 int free_enough = 0;
1785 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1786 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1791 if (free_enough >= 2) {
1793 bool found_it = false;
1795 /* use RR selection process, ensuring that the one
1799 i = last_rr_session_dir;
1802 if (++i == session_dirs.end()) {
1803 i = session_dirs.begin();
1806 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1807 if (ensure_sound_dir ((*i).path, result) == 0) {
1808 last_rr_session_dir = i;
1814 } while (i != last_rr_session_dir);
1817 result = sound_dir();
1822 /* pick FS with the most freespace (and that
1823 seems to actually work ...)
1826 vector<space_and_path> sorted;
1827 space_and_path_ascending_cmp cmp;
1829 sorted = session_dirs;
1830 sort (sorted.begin(), sorted.end(), cmp);
1832 for (i = sorted.begin(); i != sorted.end(); ++i) {
1833 if (ensure_sound_dir ((*i).path, result) == 0) {
1834 last_rr_session_dir = i;
1839 /* if the above fails, fall back to the most simplistic solution */
1841 if (i == sorted.end()) {
1850 Session::load_playlists (const XMLNode& node)
1853 XMLNodeConstIterator niter;
1854 boost::shared_ptr<Playlist> playlist;
1856 nlist = node.children();
1860 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1862 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1863 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1871 Session::load_unused_playlists (const XMLNode& node)
1874 XMLNodeConstIterator niter;
1875 boost::shared_ptr<Playlist> playlist;
1877 nlist = node.children();
1881 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1883 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1884 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1888 // now manually untrack it
1890 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1897 boost::shared_ptr<Playlist>
1898 Session::XMLPlaylistFactory (const XMLNode& node)
1901 return PlaylistFactory::create (*this, node);
1904 catch (failed_constructor& err) {
1905 return boost::shared_ptr<Playlist>();
1910 Session::load_named_selections (const XMLNode& node)
1913 XMLNodeConstIterator niter;
1916 nlist = node.children();
1920 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1922 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1923 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1931 Session::XMLNamedSelectionFactory (const XMLNode& node)
1934 return new NamedSelection (*this, node);
1937 catch (failed_constructor& err) {
1943 Session::dead_sound_dir () const
1946 res += dead_sound_dir_name;
1952 Session::old_sound_dir (bool with_path) const
1960 res += old_sound_dir_name;
1966 Session::sound_dir (bool with_path) const
1977 res += interchange_dir_name;
1979 res += legalize_for_path (_name);
1981 res += sound_dir_name;
1989 /* if this already exists, don't check for the old session sound directory */
1991 if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
1995 /* possibly support old session structure */
1998 string old_withpath;
2000 old_nopath += old_sound_dir_name;
2003 old_withpath = _path;
2004 old_withpath += old_sound_dir_name;
2006 if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2008 return old_withpath;
2013 /* ok, old "sounds" directory isn't there, return the new path */
2019 Session::peak_dir () const
2022 res += peak_dir_name;
2028 Session::automation_dir () const
2031 res += "automation/";
2036 Session::template_dir ()
2038 string path = get_user_ardour_path();
2039 path += "templates/";
2045 Session::export_dir () const
2048 res += export_dir_name;
2054 Session::suffixed_search_path (string suffix, bool data)
2058 path += get_user_ardour_path();
2059 if (path[path.length()-1] != ':') {
2064 path += get_system_data_path();
2066 path += get_system_module_path();
2069 vector<string> split_path;
2071 split (path, split_path, ':');
2074 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2079 if (distance (i, split_path.end()) != 1) {
2088 Session::template_path ()
2090 return suffixed_search_path (X_("templates"), true);
2094 Session::control_protocol_path ()
2096 return suffixed_search_path (X_("surfaces"), false);
2100 Session::load_connections (const XMLNode& node)
2102 XMLNodeList nlist = node.children();
2103 XMLNodeConstIterator niter;
2107 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2108 if ((*niter)->name() == "InputConnection") {
2109 add_connection (new ARDOUR::InputConnection (**niter));
2110 } else if ((*niter)->name() == "OutputConnection") {
2111 add_connection (new ARDOUR::OutputConnection (**niter));
2113 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2122 Session::load_edit_groups (const XMLNode& node)
2124 return load_route_groups (node, true);
2128 Session::load_mix_groups (const XMLNode& node)
2130 return load_route_groups (node, false);
2134 Session::load_route_groups (const XMLNode& node, bool edit)
2136 XMLNodeList nlist = node.children();
2137 XMLNodeConstIterator niter;
2142 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2143 if ((*niter)->name() == "RouteGroup") {
2145 rg = add_edit_group ("");
2146 rg->set_state (**niter);
2148 rg = add_mix_group ("");
2149 rg->set_state (**niter);
2158 state_file_filter (const string &str, void *arg)
2160 return (str.length() > strlen(Session::statefile_suffix()) &&
2161 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2165 bool operator()(const string* a, const string* b) {
2171 remove_end(string* state)
2173 string statename(*state);
2175 string::size_type start,end;
2176 if ((start = statename.find_last_of ('/')) != string::npos) {
2177 statename = statename.substr (start+1);
2180 if ((end = statename.rfind(".ardour")) == string::npos) {
2181 end = statename.length();
2184 return new string(statename.substr (0, end));
2188 Session::possible_states (string path)
2190 PathScanner scanner;
2191 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2193 transform(states->begin(), states->end(), states->begin(), remove_end);
2196 sort (states->begin(), states->end(), cmp);
2202 Session::possible_states () const
2204 return possible_states(_path);
2208 Session::auto_save()
2210 save_state (_current_snapshot_name);
2214 Session::add_edit_group (string name)
2216 RouteGroup* rg = new RouteGroup (*this, name);
2217 edit_groups.push_back (rg);
2218 edit_group_added (rg); /* EMIT SIGNAL */
2224 Session::add_mix_group (string name)
2226 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2227 mix_groups.push_back (rg);
2228 mix_group_added (rg); /* EMIT SIGNAL */
2234 Session::remove_edit_group (RouteGroup& rg)
2236 list<RouteGroup*>::iterator i;
2238 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2239 (*i)->apply (&Route::drop_edit_group, this);
2240 edit_groups.erase (i);
2241 edit_group_removed (); /* EMIT SIGNAL */
2248 Session::remove_mix_group (RouteGroup& rg)
2250 list<RouteGroup*>::iterator i;
2252 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2253 (*i)->apply (&Route::drop_mix_group, this);
2254 mix_groups.erase (i);
2255 mix_group_removed (); /* EMIT SIGNAL */
2262 Session::mix_group_by_name (string name)
2264 list<RouteGroup *>::iterator i;
2266 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2267 if ((*i)->name() == name) {
2275 Session::edit_group_by_name (string name)
2277 list<RouteGroup *>::iterator i;
2279 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2280 if ((*i)->name() == name) {
2288 Session::begin_reversible_command (string name)
2290 current_trans = new UndoTransaction;
2291 current_trans->set_name (name);
2295 Session::commit_reversible_command (Command *cmd)
2300 current_trans->add_command (cmd);
2303 gettimeofday (&now, 0);
2304 current_trans->set_timestamp (now);
2306 _history.add (current_trans);
2309 Session::GlobalRouteBooleanState
2310 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2312 GlobalRouteBooleanState s;
2313 boost::shared_ptr<RouteList> r = routes.reader ();
2315 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2316 if (!(*i)->hidden()) {
2317 RouteBooleanState v;
2320 Route* r = (*i).get();
2321 v.second = (r->*method)();
2330 Session::GlobalRouteMeterState
2331 Session::get_global_route_metering ()
2333 GlobalRouteMeterState s;
2334 boost::shared_ptr<RouteList> r = routes.reader ();
2336 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2337 if (!(*i)->hidden()) {
2341 v.second = (*i)->meter_point();
2351 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2353 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2355 boost::shared_ptr<Route> r = (i->first.lock());
2358 r->set_meter_point (i->second, arg);
2364 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2366 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2368 boost::shared_ptr<Route> r = (i->first.lock());
2371 Route* rp = r.get();
2372 (rp->*method) (i->second, arg);
2378 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2380 set_global_route_boolean (s, &Route::set_mute, src);
2384 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2386 set_global_route_boolean (s, &Route::set_solo, src);
2390 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2392 set_global_route_boolean (s, &Route::set_record_enable, src);
2397 Session::global_mute_memento (void* src)
2399 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2403 Session::global_metering_memento (void* src)
2405 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2409 Session::global_solo_memento (void* src)
2411 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2415 Session::global_record_enable_memento (void* src)
2417 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2422 template_filter (const string &str, void *arg)
2424 return (str.length() > strlen(Session::template_suffix()) &&
2425 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2429 Session::get_template_list (list<string> &template_names)
2431 vector<string *> *templates;
2432 PathScanner scanner;
2435 path = template_path ();
2437 templates = scanner (path, template_filter, 0, false, true);
2439 vector<string*>::iterator i;
2440 for (i = templates->begin(); i != templates->end(); ++i) {
2441 string fullpath = *(*i);
2444 start = fullpath.find_last_of ('/') + 1;
2445 if ((end = fullpath.find_last_of ('.')) <0) {
2446 end = fullpath.length();
2449 template_names.push_back(fullpath.substr(start, (end-start)));
2454 Session::read_favorite_dirs (FavoriteDirs & favs)
2456 string path = get_user_ardour_path();
2457 path += "/favorite_dirs";
2459 ifstream fav (path.c_str());
2464 if (errno != ENOENT) {
2465 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2476 getline(fav, newfav);
2482 favs.push_back (newfav);
2489 Session::write_favorite_dirs (FavoriteDirs & favs)
2491 string path = get_user_ardour_path();
2492 path += "/favorite_dirs";
2494 ofstream fav (path.c_str());
2500 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2501 fav << (*i) << endl;
2508 accept_all_non_peak_files (const string& path, void *arg)
2510 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2514 accept_all_state_files (const string& path, void *arg)
2516 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2520 Session::find_all_sources (string path, set<string>& result)
2525 if (!tree.read (path)) {
2529 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2534 XMLNodeConstIterator niter;
2536 nlist = node->children();
2540 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2544 if ((prop = (*niter)->property (X_("name"))) == 0) {
2548 if (prop->value()[0] == '/') {
2549 /* external file, ignore */
2553 string path = _path; /* /-terminated */
2554 path += sound_dir_name;
2556 path += prop->value();
2558 result.insert (path);
2565 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2567 PathScanner scanner;
2568 vector<string*>* state_files;
2570 string this_snapshot_path;
2576 if (ripped[ripped.length()-1] == '/') {
2577 ripped = ripped.substr (0, ripped.length() - 1);
2580 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2582 if (state_files == 0) {
2587 this_snapshot_path = _path;
2588 this_snapshot_path += _current_snapshot_name;
2589 this_snapshot_path += _statefile_suffix;
2591 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2593 if (exclude_this_snapshot && **i == this_snapshot_path) {
2597 if (find_all_sources (**i, result) < 0) {
2605 struct RegionCounter {
2606 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2607 AudioSourceList::iterator iter;
2608 boost::shared_ptr<Region> region;
2611 RegionCounter() : count (0) {}
2615 Session::cleanup_sources (Session::cleanup_report& rep)
2617 vector<boost::shared_ptr<Source> > dead_sources;
2618 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2619 PathScanner scanner;
2621 vector<space_and_path>::iterator i;
2622 vector<space_and_path>::iterator nexti;
2623 vector<string*>* soundfiles;
2624 vector<string> unused;
2625 set<string> all_sources;
2630 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2632 /* step 1: consider deleting all unused playlists */
2634 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2637 status = AskAboutPlaylistDeletion (*x);
2646 playlists_tbd.push_back (*x);
2650 /* leave it alone */
2655 /* now delete any that were marked for deletion */
2657 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2658 (*x)->drop_references ();
2661 playlists_tbd.clear ();
2663 /* step 2: find all un-used sources */
2668 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2670 AudioSourceList::iterator tmp;
2675 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2679 if (!i->second->used() && i->second->length() > 0) {
2680 dead_sources.push_back (i->second);
2681 i->second->GoingAway();
2687 /* build a list of all the possible sound directories for the session */
2689 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2694 sound_path += (*i).path;
2695 sound_path += sound_dir (false);
2697 if (nexti != session_dirs.end()) {
2704 /* now do the same thing for the files that ended up in the sounds dir(s)
2705 but are not referenced as sources in any snapshot.
2708 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2710 if (soundfiles == 0) {
2714 /* find all sources, but don't use this snapshot because the
2715 state file on disk still references sources we may have already
2719 find_all_sources_across_snapshots (all_sources, true);
2721 /* add our current source list
2724 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2725 boost::shared_ptr<AudioFileSource> fs;
2727 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2728 all_sources.insert (fs->path());
2732 char tmppath1[PATH_MAX+1];
2733 char tmppath2[PATH_MAX+1];
2735 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2740 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2742 realpath(spath.c_str(), tmppath1);
2743 realpath((*i).c_str(), tmppath2);
2745 if (strcmp(tmppath1, tmppath2) == 0) {
2752 unused.push_back (spath);
2756 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2758 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2759 struct stat statbuf;
2761 rep.paths.push_back (*x);
2762 if (stat ((*x).c_str(), &statbuf) == 0) {
2763 rep.space += statbuf.st_size;
2768 /* don't move the file across filesystems, just
2769 stick it in the `dead_sound_dir_name' directory
2770 on whichever filesystem it was already on.
2773 if ((*x).find ("/sounds/") != string::npos) {
2775 /* old school, go up 1 level */
2777 newpath = Glib::path_get_dirname (*x); // "sounds"
2778 newpath = Glib::path_get_dirname (newpath); // "session-name"
2782 /* new school, go up 4 levels */
2784 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2785 newpath = Glib::path_get_dirname (newpath); // "session-name"
2786 newpath = Glib::path_get_dirname (newpath); // "interchange"
2787 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2791 newpath += dead_sound_dir_name;
2793 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2794 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2799 newpath += Glib::path_get_basename ((*x));
2801 if (access (newpath.c_str(), F_OK) == 0) {
2803 /* the new path already exists, try versioning */
2805 char buf[PATH_MAX+1];
2809 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2812 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2813 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2817 if (version == 999) {
2818 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2822 newpath = newpath_v;
2827 /* it doesn't exist, or we can't read it or something */
2831 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2832 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2833 (*x), newpath, strerror (errno))
2838 /* see if there an easy to find peakfile for this file, and remove it.
2841 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2842 peakpath += ".peak";
2844 if (access (peakpath.c_str(), W_OK) == 0) {
2845 if (::unlink (peakpath.c_str()) != 0) {
2846 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2847 peakpath, _path, strerror (errno))
2849 /* try to back out */
2850 rename (newpath.c_str(), _path.c_str());
2858 /* dump the history list */
2862 /* save state so we don't end up a session file
2863 referring to non-existent sources.
2869 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2874 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2876 vector<space_and_path>::iterator i;
2877 string dead_sound_dir;
2878 struct dirent* dentry;
2879 struct stat statbuf;
2885 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2887 dead_sound_dir = (*i).path;
2888 dead_sound_dir += dead_sound_dir_name;
2890 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2894 while ((dentry = readdir (dead)) != 0) {
2896 /* avoid '.' and '..' */
2898 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2899 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2905 fullpath = dead_sound_dir;
2907 fullpath += dentry->d_name;
2909 if (stat (fullpath.c_str(), &statbuf)) {
2913 if (!S_ISREG (statbuf.st_mode)) {
2917 if (unlink (fullpath.c_str())) {
2918 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2919 fullpath, strerror (errno))
2923 rep.paths.push_back (dentry->d_name);
2924 rep.space += statbuf.st_size;
2935 Session::set_dirty ()
2937 bool was_dirty = dirty();
2939 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2942 DirtyChanged(); /* EMIT SIGNAL */
2948 Session::set_clean ()
2950 bool was_dirty = dirty();
2952 _state_of_the_state = Clean;
2955 DirtyChanged(); /* EMIT SIGNAL */
2960 Session::set_deletion_in_progress ()
2962 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2966 Session::add_controllable (Controllable* c)
2968 /* this adds a controllable to the list managed by the Session.
2969 this is a subset of those managed by the Controllable class
2970 itself, and represents the only ones whose state will be saved
2971 as part of the session.
2974 Glib::Mutex::Lock lm (controllables_lock);
2975 controllables.insert (c);
2979 Session::remove_controllable (Controllable* c)
2981 if (_state_of_the_state | Deletion) {
2985 Glib::Mutex::Lock lm (controllables_lock);
2987 Controllables::iterator x = controllables.find (c);
2989 if (x != controllables.end()) {
2990 controllables.erase (x);
2995 Session::controllable_by_id (const PBD::ID& id)
2997 Glib::Mutex::Lock lm (controllables_lock);
2999 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3000 if ((*i)->id() == id) {
3009 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3011 Stateful::add_instant_xml (node, dir);
3012 Config->add_instant_xml (node, get_user_ardour_path());
3016 Session::save_history (string snapshot_name)
3022 if (snapshot_name.empty()) {
3023 snapshot_name = _current_snapshot_name;
3026 xml_path = _path + snapshot_name + ".history";
3028 bak_path = xml_path + ".bak";
3030 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && ::rename (xml_path.c_str(), bak_path.c_str())) {
3031 error << _("could not backup old history file, current history not saved.") << endmsg;
3035 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3039 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3041 if (!tree.write (xml_path))
3043 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3045 /* don't leave a corrupt file lying around if it is
3049 if (unlink (xml_path.c_str())) {
3050 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3052 if (rename (bak_path.c_str(), xml_path.c_str()))
3054 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3065 Session::restore_history (string snapshot_name)
3070 if (snapshot_name.empty()) {
3071 snapshot_name = _current_snapshot_name;
3075 xmlpath = _path + snapshot_name + ".history";
3076 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3078 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3082 if (!tree.read (xmlpath)) {
3083 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3087 /* replace history */
3090 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3093 UndoTransaction* ut = new UndoTransaction ();
3096 ut->set_name(t->property("name")->value());
3097 stringstream ss(t->property("tv_sec")->value());
3099 ss.str(t->property("tv_usec")->value());
3101 ut->set_timestamp(tv);
3103 for (XMLNodeConstIterator child_it = t->children().begin();
3104 child_it != t->children().end();
3107 XMLNode *n = *child_it;
3110 if (n->name() == "MementoCommand" ||
3111 n->name() == "MementoUndoCommand" ||
3112 n->name() == "MementoRedoCommand") {
3114 if ((c = memento_command_factory(n))) {
3118 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3120 if ((c = global_state_command_factory (*n))) {
3121 ut->add_command (c);
3126 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3137 Session::config_changed (const char* parameter_name)
3139 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3141 if (PARAM_IS ("seamless-loop")) {
3143 } else if (PARAM_IS ("rf-speed")) {
3145 } else if (PARAM_IS ("auto-loop")) {
3147 } else if (PARAM_IS ("auto-input")) {
3149 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3150 /* auto-input only makes a difference if we're rolling */
3152 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3154 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3155 if ((*i)->record_enabled ()) {
3156 (*i)->monitor_input (!Config->get_auto_input());
3161 } else if (PARAM_IS ("punch-in")) {
3165 if ((location = _locations.auto_punch_location()) != 0) {
3167 if (Config->get_punch_in ()) {
3168 replace_event (Event::PunchIn, location->start());
3170 remove_event (location->start(), Event::PunchIn);
3174 } else if (PARAM_IS ("punch-out")) {
3178 if ((location = _locations.auto_punch_location()) != 0) {
3180 if (Config->get_punch_out()) {
3181 replace_event (Event::PunchOut, location->end());
3183 clear_events (Event::PunchOut);
3187 } else if (PARAM_IS ("edit-mode")) {
3189 Glib::Mutex::Lock lm (playlist_lock);
3191 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3192 (*i)->set_edit_mode (Config->get_edit_mode ());
3195 } else if (PARAM_IS ("use-video-sync")) {
3197 waiting_for_sync_offset = Config->get_use_video_sync();
3199 } else if (PARAM_IS ("mmc-control")) {
3201 poke_midi_thread ();
3203 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-device-id")) {
3205 set_mmc_receive_device_id (Config->get_mmc_receive_device_id());
3207 } else if (PARAM_IS ("mmc-send-device-id")) {
3209 set_mmc_send_device_id (Config->get_mmc_send_device_id());
3211 } else if (PARAM_IS ("midi-control")) {
3213 poke_midi_thread ();
3215 } else if (PARAM_IS ("raid-path")) {
3217 setup_raid_path (Config->get_raid_path());
3219 } else if (PARAM_IS ("smpte-format")) {
3223 } else if (PARAM_IS ("video-pullup")) {
3227 } else if (PARAM_IS ("seamless-loop")) {
3229 if (play_loop && transport_rolling()) {
3230 // to reset diskstreams etc
3231 request_play_loop (true);
3234 } else if (PARAM_IS ("rf-speed")) {
3236 cumulative_rf_motion = 0;
3239 } else if (PARAM_IS ("click-sound")) {
3241 setup_click_sounds (1);
3243 } else if (PARAM_IS ("click-emphasis-sound")) {
3245 setup_click_sounds (-1);
3247 } else if (PARAM_IS ("clicking")) {
3249 if (Config->get_clicking()) {
3250 if (_click_io && click_data) { // don't require emphasis data
3257 } else if (PARAM_IS ("send-mtc")) {
3259 /* only set the internal flag if we have
3263 if (_mtc_port != 0) {
3264 session_send_mtc = Config->get_send_mtc();
3265 if (session_send_mtc) {
3266 /* mark us ready to send */
3267 next_quarter_frame_to_send = 0;
3270 session_send_mtc = false;
3273 } else if (PARAM_IS ("send-mmc")) {
3275 /* only set the internal flag if we have
3279 if (_mmc_port != 0) {
3280 session_send_mmc = Config->get_send_mmc();
3283 session_send_mmc = false;
3286 } else if (PARAM_IS ("midi-feedback")) {
3288 /* only set the internal flag if we have
3292 if (_mtc_port != 0) {
3293 session_midi_feedback = Config->get_midi_feedback();
3296 } else if (PARAM_IS ("jack-time-master")) {
3298 engine().reset_timebase ();
3300 } else if (PARAM_IS ("native-file-header-format")) {
3302 if (!first_file_header_format_reset) {
3303 reset_native_file_format ();
3306 first_file_header_format_reset = false;
3308 } else if (PARAM_IS ("native-file-data-format")) {
3310 if (!first_file_data_format_reset) {
3311 reset_native_file_format ();
3314 first_file_data_format_reset = false;
3316 } else if (PARAM_IS ("slave-source")) {
3317 set_slave_source (Config->get_slave_source());
3318 } else if (PARAM_IS ("remote-model")) {
3319 set_remote_control_ids ();
3320 } else if (PARAM_IS ("denormal-model")) {
3322 } else if (PARAM_IS ("history-depth")) {
3323 set_history_depth (Config->get_history_depth());
3324 } else if (PARAM_IS ("sync-all-route-ordering")) {
3335 Session::set_history_depth (uint32_t d)
3337 _history.set_depth (d);