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;
1222 if (state_was_pending) {
1223 save_state (_current_snapshot_name);
1224 remove_pending_capture_state ();
1225 state_was_pending = false;
1235 Session::load_routes (const XMLNode& node)
1238 XMLNodeConstIterator niter;
1239 RouteList new_routes;
1241 nlist = node.children();
1245 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1247 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1250 error << _("Session: cannot create Route from XML description.") << endmsg;
1254 new_routes.push_back (route);
1257 add_routes (new_routes);
1262 boost::shared_ptr<Route>
1263 Session::XMLRouteFactory (const XMLNode& node)
1265 if (node.name() != "Route") {
1266 return boost::shared_ptr<Route> ((Route*) 0);
1269 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1270 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1273 boost::shared_ptr<Route> x (new Route (*this, node));
1279 Session::load_regions (const XMLNode& node)
1282 XMLNodeConstIterator niter;
1283 boost::shared_ptr<AudioRegion> region;
1285 nlist = node.children();
1289 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1290 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1291 error << _("Session: cannot create Region from XML description.") << endmsg;
1298 boost::shared_ptr<AudioRegion>
1299 Session::XMLRegionFactory (const XMLNode& node, bool full)
1301 const XMLProperty* prop;
1302 boost::shared_ptr<Source> source;
1303 boost::shared_ptr<AudioSource> as;
1305 uint32_t nchans = 1;
1308 if (node.name() != X_("Region")) {
1309 return boost::shared_ptr<AudioRegion>();
1312 if ((prop = node.property (X_("channels"))) != 0) {
1313 nchans = atoi (prop->value().c_str());
1317 if ((prop = node.property ("name")) == 0) {
1318 cerr << "no name for this region\n";
1322 if ((prop = node.property (X_("source-0"))) == 0) {
1323 if ((prop = node.property ("source")) == 0) {
1324 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1325 return boost::shared_ptr<AudioRegion>();
1329 PBD::ID s_id (prop->value());
1331 if ((source = source_by_id (s_id)) == 0) {
1332 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1333 return boost::shared_ptr<AudioRegion>();
1336 as = boost::dynamic_pointer_cast<AudioSource>(source);
1338 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1339 return boost::shared_ptr<AudioRegion>();
1342 sources.push_back (as);
1344 /* pickup other channels */
1346 for (uint32_t n=1; n < nchans; ++n) {
1347 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1348 if ((prop = node.property (buf)) != 0) {
1350 PBD::ID id2 (prop->value());
1352 if ((source = source_by_id (id2)) == 0) {
1353 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1354 return boost::shared_ptr<AudioRegion>();
1357 as = boost::dynamic_pointer_cast<AudioSource>(source);
1359 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1360 return boost::shared_ptr<AudioRegion>();
1362 sources.push_back (as);
1367 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1372 catch (failed_constructor& err) {
1373 return boost::shared_ptr<AudioRegion>();
1378 Session::get_sources_as_xml ()
1381 XMLNode* node = new XMLNode (X_("Sources"));
1382 Glib::Mutex::Lock lm (audio_source_lock);
1384 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1385 node->add_child_nocopy (i->second->get_state());
1388 /* XXX get MIDI and other sources here */
1394 Session::path_from_region_name (string name, string identifier)
1396 char buf[PATH_MAX+1];
1398 string dir = discover_best_sound_dir ();
1400 for (n = 0; n < 999999; ++n) {
1401 if (identifier.length()) {
1402 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1403 identifier.c_str(), n);
1405 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1407 if (access (buf, F_OK) != 0) {
1417 Session::load_sources (const XMLNode& node)
1420 XMLNodeConstIterator niter;
1421 boost::shared_ptr<Source> source;
1423 nlist = node.children();
1427 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1429 if ((source = XMLSourceFactory (**niter)) == 0) {
1430 error << _("Session: cannot create Source from XML description.") << endmsg;
1437 boost::shared_ptr<Source>
1438 Session::XMLSourceFactory (const XMLNode& node)
1440 if (node.name() != "Source") {
1441 return boost::shared_ptr<Source>();
1445 return SourceFactory::create (*this, node);
1448 catch (failed_constructor& err) {
1449 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1450 return boost::shared_ptr<Source>();
1455 Session::save_template (string template_name)
1458 string xml_path, bak_path, template_path;
1460 if (_state_of_the_state & CannotSave) {
1465 string dir = template_dir();
1467 if ((dp = opendir (dir.c_str()))) {
1470 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1471 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1476 tree.set_root (&get_template());
1479 xml_path += template_name;
1480 xml_path += _template_suffix;
1482 ifstream in(xml_path.c_str());
1485 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1491 if (!tree.write (xml_path)) {
1492 error << _("mix template not saved") << endmsg;
1500 Session::rename_template (string old_name, string new_name)
1502 string old_path = template_dir() + old_name + _template_suffix;
1503 string new_path = template_dir() + new_name + _template_suffix;
1505 return rename (old_path.c_str(), new_path.c_str());
1509 Session::delete_template (string name)
1511 string template_path = template_dir();
1512 template_path += name;
1513 template_path += _template_suffix;
1515 return remove (template_path.c_str());
1519 Session::refresh_disk_space ()
1522 struct statfs statfsbuf;
1523 vector<space_and_path>::iterator i;
1524 Glib::Mutex::Lock lm (space_lock);
1527 /* get freespace on every FS that is part of the session path */
1529 _total_free_4k_blocks = 0;
1531 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1532 statfs ((*i).path.c_str(), &statfsbuf);
1534 scale = statfsbuf.f_bsize/4096.0;
1536 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1537 _total_free_4k_blocks += (*i).blocks;
1543 Session::ensure_sound_dir (string path, string& result)
1548 /* Ensure that the parent directory exists */
1550 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1551 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1555 /* Ensure that the sounds directory exists */
1559 result += sound_dir_name;
1561 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1562 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1568 dead += dead_sound_dir_name;
1570 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1571 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1577 peak += peak_dir_name;
1579 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1580 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1584 /* callers expect this to be terminated ... */
1591 Session::discover_best_sound_dir (bool destructive)
1593 vector<space_and_path>::iterator i;
1596 /* handle common case without system calls */
1598 if (session_dirs.size() == 1) {
1602 /* OK, here's the algorithm we're following here:
1604 We want to select which directory to use for
1605 the next file source to be created. Ideally,
1606 we'd like to use a round-robin process so as to
1607 get maximum performance benefits from splitting
1608 the files across multiple disks.
1610 However, in situations without much diskspace, an
1611 RR approach may end up filling up a filesystem
1612 with new files while others still have space.
1613 Its therefore important to pay some attention to
1614 the freespace in the filesystem holding each
1615 directory as well. However, if we did that by
1616 itself, we'd keep creating new files in the file
1617 system with the most space until it was as full
1618 as all others, thus negating any performance
1619 benefits of this RAID-1 like approach.
1621 So, we use a user-configurable space threshold. If
1622 there are at least 2 filesystems with more than this
1623 much space available, we use RR selection between them.
1624 If not, then we pick the filesystem with the most space.
1626 This gets a good balance between the two
1630 refresh_disk_space ();
1632 int free_enough = 0;
1634 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1635 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1640 if (free_enough >= 2) {
1642 bool found_it = false;
1644 /* use RR selection process, ensuring that the one
1648 i = last_rr_session_dir;
1651 if (++i == session_dirs.end()) {
1652 i = session_dirs.begin();
1655 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1656 if (ensure_sound_dir ((*i).path, result) == 0) {
1657 last_rr_session_dir = i;
1663 } while (i != last_rr_session_dir);
1666 result = sound_dir();
1671 /* pick FS with the most freespace (and that
1672 seems to actually work ...)
1675 vector<space_and_path> sorted;
1676 space_and_path_ascending_cmp cmp;
1678 sorted = session_dirs;
1679 sort (sorted.begin(), sorted.end(), cmp);
1681 for (i = sorted.begin(); i != sorted.end(); ++i) {
1682 if (ensure_sound_dir ((*i).path, result) == 0) {
1683 last_rr_session_dir = i;
1688 /* if the above fails, fall back to the most simplistic solution */
1690 if (i == sorted.end()) {
1699 Session::load_playlists (const XMLNode& node)
1702 XMLNodeConstIterator niter;
1703 boost::shared_ptr<Playlist> playlist;
1705 nlist = node.children();
1709 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1711 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1712 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1720 Session::load_unused_playlists (const XMLNode& node)
1723 XMLNodeConstIterator niter;
1724 boost::shared_ptr<Playlist> playlist;
1726 nlist = node.children();
1730 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1732 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1733 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1737 // now manually untrack it
1739 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1746 boost::shared_ptr<Playlist>
1747 Session::XMLPlaylistFactory (const XMLNode& node)
1750 return PlaylistFactory::create (*this, node);
1753 catch (failed_constructor& err) {
1754 return boost::shared_ptr<Playlist>();
1759 Session::load_named_selections (const XMLNode& node)
1762 XMLNodeConstIterator niter;
1765 nlist = node.children();
1769 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1771 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1772 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1780 Session::XMLNamedSelectionFactory (const XMLNode& node)
1783 return new NamedSelection (*this, node);
1786 catch (failed_constructor& err) {
1792 Session::dead_sound_dir () const
1795 res += dead_sound_dir_name;
1801 Session::sound_dir (bool with_path) const
1803 /* support old session structure */
1805 struct stat statbuf;
1807 string old_withpath;
1809 old_nopath += old_sound_dir_name;
1812 old_withpath = _path;
1813 old_withpath += old_sound_dir_name;
1815 if (stat (old_withpath.c_str(), &statbuf) == 0) {
1817 return old_withpath;
1828 res += interchange_dir_name;
1830 res += legalize_for_path (_name);
1832 res += sound_dir_name;
1838 Session::peak_dir () const
1841 res += peak_dir_name;
1847 Session::automation_dir () const
1850 res += "automation/";
1855 Session::template_dir ()
1857 string path = get_user_ardour_path();
1858 path += "templates/";
1864 Session::suffixed_search_path (string suffix, bool data)
1868 path += get_user_ardour_path();
1869 if (path[path.length()-1] != ':') {
1874 path += get_system_data_path();
1876 path += get_system_module_path();
1879 vector<string> split_path;
1881 split (path, split_path, ':');
1884 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
1889 if (distance (i, split_path.end()) != 1) {
1898 Session::template_path ()
1900 return suffixed_search_path (X_("templates"), true);
1904 Session::control_protocol_path ()
1906 return suffixed_search_path (X_("surfaces"), false);
1910 Session::load_connections (const XMLNode& node)
1912 XMLNodeList nlist = node.children();
1913 XMLNodeConstIterator niter;
1917 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1918 if ((*niter)->name() == "InputConnection") {
1919 add_connection (new ARDOUR::InputConnection (**niter));
1920 } else if ((*niter)->name() == "OutputConnection") {
1921 add_connection (new ARDOUR::OutputConnection (**niter));
1923 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1932 Session::load_edit_groups (const XMLNode& node)
1934 return load_route_groups (node, true);
1938 Session::load_mix_groups (const XMLNode& node)
1940 return load_route_groups (node, false);
1944 Session::load_route_groups (const XMLNode& node, bool edit)
1946 XMLNodeList nlist = node.children();
1947 XMLNodeConstIterator niter;
1952 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1953 if ((*niter)->name() == "RouteGroup") {
1955 rg = add_edit_group ("");
1956 rg->set_state (**niter);
1958 rg = add_mix_group ("");
1959 rg->set_state (**niter);
1968 state_file_filter (const string &str, void *arg)
1970 return (str.length() > strlen(Session::statefile_suffix()) &&
1971 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
1975 bool operator()(const string* a, const string* b) {
1981 remove_end(string* state)
1983 string statename(*state);
1985 string::size_type start,end;
1986 if ((start = statename.find_last_of ('/')) != string::npos) {
1987 statename = statename.substr (start+1);
1990 if ((end = statename.rfind(".ardour")) == string::npos) {
1991 end = statename.length();
1994 return new string(statename.substr (0, end));
1998 Session::possible_states (string path)
2000 PathScanner scanner;
2001 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2003 transform(states->begin(), states->end(), states->begin(), remove_end);
2006 sort (states->begin(), states->end(), cmp);
2012 Session::possible_states () const
2014 return possible_states(_path);
2018 Session::auto_save()
2020 save_state (_current_snapshot_name);
2024 Session::add_edit_group (string name)
2026 RouteGroup* rg = new RouteGroup (*this, name);
2027 edit_groups.push_back (rg);
2028 edit_group_added (rg); /* EMIT SIGNAL */
2034 Session::add_mix_group (string name)
2036 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2037 mix_groups.push_back (rg);
2038 mix_group_added (rg); /* EMIT SIGNAL */
2044 Session::remove_edit_group (RouteGroup& rg)
2046 list<RouteGroup*>::iterator i;
2048 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2049 (*i)->apply (&Route::drop_edit_group, this);
2050 edit_groups.erase (i);
2051 edit_group_removed (); /* EMIT SIGNAL */
2058 Session::remove_mix_group (RouteGroup& rg)
2060 list<RouteGroup*>::iterator i;
2062 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2063 (*i)->apply (&Route::drop_mix_group, this);
2064 mix_groups.erase (i);
2065 mix_group_removed (); /* EMIT SIGNAL */
2072 Session::mix_group_by_name (string name)
2074 list<RouteGroup *>::iterator i;
2076 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2077 if ((*i)->name() == name) {
2085 Session::edit_group_by_name (string name)
2087 list<RouteGroup *>::iterator i;
2089 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2090 if ((*i)->name() == name) {
2098 Session::begin_reversible_command (string name)
2100 current_trans = new UndoTransaction;
2101 current_trans->set_name (name);
2105 Session::commit_reversible_command (Command *cmd)
2110 current_trans->add_command (cmd);
2113 gettimeofday (&now, 0);
2114 current_trans->set_timestamp (now);
2116 _history.add (current_trans);
2119 Session::GlobalRouteBooleanState
2120 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2122 GlobalRouteBooleanState s;
2123 boost::shared_ptr<RouteList> r = routes.reader ();
2125 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2126 if (!(*i)->hidden()) {
2127 RouteBooleanState v;
2130 Route* r = (*i).get();
2131 v.second = (r->*method)();
2140 Session::GlobalRouteMeterState
2141 Session::get_global_route_metering ()
2143 GlobalRouteMeterState s;
2144 boost::shared_ptr<RouteList> r = routes.reader ();
2146 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2147 if (!(*i)->hidden()) {
2151 v.second = (*i)->meter_point();
2161 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2163 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2164 i->first->set_meter_point (i->second, arg);
2169 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2171 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2172 Route* r = i->first.get();
2173 (r->*method) (i->second, arg);
2178 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2180 set_global_route_boolean (s, &Route::set_mute, src);
2184 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2186 set_global_route_boolean (s, &Route::set_solo, src);
2190 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2192 set_global_route_boolean (s, &Route::set_record_enable, src);
2197 Session::global_mute_memento (void* src)
2199 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2203 Session::global_metering_memento (void* src)
2205 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2209 Session::global_solo_memento (void* src)
2211 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2215 Session::global_record_enable_memento (void* src)
2217 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2222 template_filter (const string &str, void *arg)
2224 return (str.length() > strlen(Session::template_suffix()) &&
2225 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2229 Session::get_template_list (list<string> &template_names)
2231 vector<string *> *templates;
2232 PathScanner scanner;
2235 path = template_path ();
2237 templates = scanner (path, template_filter, 0, false, true);
2239 vector<string*>::iterator i;
2240 for (i = templates->begin(); i != templates->end(); ++i) {
2241 string fullpath = *(*i);
2244 start = fullpath.find_last_of ('/') + 1;
2245 if ((end = fullpath.find_last_of ('.')) <0) {
2246 end = fullpath.length();
2249 template_names.push_back(fullpath.substr(start, (end-start)));
2254 Session::read_favorite_dirs (FavoriteDirs & favs)
2256 string path = get_user_ardour_path();
2257 path += "/favorite_dirs";
2259 ifstream fav (path.c_str());
2264 if (errno != ENOENT) {
2265 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2276 getline(fav, newfav);
2282 favs.push_back (newfav);
2289 Session::write_favorite_dirs (FavoriteDirs & favs)
2291 string path = get_user_ardour_path();
2292 path += "/favorite_dirs";
2294 ofstream fav (path.c_str());
2300 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2301 fav << (*i) << endl;
2308 accept_all_non_peak_files (const string& path, void *arg)
2310 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2314 accept_all_state_files (const string& path, void *arg)
2316 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2320 Session::find_all_sources (string path, set<string>& result)
2325 if (!tree.read (path)) {
2329 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2334 XMLNodeConstIterator niter;
2336 nlist = node->children();
2340 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2344 if ((prop = (*niter)->property (X_("name"))) == 0) {
2348 if (prop->value()[0] == '/') {
2349 /* external file, ignore */
2353 string path = _path; /* /-terminated */
2354 path += sound_dir_name;
2356 path += prop->value();
2358 result.insert (path);
2365 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2367 PathScanner scanner;
2368 vector<string*>* state_files;
2370 string this_snapshot_path;
2376 if (ripped[ripped.length()-1] == '/') {
2377 ripped = ripped.substr (0, ripped.length() - 1);
2380 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2382 if (state_files == 0) {
2387 this_snapshot_path = _path;
2388 this_snapshot_path += _current_snapshot_name;
2389 this_snapshot_path += _statefile_suffix;
2391 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2393 if (exclude_this_snapshot && **i == this_snapshot_path) {
2397 if (find_all_sources (**i, result) < 0) {
2405 struct RegionCounter {
2406 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2407 AudioSourceList::iterator iter;
2408 boost::shared_ptr<Region> region;
2411 RegionCounter() : count (0) {}
2415 Session::cleanup_sources (Session::cleanup_report& rep)
2417 typedef map<boost::shared_ptr<Source>, RegionCounter> SourceRegionMap;
2418 SourceRegionMap dead_sources;
2420 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2421 PathScanner scanner;
2423 vector<space_and_path>::iterator i;
2424 vector<space_and_path>::iterator nexti;
2425 vector<string*>* soundfiles;
2426 vector<string> unused;
2427 set<string> all_sources;
2432 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2434 /* step 1: consider deleting all unused playlists */
2436 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2439 status = AskAboutPlaylistDeletion (*x);
2448 playlists_tbd.push_back (*x);
2452 /* leave it alone */
2457 /* now delete any that were marked for deletion */
2459 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2460 (*x)->drop_references ();
2463 playlists_tbd.clear ();
2465 /* step 2: find all un-referenced sources */
2470 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2472 /* we expect the use_count() to be at least 2: one for the shared_ptr<> in the sources
2473 list and one for the iterator. if its used by 1 region, we'd expect a value of 3.
2475 do not bother with files that are zero size, otherwise we remove the current "nascent"
2479 if (i->second.use_count() <= 3 && i->second->length() > 0) {
2481 pair<boost::shared_ptr<Source>, RegionCounter> newpair;
2483 newpair.first = i->second;
2484 newpair.second.iter = i;
2486 dead_sources.insert (newpair);
2490 /* Search the region list to find out the state of the supposedly unreferenced regions
2493 for (SourceRegionMap::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2495 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ++r) {
2497 boost::shared_ptr<AudioRegion> ar = r->second;
2499 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2501 if (ar->source (n) == i->first) {
2503 /* this region uses this source */
2505 i->second.region = ar;
2508 if (i->second.count > 1) {
2516 /* next, get rid of all regions in the region list that use any dead sources
2517 in case the sources themselves don't go away (they might be referenced in
2520 this is also where we remove the apparently unused sources from our source
2521 list. this doesn't rename them or delete them, but it means they are
2522 potential candidates for renaming after we find all soundfiles
2523 and scan for use across all snapshots (including this one).
2526 for (SourceRegionMap::iterator i = dead_sources.begin(); i != dead_sources.end(); ) {
2528 SourceRegionMap::iterator tmp;
2533 if (i->second.count == 0) {
2535 /* no regions use this source */
2537 /* remove this source from our own list to avoid us
2538 adding it to the list of all sources below
2541 audio_sources.erase (i->second.iter);
2543 } else if (i->second.count == 1) {
2545 /* the use_count for the source was 3. this means that there is only reference to it in addition to the source
2546 list and an iterator used to traverse that list. since there is a single region using the source, that
2547 must be the extra reference. this implies that its a whole-file region
2548 with no children, so remove the region and the source.
2551 remove_region (i->second.region);
2553 /* remove this source from our own list to avoid us
2554 adding it to the list of all sources below
2557 audio_sources.erase (i->second.iter);
2560 /* more than one region uses this source, do not remove it */
2561 dead_sources.erase (i);
2567 /* build a list of all the possible sound directories for the session */
2569 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2574 sound_path += (*i).path;
2575 sound_path += sound_dir (false);
2577 if (nexti != session_dirs.end()) {
2584 /* now do the same thing for the files that ended up in the sounds dir(s)
2585 but are not referenced as sources in any snapshot.
2588 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2590 if (soundfiles == 0) {
2594 /* find all sources, but don't use this snapshot because the
2595 state file on disk still references sources we may have already
2599 find_all_sources_across_snapshots (all_sources, true);
2601 /* add our current source list
2604 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2605 boost::shared_ptr<AudioFileSource> fs;
2607 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2608 all_sources.insert (fs->path());
2612 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2617 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2627 unused.push_back (spath);
2631 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2633 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2634 struct stat statbuf;
2636 rep.paths.push_back (*x);
2637 if (stat ((*x).c_str(), &statbuf) == 0) {
2638 rep.space += statbuf.st_size;
2643 /* don't move the file across filesystems, just
2644 stick it in the `dead_sound_dir_name' directory
2645 on whichever filesystem it was already on.
2648 /* XXX this is a hack ... go up 4 levels */
2650 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2651 newpath = Glib::path_get_dirname (newpath); // "session-name"
2652 newpath = Glib::path_get_dirname (newpath); // "interchange"
2653 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2656 newpath += dead_sound_dir_name;
2658 newpath += Glib::path_get_basename ((*x));
2660 if (access (newpath.c_str(), F_OK) == 0) {
2662 /* the new path already exists, try versioning */
2664 char buf[PATH_MAX+1];
2668 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2671 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2672 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2676 if (version == 999) {
2677 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2681 newpath = newpath_v;
2686 /* it doesn't exist, or we can't read it or something */
2690 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2691 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2692 (*x), newpath, strerror (errno))
2698 /* see if there an easy to find peakfile for this file, and remove it.
2701 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2702 peakpath += ".peak";
2704 if (access (peakpath.c_str(), W_OK) == 0) {
2705 if (::unlink (peakpath.c_str()) != 0) {
2706 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2707 peakpath, _path, strerror (errno))
2709 /* try to back out */
2710 rename (newpath.c_str(), _path.c_str());
2718 /* dump the history list */
2722 /* save state so we don't end up a session file
2723 referring to non-existent sources.
2729 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2734 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2736 vector<space_and_path>::iterator i;
2737 string dead_sound_dir;
2738 struct dirent* dentry;
2739 struct stat statbuf;
2745 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2747 dead_sound_dir = (*i).path;
2748 dead_sound_dir += dead_sound_dir_name;
2750 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2754 while ((dentry = readdir (dead)) != 0) {
2756 /* avoid '.' and '..' */
2758 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2759 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2765 fullpath = dead_sound_dir;
2767 fullpath += dentry->d_name;
2769 if (stat (fullpath.c_str(), &statbuf)) {
2773 if (!S_ISREG (statbuf.st_mode)) {
2777 if (unlink (fullpath.c_str())) {
2778 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2779 fullpath, strerror (errno))
2783 rep.paths.push_back (dentry->d_name);
2784 rep.space += statbuf.st_size;
2795 Session::set_dirty ()
2797 bool was_dirty = dirty();
2799 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2802 DirtyChanged(); /* EMIT SIGNAL */
2808 Session::set_clean ()
2810 bool was_dirty = dirty();
2812 _state_of_the_state = Clean;
2815 DirtyChanged(); /* EMIT SIGNAL */
2820 Session::set_deletion_in_progress ()
2822 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2826 Session::add_controllable (Controllable* c)
2828 Glib::Mutex::Lock lm (controllables_lock);
2829 controllables.insert (c);
2833 Session::remove_controllable (Controllable* c)
2835 if (_state_of_the_state | Deletion) {
2839 Glib::Mutex::Lock lm (controllables_lock);
2841 Controllables::iterator x = controllables.find (c);
2843 if (x != controllables.end()) {
2844 controllables.erase (x);
2849 Session::controllable_by_id (const PBD::ID& id)
2851 Glib::Mutex::Lock lm (controllables_lock);
2853 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2854 if ((*i)->id() == id) {
2863 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2865 Stateful::add_instant_xml (node, dir);
2866 Config->add_instant_xml (node, get_user_ardour_path());
2871 Session::save_history (string snapshot_name)
2877 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2879 if (snapshot_name.empty()) {
2880 snapshot_name = _current_snapshot_name;
2883 xml_path = _path + snapshot_name + ".history";
2885 bak_path = xml_path + ".bak";
2887 if ((access (xml_path.c_str(), F_OK) == 0) &&
2888 (rename (xml_path.c_str(), bak_path.c_str())))
2890 error << _("could not backup old history file, current history not saved.") << endmsg;
2894 cerr << "actually writing history\n";
2896 if (!tree.write (xml_path))
2898 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2900 /* don't leave a corrupt file lying around if it is
2904 if (unlink (xml_path.c_str())) {
2905 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2907 if (rename (bak_path.c_str(), xml_path.c_str()))
2909 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2920 Session::restore_history (string snapshot_name)
2925 if (snapshot_name.empty()) {
2926 snapshot_name = _current_snapshot_name;
2930 xmlpath = _path + snapshot_name + ".history";
2931 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2933 if (access (xmlpath.c_str(), F_OK)) {
2934 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2938 if (!tree.read (xmlpath)) {
2939 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2943 /* replace history */
2946 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2949 UndoTransaction* ut = new UndoTransaction ();
2952 ut->set_name(t->property("name")->value());
2953 stringstream ss(t->property("tv_sec")->value());
2955 ss.str(t->property("tv_usec")->value());
2957 ut->set_timestamp(tv);
2959 for (XMLNodeConstIterator child_it = t->children().begin();
2960 child_it != t->children().end();
2963 XMLNode *n = *child_it;
2966 if (n->name() == "MementoCommand" ||
2967 n->name() == "MementoUndoCommand" ||
2968 n->name() == "MementoRedoCommand") {
2970 if ((c = memento_command_factory(n))) {
2974 } else if (n->name() == "GlobalRecordEnableStateCommand" ||
2975 n->name() == "GlobalSoloStateCommand" ||
2976 n->name() == "GlobalMuteStateCommand") {
2978 if ((c = global_state_command_factory (n))) {
2979 ut->add_command (c);
2984 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2995 Session::config_changed (const char* parameter_name)
2997 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2999 if (PARAM_IS ("seamless-loop")) {
3001 } else if (PARAM_IS ("rf-speed")) {
3003 } else if (PARAM_IS ("auto-loop")) {
3005 } else if (PARAM_IS ("auto-input")) {
3007 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3008 /* auto-input only makes a difference if we're rolling */
3010 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3012 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3013 if ((*i)->record_enabled ()) {
3014 //cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
3015 (*i)->monitor_input (!Config->get_auto_input());
3020 } else if (PARAM_IS ("punch-in")) {
3024 if ((location = _locations.auto_punch_location()) != 0) {
3026 if (Config->get_punch_in ()) {
3027 replace_event (Event::PunchIn, location->start());
3029 remove_event (location->start(), Event::PunchIn);
3033 } else if (PARAM_IS ("punch-out")) {
3037 if ((location = _locations.auto_punch_location()) != 0) {
3039 if (Config->get_punch_out()) {
3040 replace_event (Event::PunchOut, location->end());
3042 clear_events (Event::PunchOut);
3046 } else if (PARAM_IS ("edit-mode")) {
3048 Glib::Mutex::Lock lm (playlist_lock);
3050 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3051 (*i)->set_edit_mode (Config->get_edit_mode ());
3054 } else if (PARAM_IS ("use-video-sync")) {
3056 if (transport_stopped()) {
3057 if (Config->get_use_video_sync()) {
3058 waiting_for_sync_offset = true;
3062 } else if (PARAM_IS ("mmc-control")) {
3064 poke_midi_thread ();
3066 } else if (PARAM_IS ("midi-control")) {
3068 poke_midi_thread ();
3070 } else if (PARAM_IS ("raid-path")) {
3072 setup_raid_path (Config->get_raid_path());
3074 } else if (PARAM_IS ("smpte-frames-per-second") || PARAM_IS ("smpte-drop-frames")) {
3078 } else if (PARAM_IS ("video-pullup")) {
3082 } else if (PARAM_IS ("seamless-loop")) {
3084 if (play_loop && transport_rolling()) {
3085 // to reset diskstreams etc
3086 request_play_loop (true);
3089 } else if (PARAM_IS ("rf-speed")) {
3091 cumulative_rf_motion = 0;
3094 } else if (PARAM_IS ("click-sound")) {
3096 setup_click_sounds (1);
3098 } else if (PARAM_IS ("click-emphasis-sound")) {
3100 setup_click_sounds (-1);
3102 } else if (PARAM_IS ("clicking")) {
3104 if (Config->get_clicking()) {
3105 if (_click_io && click_data) { // don't require emphasis data
3112 } else if (PARAM_IS ("send-mtc")) {
3114 /* only set the internal flag if we have
3118 if (_mtc_port != 0) {
3119 session_send_mtc = Config->get_send_mtc();
3120 if (session_send_mtc) {
3121 /* mark us ready to send */
3122 next_quarter_frame_to_send = 0;
3126 } else if (PARAM_IS ("send-mmc")) {
3128 /* only set the internal flag if we have
3132 if (_mmc_port != 0) {
3133 session_send_mmc = Config->get_send_mmc();
3136 } else if (PARAM_IS ("midi-feedback")) {
3138 /* only set the internal flag if we have
3142 if (_mtc_port != 0) {
3143 session_midi_feedback = Config->get_midi_feedback();
3146 } else if (PARAM_IS ("jack-time-master")) {
3148 engine().reset_timebase ();
3150 } else if (PARAM_IS ("native-file-header-format")) {
3152 if (!first_file_header_format_reset) {
3153 reset_native_file_format ();
3156 first_file_header_format_reset = false;
3158 } else if (PARAM_IS ("native-file-data-format")) {
3160 if (!first_file_data_format_reset) {
3161 reset_native_file_format ();
3164 first_file_data_format_reset = false;