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>
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);
128 _transport_speed = 0;
129 _last_transport_speed = 0;
130 transport_sub_state = 0;
131 _transport_frame = 0;
133 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
134 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
135 _end_location_is_free = true;
136 g_atomic_int_set (&_record_status, Disabled);
137 loop_changing = false;
139 _last_roll_location = 0;
140 _last_record_location = 0;
141 pending_locate_frame = 0;
142 pending_locate_roll = false;
143 pending_locate_flush = false;
144 dstream_buffer_size = 0;
146 state_was_pending = false;
148 outbound_mtc_smpte_frame = 0;
149 next_quarter_frame_to_send = -1;
150 current_block_size = 0;
151 solo_update_disabled = false;
152 currently_soloing = false;
153 _have_captured = false;
154 _worst_output_latency = 0;
155 _worst_input_latency = 0;
156 _worst_track_latency = 0;
157 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
159 butler_mixdown_buffer = 0;
160 butler_gain_buffer = 0;
162 session_send_mmc = false;
163 session_send_mtc = false;
164 session_midi_feedback = false;
165 post_transport_work = PostTransportWork (0);
166 g_atomic_int_set (&butler_should_do_transport_work, 0);
167 g_atomic_int_set (&butler_active, 0);
168 g_atomic_int_set (&_playback_load, 100);
169 g_atomic_int_set (&_capture_load, 100);
170 g_atomic_int_set (&_playback_load_min, 100);
171 g_atomic_int_set (&_capture_load_min, 100);
173 waiting_to_start = false;
175 _gain_automation_buffer = 0;
176 _pan_automation_buffer = 0;
178 pending_abort = false;
179 destructive_index = 0;
181 first_file_data_format_reset = true;
182 first_file_header_format_reset = true;
184 AudioDiskstream::allocate_working_buffers();
186 /* default short fade = 15ms */
188 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
189 DestructiveFileSource::setup_standard_crossfades (frame_rate());
191 last_mmc_step.tv_sec = 0;
192 last_mmc_step.tv_usec = 0;
195 /* click sounds are unset by default, which causes us to internal
196 waveforms for clicks.
200 click_emphasis_data = 0;
202 click_emphasis_length = 0;
205 process_function = &Session::process_with_events;
207 if (Config->get_use_video_sync()) {
208 waiting_for_sync_offset = true;
210 waiting_for_sync_offset = false;
213 _current_frame_rate = 48000;
214 _base_frame_rate = 48000;
218 _smpte_offset_negative = true;
219 last_smpte_valid = false;
223 last_rr_session_dir = session_dirs.begin();
224 refresh_disk_space ();
226 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
230 average_slave_delta = 1800;
231 have_first_delta_accumulator = false;
232 delta_accumulator_cnt = 0;
233 slave_state = Stopped;
235 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
237 /* These are all static "per-class" signals */
239 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
240 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
241 Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
242 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
243 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
244 Curve::CurveCreated.connect (mem_fun (*this, &Session::add_curve));
245 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
247 Controllable::GoingAway.connect (mem_fun (*this, &Session::remove_controllable));
249 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
251 /* stop IO objects from doing stuff until we're ready for them */
253 IO::disable_panners ();
254 IO::disable_ports ();
255 IO::disable_connecting ();
259 Session::second_stage_init (bool new_session)
261 AudioFileSource::set_peak_dir (peak_dir());
264 if (load_state (_current_snapshot_name)) {
267 remove_empty_sounds ();
270 if (start_butler_thread()) {
274 if (start_midi_thread ()) {
278 // set_state() will call setup_raid_path(), but if it's a new session we need
279 // to call setup_raid_path() here.
281 if (set_state (*state_tree->root())) {
285 setup_raid_path(_path);
288 /* we can't save till after ::when_engine_running() is called,
289 because otherwise we save state with no connections made.
290 therefore, we reset _state_of_the_state because ::set_state()
291 will have cleared it.
293 we also have to include Loading so that any events that get
294 generated between here and the end of ::when_engine_running()
295 will be processed directly rather than queued.
298 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
300 // set_auto_input (true);
301 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
302 _locations.added.connect (mem_fun (this, &Session::locations_added));
303 setup_click_sounds (0);
304 setup_midi_control ();
306 /* Pay attention ... */
308 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
309 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
311 if (_engine.running()) {
312 when_engine_running();
314 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
317 send_full_time_code ();
318 _engine.transport_locate (0);
319 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
320 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
322 ControlProtocolManager::instance().set_session (*this);
325 _end_location_is_free = true;
327 _end_location_is_free = false;
334 Session::raid_path () const
338 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
343 return path.substr (0, path.length() - 1); // drop final colon
347 Session::setup_raid_path (string path)
349 string::size_type colon;
353 string::size_type len = path.length();
358 if (path.length() == 0) {
362 session_dirs.clear ();
364 for (string::size_type n = 0; n < len; ++n) {
365 if (path[n] == ':') {
372 /* no multiple search path, just one location (common case) */
376 session_dirs.push_back (sp);
383 if (fspath[fspath.length()-1] != '/') {
386 fspath += sound_dir (false);
388 AudioFileSource::set_search_path (fspath);
395 while ((colon = remaining.find_first_of (':')) != string::npos) {
398 sp.path = remaining.substr (0, colon);
399 session_dirs.push_back (sp);
401 /* add sounds to file search path */
404 if (fspath[fspath.length()-1] != '/') {
407 fspath += sound_dir (false);
410 remaining = remaining.substr (colon+1);
413 if (remaining.length()) {
420 if (fspath[fspath.length()-1] != '/') {
423 fspath += sound_dir (false);
426 session_dirs.push_back (sp);
429 /* set the AudioFileSource search path */
431 AudioFileSource::set_search_path (fspath);
433 /* reset the round-robin soundfile path thingie */
435 last_rr_session_dir = session_dirs.begin();
439 Session::create (bool& new_session, string* mix_template, nframes_t initial_length)
443 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
444 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
450 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
451 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
457 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
458 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
462 dir = dead_sound_dir ();
464 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
465 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
469 dir = automation_dir ();
471 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
472 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
477 /* check new_session so we don't overwrite an existing one */
480 std::string in_path = *mix_template;
482 ifstream in(in_path.c_str());
485 string out_path = _path;
487 out_path += _statefile_suffix;
489 ofstream out(out_path.c_str());
494 // okay, session is set up. Treat like normal saved
495 // session from now on.
501 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
507 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
514 /* set initial start + end point */
516 start_location->set_end (0);
517 _locations.add (start_location);
519 end_location->set_end (initial_length);
520 _locations.add (end_location);
522 _state_of_the_state = Clean;
524 if (save_state (_current_snapshot_name)) {
525 save_history (_current_snapshot_name);
533 Session::load_diskstreams (const XMLNode& node)
536 XMLNodeConstIterator citer;
538 clist = node.children();
540 for (citer = clist.begin(); citer != clist.end(); ++citer) {
544 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
545 add_diskstream (dstream);
548 catch (failed_constructor& err) {
549 error << _("Session: could not load diskstream via XML state") << endmsg;
558 Session::remove_pending_capture_state ()
563 xml_path += _current_snapshot_name;
564 xml_path += _pending_suffix;
566 unlink (xml_path.c_str());
570 Session::save_state (string snapshot_name, bool pending)
576 if (_state_of_the_state & CannotSave) {
580 tree.set_root (&get_state());
582 if (snapshot_name.empty()) {
583 snapshot_name = _current_snapshot_name;
589 xml_path += snapshot_name;
590 xml_path += _statefile_suffix;
594 // Make backup of state file
596 if ((access (xml_path.c_str(), F_OK) == 0) &&
597 (rename(xml_path.c_str(), bak_path.c_str()))) {
598 error << _("could not backup old state file, current state not saved.") << endmsg;
605 xml_path += snapshot_name;
606 xml_path += _pending_suffix;
610 cerr << "actually writing state\n";
612 if (!tree.write (xml_path)) {
613 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
615 /* don't leave a corrupt file lying around if it is
619 if (unlink (xml_path.c_str())) {
620 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
623 if (rename (bak_path.c_str(), xml_path.c_str())) {
624 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
633 save_history(snapshot_name);
635 bool was_dirty = dirty();
637 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
640 DirtyChanged (); /* EMIT SIGNAL */
643 StateSaved (snapshot_name); /* EMIT SIGNAL */
650 Session::restore_state (string snapshot_name)
652 if (load_state (snapshot_name) == 0) {
653 set_state (*state_tree->root());
660 Session::load_state (string snapshot_name)
669 state_was_pending = false;
671 /* check for leftover pending state from a crashed capture attempt */
674 xmlpath += snapshot_name;
675 xmlpath += _pending_suffix;
677 if (!access (xmlpath.c_str(), F_OK)) {
679 /* there is pending state from a crashed capture attempt */
681 if (AskAboutPendingState()) {
682 state_was_pending = true;
686 if (!state_was_pending) {
689 xmlpath += snapshot_name;
690 xmlpath += _statefile_suffix;
693 if (access (xmlpath.c_str(), F_OK)) {
694 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
698 state_tree = new XMLTree;
702 if (state_tree->read (xmlpath)) {
705 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
714 Session::load_options (const XMLNode& node)
718 LocaleGuard lg (X_("POSIX"));
720 Config->set_variables (node, ConfigVariableBase::Session);
722 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
723 if ((prop = child->property ("val")) != 0) {
724 _end_location_is_free = (prop->value() == "yes");
732 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
734 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
735 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
737 return owner & modified_by_session_or_user;
741 Session::get_options () const
744 LocaleGuard lg (X_("POSIX"));
746 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
748 child = option_root.add_child ("end-marker-is-free");
749 child->add_property ("val", _end_location_is_free ? "yes" : "no");
761 Session::get_template()
763 /* if we don't disable rec-enable, diskstreams
764 will believe they need to store their capture
765 sources in their state node.
768 disable_record (false);
774 Session::state(bool full_state)
776 XMLNode* node = new XMLNode("Session");
779 // store libardour version, just in case
781 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
782 libardour_major_version, libardour_minor_version, libardour_micro_version);
783 node->add_property("version", string(buf));
785 /* store configuration settings */
790 node->add_property ("name", _name);
792 if (session_dirs.size() > 1) {
796 vector<space_and_path>::iterator i = session_dirs.begin();
797 vector<space_and_path>::iterator next;
799 ++i; /* skip the first one */
803 while (i != session_dirs.end()) {
807 if (next != session_dirs.end()) {
817 child = node->add_child ("Path");
818 child->add_content (p);
822 /* save the ID counter */
824 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
825 node->add_property ("id-counter", buf);
827 /* various options */
829 node->add_child_nocopy (get_options());
831 child = node->add_child ("Sources");
834 Glib::Mutex::Lock sl (audio_source_lock);
836 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
838 /* Don't save information about AudioFileSources that are empty */
840 boost::shared_ptr<AudioFileSource> fs;
842 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
843 boost::shared_ptr<DestructiveFileSource> dfs = boost::dynamic_pointer_cast<DestructiveFileSource> (fs);
845 /* destructive file sources are OK if they are empty, because
846 we will re-use them every time.
850 if (fs->length() == 0) {
856 child->add_child_nocopy (siter->second->get_state());
860 child = node->add_child ("Regions");
863 Glib::Mutex::Lock rl (region_lock);
865 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
867 /* only store regions not attached to playlists */
869 if (i->second->playlist() == 0) {
870 child->add_child_nocopy (i->second->state (true));
875 child = node->add_child ("DiskStreams");
878 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
879 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
880 if (!(*i)->hidden()) {
881 child->add_child_nocopy ((*i)->get_state());
886 node->add_child_nocopy (_locations.get_state());
888 child = node->add_child ("Connections");
890 Glib::Mutex::Lock lm (connection_lock);
891 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
892 if (!(*i)->system_dependent()) {
893 child->add_child_nocopy ((*i)->get_state());
898 child = node->add_child ("Routes");
900 boost::shared_ptr<RouteList> r = routes.reader ();
902 RoutePublicOrderSorter cmp;
903 RouteList public_order (*r);
904 public_order.sort (cmp);
906 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
907 if (!(*i)->hidden()) {
909 child->add_child_nocopy ((*i)->get_state());
911 child->add_child_nocopy ((*i)->get_template());
918 child = node->add_child ("EditGroups");
919 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
920 child->add_child_nocopy ((*i)->get_state());
923 child = node->add_child ("MixGroups");
924 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
925 child->add_child_nocopy ((*i)->get_state());
928 child = node->add_child ("Playlists");
929 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
930 if (!(*i)->hidden()) {
931 if (!(*i)->empty()) {
933 child->add_child_nocopy ((*i)->get_state());
935 child->add_child_nocopy ((*i)->get_template());
941 child = node->add_child ("UnusedPlaylists");
942 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
943 if (!(*i)->hidden()) {
944 if (!(*i)->empty()) {
946 child->add_child_nocopy ((*i)->get_state());
948 child->add_child_nocopy ((*i)->get_template());
956 child = node->add_child ("Click");
957 child->add_child_nocopy (_click_io->state (full_state));
961 child = node->add_child ("NamedSelections");
962 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
964 child->add_child_nocopy ((*i)->get_state());
969 node->add_child_nocopy (_tempo_map->get_state());
971 node->add_child_nocopy (get_control_protocol_state());
974 node->add_child_copy (*_extra_xml);
981 Session::get_control_protocol_state ()
983 ControlProtocolManager& cpm (ControlProtocolManager::instance());
984 XMLNode* node = new XMLNode (X_("ControlProtocols"));
986 cpm.foreach_known_protocol (bind (mem_fun (*this, &Session::add_control_protocol), node));
992 Session::add_control_protocol (const ControlProtocolInfo* const cpi, XMLNode* node)
995 node->add_child_nocopy (cpi->protocol->get_state());
1000 Session::set_state (const XMLNode& node)
1004 const XMLProperty* prop;
1007 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1009 if (node.name() != X_("Session")){
1010 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1014 StateManager::prohibit_save ();
1016 if ((prop = node.property ("name")) != 0) {
1017 _name = prop->value ();
1020 setup_raid_path(_path);
1022 if ((prop = node.property (X_("id-counter"))) != 0) {
1024 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1025 ID::init_counter (x);
1027 /* old sessions used a timebased counter, so fake
1028 the startup ID counter based on a standard
1033 ID::init_counter (now);
1037 IO::disable_ports ();
1038 IO::disable_connecting ();
1040 /* Object loading order:
1058 if (use_config_midi_ports ()) {
1061 if ((child = find_named_node (node, "extra")) != 0) {
1062 _extra_xml = new XMLNode (*child);
1065 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1066 load_options (*child);
1067 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1068 load_options (*child);
1070 error << _("Session: XML state has no options section") << endmsg;
1073 if ((child = find_named_node (node, "Sources")) == 0) {
1074 error << _("Session: XML state has no sources section") << endmsg;
1076 } else if (load_sources (*child)) {
1080 if ((child = find_named_node (node, "Regions")) == 0) {
1081 error << _("Session: XML state has no Regions section") << endmsg;
1083 } else if (load_regions (*child)) {
1087 if ((child = find_named_node (node, "Playlists")) == 0) {
1088 error << _("Session: XML state has no playlists section") << endmsg;
1090 } else if (load_playlists (*child)) {
1094 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1096 } else if (load_unused_playlists (*child)) {
1100 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1101 if (load_named_selections (*child)) {
1106 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1107 error << _("Session: XML state has no diskstreams section") << endmsg;
1109 } else if (load_diskstreams (*child)) {
1113 if ((child = find_named_node (node, "Connections")) == 0) {
1114 error << _("Session: XML state has no connections section") << endmsg;
1116 } else if (load_connections (*child)) {
1120 if ((child = find_named_node (node, "Locations")) == 0) {
1121 error << _("Session: XML state has no locations section") << endmsg;
1123 } else if (_locations.set_state (*child)) {
1129 if ((location = _locations.auto_loop_location()) != 0) {
1130 set_auto_loop_location (location);
1133 if ((location = _locations.auto_punch_location()) != 0) {
1134 set_auto_punch_location (location);
1137 if ((location = _locations.end_location()) == 0) {
1138 _locations.add (end_location);
1140 delete end_location;
1141 end_location = location;
1144 if ((location = _locations.start_location()) == 0) {
1145 _locations.add (start_location);
1147 delete start_location;
1148 start_location = location;
1151 _locations.save_state (_("initial state"));
1153 if ((child = find_named_node (node, "EditGroups")) == 0) {
1154 error << _("Session: XML state has no edit groups section") << endmsg;
1156 } else if (load_edit_groups (*child)) {
1160 if ((child = find_named_node (node, "MixGroups")) == 0) {
1161 error << _("Session: XML state has no mix groups section") << endmsg;
1163 } else if (load_mix_groups (*child)) {
1167 if ((child = find_named_node (node, "TempoMap")) == 0) {
1168 error << _("Session: XML state has no Tempo Map section") << endmsg;
1170 } else if (_tempo_map->set_state (*child)) {
1174 if ((child = find_named_node (node, "Routes")) == 0) {
1175 error << _("Session: XML state has no routes section") << endmsg;
1177 } else if (load_routes (*child)) {
1181 if ((child = find_named_node (node, "Click")) == 0) {
1182 warning << _("Session: XML state has no click section") << endmsg;
1183 } else if (_click_io) {
1184 _click_io->set_state (*child);
1187 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1188 ControlProtocolManager::instance().set_protocol_states (*child);
1191 /* here beginneth the second phase ... */
1193 StateReady (); /* EMIT SIGNAL */
1195 _state_of_the_state = Clean;
1197 StateManager::allow_save (_("initial state"), true);
1199 if (state_was_pending) {
1200 save_state (_current_snapshot_name);
1201 remove_pending_capture_state ();
1202 state_was_pending = false;
1208 /* we failed, re-enable state saving but don't actually save internal state */
1209 StateManager::allow_save (X_("ignored"), false);
1214 Session::load_routes (const XMLNode& node)
1217 XMLNodeConstIterator niter;
1218 RouteList new_routes;
1220 nlist = node.children();
1224 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1226 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1229 error << _("Session: cannot create Route from XML description.") << endmsg;
1233 new_routes.push_back (route);
1236 add_routes (new_routes);
1241 boost::shared_ptr<Route>
1242 Session::XMLRouteFactory (const XMLNode& node)
1244 if (node.name() != "Route") {
1245 return boost::shared_ptr<Route> ((Route*) 0);
1248 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1249 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1252 boost::shared_ptr<Route> x (new Route (*this, node));
1258 Session::load_regions (const XMLNode& node)
1261 XMLNodeConstIterator niter;
1262 boost::shared_ptr<AudioRegion> region;
1264 nlist = node.children();
1268 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1269 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1270 error << _("Session: cannot create Region from XML description.") << endmsg;
1277 boost::shared_ptr<AudioRegion>
1278 Session::XMLRegionFactory (const XMLNode& node, bool full)
1280 const XMLProperty* prop;
1281 boost::shared_ptr<Source> source;
1282 boost::shared_ptr<AudioSource> as;
1284 uint32_t nchans = 1;
1287 if (node.name() != X_("Region")) {
1288 return boost::shared_ptr<AudioRegion>();
1291 if ((prop = node.property (X_("channels"))) != 0) {
1292 nchans = atoi (prop->value().c_str());
1296 if ((prop = node.property (X_("source-0"))) == 0) {
1297 if ((prop = node.property ("source")) == 0) {
1298 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1299 return boost::shared_ptr<AudioRegion>();
1303 PBD::ID s_id (prop->value());
1305 if ((source = source_by_id (s_id)) == 0) {
1306 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1307 return boost::shared_ptr<AudioRegion>();
1310 as = boost::dynamic_pointer_cast<AudioSource>(source);
1312 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1313 return boost::shared_ptr<AudioRegion>();
1316 sources.push_back (as);
1318 /* pickup other channels */
1320 for (uint32_t n=1; n < nchans; ++n) {
1321 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1322 if ((prop = node.property (buf)) != 0) {
1324 PBD::ID id2 (prop->value());
1326 if ((source = source_by_id (id2)) == 0) {
1327 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1328 return boost::shared_ptr<AudioRegion>();
1331 as = boost::dynamic_pointer_cast<AudioSource>(source);
1333 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1334 return boost::shared_ptr<AudioRegion>();
1336 sources.push_back (as);
1341 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1346 catch (failed_constructor& err) {
1347 return boost::shared_ptr<AudioRegion>();
1352 Session::get_sources_as_xml ()
1355 XMLNode* node = new XMLNode (X_("Sources"));
1356 Glib::Mutex::Lock lm (audio_source_lock);
1358 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1359 node->add_child_nocopy (i->second->get_state());
1362 /* XXX get MIDI and other sources here */
1368 Session::path_from_region_name (string name, string identifier)
1370 char buf[PATH_MAX+1];
1372 string dir = discover_best_sound_dir ();
1374 for (n = 0; n < 999999; ++n) {
1375 if (identifier.length()) {
1376 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1377 identifier.c_str(), n);
1379 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1381 if (access (buf, F_OK) != 0) {
1391 Session::load_sources (const XMLNode& node)
1394 XMLNodeConstIterator niter;
1395 boost::shared_ptr<Source> source;
1397 nlist = node.children();
1401 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1403 if ((source = XMLSourceFactory (**niter)) == 0) {
1404 error << _("Session: cannot create Source from XML description.") << endmsg;
1411 boost::shared_ptr<Source>
1412 Session::XMLSourceFactory (const XMLNode& node)
1414 if (node.name() != "Source") {
1415 return boost::shared_ptr<Source>();
1419 return SourceFactory::create (*this, node);
1422 catch (failed_constructor& err) {
1423 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1424 return boost::shared_ptr<Source>();
1429 Session::save_template (string template_name)
1432 string xml_path, bak_path, template_path;
1434 if (_state_of_the_state & CannotSave) {
1439 string dir = template_dir();
1441 if ((dp = opendir (dir.c_str()))) {
1444 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1445 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1450 tree.set_root (&get_template());
1453 xml_path += template_name;
1454 xml_path += _template_suffix;
1456 ifstream in(xml_path.c_str());
1459 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1465 if (!tree.write (xml_path)) {
1466 error << _("mix template not saved") << endmsg;
1474 Session::rename_template (string old_name, string new_name)
1476 string old_path = template_dir() + old_name + _template_suffix;
1477 string new_path = template_dir() + new_name + _template_suffix;
1479 return rename (old_path.c_str(), new_path.c_str());
1483 Session::delete_template (string name)
1485 string template_path = template_dir();
1486 template_path += name;
1487 template_path += _template_suffix;
1489 return remove (template_path.c_str());
1493 Session::refresh_disk_space ()
1496 struct statfs statfsbuf;
1497 vector<space_and_path>::iterator i;
1498 Glib::Mutex::Lock lm (space_lock);
1501 /* get freespace on every FS that is part of the session path */
1503 _total_free_4k_blocks = 0;
1505 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1506 statfs ((*i).path.c_str(), &statfsbuf);
1508 scale = statfsbuf.f_bsize/4096.0;
1510 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1511 _total_free_4k_blocks += (*i).blocks;
1517 Session::ensure_sound_dir (string path, string& result)
1522 /* Ensure that the parent directory exists */
1524 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1525 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1529 /* Ensure that the sounds directory exists */
1533 result += sound_dir_name;
1535 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1536 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1542 dead += dead_sound_dir_name;
1544 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1545 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1551 peak += peak_dir_name;
1553 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1554 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1558 /* callers expect this to be terminated ... */
1565 Session::discover_best_sound_dir (bool destructive)
1567 vector<space_and_path>::iterator i;
1570 /* handle common case without system calls */
1572 if (session_dirs.size() == 1) {
1576 /* OK, here's the algorithm we're following here:
1578 We want to select which directory to use for
1579 the next file source to be created. Ideally,
1580 we'd like to use a round-robin process so as to
1581 get maximum performance benefits from splitting
1582 the files across multiple disks.
1584 However, in situations without much diskspace, an
1585 RR approach may end up filling up a filesystem
1586 with new files while others still have space.
1587 Its therefore important to pay some attention to
1588 the freespace in the filesystem holding each
1589 directory as well. However, if we did that by
1590 itself, we'd keep creating new files in the file
1591 system with the most space until it was as full
1592 as all others, thus negating any performance
1593 benefits of this RAID-1 like approach.
1595 So, we use a user-configurable space threshold. If
1596 there are at least 2 filesystems with more than this
1597 much space available, we use RR selection between them.
1598 If not, then we pick the filesystem with the most space.
1600 This gets a good balance between the two
1604 refresh_disk_space ();
1606 int free_enough = 0;
1608 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1609 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1614 if (free_enough >= 2) {
1616 bool found_it = false;
1618 /* use RR selection process, ensuring that the one
1622 i = last_rr_session_dir;
1625 if (++i == session_dirs.end()) {
1626 i = session_dirs.begin();
1629 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1630 if (ensure_sound_dir ((*i).path, result) == 0) {
1631 last_rr_session_dir = i;
1637 } while (i != last_rr_session_dir);
1640 result = sound_dir();
1645 /* pick FS with the most freespace (and that
1646 seems to actually work ...)
1649 vector<space_and_path> sorted;
1650 space_and_path_ascending_cmp cmp;
1652 sorted = session_dirs;
1653 sort (sorted.begin(), sorted.end(), cmp);
1655 for (i = sorted.begin(); i != sorted.end(); ++i) {
1656 if (ensure_sound_dir ((*i).path, result) == 0) {
1657 last_rr_session_dir = i;
1662 /* if the above fails, fall back to the most simplistic solution */
1664 if (i == sorted.end()) {
1673 Session::load_playlists (const XMLNode& node)
1676 XMLNodeConstIterator niter;
1679 nlist = node.children();
1683 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1685 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1686 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1694 Session::load_unused_playlists (const XMLNode& node)
1697 XMLNodeConstIterator niter;
1700 nlist = node.children();
1704 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1706 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1707 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1711 // now manually untrack it
1713 track_playlist (playlist, false);
1721 Session::XMLPlaylistFactory (const XMLNode& node)
1724 return new AudioPlaylist (*this, node);
1727 catch (failed_constructor& err) {
1733 Session::load_named_selections (const XMLNode& node)
1736 XMLNodeConstIterator niter;
1739 nlist = node.children();
1743 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1745 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1746 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1754 Session::XMLNamedSelectionFactory (const XMLNode& node)
1757 return new NamedSelection (*this, node);
1760 catch (failed_constructor& err) {
1766 Session::dead_sound_dir () const
1769 res += dead_sound_dir_name;
1775 Session::sound_dir (bool with_path) const
1777 /* support old session structure */
1779 struct stat statbuf;
1781 string old_withpath;
1783 old_nopath += old_sound_dir_name;
1786 old_withpath = _path;
1787 old_withpath += old_sound_dir_name;
1788 old_withpath += '/';
1790 if (stat (old_withpath.c_str(), &statbuf) == 0) {
1792 return old_withpath;
1803 res += interchange_dir_name;
1805 res += legalize_for_path (_name);
1807 res += sound_dir_name;
1814 Session::peak_dir () const
1817 res += peak_dir_name;
1823 Session::automation_dir () const
1826 res += "automation/";
1831 Session::template_dir ()
1833 string path = get_user_ardour_path();
1834 path += "templates/";
1840 Session::suffixed_search_path (string suffix, bool data)
1844 path += get_user_ardour_path();
1845 if (path[path.length()-1] != ':') {
1850 path += get_system_data_path();
1852 path += get_system_module_path();
1855 vector<string> split_path;
1857 split (path, split_path, ':');
1860 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
1865 if (distance (i, split_path.end()) != 1) {
1874 Session::template_path ()
1876 return suffixed_search_path (X_("templates"), true);
1880 Session::control_protocol_path ()
1882 return suffixed_search_path (X_("surfaces"), false);
1886 Session::load_connections (const XMLNode& node)
1888 XMLNodeList nlist = node.children();
1889 XMLNodeConstIterator niter;
1893 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1894 if ((*niter)->name() == "InputConnection") {
1895 add_connection (new ARDOUR::InputConnection (**niter));
1896 } else if ((*niter)->name() == "OutputConnection") {
1897 add_connection (new ARDOUR::OutputConnection (**niter));
1899 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1908 Session::load_edit_groups (const XMLNode& node)
1910 return load_route_groups (node, true);
1914 Session::load_mix_groups (const XMLNode& node)
1916 return load_route_groups (node, false);
1920 Session::load_route_groups (const XMLNode& node, bool edit)
1922 XMLNodeList nlist = node.children();
1923 XMLNodeConstIterator niter;
1928 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1929 if ((*niter)->name() == "RouteGroup") {
1931 rg = add_edit_group ("");
1932 rg->set_state (**niter);
1934 rg = add_mix_group ("");
1935 rg->set_state (**niter);
1944 state_file_filter (const string &str, void *arg)
1946 return (str.length() > strlen(Session::statefile_suffix()) &&
1947 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
1951 bool operator()(const string* a, const string* b) {
1957 remove_end(string* state)
1959 string statename(*state);
1961 string::size_type start,end;
1962 if ((start = statename.find_last_of ('/')) != string::npos) {
1963 statename = statename.substr (start+1);
1966 if ((end = statename.rfind(".ardour")) == string::npos) {
1967 end = statename.length();
1970 return new string(statename.substr (0, end));
1974 Session::possible_states (string path)
1976 PathScanner scanner;
1977 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
1979 transform(states->begin(), states->end(), states->begin(), remove_end);
1982 sort (states->begin(), states->end(), cmp);
1988 Session::possible_states () const
1990 return possible_states(_path);
1994 Session::auto_save()
1996 save_state (_current_snapshot_name);
2000 Session::add_edit_group (string name)
2002 RouteGroup* rg = new RouteGroup (*this, name);
2003 edit_groups.push_back (rg);
2004 edit_group_added (rg); /* EMIT SIGNAL */
2010 Session::add_mix_group (string name)
2012 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2013 mix_groups.push_back (rg);
2014 mix_group_added (rg); /* EMIT SIGNAL */
2020 Session::remove_edit_group (RouteGroup& rg)
2022 list<RouteGroup*>::iterator i;
2024 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2025 (*i)->apply (&Route::drop_edit_group, this);
2026 edit_groups.erase (i);
2027 edit_group_removed (); /* EMIT SIGNAL */
2034 Session::remove_mix_group (RouteGroup& rg)
2036 list<RouteGroup*>::iterator i;
2038 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2039 (*i)->apply (&Route::drop_mix_group, this);
2040 mix_groups.erase (i);
2041 mix_group_removed (); /* EMIT SIGNAL */
2048 Session::mix_group_by_name (string name)
2050 list<RouteGroup *>::iterator i;
2052 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2053 if ((*i)->name() == name) {
2061 Session::edit_group_by_name (string name)
2063 list<RouteGroup *>::iterator i;
2065 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2066 if ((*i)->name() == name) {
2074 Session::begin_reversible_command (string name)
2076 current_trans = new UndoTransaction;
2077 current_trans->set_name (name);
2081 Session::commit_reversible_command (Command *cmd)
2086 current_trans->add_command (cmd);
2089 gettimeofday (&now, 0);
2090 current_trans->set_timestamp (now);
2092 history.add (current_trans);
2095 Session::GlobalRouteBooleanState
2096 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2098 GlobalRouteBooleanState s;
2099 boost::shared_ptr<RouteList> r = routes.reader ();
2101 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2102 if (!(*i)->hidden()) {
2103 RouteBooleanState v;
2106 Route* r = (*i).get();
2107 v.second = (r->*method)();
2116 Session::GlobalRouteMeterState
2117 Session::get_global_route_metering ()
2119 GlobalRouteMeterState s;
2120 boost::shared_ptr<RouteList> r = routes.reader ();
2122 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2123 if (!(*i)->hidden()) {
2127 v.second = (*i)->meter_point();
2137 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2139 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2140 i->first->set_meter_point (i->second, arg);
2145 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2147 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2148 Route* r = i->first.get();
2149 (r->*method) (i->second, arg);
2154 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2156 set_global_route_boolean (s, &Route::set_mute, src);
2160 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2162 set_global_route_boolean (s, &Route::set_solo, src);
2166 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2168 set_global_route_boolean (s, &Route::set_record_enable, src);
2173 Session::global_mute_memento (void* src)
2175 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2179 Session::global_metering_memento (void* src)
2181 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2185 Session::global_solo_memento (void* src)
2187 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2191 Session::global_record_enable_memento (void* src)
2193 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2198 template_filter (const string &str, void *arg)
2200 return (str.length() > strlen(Session::template_suffix()) &&
2201 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2205 Session::get_template_list (list<string> &template_names)
2207 vector<string *> *templates;
2208 PathScanner scanner;
2211 path = template_path ();
2213 templates = scanner (path, template_filter, 0, false, true);
2215 vector<string*>::iterator i;
2216 for (i = templates->begin(); i != templates->end(); ++i) {
2217 string fullpath = *(*i);
2220 start = fullpath.find_last_of ('/') + 1;
2221 if ((end = fullpath.find_last_of ('.')) <0) {
2222 end = fullpath.length();
2225 template_names.push_back(fullpath.substr(start, (end-start)));
2230 Session::read_favorite_dirs (FavoriteDirs & favs)
2232 string path = get_user_ardour_path();
2233 path += "/favorite_dirs";
2235 ifstream fav (path.c_str());
2240 if (errno != ENOENT) {
2241 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2252 getline(fav, newfav);
2258 favs.push_back (newfav);
2265 Session::write_favorite_dirs (FavoriteDirs & favs)
2267 string path = get_user_ardour_path();
2268 path += "/favorite_dirs";
2270 ofstream fav (path.c_str());
2276 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2277 fav << (*i) << endl;
2284 accept_all_non_peak_files (const string& path, void *arg)
2286 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2290 accept_all_state_files (const string& path, void *arg)
2292 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2296 Session::find_all_sources (string path, set<string>& result)
2301 if (!tree.read (path)) {
2305 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2310 XMLNodeConstIterator niter;
2312 nlist = node->children();
2316 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2320 if ((prop = (*niter)->property (X_("name"))) == 0) {
2324 if (prop->value()[0] == '/') {
2325 /* external file, ignore */
2329 string path = _path; /* /-terminated */
2330 path += sound_dir_name;
2332 path += prop->value();
2334 result.insert (path);
2341 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2343 PathScanner scanner;
2344 vector<string*>* state_files;
2346 string this_snapshot_path;
2352 if (ripped[ripped.length()-1] == '/') {
2353 ripped = ripped.substr (0, ripped.length() - 1);
2356 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2358 if (state_files == 0) {
2363 this_snapshot_path = _path;
2364 this_snapshot_path += _current_snapshot_name;
2365 this_snapshot_path += _statefile_suffix;
2367 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2369 if (exclude_this_snapshot && **i == this_snapshot_path) {
2373 if (find_all_sources (**i, result) < 0) {
2382 Session::cleanup_sources (Session::cleanup_report& rep)
2384 vector<boost::shared_ptr<Source> > dead_sources;
2385 vector<Playlist*> playlists_tbd;
2386 PathScanner scanner;
2388 vector<space_and_path>::iterator i;
2389 vector<space_and_path>::iterator nexti;
2390 vector<string*>* soundfiles;
2391 vector<string> unused;
2392 set<string> all_sources;
2397 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2399 /* step 1: consider deleting all unused playlists */
2401 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2404 status = AskAboutPlaylistDeletion (*x);
2413 playlists_tbd.push_back (*x);
2417 /* leave it alone */
2422 /* now delete any that were marked for deletion */
2424 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2425 PlaylistList::iterator foo;
2427 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2428 unused_playlists.erase (foo);
2433 /* step 2: clear the undo/redo history for all playlists */
2435 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2436 (*x)->drop_all_states ();
2439 /* step 3: find all un-referenced sources */
2444 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2446 AudioSourceList::iterator tmp;
2451 /* only remove files that are not in use and have some size
2452 to them. otherwise we remove the current "nascent"
2456 if (i->second.use_count() == 1 && i->second->length() > 0) {
2457 dead_sources.push_back (i->second);
2459 /* remove this source from our own list to avoid us
2460 adding it to the list of all sources below
2463 audio_sources.erase (i);
2469 /* Step 4: get rid of all regions in the region list that use any dead sources
2470 in case the sources themselves don't go away (they might be referenced in
2474 for (vector<boost::shared_ptr<Source> >::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2476 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2477 AudioRegionList::iterator tmp;
2478 boost::shared_ptr<AudioRegion> ar;
2485 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2486 if (ar->source (n) == (*i)) {
2487 /* this region is dead */
2496 /* build a list of all the possible sound directories for the session */
2498 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2503 sound_path += (*i).path;
2504 sound_path += sound_dir_name;
2506 if (nexti != session_dirs.end()) {
2513 /* now do the same thing for the files that ended up in the sounds dir(s)
2514 but are not referenced as sources in any snapshot.
2517 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2519 if (soundfiles == 0) {
2523 /* find all sources, but don't use this snapshot because the
2524 state file on disk still references sources we may have already
2528 find_all_sources_across_snapshots (all_sources, true);
2530 /* add our current source list
2533 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2534 boost::shared_ptr<AudioFileSource> fs;
2536 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2537 all_sources.insert (fs->path());
2541 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2546 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2556 unused.push_back (spath);
2560 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2562 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2563 struct stat statbuf;
2565 rep.paths.push_back (*x);
2566 if (stat ((*x).c_str(), &statbuf) == 0) {
2567 rep.space += statbuf.st_size;
2572 /* don't move the file across filesystems, just
2573 stick it in the `dead_sound_dir_name' directory
2574 on whichever filesystem it was already on.
2577 newpath = Glib::path_get_dirname (*x);
2578 newpath = Glib::path_get_dirname (newpath);
2581 newpath += dead_sound_dir_name;
2583 newpath += Glib::path_get_basename ((*x));
2585 if (access (newpath.c_str(), F_OK) == 0) {
2587 /* the new path already exists, try versioning */
2589 char buf[PATH_MAX+1];
2593 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2596 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2597 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2601 if (version == 999) {
2602 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2606 newpath = newpath_v;
2611 /* it doesn't exist, or we can't read it or something */
2615 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2616 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2617 (*x), newpath, strerror (errno))
2623 /* see if there an easy to find peakfile for this file, and remove it.
2626 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2627 peakpath += ".peak";
2629 if (access (peakpath.c_str(), W_OK) == 0) {
2630 if (::unlink (peakpath.c_str()) != 0) {
2631 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2632 peakpath, _path, strerror (errno))
2634 /* try to back out */
2635 rename (newpath.c_str(), _path.c_str());
2644 /* dump the history list */
2648 /* save state so we don't end up a session file
2649 referring to non-existent sources.
2655 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2660 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2662 vector<space_and_path>::iterator i;
2663 string dead_sound_dir;
2664 struct dirent* dentry;
2665 struct stat statbuf;
2671 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2673 dead_sound_dir = (*i).path;
2674 dead_sound_dir += dead_sound_dir_name;
2676 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2680 while ((dentry = readdir (dead)) != 0) {
2682 /* avoid '.' and '..' */
2684 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2685 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2691 fullpath = dead_sound_dir;
2693 fullpath += dentry->d_name;
2695 if (stat (fullpath.c_str(), &statbuf)) {
2699 if (!S_ISREG (statbuf.st_mode)) {
2703 if (unlink (fullpath.c_str())) {
2704 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2705 fullpath, strerror (errno))
2709 rep.paths.push_back (dentry->d_name);
2710 rep.space += statbuf.st_size;
2721 Session::set_dirty ()
2723 bool was_dirty = dirty();
2725 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2728 DirtyChanged(); /* EMIT SIGNAL */
2734 Session::set_clean ()
2736 bool was_dirty = dirty();
2738 _state_of_the_state = Clean;
2741 DirtyChanged(); /* EMIT SIGNAL */
2746 Session::add_controllable (Controllable* c)
2748 Glib::Mutex::Lock lm (controllables_lock);
2749 controllables.insert (c);
2753 Session::remove_controllable (Controllable* c)
2755 if (_state_of_the_state | Deletion) {
2759 Glib::Mutex::Lock lm (controllables_lock);
2761 Controllables::iterator x = controllables.find (c);
2763 if (x != controllables.end()) {
2764 controllables.erase (x);
2769 Session::controllable_by_id (const PBD::ID& id)
2771 Glib::Mutex::Lock lm (controllables_lock);
2773 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2774 if ((*i)->id() == id) {
2783 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2785 Stateful::add_instant_xml (node, dir);
2786 Config->add_instant_xml (node, get_user_ardour_path());
2791 Session::save_history (string snapshot_name)
2797 tree.set_root (&history.get_state());
2799 if (snapshot_name.empty()) {
2800 snapshot_name = _current_snapshot_name;
2803 xml_path = _path + snapshot_name + ".history";
2805 bak_path = xml_path + ".bak";
2807 if ((access (xml_path.c_str(), F_OK) == 0) &&
2808 (rename (xml_path.c_str(), bak_path.c_str())))
2810 error << _("could not backup old history file, current history not saved.") << endmsg;
2814 cerr << "actually writing history\n";
2816 if (!tree.write (xml_path))
2818 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2820 /* don't leave a corrupt file lying around if it is
2824 if (unlink (xml_path.c_str()))
2826 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2828 if (rename (bak_path.c_str(), xml_path.c_str()))
2830 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2841 Session::restore_history (string snapshot_name)
2847 xmlpath = _path + snapshot_name + ".history";
2848 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2850 if (access (xmlpath.c_str(), F_OK)) {
2851 error << string_compose(_("%1: session history file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
2855 if (!tree.read (xmlpath)) {
2856 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
2860 /* replace history */
2862 for (XMLNodeConstIterator it = tree.root()->children().begin();
2863 it != tree.root()->children().end();
2867 UndoTransaction* ut = new UndoTransaction ();
2870 ut->set_name(t->property("name")->value());
2871 stringstream ss(t->property("tv_sec")->value());
2873 ss.str(t->property("tv_usec")->value());
2875 ut->set_timestamp(tv);
2877 for (XMLNodeConstIterator child_it = t->children().begin();
2878 child_it != t->children().end();
2881 XMLNode *n = *child_it;
2883 if (n->name() == "MementoCommand" ||
2884 n->name() == "MementoUndoCommand" ||
2885 n->name() == "MementoRedoCommand")
2887 c = memento_command_factory(n);
2893 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();
3030 } else if (PARAM_IS ("send-mmc")) {
3032 /* only set the internal flag if we have
3036 if (_mmc_port != 0) {
3037 session_send_mmc = Config->get_send_mmc();
3040 } else if (PARAM_IS ("midi-feedback")) {
3042 /* only set the internal flag if we have
3046 if (_mtc_port != 0) {
3047 session_midi_feedback = Config->get_midi_feedback();
3050 } else if (PARAM_IS ("jack-time-master")) {
3052 engine().reset_timebase ();
3054 } else if (PARAM_IS ("native-file-header-format")) {
3056 if (!first_file_header_format_reset) {
3057 reset_native_file_format ();
3060 first_file_header_format_reset = false;
3062 } else if (PARAM_IS ("native-file-data-format")) {
3064 if (!first_file_data_format_reset) {
3065 reset_native_file_format ();
3068 first_file_data_format_reset = false;