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>
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>
87 #include <control_protocol/control_protocol.h>
93 using namespace ARDOUR;
97 Session::first_stage_init (string fullpath, string snapshot_name)
99 if (fullpath.length() == 0) {
100 throw failed_constructor();
103 char buf[PATH_MAX+1];
104 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
105 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
106 throw failed_constructor();
111 if (_path[_path.length()-1] != '/') {
115 /* these two are just provisional settings. set_state()
116 will likely override them.
119 _name = _current_snapshot_name = snapshot_name;
121 _current_frame_rate = _engine.frame_rate ();
122 _tempo_map = new TempoMap (_current_frame_rate);
123 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
125 g_atomic_int_set (&processing_prohibited, 0);
127 _transport_speed = 0;
128 _last_transport_speed = 0;
129 transport_sub_state = 0;
130 _transport_frame = 0;
132 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
133 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
134 _end_location_is_free = true;
135 g_atomic_int_set (&_record_status, Disabled);
136 loop_changing = false;
138 _last_roll_location = 0;
139 _last_record_location = 0;
140 pending_locate_frame = 0;
141 pending_locate_roll = false;
142 pending_locate_flush = false;
143 dstream_buffer_size = 0;
145 state_was_pending = false;
147 outbound_mtc_smpte_frame = 0;
148 next_quarter_frame_to_send = -1;
149 current_block_size = 0;
150 solo_update_disabled = false;
151 currently_soloing = false;
152 _have_captured = false;
153 _worst_output_latency = 0;
154 _worst_input_latency = 0;
155 _worst_track_latency = 0;
156 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
158 butler_mixdown_buffer = 0;
159 butler_gain_buffer = 0;
161 session_send_mmc = false;
162 session_send_mtc = 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;
179 first_file_data_format_reset = true;
180 first_file_header_format_reset = true;
182 AudioDiskstream::allocate_working_buffers();
184 /* default short fade = 15ms */
186 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
187 SndFileSource::setup_standard_crossfades (frame_rate());
189 last_mmc_step.tv_sec = 0;
190 last_mmc_step.tv_usec = 0;
193 /* click sounds are unset by default, which causes us to internal
194 waveforms for clicks.
198 click_emphasis_data = 0;
200 click_emphasis_length = 0;
203 process_function = &Session::process_with_events;
205 if (Config->get_use_video_sync()) {
206 waiting_for_sync_offset = true;
208 waiting_for_sync_offset = false;
211 _current_frame_rate = 48000;
212 _base_frame_rate = 48000;
216 _smpte_offset_negative = true;
217 last_smpte_valid = false;
221 last_rr_session_dir = session_dirs.begin();
222 refresh_disk_space ();
224 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
228 average_slave_delta = 1800;
229 have_first_delta_accumulator = false;
230 delta_accumulator_cnt = 0;
231 slave_state = Stopped;
233 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
235 /* These are all static "per-class" signals */
237 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
238 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
239 Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
240 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
241 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
242 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
244 Controllable::Destroyed.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, 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)) {
529 Session::load_diskstreams (const XMLNode& node)
532 XMLNodeConstIterator citer;
534 clist = node.children();
536 for (citer = clist.begin(); citer != clist.end(); ++citer) {
540 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
541 add_diskstream (dstream);
544 catch (failed_constructor& err) {
545 error << _("Session: could not load diskstream via XML state") << endmsg;
554 Session::remove_pending_capture_state ()
559 xml_path += _current_snapshot_name;
560 xml_path += _pending_suffix;
562 unlink (xml_path.c_str());
566 Session::save_state (string snapshot_name, bool pending)
572 if (_state_of_the_state & CannotSave) {
576 tree.set_root (&get_state());
578 if (snapshot_name.empty()) {
579 snapshot_name = _current_snapshot_name;
585 xml_path += snapshot_name;
586 xml_path += _statefile_suffix;
590 // Make backup of state file
592 if ((access (xml_path.c_str(), F_OK) == 0) &&
593 (rename(xml_path.c_str(), bak_path.c_str()))) {
594 error << _("could not backup old state file, current state not saved.") << endmsg;
601 xml_path += snapshot_name;
602 xml_path += _pending_suffix;
606 cerr << "actually writing state\n";
608 if (!tree.write (xml_path)) {
609 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
611 /* don't leave a corrupt file lying around if it is
615 if (unlink (xml_path.c_str())) {
616 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
619 if (rename (bak_path.c_str(), xml_path.c_str())) {
620 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
629 save_history(snapshot_name);
631 bool was_dirty = dirty();
633 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
636 DirtyChanged (); /* EMIT SIGNAL */
639 StateSaved (snapshot_name); /* EMIT SIGNAL */
646 Session::restore_state (string snapshot_name)
648 if (load_state (snapshot_name) == 0) {
649 set_state (*state_tree->root());
656 Session::load_state (string snapshot_name)
665 state_was_pending = false;
667 /* check for leftover pending state from a crashed capture attempt */
670 xmlpath += snapshot_name;
671 xmlpath += _pending_suffix;
673 if (!access (xmlpath.c_str(), F_OK)) {
675 /* there is pending state from a crashed capture attempt */
677 if (AskAboutPendingState()) {
678 state_was_pending = true;
682 if (!state_was_pending) {
685 xmlpath += snapshot_name;
686 xmlpath += _statefile_suffix;
689 if (access (xmlpath.c_str(), F_OK)) {
690 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
694 state_tree = new XMLTree;
698 if (state_tree->read (xmlpath)) {
701 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
710 Session::load_options (const XMLNode& node)
714 LocaleGuard lg (X_("POSIX"));
716 Config->set_variables (node, ConfigVariableBase::Session);
718 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
719 if ((prop = child->property ("val")) != 0) {
720 _end_location_is_free = (prop->value() == "yes");
728 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
730 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
731 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
733 return owner & modified_by_session_or_user;
737 Session::get_options () const
740 LocaleGuard lg (X_("POSIX"));
742 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
744 child = option_root.add_child ("end-marker-is-free");
745 child->add_property ("val", _end_location_is_free ? "yes" : "no");
757 Session::get_template()
759 /* if we don't disable rec-enable, diskstreams
760 will believe they need to store their capture
761 sources in their state node.
764 disable_record (false);
770 Session::state(bool full_state)
772 XMLNode* node = new XMLNode("Session");
775 // store libardour version, just in case
777 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
778 libardour_major_version, libardour_minor_version, libardour_micro_version);
779 node->add_property("version", string(buf));
781 /* store configuration settings */
786 node->add_property ("name", _name);
788 if (session_dirs.size() > 1) {
792 vector<space_and_path>::iterator i = session_dirs.begin();
793 vector<space_and_path>::iterator next;
795 ++i; /* skip the first one */
799 while (i != session_dirs.end()) {
803 if (next != session_dirs.end()) {
813 child = node->add_child ("Path");
814 child->add_content (p);
818 /* save the ID counter */
820 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
821 node->add_property ("id-counter", buf);
823 /* various options */
825 node->add_child_nocopy (get_options());
827 child = node->add_child ("Sources");
830 Glib::Mutex::Lock sl (audio_source_lock);
832 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
834 /* Don't save information about AudioFileSources that are empty */
836 boost::shared_ptr<AudioFileSource> fs;
838 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
840 /* destructive file sources are OK if they are empty, because
841 we will re-use them every time.
844 if (!fs->destructive()) {
845 if (fs->length() == 0) {
851 child->add_child_nocopy (siter->second->get_state());
855 child = node->add_child ("Regions");
858 Glib::Mutex::Lock rl (region_lock);
860 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
862 /* only store regions not attached to playlists */
864 if (i->second->playlist() == 0) {
865 child->add_child_nocopy (i->second->state (true));
870 child = node->add_child ("DiskStreams");
873 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
874 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
875 if (!(*i)->hidden()) {
876 child->add_child_nocopy ((*i)->get_state());
882 node->add_child_nocopy (_locations.get_state());
884 // for a template, just create a new Locations, populate it
885 // with the default start and end, and get the state for that.
887 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
888 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
891 end->set_end(compute_initial_length());
893 node->add_child_nocopy (loc.get_state());
896 child = node->add_child ("Connections");
898 Glib::Mutex::Lock lm (connection_lock);
899 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
900 if (!(*i)->system_dependent()) {
901 child->add_child_nocopy ((*i)->get_state());
906 child = node->add_child ("Routes");
908 boost::shared_ptr<RouteList> r = routes.reader ();
910 RoutePublicOrderSorter cmp;
911 RouteList public_order (*r);
912 public_order.sort (cmp);
914 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
915 if (!(*i)->hidden()) {
917 child->add_child_nocopy ((*i)->get_state());
919 child->add_child_nocopy ((*i)->get_template());
926 child = node->add_child ("EditGroups");
927 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
928 child->add_child_nocopy ((*i)->get_state());
931 child = node->add_child ("MixGroups");
932 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
933 child->add_child_nocopy ((*i)->get_state());
936 child = node->add_child ("Playlists");
937 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
938 if (!(*i)->hidden()) {
939 if (!(*i)->empty()) {
941 child->add_child_nocopy ((*i)->get_state());
943 child->add_child_nocopy ((*i)->get_template());
949 child = node->add_child ("UnusedPlaylists");
950 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
951 if (!(*i)->hidden()) {
952 if (!(*i)->empty()) {
954 child->add_child_nocopy ((*i)->get_state());
956 child->add_child_nocopy ((*i)->get_template());
964 child = node->add_child ("Click");
965 child->add_child_nocopy (_click_io->state (full_state));
969 child = node->add_child ("NamedSelections");
970 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
972 child->add_child_nocopy ((*i)->get_state());
977 node->add_child_nocopy (_tempo_map->get_state());
979 node->add_child_nocopy (get_control_protocol_state());
982 node->add_child_copy (*_extra_xml);
989 Session::get_control_protocol_state ()
991 ControlProtocolManager& cpm (ControlProtocolManager::instance());
992 XMLNode* node = new XMLNode (X_("ControlProtocols"));
994 cpm.foreach_known_protocol (bind (mem_fun (*this, &Session::add_control_protocol), node));
1000 Session::add_control_protocol (const ControlProtocolInfo* const cpi, XMLNode* node)
1002 if (cpi->protocol) {
1003 node->add_child_nocopy (cpi->protocol->get_state());
1008 Session::set_state (const XMLNode& node)
1012 const XMLProperty* prop;
1015 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1017 if (node.name() != X_("Session")){
1018 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1022 if ((prop = node.property ("name")) != 0) {
1023 _name = prop->value ();
1026 setup_raid_path(_path);
1028 if ((prop = node.property (X_("id-counter"))) != 0) {
1030 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1031 ID::init_counter (x);
1033 /* old sessions used a timebased counter, so fake
1034 the startup ID counter based on a standard
1039 ID::init_counter (now);
1043 IO::disable_ports ();
1044 IO::disable_connecting ();
1046 /* Object loading order:
1064 if (use_config_midi_ports ()) {
1067 if ((child = find_named_node (node, "extra")) != 0) {
1068 _extra_xml = new XMLNode (*child);
1071 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1072 load_options (*child);
1073 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1074 load_options (*child);
1076 error << _("Session: XML state has no options section") << endmsg;
1079 if ((child = find_named_node (node, "Locations")) == 0) {
1080 error << _("Session: XML state has no locations section") << endmsg;
1082 } else if (_locations.set_state (*child)) {
1088 if ((location = _locations.auto_loop_location()) != 0) {
1089 set_auto_loop_location (location);
1092 if ((location = _locations.auto_punch_location()) != 0) {
1093 set_auto_punch_location (location);
1096 if ((location = _locations.end_location()) == 0) {
1097 _locations.add (end_location);
1099 delete end_location;
1100 end_location = location;
1103 if ((location = _locations.start_location()) == 0) {
1104 _locations.add (start_location);
1106 delete start_location;
1107 start_location = location;
1110 AudioFileSource::set_header_position_offset (start_location->start());
1112 if ((child = find_named_node (node, "Sources")) == 0) {
1113 error << _("Session: XML state has no sources section") << endmsg;
1115 } else if (load_sources (*child)) {
1119 if ((child = find_named_node (node, "Regions")) == 0) {
1120 error << _("Session: XML state has no Regions section") << endmsg;
1122 } else if (load_regions (*child)) {
1126 if ((child = find_named_node (node, "Playlists")) == 0) {
1127 error << _("Session: XML state has no playlists section") << endmsg;
1129 } else if (load_playlists (*child)) {
1133 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1135 } else if (load_unused_playlists (*child)) {
1139 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1140 if (load_named_selections (*child)) {
1145 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1146 error << _("Session: XML state has no diskstreams section") << endmsg;
1148 } else if (load_diskstreams (*child)) {
1152 if ((child = find_named_node (node, "Connections")) == 0) {
1153 error << _("Session: XML state has no connections section") << endmsg;
1155 } else if (load_connections (*child)) {
1159 if ((child = find_named_node (node, "EditGroups")) == 0) {
1160 error << _("Session: XML state has no edit groups section") << endmsg;
1162 } else if (load_edit_groups (*child)) {
1166 if ((child = find_named_node (node, "MixGroups")) == 0) {
1167 error << _("Session: XML state has no mix groups section") << endmsg;
1169 } else if (load_mix_groups (*child)) {
1173 if ((child = find_named_node (node, "TempoMap")) == 0) {
1174 error << _("Session: XML state has no Tempo Map section") << endmsg;
1176 } else if (_tempo_map->set_state (*child)) {
1180 if ((child = find_named_node (node, "Routes")) == 0) {
1181 error << _("Session: XML state has no routes section") << endmsg;
1183 } else if (load_routes (*child)) {
1187 if ((child = find_named_node (node, "Click")) == 0) {
1188 warning << _("Session: XML state has no click section") << endmsg;
1189 } else if (_click_io) {
1190 _click_io->set_state (*child);
1193 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1194 ControlProtocolManager::instance().set_protocol_states (*child);
1197 /* here beginneth the second phase ... */
1199 StateReady (); /* EMIT SIGNAL */
1201 _state_of_the_state = Clean;
1203 if (state_was_pending) {
1204 save_state (_current_snapshot_name);
1205 remove_pending_capture_state ();
1206 state_was_pending = false;
1216 Session::load_routes (const XMLNode& node)
1219 XMLNodeConstIterator niter;
1220 RouteList new_routes;
1222 nlist = node.children();
1226 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1228 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1231 error << _("Session: cannot create Route from XML description.") << endmsg;
1235 new_routes.push_back (route);
1238 add_routes (new_routes);
1243 boost::shared_ptr<Route>
1244 Session::XMLRouteFactory (const XMLNode& node)
1246 if (node.name() != "Route") {
1247 return boost::shared_ptr<Route> ((Route*) 0);
1250 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1251 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1254 boost::shared_ptr<Route> x (new Route (*this, node));
1260 Session::load_regions (const XMLNode& node)
1263 XMLNodeConstIterator niter;
1264 boost::shared_ptr<AudioRegion> region;
1266 nlist = node.children();
1270 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1271 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1272 error << _("Session: cannot create Region from XML description.") << endmsg;
1279 boost::shared_ptr<AudioRegion>
1280 Session::XMLRegionFactory (const XMLNode& node, bool full)
1282 const XMLProperty* prop;
1283 boost::shared_ptr<Source> source;
1284 boost::shared_ptr<AudioSource> as;
1286 uint32_t nchans = 1;
1289 if (node.name() != X_("Region")) {
1290 return boost::shared_ptr<AudioRegion>();
1293 if ((prop = node.property (X_("channels"))) != 0) {
1294 nchans = atoi (prop->value().c_str());
1298 if ((prop = node.property ("name")) == 0) {
1299 cerr << "no name for this region\n";
1303 if ((prop = node.property (X_("source-0"))) == 0) {
1304 if ((prop = node.property ("source")) == 0) {
1305 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1306 return boost::shared_ptr<AudioRegion>();
1310 PBD::ID s_id (prop->value());
1312 if ((source = source_by_id (s_id)) == 0) {
1313 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1314 return boost::shared_ptr<AudioRegion>();
1317 as = boost::dynamic_pointer_cast<AudioSource>(source);
1319 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1320 return boost::shared_ptr<AudioRegion>();
1323 sources.push_back (as);
1325 /* pickup other channels */
1327 for (uint32_t n=1; n < nchans; ++n) {
1328 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1329 if ((prop = node.property (buf)) != 0) {
1331 PBD::ID id2 (prop->value());
1333 if ((source = source_by_id (id2)) == 0) {
1334 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1335 return boost::shared_ptr<AudioRegion>();
1338 as = boost::dynamic_pointer_cast<AudioSource>(source);
1340 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1341 return boost::shared_ptr<AudioRegion>();
1343 sources.push_back (as);
1348 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1353 catch (failed_constructor& err) {
1354 return boost::shared_ptr<AudioRegion>();
1359 Session::get_sources_as_xml ()
1362 XMLNode* node = new XMLNode (X_("Sources"));
1363 Glib::Mutex::Lock lm (audio_source_lock);
1365 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1366 node->add_child_nocopy (i->second->get_state());
1369 /* XXX get MIDI and other sources here */
1375 Session::path_from_region_name (string name, string identifier)
1377 char buf[PATH_MAX+1];
1379 string dir = discover_best_sound_dir ();
1381 for (n = 0; n < 999999; ++n) {
1382 if (identifier.length()) {
1383 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1384 identifier.c_str(), n);
1386 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1388 if (access (buf, F_OK) != 0) {
1398 Session::load_sources (const XMLNode& node)
1401 XMLNodeConstIterator niter;
1402 boost::shared_ptr<Source> source;
1404 nlist = node.children();
1408 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1410 if ((source = XMLSourceFactory (**niter)) == 0) {
1411 error << _("Session: cannot create Source from XML description.") << endmsg;
1418 boost::shared_ptr<Source>
1419 Session::XMLSourceFactory (const XMLNode& node)
1421 if (node.name() != "Source") {
1422 return boost::shared_ptr<Source>();
1426 return SourceFactory::create (*this, node);
1429 catch (failed_constructor& err) {
1430 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1431 return boost::shared_ptr<Source>();
1436 Session::save_template (string template_name)
1439 string xml_path, bak_path, template_path;
1441 if (_state_of_the_state & CannotSave) {
1446 string dir = template_dir();
1448 if ((dp = opendir (dir.c_str()))) {
1451 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1452 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1457 tree.set_root (&get_template());
1460 xml_path += template_name;
1461 xml_path += _template_suffix;
1463 ifstream in(xml_path.c_str());
1466 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1472 if (!tree.write (xml_path)) {
1473 error << _("mix template not saved") << endmsg;
1481 Session::rename_template (string old_name, string new_name)
1483 string old_path = template_dir() + old_name + _template_suffix;
1484 string new_path = template_dir() + new_name + _template_suffix;
1486 return rename (old_path.c_str(), new_path.c_str());
1490 Session::delete_template (string name)
1492 string template_path = template_dir();
1493 template_path += name;
1494 template_path += _template_suffix;
1496 return remove (template_path.c_str());
1500 Session::refresh_disk_space ()
1503 struct statfs statfsbuf;
1504 vector<space_and_path>::iterator i;
1505 Glib::Mutex::Lock lm (space_lock);
1508 /* get freespace on every FS that is part of the session path */
1510 _total_free_4k_blocks = 0;
1512 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1513 statfs ((*i).path.c_str(), &statfsbuf);
1515 scale = statfsbuf.f_bsize/4096.0;
1517 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1518 _total_free_4k_blocks += (*i).blocks;
1524 Session::ensure_sound_dir (string path, string& result)
1529 /* Ensure that the parent directory exists */
1531 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1532 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1536 /* Ensure that the sounds directory exists */
1540 result += sound_dir_name;
1542 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1543 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1549 dead += dead_sound_dir_name;
1551 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1552 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1558 peak += peak_dir_name;
1560 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1561 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1565 /* callers expect this to be terminated ... */
1572 Session::discover_best_sound_dir (bool destructive)
1574 vector<space_and_path>::iterator i;
1577 /* handle common case without system calls */
1579 if (session_dirs.size() == 1) {
1583 /* OK, here's the algorithm we're following here:
1585 We want to select which directory to use for
1586 the next file source to be created. Ideally,
1587 we'd like to use a round-robin process so as to
1588 get maximum performance benefits from splitting
1589 the files across multiple disks.
1591 However, in situations without much diskspace, an
1592 RR approach may end up filling up a filesystem
1593 with new files while others still have space.
1594 Its therefore important to pay some attention to
1595 the freespace in the filesystem holding each
1596 directory as well. However, if we did that by
1597 itself, we'd keep creating new files in the file
1598 system with the most space until it was as full
1599 as all others, thus negating any performance
1600 benefits of this RAID-1 like approach.
1602 So, we use a user-configurable space threshold. If
1603 there are at least 2 filesystems with more than this
1604 much space available, we use RR selection between them.
1605 If not, then we pick the filesystem with the most space.
1607 This gets a good balance between the two
1611 refresh_disk_space ();
1613 int free_enough = 0;
1615 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1616 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1621 if (free_enough >= 2) {
1623 bool found_it = false;
1625 /* use RR selection process, ensuring that the one
1629 i = last_rr_session_dir;
1632 if (++i == session_dirs.end()) {
1633 i = session_dirs.begin();
1636 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1637 if (ensure_sound_dir ((*i).path, result) == 0) {
1638 last_rr_session_dir = i;
1644 } while (i != last_rr_session_dir);
1647 result = sound_dir();
1652 /* pick FS with the most freespace (and that
1653 seems to actually work ...)
1656 vector<space_and_path> sorted;
1657 space_and_path_ascending_cmp cmp;
1659 sorted = session_dirs;
1660 sort (sorted.begin(), sorted.end(), cmp);
1662 for (i = sorted.begin(); i != sorted.end(); ++i) {
1663 if (ensure_sound_dir ((*i).path, result) == 0) {
1664 last_rr_session_dir = i;
1669 /* if the above fails, fall back to the most simplistic solution */
1671 if (i == sorted.end()) {
1680 Session::load_playlists (const XMLNode& node)
1683 XMLNodeConstIterator niter;
1686 nlist = node.children();
1690 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1692 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1693 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1701 Session::load_unused_playlists (const XMLNode& node)
1704 XMLNodeConstIterator niter;
1707 nlist = node.children();
1711 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1713 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1714 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1718 // now manually untrack it
1720 track_playlist (playlist, false);
1728 Session::XMLPlaylistFactory (const XMLNode& node)
1731 return new AudioPlaylist (*this, node);
1734 catch (failed_constructor& err) {
1740 Session::load_named_selections (const XMLNode& node)
1743 XMLNodeConstIterator niter;
1746 nlist = node.children();
1750 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1752 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1753 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1761 Session::XMLNamedSelectionFactory (const XMLNode& node)
1764 return new NamedSelection (*this, node);
1767 catch (failed_constructor& err) {
1773 Session::dead_sound_dir () const
1776 res += dead_sound_dir_name;
1782 Session::sound_dir (bool with_path) const
1784 /* support old session structure */
1786 struct stat statbuf;
1788 string old_withpath;
1790 old_nopath += old_sound_dir_name;
1793 old_withpath = _path;
1794 old_withpath += old_sound_dir_name;
1795 old_withpath += '/';
1797 if (stat (old_withpath.c_str(), &statbuf) == 0) {
1799 return old_withpath;
1810 res += interchange_dir_name;
1812 res += legalize_for_path (_name);
1814 res += sound_dir_name;
1821 Session::peak_dir () const
1824 res += peak_dir_name;
1830 Session::automation_dir () const
1833 res += "automation/";
1838 Session::template_dir ()
1840 string path = get_user_ardour_path();
1841 path += "templates/";
1847 Session::suffixed_search_path (string suffix, bool data)
1851 path += get_user_ardour_path();
1852 if (path[path.length()-1] != ':') {
1857 path += get_system_data_path();
1859 path += get_system_module_path();
1862 vector<string> split_path;
1864 split (path, split_path, ':');
1867 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
1872 if (distance (i, split_path.end()) != 1) {
1881 Session::template_path ()
1883 return suffixed_search_path (X_("templates"), true);
1887 Session::control_protocol_path ()
1889 return suffixed_search_path (X_("surfaces"), false);
1893 Session::load_connections (const XMLNode& node)
1895 XMLNodeList nlist = node.children();
1896 XMLNodeConstIterator niter;
1900 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1901 if ((*niter)->name() == "InputConnection") {
1902 add_connection (new ARDOUR::InputConnection (**niter));
1903 } else if ((*niter)->name() == "OutputConnection") {
1904 add_connection (new ARDOUR::OutputConnection (**niter));
1906 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1915 Session::load_edit_groups (const XMLNode& node)
1917 return load_route_groups (node, true);
1921 Session::load_mix_groups (const XMLNode& node)
1923 return load_route_groups (node, false);
1927 Session::load_route_groups (const XMLNode& node, bool edit)
1929 XMLNodeList nlist = node.children();
1930 XMLNodeConstIterator niter;
1935 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1936 if ((*niter)->name() == "RouteGroup") {
1938 rg = add_edit_group ("");
1939 rg->set_state (**niter);
1941 rg = add_mix_group ("");
1942 rg->set_state (**niter);
1951 state_file_filter (const string &str, void *arg)
1953 return (str.length() > strlen(Session::statefile_suffix()) &&
1954 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
1958 bool operator()(const string* a, const string* b) {
1964 remove_end(string* state)
1966 string statename(*state);
1968 string::size_type start,end;
1969 if ((start = statename.find_last_of ('/')) != string::npos) {
1970 statename = statename.substr (start+1);
1973 if ((end = statename.rfind(".ardour")) == string::npos) {
1974 end = statename.length();
1977 return new string(statename.substr (0, end));
1981 Session::possible_states (string path)
1983 PathScanner scanner;
1984 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
1986 transform(states->begin(), states->end(), states->begin(), remove_end);
1989 sort (states->begin(), states->end(), cmp);
1995 Session::possible_states () const
1997 return possible_states(_path);
2001 Session::auto_save()
2003 save_state (_current_snapshot_name);
2007 Session::add_edit_group (string name)
2009 RouteGroup* rg = new RouteGroup (*this, name);
2010 edit_groups.push_back (rg);
2011 edit_group_added (rg); /* EMIT SIGNAL */
2017 Session::add_mix_group (string name)
2019 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2020 mix_groups.push_back (rg);
2021 mix_group_added (rg); /* EMIT SIGNAL */
2027 Session::remove_edit_group (RouteGroup& rg)
2029 list<RouteGroup*>::iterator i;
2031 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2032 (*i)->apply (&Route::drop_edit_group, this);
2033 edit_groups.erase (i);
2034 edit_group_removed (); /* EMIT SIGNAL */
2041 Session::remove_mix_group (RouteGroup& rg)
2043 list<RouteGroup*>::iterator i;
2045 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2046 (*i)->apply (&Route::drop_mix_group, this);
2047 mix_groups.erase (i);
2048 mix_group_removed (); /* EMIT SIGNAL */
2055 Session::mix_group_by_name (string name)
2057 list<RouteGroup *>::iterator i;
2059 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2060 if ((*i)->name() == name) {
2068 Session::edit_group_by_name (string name)
2070 list<RouteGroup *>::iterator i;
2072 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2073 if ((*i)->name() == name) {
2081 Session::begin_reversible_command (string name)
2083 current_trans = new UndoTransaction;
2084 current_trans->set_name (name);
2088 Session::commit_reversible_command (Command *cmd)
2093 current_trans->add_command (cmd);
2096 gettimeofday (&now, 0);
2097 current_trans->set_timestamp (now);
2099 _history.add (current_trans);
2102 Session::GlobalRouteBooleanState
2103 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2105 GlobalRouteBooleanState s;
2106 boost::shared_ptr<RouteList> r = routes.reader ();
2108 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2109 if (!(*i)->hidden()) {
2110 RouteBooleanState v;
2113 Route* r = (*i).get();
2114 v.second = (r->*method)();
2123 Session::GlobalRouteMeterState
2124 Session::get_global_route_metering ()
2126 GlobalRouteMeterState s;
2127 boost::shared_ptr<RouteList> r = routes.reader ();
2129 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2130 if (!(*i)->hidden()) {
2134 v.second = (*i)->meter_point();
2144 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2146 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2147 i->first->set_meter_point (i->second, arg);
2152 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2154 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2155 Route* r = i->first.get();
2156 (r->*method) (i->second, arg);
2161 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2163 set_global_route_boolean (s, &Route::set_mute, src);
2167 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2169 set_global_route_boolean (s, &Route::set_solo, src);
2173 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2175 set_global_route_boolean (s, &Route::set_record_enable, src);
2180 Session::global_mute_memento (void* src)
2182 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2186 Session::global_metering_memento (void* src)
2188 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2192 Session::global_solo_memento (void* src)
2194 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2198 Session::global_record_enable_memento (void* src)
2200 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2205 template_filter (const string &str, void *arg)
2207 return (str.length() > strlen(Session::template_suffix()) &&
2208 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2212 Session::get_template_list (list<string> &template_names)
2214 vector<string *> *templates;
2215 PathScanner scanner;
2218 path = template_path ();
2220 templates = scanner (path, template_filter, 0, false, true);
2222 vector<string*>::iterator i;
2223 for (i = templates->begin(); i != templates->end(); ++i) {
2224 string fullpath = *(*i);
2227 start = fullpath.find_last_of ('/') + 1;
2228 if ((end = fullpath.find_last_of ('.')) <0) {
2229 end = fullpath.length();
2232 template_names.push_back(fullpath.substr(start, (end-start)));
2237 Session::read_favorite_dirs (FavoriteDirs & favs)
2239 string path = get_user_ardour_path();
2240 path += "/favorite_dirs";
2242 ifstream fav (path.c_str());
2247 if (errno != ENOENT) {
2248 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2259 getline(fav, newfav);
2265 favs.push_back (newfav);
2272 Session::write_favorite_dirs (FavoriteDirs & favs)
2274 string path = get_user_ardour_path();
2275 path += "/favorite_dirs";
2277 ofstream fav (path.c_str());
2283 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2284 fav << (*i) << endl;
2291 accept_all_non_peak_files (const string& path, void *arg)
2293 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2297 accept_all_state_files (const string& path, void *arg)
2299 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2303 Session::find_all_sources (string path, set<string>& result)
2308 if (!tree.read (path)) {
2312 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2317 XMLNodeConstIterator niter;
2319 nlist = node->children();
2323 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2327 if ((prop = (*niter)->property (X_("name"))) == 0) {
2331 if (prop->value()[0] == '/') {
2332 /* external file, ignore */
2336 string path = _path; /* /-terminated */
2337 path += sound_dir_name;
2339 path += prop->value();
2341 result.insert (path);
2348 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2350 PathScanner scanner;
2351 vector<string*>* state_files;
2353 string this_snapshot_path;
2359 if (ripped[ripped.length()-1] == '/') {
2360 ripped = ripped.substr (0, ripped.length() - 1);
2363 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2365 if (state_files == 0) {
2370 this_snapshot_path = _path;
2371 this_snapshot_path += _current_snapshot_name;
2372 this_snapshot_path += _statefile_suffix;
2374 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2376 if (exclude_this_snapshot && **i == this_snapshot_path) {
2380 if (find_all_sources (**i, result) < 0) {
2389 Session::cleanup_sources (Session::cleanup_report& rep)
2391 vector<boost::shared_ptr<Source> > dead_sources;
2392 vector<Playlist*> playlists_tbd;
2393 PathScanner scanner;
2395 vector<space_and_path>::iterator i;
2396 vector<space_and_path>::iterator nexti;
2397 vector<string*>* soundfiles;
2398 vector<string> unused;
2399 set<string> all_sources;
2404 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2406 /* step 1: consider deleting all unused playlists */
2408 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2411 status = AskAboutPlaylistDeletion (*x);
2420 playlists_tbd.push_back (*x);
2424 /* leave it alone */
2429 /* now delete any that were marked for deletion */
2431 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2432 PlaylistList::iterator foo;
2434 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2435 unused_playlists.erase (foo);
2440 /* step 2: find all un-referenced sources */
2445 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2447 AudioSourceList::iterator tmp;
2452 /* only remove files that are not in use and have some size
2453 to them. otherwise we remove the current "nascent"
2457 cerr << "checking out source " << i->second->name() << " use_count = " << i->second.use_count() << endl;
2459 if (i->second.use_count() == 1 && i->second->length() > 0) {
2460 dead_sources.push_back (i->second);
2462 /* remove this source from our own list to avoid us
2463 adding it to the list of all sources below
2466 audio_sources.erase (i);
2472 /* Step 3: get rid of all regions in the region list that use any dead sources
2473 in case the sources themselves don't go away (they might be referenced in
2477 for (vector<boost::shared_ptr<Source> >::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2479 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2480 AudioRegionList::iterator tmp;
2481 boost::shared_ptr<AudioRegion> ar;
2488 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2489 if (ar->source (n) == (*i)) {
2490 /* this region is dead */
2499 /* build a list of all the possible sound directories for the session */
2501 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2506 sound_path += (*i).path;
2507 sound_path += sound_dir_name;
2509 if (nexti != session_dirs.end()) {
2516 /* now do the same thing for the files that ended up in the sounds dir(s)
2517 but are not referenced as sources in any snapshot.
2520 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2522 if (soundfiles == 0) {
2526 /* find all sources, but don't use this snapshot because the
2527 state file on disk still references sources we may have already
2531 find_all_sources_across_snapshots (all_sources, true);
2533 /* add our current source list
2536 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2537 boost::shared_ptr<AudioFileSource> fs;
2539 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2540 all_sources.insert (fs->path());
2544 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2549 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2559 unused.push_back (spath);
2563 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2565 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2566 struct stat statbuf;
2568 rep.paths.push_back (*x);
2569 if (stat ((*x).c_str(), &statbuf) == 0) {
2570 rep.space += statbuf.st_size;
2575 /* don't move the file across filesystems, just
2576 stick it in the `dead_sound_dir_name' directory
2577 on whichever filesystem it was already on.
2580 newpath = Glib::path_get_dirname (*x);
2581 newpath = Glib::path_get_dirname (newpath);
2584 newpath += dead_sound_dir_name;
2586 newpath += Glib::path_get_basename ((*x));
2588 if (access (newpath.c_str(), F_OK) == 0) {
2590 /* the new path already exists, try versioning */
2592 char buf[PATH_MAX+1];
2596 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2599 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2600 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2604 if (version == 999) {
2605 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2609 newpath = newpath_v;
2614 /* it doesn't exist, or we can't read it or something */
2618 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2619 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2620 (*x), newpath, strerror (errno))
2626 /* see if there an easy to find peakfile for this file, and remove it.
2629 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2630 peakpath += ".peak";
2632 if (access (peakpath.c_str(), W_OK) == 0) {
2633 if (::unlink (peakpath.c_str()) != 0) {
2634 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2635 peakpath, _path, strerror (errno))
2637 /* try to back out */
2638 rename (newpath.c_str(), _path.c_str());
2647 /* dump the history list */
2651 /* save state so we don't end up a session file
2652 referring to non-existent sources.
2658 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2663 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2665 vector<space_and_path>::iterator i;
2666 string dead_sound_dir;
2667 struct dirent* dentry;
2668 struct stat statbuf;
2674 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2676 dead_sound_dir = (*i).path;
2677 dead_sound_dir += dead_sound_dir_name;
2679 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2683 while ((dentry = readdir (dead)) != 0) {
2685 /* avoid '.' and '..' */
2687 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2688 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2694 fullpath = dead_sound_dir;
2696 fullpath += dentry->d_name;
2698 if (stat (fullpath.c_str(), &statbuf)) {
2702 if (!S_ISREG (statbuf.st_mode)) {
2706 if (unlink (fullpath.c_str())) {
2707 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2708 fullpath, strerror (errno))
2712 rep.paths.push_back (dentry->d_name);
2713 rep.space += statbuf.st_size;
2724 Session::set_dirty ()
2726 bool was_dirty = dirty();
2728 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2731 DirtyChanged(); /* EMIT SIGNAL */
2737 Session::set_clean ()
2739 bool was_dirty = dirty();
2741 _state_of_the_state = Clean;
2744 DirtyChanged(); /* EMIT SIGNAL */
2749 Session::add_controllable (Controllable* c)
2751 Glib::Mutex::Lock lm (controllables_lock);
2752 controllables.insert (c);
2756 Session::remove_controllable (Controllable* c)
2758 if (_state_of_the_state | Deletion) {
2762 Glib::Mutex::Lock lm (controllables_lock);
2764 Controllables::iterator x = controllables.find (c);
2766 if (x != controllables.end()) {
2767 controllables.erase (x);
2772 Session::controllable_by_id (const PBD::ID& id)
2774 Glib::Mutex::Lock lm (controllables_lock);
2776 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2777 if ((*i)->id() == id) {
2786 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2788 Stateful::add_instant_xml (node, dir);
2789 Config->add_instant_xml (node, get_user_ardour_path());
2794 Session::save_history (string snapshot_name)
2800 tree.set_root (&_history.get_state());
2802 if (snapshot_name.empty()) {
2803 snapshot_name = _current_snapshot_name;
2806 xml_path = _path + snapshot_name + ".history";
2808 bak_path = xml_path + ".bak";
2810 if ((access (xml_path.c_str(), F_OK) == 0) &&
2811 (rename (xml_path.c_str(), bak_path.c_str())))
2813 error << _("could not backup old history file, current history not saved.") << endmsg;
2817 cerr << "actually writing history\n";
2819 if (!tree.write (xml_path))
2821 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2823 /* don't leave a corrupt file lying around if it is
2827 if (unlink (xml_path.c_str())) {
2828 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2830 if (rename (bak_path.c_str(), xml_path.c_str()))
2832 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2843 Session::restore_history (string snapshot_name)
2849 xmlpath = _path + snapshot_name + ".history";
2850 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2852 if (access (xmlpath.c_str(), F_OK)) {
2853 error << string_compose(_("%1: session history file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
2857 if (!tree.read (xmlpath)) {
2858 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
2862 /* replace history */
2865 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2868 UndoTransaction* ut = new UndoTransaction ();
2871 ut->set_name(t->property("name")->value());
2872 stringstream ss(t->property("tv_sec")->value());
2874 ss.str(t->property("tv_usec")->value());
2876 ut->set_timestamp(tv);
2878 for (XMLNodeConstIterator child_it = t->children().begin();
2879 child_it != t->children().end();
2882 XMLNode *n = *child_it;
2885 if (n->name() == "MementoCommand" ||
2886 n->name() == "MementoUndoCommand" ||
2887 n->name() == "MementoRedoCommand") {
2888 if ((c = memento_command_factory(n))) {
2892 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2903 Session::config_changed (const char* parameter_name)
2905 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2907 if (PARAM_IS ("seamless-loop")) {
2909 } else if (PARAM_IS ("rf-speed")) {
2911 } else if (PARAM_IS ("auto-loop")) {
2913 } else if (PARAM_IS ("auto-input")) {
2915 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2916 /* auto-input only makes a difference if we're rolling */
2918 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2920 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2921 if ((*i)->record_enabled ()) {
2922 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
2923 (*i)->monitor_input (!Config->get_auto_input());
2928 } else if (PARAM_IS ("punch-in")) {
2932 if ((location = _locations.auto_punch_location()) != 0) {
2934 if (Config->get_punch_in ()) {
2935 replace_event (Event::PunchIn, location->start());
2937 remove_event (location->start(), Event::PunchIn);
2941 } else if (PARAM_IS ("punch-out")) {
2945 if ((location = _locations.auto_punch_location()) != 0) {
2947 if (Config->get_punch_out()) {
2948 replace_event (Event::PunchOut, location->end());
2950 clear_events (Event::PunchOut);
2954 } else if (PARAM_IS ("edit-mode")) {
2956 Glib::Mutex::Lock lm (playlist_lock);
2958 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2959 (*i)->set_edit_mode (Config->get_edit_mode ());
2962 } else if (PARAM_IS ("use-video-sync")) {
2964 if (transport_stopped()) {
2965 if (Config->get_use_video_sync()) {
2966 waiting_for_sync_offset = true;
2970 } else if (PARAM_IS ("mmc-control")) {
2972 poke_midi_thread ();
2974 } else if (PARAM_IS ("midi-control")) {
2976 poke_midi_thread ();
2978 } else if (PARAM_IS ("raid-path")) {
2980 setup_raid_path (Config->get_raid_path());
2982 } else if (PARAM_IS ("smpte-frames-per-second") || PARAM_IS ("smpte-drop-frames")) {
2986 } else if (PARAM_IS ("video-pullup")) {
2990 } else if (PARAM_IS ("seamless-loop")) {
2992 if (play_loop && transport_rolling()) {
2993 // to reset diskstreams etc
2994 request_play_loop (true);
2997 } else if (PARAM_IS ("rf-speed")) {
2999 cumulative_rf_motion = 0;
3002 } else if (PARAM_IS ("click-sound")) {
3004 setup_click_sounds (1);
3006 } else if (PARAM_IS ("click-emphasis-sound")) {
3008 setup_click_sounds (-1);
3010 } else if (PARAM_IS ("clicking")) {
3012 if (Config->get_clicking()) {
3013 if (_click_io && click_data) { // don't require emphasis data
3020 } else if (PARAM_IS ("send-mtc")) {
3022 /* only set the internal flag if we have
3026 if (_mtc_port != 0) {
3027 session_send_mtc = Config->get_send_mtc();
3028 if (session_send_mtc) {
3029 /* mark us ready to send */
3030 next_quarter_frame_to_send = 0;
3034 } else if (PARAM_IS ("send-mmc")) {
3036 /* only set the internal flag if we have
3040 if (_mmc_port != 0) {
3041 session_send_mmc = Config->get_send_mmc();
3044 } else if (PARAM_IS ("midi-feedback")) {
3046 /* only set the internal flag if we have
3050 if (_mtc_port != 0) {
3051 session_midi_feedback = Config->get_midi_feedback();
3054 } else if (PARAM_IS ("jack-time-master")) {
3056 engine().reset_timebase ();
3058 } else if (PARAM_IS ("native-file-header-format")) {
3060 if (!first_file_header_format_reset) {
3061 reset_native_file_format ();
3064 first_file_header_format_reset = false;
3066 } else if (PARAM_IS ("native-file-data-format")) {
3068 if (!first_file_data_format_reset) {
3069 reset_native_file_format ();
3072 first_file_data_format_reset = false;