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 vector<boost::shared_ptr<Source> > dead_sources;
2461 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2462 PathScanner scanner;
2464 vector<space_and_path>::iterator i;
2465 vector<space_and_path>::iterator nexti;
2466 vector<string*>* soundfiles;
2467 vector<string> unused;
2468 set<string> all_sources;
2473 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2475 /* step 1: consider deleting all unused playlists */
2477 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2480 status = AskAboutPlaylistDeletion (*x);
2489 playlists_tbd.push_back (*x);
2493 /* leave it alone */
2498 /* now delete any that were marked for deletion */
2500 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2501 (*x)->drop_references ();
2504 playlists_tbd.clear ();
2506 /* step 2: find all un-used sources */
2511 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2513 AudioSourceList::iterator tmp;
2518 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2522 if (!i->second->used() && i->second->length() > 0) {
2523 dead_sources.push_back (i->second);
2524 i->second->GoingAway();
2530 /* build a list of all the possible sound directories for the session */
2532 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2537 sound_path += (*i).path;
2538 sound_path += sound_dir (false);
2540 if (nexti != session_dirs.end()) {
2547 /* now do the same thing for the files that ended up in the sounds dir(s)
2548 but are not referenced as sources in any snapshot.
2551 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2553 if (soundfiles == 0) {
2557 /* find all sources, but don't use this snapshot because the
2558 state file on disk still references sources we may have already
2562 find_all_sources_across_snapshots (all_sources, true);
2564 /* add our current source list
2567 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2568 boost::shared_ptr<AudioFileSource> fs;
2570 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2571 all_sources.insert (fs->path());
2575 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2580 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2589 unused.push_back (spath);
2593 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2595 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2596 struct stat statbuf;
2598 rep.paths.push_back (*x);
2599 if (stat ((*x).c_str(), &statbuf) == 0) {
2600 rep.space += statbuf.st_size;
2605 /* don't move the file across filesystems, just
2606 stick it in the `dead_sound_dir_name' directory
2607 on whichever filesystem it was already on.
2610 if (_path.find ("/sounds/")) {
2612 /* old school, go up 1 level */
2614 newpath = Glib::path_get_dirname (*x); // "sounds"
2615 newpath = Glib::path_get_dirname (newpath); // "session-name"
2619 /* new school, go up 4 levels */
2621 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2622 newpath = Glib::path_get_dirname (newpath); // "session-name"
2623 newpath = Glib::path_get_dirname (newpath); // "interchange"
2624 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2628 newpath += dead_sound_dir_name;
2630 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2631 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2636 newpath += Glib::path_get_basename ((*x));
2638 if (access (newpath.c_str(), F_OK) == 0) {
2640 /* the new path already exists, try versioning */
2642 char buf[PATH_MAX+1];
2646 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2649 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2650 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2654 if (version == 999) {
2655 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2659 newpath = newpath_v;
2664 /* it doesn't exist, or we can't read it or something */
2668 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2669 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2670 (*x), newpath, strerror (errno))
2675 /* see if there an easy to find peakfile for this file, and remove it.
2678 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2679 peakpath += ".peak";
2681 if (access (peakpath.c_str(), W_OK) == 0) {
2682 if (::unlink (peakpath.c_str()) != 0) {
2683 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2684 peakpath, _path, strerror (errno))
2686 /* try to back out */
2687 rename (newpath.c_str(), _path.c_str());
2695 /* dump the history list */
2699 /* save state so we don't end up a session file
2700 referring to non-existent sources.
2706 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2711 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2713 vector<space_and_path>::iterator i;
2714 string dead_sound_dir;
2715 struct dirent* dentry;
2716 struct stat statbuf;
2722 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2724 dead_sound_dir = (*i).path;
2725 dead_sound_dir += dead_sound_dir_name;
2727 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2731 while ((dentry = readdir (dead)) != 0) {
2733 /* avoid '.' and '..' */
2735 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2736 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2742 fullpath = dead_sound_dir;
2744 fullpath += dentry->d_name;
2746 if (stat (fullpath.c_str(), &statbuf)) {
2750 if (!S_ISREG (statbuf.st_mode)) {
2754 if (unlink (fullpath.c_str())) {
2755 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2756 fullpath, strerror (errno))
2760 rep.paths.push_back (dentry->d_name);
2761 rep.space += statbuf.st_size;
2772 Session::set_dirty ()
2774 bool was_dirty = dirty();
2776 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2779 DirtyChanged(); /* EMIT SIGNAL */
2785 Session::set_clean ()
2787 bool was_dirty = dirty();
2789 _state_of_the_state = Clean;
2792 DirtyChanged(); /* EMIT SIGNAL */
2797 Session::set_deletion_in_progress ()
2799 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2803 Session::add_controllable (Controllable* c)
2805 Glib::Mutex::Lock lm (controllables_lock);
2806 controllables.insert (c);
2810 Session::remove_controllable (Controllable* c)
2812 if (_state_of_the_state | Deletion) {
2816 Glib::Mutex::Lock lm (controllables_lock);
2818 Controllables::iterator x = controllables.find (c);
2820 if (x != controllables.end()) {
2821 controllables.erase (x);
2826 Session::controllable_by_id (const PBD::ID& id)
2828 Glib::Mutex::Lock lm (controllables_lock);
2830 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2831 if ((*i)->id() == id) {
2840 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2842 Stateful::add_instant_xml (node, dir);
2843 Config->add_instant_xml (node, get_user_ardour_path());
2848 Session::save_history (string snapshot_name)
2854 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2856 if (snapshot_name.empty()) {
2857 snapshot_name = _current_snapshot_name;
2860 xml_path = _path + snapshot_name + ".history";
2862 bak_path = xml_path + ".bak";
2864 if ((access (xml_path.c_str(), F_OK) == 0) &&
2865 (rename (xml_path.c_str(), bak_path.c_str())))
2867 error << _("could not backup old history file, current history not saved.") << endmsg;
2871 if (!tree.write (xml_path))
2873 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2875 /* don't leave a corrupt file lying around if it is
2879 if (unlink (xml_path.c_str())) {
2880 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2882 if (rename (bak_path.c_str(), xml_path.c_str()))
2884 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2895 Session::restore_history (string snapshot_name)
2900 if (snapshot_name.empty()) {
2901 snapshot_name = _current_snapshot_name;
2905 xmlpath = _path + snapshot_name + ".history";
2906 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2908 if (access (xmlpath.c_str(), F_OK)) {
2909 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2913 if (!tree.read (xmlpath)) {
2914 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2918 /* replace history */
2921 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2924 UndoTransaction* ut = new UndoTransaction ();
2927 ut->set_name(t->property("name")->value());
2928 stringstream ss(t->property("tv_sec")->value());
2930 ss.str(t->property("tv_usec")->value());
2932 ut->set_timestamp(tv);
2934 for (XMLNodeConstIterator child_it = t->children().begin();
2935 child_it != t->children().end();
2938 XMLNode *n = *child_it;
2941 if (n->name() == "MementoCommand" ||
2942 n->name() == "MementoUndoCommand" ||
2943 n->name() == "MementoRedoCommand") {
2945 if ((c = memento_command_factory(n))) {
2949 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2951 if ((c = global_state_command_factory (*n))) {
2952 ut->add_command (c);
2957 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2968 Session::config_changed (const char* parameter_name)
2970 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2972 if (PARAM_IS ("seamless-loop")) {
2974 } else if (PARAM_IS ("rf-speed")) {
2976 } else if (PARAM_IS ("auto-loop")) {
2978 } else if (PARAM_IS ("auto-input")) {
2980 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2981 /* auto-input only makes a difference if we're rolling */
2983 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2985 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
2986 if ((*i)->record_enabled ()) {
2987 (*i)->monitor_input (!Config->get_auto_input());
2992 } else if (PARAM_IS ("punch-in")) {
2996 if ((location = _locations.auto_punch_location()) != 0) {
2998 if (Config->get_punch_in ()) {
2999 replace_event (Event::PunchIn, location->start());
3001 remove_event (location->start(), Event::PunchIn);
3005 } else if (PARAM_IS ("punch-out")) {
3009 if ((location = _locations.auto_punch_location()) != 0) {
3011 if (Config->get_punch_out()) {
3012 replace_event (Event::PunchOut, location->end());
3014 clear_events (Event::PunchOut);
3018 } else if (PARAM_IS ("edit-mode")) {
3020 Glib::Mutex::Lock lm (playlist_lock);
3022 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3023 (*i)->set_edit_mode (Config->get_edit_mode ());
3026 } else if (PARAM_IS ("use-video-sync")) {
3028 if (transport_stopped()) {
3029 if (Config->get_use_video_sync()) {
3030 waiting_for_sync_offset = true;
3034 } else if (PARAM_IS ("mmc-control")) {
3036 poke_midi_thread ();
3038 } else if (PARAM_IS ("midi-control")) {
3040 poke_midi_thread ();
3042 } else if (PARAM_IS ("raid-path")) {
3044 setup_raid_path (Config->get_raid_path());
3046 } else if (PARAM_IS ("smpte-format")) {
3050 } else if (PARAM_IS ("video-pullup")) {
3054 } else if (PARAM_IS ("seamless-loop")) {
3056 if (play_loop && transport_rolling()) {
3057 // to reset diskstreams etc
3058 request_play_loop (true);
3061 } else if (PARAM_IS ("rf-speed")) {
3063 cumulative_rf_motion = 0;
3066 } else if (PARAM_IS ("click-sound")) {
3068 setup_click_sounds (1);
3070 } else if (PARAM_IS ("click-emphasis-sound")) {
3072 setup_click_sounds (-1);
3074 } else if (PARAM_IS ("clicking")) {
3076 if (Config->get_clicking()) {
3077 if (_click_io && click_data) { // don't require emphasis data
3084 } else if (PARAM_IS ("send-mtc")) {
3086 /* only set the internal flag if we have
3090 if (_mtc_port != 0) {
3091 session_send_mtc = Config->get_send_mtc();
3092 if (session_send_mtc) {
3093 /* mark us ready to send */
3094 next_quarter_frame_to_send = 0;
3098 } else if (PARAM_IS ("send-mmc")) {
3100 /* only set the internal flag if we have
3104 if (_mmc_port != 0) {
3105 session_send_mmc = Config->get_send_mmc();
3108 } else if (PARAM_IS ("midi-feedback")) {
3110 /* only set the internal flag if we have
3114 if (_mtc_port != 0) {
3115 session_midi_feedback = Config->get_midi_feedback();
3118 } else if (PARAM_IS ("jack-time-master")) {
3120 engine().reset_timebase ();
3122 } else if (PARAM_IS ("native-file-header-format")) {
3124 if (!first_file_header_format_reset) {
3125 reset_native_file_format ();
3128 first_file_header_format_reset = false;
3130 } else if (PARAM_IS ("native-file-data-format")) {
3132 if (!first_file_data_format_reset) {
3133 reset_native_file_format ();
3136 first_file_data_format_reset = false;
3138 } else if (PARAM_IS ("slave-source")) {
3139 set_slave_source (Config->get_slave_source());