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.
26 #include <sigc++/bind.h>
28 #include <cstdio> /* snprintf(3) ... grrr */
43 #include <sys/param.h>
44 #include <sys/mount.h>
49 #include <midi++/mmc.h>
50 #include <midi++/port.h>
51 #include <pbd/error.h>
53 #include <glibmm/thread.h>
54 #include <pbd/pathscanner.h>
55 #include <pbd/pthread_utils.h>
56 #include <pbd/strsplit.h>
57 #include <pbd/stacktrace.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/destructive_filesource.h>
67 #include <ardour/sndfile_helpers.h>
68 #include <ardour/auditioner.h>
69 #include <ardour/export.h>
70 #include <ardour/redirect.h>
71 #include <ardour/send.h>
72 #include <ardour/insert.h>
73 #include <ardour/connection.h>
74 #include <ardour/slave.h>
75 #include <ardour/tempo.h>
76 #include <ardour/audio_track.h>
77 #include <ardour/cycle_timer.h>
78 #include <ardour/utils.h>
79 #include <ardour/named_selection.h>
80 #include <ardour/version.h>
81 #include <ardour/location.h>
82 #include <ardour/audioregion.h>
83 #include <ardour/crossfade.h>
84 #include <ardour/control_protocol_manager.h>
85 #include <ardour/region_factory.h>
86 #include <ardour/source_factory.h>
87 #include <ardour/playlist_factory.h>
89 #include <control_protocol/control_protocol.h>
95 using namespace ARDOUR;
99 Session::first_stage_init (string fullpath, string snapshot_name)
101 if (fullpath.length() == 0) {
103 throw failed_constructor();
106 char buf[PATH_MAX+1];
107 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
108 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
110 throw failed_constructor();
115 if (_path[_path.length()-1] != '/') {
119 /* these two are just provisional settings. set_state()
120 will likely override them.
123 _name = _current_snapshot_name = snapshot_name;
125 _current_frame_rate = _engine.frame_rate ();
126 _tempo_map = new TempoMap (_current_frame_rate);
127 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
129 g_atomic_int_set (&processing_prohibited, 0);
131 _transport_speed = 0;
132 _last_transport_speed = 0;
133 transport_sub_state = 0;
134 _transport_frame = 0;
136 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
137 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
138 _end_location_is_free = true;
139 g_atomic_int_set (&_record_status, Disabled);
140 loop_changing = false;
142 _last_roll_location = 0;
143 _last_record_location = 0;
144 pending_locate_frame = 0;
145 pending_locate_roll = false;
146 pending_locate_flush = false;
147 dstream_buffer_size = 0;
149 state_was_pending = false;
151 outbound_mtc_smpte_frame = 0;
152 next_quarter_frame_to_send = -1;
153 current_block_size = 0;
154 solo_update_disabled = false;
155 currently_soloing = false;
156 _have_captured = false;
157 _worst_output_latency = 0;
158 _worst_input_latency = 0;
159 _worst_track_latency = 0;
160 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
162 butler_mixdown_buffer = 0;
163 butler_gain_buffer = 0;
165 session_send_mmc = false;
166 session_send_mtc = false;
167 post_transport_work = PostTransportWork (0);
168 g_atomic_int_set (&butler_should_do_transport_work, 0);
169 g_atomic_int_set (&butler_active, 0);
170 g_atomic_int_set (&_playback_load, 100);
171 g_atomic_int_set (&_capture_load, 100);
172 g_atomic_int_set (&_playback_load_min, 100);
173 g_atomic_int_set (&_capture_load_min, 100);
175 waiting_to_start = false;
177 _gain_automation_buffer = 0;
178 _pan_automation_buffer = 0;
180 pending_abort = false;
181 destructive_index = 0;
183 first_file_data_format_reset = true;
184 first_file_header_format_reset = true;
186 AudioDiskstream::allocate_working_buffers();
188 /* default short fade = 15ms */
190 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
191 SndFileSource::setup_standard_crossfades (frame_rate());
193 last_mmc_step.tv_sec = 0;
194 last_mmc_step.tv_usec = 0;
197 /* click sounds are unset by default, which causes us to internal
198 waveforms for clicks.
202 click_emphasis_data = 0;
204 click_emphasis_length = 0;
207 process_function = &Session::process_with_events;
209 if (Config->get_use_video_sync()) {
210 waiting_for_sync_offset = true;
212 waiting_for_sync_offset = false;
215 _current_frame_rate = 48000;
216 _base_frame_rate = 48000;
220 _smpte_offset_negative = true;
221 last_smpte_valid = false;
225 last_rr_session_dir = session_dirs.begin();
226 refresh_disk_space ();
228 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
232 average_slave_delta = 1800;
233 have_first_delta_accumulator = false;
234 delta_accumulator_cnt = 0;
235 slave_state = Stopped;
237 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
239 /* These are all static "per-class" signals */
241 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
242 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
243 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
244 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
245 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
246 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
248 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
250 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
252 /* stop IO objects from doing stuff until we're ready for them */
254 IO::disable_panners ();
255 IO::disable_ports ();
256 IO::disable_connecting ();
260 Session::second_stage_init (bool new_session)
262 AudioFileSource::set_peak_dir (peak_dir());
265 if (load_state (_current_snapshot_name)) {
268 remove_empty_sounds ();
271 if (start_butler_thread()) {
275 if (start_midi_thread ()) {
279 // set_state() will call setup_raid_path(), but if it's a new session we need
280 // to call setup_raid_path() here.
282 if (set_state (*state_tree->root())) {
286 setup_raid_path(_path);
289 /* we can't save till after ::when_engine_running() is called,
290 because otherwise we save state with no connections made.
291 therefore, we reset _state_of_the_state because ::set_state()
292 will have cleared it.
294 we also have to include Loading so that any events that get
295 generated between here and the end of ::when_engine_running()
296 will be processed directly rather than queued.
299 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
301 // set_auto_input (true);
302 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
303 _locations.added.connect (mem_fun (this, &Session::locations_added));
304 setup_click_sounds (0);
305 setup_midi_control ();
307 /* Pay attention ... */
309 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
310 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
313 when_engine_running();
320 send_full_time_code ();
321 _engine.transport_locate (0);
322 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
323 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
325 ControlProtocolManager::instance().set_session (*this);
328 _end_location_is_free = true;
330 _end_location_is_free = false;
337 Session::raid_path () const
341 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
346 return path.substr (0, path.length() - 1); // drop final colon
350 Session::setup_raid_path (string path)
352 string::size_type colon;
356 string::size_type len = path.length();
361 if (path.length() == 0) {
365 session_dirs.clear ();
367 for (string::size_type n = 0; n < len; ++n) {
368 if (path[n] == ':') {
375 /* no multiple search path, just one location (common case) */
379 session_dirs.push_back (sp);
386 if (fspath[fspath.length()-1] != '/') {
390 fspath += sound_dir (false);
392 AudioFileSource::set_search_path (fspath);
399 while ((colon = remaining.find_first_of (':')) != string::npos) {
402 sp.path = remaining.substr (0, colon);
403 session_dirs.push_back (sp);
405 /* add sounds to file search path */
408 if (fspath[fspath.length()-1] != '/') {
411 fspath += sound_dir (false);
414 remaining = remaining.substr (colon+1);
417 if (remaining.length()) {
424 if (fspath[fspath.length()-1] != '/') {
427 fspath += sound_dir (false);
430 session_dirs.push_back (sp);
433 /* set the AudioFileSource search path */
435 AudioFileSource::set_search_path (fspath);
437 /* reset the round-robin soundfile path thingie */
439 last_rr_session_dir = session_dirs.begin();
443 Session::create (bool& new_session, string* mix_template, nframes_t initial_length)
447 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
448 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
454 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
455 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
461 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
462 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
466 dir = dead_sound_dir ();
468 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
469 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
473 dir = automation_dir ();
475 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
476 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
481 /* check new_session so we don't overwrite an existing one */
484 std::string in_path = *mix_template;
486 ifstream in(in_path.c_str());
489 string out_path = _path;
491 out_path += _statefile_suffix;
493 ofstream out(out_path.c_str());
498 // okay, session is set up. Treat like normal saved
499 // session from now on.
505 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
511 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
518 /* set initial start + end point */
520 start_location->set_end (0);
521 _locations.add (start_location);
523 end_location->set_end (initial_length);
524 _locations.add (end_location);
526 _state_of_the_state = Clean;
528 if (save_state (_current_snapshot_name)) {
536 Session::load_diskstreams (const XMLNode& node)
539 XMLNodeConstIterator citer;
541 clist = node.children();
543 for (citer = clist.begin(); citer != clist.end(); ++citer) {
547 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
548 add_diskstream (dstream);
551 catch (failed_constructor& err) {
552 error << _("Session: could not load diskstream via XML state") << endmsg;
561 Session::remove_pending_capture_state ()
566 xml_path += _current_snapshot_name;
567 xml_path += _pending_suffix;
569 unlink (xml_path.c_str());
573 Session::save_state (string snapshot_name, bool pending)
579 if (_state_of_the_state & CannotSave) {
583 tree.set_root (&get_state());
585 if (snapshot_name.empty()) {
586 snapshot_name = _current_snapshot_name;
592 xml_path += snapshot_name;
593 xml_path += _statefile_suffix;
598 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
600 // Make backup of state file
602 ifstream in (xml_path.c_str());
603 ofstream out (bak_path.c_str());
606 error << string_compose (_("Could not open existing session file %1 for backup"), xml_path) << endmsg;
611 error << string_compose (_("Could not open backup session file %1"), bak_path) << endmsg;
618 error << string_compose (_("Could not copy existing session file %1 to %2 for backup"), xml_path, bak_path) << endmsg;
619 unlink (bak_path.c_str());
627 xml_path += snapshot_name;
628 xml_path += _pending_suffix;
635 tmp_path += snapshot_name;
638 cerr << "actually writing state\n";
640 if (!tree.write (tmp_path)) {
641 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
642 unlink (tmp_path.c_str());
647 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
648 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
649 unlink (tmp_path.c_str());
656 save_history (snapshot_name);
658 bool was_dirty = dirty();
660 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
663 DirtyChanged (); /* EMIT SIGNAL */
666 StateSaved (snapshot_name); /* EMIT SIGNAL */
673 Session::restore_state (string snapshot_name)
675 if (load_state (snapshot_name) == 0) {
676 set_state (*state_tree->root());
683 Session::load_state (string snapshot_name)
692 state_was_pending = false;
694 /* check for leftover pending state from a crashed capture attempt */
697 xmlpath += snapshot_name;
698 xmlpath += _pending_suffix;
700 if (!access (xmlpath.c_str(), F_OK)) {
702 /* there is pending state from a crashed capture attempt */
704 if (AskAboutPendingState()) {
705 state_was_pending = true;
709 if (!state_was_pending) {
712 xmlpath += snapshot_name;
713 xmlpath += _statefile_suffix;
716 if (access (xmlpath.c_str(), F_OK)) {
717 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
721 state_tree = new XMLTree;
725 if (state_tree->read (xmlpath)) {
728 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
737 Session::load_options (const XMLNode& node)
741 LocaleGuard lg (X_("POSIX"));
743 Config->set_variables (node, ConfigVariableBase::Session);
745 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
746 if ((prop = child->property ("val")) != 0) {
747 _end_location_is_free = (prop->value() == "yes");
755 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
757 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
758 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
760 return owner & modified_by_session_or_user;
764 Session::get_options () const
767 LocaleGuard lg (X_("POSIX"));
769 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
771 child = option_root.add_child ("end-marker-is-free");
772 child->add_property ("val", _end_location_is_free ? "yes" : "no");
784 Session::get_template()
786 /* if we don't disable rec-enable, diskstreams
787 will believe they need to store their capture
788 sources in their state node.
791 disable_record (false);
797 Session::state(bool full_state)
799 XMLNode* node = new XMLNode("Session");
802 // store libardour version, just in case
804 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
805 libardour_major_version, libardour_minor_version, libardour_micro_version);
806 node->add_property("version", string(buf));
808 /* store configuration settings */
813 node->add_property ("name", _name);
815 if (session_dirs.size() > 1) {
819 vector<space_and_path>::iterator i = session_dirs.begin();
820 vector<space_and_path>::iterator next;
822 ++i; /* skip the first one */
826 while (i != session_dirs.end()) {
830 if (next != session_dirs.end()) {
840 child = node->add_child ("Path");
841 child->add_content (p);
845 /* save the ID counter */
847 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
848 node->add_property ("id-counter", buf);
850 /* various options */
852 node->add_child_nocopy (get_options());
854 child = node->add_child ("Sources");
857 Glib::Mutex::Lock sl (audio_source_lock);
859 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
861 /* Don't save information about AudioFileSources that are empty */
863 boost::shared_ptr<AudioFileSource> fs;
865 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
867 /* destructive file sources are OK if they are empty, because
868 we will re-use them every time.
871 if (!fs->destructive()) {
872 if (fs->length() == 0) {
878 child->add_child_nocopy (siter->second->get_state());
882 child = node->add_child ("Regions");
885 Glib::Mutex::Lock rl (region_lock);
887 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
889 /* only store regions not attached to playlists */
891 if (i->second->playlist() == 0) {
892 child->add_child_nocopy (i->second->state (true));
897 child = node->add_child ("DiskStreams");
900 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
901 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
902 if (!(*i)->hidden()) {
903 child->add_child_nocopy ((*i)->get_state());
909 node->add_child_nocopy (_locations.get_state());
911 // for a template, just create a new Locations, populate it
912 // with the default start and end, and get the state for that.
914 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
915 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
918 end->set_end(compute_initial_length());
920 node->add_child_nocopy (loc.get_state());
923 child = node->add_child ("Connections");
925 Glib::Mutex::Lock lm (connection_lock);
926 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
927 if (!(*i)->system_dependent()) {
928 child->add_child_nocopy ((*i)->get_state());
933 child = node->add_child ("Routes");
935 boost::shared_ptr<RouteList> r = routes.reader ();
937 RoutePublicOrderSorter cmp;
938 RouteList public_order (*r);
939 public_order.sort (cmp);
941 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
942 if (!(*i)->hidden()) {
944 child->add_child_nocopy ((*i)->get_state());
946 child->add_child_nocopy ((*i)->get_template());
953 child = node->add_child ("EditGroups");
954 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
955 child->add_child_nocopy ((*i)->get_state());
958 child = node->add_child ("MixGroups");
959 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
960 child->add_child_nocopy ((*i)->get_state());
963 child = node->add_child ("Playlists");
964 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
965 if (!(*i)->hidden()) {
966 if (!(*i)->empty()) {
968 child->add_child_nocopy ((*i)->get_state());
970 child->add_child_nocopy ((*i)->get_template());
976 child = node->add_child ("UnusedPlaylists");
977 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
978 if (!(*i)->hidden()) {
979 if (!(*i)->empty()) {
981 child->add_child_nocopy ((*i)->get_state());
983 child->add_child_nocopy ((*i)->get_template());
991 child = node->add_child ("Click");
992 child->add_child_nocopy (_click_io->state (full_state));
996 child = node->add_child ("NamedSelections");
997 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
999 child->add_child_nocopy ((*i)->get_state());
1004 node->add_child_nocopy (_tempo_map->get_state());
1006 node->add_child_nocopy (get_control_protocol_state());
1009 node->add_child_copy (*_extra_xml);
1016 Session::get_control_protocol_state ()
1018 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1019 XMLNode* node = new XMLNode (X_("ControlProtocols"));
1021 cpm.foreach_known_protocol (bind (mem_fun (*this, &Session::add_control_protocol), node));
1027 Session::add_control_protocol (const ControlProtocolInfo* const cpi, XMLNode* node)
1029 if (cpi->protocol) {
1030 node->add_child_nocopy (cpi->protocol->get_state());
1035 Session::set_state (const XMLNode& node)
1039 const XMLProperty* prop;
1042 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1044 if (node.name() != X_("Session")){
1045 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1049 if ((prop = node.property ("name")) != 0) {
1050 _name = prop->value ();
1053 setup_raid_path(_path);
1055 if ((prop = node.property (X_("id-counter"))) != 0) {
1057 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1058 ID::init_counter (x);
1060 /* old sessions used a timebased counter, so fake
1061 the startup ID counter based on a standard
1066 ID::init_counter (now);
1070 IO::disable_ports ();
1071 IO::disable_connecting ();
1073 /* Object loading order:
1091 if (use_config_midi_ports ()) {
1094 if ((child = find_named_node (node, "extra")) != 0) {
1095 _extra_xml = new XMLNode (*child);
1098 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1099 load_options (*child);
1100 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1101 load_options (*child);
1103 error << _("Session: XML state has no options section") << endmsg;
1106 if ((child = find_named_node (node, "Locations")) == 0) {
1107 error << _("Session: XML state has no locations section") << endmsg;
1109 } else if (_locations.set_state (*child)) {
1115 if ((location = _locations.auto_loop_location()) != 0) {
1116 set_auto_loop_location (location);
1119 if ((location = _locations.auto_punch_location()) != 0) {
1120 set_auto_punch_location (location);
1123 if ((location = _locations.end_location()) == 0) {
1124 _locations.add (end_location);
1126 delete end_location;
1127 end_location = location;
1130 if ((location = _locations.start_location()) == 0) {
1131 _locations.add (start_location);
1133 delete start_location;
1134 start_location = location;
1137 AudioFileSource::set_header_position_offset (start_location->start());
1139 if ((child = find_named_node (node, "Sources")) == 0) {
1140 error << _("Session: XML state has no sources section") << endmsg;
1142 } else if (load_sources (*child)) {
1146 if ((child = find_named_node (node, "Regions")) == 0) {
1147 error << _("Session: XML state has no Regions section") << endmsg;
1149 } else if (load_regions (*child)) {
1153 if ((child = find_named_node (node, "Playlists")) == 0) {
1154 error << _("Session: XML state has no playlists section") << endmsg;
1156 } else if (load_playlists (*child)) {
1160 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1162 } else if (load_unused_playlists (*child)) {
1166 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1167 if (load_named_selections (*child)) {
1172 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1173 error << _("Session: XML state has no diskstreams section") << endmsg;
1175 } else if (load_diskstreams (*child)) {
1179 if ((child = find_named_node (node, "Connections")) == 0) {
1180 error << _("Session: XML state has no connections section") << endmsg;
1182 } else if (load_connections (*child)) {
1186 if ((child = find_named_node (node, "EditGroups")) == 0) {
1187 error << _("Session: XML state has no edit groups section") << endmsg;
1189 } else if (load_edit_groups (*child)) {
1193 if ((child = find_named_node (node, "MixGroups")) == 0) {
1194 error << _("Session: XML state has no mix groups section") << endmsg;
1196 } else if (load_mix_groups (*child)) {
1200 if ((child = find_named_node (node, "TempoMap")) == 0) {
1201 error << _("Session: XML state has no Tempo Map section") << endmsg;
1203 } else if (_tempo_map->set_state (*child)) {
1207 if ((child = find_named_node (node, "Routes")) == 0) {
1208 error << _("Session: XML state has no routes section") << endmsg;
1210 } else if (load_routes (*child)) {
1214 if ((child = find_named_node (node, "Click")) == 0) {
1215 warning << _("Session: XML state has no click section") << endmsg;
1216 } else if (_click_io) {
1217 _click_io->set_state (*child);
1220 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1221 ControlProtocolManager::instance().set_protocol_states (*child);
1224 /* here beginneth the second phase ... */
1226 StateReady (); /* EMIT SIGNAL */
1228 _state_of_the_state = Clean;
1230 if (state_was_pending) {
1231 save_state (_current_snapshot_name);
1232 remove_pending_capture_state ();
1233 state_was_pending = false;
1243 Session::load_routes (const XMLNode& node)
1246 XMLNodeConstIterator niter;
1247 RouteList new_routes;
1249 nlist = node.children();
1253 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1255 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1258 error << _("Session: cannot create Route from XML description.") << endmsg;
1262 new_routes.push_back (route);
1265 add_routes (new_routes);
1270 boost::shared_ptr<Route>
1271 Session::XMLRouteFactory (const XMLNode& node)
1273 if (node.name() != "Route") {
1274 return boost::shared_ptr<Route> ((Route*) 0);
1277 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1278 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1281 boost::shared_ptr<Route> x (new Route (*this, node));
1287 Session::load_regions (const XMLNode& node)
1290 XMLNodeConstIterator niter;
1291 boost::shared_ptr<AudioRegion> region;
1293 nlist = node.children();
1297 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1298 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1299 error << _("Session: cannot create Region from XML description.") << endmsg;
1306 boost::shared_ptr<AudioRegion>
1307 Session::XMLRegionFactory (const XMLNode& node, bool full)
1309 const XMLProperty* prop;
1310 boost::shared_ptr<Source> source;
1311 boost::shared_ptr<AudioSource> as;
1313 uint32_t nchans = 1;
1316 if (node.name() != X_("Region")) {
1317 return boost::shared_ptr<AudioRegion>();
1320 if ((prop = node.property (X_("channels"))) != 0) {
1321 nchans = atoi (prop->value().c_str());
1325 if ((prop = node.property ("name")) == 0) {
1326 cerr << "no name for this region\n";
1330 if ((prop = node.property (X_("source-0"))) == 0) {
1331 if ((prop = node.property ("source")) == 0) {
1332 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1333 return boost::shared_ptr<AudioRegion>();
1337 PBD::ID s_id (prop->value());
1339 if ((source = source_by_id (s_id)) == 0) {
1340 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1341 return boost::shared_ptr<AudioRegion>();
1344 as = boost::dynamic_pointer_cast<AudioSource>(source);
1346 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1347 return boost::shared_ptr<AudioRegion>();
1350 sources.push_back (as);
1352 /* pickup other channels */
1354 for (uint32_t n=1; n < nchans; ++n) {
1355 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1356 if ((prop = node.property (buf)) != 0) {
1358 PBD::ID id2 (prop->value());
1360 if ((source = source_by_id (id2)) == 0) {
1361 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1362 return boost::shared_ptr<AudioRegion>();
1365 as = boost::dynamic_pointer_cast<AudioSource>(source);
1367 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1368 return boost::shared_ptr<AudioRegion>();
1370 sources.push_back (as);
1375 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1380 catch (failed_constructor& err) {
1381 return boost::shared_ptr<AudioRegion>();
1386 Session::get_sources_as_xml ()
1389 XMLNode* node = new XMLNode (X_("Sources"));
1390 Glib::Mutex::Lock lm (audio_source_lock);
1392 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1393 node->add_child_nocopy (i->second->get_state());
1396 /* XXX get MIDI and other sources here */
1402 Session::path_from_region_name (string name, string identifier)
1404 char buf[PATH_MAX+1];
1406 string dir = discover_best_sound_dir ();
1408 for (n = 0; n < 999999; ++n) {
1409 if (identifier.length()) {
1410 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1411 identifier.c_str(), n);
1413 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1415 if (access (buf, F_OK) != 0) {
1425 Session::load_sources (const XMLNode& node)
1428 XMLNodeConstIterator niter;
1429 boost::shared_ptr<Source> source;
1431 nlist = node.children();
1435 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1437 if ((source = XMLSourceFactory (**niter)) == 0) {
1438 error << _("Session: cannot create Source from XML description.") << endmsg;
1446 boost::shared_ptr<Source>
1447 Session::XMLSourceFactory (const XMLNode& node)
1449 if (node.name() != "Source") {
1450 return boost::shared_ptr<Source>();
1454 return SourceFactory::create (*this, node);
1457 catch (failed_constructor& err) {
1458 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1459 return boost::shared_ptr<Source>();
1464 Session::save_template (string template_name)
1467 string xml_path, bak_path, template_path;
1469 if (_state_of_the_state & CannotSave) {
1474 string dir = template_dir();
1476 if ((dp = opendir (dir.c_str()))) {
1479 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1480 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1485 tree.set_root (&get_template());
1488 xml_path += template_name;
1489 xml_path += _template_suffix;
1491 ifstream in(xml_path.c_str());
1494 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1500 if (!tree.write (xml_path)) {
1501 error << _("mix template not saved") << endmsg;
1509 Session::rename_template (string old_name, string new_name)
1511 string old_path = template_dir() + old_name + _template_suffix;
1512 string new_path = template_dir() + new_name + _template_suffix;
1514 return rename (old_path.c_str(), new_path.c_str());
1518 Session::delete_template (string name)
1520 string template_path = template_dir();
1521 template_path += name;
1522 template_path += _template_suffix;
1524 return remove (template_path.c_str());
1528 Session::refresh_disk_space ()
1531 struct statfs statfsbuf;
1532 vector<space_and_path>::iterator i;
1533 Glib::Mutex::Lock lm (space_lock);
1536 /* get freespace on every FS that is part of the session path */
1538 _total_free_4k_blocks = 0;
1540 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1541 statfs ((*i).path.c_str(), &statfsbuf);
1543 scale = statfsbuf.f_bsize/4096.0;
1545 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1546 _total_free_4k_blocks += (*i).blocks;
1552 Session::ensure_sound_dir (string path, string& result)
1557 /* Ensure that the parent directory exists */
1559 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1560 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1564 /* Ensure that the sounds directory exists */
1568 result += sound_dir_name;
1570 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1571 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1577 dead += dead_sound_dir_name;
1579 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1580 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1586 peak += peak_dir_name;
1588 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1589 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1593 /* callers expect this to be terminated ... */
1600 Session::discover_best_sound_dir (bool destructive)
1602 vector<space_and_path>::iterator i;
1605 /* handle common case without system calls */
1607 if (session_dirs.size() == 1) {
1611 /* OK, here's the algorithm we're following here:
1613 We want to select which directory to use for
1614 the next file source to be created. Ideally,
1615 we'd like to use a round-robin process so as to
1616 get maximum performance benefits from splitting
1617 the files across multiple disks.
1619 However, in situations without much diskspace, an
1620 RR approach may end up filling up a filesystem
1621 with new files while others still have space.
1622 Its therefore important to pay some attention to
1623 the freespace in the filesystem holding each
1624 directory as well. However, if we did that by
1625 itself, we'd keep creating new files in the file
1626 system with the most space until it was as full
1627 as all others, thus negating any performance
1628 benefits of this RAID-1 like approach.
1630 So, we use a user-configurable space threshold. If
1631 there are at least 2 filesystems with more than this
1632 much space available, we use RR selection between them.
1633 If not, then we pick the filesystem with the most space.
1635 This gets a good balance between the two
1639 refresh_disk_space ();
1641 int free_enough = 0;
1643 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1644 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1649 if (free_enough >= 2) {
1651 bool found_it = false;
1653 /* use RR selection process, ensuring that the one
1657 i = last_rr_session_dir;
1660 if (++i == session_dirs.end()) {
1661 i = session_dirs.begin();
1664 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1665 if (ensure_sound_dir ((*i).path, result) == 0) {
1666 last_rr_session_dir = i;
1672 } while (i != last_rr_session_dir);
1675 result = sound_dir();
1680 /* pick FS with the most freespace (and that
1681 seems to actually work ...)
1684 vector<space_and_path> sorted;
1685 space_and_path_ascending_cmp cmp;
1687 sorted = session_dirs;
1688 sort (sorted.begin(), sorted.end(), cmp);
1690 for (i = sorted.begin(); i != sorted.end(); ++i) {
1691 if (ensure_sound_dir ((*i).path, result) == 0) {
1692 last_rr_session_dir = i;
1697 /* if the above fails, fall back to the most simplistic solution */
1699 if (i == sorted.end()) {
1708 Session::load_playlists (const XMLNode& node)
1711 XMLNodeConstIterator niter;
1712 boost::shared_ptr<Playlist> playlist;
1714 nlist = node.children();
1718 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1720 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1721 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1729 Session::load_unused_playlists (const XMLNode& node)
1732 XMLNodeConstIterator niter;
1733 boost::shared_ptr<Playlist> playlist;
1735 nlist = node.children();
1739 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1741 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1742 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1746 // now manually untrack it
1748 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1755 boost::shared_ptr<Playlist>
1756 Session::XMLPlaylistFactory (const XMLNode& node)
1759 return PlaylistFactory::create (*this, node);
1762 catch (failed_constructor& err) {
1763 return boost::shared_ptr<Playlist>();
1768 Session::load_named_selections (const XMLNode& node)
1771 XMLNodeConstIterator niter;
1774 nlist = node.children();
1778 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1780 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1781 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1789 Session::XMLNamedSelectionFactory (const XMLNode& node)
1792 return new NamedSelection (*this, node);
1795 catch (failed_constructor& err) {
1801 Session::dead_sound_dir () const
1804 res += dead_sound_dir_name;
1810 Session::sound_dir (bool with_path) const
1812 /* support old session structure */
1814 struct stat statbuf;
1816 string old_withpath;
1818 old_nopath += old_sound_dir_name;
1821 old_withpath = _path;
1822 old_withpath += old_sound_dir_name;
1824 if (stat (old_withpath.c_str(), &statbuf) == 0) {
1826 return old_withpath;
1837 res += interchange_dir_name;
1839 res += legalize_for_path (_name);
1841 res += sound_dir_name;
1847 Session::peak_dir () const
1850 res += peak_dir_name;
1856 Session::automation_dir () const
1859 res += "automation/";
1864 Session::template_dir ()
1866 string path = get_user_ardour_path();
1867 path += "templates/";
1873 Session::suffixed_search_path (string suffix, bool data)
1877 path += get_user_ardour_path();
1878 if (path[path.length()-1] != ':') {
1883 path += get_system_data_path();
1885 path += get_system_module_path();
1888 vector<string> split_path;
1890 split (path, split_path, ':');
1893 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
1898 if (distance (i, split_path.end()) != 1) {
1907 Session::template_path ()
1909 return suffixed_search_path (X_("templates"), true);
1913 Session::control_protocol_path ()
1915 return suffixed_search_path (X_("surfaces"), false);
1919 Session::load_connections (const XMLNode& node)
1921 XMLNodeList nlist = node.children();
1922 XMLNodeConstIterator niter;
1926 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1927 if ((*niter)->name() == "InputConnection") {
1928 add_connection (new ARDOUR::InputConnection (**niter));
1929 } else if ((*niter)->name() == "OutputConnection") {
1930 add_connection (new ARDOUR::OutputConnection (**niter));
1932 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1941 Session::load_edit_groups (const XMLNode& node)
1943 return load_route_groups (node, true);
1947 Session::load_mix_groups (const XMLNode& node)
1949 return load_route_groups (node, false);
1953 Session::load_route_groups (const XMLNode& node, bool edit)
1955 XMLNodeList nlist = node.children();
1956 XMLNodeConstIterator niter;
1961 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1962 if ((*niter)->name() == "RouteGroup") {
1964 rg = add_edit_group ("");
1965 rg->set_state (**niter);
1967 rg = add_mix_group ("");
1968 rg->set_state (**niter);
1977 state_file_filter (const string &str, void *arg)
1979 return (str.length() > strlen(Session::statefile_suffix()) &&
1980 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
1984 bool operator()(const string* a, const string* b) {
1990 remove_end(string* state)
1992 string statename(*state);
1994 string::size_type start,end;
1995 if ((start = statename.find_last_of ('/')) != string::npos) {
1996 statename = statename.substr (start+1);
1999 if ((end = statename.rfind(".ardour")) == string::npos) {
2000 end = statename.length();
2003 return new string(statename.substr (0, end));
2007 Session::possible_states (string path)
2009 PathScanner scanner;
2010 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2012 transform(states->begin(), states->end(), states->begin(), remove_end);
2015 sort (states->begin(), states->end(), cmp);
2021 Session::possible_states () const
2023 return possible_states(_path);
2027 Session::auto_save()
2029 save_state (_current_snapshot_name);
2033 Session::add_edit_group (string name)
2035 RouteGroup* rg = new RouteGroup (*this, name);
2036 edit_groups.push_back (rg);
2037 edit_group_added (rg); /* EMIT SIGNAL */
2043 Session::add_mix_group (string name)
2045 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2046 mix_groups.push_back (rg);
2047 mix_group_added (rg); /* EMIT SIGNAL */
2053 Session::remove_edit_group (RouteGroup& rg)
2055 list<RouteGroup*>::iterator i;
2057 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2058 (*i)->apply (&Route::drop_edit_group, this);
2059 edit_groups.erase (i);
2060 edit_group_removed (); /* EMIT SIGNAL */
2067 Session::remove_mix_group (RouteGroup& rg)
2069 list<RouteGroup*>::iterator i;
2071 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2072 (*i)->apply (&Route::drop_mix_group, this);
2073 mix_groups.erase (i);
2074 mix_group_removed (); /* EMIT SIGNAL */
2081 Session::mix_group_by_name (string name)
2083 list<RouteGroup *>::iterator i;
2085 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2086 if ((*i)->name() == name) {
2094 Session::edit_group_by_name (string name)
2096 list<RouteGroup *>::iterator i;
2098 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2099 if ((*i)->name() == name) {
2107 Session::begin_reversible_command (string name)
2109 current_trans = new UndoTransaction;
2110 current_trans->set_name (name);
2114 Session::commit_reversible_command (Command *cmd)
2119 current_trans->add_command (cmd);
2122 gettimeofday (&now, 0);
2123 current_trans->set_timestamp (now);
2125 _history.add (current_trans);
2128 Session::GlobalRouteBooleanState
2129 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2131 GlobalRouteBooleanState s;
2132 boost::shared_ptr<RouteList> r = routes.reader ();
2134 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2135 if (!(*i)->hidden()) {
2136 RouteBooleanState v;
2139 Route* r = (*i).get();
2140 v.second = (r->*method)();
2149 Session::GlobalRouteMeterState
2150 Session::get_global_route_metering ()
2152 GlobalRouteMeterState s;
2153 boost::shared_ptr<RouteList> r = routes.reader ();
2155 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2156 if (!(*i)->hidden()) {
2160 v.second = (*i)->meter_point();
2170 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2172 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2174 boost::shared_ptr<Route> r = (i->first.lock());
2177 r->set_meter_point (i->second, arg);
2183 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2185 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2187 boost::shared_ptr<Route> r = (i->first.lock());
2190 Route* rp = r.get();
2191 (rp->*method) (i->second, arg);
2197 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2199 set_global_route_boolean (s, &Route::set_mute, src);
2203 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2205 set_global_route_boolean (s, &Route::set_solo, src);
2209 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2211 set_global_route_boolean (s, &Route::set_record_enable, src);
2216 Session::global_mute_memento (void* src)
2218 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2222 Session::global_metering_memento (void* src)
2224 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2228 Session::global_solo_memento (void* src)
2230 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2234 Session::global_record_enable_memento (void* src)
2236 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2241 template_filter (const string &str, void *arg)
2243 return (str.length() > strlen(Session::template_suffix()) &&
2244 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2248 Session::get_template_list (list<string> &template_names)
2250 vector<string *> *templates;
2251 PathScanner scanner;
2254 path = template_path ();
2256 templates = scanner (path, template_filter, 0, false, true);
2258 vector<string*>::iterator i;
2259 for (i = templates->begin(); i != templates->end(); ++i) {
2260 string fullpath = *(*i);
2263 start = fullpath.find_last_of ('/') + 1;
2264 if ((end = fullpath.find_last_of ('.')) <0) {
2265 end = fullpath.length();
2268 template_names.push_back(fullpath.substr(start, (end-start)));
2273 Session::read_favorite_dirs (FavoriteDirs & favs)
2275 string path = get_user_ardour_path();
2276 path += "/favorite_dirs";
2278 ifstream fav (path.c_str());
2283 if (errno != ENOENT) {
2284 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2295 getline(fav, newfav);
2301 favs.push_back (newfav);
2308 Session::write_favorite_dirs (FavoriteDirs & favs)
2310 string path = get_user_ardour_path();
2311 path += "/favorite_dirs";
2313 ofstream fav (path.c_str());
2319 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2320 fav << (*i) << endl;
2327 accept_all_non_peak_files (const string& path, void *arg)
2329 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2333 accept_all_state_files (const string& path, void *arg)
2335 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2339 Session::find_all_sources (string path, set<string>& result)
2344 if (!tree.read (path)) {
2348 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2353 XMLNodeConstIterator niter;
2355 nlist = node->children();
2359 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2363 if ((prop = (*niter)->property (X_("name"))) == 0) {
2367 if (prop->value()[0] == '/') {
2368 /* external file, ignore */
2372 string path = _path; /* /-terminated */
2373 path += sound_dir_name;
2375 path += prop->value();
2377 result.insert (path);
2384 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2386 PathScanner scanner;
2387 vector<string*>* state_files;
2389 string this_snapshot_path;
2395 if (ripped[ripped.length()-1] == '/') {
2396 ripped = ripped.substr (0, ripped.length() - 1);
2399 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2401 if (state_files == 0) {
2406 this_snapshot_path = _path;
2407 this_snapshot_path += _current_snapshot_name;
2408 this_snapshot_path += _statefile_suffix;
2410 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2412 if (exclude_this_snapshot && **i == this_snapshot_path) {
2416 if (find_all_sources (**i, result) < 0) {
2424 struct RegionCounter {
2425 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2426 AudioSourceList::iterator iter;
2427 boost::shared_ptr<Region> region;
2430 RegionCounter() : count (0) {}
2434 Session::cleanup_sources (Session::cleanup_report& rep)
2436 typedef map<boost::shared_ptr<Source>, RegionCounter> SourceRegionMap;
2437 SourceRegionMap dead_sources;
2439 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2440 PathScanner scanner;
2442 vector<space_and_path>::iterator i;
2443 vector<space_and_path>::iterator nexti;
2444 vector<string*>* soundfiles;
2445 vector<string> unused;
2446 set<string> all_sources;
2451 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2453 /* step 1: consider deleting all unused playlists */
2455 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2458 status = AskAboutPlaylistDeletion (*x);
2467 playlists_tbd.push_back (*x);
2471 /* leave it alone */
2476 /* now delete any that were marked for deletion */
2478 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2479 (*x)->drop_references ();
2482 playlists_tbd.clear ();
2484 /* step 2: find all un-referenced sources */
2489 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2491 /* we expect the use_count() to be at least 2: one for the shared_ptr<> in the sources
2492 list and one for the iterator. if its used by 1 region, we'd expect a value of 3.
2494 do not bother with files that are zero size, otherwise we remove the current "nascent"
2498 if (i->second.use_count() <= 3 && i->second->length() > 0) {
2500 pair<boost::shared_ptr<Source>, RegionCounter> newpair;
2502 newpair.first = i->second;
2503 newpair.second.iter = i;
2505 dead_sources.insert (newpair);
2509 /* Search the region list to find out the state of the supposedly unreferenced regions
2512 for (SourceRegionMap::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2514 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ++r) {
2516 boost::shared_ptr<AudioRegion> ar = r->second;
2518 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2520 if (ar->source (n) == i->first) {
2522 /* this region uses this source */
2524 i->second.region = ar;
2527 if (i->second.count > 1) {
2535 /* next, get rid of all regions in the region list that use any dead sources
2536 in case the sources themselves don't go away (they might be referenced in
2539 this is also where we remove the apparently unused sources from our source
2540 list. this doesn't rename them or delete them, but it means they are
2541 potential candidates for renaming after we find all soundfiles
2542 and scan for use across all snapshots (including this one).
2545 for (SourceRegionMap::iterator i = dead_sources.begin(); i != dead_sources.end(); ) {
2547 SourceRegionMap::iterator tmp;
2552 if (i->second.count == 0) {
2554 /* no regions use this source */
2556 /* remove this source from our own list to avoid us
2557 adding it to the list of all sources below
2560 audio_sources.erase (i->second.iter);
2562 } else if (i->second.count == 1) {
2564 /* the use_count for the source was 3. this means that there is only reference to it in addition to the source
2565 list and an iterator used to traverse that list. since there is a single region using the source, that
2566 must be the extra reference. this implies that its a whole-file region
2567 with no children, so remove the region and the source.
2570 remove_region (i->second.region);
2572 /* remove this source from our own list to avoid us
2573 adding it to the list of all sources below
2576 audio_sources.erase (i->second.iter);
2579 /* more than one region uses this source, do not remove it */
2580 dead_sources.erase (i);
2586 /* build a list of all the possible sound directories for the session */
2588 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2593 sound_path += (*i).path;
2594 sound_path += sound_dir (false);
2596 if (nexti != session_dirs.end()) {
2603 /* now do the same thing for the files that ended up in the sounds dir(s)
2604 but are not referenced as sources in any snapshot.
2607 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2609 if (soundfiles == 0) {
2613 /* find all sources, but don't use this snapshot because the
2614 state file on disk still references sources we may have already
2618 find_all_sources_across_snapshots (all_sources, true);
2620 /* add our current source list
2623 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2624 boost::shared_ptr<AudioFileSource> fs;
2626 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2627 all_sources.insert (fs->path());
2631 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2636 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2646 unused.push_back (spath);
2650 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2652 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2653 struct stat statbuf;
2655 rep.paths.push_back (*x);
2656 if (stat ((*x).c_str(), &statbuf) == 0) {
2657 rep.space += statbuf.st_size;
2662 /* don't move the file across filesystems, just
2663 stick it in the `dead_sound_dir_name' directory
2664 on whichever filesystem it was already on.
2667 /* XXX this is a hack ... go up 4 levels */
2669 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2670 newpath = Glib::path_get_dirname (newpath); // "session-name"
2671 newpath = Glib::path_get_dirname (newpath); // "interchange"
2672 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2675 newpath += dead_sound_dir_name;
2677 newpath += Glib::path_get_basename ((*x));
2679 if (access (newpath.c_str(), F_OK) == 0) {
2681 /* the new path already exists, try versioning */
2683 char buf[PATH_MAX+1];
2687 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2690 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2691 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2695 if (version == 999) {
2696 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2700 newpath = newpath_v;
2705 /* it doesn't exist, or we can't read it or something */
2709 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2710 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2711 (*x), newpath, strerror (errno))
2717 /* see if there an easy to find peakfile for this file, and remove it.
2720 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2721 peakpath += ".peak";
2723 if (access (peakpath.c_str(), W_OK) == 0) {
2724 if (::unlink (peakpath.c_str()) != 0) {
2725 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2726 peakpath, _path, strerror (errno))
2728 /* try to back out */
2729 rename (newpath.c_str(), _path.c_str());
2737 /* dump the history list */
2741 /* save state so we don't end up a session file
2742 referring to non-existent sources.
2748 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2753 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2755 vector<space_and_path>::iterator i;
2756 string dead_sound_dir;
2757 struct dirent* dentry;
2758 struct stat statbuf;
2764 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2766 dead_sound_dir = (*i).path;
2767 dead_sound_dir += dead_sound_dir_name;
2769 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2773 while ((dentry = readdir (dead)) != 0) {
2775 /* avoid '.' and '..' */
2777 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2778 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2784 fullpath = dead_sound_dir;
2786 fullpath += dentry->d_name;
2788 if (stat (fullpath.c_str(), &statbuf)) {
2792 if (!S_ISREG (statbuf.st_mode)) {
2796 if (unlink (fullpath.c_str())) {
2797 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2798 fullpath, strerror (errno))
2802 rep.paths.push_back (dentry->d_name);
2803 rep.space += statbuf.st_size;
2814 Session::set_dirty ()
2816 bool was_dirty = dirty();
2818 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2821 DirtyChanged(); /* EMIT SIGNAL */
2827 Session::set_clean ()
2829 bool was_dirty = dirty();
2831 _state_of_the_state = Clean;
2834 DirtyChanged(); /* EMIT SIGNAL */
2839 Session::set_deletion_in_progress ()
2841 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2845 Session::add_controllable (Controllable* c)
2847 Glib::Mutex::Lock lm (controllables_lock);
2848 controllables.insert (c);
2852 Session::remove_controllable (Controllable* c)
2854 if (_state_of_the_state | Deletion) {
2858 Glib::Mutex::Lock lm (controllables_lock);
2860 Controllables::iterator x = controllables.find (c);
2862 if (x != controllables.end()) {
2863 controllables.erase (x);
2868 Session::controllable_by_id (const PBD::ID& id)
2870 Glib::Mutex::Lock lm (controllables_lock);
2872 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2873 if ((*i)->id() == id) {
2882 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2884 Stateful::add_instant_xml (node, dir);
2885 Config->add_instant_xml (node, get_user_ardour_path());
2890 Session::save_history (string snapshot_name)
2896 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2898 if (snapshot_name.empty()) {
2899 snapshot_name = _current_snapshot_name;
2902 xml_path = _path + snapshot_name + ".history";
2904 bak_path = xml_path + ".bak";
2906 if ((access (xml_path.c_str(), F_OK) == 0) &&
2907 (rename (xml_path.c_str(), bak_path.c_str())))
2909 error << _("could not backup old history file, current history not saved.") << endmsg;
2913 cerr << "actually writing history\n";
2915 if (!tree.write (xml_path))
2917 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2919 /* don't leave a corrupt file lying around if it is
2923 if (unlink (xml_path.c_str())) {
2924 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2926 if (rename (bak_path.c_str(), xml_path.c_str()))
2928 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2939 Session::restore_history (string snapshot_name)
2944 if (snapshot_name.empty()) {
2945 snapshot_name = _current_snapshot_name;
2949 xmlpath = _path + snapshot_name + ".history";
2950 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2952 if (access (xmlpath.c_str(), F_OK)) {
2953 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2957 if (!tree.read (xmlpath)) {
2958 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2962 /* replace history */
2965 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2968 UndoTransaction* ut = new UndoTransaction ();
2971 ut->set_name(t->property("name")->value());
2972 stringstream ss(t->property("tv_sec")->value());
2974 ss.str(t->property("tv_usec")->value());
2976 ut->set_timestamp(tv);
2978 for (XMLNodeConstIterator child_it = t->children().begin();
2979 child_it != t->children().end();
2982 XMLNode *n = *child_it;
2985 if (n->name() == "MementoCommand" ||
2986 n->name() == "MementoUndoCommand" ||
2987 n->name() == "MementoRedoCommand") {
2989 if ((c = memento_command_factory(n))) {
2993 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2995 if ((c = global_state_command_factory (*n))) {
2996 ut->add_command (c);
3001 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3012 Session::config_changed (const char* parameter_name)
3014 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3016 if (PARAM_IS ("seamless-loop")) {
3018 } else if (PARAM_IS ("rf-speed")) {
3020 } else if (PARAM_IS ("auto-loop")) {
3022 } else if (PARAM_IS ("auto-input")) {
3024 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3025 /* auto-input only makes a difference if we're rolling */
3027 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3029 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3030 if ((*i)->record_enabled ()) {
3031 (*i)->monitor_input (!Config->get_auto_input());
3036 } else if (PARAM_IS ("punch-in")) {
3040 if ((location = _locations.auto_punch_location()) != 0) {
3042 if (Config->get_punch_in ()) {
3043 replace_event (Event::PunchIn, location->start());
3045 remove_event (location->start(), Event::PunchIn);
3049 } else if (PARAM_IS ("punch-out")) {
3053 if ((location = _locations.auto_punch_location()) != 0) {
3055 if (Config->get_punch_out()) {
3056 replace_event (Event::PunchOut, location->end());
3058 clear_events (Event::PunchOut);
3062 } else if (PARAM_IS ("edit-mode")) {
3064 Glib::Mutex::Lock lm (playlist_lock);
3066 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3067 (*i)->set_edit_mode (Config->get_edit_mode ());
3070 } else if (PARAM_IS ("use-video-sync")) {
3072 if (transport_stopped()) {
3073 if (Config->get_use_video_sync()) {
3074 waiting_for_sync_offset = true;
3078 } else if (PARAM_IS ("mmc-control")) {
3080 poke_midi_thread ();
3082 } else if (PARAM_IS ("midi-control")) {
3084 poke_midi_thread ();
3086 } else if (PARAM_IS ("raid-path")) {
3088 setup_raid_path (Config->get_raid_path());
3090 } else if (PARAM_IS ("smpte-format")) {
3094 } else if (PARAM_IS ("video-pullup")) {
3098 } else if (PARAM_IS ("seamless-loop")) {
3100 if (play_loop && transport_rolling()) {
3101 // to reset diskstreams etc
3102 request_play_loop (true);
3105 } else if (PARAM_IS ("rf-speed")) {
3107 cumulative_rf_motion = 0;
3110 } else if (PARAM_IS ("click-sound")) {
3112 setup_click_sounds (1);
3114 } else if (PARAM_IS ("click-emphasis-sound")) {
3116 setup_click_sounds (-1);
3118 } else if (PARAM_IS ("clicking")) {
3120 if (Config->get_clicking()) {
3121 if (_click_io && click_data) { // don't require emphasis data
3128 } else if (PARAM_IS ("send-mtc")) {
3130 /* only set the internal flag if we have
3134 if (_mtc_port != 0) {
3135 session_send_mtc = Config->get_send_mtc();
3136 if (session_send_mtc) {
3137 /* mark us ready to send */
3138 next_quarter_frame_to_send = 0;
3142 } else if (PARAM_IS ("send-mmc")) {
3144 /* only set the internal flag if we have
3148 if (_mmc_port != 0) {
3149 session_send_mmc = Config->get_send_mmc();
3152 } else if (PARAM_IS ("midi-feedback")) {
3154 /* only set the internal flag if we have
3158 if (_mtc_port != 0) {
3159 session_midi_feedback = Config->get_midi_feedback();
3162 } else if (PARAM_IS ("jack-time-master")) {
3164 engine().reset_timebase ();
3166 } else if (PARAM_IS ("native-file-header-format")) {
3168 if (!first_file_header_format_reset) {
3169 reset_native_file_format ();
3172 first_file_header_format_reset = false;
3174 } else if (PARAM_IS ("native-file-data-format")) {
3176 if (!first_file_data_format_reset) {
3177 reset_native_file_format ();
3180 first_file_data_format_reset = false;