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.
25 #include <sigc++/bind.h>
27 #include <cstdio> /* snprintf(3) ... grrr */
42 #include <sys/param.h>
43 #include <sys/mount.h>
48 #include <midi++/mmc.h>
49 #include <midi++/port.h>
50 #include <pbd/error.h>
52 #include <glibmm/thread.h>
53 #include <pbd/pathscanner.h>
54 #include <pbd/pthread_utils.h>
55 #include <pbd/strsplit.h>
56 #include <pbd/stacktrace.h>
57 #include <pbd/copyfile.h>
59 #include <ardour/audioengine.h>
60 #include <ardour/configuration.h>
61 #include <ardour/session.h>
62 #include <ardour/audio_diskstream.h>
63 #include <ardour/utils.h>
64 #include <ardour/audioplaylist.h>
65 #include <ardour/audiofilesource.h>
66 #include <ardour/silentfilesource.h>
67 #include <ardour/sndfilesource.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 auto_play_legal = false;
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;
187 butler_thread = (pthread_t) 0;
188 midi_thread = (pthread_t) 0;
190 AudioDiskstream::allocate_working_buffers();
192 /* default short fade = 15ms */
194 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
195 SndFileSource::setup_standard_crossfades (frame_rate());
197 last_mmc_step.tv_sec = 0;
198 last_mmc_step.tv_usec = 0;
201 /* click sounds are unset by default, which causes us to internal
202 waveforms for clicks.
206 click_emphasis_data = 0;
208 click_emphasis_length = 0;
211 process_function = &Session::process_with_events;
213 if (Config->get_use_video_sync()) {
214 waiting_for_sync_offset = true;
216 waiting_for_sync_offset = false;
219 _current_frame_rate = 48000;
220 _base_frame_rate = 48000;
224 _smpte_offset_negative = true;
225 last_smpte_valid = false;
229 last_rr_session_dir = session_dirs.begin();
230 refresh_disk_space ();
232 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
236 average_slave_delta = 1800;
237 have_first_delta_accumulator = false;
238 delta_accumulator_cnt = 0;
239 slave_state = Stopped;
241 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
243 /* These are all static "per-class" signals */
245 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
246 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
247 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
248 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
249 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
250 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
252 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
254 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
256 /* stop IO objects from doing stuff until we're ready for them */
258 IO::disable_panners ();
259 IO::disable_ports ();
260 IO::disable_connecting ();
264 Session::second_stage_init (bool new_session)
266 AudioFileSource::set_peak_dir (peak_dir());
269 if (load_state (_current_snapshot_name)) {
272 remove_empty_sounds ();
275 if (start_butler_thread()) {
279 if (start_midi_thread ()) {
283 // set_state() will call setup_raid_path(), but if it's a new session we need
284 // to call setup_raid_path() here.
286 if (set_state (*state_tree->root())) {
290 setup_raid_path(_path);
293 /* we can't save till after ::when_engine_running() is called,
294 because otherwise we save state with no connections made.
295 therefore, we reset _state_of_the_state because ::set_state()
296 will have cleared it.
298 we also have to include Loading so that any events that get
299 generated between here and the end of ::when_engine_running()
300 will be processed directly rather than queued.
303 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
305 // set_auto_input (true);
306 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
307 _locations.added.connect (mem_fun (this, &Session::locations_added));
308 setup_click_sounds (0);
309 setup_midi_control ();
311 /* Pay attention ... */
313 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
314 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
317 when_engine_running();
320 /* handle this one in a different way than all others, so that its clear what happened */
322 catch (AudioEngine::PortRegistrationFailure& err) {
323 error << _("Unable to create all required ports")
332 send_full_time_code ();
333 _engine.transport_locate (0);
334 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
335 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
337 ControlProtocolManager::instance().set_session (*this);
340 _end_location_is_free = true;
342 _end_location_is_free = false;
349 Session::raid_path () const
353 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
358 return path.substr (0, path.length() - 1); // drop final colon
362 Session::setup_raid_path (string path)
364 string::size_type colon;
368 string::size_type len = path.length();
373 if (path.length() == 0) {
377 session_dirs.clear ();
379 for (string::size_type n = 0; n < len; ++n) {
380 if (path[n] == ':') {
387 /* no multiple search path, just one location (common case) */
391 session_dirs.push_back (sp);
398 if (fspath[fspath.length()-1] != '/') {
402 fspath += sound_dir (false);
404 AudioFileSource::set_search_path (fspath);
411 while ((colon = remaining.find_first_of (':')) != string::npos) {
414 sp.path = remaining.substr (0, colon);
415 session_dirs.push_back (sp);
417 /* add sounds to file search path */
420 if (fspath[fspath.length()-1] != '/') {
423 fspath += sound_dir (false);
426 remaining = remaining.substr (colon+1);
429 if (remaining.length()) {
436 if (fspath[fspath.length()-1] != '/') {
439 fspath += sound_dir (false);
442 session_dirs.push_back (sp);
445 /* set the AudioFileSource search path */
447 AudioFileSource::set_search_path (fspath);
449 /* reset the round-robin soundfile path thingie */
451 last_rr_session_dir = session_dirs.begin();
455 Session::create (bool& new_session, string* mix_template, nframes_t initial_length)
459 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
460 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
466 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
467 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
471 /* if this is is an existing session with an old "sounds" directory, just use it. see Session::sound_dir() for more details */
473 if (!Glib::file_test (old_sound_dir(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
477 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
478 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483 dir = dead_sound_dir ();
485 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
486 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
492 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
493 error << string_compose(_("Session: cannot create session export dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
498 /* check new_session so we don't overwrite an existing one */
501 std::string in_path = *mix_template;
503 ifstream in(in_path.c_str());
506 string out_path = _path;
508 out_path += _statefile_suffix;
510 ofstream out(out_path.c_str());
515 // okay, session is set up. Treat like normal saved
516 // session from now on.
522 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
528 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
535 /* set initial start + end point */
537 start_location->set_end (0);
538 _locations.add (start_location);
540 end_location->set_end (initial_length);
541 _locations.add (end_location);
543 _state_of_the_state = Clean;
545 if (save_state (_current_snapshot_name)) {
553 Session::load_diskstreams (const XMLNode& node)
556 XMLNodeConstIterator citer;
558 clist = node.children();
560 for (citer = clist.begin(); citer != clist.end(); ++citer) {
564 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
565 add_diskstream (dstream);
568 catch (failed_constructor& err) {
569 error << _("Session: could not load diskstream via XML state") << endmsg;
578 Session::maybe_write_autosave()
580 if (dirty() && record_status() != Recording) {
581 save_state("", true);
586 Session::remove_pending_capture_state ()
591 xml_path += _current_snapshot_name;
592 xml_path += _pending_suffix;
594 unlink (xml_path.c_str());
597 /** Rename a state file.
598 * @param snapshot_name Snapshot name.
601 Session::rename_state (string old_name, string new_name)
603 if (old_name == _current_snapshot_name || old_name == _name) {
604 /* refuse to rename the current snapshot or the "main" one */
608 const string old_xml_path = _path + old_name + _statefile_suffix;
609 const string new_xml_path = _path + new_name + _statefile_suffix;
611 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
612 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
616 /** Remove a state file.
617 * @param snapshot_name Snapshot name.
620 Session::remove_state (string snapshot_name)
622 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
623 /* refuse to remove the current snapshot or the "main" one */
627 const string xml_path = _path + snapshot_name + _statefile_suffix;
629 /* make a backup copy of the state file */
630 const string bak_path = xml_path + ".bak";
631 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
632 copy_file (xml_path, bak_path);
636 unlink (xml_path.c_str());
640 Session::save_state (string snapshot_name, bool pending)
646 if (_state_of_the_state & CannotSave) {
650 if (!_engine.connected ()) {
651 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
656 tree.set_root (&get_state());
658 if (snapshot_name.empty()) {
659 snapshot_name = _current_snapshot_name;
664 /* proper save: use _statefile_suffix (.ardour in English) */
666 xml_path += snapshot_name;
667 xml_path += _statefile_suffix;
669 /* make a backup copy of the old file */
673 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
674 copy_file (xml_path, bak_path);
679 /* pending save: use _pending_suffix (.pending in English) */
681 xml_path += snapshot_name;
682 xml_path += _pending_suffix;
689 tmp_path += snapshot_name;
692 // cerr << "actually writing state to " << xml_path << endl;
694 if (!tree.write (tmp_path)) {
695 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
696 unlink (tmp_path.c_str());
701 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
702 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
703 unlink (tmp_path.c_str());
710 save_history (snapshot_name);
712 bool was_dirty = dirty();
714 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
717 DirtyChanged (); /* EMIT SIGNAL */
720 StateSaved (snapshot_name); /* EMIT SIGNAL */
727 Session::restore_state (string snapshot_name)
729 if (load_state (snapshot_name) == 0) {
730 set_state (*state_tree->root());
737 Session::load_state (string snapshot_name)
746 state_was_pending = false;
748 /* check for leftover pending state from a crashed capture attempt */
751 xmlpath += snapshot_name;
752 xmlpath += _pending_suffix;
754 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
756 /* there is pending state from a crashed capture attempt */
758 if (AskAboutPendingState()) {
759 state_was_pending = true;
763 if (!state_was_pending) {
766 xmlpath += snapshot_name;
767 xmlpath += _statefile_suffix;
770 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
771 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
775 state_tree = new XMLTree;
779 if (!state_tree->read (xmlpath)) {
780 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
786 XMLNode& root (*state_tree->root());
788 if (root.name() != X_("Session")) {
789 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
795 const XMLProperty* prop;
798 if ((prop = root.property ("version")) == 0) {
799 /* no version implies very old version of Ardour */
803 major_version = atoi (prop->value()); // grab just the first number before the period
804 if (major_version < 2) {
813 backup_path += snapshot_name;
815 backup_path += _statefile_suffix;
817 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
818 xmlpath, backup_path)
821 copy_file (xmlpath, backup_path);
823 /* if it fails, don't worry. right? */
830 Session::load_options (const XMLNode& node)
834 LocaleGuard lg (X_("POSIX"));
836 Config->set_variables (node, ConfigVariableBase::Session);
838 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
839 if ((prop = child->property ("val")) != 0) {
840 _end_location_is_free = (prop->value() == "yes");
848 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
850 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
851 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
853 return owner & modified_by_session_or_user;
857 Session::get_options () const
860 LocaleGuard lg (X_("POSIX"));
862 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
864 child = option_root.add_child ("end-marker-is-free");
865 child->add_property ("val", _end_location_is_free ? "yes" : "no");
877 Session::get_template()
879 /* if we don't disable rec-enable, diskstreams
880 will believe they need to store their capture
881 sources in their state node.
884 disable_record (false);
890 Session::state(bool full_state)
892 XMLNode* node = new XMLNode("Session");
895 // store libardour version, just in case
897 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
898 libardour_major_version, libardour_minor_version, libardour_micro_version);
899 node->add_property("version", string(buf));
901 /* store configuration settings */
906 node->add_property ("name", _name);
908 if (session_dirs.size() > 1) {
912 vector<space_and_path>::iterator i = session_dirs.begin();
913 vector<space_and_path>::iterator next;
915 ++i; /* skip the first one */
919 while (i != session_dirs.end()) {
923 if (next != session_dirs.end()) {
933 child = node->add_child ("Path");
934 child->add_content (p);
938 /* save the ID counter */
940 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
941 node->add_property ("id-counter", buf);
943 /* various options */
945 node->add_child_nocopy (get_options());
947 child = node->add_child ("Sources");
950 Glib::Mutex::Lock sl (audio_source_lock);
952 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
954 /* Don't save information about AudioFileSources that are empty */
956 boost::shared_ptr<AudioFileSource> fs;
958 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
960 /* destructive file sources are OK if they are empty, because
961 we will re-use them every time.
964 if (!fs->destructive()) {
965 if (fs->length() == 0) {
971 child->add_child_nocopy (siter->second->get_state());
975 child = node->add_child ("Regions");
978 Glib::Mutex::Lock rl (region_lock);
980 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
982 /* only store regions not attached to playlists */
984 if (i->second->playlist() == 0) {
985 child->add_child_nocopy (i->second->state (true));
990 child = node->add_child ("DiskStreams");
993 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
994 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
995 if (!(*i)->hidden()) {
996 child->add_child_nocopy ((*i)->get_state());
1002 node->add_child_nocopy (_locations.get_state());
1004 // for a template, just create a new Locations, populate it
1005 // with the default start and end, and get the state for that.
1007 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1008 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1011 end->set_end(compute_initial_length());
1013 node->add_child_nocopy (loc.get_state());
1016 child = node->add_child ("Connections");
1018 Glib::Mutex::Lock lm (connection_lock);
1019 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1020 if (!(*i)->system_dependent()) {
1021 child->add_child_nocopy ((*i)->get_state());
1026 child = node->add_child ("Routes");
1028 boost::shared_ptr<RouteList> r = routes.reader ();
1030 RoutePublicOrderSorter cmp;
1031 RouteList public_order (*r);
1032 public_order.sort (cmp);
1034 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1035 if (!(*i)->hidden()) {
1037 child->add_child_nocopy ((*i)->get_state());
1039 child->add_child_nocopy ((*i)->get_template());
1046 child = node->add_child ("EditGroups");
1047 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1048 child->add_child_nocopy ((*i)->get_state());
1051 child = node->add_child ("MixGroups");
1052 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1053 child->add_child_nocopy ((*i)->get_state());
1056 child = node->add_child ("Playlists");
1057 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1058 if (!(*i)->hidden()) {
1059 if (!(*i)->empty()) {
1061 child->add_child_nocopy ((*i)->get_state());
1063 child->add_child_nocopy ((*i)->get_template());
1069 child = node->add_child ("UnusedPlaylists");
1070 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1071 if (!(*i)->hidden()) {
1072 if (!(*i)->empty()) {
1074 child->add_child_nocopy ((*i)->get_state());
1076 child->add_child_nocopy ((*i)->get_template());
1084 child = node->add_child ("Click");
1085 child->add_child_nocopy (_click_io->state (full_state));
1089 child = node->add_child ("NamedSelections");
1090 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1092 child->add_child_nocopy ((*i)->get_state());
1097 node->add_child_nocopy (_tempo_map->get_state());
1099 node->add_child_nocopy (get_control_protocol_state());
1102 node->add_child_copy (*_extra_xml);
1109 Session::get_control_protocol_state ()
1111 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1112 return cpm.get_state();
1116 Session::set_state (const XMLNode& node)
1120 const XMLProperty* prop;
1123 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1125 if (node.name() != X_("Session")){
1126 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1130 if ((prop = node.property ("name")) != 0) {
1131 _name = prop->value ();
1134 setup_raid_path(_path);
1136 if ((prop = node.property (X_("id-counter"))) != 0) {
1138 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1139 ID::init_counter (x);
1141 /* old sessions used a timebased counter, so fake
1142 the startup ID counter based on a standard
1147 ID::init_counter (now);
1151 IO::disable_ports ();
1152 IO::disable_connecting ();
1154 /* Object loading order:
1172 if (use_config_midi_ports ()) {
1175 if ((child = find_named_node (node, "extra")) != 0) {
1176 _extra_xml = new XMLNode (*child);
1179 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1180 load_options (*child);
1181 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1182 load_options (*child);
1184 error << _("Session: XML state has no options section") << endmsg;
1187 if ((child = find_named_node (node, "Locations")) == 0) {
1188 error << _("Session: XML state has no locations section") << endmsg;
1190 } else if (_locations.set_state (*child)) {
1196 if ((location = _locations.auto_loop_location()) != 0) {
1197 set_auto_loop_location (location);
1200 if ((location = _locations.auto_punch_location()) != 0) {
1201 set_auto_punch_location (location);
1204 if ((location = _locations.end_location()) == 0) {
1205 _locations.add (end_location);
1207 delete end_location;
1208 end_location = location;
1211 if ((location = _locations.start_location()) == 0) {
1212 _locations.add (start_location);
1214 delete start_location;
1215 start_location = location;
1218 AudioFileSource::set_header_position_offset (start_location->start());
1220 if ((child = find_named_node (node, "Sources")) == 0) {
1221 error << _("Session: XML state has no sources section") << endmsg;
1223 } else if (load_sources (*child)) {
1227 if ((child = find_named_node (node, "Regions")) == 0) {
1228 error << _("Session: XML state has no Regions section") << endmsg;
1230 } else if (load_regions (*child)) {
1234 if ((child = find_named_node (node, "Playlists")) == 0) {
1235 error << _("Session: XML state has no playlists section") << endmsg;
1237 } else if (load_playlists (*child)) {
1241 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1243 } else if (load_unused_playlists (*child)) {
1247 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1248 if (load_named_selections (*child)) {
1253 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1254 error << _("Session: XML state has no diskstreams section") << endmsg;
1256 } else if (load_diskstreams (*child)) {
1260 if ((child = find_named_node (node, "Connections")) == 0) {
1261 error << _("Session: XML state has no connections section") << endmsg;
1263 } else if (load_connections (*child)) {
1267 if ((child = find_named_node (node, "EditGroups")) == 0) {
1268 error << _("Session: XML state has no edit groups section") << endmsg;
1270 } else if (load_edit_groups (*child)) {
1274 if ((child = find_named_node (node, "MixGroups")) == 0) {
1275 error << _("Session: XML state has no mix groups section") << endmsg;
1277 } else if (load_mix_groups (*child)) {
1281 if ((child = find_named_node (node, "TempoMap")) == 0) {
1282 error << _("Session: XML state has no Tempo Map section") << endmsg;
1284 } else if (_tempo_map->set_state (*child)) {
1288 if ((child = find_named_node (node, "Routes")) == 0) {
1289 error << _("Session: XML state has no routes section") << endmsg;
1291 } else if (load_routes (*child)) {
1295 if ((child = find_named_node (node, "Click")) == 0) {
1296 warning << _("Session: XML state has no click section") << endmsg;
1297 } else if (_click_io) {
1298 _click_io->set_state (*child);
1301 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1302 ControlProtocolManager::instance().set_protocol_states (*child);
1305 /* here beginneth the second phase ... */
1307 StateReady (); /* EMIT SIGNAL */
1309 _state_of_the_state = Clean;
1311 if (state_was_pending) {
1312 save_state (_current_snapshot_name);
1313 remove_pending_capture_state ();
1314 state_was_pending = false;
1324 Session::load_routes (const XMLNode& node)
1327 XMLNodeConstIterator niter;
1328 RouteList new_routes;
1330 nlist = node.children();
1334 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1336 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1339 error << _("Session: cannot create Route from XML description.") << endmsg;
1343 new_routes.push_back (route);
1346 add_routes (new_routes);
1351 boost::shared_ptr<Route>
1352 Session::XMLRouteFactory (const XMLNode& node)
1354 if (node.name() != "Route") {
1355 return boost::shared_ptr<Route> ((Route*) 0);
1358 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1359 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1362 boost::shared_ptr<Route> x (new Route (*this, node));
1368 Session::load_regions (const XMLNode& node)
1371 XMLNodeConstIterator niter;
1372 boost::shared_ptr<AudioRegion> region;
1374 nlist = node.children();
1378 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1379 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1380 error << _("Session: cannot create Region from XML description.") << endmsg;
1387 boost::shared_ptr<AudioRegion>
1388 Session::XMLRegionFactory (const XMLNode& node, bool full)
1390 const XMLProperty* prop;
1391 boost::shared_ptr<Source> source;
1392 boost::shared_ptr<AudioSource> as;
1394 uint32_t nchans = 1;
1397 if (node.name() != X_("Region")) {
1398 return boost::shared_ptr<AudioRegion>();
1401 if ((prop = node.property (X_("channels"))) != 0) {
1402 nchans = atoi (prop->value().c_str());
1406 if ((prop = node.property ("name")) == 0) {
1407 cerr << "no name for this region\n";
1411 if ((prop = node.property (X_("source-0"))) == 0) {
1412 if ((prop = node.property ("source")) == 0) {
1413 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1414 return boost::shared_ptr<AudioRegion>();
1418 PBD::ID s_id (prop->value());
1420 if ((source = source_by_id (s_id)) == 0) {
1421 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1422 return boost::shared_ptr<AudioRegion>();
1425 as = boost::dynamic_pointer_cast<AudioSource>(source);
1427 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1428 return boost::shared_ptr<AudioRegion>();
1431 sources.push_back (as);
1433 /* pickup other channels */
1435 for (uint32_t n=1; n < nchans; ++n) {
1436 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1437 if ((prop = node.property (buf)) != 0) {
1439 PBD::ID id2 (prop->value());
1441 if ((source = source_by_id (id2)) == 0) {
1442 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1443 return boost::shared_ptr<AudioRegion>();
1446 as = boost::dynamic_pointer_cast<AudioSource>(source);
1448 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1449 return boost::shared_ptr<AudioRegion>();
1451 sources.push_back (as);
1456 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1458 /* a final detail: this is the one and only place that we know how long missing files are */
1460 if (region->whole_file()) {
1461 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1462 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1464 sfp->set_length (region->length());
1474 catch (failed_constructor& err) {
1475 return boost::shared_ptr<AudioRegion>();
1480 Session::get_sources_as_xml ()
1483 XMLNode* node = new XMLNode (X_("Sources"));
1484 Glib::Mutex::Lock lm (audio_source_lock);
1486 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1487 node->add_child_nocopy (i->second->get_state());
1490 /* XXX get MIDI and other sources here */
1496 Session::path_from_region_name (string name, string identifier)
1498 char buf[PATH_MAX+1];
1500 string dir = discover_best_sound_dir ();
1502 for (n = 0; n < 999999; ++n) {
1503 if (identifier.length()) {
1504 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1505 identifier.c_str(), n);
1507 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1510 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1515 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1524 Session::load_sources (const XMLNode& node)
1527 XMLNodeConstIterator niter;
1528 boost::shared_ptr<Source> source;
1530 nlist = node.children();
1534 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1537 if ((source = XMLSourceFactory (**niter)) == 0) {
1538 error << _("Session: cannot create Source from XML description.") << endmsg;
1542 catch (non_existent_source& err) {
1543 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1544 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1551 boost::shared_ptr<Source>
1552 Session::XMLSourceFactory (const XMLNode& node)
1554 if (node.name() != "Source") {
1555 return boost::shared_ptr<Source>();
1559 return SourceFactory::create (*this, node);
1562 catch (failed_constructor& err) {
1563 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1564 return boost::shared_ptr<Source>();
1569 Session::save_template (string template_name)
1572 string xml_path, bak_path, template_path;
1574 if (_state_of_the_state & CannotSave) {
1579 string dir = template_dir();
1581 if ((dp = opendir (dir.c_str()))) {
1584 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1585 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1590 tree.set_root (&get_template());
1593 xml_path += template_name;
1594 xml_path += _template_suffix;
1596 ifstream in(xml_path.c_str());
1599 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1605 if (!tree.write (xml_path)) {
1606 error << _("mix template not saved") << endmsg;
1614 Session::rename_template (string old_name, string new_name)
1616 string old_path = template_dir() + old_name + _template_suffix;
1617 string new_path = template_dir() + new_name + _template_suffix;
1619 return rename (old_path.c_str(), new_path.c_str());
1623 Session::delete_template (string name)
1625 string template_path = template_dir();
1626 template_path += name;
1627 template_path += _template_suffix;
1629 return remove (template_path.c_str());
1633 Session::refresh_disk_space ()
1636 struct statfs statfsbuf;
1637 vector<space_and_path>::iterator i;
1638 Glib::Mutex::Lock lm (space_lock);
1641 /* get freespace on every FS that is part of the session path */
1643 _total_free_4k_blocks = 0;
1645 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1646 statfs ((*i).path.c_str(), &statfsbuf);
1648 scale = statfsbuf.f_bsize/4096.0;
1650 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1651 _total_free_4k_blocks += (*i).blocks;
1657 Session::ensure_sound_dir (string path, string& result)
1662 /* Ensure that the parent directory exists */
1664 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1665 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1669 /* Ensure that the sounds directory exists */
1673 result += sound_dir_name;
1675 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1676 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1682 dead += dead_sound_dir_name;
1684 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1685 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1691 peak += peak_dir_name;
1693 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1694 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1698 /* callers expect this to be terminated ... */
1705 Session::discover_best_sound_dir (bool destructive)
1707 vector<space_and_path>::iterator i;
1710 /* handle common case without system calls */
1712 if (session_dirs.size() == 1) {
1716 /* OK, here's the algorithm we're following here:
1718 We want to select which directory to use for
1719 the next file source to be created. Ideally,
1720 we'd like to use a round-robin process so as to
1721 get maximum performance benefits from splitting
1722 the files across multiple disks.
1724 However, in situations without much diskspace, an
1725 RR approach may end up filling up a filesystem
1726 with new files while others still have space.
1727 Its therefore important to pay some attention to
1728 the freespace in the filesystem holding each
1729 directory as well. However, if we did that by
1730 itself, we'd keep creating new files in the file
1731 system with the most space until it was as full
1732 as all others, thus negating any performance
1733 benefits of this RAID-1 like approach.
1735 So, we use a user-configurable space threshold. If
1736 there are at least 2 filesystems with more than this
1737 much space available, we use RR selection between them.
1738 If not, then we pick the filesystem with the most space.
1740 This gets a good balance between the two
1744 refresh_disk_space ();
1746 int free_enough = 0;
1748 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1749 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1754 if (free_enough >= 2) {
1756 bool found_it = false;
1758 /* use RR selection process, ensuring that the one
1762 i = last_rr_session_dir;
1765 if (++i == session_dirs.end()) {
1766 i = session_dirs.begin();
1769 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1770 if (ensure_sound_dir ((*i).path, result) == 0) {
1771 last_rr_session_dir = i;
1777 } while (i != last_rr_session_dir);
1780 result = sound_dir();
1785 /* pick FS with the most freespace (and that
1786 seems to actually work ...)
1789 vector<space_and_path> sorted;
1790 space_and_path_ascending_cmp cmp;
1792 sorted = session_dirs;
1793 sort (sorted.begin(), sorted.end(), cmp);
1795 for (i = sorted.begin(); i != sorted.end(); ++i) {
1796 if (ensure_sound_dir ((*i).path, result) == 0) {
1797 last_rr_session_dir = i;
1802 /* if the above fails, fall back to the most simplistic solution */
1804 if (i == sorted.end()) {
1813 Session::load_playlists (const XMLNode& node)
1816 XMLNodeConstIterator niter;
1817 boost::shared_ptr<Playlist> playlist;
1819 nlist = node.children();
1823 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1825 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1826 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1834 Session::load_unused_playlists (const XMLNode& node)
1837 XMLNodeConstIterator niter;
1838 boost::shared_ptr<Playlist> playlist;
1840 nlist = node.children();
1844 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1846 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1847 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1851 // now manually untrack it
1853 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1860 boost::shared_ptr<Playlist>
1861 Session::XMLPlaylistFactory (const XMLNode& node)
1864 return PlaylistFactory::create (*this, node);
1867 catch (failed_constructor& err) {
1868 return boost::shared_ptr<Playlist>();
1873 Session::load_named_selections (const XMLNode& node)
1876 XMLNodeConstIterator niter;
1879 nlist = node.children();
1883 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1885 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1886 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1894 Session::XMLNamedSelectionFactory (const XMLNode& node)
1897 return new NamedSelection (*this, node);
1900 catch (failed_constructor& err) {
1906 Session::dead_sound_dir () const
1909 res += dead_sound_dir_name;
1915 Session::old_sound_dir (bool with_path) const
1923 res += old_sound_dir_name;
1929 Session::sound_dir (bool with_path) const
1940 res += interchange_dir_name;
1942 res += legalize_for_path (_name);
1944 res += sound_dir_name;
1952 /* if this already exists, don't check for the old session sound directory */
1954 if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
1958 /* possibly support old session structure */
1961 string old_withpath;
1963 old_nopath += old_sound_dir_name;
1966 old_withpath = _path;
1967 old_withpath += old_sound_dir_name;
1969 if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
1971 return old_withpath;
1976 /* ok, old "sounds" directory isn't there, return the new path */
1982 Session::peak_dir () const
1985 res += peak_dir_name;
1991 Session::automation_dir () const
1994 res += "automation/";
1999 Session::template_dir ()
2001 string path = get_user_ardour_path();
2002 path += "templates/";
2008 Session::export_dir () const
2011 res += export_dir_name;
2017 Session::suffixed_search_path (string suffix, bool data)
2021 path += get_user_ardour_path();
2022 if (path[path.length()-1] != ':') {
2027 path += get_system_data_path();
2029 path += get_system_module_path();
2032 vector<string> split_path;
2034 split (path, split_path, ':');
2037 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2042 if (distance (i, split_path.end()) != 1) {
2051 Session::template_path ()
2053 return suffixed_search_path (X_("templates"), true);
2057 Session::control_protocol_path ()
2059 return suffixed_search_path (X_("surfaces"), false);
2063 Session::load_connections (const XMLNode& node)
2065 XMLNodeList nlist = node.children();
2066 XMLNodeConstIterator niter;
2070 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2071 if ((*niter)->name() == "InputConnection") {
2072 add_connection (new ARDOUR::InputConnection (**niter));
2073 } else if ((*niter)->name() == "OutputConnection") {
2074 add_connection (new ARDOUR::OutputConnection (**niter));
2076 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2085 Session::load_edit_groups (const XMLNode& node)
2087 return load_route_groups (node, true);
2091 Session::load_mix_groups (const XMLNode& node)
2093 return load_route_groups (node, false);
2097 Session::load_route_groups (const XMLNode& node, bool edit)
2099 XMLNodeList nlist = node.children();
2100 XMLNodeConstIterator niter;
2105 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2106 if ((*niter)->name() == "RouteGroup") {
2108 rg = add_edit_group ("");
2109 rg->set_state (**niter);
2111 rg = add_mix_group ("");
2112 rg->set_state (**niter);
2121 state_file_filter (const string &str, void *arg)
2123 return (str.length() > strlen(Session::statefile_suffix()) &&
2124 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2128 bool operator()(const string* a, const string* b) {
2134 remove_end(string* state)
2136 string statename(*state);
2138 string::size_type start,end;
2139 if ((start = statename.find_last_of ('/')) != string::npos) {
2140 statename = statename.substr (start+1);
2143 if ((end = statename.rfind(".ardour")) == string::npos) {
2144 end = statename.length();
2147 return new string(statename.substr (0, end));
2151 Session::possible_states (string path)
2153 PathScanner scanner;
2154 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2156 transform(states->begin(), states->end(), states->begin(), remove_end);
2159 sort (states->begin(), states->end(), cmp);
2165 Session::possible_states () const
2167 return possible_states(_path);
2171 Session::auto_save()
2173 save_state (_current_snapshot_name);
2177 Session::add_edit_group (string name)
2179 RouteGroup* rg = new RouteGroup (*this, name);
2180 edit_groups.push_back (rg);
2181 edit_group_added (rg); /* EMIT SIGNAL */
2187 Session::add_mix_group (string name)
2189 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2190 mix_groups.push_back (rg);
2191 mix_group_added (rg); /* EMIT SIGNAL */
2197 Session::remove_edit_group (RouteGroup& rg)
2199 list<RouteGroup*>::iterator i;
2201 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2202 (*i)->apply (&Route::drop_edit_group, this);
2203 edit_groups.erase (i);
2204 edit_group_removed (); /* EMIT SIGNAL */
2211 Session::remove_mix_group (RouteGroup& rg)
2213 list<RouteGroup*>::iterator i;
2215 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2216 (*i)->apply (&Route::drop_mix_group, this);
2217 mix_groups.erase (i);
2218 mix_group_removed (); /* EMIT SIGNAL */
2225 Session::mix_group_by_name (string name)
2227 list<RouteGroup *>::iterator i;
2229 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2230 if ((*i)->name() == name) {
2238 Session::edit_group_by_name (string name)
2240 list<RouteGroup *>::iterator i;
2242 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2243 if ((*i)->name() == name) {
2251 Session::begin_reversible_command (string name)
2253 current_trans = new UndoTransaction;
2254 current_trans->set_name (name);
2258 Session::commit_reversible_command (Command *cmd)
2263 current_trans->add_command (cmd);
2266 gettimeofday (&now, 0);
2267 current_trans->set_timestamp (now);
2269 _history.add (current_trans);
2272 Session::GlobalRouteBooleanState
2273 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2275 GlobalRouteBooleanState s;
2276 boost::shared_ptr<RouteList> r = routes.reader ();
2278 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2279 if (!(*i)->hidden()) {
2280 RouteBooleanState v;
2283 Route* r = (*i).get();
2284 v.second = (r->*method)();
2293 Session::GlobalRouteMeterState
2294 Session::get_global_route_metering ()
2296 GlobalRouteMeterState s;
2297 boost::shared_ptr<RouteList> r = routes.reader ();
2299 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2300 if (!(*i)->hidden()) {
2304 v.second = (*i)->meter_point();
2314 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2316 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2318 boost::shared_ptr<Route> r = (i->first.lock());
2321 r->set_meter_point (i->second, arg);
2327 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2329 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2331 boost::shared_ptr<Route> r = (i->first.lock());
2334 Route* rp = r.get();
2335 (rp->*method) (i->second, arg);
2341 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2343 set_global_route_boolean (s, &Route::set_mute, src);
2347 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2349 set_global_route_boolean (s, &Route::set_solo, src);
2353 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2355 set_global_route_boolean (s, &Route::set_record_enable, src);
2360 Session::global_mute_memento (void* src)
2362 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2366 Session::global_metering_memento (void* src)
2368 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2372 Session::global_solo_memento (void* src)
2374 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2378 Session::global_record_enable_memento (void* src)
2380 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2385 template_filter (const string &str, void *arg)
2387 return (str.length() > strlen(Session::template_suffix()) &&
2388 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2392 Session::get_template_list (list<string> &template_names)
2394 vector<string *> *templates;
2395 PathScanner scanner;
2398 path = template_path ();
2400 templates = scanner (path, template_filter, 0, false, true);
2402 vector<string*>::iterator i;
2403 for (i = templates->begin(); i != templates->end(); ++i) {
2404 string fullpath = *(*i);
2407 start = fullpath.find_last_of ('/') + 1;
2408 if ((end = fullpath.find_last_of ('.')) <0) {
2409 end = fullpath.length();
2412 template_names.push_back(fullpath.substr(start, (end-start)));
2417 Session::read_favorite_dirs (FavoriteDirs & favs)
2419 string path = get_user_ardour_path();
2420 path += "/favorite_dirs";
2422 ifstream fav (path.c_str());
2427 if (errno != ENOENT) {
2428 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2439 getline(fav, newfav);
2445 favs.push_back (newfav);
2452 Session::write_favorite_dirs (FavoriteDirs & favs)
2454 string path = get_user_ardour_path();
2455 path += "/favorite_dirs";
2457 ofstream fav (path.c_str());
2463 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2464 fav << (*i) << endl;
2471 accept_all_non_peak_files (const string& path, void *arg)
2473 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2477 accept_all_state_files (const string& path, void *arg)
2479 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2483 Session::find_all_sources (string path, set<string>& result)
2488 if (!tree.read (path)) {
2492 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2497 XMLNodeConstIterator niter;
2499 nlist = node->children();
2503 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2507 if ((prop = (*niter)->property (X_("name"))) == 0) {
2511 if (prop->value()[0] == '/') {
2512 /* external file, ignore */
2516 string path = _path; /* /-terminated */
2517 path += sound_dir_name;
2519 path += prop->value();
2521 result.insert (path);
2528 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2530 PathScanner scanner;
2531 vector<string*>* state_files;
2533 string this_snapshot_path;
2539 if (ripped[ripped.length()-1] == '/') {
2540 ripped = ripped.substr (0, ripped.length() - 1);
2543 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2545 if (state_files == 0) {
2550 this_snapshot_path = _path;
2551 this_snapshot_path += _current_snapshot_name;
2552 this_snapshot_path += _statefile_suffix;
2554 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2556 if (exclude_this_snapshot && **i == this_snapshot_path) {
2560 if (find_all_sources (**i, result) < 0) {
2568 struct RegionCounter {
2569 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2570 AudioSourceList::iterator iter;
2571 boost::shared_ptr<Region> region;
2574 RegionCounter() : count (0) {}
2578 Session::cleanup_sources (Session::cleanup_report& rep)
2580 vector<boost::shared_ptr<Source> > dead_sources;
2581 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2582 PathScanner scanner;
2584 vector<space_and_path>::iterator i;
2585 vector<space_and_path>::iterator nexti;
2586 vector<string*>* soundfiles;
2587 vector<string> unused;
2588 set<string> all_sources;
2593 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2595 /* step 1: consider deleting all unused playlists */
2597 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2600 status = AskAboutPlaylistDeletion (*x);
2609 playlists_tbd.push_back (*x);
2613 /* leave it alone */
2618 /* now delete any that were marked for deletion */
2620 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2621 (*x)->drop_references ();
2624 playlists_tbd.clear ();
2626 /* step 2: find all un-used sources */
2631 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2633 AudioSourceList::iterator tmp;
2638 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2642 if (!i->second->used() && i->second->length() > 0) {
2643 dead_sources.push_back (i->second);
2644 i->second->GoingAway();
2650 /* build a list of all the possible sound directories for the session */
2652 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2657 sound_path += (*i).path;
2658 sound_path += sound_dir (false);
2660 if (nexti != session_dirs.end()) {
2667 /* now do the same thing for the files that ended up in the sounds dir(s)
2668 but are not referenced as sources in any snapshot.
2671 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2673 if (soundfiles == 0) {
2677 /* find all sources, but don't use this snapshot because the
2678 state file on disk still references sources we may have already
2682 find_all_sources_across_snapshots (all_sources, true);
2684 /* add our current source list
2687 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2688 boost::shared_ptr<AudioFileSource> fs;
2690 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2691 all_sources.insert (fs->path());
2695 char tmppath1[PATH_MAX+1];
2696 char tmppath2[PATH_MAX+1];
2698 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2703 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2705 realpath(spath.c_str(), tmppath1);
2706 realpath((*i).c_str(), tmppath2);
2708 if (strcmp(tmppath1, tmppath2) == 0) {
2715 unused.push_back (spath);
2719 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2721 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2722 struct stat statbuf;
2724 rep.paths.push_back (*x);
2725 if (stat ((*x).c_str(), &statbuf) == 0) {
2726 rep.space += statbuf.st_size;
2731 /* don't move the file across filesystems, just
2732 stick it in the `dead_sound_dir_name' directory
2733 on whichever filesystem it was already on.
2736 if ((*x).find ("/sounds/") != string::npos) {
2738 /* old school, go up 1 level */
2740 newpath = Glib::path_get_dirname (*x); // "sounds"
2741 newpath = Glib::path_get_dirname (newpath); // "session-name"
2745 /* new school, go up 4 levels */
2747 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2748 newpath = Glib::path_get_dirname (newpath); // "session-name"
2749 newpath = Glib::path_get_dirname (newpath); // "interchange"
2750 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2754 newpath += dead_sound_dir_name;
2756 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2757 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2762 newpath += Glib::path_get_basename ((*x));
2764 if (access (newpath.c_str(), F_OK) == 0) {
2766 /* the new path already exists, try versioning */
2768 char buf[PATH_MAX+1];
2772 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2775 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2776 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2780 if (version == 999) {
2781 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2785 newpath = newpath_v;
2790 /* it doesn't exist, or we can't read it or something */
2794 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2795 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2796 (*x), newpath, strerror (errno))
2801 /* see if there an easy to find peakfile for this file, and remove it.
2804 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2805 peakpath += ".peak";
2807 if (access (peakpath.c_str(), W_OK) == 0) {
2808 if (::unlink (peakpath.c_str()) != 0) {
2809 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2810 peakpath, _path, strerror (errno))
2812 /* try to back out */
2813 rename (newpath.c_str(), _path.c_str());
2821 /* dump the history list */
2825 /* save state so we don't end up a session file
2826 referring to non-existent sources.
2832 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2837 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2839 vector<space_and_path>::iterator i;
2840 string dead_sound_dir;
2841 struct dirent* dentry;
2842 struct stat statbuf;
2848 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2850 dead_sound_dir = (*i).path;
2851 dead_sound_dir += dead_sound_dir_name;
2853 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2857 while ((dentry = readdir (dead)) != 0) {
2859 /* avoid '.' and '..' */
2861 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2862 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2868 fullpath = dead_sound_dir;
2870 fullpath += dentry->d_name;
2872 if (stat (fullpath.c_str(), &statbuf)) {
2876 if (!S_ISREG (statbuf.st_mode)) {
2880 if (unlink (fullpath.c_str())) {
2881 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2882 fullpath, strerror (errno))
2886 rep.paths.push_back (dentry->d_name);
2887 rep.space += statbuf.st_size;
2898 Session::set_dirty ()
2900 bool was_dirty = dirty();
2902 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2905 DirtyChanged(); /* EMIT SIGNAL */
2911 Session::set_clean ()
2913 bool was_dirty = dirty();
2915 _state_of_the_state = Clean;
2918 DirtyChanged(); /* EMIT SIGNAL */
2923 Session::set_deletion_in_progress ()
2925 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2929 Session::add_controllable (Controllable* c)
2931 /* this adds a controllable to the list managed by the Session.
2932 this is a subset of those managed by the Controllable class
2933 itself, and represents the only ones whose state will be saved
2934 as part of the session.
2937 Glib::Mutex::Lock lm (controllables_lock);
2938 controllables.insert (c);
2942 Session::remove_controllable (Controllable* c)
2944 if (_state_of_the_state | Deletion) {
2948 Glib::Mutex::Lock lm (controllables_lock);
2950 Controllables::iterator x = controllables.find (c);
2952 if (x != controllables.end()) {
2953 controllables.erase (x);
2958 Session::controllable_by_id (const PBD::ID& id)
2960 Glib::Mutex::Lock lm (controllables_lock);
2962 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
2963 if ((*i)->id() == id) {
2972 Session::add_instant_xml (XMLNode& node, const std::string& dir)
2974 Stateful::add_instant_xml (node, dir);
2975 Config->add_instant_xml (node, get_user_ardour_path());
2980 Session::save_history (string snapshot_name)
2986 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
2988 if (snapshot_name.empty()) {
2989 snapshot_name = _current_snapshot_name;
2992 xml_path = _path + snapshot_name + ".history";
2994 bak_path = xml_path + ".bak";
2996 if ((access (xml_path.c_str(), F_OK) == 0) &&
2997 (rename (xml_path.c_str(), bak_path.c_str())))
2999 error << _("could not backup old history file, current history not saved.") << endmsg;
3003 if (!tree.write (xml_path))
3005 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3007 /* don't leave a corrupt file lying around if it is
3011 if (unlink (xml_path.c_str())) {
3012 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3014 if (rename (bak_path.c_str(), xml_path.c_str()))
3016 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3027 Session::restore_history (string snapshot_name)
3032 if (snapshot_name.empty()) {
3033 snapshot_name = _current_snapshot_name;
3037 xmlpath = _path + snapshot_name + ".history";
3038 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3040 if (access (xmlpath.c_str(), F_OK)) {
3041 info << string_compose (_("%1: no history file \"%2\" for this session."), _name, xmlpath) << endmsg;
3045 if (!tree.read (xmlpath)) {
3046 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3050 /* replace history */
3053 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3056 UndoTransaction* ut = new UndoTransaction ();
3059 ut->set_name(t->property("name")->value());
3060 stringstream ss(t->property("tv_sec")->value());
3062 ss.str(t->property("tv_usec")->value());
3064 ut->set_timestamp(tv);
3066 for (XMLNodeConstIterator child_it = t->children().begin();
3067 child_it != t->children().end();
3070 XMLNode *n = *child_it;
3073 if (n->name() == "MementoCommand" ||
3074 n->name() == "MementoUndoCommand" ||
3075 n->name() == "MementoRedoCommand") {
3077 if ((c = memento_command_factory(n))) {
3081 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3083 if ((c = global_state_command_factory (*n))) {
3084 ut->add_command (c);
3089 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3100 Session::config_changed (const char* parameter_name)
3102 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3104 if (PARAM_IS ("seamless-loop")) {
3106 } else if (PARAM_IS ("rf-speed")) {
3108 } else if (PARAM_IS ("auto-loop")) {
3110 } else if (PARAM_IS ("auto-input")) {
3112 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3113 /* auto-input only makes a difference if we're rolling */
3115 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3117 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3118 if ((*i)->record_enabled ()) {
3119 (*i)->monitor_input (!Config->get_auto_input());
3124 } else if (PARAM_IS ("punch-in")) {
3128 if ((location = _locations.auto_punch_location()) != 0) {
3130 if (Config->get_punch_in ()) {
3131 replace_event (Event::PunchIn, location->start());
3133 remove_event (location->start(), Event::PunchIn);
3137 } else if (PARAM_IS ("punch-out")) {
3141 if ((location = _locations.auto_punch_location()) != 0) {
3143 if (Config->get_punch_out()) {
3144 replace_event (Event::PunchOut, location->end());
3146 clear_events (Event::PunchOut);
3150 } else if (PARAM_IS ("edit-mode")) {
3152 Glib::Mutex::Lock lm (playlist_lock);
3154 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3155 (*i)->set_edit_mode (Config->get_edit_mode ());
3158 } else if (PARAM_IS ("use-video-sync")) {
3160 waiting_for_sync_offset = Config->get_use_video_sync();
3162 } else if (PARAM_IS ("mmc-control")) {
3164 poke_midi_thread ();
3166 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-id")) {
3169 mmc->set_receive_device_id (Config->get_mmc_receive_device_id());
3172 } else if (PARAM_IS ("mmc-send-id")) {
3175 mmc->set_send_device_id (Config->get_mmc_send_device_id());
3178 } else if (PARAM_IS ("midi-control")) {
3180 poke_midi_thread ();
3182 } else if (PARAM_IS ("raid-path")) {
3184 setup_raid_path (Config->get_raid_path());
3186 } else if (PARAM_IS ("smpte-format")) {
3190 } else if (PARAM_IS ("video-pullup")) {
3194 } else if (PARAM_IS ("seamless-loop")) {
3196 if (play_loop && transport_rolling()) {
3197 // to reset diskstreams etc
3198 request_play_loop (true);
3201 } else if (PARAM_IS ("rf-speed")) {
3203 cumulative_rf_motion = 0;
3206 } else if (PARAM_IS ("click-sound")) {
3208 setup_click_sounds (1);
3210 } else if (PARAM_IS ("click-emphasis-sound")) {
3212 setup_click_sounds (-1);
3214 } else if (PARAM_IS ("clicking")) {
3216 if (Config->get_clicking()) {
3217 if (_click_io && click_data) { // don't require emphasis data
3224 } else if (PARAM_IS ("send-mtc")) {
3226 /* only set the internal flag if we have
3230 if (_mtc_port != 0) {
3231 session_send_mtc = Config->get_send_mtc();
3232 if (session_send_mtc) {
3233 /* mark us ready to send */
3234 next_quarter_frame_to_send = 0;
3237 session_send_mtc = false;
3240 } else if (PARAM_IS ("send-mmc")) {
3242 /* only set the internal flag if we have
3246 if (_mmc_port != 0) {
3247 session_send_mmc = Config->get_send_mmc();
3250 session_send_mmc = false;
3253 } else if (PARAM_IS ("midi-feedback")) {
3255 /* only set the internal flag if we have
3259 if (_mtc_port != 0) {
3260 session_midi_feedback = Config->get_midi_feedback();
3263 } else if (PARAM_IS ("jack-time-master")) {
3265 engine().reset_timebase ();
3267 } else if (PARAM_IS ("native-file-header-format")) {
3269 if (!first_file_header_format_reset) {
3270 reset_native_file_format ();
3273 first_file_header_format_reset = false;
3275 } else if (PARAM_IS ("native-file-data-format")) {
3277 if (!first_file_data_format_reset) {
3278 reset_native_file_format ();
3281 first_file_data_format_reset = false;
3283 } else if (PARAM_IS ("slave-source")) {
3284 set_slave_source (Config->get_slave_source());
3285 } else if (PARAM_IS ("remote-model")) {
3286 set_remote_control_ids ();
3287 } else if (PARAM_IS ("denormal-model")) {