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 _tempo_map = new TempoMap (_current_frame_rate);
131 _tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
133 g_atomic_int_set (&processing_prohibited, 0);
135 _transport_speed = 0;
136 _last_transport_speed = 0;
137 auto_play_legal = false;
138 transport_sub_state = 0;
139 _transport_frame = 0;
141 _requested_return_frame = -1;
142 end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
143 start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
144 _end_location_is_free = true;
145 g_atomic_int_set (&_record_status, Disabled);
146 loop_changing = false;
148 _last_roll_location = 0;
149 _last_record_location = 0;
150 pending_locate_frame = 0;
151 pending_locate_roll = false;
152 pending_locate_flush = false;
153 dstream_buffer_size = 0;
155 state_was_pending = false;
157 outbound_mtc_smpte_frame = 0;
158 next_quarter_frame_to_send = -1;
159 current_block_size = 0;
160 solo_update_disabled = false;
161 currently_soloing = false;
162 _have_captured = false;
163 _worst_output_latency = 0;
164 _worst_input_latency = 0;
165 _worst_track_latency = 0;
166 _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading);
170 butler_mixdown_buffer = 0;
171 butler_gain_buffer = 0;
173 session_send_mmc = false;
174 session_send_mtc = false;
175 post_transport_work = PostTransportWork (0);
176 g_atomic_int_set (&butler_should_do_transport_work, 0);
177 g_atomic_int_set (&butler_active, 0);
178 g_atomic_int_set (&_playback_load, 100);
179 g_atomic_int_set (&_capture_load, 100);
180 g_atomic_int_set (&_playback_load_min, 100);
181 g_atomic_int_set (&_capture_load_min, 100);
183 waiting_to_start = false;
185 _gain_automation_buffer = 0;
186 _pan_automation_buffer = 0;
188 pending_abort = false;
189 destructive_index = 0;
191 first_file_data_format_reset = true;
192 first_file_header_format_reset = true;
193 butler_thread = (pthread_t) 0;
194 midi_thread = (pthread_t) 0;
196 AudioDiskstream::allocate_working_buffers();
198 /* default short fade = 15ms */
200 Crossfade::set_short_xfade_length ((nframes_t) floor (Config->get_short_xfade_seconds() * frame_rate()));
201 SndFileSource::setup_standard_crossfades (frame_rate());
203 last_mmc_step.tv_sec = 0;
204 last_mmc_step.tv_usec = 0;
207 /* click sounds are unset by default, which causes us to internal
208 waveforms for clicks.
212 click_emphasis_data = 0;
214 click_emphasis_length = 0;
217 process_function = &Session::process_with_events;
219 if (Config->get_use_video_sync()) {
220 waiting_for_sync_offset = true;
222 waiting_for_sync_offset = false;
225 _current_frame_rate = 48000;
226 _base_frame_rate = 48000;
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::create (bool& new_session, const string& mix_template, nframes_t initial_length)
476 if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
477 error << string_compose(_("Session: cannot create session dir \"%1\" (%2)"), _path, strerror (errno)) << endmsg;
483 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
484 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
488 /* if this is is an existing session with an old "sounds" directory, just use it. see Session::sound_dir() for more details */
490 if (!Glib::file_test (old_sound_dir(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
494 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
495 error << string_compose(_("Session: cannot create session sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
500 dir = dead_sound_dir ();
502 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
503 error << string_compose(_("Session: cannot create session dead sounds dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
509 if (g_mkdir_with_parents (dir.c_str(), 0755) < 0) {
510 error << string_compose(_("Session: cannot create session export dir \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
515 /* check new_session so we don't overwrite an existing one */
517 if (!mix_template.empty()) {
518 std::string in_path = mix_template;
520 ifstream in(in_path.c_str());
523 string out_path = _path;
525 out_path += _statefile_suffix;
527 ofstream out(out_path.c_str());
532 // okay, session is set up. Treat like normal saved
533 // session from now on.
539 error << string_compose (_("Could not open %1 for writing mix template"), out_path)
545 error << string_compose (_("Could not open mix template %1 for reading"), in_path)
552 /* set initial start + end point */
554 start_location->set_end (0);
555 _locations.add (start_location);
557 end_location->set_end (initial_length);
558 _locations.add (end_location);
560 _state_of_the_state = Clean;
569 Session::load_diskstreams (const XMLNode& node)
572 XMLNodeConstIterator citer;
574 clist = node.children();
576 for (citer = clist.begin(); citer != clist.end(); ++citer) {
580 boost::shared_ptr<AudioDiskstream> dstream (new AudioDiskstream (*this, **citer));
581 add_diskstream (dstream);
584 catch (failed_constructor& err) {
585 error << _("Session: could not load diskstream via XML state") << endmsg;
594 Session::maybe_write_autosave()
596 if (dirty() && record_status() != Recording) {
597 save_state("", true);
602 Session::remove_pending_capture_state ()
607 xml_path += _current_snapshot_name;
608 xml_path += _pending_suffix;
610 unlink (xml_path.c_str());
613 /** Rename a state file.
614 * @param snapshot_name Snapshot name.
617 Session::rename_state (string old_name, string new_name)
619 if (old_name == _current_snapshot_name || old_name == _name) {
620 /* refuse to rename the current snapshot or the "main" one */
624 const string old_xml_path = _path + old_name + _statefile_suffix;
625 const string new_xml_path = _path + new_name + _statefile_suffix;
627 if (rename (old_xml_path.c_str(), new_xml_path.c_str()) != 0) {
628 error << string_compose(_("could not rename snapshot %1 to %2"), old_name, new_name) << endmsg;
632 /** Remove a state file.
633 * @param snapshot_name Snapshot name.
636 Session::remove_state (string snapshot_name)
638 if (snapshot_name == _current_snapshot_name || snapshot_name == _name) {
639 /* refuse to remove the current snapshot or the "main" one */
643 const string xml_path = _path + snapshot_name + _statefile_suffix;
645 /* make a backup copy of the state file */
646 const string bak_path = xml_path + ".bak";
647 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
648 copy_file (xml_path, bak_path);
652 unlink (xml_path.c_str());
656 Session::save_state (string snapshot_name, bool pending)
662 if (_state_of_the_state & CannotSave) {
666 if (!_engine.connected ()) {
667 error << _("Ardour's audio engine is not connected and state saving would lose all I/O connections. Session not saved")
672 tree.set_root (&get_state());
674 if (snapshot_name.empty()) {
675 snapshot_name = _current_snapshot_name;
680 /* proper save: use _statefile_suffix (.ardour in English) */
682 xml_path += snapshot_name;
683 xml_path += _statefile_suffix;
685 /* make a backup copy of the old file */
689 if (g_file_test (xml_path.c_str(), G_FILE_TEST_EXISTS)) {
690 copy_file (xml_path, bak_path);
695 /* pending save: use _pending_suffix (.pending in English) */
697 xml_path += snapshot_name;
698 xml_path += _pending_suffix;
705 tmp_path += snapshot_name;
708 // cerr << "actually writing state to " << xml_path << endl;
710 if (!tree.write (tmp_path)) {
711 error << string_compose (_("state could not be saved to %1"), tmp_path) << endmsg;
712 unlink (tmp_path.c_str());
717 if (rename (tmp_path.c_str(), xml_path.c_str()) != 0) {
718 error << string_compose (_("could not rename temporary session file %1 to %2"), tmp_path, xml_path) << endmsg;
719 unlink (tmp_path.c_str());
726 save_history (snapshot_name);
728 bool was_dirty = dirty();
730 _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
734 DirtyChanged (); /* EMIT SIGNAL */
737 StateSaved (snapshot_name); /* EMIT SIGNAL */
744 Session::restore_state (string snapshot_name)
746 if (load_state (snapshot_name) == 0) {
747 set_state (*state_tree->root());
754 Session::load_state (string snapshot_name)
763 state_was_pending = false;
765 /* check for leftover pending state from a crashed capture attempt */
768 xmlpath += snapshot_name;
769 xmlpath += _pending_suffix;
771 if (Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
773 /* there is pending state from a crashed capture attempt */
775 if (AskAboutPendingState()) {
776 state_was_pending = true;
780 if (!state_was_pending) {
783 xmlpath += snapshot_name;
784 xmlpath += _statefile_suffix;
787 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
788 error << string_compose(_("%1: session state information file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
792 state_tree = new XMLTree;
796 if (!state_tree->read (xmlpath)) {
797 error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
803 XMLNode& root (*state_tree->root());
805 if (root.name() != X_("Session")) {
806 error << string_compose (_("Session file %1 is not an Ardour session"), xmlpath) << endmsg;
812 const XMLProperty* prop;
815 if ((prop = root.property ("version")) == 0) {
816 /* no version implies very old version of Ardour */
820 major_version = atoi (prop->value()); // grab just the first number before the period
821 if (major_version < 2) {
830 backup_path += snapshot_name;
832 backup_path += _statefile_suffix;
834 /* don't make another copy if it already exists */
836 if (!Glib::file_test (backup_path, Glib::FILE_TEST_EXISTS)) {
837 info << string_compose (_("Copying old session file %1 to %2\nUse %2 with Ardour versions before 2.0 from now on"),
838 xmlpath, backup_path)
841 copy_file (xmlpath, backup_path);
843 /* if it fails, don't worry. right? */
851 Session::load_options (const XMLNode& node)
855 LocaleGuard lg (X_("POSIX"));
857 Config->set_variables (node, ConfigVariableBase::Session);
859 if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
860 if ((prop = child->property ("val")) != 0) {
861 _end_location_is_free = (prop->value() == "yes");
869 Session::save_config_options_predicate (ConfigVariableBase::Owner owner) const
871 const ConfigVariableBase::Owner modified_by_session_or_user = (ConfigVariableBase::Owner)
872 (ConfigVariableBase::Session|ConfigVariableBase::Interface);
874 return owner & modified_by_session_or_user;
878 Session::get_options () const
881 LocaleGuard lg (X_("POSIX"));
883 XMLNode& option_root = Config->get_variables (mem_fun (*this, &Session::save_config_options_predicate));
885 child = option_root.add_child ("end-marker-is-free");
886 child->add_property ("val", _end_location_is_free ? "yes" : "no");
898 Session::get_template()
900 /* if we don't disable rec-enable, diskstreams
901 will believe they need to store their capture
902 sources in their state node.
905 disable_record (false);
911 Session::state(bool full_state)
913 XMLNode* node = new XMLNode("Session");
916 // store libardour version, just in case
918 snprintf(buf, sizeof(buf)-1, "%d.%d.%d",
919 libardour2_major_version, libardour2_minor_version, libardour2_micro_version);
920 node->add_property("version", string(buf));
922 /* store configuration settings */
927 node->add_property ("name", _name);
929 if (session_dirs.size() > 1) {
933 vector<space_and_path>::iterator i = session_dirs.begin();
934 vector<space_and_path>::iterator next;
936 ++i; /* skip the first one */
940 while (i != session_dirs.end()) {
944 if (next != session_dirs.end()) {
954 child = node->add_child ("Path");
955 child->add_content (p);
959 /* save the ID counter */
961 snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
962 node->add_property ("id-counter", buf);
964 /* various options */
966 node->add_child_nocopy (get_options());
968 child = node->add_child ("Sources");
971 Glib::Mutex::Lock sl (audio_source_lock);
973 for (AudioSourceList::iterator siter = audio_sources.begin(); siter != audio_sources.end(); ++siter) {
975 /* Don't save information about AudioFileSources that are empty */
977 boost::shared_ptr<AudioFileSource> fs;
979 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
981 /* destructive file sources are OK if they are empty, because
982 we will re-use them every time.
985 if (!fs->destructive()) {
986 if (fs->length() == 0) {
992 child->add_child_nocopy (siter->second->get_state());
996 child = node->add_child ("Regions");
999 Glib::Mutex::Lock rl (region_lock);
1001 for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
1003 /* only store regions not attached to playlists */
1005 if (i->second->playlist() == 0) {
1006 child->add_child_nocopy (i->second->state (true));
1011 child = node->add_child ("DiskStreams");
1014 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
1015 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
1016 if (!(*i)->hidden()) {
1017 child->add_child_nocopy ((*i)->get_state());
1023 node->add_child_nocopy (_locations.get_state());
1025 // for a template, just create a new Locations, populate it
1026 // with the default start and end, and get the state for that.
1028 Location* start = new Location(0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
1029 Location* end = new Location(0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
1032 end->set_end(compute_initial_length());
1034 node->add_child_nocopy (loc.get_state());
1037 child = node->add_child ("Connections");
1039 Glib::Mutex::Lock lm (connection_lock);
1040 for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
1041 if (!(*i)->system_dependent()) {
1042 child->add_child_nocopy ((*i)->get_state());
1047 child = node->add_child ("Routes");
1049 boost::shared_ptr<RouteList> r = routes.reader ();
1051 RoutePublicOrderSorter cmp;
1052 RouteList public_order (*r);
1053 public_order.sort (cmp);
1055 for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
1056 if (!(*i)->hidden()) {
1058 child->add_child_nocopy ((*i)->get_state());
1060 child->add_child_nocopy ((*i)->get_template());
1067 child = node->add_child ("EditGroups");
1068 for (list<RouteGroup *>::iterator i = edit_groups.begin(); i != edit_groups.end(); ++i) {
1069 child->add_child_nocopy ((*i)->get_state());
1072 child = node->add_child ("MixGroups");
1073 for (list<RouteGroup *>::iterator i = mix_groups.begin(); i != mix_groups.end(); ++i) {
1074 child->add_child_nocopy ((*i)->get_state());
1077 child = node->add_child ("Playlists");
1078 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
1079 if (!(*i)->hidden()) {
1080 if (!(*i)->empty()) {
1082 child->add_child_nocopy ((*i)->get_state());
1084 child->add_child_nocopy ((*i)->get_template());
1090 child = node->add_child ("UnusedPlaylists");
1091 for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ++i) {
1092 if (!(*i)->hidden()) {
1093 if (!(*i)->empty()) {
1095 child->add_child_nocopy ((*i)->get_state());
1097 child->add_child_nocopy ((*i)->get_template());
1105 child = node->add_child ("Click");
1106 child->add_child_nocopy (_click_io->state (full_state));
1110 child = node->add_child ("NamedSelections");
1111 for (NamedSelectionList::iterator i = named_selections.begin(); i != named_selections.end(); ++i) {
1113 child->add_child_nocopy ((*i)->get_state());
1118 node->add_child_nocopy (_tempo_map->get_state());
1120 node->add_child_nocopy (get_control_protocol_state());
1123 node->add_child_copy (*_extra_xml);
1130 Session::get_control_protocol_state ()
1132 ControlProtocolManager& cpm (ControlProtocolManager::instance());
1133 return cpm.get_state();
1137 Session::set_state (const XMLNode& node)
1141 const XMLProperty* prop;
1144 _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
1147 if (node.name() != X_("Session")){
1148 fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
1152 if ((prop = node.property ("name")) != 0) {
1153 _name = prop->value ();
1156 setup_raid_path(_path);
1158 if ((prop = node.property (X_("id-counter"))) != 0) {
1160 sscanf (prop->value().c_str(), "%" PRIu64, &x);
1161 ID::init_counter (x);
1163 /* old sessions used a timebased counter, so fake
1164 the startup ID counter based on a standard
1169 ID::init_counter (now);
1173 IO::disable_ports ();
1174 IO::disable_connecting ();
1176 /* Object loading order:
1194 if (use_config_midi_ports ()) {
1197 if ((child = find_named_node (node, "extra")) != 0) {
1198 _extra_xml = new XMLNode (*child);
1201 if (((child = find_named_node (node, "Options")) != 0)) { /* old style */
1202 load_options (*child);
1203 } else if ((child = find_named_node (node, "Config")) != 0) { /* new style */
1204 load_options (*child);
1206 error << _("Session: XML state has no options section") << endmsg;
1209 if ((child = find_named_node (node, "Locations")) == 0) {
1210 error << _("Session: XML state has no locations section") << endmsg;
1212 } else if (_locations.set_state (*child)) {
1218 if ((location = _locations.auto_loop_location()) != 0) {
1219 set_auto_loop_location (location);
1222 if ((location = _locations.auto_punch_location()) != 0) {
1223 set_auto_punch_location (location);
1226 if ((location = _locations.end_location()) == 0) {
1227 _locations.add (end_location);
1229 delete end_location;
1230 end_location = location;
1233 if ((location = _locations.start_location()) == 0) {
1234 _locations.add (start_location);
1236 delete start_location;
1237 start_location = location;
1240 AudioFileSource::set_header_position_offset (start_location->start());
1242 if ((child = find_named_node (node, "Sources")) == 0) {
1243 error << _("Session: XML state has no sources section") << endmsg;
1245 } else if (load_sources (*child)) {
1249 if ((child = find_named_node (node, "Regions")) == 0) {
1250 error << _("Session: XML state has no Regions section") << endmsg;
1252 } else if (load_regions (*child)) {
1256 if ((child = find_named_node (node, "Playlists")) == 0) {
1257 error << _("Session: XML state has no playlists section") << endmsg;
1259 } else if (load_playlists (*child)) {
1263 if ((child = find_named_node (node, "UnusedPlaylists")) == 0) {
1265 } else if (load_unused_playlists (*child)) {
1269 if ((child = find_named_node (node, "NamedSelections")) != 0) {
1270 if (load_named_selections (*child)) {
1275 if ((child = find_named_node (node, "DiskStreams")) == 0) {
1276 error << _("Session: XML state has no diskstreams section") << endmsg;
1278 } else if (load_diskstreams (*child)) {
1282 if ((child = find_named_node (node, "Connections")) == 0) {
1283 error << _("Session: XML state has no connections section") << endmsg;
1285 } else if (load_connections (*child)) {
1289 if ((child = find_named_node (node, "EditGroups")) == 0) {
1290 error << _("Session: XML state has no edit groups section") << endmsg;
1292 } else if (load_edit_groups (*child)) {
1296 if ((child = find_named_node (node, "MixGroups")) == 0) {
1297 error << _("Session: XML state has no mix groups section") << endmsg;
1299 } else if (load_mix_groups (*child)) {
1303 if ((child = find_named_node (node, "TempoMap")) == 0) {
1304 error << _("Session: XML state has no Tempo Map section") << endmsg;
1306 } else if (_tempo_map->set_state (*child)) {
1310 if ((child = find_named_node (node, "Routes")) == 0) {
1311 error << _("Session: XML state has no routes section") << endmsg;
1313 } else if (load_routes (*child)) {
1317 if ((child = find_named_node (node, "Click")) == 0) {
1318 warning << _("Session: XML state has no click section") << endmsg;
1319 } else if (_click_io) {
1320 _click_io->set_state (*child);
1323 if ((child = find_named_node (node, "ControlProtocols")) != 0) {
1324 ControlProtocolManager::instance().set_protocol_states (*child);
1327 /* here beginneth the second phase ... */
1329 StateReady (); /* EMIT SIGNAL */
1338 Session::load_routes (const XMLNode& node)
1341 XMLNodeConstIterator niter;
1342 RouteList new_routes;
1344 nlist = node.children();
1348 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1350 boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
1353 error << _("Session: cannot create Route from XML description.") << endmsg;
1357 new_routes.push_back (route);
1360 add_routes (new_routes, false);
1365 boost::shared_ptr<Route>
1366 Session::XMLRouteFactory (const XMLNode& node)
1368 if (node.name() != "Route") {
1369 return boost::shared_ptr<Route> ((Route*) 0);
1372 if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
1373 boost::shared_ptr<Route> x (new AudioTrack (*this, node));
1376 boost::shared_ptr<Route> x (new Route (*this, node));
1382 Session::load_regions (const XMLNode& node)
1385 XMLNodeConstIterator niter;
1386 boost::shared_ptr<AudioRegion> region;
1388 nlist = node.children();
1392 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1393 if ((region = XMLRegionFactory (**niter, false)) == 0) {
1394 error << _("Session: cannot create Region from XML description.") << endmsg;
1401 boost::shared_ptr<AudioRegion>
1402 Session::XMLRegionFactory (const XMLNode& node, bool full)
1404 const XMLProperty* prop;
1405 boost::shared_ptr<Source> source;
1406 boost::shared_ptr<AudioSource> as;
1408 SourceList master_sources;
1409 uint32_t nchans = 1;
1412 if (node.name() != X_("Region")) {
1413 return boost::shared_ptr<AudioRegion>();
1416 if ((prop = node.property (X_("channels"))) != 0) {
1417 nchans = atoi (prop->value().c_str());
1421 if ((prop = node.property ("name")) == 0) {
1422 cerr << "no name for this region\n";
1426 if ((prop = node.property (X_("source-0"))) == 0) {
1427 if ((prop = node.property ("source")) == 0) {
1428 error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
1429 return boost::shared_ptr<AudioRegion>();
1433 PBD::ID s_id (prop->value());
1435 if ((source = source_by_id (s_id)) == 0) {
1436 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
1437 return boost::shared_ptr<AudioRegion>();
1440 as = boost::dynamic_pointer_cast<AudioSource>(source);
1442 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
1443 return boost::shared_ptr<AudioRegion>();
1446 sources.push_back (as);
1448 /* pickup other channels */
1450 for (uint32_t n=1; n < nchans; ++n) {
1451 snprintf (buf, sizeof(buf), X_("source-%d"), n);
1452 if ((prop = node.property (buf)) != 0) {
1454 PBD::ID id2 (prop->value());
1456 if ((source = source_by_id (id2)) == 0) {
1457 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1458 return boost::shared_ptr<AudioRegion>();
1461 as = boost::dynamic_pointer_cast<AudioSource>(source);
1463 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1464 return boost::shared_ptr<AudioRegion>();
1466 sources.push_back (as);
1470 for (uint32_t n=0; n < nchans; ++n) {
1471 snprintf (buf, sizeof(buf), X_("master-source-%d"), n);
1472 if ((prop = node.property (buf)) != 0) {
1474 PBD::ID id2 (prop->value());
1476 if ((source = source_by_id (id2)) == 0) {
1477 error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
1478 return boost::shared_ptr<AudioRegion>();
1481 as = boost::dynamic_pointer_cast<AudioSource>(source);
1483 error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
1484 return boost::shared_ptr<AudioRegion>();
1486 master_sources.push_back (as);
1491 boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
1493 /* a final detail: this is the one and only place that we know how long missing files are */
1495 if (region->whole_file()) {
1496 for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
1497 boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
1499 sfp->set_length (region->length());
1504 if (!master_sources.empty()) {
1505 if (master_sources.size() != nchans) {
1506 error << _("Session: XMLNode describing an AudioRegion is missing some master sources; ignored") << endmsg;
1508 region->set_master_sources (master_sources);
1516 catch (failed_constructor& err) {
1517 return boost::shared_ptr<AudioRegion>();
1522 Session::get_sources_as_xml ()
1525 XMLNode* node = new XMLNode (X_("Sources"));
1526 Glib::Mutex::Lock lm (audio_source_lock);
1528 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
1529 node->add_child_nocopy (i->second->get_state());
1532 /* XXX get MIDI and other sources here */
1538 Session::path_from_region_name (string name, string identifier)
1540 char buf[PATH_MAX+1];
1542 string dir = discover_best_sound_dir ();
1544 for (n = 0; n < 999999; ++n) {
1545 if (identifier.length()) {
1546 snprintf (buf, sizeof(buf), "%s/%s%s%" PRIu32 ".wav", dir.c_str(), name.c_str(),
1547 identifier.c_str(), n);
1549 snprintf (buf, sizeof(buf), "%s/%s-%" PRIu32 ".wav", dir.c_str(), name.c_str(), n);
1552 if (!Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
1557 error << string_compose (_("cannot create new file from region name \"%1\" with ident = \"%2\": too many existing files with similar names"),
1566 Session::load_sources (const XMLNode& node)
1569 XMLNodeConstIterator niter;
1570 boost::shared_ptr<Source> source;
1572 nlist = node.children();
1576 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1579 if ((source = XMLSourceFactory (**niter)) == 0) {
1580 error << _("Session: cannot create Source from XML description.") << endmsg;
1584 catch (non_existent_source& err) {
1585 warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
1586 source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
1593 boost::shared_ptr<Source>
1594 Session::XMLSourceFactory (const XMLNode& node)
1596 if (node.name() != "Source") {
1597 return boost::shared_ptr<Source>();
1601 return SourceFactory::create (*this, node);
1604 catch (failed_constructor& err) {
1605 error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
1606 return boost::shared_ptr<Source>();
1611 Session::save_template (string template_name)
1614 string xml_path, bak_path, template_path;
1616 if (_state_of_the_state & CannotSave) {
1621 string dir = template_dir();
1623 if ((dp = opendir (dir.c_str()))) {
1626 if (g_mkdir_with_parents (dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
1627 error << string_compose(_("Could not create mix templates directory \"%1\" (%2)"), dir, strerror (errno)) << endmsg;
1632 tree.set_root (&get_template());
1635 xml_path += template_name;
1636 xml_path += _template_suffix;
1638 ifstream in(xml_path.c_str());
1641 warning << string_compose(_("Template \"%1\" already exists - new version not created"), template_name) << endmsg;
1647 if (!tree.write (xml_path)) {
1648 error << _("mix template not saved") << endmsg;
1656 Session::rename_template (string old_name, string new_name)
1658 string old_path = template_dir() + old_name + _template_suffix;
1659 string new_path = template_dir() + new_name + _template_suffix;
1661 return rename (old_path.c_str(), new_path.c_str());
1665 Session::delete_template (string name)
1667 string template_path = template_dir();
1668 template_path += name;
1669 template_path += _template_suffix;
1671 return remove (template_path.c_str());
1675 Session::refresh_disk_space ()
1678 struct statfs statfsbuf;
1679 vector<space_and_path>::iterator i;
1680 Glib::Mutex::Lock lm (space_lock);
1683 /* get freespace on every FS that is part of the session path */
1685 _total_free_4k_blocks = 0;
1687 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1688 statfs ((*i).path.c_str(), &statfsbuf);
1690 scale = statfsbuf.f_bsize/4096.0;
1692 (*i).blocks = (uint32_t) floor (statfsbuf.f_bavail * scale);
1693 _total_free_4k_blocks += (*i).blocks;
1699 Session::ensure_sound_dir (string path, string& result)
1704 /* Ensure that the parent directory exists */
1706 if (g_mkdir_with_parents (path.c_str(), 0775)) {
1707 error << string_compose(_("cannot create session directory \"%1\"; ignored"), path) << endmsg;
1711 /* Ensure that the sounds directory exists */
1715 result += sound_dir_name;
1717 if (g_mkdir_with_parents (result.c_str(), 0775)) {
1718 error << string_compose(_("cannot create sounds directory \"%1\"; ignored"), result) << endmsg;
1724 dead += dead_sound_dir_name;
1726 if (g_mkdir_with_parents (dead.c_str(), 0775)) {
1727 error << string_compose(_("cannot create dead sounds directory \"%1\"; ignored"), dead) << endmsg;
1733 peak += peak_dir_name;
1735 if (g_mkdir_with_parents (peak.c_str(), 0775)) {
1736 error << string_compose(_("cannot create peak file directory \"%1\"; ignored"), peak) << endmsg;
1740 /* callers expect this to be terminated ... */
1747 Session::discover_best_sound_dir (bool destructive)
1749 vector<space_and_path>::iterator i;
1752 /* handle common case without system calls */
1754 if (session_dirs.size() == 1) {
1758 /* OK, here's the algorithm we're following here:
1760 We want to select which directory to use for
1761 the next file source to be created. Ideally,
1762 we'd like to use a round-robin process so as to
1763 get maximum performance benefits from splitting
1764 the files across multiple disks.
1766 However, in situations without much diskspace, an
1767 RR approach may end up filling up a filesystem
1768 with new files while others still have space.
1769 Its therefore important to pay some attention to
1770 the freespace in the filesystem holding each
1771 directory as well. However, if we did that by
1772 itself, we'd keep creating new files in the file
1773 system with the most space until it was as full
1774 as all others, thus negating any performance
1775 benefits of this RAID-1 like approach.
1777 So, we use a user-configurable space threshold. If
1778 there are at least 2 filesystems with more than this
1779 much space available, we use RR selection between them.
1780 If not, then we pick the filesystem with the most space.
1782 This gets a good balance between the two
1786 refresh_disk_space ();
1788 int free_enough = 0;
1790 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
1791 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1796 if (free_enough >= 2) {
1798 bool found_it = false;
1800 /* use RR selection process, ensuring that the one
1804 i = last_rr_session_dir;
1807 if (++i == session_dirs.end()) {
1808 i = session_dirs.begin();
1811 if ((*i).blocks * 4096 >= Config->get_disk_choice_space_threshold()) {
1812 if (ensure_sound_dir ((*i).path, result) == 0) {
1813 last_rr_session_dir = i;
1819 } while (i != last_rr_session_dir);
1822 result = sound_dir();
1827 /* pick FS with the most freespace (and that
1828 seems to actually work ...)
1831 vector<space_and_path> sorted;
1832 space_and_path_ascending_cmp cmp;
1834 sorted = session_dirs;
1835 sort (sorted.begin(), sorted.end(), cmp);
1837 for (i = sorted.begin(); i != sorted.end(); ++i) {
1838 if (ensure_sound_dir ((*i).path, result) == 0) {
1839 last_rr_session_dir = i;
1844 /* if the above fails, fall back to the most simplistic solution */
1846 if (i == sorted.end()) {
1855 Session::load_playlists (const XMLNode& node)
1858 XMLNodeConstIterator niter;
1859 boost::shared_ptr<Playlist> playlist;
1861 nlist = node.children();
1865 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1867 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1868 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1876 Session::load_unused_playlists (const XMLNode& node)
1879 XMLNodeConstIterator niter;
1880 boost::shared_ptr<Playlist> playlist;
1882 nlist = node.children();
1886 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1888 if ((playlist = XMLPlaylistFactory (**niter)) == 0) {
1889 error << _("Session: cannot create Playlist from XML description.") << endmsg;
1893 // now manually untrack it
1895 track_playlist (false, boost::weak_ptr<Playlist> (playlist));
1902 boost::shared_ptr<Playlist>
1903 Session::XMLPlaylistFactory (const XMLNode& node)
1906 return PlaylistFactory::create (*this, node);
1909 catch (failed_constructor& err) {
1910 return boost::shared_ptr<Playlist>();
1915 Session::load_named_selections (const XMLNode& node)
1918 XMLNodeConstIterator niter;
1921 nlist = node.children();
1925 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
1927 if ((ns = XMLNamedSelectionFactory (**niter)) == 0) {
1928 error << _("Session: cannot create Named Selection from XML description.") << endmsg;
1936 Session::XMLNamedSelectionFactory (const XMLNode& node)
1939 return new NamedSelection (*this, node);
1942 catch (failed_constructor& err) {
1948 Session::dead_sound_dir () const
1951 res += dead_sound_dir_name;
1957 Session::old_sound_dir (bool with_path) const
1965 res += old_sound_dir_name;
1971 Session::sound_dir (bool with_path) const
1982 res += interchange_dir_name;
1984 res += legalize_for_path (_name);
1986 res += sound_dir_name;
1994 /* if this already exists, don't check for the old session sound directory */
1996 if (Glib::file_test (full, Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2000 /* possibly support old session structure */
2003 string old_withpath;
2005 old_nopath += old_sound_dir_name;
2008 old_withpath = _path;
2009 old_withpath += old_sound_dir_name;
2011 if (Glib::file_test (old_withpath.c_str(), Glib::FILE_TEST_IS_DIR|Glib::FILE_TEST_EXISTS)) {
2013 return old_withpath;
2018 /* ok, old "sounds" directory isn't there, return the new path */
2024 Session::peak_dir () const
2027 res += peak_dir_name;
2033 Session::automation_dir () const
2036 res += "automation/";
2041 Session::template_dir ()
2043 string path = get_user_ardour_path();
2044 path += "templates/";
2050 Session::export_dir () const
2053 res += export_dir_name;
2059 Session::suffixed_search_path (string suffix, bool data)
2063 path += get_user_ardour_path();
2064 if (path[path.length()-1] != ':') {
2069 path += get_system_data_path();
2071 path += get_system_module_path();
2074 vector<string> split_path;
2076 split (path, split_path, ':');
2079 for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
2084 if (distance (i, split_path.end()) != 1) {
2093 Session::template_path ()
2095 return suffixed_search_path (X_("templates"), true);
2099 Session::control_protocol_path ()
2101 return suffixed_search_path (X_("surfaces"), false);
2105 Session::load_connections (const XMLNode& node)
2107 XMLNodeList nlist = node.children();
2108 XMLNodeConstIterator niter;
2112 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2113 if ((*niter)->name() == "InputConnection") {
2114 add_connection (new ARDOUR::InputConnection (**niter));
2115 } else if ((*niter)->name() == "OutputConnection") {
2116 add_connection (new ARDOUR::OutputConnection (**niter));
2118 error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg;
2127 Session::load_edit_groups (const XMLNode& node)
2129 return load_route_groups (node, true);
2133 Session::load_mix_groups (const XMLNode& node)
2135 return load_route_groups (node, false);
2139 Session::load_route_groups (const XMLNode& node, bool edit)
2141 XMLNodeList nlist = node.children();
2142 XMLNodeConstIterator niter;
2147 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2148 if ((*niter)->name() == "RouteGroup") {
2150 rg = add_edit_group ("");
2151 rg->set_state (**niter);
2153 rg = add_mix_group ("");
2154 rg->set_state (**niter);
2163 state_file_filter (const string &str, void *arg)
2165 return (str.length() > strlen(Session::statefile_suffix()) &&
2166 str.find (Session::statefile_suffix()) == (str.length() - strlen (Session::statefile_suffix())));
2170 bool operator()(const string* a, const string* b) {
2176 remove_end(string* state)
2178 string statename(*state);
2180 string::size_type start,end;
2181 if ((start = statename.find_last_of ('/')) != string::npos) {
2182 statename = statename.substr (start+1);
2185 if ((end = statename.rfind(".ardour")) == string::npos) {
2186 end = statename.length();
2189 return new string(statename.substr (0, end));
2193 Session::possible_states (string path)
2195 PathScanner scanner;
2196 vector<string*>* states = scanner (path, state_file_filter, 0, false, false);
2198 transform(states->begin(), states->end(), states->begin(), remove_end);
2201 sort (states->begin(), states->end(), cmp);
2207 Session::possible_states () const
2209 return possible_states(_path);
2213 Session::auto_save()
2215 save_state (_current_snapshot_name);
2219 Session::add_edit_group (string name)
2221 RouteGroup* rg = new RouteGroup (*this, name);
2222 edit_groups.push_back (rg);
2223 edit_group_added (rg); /* EMIT SIGNAL */
2229 Session::add_mix_group (string name)
2231 RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
2232 mix_groups.push_back (rg);
2233 mix_group_added (rg); /* EMIT SIGNAL */
2239 Session::remove_edit_group (RouteGroup& rg)
2241 list<RouteGroup*>::iterator i;
2243 if ((i = find (edit_groups.begin(), edit_groups.end(), &rg)) != edit_groups.end()) {
2244 (*i)->apply (&Route::drop_edit_group, this);
2245 edit_groups.erase (i);
2246 edit_group_removed (); /* EMIT SIGNAL */
2253 Session::remove_mix_group (RouteGroup& rg)
2255 list<RouteGroup*>::iterator i;
2257 if ((i = find (mix_groups.begin(), mix_groups.end(), &rg)) != mix_groups.end()) {
2258 (*i)->apply (&Route::drop_mix_group, this);
2259 mix_groups.erase (i);
2260 mix_group_removed (); /* EMIT SIGNAL */
2267 Session::mix_group_by_name (string name)
2269 list<RouteGroup *>::iterator i;
2271 for (i = mix_groups.begin(); i != mix_groups.end(); ++i) {
2272 if ((*i)->name() == name) {
2280 Session::edit_group_by_name (string name)
2282 list<RouteGroup *>::iterator i;
2284 for (i = edit_groups.begin(); i != edit_groups.end(); ++i) {
2285 if ((*i)->name() == name) {
2293 Session::begin_reversible_command (string name)
2295 current_trans = new UndoTransaction;
2296 current_trans->set_name (name);
2300 Session::commit_reversible_command (Command *cmd)
2305 current_trans->add_command (cmd);
2308 if (current_trans->empty()) {
2312 gettimeofday (&now, 0);
2313 current_trans->set_timestamp (now);
2315 _history.add (current_trans);
2318 Session::GlobalRouteBooleanState
2319 Session::get_global_route_boolean (bool (Route::*method)(void) const)
2321 GlobalRouteBooleanState s;
2322 boost::shared_ptr<RouteList> r = routes.reader ();
2324 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2325 if (!(*i)->hidden()) {
2326 RouteBooleanState v;
2329 Route* r = (*i).get();
2330 v.second = (r->*method)();
2339 Session::GlobalRouteMeterState
2340 Session::get_global_route_metering ()
2342 GlobalRouteMeterState s;
2343 boost::shared_ptr<RouteList> r = routes.reader ();
2345 for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
2346 if (!(*i)->hidden()) {
2350 v.second = (*i)->meter_point();
2360 Session::set_global_route_metering (GlobalRouteMeterState s, void* arg)
2362 for (GlobalRouteMeterState::iterator i = s.begin(); i != s.end(); ++i) {
2364 boost::shared_ptr<Route> r = (i->first.lock());
2367 r->set_meter_point (i->second, arg);
2373 Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
2375 for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
2377 boost::shared_ptr<Route> r = (i->first.lock());
2380 Route* rp = r.get();
2381 (rp->*method) (i->second, arg);
2387 Session::set_global_mute (GlobalRouteBooleanState s, void* src)
2389 set_global_route_boolean (s, &Route::set_mute, src);
2393 Session::set_global_solo (GlobalRouteBooleanState s, void* src)
2395 set_global_route_boolean (s, &Route::set_solo, src);
2399 Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
2401 set_global_route_boolean (s, &Route::set_record_enable, src);
2406 Session::global_mute_memento (void* src)
2408 return sigc::bind (mem_fun (*this, &Session::set_global_mute), get_global_route_boolean (&Route::muted), src);
2412 Session::global_metering_memento (void* src)
2414 return sigc::bind (mem_fun (*this, &Session::set_global_route_metering), get_global_route_metering (), src);
2418 Session::global_solo_memento (void* src)
2420 return sigc::bind (mem_fun (*this, &Session::set_global_solo), get_global_route_boolean (&Route::soloed), src);
2424 Session::global_record_enable_memento (void* src)
2426 return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
2431 template_filter (const string &str, void *arg)
2433 return (str.length() > strlen(Session::template_suffix()) &&
2434 str.find (Session::template_suffix()) == (str.length() - strlen (Session::template_suffix())));
2438 Session::get_template_list (list<string> &template_names)
2440 vector<string *> *templates;
2441 PathScanner scanner;
2444 path = template_path ();
2446 templates = scanner (path, template_filter, 0, false, true);
2448 vector<string*>::iterator i;
2449 for (i = templates->begin(); i != templates->end(); ++i) {
2450 string fullpath = *(*i);
2453 start = fullpath.find_last_of ('/') + 1;
2454 if ((end = fullpath.find_last_of ('.')) <0) {
2455 end = fullpath.length();
2458 template_names.push_back(fullpath.substr(start, (end-start)));
2463 Session::read_favorite_dirs (FavoriteDirs & favs)
2465 string path = get_user_ardour_path();
2466 path += "/favorite_dirs";
2468 ifstream fav (path.c_str());
2473 if (errno != ENOENT) {
2474 //error << string_compose (_("cannot open favorite file %1 (%2)"), path, strerror (errno)) << endmsg;
2485 getline(fav, newfav);
2491 favs.push_back (newfav);
2498 Session::write_favorite_dirs (FavoriteDirs & favs)
2500 string path = get_user_ardour_path();
2501 path += "/favorite_dirs";
2503 ofstream fav (path.c_str());
2509 for (FavoriteDirs::iterator i = favs.begin(); i != favs.end(); ++i) {
2510 fav << (*i) << endl;
2517 accept_all_non_peak_files (const string& path, void *arg)
2519 return (path.length() > 5 && path.find (".peak") != (path.length() - 5));
2523 accept_all_state_files (const string& path, void *arg)
2525 return (path.length() > 7 && path.find (".ardour") == (path.length() - 7));
2529 Session::find_all_sources (string path, set<string>& result)
2534 if (!tree.read (path)) {
2538 if ((node = find_named_node (*tree.root(), "Sources")) == 0) {
2543 XMLNodeConstIterator niter;
2545 nlist = node->children();
2549 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
2553 if ((prop = (*niter)->property (X_("name"))) == 0) {
2557 if (prop->value()[0] == '/') {
2558 /* external file, ignore */
2562 string path = _path; /* /-terminated */
2563 path += sound_dir_name;
2565 path += prop->value();
2567 result.insert (path);
2574 Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_this_snapshot)
2576 PathScanner scanner;
2577 vector<string*>* state_files;
2579 string this_snapshot_path;
2585 if (ripped[ripped.length()-1] == '/') {
2586 ripped = ripped.substr (0, ripped.length() - 1);
2589 state_files = scanner (ripped, accept_all_state_files, (void *) 0, false, true);
2591 if (state_files == 0) {
2596 this_snapshot_path = _path;
2597 this_snapshot_path += _current_snapshot_name;
2598 this_snapshot_path += _statefile_suffix;
2600 for (vector<string*>::iterator i = state_files->begin(); i != state_files->end(); ++i) {
2602 if (exclude_this_snapshot && **i == this_snapshot_path) {
2606 if (find_all_sources (**i, result) < 0) {
2614 struct RegionCounter {
2615 typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
2616 AudioSourceList::iterator iter;
2617 boost::shared_ptr<Region> region;
2620 RegionCounter() : count (0) {}
2624 Session::cleanup_sources (Session::cleanup_report& rep)
2626 vector<boost::shared_ptr<Source> > dead_sources;
2627 vector<boost::shared_ptr<Playlist> > playlists_tbd;
2628 PathScanner scanner;
2630 vector<space_and_path>::iterator i;
2631 vector<space_and_path>::iterator nexti;
2632 vector<string*>* soundfiles;
2633 vector<string> unused;
2634 set<string> all_sources;
2639 _state_of_the_state = (StateOfTheState) (_state_of_the_state | InCleanup);
2642 /* step 1: consider deleting all unused playlists */
2644 for (PlaylistList::iterator x = unused_playlists.begin(); x != unused_playlists.end(); ++x) {
2647 status = AskAboutPlaylistDeletion (*x);
2656 playlists_tbd.push_back (*x);
2660 /* leave it alone */
2665 /* now delete any that were marked for deletion */
2667 for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
2668 (*x)->drop_references ();
2671 playlists_tbd.clear ();
2673 /* step 2: find all un-used sources */
2678 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
2680 AudioSourceList::iterator tmp;
2685 /* do not bother with files that are zero size, otherwise we remove the current "nascent"
2689 if (!i->second->used() && i->second->length() > 0) {
2690 dead_sources.push_back (i->second);
2691 i->second->GoingAway();
2697 /* build a list of all the possible sound directories for the session */
2699 for (i = session_dirs.begin(); i != session_dirs.end(); ) {
2704 sound_path += (*i).path;
2705 sound_path += sound_dir (false);
2707 if (nexti != session_dirs.end()) {
2714 /* now do the same thing for the files that ended up in the sounds dir(s)
2715 but are not referenced as sources in any snapshot.
2718 soundfiles = scanner (sound_path, accept_all_non_peak_files, (void *) 0, false, true);
2720 if (soundfiles == 0) {
2724 /* find all sources, but don't use this snapshot because the
2725 state file on disk still references sources we may have already
2729 find_all_sources_across_snapshots (all_sources, true);
2731 /* add our current source list
2734 for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
2735 boost::shared_ptr<AudioFileSource> fs;
2737 if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
2738 all_sources.insert (fs->path());
2742 char tmppath1[PATH_MAX+1];
2743 char tmppath2[PATH_MAX+1];
2745 for (vector<string*>::iterator x = soundfiles->begin(); x != soundfiles->end(); ++x) {
2750 for (set<string>::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
2752 realpath(spath.c_str(), tmppath1);
2753 realpath((*i).c_str(), tmppath2);
2755 if (strcmp(tmppath1, tmppath2) == 0) {
2762 unused.push_back (spath);
2766 /* now try to move all unused files into the "dead_sounds" directory(ies) */
2768 for (vector<string>::iterator x = unused.begin(); x != unused.end(); ++x) {
2769 struct stat statbuf;
2771 rep.paths.push_back (*x);
2772 if (stat ((*x).c_str(), &statbuf) == 0) {
2773 rep.space += statbuf.st_size;
2778 /* don't move the file across filesystems, just
2779 stick it in the `dead_sound_dir_name' directory
2780 on whichever filesystem it was already on.
2783 if ((*x).find ("/sounds/") != string::npos) {
2785 /* old school, go up 1 level */
2787 newpath = Glib::path_get_dirname (*x); // "sounds"
2788 newpath = Glib::path_get_dirname (newpath); // "session-name"
2792 /* new school, go up 4 levels */
2794 newpath = Glib::path_get_dirname (*x); // "audiofiles"
2795 newpath = Glib::path_get_dirname (newpath); // "session-name"
2796 newpath = Glib::path_get_dirname (newpath); // "interchange"
2797 newpath = Glib::path_get_dirname (newpath); // "session-dir"
2801 newpath += dead_sound_dir_name;
2803 if (g_mkdir_with_parents (newpath.c_str(), 0755) < 0) {
2804 error << string_compose(_("Session: cannot create session peakfile dir \"%1\" (%2)"), newpath, strerror (errno)) << endmsg;
2809 newpath += Glib::path_get_basename ((*x));
2811 if (access (newpath.c_str(), F_OK) == 0) {
2813 /* the new path already exists, try versioning */
2815 char buf[PATH_MAX+1];
2819 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
2822 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
2823 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
2827 if (version == 999) {
2828 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
2832 newpath = newpath_v;
2837 /* it doesn't exist, or we can't read it or something */
2841 if (::rename ((*x).c_str(), newpath.c_str()) != 0) {
2842 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
2843 (*x), newpath, strerror (errno))
2848 /* see if there an easy to find peakfile for this file, and remove it.
2851 string peakpath = (*x).substr (0, (*x).find_last_of ('.'));
2852 peakpath += ".peak";
2854 if (access (peakpath.c_str(), W_OK) == 0) {
2855 if (::unlink (peakpath.c_str()) != 0) {
2856 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
2857 peakpath, _path, strerror (errno))
2859 /* try to back out */
2860 rename (newpath.c_str(), _path.c_str());
2868 /* dump the history list */
2872 /* save state so we don't end up a session file
2873 referring to non-existent sources.
2879 _state_of_the_state = (StateOfTheState) (_state_of_the_state & ~InCleanup);
2885 Session::cleanup_trash_sources (Session::cleanup_report& rep)
2887 vector<space_and_path>::iterator i;
2888 string dead_sound_dir;
2889 struct dirent* dentry;
2890 struct stat statbuf;
2896 for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
2898 dead_sound_dir = (*i).path;
2899 dead_sound_dir += dead_sound_dir_name;
2901 if ((dead = opendir (dead_sound_dir.c_str())) == 0) {
2905 while ((dentry = readdir (dead)) != 0) {
2907 /* avoid '.' and '..' */
2909 if ((dentry->d_name[0] == '.' && dentry->d_name[1] == '\0') ||
2910 (dentry->d_name[2] == '\0' && dentry->d_name[0] == '.' && dentry->d_name[1] == '.')) {
2916 fullpath = dead_sound_dir;
2918 fullpath += dentry->d_name;
2920 if (stat (fullpath.c_str(), &statbuf)) {
2924 if (!S_ISREG (statbuf.st_mode)) {
2928 if (unlink (fullpath.c_str())) {
2929 error << string_compose (_("cannot remove dead sound file %1 (%2)"),
2930 fullpath, strerror (errno))
2934 rep.paths.push_back (dentry->d_name);
2935 rep.space += statbuf.st_size;
2946 Session::set_dirty ()
2948 bool was_dirty = dirty();
2950 _state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
2954 DirtyChanged(); /* EMIT SIGNAL */
2960 Session::set_clean ()
2962 bool was_dirty = dirty();
2964 _state_of_the_state = Clean;
2968 DirtyChanged(); /* EMIT SIGNAL */
2973 Session::set_deletion_in_progress ()
2975 _state_of_the_state = StateOfTheState (_state_of_the_state | Deletion);
2980 Session::add_controllable (Controllable* c)
2982 /* this adds a controllable to the list managed by the Session.
2983 this is a subset of those managed by the Controllable class
2984 itself, and represents the only ones whose state will be saved
2985 as part of the session.
2988 Glib::Mutex::Lock lm (controllables_lock);
2989 controllables.insert (c);
2993 Session::remove_controllable (Controllable* c)
2995 if (_state_of_the_state | Deletion) {
2999 Glib::Mutex::Lock lm (controllables_lock);
3001 Controllables::iterator x = controllables.find (c);
3003 if (x != controllables.end()) {
3004 controllables.erase (x);
3009 Session::controllable_by_id (const PBD::ID& id)
3011 Glib::Mutex::Lock lm (controllables_lock);
3013 for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
3014 if ((*i)->id() == id) {
3023 Session::add_instant_xml (XMLNode& node, const std::string& dir)
3025 Stateful::add_instant_xml (node, dir);
3026 Config->add_instant_xml (node, get_user_ardour_path());
3030 Session::save_history (string snapshot_name)
3036 if (snapshot_name.empty()) {
3037 snapshot_name = _current_snapshot_name;
3040 xml_path = _path + snapshot_name + ".history";
3042 bak_path = xml_path + ".bak";
3044 if (Glib::file_test (xml_path, Glib::FILE_TEST_EXISTS) && ::rename (xml_path.c_str(), bak_path.c_str())) {
3045 error << _("could not backup old history file, current history not saved.") << endmsg;
3049 if (!Config->get_save_history() || Config->get_saved_history_depth() < 0) {
3053 tree.set_root (&_history.get_state (Config->get_saved_history_depth()));
3055 if (!tree.write (xml_path))
3057 error << string_compose (_("history could not be saved to %1"), xml_path) << endmsg;
3059 /* don't leave a corrupt file lying around if it is
3063 if (unlink (xml_path.c_str())) {
3064 error << string_compose (_("could not remove corrupt history file %1"), xml_path) << endmsg;
3066 if (rename (bak_path.c_str(), xml_path.c_str()))
3068 error << string_compose (_("could not restore history file from backup %1"), bak_path) << endmsg;
3079 Session::restore_history (string snapshot_name)
3084 if (snapshot_name.empty()) {
3085 snapshot_name = _current_snapshot_name;
3089 xmlpath = _path + snapshot_name + ".history";
3090 cerr << string_compose(_("Loading history from '%1'."), xmlpath) << endmsg;
3092 if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) {
3096 if (!tree.read (xmlpath)) {
3097 error << string_compose (_("Could not understand session history file \"%1\""), xmlpath) << endmsg;
3101 /* replace history */
3104 for (XMLNodeConstIterator it = tree.root()->children().begin(); it != tree.root()->children().end(); it++) {
3107 UndoTransaction* ut = new UndoTransaction ();
3110 ut->set_name(t->property("name")->value());
3111 stringstream ss(t->property("tv_sec")->value());
3113 ss.str(t->property("tv_usec")->value());
3115 ut->set_timestamp(tv);
3117 for (XMLNodeConstIterator child_it = t->children().begin();
3118 child_it != t->children().end();
3121 XMLNode *n = *child_it;
3124 if (n->name() == "MementoCommand" ||
3125 n->name() == "MementoUndoCommand" ||
3126 n->name() == "MementoRedoCommand") {
3128 if ((c = memento_command_factory(n))) {
3132 } else if (n->name() == X_("GlobalRouteStateCommand")) {
3134 if ((c = global_state_command_factory (*n))) {
3135 ut->add_command (c);
3140 error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
3151 Session::config_changed (const char* parameter_name)
3153 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
3155 if (PARAM_IS ("seamless-loop")) {
3157 } else if (PARAM_IS ("rf-speed")) {
3159 } else if (PARAM_IS ("auto-loop")) {
3161 } else if (PARAM_IS ("auto-input")) {
3163 if (Config->get_monitoring_model() == HardwareMonitoring && transport_rolling()) {
3164 /* auto-input only makes a difference if we're rolling */
3166 boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
3168 for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
3169 if ((*i)->record_enabled ()) {
3170 (*i)->monitor_input (!Config->get_auto_input());
3175 } else if (PARAM_IS ("punch-in")) {
3179 if ((location = _locations.auto_punch_location()) != 0) {
3181 if (Config->get_punch_in ()) {
3182 replace_event (Event::PunchIn, location->start());
3184 remove_event (location->start(), Event::PunchIn);
3188 } else if (PARAM_IS ("punch-out")) {
3192 if ((location = _locations.auto_punch_location()) != 0) {
3194 if (Config->get_punch_out()) {
3195 replace_event (Event::PunchOut, location->end());
3197 clear_events (Event::PunchOut);
3201 } else if (PARAM_IS ("edit-mode")) {
3203 Glib::Mutex::Lock lm (playlist_lock);
3205 for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
3206 (*i)->set_edit_mode (Config->get_edit_mode ());
3209 } else if (PARAM_IS ("use-video-sync")) {
3211 waiting_for_sync_offset = Config->get_use_video_sync();
3213 } else if (PARAM_IS ("mmc-control")) {
3215 poke_midi_thread ();
3217 } else if (PARAM_IS ("mmc-device-id") || PARAM_IS ("mmc-receive-device-id")) {
3219 set_mmc_receive_device_id (Config->get_mmc_receive_device_id());
3221 } else if (PARAM_IS ("mmc-send-device-id")) {
3223 set_mmc_send_device_id (Config->get_mmc_send_device_id());
3225 } else if (PARAM_IS ("midi-control")) {
3227 poke_midi_thread ();
3229 } else if (PARAM_IS ("raid-path")) {
3231 setup_raid_path (Config->get_raid_path());
3233 } else if (PARAM_IS ("smpte-format")) {
3237 } else if (PARAM_IS ("video-pullup")) {
3241 } else if (PARAM_IS ("seamless-loop")) {
3243 if (play_loop && transport_rolling()) {
3244 // to reset diskstreams etc
3245 request_play_loop (true);
3248 } else if (PARAM_IS ("rf-speed")) {
3250 cumulative_rf_motion = 0;
3253 } else if (PARAM_IS ("click-sound")) {
3255 setup_click_sounds (1);
3257 } else if (PARAM_IS ("click-emphasis-sound")) {
3259 setup_click_sounds (-1);
3261 } else if (PARAM_IS ("clicking")) {
3263 if (Config->get_clicking()) {
3264 if (_click_io && click_data) { // don't require emphasis data
3271 } else if (PARAM_IS ("send-mtc")) {
3273 /* only set the internal flag if we have
3277 if (_mtc_port != 0) {
3278 session_send_mtc = Config->get_send_mtc();
3279 if (session_send_mtc) {
3280 /* mark us ready to send */
3281 next_quarter_frame_to_send = 0;
3284 session_send_mtc = false;
3287 } else if (PARAM_IS ("send-mmc")) {
3289 /* only set the internal flag if we have
3293 if (_mmc_port != 0) {
3294 session_send_mmc = Config->get_send_mmc();
3297 session_send_mmc = false;
3300 } else if (PARAM_IS ("midi-feedback")) {
3302 /* only set the internal flag if we have
3306 if (_mtc_port != 0) {
3307 session_midi_feedback = Config->get_midi_feedback();
3310 } else if (PARAM_IS ("jack-time-master")) {
3312 engine().reset_timebase ();
3314 } else if (PARAM_IS ("native-file-header-format")) {
3316 if (!first_file_header_format_reset) {
3317 reset_native_file_format ();
3320 first_file_header_format_reset = false;
3322 } else if (PARAM_IS ("native-file-data-format")) {
3324 if (!first_file_data_format_reset) {
3325 reset_native_file_format ();
3328 first_file_data_format_reset = false;
3330 } else if (PARAM_IS ("slave-source")) {
3331 set_slave_source (Config->get_slave_source());
3332 } else if (PARAM_IS ("remote-model")) {
3333 set_remote_control_ids ();
3334 } else if (PARAM_IS ("denormal-model")) {
3336 } else if (PARAM_IS ("history-depth")) {
3337 set_history_depth (Config->get_history_depth());
3338 } else if (PARAM_IS ("sync-all-route-ordering")) {
3349 Session::set_history_depth (uint32_t d)
3351 _history.set_depth (d);