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/silentfilesource.h>
68 #include <ardour/destructive_filesource.h>
69 #include <ardour/sndfile_helpers.h>
70 #include <ardour/auditioner.h>
71 #include <ardour/export.h>
72 #include <ardour/redirect.h>
73 #include <ardour/send.h>
74 #include <ardour/insert.h>
75 #include <ardour/connection.h>
76 #include <ardour/slave.h>
77 #include <ardour/tempo.h>
78 #include <ardour/audio_track.h>
79 #include <ardour/cycle_timer.h>
80 #include <ardour/utils.h>
81 #include <ardour/named_selection.h>
82 #include <ardour/version.h>
83 #include <ardour/location.h>
84 #include <ardour/audioregion.h>
85 #include <ardour/crossfade.h>
86 #include <ardour/control_protocol_manager.h>
87 #include <ardour/region_factory.h>
88 #include <ardour/source_factory.h>
89 #include <ardour/playlist_factory.h>
91 #include <control_protocol/control_protocol.h>
97 using namespace ARDOUR;
101 Session::first_stage_init (string fullpath, string snapshot_name)
103 if (fullpath.length() == 0) {
105 throw failed_constructor();
108 char buf[PATH_MAX+1];
109 if (!realpath (fullpath.c_str(), buf) && (errno != ENOENT)) {
110 error << string_compose(_("Could not use path %1 (%s)"), buf, strerror(errno)) << endmsg;
112 throw failed_constructor();
117 if (_path[_path.length()-1] != '/') {
121 /* these two are just provisional settings. set_state()
122 will likely override them.
125 _name = _current_snapshot_name = snapshot_name;
127 _current_frame_rate = _engine.frame_rate ();
128 _tempo_map = new TempoMap (_current_frame_rate);
129 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
131 g_atomic_int_set (&processing_prohibited, 0);
133 _transport_speed = 0;
134 _last_transport_speed = 0;
135 transport_sub_state = 0;
136 _transport_frame = 0;
138 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
139 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
140 _end_location_is_free = true;
141 g_atomic_int_set (&_record_status, Disabled);
142 loop_changing = false;
144 _last_roll_location = 0;
145 _last_record_location = 0;
146 pending_locate_frame = 0;
147 pending_locate_roll = false;
148 pending_locate_flush = false;
149 dstream_buffer_size = 0;
151 state_was_pending = false;
153 outbound_mtc_smpte_frame = 0;
154 next_quarter_frame_to_send = -1;
155 current_block_size = 0;
156 solo_update_disabled = false;
157 currently_soloing = false;
158 _have_captured = false;
159 _worst_output_latency = 0;
160 _worst_input_latency = 0;
161 _worst_track_latency = 0;
162 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading|Deletion);
164 butler_mixdown_buffer = 0;
165 butler_gain_buffer = 0;
167 session_send_mmc = false;
168 session_send_mtc = false;
169 post_transport_work = PostTransportWork (0);
170 g_atomic_int_set (&butler_should_do_transport_work, 0);
171 g_atomic_int_set (&butler_active, 0);
172 g_atomic_int_set (&_playback_load, 100);
173 g_atomic_int_set (&_capture_load, 100);
174 g_atomic_int_set (&_playback_load_min, 100);
175 g_atomic_int_set (&_capture_load_min, 100);
177 waiting_to_start = false;
179 _gain_automation_buffer = 0;
180 _pan_automation_buffer = 0;
182 pending_abort = false;
183 destructive_index = 0;
185 first_file_data_format_reset = true;
186 first_file_header_format_reset = true;
188 AudioDiskstream::allocate_working_buffers();
190 /* default short fade = 15ms */
192 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
193 SndFileSource::setup_standard_crossfades (frame_rate());
195 last_mmc_step.tv_sec = 0;
196 last_mmc_step.tv_usec = 0;
199 /* click sounds are unset by default, which causes us to internal
200 waveforms for clicks.
204 click_emphasis_data = 0;
206 click_emphasis_length = 0;
209 process_function = &Session::process_with_events;
211 if (Config->get_use_video_sync()) {
212 waiting_for_sync_offset = true;
214 waiting_for_sync_offset = false;
217 _current_frame_rate = 48000;
218 _base_frame_rate = 48000;
222 _smpte_offset_negative = true;
223 last_smpte_valid = false;
227 last_rr_session_dir = session_dirs.begin();
228 refresh_disk_space ();
230 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
234 average_slave_delta = 1800;
235 have_first_delta_accumulator = false;
236 delta_accumulator_cnt = 0;
237 slave_state = Stopped;
239 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
241 /* These are all static "per-class" signals */
243 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
244 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
245 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
246 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
247 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
248 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
250 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
252 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
254 /* stop IO objects from doing stuff until we're ready for them */
256 IO::disable_panners ();
257 IO::disable_ports ();
258 IO::disable_connecting ();
262 Session::second_stage_init (bool new_session)
264 AudioFileSource::set_peak_dir (peak_dir());
267 if (load_state (_current_snapshot_name)) {
270 remove_empty_sounds ();
273 if (start_butler_thread()) {
277 if (start_midi_thread ()) {
281 // set_state() will call setup_raid_path(), but if it's a new session we need
282 // to call setup_raid_path() here.
284 if (set_state (*state_tree->root())) {
288 setup_raid_path(_path);
291 /* we can't save till after ::when_engine_running() is called,
292 because otherwise we save state with no connections made.
293 therefore, we reset _state_of_the_state because ::set_state()
294 will have cleared it.
296 we also have to include Loading so that any events that get
297 generated between here and the end of ::when_engine_running()
298 will be processed directly rather than queued.
301 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
303 // set_auto_input (true);
304 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
305 _locations.added.connect (mem_fun (this, &Session::locations_added));
306 setup_click_sounds (0);
307 setup_midi_control ();
309 /* Pay attention ... */
311 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
312 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
315 when_engine_running();
318 /* handle this one in a different way than all others, so that its clear what happened */
320 catch (AudioEngine::PortRegistrationFailure& err) {
321 error << _("Unable to create all required ports")
330 send_full_time_code ();
331 _engine.transport_locate (0);
332 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
333 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
335 ControlProtocolManager::instance().set_session (*this);
338 _end_location_is_free = true;
340 _end_location_is_free = false;
347 Session::raid_path () const
351 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
356 return path.substr (0, path.length() - 1); // drop final colon
360 Session::setup_raid_path (string path)
362 string::size_type colon;
366 string::size_type len = path.length();
371 if (path.length() == 0) {
375 session_dirs.clear ();
377 for (string::size_type n = 0; n < len; ++n) {
378 if (path[n] == ':') {
385 /* no multiple search path, just one location (common case) */
389 session_dirs.push_back (sp);
396 if (fspath[fspath.length()-1] != '/') {
400 fspath += sound_dir (false);
402 AudioFileSource::set_search_path (fspath);
409 while ((colon = remaining.find_first_of (':')) != string::npos) {
412 sp.path = remaining.substr (0, colon);
413 session_dirs.push_back (sp);
415 /* add sounds to file search path */
418 if (fspath[fspath.length()-1] != '/') {
421 fspath += sound_dir (false);
424 remaining = remaining.substr (colon+1);
427 if (remaining.length()) {
434 if (fspath[fspath.length()-1] != '/') {
437 fspath += sound_dir (false);
440 session_dirs.push_back (sp);
443 /* set the AudioFileSource search path */
445 AudioFileSource::set_search_path (fspath);
447 /* reset the round-robin soundfile path thingie */
449 last_rr_session_dir = session_dirs.begin();
453 Session::create (bool& new_session, string* mix_template, nframes_t initial_length)
457 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
458 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
464 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
465 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
472 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
476 dir = dead_sound_dir ();
478 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
479 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483 dir = automation_dir ();
485 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
486 error << string_compose(_("Session: cannot create session automation dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
491 /* check new_session so we don't overwrite an existing one */
494 std::string in_path = *mix_template;
496 ifstream in(in_path.c_str());
499 string out_path = _path;
501 out_path += _statefile_suffix;
503 ofstream out(out_path.c_str());
508 // okay, session is set up. Treat like normal saved
509 // session from now on.
515 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
521 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
528 /* set initial start + end point */
530 start_location->set_end (0);
531 _locations.add (start_location);
533 end_location->set_end (initial_length);
534 _locations.add (end_location);
536 _state_of_the_state = Clean;
538 if (save_state (_current_snapshot_name)) {
546 Session::load_diskstreams (const XMLNode& node)
549 XMLNodeConstIterator citer;
551 clist = node.children();
553 for (citer = clist.begin(); citer != clist.end(); ++citer) {
557 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
558 add_diskstream (dstream);
561 catch (failed_constructor& err) {
562 error << _("Session: could not load diskstream via XML state") << endmsg;
571 Session::remove_pending_capture_state ()
576 xml_path += _current_snapshot_name;
577 xml_path += _pending_suffix;
579 unlink (xml_path.c_str());
583 Session::save_state (string snapshot_name, bool pending)
589 if (_state_of_the_state & CannotSave) {
593 if (!_engine.connected ()) {
594 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
599 tree.set_root (&get_state());
601 if (snapshot_name.empty()) {
602 snapshot_name = _current_snapshot_name;
608 xml_path += snapshot_name;
609 xml_path += _statefile_suffix;
614 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
615 copy_file (xml_path, bak_path);
621 xml_path += snapshot_name;
622 xml_path += _pending_suffix;
629 tmp_path += snapshot_name;
632 cerr << "actually writing state\n";
634 if (!tree.write (tmp_path)) {
635 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
636 unlink (tmp_path.c_str());
641 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
642 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
643 unlink (tmp_path.c_str());
650 save_history (snapshot_name);
652 bool was_dirty = dirty();
654 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
657 DirtyChanged (); /* EMIT SIGNAL */
660 StateSaved (snapshot_name); /* EMIT SIGNAL */
667 Session::restore_state (string snapshot_name)
669 if (load_state (snapshot_name) == 0) {
670 set_state (*state_tree->root());
677 Session::load_state (string snapshot_name)
686 state_was_pending = false;
688 /* check for leftover pending state from a crashed capture attempt */
691 xmlpath += snapshot_name;
692 xmlpath += _pending_suffix;
694 if (!access (xmlpath.c_str(), F_OK)) {
696 /* there is pending state from a crashed capture attempt */
698 if (AskAboutPendingState()) {
699 state_was_pending = true;
703 if (!state_was_pending) {
706 xmlpath += snapshot_name;
707 xmlpath += _statefile_suffix;
710 if (access (xmlpath.c_str(), F_OK)) {
711 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
715 state_tree = new XMLTree;
719 if (!state_tree->read (xmlpath)) {
720 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
726 XMLNode& root (*state_tree->root());
728 if (root.name() != X_("Session")) {
729 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
735 const XMLProperty* prop;
738 if ((prop = root.property ("version")) == 0) {
739 /* no version implies very old version of Ardour */
743 major_version = atoi (prop->value()); // grab just the first number before the period
744 if (major_version < 2) {
752 backup_path = xmlpath;
755 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
756 xmlpath, backup_path)
759 copy_file (xmlpath, backup_path);
761 /* if it fails, don't worry. right? */
768 Session::load_options (const XMLNode& node)
772 LocaleGuard lg (X_("POSIX"));
774 Config->set_variables (node, ConfigVariableBase::Session);
776 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
777 if ((prop = child->property ("val")) != 0) {
778 _end_location_is_free = (prop->value() == "yes");
786 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
788 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
789 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
791 return owner & modified_by_session_or_user;
795 Session::get_options () const
798 LocaleGuard lg (X_("POSIX"));
800 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
802 child = option_root.add_child ("end-marker-is-free");
803 child->add_property ("val", _end_location_is_free ? "yes" : "no");
815 Session::get_template()
817 /* if we don't disable rec-enable, diskstreams
818 will believe they need to store their capture
819 sources in their state node.
822 disable_record (false);
828 Session::state(bool full_state)
830 XMLNode* node = new XMLNode("Session");
833 // store libardour version, just in case
835 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
836 libardour_major_version, libardour_minor_version, libardour_micro_version);
837 node->add_property("version", string(buf));
839 /* store configuration settings */
844 node->add_property ("name", _name);
846 if (session_dirs.size() > 1) {
850 vector<space_and_path>::iterator i = session_dirs.begin();
851 vector<space_and_path>::iterator next;
853 ++i; /* skip the first one */
857 while (i != session_dirs.end()) {
861 if (next != session_dirs.end()) {
871 child = node->add_child ("Path");
872 child->add_content (p);
876 /* save the ID counter */
878 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
879 node->add_property ("id-counter", buf);
881 /* various options */
883 node->add_child_nocopy (get_options());
885 child = node->add_child ("Sources");
888 Glib::Mutex::Lock sl (audio_source_lock);
890 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
892 /* Don't save information about AudioFileSources that are empty */
894 boost::shared_ptr<AudioFileSource> fs;
896 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
898 /* destructive file sources are OK if they are empty, because
899 we will re-use them every time.
902 if (!fs->destructive()) {
903 if (fs->length() == 0) {
909 child->add_child_nocopy (siter->second->get_state());
913 child = node->add_child ("Regions");
916 Glib::Mutex::Lock rl (region_lock);
918 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
920 /* only store regions not attached to playlists */
922 if (i->second->playlist() == 0) {
923 child->add_child_nocopy (i->second->state (true));
928 child = node->add_child ("DiskStreams");
931 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
932 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
933 if (!(*i)->hidden()) {
934 child->add_child_nocopy ((*i)->get_state());
940 node->add_child_nocopy (_locations.get_state());
942 // for a template, just create a new Locations, populate it
943 // with the default start and end, and get the state for that.
945 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
946 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
949 end->set_end(compute_initial_length());
951 node->add_child_nocopy (loc.get_state());
954 child = node->add_child ("Connections");
956 Glib::Mutex::Lock lm (connection_lock);
957 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
958 if (!(*i)->system_dependent()) {
959 child->add_child_nocopy ((*i)->get_state());
964 child = node->add_child ("Routes");
966 boost::shared_ptr<RouteList> r = routes.reader ();
968 RoutePublicOrderSorter cmp;
969 RouteList public_order (*r);
970 public_order.sort (cmp);
972 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
973 if (!(*i)->hidden()) {
975 child->add_child_nocopy ((*i)->get_state());
977 child->add_child_nocopy ((*i)->get_template());
984 child = node->add_child ("EditGroups");
985 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
986 child->add_child_nocopy ((*i)->get_state());
989 child = node->add_child ("MixGroups");
990 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
991 child->add_child_nocopy ((*i)->get_state());
994 child = node->add_child ("Playlists");
995 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
996 if (!(*i)->hidden()) {
997 if (!(*i)->empty()) {
999 child->add_child_nocopy ((*i)->get_state());
1001 child->add_child_nocopy ((*i)->get_template());
1007 child = node->add_child ("UnusedPlaylists");
1008 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1009 if (!(*i)->hidden()) {
1010 if (!(*i)->empty()) {
1012 child->add_child_nocopy ((*i)->get_state());
1014 child->add_child_nocopy ((*i)->get_template());
1022 child = node->add_child ("Click");
1023 child->add_child_nocopy (_click_io->state (full_state));
1027 child = node->add_child ("NamedSelections");
1028 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1030 child->add_child_nocopy ((*i)->get_state());
1035 node->add_child_nocopy (_tempo_map->get_state());
1037 node->add_child_nocopy (get_control_protocol_state());
1040 node->add_child_copy (*_extra_xml);
1047 Session::get_control_protocol_state ()
1049 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1050 return cpm.get_state();
1054 Session::set_state (const XMLNode& node)
1058 const XMLProperty* prop;
1061 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1063 if (node.name() != X_("Session")){
1064 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1068 if ((prop = node.property ("name")) != 0) {
1069 _name = prop->value ();
1072 setup_raid_path(_path);
1074 if ((prop = node.property (X_("id-counter"))) != 0) {
1076 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1077 ID::init_counter (x);
1079 /* old sessions used a timebased counter, so fake
1080 the startup ID counter based on a standard
1085 ID::init_counter (now);
1089 IO::disable_ports ();
1090 IO::disable_connecting ();
1092 /* Object loading order:
1110 if (use_config_midi_ports ()) {
1113 if ((child = find_named_node (node, "extra")) != 0) {
1114 _extra_xml = new XMLNode (*child);
1117 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1118 load_options (*child);
1119 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1120 load_options (*child);
1122 error << _("Session: XML state has no options section") << endmsg;
1125 if ((child = find_named_node (node, "Locations")) == 0) {
1126 error << _("Session: XML state has no locations section") << endmsg;
1128 } else if (_locations.set_state (*child)) {
1134 if ((location = _locations.auto_loop_location()) != 0) {
1135 set_auto_loop_location (location);
1138 if ((location = _locations.auto_punch_location()) != 0) {
1139 set_auto_punch_location (location);
1142 if ((location = _locations.end_location()) == 0) {
1143 _locations.add (end_location);
1145 delete end_location;
1146 end_location = location;
1149 if ((location = _locations.start_location()) == 0) {
1150 _locations.add (start_location);
1152 delete start_location;
1153 start_location = location;
1156 AudioFileSource::set_header_position_offset (start_location->start());
1158 if ((child = find_named_node (node, "Sources")) == 0) {
1159 error << _("Session: XML state has no sources section") << endmsg;
1161 } else if (load_sources (*child)) {
1165 if ((child = find_named_node (node, "Regions")) == 0) {
1166 error << _("Session: XML state has no Regions section") << endmsg;
1168 } else if (load_regions (*child)) {
1172 if ((child = find_named_node (node, "Playlists")) == 0) {
1173 error << _("Session: XML state has no playlists section") << endmsg;
1175 } else if (load_playlists (*child)) {
1179 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1181 } else if (load_unused_playlists (*child)) {
1185 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1186 if (load_named_selections (*child)) {
1191 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1192 error << _("Session: XML state has no diskstreams section") << endmsg;
1194 } else if (load_diskstreams (*child)) {
1198 if ((child = find_named_node (node, "Connections")) == 0) {
1199 error << _("Session: XML state has no connections section") << endmsg;
1201 } else if (load_connections (*child)) {
1205 if ((child = find_named_node (node, "EditGroups")) == 0) {
1206 error << _("Session: XML state has no edit groups section") << endmsg;
1208 } else if (load_edit_groups (*child)) {
1212 if ((child = find_named_node (node, "MixGroups")) == 0) {
1213 error << _("Session: XML state has no mix groups section") << endmsg;
1215 } else if (load_mix_groups (*child)) {
1219 if ((child = find_named_node (node, "TempoMap")) == 0) {
1220 error << _("Session: XML state has no Tempo Map section") << endmsg;
1222 } else if (_tempo_map->set_state (*child)) {
1226 if ((child = find_named_node (node, "Routes")) == 0) {
1227 error << _("Session: XML state has no routes section") << endmsg;
1229 } else if (load_routes (*child)) {
1233 if ((child = find_named_node (node, "Click")) == 0) {
1234 warning << _("Session: XML state has no click section") << endmsg;
1235 } else if (_click_io) {
1236 _click_io->set_state (*child);
1239 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1240 ControlProtocolManager::instance().set_protocol_states (*child);
1243 /* here beginneth the second phase ... */
1245 StateReady (); /* EMIT SIGNAL */
1247 _state_of_the_state = Clean;
1249 if (state_was_pending) {
1250 save_state (_current_snapshot_name);
1251 remove_pending_capture_state ();
1252 state_was_pending = false;
1262 Session::load_routes (const XMLNode& node)
1265 XMLNodeConstIterator niter;
1266 RouteList new_routes;
1268 nlist = node.children();
1272 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1274 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1277 error << _("Session: cannot create Route from XML description.") << endmsg;
1281 new_routes.push_back (route);
1284 add_routes (new_routes);
1289 boost::shared_ptr<Route>
1290 Session::XMLRouteFactory (const XMLNode& node)
1292 if (node.name() != "Route") {
1293 return boost::shared_ptr<Route> ((Route*) 0);
1296 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1297 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1300 boost::shared_ptr<Route> x (new Route (*this, node));
1306 Session::load_regions (const XMLNode& node)
1309 XMLNodeConstIterator niter;
1310 boost::shared_ptr<AudioRegion> region;
1312 nlist = node.children();
1316 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1317 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1318 error << _("Session: cannot create Region from XML description.") << endmsg;
1325 boost::shared_ptr<AudioRegion>
1326 Session::XMLRegionFactory (const XMLNode& node, bool full)
1328 const XMLProperty* prop;
1329 boost::shared_ptr<Source> source;
1330 boost::shared_ptr<AudioSource> as;
1332 uint32_t nchans = 1;
1335 if (node.name() != X_("Region")) {
1336 return boost::shared_ptr<AudioRegion>();
1339 if ((prop = node.property (X_("channels"))) != 0) {
1340 nchans = atoi (prop->value().c_str());
1344 if ((prop = node.property ("name")) == 0) {
1345 cerr << "no name for this region\n";
1349 if ((prop = node.property (X_("source-0"))) == 0) {
1350 if ((prop = node.property ("source")) == 0) {
1351 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1352 return boost::shared_ptr<AudioRegion>();
1356 PBD::ID s_id (prop->value());
1358 if ((source = source_by_id (s_id)) == 0) {
1359 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1360 return boost::shared_ptr<AudioRegion>();
1363 as = boost::dynamic_pointer_cast<AudioSource>(source);
1365 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1366 return boost::shared_ptr<AudioRegion>();
1369 sources.push_back (as);
1371 /* pickup other channels */
1373 for (uint32_t n=1; n < nchans; ++n) {
1374 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1375 if ((prop = node.property (buf)) != 0) {
1377 PBD::ID id2 (prop->value());
1379 if ((source = source_by_id (id2)) == 0) {
1380 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1381 return boost::shared_ptr<AudioRegion>();
1384 as = boost::dynamic_pointer_cast<AudioSource>(source);
1386 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1387 return boost::shared_ptr<AudioRegion>();
1389 sources.push_back (as);
1394 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1396 /* a final detail: this is the one and only place that we know how long missing files are */
1398 if (region->whole_file()) {
1399 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1400 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1402 sfp->set_length (region->length());
1412 catch (failed_constructor& err) {
1413 return boost::shared_ptr<AudioRegion>();
1418 Session::get_sources_as_xml ()
1421 XMLNode* node = new XMLNode (X_("Sources"));
1422 Glib::Mutex::Lock lm (audio_source_lock);
1424 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1425 node->add_child_nocopy (i->second->get_state());
1428 /* XXX get MIDI and other sources here */
1434 Session::path_from_region_name (string name, string identifier)
1436 char buf[PATH_MAX+1];
1438 string dir = discover_best_sound_dir ();
1440 for (n = 0; n < 999999; ++n) {
1441 if (identifier.length()) {
1442 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1443 identifier.c_str(), n);
1445 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1447 if (access (buf, F_OK) != 0) {
1457 Session::load_sources (const XMLNode& node)
1460 XMLNodeConstIterator niter;
1461 boost::shared_ptr<Source> source;
1463 nlist = node.children();
1467 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1470 if ((source = XMLSourceFactory (**niter)) == 0) {
1471 error << _("Session: cannot create Source from XML description.") << endmsg;
1475 catch (non_existent_source& err) {
1476 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1477 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1484 boost::shared_ptr<Source>
1485 Session::XMLSourceFactory (const XMLNode& node)
1487 if (node.name() != "Source") {
1488 return boost::shared_ptr<Source>();
1492 return SourceFactory::create (*this, node);
1495 catch (failed_constructor& err) {
1496 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1497 return boost::shared_ptr<Source>();
1502 Session::save_template (string template_name)
1505 string xml_path, bak_path, template_path;
1507 if (_state_of_the_state & CannotSave) {
1512 string dir = template_dir();
1514 if ((dp = opendir (dir.c_str()))) {
1517 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1518 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1523 tree.set_root (&get_template());
1526 xml_path += template_name;
1527 xml_path += _template_suffix;
1529 ifstream in(xml_path.c_str());
1532 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1538 if (!tree.write (xml_path)) {
1539 error << _("mix template not saved") << endmsg;
1547 Session::rename_template (string old_name, string new_name)
1549 string old_path = template_dir() + old_name + _template_suffix;
1550 string new_path = template_dir() + new_name + _template_suffix;
1552 return rename (old_path.c_str(), new_path.c_str());
1556 Session::delete_template (string name)
1558 string template_path = template_dir();
1559 template_path += name;
1560 template_path += _template_suffix;
1562 return remove (template_path.c_str());
1566 Session::refresh_disk_space ()
1569 struct statfs statfsbuf;
1570 vector<space_and_path>::iterator i;
1571 Glib::Mutex::Lock lm (space_lock);
1574 /* get freespace on every FS that is part of the session path */
1576 _total_free_4k_blocks = 0;
1578 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1579 statfs ((*i).path.c_str(), &statfsbuf);
1581 scale = statfsbuf.f_bsize/4096.0;
1583 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1584 _total_free_4k_blocks += (*i).blocks;
1590 Session::ensure_sound_dir (string path, string& result)
1595 /* Ensure that the parent directory exists */
1597 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1598 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1602 /* Ensure that the sounds directory exists */
1606 result += sound_dir_name;
1608 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1609 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1615 dead += dead_sound_dir_name;
1617 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1618 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1624 peak += peak_dir_name;
1626 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1627 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1631 /* callers expect this to be terminated ... */
1638 Session::discover_best_sound_dir (bool destructive)
1640 vector<space_and_path>::iterator i;
1643 /* handle common case without system calls */
1645 if (session_dirs.size() == 1) {
1649 /* OK, here's the algorithm we're following here:
1651 We want to select which directory to use for
1652 the next file source to be created. Ideally,
1653 we'd like to use a round-robin process so as to
1654 get maximum performance benefits from splitting
1655 the files across multiple disks.
1657 However, in situations without much diskspace, an
1658 RR approach may end up filling up a filesystem
1659 with new files while others still have space.
1660 Its therefore important to pay some attention to
1661 the freespace in the filesystem holding each
1662 directory as well. However, if we did that by
1663 itself, we'd keep creating new files in the file
1664 system with the most space until it was as full
1665 as all others, thus negating any performance
1666 benefits of this RAID-1 like approach.
1668 So, we use a user-configurable space threshold. If
1669 there are at least 2 filesystems with more than this
1670 much space available, we use RR selection between them.
1671 If not, then we pick the filesystem with the most space.
1673 This gets a good balance between the two
1677 refresh_disk_space ();
1679 int free_enough = 0;
1681 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1682 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1687 if (free_enough >= 2) {
1689 bool found_it = false;
1691 /* use RR selection process, ensuring that the one
1695 i = last_rr_session_dir;
1698 if (++i == session_dirs.end()) {
1699 i = session_dirs.begin();
1702 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1703 if (ensure_sound_dir ((*i).path, result) == 0) {
1704 last_rr_session_dir = i;
1710 } while (i != last_rr_session_dir);
1713 result = sound_dir();
1718 /* pick FS with the most freespace (and that
1719 seems to actually work ...)
1722 vector<space_and_path> sorted;
1723 space_and_path_ascending_cmp cmp;
1725 sorted = session_dirs;
1726 sort (sorted.begin(), sorted.end(), cmp);
1728 for (i = sorted.begin(); i != sorted.end(); ++i) {
1729 if (ensure_sound_dir ((*i).path, result) == 0) {
1730 last_rr_session_dir = i;
1735 /* if the above fails, fall back to the most simplistic solution */
1737 if (i == sorted.end()) {
1746 Session::load_playlists (const XMLNode& node)
1749 XMLNodeConstIterator niter;
1750 boost::shared_ptr<Playlist> playlist;
1752 nlist = node.children();
1756 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1758 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1759 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1767 Session::load_unused_playlists (const XMLNode& node)
1770 XMLNodeConstIterator niter;
1771 boost::shared_ptr<Playlist> playlist;
1773 nlist = node.children();
1777 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1779 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1780 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1784 // now manually untrack it
1786 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1793 boost::shared_ptr<Playlist>
1794 Session::XMLPlaylistFactory (const XMLNode& node)
1797 return PlaylistFactory::create (*this, node);
1800 catch (failed_constructor& err) {
1801 return boost::shared_ptr<Playlist>();
1806 Session::load_named_selections (const XMLNode& node)
1809 XMLNodeConstIterator niter;
1812 nlist = node.children();
1816 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1818 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1819 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1827 Session::XMLNamedSelectionFactory (const XMLNode& node)
1830 return new NamedSelection (*this, node);
1833 catch (failed_constructor& err) {
1839 Session::dead_sound_dir () const
1842 res += dead_sound_dir_name;
1848 Session::sound_dir (bool with_path) const
1850 /* support old session structure */
1852 struct stat statbuf;
1854 string old_withpath;
1856 old_nopath += old_sound_dir_name;
1859 old_withpath = _path;
1860 old_withpath += old_sound_dir_name;
1862 if (stat (old_withpath.c_str(), &statbuf) == 0) {
1864 return old_withpath;
1875 res += interchange_dir_name;
1877 res += legalize_for_path (_name);
1879 res += sound_dir_name;
1885 Session::peak_dir () const
1888 res += peak_dir_name;
1894 Session::automation_dir () const
1897 res += "automation/";
1902 Session::template_dir ()
1904 string path = get_user_ardour_path();
1905 path += "templates/";
1911 Session::suffixed_search_path (string suffix, bool data)
1915 path += get_user_ardour_path();
1916 if (path[path.length()-1] != ':') {
1921 path += get_system_data_path();
1923 path += get_system_module_path();
1926 vector<string> split_path;
1928 split (path, split_path, ':');
1931 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
1936 if (distance (i, split_path.end()) != 1) {
1945 Session::template_path ()
1947 return suffixed_search_path (X_("templates"), true);
1951 Session::control_protocol_path ()
1953 return suffixed_search_path (X_("surfaces"), false);
1957 Session::load_connections (const XMLNode& node)
1959 XMLNodeList nlist = node.children();
1960 XMLNodeConstIterator niter;
1964 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1965 if ((*niter)->name() == "InputConnection") {
1966 add_connection (new ARDOUR::InputConnection (**niter));
1967 } else if ((*niter)->name() == "OutputConnection") {
1968 add_connection (new ARDOUR::OutputConnection (**niter));
1970 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
1979 Session::load_edit_groups (const XMLNode& node)
1981 return load_route_groups (node, true);
1985 Session::load_mix_groups (const XMLNode& node)
1987 return load_route_groups (node, false);
1991 Session::load_route_groups (const XMLNode& node, bool edit)
1993 XMLNodeList nlist = node.children();
1994 XMLNodeConstIterator niter;
1999 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2000 if ((*niter)->name() == "RouteGroup") {
2002 rg = add_edit_group ("");
2003 rg->set_state (**niter);
2005 rg = add_mix_group ("");
2006 rg->set_state (**niter);
2015 state_file_filter (const string &str, void *arg)
2017 return (str.length() > strlen(Session::statefile_suffix()) &&
2018 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2022 bool operator()(const string* a, const string* b) {
2028 remove_end(string* state)
2030 string statename(*state);
2032 string::size_type start,end;
2033 if ((start = statename.find_last_of ('/')) != string::npos) {
2034 statename = statename.substr (start+1);
2037 if ((end = statename.rfind(".ardour")) == string::npos) {
2038 end = statename.length();
2041 return new string(statename.substr (0, end));
2045 Session::possible_states (string path)
2047 PathScanner scanner;
2048 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2050 transform(states->begin(), states->end(), states->begin(), remove_end);
2053 sort (states->begin(), states->end(), cmp);
2059 Session::possible_states () const
2061 return possible_states(_path);
2065 Session::auto_save()
2067 save_state (_current_snapshot_name);
2071 Session::add_edit_group (string name)
2073 RouteGroup* rg = new RouteGroup (*this, name);
2074 edit_groups.push_back (rg);
2075 edit_group_added (rg); /* EMIT SIGNAL */
2081 Session::add_mix_group (string name)
2083 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2084 mix_groups.push_back (rg);
2085 mix_group_added (rg); /* EMIT SIGNAL */
2091 Session::remove_edit_group (RouteGroup& rg)
2093 list<RouteGroup*>::iterator i;
2095 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2096 (*i)->apply (&Route::drop_edit_group, this);
2097 edit_groups.erase (i);
2098 edit_group_removed (); /* EMIT SIGNAL */
2105 Session::remove_mix_group (RouteGroup& rg)
2107 list<RouteGroup*>::iterator i;
2109 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2110 (*i)->apply (&Route::drop_mix_group, this);
2111 mix_groups.erase (i);
2112 mix_group_removed (); /* EMIT SIGNAL */
2119 Session::mix_group_by_name (string name)
2121 list<RouteGroup *>::iterator i;
2123 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2124 if ((*i)->name() == name) {
2132 Session::edit_group_by_name (string name)
2134 list<RouteGroup *>::iterator i;
2136 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2137 if ((*i)->name() == name) {
2145 Session::begin_reversible_command (string name)
2147 current_trans = new UndoTransaction;
2148 current_trans->set_name (name);
2152 Session::commit_reversible_command (Command *cmd)
2157 current_trans->add_command (cmd);
2160 gettimeofday (&now, 0);
2161 current_trans->set_timestamp (now);
2163 _history.add (current_trans);
2166 Session::GlobalRouteBooleanState
2167 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2169 GlobalRouteBooleanState s;
2170 boost::shared_ptr<RouteList> r = routes.reader ();
2172 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2173 if (!(*i)->hidden()) {
2174 RouteBooleanState v;
2177 Route* r = (*i).get();
2178 v.second = (r->*method)();
2187 Session::GlobalRouteMeterState
2188 Session::get_global_route_metering ()
2190 GlobalRouteMeterState s;
2191 boost::shared_ptr<RouteList> r = routes.reader ();
2193 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2194 if (!(*i)->hidden()) {
2198 v.second = (*i)->meter_point();
2208 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2210 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2212 boost::shared_ptr<Route> r = (i->first.lock());
2215 r->set_meter_point (i->second, arg);
2221 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2223 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2225 boost::shared_ptr<Route> r = (i->first.lock());
2228 Route* rp = r.get();
2229 (rp->*method) (i->second, arg);
2235 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2237 set_global_route_boolean (s, &Route::set_mute, src);
2241 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2243 set_global_route_boolean (s, &Route::set_solo, src);
2247 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2249 set_global_route_boolean (s, &Route::set_record_enable, src);
2254 Session::global_mute_memento (void* src)
2256 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2260 Session::global_metering_memento (void* src)
2262 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2266 Session::global_solo_memento (void* src)
2268 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2272 Session::global_record_enable_memento (void* src)
2274 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2279 template_filter (const string &str, void *arg)
2281 return (str.length() > strlen(Session::template_suffix()) &&
2282 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2286 Session::get_template_list (list<string> &template_names)
2288 vector<string *> *templates;
2289 PathScanner scanner;
2292 path = template_path ();
2294 templates = scanner (path, template_filter, 0, false, true);
2296 vector<string*>::iterator i;
2297 for (i = templates->begin(); i != templates->end(); ++i) {
2298 string fullpath = *(*i);
2301 start = fullpath.find_last_of ('/') + 1;
2302 if ((end = fullpath.find_last_of ('.')) <0) {
2303 end = fullpath.length();
2306 template_names.push_back(fullpath.substr(start, (end-start)));
2311 Session::read_favorite_dirs (FavoriteDirs & favs)
2313 string path = get_user_ardour_path();
2314 path += "/favorite_dirs";
2316 ifstream fav (path.c_str());
2321 if (errno != ENOENT) {
2322 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2333 getline(fav, newfav);
2339 favs.push_back (newfav);
2346 Session::write_favorite_dirs (FavoriteDirs & favs)
2348 string path = get_user_ardour_path();
2349 path += "/favorite_dirs";
2351 ofstream fav (path.c_str());
2357 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2358 fav << (*i) << endl;
2365 accept_all_non_peak_files (const string& path, void *arg)
2367 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2371 accept_all_state_files (const string& path, void *arg)
2373 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2377 Session::find_all_sources (string path, set<string>& result)
2382 if (!tree.read (path)) {
2386 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2391 XMLNodeConstIterator niter;
2393 nlist = node->children();
2397 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2401 if ((prop = (*niter)->property (X_("name"))) == 0) {
2405 if (prop->value()[0] == '/') {
2406 /* external file, ignore */
2410 string path = _path; /* /-terminated */
2411 path += sound_dir_name;
2413 path += prop->value();
2415 result.insert (path);
2422 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2424 PathScanner scanner;
2425 vector<string*>* state_files;
2427 string this_snapshot_path;
2433 if (ripped[ripped.length()-1] == '/') {
2434 ripped = ripped.substr (0, ripped.length() - 1);
2437 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2439 if (state_files == 0) {
2444 this_snapshot_path = _path;
2445 this_snapshot_path += _current_snapshot_name;
2446 this_snapshot_path += _statefile_suffix;
2448 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2450 if (exclude_this_snapshot && **i == this_snapshot_path) {
2454 if (find_all_sources (**i, result) < 0) {
2462 struct RegionCounter {
2463 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2464 AudioSourceList::iterator iter;
2465 boost::shared_ptr<Region> region;
2468 RegionCounter() : count (0) {}
2472 Session::cleanup_sources (Session::cleanup_report& rep)
2474 vector<boost::shared_ptr<Source> > dead_sources;
2475 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2476 PathScanner scanner;
2478 vector<space_and_path>::iterator i;
2479 vector<space_and_path>::iterator nexti;
2480 vector<string*>* soundfiles;
2481 vector<string> unused;
2482 set<string> all_sources;
2487 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2489 /* step 1: consider deleting all unused playlists */
2491 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2494 status = AskAboutPlaylistDeletion (*x);
2503 playlists_tbd.push_back (*x);
2507 /* leave it alone */
2512 /* now delete any that were marked for deletion */
2514 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2515 (*x)->drop_references ();
2518 playlists_tbd.clear ();
2520 /* step 2: find all un-used sources */
2525 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2527 AudioSourceList::iterator tmp;
2532 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2536 if (!i->second->used() && i->second->length() > 0) {
2537 dead_sources.push_back (i->second);
2538 i->second->GoingAway();
2544 /* build a list of all the possible sound directories for the session */
2546 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2551 sound_path += (*i).path;
2552 sound_path += sound_dir (false);
2554 if (nexti != session_dirs.end()) {
2561 /* now do the same thing for the files that ended up in the sounds dir(s)
2562 but are not referenced as sources in any snapshot.
2565 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2567 if (soundfiles == 0) {
2571 /* find all sources, but don't use this snapshot because the
2572 state file on disk still references sources we may have already
2576 find_all_sources_across_snapshots (all_sources, true);
2578 /* add our current source list
2581 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2582 boost::shared_ptr<AudioFileSource> fs;
2584 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2585 all_sources.insert (fs->path());
2589 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2594 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2603 unused.push_back (spath);
2607 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2609 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2610 struct stat statbuf;
2612 rep.paths.push_back (*x);
2613 if (stat ((*x).c_str(), &statbuf) == 0) {
2614 rep.space += statbuf.st_size;
2619 /* don't move the file across filesystems, just
2620 stick it in the `dead_sound_dir_name' directory
2621 on whichever filesystem it was already on.
2624 if (_path.find ("/sounds/")) {
2626 /* old school, go up 1 level */
2628 newpath = Glib::path_get_dirname (*x); // "sounds"
2629 newpath = Glib::path_get_dirname (newpath); // "session-name"
2633 /* new school, go up 4 levels */
2635 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2636 newpath = Glib::path_get_dirname (newpath); // "session-name"
2637 newpath = Glib::path_get_dirname (newpath); // "interchange"
2638 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2642 newpath += dead_sound_dir_name;
2644 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2645 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2650 newpath += Glib::path_get_basename ((*x));
2652 if (access (newpath.c_str(), F_OK) == 0) {
2654 /* the new path already exists, try versioning */
2656 char buf[PATH_MAX+1];
2660 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2663 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2664 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2668 if (version == 999) {
2669 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2673 newpath = newpath_v;
2678 /* it doesn't exist, or we can't read it or something */
2682 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2683 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2684 (*x), newpath, strerror (errno))
2689 /* see if there an easy to find peakfile for this file, and remove it.
2692 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2693 peakpath += ".peak";
2695 if (access (peakpath.c_str(), W_OK) == 0) {
2696 if (::unlink (peakpath.c_str()) != 0) {
2697 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2698 peakpath, _path, strerror (errno))
2700 /* try to back out */
2701 rename (newpath.c_str(), _path.c_str());
2709 /* dump the history list */
2713 /* save state so we don't end up a session file
2714 referring to non-existent sources.
2720 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2725 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2727 vector<space_and_path>::iterator i;
2728 string dead_sound_dir;
2729 struct dirent* dentry;
2730 struct stat statbuf;
2736 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2738 dead_sound_dir = (*i).path;
2739 dead_sound_dir += dead_sound_dir_name;
2741 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2745 while ((dentry = readdir (dead)) != 0) {
2747 /* avoid '.' and '..' */
2749 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2750 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2756 fullpath = dead_sound_dir;
2758 fullpath += dentry->d_name;
2760 if (stat (fullpath.c_str(), &statbuf)) {
2764 if (!S_ISREG (statbuf.st_mode)) {
2768 if (unlink (fullpath.c_str())) {
2769 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2770 fullpath, strerror (errno))
2774 rep.paths.push_back (dentry->d_name);
2775 rep.space += statbuf.st_size;
2786 Session::set_dirty ()
2788 bool was_dirty = dirty();
2790 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2793 DirtyChanged(); /* EMIT SIGNAL */
2799 Session::set_clean ()
2801 bool was_dirty = dirty();
2803 _state_of_the_state = Clean;
2806 DirtyChanged(); /* EMIT SIGNAL */
2811 Session::set_deletion_in_progress ()
2813 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2817 Session::add_controllable (Controllable* c)
2819 Glib::Mutex::Lock lm (controllables_lock);
2820 controllables.insert (c);
2824 Session::remove_controllable (Controllable* c)
2826 if (_state_of_the_state | Deletion) {
2830 Glib::Mutex::Lock lm (controllables_lock);
2832 Controllables::iterator x = controllables.find (c);
2834 if (x != controllables.end()) {
2835 controllables.erase (x);
2840 Session::controllable_by_id (const PBD::ID& id)
2842 Glib::Mutex::Lock lm (controllables_lock);
2844 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2845 if ((*i)->id() == id) {
2854 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2856 Stateful::add_instant_xml (node, dir);
2857 Config->add_instant_xml (node, get_user_ardour_path());
2862 Session::save_history (string snapshot_name)
2868 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2870 if (snapshot_name.empty()) {
2871 snapshot_name = _current_snapshot_name;
2874 xml_path = _path + snapshot_name + ".history";
2876 bak_path = xml_path + ".bak";
2878 if ((access (xml_path.c_str(), F_OK) == 0) &&
2879 (rename (xml_path.c_str(), bak_path.c_str())))
2881 error << _("could not backup old history file, current history not saved.") << endmsg;
2885 if (!tree.write (xml_path))
2887 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
2889 /* don't leave a corrupt file lying around if it is
2893 if (unlink (xml_path.c_str())) {
2894 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
2896 if (rename (bak_path.c_str(), xml_path.c_str()))
2898 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
2909 Session::restore_history (string snapshot_name)
2914 if (snapshot_name.empty()) {
2915 snapshot_name = _current_snapshot_name;
2919 xmlpath = _path + snapshot_name + ".history";
2920 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
2922 if (access (xmlpath.c_str(), F_OK)) {
2923 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
2927 if (!tree.read (xmlpath)) {
2928 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
2932 /* replace history */
2935 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
2938 UndoTransaction* ut = new UndoTransaction ();
2941 ut->set_name(t->property("name")->value());
2942 stringstream ss(t->property("tv_sec")->value());
2944 ss.str(t->property("tv_usec")->value());
2946 ut->set_timestamp(tv);
2948 for (XMLNodeConstIterator child_it = t->children().begin();
2949 child_it != t->children().end();
2952 XMLNode *n = *child_it;
2955 if (n->name() == "MementoCommand" ||
2956 n->name() == "MementoUndoCommand" ||
2957 n->name() == "MementoRedoCommand") {
2959 if ((c = memento_command_factory(n))) {
2963 } else if (n->name() == X_("GlobalRouteStateCommand")) {
2965 if ((c = global_state_command_factory (*n))) {
2966 ut->add_command (c);
2971 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
2982 Session::config_changed (const char* parameter_name)
2984 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
2986 if (PARAM_IS ("seamless-loop")) {
2988 } else if (PARAM_IS ("rf-speed")) {
2990 } else if (PARAM_IS ("auto-loop")) {
2992 } else if (PARAM_IS ("auto-input")) {
2994 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
2995 /* auto-input only makes a difference if we're rolling */
2997 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
2999 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3000 if ((*i)->record_enabled ()) {
3001 (*i)->monitor_input (!Config->get_auto_input());
3006 } else if (PARAM_IS ("punch-in")) {
3010 if ((location = _locations.auto_punch_location()) != 0) {
3012 if (Config->get_punch_in ()) {
3013 replace_event (Event::PunchIn, location->start());
3015 remove_event (location->start(), Event::PunchIn);
3019 } else if (PARAM_IS ("punch-out")) {
3023 if ((location = _locations.auto_punch_location()) != 0) {
3025 if (Config->get_punch_out()) {
3026 replace_event (Event::PunchOut, location->end());
3028 clear_events (Event::PunchOut);
3032 } else if (PARAM_IS ("edit-mode")) {
3034 Glib::Mutex::Lock lm (playlist_lock);
3036 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3037 (*i)->set_edit_mode (Config->get_edit_mode ());
3040 } else if (PARAM_IS ("use-video-sync")) {
3042 if (transport_stopped()) {
3043 if (Config->get_use_video_sync()) {
3044 waiting_for_sync_offset = true;
3048 } else if (PARAM_IS ("mmc-control")) {
3050 poke_midi_thread ();
3052 } else if (PARAM_IS ("midi-control")) {
3054 poke_midi_thread ();
3056 } else if (PARAM_IS ("raid-path")) {
3058 setup_raid_path (Config->get_raid_path());
3060 } else if (PARAM_IS ("smpte-format")) {
3064 } else if (PARAM_IS ("video-pullup")) {
3068 } else if (PARAM_IS ("seamless-loop")) {
3070 if (play_loop && transport_rolling()) {
3071 // to reset diskstreams etc
3072 request_play_loop (true);
3075 } else if (PARAM_IS ("rf-speed")) {
3077 cumulative_rf_motion = 0;
3080 } else if (PARAM_IS ("click-sound")) {
3082 setup_click_sounds (1);
3084 } else if (PARAM_IS ("click-emphasis-sound")) {
3086 setup_click_sounds (-1);
3088 } else if (PARAM_IS ("clicking")) {
3090 if (Config->get_clicking()) {
3091 if (_click_io && click_data) { // don't require emphasis data
3098 } else if (PARAM_IS ("send-mtc")) {
3100 /* only set the internal flag if we have
3104 if (_mtc_port != 0) {
3105 session_send_mtc = Config->get_send_mtc();
3106 if (session_send_mtc) {
3107 /* mark us ready to send */
3108 next_quarter_frame_to_send = 0;
3112 } else if (PARAM_IS ("send-mmc")) {
3114 /* only set the internal flag if we have
3118 if (_mmc_port != 0) {
3119 session_send_mmc = Config->get_send_mmc();
3122 } else if (PARAM_IS ("midi-feedback")) {
3124 /* only set the internal flag if we have
3128 if (_mtc_port != 0) {
3129 session_midi_feedback = Config->get_midi_feedback();
3132 } else if (PARAM_IS ("jack-time-master")) {
3134 engine().reset_timebase ();
3136 } else if (PARAM_IS ("native-file-header-format")) {
3138 if (!first_file_header_format_reset) {
3139 reset_native_file_format ();
3142 first_file_header_format_reset = false;
3144 } else if (PARAM_IS ("native-file-data-format")) {
3146 if (!first_file_data_format_reset) {
3147 reset_native_file_format ();
3150 first_file_data_format_reset = false;
3152 } else if (PARAM_IS ("slave-source")) {
3153 set_slave_source (Config->get_slave_source());