2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <sigc++/bind.h>
28 #include <cstdio> /* snprintf(3) ... grrr */
43 #include <sys/mount.h>
44 #include <sys/param.h>
49 #include <midi++/mmc.h>
50 #include <midi++/port.h>
51 #include <pbd/error.h>
53 #include <glibmm/thread.h>
54 #include <pbd/pathscanner.h>
55 #include <pbd/pthread_utils.h>
56 #include <pbd/strsplit.h>
58 #include <ardour/audioengine.h>
59 #include <ardour/configuration.h>
60 #include <ardour/session.h>
61 #include <ardour/audio_diskstream.h>
62 #include <ardour/utils.h>
63 #include <ardour/audioplaylist.h>
64 #include <ardour/audiofilesource.h>
65 #include <ardour/destructive_filesource.h>
66 #include <ardour/sndfile_helpers.h>
67 #include <ardour/auditioner.h>
68 #include <ardour/export.h>
69 #include <ardour/redirect.h>
70 #include <ardour/send.h>
71 #include <ardour/insert.h>
72 #include <ardour/connection.h>
73 #include <ardour/slave.h>
74 #include <ardour/tempo.h>
75 #include <ardour/audio_track.h>
76 #include <ardour/cycle_timer.h>
77 #include <ardour/utils.h>
78 #include <ardour/named_selection.h>
79 #include <ardour/version.h>
80 #include <ardour/location.h>
81 #include <ardour/audioregion.h>
82 #include <ardour/crossfade.h>
83 #include <ardour/control_protocol_manager.h>
84 #include <ardour/region_factory.h>
85 #include <ardour/source_factory.h>
91 using namespace ARDOUR;
95 Session::first_stage_init (string fullpath, string snapshot_name)
97 if (fullpath.length() == 0) {
98 throw failed_constructor();
101 char buf[PATH_MAX+1];
102 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
103 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
104 throw failed_constructor();
109 if (_path[_path.length()-1] != '/') {
113 /* these two are just provisional settings. set_state()
114 will likely override them.
117 _name = _current_snapshot_name = snapshot_name;
119 _current_frame_rate = _engine.frame_rate ();
120 _tempo_map = new TempoMap (_current_frame_rate);
121 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
123 g_atomic_int_set (&processing_prohibited, 0);
126 _transport_speed = 0;
127 _last_transport_speed = 0;
128 transport_sub_state = 0;
129 _transport_frame = 0;
131 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
132 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
133 _end_location_is_free = true;
134 g_atomic_int_set (&_record_status, Disabled);
135 loop_changing = false;
137 _last_roll_location = 0;
138 _last_record_location = 0;
139 pending_locate_frame = 0;
140 pending_locate_roll = false;
141 pending_locate_flush = false;
142 dstream_buffer_size = 0;
144 state_was_pending = false;
146 outbound_mtc_smpte_frame = 0;
147 next_quarter_frame_to_send = -1;
148 current_block_size = 0;
149 solo_update_disabled = false;
150 currently_soloing = false;
151 _have_captured = false;
152 _worst_output_latency = 0;
153 _worst_input_latency = 0;
154 _worst_track_latency = 0;
155 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
157 butler_mixdown_buffer = 0;
158 butler_gain_buffer = 0;
160 session_send_mmc = false;
161 session_send_mtc = false;
162 session_midi_feedback = false;
163 post_transport_work = PostTransportWork (0);
164 g_atomic_int_set (&butler_should_do_transport_work, 0);
165 g_atomic_int_set (&butler_active, 0);
166 g_atomic_int_set (&_playback_load, 100);
167 g_atomic_int_set (&_capture_load, 100);
168 g_atomic_int_set (&_playback_load_min, 100);
169 g_atomic_int_set (&_capture_load_min, 100);
171 waiting_to_start = false;
173 _gain_automation_buffer = 0;
174 _pan_automation_buffer = 0;
176 pending_abort = false;
177 destructive_index = 0;
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 DestructiveFileSource::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 Curve::CurveCreated.connect (mem_fun (*this, &Session::add_curve));
243 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
245 Controllable::Created.connect (mem_fun (*this, &Session::add_controllable));
246 Controllable::GoingAway.connect (mem_fun (*this, &Session::remove_controllable));
248 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
250 /* stop IO objects from doing stuff until we're ready for them */
252 IO::disable_panners ();
253 IO::disable_ports ();
254 IO::disable_connecting ();
258 Session::second_stage_init (bool new_session)
260 AudioFileSource::set_peak_dir (peak_dir());
263 if (load_state (_current_snapshot_name)) {
266 remove_empty_sounds ();
269 if (start_butler_thread()) {
273 if (start_midi_thread ()) {
277 // set_state() will call setup_raid_path(), but if it's a new session we need
278 // to call setup_raid_path() here.
280 if (set_state (*state_tree->root())) {
284 setup_raid_path(_path);
287 /* we can't save till after ::when_engine_running() is called,
288 because otherwise we save state with no connections made.
289 therefore, we reset _state_of_the_state because ::set_state()
290 will have cleared it.
292 we also have to include Loading so that any events that get
293 generated between here and the end of ::when_engine_running()
294 will be processed directly rather than queued.
297 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
299 // set_auto_input (true);
300 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
301 _locations.added.connect (mem_fun (this, &Session::locations_added));
302 setup_click_sounds (0);
303 setup_midi_control ();
305 /* Pay attention ... */
307 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
308 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
310 if (_engine.running()) {
311 when_engine_running();
313 first_time_running = _engine.Running.connect (mem_fun (*this, &Session::when_engine_running));
316 send_full_time_code ();
317 _engine.transport_locate (0);
318 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
319 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
321 ControlProtocolManager::instance().set_session (*this);
324 _end_location_is_free = true;
326 _end_location_is_free = false;
333 Session::raid_path () const
337 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
342 return path.substr (0, path.length() - 1); // drop final colon
346 Session::setup_raid_path (string path)
348 string::size_type colon;
352 string::size_type len = path.length();
357 if (path.length() == 0) {
361 session_dirs.clear ();
363 for (string::size_type n = 0; n < len; ++n) {
364 if (path[n] == ':') {
371 /* no multiple search path, just one location (common case) */
375 session_dirs.push_back (sp);
382 if (fspath[fspath.length()-1] != '/') {
385 fspath += sound_dir (false);
387 AudioFileSource::set_search_path (fspath);
394 while ((colon = remaining.find_first_of (':')) != string::npos) {
397 sp.path = remaining.substr (0, colon);
398 session_dirs.push_back (sp);
400 /* add sounds to file search path */
403 if (fspath[fspath.length()-1] != '/') {
406 fspath += sound_dir (false);
409 remaining = remaining.substr (colon+1);
412 if (remaining.length()) {
419 if (fspath[fspath.length()-1] != '/') {
422 fspath += sound_dir (false);
425 session_dirs.push_back (sp);
428 /* set the AudioFileSource search path */
430 AudioFileSource::set_search_path (fspath);
432 /* reset the round-robin soundfile path thingie */
434 last_rr_session_dir = session_dirs.begin();
438 Session::create (bool& new_session, string* mix_template, nframes_t initial_length)
442 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
443 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
449 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
450 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
456 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
457 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
461 dir = dead_sound_dir ();
463 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
464 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
468 dir = automation_dir ();
470 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
471 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
476 /* check new_session so we don't overwrite an existing one */
479 std::string in_path = *mix_template;
481 ifstream in(in_path.c_str());
484 string out_path = _path;
486 out_path += _statefile_suffix;
488 ofstream out(out_path.c_str());
493 // okay, session is set up. Treat like normal saved
494 // session from now on.
500 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
506 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
513 /* set initial start + end point */
515 start_location->set_end (0);
516 _locations.add (start_location);
518 end_location->set_end (initial_length);
519 _locations.add (end_location);
521 _state_of_the_state = Clean;
523 if (save_state (_current_snapshot_name)) {
524 save_history (_current_snapshot_name);
532 Session::load_diskstreams (const XMLNode& node)
535 XMLNodeConstIterator citer;
537 clist = node.children();
539 for (citer = clist.begin(); citer != clist.end(); ++citer) {
543 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
544 add_diskstream (dstream);
547 catch (failed_constructor& err) {
548 error << _("Session: could not load diskstream via XML state") << endmsg;
557 Session::remove_pending_capture_state ()
562 xml_path += _current_snapshot_name;
563 xml_path += _pending_suffix;
565 unlink (xml_path.c_str());
569 Session::save_state (string snapshot_name, bool pending)
575 if (_state_of_the_state & CannotSave) {
579 tree.set_root (&get_state());
581 if (snapshot_name.empty()) {
582 snapshot_name = _current_snapshot_name;
588 xml_path += snapshot_name;
589 xml_path += _statefile_suffix;
593 // Make backup of state file
595 if ((access (xml_path.c_str(), F_OK) == 0) &&
596 (rename(xml_path.c_str(), bak_path.c_str()))) {
597 error << _("could not backup old state file, current state not saved.") << endmsg;
604 xml_path += snapshot_name;
605 xml_path += _pending_suffix;
609 cerr << "actually writing state\n";
611 if (!tree.write (xml_path)) {
612 error << string_compose (_("state could not be saved to %1"), xml_path) << endmsg;
614 /* don't leave a corrupt file lying around if it is
618 if (unlink (xml_path.c_str())) {
619 error << string_compose (_("could not remove corrupt state file %1"), xml_path) << endmsg;
622 if (rename (bak_path.c_str(), xml_path.c_str())) {
623 error << string_compose (_("could not restore state file from backup %1"), bak_path) << endmsg;
632 save_history(snapshot_name);
634 bool was_dirty = dirty();
636 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
639 DirtyChanged (); /* EMIT SIGNAL */
642 StateSaved (snapshot_name); /* EMIT SIGNAL */
649 Session::restore_state (string snapshot_name)
651 if (load_state (snapshot_name) == 0) {
652 set_state (*state_tree->root());
659 Session::load_state (string snapshot_name)
668 state_was_pending = false;
670 /* check for leftover pending state from a crashed capture attempt */
673 xmlpath += snapshot_name;
674 xmlpath += _pending_suffix;
676 if (!access (xmlpath.c_str(), F_OK)) {
678 /* there is pending state from a crashed capture attempt */
680 if (AskAboutPendingState()) {
681 state_was_pending = true;
685 if (!state_was_pending) {
688 xmlpath += snapshot_name;
689 xmlpath += _statefile_suffix;
692 if (access (xmlpath.c_str(), F_OK)) {
693 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
697 state_tree = new XMLTree;
701 if (state_tree->read (xmlpath)) {
704 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
713 Session::load_options (const XMLNode& node)
717 LocaleGuard lg (X_("POSIX"));
719 Config->set_variables (node, ConfigVariableBase::Session);
721 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
722 if ((prop = child->property ("val")) != 0) {
723 _end_location_is_free = (prop->value() == "yes");
731 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
733 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
734 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
736 return owner & modified_by_session_or_user;
740 Session::get_options () const
743 LocaleGuard lg (X_("POSIX"));
745 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
747 child = option_root.add_child ("end-marker-is-free");
748 child->add_property ("val", _end_location_is_free ? "yes" : "no");
760 Session::get_template()
762 /* if we don't disable rec-enable, diskstreams
763 will believe they need to store their capture
764 sources in their state node.
767 disable_record (false);
773 Session::state(bool full_state)
775 XMLNode* node = new XMLNode("Session");
778 // store libardour version, just in case
780 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
781 libardour_major_version, libardour_minor_version, libardour_micro_version);
782 node->add_property("version", string(buf));
784 /* store configuration settings */
789 node->add_property ("name", _name);
791 if (session_dirs.size() > 1) {
795 vector<space_and_path>::iterator i = session_dirs.begin();
796 vector<space_and_path>::iterator next;
798 ++i; /* skip the first one */
802 while (i != session_dirs.end()) {
806 if (next != session_dirs.end()) {
816 child = node->add_child ("Path");
817 child->add_content (p);
821 /* save the ID counter */
823 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
824 node->add_property ("id-counter", buf);
826 /* various options */
828 node->add_child_nocopy (get_options());
830 child = node->add_child ("Sources");
833 Glib::Mutex::Lock sl (audio_source_lock);
835 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
837 /* Don't save information about AudioFileSources that are empty */
839 boost::shared_ptr<AudioFileSource> fs;
841 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
842 boost::shared_ptr<DestructiveFileSource> dfs = boost::dynamic_pointer_cast<DestructiveFileSource> (fs);
844 /* destructive file sources are OK if they are empty, because
845 we will re-use them every time.
849 if (fs->length() == 0) {
855 child->add_child_nocopy (siter->second->get_state());
859 child = node->add_child ("Regions");
862 Glib::Mutex::Lock rl (region_lock);
864 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
866 /* only store regions not attached to playlists */
868 if (i->second->playlist() == 0) {
869 child->add_child_nocopy (i->second->state (true));
874 child = node->add_child ("DiskStreams");
877 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
878 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
879 if (!(*i)->hidden()) {
880 child->add_child_nocopy ((*i)->get_state());
885 node->add_child_nocopy (_locations.get_state());
887 child = node->add_child ("Connections");
889 Glib::Mutex::Lock lm (connection_lock);
890 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
891 if (!(*i)->system_dependent()) {
892 child->add_child_nocopy ((*i)->get_state());
897 child = node->add_child ("Routes");
899 boost::shared_ptr<RouteList> r = routes.reader ();
901 RoutePublicOrderSorter cmp;
902 RouteList public_order (*r);
903 public_order.sort (cmp);
905 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
906 if (!(*i)->hidden()) {
908 child->add_child_nocopy ((*i)->get_state());
910 child->add_child_nocopy ((*i)->get_template());
917 child = node->add_child ("EditGroups");
918 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
919 child->add_child_nocopy ((*i)->get_state());
922 child = node->add_child ("MixGroups");
923 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
924 child->add_child_nocopy ((*i)->get_state());
927 child = node->add_child ("Playlists");
928 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
929 if (!(*i)->hidden()) {
930 if (!(*i)->empty()) {
932 child->add_child_nocopy ((*i)->get_state());
934 child->add_child_nocopy ((*i)->get_template());
940 child = node->add_child ("UnusedPlaylists");
941 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
942 if (!(*i)->hidden()) {
943 if (!(*i)->empty()) {
945 child->add_child_nocopy ((*i)->get_state());
947 child->add_child_nocopy ((*i)->get_template());
955 child = node->add_child ("Click");
956 child->add_child_nocopy (_click_io->state (full_state));
960 child = node->add_child ("NamedSelections");
961 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
963 child->add_child_nocopy ((*i)->get_state());
968 node->add_child_nocopy (_tempo_map->get_state());
971 node->add_child_copy (*_extra_xml);
978 Session::set_state (const XMLNode& node)
982 const XMLProperty* prop;
985 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
987 if (node.name() != X_("Session")){
988 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
992 StateManager::prohibit_save ();
994 if ((prop = node.property ("name")) != 0) {
995 _name = prop->value ();
998 setup_raid_path(_path);
1000 if ((prop = node.property (X_("id-counter"))) != 0) {
1002 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1003 ID::init_counter (x);
1005 /* old sessions used a timebased counter, so fake
1006 the startup ID counter based on a standard
1011 ID::init_counter (now);
1015 IO::disable_ports ();
1016 IO::disable_connecting ();
1018 /* Object loading order:
1035 if (use_config_midi_ports ()) {
1038 if ((child = find_named_node (node, "extra")) != 0) {
1039 _extra_xml = new XMLNode (*child);
1042 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1043 load_options (*child);
1044 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1045 load_options (*child);
1047 error << _("Session: XML state has no options section") << endmsg;
1050 if ((child = find_named_node (node, "Sources")) == 0) {
1051 error << _("Session: XML state has no sources section") << endmsg;
1053 } else if (load_sources (*child)) {
1057 if ((child = find_named_node (node, "Regions")) == 0) {
1058 error << _("Session: XML state has no Regions section") << endmsg;
1060 } else if (load_regions (*child)) {
1064 if ((child = find_named_node (node, "Playlists")) == 0) {
1065 error << _("Session: XML state has no playlists section") << endmsg;
1067 } else if (load_playlists (*child)) {
1071 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1073 } else if (load_unused_playlists (*child)) {
1077 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1078 if (load_named_selections (*child)) {
1083 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1084 error << _("Session: XML state has no diskstreams section") << endmsg;
1086 } else if (load_diskstreams (*child)) {
1090 if ((child = find_named_node (node, "Connections")) == 0) {
1091 error << _("Session: XML state has no connections section") << endmsg;
1093 } else if (load_connections (*child)) {
1097 if ((child = find_named_node (node, "Locations")) == 0) {
1098 error << _("Session: XML state has no locations section") << endmsg;
1100 } else if (_locations.set_state (*child)) {
1106 if ((location = _locations.auto_loop_location()) != 0) {
1107 set_auto_loop_location (location);
1110 if ((location = _locations.auto_punch_location()) != 0) {
1111 set_auto_punch_location (location);
1114 if ((location = _locations.end_location()) == 0) {
1115 _locations.add (end_location);
1117 delete end_location;
1118 end_location = location;
1121 if ((location = _locations.start_location()) == 0) {
1122 _locations.add (start_location);
1124 delete start_location;
1125 start_location = location;
1128 _locations.save_state (_("initial state"));
1130 if ((child = find_named_node (node, "EditGroups")) == 0) {
1131 error << _("Session: XML state has no edit groups section") << endmsg;
1133 } else if (load_edit_groups (*child)) {
1137 if ((child = find_named_node (node, "MixGroups")) == 0) {
1138 error << _("Session: XML state has no mix groups section") << endmsg;
1140 } else if (load_mix_groups (*child)) {
1144 if ((child = find_named_node (node, "TempoMap")) == 0) {
1145 error << _("Session: XML state has no Tempo Map section") << endmsg;
1147 } else if (_tempo_map->set_state (*child)) {
1151 if ((child = find_named_node (node, "Routes")) == 0) {
1152 error << _("Session: XML state has no routes section") << endmsg;
1154 } else if (load_routes (*child)) {
1158 if ((child = find_named_node (node, "Click")) == 0) {
1159 warning << _("Session: XML state has no click section") << endmsg;
1160 } else if (_click_io) {
1161 _click_io->set_state (*child);
1164 /* here beginneth the second phase ... */
1166 StateReady (); /* EMIT SIGNAL */
1168 _state_of_the_state = Clean;
1170 StateManager::allow_save (_("initial state"), true);
1172 if (state_was_pending) {
1173 save_state (_current_snapshot_name);
1174 remove_pending_capture_state ();
1175 state_was_pending = false;
1181 /* we failed, re-enable state saving but don't actually save internal state */
1182 StateManager::allow_save (X_("ignored"), false);
1187 Session::load_routes (const XMLNode& node)
1190 XMLNodeConstIterator niter;
1191 RouteList new_routes;
1193 nlist = node.children();
1197 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1199 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1202 error << _("Session: cannot create Route from XML description.") << endmsg;
1206 new_routes.push_back (route);
1209 add_routes (new_routes);
1214 boost::shared_ptr<Route>
1215 Session::XMLRouteFactory (const XMLNode& node)
1217 if (node.name() != "Route") {
1218 return boost::shared_ptr<Route> ((Route*) 0);
1221 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1222 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1225 boost::shared_ptr<Route> x (new Route (*this, node));
1231 Session::load_regions (const XMLNode& node)
1234 XMLNodeConstIterator niter;
1235 boost::shared_ptr<AudioRegion> region;
1237 nlist = node.children();
1241 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1242 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1243 error << _("Session: cannot create Region from XML description.") << endmsg;
1250 boost::shared_ptr<AudioRegion>
1251 Session::XMLRegionFactory (const XMLNode& node, bool full)
1253 const XMLProperty* prop;
1254 boost::shared_ptr<Source> source;
1255 boost::shared_ptr<AudioSource> as;
1257 uint32_t nchans = 1;
1260 if (node.name() != X_("Region")) {
1261 return boost::shared_ptr<AudioRegion>();
1264 if ((prop = node.property (X_("channels"))) != 0) {
1265 nchans = atoi (prop->value().c_str());
1269 if ((prop = node.property (X_("source-0"))) == 0) {
1270 if ((prop = node.property ("source")) == 0) {
1271 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1272 return boost::shared_ptr<AudioRegion>();
1276 PBD::ID s_id (prop->value());
1278 if ((source = source_by_id (s_id)) == 0) {
1279 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1280 return boost::shared_ptr<AudioRegion>();
1283 as = boost::dynamic_pointer_cast<AudioSource>(source);
1285 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1286 return boost::shared_ptr<AudioRegion>();
1289 sources.push_back (as);
1291 /* pickup other channels */
1293 for (uint32_t n=1; n < nchans; ++n) {
1294 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1295 if ((prop = node.property (buf)) != 0) {
1297 PBD::ID id2 (prop->value());
1299 if ((source = source_by_id (id2)) == 0) {
1300 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1301 return boost::shared_ptr<AudioRegion>();
1304 as = boost::dynamic_pointer_cast<AudioSource>(source);
1306 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1307 return boost::shared_ptr<AudioRegion>();
1309 sources.push_back (as);
1314 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1319 catch (failed_constructor& err) {
1320 return boost::shared_ptr<AudioRegion>();
1325 Session::get_sources_as_xml ()
1328 XMLNode* node = new XMLNode (X_("Sources"));
1329 Glib::Mutex::Lock lm (audio_source_lock);
1331 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1332 node->add_child_nocopy (i->second->get_state());
1335 /* XXX get MIDI and other sources here */
1341 Session::path_from_region_name (string name, string identifier)
1343 char buf[PATH_MAX+1];
1345 string dir = discover_best_sound_dir ();
1347 for (n = 0; n < 999999; ++n) {
1348 if (identifier.length()) {
1349 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1350 identifier.c_str(), n);
1352 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1354 if (access (buf, F_OK) != 0) {
1364 Session::load_sources (const XMLNode& node)
1367 XMLNodeConstIterator niter;
1368 boost::shared_ptr<Source> source;
1370 nlist = node.children();
1374 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1376 if ((source = XMLSourceFactory (**niter)) == 0) {
1377 error << _("Session: cannot create Source from XML description.") << endmsg;
1384 boost::shared_ptr<Source>
1385 Session::XMLSourceFactory (const XMLNode& node)
1387 if (node.name() != "Source") {
1388 return boost::shared_ptr<Source>();
1392 return SourceFactory::create (*this, node);
1395 catch (failed_constructor& err) {
1396 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1397 return boost::shared_ptr<Source>();
1402 Session::save_template (string template_name)
1405 string xml_path, bak_path, template_path;
1407 if (_state_of_the_state & CannotSave) {
1412 string dir = template_dir();
1414 if ((dp = opendir (dir.c_str()))) {
1417 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1418 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1423 tree.set_root (&get_template());
1426 xml_path += template_name;
1427 xml_path += _template_suffix;
1429 ifstream in(xml_path.c_str());
1432 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1438 if (!tree.write (xml_path)) {
1439 error << _("mix template not saved") << endmsg;
1447 Session::rename_template (string old_name, string new_name)
1449 string old_path = template_dir() + old_name + _template_suffix;
1450 string new_path = template_dir() + new_name + _template_suffix;
1452 return rename (old_path.c_str(), new_path.c_str());
1456 Session::delete_template (string name)
1458 string template_path = template_dir();
1459 template_path += name;
1460 template_path += _template_suffix;
1462 return remove (template_path.c_str());
1466 Session::refresh_disk_space ()
1469 struct statfs statfsbuf;
1470 vector<space_and_path>::iterator i;
1471 Glib::Mutex::Lock lm (space_lock);
1474 /* get freespace on every FS that is part of the session path */
1476 _total_free_4k_blocks = 0;
1478 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1479 statfs ((*i).path.c_str(), &statfsbuf);
1481 scale = statfsbuf.f_bsize/4096.0;
1483 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1484 _total_free_4k_blocks += (*i).blocks;
1490 Session::ensure_sound_dir (string path, string& result)
1495 /* Ensure that the parent directory exists */
1497 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1498 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1502 /* Ensure that the sounds directory exists */
1506 result += sound_dir_name;
1508 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1509 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1515 dead += dead_sound_dir_name;
1517 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1518 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1524 peak += peak_dir_name;
1526 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1527 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1531 /* callers expect this to be terminated ... */
1538 Session::discover_best_sound_dir (bool destructive)
1540 vector<space_and_path>::iterator i;
1543 /* handle common case without system calls */
1545 if (session_dirs.size() == 1) {
1549 /* OK, here's the algorithm we're following here:
1551 We want to select which directory to use for
1552 the next file source to be created. Ideally,
1553 we'd like to use a round-robin process so as to
1554 get maximum performance benefits from splitting
1555 the files across multiple disks.
1557 However, in situations without much diskspace, an
1558 RR approach may end up filling up a filesystem
1559 with new files while others still have space.
1560 Its therefore important to pay some attention to
1561 the freespace in the filesystem holding each
1562 directory as well. However, if we did that by
1563 itself, we'd keep creating new files in the file
1564 system with the most space until it was as full
1565 as all others, thus negating any performance
1566 benefits of this RAID-1 like approach.
1568 So, we use a user-configurable space threshold. If
1569 there are at least 2 filesystems with more than this
1570 much space available, we use RR selection between them.
1571 If not, then we pick the filesystem with the most space.
1573 This gets a good balance between the two
1577 refresh_disk_space ();
1579 int free_enough = 0;
1581 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1582 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1587 if (free_enough >= 2) {
1589 bool found_it = false;
1591 /* use RR selection process, ensuring that the one
1595 i = last_rr_session_dir;
1598 if (++i == session_dirs.end()) {
1599 i = session_dirs.begin();
1602 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1603 if (ensure_sound_dir ((*i).path, result) == 0) {
1604 last_rr_session_dir = i;
1610 } while (i != last_rr_session_dir);
1613 result = sound_dir();
1618 /* pick FS with the most freespace (and that
1619 seems to actually work ...)
1622 vector<space_and_path> sorted;
1623 space_and_path_ascending_cmp cmp;
1625 sorted = session_dirs;
1626 sort (sorted.begin(), sorted.end(), cmp);
1628 for (i = sorted.begin(); i != sorted.end(); ++i) {
1629 if (ensure_sound_dir ((*i).path, result) == 0) {
1630 last_rr_session_dir = i;
1635 /* if the above fails, fall back to the most simplistic solution */
1637 if (i == sorted.end()) {
1646 Session::load_playlists (const XMLNode& node)
1649 XMLNodeConstIterator niter;
1652 nlist = node.children();
1656 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1658 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1659 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1667 Session::load_unused_playlists (const XMLNode& node)
1670 XMLNodeConstIterator niter;
1673 nlist = node.children();
1677 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1679 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1680 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1684 // now manually untrack it
1686 track_playlist (playlist, false);
1694 Session::XMLPlaylistFactory (const XMLNode& node)
1697 return new AudioPlaylist (*this, node);
1700 catch (failed_constructor& err) {
1706 Session::load_named_selections (const XMLNode& node)
1709 XMLNodeConstIterator niter;
1712 nlist = node.children();
1716 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1718 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1719 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1727 Session::XMLNamedSelectionFactory (const XMLNode& node)
1730 return new NamedSelection (*this, node);
1733 catch (failed_constructor& err) {
1739 Session::dead_sound_dir () const
1742 res += dead_sound_dir_name;
1748 Session::sound_dir (bool with_path) const
1750 /* support old session structure */
1752 struct stat statbuf;
1754 string old_withpath;
1756 old_nopath += old_sound_dir_name;
1759 old_withpath = _path;
1760 old_withpath += old_sound_dir_name;
1761 old_withpath += '/';
1763 if (stat (old_withpath.c_str(), &statbuf) == 0) {
1765 return old_withpath;
1776 res += interchange_dir_name;
1778 res += legalize_for_path (_name);
1780 res += sound_dir_name;
1787 Session::peak_dir () const
1790 res += peak_dir_name;
1796 Session::automation_dir () const
1799 res += "automation/";
1804 Session::template_dir ()
1806 string path = get_user_ardour_path();
1807 path += "templates/";
1813 Session::suffixed_search_path (string suffix, bool data)
1817 path += get_user_ardour_path();
1818 if (path[path.length()-1] != ':') {
1823 path += get_system_data_path();
1825 path += get_system_module_path();
1828 vector<string> split_path;
1830 split (path, split_path, ':');
1833 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
1838 if (distance (i, split_path.end()) != 1) {
1847 Session::template_path ()
1849 return suffixed_search_path (X_("templates"), true);
1853 Session::control_protocol_path ()
1855 return suffixed_search_path (X_("surfaces"), false);
1859 Session::load_connections (const XMLNode& node)
1861 XMLNodeList nlist = node.children();
1862 XMLNodeConstIterator niter;
1866 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1867 if ((*niter)->name() == "InputConnection") {
1868 add_connection (new ARDOUR::InputConnection (**niter));
1869 } else if ((*niter)->name() == "OutputConnection") {
1870 add_connection (new ARDOUR::OutputConnection (**niter));
1872 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1881 Session::load_edit_groups (const XMLNode& node)
1883 return load_route_groups (node, true);
1887 Session::load_mix_groups (const XMLNode& node)
1889 return load_route_groups (node, false);
1893 Session::load_route_groups (const XMLNode& node, bool edit)
1895 XMLNodeList nlist = node.children();
1896 XMLNodeConstIterator niter;
1901 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1902 if ((*niter)->name() == "RouteGroup") {
1904 rg = add_edit_group ("");
1905 rg->set_state (**niter);
1907 rg = add_mix_group ("");
1908 rg->set_state (**niter);
1917 state_file_filter (const string &str, void *arg)
1919 return (str.length() > strlen(Session::statefile_suffix()) &&
1920 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
1924 bool operator()(const string* a, const string* b) {
1930 remove_end(string* state)
1932 string statename(*state);
1934 string::size_type start,end;
1935 if ((start = statename.find_last_of ('/')) != string::npos) {
1936 statename = statename.substr (start+1);
1939 if ((end = statename.rfind(".ardour")) == string::npos) {
1940 end = statename.length();
1943 return new string(statename.substr (0, end));
1947 Session::possible_states (string path)
1949 PathScanner scanner;
1950 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
1952 transform(states->begin(), states->end(), states->begin(), remove_end);
1955 sort (states->begin(), states->end(), cmp);
1961 Session::possible_states () const
1963 return possible_states(_path);
1967 Session::auto_save()
1969 save_state (_current_snapshot_name);
1973 Session::add_edit_group (string name)
1975 RouteGroup* rg = new RouteGroup (*this, name);
1976 edit_groups.push_back (rg);
1977 edit_group_added (rg); /* EMIT SIGNAL */
1983 Session::add_mix_group (string name)
1985 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
1986 mix_groups.push_back (rg);
1987 mix_group_added (rg); /* EMIT SIGNAL */
1993 Session::remove_edit_group (RouteGroup& rg)
1995 list<RouteGroup*>::iterator i;
1997 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
1998 (*i)->apply (&Route::drop_edit_group, this);
1999 edit_groups.erase (i);
2000 edit_group_removed (); /* EMIT SIGNAL */
2007 Session::remove_mix_group (RouteGroup& rg)
2009 list<RouteGroup*>::iterator i;
2011 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2012 (*i)->apply (&Route::drop_mix_group, this);
2013 mix_groups.erase (i);
2014 mix_group_removed (); /* EMIT SIGNAL */
2021 Session::mix_group_by_name (string name)
2023 list<RouteGroup *>::iterator i;
2025 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2026 if ((*i)->name() == name) {
2034 Session::edit_group_by_name (string name)
2036 list<RouteGroup *>::iterator i;
2038 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2039 if ((*i)->name() == name) {
2047 Session::begin_reversible_command (string name)
2049 current_trans = new UndoTransaction;
2050 current_trans->set_name (name);
2054 Session::commit_reversible_command (Command *cmd)
2059 current_trans->add_command (cmd);
2062 gettimeofday (&now, 0);
2063 current_trans->set_timestamp (now);
2065 history.add (current_trans);
2068 Session::GlobalRouteBooleanState
2069 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2071 GlobalRouteBooleanState s;
2072 boost::shared_ptr<RouteList> r = routes.reader ();
2074 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2075 if (!(*i)->hidden()) {
2076 RouteBooleanState v;
2079 Route* r = (*i).get();
2080 v.second = (r->*method)();
2089 Session::GlobalRouteMeterState
2090 Session::get_global_route_metering ()
2092 GlobalRouteMeterState s;
2093 boost::shared_ptr<RouteList> r = routes.reader ();
2095 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2096 if (!(*i)->hidden()) {
2100 v.second = (*i)->meter_point();
2110 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2112 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2113 i->first->set_meter_point (i->second, arg);
2118 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2120 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2121 Route* r = i->first.get();
2122 (r->*method) (i->second, arg);
2127 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2129 set_global_route_boolean (s, &Route::set_mute, src);
2133 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2135 set_global_route_boolean (s, &Route::set_solo, src);
2139 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2141 set_global_route_boolean (s, &Route::set_record_enable, src);
2146 Session::global_mute_memento (void* src)
2148 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2152 Session::global_metering_memento (void* src)
2154 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2158 Session::global_solo_memento (void* src)
2160 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2164 Session::global_record_enable_memento (void* src)
2166 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2171 template_filter (const string &str, void *arg)
2173 return (str.length() > strlen(Session::template_suffix()) &&
2174 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2178 Session::get_template_list (list<string> &template_names)
2180 vector<string *> *templates;
2181 PathScanner scanner;
2184 path = template_path ();
2186 templates = scanner (path, template_filter, 0, false, true);
2188 vector<string*>::iterator i;
2189 for (i = templates->begin(); i != templates->end(); ++i) {
2190 string fullpath = *(*i);
2193 start = fullpath.find_last_of ('/') + 1;
2194 if ((end = fullpath.find_last_of ('.')) <0) {
2195 end = fullpath.length();
2198 template_names.push_back(fullpath.substr(start, (end-start)));
2203 Session::read_favorite_dirs (FavoriteDirs & favs)
2205 string path = get_user_ardour_path();
2206 path += "/favorite_dirs";
2208 ifstream fav (path.c_str());
2213 if (errno != ENOENT) {
2214 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2225 getline(fav, newfav);
2231 favs.push_back (newfav);
2238 Session::write_favorite_dirs (FavoriteDirs & favs)
2240 string path = get_user_ardour_path();
2241 path += "/favorite_dirs";
2243 ofstream fav (path.c_str());
2249 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2250 fav << (*i) << endl;
2257 accept_all_non_peak_files (const string& path, void *arg)
2259 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2263 accept_all_state_files (const string& path, void *arg)
2265 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2269 Session::find_all_sources (string path, set<string>& result)
2274 if (!tree.read (path)) {
2278 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2283 XMLNodeConstIterator niter;
2285 nlist = node->children();
2289 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2293 if ((prop = (*niter)->property (X_("name"))) == 0) {
2297 if (prop->value()[0] == '/') {
2298 /* external file, ignore */
2302 string path = _path; /* /-terminated */
2303 path += sound_dir_name;
2305 path += prop->value();
2307 result.insert (path);
2314 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2316 PathScanner scanner;
2317 vector<string*>* state_files;
2319 string this_snapshot_path;
2325 if (ripped[ripped.length()-1] == '/') {
2326 ripped = ripped.substr (0, ripped.length() - 1);
2329 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2331 if (state_files == 0) {
2336 this_snapshot_path = _path;
2337 this_snapshot_path += _current_snapshot_name;
2338 this_snapshot_path += _statefile_suffix;
2340 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2342 if (exclude_this_snapshot && **i == this_snapshot_path) {
2346 if (find_all_sources (**i, result) < 0) {
2355 Session::cleanup_sources (Session::cleanup_report& rep)
2357 vector<boost::shared_ptr<Source> > dead_sources;
2358 vector<Playlist*> playlists_tbd;
2359 PathScanner scanner;
2361 vector<space_and_path>::iterator i;
2362 vector<space_and_path>::iterator nexti;
2363 vector<string*>* soundfiles;
2364 vector<string> unused;
2365 set<string> all_sources;
2370 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2372 /* step 1: consider deleting all unused playlists */
2374 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2377 status = AskAboutPlaylistDeletion (*x);
2386 playlists_tbd.push_back (*x);
2390 /* leave it alone */
2395 /* now delete any that were marked for deletion */
2397 for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2398 PlaylistList::iterator foo;
2400 if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
2401 unused_playlists.erase (foo);
2406 /* step 2: clear the undo/redo history for all playlists */
2408 for (PlaylistList::iterator x = playlists.begin(); x != playlists.end(); ++x) {
2409 (*x)->drop_all_states ();
2412 /* step 3: find all un-referenced sources */
2417 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2419 AudioSourceList::iterator tmp;
2424 /* only remove files that are not in use and have some size
2425 to them. otherwise we remove the current "nascent"
2429 if (i->second.use_count() == 1 && i->second->length() > 0) {
2430 dead_sources.push_back (i->second);
2432 /* remove this source from our own list to avoid us
2433 adding it to the list of all sources below
2436 audio_sources.erase (i);
2442 /* Step 4: get rid of all regions in the region list that use any dead sources
2443 in case the sources themselves don't go away (they might be referenced in
2447 for (vector<boost::shared_ptr<Source> >::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2449 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
2450 AudioRegionList::iterator tmp;
2451 boost::shared_ptr<AudioRegion> ar;
2458 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2459 if (ar->source (n) == (*i)) {
2460 /* this region is dead */
2469 /* build a list of all the possible sound directories for the session */
2471 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2476 sound_path += (*i).path;
2477 sound_path += sound_dir_name;
2479 if (nexti != session_dirs.end()) {
2486 /* now do the same thing for the files that ended up in the sounds dir(s)
2487 but are not referenced as sources in any snapshot.
2490 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2492 if (soundfiles == 0) {
2496 /* find all sources, but don't use this snapshot because the
2497 state file on disk still references sources we may have already
2501 find_all_sources_across_snapshots (all_sources, true);
2503 /* add our current source list
2506 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2507 boost::shared_ptr<AudioFileSource> fs;
2509 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2510 all_sources.insert (fs->path());
2514 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2519 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2529 unused.push_back (spath);
2533 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2535 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2536 struct stat statbuf;
2538 rep.paths.push_back (*x);
2539 if (stat ((*x).c_str(), &statbuf) == 0) {
2540 rep.space += statbuf.st_size;
2545 /* don't move the file across filesystems, just
2546 stick it in the `dead_sound_dir_name' directory
2547 on whichever filesystem it was already on.
2550 newpath = Glib::path_get_dirname (*x);
2551 newpath = Glib::path_get_dirname (newpath);
2554 newpath += dead_sound_dir_name;
2556 newpath += Glib::path_get_basename ((*x));
2558 if (access (newpath.c_str(), F_OK) == 0) {
2560 /* the new path already exists, try versioning */
2562 char buf[PATH_MAX+1];
2566 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2569 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2570 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2574 if (version == 999) {
2575 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2579 newpath = newpath_v;
2584 /* it doesn't exist, or we can't read it or something */
2588 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2589 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2590 (*x), newpath, strerror (errno))
2596 /* see if there an easy to find peakfile for this file, and remove it.
2599 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2600 peakpath += ".peak";
2602 if (access (peakpath.c_str(), W_OK) == 0) {
2603 if (::unlink (peakpath.c_str()) != 0) {
2604 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2605 peakpath, _path, strerror (errno))
2607 /* try to back out */
2608 rename (newpath.c_str(), _path.c_str());
2617 /* dump the history list */
2621 /* save state so we don't end up a session file
2622 referring to non-existent sources.
2628 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2633 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2635 vector<space_and_path>::iterator i;
2636 string dead_sound_dir;
2637 struct dirent* dentry;
2638 struct stat statbuf;
2644 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2646 dead_sound_dir = (*i).path;
2647 dead_sound_dir += dead_sound_dir_name;
2649 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2653 while ((dentry = readdir (dead)) != 0) {
2655 /* avoid '.' and '..' */
2657 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2658 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2664 fullpath = dead_sound_dir;
2666 fullpath += dentry->d_name;
2668 if (stat (fullpath.c_str(), &statbuf)) {
2672 if (!S_ISREG (statbuf.st_mode)) {
2676 if (unlink (fullpath.c_str())) {
2677 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2678 fullpath, strerror (errno))
2682 rep.paths.push_back (dentry->d_name);
2683 rep.space += statbuf.st_size;
2694 Session::set_dirty ()
2696 bool was_dirty = dirty();
2698 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2701 DirtyChanged(); /* EMIT SIGNAL */
2707 Session::set_clean ()
2709 bool was_dirty = dirty();
2711 _state_of_the_state = Clean;
2714 DirtyChanged(); /* EMIT SIGNAL */
2719 Session::add_controllable (Controllable* c)
2721 Glib::Mutex::Lock lm (controllables_lock);
2722 controllables.push_back (c);
2726 Session::remove_controllable (Controllable* c)
2728 if (_state_of_the_state | Deletion) {
2732 Glib::Mutex::Lock lm (controllables_lock);
2733 controllables.remove (c);
2737 Session::controllable_by_id (const PBD::ID& id)
2739 Glib::Mutex::Lock lm (controllables_lock);
2741 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2742 if ((*i)->id() == id) {
2751 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2753 Stateful::add_instant_xml (node, dir);
2754 Config->add_instant_xml (node, get_user_ardour_path());
2759 Session::save_history (string snapshot_name)
2765 tree.set_root (&history.get_state());
2767 if (snapshot_name.empty()) {
2768 snapshot_name = _current_snapshot_name;
2771 xml_path = _path + snapshot_name + ".history";
2773 bak_path = xml_path + ".bak";
2775 if ((access (xml_path.c_str(), F_OK) == 0) &&
2776 (rename (xml_path.c_str(), bak_path.c_str())))
2778 error << _("could not backup old history file, current history not saved.") << endmsg;
2782 cerr << "actually writing history\n";
2784 if (!tree.write (xml_path))
2786 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2788 /* don't leave a corrupt file lying around if it is
2792 if (unlink (xml_path.c_str()))
2794 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2796 if (rename (bak_path.c_str(), xml_path.c_str()))
2798 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2809 Session::restore_history (string snapshot_name)
2815 xmlpath = _path + snapshot_name + ".history";
2816 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2818 if (access (xmlpath.c_str(), F_OK)) {
2819 error << string_compose(_("%1: session history file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
2823 if (!tree.read (xmlpath)) {
2824 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
2828 /* replace history */
2830 for (XMLNodeConstIterator it = tree.root()->children().begin();
2831 it != tree.root()->children().end();
2835 UndoTransaction* ut = new UndoTransaction ();
2838 ut->set_name(t->property("name")->value());
2839 stringstream ss(t->property("tv_sec")->value());
2841 ss.str(t->property("tv_usec")->value());
2843 ut->set_timestamp(tv);
2845 for (XMLNodeConstIterator child_it = t->children().begin();
2846 child_it != t->children().end();
2849 XMLNode *n = *child_it;
2851 if (n->name() == "MementoCommand" ||
2852 n->name() == "MementoUndoCommand" ||
2853 n->name() == "MementoRedoCommand")
2855 c = memento_command_factory(n);
2861 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2871 Session::config_changed (const char* parameter_name)
2873 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2875 if (PARAM_IS ("seamless-loop")) {
2877 } else if (PARAM_IS ("rf-speed")) {
2879 } else if (PARAM_IS ("auto-loop")) {
2881 } else if (PARAM_IS ("auto-input")) {
2883 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2884 /* auto-input only makes a difference if we're rolling */
2886 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2888 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2889 if ((*i)->record_enabled ()) {
2890 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
2891 (*i)->monitor_input (!Config->get_auto_input());
2896 } else if (PARAM_IS ("punch-in")) {
2900 if ((location = _locations.auto_punch_location()) != 0) {
2902 if (Config->get_punch_in ()) {
2903 replace_event (Event::PunchIn, location->start());
2905 remove_event (location->start(), Event::PunchIn);
2909 } else if (PARAM_IS ("punch-out")) {
2913 if ((location = _locations.auto_punch_location()) != 0) {
2915 if (Config->get_punch_out()) {
2916 replace_event (Event::PunchOut, location->end());
2918 clear_events (Event::PunchOut);
2922 } else if (PARAM_IS ("edit-mode")) {
2924 Glib::Mutex::Lock lm (playlist_lock);
2926 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2927 (*i)->set_edit_mode (Config->get_edit_mode ());
2930 } else if (PARAM_IS ("use-video-sync")) {
2932 if (transport_stopped()) {
2933 if (Config->get_use_video_sync()) {
2934 waiting_for_sync_offset = true;
2938 } else if (PARAM_IS ("mmc-control")) {
2940 poke_midi_thread ();
2942 } else if (PARAM_IS ("midi-control")) {
2944 poke_midi_thread ();
2946 } else if (PARAM_IS ("raid-path")) {
2948 setup_raid_path (Config->get_raid_path());
2950 } else if (PARAM_IS ("smpte-frames-per-second") || PARAM_IS ("smpte-drop-frames")) {
2954 } else if (PARAM_IS ("video-pullup")) {
2958 } else if (PARAM_IS ("seamless-loop")) {
2960 if (play_loop && transport_rolling()) {
2961 // to reset diskstreams etc
2962 request_play_loop (true);
2965 } else if (PARAM_IS ("rf-speed")) {
2967 cumulative_rf_motion = 0;
2970 } else if (PARAM_IS ("click-sound")) {
2972 setup_click_sounds (1);
2974 } else if (PARAM_IS ("click-emphasis-sound")) {
2976 setup_click_sounds (-1);
2978 } else if (PARAM_IS ("clicking")) {
2980 if (Config->get_clicking()) {
2981 if (_click_io && click_data) { // don't require emphasis data
2988 } else if (PARAM_IS ("send-mtc")) {
2990 /* only set the internal flag if we have
2994 if (_mtc_port != 0) {
2995 session_send_mtc = Config->get_send_mtc();
2998 } else if (PARAM_IS ("send-mmc")) {
3000 /* only set the internal flag if we have
3004 if (_mmc_port != 0) {
3005 session_send_mmc = Config->get_send_mmc();
3008 } else if (PARAM_IS ("midi-feedback")) {
3010 /* only set the internal flag if we have
3014 if (_mtc_port != 0) {
3015 session_midi_feedback = Config->get_midi_feedback();
3018 } else if (PARAM_IS ("jack-time-master")) {
3020 engine().reset_timebase ();
3022 } else if (PARAM_IS ("native-file-header-format")) {
3024 if (!first_file_header_format_reset) {
3025 reset_native_file_format ();
3028 first_file_header_format_reset = false;
3030 } else if (PARAM_IS ("native-file-data-format")) {
3032 if (!first_file_data_format_reset) {
3033 reset_native_file_format ();
3036 first_file_data_format_reset = false;