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>
47 #include <glibmm/thread.h>
49 #include <midi++/mmc.h>
50 #include <midi++/port.h>
52 #include <pbd/error.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 set_history_depth (Config->get_history_depth());
123 /* these two are just provisional settings. set_state()
124 will likely override them.
127 _name = _current_snapshot_name = snapshot_name;
129 _current_frame_rate = _engine.frame_rate ();
130 _nominal_frame_rate = _current_frame_rate;
131 _base_frame_rate = _current_frame_rate;
133 _tempo_map = new TempoMap (_current_frame_rate);
134 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
136 g_atomic_int_set (&processing_prohibited, 0);
138 _transport_speed = 0;
139 _last_transport_speed = 0;
140 auto_play_legal = false;
141 transport_sub_state = 0;
142 _transport_frame = 0;
144 _requested_return_frame = -1;
145 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
146 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
147 _end_location_is_free = true;
148 g_atomic_int_set (&_record_status, Disabled);
149 loop_changing = false;
151 _last_roll_location = 0;
152 _last_record_location = 0;
153 pending_locate_frame = 0;
154 pending_locate_roll = false;
155 pending_locate_flush = false;
156 dstream_buffer_size = 0;
158 state_was_pending = false;
160 outbound_mtc_smpte_frame = 0;
161 next_quarter_frame_to_send = -1;
162 current_block_size = 0;
163 solo_update_disabled = false;
164 currently_soloing = false;
165 _have_captured = false;
166 _worst_output_latency = 0;
167 _worst_input_latency = 0;
168 _worst_track_latency = 0;
169 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
173 butler_mixdown_buffer = 0;
174 butler_gain_buffer = 0;
176 session_send_mmc = false;
177 session_send_mtc = false;
178 post_transport_work = PostTransportWork (0);
179 g_atomic_int_set (&butler_should_do_transport_work, 0);
180 g_atomic_int_set (&butler_active, 0);
181 g_atomic_int_set (&_playback_load, 100);
182 g_atomic_int_set (&_capture_load, 100);
183 g_atomic_int_set (&_playback_load_min, 100);
184 g_atomic_int_set (&_capture_load_min, 100);
186 waiting_to_start = false;
188 _gain_automation_buffer = 0;
189 _pan_automation_buffer = 0;
191 pending_abort = false;
192 destructive_index = 0;
194 first_file_data_format_reset = true;
195 first_file_header_format_reset = true;
196 butler_thread = (pthread_t) 0;
197 midi_thread = (pthread_t) 0;
199 AudioDiskstream::allocate_working_buffers();
201 /* default short fade = 15ms */
203 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
204 SndFileSource::setup_standard_crossfades (frame_rate());
206 last_mmc_step.tv_sec = 0;
207 last_mmc_step.tv_usec = 0;
210 /* click sounds are unset by default, which causes us to internal
211 waveforms for clicks.
215 click_emphasis_data = 0;
217 click_emphasis_length = 0;
220 process_function = &Session::process_with_events;
222 if (Config->get_use_video_sync()) {
223 waiting_for_sync_offset = true;
225 waiting_for_sync_offset = false;
230 _smpte_offset_negative = true;
231 last_smpte_valid = false;
235 last_rr_session_dir = session_dirs.begin();
236 refresh_disk_space ();
238 // set_default_fade (0.2, 5.0); /* steepness, millisecs */
242 average_slave_delta = 1800;
243 have_first_delta_accumulator = false;
244 delta_accumulator_cnt = 0;
245 slave_state = Stopped;
247 _engine.GraphReordered.connect (mem_fun (*this, &Session::graph_reordered));
249 /* These are all static "per-class" signals */
251 RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
252 SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
253 PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
254 Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
255 NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
256 AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
258 Controllable::Destroyed.connect (mem_fun (*this, &Session::remove_controllable));
260 IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
262 /* stop IO objects from doing stuff until we're ready for them */
264 IO::disable_panners ();
265 IO::disable_ports ();
266 IO::disable_connecting ();
270 Session::second_stage_init (bool new_session)
272 AudioFileSource::set_peak_dir (peak_dir());
275 if (load_state (_current_snapshot_name)) {
278 remove_empty_sounds ();
281 if (start_butler_thread()) {
285 if (start_midi_thread ()) {
289 // set_state() will call setup_raid_path(), but if it's a new session we need
290 // to call setup_raid_path() here.
293 if (set_state (*state_tree->root())) {
297 setup_raid_path(_path);
300 /* we can't save till after ::when_engine_running() is called,
301 because otherwise we save state with no connections made.
302 therefore, we reset _state_of_the_state because ::set_state()
303 will have cleared it.
305 we also have to include Loading so that any events that get
306 generated between here and the end of ::when_engine_running()
307 will be processed directly rather than queued.
310 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
313 _locations.changed.connect (mem_fun (this, &Session::locations_changed));
314 _locations.added.connect (mem_fun (this, &Session::locations_added));
315 setup_click_sounds (0);
316 setup_midi_control ();
318 /* Pay attention ... */
320 _engine.Halted.connect (mem_fun (*this, &Session::engine_halted));
321 _engine.Xrun.connect (mem_fun (*this, &Session::xrun_recovery));
324 when_engine_running();
327 /* handle this one in a different way than all others, so that its clear what happened */
329 catch (AudioEngine::PortRegistrationFailure& err) {
338 send_full_time_code ();
339 _engine.transport_locate (0);
340 deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
341 deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
343 ControlProtocolManager::instance().set_session (*this);
346 _end_location_is_free = true;
348 _end_location_is_free = false;
351 _state_of_the_state = Clean;
354 DirtyChanged (); /* EMIT SIGNAL */
356 if (state_was_pending) {
357 save_state (_current_snapshot_name);
358 remove_pending_capture_state ();
359 state_was_pending = false;
366 Session::raid_path () const
370 for (vector<space_and_path>::const_iterator i = session_dirs.begin(); i != session_dirs.end(); ++i) {
375 return path.substr (0, path.length() - 1); // drop final colon
379 Session::setup_raid_path (string path)
381 string::size_type colon;
385 string::size_type len = path.length();
390 if (path.length() == 0) {
394 session_dirs.clear ();
396 for (string::size_type n = 0; n < len; ++n) {
397 if (path[n] == ':') {
404 /* no multiple search path, just one location (common case) */
408 session_dirs.push_back (sp);
415 if (fspath[fspath.length()-1] != '/') {
419 fspath += sound_dir (false);
421 AudioFileSource::set_search_path (fspath);
428 while ((colon = remaining.find_first_of (':')) != string::npos) {
431 sp.path = remaining.substr (0, colon);
432 session_dirs.push_back (sp);
434 /* add sounds to file search path */
437 if (fspath[fspath.length()-1] != '/') {
440 fspath += sound_dir (false);
443 remaining = remaining.substr (colon+1);
446 if (remaining.length()) {
453 if (fspath[fspath.length()-1] != '/') {
456 fspath += sound_dir (false);
459 session_dirs.push_back (sp);
462 /* set the AudioFileSource search path */
464 AudioFileSource::set_search_path (fspath);
466 /* reset the round-robin soundfile path thingie */
468 last_rr_session_dir = session_dirs.begin();
472 Session::ensure_subdirs ()
478 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
479 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
483 /* if this is is an existing session with an old "sounds" directory, just use it. see Session::sound_dir() for more details */
485 if (!Glib::file_test (old_sound_dir(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
489 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
490 error << string_compose(_("Session: cannot create session sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
495 dir = dead_sound_dir ();
497 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
498 error << string_compose(_("Session: cannot create session dead sounds folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
504 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
505 error << string_compose(_("Session: cannot create session export folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
509 dir = analysis_dir ();
511 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
512 error << string_compose(_("Session: cannot create session analysis folder \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
520 Session::create (bool& new_session, const string& mix_template, nframes_t initial_length)
523 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
524 error << string_compose(_("Session: cannot create session folder \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
528 if (ensure_subdirs ()) {
532 /* check new_session so we don't overwrite an existing one */
534 if (!mix_template.empty()) {
535 std::string in_path = mix_template;
537 ifstream in(in_path.c_str());
540 string out_path = _path;
542 out_path += _statefile_suffix;
544 ofstream out(out_path.c_str());
549 // okay, session is set up. Treat like normal saved
550 // session from now on.
556 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
562 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
569 /* set initial start + end point */
571 start_location->set_end (0);
572 _locations.add (start_location);
574 end_location->set_end (initial_length);
575 _locations.add (end_location);
577 _state_of_the_state = Clean;
585 Session::load_diskstreams (const XMLNode& node)
588 XMLNodeConstIterator citer;
590 clist = node.children();
592 for (citer = clist.begin(); citer != clist.end(); ++citer) {
596 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
597 add_diskstream (dstream);
600 catch (failed_constructor& err) {
601 error << _("Session: could not load diskstream via XML state") << endmsg;
610 Session::maybe_write_autosave()
612 if (dirty() && record_status() != Recording) {
613 save_state("", true);
618 Session::remove_pending_capture_state ()
623 xml_path += _current_snapshot_name;
624 xml_path += _pending_suffix;
626 unlink (xml_path.c_str());
629 /** Rename a state file.
630 * @param snapshot_name Snapshot name.
633 Session::rename_state (string old_name, string new_name)
635 if (old_name == _current_snapshot_name || old_name == _name) {
636 /* refuse to rename the current snapshot or the "main" one */
640 const string old_xml_path = _path + old_name + _statefile_suffix;
641 const string new_xml_path = _path + new_name + _statefile_suffix;
643 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
644 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
648 /** Remove a state file.
649 * @param snapshot_name Snapshot name.
652 Session::remove_state (string snapshot_name)
654 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
655 /* refuse to remove the current snapshot or the "main" one */
659 const string xml_path = _path + snapshot_name + _statefile_suffix;
661 /* make a backup copy of the state file */
662 const string bak_path = xml_path + ".bak";
663 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
664 copy_file (xml_path, bak_path);
668 unlink (xml_path.c_str());
672 Session::save_state (string snapshot_name, bool pending)
678 if (_state_of_the_state & CannotSave) {
682 if (!_engine.connected ()) {
683 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
688 tree.set_root (&get_state());
690 if (snapshot_name.empty()) {
691 snapshot_name = _current_snapshot_name;
696 /* proper save: use _statefile_suffix (.ardour in English) */
698 xml_path += snapshot_name;
699 xml_path += _statefile_suffix;
701 /* make a backup copy of the old file */
705 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
706 copy_file (xml_path, bak_path);
711 /* pending save: use _pending_suffix (.pending in English) */
713 xml_path += snapshot_name;
714 xml_path += _pending_suffix;
721 tmp_path += snapshot_name;
724 // cerr << "actually writing state to " << xml_path << endl;
726 if (!tree.write (tmp_path)) {
727 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
728 unlink (tmp_path.c_str());
733 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
734 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
735 unlink (tmp_path.c_str());
742 save_history (snapshot_name);
744 bool was_dirty = dirty();
746 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
750 DirtyChanged (); /* EMIT SIGNAL */
753 StateSaved (snapshot_name); /* EMIT SIGNAL */
760 Session::restore_state (string snapshot_name)
762 if (load_state (snapshot_name) == 0) {
763 set_state (*state_tree->root());
770 Session::load_state (string snapshot_name)
779 state_was_pending = false;
781 /* check for leftover pending state from a crashed capture attempt */
784 xmlpath += snapshot_name;
785 xmlpath += _pending_suffix;
787 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
789 /* there is pending state from a crashed capture attempt */
791 if (AskAboutPendingState()) {
792 state_was_pending = true;
796 if (!state_was_pending) {
799 xmlpath += snapshot_name;
800 xmlpath += _statefile_suffix;
803 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
804 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
808 state_tree = new XMLTree;
812 if (!state_tree->read (xmlpath)) {
813 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
819 XMLNode& root (*state_tree->root());
821 if (root.name() != X_("Session")) {
822 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
828 const XMLProperty* prop;
831 if ((prop = root.property ("version")) == 0) {
832 /* no version implies very old version of Ardour */
836 major_version = atoi (prop->value()); // grab just the first number before the period
837 if (major_version < 2) {
846 backup_path += snapshot_name;
848 backup_path += _statefile_suffix;
850 /* don't make another copy if it already exists */
852 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
853 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
854 xmlpath, backup_path)
857 copy_file (xmlpath, backup_path);
859 /* if it fails, don't worry. right? */
867 Session::load_options (const XMLNode& node)
871 LocaleGuard lg (X_("POSIX"));
873 Config->set_variables (node, ConfigVariableBase::Session);
875 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
876 if ((prop = child->property ("val")) != 0) {
877 _end_location_is_free = (prop->value() == "yes");
885 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
887 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
888 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
890 return owner & modified_by_session_or_user;
894 Session::get_options () const
897 LocaleGuard lg (X_("POSIX"));
899 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
901 child = option_root.add_child ("end-marker-is-free");
902 child->add_property ("val", _end_location_is_free ? "yes" : "no");
914 Session::get_template()
916 /* if we don't disable rec-enable, diskstreams
917 will believe they need to store their capture
918 sources in their state node.
921 disable_record (false);
927 Session::state(bool full_state)
929 XMLNode* node = new XMLNode("Session");
932 // store libardour version, just in case
934 snprintf(buf, sizeof(buf), "%d.%d.%d", libardour2_major_version, libardour2_minor_version, libardour2_micro_version);
935 node->add_property("version", string(buf));
937 /* store configuration settings */
941 node->add_property ("name", _name);
942 snprintf (buf, sizeof (buf), "%" PRId32, _nominal_frame_rate);
943 node->add_property ("sample-rate", buf);
945 if (session_dirs.size() > 1) {
949 vector<space_and_path>::iterator i = session_dirs.begin();
950 vector<space_and_path>::iterator next;
952 ++i; /* skip the first one */
956 while (i != session_dirs.end()) {
960 if (next != session_dirs.end()) {
970 child = node->add_child ("Path");
971 child->add_content (p);
975 /* save the ID counter */
977 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
978 node->add_property ("id-counter", buf);
980 /* various options */
982 node->add_child_nocopy (get_options());
984 child = node->add_child ("Sources");
987 Glib::Mutex::Lock sl (audio_source_lock);
989 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
991 /* Don't save information about AudioFileSources that are empty */
993 boost::shared_ptr<AudioFileSource> fs;
995 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
997 /* destructive file sources are OK if they are empty, because
998 we will re-use them every time.
1001 if (!fs->destructive()) {
1002 if (fs->length() == 0) {
1008 child->add_child_nocopy (siter->second->get_state());
1012 child = node->add_child ("Regions");
1015 Glib::Mutex::Lock rl (region_lock);
1017 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1019 /* only store regions not attached to playlists */
1021 if (i->second->playlist() == 0) {
1022 child->add_child_nocopy (i->second->state (true));
1027 child = node->add_child ("DiskStreams");
1030 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1031 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1032 if (!(*i)->hidden()) {
1033 child->add_child_nocopy ((*i)->get_state());
1039 node->add_child_nocopy (_locations.get_state());
1041 // for a template, just create a new Locations, populate it
1042 // with the default start and end, and get the state for that.
1044 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1045 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1048 end->set_end(compute_initial_length());
1050 node->add_child_nocopy (loc.get_state());
1053 child = node->add_child ("Connections");
1055 Glib::Mutex::Lock lm (connection_lock);
1056 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1057 if (!(*i)->system_dependent()) {
1058 child->add_child_nocopy ((*i)->get_state());
1063 child = node->add_child ("Routes");
1065 boost::shared_ptr<RouteList> r = routes.reader ();
1067 RoutePublicOrderSorter cmp;
1068 RouteList public_order (*r);
1069 public_order.sort (cmp);
1071 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1072 if (!(*i)->hidden()) {
1074 child->add_child_nocopy ((*i)->get_state());
1076 child->add_child_nocopy ((*i)->get_template());
1083 child = node->add_child ("EditGroups");
1084 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1085 child->add_child_nocopy ((*i)->get_state());
1088 child = node->add_child ("MixGroups");
1089 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1090 child->add_child_nocopy ((*i)->get_state());
1093 child = node->add_child ("Playlists");
1094 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1095 if (!(*i)->hidden()) {
1096 if (!(*i)->empty()) {
1098 child->add_child_nocopy ((*i)->get_state());
1100 child->add_child_nocopy ((*i)->get_template());
1106 child = node->add_child ("UnusedPlaylists");
1107 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1108 if (!(*i)->hidden()) {
1109 if (!(*i)->empty()) {
1111 child->add_child_nocopy ((*i)->get_state());
1113 child->add_child_nocopy ((*i)->get_template());
1121 child = node->add_child ("Click");
1122 child->add_child_nocopy (_click_io->state (full_state));
1126 child = node->add_child ("NamedSelections");
1127 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1129 child->add_child_nocopy ((*i)->get_state());
1134 node->add_child_nocopy (_tempo_map->get_state());
1136 node->add_child_nocopy (get_control_protocol_state());
1139 node->add_child_copy (*_extra_xml);
1146 Session::get_control_protocol_state ()
1148 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1149 return cpm.get_state();
1153 Session::set_state (const XMLNode& node)
1157 const XMLProperty* prop;
1160 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1162 if (node.name() != X_("Session")){
1163 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1167 if ((prop = node.property ("name")) != 0) {
1168 _name = prop->value ();
1171 if ((prop = node.property (X_("sample-rate"))) != 0) {
1173 _nominal_frame_rate = atoi (prop->value());
1175 if (_nominal_frame_rate != _current_frame_rate) {
1176 if (AskAboutSampleRateMismatch (_nominal_frame_rate, _current_frame_rate)) {
1182 setup_raid_path(_path);
1184 if ((prop = node.property (X_("id-counter"))) != 0) {
1186 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1187 ID::init_counter (x);
1189 /* old sessions used a timebased counter, so fake
1190 the startup ID counter based on a standard
1195 ID::init_counter (now);
1199 IO::disable_ports ();
1200 IO::disable_connecting ();
1202 /* Object loading order:
1220 if (use_config_midi_ports ()) {
1223 if ((child = find_named_node (node, "extra")) != 0) {
1224 _extra_xml = new XMLNode (*child);
1227 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1228 load_options (*child);
1229 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1230 load_options (*child);
1232 error << _("Session: XML state has no options section") << endmsg;
1235 if ((child = find_named_node (node, "Locations")) == 0) {
1236 error << _("Session: XML state has no locations section") << endmsg;
1238 } else if (_locations.set_state (*child)) {
1244 if ((location = _locations.auto_loop_location()) != 0) {
1245 set_auto_loop_location (location);
1248 if ((location = _locations.auto_punch_location()) != 0) {
1249 set_auto_punch_location (location);
1252 if ((location = _locations.end_location()) == 0) {
1253 _locations.add (end_location);
1255 delete end_location;
1256 end_location = location;
1259 if ((location = _locations.start_location()) == 0) {
1260 _locations.add (start_location);
1262 delete start_location;
1263 start_location = location;
1266 AudioFileSource::set_header_position_offset (start_location->start());
1268 if ((child = find_named_node (node, "Sources")) == 0) {
1269 error << _("Session: XML state has no sources section") << endmsg;
1271 } else if (load_sources (*child)) {
1275 if ((child = find_named_node (node, "Regions")) == 0) {
1276 error << _("Session: XML state has no Regions section") << endmsg;
1278 } else if (load_regions (*child)) {
1282 if ((child = find_named_node (node, "Playlists")) == 0) {
1283 error << _("Session: XML state has no playlists section") << endmsg;
1285 } else if (load_playlists (*child)) {
1289 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1291 } else if (load_unused_playlists (*child)) {
1295 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1296 if (load_named_selections (*child)) {
1301 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1302 error << _("Session: XML state has no diskstreams section") << endmsg;
1304 } else if (load_diskstreams (*child)) {
1308 if ((child = find_named_node (node, "Connections")) == 0) {
1309 error << _("Session: XML state has no connections section") << endmsg;
1311 } else if (load_connections (*child)) {
1315 if ((child = find_named_node (node, "EditGroups")) == 0) {
1316 error << _("Session: XML state has no edit groups section") << endmsg;
1318 } else if (load_edit_groups (*child)) {
1322 if ((child = find_named_node (node, "MixGroups")) == 0) {
1323 error << _("Session: XML state has no mix groups section") << endmsg;
1325 } else if (load_mix_groups (*child)) {
1329 if ((child = find_named_node (node, "TempoMap")) == 0) {
1330 error << _("Session: XML state has no Tempo Map section") << endmsg;
1332 } else if (_tempo_map->set_state (*child)) {
1336 if ((child = find_named_node (node, "Routes")) == 0) {
1337 error << _("Session: XML state has no routes section") << endmsg;
1339 } else if (load_routes (*child)) {
1343 if ((child = find_named_node (node, "Click")) == 0) {
1344 warning << _("Session: XML state has no click section") << endmsg;
1345 } else if (_click_io) {
1346 _click_io->set_state (*child);
1349 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1350 ControlProtocolManager::instance().set_protocol_states (*child);
1353 /* here beginneth the second phase ... */
1355 StateReady (); /* EMIT SIGNAL */
1364 Session::load_routes (const XMLNode& node)
1367 XMLNodeConstIterator niter;
1368 RouteList new_routes;
1370 nlist = node.children();
1374 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1376 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1379 error << _("Session: cannot create Route from XML description.") << endmsg;
1383 new_routes.push_back (route);
1386 add_routes (new_routes, false);
1391 boost::shared_ptr<Route>
1392 Session::XMLRouteFactory (const XMLNode& node)
1394 if (node.name() != "Route") {
1395 return boost::shared_ptr<Route> ((Route*) 0);
1398 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1399 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1402 boost::shared_ptr<Route> x (new Route (*this, node));
1408 Session::load_regions (const XMLNode& node)
1411 XMLNodeConstIterator niter;
1412 boost::shared_ptr<AudioRegion> region;
1414 nlist = node.children();
1418 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1419 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1420 error << _("Session: cannot create Region from XML description.");
1421 const XMLProperty *name = (**niter).property("name");
1424 error << " " << string_compose (_("Can not load state for region '%1'"), name->value());
1434 boost::shared_ptr<AudioRegion>
1435 Session::XMLRegionFactory (const XMLNode& node, bool full)
1437 const XMLProperty* prop;
1438 boost::shared_ptr<Source> source;
1439 boost::shared_ptr<AudioSource> as;
1441 SourceList master_sources;
1442 uint32_t nchans = 1;
1445 if (node.name() != X_("Region")) {
1446 return boost::shared_ptr<AudioRegion>();
1449 if ((prop = node.property (X_("channels"))) != 0) {
1450 nchans = atoi (prop->value().c_str());
1454 if ((prop = node.property ("name")) == 0) {
1455 cerr << "no name for this region\n";
1459 if ((prop = node.property (X_("source-0"))) == 0) {
1460 if ((prop = node.property ("source")) == 0) {
1461 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1462 return boost::shared_ptr<AudioRegion>();
1466 PBD::ID s_id (prop->value());
1468 if ((source = source_by_id (s_id)) == 0) {
1469 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1470 return boost::shared_ptr<AudioRegion>();
1473 as = boost::dynamic_pointer_cast<AudioSource>(source);
1475 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1476 return boost::shared_ptr<AudioRegion>();
1479 sources.push_back (as);
1481 /* pickup other channels */
1483 for (uint32_t n=1; n < nchans; ++n) {
1484 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1485 if ((prop = node.property (buf)) != 0) {
1487 PBD::ID id2 (prop->value());
1489 if ((source = source_by_id (id2)) == 0) {
1490 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1491 return boost::shared_ptr<AudioRegion>();
1494 as = boost::dynamic_pointer_cast<AudioSource>(source);
1496 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1497 return boost::shared_ptr<AudioRegion>();
1499 sources.push_back (as);
1503 for (uint32_t n=0; n < nchans; ++n) {
1504 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1505 if ((prop = node.property (buf)) != 0) {
1507 PBD::ID id2 (prop->value());
1509 if ((source = source_by_id (id2)) == 0) {
1510 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1511 return boost::shared_ptr<AudioRegion>();
1514 as = boost::dynamic_pointer_cast<AudioSource>(source);
1516 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1517 return boost::shared_ptr<AudioRegion>();
1519 master_sources.push_back (as);
1524 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1526 /* a final detail: this is the one and only place that we know how long missing files are */
1528 if (region->whole_file()) {
1529 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1530 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1532 sfp->set_length (region->length());
1537 if (!master_sources.empty()) {
1538 if (master_sources.size() != nchans) {
1539 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1541 region->set_master_sources (master_sources);
1549 catch (failed_constructor& err) {
1550 return boost::shared_ptr<AudioRegion>();
1555 Session::get_sources_as_xml ()
1558 XMLNode* node = new XMLNode (X_("Sources"));
1559 Glib::Mutex::Lock lm (audio_source_lock);
1561 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1562 node->add_child_nocopy (i->second->get_state());
1565 /* XXX get MIDI and other sources here */
1571 Session::path_from_region_name (string name, string identifier)
1573 char buf[PATH_MAX+1];
1575 string dir = discover_best_sound_dir ();
1577 for (n = 0; n < 999999; ++n) {
1578 if (identifier.length()) {
1579 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1580 identifier.c_str(), n);
1582 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1585 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1590 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1599 Session::load_sources (const XMLNode& node)
1602 XMLNodeConstIterator niter;
1603 boost::shared_ptr<Source> source;
1605 nlist = node.children();
1609 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1612 if ((source = XMLSourceFactory (**niter)) == 0) {
1613 error << _("Session: cannot create Source from XML description.") << endmsg;
1617 catch (non_existent_source& err) {
1618 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1619 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1626 boost::shared_ptr<Source>
1627 Session::XMLSourceFactory (const XMLNode& node)
1629 if (node.name() != "Source") {
1630 return boost::shared_ptr<Source>();
1634 return SourceFactory::create (*this, node);
1637 catch (failed_constructor& err) {
1638 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1639 return boost::shared_ptr<Source>();
1644 Session::save_template (string template_name)
1647 string xml_path, bak_path, template_path;
1649 if (_state_of_the_state & CannotSave) {
1654 string dir = template_dir();
1656 if ((dp = opendir (dir.c_str()))) {
1659 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1660 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1665 tree.set_root (&get_template());
1668 xml_path += template_name;
1669 xml_path += _template_suffix;
1671 ifstream in(xml_path.c_str());
1674 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1680 if (!tree.write (xml_path)) {
1681 error << _("mix template not saved") << endmsg;
1689 Session::rename_template (string old_name, string new_name)
1691 string old_path = template_dir() + old_name + _template_suffix;
1692 string new_path = template_dir() + new_name + _template_suffix;
1694 return rename (old_path.c_str(), new_path.c_str());
1698 Session::delete_template (string name)
1700 string template_path = template_dir();
1701 template_path += name;
1702 template_path += _template_suffix;
1704 return remove (template_path.c_str());
1708 Session::refresh_disk_space ()
1711 struct statfs statfsbuf;
1712 vector<space_and_path>::iterator i;
1713 Glib::Mutex::Lock lm (space_lock);
1716 /* get freespace on every FS that is part of the session path */
1718 _total_free_4k_blocks = 0;
1720 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1721 statfs ((*i).path.c_str(), &statfsbuf);
1723 scale = statfsbuf.f_bsize/4096.0;
1725 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1726 _total_free_4k_blocks += (*i).blocks;
1732 Session::ensure_sound_dir (string path, string& result)
1737 /* Ensure that the parent directory exists */
1739 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1740 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1744 /* Ensure that the sounds directory exists */
1748 result += sound_dir_name;
1750 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1751 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1757 dead += dead_sound_dir_name;
1759 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1760 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1766 peak += peak_dir_name;
1768 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1769 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1773 /* callers expect this to be terminated ... */
1780 Session::discover_best_sound_dir (bool destructive)
1782 vector<space_and_path>::iterator i;
1785 /* handle common case without system calls */
1787 if (session_dirs.size() == 1) {
1791 /* OK, here's the algorithm we're following here:
1793 We want to select which directory to use for
1794 the next file source to be created. Ideally,
1795 we'd like to use a round-robin process so as to
1796 get maximum performance benefits from splitting
1797 the files across multiple disks.
1799 However, in situations without much diskspace, an
1800 RR approach may end up filling up a filesystem
1801 with new files while others still have space.
1802 Its therefore important to pay some attention to
1803 the freespace in the filesystem holding each
1804 directory as well. However, if we did that by
1805 itself, we'd keep creating new files in the file
1806 system with the most space until it was as full
1807 as all others, thus negating any performance
1808 benefits of this RAID-1 like approach.
1810 So, we use a user-configurable space threshold. If
1811 there are at least 2 filesystems with more than this
1812 much space available, we use RR selection between them.
1813 If not, then we pick the filesystem with the most space.
1815 This gets a good balance between the two
1819 refresh_disk_space ();
1821 int free_enough = 0;
1823 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1824 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1829 if (free_enough >= 2) {
1831 bool found_it = false;
1833 /* use RR selection process, ensuring that the one
1837 i = last_rr_session_dir;
1840 if (++i == session_dirs.end()) {
1841 i = session_dirs.begin();
1844 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1845 if (ensure_sound_dir ((*i).path, result) == 0) {
1846 last_rr_session_dir = i;
1852 } while (i != last_rr_session_dir);
1855 result = sound_dir();
1860 /* pick FS with the most freespace (and that
1861 seems to actually work ...)
1864 vector<space_and_path> sorted;
1865 space_and_path_ascending_cmp cmp;
1867 sorted = session_dirs;
1868 sort (sorted.begin(), sorted.end(), cmp);
1870 for (i = sorted.begin(); i != sorted.end(); ++i) {
1871 if (ensure_sound_dir ((*i).path, result) == 0) {
1872 last_rr_session_dir = i;
1877 /* if the above fails, fall back to the most simplistic solution */
1879 if (i == sorted.end()) {
1888 Session::load_playlists (const XMLNode& node)
1891 XMLNodeConstIterator niter;
1892 boost::shared_ptr<Playlist> playlist;
1894 nlist = node.children();
1898 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1900 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1901 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1909 Session::load_unused_playlists (const XMLNode& node)
1912 XMLNodeConstIterator niter;
1913 boost::shared_ptr<Playlist> playlist;
1915 nlist = node.children();
1919 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1921 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1922 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1926 // now manually untrack it
1928 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1935 boost::shared_ptr<Playlist>
1936 Session::XMLPlaylistFactory (const XMLNode& node)
1939 return PlaylistFactory::create (*this, node);
1942 catch (failed_constructor& err) {
1943 return boost::shared_ptr<Playlist>();
1948 Session::load_named_selections (const XMLNode& node)
1951 XMLNodeConstIterator niter;
1954 nlist = node.children();
1958 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1960 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1961 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1969 Session::XMLNamedSelectionFactory (const XMLNode& node)
1972 return new NamedSelection (*this, node);
1975 catch (failed_constructor& err) {
1981 Session::dead_sound_dir () const
1984 res += dead_sound_dir_name;
1990 Session::old_sound_dir (bool with_path) const
1998 res += old_sound_dir_name;
2004 Session::sound_dir (bool with_path) const
2015 res += interchange_dir_name;
2017 res += legalize_for_path (_name);
2019 res += sound_dir_name;
2027 /* if this already exists, don't check for the old session sound directory */
2029 if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2033 /* possibly support old session structure */
2036 string old_withpath;
2038 old_nopath += old_sound_dir_name;
2041 old_withpath = _path;
2042 old_withpath += old_sound_dir_name;
2044 if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2046 return old_withpath;
2051 /* ok, old "sounds" directory isn't there, return the new path */
2057 Session::peak_dir () const
2060 res += peak_dir_name;
2066 Session::automation_dir () const
2069 res += "automation/";
2074 Session::analysis_dir () const
2082 Session::template_dir ()
2084 string path = get_user_ardour_path();
2085 path += "templates/";
2091 Session::export_dir () const
2094 res += export_dir_name;
2100 Session::suffixed_search_path (string suffix, bool data)
2104 path += get_user_ardour_path();
2105 if (path[path.length()-1] != ':') {
2110 path += get_system_data_path();
2112 path += get_system_module_path();
2115 vector<string> split_path;
2117 split (path, split_path, ':');
2120 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2125 if (distance (i, split_path.end()) != 1) {
2134 Session::template_path ()
2136 return suffixed_search_path (X_("templates"), true);
2140 Session::control_protocol_path ()
2142 char *p = getenv ("ARDOUR_CONTROL_SURFACE_PATH");
2146 return suffixed_search_path (X_("surfaces"), false);
2150 Session::load_connections (const XMLNode& node)
2152 XMLNodeList nlist = node.children();
2153 XMLNodeConstIterator niter;
2157 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2158 if ((*niter)->name() == "InputConnection") {
2159 add_connection (new ARDOUR::InputConnection (**niter));
2160 } else if ((*niter)->name() == "OutputConnection") {
2161 add_connection (new ARDOUR::OutputConnection (**niter));
2163 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2172 Session::load_edit_groups (const XMLNode& node)
2174 return load_route_groups (node, true);
2178 Session::load_mix_groups (const XMLNode& node)
2180 return load_route_groups (node, false);
2184 Session::load_route_groups (const XMLNode& node, bool edit)
2186 XMLNodeList nlist = node.children();
2187 XMLNodeConstIterator niter;
2192 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2193 if ((*niter)->name() == "RouteGroup") {
2195 rg = add_edit_group ("");
2196 rg->set_state (**niter);
2198 rg = add_mix_group ("");
2199 rg->set_state (**niter);
2208 state_file_filter (const string &str, void *arg)
2210 return (str.length() > strlen(Session::statefile_suffix()) &&
2211 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2215 bool operator()(const string* a, const string* b) {
2221 remove_end(string* state)
2223 string statename(*state);
2225 string::size_type start,end;
2226 if ((start = statename.find_last_of ('/')) != string::npos) {
2227 statename = statename.substr (start+1);
2230 if ((end = statename.rfind(".ardour")) == string::npos) {
2231 end = statename.length();
2234 return new string(statename.substr (0, end));
2238 Session::possible_states (string path)
2240 PathScanner scanner;
2241 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2243 transform(states->begin(), states->end(), states->begin(), remove_end);
2246 sort (states->begin(), states->end(), cmp);
2252 Session::possible_states () const
2254 return possible_states(_path);
2258 Session::auto_save()
2260 save_state (_current_snapshot_name);
2264 Session::add_edit_group (string name)
2266 RouteGroup* rg = new RouteGroup (*this, name);
2267 edit_groups.push_back (rg);
2268 edit_group_added (rg); /* EMIT SIGNAL */
2274 Session::add_mix_group (string name)
2276 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2277 mix_groups.push_back (rg);
2278 mix_group_added (rg); /* EMIT SIGNAL */
2284 Session::remove_edit_group (RouteGroup& rg)
2286 list<RouteGroup*>::iterator i;
2288 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2289 (*i)->apply (&Route::drop_edit_group, this);
2290 edit_groups.erase (i);
2291 edit_group_removed (); /* EMIT SIGNAL */
2298 Session::remove_mix_group (RouteGroup& rg)
2300 list<RouteGroup*>::iterator i;
2302 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2303 (*i)->apply (&Route::drop_mix_group, this);
2304 mix_groups.erase (i);
2305 mix_group_removed (); /* EMIT SIGNAL */
2312 Session::mix_group_by_name (string name)
2314 list<RouteGroup *>::iterator i;
2316 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2317 if ((*i)->name() == name) {
2325 Session::edit_group_by_name (string name)
2327 list<RouteGroup *>::iterator i;
2329 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2330 if ((*i)->name() == name) {
2338 Session::begin_reversible_command (string name)
2340 current_trans = new UndoTransaction;
2341 current_trans->set_name (name);
2345 Session::commit_reversible_command (Command *cmd)
2350 current_trans->add_command (cmd);
2353 if (current_trans->empty()) {
2357 gettimeofday (&now, 0);
2358 current_trans->set_timestamp (now);
2360 _history.add (current_trans);
2363 Session::GlobalRouteBooleanState
2364 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2366 GlobalRouteBooleanState s;
2367 boost::shared_ptr<RouteList> r = routes.reader ();
2369 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2370 if (!(*i)->hidden()) {
2371 RouteBooleanState v;
2374 Route* r = (*i).get();
2375 v.second = (r->*method)();
2384 Session::GlobalRouteMeterState
2385 Session::get_global_route_metering ()
2387 GlobalRouteMeterState s;
2388 boost::shared_ptr<RouteList> r = routes.reader ();
2390 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2391 if (!(*i)->hidden()) {
2395 v.second = (*i)->meter_point();
2405 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2407 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2409 boost::shared_ptr<Route> r = (i->first.lock());
2412 r->set_meter_point (i->second, arg);
2418 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2420 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2422 boost::shared_ptr<Route> r = (i->first.lock());
2425 Route* rp = r.get();
2426 (rp->*method) (i->second, arg);
2432 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2434 set_global_route_boolean (s, &Route::set_mute, src);
2438 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2440 set_global_route_boolean (s, &Route::set_solo, src);
2444 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2446 set_global_route_boolean (s, &Route::set_record_enable, src);
2451 Session::global_mute_memento (void* src)
2453 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2457 Session::global_metering_memento (void* src)
2459 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2463 Session::global_solo_memento (void* src)
2465 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2469 Session::global_record_enable_memento (void* src)
2471 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2476 template_filter (const string &str, void *arg)
2478 return (str.length() > strlen(Session::template_suffix()) &&
2479 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2483 Session::get_template_list (list<string> &template_names)
2485 vector<string *> *templates;
2486 PathScanner scanner;
2489 path = template_path ();
2491 templates = scanner (path, template_filter, 0, false, true);
2493 vector<string*>::iterator i;
2494 for (i = templates->begin(); i != templates->end(); ++i) {
2495 string fullpath = *(*i);
2498 start = fullpath.find_last_of ('/') + 1;
2499 if ((end = fullpath.find_last_of ('.')) <0) {
2500 end = fullpath.length();
2503 template_names.push_back(fullpath.substr(start, (end-start)));
2508 Session::read_favorite_dirs (FavoriteDirs & favs)
2510 string path = get_user_ardour_path();
2511 path += "/favorite_dirs";
2513 ifstream fav (path.c_str());
2518 if (errno != ENOENT) {
2519 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2530 getline(fav, newfav);
2536 favs.push_back (newfav);
2543 Session::write_favorite_dirs (FavoriteDirs & favs)
2545 string path = get_user_ardour_path();
2546 path += "/favorite_dirs";
2548 ofstream fav (path.c_str());
2554 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2555 fav << (*i) << endl;
2562 accept_all_non_peak_files (const string& path, void *arg)
2564 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2568 accept_all_state_files (const string& path, void *arg)
2570 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2574 Session::find_all_sources (string path, set<string>& result)
2579 if (!tree.read (path)) {
2583 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2588 XMLNodeConstIterator niter;
2590 nlist = node->children();
2594 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2598 if ((prop = (*niter)->property (X_("name"))) == 0) {
2602 if (prop->value()[0] == '/') {
2603 /* external file, ignore */
2607 string path = _path; /* /-terminated */
2608 path += sound_dir_name;
2610 path += prop->value();
2612 result.insert (path);
2619 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2621 PathScanner scanner;
2622 vector<string*>* state_files;
2624 string this_snapshot_path;
2630 if (ripped[ripped.length()-1] == '/') {
2631 ripped = ripped.substr (0, ripped.length() - 1);
2634 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2636 if (state_files == 0) {
2641 this_snapshot_path = _path;
2642 this_snapshot_path += _current_snapshot_name;
2643 this_snapshot_path += _statefile_suffix;
2645 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2647 if (exclude_this_snapshot && **i == this_snapshot_path) {
2651 if (find_all_sources (**i, result) < 0) {
2659 struct RegionCounter {
2660 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2661 AudioSourceList::iterator iter;
2662 boost::shared_ptr<Region> region;
2665 RegionCounter() : count (0) {}
2669 Session::cleanup_sources (Session::cleanup_report& rep)
2671 vector<boost::shared_ptr<Source> > dead_sources;
2672 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2673 PathScanner scanner;
2675 vector<space_and_path>::iterator i;
2676 vector<space_and_path>::iterator nexti;
2677 vector<string*>* soundfiles;
2678 vector<string> unused;
2679 set<string> all_sources;
2684 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2687 /* step 1: consider deleting all unused playlists */
2689 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2692 status = AskAboutPlaylistDeletion (*x);
2701 playlists_tbd.push_back (*x);
2705 /* leave it alone */
2710 /* now delete any that were marked for deletion */
2712 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2713 (*x)->drop_references ();
2716 playlists_tbd.clear ();
2718 /* step 2: find all un-used sources */
2723 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2725 AudioSourceList::iterator tmp;
2730 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2734 if (!i->second->used() && i->second->length() > 0) {
2735 dead_sources.push_back (i->second);
2736 i->second->GoingAway();
2742 /* build a list of all the possible sound directories for the session */
2744 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2749 sound_path += (*i).path;
2750 sound_path += sound_dir (false);
2752 if (nexti != session_dirs.end()) {
2759 /* now do the same thing for the files that ended up in the sounds dir(s)
2760 but are not referenced as sources in any snapshot.
2763 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2765 if (soundfiles == 0) {
2769 /* find all sources, but don't use this snapshot because the
2770 state file on disk still references sources we may have already
2774 find_all_sources_across_snapshots (all_sources, true);
2776 /* add our current source list
2779 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2780 boost::shared_ptr<AudioFileSource> fs;
2782 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2783 all_sources.insert (fs->path());
2787 char tmppath1[PATH_MAX+1];
2788 char tmppath2[PATH_MAX+1];
2790 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2795 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2797 realpath(spath.c_str(), tmppath1);
2798 realpath((*i).c_str(), tmppath2);
2800 if (strcmp(tmppath1, tmppath2) == 0) {
2807 unused.push_back (spath);
2811 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2813 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2814 struct stat statbuf;
2816 rep.paths.push_back (*x);
2817 if (stat ((*x).c_str(), &statbuf) == 0) {
2818 rep.space += statbuf.st_size;
2823 /* don't move the file across filesystems, just
2824 stick it in the `dead_sound_dir_name' directory
2825 on whichever filesystem it was already on.
2828 if ((*x).find ("/sounds/") != string::npos) {
2830 /* old school, go up 1 level */
2832 newpath = Glib::path_get_dirname (*x); // "sounds"
2833 newpath = Glib::path_get_dirname (newpath); // "session-name"
2837 /* new school, go up 4 levels */
2839 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2840 newpath = Glib::path_get_dirname (newpath); // "session-name"
2841 newpath = Glib::path_get_dirname (newpath); // "interchange"
2842 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2846 newpath += dead_sound_dir_name;
2848 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2849 error << string_compose(_("Session: cannot create session peakfile folder \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2854 newpath += Glib::path_get_basename ((*x));
2856 if (access (newpath.c_str(), F_OK) == 0) {
2858 /* the new path already exists, try versioning */
2860 char buf[PATH_MAX+1];
2864 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2867 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2868 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2872 if (version == 999) {
2873 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2877 newpath = newpath_v;
2882 /* it doesn't exist, or we can't read it or something */
2886 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2887 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2888 (*x), newpath, strerror (errno))
2893 /* see if there an easy to find peakfile for this file, and remove it.
2896 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2897 peakpath += ".peak";
2899 if (access (peakpath.c_str(), W_OK) == 0) {
2900 if (::unlink (peakpath.c_str()) != 0) {
2901 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2902 peakpath, _path, strerror (errno))
2904 /* try to back out */
2905 rename (newpath.c_str(), _path.c_str());
2913 /* dump the history list */
2917 /* save state so we don't end up a session file
2918 referring to non-existent sources.
2924 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2930 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2932 vector<space_and_path>::iterator i;
2933 string dead_sound_dir;
2934 struct dirent* dentry;
2935 struct stat statbuf;
2941 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2943 dead_sound_dir = (*i).path;
2944 dead_sound_dir += dead_sound_dir_name;
2946 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2950 while ((dentry = readdir (dead)) != 0) {
2952 /* avoid '.' and '..' */
2954 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2955 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2961 fullpath = dead_sound_dir;
2963 fullpath += dentry->d_name;
2965 if (stat (fullpath.c_str(), &statbuf)) {
2969 if (!S_ISREG (statbuf.st_mode)) {
2973 if (unlink (fullpath.c_str())) {
2974 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2975 fullpath, strerror (errno))
2979 rep.paths.push_back (dentry->d_name);
2980 rep.space += statbuf.st_size;
2991 Session::set_dirty ()
2993 bool was_dirty = dirty();
2995 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2999 DirtyChanged(); /* EMIT SIGNAL */
3005 Session::set_clean ()
3007 bool was_dirty = dirty();
3009 _state_of_the_state = Clean;
3013 DirtyChanged(); /* EMIT SIGNAL */
3018 Session::set_deletion_in_progress ()
3020 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
3025 Session::add_controllable (Controllable* c)
3027 /* this adds a controllable to the list managed by the Session.
3028 this is a subset of those managed by the Controllable class
3029 itself, and represents the only ones whose state will be saved
3030 as part of the session.
3033 Glib::Mutex::Lock lm (controllables_lock);
3034 controllables.insert (c);
3038 Session::remove_controllable (Controllable* c)
3040 if (_state_of_the_state | Deletion) {
3044 Glib::Mutex::Lock lm (controllables_lock);
3046 Controllables::iterator x = controllables.find (c);
3048 if (x != controllables.end()) {
3049 controllables.erase (x);
3054 Session::controllable_by_id (const PBD::ID& id)
3056 Glib::Mutex::Lock lm (controllables_lock);
3058 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3059 if ((*i)->id() == id) {
3068 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3070 Stateful::add_instant_xml (node, dir);
3071 Config->add_instant_xml (node, get_user_ardour_path());
3075 Session::save_history (string snapshot_name)
3081 if (snapshot_name.empty()) {
3082 snapshot_name = _current_snapshot_name;
3085 xml_path = _path + snapshot_name + ".history";
3087 bak_path = xml_path + ".bak";
3089 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && ::rename (xml_path.c_str(), bak_path.c_str())) {
3090 error << _("could not backup old history file, current history not saved.") << endmsg;
3094 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3098 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3100 if (!tree.write (xml_path))
3102 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3104 /* don't leave a corrupt file lying around if it is
3108 if (unlink (xml_path.c_str())) {
3109 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3111 if (rename (bak_path.c_str(), xml_path.c_str()))
3113 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3124 Session::restore_history (string snapshot_name)
3129 if (snapshot_name.empty()) {
3130 snapshot_name = _current_snapshot_name;
3134 xmlpath = _path + snapshot_name + ".history";
3135 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3137 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3141 if (!tree.read (xmlpath)) {
3142 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3146 /* replace history */
3149 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3152 UndoTransaction* ut = new UndoTransaction ();
3155 ut->set_name(t->property("name")->value());
3156 stringstream ss(t->property("tv_sec")->value());
3158 ss.str(t->property("tv_usec")->value());
3160 ut->set_timestamp(tv);
3162 for (XMLNodeConstIterator child_it = t->children().begin();
3163 child_it != t->children().end();
3166 XMLNode *n = *child_it;
3169 if (n->name() == "MementoCommand" ||
3170 n->name() == "MementoUndoCommand" ||
3171 n->name() == "MementoRedoCommand") {
3173 if ((c = memento_command_factory(n))) {
3177 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3179 if ((c = global_state_command_factory (*n))) {
3180 ut->add_command (c);
3185 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3196 Session::config_changed (const char* parameter_name)
3198 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3200 if (PARAM_IS ("seamless-loop")) {
3202 } else if (PARAM_IS ("rf-speed")) {
3204 } else if (PARAM_IS ("auto-loop")) {
3206 } else if (PARAM_IS ("auto-input")) {
3208 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3209 /* auto-input only makes a difference if we're rolling */
3211 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3213 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3214 if ((*i)->record_enabled ()) {
3215 (*i)->monitor_input (!Config->get_auto_input());
3220 } else if (PARAM_IS ("punch-in")) {
3224 if ((location = _locations.auto_punch_location()) != 0) {
3226 if (Config->get_punch_in ()) {
3227 replace_event (Event::PunchIn, location->start());
3229 remove_event (location->start(), Event::PunchIn);
3233 } else if (PARAM_IS ("punch-out")) {
3237 if ((location = _locations.auto_punch_location()) != 0) {
3239 if (Config->get_punch_out()) {
3240 replace_event (Event::PunchOut, location->end());
3242 clear_events (Event::PunchOut);
3246 } else if (PARAM_IS ("edit-mode")) {
3248 Glib::Mutex::Lock lm (playlist_lock);
3250 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3251 (*i)->set_edit_mode (Config->get_edit_mode ());
3254 } else if (PARAM_IS ("use-video-sync")) {
3256 waiting_for_sync_offset = Config->get_use_video_sync();
3258 } else if (PARAM_IS ("mmc-control")) {
3260 poke_midi_thread ();
3262 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-device-id")) {
3264 set_mmc_receive_device_id (Config->get_mmc_receive_device_id());
3266 } else if (PARAM_IS ("mmc-send-device-id")) {
3268 set_mmc_send_device_id (Config->get_mmc_send_device_id());
3270 } else if (PARAM_IS ("midi-control")) {
3272 poke_midi_thread ();
3274 } else if (PARAM_IS ("raid-path")) {
3276 setup_raid_path (Config->get_raid_path());
3278 } else if (PARAM_IS ("smpte-format")) {
3282 } else if (PARAM_IS ("video-pullup")) {
3286 } else if (PARAM_IS ("seamless-loop")) {
3288 if (play_loop && transport_rolling()) {
3289 // to reset diskstreams etc
3290 request_play_loop (true);
3293 } else if (PARAM_IS ("rf-speed")) {
3295 cumulative_rf_motion = 0;
3298 } else if (PARAM_IS ("click-sound")) {
3300 setup_click_sounds (1);
3302 } else if (PARAM_IS ("click-emphasis-sound")) {
3304 setup_click_sounds (-1);
3306 } else if (PARAM_IS ("clicking")) {
3308 if (Config->get_clicking()) {
3309 if (_click_io && click_data) { // don't require emphasis data
3316 } else if (PARAM_IS ("send-mtc")) {
3318 /* only set the internal flag if we have
3322 if (_mtc_port != 0) {
3323 session_send_mtc = Config->get_send_mtc();
3324 if (session_send_mtc) {
3325 /* mark us ready to send */
3326 next_quarter_frame_to_send = 0;
3329 session_send_mtc = false;
3332 } else if (PARAM_IS ("send-mmc")) {
3334 /* only set the internal flag if we have
3338 if (_mmc_port != 0) {
3339 session_send_mmc = Config->get_send_mmc();
3342 session_send_mmc = false;
3345 } else if (PARAM_IS ("midi-feedback")) {
3347 /* only set the internal flag if we have
3351 if (_mtc_port != 0) {
3352 session_midi_feedback = Config->get_midi_feedback();
3355 } else if (PARAM_IS ("jack-time-master")) {
3357 engine().reset_timebase ();
3359 } else if (PARAM_IS ("native-file-header-format")) {
3361 if (!first_file_header_format_reset) {
3362 reset_native_file_format ();
3365 first_file_header_format_reset = false;
3367 } else if (PARAM_IS ("native-file-data-format")) {
3369 if (!first_file_data_format_reset) {
3370 reset_native_file_format ();
3373 first_file_data_format_reset = false;
3375 } else if (PARAM_IS ("slave-source")) {
3376 set_slave_source (Config->get_slave_source());
3377 } else if (PARAM_IS ("remote-model")) {
3378 set_remote_control_ids ();
3379 } else if (PARAM_IS ("denormal-model")) {
3381 } else if (PARAM_IS ("history-depth")) {
3382 set_history_depth (Config->get_history_depth());
3383 } else if (PARAM_IS ("sync-all-route-ordering")) {
3394 Session::set_history_depth (uint32_t d)
3396 _history.set_depth (d);