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/mount.h>
44 #include <sys/param.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>
58 #include <ardour/audioengine.h>
59 #include <ardour/configuration.h>
60 #include <ardour/session.h>
61 #include <ardour/audio_diskstream.h>
62 #include <ardour/utils.h>
63 #include <ardour/audioplaylist.h>
64 #include <ardour/audiofilesource.h>
65 #include <ardour/destructive_filesource.h>
66 #include <ardour/sndfile_helpers.h>
67 #include <ardour/auditioner.h>
68 #include <ardour/export.h>
69 #include <ardour/redirect.h>
70 #include <ardour/send.h>
71 #include <ardour/insert.h>
72 #include <ardour/connection.h>
73 #include <ardour/slave.h>
74 #include <ardour/tempo.h>
75 #include <ardour/audio_track.h>
76 #include <ardour/cycle_timer.h>
77 #include <ardour/utils.h>
78 #include <ardour/named_selection.h>
79 #include <ardour/version.h>
80 #include <ardour/location.h>
81 #include <ardour/audioregion.h>
82 #include <ardour/crossfade.h>
83 #include <ardour/control_protocol_manager.h>
84 #include <ardour/region_factory.h>
85 #include <ardour/source_factory.h>
91 using namespace ARDOUR;
95 Session::first_stage_init (string fullpath, string snapshot_name)
97 if (fullpath.length() == 0) {
98 throw failed_constructor();
101 char buf[PATH_MAX+1];
102 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
103 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
104 throw failed_constructor();
109 if (_path[_path.length()-1] != '/') {
113 /* these two are just provisional settings. set_state()
114 will likely override them.
117 _name = _current_snapshot_name = snapshot_name;
119 _current_frame_rate = _engine.frame_rate ();
120 _tempo_map = new TempoMap (_current_frame_rate);
121 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
123 g_atomic_int_set (&processing_prohibited, 0);
126 _transport_speed = 0;
127 _last_transport_speed = 0;
128 transport_sub_state = 0;
129 _transport_frame = 0;
131 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
132 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
133 _end_location_is_free = true;
134 g_atomic_int_set (&_record_status, Disabled);
135 loop_changing = false;
137 _last_roll_location = 0;
138 _last_record_location = 0;
139 pending_locate_frame = 0;
140 pending_locate_roll = false;
141 pending_locate_flush = false;
142 dstream_buffer_size = 0;
144 state_was_pending = false;
146 outbound_mtc_smpte_frame = 0;
147 next_quarter_frame_to_send = -1;
148 current_block_size = 0;
149 solo_update_disabled = false;
150 currently_soloing = false;
151 _have_captured = false;
152 _worst_output_latency = 0;
153 _worst_input_latency = 0;
154 _worst_track_latency = 0;
155 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
157 butler_mixdown_buffer = 0;
158 butler_gain_buffer = 0;
160 session_send_mmc = false;
161 session_send_mtc = false;
162 session_midi_feedback = false;
163 post_transport_work = PostTransportWork (0);
164 g_atomic_int_set (&butler_should_do_transport_work, 0);
165 g_atomic_int_set (&butler_active, 0);
166 g_atomic_int_set (&_playback_load, 100);
167 g_atomic_int_set (&_capture_load, 100);
168 g_atomic_int_set (&_playback_load_min, 100);
169 g_atomic_int_set (&_capture_load_min, 100);
171 waiting_to_start = false;
173 _gain_automation_buffer = 0;
174 _pan_automation_buffer = 0;
176 pending_abort = false;
177 destructive_index = 0;
180 AudioDiskstream::allocate_working_buffers();
182 /* default short fade = 15ms */
184 Crossfade::set_short_xfade_length ((jack_nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
185 DestructiveFileSource::setup_standard_crossfades (frame_rate());
187 last_mmc_step.tv_sec = 0;
188 last_mmc_step.tv_usec = 0;
191 /* click sounds are unset by default, which causes us to internal
192 waveforms for clicks.
196 click_emphasis_data = 0;
198 click_emphasis_length = 0;
201 process_function = &Session::process_with_events;
203 if (Config->get_use_video_sync()) {
204 waiting_for_sync_offset = true;
206 waiting_for_sync_offset = false;
209 _current_frame_rate = 48000;
210 _base_frame_rate = 48000;
214 _smpte_offset_negative = true;
215 last_smpte_valid = false;
219 last_rr_session_dir = session_dirs.begin();
220 refresh_disk_space ();
222 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
226 average_slave_delta = 1800;
227 have_first_delta_accumulator = false;
228 delta_accumulator_cnt = 0;
229 slave_state = Stopped;
231 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
233 /* These are all static "per-class" signals */
235 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
236 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
237 Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
238 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
239 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
240 Curve::CurveCreated.connect (mem_fun (*this, &Session::add_curve));
241 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
243 Controllable::Created.connect (mem_fun (*this, &Session::add_controllable));
244 Controllable::GoingAway.connect (mem_fun (*this, &Session::remove_controllable));
246 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
248 /* stop IO objects from doing stuff until we're ready for them */
250 IO::disable_panners ();
251 IO::disable_ports ();
252 IO::disable_connecting ();
256 Session::second_stage_init (bool new_session)
258 AudioFileSource::set_peak_dir (peak_dir());
261 if (load_state (_current_snapshot_name)) {
264 remove_empty_sounds ();
267 if (start_butler_thread()) {
271 if (start_midi_thread ()) {
275 // set_state() will call setup_raid_path(), but if it's a new session we need
276 // to call setup_raid_path() here.
278 if (set_state (*state_tree->root())) {
282 setup_raid_path(_path);
285 /* we can't save till after ::when_engine_running() is called,
286 because otherwise we save state with no connections made.
287 therefore, we reset _state_of_the_state because ::set_state()
288 will have cleared it.
290 we also have to include Loading so that any events that get
291 generated between here and the end of ::when_engine_running()
292 will be processed directly rather than queued.
295 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
297 // set_auto_input (true);
298 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
299 _locations.added.connect (mem_fun (this, &Session::locations_added));
300 setup_click_sounds (0);
301 setup_midi_control ();
303 /* Pay attention ... */
305 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
306 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
308 if (_engine.running()) {
309 when_engine_running();
311 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
314 send_full_time_code ();
315 _engine.transport_locate (0);
316 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
317 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
319 ControlProtocolManager::instance().set_session (*this);
322 _end_location_is_free = true;
324 _end_location_is_free = false;
331 Session::raid_path () const
335 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
340 return path.substr (0, path.length() - 1); // drop final colon
344 Session::setup_raid_path (string path)
346 string::size_type colon;
350 string::size_type len = path.length();
355 if (path.length() == 0) {
359 session_dirs.clear ();
361 for (string::size_type n = 0; n < len; ++n) {
362 if (path[n] == ':') {
369 /* no multiple search path, just one location (common case) */
373 session_dirs.push_back (sp);
380 if (fspath[fspath.length()-1] != '/') {
383 fspath += sound_dir (false);
385 AudioFileSource::set_search_path (fspath);
392 while ((colon = remaining.find_first_of (':')) != string::npos) {
395 sp.path = remaining.substr (0, colon);
396 session_dirs.push_back (sp);
398 /* add sounds to file search path */
401 if (fspath[fspath.length()-1] != '/') {
404 fspath += sound_dir (false);
407 remaining = remaining.substr (colon+1);
410 if (remaining.length()) {
417 if (fspath[fspath.length()-1] != '/') {
420 fspath += sound_dir (false);
423 session_dirs.push_back (sp);
426 /* set the AudioFileSource search path */
428 AudioFileSource::set_search_path (fspath);
430 /* reset the round-robin soundfile path thingie */
432 last_rr_session_dir = session_dirs.begin();
436 Session::create (bool& new_session, string* mix_template, jack_nframes_t initial_length)
440 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
441 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
447 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
448 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
454 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
455 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
459 dir = dead_sound_dir ();
461 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
462 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
466 dir = automation_dir ();
468 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
469 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
474 /* check new_session so we don't overwrite an existing one */
477 std::string in_path = *mix_template;
479 ifstream in(in_path.c_str());
482 string out_path = _path;
484 out_path += _statefile_suffix;
486 ofstream out(out_path.c_str());
491 // okay, session is set up. Treat like normal saved
492 // session from now on.
498 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
504 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
511 /* set initial start + end point */
513 start_location->set_end (0);
514 _locations.add (start_location);
516 end_location->set_end (initial_length);
517 _locations.add (end_location);
519 _state_of_the_state = Clean;
521 if (save_state (_current_snapshot_name)) {
522 save_history (_current_snapshot_name);
530 Session::load_diskstreams (const XMLNode& node)
533 XMLNodeConstIterator citer;
535 clist = node.children();
537 for (citer = clist.begin(); citer != clist.end(); ++citer) {
541 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
542 add_diskstream (dstream);
545 catch (failed_constructor& err) {
546 error << _("Session: could not load diskstream via XML state") << endmsg;
555 Session::remove_pending_capture_state ()
560 xml_path += _current_snapshot_name;
561 xml_path += _pending_suffix;
563 unlink (xml_path.c_str());
567 Session::save_state (string snapshot_name, bool pending)
573 if (_state_of_the_state & CannotSave) {
577 tree.set_root (&get_state());
579 if (snapshot_name.empty()) {
580 snapshot_name = _current_snapshot_name;
586 xml_path += snapshot_name;
587 xml_path += _statefile_suffix;
591 // Make backup of state file
593 if ((access (xml_path.c_str(), F_OK) == 0) &&
594 (rename(xml_path.c_str(), bak_path.c_str()))) {
595 error << _("could not backup old state file, current state not saved.") << endmsg;
602 xml_path += snapshot_name;
603 xml_path += _pending_suffix;
607 cerr << "actually writing state\n";
609 if (!tree.write (xml_path)) {
610 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
612 /* don't leave a corrupt file lying around if it is
616 if (unlink (xml_path.c_str())) {
617 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
620 if (rename (bak_path.c_str(), xml_path.c_str())) {
621 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
630 save_history(snapshot_name);
632 bool was_dirty = dirty();
634 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
637 DirtyChanged (); /* EMIT SIGNAL */
640 StateSaved (snapshot_name); /* EMIT SIGNAL */
647 Session::restore_state (string snapshot_name)
649 if (load_state (snapshot_name) == 0) {
650 set_state (*state_tree->root());
657 Session::load_state (string snapshot_name)
666 state_was_pending = false;
668 /* check for leftover pending state from a crashed capture attempt */
671 xmlpath += snapshot_name;
672 xmlpath += _pending_suffix;
674 if (!access (xmlpath.c_str(), F_OK)) {
676 /* there is pending state from a crashed capture attempt */
678 if (AskAboutPendingState()) {
679 state_was_pending = true;
683 if (!state_was_pending) {
686 xmlpath += snapshot_name;
687 xmlpath += _statefile_suffix;
690 if (access (xmlpath.c_str(), F_OK)) {
691 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
695 state_tree = new XMLTree;
699 if (state_tree->read (xmlpath)) {
702 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
711 Session::load_options (const XMLNode& node)
715 LocaleGuard lg (X_("POSIX"));
717 Config->set_variables (node, ConfigVariableBase::Session);
719 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
720 if ((prop = child->property ("val")) != 0) {
721 _end_location_is_free = (prop->value() == "yes");
729 Session::get_options () const
732 LocaleGuard lg (X_("POSIX"));
734 XMLNode& option_root = Config->get_partial_state (ConfigVariableBase::Interface);
736 child = option_root.add_child ("end-marker-is-free");
737 child->add_property ("val", _end_location_is_free ? "yes" : "no");
739 child = option_root.add_child ("full-xfades-unmuted");
751 Session::get_template()
753 /* if we don't disable rec-enable, diskstreams
754 will believe they need to store their capture
755 sources in their state node.
758 disable_record (false);
764 Session::state(bool full_state)
766 XMLNode* node = new XMLNode("Session");
769 // store libardour version, just in case
771 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
772 libardour_major_version, libardour_minor_version, libardour_micro_version);
773 node->add_property("version", string(buf));
775 /* store configuration settings */
780 node->add_property ("name", _name);
782 if (session_dirs.size() > 1) {
786 vector<space_and_path>::iterator i = session_dirs.begin();
787 vector<space_and_path>::iterator next;
789 ++i; /* skip the first one */
793 while (i != session_dirs.end()) {
797 if (next != session_dirs.end()) {
807 child = node->add_child ("Path");
808 child->add_content (p);
812 /* save the ID counter */
814 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
815 node->add_property ("id-counter", buf);
817 /* various options */
819 node->add_child_nocopy (get_options());
821 child = node->add_child ("Sources");
824 Glib::Mutex::Lock sl (audio_source_lock);
826 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
828 /* Don't save information about AudioFileSources that are empty */
830 boost::shared_ptr<AudioFileSource> fs;
832 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
833 boost::shared_ptr<DestructiveFileSource> dfs = boost::dynamic_pointer_cast<DestructiveFileSource> (fs);
835 /* destructive file sources are OK if they are empty, because
836 we will re-use them every time.
840 if (fs->length() == 0) {
846 child->add_child_nocopy (siter->second->get_state());
850 child = node->add_child ("Regions");
853 Glib::Mutex::Lock rl (region_lock);
855 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
857 /* only store regions not attached to playlists */
859 if (i->second->playlist() == 0) {
860 child->add_child_nocopy (i->second->state (true));
865 child = node->add_child ("DiskStreams");
868 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
869 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
870 if (!(*i)->hidden()) {
871 child->add_child_nocopy ((*i)->get_state());
876 node->add_child_nocopy (_locations.get_state());
878 child = node->add_child ("Connections");
880 Glib::Mutex::Lock lm (connection_lock);
881 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
882 if (!(*i)->system_dependent()) {
883 child->add_child_nocopy ((*i)->get_state());
888 child = node->add_child ("Routes");
890 boost::shared_ptr<RouteList> r = routes.reader ();
892 RoutePublicOrderSorter cmp;
893 RouteList public_order (*r);
894 public_order.sort (cmp);
896 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
897 if (!(*i)->hidden()) {
899 child->add_child_nocopy ((*i)->get_state());
901 child->add_child_nocopy ((*i)->get_template());
908 child = node->add_child ("EditGroups");
909 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
910 child->add_child_nocopy ((*i)->get_state());
913 child = node->add_child ("MixGroups");
914 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
915 child->add_child_nocopy ((*i)->get_state());
918 child = node->add_child ("Playlists");
919 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
920 if (!(*i)->hidden()) {
921 if (!(*i)->empty()) {
923 child->add_child_nocopy ((*i)->get_state());
925 child->add_child_nocopy ((*i)->get_template());
931 child = node->add_child ("UnusedPlaylists");
932 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
933 if (!(*i)->hidden()) {
934 if (!(*i)->empty()) {
936 child->add_child_nocopy ((*i)->get_state());
938 child->add_child_nocopy ((*i)->get_template());
946 child = node->add_child ("Click");
947 child->add_child_nocopy (_click_io->state (full_state));
951 child = node->add_child ("NamedSelections");
952 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
954 child->add_child_nocopy ((*i)->get_state());
959 node->add_child_nocopy (_tempo_map->get_state());
962 node->add_child_copy (*_extra_xml);
969 Session::set_state (const XMLNode& node)
973 const XMLProperty* prop;
976 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
978 if (node.name() != X_("Session")){
979 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
983 StateManager::prohibit_save ();
985 if ((prop = node.property ("name")) != 0) {
986 _name = prop->value ();
989 setup_raid_path(_path);
991 if ((prop = node.property (X_("id-counter"))) != 0) {
993 sscanf (prop->value().c_str(), "%" PRIu64, &x);
994 ID::init_counter (x);
996 /* old sessions used a timebased counter, so fake
997 the startup ID counter based on a standard
1002 ID::init_counter (now);
1006 IO::disable_ports ();
1007 IO::disable_connecting ();
1009 /* Object loading order:
1026 if (use_config_midi_ports ()) {
1029 if ((child = find_named_node (node, "extra")) != 0) {
1030 _extra_xml = new XMLNode (*child);
1033 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1034 load_options (*child);
1035 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1036 load_options (*child);
1038 error << _("Session: XML state has no options section") << endmsg;
1041 if ((child = find_named_node (node, "Sources")) == 0) {
1042 error << _("Session: XML state has no sources section") << endmsg;
1044 } else if (load_sources (*child)) {
1048 if ((child = find_named_node (node, "Regions")) == 0) {
1049 error << _("Session: XML state has no Regions section") << endmsg;
1051 } else if (load_regions (*child)) {
1055 if ((child = find_named_node (node, "Playlists")) == 0) {
1056 error << _("Session: XML state has no playlists section") << endmsg;
1058 } else if (load_playlists (*child)) {
1062 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1064 } else if (load_unused_playlists (*child)) {
1068 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1069 if (load_named_selections (*child)) {
1074 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1075 error << _("Session: XML state has no diskstreams section") << endmsg;
1077 } else if (load_diskstreams (*child)) {
1081 if ((child = find_named_node (node, "Connections")) == 0) {
1082 error << _("Session: XML state has no connections section") << endmsg;
1084 } else if (load_connections (*child)) {
1088 if ((child = find_named_node (node, "Locations")) == 0) {
1089 error << _("Session: XML state has no locations section") << endmsg;
1091 } else if (_locations.set_state (*child)) {
1097 if ((location = _locations.auto_loop_location()) != 0) {
1098 set_auto_loop_location (location);
1101 if ((location = _locations.auto_punch_location()) != 0) {
1102 set_auto_punch_location (location);
1105 if ((location = _locations.end_location()) == 0) {
1106 _locations.add (end_location);
1108 delete end_location;
1109 end_location = location;
1112 if ((location = _locations.start_location()) == 0) {
1113 _locations.add (start_location);
1115 delete start_location;
1116 start_location = location;
1119 _locations.save_state (_("initial state"));
1121 if ((child = find_named_node (node, "EditGroups")) == 0) {
1122 error << _("Session: XML state has no edit groups section") << endmsg;
1124 } else if (load_edit_groups (*child)) {
1128 if ((child = find_named_node (node, "MixGroups")) == 0) {
1129 error << _("Session: XML state has no mix groups section") << endmsg;
1131 } else if (load_mix_groups (*child)) {
1135 if ((child = find_named_node (node, "TempoMap")) == 0) {
1136 error << _("Session: XML state has no Tempo Map section") << endmsg;
1138 } else if (_tempo_map->set_state (*child)) {
1142 if ((child = find_named_node (node, "Routes")) == 0) {
1143 error << _("Session: XML state has no routes section") << endmsg;
1145 } else if (load_routes (*child)) {
1149 if ((child = find_named_node (node, "Click")) == 0) {
1150 warning << _("Session: XML state has no click section") << endmsg;
1151 } else if (_click_io) {
1152 _click_io->set_state (*child);
1155 /* here beginneth the second phase ... */
1157 StateReady (); /* EMIT SIGNAL */
1159 _state_of_the_state = Clean;
1161 StateManager::allow_save (_("initial state"), true);
1163 if (state_was_pending) {
1164 save_state (_current_snapshot_name);
1165 remove_pending_capture_state ();
1166 state_was_pending = false;
1172 /* we failed, re-enable state saving but don't actually save internal state */
1173 StateManager::allow_save (X_("ignored"), false);
1178 Session::load_routes (const XMLNode& node)
1181 XMLNodeConstIterator niter;
1182 RouteList new_routes;
1184 nlist = node.children();
1188 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1190 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1193 error << _("Session: cannot create Route from XML description.") << endmsg;
1197 new_routes.push_back (route);
1200 add_routes (new_routes);
1205 boost::shared_ptr<Route>
1206 Session::XMLRouteFactory (const XMLNode& node)
1208 if (node.name() != "Route") {
1209 return boost::shared_ptr<Route> ((Route*) 0);
1212 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1213 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1216 boost::shared_ptr<Route> x (new Route (*this, node));
1222 Session::load_regions (const XMLNode& node)
1225 XMLNodeConstIterator niter;
1226 boost::shared_ptr<AudioRegion> region;
1228 nlist = node.children();
1232 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1233 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1234 error << _("Session: cannot create Region from XML description.") << endmsg;
1241 boost::shared_ptr<AudioRegion>
1242 Session::XMLRegionFactory (const XMLNode& node, bool full)
1244 const XMLProperty* prop;
1245 boost::shared_ptr<Source> source;
1246 boost::shared_ptr<AudioSource> as;
1248 uint32_t nchans = 1;
1251 if (node.name() != X_("Region")) {
1252 return boost::shared_ptr<AudioRegion>();
1255 if ((prop = node.property (X_("channels"))) != 0) {
1256 nchans = atoi (prop->value().c_str());
1260 if ((prop = node.property (X_("source-0"))) == 0) {
1261 if ((prop = node.property ("source")) == 0) {
1262 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1263 return boost::shared_ptr<AudioRegion>();
1267 PBD::ID s_id (prop->value());
1269 if ((source = source_by_id (s_id)) == 0) {
1270 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1271 return boost::shared_ptr<AudioRegion>();
1274 as = boost::dynamic_pointer_cast<AudioSource>(source);
1276 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1277 return boost::shared_ptr<AudioRegion>();
1280 sources.push_back (as);
1282 /* pickup other channels */
1284 for (uint32_t n=1; n < nchans; ++n) {
1285 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1286 if ((prop = node.property (buf)) != 0) {
1288 PBD::ID id2 (prop->value());
1290 if ((source = source_by_id (id2)) == 0) {
1291 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1292 return boost::shared_ptr<AudioRegion>();
1295 as = boost::dynamic_pointer_cast<AudioSource>(source);
1297 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1298 return boost::shared_ptr<AudioRegion>();
1300 sources.push_back (as);
1305 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1310 catch (failed_constructor& err) {
1311 return boost::shared_ptr<AudioRegion>();
1316 Session::get_sources_as_xml ()
1319 XMLNode* node = new XMLNode (X_("Sources"));
1320 Glib::Mutex::Lock lm (audio_source_lock);
1322 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1323 node->add_child_nocopy (i->second->get_state());
1326 /* XXX get MIDI and other sources here */
1332 Session::path_from_region_name (string name, string identifier)
1334 char buf[PATH_MAX+1];
1336 string dir = discover_best_sound_dir ();
1338 for (n = 0; n < 999999; ++n) {
1339 if (identifier.length()) {
1340 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1341 identifier.c_str(), n);
1343 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1345 if (access (buf, F_OK) != 0) {
1355 Session::load_sources (const XMLNode& node)
1358 XMLNodeConstIterator niter;
1359 boost::shared_ptr<Source> source;
1361 nlist = node.children();
1365 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1367 if ((source = XMLSourceFactory (**niter)) == 0) {
1368 error << _("Session: cannot create Source from XML description.") << endmsg;
1375 boost::shared_ptr<Source>
1376 Session::XMLSourceFactory (const XMLNode& node)
1378 if (node.name() != "Source") {
1379 return boost::shared_ptr<Source>();
1383 return SourceFactory::create (*this, node);
1386 catch (failed_constructor& err) {
1387 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1388 return boost::shared_ptr<Source>();
1393 Session::save_template (string template_name)
1396 string xml_path, bak_path, template_path;
1398 if (_state_of_the_state & CannotSave) {
1403 string dir = template_dir();
1405 if ((dp = opendir (dir.c_str()))) {
1408 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1409 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1414 tree.set_root (&get_template());
1417 xml_path += template_name;
1418 xml_path += _template_suffix;
1420 ifstream in(xml_path.c_str());
1423 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1429 if (!tree.write (xml_path)) {
1430 error << _("mix template not saved") << endmsg;
1438 Session::rename_template (string old_name, string new_name)
1440 string old_path = template_dir() + old_name + _template_suffix;
1441 string new_path = template_dir() + new_name + _template_suffix;
1443 return rename (old_path.c_str(), new_path.c_str());
1447 Session::delete_template (string name)
1449 string template_path = template_dir();
1450 template_path += name;
1451 template_path += _template_suffix;
1453 return remove (template_path.c_str());
1457 Session::refresh_disk_space ()
1460 struct statfs statfsbuf;
1461 vector<space_and_path>::iterator i;
1462 Glib::Mutex::Lock lm (space_lock);
1465 /* get freespace on every FS that is part of the session path */
1467 _total_free_4k_blocks = 0;
1469 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1470 statfs ((*i).path.c_str(), &statfsbuf);
1472 scale = statfsbuf.f_bsize/4096.0;
1474 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1475 _total_free_4k_blocks += (*i).blocks;
1481 Session::ensure_sound_dir (string path, string& result)
1486 /* Ensure that the parent directory exists */
1488 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1489 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1493 /* Ensure that the sounds directory exists */
1497 result += sound_dir_name;
1499 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1500 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1506 dead += dead_sound_dir_name;
1508 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1509 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1515 peak += peak_dir_name;
1517 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1518 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1522 /* callers expect this to be terminated ... */
1529 Session::discover_best_sound_dir (bool destructive)
1531 vector<space_and_path>::iterator i;
1534 /* handle common case without system calls */
1536 if (session_dirs.size() == 1) {
1540 /* OK, here's the algorithm we're following here:
1542 We want to select which directory to use for
1543 the next file source to be created. Ideally,
1544 we'd like to use a round-robin process so as to
1545 get maximum performance benefits from splitting
1546 the files across multiple disks.
1548 However, in situations without much diskspace, an
1549 RR approach may end up filling up a filesystem
1550 with new files while others still have space.
1551 Its therefore important to pay some attention to
1552 the freespace in the filesystem holding each
1553 directory as well. However, if we did that by
1554 itself, we'd keep creating new files in the file
1555 system with the most space until it was as full
1556 as all others, thus negating any performance
1557 benefits of this RAID-1 like approach.
1559 So, we use a user-configurable space threshold. If
1560 there are at least 2 filesystems with more than this
1561 much space available, we use RR selection between them.
1562 If not, then we pick the filesystem with the most space.
1564 This gets a good balance between the two
1568 refresh_disk_space ();
1570 int free_enough = 0;
1572 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1573 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1578 if (free_enough >= 2) {
1580 bool found_it = false;
1582 /* use RR selection process, ensuring that the one
1586 i = last_rr_session_dir;
1589 if (++i == session_dirs.end()) {
1590 i = session_dirs.begin();
1593 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1594 if (ensure_sound_dir ((*i).path, result) == 0) {
1595 last_rr_session_dir = i;
1601 } while (i != last_rr_session_dir);
1604 result = sound_dir();
1609 /* pick FS with the most freespace (and that
1610 seems to actually work ...)
1613 vector<space_and_path> sorted;
1614 space_and_path_ascending_cmp cmp;
1616 sorted = session_dirs;
1617 sort (sorted.begin(), sorted.end(), cmp);
1619 for (i = sorted.begin(); i != sorted.end(); ++i) {
1620 if (ensure_sound_dir ((*i).path, result) == 0) {
1621 last_rr_session_dir = i;
1626 /* if the above fails, fall back to the most simplistic solution */
1628 if (i == sorted.end()) {
1637 Session::load_playlists (const XMLNode& node)
1640 XMLNodeConstIterator niter;
1643 nlist = node.children();
1647 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1649 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1650 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1658 Session::load_unused_playlists (const XMLNode& node)
1661 XMLNodeConstIterator niter;
1664 nlist = node.children();
1668 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1670 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1671 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1675 // now manually untrack it
1677 track_playlist (playlist, false);
1685 Session::XMLPlaylistFactory (const XMLNode& node)
1688 return new AudioPlaylist (*this, node);
1691 catch (failed_constructor& err) {
1697 Session::load_named_selections (const XMLNode& node)
1700 XMLNodeConstIterator niter;
1703 nlist = node.children();
1707 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1709 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1710 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1718 Session::XMLNamedSelectionFactory (const XMLNode& node)
1721 return new NamedSelection (*this, node);
1724 catch (failed_constructor& err) {
1730 Session::dead_sound_dir () const
1733 res += dead_sound_dir_name;
1739 Session::sound_dir (bool with_path) const
1741 /* support old session structure */
1743 struct stat statbuf;
1745 string old_withpath;
1747 old_nopath += old_sound_dir_name;
1750 old_withpath = _path;
1751 old_withpath += old_sound_dir_name;
1752 old_withpath += '/';
1754 if (stat (old_withpath.c_str(), &statbuf) == 0) {
1756 return old_withpath;
1767 res += interchange_dir_name;
1769 res += legalize_for_path (_name);
1771 res += sound_dir_name;
1778 Session::peak_dir () const
1781 res += peak_dir_name;
1787 Session::automation_dir () const
1790 res += "automation/";
1795 Session::template_dir ()
1797 string path = get_user_ardour_path();
1798 path += "templates/";
1804 Session::suffixed_search_path (string suffix, bool data)
1808 path += get_user_ardour_path();
1809 if (path[path.length()-1] != ':') {
1814 path += get_system_data_path();
1816 path += get_system_module_path();
1819 vector<string> split_path;
1821 split (path, split_path, ':');
1824 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
1829 if (distance (i, split_path.end()) != 1) {
1838 Session::template_path ()
1840 return suffixed_search_path (X_("templates"), true);
1844 Session::control_protocol_path ()
1846 return suffixed_search_path (X_("surfaces"), false);
1850 Session::load_connections (const XMLNode& node)
1852 XMLNodeList nlist = node.children();
1853 XMLNodeConstIterator niter;
1857 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1858 if ((*niter)->name() == "InputConnection") {
1859 add_connection (new ARDOUR::InputConnection (**niter));
1860 } else if ((*niter)->name() == "OutputConnection") {
1861 add_connection (new ARDOUR::OutputConnection (**niter));
1863 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1872 Session::load_edit_groups (const XMLNode& node)
1874 return load_route_groups (node, true);
1878 Session::load_mix_groups (const XMLNode& node)
1880 return load_route_groups (node, false);
1884 Session::load_route_groups (const XMLNode& node, bool edit)
1886 XMLNodeList nlist = node.children();
1887 XMLNodeConstIterator niter;
1892 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1893 if ((*niter)->name() == "RouteGroup") {
1895 rg = add_edit_group ("");
1896 rg->set_state (**niter);
1898 rg = add_mix_group ("");
1899 rg->set_state (**niter);
1908 state_file_filter (const string &str, void *arg)
1910 return (str.length() > strlen(Session::statefile_suffix()) &&
1911 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
1915 bool operator()(const string* a, const string* b) {
1921 remove_end(string* state)
1923 string statename(*state);
1925 string::size_type start,end;
1926 if ((start = statename.find_last_of ('/')) != string::npos) {
1927 statename = statename.substr (start+1);
1930 if ((end = statename.rfind(".ardour")) == string::npos) {
1931 end = statename.length();
1934 return new string(statename.substr (0, end));
1938 Session::possible_states (string path)
1940 PathScanner scanner;
1941 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
1943 transform(states->begin(), states->end(), states->begin(), remove_end);
1946 sort (states->begin(), states->end(), cmp);
1952 Session::possible_states () const
1954 return possible_states(_path);
1958 Session::auto_save()
1960 save_state (_current_snapshot_name);
1964 Session::add_edit_group (string name)
1966 RouteGroup* rg = new RouteGroup (*this, name);
1967 edit_groups.push_back (rg);
1968 edit_group_added (rg); /* EMIT SIGNAL */
1974 Session::add_mix_group (string name)
1976 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
1977 mix_groups.push_back (rg);
1978 mix_group_added (rg); /* EMIT SIGNAL */
1984 Session::remove_edit_group (RouteGroup& rg)
1986 list<RouteGroup*>::iterator i;
1988 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
1989 (*i)->apply (&Route::drop_edit_group, this);
1990 edit_groups.erase (i);
1991 edit_group_removed (); /* EMIT SIGNAL */
1998 Session::remove_mix_group (RouteGroup& rg)
2000 list<RouteGroup*>::iterator i;
2002 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2003 (*i)->apply (&Route::drop_mix_group, this);
2004 mix_groups.erase (i);
2005 mix_group_removed (); /* EMIT SIGNAL */
2012 Session::mix_group_by_name (string name)
2014 list<RouteGroup *>::iterator i;
2016 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2017 if ((*i)->name() == name) {
2025 Session::edit_group_by_name (string name)
2027 list<RouteGroup *>::iterator i;
2029 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2030 if ((*i)->name() == name) {
2038 Session::begin_reversible_command (string name)
2040 current_trans = new UndoTransaction;
2041 current_trans->set_name (name);
2045 Session::commit_reversible_command (Command *cmd)
2050 current_trans->add_command (cmd);
2053 gettimeofday (&now, 0);
2054 current_trans->set_timestamp (now);
2056 history.add (current_trans);
2059 Session::GlobalRouteBooleanState
2060 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2062 GlobalRouteBooleanState s;
2063 boost::shared_ptr<RouteList> r = routes.reader ();
2065 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2066 if (!(*i)->hidden()) {
2067 RouteBooleanState v;
2070 Route* r = (*i).get();
2071 v.second = (r->*method)();
2080 Session::GlobalRouteMeterState
2081 Session::get_global_route_metering ()
2083 GlobalRouteMeterState s;
2084 boost::shared_ptr<RouteList> r = routes.reader ();
2086 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2087 if (!(*i)->hidden()) {
2091 v.second = (*i)->meter_point();
2101 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2103 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2104 i->first->set_meter_point (i->second, arg);
2109 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2111 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2112 Route* r = i->first.get();
2113 (r->*method) (i->second, arg);
2118 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2120 set_global_route_boolean (s, &Route::set_mute, src);
2124 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2126 set_global_route_boolean (s, &Route::set_solo, src);
2130 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2132 set_global_route_boolean (s, &Route::set_record_enable, src);
2137 Session::global_mute_memento (void* src)
2139 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2143 Session::global_metering_memento (void* src)
2145 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2149 Session::global_solo_memento (void* src)
2151 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2155 Session::global_record_enable_memento (void* src)
2157 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2162 template_filter (const string &str, void *arg)
2164 return (str.length() > strlen(Session::template_suffix()) &&
2165 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2169 Session::get_template_list (list<string> &template_names)
2171 vector<string *> *templates;
2172 PathScanner scanner;
2175 path = template_path ();
2177 templates = scanner (path, template_filter, 0, false, true);
2179 vector<string*>::iterator i;
2180 for (i = templates->begin(); i != templates->end(); ++i) {
2181 string fullpath = *(*i);
2184 start = fullpath.find_last_of ('/') + 1;
2185 if ((end = fullpath.find_last_of ('.')) <0) {
2186 end = fullpath.length();
2189 template_names.push_back(fullpath.substr(start, (end-start)));
2194 Session::read_favorite_dirs (FavoriteDirs & favs)
2196 string path = get_user_ardour_path();
2197 path += "/favorite_dirs";
2199 ifstream fav (path.c_str());
2204 if (errno != ENOENT) {
2205 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2216 getline(fav, newfav);
2222 favs.push_back (newfav);
2229 Session::write_favorite_dirs (FavoriteDirs & favs)
2231 string path = get_user_ardour_path();
2232 path += "/favorite_dirs";
2234 ofstream fav (path.c_str());
2240 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2241 fav << (*i) << endl;
2248 accept_all_non_peak_files (const string& path, void *arg)
2250 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2254 accept_all_state_files (const string& path, void *arg)
2256 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2260 Session::find_all_sources (string path, set<string>& result)
2265 if (!tree.read (path)) {
2269 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2274 XMLNodeConstIterator niter;
2276 nlist = node->children();
2280 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2284 if ((prop = (*niter)->property (X_("name"))) == 0) {
2288 if (prop->value()[0] == '/') {
2289 /* external file, ignore */
2293 string path = _path; /* /-terminated */
2294 path += sound_dir_name;
2296 path += prop->value();
2298 result.insert (path);
2305 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2307 PathScanner scanner;
2308 vector<string*>* state_files;
2310 string this_snapshot_path;
2316 if (ripped[ripped.length()-1] == '/') {
2317 ripped = ripped.substr (0, ripped.length() - 1);
2320 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2322 if (state_files == 0) {
2327 this_snapshot_path = _path;
2328 this_snapshot_path += _current_snapshot_name;
2329 this_snapshot_path += _statefile_suffix;
2331 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2333 if (exclude_this_snapshot && **i == this_snapshot_path) {
2337 if (find_all_sources (**i, result) < 0) {
2346 Session::cleanup_sources (Session::cleanup_report& rep)
2348 vector<boost::shared_ptr<Source> > dead_sources;
2349 vector<Playlist*> playlists_tbd;
2350 PathScanner scanner;
2352 vector<space_and_path>::iterator i;
2353 vector<space_and_path>::iterator nexti;
2354 vector<string*>* soundfiles;
2355 vector<string> unused;
2356 set<string> all_sources;
2361 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2363 /* step 1: consider deleting all unused playlists */
2365 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2368 status = AskAboutPlaylistDeletion (*x);
2377 playlists_tbd.push_back (*x);
2381 /* leave it alone */
2386 /* now delete any that were marked for deletion */
2388 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2389 PlaylistList::iterator foo;
2391 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2392 unused_playlists.erase (foo);
2397 /* step 2: clear the undo/redo history for all playlists */
2399 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2400 (*x)->drop_all_states ();
2403 /* step 3: find all un-referenced sources */
2408 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2410 AudioSourceList::iterator tmp;
2415 /* only remove files that are not in use and have some size
2416 to them. otherwise we remove the current "nascent"
2420 if (i->second.use_count() == 1 && i->second->length() > 0) {
2421 dead_sources.push_back (i->second);
2423 /* remove this source from our own list to avoid us
2424 adding it to the list of all sources below
2427 audio_sources.erase (i);
2433 /* Step 4: get rid of all regions in the region list that use any dead sources
2434 in case the sources themselves don't go away (they might be referenced in
2438 for (vector<boost::shared_ptr<Source> >::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2440 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2441 AudioRegionList::iterator tmp;
2442 boost::shared_ptr<AudioRegion> ar;
2449 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2450 if (ar->source (n) == (*i)) {
2451 /* this region is dead */
2460 /* build a list of all the possible sound directories for the session */
2462 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2467 sound_path += (*i).path;
2468 sound_path += sound_dir_name;
2470 if (nexti != session_dirs.end()) {
2477 /* now do the same thing for the files that ended up in the sounds dir(s)
2478 but are not referenced as sources in any snapshot.
2481 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2483 if (soundfiles == 0) {
2487 /* find all sources, but don't use this snapshot because the
2488 state file on disk still references sources we may have already
2492 find_all_sources_across_snapshots (all_sources, true);
2494 /* add our current source list
2497 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2498 boost::shared_ptr<AudioFileSource> fs;
2500 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2501 all_sources.insert (fs->path());
2505 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2510 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2520 unused.push_back (spath);
2524 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2526 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2527 struct stat statbuf;
2529 rep.paths.push_back (*x);
2530 if (stat ((*x).c_str(), &statbuf) == 0) {
2531 rep.space += statbuf.st_size;
2536 /* don't move the file across filesystems, just
2537 stick it in the `dead_sound_dir_name' directory
2538 on whichever filesystem it was already on.
2541 newpath = Glib::path_get_dirname (*x);
2542 newpath = Glib::path_get_dirname (newpath);
2545 newpath += dead_sound_dir_name;
2547 newpath += Glib::path_get_basename ((*x));
2549 if (access (newpath.c_str(), F_OK) == 0) {
2551 /* the new path already exists, try versioning */
2553 char buf[PATH_MAX+1];
2557 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2560 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2561 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2565 if (version == 999) {
2566 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2570 newpath = newpath_v;
2575 /* it doesn't exist, or we can't read it or something */
2579 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2580 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2581 (*x), newpath, strerror (errno))
2587 /* see if there an easy to find peakfile for this file, and remove it.
2590 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2591 peakpath += ".peak";
2593 if (access (peakpath.c_str(), W_OK) == 0) {
2594 if (::unlink (peakpath.c_str()) != 0) {
2595 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2596 peakpath, _path, strerror (errno))
2598 /* try to back out */
2599 rename (newpath.c_str(), _path.c_str());
2608 /* dump the history list */
2612 /* save state so we don't end up a session file
2613 referring to non-existent sources.
2619 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2624 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2626 vector<space_and_path>::iterator i;
2627 string dead_sound_dir;
2628 struct dirent* dentry;
2629 struct stat statbuf;
2635 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2637 dead_sound_dir = (*i).path;
2638 dead_sound_dir += dead_sound_dir_name;
2640 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2644 while ((dentry = readdir (dead)) != 0) {
2646 /* avoid '.' and '..' */
2648 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2649 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2655 fullpath = dead_sound_dir;
2657 fullpath += dentry->d_name;
2659 if (stat (fullpath.c_str(), &statbuf)) {
2663 if (!S_ISREG (statbuf.st_mode)) {
2667 if (unlink (fullpath.c_str())) {
2668 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2669 fullpath, strerror (errno))
2673 rep.paths.push_back (dentry->d_name);
2674 rep.space += statbuf.st_size;
2685 Session::set_dirty ()
2687 bool was_dirty = dirty();
2689 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2692 DirtyChanged(); /* EMIT SIGNAL */
2698 Session::set_clean ()
2700 bool was_dirty = dirty();
2702 _state_of_the_state = Clean;
2705 DirtyChanged(); /* EMIT SIGNAL */
2710 Session::add_controllable (Controllable* c)
2712 Glib::Mutex::Lock lm (controllables_lock);
2713 controllables.push_back (c);
2717 Session::remove_controllable (Controllable* c)
2719 if (_state_of_the_state | Deletion) {
2723 Glib::Mutex::Lock lm (controllables_lock);
2724 controllables.remove (c);
2728 Session::controllable_by_id (const PBD::ID& id)
2730 Glib::Mutex::Lock lm (controllables_lock);
2732 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2733 if ((*i)->id() == id) {
2742 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2744 Stateful::add_instant_xml (node, dir);
2745 Config->add_instant_xml (node, get_user_ardour_path());
2750 Session::save_history (string snapshot_name)
2756 tree.set_root (&history.get_state());
2758 if (snapshot_name.empty()) {
2759 snapshot_name = _current_snapshot_name;
2762 xml_path = _path + snapshot_name + ".history";
2764 bak_path = xml_path + ".bak";
2766 if ((access (xml_path.c_str(), F_OK) == 0) &&
2767 (rename (xml_path.c_str(), bak_path.c_str())))
2769 error << _("could not backup old history file, current history not saved.") << endmsg;
2773 cerr << "actually writing history\n";
2775 if (!tree.write (xml_path))
2777 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2779 /* don't leave a corrupt file lying around if it is
2783 if (unlink (xml_path.c_str()))
2785 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2787 if (rename (bak_path.c_str(), xml_path.c_str()))
2789 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2800 Session::restore_history (string snapshot_name)
2806 xmlpath = _path + snapshot_name + ".history";
2807 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2809 if (access (xmlpath.c_str(), F_OK)) {
2810 error << string_compose(_("%1: session history file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
2814 if (!tree.read (xmlpath)) {
2815 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
2819 /* replace history */
2821 for (XMLNodeConstIterator it = tree.root()->children().begin();
2822 it != tree.root()->children().end();
2826 UndoTransaction* ut = new UndoTransaction ();
2829 ut->set_name(t->property("name")->value());
2830 stringstream ss(t->property("tv_sec")->value());
2832 ss.str(t->property("tv_usec")->value());
2834 ut->set_timestamp(tv);
2836 for (XMLNodeConstIterator child_it = t->children().begin();
2837 child_it != t->children().end();
2840 XMLNode *n = *child_it;
2842 if (n->name() == "MementoCommand" ||
2843 n->name() == "MementoUndoCommand" ||
2844 n->name() == "MementoRedoCommand")
2846 c = memento_command_factory(n);
2852 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2862 Session::config_changed (const char* parameter_name)
2864 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2866 if (PARAM_IS ("seamless-loop")) {
2868 } else if (PARAM_IS ("rf-speed")) {
2870 } else if (PARAM_IS ("auto-loop")) {
2872 } else if (PARAM_IS ("auto-input")) {
2874 if (Config->get_use_hardware_monitoring() && transport_rolling()) {
2875 /* auto-input only makes a difference if we're rolling */
2877 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2879 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2880 if ((*i)->record_enabled ()) {
2881 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
2882 (*i)->monitor_input (!Config->get_auto_input());
2887 } else if (PARAM_IS ("punch-in")) {
2891 if ((location = _locations.auto_punch_location()) != 0) {
2893 if (Config->get_punch_in ()) {
2894 replace_event (Event::PunchIn, location->start());
2896 remove_event (location->start(), Event::PunchIn);
2900 } else if (PARAM_IS ("punch-out")) {
2904 if ((location = _locations.auto_punch_location()) != 0) {
2906 if (Config->get_punch_out()) {
2907 replace_event (Event::PunchOut, location->end());
2909 clear_events (Event::PunchOut);
2913 } else if (PARAM_IS ("edit-mode")) {
2915 Glib::Mutex::Lock lm (playlist_lock);
2917 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2918 (*i)->set_edit_mode (Config->get_edit_mode ());
2921 } else if (PARAM_IS ("use-video-sync")) {
2923 if (transport_stopped()) {
2924 if (Config->get_use_video_sync()) {
2925 waiting_for_sync_offset = true;
2929 } else if (PARAM_IS ("mmc-control")) {
2931 poke_midi_thread ();
2933 } else if (PARAM_IS ("midi-control")) {
2935 poke_midi_thread ();
2937 } else if (PARAM_IS ("raid-path")) {
2939 setup_raid_path (Config->get_raid_path());
2941 } else if (PARAM_IS ("smpte-frames-per-second") || PARAM_IS ("smpte-drop-frames")) {
2945 } else if (PARAM_IS ("video-pullup")) {
2949 } else if (PARAM_IS ("seamless-loop")) {
2951 if (play_loop && transport_rolling()) {
2952 // to reset diskstreams etc
2953 request_play_loop (true);
2956 } else if (PARAM_IS ("rf-speed")) {
2958 cumulative_rf_motion = 0;
2961 } else if (PARAM_IS ("click-sound")) {
2963 setup_click_sounds (1);
2965 } else if (PARAM_IS ("click-emphasis-sound")) {
2967 setup_click_sounds (-1);
2969 } else if (PARAM_IS ("clicking")) {
2971 if (Config->get_clicking()) {
2972 if (_click_io && click_data) { // don't require emphasis data
2979 } else if (PARAM_IS ("send-mtc")) {
2981 /* only set the internal flag if we have
2985 if (_mtc_port != 0) {
2986 session_send_mtc = Config->get_send_mtc();
2989 } else if (PARAM_IS ("send-mmc")) {
2991 /* only set the internal flag if we have
2995 if (_mmc_port != 0) {
2996 session_send_mmc = Config->get_send_mmc();
2999 } else if (PARAM_IS ("midi-feedback")) {
3001 /* only set the internal flag if we have
3005 if (_mtc_port != 0) {
3006 session_midi_feedback = Config->get_midi_feedback();