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>
58 #include <pbd/copyfile.h>
60 #include <ardour/audioengine.h>
61 #include <ardour/configuration.h>
62 #include <ardour/session.h>
63 #include <ardour/audio_diskstream.h>
64 #include <ardour/utils.h>
65 #include <ardour/audioplaylist.h>
66 #include <ardour/audiofilesource.h>
67 #include <ardour/destructive_filesource.h>
68 #include <ardour/sndfile_helpers.h>
69 #include <ardour/auditioner.h>
70 #include <ardour/export.h>
71 #include <ardour/redirect.h>
72 #include <ardour/send.h>
73 #include <ardour/insert.h>
74 #include <ardour/connection.h>
75 #include <ardour/slave.h>
76 #include <ardour/tempo.h>
77 #include <ardour/audio_track.h>
78 #include <ardour/cycle_timer.h>
79 #include <ardour/utils.h>
80 #include <ardour/named_selection.h>
81 #include <ardour/version.h>
82 #include <ardour/location.h>
83 #include <ardour/audioregion.h>
84 #include <ardour/crossfade.h>
85 #include <ardour/control_protocol_manager.h>
86 #include <ardour/region_factory.h>
87 #include <ardour/source_factory.h>
88 #include <ardour/playlist_factory.h>
90 #include <control_protocol/control_protocol.h>
96 using namespace ARDOUR;
100 Session::first_stage_init (string fullpath, string snapshot_name)
102 if (fullpath.length() == 0) {
104 throw failed_constructor();
107 char buf[PATH_MAX+1];
108 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
109 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
111 throw failed_constructor();
116 if (_path[_path.length()-1] != '/') {
120 /* these two are just provisional settings. set_state()
121 will likely override them.
124 _name = _current_snapshot_name = snapshot_name;
126 _current_frame_rate = _engine.frame_rate ();
127 _tempo_map = new TempoMap (_current_frame_rate);
128 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
130 g_atomic_int_set (&processing_prohibited, 0);
132 _transport_speed = 0;
133 _last_transport_speed = 0;
134 transport_sub_state = 0;
135 _transport_frame = 0;
137 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
138 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
139 _end_location_is_free = true;
140 g_atomic_int_set (&_record_status, Disabled);
141 loop_changing = false;
143 _last_roll_location = 0;
144 _last_record_location = 0;
145 pending_locate_frame = 0;
146 pending_locate_roll = false;
147 pending_locate_flush = false;
148 dstream_buffer_size = 0;
150 state_was_pending = false;
152 outbound_mtc_smpte_frame = 0;
153 next_quarter_frame_to_send = -1;
154 current_block_size = 0;
155 solo_update_disabled = false;
156 currently_soloing = false;
157 _have_captured = false;
158 _worst_output_latency = 0;
159 _worst_input_latency = 0;
160 _worst_track_latency = 0;
161 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
163 butler_mixdown_buffer = 0;
164 butler_gain_buffer = 0;
166 session_send_mmc = false;
167 session_send_mtc = false;
168 post_transport_work = PostTransportWork (0);
169 g_atomic_int_set (&butler_should_do_transport_work, 0);
170 g_atomic_int_set (&butler_active, 0);
171 g_atomic_int_set (&_playback_load, 100);
172 g_atomic_int_set (&_capture_load, 100);
173 g_atomic_int_set (&_playback_load_min, 100);
174 g_atomic_int_set (&_capture_load_min, 100);
176 waiting_to_start = false;
178 _gain_automation_buffer = 0;
179 _pan_automation_buffer = 0;
181 pending_abort = false;
182 destructive_index = 0;
184 first_file_data_format_reset = true;
185 first_file_header_format_reset = true;
187 AudioDiskstream::allocate_working_buffers();
189 /* default short fade = 15ms */
191 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
192 SndFileSource::setup_standard_crossfades (frame_rate());
194 last_mmc_step.tv_sec = 0;
195 last_mmc_step.tv_usec = 0;
198 /* click sounds are unset by default, which causes us to internal
199 waveforms for clicks.
203 click_emphasis_data = 0;
205 click_emphasis_length = 0;
208 process_function = &Session::process_with_events;
210 if (Config->get_use_video_sync()) {
211 waiting_for_sync_offset = true;
213 waiting_for_sync_offset = false;
216 _current_frame_rate = 48000;
217 _base_frame_rate = 48000;
221 _smpte_offset_negative = true;
222 last_smpte_valid = false;
226 last_rr_session_dir = session_dirs.begin();
227 refresh_disk_space ();
229 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
233 average_slave_delta = 1800;
234 have_first_delta_accumulator = false;
235 delta_accumulator_cnt = 0;
236 slave_state = Stopped;
238 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
240 /* These are all static "per-class" signals */
242 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
243 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
244 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
245 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
246 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
247 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
249 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
251 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
253 /* stop IO objects from doing stuff until we're ready for them */
255 IO::disable_panners ();
256 IO::disable_ports ();
257 IO::disable_connecting ();
261 Session::second_stage_init (bool new_session)
263 AudioFileSource::set_peak_dir (peak_dir());
266 if (load_state (_current_snapshot_name)) {
269 remove_empty_sounds ();
272 if (start_butler_thread()) {
276 if (start_midi_thread ()) {
280 // set_state() will call setup_raid_path(), but if it's a new session we need
281 // to call setup_raid_path() here.
283 if (set_state (*state_tree->root())) {
287 setup_raid_path(_path);
290 /* we can't save till after ::when_engine_running() is called,
291 because otherwise we save state with no connections made.
292 therefore, we reset _state_of_the_state because ::set_state()
293 will have cleared it.
295 we also have to include Loading so that any events that get
296 generated between here and the end of ::when_engine_running()
297 will be processed directly rather than queued.
300 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
302 // set_auto_input (true);
303 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
304 _locations.added.connect (mem_fun (this, &Session::locations_added));
305 setup_click_sounds (0);
306 setup_midi_control ();
308 /* Pay attention ... */
310 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
311 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
314 when_engine_running();
317 /* handle this one in a different way than all others, so that its clear what happened */
319 catch (AudioEngine::PortRegistrationFailure& err) {
320 error << _("Unable to create all required ports")
329 send_full_time_code ();
330 _engine.transport_locate (0);
331 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
332 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
334 ControlProtocolManager::instance().set_session (*this);
337 _end_location_is_free = true;
339 _end_location_is_free = false;
346 Session::raid_path () const
350 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
355 return path.substr (0, path.length() - 1); // drop final colon
359 Session::setup_raid_path (string path)
361 string::size_type colon;
365 string::size_type len = path.length();
370 if (path.length() == 0) {
374 session_dirs.clear ();
376 for (string::size_type n = 0; n < len; ++n) {
377 if (path[n] == ':') {
384 /* no multiple search path, just one location (common case) */
388 session_dirs.push_back (sp);
395 if (fspath[fspath.length()-1] != '/') {
399 fspath += sound_dir (false);
401 AudioFileSource::set_search_path (fspath);
408 while ((colon = remaining.find_first_of (':')) != string::npos) {
411 sp.path = remaining.substr (0, colon);
412 session_dirs.push_back (sp);
414 /* add sounds to file search path */
417 if (fspath[fspath.length()-1] != '/') {
420 fspath += sound_dir (false);
423 remaining = remaining.substr (colon+1);
426 if (remaining.length()) {
433 if (fspath[fspath.length()-1] != '/') {
436 fspath += sound_dir (false);
439 session_dirs.push_back (sp);
442 /* set the AudioFileSource search path */
444 AudioFileSource::set_search_path (fspath);
446 /* reset the round-robin soundfile path thingie */
448 last_rr_session_dir = session_dirs.begin();
452 Session::create (bool& new_session, string* mix_template, nframes_t initial_length)
456 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
457 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
463 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
464 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
470 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
471 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
475 dir = dead_sound_dir ();
477 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
478 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
482 dir = automation_dir ();
484 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
485 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
490 /* check new_session so we don't overwrite an existing one */
493 std::string in_path = *mix_template;
495 ifstream in(in_path.c_str());
498 string out_path = _path;
500 out_path += _statefile_suffix;
502 ofstream out(out_path.c_str());
507 // okay, session is set up. Treat like normal saved
508 // session from now on.
514 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
520 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
527 /* set initial start + end point */
529 start_location->set_end (0);
530 _locations.add (start_location);
532 end_location->set_end (initial_length);
533 _locations.add (end_location);
535 _state_of_the_state = Clean;
537 if (save_state (_current_snapshot_name)) {
545 Session::load_diskstreams (const XMLNode& node)
548 XMLNodeConstIterator citer;
550 clist = node.children();
552 for (citer = clist.begin(); citer != clist.end(); ++citer) {
556 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
557 add_diskstream (dstream);
560 catch (failed_constructor& err) {
561 error << _("Session: could not load diskstream via XML state") << endmsg;
570 Session::remove_pending_capture_state ()
575 xml_path += _current_snapshot_name;
576 xml_path += _pending_suffix;
578 unlink (xml_path.c_str());
582 Session::save_state (string snapshot_name, bool pending)
588 if (_state_of_the_state & CannotSave) {
592 tree.set_root (&get_state());
594 if (snapshot_name.empty()) {
595 snapshot_name = _current_snapshot_name;
601 xml_path += snapshot_name;
602 xml_path += _statefile_suffix;
607 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
608 copy_file (xml_path, bak_path);
614 xml_path += snapshot_name;
615 xml_path += _pending_suffix;
622 tmp_path += snapshot_name;
625 cerr << "actually writing state\n";
627 if (!tree.write (tmp_path)) {
628 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
629 unlink (tmp_path.c_str());
634 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
635 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
636 unlink (tmp_path.c_str());
643 save_history (snapshot_name);
645 bool was_dirty = dirty();
647 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
650 DirtyChanged (); /* EMIT SIGNAL */
653 StateSaved (snapshot_name); /* EMIT SIGNAL */
660 Session::restore_state (string snapshot_name)
662 if (load_state (snapshot_name) == 0) {
663 set_state (*state_tree->root());
670 Session::load_state (string snapshot_name)
679 state_was_pending = false;
681 /* check for leftover pending state from a crashed capture attempt */
684 xmlpath += snapshot_name;
685 xmlpath += _pending_suffix;
687 if (!access (xmlpath.c_str(), F_OK)) {
689 /* there is pending state from a crashed capture attempt */
691 if (AskAboutPendingState()) {
692 state_was_pending = true;
696 if (!state_was_pending) {
699 xmlpath += snapshot_name;
700 xmlpath += _statefile_suffix;
703 if (access (xmlpath.c_str(), F_OK)) {
704 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
708 state_tree = new XMLTree;
712 if (!state_tree->read (xmlpath)) {
713 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
719 XMLNode& root (*state_tree->root());
721 if (root.name() != X_("Session")) {
722 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
728 const XMLProperty* prop;
731 if ((prop = root.property ("version")) == 0) {
732 /* no version implies very old version of Ardour */
736 major_version = atoi (prop->value()); // grab just the first number before the period
737 if (major_version < 2) {
745 backup_path = xmlpath;
748 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
749 xmlpath, backup_path)
752 copy_file (xmlpath, backup_path);
754 /* if it fails, don't worry. right? */
761 Session::load_options (const XMLNode& node)
765 LocaleGuard lg (X_("POSIX"));
767 Config->set_variables (node, ConfigVariableBase::Session);
769 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
770 if ((prop = child->property ("val")) != 0) {
771 _end_location_is_free = (prop->value() == "yes");
779 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
781 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
782 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
784 return owner & modified_by_session_or_user;
788 Session::get_options () const
791 LocaleGuard lg (X_("POSIX"));
793 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
795 child = option_root.add_child ("end-marker-is-free");
796 child->add_property ("val", _end_location_is_free ? "yes" : "no");
808 Session::get_template()
810 /* if we don't disable rec-enable, diskstreams
811 will believe they need to store their capture
812 sources in their state node.
815 disable_record (false);
821 Session::state(bool full_state)
823 XMLNode* node = new XMLNode("Session");
826 // store libardour version, just in case
828 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
829 libardour_major_version, libardour_minor_version, libardour_micro_version);
830 node->add_property("version", string(buf));
832 /* store configuration settings */
837 node->add_property ("name", _name);
839 if (session_dirs.size() > 1) {
843 vector<space_and_path>::iterator i = session_dirs.begin();
844 vector<space_and_path>::iterator next;
846 ++i; /* skip the first one */
850 while (i != session_dirs.end()) {
854 if (next != session_dirs.end()) {
864 child = node->add_child ("Path");
865 child->add_content (p);
869 /* save the ID counter */
871 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
872 node->add_property ("id-counter", buf);
874 /* various options */
876 node->add_child_nocopy (get_options());
878 child = node->add_child ("Sources");
881 Glib::Mutex::Lock sl (audio_source_lock);
883 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
885 /* Don't save information about AudioFileSources that are empty */
887 boost::shared_ptr<AudioFileSource> fs;
889 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
891 /* destructive file sources are OK if they are empty, because
892 we will re-use them every time.
895 if (!fs->destructive()) {
896 if (fs->length() == 0) {
902 child->add_child_nocopy (siter->second->get_state());
906 child = node->add_child ("Regions");
909 Glib::Mutex::Lock rl (region_lock);
911 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
913 /* only store regions not attached to playlists */
915 if (i->second->playlist() == 0) {
916 child->add_child_nocopy (i->second->state (true));
921 child = node->add_child ("DiskStreams");
924 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
925 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
926 if (!(*i)->hidden()) {
927 child->add_child_nocopy ((*i)->get_state());
933 node->add_child_nocopy (_locations.get_state());
935 // for a template, just create a new Locations, populate it
936 // with the default start and end, and get the state for that.
938 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
939 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
942 end->set_end(compute_initial_length());
944 node->add_child_nocopy (loc.get_state());
947 child = node->add_child ("Connections");
949 Glib::Mutex::Lock lm (connection_lock);
950 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
951 if (!(*i)->system_dependent()) {
952 child->add_child_nocopy ((*i)->get_state());
957 child = node->add_child ("Routes");
959 boost::shared_ptr<RouteList> r = routes.reader ();
961 RoutePublicOrderSorter cmp;
962 RouteList public_order (*r);
963 public_order.sort (cmp);
965 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
966 if (!(*i)->hidden()) {
968 child->add_child_nocopy ((*i)->get_state());
970 child->add_child_nocopy ((*i)->get_template());
977 child = node->add_child ("EditGroups");
978 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
979 child->add_child_nocopy ((*i)->get_state());
982 child = node->add_child ("MixGroups");
983 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
984 child->add_child_nocopy ((*i)->get_state());
987 child = node->add_child ("Playlists");
988 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
989 if (!(*i)->hidden()) {
990 if (!(*i)->empty()) {
992 child->add_child_nocopy ((*i)->get_state());
994 child->add_child_nocopy ((*i)->get_template());
1000 child = node->add_child ("UnusedPlaylists");
1001 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1002 if (!(*i)->hidden()) {
1003 if (!(*i)->empty()) {
1005 child->add_child_nocopy ((*i)->get_state());
1007 child->add_child_nocopy ((*i)->get_template());
1015 child = node->add_child ("Click");
1016 child->add_child_nocopy (_click_io->state (full_state));
1020 child = node->add_child ("NamedSelections");
1021 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1023 child->add_child_nocopy ((*i)->get_state());
1028 node->add_child_nocopy (_tempo_map->get_state());
1030 node->add_child_nocopy (get_control_protocol_state());
1033 node->add_child_copy (*_extra_xml);
1040 Session::get_control_protocol_state ()
1042 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1043 XMLNode* node = new XMLNode (X_("ControlProtocols"));
1045 cpm.foreach_known_protocol (bind (mem_fun (*this, &Session::add_control_protocol), node));
1051 Session::add_control_protocol (const ControlProtocolInfo* const cpi, XMLNode* node)
1053 if (cpi->protocol) {
1054 node->add_child_nocopy (cpi->protocol->get_state());
1059 Session::set_state (const XMLNode& node)
1063 const XMLProperty* prop;
1066 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1068 if (node.name() != X_("Session")){
1069 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1073 if ((prop = node.property ("name")) != 0) {
1074 _name = prop->value ();
1077 setup_raid_path(_path);
1079 if ((prop = node.property (X_("id-counter"))) != 0) {
1081 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1082 ID::init_counter (x);
1084 /* old sessions used a timebased counter, so fake
1085 the startup ID counter based on a standard
1090 ID::init_counter (now);
1094 IO::disable_ports ();
1095 IO::disable_connecting ();
1097 /* Object loading order:
1115 if (use_config_midi_ports ()) {
1118 if ((child = find_named_node (node, "extra")) != 0) {
1119 _extra_xml = new XMLNode (*child);
1122 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1123 load_options (*child);
1124 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1125 load_options (*child);
1127 error << _("Session: XML state has no options section") << endmsg;
1130 if ((child = find_named_node (node, "Locations")) == 0) {
1131 error << _("Session: XML state has no locations section") << endmsg;
1133 } else if (_locations.set_state (*child)) {
1139 if ((location = _locations.auto_loop_location()) != 0) {
1140 set_auto_loop_location (location);
1143 if ((location = _locations.auto_punch_location()) != 0) {
1144 set_auto_punch_location (location);
1147 if ((location = _locations.end_location()) == 0) {
1148 _locations.add (end_location);
1150 delete end_location;
1151 end_location = location;
1154 if ((location = _locations.start_location()) == 0) {
1155 _locations.add (start_location);
1157 delete start_location;
1158 start_location = location;
1161 AudioFileSource::set_header_position_offset (start_location->start());
1163 if ((child = find_named_node (node, "Sources")) == 0) {
1164 error << _("Session: XML state has no sources section") << endmsg;
1166 } else if (load_sources (*child)) {
1170 if ((child = find_named_node (node, "Regions")) == 0) {
1171 error << _("Session: XML state has no Regions section") << endmsg;
1173 } else if (load_regions (*child)) {
1177 if ((child = find_named_node (node, "Playlists")) == 0) {
1178 error << _("Session: XML state has no playlists section") << endmsg;
1180 } else if (load_playlists (*child)) {
1184 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1186 } else if (load_unused_playlists (*child)) {
1190 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1191 if (load_named_selections (*child)) {
1196 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1197 error << _("Session: XML state has no diskstreams section") << endmsg;
1199 } else if (load_diskstreams (*child)) {
1203 if ((child = find_named_node (node, "Connections")) == 0) {
1204 error << _("Session: XML state has no connections section") << endmsg;
1206 } else if (load_connections (*child)) {
1210 if ((child = find_named_node (node, "EditGroups")) == 0) {
1211 error << _("Session: XML state has no edit groups section") << endmsg;
1213 } else if (load_edit_groups (*child)) {
1217 if ((child = find_named_node (node, "MixGroups")) == 0) {
1218 error << _("Session: XML state has no mix groups section") << endmsg;
1220 } else if (load_mix_groups (*child)) {
1224 if ((child = find_named_node (node, "TempoMap")) == 0) {
1225 error << _("Session: XML state has no Tempo Map section") << endmsg;
1227 } else if (_tempo_map->set_state (*child)) {
1231 if ((child = find_named_node (node, "Routes")) == 0) {
1232 error << _("Session: XML state has no routes section") << endmsg;
1234 } else if (load_routes (*child)) {
1238 if ((child = find_named_node (node, "Click")) == 0) {
1239 warning << _("Session: XML state has no click section") << endmsg;
1240 } else if (_click_io) {
1241 _click_io->set_state (*child);
1244 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1245 ControlProtocolManager::instance().set_protocol_states (*child);
1248 /* here beginneth the second phase ... */
1250 StateReady (); /* EMIT SIGNAL */
1252 _state_of_the_state = Clean;
1254 if (state_was_pending) {
1255 save_state (_current_snapshot_name);
1256 remove_pending_capture_state ();
1257 state_was_pending = false;
1267 Session::load_routes (const XMLNode& node)
1270 XMLNodeConstIterator niter;
1271 RouteList new_routes;
1273 nlist = node.children();
1277 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1279 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1282 error << _("Session: cannot create Route from XML description.") << endmsg;
1286 new_routes.push_back (route);
1289 add_routes (new_routes);
1294 boost::shared_ptr<Route>
1295 Session::XMLRouteFactory (const XMLNode& node)
1297 if (node.name() != "Route") {
1298 return boost::shared_ptr<Route> ((Route*) 0);
1301 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1302 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1305 boost::shared_ptr<Route> x (new Route (*this, node));
1311 Session::load_regions (const XMLNode& node)
1314 XMLNodeConstIterator niter;
1315 boost::shared_ptr<AudioRegion> region;
1317 nlist = node.children();
1321 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1322 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1323 error << _("Session: cannot create Region from XML description.") << endmsg;
1330 boost::shared_ptr<AudioRegion>
1331 Session::XMLRegionFactory (const XMLNode& node, bool full)
1333 const XMLProperty* prop;
1334 boost::shared_ptr<Source> source;
1335 boost::shared_ptr<AudioSource> as;
1337 uint32_t nchans = 1;
1340 if (node.name() != X_("Region")) {
1341 return boost::shared_ptr<AudioRegion>();
1344 if ((prop = node.property (X_("channels"))) != 0) {
1345 nchans = atoi (prop->value().c_str());
1349 if ((prop = node.property ("name")) == 0) {
1350 cerr << "no name for this region\n";
1354 if ((prop = node.property (X_("source-0"))) == 0) {
1355 if ((prop = node.property ("source")) == 0) {
1356 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1357 return boost::shared_ptr<AudioRegion>();
1361 PBD::ID s_id (prop->value());
1363 if ((source = source_by_id (s_id)) == 0) {
1364 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1365 return boost::shared_ptr<AudioRegion>();
1368 as = boost::dynamic_pointer_cast<AudioSource>(source);
1370 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1371 return boost::shared_ptr<AudioRegion>();
1374 sources.push_back (as);
1376 /* pickup other channels */
1378 for (uint32_t n=1; n < nchans; ++n) {
1379 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1380 if ((prop = node.property (buf)) != 0) {
1382 PBD::ID id2 (prop->value());
1384 if ((source = source_by_id (id2)) == 0) {
1385 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1386 return boost::shared_ptr<AudioRegion>();
1389 as = boost::dynamic_pointer_cast<AudioSource>(source);
1391 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1392 return boost::shared_ptr<AudioRegion>();
1394 sources.push_back (as);
1399 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1404 catch (failed_constructor& err) {
1405 return boost::shared_ptr<AudioRegion>();
1410 Session::get_sources_as_xml ()
1413 XMLNode* node = new XMLNode (X_("Sources"));
1414 Glib::Mutex::Lock lm (audio_source_lock);
1416 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1417 node->add_child_nocopy (i->second->get_state());
1420 /* XXX get MIDI and other sources here */
1426 Session::path_from_region_name (string name, string identifier)
1428 char buf[PATH_MAX+1];
1430 string dir = discover_best_sound_dir ();
1432 for (n = 0; n < 999999; ++n) {
1433 if (identifier.length()) {
1434 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1435 identifier.c_str(), n);
1437 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1439 if (access (buf, F_OK) != 0) {
1449 Session::load_sources (const XMLNode& node)
1452 XMLNodeConstIterator niter;
1453 boost::shared_ptr<Source> source;
1455 nlist = node.children();
1459 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1461 if ((source = XMLSourceFactory (**niter)) == 0) {
1462 error << _("Session: cannot create Source from XML description.") << endmsg;
1470 boost::shared_ptr<Source>
1471 Session::XMLSourceFactory (const XMLNode& node)
1473 if (node.name() != "Source") {
1474 return boost::shared_ptr<Source>();
1478 return SourceFactory::create (*this, node);
1481 catch (failed_constructor& err) {
1482 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1483 return boost::shared_ptr<Source>();
1488 Session::save_template (string template_name)
1491 string xml_path, bak_path, template_path;
1493 if (_state_of_the_state & CannotSave) {
1498 string dir = template_dir();
1500 if ((dp = opendir (dir.c_str()))) {
1503 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1504 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1509 tree.set_root (&get_template());
1512 xml_path += template_name;
1513 xml_path += _template_suffix;
1515 ifstream in(xml_path.c_str());
1518 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1524 if (!tree.write (xml_path)) {
1525 error << _("mix template not saved") << endmsg;
1533 Session::rename_template (string old_name, string new_name)
1535 string old_path = template_dir() + old_name + _template_suffix;
1536 string new_path = template_dir() + new_name + _template_suffix;
1538 return rename (old_path.c_str(), new_path.c_str());
1542 Session::delete_template (string name)
1544 string template_path = template_dir();
1545 template_path += name;
1546 template_path += _template_suffix;
1548 return remove (template_path.c_str());
1552 Session::refresh_disk_space ()
1555 struct statfs statfsbuf;
1556 vector<space_and_path>::iterator i;
1557 Glib::Mutex::Lock lm (space_lock);
1560 /* get freespace on every FS that is part of the session path */
1562 _total_free_4k_blocks = 0;
1564 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1565 statfs ((*i).path.c_str(), &statfsbuf);
1567 scale = statfsbuf.f_bsize/4096.0;
1569 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1570 _total_free_4k_blocks += (*i).blocks;
1576 Session::ensure_sound_dir (string path, string& result)
1581 /* Ensure that the parent directory exists */
1583 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1584 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1588 /* Ensure that the sounds directory exists */
1592 result += sound_dir_name;
1594 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1595 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1601 dead += dead_sound_dir_name;
1603 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1604 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1610 peak += peak_dir_name;
1612 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1613 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1617 /* callers expect this to be terminated ... */
1624 Session::discover_best_sound_dir (bool destructive)
1626 vector<space_and_path>::iterator i;
1629 /* handle common case without system calls */
1631 if (session_dirs.size() == 1) {
1635 /* OK, here's the algorithm we're following here:
1637 We want to select which directory to use for
1638 the next file source to be created. Ideally,
1639 we'd like to use a round-robin process so as to
1640 get maximum performance benefits from splitting
1641 the files across multiple disks.
1643 However, in situations without much diskspace, an
1644 RR approach may end up filling up a filesystem
1645 with new files while others still have space.
1646 Its therefore important to pay some attention to
1647 the freespace in the filesystem holding each
1648 directory as well. However, if we did that by
1649 itself, we'd keep creating new files in the file
1650 system with the most space until it was as full
1651 as all others, thus negating any performance
1652 benefits of this RAID-1 like approach.
1654 So, we use a user-configurable space threshold. If
1655 there are at least 2 filesystems with more than this
1656 much space available, we use RR selection between them.
1657 If not, then we pick the filesystem with the most space.
1659 This gets a good balance between the two
1663 refresh_disk_space ();
1665 int free_enough = 0;
1667 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1668 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1673 if (free_enough >= 2) {
1675 bool found_it = false;
1677 /* use RR selection process, ensuring that the one
1681 i = last_rr_session_dir;
1684 if (++i == session_dirs.end()) {
1685 i = session_dirs.begin();
1688 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1689 if (ensure_sound_dir ((*i).path, result) == 0) {
1690 last_rr_session_dir = i;
1696 } while (i != last_rr_session_dir);
1699 result = sound_dir();
1704 /* pick FS with the most freespace (and that
1705 seems to actually work ...)
1708 vector<space_and_path> sorted;
1709 space_and_path_ascending_cmp cmp;
1711 sorted = session_dirs;
1712 sort (sorted.begin(), sorted.end(), cmp);
1714 for (i = sorted.begin(); i != sorted.end(); ++i) {
1715 if (ensure_sound_dir ((*i).path, result) == 0) {
1716 last_rr_session_dir = i;
1721 /* if the above fails, fall back to the most simplistic solution */
1723 if (i == sorted.end()) {
1732 Session::load_playlists (const XMLNode& node)
1735 XMLNodeConstIterator niter;
1736 boost::shared_ptr<Playlist> playlist;
1738 nlist = node.children();
1742 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1744 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1745 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1753 Session::load_unused_playlists (const XMLNode& node)
1756 XMLNodeConstIterator niter;
1757 boost::shared_ptr<Playlist> playlist;
1759 nlist = node.children();
1763 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1765 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1766 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1770 // now manually untrack it
1772 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1779 boost::shared_ptr<Playlist>
1780 Session::XMLPlaylistFactory (const XMLNode& node)
1783 return PlaylistFactory::create (*this, node);
1786 catch (failed_constructor& err) {
1787 return boost::shared_ptr<Playlist>();
1792 Session::load_named_selections (const XMLNode& node)
1795 XMLNodeConstIterator niter;
1798 nlist = node.children();
1802 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1804 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1805 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1813 Session::XMLNamedSelectionFactory (const XMLNode& node)
1816 return new NamedSelection (*this, node);
1819 catch (failed_constructor& err) {
1825 Session::dead_sound_dir () const
1828 res += dead_sound_dir_name;
1834 Session::sound_dir (bool with_path) const
1836 /* support old session structure */
1838 struct stat statbuf;
1840 string old_withpath;
1842 old_nopath += old_sound_dir_name;
1845 old_withpath = _path;
1846 old_withpath += old_sound_dir_name;
1848 if (stat (old_withpath.c_str(), &statbuf) == 0) {
1850 return old_withpath;
1861 res += interchange_dir_name;
1863 res += legalize_for_path (_name);
1865 res += sound_dir_name;
1871 Session::peak_dir () const
1874 res += peak_dir_name;
1880 Session::automation_dir () const
1883 res += "automation/";
1888 Session::template_dir ()
1890 string path = get_user_ardour_path();
1891 path += "templates/";
1897 Session::suffixed_search_path (string suffix, bool data)
1901 path += get_user_ardour_path();
1902 if (path[path.length()-1] != ':') {
1907 path += get_system_data_path();
1909 path += get_system_module_path();
1912 vector<string> split_path;
1914 split (path, split_path, ':');
1917 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
1922 if (distance (i, split_path.end()) != 1) {
1931 Session::template_path ()
1933 return suffixed_search_path (X_("templates"), true);
1937 Session::control_protocol_path ()
1939 return suffixed_search_path (X_("surfaces"), false);
1943 Session::load_connections (const XMLNode& node)
1945 XMLNodeList nlist = node.children();
1946 XMLNodeConstIterator niter;
1950 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1951 if ((*niter)->name() == "InputConnection") {
1952 add_connection (new ARDOUR::InputConnection (**niter));
1953 } else if ((*niter)->name() == "OutputConnection") {
1954 add_connection (new ARDOUR::OutputConnection (**niter));
1956 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1965 Session::load_edit_groups (const XMLNode& node)
1967 return load_route_groups (node, true);
1971 Session::load_mix_groups (const XMLNode& node)
1973 return load_route_groups (node, false);
1977 Session::load_route_groups (const XMLNode& node, bool edit)
1979 XMLNodeList nlist = node.children();
1980 XMLNodeConstIterator niter;
1985 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1986 if ((*niter)->name() == "RouteGroup") {
1988 rg = add_edit_group ("");
1989 rg->set_state (**niter);
1991 rg = add_mix_group ("");
1992 rg->set_state (**niter);
2001 state_file_filter (const string &str, void *arg)
2003 return (str.length() > strlen(Session::statefile_suffix()) &&
2004 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2008 bool operator()(const string* a, const string* b) {
2014 remove_end(string* state)
2016 string statename(*state);
2018 string::size_type start,end;
2019 if ((start = statename.find_last_of ('/')) != string::npos) {
2020 statename = statename.substr (start+1);
2023 if ((end = statename.rfind(".ardour")) == string::npos) {
2024 end = statename.length();
2027 return new string(statename.substr (0, end));
2031 Session::possible_states (string path)
2033 PathScanner scanner;
2034 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2036 transform(states->begin(), states->end(), states->begin(), remove_end);
2039 sort (states->begin(), states->end(), cmp);
2045 Session::possible_states () const
2047 return possible_states(_path);
2051 Session::auto_save()
2053 save_state (_current_snapshot_name);
2057 Session::add_edit_group (string name)
2059 RouteGroup* rg = new RouteGroup (*this, name);
2060 edit_groups.push_back (rg);
2061 edit_group_added (rg); /* EMIT SIGNAL */
2067 Session::add_mix_group (string name)
2069 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2070 mix_groups.push_back (rg);
2071 mix_group_added (rg); /* EMIT SIGNAL */
2077 Session::remove_edit_group (RouteGroup& rg)
2079 list<RouteGroup*>::iterator i;
2081 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2082 (*i)->apply (&Route::drop_edit_group, this);
2083 edit_groups.erase (i);
2084 edit_group_removed (); /* EMIT SIGNAL */
2091 Session::remove_mix_group (RouteGroup& rg)
2093 list<RouteGroup*>::iterator i;
2095 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2096 (*i)->apply (&Route::drop_mix_group, this);
2097 mix_groups.erase (i);
2098 mix_group_removed (); /* EMIT SIGNAL */
2105 Session::mix_group_by_name (string name)
2107 list<RouteGroup *>::iterator i;
2109 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2110 if ((*i)->name() == name) {
2118 Session::edit_group_by_name (string name)
2120 list<RouteGroup *>::iterator i;
2122 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2123 if ((*i)->name() == name) {
2131 Session::begin_reversible_command (string name)
2133 current_trans = new UndoTransaction;
2134 current_trans->set_name (name);
2138 Session::commit_reversible_command (Command *cmd)
2143 current_trans->add_command (cmd);
2146 gettimeofday (&now, 0);
2147 current_trans->set_timestamp (now);
2149 _history.add (current_trans);
2152 Session::GlobalRouteBooleanState
2153 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2155 GlobalRouteBooleanState s;
2156 boost::shared_ptr<RouteList> r = routes.reader ();
2158 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2159 if (!(*i)->hidden()) {
2160 RouteBooleanState v;
2163 Route* r = (*i).get();
2164 v.second = (r->*method)();
2173 Session::GlobalRouteMeterState
2174 Session::get_global_route_metering ()
2176 GlobalRouteMeterState s;
2177 boost::shared_ptr<RouteList> r = routes.reader ();
2179 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2180 if (!(*i)->hidden()) {
2184 v.second = (*i)->meter_point();
2194 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2196 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2198 boost::shared_ptr<Route> r = (i->first.lock());
2201 r->set_meter_point (i->second, arg);
2207 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2209 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2211 boost::shared_ptr<Route> r = (i->first.lock());
2214 Route* rp = r.get();
2215 (rp->*method) (i->second, arg);
2221 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2223 set_global_route_boolean (s, &Route::set_mute, src);
2227 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2229 set_global_route_boolean (s, &Route::set_solo, src);
2233 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2235 set_global_route_boolean (s, &Route::set_record_enable, src);
2240 Session::global_mute_memento (void* src)
2242 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2246 Session::global_metering_memento (void* src)
2248 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2252 Session::global_solo_memento (void* src)
2254 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2258 Session::global_record_enable_memento (void* src)
2260 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2265 template_filter (const string &str, void *arg)
2267 return (str.length() > strlen(Session::template_suffix()) &&
2268 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2272 Session::get_template_list (list<string> &template_names)
2274 vector<string *> *templates;
2275 PathScanner scanner;
2278 path = template_path ();
2280 templates = scanner (path, template_filter, 0, false, true);
2282 vector<string*>::iterator i;
2283 for (i = templates->begin(); i != templates->end(); ++i) {
2284 string fullpath = *(*i);
2287 start = fullpath.find_last_of ('/') + 1;
2288 if ((end = fullpath.find_last_of ('.')) <0) {
2289 end = fullpath.length();
2292 template_names.push_back(fullpath.substr(start, (end-start)));
2297 Session::read_favorite_dirs (FavoriteDirs & favs)
2299 string path = get_user_ardour_path();
2300 path += "/favorite_dirs";
2302 ifstream fav (path.c_str());
2307 if (errno != ENOENT) {
2308 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2319 getline(fav, newfav);
2325 favs.push_back (newfav);
2332 Session::write_favorite_dirs (FavoriteDirs & favs)
2334 string path = get_user_ardour_path();
2335 path += "/favorite_dirs";
2337 ofstream fav (path.c_str());
2343 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2344 fav << (*i) << endl;
2351 accept_all_non_peak_files (const string& path, void *arg)
2353 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2357 accept_all_state_files (const string& path, void *arg)
2359 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2363 Session::find_all_sources (string path, set<string>& result)
2368 if (!tree.read (path)) {
2372 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2377 XMLNodeConstIterator niter;
2379 nlist = node->children();
2383 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2387 if ((prop = (*niter)->property (X_("name"))) == 0) {
2391 if (prop->value()[0] == '/') {
2392 /* external file, ignore */
2396 string path = _path; /* /-terminated */
2397 path += sound_dir_name;
2399 path += prop->value();
2401 result.insert (path);
2408 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2410 PathScanner scanner;
2411 vector<string*>* state_files;
2413 string this_snapshot_path;
2419 if (ripped[ripped.length()-1] == '/') {
2420 ripped = ripped.substr (0, ripped.length() - 1);
2423 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2425 if (state_files == 0) {
2430 this_snapshot_path = _path;
2431 this_snapshot_path += _current_snapshot_name;
2432 this_snapshot_path += _statefile_suffix;
2434 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2436 if (exclude_this_snapshot && **i == this_snapshot_path) {
2440 if (find_all_sources (**i, result) < 0) {
2448 struct RegionCounter {
2449 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2450 AudioSourceList::iterator iter;
2451 boost::shared_ptr<Region> region;
2454 RegionCounter() : count (0) {}
2458 Session::cleanup_sources (Session::cleanup_report& rep)
2460 typedef map<boost::shared_ptr<Source>, RegionCounter> SourceRegionMap;
2461 SourceRegionMap dead_sources;
2463 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2464 PathScanner scanner;
2466 vector<space_and_path>::iterator i;
2467 vector<space_and_path>::iterator nexti;
2468 vector<string*>* soundfiles;
2469 vector<string> unused;
2470 set<string> all_sources;
2475 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2477 /* step 1: consider deleting all unused playlists */
2479 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2482 status = AskAboutPlaylistDeletion (*x);
2491 playlists_tbd.push_back (*x);
2495 /* leave it alone */
2500 /* now delete any that were marked for deletion */
2502 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2503 (*x)->drop_references ();
2506 playlists_tbd.clear ();
2508 /* step 2: find all un-referenced sources */
2513 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2515 /* we expect the use_count() to be at least 2: one for the shared_ptr<> in the sources
2516 list and one for the iterator. if its used by 1 region, we'd expect a value of 3.
2518 do not bother with files that are zero size, otherwise we remove the current "nascent"
2522 if (i->second.use_count() <= 3 && i->second->length() > 0) {
2524 pair<boost::shared_ptr<Source>, RegionCounter> newpair;
2526 newpair.first = i->second;
2527 newpair.second.iter = i;
2529 dead_sources.insert (newpair);
2533 /* Search the region list to find out the state of the supposedly unreferenced regions
2536 for (SourceRegionMap::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
2538 for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ++r) {
2540 boost::shared_ptr<AudioRegion> ar = r->second;
2542 for (uint32_t n = 0; n < ar->n_channels(); ++n) {
2544 if (ar->source (n) == i->first) {
2546 /* this region uses this source */
2548 i->second.region = ar;
2551 if (i->second.count > 1) {
2559 /* next, get rid of all regions in the region list that use any dead sources
2560 in case the sources themselves don't go away (they might be referenced in
2563 this is also where we remove the apparently unused sources from our source
2564 list. this doesn't rename them or delete them, but it means they are
2565 potential candidates for renaming after we find all soundfiles
2566 and scan for use across all snapshots (including this one).
2569 for (SourceRegionMap::iterator i = dead_sources.begin(); i != dead_sources.end(); ) {
2571 SourceRegionMap::iterator tmp;
2576 if (i->second.count == 0) {
2578 /* no regions use this source */
2580 /* remove this source from our own list to avoid us
2581 adding it to the list of all sources below
2584 audio_sources.erase (i->second.iter);
2586 } else if (i->second.count == 1) {
2588 /* the use_count for the source was 3. this means that there is only reference to it in addition to the source
2589 list and an iterator used to traverse that list. since there is a single region using the source, that
2590 must be the extra reference. this implies that its a whole-file region
2591 with no children, so remove the region and the source.
2594 remove_region (i->second.region);
2596 /* remove this source from our own list to avoid us
2597 adding it to the list of all sources below
2600 audio_sources.erase (i->second.iter);
2603 /* more than one region uses this source, do not remove it */
2604 dead_sources.erase (i);
2610 /* build a list of all the possible sound directories for the session */
2612 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2617 sound_path += (*i).path;
2618 sound_path += sound_dir (false);
2620 if (nexti != session_dirs.end()) {
2627 /* now do the same thing for the files that ended up in the sounds dir(s)
2628 but are not referenced as sources in any snapshot.
2631 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2633 if (soundfiles == 0) {
2637 /* find all sources, but don't use this snapshot because the
2638 state file on disk still references sources we may have already
2642 find_all_sources_across_snapshots (all_sources, true);
2644 /* add our current source list
2647 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2648 boost::shared_ptr<AudioFileSource> fs;
2650 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2651 all_sources.insert (fs->path());
2655 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2660 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2670 unused.push_back (spath);
2674 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2676 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2677 struct stat statbuf;
2679 rep.paths.push_back (*x);
2680 if (stat ((*x).c_str(), &statbuf) == 0) {
2681 rep.space += statbuf.st_size;
2686 /* don't move the file across filesystems, just
2687 stick it in the `dead_sound_dir_name' directory
2688 on whichever filesystem it was already on.
2691 /* XXX this is a hack ... go up 4 levels */
2693 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2694 newpath = Glib::path_get_dirname (newpath); // "session-name"
2695 newpath = Glib::path_get_dirname (newpath); // "interchange"
2696 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2699 newpath += dead_sound_dir_name;
2701 newpath += Glib::path_get_basename ((*x));
2703 if (access (newpath.c_str(), F_OK) == 0) {
2705 /* the new path already exists, try versioning */
2707 char buf[PATH_MAX+1];
2711 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2714 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2715 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2719 if (version == 999) {
2720 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2724 newpath = newpath_v;
2729 /* it doesn't exist, or we can't read it or something */
2733 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2734 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2735 (*x), newpath, strerror (errno))
2741 /* see if there an easy to find peakfile for this file, and remove it.
2744 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2745 peakpath += ".peak";
2747 if (access (peakpath.c_str(), W_OK) == 0) {
2748 if (::unlink (peakpath.c_str()) != 0) {
2749 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2750 peakpath, _path, strerror (errno))
2752 /* try to back out */
2753 rename (newpath.c_str(), _path.c_str());
2761 /* dump the history list */
2765 /* save state so we don't end up a session file
2766 referring to non-existent sources.
2772 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2777 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2779 vector<space_and_path>::iterator i;
2780 string dead_sound_dir;
2781 struct dirent* dentry;
2782 struct stat statbuf;
2788 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2790 dead_sound_dir = (*i).path;
2791 dead_sound_dir += dead_sound_dir_name;
2793 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2797 while ((dentry = readdir (dead)) != 0) {
2799 /* avoid '.' and '..' */
2801 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2802 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2808 fullpath = dead_sound_dir;
2810 fullpath += dentry->d_name;
2812 if (stat (fullpath.c_str(), &statbuf)) {
2816 if (!S_ISREG (statbuf.st_mode)) {
2820 if (unlink (fullpath.c_str())) {
2821 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2822 fullpath, strerror (errno))
2826 rep.paths.push_back (dentry->d_name);
2827 rep.space += statbuf.st_size;
2838 Session::set_dirty ()
2840 bool was_dirty = dirty();
2842 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2845 DirtyChanged(); /* EMIT SIGNAL */
2851 Session::set_clean ()
2853 bool was_dirty = dirty();
2855 _state_of_the_state = Clean;
2858 DirtyChanged(); /* EMIT SIGNAL */
2863 Session::set_deletion_in_progress ()
2865 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2869 Session::add_controllable (Controllable* c)
2871 Glib::Mutex::Lock lm (controllables_lock);
2872 controllables.insert (c);
2876 Session::remove_controllable (Controllable* c)
2878 if (_state_of_the_state | Deletion) {
2882 Glib::Mutex::Lock lm (controllables_lock);
2884 Controllables::iterator x = controllables.find (c);
2886 if (x != controllables.end()) {
2887 controllables.erase (x);
2892 Session::controllable_by_id (const PBD::ID& id)
2894 Glib::Mutex::Lock lm (controllables_lock);
2896 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2897 if ((*i)->id() == id) {
2906 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2908 Stateful::add_instant_xml (node, dir);
2909 Config->add_instant_xml (node, get_user_ardour_path());
2914 Session::save_history (string snapshot_name)
2920 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2922 if (snapshot_name.empty()) {
2923 snapshot_name = _current_snapshot_name;
2926 xml_path = _path + snapshot_name + ".history";
2928 bak_path = xml_path + ".bak";
2930 if ((access (xml_path.c_str(), F_OK) == 0) &&
2931 (rename (xml_path.c_str(), bak_path.c_str())))
2933 error << _("could not backup old history file, current history not saved.") << endmsg;
2937 cerr << "actually writing history\n";
2939 if (!tree.write (xml_path))
2941 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2943 /* don't leave a corrupt file lying around if it is
2947 if (unlink (xml_path.c_str())) {
2948 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2950 if (rename (bak_path.c_str(), xml_path.c_str()))
2952 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2963 Session::restore_history (string snapshot_name)
2968 if (snapshot_name.empty()) {
2969 snapshot_name = _current_snapshot_name;
2973 xmlpath = _path + snapshot_name + ".history";
2974 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2976 if (access (xmlpath.c_str(), F_OK)) {
2977 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2981 if (!tree.read (xmlpath)) {
2982 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2986 /* replace history */
2989 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2992 UndoTransaction* ut = new UndoTransaction ();
2995 ut->set_name(t->property("name")->value());
2996 stringstream ss(t->property("tv_sec")->value());
2998 ss.str(t->property("tv_usec")->value());
3000 ut->set_timestamp(tv);
3002 for (XMLNodeConstIterator child_it = t->children().begin();
3003 child_it != t->children().end();
3006 XMLNode *n = *child_it;
3009 if (n->name() == "MementoCommand" ||
3010 n->name() == "MementoUndoCommand" ||
3011 n->name() == "MementoRedoCommand") {
3013 if ((c = memento_command_factory(n))) {
3017 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3019 if ((c = global_state_command_factory (*n))) {
3020 ut->add_command (c);
3025 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3036 Session::config_changed (const char* parameter_name)
3038 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3040 if (PARAM_IS ("seamless-loop")) {
3042 } else if (PARAM_IS ("rf-speed")) {
3044 } else if (PARAM_IS ("auto-loop")) {
3046 } else if (PARAM_IS ("auto-input")) {
3048 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3049 /* auto-input only makes a difference if we're rolling */
3051 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3053 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3054 if ((*i)->record_enabled ()) {
3055 (*i)->monitor_input (!Config->get_auto_input());
3060 } else if (PARAM_IS ("punch-in")) {
3064 if ((location = _locations.auto_punch_location()) != 0) {
3066 if (Config->get_punch_in ()) {
3067 replace_event (Event::PunchIn, location->start());
3069 remove_event (location->start(), Event::PunchIn);
3073 } else if (PARAM_IS ("punch-out")) {
3077 if ((location = _locations.auto_punch_location()) != 0) {
3079 if (Config->get_punch_out()) {
3080 replace_event (Event::PunchOut, location->end());
3082 clear_events (Event::PunchOut);
3086 } else if (PARAM_IS ("edit-mode")) {
3088 Glib::Mutex::Lock lm (playlist_lock);
3090 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3091 (*i)->set_edit_mode (Config->get_edit_mode ());
3094 } else if (PARAM_IS ("use-video-sync")) {
3096 if (transport_stopped()) {
3097 if (Config->get_use_video_sync()) {
3098 waiting_for_sync_offset = true;
3102 } else if (PARAM_IS ("mmc-control")) {
3104 poke_midi_thread ();
3106 } else if (PARAM_IS ("midi-control")) {
3108 poke_midi_thread ();
3110 } else if (PARAM_IS ("raid-path")) {
3112 setup_raid_path (Config->get_raid_path());
3114 } else if (PARAM_IS ("smpte-format")) {
3118 } else if (PARAM_IS ("video-pullup")) {
3122 } else if (PARAM_IS ("seamless-loop")) {
3124 if (play_loop && transport_rolling()) {
3125 // to reset diskstreams etc
3126 request_play_loop (true);
3129 } else if (PARAM_IS ("rf-speed")) {
3131 cumulative_rf_motion = 0;
3134 } else if (PARAM_IS ("click-sound")) {
3136 setup_click_sounds (1);
3138 } else if (PARAM_IS ("click-emphasis-sound")) {
3140 setup_click_sounds (-1);
3142 } else if (PARAM_IS ("clicking")) {
3144 if (Config->get_clicking()) {
3145 if (_click_io && click_data) { // don't require emphasis data
3152 } else if (PARAM_IS ("send-mtc")) {
3154 /* only set the internal flag if we have
3158 if (_mtc_port != 0) {
3159 session_send_mtc = Config->get_send_mtc();
3160 if (session_send_mtc) {
3161 /* mark us ready to send */
3162 next_quarter_frame_to_send = 0;
3166 } else if (PARAM_IS ("send-mmc")) {
3168 /* only set the internal flag if we have
3172 if (_mmc_port != 0) {
3173 session_send_mmc = Config->get_send_mmc();
3176 } else if (PARAM_IS ("midi-feedback")) {
3178 /* only set the internal flag if we have
3182 if (_mtc_port != 0) {
3183 session_midi_feedback = Config->get_midi_feedback();
3186 } else if (PARAM_IS ("jack-time-master")) {
3188 engine().reset_timebase ();
3190 } else if (PARAM_IS ("native-file-header-format")) {
3192 if (!first_file_header_format_reset) {
3193 reset_native_file_format ();
3196 first_file_header_format_reset = false;
3198 } else if (PARAM_IS ("native-file-data-format")) {
3200 if (!first_file_data_format_reset) {
3201 reset_native_file_format ();
3204 first_file_data_format_reset = false;