2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <sigc++/bind.h>
28 #include <cstdio> /* snprintf(3) ... grrr */
43 #include <sys/param.h>
44 #include <sys/mount.h>
49 #include <midi++/mmc.h>
50 #include <midi++/port.h>
51 #include <pbd/error.h>
53 #include <glibmm/thread.h>
54 #include <pbd/pathscanner.h>
55 #include <pbd/pthread_utils.h>
56 #include <pbd/strsplit.h>
57 #include <pbd/stacktrace.h>
59 #include <ardour/audioengine.h>
60 #include <ardour/configuration.h>
61 #include <ardour/session.h>
62 #include <ardour/audio_diskstream.h>
63 #include <ardour/utils.h>
64 #include <ardour/audioplaylist.h>
65 #include <ardour/audiofilesource.h>
66 #include <ardour/destructive_filesource.h>
67 #include <ardour/sndfile_helpers.h>
68 #include <ardour/auditioner.h>
69 #include <ardour/export.h>
70 #include <ardour/redirect.h>
71 #include <ardour/send.h>
72 #include <ardour/insert.h>
73 #include <ardour/connection.h>
74 #include <ardour/slave.h>
75 #include <ardour/tempo.h>
76 #include <ardour/audio_track.h>
77 #include <ardour/cycle_timer.h>
78 #include <ardour/utils.h>
79 #include <ardour/named_selection.h>
80 #include <ardour/version.h>
81 #include <ardour/location.h>
82 #include <ardour/audioregion.h>
83 #include <ardour/crossfade.h>
84 #include <ardour/control_protocol_manager.h>
85 #include <ardour/region_factory.h>
86 #include <ardour/source_factory.h>
87 #include <ardour/playlist_factory.h>
89 #include <control_protocol/control_protocol.h>
95 using namespace ARDOUR;
99 Session::first_stage_init (string fullpath, string snapshot_name)
101 if (fullpath.length() == 0) {
102 throw failed_constructor();
105 char buf[PATH_MAX+1];
106 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
107 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
108 throw failed_constructor();
113 if (_path[_path.length()-1] != '/') {
117 /* these two are just provisional settings. set_state()
118 will likely override them.
121 _name = _current_snapshot_name = snapshot_name;
123 _current_frame_rate = _engine.frame_rate ();
124 _tempo_map = new TempoMap (_current_frame_rate);
125 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
127 g_atomic_int_set (&processing_prohibited, 0);
129 _transport_speed = 0;
130 _last_transport_speed = 0;
131 transport_sub_state = 0;
132 _transport_frame = 0;
134 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
135 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
136 _end_location_is_free = true;
137 g_atomic_int_set (&_record_status, Disabled);
138 loop_changing = false;
140 _last_roll_location = 0;
141 _last_record_location = 0;
142 pending_locate_frame = 0;
143 pending_locate_roll = false;
144 pending_locate_flush = false;
145 dstream_buffer_size = 0;
147 state_was_pending = false;
149 outbound_mtc_smpte_frame = 0;
150 next_quarter_frame_to_send = -1;
151 current_block_size = 0;
152 solo_update_disabled = false;
153 currently_soloing = false;
154 _have_captured = false;
155 _worst_output_latency = 0;
156 _worst_input_latency = 0;
157 _worst_track_latency = 0;
158 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
160 butler_mixdown_buffer = 0;
161 butler_gain_buffer = 0;
163 session_send_mmc = false;
164 session_send_mtc = 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 SndFileSource::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 PlaylistFactory::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 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
246 Controllable::Destroyed.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 when_engine_running();
312 send_full_time_code ();
313 _engine.transport_locate (0);
314 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
315 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
317 ControlProtocolManager::instance().set_session (*this);
320 _end_location_is_free = true;
322 _end_location_is_free = false;
329 Session::raid_path () const
333 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
338 return path.substr (0, path.length() - 1); // drop final colon
342 Session::setup_raid_path (string path)
344 string::size_type colon;
348 string::size_type len = path.length();
353 if (path.length() == 0) {
357 session_dirs.clear ();
359 for (string::size_type n = 0; n < len; ++n) {
360 if (path[n] == ':') {
367 /* no multiple search path, just one location (common case) */
371 session_dirs.push_back (sp);
378 if (fspath[fspath.length()-1] != '/') {
382 fspath += sound_dir (false);
384 AudioFileSource::set_search_path (fspath);
391 while ((colon = remaining.find_first_of (':')) != string::npos) {
394 sp.path = remaining.substr (0, colon);
395 session_dirs.push_back (sp);
397 /* add sounds to file search path */
400 if (fspath[fspath.length()-1] != '/') {
403 fspath += sound_dir (false);
406 remaining = remaining.substr (colon+1);
409 if (remaining.length()) {
416 if (fspath[fspath.length()-1] != '/') {
419 fspath += sound_dir (false);
422 session_dirs.push_back (sp);
425 /* set the AudioFileSource search path */
427 AudioFileSource::set_search_path (fspath);
429 /* reset the round-robin soundfile path thingie */
431 last_rr_session_dir = session_dirs.begin();
435 Session::create (bool& new_session, string* mix_template, nframes_t initial_length)
439 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
440 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
446 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
447 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
453 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
454 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
458 dir = dead_sound_dir ();
460 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
461 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
465 dir = automation_dir ();
467 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
468 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
473 /* check new_session so we don't overwrite an existing one */
476 std::string in_path = *mix_template;
478 ifstream in(in_path.c_str());
481 string out_path = _path;
483 out_path += _statefile_suffix;
485 ofstream out(out_path.c_str());
490 // okay, session is set up. Treat like normal saved
491 // session from now on.
497 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
503 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
510 /* set initial start + end point */
512 start_location->set_end (0);
513 _locations.add (start_location);
515 end_location->set_end (initial_length);
516 _locations.add (end_location);
518 _state_of_the_state = Clean;
520 if (save_state (_current_snapshot_name)) {
528 Session::load_diskstreams (const XMLNode& node)
531 XMLNodeConstIterator citer;
533 clist = node.children();
535 for (citer = clist.begin(); citer != clist.end(); ++citer) {
539 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
540 add_diskstream (dstream);
543 catch (failed_constructor& err) {
544 error << _("Session: could not load diskstream via XML state") << endmsg;
553 Session::remove_pending_capture_state ()
558 xml_path += _current_snapshot_name;
559 xml_path += _pending_suffix;
561 unlink (xml_path.c_str());
565 Session::save_state (string snapshot_name, bool pending)
571 if (_state_of_the_state & CannotSave) {
575 tree.set_root (&get_state());
577 if (snapshot_name.empty()) {
578 snapshot_name = _current_snapshot_name;
584 xml_path += snapshot_name;
585 xml_path += _statefile_suffix;
590 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
592 // Make backup of state file
594 ifstream in (xml_path.c_str());
595 ofstream out (bak_path.c_str());
598 error << string_compose (_("Could not open existing session file %1 for backup"), xml_path) << endmsg;
603 error << string_compose (_("Could not open backup session file %1"), bak_path) << endmsg;
610 error << string_compose (_("Could not copy existing session file %1 to %2 for backup"), xml_path, bak_path) << endmsg;
611 unlink (bak_path.c_str());
619 xml_path += snapshot_name;
620 xml_path += _pending_suffix;
627 tmp_path += snapshot_name;
630 cerr << "actually writing state\n";
632 if (!tree.write (tmp_path)) {
633 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
634 unlink (tmp_path.c_str());
639 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
640 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
641 unlink (tmp_path.c_str());
648 save_history (snapshot_name);
650 bool was_dirty = dirty();
652 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
655 DirtyChanged (); /* EMIT SIGNAL */
658 StateSaved (snapshot_name); /* EMIT SIGNAL */
665 Session::restore_state (string snapshot_name)
667 if (load_state (snapshot_name) == 0) {
668 set_state (*state_tree->root());
675 Session::load_state (string snapshot_name)
684 state_was_pending = false;
686 /* check for leftover pending state from a crashed capture attempt */
689 xmlpath += snapshot_name;
690 xmlpath += _pending_suffix;
692 if (!access (xmlpath.c_str(), F_OK)) {
694 /* there is pending state from a crashed capture attempt */
696 if (AskAboutPendingState()) {
697 state_was_pending = true;
701 if (!state_was_pending) {
704 xmlpath += snapshot_name;
705 xmlpath += _statefile_suffix;
708 if (access (xmlpath.c_str(), F_OK)) {
709 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
713 state_tree = new XMLTree;
717 if (state_tree->read (xmlpath)) {
720 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
729 Session::load_options (const XMLNode& node)
733 LocaleGuard lg (X_("POSIX"));
735 Config->set_variables (node, ConfigVariableBase::Session);
737 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
738 if ((prop = child->property ("val")) != 0) {
739 _end_location_is_free = (prop->value() == "yes");
747 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
749 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
750 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
752 return owner & modified_by_session_or_user;
756 Session::get_options () const
759 LocaleGuard lg (X_("POSIX"));
761 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
763 child = option_root.add_child ("end-marker-is-free");
764 child->add_property ("val", _end_location_is_free ? "yes" : "no");
776 Session::get_template()
778 /* if we don't disable rec-enable, diskstreams
779 will believe they need to store their capture
780 sources in their state node.
783 disable_record (false);
789 Session::state(bool full_state)
791 XMLNode* node = new XMLNode("Session");
794 // store libardour version, just in case
796 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
797 libardour_major_version, libardour_minor_version, libardour_micro_version);
798 node->add_property("version", string(buf));
800 /* store configuration settings */
805 node->add_property ("name", _name);
807 if (session_dirs.size() > 1) {
811 vector<space_and_path>::iterator i = session_dirs.begin();
812 vector<space_and_path>::iterator next;
814 ++i; /* skip the first one */
818 while (i != session_dirs.end()) {
822 if (next != session_dirs.end()) {
832 child = node->add_child ("Path");
833 child->add_content (p);
837 /* save the ID counter */
839 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
840 node->add_property ("id-counter", buf);
842 /* various options */
844 node->add_child_nocopy (get_options());
846 child = node->add_child ("Sources");
849 Glib::Mutex::Lock sl (audio_source_lock);
851 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
853 /* Don't save information about AudioFileSources that are empty */
855 boost::shared_ptr<AudioFileSource> fs;
857 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
859 /* destructive file sources are OK if they are empty, because
860 we will re-use them every time.
863 if (!fs->destructive()) {
864 if (fs->length() == 0) {
870 child->add_child_nocopy (siter->second->get_state());
874 child = node->add_child ("Regions");
877 Glib::Mutex::Lock rl (region_lock);
879 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
881 /* only store regions not attached to playlists */
883 if (i->second->playlist() == 0) {
884 child->add_child_nocopy (i->second->state (true));
889 child = node->add_child ("DiskStreams");
892 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
893 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
894 if (!(*i)->hidden()) {
895 child->add_child_nocopy ((*i)->get_state());
901 node->add_child_nocopy (_locations.get_state());
903 // for a template, just create a new Locations, populate it
904 // with the default start and end, and get the state for that.
906 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
907 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
910 end->set_end(compute_initial_length());
912 node->add_child_nocopy (loc.get_state());
915 child = node->add_child ("Connections");
917 Glib::Mutex::Lock lm (connection_lock);
918 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
919 if (!(*i)->system_dependent()) {
920 child->add_child_nocopy ((*i)->get_state());
925 child = node->add_child ("Routes");
927 boost::shared_ptr<RouteList> r = routes.reader ();
929 RoutePublicOrderSorter cmp;
930 RouteList public_order (*r);
931 public_order.sort (cmp);
933 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
934 if (!(*i)->hidden()) {
936 child->add_child_nocopy ((*i)->get_state());
938 child->add_child_nocopy ((*i)->get_template());
945 child = node->add_child ("EditGroups");
946 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
947 child->add_child_nocopy ((*i)->get_state());
950 child = node->add_child ("MixGroups");
951 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
952 child->add_child_nocopy ((*i)->get_state());
955 child = node->add_child ("Playlists");
956 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
957 if (!(*i)->hidden()) {
958 if (!(*i)->empty()) {
960 child->add_child_nocopy ((*i)->get_state());
962 child->add_child_nocopy ((*i)->get_template());
968 child = node->add_child ("UnusedPlaylists");
969 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
970 if (!(*i)->hidden()) {
971 if (!(*i)->empty()) {
973 child->add_child_nocopy ((*i)->get_state());
975 child->add_child_nocopy ((*i)->get_template());
983 child = node->add_child ("Click");
984 child->add_child_nocopy (_click_io->state (full_state));
988 child = node->add_child ("NamedSelections");
989 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
991 child->add_child_nocopy ((*i)->get_state());
996 node->add_child_nocopy (_tempo_map->get_state());
998 node->add_child_nocopy (get_control_protocol_state());
1001 node->add_child_copy (*_extra_xml);
1008 Session::get_control_protocol_state ()
1010 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1011 XMLNode* node = new XMLNode (X_("ControlProtocols"));
1013 cpm.foreach_known_protocol (bind (mem_fun (*this, &Session::add_control_protocol), node));
1019 Session::add_control_protocol (const ControlProtocolInfo* const cpi, XMLNode* node)
1021 if (cpi->protocol) {
1022 node->add_child_nocopy (cpi->protocol->get_state());
1027 Session::set_state (const XMLNode& node)
1031 const XMLProperty* prop;
1034 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1036 if (node.name() != X_("Session")){
1037 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1041 if ((prop = node.property ("name")) != 0) {
1042 _name = prop->value ();
1045 setup_raid_path(_path);
1047 if ((prop = node.property (X_("id-counter"))) != 0) {
1049 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1050 ID::init_counter (x);
1052 /* old sessions used a timebased counter, so fake
1053 the startup ID counter based on a standard
1058 ID::init_counter (now);
1062 IO::disable_ports ();
1063 IO::disable_connecting ();
1065 /* Object loading order:
1083 if (use_config_midi_ports ()) {
1086 if ((child = find_named_node (node, "extra")) != 0) {
1087 _extra_xml = new XMLNode (*child);
1090 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1091 load_options (*child);
1092 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1093 load_options (*child);
1095 error << _("Session: XML state has no options section") << endmsg;
1098 if ((child = find_named_node (node, "Locations")) == 0) {
1099 error << _("Session: XML state has no locations section") << endmsg;
1101 } else if (_locations.set_state (*child)) {
1107 if ((location = _locations.auto_loop_location()) != 0) {
1108 set_auto_loop_location (location);
1111 if ((location = _locations.auto_punch_location()) != 0) {
1112 set_auto_punch_location (location);
1115 if ((location = _locations.end_location()) == 0) {
1116 _locations.add (end_location);
1118 delete end_location;
1119 end_location = location;
1122 if ((location = _locations.start_location()) == 0) {
1123 _locations.add (start_location);
1125 delete start_location;
1126 start_location = location;
1129 AudioFileSource::set_header_position_offset (start_location->start());
1131 if ((child = find_named_node (node, "Sources")) == 0) {
1132 error << _("Session: XML state has no sources section") << endmsg;
1134 } else if (load_sources (*child)) {
1138 if ((child = find_named_node (node, "Regions")) == 0) {
1139 error << _("Session: XML state has no Regions section") << endmsg;
1141 } else if (load_regions (*child)) {
1145 if ((child = find_named_node (node, "Playlists")) == 0) {
1146 error << _("Session: XML state has no playlists section") << endmsg;
1148 } else if (load_playlists (*child)) {
1152 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1154 } else if (load_unused_playlists (*child)) {
1158 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1159 if (load_named_selections (*child)) {
1164 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1165 error << _("Session: XML state has no diskstreams section") << endmsg;
1167 } else if (load_diskstreams (*child)) {
1171 if ((child = find_named_node (node, "Connections")) == 0) {
1172 error << _("Session: XML state has no connections section") << endmsg;
1174 } else if (load_connections (*child)) {
1178 if ((child = find_named_node (node, "EditGroups")) == 0) {
1179 error << _("Session: XML state has no edit groups section") << endmsg;
1181 } else if (load_edit_groups (*child)) {
1185 if ((child = find_named_node (node, "MixGroups")) == 0) {
1186 error << _("Session: XML state has no mix groups section") << endmsg;
1188 } else if (load_mix_groups (*child)) {
1192 if ((child = find_named_node (node, "TempoMap")) == 0) {
1193 error << _("Session: XML state has no Tempo Map section") << endmsg;
1195 } else if (_tempo_map->set_state (*child)) {
1199 if ((child = find_named_node (node, "Routes")) == 0) {
1200 error << _("Session: XML state has no routes section") << endmsg;
1202 } else if (load_routes (*child)) {
1206 if ((child = find_named_node (node, "Click")) == 0) {
1207 warning << _("Session: XML state has no click section") << endmsg;
1208 } else if (_click_io) {
1209 _click_io->set_state (*child);
1212 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1213 ControlProtocolManager::instance().set_protocol_states (*child);
1216 /* here beginneth the second phase ... */
1218 StateReady (); /* EMIT SIGNAL */
1220 _state_of_the_state = Clean;
1221 cerr << "session marked clean\n";
1223 if (state_was_pending) {
1224 save_state (_current_snapshot_name);
1225 remove_pending_capture_state ();
1226 state_was_pending = false;
1236 Session::load_routes (const XMLNode& node)
1239 XMLNodeConstIterator niter;
1240 RouteList new_routes;
1242 nlist = node.children();
1246 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1248 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1251 error << _("Session: cannot create Route from XML description.") << endmsg;
1255 new_routes.push_back (route);
1258 add_routes (new_routes);
1263 boost::shared_ptr<Route>
1264 Session::XMLRouteFactory (const XMLNode& node)
1266 if (node.name() != "Route") {
1267 return boost::shared_ptr<Route> ((Route*) 0);
1270 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1271 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1274 boost::shared_ptr<Route> x (new Route (*this, node));
1280 Session::load_regions (const XMLNode& node)
1283 XMLNodeConstIterator niter;
1284 boost::shared_ptr<AudioRegion> region;
1286 nlist = node.children();
1290 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1291 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1292 error << _("Session: cannot create Region from XML description.") << endmsg;
1299 boost::shared_ptr<AudioRegion>
1300 Session::XMLRegionFactory (const XMLNode& node, bool full)
1302 const XMLProperty* prop;
1303 boost::shared_ptr<Source> source;
1304 boost::shared_ptr<AudioSource> as;
1306 uint32_t nchans = 1;
1309 if (node.name() != X_("Region")) {
1310 return boost::shared_ptr<AudioRegion>();
1313 if ((prop = node.property (X_("channels"))) != 0) {
1314 nchans = atoi (prop->value().c_str());
1318 if ((prop = node.property ("name")) == 0) {
1319 cerr << "no name for this region\n";
1323 if ((prop = node.property (X_("source-0"))) == 0) {
1324 if ((prop = node.property ("source")) == 0) {
1325 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1326 return boost::shared_ptr<AudioRegion>();
1330 PBD::ID s_id (prop->value());
1332 if ((source = source_by_id (s_id)) == 0) {
1333 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1334 return boost::shared_ptr<AudioRegion>();
1337 as = boost::dynamic_pointer_cast<AudioSource>(source);
1339 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1340 return boost::shared_ptr<AudioRegion>();
1343 sources.push_back (as);
1345 /* pickup other channels */
1347 for (uint32_t n=1; n < nchans; ++n) {
1348 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1349 if ((prop = node.property (buf)) != 0) {
1351 PBD::ID id2 (prop->value());
1353 if ((source = source_by_id (id2)) == 0) {
1354 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1355 return boost::shared_ptr<AudioRegion>();
1358 as = boost::dynamic_pointer_cast<AudioSource>(source);
1360 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1361 return boost::shared_ptr<AudioRegion>();
1363 sources.push_back (as);
1368 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1373 catch (failed_constructor& err) {
1374 return boost::shared_ptr<AudioRegion>();
1379 Session::get_sources_as_xml ()
1382 XMLNode* node = new XMLNode (X_("Sources"));
1383 Glib::Mutex::Lock lm (audio_source_lock);
1385 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1386 node->add_child_nocopy (i->second->get_state());
1389 /* XXX get MIDI and other sources here */
1395 Session::path_from_region_name (string name, string identifier)
1397 char buf[PATH_MAX+1];
1399 string dir = discover_best_sound_dir ();
1401 for (n = 0; n < 999999; ++n) {
1402 if (identifier.length()) {
1403 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1404 identifier.c_str(), n);
1406 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1408 if (access (buf, F_OK) != 0) {
1418 Session::load_sources (const XMLNode& node)
1421 XMLNodeConstIterator niter;
1422 boost::shared_ptr<Source> source;
1424 nlist = node.children();
1428 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1430 if ((source = XMLSourceFactory (**niter)) == 0) {
1431 error << _("Session: cannot create Source from XML description.") << endmsg;
1438 boost::shared_ptr<Source>
1439 Session::XMLSourceFactory (const XMLNode& node)
1441 if (node.name() != "Source") {
1442 return boost::shared_ptr<Source>();
1446 return SourceFactory::create (*this, node);
1449 catch (failed_constructor& err) {
1450 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1451 return boost::shared_ptr<Source>();
1456 Session::save_template (string template_name)
1459 string xml_path, bak_path, template_path;
1461 if (_state_of_the_state & CannotSave) {
1466 string dir = template_dir();
1468 if ((dp = opendir (dir.c_str()))) {
1471 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1472 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1477 tree.set_root (&get_template());
1480 xml_path += template_name;
1481 xml_path += _template_suffix;
1483 ifstream in(xml_path.c_str());
1486 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1492 if (!tree.write (xml_path)) {
1493 error << _("mix template not saved") << endmsg;
1501 Session::rename_template (string old_name, string new_name)
1503 string old_path = template_dir() + old_name + _template_suffix;
1504 string new_path = template_dir() + new_name + _template_suffix;
1506 return rename (old_path.c_str(), new_path.c_str());
1510 Session::delete_template (string name)
1512 string template_path = template_dir();
1513 template_path += name;
1514 template_path += _template_suffix;
1516 return remove (template_path.c_str());
1520 Session::refresh_disk_space ()
1523 struct statfs statfsbuf;
1524 vector<space_and_path>::iterator i;
1525 Glib::Mutex::Lock lm (space_lock);
1528 /* get freespace on every FS that is part of the session path */
1530 _total_free_4k_blocks = 0;
1532 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1533 statfs ((*i).path.c_str(), &statfsbuf);
1535 scale = statfsbuf.f_bsize/4096.0;
1537 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1538 _total_free_4k_blocks += (*i).blocks;
1544 Session::ensure_sound_dir (string path, string& result)
1549 /* Ensure that the parent directory exists */
1551 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1552 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1556 /* Ensure that the sounds directory exists */
1560 result += sound_dir_name;
1562 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1563 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1569 dead += dead_sound_dir_name;
1571 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1572 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1578 peak += peak_dir_name;
1580 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1581 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1585 /* callers expect this to be terminated ... */
1592 Session::discover_best_sound_dir (bool destructive)
1594 vector<space_and_path>::iterator i;
1597 /* handle common case without system calls */
1599 if (session_dirs.size() == 1) {
1603 /* OK, here's the algorithm we're following here:
1605 We want to select which directory to use for
1606 the next file source to be created. Ideally,
1607 we'd like to use a round-robin process so as to
1608 get maximum performance benefits from splitting
1609 the files across multiple disks.
1611 However, in situations without much diskspace, an
1612 RR approach may end up filling up a filesystem
1613 with new files while others still have space.
1614 Its therefore important to pay some attention to
1615 the freespace in the filesystem holding each
1616 directory as well. However, if we did that by
1617 itself, we'd keep creating new files in the file
1618 system with the most space until it was as full
1619 as all others, thus negating any performance
1620 benefits of this RAID-1 like approach.
1622 So, we use a user-configurable space threshold. If
1623 there are at least 2 filesystems with more than this
1624 much space available, we use RR selection between them.
1625 If not, then we pick the filesystem with the most space.
1627 This gets a good balance between the two
1631 refresh_disk_space ();
1633 int free_enough = 0;
1635 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1636 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1641 if (free_enough >= 2) {
1643 bool found_it = false;
1645 /* use RR selection process, ensuring that the one
1649 i = last_rr_session_dir;
1652 if (++i == session_dirs.end()) {
1653 i = session_dirs.begin();
1656 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1657 if (ensure_sound_dir ((*i).path, result) == 0) {
1658 last_rr_session_dir = i;
1664 } while (i != last_rr_session_dir);
1667 result = sound_dir();
1672 /* pick FS with the most freespace (and that
1673 seems to actually work ...)
1676 vector<space_and_path> sorted;
1677 space_and_path_ascending_cmp cmp;
1679 sorted = session_dirs;
1680 sort (sorted.begin(), sorted.end(), cmp);
1682 for (i = sorted.begin(); i != sorted.end(); ++i) {
1683 if (ensure_sound_dir ((*i).path, result) == 0) {
1684 last_rr_session_dir = i;
1689 /* if the above fails, fall back to the most simplistic solution */
1691 if (i == sorted.end()) {
1700 Session::load_playlists (const XMLNode& node)
1703 XMLNodeConstIterator niter;
1704 boost::shared_ptr<Playlist> playlist;
1706 nlist = node.children();
1710 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1712 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1713 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1721 Session::load_unused_playlists (const XMLNode& node)
1724 XMLNodeConstIterator niter;
1725 boost::shared_ptr<Playlist> playlist;
1727 nlist = node.children();
1731 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1733 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1734 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1738 // now manually untrack it
1740 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1747 boost::shared_ptr<Playlist>
1748 Session::XMLPlaylistFactory (const XMLNode& node)
1751 return PlaylistFactory::create (*this, node);
1754 catch (failed_constructor& err) {
1755 return boost::shared_ptr<Playlist>();
1760 Session::load_named_selections (const XMLNode& node)
1763 XMLNodeConstIterator niter;
1766 nlist = node.children();
1770 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1772 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1773 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1781 Session::XMLNamedSelectionFactory (const XMLNode& node)
1784 return new NamedSelection (*this, node);
1787 catch (failed_constructor& err) {
1793 Session::dead_sound_dir () const
1796 res += dead_sound_dir_name;
1802 Session::sound_dir (bool with_path) const
1804 /* support old session structure */
1806 struct stat statbuf;
1808 string old_withpath;
1810 old_nopath += old_sound_dir_name;
1813 old_withpath = _path;
1814 old_withpath += old_sound_dir_name;
1816 if (stat (old_withpath.c_str(), &statbuf) == 0) {
1818 return old_withpath;
1829 res += interchange_dir_name;
1831 res += legalize_for_path (_name);
1833 res += sound_dir_name;
1839 Session::peak_dir () const
1842 res += peak_dir_name;
1848 Session::automation_dir () const
1851 res += "automation/";
1856 Session::template_dir ()
1858 string path = get_user_ardour_path();
1859 path += "templates/";
1865 Session::suffixed_search_path (string suffix, bool data)
1869 path += get_user_ardour_path();
1870 if (path[path.length()-1] != ':') {
1875 path += get_system_data_path();
1877 path += get_system_module_path();
1880 vector<string> split_path;
1882 split (path, split_path, ':');
1885 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
1890 if (distance (i, split_path.end()) != 1) {
1899 Session::template_path ()
1901 return suffixed_search_path (X_("templates"), true);
1905 Session::control_protocol_path ()
1907 return suffixed_search_path (X_("surfaces"), false);
1911 Session::load_connections (const XMLNode& node)
1913 XMLNodeList nlist = node.children();
1914 XMLNodeConstIterator niter;
1918 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1919 if ((*niter)->name() == "InputConnection") {
1920 add_connection (new ARDOUR::InputConnection (**niter));
1921 } else if ((*niter)->name() == "OutputConnection") {
1922 add_connection (new ARDOUR::OutputConnection (**niter));
1924 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1933 Session::load_edit_groups (const XMLNode& node)
1935 return load_route_groups (node, true);
1939 Session::load_mix_groups (const XMLNode& node)
1941 return load_route_groups (node, false);
1945 Session::load_route_groups (const XMLNode& node, bool edit)
1947 XMLNodeList nlist = node.children();
1948 XMLNodeConstIterator niter;
1953 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1954 if ((*niter)->name() == "RouteGroup") {
1956 rg = add_edit_group ("");
1957 rg->set_state (**niter);
1959 rg = add_mix_group ("");
1960 rg->set_state (**niter);
1969 state_file_filter (const string &str, void *arg)
1971 return (str.length() > strlen(Session::statefile_suffix()) &&
1972 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
1976 bool operator()(const string* a, const string* b) {
1982 remove_end(string* state)
1984 string statename(*state);
1986 string::size_type start,end;
1987 if ((start = statename.find_last_of ('/')) != string::npos) {
1988 statename = statename.substr (start+1);
1991 if ((end = statename.rfind(".ardour")) == string::npos) {
1992 end = statename.length();
1995 return new string(statename.substr (0, end));
1999 Session::possible_states (string path)
2001 PathScanner scanner;
2002 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2004 transform(states->begin(), states->end(), states->begin(), remove_end);
2007 sort (states->begin(), states->end(), cmp);
2013 Session::possible_states () const
2015 return possible_states(_path);
2019 Session::auto_save()
2021 save_state (_current_snapshot_name);
2025 Session::add_edit_group (string name)
2027 RouteGroup* rg = new RouteGroup (*this, name);
2028 edit_groups.push_back (rg);
2029 edit_group_added (rg); /* EMIT SIGNAL */
2035 Session::add_mix_group (string name)
2037 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2038 mix_groups.push_back (rg);
2039 mix_group_added (rg); /* EMIT SIGNAL */
2045 Session::remove_edit_group (RouteGroup& rg)
2047 list<RouteGroup*>::iterator i;
2049 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2050 (*i)->apply (&Route::drop_edit_group, this);
2051 edit_groups.erase (i);
2052 edit_group_removed (); /* EMIT SIGNAL */
2059 Session::remove_mix_group (RouteGroup& rg)
2061 list<RouteGroup*>::iterator i;
2063 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2064 (*i)->apply (&Route::drop_mix_group, this);
2065 mix_groups.erase (i);
2066 mix_group_removed (); /* EMIT SIGNAL */
2073 Session::mix_group_by_name (string name)
2075 list<RouteGroup *>::iterator i;
2077 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2078 if ((*i)->name() == name) {
2086 Session::edit_group_by_name (string name)
2088 list<RouteGroup *>::iterator i;
2090 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2091 if ((*i)->name() == name) {
2099 Session::begin_reversible_command (string name)
2101 current_trans = new UndoTransaction;
2102 current_trans->set_name (name);
2106 Session::commit_reversible_command (Command *cmd)
2111 current_trans->add_command (cmd);
2114 gettimeofday (&now, 0);
2115 current_trans->set_timestamp (now);
2117 _history.add (current_trans);
2120 Session::GlobalRouteBooleanState
2121 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2123 GlobalRouteBooleanState s;
2124 boost::shared_ptr<RouteList> r = routes.reader ();
2126 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2127 if (!(*i)->hidden()) {
2128 RouteBooleanState v;
2131 Route* r = (*i).get();
2132 v.second = (r->*method)();
2141 Session::GlobalRouteMeterState
2142 Session::get_global_route_metering ()
2144 GlobalRouteMeterState s;
2145 boost::shared_ptr<RouteList> r = routes.reader ();
2147 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2148 if (!(*i)->hidden()) {
2152 v.second = (*i)->meter_point();
2162 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2164 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2165 i->first->set_meter_point (i->second, arg);
2170 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2172 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2173 Route* r = i->first.get();
2174 (r->*method) (i->second, arg);
2179 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2181 set_global_route_boolean (s, &Route::set_mute, src);
2185 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2187 set_global_route_boolean (s, &Route::set_solo, src);
2191 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2193 set_global_route_boolean (s, &Route::set_record_enable, src);
2198 Session::global_mute_memento (void* src)
2200 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2204 Session::global_metering_memento (void* src)
2206 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2210 Session::global_solo_memento (void* src)
2212 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2216 Session::global_record_enable_memento (void* src)
2218 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2223 template_filter (const string &str, void *arg)
2225 return (str.length() > strlen(Session::template_suffix()) &&
2226 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2230 Session::get_template_list (list<string> &template_names)
2232 vector<string *> *templates;
2233 PathScanner scanner;
2236 path = template_path ();
2238 templates = scanner (path, template_filter, 0, false, true);
2240 vector<string*>::iterator i;
2241 for (i = templates->begin(); i != templates->end(); ++i) {
2242 string fullpath = *(*i);
2245 start = fullpath.find_last_of ('/') + 1;
2246 if ((end = fullpath.find_last_of ('.')) <0) {
2247 end = fullpath.length();
2250 template_names.push_back(fullpath.substr(start, (end-start)));
2255 Session::read_favorite_dirs (FavoriteDirs & favs)
2257 string path = get_user_ardour_path();
2258 path += "/favorite_dirs";
2260 ifstream fav (path.c_str());
2265 if (errno != ENOENT) {
2266 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2277 getline(fav, newfav);
2283 favs.push_back (newfav);
2290 Session::write_favorite_dirs (FavoriteDirs & favs)
2292 string path = get_user_ardour_path();
2293 path += "/favorite_dirs";
2295 ofstream fav (path.c_str());
2301 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2302 fav << (*i) << endl;
2309 accept_all_non_peak_files (const string& path, void *arg)
2311 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2315 accept_all_state_files (const string& path, void *arg)
2317 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2321 Session::find_all_sources (string path, set<string>& result)
2326 if (!tree.read (path)) {
2330 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2335 XMLNodeConstIterator niter;
2337 nlist = node->children();
2341 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2345 if ((prop = (*niter)->property (X_("name"))) == 0) {
2349 if (prop->value()[0] == '/') {
2350 /* external file, ignore */
2354 string path = _path; /* /-terminated */
2355 path += sound_dir_name;
2357 path += prop->value();
2359 result.insert (path);
2366 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2368 PathScanner scanner;
2369 vector<string*>* state_files;
2371 string this_snapshot_path;
2377 if (ripped[ripped.length()-1] == '/') {
2378 ripped = ripped.substr (0, ripped.length() - 1);
2381 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2383 if (state_files == 0) {
2388 this_snapshot_path = _path;
2389 this_snapshot_path += _current_snapshot_name;
2390 this_snapshot_path += _statefile_suffix;
2392 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2394 if (exclude_this_snapshot && **i == this_snapshot_path) {
2398 if (find_all_sources (**i, result) < 0) {
2406 struct RegionCounter {
2407 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2408 AudioSourceList::iterator iter;
2409 boost::shared_ptr<Region> region;
2412 RegionCounter() : count (0) {}
2416 Session::cleanup_sources (Session::cleanup_report& rep)
2418 typedef map<boost::shared_ptr<Source>, RegionCounter> SourceRegionMap;
2419 SourceRegionMap dead_sources;
2421 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2422 PathScanner scanner;
2424 vector<space_and_path>::iterator i;
2425 vector<space_and_path>::iterator nexti;
2426 vector<string*>* soundfiles;
2427 vector<string> unused;
2428 set<string> all_sources;
2433 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2435 /* step 1: consider deleting all unused playlists */
2437 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2440 status = AskAboutPlaylistDeletion (*x);
2449 playlists_tbd.push_back (*x);
2453 /* leave it alone */
2458 /* now delete any that were marked for deletion */
2460 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2461 (*x)->drop_references ();
2464 playlists_tbd.clear ();
2466 /* step 2: find all un-referenced sources */
2471 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2473 /* we expect the use_count() to be at least 2: one for the shared_ptr<> in the sources
2474 list and one for the iterator. if its used by 1 region, we'd expect a value of 3.
2476 do not bother with files that are zero size, otherwise we remove the current "nascent"
2480 if (i->second.use_count() <= 3 && i->second->length() > 0) {
2482 pair<boost::shared_ptr<Source>, RegionCounter> newpair;
2484 newpair.first = i->second;
2485 newpair.second.iter = i;
2487 dead_sources.insert (newpair);
2491 /* Search the region list to find out the state of the supposedly unreferenced regions
2494 for (SourceRegionMap::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2496 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ++r) {
2498 boost::shared_ptr<AudioRegion> ar = r->second;
2500 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2502 if (ar->source (n) == i->first) {
2504 /* this region uses this source */
2506 i->second.region = ar;
2509 if (i->second.count > 1) {
2517 /* next, get rid of all regions in the region list that use any dead sources
2518 in case the sources themselves don't go away (they might be referenced in
2521 this is also where we remove the apparently unused sources from our source
2522 list. this doesn't rename them or delete them, but it means they are
2523 potential candidates for renaming after we find all soundfiles
2524 and scan for use across all snapshots (including this one).
2527 for (SourceRegionMap::iterator i = dead_sources.begin(); i != dead_sources.end(); ) {
2529 SourceRegionMap::iterator tmp;
2534 if (i->second.count == 0) {
2536 /* no regions use this source */
2538 /* remove this source from our own list to avoid us
2539 adding it to the list of all sources below
2542 audio_sources.erase (i->second.iter);
2544 } else if (i->second.count == 1) {
2546 /* the use_count for the source was 3. this means that there is only reference to it in addition to the source
2547 list and an iterator used to traverse that list. since there is a single region using the source, that
2548 must be the extra reference. this implies that its a whole-file region
2549 with no children, so remove the region and the source.
2552 remove_region (i->second.region);
2554 /* remove this source from our own list to avoid us
2555 adding it to the list of all sources below
2558 audio_sources.erase (i->second.iter);
2561 /* more than one region uses this source, do not remove it */
2562 dead_sources.erase (i);
2568 /* build a list of all the possible sound directories for the session */
2570 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2575 sound_path += (*i).path;
2576 sound_path += sound_dir (false);
2578 if (nexti != session_dirs.end()) {
2585 /* now do the same thing for the files that ended up in the sounds dir(s)
2586 but are not referenced as sources in any snapshot.
2589 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2591 if (soundfiles == 0) {
2595 /* find all sources, but don't use this snapshot because the
2596 state file on disk still references sources we may have already
2600 find_all_sources_across_snapshots (all_sources, true);
2602 /* add our current source list
2605 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2606 boost::shared_ptr<AudioFileSource> fs;
2608 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2609 all_sources.insert (fs->path());
2613 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2618 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2628 unused.push_back (spath);
2632 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2634 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2635 struct stat statbuf;
2637 rep.paths.push_back (*x);
2638 if (stat ((*x).c_str(), &statbuf) == 0) {
2639 rep.space += statbuf.st_size;
2644 /* don't move the file across filesystems, just
2645 stick it in the `dead_sound_dir_name' directory
2646 on whichever filesystem it was already on.
2649 /* XXX this is a hack ... go up 4 levels */
2651 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2652 newpath = Glib::path_get_dirname (newpath); // "session-name"
2653 newpath = Glib::path_get_dirname (newpath); // "interchange"
2654 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2657 newpath += dead_sound_dir_name;
2659 newpath += Glib::path_get_basename ((*x));
2661 if (access (newpath.c_str(), F_OK) == 0) {
2663 /* the new path already exists, try versioning */
2665 char buf[PATH_MAX+1];
2669 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2672 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2673 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2677 if (version == 999) {
2678 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2682 newpath = newpath_v;
2687 /* it doesn't exist, or we can't read it or something */
2691 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2692 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2693 (*x), newpath, strerror (errno))
2699 /* see if there an easy to find peakfile for this file, and remove it.
2702 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2703 peakpath += ".peak";
2705 if (access (peakpath.c_str(), W_OK) == 0) {
2706 if (::unlink (peakpath.c_str()) != 0) {
2707 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2708 peakpath, _path, strerror (errno))
2710 /* try to back out */
2711 rename (newpath.c_str(), _path.c_str());
2719 /* dump the history list */
2723 /* save state so we don't end up a session file
2724 referring to non-existent sources.
2730 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2735 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2737 vector<space_and_path>::iterator i;
2738 string dead_sound_dir;
2739 struct dirent* dentry;
2740 struct stat statbuf;
2746 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2748 dead_sound_dir = (*i).path;
2749 dead_sound_dir += dead_sound_dir_name;
2751 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2755 while ((dentry = readdir (dead)) != 0) {
2757 /* avoid '.' and '..' */
2759 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2760 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2766 fullpath = dead_sound_dir;
2768 fullpath += dentry->d_name;
2770 if (stat (fullpath.c_str(), &statbuf)) {
2774 if (!S_ISREG (statbuf.st_mode)) {
2778 if (unlink (fullpath.c_str())) {
2779 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2780 fullpath, strerror (errno))
2784 rep.paths.push_back (dentry->d_name);
2785 rep.space += statbuf.st_size;
2796 Session::set_dirty ()
2798 bool was_dirty = dirty();
2800 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2803 DirtyChanged(); /* EMIT SIGNAL */
2809 Session::set_clean ()
2811 bool was_dirty = dirty();
2813 _state_of_the_state = Clean;
2816 DirtyChanged(); /* EMIT SIGNAL */
2821 Session::add_controllable (Controllable* c)
2823 Glib::Mutex::Lock lm (controllables_lock);
2824 controllables.insert (c);
2828 Session::remove_controllable (Controllable* c)
2830 if (_state_of_the_state | Deletion) {
2834 Glib::Mutex::Lock lm (controllables_lock);
2836 Controllables::iterator x = controllables.find (c);
2838 if (x != controllables.end()) {
2839 controllables.erase (x);
2844 Session::controllable_by_id (const PBD::ID& id)
2846 Glib::Mutex::Lock lm (controllables_lock);
2848 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2849 if ((*i)->id() == id) {
2858 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2860 Stateful::add_instant_xml (node, dir);
2861 Config->add_instant_xml (node, get_user_ardour_path());
2866 Session::save_history (string snapshot_name)
2872 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2874 if (snapshot_name.empty()) {
2875 snapshot_name = _current_snapshot_name;
2878 xml_path = _path + snapshot_name + ".history";
2880 bak_path = xml_path + ".bak";
2882 if ((access (xml_path.c_str(), F_OK) == 0) &&
2883 (rename (xml_path.c_str(), bak_path.c_str())))
2885 error << _("could not backup old history file, current history not saved.") << endmsg;
2889 cerr << "actually writing history\n";
2891 if (!tree.write (xml_path))
2893 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2895 /* don't leave a corrupt file lying around if it is
2899 if (unlink (xml_path.c_str())) {
2900 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2902 if (rename (bak_path.c_str(), xml_path.c_str()))
2904 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2915 Session::restore_history (string snapshot_name)
2921 xmlpath = _path + snapshot_name + ".history";
2922 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2924 if (access (xmlpath.c_str(), F_OK)) {
2925 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2929 if (!tree.read (xmlpath)) {
2930 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2934 /* replace history */
2937 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2940 UndoTransaction* ut = new UndoTransaction ();
2943 ut->set_name(t->property("name")->value());
2944 stringstream ss(t->property("tv_sec")->value());
2946 ss.str(t->property("tv_usec")->value());
2948 ut->set_timestamp(tv);
2950 for (XMLNodeConstIterator child_it = t->children().begin();
2951 child_it != t->children().end();
2954 XMLNode *n = *child_it;
2957 if (n->name() == "MementoCommand" ||
2958 n->name() == "MementoUndoCommand" ||
2959 n->name() == "MementoRedoCommand") {
2960 if ((c = memento_command_factory(n))) {
2964 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2975 Session::config_changed (const char* parameter_name)
2977 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2979 if (PARAM_IS ("seamless-loop")) {
2981 } else if (PARAM_IS ("rf-speed")) {
2983 } else if (PARAM_IS ("auto-loop")) {
2985 } else if (PARAM_IS ("auto-input")) {
2987 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2988 /* auto-input only makes a difference if we're rolling */
2990 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2992 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2993 if ((*i)->record_enabled ()) {
2994 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
2995 (*i)->monitor_input (!Config->get_auto_input());
3000 } else if (PARAM_IS ("punch-in")) {
3004 if ((location = _locations.auto_punch_location()) != 0) {
3006 if (Config->get_punch_in ()) {
3007 replace_event (Event::PunchIn, location->start());
3009 remove_event (location->start(), Event::PunchIn);
3013 } else if (PARAM_IS ("punch-out")) {
3017 if ((location = _locations.auto_punch_location()) != 0) {
3019 if (Config->get_punch_out()) {
3020 replace_event (Event::PunchOut, location->end());
3022 clear_events (Event::PunchOut);
3026 } else if (PARAM_IS ("edit-mode")) {
3028 Glib::Mutex::Lock lm (playlist_lock);
3030 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3031 (*i)->set_edit_mode (Config->get_edit_mode ());
3034 } else if (PARAM_IS ("use-video-sync")) {
3036 if (transport_stopped()) {
3037 if (Config->get_use_video_sync()) {
3038 waiting_for_sync_offset = true;
3042 } else if (PARAM_IS ("mmc-control")) {
3044 poke_midi_thread ();
3046 } else if (PARAM_IS ("midi-control")) {
3048 poke_midi_thread ();
3050 } else if (PARAM_IS ("raid-path")) {
3052 setup_raid_path (Config->get_raid_path());
3054 } else if (PARAM_IS ("smpte-frames-per-second") || PARAM_IS ("smpte-drop-frames")) {
3058 } else if (PARAM_IS ("video-pullup")) {
3062 } else if (PARAM_IS ("seamless-loop")) {
3064 if (play_loop && transport_rolling()) {
3065 // to reset diskstreams etc
3066 request_play_loop (true);
3069 } else if (PARAM_IS ("rf-speed")) {
3071 cumulative_rf_motion = 0;
3074 } else if (PARAM_IS ("click-sound")) {
3076 setup_click_sounds (1);
3078 } else if (PARAM_IS ("click-emphasis-sound")) {
3080 setup_click_sounds (-1);
3082 } else if (PARAM_IS ("clicking")) {
3084 if (Config->get_clicking()) {
3085 if (_click_io && click_data) { // don't require emphasis data
3092 } else if (PARAM_IS ("send-mtc")) {
3094 /* only set the internal flag if we have
3098 if (_mtc_port != 0) {
3099 session_send_mtc = Config->get_send_mtc();
3100 if (session_send_mtc) {
3101 /* mark us ready to send */
3102 next_quarter_frame_to_send = 0;
3106 } else if (PARAM_IS ("send-mmc")) {
3108 /* only set the internal flag if we have
3112 if (_mmc_port != 0) {
3113 session_send_mmc = Config->get_send_mmc();
3116 } else if (PARAM_IS ("midi-feedback")) {
3118 /* only set the internal flag if we have
3122 if (_mtc_port != 0) {
3123 session_midi_feedback = Config->get_midi_feedback();
3126 } else if (PARAM_IS ("jack-time-master")) {
3128 engine().reset_timebase ();
3130 } else if (PARAM_IS ("native-file-header-format")) {
3132 if (!first_file_header_format_reset) {
3133 reset_native_file_format ();
3136 first_file_header_format_reset = false;
3138 } else if (PARAM_IS ("native-file-data-format")) {
3140 if (!first_file_data_format_reset) {
3141 reset_native_file_format ();
3144 first_file_data_format_reset = false;